Commit 98f4d038 authored by Robert Schmidt's avatar Robert Schmidt

Merge branch 'integration_2023_w14' into 'develop'

integration_2023_w14

See merge request oai/openairinterface5g!2048

* !1861 NR UE RX Multi-threading
* !2017 scheduling aperiodic SRS at UE
* !2046 Correctly allocate GUTI in NAS UE structures
* !2033 PBCH radio link failure detection at MAC
* !1959 bugfix: change memory management of interface between PHY and MAC scheduler
* !2041 hack: see "Bye." message when quitting gnb running with aw2s
* !2047 NR RRC - RRCReestablishment - Fix MultiplePDU Regression
parents daa1a911 486ae6e7
...@@ -1474,6 +1474,7 @@ set (MAC_SRC ...@@ -1474,6 +1474,7 @@ set (MAC_SRC
set (MAC_NR_SRC set (MAC_NR_SRC
${NR_PHY_INTERFACE_DIR}/NR_IF_Module.c ${NR_PHY_INTERFACE_DIR}/NR_IF_Module.c
${NR_PHY_INTERFACE_DIR}/nr_sched_response.c
${NR_GNB_MAC_DIR}/main.c ${NR_GNB_MAC_DIR}/main.c
${NR_GNB_MAC_DIR}/config.c ${NR_GNB_MAC_DIR}/config.c
${NR_GNB_MAC_DIR}/gNB_scheduler.c ${NR_GNB_MAC_DIR}/gNB_scheduler.c
...@@ -2016,7 +2017,9 @@ add_boolean_option(ENABLE_NRQTSCOPE OFF "Build the Qt-Scope" OFF) ...@@ -2016,7 +2017,9 @@ add_boolean_option(ENABLE_NRQTSCOPE OFF "Build the Qt-Scope" OFF)
if (ENABLE_NRQTSCOPE) if (ENABLE_NRQTSCOPE)
find_package(Qt5 REQUIRED COMPONENTS Widgets Charts) find_package(Qt5 REQUIRED COMPONENTS Widgets Charts)
message ("Qt5 Widgets and Charts found for nrqtscope") message ("Qt5 Widgets and Charts found for nrqtscope")
set(QTSCOPE_SOURCE_NR ${OPENAIR1_DIR}/PHY/TOOLS/nr_phy_qt_scope.cpp) set(QTSCOPE_SOURCE_NR
${OPENAIR1_DIR}/PHY/TOOLS/nr_phy_qt_scope.cpp
${OPENAIR1_DIR}/PHY/TOOLS/phy_scope_interface.c)
# Creates rules for calling the Meta-Object Compiler (moc) on the given source files # Creates rules for calling the Meta-Object Compiler (moc) on the given source files
qt5_wrap_cpp(QTSCOPE_SOURCE_NR ${OPENAIR1_DIR}/PHY/TOOLS/nr_phy_qt_scope.h) qt5_wrap_cpp(QTSCOPE_SOURCE_NR ${OPENAIR1_DIR}/PHY/TOOLS/nr_phy_qt_scope.h)
add_library(nrqtscope MODULE ${QTSCOPE_SOURCE_NR}) add_library(nrqtscope MODULE ${QTSCOPE_SOURCE_NR})
......
...@@ -14,8 +14,8 @@ Ref : ...@@ -14,8 +14,8 @@ Ref :
L1 Tx processing : 210.0 L1 Tx processing : 210.0
DLSCH encoding : 137.0 DLSCH encoding : 137.0
L1 Rx processing : 345.0 L1 Rx processing : 345.0
PUSCH inner-receiver : 184.0 PUSCH inner-receiver : 210.0
PUSCH decoding : 276.0 PUSCH decoding : 210.0
Schedule Response : 48.0 Schedule Response : 48.0
DL & UL scheduling timing : 13.0 DL & UL scheduling timing : 13.0
UL Indication : 60.0 UL Indication : 60.0
......
...@@ -14,10 +14,10 @@ Ref : ...@@ -14,10 +14,10 @@ Ref :
L1 Tx processing : 400.0 L1 Tx processing : 400.0
DLSCH encoding : 177.0 DLSCH encoding : 177.0
L1 Rx processing : 345.0 L1 Rx processing : 345.0
PUSCH inner-receiver : 184.0 PUSCH inner-receiver : 210.0
PUSCH decoding : 276.0 PUSCH decoding : 210.0
Schedule Response : 111.0 Schedule Response : 111.0
DL & UL scheduling timing : 37.0 DL & UL scheduling timing : 20.0
UL Indication : 127.0 UL Indication : 127.0
Threshold : Threshold :
feprx : 1.25 feprx : 1.25
......
...@@ -14,11 +14,11 @@ Ref : ...@@ -14,11 +14,11 @@ Ref :
L1 Tx processing : 170.0 L1 Tx processing : 170.0
DLSCH encoding : 118.0 DLSCH encoding : 118.0
L1 Rx processing : 305.0 L1 Rx processing : 305.0
PUSCH inner-receiver : 117.0 PUSCH inner-receiver : 150.0
PUSCH decoding : 303.0 PUSCH decoding : 210.0
Schedule Response : 25.0 Schedule Response : 20.0
DL & UL scheduling timing : 10.0 DL & UL scheduling timing : 10.0
UL Indication : 34.0 UL Indication : 30.0
Threshold : Threshold :
feprx : 1.25 feprx : 1.25
feptx_prec : 1.25 feptx_prec : 1.25
......
...@@ -98,6 +98,8 @@ void *one_thread(void *arg) { ...@@ -98,6 +98,8 @@ void *one_thread(void *arg) {
myThread->runningOnKey=-1; myThread->runningOnKey=-1;
mutexunlock(tp->incomingFifo.lockF); mutexunlock(tp->incomingFifo.lockF);
} }
else
delNotifiedFIFO_elt(elt);
} while (!myThread->terminate); } while (!myThread->terminate);
return NULL; return NULL;
} }
......
...@@ -279,6 +279,8 @@ static inline void pushTpool(tpool_t *t, notifiedFIFO_elt_t *msg) { ...@@ -279,6 +279,8 @@ static inline void pushTpool(tpool_t *t, notifiedFIFO_elt_t *msg) {
if (msg->reponseFifo) if (msg->reponseFifo)
pushNotifiedFIFO(msg->reponseFifo, msg); pushNotifiedFIFO(msg->reponseFifo, msg);
else
delNotifiedFIFO_elt(msg);
} }
} }
......
...@@ -16,19 +16,20 @@ The UE exits when at any point in operation it gets out of synchronization. When ...@@ -16,19 +16,20 @@ The UE exits when at any point in operation it gets out of synchronization. When
## Initial Synchronization Block ## Initial Synchronization Block
```mermaid ```mermaid
graph TD graph TD
A(Start) -->|UE_thread| B["readFrame<br/>--Reads samples worth 2 frames"] start(Start) -->|UE_thread| rxRu["RU read<br/>(Reads two frames)"]
B --> |Tpool thread| C["UE_synch<br/>--PSS & SSS detection<br/>--PBCH decode"] rxRu --> |Tpool thread| sync["SSB detection<br/>(PSS & SSS detection<br/>PBCH decoding<br/>SIB decoding)"]
B --> |UE_thread| D["readFrame<br/>--trash samples to unblock radio"] rxRu --> |UE_thread| rxRuDummy["RU read<br/>(Dummy read till sync detection to avoid buffer overflow at radio)"]
C --> |Tpool thread| E[syncInFrame<br/>--shift first sample to start of frame] sync --> |Tpool thread| frameSync["Frame synchronization<br/>(Shift received samples to align with frame)"]
D --> |UE_thread| E rxRuDummy --> |UE_thread| frameSync
``` ```
## Regular Slot Processing ## Regular Slot Processing
```mermaid ```mermaid
graph TD graph TD
E[syncInFrame<br/>--shift first sample to start of frame] -->|UE_thread| F["trx_read_func (slot n)"] sync["Frame synchronization<br/>(Shift received samples to align with frame)"] -->|UE_thread| hw_read["RU read (slot n)"]
F --> |Tpool thread| G["processSlotTX (slot n+4)<br/>--PUSCH encode<br/>--PUCCH encode<br/>--trx_write_func"] hw_read --> |UE_thread| rxPreProc["PBCH & PDCCH decoding (slot n)"]
F --> |UE_thread| H["UE_processing (slot n)<br/>--PDCCH decode<br/>--PDSCH decode"] hw_read --> |Tpool thread| txProc["Tx processing (slot n+3)<br/>PUSCH encode<br/>PUCCH encode (wait for DLSCH in slot n+3-k1 to finish)<br/>RU write"]
G --> |Tpool thread| I(Merge) rxPreProc --> |Tpool thread| rxProc["PDSCH decoding (slot n)"]
H --> |UE_thread| I(Merge) rxPreProc --> |UE_thread| join(Merge)
I --> |Go to next slot<br/>UE_thread| F txProc --> |Tpool thread| join
join --> |Go to next slot<br/>UE_thread| hw_read
``` ```
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
#include "PHY/NR_TRANSPORT/nr_transport_proto.h" #include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/MODULATION/nr_modulation.h" #include "PHY/MODULATION/nr_modulation.h"
#include "PHY/NR_TRANSPORT/nr_dlsch.h" #include "PHY/NR_TRANSPORT/nr_dlsch.h"
#include "openair2/NR_PHY_INTERFACE/nr_sched_response.h"
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all #undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
...@@ -126,6 +127,8 @@ void tx_func(void *param) { ...@@ -126,6 +127,8 @@ void tx_func(void *param) {
1); 1);
clock_gettime(CLOCK_MONOTONIC,&info->gNB->rt_L1_profiling.return_L1_TX[rt_prof_idx]); clock_gettime(CLOCK_MONOTONIC,&info->gNB->rt_L1_profiling.return_L1_TX[rt_prof_idx]);
/* this thread is done with the sched_info, decrease the reference counter */
deref_sched_response(info->sched_response_id);
} }
void rx_func(void *param) void rx_func(void *param)
......
...@@ -328,7 +328,9 @@ void fh_if5_south_in(RU_t *ru, ...@@ -328,7 +328,9 @@ void fh_if5_south_in(RU_t *ru,
if (proc->first_rx == 0) { if (proc->first_rx == 0) {
if (proc->tti_rx != *tti) { if (proc->tti_rx != *tti) {
LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->tti_rx %d, subframe %d)\n",proc->tti_rx,*tti); LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->tti_rx %d, subframe %d)\n",proc->tti_rx,*tti);
exit_fun("Exiting"); if (!oai_exit)
exit_fun("Exiting");
return;
} }
if (proc->frame_rx != *frame) { if (proc->frame_rx != *frame) {
......
...@@ -203,6 +203,7 @@ static void process_queued_nr_nfapi_msgs(NR_UE_MAC_INST_t *mac, int sfn_slot) ...@@ -203,6 +203,7 @@ static void process_queued_nr_nfapi_msgs(NR_UE_MAC_INST_t *mac, int sfn_slot)
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); 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) { if (ul_tti_request_crc && ul_tti_request_crc->n_pdus > 0) {
check_and_process_dci(NULL, NULL, NULL, ul_tti_request_crc); check_and_process_dci(NULL, NULL, NULL, ul_tti_request_crc);
free_and_zero(ul_tti_request_crc);
} }
} }
...@@ -232,6 +233,8 @@ static void process_queued_nr_nfapi_msgs(NR_UE_MAC_INST_t *mac, int sfn_slot) ...@@ -232,6 +233,8 @@ static void process_queued_nr_nfapi_msgs(NR_UE_MAC_INST_t *mac, int sfn_slot)
if (get_softmodem_params()->nsa) if (get_softmodem_params()->nsa)
save_nr_measurement_info(dl_tti_request); save_nr_measurement_info(dl_tti_request);
check_and_process_dci(dl_tti_request, tx_data_request, NULL, NULL); check_and_process_dci(dl_tti_request, tx_data_request, NULL, NULL);
free_and_zero(dl_tti_request);
free_and_zero(tx_data_request);
} }
else { else {
AssertFatal(false, "We dont have PDUs in either dl_tti %d or tx_req %d\n", AssertFatal(false, "We dont have PDUs in either dl_tti %d or tx_req %d\n",
...@@ -240,6 +243,7 @@ static void process_queued_nr_nfapi_msgs(NR_UE_MAC_INST_t *mac, int sfn_slot) ...@@ -240,6 +243,7 @@ static void process_queued_nr_nfapi_msgs(NR_UE_MAC_INST_t *mac, int sfn_slot)
} }
if (ul_dci_request && ul_dci_request->numPdus > 0) { if (ul_dci_request && ul_dci_request->numPdus > 0) {
check_and_process_dci(NULL, NULL, ul_dci_request, NULL); check_and_process_dci(NULL, NULL, ul_dci_request, NULL);
free_and_zero(ul_dci_request);
} }
} }
...@@ -324,14 +328,6 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg) ...@@ -324,14 +328,6 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
if (pthread_mutex_lock(&mac->mutex_dl_info)) abort(); if (pthread_mutex_lock(&mac->mutex_dl_info)) abort();
memset(&mac->dl_info, 0, sizeof(mac->dl_info));
mac->dl_info.cc_id = CC_id;
mac->dl_info.gNB_index = gNB_id;
mac->dl_info.module_id = mod_id;
mac->dl_info.frame = frame;
mac->dl_info.slot = slot;
mac->dl_info.dci_ind = NULL;
mac->dl_info.rx_ind = NULL;
if (ch_info) { if (ch_info) {
mac->nr_ue_emul_l1.pmi = ch_info->csi[0].pmi; mac->nr_ue_emul_l1.pmi = ch_info->csi[0].pmi;
mac->nr_ue_emul_l1.ri = ch_info->csi[0].ri; mac->nr_ue_emul_l1.ri = ch_info->csi[0].ri;
...@@ -343,6 +339,14 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg) ...@@ -343,6 +339,14 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
mac->scc->tdd_UL_DL_ConfigurationCommon : mac->scc->tdd_UL_DL_ConfigurationCommon :
mac->scc_SIB->tdd_UL_DL_ConfigurationCommon, mac->scc_SIB->tdd_UL_DL_ConfigurationCommon,
ul_info.slot_rx)) { ul_info.slot_rx)) {
memset(&mac->dl_info, 0, sizeof(mac->dl_info));
mac->dl_info.cc_id = CC_id;
mac->dl_info.gNB_index = gNB_id;
mac->dl_info.module_id = mod_id;
mac->dl_info.frame = frame;
mac->dl_info.slot = slot;
mac->dl_info.dci_ind = NULL;
mac->dl_info.rx_ind = NULL;
nr_ue_dl_indication(&mac->dl_info, &ul_time_alignment); nr_ue_dl_indication(&mac->dl_info, &ul_time_alignment);
} }
...@@ -446,7 +450,7 @@ static void UE_synch(void *arg) { ...@@ -446,7 +450,7 @@ static void UE_synch(void *arg) {
break; break;
*/ */
case pbch: case pbch:
LOG_I(PHY, "[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode); LOG_I(PHY, "[UE thread Synch] Running Initial Synch \n");
uint64_t dl_carrier, ul_carrier; uint64_t dl_carrier, ul_carrier;
nr_get_carrier_frequencies(UE, &dl_carrier, &ul_carrier); nr_get_carrier_frequencies(UE, &dl_carrier, &ul_carrier);
...@@ -563,6 +567,12 @@ void processSlotTX(void *arg) { ...@@ -563,6 +567,12 @@ void processSlotTX(void *arg) {
LOG_D(PHY,"%d.%d => slot type %d\n", proc->frame_tx, proc->nr_slot_tx, proc->tx_slot_type); LOG_D(PHY,"%d.%d => slot type %d\n", proc->frame_tx, proc->nr_slot_tx, proc->tx_slot_type);
if (proc->tx_slot_type == NR_UPLINK_SLOT || proc->tx_slot_type == NR_MIXED_SLOT){ if (proc->tx_slot_type == NR_UPLINK_SLOT || proc->tx_slot_type == NR_MIXED_SLOT){
// wait for rx slots to send indication (if any) that DLSCH decoding is finished
for(int i=0; i < rxtxD->tx_wait_for_dlsch; i++) {
notifiedFIFO_elt_t *res = pullNotifiedFIFO(UE->tx_resume_ind_fifo[proc->nr_slot_tx]);
delNotifiedFIFO_elt(res);
}
// trigger L2 to run ue_scheduler thru IF module // trigger L2 to run ue_scheduler thru IF module
// [TODO] mapping right after NR initial sync // [TODO] mapping right after NR initial sync
if(UE->if_inst != NULL && UE->if_inst->ul_indication != NULL) { if(UE->if_inst != NULL && UE->if_inst->ul_indication != NULL) {
...@@ -589,10 +599,8 @@ void processSlotTX(void *arg) { ...@@ -589,10 +599,8 @@ void processSlotTX(void *arg) {
RU_write(rxtxD); RU_write(rxtxD);
} }
void UE_processing(nr_rxtx_thread_data_t *rxtxD) { nr_phy_data_t UE_dl_preprocessing(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
UE_nr_rxtx_proc_t *proc = &rxtxD->proc;
PHY_VARS_NR_UE *UE = rxtxD->UE;
nr_phy_data_t phy_data = {0}; nr_phy_data_t phy_data = {0};
if (IS_SOFTMODEM_NOS1 || get_softmodem_params()->sa) { if (IS_SOFTMODEM_NOS1 || get_softmodem_params()->sa) {
...@@ -624,17 +632,28 @@ void UE_processing(nr_rxtx_thread_data_t *rxtxD) { ...@@ -624,17 +632,28 @@ void UE_processing(nr_rxtx_thread_data_t *rxtxD) {
UE->if_inst->dl_indication(&dl_indication, NULL); UE->if_inst->dl_indication(&dl_indication, NULL);
} }
// Process Rx data for one sub-frame
#ifdef UE_SLOT_PARALLELISATION
phy_procedures_slot_parallelization_nrUE_RX( UE, proc, 0, 0, 1, no_relay, NULL );
#else
uint64_t a=rdtsc_oai(); uint64_t a=rdtsc_oai();
phy_procedures_nrUE_RX(UE, proc, &phy_data); pbch_pdcch_processing(UE, proc, &phy_data);
if (phy_data.dlsch[0].active) {
// indicate to tx thread to wait for DLSCH decoding
const int ack_nack_slot = (proc->nr_slot_rx + phy_data.dlsch[0].dlsch_config.k1_feedback) % UE->frame_parms.slots_per_frame;
UE->tx_wait_for_dlsch[ack_nack_slot]++;
}
LOG_D(PHY, "In %s: slot %d, time %llu\n", __FUNCTION__, proc->nr_slot_rx, (rdtsc_oai()-a)/3500); LOG_D(PHY, "In %s: slot %d, time %llu\n", __FUNCTION__, proc->nr_slot_rx, (rdtsc_oai()-a)/3500);
#endif
} }
ue_ta_procedures(UE, proc->nr_slot_tx, proc->frame_tx); ue_ta_procedures(UE, proc->nr_slot_tx, proc->frame_tx);
return phy_data;
}
void UE_dl_processing(void *arg) {
nr_rxtx_thread_data_t *rxtxD = (nr_rxtx_thread_data_t *) arg;
UE_nr_rxtx_proc_t *proc = &rxtxD->proc;
PHY_VARS_NR_UE *UE = rxtxD->UE;
nr_phy_data_t *phy_data = &rxtxD->phy_data;
pdsch_processing(UE, proc, phy_data);
} }
void dummyWrite(PHY_VARS_NR_UE *UE,openair0_timestamp timestamp, int writeBlockSize) { void dummyWrite(PHY_VARS_NR_UE *UE,openair0_timestamp timestamp, int writeBlockSize) {
...@@ -688,7 +707,7 @@ void readFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp, bool toTrash) ...@@ -688,7 +707,7 @@ void readFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp, bool toTrash)
void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) { void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) {
LOG_I(PHY,"Resynchronizing RX by %d samples (mode = %d)\n",UE->rx_offset,UE->mode); LOG_I(PHY,"Resynchronizing RX by %d samples\n",UE->rx_offset);
if (IS_SOFTMODEM_IQPLAYER || IS_SOFTMODEM_IQRECORDER) { if (IS_SOFTMODEM_IQPLAYER || IS_SOFTMODEM_IQRECORDER) {
// Resynchonize by slot (will work with numerology 1 only) // Resynchonize by slot (will work with numerology 1 only)
...@@ -755,7 +774,6 @@ void *UE_thread(void *arg) { ...@@ -755,7 +774,6 @@ void *UE_thread(void *arg) {
fapi_nr_config_request_t *cfg = &UE->nrUE_config; fapi_nr_config_request_t *cfg = &UE->nrUE_config;
AssertFatal(0== openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]), ""); AssertFatal(0== openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]), "");
UE->rfdevice.host_type = RAU_HOST; UE->rfdevice.host_type = RAU_HOST;
UE->lost_sync = 0;
UE->is_synchronized = 0; UE->is_synchronized = 0;
AssertFatal(UE->rfdevice.trx_start_func(&UE->rfdevice) == 0, "Could not start the device\n"); AssertFatal(UE->rfdevice.trx_start_func(&UE->rfdevice) == 0, "Could not start the device\n");
...@@ -774,12 +792,16 @@ void *UE_thread(void *arg) { ...@@ -774,12 +792,16 @@ void *UE_thread(void *arg) {
bool syncRunning=false; bool syncRunning=false;
const int nb_slot_frame = UE->frame_parms.slots_per_frame; const int nb_slot_frame = UE->frame_parms.slots_per_frame;
int absolute_slot=0, decoded_frame_rx=INT_MAX, trashed_frames=0; int absolute_slot=0, decoded_frame_rx=INT_MAX, trashed_frames=0;
initNotifiedFIFO(&UE->phy_config_ind);
int num_ind_fifo = nb_slot_frame;
for(int i=0; i < num_ind_fifo; i++) {
UE->tx_wait_for_dlsch[num_ind_fifo] = 0;
UE->tx_resume_ind_fifo[i] = malloc(sizeof(*UE->tx_resume_ind_fifo[i]));
initNotifiedFIFO(UE->tx_resume_ind_fifo[i]);
}
while (!oai_exit) { while (!oai_exit) {
if (UE->lost_sync) {
UE->is_synchronized = 0;
UE->lost_sync = 0;
}
if (syncRunning) { if (syncRunning) {
notifiedFIFO_elt_t *res=tryPullTpool(&nf,&(get_nrUE_params()->Tpool)); notifiedFIFO_elt_t *res=tryPullTpool(&nf,&(get_nrUE_params()->Tpool));
...@@ -796,6 +818,11 @@ void *UE_thread(void *arg) { ...@@ -796,6 +818,11 @@ void *UE_thread(void *arg) {
decoded_frame_rx=(((mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | tmp->proc.decoded_frame_rx); decoded_frame_rx=(((mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | tmp->proc.decoded_frame_rx);
// shift the frame index with all the frames we trashed meanwhile we perform the synch search // shift the frame index with all the frames we trashed meanwhile we perform the synch search
decoded_frame_rx=(decoded_frame_rx + UE->init_sync_frame + trashed_frames) % MAX_FRAME_NUMBER; decoded_frame_rx=(decoded_frame_rx + UE->init_sync_frame + trashed_frames) % MAX_FRAME_NUMBER;
// wait for RRC to configure PHY parameters from SIB
if (get_softmodem_params()->sa) {
notifiedFIFO_elt_t *phy_config_res = pullNotifiedFIFO(&UE->phy_config_ind);
delNotifiedFIFO_elt(phy_config_res);
}
} }
delNotifiedFIFO_elt(res); delNotifiedFIFO_elt(res);
start_rx_stream=0; start_rx_stream=0;
...@@ -933,15 +960,22 @@ void *UE_thread(void *arg) { ...@@ -933,15 +960,22 @@ void *UE_thread(void *arg) {
curMsgTx->writeBlockSize = writeBlockSize; curMsgTx->writeBlockSize = writeBlockSize;
curMsgTx->proc.timestamp_tx = writeTimestamp; curMsgTx->proc.timestamp_tx = writeTimestamp;
curMsgTx->UE = UE; curMsgTx->UE = UE;
curMsgTx->tx_wait_for_dlsch = UE->tx_wait_for_dlsch[curMsgTx->proc.nr_slot_tx];
UE->tx_wait_for_dlsch[curMsgTx->proc.nr_slot_tx] = 0;
pushTpool(&(get_nrUE_params()->Tpool), newElt); pushTpool(&(get_nrUE_params()->Tpool), newElt);
// RX slot processing // RX slot processing. We launch and forget.
UE_processing(&curMsg); newElt = newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), curMsg.proc.nr_slot_rx, NULL, UE_dl_processing);
nr_rxtx_thread_data_t *curMsgRx = (nr_rxtx_thread_data_t *) NotifiedFifoData(newElt);
curMsgRx->proc = curMsg.proc;
curMsgRx->UE = UE;
curMsgRx->phy_data = UE_dl_preprocessing(UE, &curMsg.proc);
pushTpool(&(get_nrUE_params()->Tpool), newElt);
if (curMsg.proc.decoded_frame_rx != -1) if (curMsg.proc.decoded_frame_rx != -1)
decoded_frame_rx=(((mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | curMsg.proc.decoded_frame_rx); decoded_frame_rx=(((mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | curMsg.proc.decoded_frame_rx);
else else
decoded_frame_rx=-1; decoded_frame_rx=-1;
if (decoded_frame_rx>0 && decoded_frame_rx != curMsg.proc.frame_rx) if (decoded_frame_rx>0 && decoded_frame_rx != curMsg.proc.frame_rx)
LOG_E(PHY,"Decoded frame index (%d) is not compatible with current context (%d), UE should go back to synch mode\n", LOG_E(PHY,"Decoded frame index (%d) is not compatible with current context (%d), UE should go back to synch mode\n",
......
...@@ -264,7 +264,6 @@ static void get_options(void) { ...@@ -264,7 +264,6 @@ static void get_options(void) {
paramdef_t cmdline_params[] =CMDLINE_NRUEPARAMS_DESC ; paramdef_t cmdline_params[] =CMDLINE_NRUEPARAMS_DESC ;
int numparams = sizeof(cmdline_params)/sizeof(paramdef_t); int numparams = sizeof(cmdline_params)/sizeof(paramdef_t);
config_get(cmdline_params,numparams,NULL); config_get(cmdline_params,numparams,NULL);
config_process_cmdline( cmdline_params,numparams,NULL);
if (vcdflag > 0) if (vcdflag > 0)
ouput_vcd = 1; ouput_vcd = 1;
...@@ -272,38 +271,7 @@ static void get_options(void) { ...@@ -272,38 +271,7 @@ static void get_options(void) {
// set PHY vars from command line // set PHY vars from command line
void set_options(int CC_id, PHY_VARS_NR_UE *UE){ void set_options(int CC_id, PHY_VARS_NR_UE *UE){
NR_DL_FRAME_PARMS *fp = &UE->frame_parms; NR_DL_FRAME_PARMS *fp = &UE->frame_parms;
paramdef_t cmdline_params[] = CMDLINE_NRUE_PHYPARAMS_DESC ;
int numparams = sizeof(cmdline_params)/sizeof(paramdef_t);
UE->mode = normal_txrx;
config_get(cmdline_params,numparams,NULL);
int pindex = config_paramidx_fromname(cmdline_params,numparams, CALIBRX_OPT);
if ( (cmdline_params[pindex].paramflags & PARAMFLAG_PARAMSET) != 0) UE->mode = rx_calib_ue;
pindex = config_paramidx_fromname(cmdline_params,numparams, CALIBRXMED_OPT);
if ( (cmdline_params[pindex].paramflags & PARAMFLAG_PARAMSET) != 0) UE->mode = rx_calib_ue_med;
pindex = config_paramidx_fromname(cmdline_params,numparams, CALIBRXBYP_OPT);
if ( (cmdline_params[pindex].paramflags & PARAMFLAG_PARAMSET) != 0) UE->mode = rx_calib_ue_byp;
pindex = config_paramidx_fromname(cmdline_params,numparams, DBGPRACH_OPT);
if (cmdline_params[pindex].uptr)
if ( *(cmdline_params[pindex].uptr) > 0) UE->mode = debug_prach;
pindex = config_paramidx_fromname(cmdline_params,numparams,NOL2CONNECT_OPT );
if (cmdline_params[pindex].uptr)
if ( *(cmdline_params[pindex].uptr) > 0) UE->mode = no_L2_connect;
pindex = config_paramidx_fromname(cmdline_params,numparams,CALIBPRACH_OPT );
if (cmdline_params[pindex].uptr)
if ( *(cmdline_params[pindex].uptr) > 0) UE->mode = calib_prach_tx;
pindex = config_paramidx_fromname(cmdline_params,numparams,DUMPFRAME_OPT );
if ((cmdline_params[pindex].paramflags & PARAMFLAG_PARAMSET) != 0)
UE->mode = rx_dump_frame;
// Init power variables // Init power variables
tx_max_power[CC_id] = tx_max_power[0]; tx_max_power[CC_id] = tx_max_power[0];
...@@ -316,9 +284,18 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){ ...@@ -316,9 +284,18 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){
UE->tx_power_max_dBm = tx_max_power[CC_id]; UE->tx_power_max_dBm = tx_max_power[CC_id];
UE->rf_map.card = card_offset; UE->rf_map.card = card_offset;
UE->rf_map.chain = CC_id + chain_offset; UE->rf_map.chain = CC_id + chain_offset;
UE->max_ldpc_iterations = nrUE_params.max_ldpc_iterations;
LOG_I(PHY,"Set UE mode %d, UE_fo_compensation %d, UE_scan_carrier %d, UE_no_timing_correction %d \n, chest-freq %d\n", UE->UE_scan_carrier = nrUE_params.UE_scan_carrier;
UE->mode, UE->UE_fo_compensation, UE->UE_scan_carrier, UE->no_timing_correction, UE->chest_freq); UE->UE_fo_compensation = nrUE_params.UE_fo_compensation;
UE->if_freq = nrUE_params.if_freq;
UE->if_freq_off = nrUE_params.if_freq_off;
UE->chest_freq = nrUE_params.chest_freq;
UE->chest_time = nrUE_params.chest_time;
UE->no_timing_correction = nrUE_params.no_timing_correction;
UE->timing_advance = nrUE_params.timing_advance;
LOG_I(PHY,"Set UE_fo_compensation %d, UE_scan_carrier %d, UE_no_timing_correction %d \n, chest-freq %d, chest-time %d\n",
UE->UE_fo_compensation, UE->UE_scan_carrier, UE->no_timing_correction, UE->chest_freq, UE->chest_time);
// Set FP variables // Set FP variables
...@@ -327,10 +304,14 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){ ...@@ -327,10 +304,14 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){
LOG_I(PHY, "Set UE frame_type %d\n", fp->frame_type); LOG_I(PHY, "Set UE frame_type %d\n", fp->frame_type);
} }
LOG_I(PHY, "Set UE nb_rx_antenna %d, nb_tx_antenna %d, threequarter_fs %d, ssb_start_subcarrier %d\n", fp->nb_antennas_rx, fp->nb_antennas_tx, fp->threequarter_fs, fp->ssb_start_subcarrier); fp->nb_antennas_rx = nrUE_params.nb_antennas_rx;
fp->nb_antennas_tx = nrUE_params.nb_antennas_tx;
fp->threequarter_fs = nrUE_params.threequarter_fs;
fp->N_RB_DL = nrUE_params.N_RB_DL;
fp->ssb_start_subcarrier = nrUE_params.ssb_start_subcarrier;
fp->ofdm_offset_divisor = nrUE_params.ofdm_offset_divisor;
fp->ofdm_offset_divisor = nrUE_params.ofdm_offset_divisor; LOG_I(PHY, "Set UE nb_rx_antenna %d, nb_tx_antenna %d, threequarter_fs %d, ssb_start_subcarrier %d\n", fp->nb_antennas_rx, fp->nb_antennas_tx, fp->threequarter_fs, fp->ssb_start_subcarrier);
UE->max_ldpc_iterations = nrUE_params.max_ldpc_iterations;
} }
......
...@@ -36,54 +36,51 @@ ...@@ -36,54 +36,51 @@
{"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, .iptr=&single_thread_flag, .defintval=1, TYPE_INT, 0}, \ {"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, .iptr=&single_thread_flag, .defintval=1, TYPE_INT, 0}, \
{"dlsch-parallel", CONFIG_HLP_DLSCH_PARA, 0, .u8ptr=NULL, .defintval=0, TYPE_UINT8, 0}, \ {"dlsch-parallel", CONFIG_HLP_DLSCH_PARA, 0, .u8ptr=NULL, .defintval=0, TYPE_UINT8, 0}, \
{"offset-divisor", CONFIG_HLP_OFFSET_DIV, 0, .uptr=&nrUE_params.ofdm_offset_divisor, .defuintval=8, TYPE_UINT32, 0}, \ {"offset-divisor", CONFIG_HLP_OFFSET_DIV, 0, .uptr=&nrUE_params.ofdm_offset_divisor, .defuintval=8, TYPE_UINT32, 0}, \
{"max-ldpc-iterations", CONFIG_HLP_MAX_LDPC_ITERATIONS, 0, .u8ptr=&nrUE_params.max_ldpc_iterations, .defuintval=5, TYPE_UINT8, 0}, \ {"max-ldpc-iterations", CONFIG_HLP_MAX_LDPC_ITERATIONS, 0, .iptr=&nrUE_params.max_ldpc_iterations, .defuintval=5, TYPE_UINT8, 0}, \
{"nr-dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, .iptr=(int32_t *)&nr_dlsch_demod_shift, .defintval=0, TYPE_INT, 0}, \ {"nr-dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, .iptr=(int32_t *)&nr_dlsch_demod_shift, .defintval=0, TYPE_INT, 0}, \
{"V" , CONFIG_HLP_VCD, PARAMFLAG_BOOL, .iptr=&vcdflag, .defintval=0, TYPE_INT, 0}, \ {"V" , CONFIG_HLP_VCD, PARAMFLAG_BOOL, .iptr=&vcdflag, .defintval=0, TYPE_INT, 0}, \
{"uecap_file", CONFIG_HLP_UECAP_FILE, 0, .strptr=&uecap_file, .defstrval="./uecap_ports1.xml", TYPE_STRING, 0}, \ {"uecap_file", CONFIG_HLP_UECAP_FILE, 0, .strptr=&uecap_file, .defstrval="./uecap_ports1.xml", TYPE_STRING, 0}, \
{"rrc_config_path", CONFIG_HLP_RRC_CFG_PATH, 0, .strptr=&rrc_config_path, .defstrval="./", TYPE_STRING, 0}, \ {"rrc_config_path", CONFIG_HLP_RRC_CFG_PATH, 0, .strptr=&rrc_config_path, .defstrval="./", TYPE_STRING, 0}, \
{"ue-idx-standalone", NULL, 0, .u16ptr=&ue_idx_standalone, .defuintval=0xFFFF, TYPE_UINT16, 0} \ {"ue-idx-standalone", NULL, 0, .u16ptr=&ue_idx_standalone, .defuintval=0xFFFF, TYPE_UINT16, 0}, \
}
// clang-format on
/*------------------------------------------------------------------------------------------------------------------------------------------*/
/* command line parameters defining UE running mode */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*------------------------------------------------------------------------------------------------------------------------------------------*/
// clang-format off
#define CMDLINE_NRUE_PHYPARAMS_DESC { \
{ CALIBRX_OPT, CONFIG_HLP_CALUER, 0, .iptr=&rx_input_level_dBm, .defintval=0, TYPE_INT, 0}, \
{ CALIBRXMED_OPT, CONFIG_HLP_CALUERM, 0, .iptr=&rx_input_level_dBm, .defintval=0, TYPE_INT, 0}, \
{ CALIBRXBYP_OPT, CONFIG_HLP_CALUERB, 0, .iptr=&rx_input_level_dBm, .defintval=0, TYPE_INT, 0}, \
{ DBGPRACH_OPT, CONFIG_HLP_DBGUEPR, PARAMFLAG_BOOL, .uptr=NULL, .defuintval=1, TYPE_INT, 0}, \
{ NOL2CONNECT_OPT, CONFIG_HLP_NOL2CN, PARAMFLAG_BOOL, .uptr=NULL, .defuintval=1, TYPE_INT, 0}, \
{ CALIBPRACH_OPT, CONFIG_HLP_CALPRACH, PARAMFLAG_BOOL, .uptr=NULL, .defuintval=1, TYPE_INT, 0}, \
{ DUMPFRAME_OPT, CONFIG_HLP_DUMPFRAME, PARAMFLAG_BOOL, .iptr=&dumpframe, .defintval=0, TYPE_INT, 0}, \
{"ue-rxgain", CONFIG_HLP_UERXG, 0, .dblptr=&(rx_gain[0][0]), .defdblval=110, TYPE_DOUBLE, 0}, \ {"ue-rxgain", CONFIG_HLP_UERXG, 0, .dblptr=&(rx_gain[0][0]), .defdblval=110, TYPE_DOUBLE, 0}, \
{"ue-rxgain-off", CONFIG_HLP_UERXGOFF, 0, .dblptr=&rx_gain_off, .defdblval=0, TYPE_DOUBLE, 0}, \ {"ue-rxgain-off", CONFIG_HLP_UERXGOFF, 0, .dblptr=&rx_gain_off, .defdblval=0, TYPE_DOUBLE, 0}, \
{"ue-txgain", CONFIG_HLP_UETXG, 0, .dblptr=&(tx_gain[0][0]), .defdblval=0, TYPE_DOUBLE, 0}, \ {"ue-txgain", CONFIG_HLP_UETXG, 0, .dblptr=&(tx_gain[0][0]), .defdblval=0, TYPE_DOUBLE, 0}, \
{"ue-nb-ant-rx", CONFIG_HLP_UENANTR, 0, .u8ptr=&(fp->nb_antennas_rx), .defuintval=1, TYPE_UINT8, 0}, \ {"ue-nb-ant-rx", CONFIG_HLP_UENANTR, 0, .iptr=&(nrUE_params.nb_antennas_rx), .defuintval=1, TYPE_UINT8, 0}, \
{"ue-nb-ant-tx", CONFIG_HLP_UENANTT, 0, .u8ptr=&(fp->nb_antennas_tx), .defuintval=1, TYPE_UINT8, 0}, \ {"ue-nb-ant-tx", CONFIG_HLP_UENANTT, 0, .iptr=&(nrUE_params.nb_antennas_tx), .defuintval=1, TYPE_UINT8, 0}, \
{"ue-scan-carrier", CONFIG_HLP_UESCAN, PARAMFLAG_BOOL, .iptr=&(UE->UE_scan_carrier), .defintval=0, TYPE_INT, 0}, \ {"ue-scan-carrier", CONFIG_HLP_UESCAN, PARAMFLAG_BOOL, .iptr=&(nrUE_params.UE_scan_carrier), .defintval=0, TYPE_INT, 0}, \
{"ue-fo-compensation", CONFIG_HLP_UEFO, PARAMFLAG_BOOL, .iptr=&(UE->UE_fo_compensation), .defintval=0, TYPE_INT, 0}, \ {"ue-fo-compensation", CONFIG_HLP_UEFO, PARAMFLAG_BOOL, .iptr=&(nrUE_params.UE_fo_compensation), .defintval=0, TYPE_INT, 0}, \
{"ue-max-power", NULL, 0, .iptr=&(tx_max_power[0]), .defintval=90, TYPE_INT, 0}, \ {"ue-max-power", NULL, 0, .iptr=&(tx_max_power[0]), .defintval=90, TYPE_INT, 0}, \
{"A" , CONFIG_HLP_TADV, 0, .iptr=&(UE->timing_advance), .defintval=0, TYPE_INT, 0}, \ {"A" , CONFIG_HLP_TADV, 0, .iptr=&(nrUE_params.timing_advance), .defintval=0, TYPE_INT, 0}, \
{"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, .u8ptr=&(fp->threequarter_fs), .defintval=0, TYPE_UINT8, 0}, \ {"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, .iptr=&(nrUE_params.threequarter_fs), .defintval=0, TYPE_UINT8, 0}, \
{"r" , CONFIG_HLP_PRB_SA, 0, .iptr=&(fp->N_RB_DL), .defintval=106, TYPE_UINT, 0}, \ {"r" , CONFIG_HLP_PRB_SA, 0, .iptr=&(nrUE_params.N_RB_DL), .defintval=106, TYPE_UINT, 0}, \
{"ssb", CONFIG_HLP_SSC, 0, .u16ptr=&(fp->ssb_start_subcarrier), .defintval=516, TYPE_UINT16, 0}, \ {"ssb", CONFIG_HLP_SSC, 0, .iptr=&(nrUE_params.ssb_start_subcarrier), .defintval=516, TYPE_UINT16, 0}, \
{"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, .iptr=&tddflag, .defintval=0, TYPE_INT, 0}, \ {"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, .iptr=&tddflag, .defintval=0, TYPE_INT, 0}, \
{"if_freq" , CONFIG_HLP_IF_FREQ, 0, .u64ptr=&(UE->if_freq), .defuintval=0, TYPE_UINT64, 0}, \ {"if_freq" , CONFIG_HLP_IF_FREQ, 0, .u64ptr=&(nrUE_params.if_freq), .defuintval=0, TYPE_UINT64, 0}, \
{"if_freq_off" , CONFIG_HLP_IF_FREQ_OFF, 0, .iptr=&(UE->if_freq_off), .defuintval=0, TYPE_INT, 0}, \ {"if_freq_off" , CONFIG_HLP_IF_FREQ_OFF, 0, .iptr=&(nrUE_params.if_freq_off), .defuintval=0, TYPE_INT, 0}, \
{"chest-freq", CONFIG_HLP_CHESTFREQ, 0, .iptr=&(UE->chest_freq), .defintval=0, TYPE_INT, 0}, \ {"chest-freq", CONFIG_HLP_CHESTFREQ, 0, .iptr=&(nrUE_params.chest_freq), .defintval=0, TYPE_INT, 0}, \
{"chest-time", CONFIG_HLP_CHESTTIME, 0, .iptr=&(UE->chest_time), .defintval=0, TYPE_INT, 0}, \ {"chest-time", CONFIG_HLP_CHESTTIME, 0, .iptr=&(nrUE_params.chest_time), .defintval=0, TYPE_INT, 0}, \
{"ue-timing-correction-disable", CONFIG_HLP_DISABLETIMECORR, PARAMFLAG_BOOL, .iptr=&(UE->no_timing_correction), .defintval=0, TYPE_INT, 0}, \ {"ue-timing-correction-disable", CONFIG_HLP_DISABLETIMECORR, PARAMFLAG_BOOL, .iptr=&(nrUE_params.no_timing_correction), .defintval=0, TYPE_INT, 0}, \
} }
// clang-format on // clang-format on
typedef struct { typedef struct {
uint64_t optmask; //mask to store boolean config options uint64_t optmask; //mask to store boolean config options
uint32_t ofdm_offset_divisor; // Divisor for sample offset computation for each OFDM symbol uint32_t ofdm_offset_divisor; // Divisor for sample offset computation for each OFDM symbol
uint8_t max_ldpc_iterations; // number of maximum LDPC iterations int max_ldpc_iterations; // number of maximum LDPC iterations
tpool_t Tpool; // thread pool tpool_t Tpool; // thread pool
int UE_scan_carrier;
int UE_fo_compensation;
int timing_advance;
uint64_t if_freq;
int if_freq_off;
int chest_freq;
int chest_time;
int no_timing_correction;
int nb_antennas_rx;
int nb_antennas_tx;
int threequarter_fs;
int N_RB_DL;
int ssb_start_subcarrier;
} nrUE_params_t; } nrUE_params_t;
extern uint64_t get_nrUE_optmask(void); extern uint64_t get_nrUE_optmask(void);
extern uint64_t set_nrUE_optmask(uint64_t bitmask); extern uint64_t set_nrUE_optmask(uint64_t bitmask);
......
...@@ -38,11 +38,12 @@ extern "C" ...@@ -38,11 +38,12 @@ extern "C"
#endif #endif
/* help strings definition for command line options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */ /* help strings definition for command line options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */
#define CONFIG_HLP_RFCFGF "Configuration file for front-end (e.g. LMS7002M)\n" #define CONFIG_HLP_RFCFGF "Configuration file for front-end (e.g. LMS7002M)\n"
#define CONFIG_HLP_SPLIT73 "Split 7.3 (below rate matching) option: <cu|du>:<remote ip address>:<remote port>" #define CONFIG_HLP_SPLIT73 "Split 7.3 (below rate matching) option: <cu|du>:<remote ip address>:<remote port>\n"
#define CONFIG_HLP_TPOOL "Thread pool configuration: \n\ #define CONFIG_HLP_TPOOL "Thread pool configuration: \n\
default no pool (runs in calling thread),\n\
list of cores, comma separated (negative value is no core affinity)\n\ list of cores, comma separated (negative value is no core affinity)\n\
example: -1,3 launches two working threads one floating, the second set on core 3" example: -1,3 launches two working threads one floating, the second set on core 3\n\
default 8 floating threads\n\
use N for no pool (runs in calling thread) recommended with rfsim.\n"
#define CONFIG_HLP_ULMAXE "set the eNodeB max ULSCH erros\n" #define CONFIG_HLP_ULMAXE "set the eNodeB max ULSCH erros\n"
#define CONFIG_HLP_CALUER "set UE RX calibration\n" #define CONFIG_HLP_CALUER "set UE RX calibration\n"
#define CONFIG_HLP_CALUERM "" #define CONFIG_HLP_CALUERM ""
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "stddef.h" #include "stddef.h"
#include "platform_types.h" #include "platform_types.h"
#include "fapi_nr_ue_constants.h" #include "fapi_nr_ue_constants.h"
#include "PHY/impl_defs_top.h"
#include "PHY/impl_defs_nr.h" #include "PHY/impl_defs_nr.h"
#include "common/utils/nr/nr_common.h" #include "common/utils/nr/nr_common.h"
...@@ -116,7 +117,8 @@ typedef struct { ...@@ -116,7 +117,8 @@ typedef struct {
} fapi_nr_pdsch_pdu_t; } fapi_nr_pdsch_pdu_t;
typedef struct { typedef struct {
uint8_t* pdu; // 3bytes bool decoded_pdu;
uint8_t pdu[3];
uint8_t additional_bits; uint8_t additional_bits;
uint8_t ssb_index; uint8_t ssb_index;
uint8_t ssb_length; uint8_t ssb_length;
...@@ -390,8 +392,6 @@ typedef struct { ...@@ -390,8 +392,6 @@ typedef struct {
} fapi_nr_ul_config_request_pdu_t; } fapi_nr_ul_config_request_pdu_t;
typedef struct { typedef struct {
//uint16_t sfn;
//uint16_t slot;
uint16_t sfn; uint16_t sfn;
uint16_t slot; uint16_t slot;
uint8_t number_pdus; uint8_t number_pdus;
...@@ -423,9 +423,6 @@ typedef struct { ...@@ -423,9 +423,6 @@ typedef struct {
typedef struct { typedef struct {
fapi_nr_dl_config_dci_dl_pdu_rel15_t dci_config_rel15; fapi_nr_dl_config_dci_dl_pdu_rel15_t dci_config_rel15;
} fapi_nr_dl_config_dci_pdu; } fapi_nr_dl_config_dci_pdu;
typedef struct{
uint8_t aperiodicSRS_ResourceTrigger;
} fapi_nr_dl_srs_config_t;
typedef enum{vrb_to_prb_mapping_non_interleaved = 0, vrb_to_prb_mapping_interleaved = 1} vrb_to_prb_mapping_t; typedef enum{vrb_to_prb_mapping_non_interleaved = 0, vrb_to_prb_mapping_interleaved = 1} vrb_to_prb_mapping_t;
...@@ -462,7 +459,6 @@ typedef struct { ...@@ -462,7 +459,6 @@ typedef struct {
uint16_t dmrs_ports; uint16_t dmrs_ports;
uint8_t n_front_load_symb; uint8_t n_front_load_symb;
uint8_t tci_state; uint8_t tci_state;
fapi_nr_dl_srs_config_t srs_config;
uint8_t cbgti; uint8_t cbgti;
uint8_t codeBlockGroupFlushIndicator; uint8_t codeBlockGroupFlushIndicator;
// to be check the fields needed to L1 with NR_DL_UE_HARQ_t and NR_UE_DLSCH_t // to be check the fields needed to L1 with NR_DL_UE_HARQ_t and NR_UE_DLSCH_t
...@@ -483,6 +479,7 @@ typedef struct { ...@@ -483,6 +479,7 @@ typedef struct {
uint8_t nscid; uint8_t nscid;
uint16_t dlDmrsScramblingId; uint16_t dlDmrsScramblingId;
uint16_t pduBitmap; uint16_t pduBitmap;
uint32_t k1_feedback;
} fapi_nr_dl_config_dlsch_pdu_rel15_t; } fapi_nr_dl_config_dlsch_pdu_rel15_t;
typedef struct { typedef struct {
......
...@@ -202,7 +202,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) ...@@ -202,7 +202,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
// create shortcuts // create shortcuts
NR_DL_FRAME_PARMS *const fp = &ue->frame_parms; NR_DL_FRAME_PARMS *const fp = &ue->frame_parms;
NR_UE_COMMON *const common_vars = &ue->common_vars; NR_UE_COMMON *const common_vars = &ue->common_vars;
NR_UE_PBCH **const pbch_vars = ue->pbch_vars;
NR_UE_PRACH **const prach_vars = ue->prach_vars; NR_UE_PRACH **const prach_vars = ue->prach_vars;
NR_UE_CSI_IM **const csiim_vars = ue->csiim_vars; NR_UE_CSI_IM **const csiim_vars = ue->csiim_vars;
NR_UE_CSI_RS **const csirs_vars = ue->csirs_vars; NR_UE_CSI_RS **const csirs_vars = ue->csirs_vars;
...@@ -357,7 +356,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) ...@@ -357,7 +356,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
// DLSCH // DLSCH
for (gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) { for (gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) {
prach_vars[gNB_id] = (NR_UE_PRACH *)malloc16_clear(sizeof(NR_UE_PRACH)); prach_vars[gNB_id] = (NR_UE_PRACH *)malloc16_clear(sizeof(NR_UE_PRACH));
pbch_vars[gNB_id] = (NR_UE_PBCH *)malloc16_clear(sizeof(NR_UE_PBCH));
csiim_vars[gNB_id] = (NR_UE_CSI_IM *)malloc16_clear(sizeof(NR_UE_CSI_IM)); csiim_vars[gNB_id] = (NR_UE_CSI_IM *)malloc16_clear(sizeof(NR_UE_CSI_IM));
csirs_vars[gNB_id] = (NR_UE_CSI_RS *)malloc16_clear(sizeof(NR_UE_CSI_RS)); csirs_vars[gNB_id] = (NR_UE_CSI_RS *)malloc16_clear(sizeof(NR_UE_CSI_RS));
srs_vars[gNB_id] = (NR_UE_SRS *)malloc16_clear(sizeof(NR_UE_SRS)); srs_vars[gNB_id] = (NR_UE_SRS *)malloc16_clear(sizeof(NR_UE_SRS));
...@@ -476,7 +474,6 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) ...@@ -476,7 +474,6 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
free_and_zero(ue->csirs_vars[gNB_id]); free_and_zero(ue->csirs_vars[gNB_id]);
free_and_zero(ue->srs_vars[gNB_id]); free_and_zero(ue->srs_vars[gNB_id]);
free_and_zero(ue->pbch_vars[gNB_id]);
free_and_zero(ue->prach_vars[gNB_id]); free_and_zero(ue->prach_vars[gNB_id]);
} }
...@@ -523,7 +520,6 @@ void free_nr_ue_dl_harq(NR_DL_UE_HARQ_t harq_list[2][NR_MAX_DLSCH_HARQ_PROCESSES ...@@ -523,7 +520,6 @@ void free_nr_ue_dl_harq(NR_DL_UE_HARQ_t harq_list[2][NR_MAX_DLSCH_HARQ_PROCESSES
for (int j=0; j < 2; j++) { for (int j=0; j < 2; j++) {
for (int i=0; i<number_of_processes; i++) { for (int i=0; i<number_of_processes; i++) {
free_and_zero(harq_list[j][i].b);
for (int r=0; r<a_segments; r++) { for (int r=0; r<a_segments; r++) {
free_and_zero(harq_list[j][i].c[r]); free_and_zero(harq_list[j][i].c[r]);
...@@ -575,18 +571,10 @@ void nr_init_dl_harq_processes(NR_DL_UE_HARQ_t harq_list[2][NR_MAX_DLSCH_HARQ_PR ...@@ -575,18 +571,10 @@ void nr_init_dl_harq_processes(NR_DL_UE_HARQ_t harq_list[2][NR_MAX_DLSCH_HARQ_PR
a_segments = (a_segments/273)+1; a_segments = (a_segments/273)+1;
} }
uint32_t dlsch_bytes = a_segments*1056; // allocated bytes per segment
for (int j=0; j<2; j++) { for (int j=0; j<2; j++) {
for (int i=0; i<number_of_processes; i++) { for (int i=0; i<number_of_processes; i++) {
memset(harq_list[j] + i, 0, sizeof(NR_DL_UE_HARQ_t)); memset(harq_list[j] + i, 0, sizeof(NR_DL_UE_HARQ_t));
init_downlink_harq_status(harq_list[j] + i); init_downlink_harq_status(harq_list[j] + i);
harq_list[j][i].b = malloc16(dlsch_bytes);
if (harq_list[j][i].b)
memset(harq_list[j][i].b, 0, dlsch_bytes);
else
AssertFatal(true, "Unable to reset harq memory \"b\"\n");
harq_list[j][i].c = malloc16(a_segments*sizeof(uint8_t *)); harq_list[j][i].c = malloc16(a_segments*sizeof(uint8_t *));
harq_list[j][i].d = malloc16(a_segments*sizeof(int16_t *)); harq_list[j][i].d = malloc16(a_segments*sizeof(int16_t *));
......
...@@ -977,13 +977,11 @@ int nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, c16_t r ...@@ -977,13 +977,11 @@ int nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, c16_t r
csirs_measurements.i2 = *i2; csirs_measurements.i2 = *i2;
csirs_measurements.cqi = cqi; csirs_measurements.cqi = cqi;
nr_downlink_indication_t dl_indication; nr_downlink_indication_t dl_indication;
fapi_nr_rx_indication_t *rx_ind = calloc(sizeof(*rx_ind),1); fapi_nr_rx_indication_t rx_ind = {0};
nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, NULL); nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, NULL);
nr_fill_rx_indication(rx_ind, FAPI_NR_CSIRS_IND, ue, NULL, NULL, 1, proc, (void *)&csirs_measurements); nr_fill_rx_indication(&rx_ind, FAPI_NR_CSIRS_IND, ue, NULL, NULL, 1, proc, (void *)&csirs_measurements, NULL);
if (ue->if_inst && ue->if_inst->dl_indication) { if (ue->if_inst && ue->if_inst->dl_indication) {
ue->if_inst->dl_indication(&dl_indication, NULL); ue->if_inst->dl_indication(&dl_indication, NULL);
} else {
free(rx_ind);
} }
return 0; return 0;
......
...@@ -51,15 +51,8 @@ ...@@ -51,15 +51,8 @@
#define OAI_UL_LDPC_MAX_NUM_LLR 27000//26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX = 68*384 #define OAI_UL_LDPC_MAX_NUM_LLR 27000//26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX = 68*384
//#define OAI_LDPC_MAX_NUM_LLR 27000//26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX //#define OAI_LDPC_MAX_NUM_LLR 27000//26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX
static uint64_t nb_total_decod =0;
static uint64_t nb_error_decod =0;
static extended_kpi_ue kpiStructure = {0}; static extended_kpi_ue kpiStructure = {0};
notifiedFIFO_t freeBlocks_dl;
notifiedFIFO_elt_t *msgToPush_dl;
int nbDlProcessing =0;
extended_kpi_ue* getKPIUE(void) { extended_kpi_ue* getKPIUE(void) {
return &kpiStructure; return &kpiStructure;
} }
...@@ -77,7 +70,7 @@ void nr_dlsch_unscrambling(int16_t *llr, uint32_t size, uint8_t q, uint32_t Nid, ...@@ -77,7 +70,7 @@ void nr_dlsch_unscrambling(int16_t *llr, uint32_t size, uint8_t q, uint32_t Nid,
nr_codeword_unscrambling(llr, size, q, Nid, n_RNTI); nr_codeword_unscrambling(llr, size, q, Nid, n_RNTI);
} }
bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, notifiedFIFO_elt_t *req, bool last, notifiedFIFO_t *nf_p) { bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, notifiedFIFO_elt_t *req, bool last, notifiedFIFO_t *nf_p, int b_size, uint8_t b[b_size], int *num_seg_ok, UE_nr_rxtx_proc_t *proc) {
ldpcDecode_ue_t *rdata = (ldpcDecode_ue_t*) NotifiedFifoData(req); ldpcDecode_ue_t *rdata = (ldpcDecode_ue_t*) NotifiedFifoData(req);
NR_DL_UE_HARQ_t *harq_process = rdata->harq_process; NR_DL_UE_HARQ_t *harq_process = rdata->harq_process;
NR_UE_DLSCH_t *dlsch = (NR_UE_DLSCH_t *) rdata->dlsch; NR_UE_DLSCH_t *dlsch = (NR_UE_DLSCH_t *) rdata->dlsch;
...@@ -90,10 +83,11 @@ bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, notifiedFIFO_elt_t *req, bool ...@@ -90,10 +83,11 @@ bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, notifiedFIFO_elt_t *req, bool
bool decodeSuccess = (rdata->decodeIterations < (1+dlsch->max_ldpc_iterations)); bool decodeSuccess = (rdata->decodeIterations < (1+dlsch->max_ldpc_iterations));
if (decodeSuccess) { if (decodeSuccess) {
memcpy(harq_process->b+rdata->offset, memcpy(b+rdata->offset,
harq_process->c[r], harq_process->c[r],
rdata->Kr_bytes - (harq_process->F>>3) -((harq_process->C>1)?3:0)); rdata->Kr_bytes - (harq_process->F>>3) -((harq_process->C>1)?3:0));
(*num_seg_ok)++;
} else { } else {
if ( !last ) { if ( !last ) {
int nb=abortTpoolJob(&get_nrUE_params()->Tpool, req->key); int nb=abortTpoolJob(&get_nrUE_params()->Tpool, req->key);
...@@ -111,7 +105,20 @@ bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, notifiedFIFO_elt_t *req, bool ...@@ -111,7 +105,20 @@ bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, notifiedFIFO_elt_t *req, bool
kpiStructure.dl_mcs = dlsch->dlsch_config.mcs; kpiStructure.dl_mcs = dlsch->dlsch_config.mcs;
kpiStructure.nofRBs = dlsch->dlsch_config.number_rbs; kpiStructure.nofRBs = dlsch->dlsch_config.number_rbs;
if (decodeSuccess) { if (*num_seg_ok == harq_process->C) {
if (harq_process->C > 1) {
/* check global CRC */
int A = dlsch->dlsch_config.TBS;
int crc_length = A > 3824 ? 3 : 2;
int crc_type = A > 3824 ? CRC24_A : CRC16;
if (!check_crc(b, A + crc_length*8, 0 /* F - unused */, crc_type)) {
harq_process->ack = 0;
dlsch->last_iteration_cnt = dlsch->max_ldpc_iterations + 1;
LOG_E(PHY, " Frame %d.%d LDPC global CRC fails, but individual LDPC CRC succeeded. %d segs\n", proc->frame_rx, proc->nr_slot_rx, harq_process->C);
LOG_D(PHY, "DLSCH received nok \n");
return true; //stop
}
}
//LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_slot_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d\n", //LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_slot_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d\n",
// phy_vars_ue->Mod_id,nr_slot_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round); // phy_vars_ue->Mod_id,nr_slot_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round);
harq_process->status = SCH_IDLE; harq_process->status = SCH_IDLE;
...@@ -277,7 +284,7 @@ void nr_processDLSegment(void* arg) { ...@@ -277,7 +284,7 @@ void nr_processDLSegment(void* arg) {
if (no_iteration_ldpc > dlsch->max_ldpc_iterations) if (no_iteration_ldpc > dlsch->max_ldpc_iterations)
no_iteration_ldpc = dlsch->max_ldpc_iterations; no_iteration_ldpc = dlsch->max_ldpc_iterations;
} else { } else {
LOG_D(PHY,"CRC NOT OK\n"); LOG_I(PHY,"%d.%d CRC NOT OK\n",rdata->proc->frame_rx,rdata->proc->nr_slot_rx);
no_iteration_ldpc = dlsch->max_ldpc_iterations + 1; no_iteration_ldpc = dlsch->max_ldpc_iterations + 1;
} }
...@@ -287,12 +294,6 @@ void nr_processDLSegment(void* arg) { ...@@ -287,12 +294,6 @@ void nr_processDLSegment(void* arg) {
rdata->decodeIterations = no_iteration_ldpc; rdata->decodeIterations = no_iteration_ldpc;
nb_total_decod++;
if (no_iteration_ldpc > dlsch->max_ldpc_iterations) {
nb_error_decod++;
}
for (int m=0; m < Kr>>3; m ++) { for (int m=0; m < Kr>>3; m ++) {
harq_process->c[r][m]= (uint8_t) llrProcBuf[m]; harq_process->c[r][m]= (uint8_t) llrProcBuf[m];
} }
...@@ -311,7 +312,9 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, ...@@ -311,7 +312,9 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
uint32_t frame, uint32_t frame,
uint16_t nb_symb_sch, uint16_t nb_symb_sch,
uint8_t nr_slot_rx, uint8_t nr_slot_rx,
uint8_t harq_pid) { uint8_t harq_pid,
int b_size,
uint8_t b[b_size]) {
uint32_t A,E; uint32_t A,E;
uint32_t G; uint32_t G;
uint32_t ret,offset; uint32_t ret,offset;
...@@ -476,6 +479,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, ...@@ -476,6 +479,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
rdata->offset = offset; rdata->offset = offset;
rdata->dlsch = dlsch; rdata->dlsch = dlsch;
rdata->dlsch_id = 0; rdata->dlsch_id = 0;
rdata->proc = proc;
reset_meas(&rdata->ts_deinterleave); reset_meas(&rdata->ts_deinterleave);
reset_meas(&rdata->ts_rate_unmatch); reset_meas(&rdata->ts_rate_unmatch);
reset_meas(&rdata->ts_ldpc_decode); reset_meas(&rdata->ts_ldpc_decode);
...@@ -486,6 +490,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, ...@@ -486,6 +490,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0)); offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0));
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
} }
int num_seg_ok = 0;
for (r=0; r<nbDecode; r++) { for (r=0; r<nbDecode; r++) {
notifiedFIFO_elt_t *req=pullTpool(&nf, &get_nrUE_params()->Tpool); notifiedFIFO_elt_t *req=pullTpool(&nf, &get_nrUE_params()->Tpool);
if (req == NULL) if (req == NULL)
...@@ -493,7 +498,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, ...@@ -493,7 +498,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
bool last = false; bool last = false;
if (r == nbDecode - 1) if (r == nbDecode - 1)
last = true; last = true;
bool stop = nr_ue_postDecode(phy_vars_ue, req, last, &nf); bool stop = nr_ue_postDecode(phy_vars_ue, req, last, &nf, b_size, b, &num_seg_ok, proc);
delNotifiedFIFO_elt(req); delNotifiedFIFO_elt(req);
if (stop) if (stop)
break; break;
......
...@@ -155,12 +155,11 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini ...@@ -155,12 +155,11 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini
proc,i,i-pbch_initial_symbol,temp_ptr->i_ssb,temp_ptr->n_hf,rxdataF); proc,i,i-pbch_initial_symbol,temp_ptr->i_ssb,temp_ptr->n_hf,rxdataF);
stop_meas(&ue->dlsch_channel_estimation_stats); stop_meas(&ue->dlsch_channel_estimation_stats);
fapiPbch_t result; fapiPbch_t result = {0};
ret = nr_rx_pbch(ue, ret = nr_rx_pbch(ue,
proc, proc,
estimateSz, estimateSz,
dl_ch_estimates, dl_ch_estimates,
ue->pbch_vars[0],
frame_parms, frame_parms,
temp_ptr->i_ssb, temp_ptr->i_ssb,
SISO, SISO,
...@@ -188,11 +187,6 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini ...@@ -188,11 +187,6 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini
// openair_daq_vars.dlsch_transmission_mode = (pbch_tx_ant>1) ? 2 : 1; // openair_daq_vars.dlsch_transmission_mode = (pbch_tx_ant>1) ? 2 : 1;
// flip byte endian on 24-bits for MIB
// dummy = ue->pbch_vars[0]->decoded_output[0];
// ue->pbch_vars[0]->decoded_output[0] = ue->pbch_vars[0]->decoded_output[2];
// ue->pbch_vars[0]->decoded_output[2] = dummy;
#ifdef DEBUG_INITIAL_SYNCH #ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY,"[UE%d] Initial sync: pbch decoded sucessfully\n",ue->Mod_id); LOG_I(PHY,"[UE%d] Initial sync: pbch decoded sucessfully\n",ue->Mod_id);
#endif #endif
...@@ -447,8 +441,6 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, ...@@ -447,8 +441,6 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
// send sync status to higher layers later when timing offset converge to target timing // send sync status to higher layers later when timing offset converge to target timing
ue->pbch_vars[0]->pdu_errors_conseq=0;
} }
...@@ -466,10 +458,6 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, ...@@ -466,10 +458,6 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
frame_parms->Nid_cell,frame_parms->frame_type); frame_parms->Nid_cell,frame_parms->frame_type);
#endif #endif
ue->pbch_vars[0]->pdu_errors_last=ue->pbch_vars[0]->pdu_errors;
ue->pbch_vars[0]->pdu_errors++;
ue->pbch_vars[0]->pdu_errors_conseq++;
} }
// gain control // gain control
......
...@@ -302,8 +302,7 @@ void nr_pbch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms, ...@@ -302,8 +302,7 @@ void nr_pbch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms,
#endif #endif
} }
static void nr_pbch_unscrambling(NR_UE_PBCH *pbch, static void nr_pbch_unscrambling(int16_t *demod_pbch_e,
int16_t *demod_pbch_e,
uint16_t Nid, uint16_t Nid,
uint8_t nushift, uint8_t nushift,
uint16_t M, uint16_t M,
...@@ -311,7 +310,8 @@ static void nr_pbch_unscrambling(NR_UE_PBCH *pbch, ...@@ -311,7 +310,8 @@ static void nr_pbch_unscrambling(NR_UE_PBCH *pbch,
uint8_t bitwise, uint8_t bitwise,
uint32_t unscrambling_mask, uint32_t unscrambling_mask,
uint32_t pbch_a_prime, uint32_t pbch_a_prime,
uint32_t *pbch_a_interleaved) { uint32_t *pbch_a_interleaved)
{
uint8_t reset, offset; uint8_t reset, offset;
uint32_t x1 = 0, x2 = 0, s = 0; uint32_t x1 = 0, x2 = 0, s = 0;
uint8_t k=0; uint8_t k=0;
...@@ -384,17 +384,17 @@ unsigned char sign(int8_t x) { ...@@ -384,17 +384,17 @@ unsigned char sign(int8_t x) {
uint8_t pbch_deinterleaving_pattern[32] = {28,0,31,30,7,29,25,27,5,8,24,9,10,11,12,13,1,4,3,14,15,16,17,2,26,18,19,20,21,22,6,23}; uint8_t pbch_deinterleaving_pattern[32] = {28,0,31,30,7,29,25,27,5,8,24,9,10,11,12,13,1,4,3,14,15,16,17,2,26,18,19,20,21,22,6,23};
int nr_rx_pbch( PHY_VARS_NR_UE *ue, int nr_rx_pbch(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc, UE_nr_rxtx_proc_t *proc,
int estimateSz, struct complex16 dl_ch_estimates [][estimateSz], int estimateSz,
NR_UE_PBCH *nr_ue_pbch_vars, struct complex16 dl_ch_estimates [][estimateSz],
NR_DL_FRAME_PARMS *frame_parms, NR_DL_FRAME_PARMS *frame_parms,
uint8_t i_ssb, uint8_t i_ssb,
MIMO_mode_t mimo_mode, MIMO_mode_t mimo_mode,
nr_phy_data_t *phy_data, nr_phy_data_t *phy_data,
fapiPbch_t *result, fapiPbch_t *result,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
{
int max_h=0; int max_h=0;
int symbol; int symbol;
//uint8_t pbch_a[64]; //uint8_t pbch_a[64];
...@@ -456,7 +456,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, ...@@ -456,7 +456,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
} }
#ifdef DEBUG_PBCH #ifdef DEBUG_PBCH
LOG_I(PHY,"[PHY] PBCH log2_maxh = %d (%d)\n",nr_ue_pbch_vars->log2_maxh,max_h); LOG_I(PHY,"[PHY] PBCH log2_maxh = %d (%d)\n", log2_maxh, max_h);
#endif #endif
__attribute__ ((aligned(32))) struct complex16 rxdataF_comp[frame_parms->nb_antennas_rx][PBCH_MAX_RE_PER_SYMBOL]; __attribute__ ((aligned(32))) struct complex16 rxdataF_comp[frame_parms->nb_antennas_rx][PBCH_MAX_RE_PER_SYMBOL];
nr_pbch_channel_compensation(rxdataF_ext, nr_pbch_channel_compensation(rxdataF_ext,
...@@ -464,7 +464,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, ...@@ -464,7 +464,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
nb_re, nb_re,
rxdataF_comp, rxdataF_comp,
frame_parms, frame_parms,
log2_maxh); // log2_maxh+I0_shift log2_maxh); // log2_maxh+I0_shift
/*if (frame_parms->nb_antennas_rx > 1) /*if (frame_parms->nb_antennas_rx > 1)
pbch_detection_mrc(frame_parms, pbch_detection_mrc(frame_parms,
...@@ -504,16 +504,25 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, ...@@ -504,16 +504,25 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
uint32_t unscrambling_mask = (Lmax==64)?0x100006D:0x1000041; uint32_t unscrambling_mask = (Lmax==64)?0x100006D:0x1000041;
uint32_t pbch_a_interleaved=0; uint32_t pbch_a_interleaved=0;
uint32_t pbch_a_prime=0; uint32_t pbch_a_prime=0;
nr_pbch_unscrambling(nr_ue_pbch_vars, pbch_e_rx, frame_parms->Nid_cell, nushift, M, NR_POLAR_PBCH_E, nr_pbch_unscrambling(pbch_e_rx, frame_parms->Nid_cell, nushift, M, NR_POLAR_PBCH_E,
0, 0, pbch_a_prime, &pbch_a_interleaved); 0, 0, pbch_a_prime, &pbch_a_interleaved);
//polar decoding de-rate matching //polar decoding de-rate matching
uint64_t tmp=0; uint64_t tmp=0;
decoderState = polar_decoder_int16(pbch_e_rx,(uint64_t *)&tmp,0, decoderState = polar_decoder_int16(pbch_e_rx,(uint64_t *)&tmp,0,
NR_POLAR_PBCH_MESSAGE_TYPE, NR_POLAR_PBCH_PAYLOAD_BITS, NR_POLAR_PBCH_AGGREGATION_LEVEL); NR_POLAR_PBCH_MESSAGE_TYPE, NR_POLAR_PBCH_PAYLOAD_BITS, NR_POLAR_PBCH_AGGREGATION_LEVEL);
pbch_a_prime=tmp; pbch_a_prime = tmp;
if(decoderState)
return(decoderState); nr_downlink_indication_t dl_indication;
fapi_nr_rx_indication_t rx_ind = {0};
uint16_t number_pdus = 1;
if(decoderState) {
nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, phy_data);
nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, ue, NULL, NULL, number_pdus, proc, NULL, NULL);
if (ue->if_inst && ue->if_inst->dl_indication)
ue->if_inst->dl_indication(&dl_indication, NULL);
return(decoderState);
}
// printf("polar decoder output 0x%08x\n",pbch_a_prime); // printf("polar decoder output 0x%08x\n",pbch_a_prime);
// Decoder reversal // Decoder reversal
uint32_t a_reversed=0; uint32_t a_reversed=0;
...@@ -526,7 +535,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, ...@@ -526,7 +535,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
M = (Lmax == 64)? (NR_POLAR_PBCH_PAYLOAD_BITS - 6) : (NR_POLAR_PBCH_PAYLOAD_BITS - 3); M = (Lmax == 64)? (NR_POLAR_PBCH_PAYLOAD_BITS - 6) : (NR_POLAR_PBCH_PAYLOAD_BITS - 3);
nushift = ((pbch_a_prime>>24)&1) ^ (((pbch_a_prime>>6)&1)<<1); nushift = ((pbch_a_prime>>24)&1) ^ (((pbch_a_prime>>6)&1)<<1);
pbch_a_interleaved=0; pbch_a_interleaved=0;
nr_pbch_unscrambling(nr_ue_pbch_vars, pbch_e_rx, frame_parms->Nid_cell, nushift, M, NR_POLAR_PBCH_PAYLOAD_BITS, nr_pbch_unscrambling(pbch_e_rx, frame_parms->Nid_cell, nushift, M, NR_POLAR_PBCH_PAYLOAD_BITS,
1, unscrambling_mask, pbch_a_prime, &pbch_a_interleaved); 1, unscrambling_mask, pbch_a_prime, &pbch_a_interleaved);
//printf("nushift %d sfn 3rd %d 2nd %d", nushift,((pbch_a_prime>>6)&1), ((pbch_a_prime>>24)&1) ); //printf("nushift %d sfn 3rd %d 2nd %d", nushift,((pbch_a_prime>>6)&1), ((pbch_a_prime>>24)&1) );
//payload deinterleaving //payload deinterleaving
...@@ -577,17 +586,12 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, ...@@ -577,17 +586,12 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
} }
#endif #endif
nr_downlink_indication_t dl_indication;
fapi_nr_rx_indication_t *rx_ind=calloc(sizeof(*rx_ind),1);
uint16_t number_pdus = 1;
nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, phy_data); nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, phy_data);
nr_fill_rx_indication(rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, ue, NULL, NULL, number_pdus, proc,(void *)result); nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, ue, NULL, NULL, number_pdus, proc, (void *)result, NULL);
if (ue->if_inst && ue->if_inst->dl_indication) if (ue->if_inst && ue->if_inst->dl_indication)
ue->if_inst->dl_indication(&dl_indication, NULL); ue->if_inst->dl_indication(&dl_indication, NULL);
else
free(rx_ind); // dl_indication would free(), so free() here if not called
return 0; return 0;
} }
...@@ -205,7 +205,9 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, ...@@ -205,7 +205,9 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
uint32_t frame, uint32_t frame,
uint16_t nb_symb_sch, uint16_t nb_symb_sch,
uint8_t nr_slot_rx, uint8_t nr_slot_rx,
uint8_t harq_pid); uint8_t harq_pid,
int b_size,
uint8_t b[b_size]);
int nr_ulsch_encoding(PHY_VARS_NR_UE *ue, int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
NR_UE_ULSCH_t *ulsch, NR_UE_ULSCH_t *ulsch,
...@@ -285,7 +287,6 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue, ...@@ -285,7 +287,6 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc, UE_nr_rxtx_proc_t *proc,
const int estimateSz, const int estimateSz,
struct complex16 dl_ch_estimates[][estimateSz], struct complex16 dl_ch_estimates[][estimateSz],
NR_UE_PBCH *nr_ue_pbch_vars,
NR_DL_FRAME_PARMS *frame_parms, NR_DL_FRAME_PARMS *frame_parms,
uint8_t i_ssb, uint8_t i_ssb,
MIMO_mode_t mimo_mode, MIMO_mode_t mimo_mode,
......
...@@ -119,8 +119,6 @@ typedef struct { ...@@ -119,8 +119,6 @@ typedef struct {
uint32_t TBS; uint32_t TBS;
/// The payload + CRC size in bits /// The payload + CRC size in bits
uint32_t B; uint32_t B;
/// Pointer to the payload
uint8_t *b;
/// Pointers to transport block segments /// Pointers to transport block segments
uint8_t **c; uint8_t **c;
/// soft bits for each received segment ("d"-sequence)(for definition see 36-212 V8.6 2009-03, p.15) /// soft bits for each received segment ("d"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
......
...@@ -317,6 +317,34 @@ void CIRPlot::timerEvent(QTimerEvent *event) ...@@ -317,6 +317,34 @@ void CIRPlot::timerEvent(QTimerEvent *event)
this->series->replace(points); this->series->replace(points);
} }
void CIRPlotUE::timerEvent(QTimerEvent *event)
{
if (!this->isVisible())
return;
scopeGraphData_t *data = this->valueProvider->getPlotValue();
if (data) {
this->data = (complex16 *)(data + 1);
this->len = data->lineSz;
QVector<QPointF> points(this->len);
float maxY = this->axisY->max();
for (int i = 0; i < this->len / 2; i++) {
float value = SquaredNorm(this->data[i + this->len / 2]);
points[i] = QPointF(i - this->len / 2, value);
maxY = std::max(maxY, value);
}
for (int i = 0; i < this->len / 2; i++) {
float value = SquaredNorm(this->data[i]);
points[i + this->len / 2] = QPointF(i, value);
maxY = std::max(maxY, value);
}
this->axisY->setMax(maxY);
this->series->replace(points);
}
}
LLRPlot::LLRPlot(int16_t *data, int len) : data(data), len(len) LLRPlot::LLRPlot(int16_t *data, int len) : data(data), len(len)
{ {
this->legend()->hide(); this->legend()->hide();
...@@ -361,6 +389,28 @@ void LLRPlot::timerEvent(QTimerEvent *event) ...@@ -361,6 +389,28 @@ void LLRPlot::timerEvent(QTimerEvent *event)
this->series->replace(points); this->series->replace(points);
} }
void LLRPlotUE::timerEvent(QTimerEvent *event)
{
if (!this->isVisible())
return;
scopeGraphData_t *data = this->valueProvider->getPlotValue();
if (data) {
this->data = (int16_t *)(data + 1);
this->len = data->lineSz;
QVector<QPointF> points(this->len);
int maxY = this->axisY->max();
for (int i = 0; i < this->len; i++) {
points[i] = QPointF(i, this->data[i]);
maxY = std::max(maxY, abs(this->data[i]));
}
this->axisY->setRange(-maxY, maxY);
this->series->replace(points);
}
}
IQPlot::IQPlot(complex16 *data, int len) : data(data), len(len) IQPlot::IQPlot(complex16 *data, int len) : data(data), len(len)
{ {
this->legend()->hide(); this->legend()->hide();
...@@ -407,6 +457,32 @@ void IQPlot::timerEvent(QTimerEvent *event) ...@@ -407,6 +457,32 @@ void IQPlot::timerEvent(QTimerEvent *event)
this->series->replace(points); this->series->replace(points);
} }
void IQPlotUE::timerEvent(QTimerEvent *event)
{
if (!this->isVisible())
return;
scopeGraphData_t *data = this->valueProvider->getPlotValue();
if (data) {
this->data = (complex16 *)(data + 1);
this->len = data->lineSz;
QVector<QPointF> points(this->len);
int maxX = this->axisX->max();
int maxY = this->axisY->max();
for (int i = 0; i < this->len; i++) {
points[i] = QPointF(this->data[i].r, this->data[i].i);
maxX = std::max(maxX, abs(this->data[i].r));
maxY = std::max(maxY, abs(this->data[i].i));
}
this->axisX->setRange(-maxX, maxX);
this->axisY->setRange(-maxY, maxY);
this->series->replace(points);
}
}
KPIPlot::KPIPlot(ValueProvider *valueProvider, float *limits) : valueProvider(valueProvider), limits(limits) KPIPlot::KPIPlot(ValueProvider *valueProvider, float *limits) : valueProvider(valueProvider), limits(limits)
{ {
this->series = new QLineSeries(); this->series = new QLineSeries();
...@@ -815,11 +891,42 @@ float PainterWidgetUE::getValue() ...@@ -815,11 +891,42 @@ float PainterWidgetUE::getValue()
case PlotTypeUE::timingAdvance: case PlotTypeUE::timingAdvance:
return (float)this->ue->timing_advance; return (float)this->ue->timing_advance;
default: default:
return 0; return 0;
} }
} }
scopeGraphData_t *PainterWidgetUE::getPlotValue()
{
scopeData_t *scope = (scopeData_t *)this->ue->scopeData;
scopeGraphData_t **data = (scopeGraphData_t **)scope->liveData;
switch (this->plotType) {
case PlotTypeUE::CIR:
return data[pbchDlChEstimateTime];
case PlotTypeUE::pbchLLR:
return data[pbchLlr];
case PlotTypeUE::pbchIQ:
return data[pbchRxdataF_comp];
case PlotTypeUE::pdcchLLR:
return data[pdcchLlr];
case PlotTypeUE::pdcchIQ:
return data[pdcchRxdataF_comp];
case PlotTypeUE::pdschLLR:
return data[pdschLlr];
case PlotTypeUE::pdschIQ:
return data[pdschRxdataF_comp];
default:
return nullptr;
}
}
/* @UE Class: this function is called when a resize event is detected, then the widget will be adjusted accordignly. */ /* @UE Class: this function is called when a resize event is detected, then the widget will be adjusted accordignly. */
void PainterWidgetUE::resizeEvent(QResizeEvent *event) void PainterWidgetUE::resizeEvent(QResizeEvent *event)
{ {
...@@ -890,7 +997,7 @@ void PainterWidgetUE::makeConnections(int type) ...@@ -890,7 +997,7 @@ void PainterWidgetUE::makeConnections(int type)
this->comboBox->setCurrentIndex(static_cast<int>(PlotTypeUE::empty)); this->comboBox->setCurrentIndex(static_cast<int>(PlotTypeUE::empty));
break; break;
} }
newChart = new LLRPlot((int16_t *)(data[pbchLlr] + 1), data[pbchLlr]->lineSz); newChart = new LLRPlotUE((int16_t *)(data[pbchLlr] + 1), data[pbchLlr]->lineSz, this);
break; break;
} }
case PlotTypeUE::pbchIQ: { case PlotTypeUE::pbchIQ: {
...@@ -900,7 +1007,7 @@ void PainterWidgetUE::makeConnections(int type) ...@@ -900,7 +1007,7 @@ void PainterWidgetUE::makeConnections(int type)
this->comboBox->setCurrentIndex(static_cast<int>(PlotTypeUE::empty)); this->comboBox->setCurrentIndex(static_cast<int>(PlotTypeUE::empty));
break; break;
} }
newChart = new IQPlot((complex16 *)(data[pbchRxdataF_comp] + 1), data[pbchRxdataF_comp]->lineSz); newChart = new IQPlotUE((complex16 *)(data[pbchRxdataF_comp] + 1), data[pbchRxdataF_comp]->lineSz, this);
break; break;
} }
case PlotTypeUE::pdcchLLR: { case PlotTypeUE::pdcchLLR: {
...@@ -910,7 +1017,7 @@ void PainterWidgetUE::makeConnections(int type) ...@@ -910,7 +1017,7 @@ void PainterWidgetUE::makeConnections(int type)
this->comboBox->setCurrentIndex(static_cast<int>(PlotTypeUE::empty)); this->comboBox->setCurrentIndex(static_cast<int>(PlotTypeUE::empty));
break; break;
} }
newChart = new LLRPlot((int16_t *)(data[pdcchLlr] + 1), data[pdcchLlr]->lineSz); newChart = new LLRPlotUE((int16_t *)(data[pdcchLlr] + 1), data[pdcchLlr]->lineSz, this);
break; break;
} }
case PlotTypeUE::pdcchIQ: { case PlotTypeUE::pdcchIQ: {
...@@ -920,7 +1027,7 @@ void PainterWidgetUE::makeConnections(int type) ...@@ -920,7 +1027,7 @@ void PainterWidgetUE::makeConnections(int type)
this->comboBox->setCurrentIndex(static_cast<int>(PlotTypeUE::empty)); this->comboBox->setCurrentIndex(static_cast<int>(PlotTypeUE::empty));
break; break;
} }
newChart = new IQPlot((complex16 *)(data[pdcchRxdataF_comp] + 1), data[pdcchRxdataF_comp]->lineSz); newChart = new IQPlotUE((complex16 *)(data[pdcchRxdataF_comp] + 1), data[pdcchRxdataF_comp]->lineSz, this);
break; break;
} }
case PlotTypeUE::pdschLLR: { case PlotTypeUE::pdschLLR: {
...@@ -930,7 +1037,7 @@ void PainterWidgetUE::makeConnections(int type) ...@@ -930,7 +1037,7 @@ void PainterWidgetUE::makeConnections(int type)
this->comboBox->setCurrentIndex(static_cast<int>(PlotTypeUE::empty)); this->comboBox->setCurrentIndex(static_cast<int>(PlotTypeUE::empty));
break; break;
} }
newChart = new LLRPlot((int16_t *)(data[pdschLlr] + 1), data[pdschLlr]->lineSz); newChart = new LLRPlotUE((int16_t *)(data[pdschLlr] + 1), data[pdschLlr]->lineSz, this);
break; break;
} }
case PlotTypeUE::pdschIQ: { case PlotTypeUE::pdschIQ: {
...@@ -940,7 +1047,7 @@ void PainterWidgetUE::makeConnections(int type) ...@@ -940,7 +1047,7 @@ void PainterWidgetUE::makeConnections(int type)
this->comboBox->setCurrentIndex(static_cast<int>(PlotTypeUE::empty)); this->comboBox->setCurrentIndex(static_cast<int>(PlotTypeUE::empty));
break; break;
} }
newChart = new IQPlot((complex16 *)(data[pdschRxdataF_comp] + 1), data[pdschRxdataF_comp]->lineSz); newChart = new IQPlotUE((complex16 *)(data[pdschRxdataF_comp] + 1), data[pdschRxdataF_comp]->lineSz, this);
break; break;
} }
...@@ -1147,6 +1254,7 @@ void nrUEinitQtScope(PHY_VARS_NR_UE *ue) ...@@ -1147,6 +1254,7 @@ void nrUEinitQtScope(PHY_VARS_NR_UE *ue)
scope->liveData = calloc(sizeof(scopeGraphData_t *), UEdataTypeNumberOfItems); scope->liveData = calloc(sizeof(scopeGraphData_t *), UEdataTypeNumberOfItems);
scope->copyData = UEcopyData; scope->copyData = UEcopyData;
UEcopyDataMutexInit();
ue->scopeData = scope; ue->scopeData = scope;
......
...@@ -91,6 +91,14 @@ class ValueProvider { ...@@ -91,6 +91,14 @@ class ValueProvider {
virtual float getValue() = 0; virtual float getValue() = 0;
}; };
class ValueProviderUE : public ValueProvider {
public:
/// This pure virtual function is meant to provide the graph values to be plotted
virtual scopeGraphData_t *getPlotValue() {
return nullptr;
}
};
/// An editable GUI field for a dialog box to set certain KPI configurations /// An editable GUI field for a dialog box to set certain KPI configurations
class ConfigBoxFloat : public QLineEdit { class ConfigBoxFloat : public QLineEdit {
Q_OBJECT Q_OBJECT
...@@ -206,7 +214,6 @@ class CIRPlot : public QChart { ...@@ -206,7 +214,6 @@ class CIRPlot : public QChart {
/// \param event Pointer to the timer event /// \param event Pointer to the timer event
virtual void timerEvent(QTimerEvent *event) override; virtual void timerEvent(QTimerEvent *event) override;
private:
/// Pointer to the CIR data /// Pointer to the CIR data
complex16 *data; complex16 *data;
...@@ -223,6 +230,21 @@ class CIRPlot : public QChart { ...@@ -223,6 +230,21 @@ class CIRPlot : public QChart {
QValueAxis *axisY; QValueAxis *axisY;
}; };
class CIRPlotUE : public CIRPlot {
Q_OBJECT
public:
CIRPlotUE(complex16 *data, int len, ValueProviderUE *valueProvider) : CIRPlot(data, len), valueProvider(valueProvider) {}
protected:
/// This function is triggered when the own timer expires. It updates the plotted CIR
/// \param event Pointer to the timer event
virtual void timerEvent(QTimerEvent *event) override;
private:
ValueProviderUE *valueProvider;
};
/// Chart class for plotting LLRs /// Chart class for plotting LLRs
class LLRPlot : public QChart { class LLRPlot : public QChart {
Q_OBJECT Q_OBJECT
...@@ -238,7 +260,6 @@ class LLRPlot : public QChart { ...@@ -238,7 +260,6 @@ class LLRPlot : public QChart {
/// \param event Pointer to the timer event /// \param event Pointer to the timer event
virtual void timerEvent(QTimerEvent *event) override; virtual void timerEvent(QTimerEvent *event) override;
private:
/// Pointer to the LLR data /// Pointer to the LLR data
int16_t *data; int16_t *data;
...@@ -255,6 +276,21 @@ class LLRPlot : public QChart { ...@@ -255,6 +276,21 @@ class LLRPlot : public QChart {
QValueAxis *axisY; QValueAxis *axisY;
}; };
class LLRPlotUE : public LLRPlot {
Q_OBJECT
public:
LLRPlotUE(int16_t *data, int len, ValueProviderUE *valueProvider) : LLRPlot(data, len), valueProvider(valueProvider) {}
protected:
/// This function is triggered when the own timer expires. It updates the plotted I/Q constellation diagram
/// \param event Pointer to the timer event
virtual void timerEvent(QTimerEvent *event) override;
private:
ValueProviderUE *valueProvider;
};
/// Chart class for plotting the I/Q constellation diagram /// Chart class for plotting the I/Q constellation diagram
class IQPlot : public QChart { class IQPlot : public QChart {
Q_OBJECT Q_OBJECT
...@@ -270,7 +306,6 @@ class IQPlot : public QChart { ...@@ -270,7 +306,6 @@ class IQPlot : public QChart {
/// \param event Pointer to the timer event /// \param event Pointer to the timer event
virtual void timerEvent(QTimerEvent *event) override; virtual void timerEvent(QTimerEvent *event) override;
private:
/// Pointer to the I/Q data /// Pointer to the I/Q data
complex16 *data; complex16 *data;
...@@ -287,6 +322,22 @@ class IQPlot : public QChart { ...@@ -287,6 +322,22 @@ class IQPlot : public QChart {
QValueAxis *axisY; QValueAxis *axisY;
}; };
class IQPlotUE : public IQPlot {
Q_OBJECT
public:
IQPlotUE(complex16 *data, int len, ValueProviderUE *valueProvider) : IQPlot(data, len), valueProvider(valueProvider) {}
protected:
/// This function is triggered when the own timer expires. It updates the plotted I/Q constellation diagram
/// \param event Pointer to the timer event
virtual void timerEvent(QTimerEvent *event) override;
private:
/// Pointer to an instance of a class that implements the ValueProvider interface
ValueProviderUE *valueProvider;
};
/// Generic class for plotting KPI values with min., max. and average bars /// Generic class for plotting KPI values with min., max. and average bars
class KPIPlot : public QChart { class KPIPlot : public QChart {
Q_OBJECT Q_OBJECT
...@@ -422,7 +473,7 @@ class PainterWidgetGnb : public QWidget, public ValueProvider { ...@@ -422,7 +473,7 @@ class PainterWidgetGnb : public QWidget, public ValueProvider {
}; };
/// Widget showing one selectable UE KPI /// Widget showing one selectable UE KPI
class PainterWidgetUE : public QWidget, public ValueProvider { class PainterWidgetUE : public QWidget, public ValueProviderUE {
Q_OBJECT Q_OBJECT
public: public:
...@@ -435,6 +486,8 @@ class PainterWidgetUE : public QWidget, public ValueProvider { ...@@ -435,6 +486,8 @@ class PainterWidgetUE : public QWidget, public ValueProvider {
/// This function provides the current KPI value to be plotted /// This function provides the current KPI value to be plotted
virtual float getValue() override; virtual float getValue() override;
virtual scopeGraphData_t *getPlotValue() override;
protected: protected:
/// This function is called to change the widget size /// This function is called to change the widget size
/// \param event Pointer to the resize event /// \param event Pointer to the resize event
......
...@@ -1137,8 +1137,6 @@ static void *nrUEscopeThread(void *arg) { ...@@ -1137,8 +1137,6 @@ static void *nrUEscopeThread(void *arg) {
} }
#endif #endif
pthread_mutex_t UEcopyDataMutex;
STATICFORXSCOPE void nrUEinitScope(PHY_VARS_NR_UE *ue) STATICFORXSCOPE void nrUEinitScope(PHY_VARS_NR_UE *ue)
{ {
AssertFatal(ue->scopeData=malloc(sizeof(scopeData_t)),""); AssertFatal(ue->scopeData=malloc(sizeof(scopeData_t)),"");
...@@ -1148,8 +1146,8 @@ STATICFORXSCOPE void nrUEinitScope(PHY_VARS_NR_UE *ue) ...@@ -1148,8 +1146,8 @@ STATICFORXSCOPE void nrUEinitScope(PHY_VARS_NR_UE *ue)
#ifndef WEBSRVSCOPE #ifndef WEBSRVSCOPE
pthread_t forms_thread; pthread_t forms_thread;
threadCreate(&forms_thread, nrUEscopeThread, ue, "scope", -1, OAI_PRIORITY_RT_LOW); threadCreate(&forms_thread, nrUEscopeThread, ue, "scope", -1, OAI_PRIORITY_RT_LOW);
UEcopyDataMutexInit();
#endif #endif
pthread_mutex_init(&UEcopyDataMutex, NULL);
} }
void nrscope_autoinit(void *dataptr) { void nrscope_autoinit(void *dataptr) {
......
...@@ -35,9 +35,16 @@ ...@@ -35,9 +35,16 @@
#include "phy_scope_interface.h" #include "phy_scope_interface.h"
#define SOFTSCOPE_ENDFUNC_IDX 0 #define SOFTSCOPE_ENDFUNC_IDX 0
#define THREAD_MEM 4
static loader_shlibfunc_t scope_fdesc[]= {{"end_forms",NULL}}; static loader_shlibfunc_t scope_fdesc[]= {{"end_forms",NULL}};
pthread_mutex_t UEcopyDataMutex;
int UEcopyDataMutexInit(void) {
return pthread_mutex_init(&UEcopyDataMutex, NULL);
}
int load_softscope(char *exectype, void *initarg) { int load_softscope(char *exectype, void *initarg) {
char libname[64]; char libname[64];
sprintf(libname,"%.10sscope",exectype); sprintf(libname,"%.10sscope",exectype);
...@@ -56,16 +63,19 @@ int end_forms(void) { ...@@ -56,16 +63,19 @@ int end_forms(void) {
void UEcopyData(PHY_VARS_NR_UE *ue, enum UEdataType type, void *dataIn, int elementSz, int colSz, int lineSz) { void UEcopyData(PHY_VARS_NR_UE *ue, enum UEdataType type, void *dataIn, int elementSz, int colSz, int lineSz) {
// Local static copy of the scope data bufs // Local static copy of the scope data bufs
// The active data buf is alterned to avoid interference between the Scope thread (display) and the Rx thread (data input) // The active data buf is alterned to avoid interference between the Scope thread (display) and the Rx thread (data input)
// Index of "2" could be set to the number of Rx threads + 1 // Index of THREAD_MEM could be set to the number of Rx threads + 1. Rx slots could run asynchronous to each other.
static scopeGraphData_t *copyDataBufs[UEdataTypeNumberOfItems][2] = {0}; // THREAD_MEM = 4 slot process running in parallel is an assumption. THREAD_MEM can be increased if scope appears inconsistent.
static scopeGraphData_t *copyDataBufs[UEdataTypeNumberOfItems][THREAD_MEM] = {0};
static int copyDataBufsIdx[UEdataTypeNumberOfItems] = {0}; static int copyDataBufsIdx[UEdataTypeNumberOfItems] = {0};
scopeData_t *tmp = (scopeData_t *)ue->scopeData; scopeData_t *tmp = (scopeData_t *)ue->scopeData;
if (tmp) { if (tmp) {
// Begin of critical zone between UE Rx threads that might copy new data at the same time: might require a mutex // Begin of critical zone between UE Rx threads that might copy new data at the same time:
int newCopyDataIdx = (copyDataBufsIdx[type]==0)?1:0; pthread_mutex_lock(&UEcopyDataMutex);
int newCopyDataIdx = (copyDataBufsIdx[type]<(THREAD_MEM-1))?copyDataBufsIdx[type]+1:0;
copyDataBufsIdx[type] = newCopyDataIdx; copyDataBufsIdx[type] = newCopyDataIdx;
pthread_mutex_unlock(&UEcopyDataMutex);
// End of critical zone between UE Rx threads // End of critical zone between UE Rx threads
// New data will be copied in a different buffer than the live one // New data will be copied in a different buffer than the live one
......
...@@ -31,15 +31,21 @@ ...@@ -31,15 +31,21 @@
*/ */
#ifndef __PHY_SCOPE_INTERFACE_H__ #ifndef __PHY_SCOPE_INTERFACE_H__
#define __PHY_SCOPE_INTERFACE_H__ #define __PHY_SCOPE_INTERFACE_H__
#ifdef __cplusplus
#include <atomic>
#define _Atomic(X) std::atomic< X >
#endif
#include <openair1/PHY/defs_gNB.h> #include <openair1/PHY/defs_gNB.h>
#include <openair1/PHY/defs_nr_UE.h> #include <openair1/PHY/defs_nr_UE.h>
typedef struct { typedef struct {
uint32_t nb_total; _Atomic(uint32_t) nb_total;
uint32_t nb_nack; _Atomic(uint32_t) nb_nack;
uint32_t blockSize; // block size, to be used for throughput calculation _Atomic(uint32_t) blockSize; // block size, to be used for throughput calculation
uint16_t nofRBs; _Atomic(uint16_t) nofRBs;
uint8_t dl_mcs; _Atomic(uint8_t ) dl_mcs;
} extended_kpi_ue; } extended_kpi_ue;
typedef struct { typedef struct {
...@@ -80,6 +86,7 @@ typedef struct { ...@@ -80,6 +86,7 @@ typedef struct {
int load_softscope(char *exectype, void *initarg); int load_softscope(char *exectype, void *initarg);
int end_forms(void) ; int end_forms(void) ;
int UEcopyDataMutexInit(void);
void UEcopyData(PHY_VARS_NR_UE *ue, enum UEdataType type, void *dataIn, int elementSz, int colSz, int lineSz); void UEcopyData(PHY_VARS_NR_UE *ue, enum UEdataType type, void *dataIn, int elementSz, int colSz, int lineSz);
#define UEscopeCopy(ue, type, ...) if(ue->scopeData) ((scopeData_t*)ue->scopeData)->copyData(ue, type, ##__VA_ARGS__); #define UEscopeCopy(ue, type, ...) if(ue->scopeData) ((scopeData_t*)ue->scopeData)->copyData(ue, type, ##__VA_ARGS__);
......
...@@ -823,6 +823,8 @@ typedef struct processingData_L1tx { ...@@ -823,6 +823,8 @@ typedef struct processingData_L1tx {
uint16_t num_pdsch_slot; uint16_t num_pdsch_slot;
int num_dl_pdcch; int num_dl_pdcch;
int num_ul_pdcch; int num_ul_pdcch;
/* a reference to the sched_response, to release it when not needed anymore */
int sched_response_id;
} processingData_L1tx_t; } processingData_L1tx_t;
#endif #endif
...@@ -32,6 +32,10 @@ ...@@ -32,6 +32,10 @@
#ifndef __PHY_DEFS_NR_UE__H__ #ifndef __PHY_DEFS_NR_UE__H__
#define __PHY_DEFS_NR_UE__H__ #define __PHY_DEFS_NR_UE__H__
#ifdef __cplusplus
#include <atomic>
#define _Atomic(X) std::atomic< X >
#endif
#include "defs_nr_common.h" #include "defs_nr_common.h"
#include "CODING/nrPolar_tools/nr_polar_pbch_defs.h" #include "CODING/nrPolar_tools/nr_polar_pbch_defs.h"
...@@ -316,17 +320,6 @@ typedef struct { ...@@ -316,17 +320,6 @@ typedef struct {
#define PBCH_A 24 #define PBCH_A 24
typedef struct {
/// \brief Total number of PDU errors.
uint32_t pdu_errors;
/// \brief Total number of PDU errors 128 frames ago.
uint32_t pdu_errors_last;
/// \brief Total number of consecutive PDU errors.
uint32_t pdu_errors_conseq;
/// \brief FER (in percent) .
//uint32_t pdu_fer;
} NR_UE_PBCH;
typedef struct { typedef struct {
int16_t amp; int16_t amp;
bool active; bool active;
...@@ -385,9 +378,6 @@ typedef struct { ...@@ -385,9 +378,6 @@ typedef struct {
uint8_t CC_id; uint8_t CC_id;
/// \brief Mapping of CC_id antennas to cards /// \brief Mapping of CC_id antennas to cards
openair0_rf_map rf_map; openair0_rf_map rf_map;
//uint8_t local_flag;
/// \brief Indicator of current run mode of UE (normal_txrx, rx_calib_ue, no_L2_connect, debug_prach)
runmode_t mode;
/// \brief Indicator that UE should perform band scanning /// \brief Indicator that UE should perform band scanning
int UE_scan; int UE_scan;
/// \brief Indicator that UE should perform coarse scanning around carrier /// \brief Indicator that UE should perform coarse scanning around carrier
...@@ -402,8 +392,6 @@ typedef struct { ...@@ -402,8 +392,6 @@ typedef struct {
int is_synchronized; int is_synchronized;
/// \brief Target gNB Nid_cell when UE is resynchronizing /// \brief Target gNB Nid_cell when UE is resynchronizing
int target_Nid_cell; int target_Nid_cell;
/// \brief Indicator that UE lost frame synchronization
int lost_sync;
/// Data structure for UE process scheduling /// Data structure for UE process scheduling
UE_nr_proc_t proc; UE_nr_proc_t proc;
/// Flag to indicate the UE shouldn't do timing correction at all /// Flag to indicate the UE shouldn't do timing correction at all
...@@ -444,7 +432,6 @@ typedef struct { ...@@ -444,7 +432,6 @@ typedef struct {
fapi_nr_config_request_t nrUE_config; fapi_nr_config_request_t nrUE_config;
nr_synch_request_t synch_request; nr_synch_request_t synch_request;
NR_UE_PBCH *pbch_vars[NUMBER_OF_CONNECTED_gNB_MAX];
NR_UE_PRACH *prach_vars[NUMBER_OF_CONNECTED_gNB_MAX]; NR_UE_PRACH *prach_vars[NUMBER_OF_CONNECTED_gNB_MAX];
NR_UE_CSI_IM *csiim_vars[NUMBER_OF_CONNECTED_gNB_MAX]; NR_UE_CSI_IM *csiim_vars[NUMBER_OF_CONNECTED_gNB_MAX];
NR_UE_CSI_RS *csirs_vars[NUMBER_OF_CONNECTED_gNB_MAX]; NR_UE_CSI_RS *csirs_vars[NUMBER_OF_CONNECTED_gNB_MAX];
...@@ -655,7 +642,7 @@ typedef struct { ...@@ -655,7 +642,7 @@ typedef struct {
SLIST_HEAD(ral_thresholds_lte_poll_s, ral_threshold_phy_t) ral_thresholds_lte_polled[RAL_LINK_PARAM_LTE_MAX]; SLIST_HEAD(ral_thresholds_lte_poll_s, ral_threshold_phy_t) ral_thresholds_lte_polled[RAL_LINK_PARAM_LTE_MAX];
#endif #endif
int dl_errors; int dl_errors;
int dl_stats[8]; _Atomic(int) dl_stats[16];
void* scopeData; void* scopeData;
// Pointers to hold PDSCH data only for phy simulators // Pointers to hold PDSCH data only for phy simulators
void *phy_sim_rxdataF; void *phy_sim_rxdataF;
...@@ -664,6 +651,10 @@ typedef struct { ...@@ -664,6 +651,10 @@ typedef struct {
void *phy_sim_pdsch_rxdataF_comp; void *phy_sim_pdsch_rxdataF_comp;
void *phy_sim_pdsch_dl_ch_estimates; void *phy_sim_pdsch_dl_ch_estimates;
void *phy_sim_pdsch_dl_ch_estimates_ext; void *phy_sim_pdsch_dl_ch_estimates_ext;
uint8_t *phy_sim_dlsch_b;
notifiedFIFO_t phy_config_ind;
notifiedFIFO_t *tx_resume_ind_fifo[NR_MAX_SLOTS_PER_FRAME];
int tx_wait_for_dlsch[NR_MAX_SLOTS_PER_FRAME];
} PHY_VARS_NR_UE; } PHY_VARS_NR_UE;
typedef struct nr_phy_data_tx_s { typedef struct nr_phy_data_tx_s {
...@@ -682,6 +673,8 @@ typedef struct nr_rxtx_thread_data_s { ...@@ -682,6 +673,8 @@ typedef struct nr_rxtx_thread_data_s {
UE_nr_rxtx_proc_t proc; UE_nr_rxtx_proc_t proc;
PHY_VARS_NR_UE *UE; PHY_VARS_NR_UE *UE;
int writeBlockSize; int writeBlockSize;
nr_phy_data_t phy_data;
int tx_wait_for_dlsch;
} nr_rxtx_thread_data_t; } nr_rxtx_thread_data_t;
typedef struct LDPCDecode_ue_s { typedef struct LDPCDecode_ue_s {
...@@ -707,6 +700,7 @@ typedef struct LDPCDecode_ue_s { ...@@ -707,6 +700,7 @@ typedef struct LDPCDecode_ue_s {
time_stats_t ts_deinterleave; time_stats_t ts_deinterleave;
time_stats_t ts_rate_unmatch; time_stats_t ts_rate_unmatch;
time_stats_t ts_ldpc_decode; time_stats_t ts_ldpc_decode;
UE_nr_rxtx_proc_t *proc;
} ldpcDecode_ue_t; } ldpcDecode_ue_t;
#include "SIMULATION/ETH_TRANSPORT/defs.h" #include "SIMULATION/ETH_TRANSPORT/defs.h"
......
...@@ -270,7 +270,7 @@ ...@@ -270,7 +270,7 @@
/* FFS_NR_TODO it defines ue capability which is the number of slots */ /* FFS_NR_TODO it defines ue capability which is the number of slots */
/* - between reception of pdsch and tarnsmission of its acknowlegment */ /* - between reception of pdsch and tarnsmission of its acknowlegment */
/* - between reception of un uplink grant and its related transmission */ /* - between reception of un uplink grant and its related transmission */
#define NR_UE_CAPABILITY_SLOT_RX_TO_TX (4) #define NR_UE_CAPABILITY_SLOT_RX_TO_TX (3)
#ifndef NO_RAT_NR #ifndef NO_RAT_NR
#define DURATION_RX_TO_TX (NR_UE_CAPABILITY_SLOT_RX_TO_TX) /* for NR this will certainly depends to such UE capability which is not yet defined */ #define DURATION_RX_TO_TX (NR_UE_CAPABILITY_SLOT_RX_TO_TX) /* for NR this will certainly depends to such UE capability which is not yet defined */
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "PHY/NR_TRANSPORT/nr_dlsch.h" #include "PHY/NR_TRANSPORT/nr_dlsch.h"
#include "PHY/NR_TRANSPORT/nr_dci.h" #include "PHY/NR_TRANSPORT/nr_dci.h"
#include "nfapi/oai_integration/vendor_ext.h" #include "nfapi/oai_integration/vendor_ext.h"
#include "openair2/NR_PHY_INTERFACE/nr_sched_response.h"
extern int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req); extern int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req);
extern int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req); extern int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req);
...@@ -131,10 +132,10 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO) ...@@ -131,10 +132,10 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO)
{ {
// copy data from L2 interface into L1 structures // copy data from L2 interface into L1 structures
module_id_t Mod_id = Sched_INFO->module_id; module_id_t Mod_id = Sched_INFO->module_id;
nfapi_nr_dl_tti_request_t *DL_req = Sched_INFO->DL_req; nfapi_nr_dl_tti_request_t *DL_req = &Sched_INFO->DL_req;
nfapi_nr_tx_data_request_t *TX_req = Sched_INFO->TX_req; nfapi_nr_tx_data_request_t *TX_req = &Sched_INFO->TX_req;
nfapi_nr_ul_tti_request_t *UL_tti_req = Sched_INFO->UL_tti_req; nfapi_nr_ul_tti_request_t *UL_tti_req = &Sched_INFO->UL_tti_req;
nfapi_nr_ul_dci_request_t *UL_dci_req = Sched_INFO->UL_dci_req; nfapi_nr_ul_dci_request_t *UL_dci_req = &Sched_INFO->UL_dci_req;
frame_t frame = Sched_INFO->frame; frame_t frame = Sched_INFO->frame;
sub_frame_t slot = Sched_INFO->slot; sub_frame_t slot = Sched_INFO->slot;
...@@ -169,6 +170,8 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO) ...@@ -169,6 +170,8 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO)
msgTx->num_ul_pdcch = number_ul_dci_pdu; msgTx->num_ul_pdcch = number_ul_dci_pdu;
msgTx->slot = slot; msgTx->slot = slot;
msgTx->frame = frame; msgTx->frame = frame;
/* store the sched_response_id for the TX thread to release it when done */
msgTx->sched_response_id = Sched_INFO->sched_response_id;
for (int i=0;i<number_dl_pdu;i++) { for (int i=0;i<number_dl_pdu;i++) {
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu = &DL_req->dl_tti_request_body.dl_tti_pdu_list[i]; nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu = &DL_req->dl_tti_request_body.dl_tti_pdu_list[i];
...@@ -208,6 +211,11 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO) ...@@ -208,6 +211,11 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO)
for (int i=0; i<number_ul_dci_pdu; i++) for (int i=0; i<number_ul_dci_pdu; i++)
msgTx->ul_pdcch_pdu[i] = UL_dci_req->ul_dci_pdu_list[i]; msgTx->ul_pdcch_pdu[i] = UL_dci_req->ul_dci_pdu_list[i];
/* Both the current thread and the TX thread will access the sched_info
* at the same time, so increase its reference counter, so that it is
* released only when both threads are done with it.
*/
inc_ref_sched_response(Sched_INFO->sched_response_id);
pushNotifiedFIFO(&gNB->L1_tx_filled,res); pushNotifiedFIFO(&gNB->L1_tx_filled,res);
} }
...@@ -250,5 +258,9 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO) ...@@ -250,5 +258,9 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO)
if (number_dl_pdu>0) if (number_dl_pdu>0)
oai_nfapi_dl_tti_req(DL_req); oai_nfapi_dl_tti_req(DL_req);
} }
/* this thread is done with the sched_info, decrease the reference counter */
deref_sched_response(Sched_INFO->sched_response_id);
stop_meas(&gNB->schedule_response_stats); stop_meas(&gNB->schedule_response_stats);
} }
...@@ -83,7 +83,7 @@ ...@@ -83,7 +83,7 @@
typedef struct { typedef struct {
uint8_t decoded_output[64]; uint8_t decoded_output[3]; // PBCH paylod not larger than 3B
uint8_t xtra_byte; uint8_t xtra_byte;
} fapiPbch_t; } fapiPbch_t;
...@@ -98,17 +98,16 @@ typedef struct { ...@@ -98,17 +98,16 @@ typedef struct {
*/ */
void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data); void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data);
/*! \brief Scheduling for UE RX procedures in normal subframes. void send_slot_ind(notifiedFIFO_t *nf, int slot);
@param ue Pointer to UE variables on which to act
@param proc Pointer to proc information void pbch_pdcch_processing(PHY_VARS_NR_UE *ue,
@param dlsch_parallel use multithreaded dlsch processing
@param phy_pdcch_config PDCCH Config for this slot
@param txFifo Result fifo if PDSCH is run in parallel
*/
int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc, UE_nr_rxtx_proc_t *proc,
nr_phy_data_t *phy_data); nr_phy_data_t *phy_data);
void pdsch_processing(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
nr_phy_data_t *phy_data);
int phy_procedures_slot_parallelization_nrUE_RX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t abstraction_flag, uint8_t do_pdcch_flag, relaying_type_t r_type); int phy_procedures_slot_parallelization_nrUE_RX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t abstraction_flag, uint8_t do_pdcch_flag, relaying_type_t r_type);
void processSlotTX(void *arg); void processSlotTX(void *arg);
...@@ -166,7 +165,8 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind, ...@@ -166,7 +165,8 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
NR_UE_DLSCH_t *dlsch1, NR_UE_DLSCH_t *dlsch1,
uint16_t n_pdus, uint16_t n_pdus,
UE_nr_rxtx_proc_t *proc, UE_nr_rxtx_proc_t *proc,
void *typeSpecific); void *typeSpecific,
uint8_t *b);
bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc, UE_nr_rxtx_proc_t *proc,
......
...@@ -544,8 +544,10 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ ...@@ -544,8 +544,10 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
int8_t nr_ue_phy_config_request(nr_phy_config_t *phy_config) int8_t nr_ue_phy_config_request(nr_phy_config_t *phy_config)
{ {
fapi_nr_config_request_t *nrUE_config = &PHY_vars_UE_g[phy_config->Mod_id][phy_config->CC_id]->nrUE_config; fapi_nr_config_request_t *nrUE_config = &PHY_vars_UE_g[phy_config->Mod_id][phy_config->CC_id]->nrUE_config;
if(phy_config != NULL) if(phy_config != NULL) {
memcpy(nrUE_config,&phy_config->config_req,sizeof(fapi_nr_config_request_t)); memcpy(nrUE_config,&phy_config->config_req,sizeof(fapi_nr_config_request_t));
pushNotifiedFIFO(&PHY_vars_UE_g[phy_config->Mod_id][phy_config->CC_id]->phy_config_ind, newNotifiedFIFO_elt(1,0,NULL,NULL));
}
return 0; return 0;
} }
......
This diff is collapsed.
...@@ -81,6 +81,17 @@ void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) {} ...@@ -81,6 +81,17 @@ void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) {}
NR_IF_Module_t *NR_IF_Module_init(int Mod_id) { return (NULL); } NR_IF_Module_t *NR_IF_Module_init(int Mod_id) { return (NULL); }
nfapi_mode_t nfapi_getmode(void) { return NFAPI_MODE_UNKNOWN; } nfapi_mode_t nfapi_getmode(void) { return NFAPI_MODE_UNKNOWN; }
void inc_ref_sched_response(int _)
{
LOG_E(PHY, "fatal\n");
exit(1);
}
void deref_sched_response(int _)
{
LOG_E(PHY, "fatal\n");
exit(1);
}
nrUE_params_t nrUE_params={0}; nrUE_params_t nrUE_params={0};
nrUE_params_t *get_nrUE_params(void) { nrUE_params_t *get_nrUE_params(void) {
...@@ -542,9 +553,17 @@ int main(int argc, char **argv) ...@@ -542,9 +553,17 @@ int main(int argc, char **argv)
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DECODING0, VCD_FUNCTION_IN); vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DECODING0, VCD_FUNCTION_IN);
int a_segments = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*NR_MAX_NB_LAYERS; //number of segments to be allocated
int num_rb = dlsch0_ue->dlsch_config.number_rbs;
if (num_rb != 273) {
a_segments = a_segments*num_rb;
a_segments = (a_segments/273)+1;
}
uint32_t dlsch_bytes = a_segments*1056; // allocated bytes per segment
__attribute__ ((aligned(32))) uint8_t b[dlsch_bytes];
ret = nr_dlsch_decoding(UE, &proc, 0, channel_output_fixed, &UE->frame_parms, ret = nr_dlsch_decoding(UE, &proc, 0, channel_output_fixed, &UE->frame_parms,
dlsch0_ue, harq_process, frame, nb_symb_sch, dlsch0_ue, harq_process, frame, nb_symb_sch,
slot,harq_pid); slot,harq_pid,dlsch_bytes,b);
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DECODING0, VCD_FUNCTION_OUT); vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DECODING0, VCD_FUNCTION_OUT);
...@@ -555,7 +574,7 @@ int main(int argc, char **argv) ...@@ -555,7 +574,7 @@ int main(int argc, char **argv)
errors_bit = 0; errors_bit = 0;
for (i = 0; i < TBS; i++) { for (i = 0; i < TBS; i++) {
estimated_output_bit[i] = (harq_process->b[i / 8] & (1 << (i & 7))) >> (i & 7); estimated_output_bit[i] = (b[i / 8] & (1 << (i & 7))) >> (i & 7);
test_input_bit[i] = (test_input[i / 8] & (1 << (i & 7))) >> (i & 7); // Further correct for multiple segments test_input_bit[i] = (test_input[i / 8] & (1 << (i & 7))) >> (i & 7); // Further correct for multiple segments
if (estimated_output_bit[i] != test_input_bit[i]) { if (estimated_output_bit[i] != test_input_bit[i]) {
......
...@@ -328,7 +328,7 @@ int main(int argc, char **argv) ...@@ -328,7 +328,7 @@ int main(int argc, char **argv)
//int frame_length_complex_samples_no_prefix; //int frame_length_complex_samples_no_prefix;
NR_DL_FRAME_PARMS *frame_parms; NR_DL_FRAME_PARMS *frame_parms;
UE_nr_rxtx_proc_t UE_proc; UE_nr_rxtx_proc_t UE_proc;
NR_Sched_Rsp_t Sched_INFO; NR_Sched_Rsp_t *Sched_INFO;
gNB_MAC_INST *gNB_mac; gNB_MAC_INST *gNB_mac;
NR_UE_MAC_INST_t *UE_mac; NR_UE_MAC_INST_t *UE_mac;
int cyclic_prefix_type = NFAPI_CP_NORMAL; int cyclic_prefix_type = NFAPI_CP_NORMAL;
...@@ -940,6 +940,13 @@ int main(int argc, char **argv) ...@@ -940,6 +940,13 @@ int main(int argc, char **argv)
UE->phy_sim_pdsch_rxdataF_comp = calloc(sizeof(int32_t *) * frame_parms->nb_antennas_rx * g_nrOfLayers, rx_size); UE->phy_sim_pdsch_rxdataF_comp = calloc(sizeof(int32_t *) * frame_parms->nb_antennas_rx * g_nrOfLayers, rx_size);
UE->phy_sim_pdsch_dl_ch_estimates = calloc(sizeof(int32_t *) * frame_parms->nb_antennas_rx * g_nrOfLayers, rx_size); UE->phy_sim_pdsch_dl_ch_estimates = calloc(sizeof(int32_t *) * frame_parms->nb_antennas_rx * g_nrOfLayers, rx_size);
UE->phy_sim_pdsch_dl_ch_estimates_ext = calloc(sizeof(int32_t *) * frame_parms->nb_antennas_rx * g_nrOfLayers, rx_size); UE->phy_sim_pdsch_dl_ch_estimates_ext = calloc(sizeof(int32_t *) * frame_parms->nb_antennas_rx * g_nrOfLayers, rx_size);
int a_segments = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*NR_MAX_NB_LAYERS; //number of segments to be allocated
if (g_rbSize != 273) {
a_segments = a_segments*g_rbSize;
a_segments = (a_segments/273)+1;
}
uint32_t dlsch_bytes = a_segments*1056; // allocated bytes per segment
UE->phy_sim_dlsch_b = calloc(1, dlsch_bytes);
for (SNR = snr0; SNR < snr1; SNR += .2) { for (SNR = snr0; SNR < snr1; SNR += .2) {
...@@ -994,28 +1001,33 @@ int main(int argc, char **argv) ...@@ -994,28 +1001,33 @@ int main(int argc, char **argv)
round = 0; round = 0;
UE_harq_process->DLround = round; UE_harq_process->DLround = round;
UE_harq_process->first_rx = 1; UE_harq_process->first_rx = 1;
Sched_INFO = malloc(sizeof(*Sched_INFO));
if (Sched_INFO == NULL) {
LOG_E(PHY, "out of memory\n");
exit(1);
}
memset(Sched_INFO, 0, sizeof(*Sched_INFO));
Sched_INFO->sched_response_id = -1;
while ((round<num_rounds) && (UE_harq_process->ack==0)) { while ((round<num_rounds) && (UE_harq_process->ack==0)) {
round_trials[round]++; round_trials[round]++;
clear_nr_nfapi_information(RC.nrmac[0], 0, frame, slot); clear_nr_nfapi_information(RC.nrmac[0], 0, frame, slot, &Sched_INFO->DL_req, &Sched_INFO->TX_req, &Sched_INFO->UL_dci_req);
UE_info->UE_sched_ctrl.harq_processes[harq_pid].ndi = !(trial&1); UE_info->UE_sched_ctrl.harq_processes[harq_pid].ndi = !(trial&1);
UE_info->UE_sched_ctrl.harq_processes[harq_pid].round = round; UE_info->UE_sched_ctrl.harq_processes[harq_pid].round = round;
nr_schedule_ue_spec(0, frame, slot); nr_schedule_ue_spec(0, frame, slot, &Sched_INFO->DL_req, &Sched_INFO->TX_req);
Sched_INFO.module_id = 0; Sched_INFO->module_id = 0;
Sched_INFO.CC_id = 0; Sched_INFO->CC_id = 0;
Sched_INFO.frame = frame; Sched_INFO->frame = frame;
Sched_INFO.slot = slot; Sched_INFO->slot = slot;
Sched_INFO.DL_req = &gNB_mac->DL_req[0]; Sched_INFO->UL_dci_req.numPdus = 0;
Sched_INFO.UL_tti_req = gNB_mac->UL_tti_req_ahead[0];
Sched_INFO.UL_dci_req = NULL;
Sched_INFO.TX_req = &gNB_mac->TX_req[0];
pushNotifiedFIFO(&gNB->L1_tx_free,msgL1Tx); pushNotifiedFIFO(&gNB->L1_tx_free,msgL1Tx);
nr_schedule_response(&Sched_INFO); nr_schedule_response(Sched_INFO);
/* PTRS values for DLSIM calculations */ /* PTRS values for DLSIM calculations */
nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[Sched_INFO.CC_id].dl_tti_request_body; nfapi_nr_dl_tti_request_body_t *dl_req = &Sched_INFO->DL_req.dl_tti_request_body;
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[1]; nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[1];
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15; nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15;
pdu_bit_map = pdsch_pdu_rel15->pduBitmap; pdu_bit_map = pdsch_pdu_rel15->pduBitmap;
...@@ -1153,9 +1165,12 @@ int main(int argc, char **argv) ...@@ -1153,9 +1165,12 @@ int main(int argc, char **argv)
nr_ue_dcireq(&dcireq); //to be replaced with function pointer later nr_ue_dcireq(&dcireq); //to be replaced with function pointer later
nr_ue_scheduled_response(&scheduled_response); nr_ue_scheduled_response(&scheduled_response);
phy_procedures_nrUE_RX(UE, pbch_pdcch_processing(UE,
&UE_proc, &UE_proc,
&phy_data); &phy_data);
pdsch_processing(UE,
&UE_proc,
&phy_data);
//---------------------------------------------------------- //----------------------------------------------------------
//---------------------- count errors ---------------------- //---------------------- count errors ----------------------
...@@ -1198,7 +1213,7 @@ int main(int argc, char **argv) ...@@ -1198,7 +1213,7 @@ int main(int argc, char **argv)
for (i = 0; i < TBS; i++) { for (i = 0; i < TBS; i++) {
estimated_output_bit[i] = (UE_harq_process->b[i/8] & (1 << (i & 7))) >> (i & 7); estimated_output_bit[i] = (UE->phy_sim_dlsch_b[i/8] & (1 << (i & 7))) >> (i & 7);
test_input_bit[i] = (gNB_dlsch->harq_process.b[i / 8] & (1 << (i & 7))) >> (i & 7); // Further correct for multiple segments test_input_bit[i] = (gNB_dlsch->harq_process.b[i / 8] & (1 << (i & 7))) >> (i & 7); // Further correct for multiple segments
if (estimated_output_bit[i] != test_input_bit[i]) { if (estimated_output_bit[i] != test_input_bit[i]) {
...@@ -1347,6 +1362,7 @@ int main(int argc, char **argv) ...@@ -1347,6 +1362,7 @@ int main(int argc, char **argv)
free(UE->phy_sim_pdsch_rxdataF_comp); free(UE->phy_sim_pdsch_rxdataF_comp);
free(UE->phy_sim_pdsch_dl_ch_estimates); free(UE->phy_sim_pdsch_dl_ch_estimates);
free(UE->phy_sim_pdsch_dl_ch_estimates_ext); free(UE->phy_sim_pdsch_dl_ch_estimates_ext);
free(UE->phy_sim_dlsch_b);
if (output_fd) if (output_fd)
fclose(output_fd); fclose(output_fd);
......
...@@ -67,6 +67,17 @@ openair0_config_t openair0_cfg[MAX_CARDS]; ...@@ -67,6 +67,17 @@ openair0_config_t openair0_cfg[MAX_CARDS];
uint8_t const nr_rv_round_map[4] = {0, 2, 3, 1}; uint8_t const nr_rv_round_map[4] = {0, 2, 3, 1};
void inc_ref_sched_response(int _)
{
LOG_E(PHY, "fatal\n");
exit(1);
}
void deref_sched_response(int _)
{
LOG_E(PHY, "fatal\n");
exit(1);
}
uint64_t get_softmodem_optmask(void) {return 0;} uint64_t get_softmodem_optmask(void) {return 0;}
static softmodem_params_t softmodem_params; static softmodem_params_t softmodem_params;
softmodem_params_t *get_softmodem_params(void) { softmodem_params_t *get_softmodem_params(void) {
...@@ -96,7 +107,8 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind, ...@@ -96,7 +107,8 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
NR_UE_DLSCH_t *dlsch1, NR_UE_DLSCH_t *dlsch1,
uint16_t n_pdus, uint16_t n_pdus,
UE_nr_rxtx_proc_t *proc, UE_nr_rxtx_proc_t *proc,
void *typeSpecific ) {} void *typeSpecific,
uint8_t *b) {}
int nr_ue_pdcch_procedures(PHY_VARS_NR_UE *ue, int nr_ue_pdcch_procedures(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc, UE_nr_rxtx_proc_t *proc,
...@@ -793,8 +805,8 @@ int main(int argc, char **argv) ...@@ -793,8 +805,8 @@ int main(int argc, char **argv)
fapiPbch_t result; fapiPbch_t result;
ret = nr_rx_pbch(UE, ret = nr_rx_pbch(UE,
&proc, &proc,
estimateSz, dl_ch_estimates, estimateSz,
UE->pbch_vars[0], dl_ch_estimates,
frame_parms, frame_parms,
ssb_index%8, ssb_index%8,
SISO, SISO,
...@@ -813,7 +825,6 @@ int main(int argc, char **argv) ...@@ -813,7 +825,6 @@ int main(int argc, char **argv)
for (i=0;i<3;i++){ for (i=0;i<3;i++){
payload_ret += (result.decoded_output[i] == ((msgDataTx.ssb[ssb_index].ssb_pdu.ssb_pdu_rel15.bchPayload>>(8*i)) & 0xff)); payload_ret += (result.decoded_output[i] == ((msgDataTx.ssb[ssb_index].ssb_pdu.ssb_pdu_rel15.bchPayload>>(8*i)) & 0xff));
} }
//printf("xtra byte gNB: 0x%02x UE: 0x%02x\n",gNB_xtra_byte, UE->pbch_vars[0]->xtra_byte);
//printf("ret %d\n", payload_ret); //printf("ret %d\n", payload_ret);
if (payload_ret!=4) if (payload_ret!=4)
n_errors_payload++; n_errors_payload++;
......
...@@ -86,6 +86,17 @@ softmodem_params_t *get_softmodem_params(void) {return 0;} ...@@ -86,6 +86,17 @@ softmodem_params_t *get_softmodem_params(void) {return 0;}
instance_t DUuniqInstance=0; instance_t DUuniqInstance=0;
instance_t CUuniqInstance=0; instance_t CUuniqInstance=0;
void inc_ref_sched_response(int _)
{
LOG_E(PHY, "fatal\n");
exit(1);
}
void deref_sched_response(int _)
{
LOG_E(PHY, "fatal\n");
exit(1);
}
int nr_derive_key_ng_ran_star(uint16_t pci, uint64_t nr_arfcn_dl, const uint8_t key[32], uint8_t *key_ng_ran_star) int nr_derive_key_ng_ran_star(uint16_t pci, uint64_t nr_arfcn_dl, const uint8_t key[32], uint8_t *key_ng_ran_star)
{ {
return 0; return 0;
......
...@@ -73,6 +73,17 @@ void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) {} ...@@ -73,6 +73,17 @@ void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) {}
NR_IF_Module_t *NR_IF_Module_init(int Mod_id) { return (NULL); } NR_IF_Module_t *NR_IF_Module_init(int Mod_id) { return (NULL); }
nfapi_mode_t nfapi_getmode(void) { return NFAPI_MODE_UNKNOWN; } nfapi_mode_t nfapi_getmode(void) { return NFAPI_MODE_UNKNOWN; }
void inc_ref_sched_response(int _)
{
LOG_E(PHY, "fatal\n");
exit(1);
}
void deref_sched_response(int _)
{
LOG_E(PHY, "fatal\n");
exit(1);
}
nrUE_params_t nrUE_params={0}; nrUE_params_t nrUE_params={0};
nrUE_params_t *get_nrUE_params(void) { nrUE_params_t *get_nrUE_params(void) {
......
...@@ -80,6 +80,17 @@ PHY_VARS_NR_UE *PHY_vars_UE_g[1][1] = { { NULL } }; ...@@ -80,6 +80,17 @@ PHY_VARS_NR_UE *PHY_vars_UE_g[1][1] = { { NULL } };
uint16_t n_rnti = 0x1234; uint16_t n_rnti = 0x1234;
openair0_config_t openair0_cfg[MAX_CARDS]; openair0_config_t openair0_cfg[MAX_CARDS];
void inc_ref_sched_response(int _)
{
LOG_E(PHY, "fatal\n");
exit(1);
}
void deref_sched_response(int _)
{
LOG_E(PHY, "fatal\n");
exit(1);
}
int nr_postDecode_sim(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) { int nr_postDecode_sim(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) {
ldpcDecode_t *rdata = (ldpcDecode_t*) NotifiedFifoData(req); ldpcDecode_t *rdata = (ldpcDecode_t*) NotifiedFifoData(req);
NR_UL_gNB_HARQ_t *ulsch_harq = rdata->ulsch_harq; NR_UL_gNB_HARQ_t *ulsch_harq = rdata->ulsch_harq;
......
...@@ -759,10 +759,10 @@ int main(int argc, char **argv) ...@@ -759,10 +759,10 @@ int main(int argc, char **argv)
NR_gNB_ULSCH_t *ulsch_gNB = &gNB->ulsch[UE_id]; NR_gNB_ULSCH_t *ulsch_gNB = &gNB->ulsch[UE_id];
// nfapi_nr_ul_config_ulsch_pdu *rel15_ul = &ulsch_gNB->harq_process->ulsch_pdu; // nfapi_nr_ul_config_ulsch_pdu *rel15_ul = &ulsch_gNB->harq_process->ulsch_pdu;
nfapi_nr_ul_tti_request_t *UL_tti_req = malloc(sizeof(*UL_tti_req));
NR_Sched_Rsp_t *Sched_INFO = malloc(sizeof(*Sched_INFO)); NR_Sched_Rsp_t *Sched_INFO = malloc(sizeof(*Sched_INFO));
memset((void*)Sched_INFO,0,sizeof(*Sched_INFO)); memset((void*)Sched_INFO,0,sizeof(*Sched_INFO));
Sched_INFO->UL_tti_req=UL_tti_req; nfapi_nr_ul_tti_request_t *UL_tti_req = &Sched_INFO->UL_tti_req;
Sched_INFO->sched_response_id = -1;
nr_phy_data_tx_t phy_data = {0}; nr_phy_data_tx_t phy_data = {0};
......
...@@ -701,6 +701,9 @@ int nr_rrc_mac_config_req_ue(module_id_t module_id, ...@@ -701,6 +701,9 @@ int nr_rrc_mac_config_req_ue(module_id_t module_id,
RA_config_t *ra = &mac->ra; RA_config_t *ra = &mac->ra;
fapi_nr_config_request_t *cfg = &mac->phy_config.config_req; fapi_nr_config_request_t *cfg = &mac->phy_config.config_req;
if (mac->dl_config_request == NULL) // for SIB1 reception
mac->dl_config_request = calloc(NR_MAX_SLOTS_PER_FRAME, sizeof(*mac->dl_config_request));
// TODO do something FAPI-like P5 L1/L2 config interface in config_si, config_mib, etc. // TODO do something FAPI-like P5 L1/L2 config interface in config_si, config_mib, etc.
if(mibP != NULL){ if(mibP != NULL){
...@@ -726,9 +729,21 @@ int nr_rrc_mac_config_req_ue(module_id_t module_id, ...@@ -726,9 +729,21 @@ int nr_rrc_mac_config_req_ue(module_id_t module_id,
} }
} }
LOG_I(NR_MAC, "Initializing ul_config_request. num_slots_ul = %d\n", num_slots_ul); LOG_I(NR_MAC, "Initializing ul_config_request. num_slots_ul = %d\n", num_slots_ul);
mac->ul_config_request = (fapi_nr_ul_config_request_t *)calloc(num_slots_ul, sizeof(fapi_nr_ul_config_request_t)); mac->ul_config_request = calloc(num_slots_ul, sizeof(*mac->ul_config_request));
for (int i=0; i<num_slots_ul; i++) for (int i=0; i<num_slots_ul; i++)
pthread_mutex_init(&(mac->ul_config_request[i].mutex_ul_config), NULL); pthread_mutex_init(&(mac->ul_config_request[i].mutex_ul_config), NULL);
int num_slots_dl = nr_slots_per_frame[mac->mib->subCarrierSpacingCommon];
if (cfg->cell_config.frame_duplex_type == TDD) {
num_slots_dl = mac->scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots;
if (mac->scc_SIB->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols > 0) {
num_slots_dl++;
}
}
LOG_I(NR_MAC, "Initializing dl_config_request. num_slots_dl = %d\n", num_slots_dl);
mac->dl_config_request = realloc(mac->dl_config_request, num_slots_dl*sizeof(*mac->dl_config_request));
memset(mac->dl_config_request, 0, num_slots_dl*sizeof(fapi_nr_dl_config_request_t));
// Setup the SSB to Rach Occasionsif (cell_group_config->spCellConfig) { mapping according to the config // Setup the SSB to Rach Occasionsif (cell_group_config->spCellConfig) { mapping according to the config
build_ssb_to_ro_map(mac);//->scc, mac->phy_config.config_req.cell_config.frame_duplex_type); build_ssb_to_ro_map(mac);//->scc, mac->phy_config.config_req.cell_config.frame_duplex_type);
if (!get_softmodem_params()->emulate_l1) if (!get_softmodem_params()->emulate_l1)
......
...@@ -376,8 +376,9 @@ typedef struct { ...@@ -376,8 +376,9 @@ typedef struct {
uint32_t ssb_index; uint32_t ssb_index;
/// SSB RSRP in dBm /// SSB RSRP in dBm
short ssb_rsrp_dBm; short ssb_rsrp_dBm;
int consecutive_bch_failures;
} NR_PHY_meas_t; } NR_SSB_meas_t;
/*!\brief Top level UE MAC structure */ /*!\brief Top level UE MAC structure */
typedef struct { typedef struct {
...@@ -441,7 +442,7 @@ typedef struct { ...@@ -441,7 +442,7 @@ typedef struct {
int first_ul_tx[NR_MAX_HARQ_PROCESSES]; int first_ul_tx[NR_MAX_HARQ_PROCESSES];
//// FAPI-like interface message //// FAPI-like interface message
fapi_nr_ul_config_request_t *ul_config_request; fapi_nr_ul_config_request_t *ul_config_request;
fapi_nr_dl_config_request_t dl_config_request; fapi_nr_dl_config_request_t *dl_config_request;
/// Interface module instances /// Interface module instances
nr_ue_if_module_t *if_module; nr_ue_if_module_t *if_module;
...@@ -465,9 +466,9 @@ typedef struct { ...@@ -465,9 +466,9 @@ typedef struct {
uint16_t nr_band; uint16_t nr_band;
uint8_t ssb_subcarrier_offset; uint8_t ssb_subcarrier_offset;
NR_PHY_meas_t phy_measurements; NR_SSB_meas_t ssb_measurements;
dci_pdu_rel15_t def_dci_pdu_rel15[8]; dci_pdu_rel15_t def_dci_pdu_rel15[NR_MAX_SLOTS_PER_FRAME][8];
// Defined for abstracted mode // Defined for abstracted mode
nr_downlink_indication_t dl_info; nr_downlink_indication_t dl_info;
......
...@@ -190,6 +190,8 @@ int8_t nr_ue_process_csirs_measurements(module_id_t module_id, frame_t frame, in ...@@ -190,6 +190,8 @@ int8_t nr_ue_process_csirs_measurements(module_id_t module_id, frame_t frame, in
uint32_t get_ssb_frame(uint32_t test); uint32_t get_ssb_frame(uint32_t test);
void nr_ue_aperiodic_srs_scheduling(NR_UE_MAC_INST_t *mac, long resource_trigger, int frame, int slot);
bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac, bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac,
PUCCH_sched_t *pucch, PUCCH_sched_t *pucch,
frame_t frame, frame_t frame,
...@@ -441,9 +443,11 @@ static uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, ...@@ -441,9 +443,11 @@ static uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
uint16_t rnti, uint16_t rnti,
int ss_type, int ss_type,
uint64_t *dci_pdu, uint64_t *dci_pdu,
dci_pdu_rel15_t *dci_pdu_rel15); dci_pdu_rel15_t *dci_pdu_rel15,
int slot);
fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int slot); fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int slot);
fapi_nr_dl_config_request_t *get_dl_config_request(NR_UE_MAC_INST_t *mac, int slot);
void fill_ul_config(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, int slot_tx, uint8_t pdu_type); void fill_ul_config(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, int slot_tx, uint8_t pdu_type);
......
...@@ -55,6 +55,7 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst) { ...@@ -55,6 +55,7 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst) {
nr_ue_mac_inst->sib1_decoded = false; nr_ue_mac_inst->sib1_decoded = false;
nr_ue_mac_inst->phy_config_request_sent = false; nr_ue_mac_inst->phy_config_request_sent = false;
nr_ue_mac_inst->state = UE_NOT_SYNC; nr_ue_mac_inst->state = UE_NOT_SYNC;
memset(&nr_ue_mac_inst->ssb_measurements, 0, sizeof(nr_ue_mac_inst->ssb_measurements));
for (int j=0;j<NB_NR_UE_MAC_INST;j++) { for (int j=0;j<NB_NR_UE_MAC_INST;j++) {
nr_ue_init_mac(j); nr_ue_init_mac(j);
......
...@@ -124,7 +124,7 @@ int16_t get_prach_tx_power(module_id_t mod_id) { ...@@ -124,7 +124,7 @@ int16_t get_prach_tx_power(module_id_t mod_id) {
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
RA_config_t *ra = &mac->ra; RA_config_t *ra = &mac->ra;
int16_t pathloss = compute_nr_SSB_PL(mac, mac->phy_measurements.ssb_rsrp_dBm); int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm);
int16_t ra_preamble_rx_power = (int16_t)(ra->prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER - pathloss + 30); int16_t ra_preamble_rx_power = (int16_t)(ra->prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER - pathloss + 30);
return min(nr_get_Pcmax(mod_id), ra_preamble_rx_power); return min(nr_get_Pcmax(mod_id), ra_preamble_rx_power);
...@@ -674,7 +674,7 @@ void nr_get_prach_resources(module_id_t mod_id, ...@@ -674,7 +674,7 @@ void nr_get_prach_resources(module_id_t mod_id,
} else { } else {
/* TODO: This controls the tx_power of UE and the ramping procedure of RA of UE. Later we /* TODO: This controls the tx_power of UE and the ramping procedure of RA of UE. Later we
can abstract this, perhaps in the proxy. But for the time being lets leave it as below. */ can abstract this, perhaps in the proxy. But for the time being lets leave it as below. */
int16_t dl_pathloss = !get_softmodem_params()->emulate_l1 ? compute_nr_SSB_PL(mac, mac->phy_measurements.ssb_rsrp_dBm) : 0; int16_t dl_pathloss = !get_softmodem_params()->emulate_l1 ? compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm) : 0;
ssb_rach_config(ra, prach_resources, nr_rach_ConfigCommon); ssb_rach_config(ra, prach_resources, nr_rach_ConfigCommon);
ra_preambles_config(prach_resources, mac, dl_pathloss); ra_preambles_config(prach_resources, mac, dl_pathloss);
LOG_D(MAC, "[RAPROC] - Selected RA preamble index %d for contention-based random access procedure... \n", ra->ra_PreambleIndex); LOG_D(MAC, "[RAPROC] - Selected RA preamble index %d for contention-based random access procedure... \n", ra->ra_PreambleIndex);
......
...@@ -172,7 +172,7 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t ...@@ -172,7 +172,7 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
rel15->dci_length_options[i] = nr_dci_size(current_DL_BWP, rel15->dci_length_options[i] = nr_dci_size(current_DL_BWP,
current_UL_BWP, current_UL_BWP,
mac->cg, mac->cg,
&mac->def_dci_pdu_rel15[dci_format], &mac->def_dci_pdu_rel15[dl_config->slot][dci_format],
dci_format, dci_format,
NR_RNTI_TC, NR_RNTI_TC,
coreset, coreset,
......
This diff is collapsed.
...@@ -56,10 +56,13 @@ ...@@ -56,10 +56,13 @@
const uint8_t nr_rv_round_map[4] = { 0, 2, 3, 1 }; const uint8_t nr_rv_round_map[4] = { 0, 2, 3, 1 };
uint16_t nr_pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 }; uint16_t nr_pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 };
void clear_nr_nfapi_information(gNB_MAC_INST * gNB, void clear_nr_nfapi_information(gNB_MAC_INST *gNB,
int CC_idP, int CC_idP,
frame_t frameP, frame_t frameP,
sub_frame_t slotP) sub_frame_t slotP,
nfapi_nr_dl_tti_request_t *DL_req,
nfapi_nr_tx_data_request_t *TX_req,
nfapi_nr_ul_dci_request_t *UL_dci_req)
{ {
NR_ServingCellConfigCommon_t *scc = gNB->common_channels->ServingCellConfigCommon; NR_ServingCellConfigCommon_t *scc = gNB->common_channels->ServingCellConfigCommon;
...@@ -67,10 +70,7 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB, ...@@ -67,10 +70,7 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
UL_tti_req_ahead_initialization(gNB, scc, num_slots, CC_idP, frameP, slotP, *scc->ssbSubcarrierSpacing); UL_tti_req_ahead_initialization(gNB, scc, num_slots, CC_idP, frameP, slotP, *scc->ssbSubcarrierSpacing);
nfapi_nr_dl_tti_request_t *DL_req = &gNB->DL_req[0];
nfapi_nr_dl_tti_pdcch_pdu_rel15_t **pdcch = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t **)gNB->pdcch_pdu_idx[CC_idP]; nfapi_nr_dl_tti_pdcch_pdu_rel15_t **pdcch = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t **)gNB->pdcch_pdu_idx[CC_idP];
nfapi_nr_ul_dci_request_t *UL_dci_req = &gNB->UL_dci_req[0];
nfapi_nr_tx_data_request_t *TX_req = &gNB->TX_req[0];
gNB->pdu_index[CC_idP] = 0; gNB->pdu_index[CC_idP] = 0;
...@@ -96,23 +96,53 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB, ...@@ -96,23 +96,53 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
future_ul_tti_req->n_ulcch = 0; future_ul_tti_req->n_ulcch = 0;
future_ul_tti_req->n_group = 0; future_ul_tti_req->n_group = 0;
/* UL_tti_req is a simple pointer into the current UL_tti_req_ahead, i.e.,
* it walks over UL_tti_req_ahead in a circular fashion */
const int current_index = ul_buffer_index(frameP, slotP, *scc->ssbSubcarrierSpacing, gNB->UL_tti_req_ahead_size);
gNB->UL_tti_req[CC_idP] = &gNB->UL_tti_req_ahead[CC_idP][current_index];
TX_req[CC_idP].Number_of_PDUs = 0; TX_req[CC_idP].Number_of_PDUs = 0;
} }
bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot) { bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot) {
return (bitmap >> (slot % 64)) & 0x01; return (bitmap >> (slot % 64)) & 0x01;
} }
void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, /* the structure nfapi_nr_ul_tti_request_t is very big, let's copy only what is necessary */
frame_t frame, static void copy_ul_tti_req(nfapi_nr_ul_tti_request_t *to, nfapi_nr_ul_tti_request_t *from)
sub_frame_t slot)
{ {
int i;
to->header = from->header;
to->SFN = from->SFN;
to->Slot = from->Slot;
to->n_pdus = from->n_pdus;
to->rach_present = from->rach_present;
to->n_ulsch = from->n_ulsch;
to->n_ulcch = from->n_ulcch;
to->n_group = from->n_group;
for (i = 0; i < from->n_pdus; i++) {
to->pdus_list[i].pdu_type = from->pdus_list[i].pdu_type;
to->pdus_list[i].pdu_size = from->pdus_list[i].pdu_size;
switch (from->pdus_list[i].pdu_type) {
case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE:
to->pdus_list[i].prach_pdu = from->pdus_list[i].prach_pdu;
break;
case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE:
to->pdus_list[i].pusch_pdu = from->pdus_list[i].pusch_pdu;
break;
case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE:
to->pdus_list[i].pucch_pdu = from->pdus_list[i].pucch_pdu;
break;
case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE:
to->pdus_list[i].srs_pdu = from->pdus_list[i].srs_pdu;
break;
}
}
for (i = 0; i < from->n_group; i++)
to->groups_list[i] = from->groups_list[i];
}
void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, sub_frame_t slot, NR_Sched_Rsp_t *sched_info)
{
protocol_ctxt_t ctxt = {0}; protocol_ctxt_t ctxt = {0};
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frame, slot,module_idP); PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frame, slot,module_idP);
...@@ -157,8 +187,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, ...@@ -157,8 +187,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
uint16_t *vrb_map_UL = cc[CC_id].vrb_map_UL; uint16_t *vrb_map_UL = cc[CC_id].vrb_map_UL;
memcpy(&vrb_map_UL[prev_slot % size * MAX_BWP_SIZE], &gNB->ulprbbl, sizeof(uint16_t) * MAX_BWP_SIZE); memcpy(&vrb_map_UL[prev_slot % size * MAX_BWP_SIZE], &gNB->ulprbbl, sizeof(uint16_t) * MAX_BWP_SIZE);
clear_nr_nfapi_information(gNB, CC_id, frame, slot); clear_nr_nfapi_information(gNB, CC_id, frame, slot, &sched_info->DL_req, &sched_info->TX_req, &sched_info->UL_dci_req);
} }
if ((slot == 0) && (frame & 127) == 0) { if ((slot == 0) && (frame & 127) == 0) {
...@@ -172,12 +201,11 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, ...@@ -172,12 +201,11 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
schedule_nr_bwp_switch(module_idP, frame, slot); schedule_nr_bwp_switch(module_idP, frame, slot);
// This schedules MIB // This schedules MIB
schedule_nr_mib(module_idP, frame, slot); schedule_nr_mib(module_idP, frame, slot, &sched_info->DL_req);
// This schedules SIB1 // This schedules SIB1
if (get_softmodem_params()->sa == 1) if (get_softmodem_params()->sa == 1)
schedule_nr_sib1(module_idP, frame, slot); schedule_nr_sib1(module_idP, frame, slot, &sched_info->DL_req, &sched_info->TX_req);
// This schedule PRACH if we are not in phy_test mode // This schedule PRACH if we are not in phy_test mode
if (get_softmodem_params()->phy_test == 0) { if (get_softmodem_params()->phy_test == 0) {
...@@ -194,7 +222,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, ...@@ -194,7 +222,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
} }
// Schedule CSI-RS transmission // Schedule CSI-RS transmission
nr_csirs_scheduling(module_idP, frame, slot, nr_slots_per_frame[*scc->ssbSubcarrierSpacing]); nr_csirs_scheduling(module_idP, frame, slot, nr_slots_per_frame[*scc->ssbSubcarrierSpacing], &sched_info->DL_req);
// Schedule CSI measurement reporting // Schedule CSI measurement reporting
nr_csi_meas_reporting(module_idP, frame, slot); nr_csi_meas_reporting(module_idP, frame, slot);
...@@ -204,22 +232,29 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, ...@@ -204,22 +232,29 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
// This schedule RA procedure if not in phy_test mode // This schedule RA procedure if not in phy_test mode
// Otherwise consider 5G already connected // Otherwise consider 5G already connected
if (get_softmodem_params()->phy_test == 0) { if (get_softmodem_params()->phy_test == 0) {
nr_schedule_RA(module_idP, frame, slot); nr_schedule_RA(module_idP, frame, slot, &sched_info->UL_dci_req, &sched_info->DL_req, &sched_info->TX_req);
} }
// This schedules the DCI for Uplink and subsequently PUSCH // This schedules the DCI for Uplink and subsequently PUSCH
nr_schedule_ulsch(module_idP, frame, slot); nr_schedule_ulsch(module_idP, frame, slot, &sched_info->UL_dci_req);
// This schedules the DCI for Downlink and PDSCH // This schedules the DCI for Downlink and PDSCH
start_meas(&gNB->schedule_dlsch); start_meas(&gNB->schedule_dlsch);
nr_schedule_ue_spec(module_idP, frame, slot); nr_schedule_ue_spec(module_idP, frame, slot, &sched_info->DL_req, &sched_info->TX_req);
stop_meas(&gNB->schedule_dlsch); stop_meas(&gNB->schedule_dlsch);
nr_sr_reporting(gNB, frame, slot); nr_sr_reporting(gNB, frame, slot);
nr_schedule_pucch(gNB, frame, slot); nr_schedule_pucch(gNB, frame, slot);
/* TODO: we copy from gNB->UL_tti_req_ahead[0][current_index], ie. CC_id == 0,
* is more than 1 CC supported?
*/
AssertFatal(MAX_NUM_CCs == 1, "only 1 CC supported\n");
const int current_index = ul_buffer_index(frame, slot, *scc->ssbSubcarrierSpacing, gNB->UL_tti_req_ahead_size);
copy_ul_tti_req(&sched_info->UL_tti_req, &gNB->UL_tti_req_ahead[0][current_index]);
stop_meas(&gNB->eNB_scheduler); stop_meas(&gNB->eNB_scheduler);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_OUT); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_OUT);
} }
...@@ -662,8 +662,13 @@ void nr_initiate_ra_proc(module_id_t module_idP, ...@@ -662,8 +662,13 @@ void nr_initiate_ra_proc(module_id_t module_idP,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0);
} }
void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) { void nr_schedule_RA(module_id_t module_idP,
frame_t frameP,
sub_frame_t slotP,
nfapi_nr_ul_dci_request_t *ul_dci_req,
nfapi_nr_dl_tti_request_t *DL_req,
nfapi_nr_tx_data_request_t *TX_req)
{
gNB_MAC_INST *mac = RC.nrmac[module_idP]; gNB_MAC_INST *mac = RC.nrmac[module_idP];
start_meas(&mac->schedule_ra); start_meas(&mac->schedule_ra);
...@@ -674,15 +679,15 @@ void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) { ...@@ -674,15 +679,15 @@ void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) {
LOG_D(NR_MAC, "RA[state:%d]\n", ra->state); LOG_D(NR_MAC, "RA[state:%d]\n", ra->state);
switch (ra->state) { switch (ra->state) {
case Msg2: case Msg2:
nr_generate_Msg2(module_idP, CC_id, frameP, slotP, ra); nr_generate_Msg2(module_idP, CC_id, frameP, slotP, ra, DL_req, TX_req);
break; break;
case Msg3_retransmission: case Msg3_retransmission:
nr_generate_Msg3_retransmission(module_idP, CC_id, frameP, slotP, ra); nr_generate_Msg3_retransmission(module_idP, CC_id, frameP, slotP, ra, ul_dci_req);
break; break;
case Msg3_dcch_dtch: case Msg3_dcch_dtch:
nr_generate_Msg3_dcch_dtch_response(module_idP, CC_id, frameP, slotP, ra); nr_generate_Msg3_dcch_dtch_response(module_idP, CC_id, frameP, slotP, ra, DL_req, TX_req);
case Msg4: case Msg4:
nr_generate_Msg4(module_idP, CC_id, frameP, slotP, ra); nr_generate_Msg4(module_idP, CC_id, frameP, slotP, ra, DL_req, TX_req);
break; break;
case WAIT_Msg4_ACK: case WAIT_Msg4_ACK:
nr_check_Msg4_Ack(module_idP, CC_id, frameP, slotP, ra); nr_check_Msg4_Ack(module_idP, CC_id, frameP, slotP, ra);
...@@ -695,9 +700,13 @@ void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) { ...@@ -695,9 +700,13 @@ void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) {
stop_meas(&mac->schedule_ra); stop_meas(&mac->schedule_ra);
} }
void nr_generate_Msg3_retransmission(module_id_t module_idP,
void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t frame, sub_frame_t slot, NR_RA_t *ra) { int CC_id,
frame_t frame,
sub_frame_t slot,
NR_RA_t *ra,
nfapi_nr_ul_dci_request_t *ul_dci_req)
{
gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
...@@ -784,8 +793,6 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t ...@@ -784,8 +793,6 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t
NR_ControlResourceSet_t *coreset = ra->coreset; NR_ControlResourceSet_t *coreset = ra->coreset;
AssertFatal(coreset!=NULL,"Coreset cannot be null for RA-Msg3 retransmission\n"); AssertFatal(coreset!=NULL,"Coreset cannot be null for RA-Msg3 retransmission\n");
nfapi_nr_ul_dci_request_t *ul_dci_req = &nr_mac->UL_dci_req[CC_id];
const int coresetid = coreset->controlResourceSetId; const int coresetid = coreset->controlResourceSetId;
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = nr_mac->pdcch_pdu_idx[CC_id][coresetid]; nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = nr_mac->pdcch_pdu_idx[CC_id][coresetid];
if (!pdcch_pdu_rel15) { if (!pdcch_pdu_rel15) {
...@@ -1148,8 +1155,14 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t ...@@ -1148,8 +1155,14 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
nr_fill_rar(module_idP, ra, RAR_pdu, pusch_pdu); nr_fill_rar(module_idP, ra, RAR_pdu, pusch_pdu);
} }
void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra) { void nr_generate_Msg2(module_id_t module_idP,
int CC_id,
frame_t frameP,
sub_frame_t slotP,
NR_RA_t *ra,
nfapi_nr_dl_tti_request_t *DL_req,
nfapi_nr_tx_data_request_t *TX_req)
{
gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
NR_UE_DL_BWP_t *dl_bwp = &ra->DL_BWP; NR_UE_DL_BWP_t *dl_bwp = &ra->DL_BWP;
...@@ -1198,7 +1211,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra ...@@ -1198,7 +1211,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
} }
// Checking if the DCI allocation is feasible in current subframe // Checking if the DCI allocation is feasible in current subframe
nfapi_nr_dl_tti_request_body_t *dl_req = &nr_mac->DL_req[CC_id].dl_tti_request_body; nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body;
if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) { if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) {
LOG_I(NR_MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, ra->RA_rnti); LOG_I(NR_MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, ra->RA_rnti);
return; return;
...@@ -1369,7 +1382,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra ...@@ -1369,7 +1382,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
nr_mac->cset0_bwp_size); nr_mac->cset0_bwp_size);
// DL TX request // DL TX request
nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs]; nfapi_nr_pdu_t *tx_req = &TX_req->pdu_list[TX_req->Number_of_PDUs];
// Program UL processing for Msg3 // Program UL processing for Msg3
nr_get_Msg3alloc(module_idP, CC_id, scc, slotP, frameP, ra, nr_mac->tdd_beam_association); nr_get_Msg3alloc(module_idP, CC_id, scc, slotP, frameP, ra, nr_mac->tdd_beam_association);
...@@ -1395,9 +1408,9 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra ...@@ -1395,9 +1408,9 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
tx_req->PDU_index = pduindex; tx_req->PDU_index = pduindex;
tx_req->num_TLV = 1; tx_req->num_TLV = 1;
tx_req->TLVs[0].length = tx_req->PDU_length + 2; tx_req->TLVs[0].length = tx_req->PDU_length + 2;
nr_mac->TX_req[CC_id].SFN = frameP; TX_req->SFN = frameP;
nr_mac->TX_req[CC_id].Number_of_PDUs++; TX_req->Number_of_PDUs++;
nr_mac->TX_req[CC_id].Slot = slotP; TX_req->Slot = slotP;
// Mark the corresponding symbols RBs as used // Mark the corresponding symbols RBs as used
fill_pdcch_vrb_map(nr_mac, fill_pdcch_vrb_map(nr_mac,
...@@ -1600,7 +1613,13 @@ void prepare_dl_pdus(gNB_MAC_INST *nr_mac, ...@@ -1600,7 +1613,13 @@ void prepare_dl_pdus(gNB_MAC_INST *nr_mac,
LOG_D(NR_MAC,"numDlDci: %i\n", pdcch_pdu_rel15->numDlDci); LOG_D(NR_MAC,"numDlDci: %i\n", pdcch_pdu_rel15->numDlDci);
} }
void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra) void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP,
int CC_id,
frame_t frameP,
sub_frame_t slotP,
NR_RA_t *ra,
nfapi_nr_dl_tti_request_t *DL_req,
nfapi_nr_tx_data_request_t *TX_req)
{ {
gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
...@@ -1654,7 +1673,7 @@ void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP, int CC_id, fram ...@@ -1654,7 +1673,7 @@ void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP, int CC_id, fram
} }
// Checking if the DCI allocation is feasible in current subframe // Checking if the DCI allocation is feasible in current subframe
nfapi_nr_dl_tti_request_body_t *dl_req = &nr_mac->DL_req[CC_id].dl_tti_request_body; nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body;
if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) { if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) {
LOG_I(NR_MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, rnti); LOG_I(NR_MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, rnti);
return; return;
...@@ -1734,15 +1753,15 @@ void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP, int CC_id, fram ...@@ -1734,15 +1753,15 @@ void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP, int CC_id, fram
0, time_domain_assignment, CC_id, rnti, 0, mcsIndex, tb_scaling, pduindex, rbStart, rbSize); 0, time_domain_assignment, CC_id, rnti, 0, mcsIndex, tb_scaling, pduindex, rbStart, rbSize);
// DL TX request // DL TX request
nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs]; nfapi_nr_pdu_t *tx_req = &TX_req->pdu_list[TX_req->Number_of_PDUs];
memcpy(tx_req->TLVs[0].value.direct, buf, sizeof(uint8_t) * tb_size); memcpy(tx_req->TLVs[0].value.direct, buf, sizeof(uint8_t) * tb_size);
tx_req->PDU_length = tb_size; tx_req->PDU_length = tb_size;
tx_req->PDU_index = pduindex; tx_req->PDU_index = pduindex;
tx_req->num_TLV = 1; tx_req->num_TLV = 1;
tx_req->TLVs[0].length = tb_size + 2; tx_req->TLVs[0].length = tb_size + 2;
nr_mac->TX_req[CC_id].SFN = frameP; TX_req->SFN = frameP;
nr_mac->TX_req[CC_id].Number_of_PDUs++; TX_req->Number_of_PDUs++;
nr_mac->TX_req[CC_id].Slot = slotP; TX_req->Slot = slotP;
// Mark the corresponding symbols and RBs as used // Mark the corresponding symbols and RBs as used
fill_pdcch_vrb_map(nr_mac, fill_pdcch_vrb_map(nr_mac,
...@@ -1780,7 +1799,13 @@ void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP, int CC_id, fram ...@@ -1780,7 +1799,13 @@ void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP, int CC_id, fram
sched_ctrl->ul_failure = 0; sched_ctrl->ul_failure = 0;
} }
void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra) void nr_generate_Msg4(module_id_t module_idP,
int CC_id,
frame_t frameP,
sub_frame_t slotP,
NR_RA_t *ra,
nfapi_nr_dl_tti_request_t *DL_req,
nfapi_nr_tx_data_request_t *TX_req)
{ {
gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
...@@ -1854,7 +1879,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra ...@@ -1854,7 +1879,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
} }
// Checking if the DCI allocation is feasible in current subframe // Checking if the DCI allocation is feasible in current subframe
nfapi_nr_dl_tti_request_body_t *dl_req = &nr_mac->DL_req[CC_id].dl_tti_request_body; nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body;
if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) { if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) {
LOG_I(NR_MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, ra->rnti); LOG_I(NR_MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, ra->rnti);
return; return;
...@@ -2006,15 +2031,15 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra ...@@ -2006,15 +2031,15 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
T_INT(frameP), T_INT(slotP), T_INT(current_harq_pid), T_BUFFER(harq->transportBlock, harq->tb_size)); T_INT(frameP), T_INT(slotP), T_INT(current_harq_pid), T_BUFFER(harq->transportBlock, harq->tb_size));
// DL TX request // DL TX request
nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs]; nfapi_nr_pdu_t *tx_req = &TX_req->pdu_list[TX_req->Number_of_PDUs];
memcpy(tx_req->TLVs[0].value.direct, harq->transportBlock, sizeof(uint8_t) * harq->tb_size); memcpy(tx_req->TLVs[0].value.direct, harq->transportBlock, sizeof(uint8_t) * harq->tb_size);
tx_req->PDU_length = harq->tb_size; tx_req->PDU_length = harq->tb_size;
tx_req->PDU_index = pduindex; tx_req->PDU_index = pduindex;
tx_req->num_TLV = 1; tx_req->num_TLV = 1;
tx_req->TLVs[0].length = harq->tb_size + 2; tx_req->TLVs[0].length = harq->tb_size + 2;
nr_mac->TX_req[CC_id].SFN = frameP; TX_req->SFN = frameP;
nr_mac->TX_req[CC_id].Number_of_PDUs++; TX_req->Number_of_PDUs++;
nr_mac->TX_req[CC_id].Slot = slotP; TX_req->Slot = slotP;
// Mark the corresponding symbols and RBs as used // Mark the corresponding symbols and RBs as used
fill_pdcch_vrb_map(nr_mac, fill_pdcch_vrb_map(nr_mac,
......
...@@ -89,10 +89,10 @@ void schedule_ssb(frame_t frame, sub_frame_t slot, ...@@ -89,10 +89,10 @@ void schedule_ssb(frame_t frame, sub_frame_t slot,
} }
void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) { void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, nfapi_nr_dl_tti_request_t *DL_req)
{
gNB_MAC_INST *gNB = RC.nrmac[module_idP]; gNB_MAC_INST *gNB = RC.nrmac[module_idP];
NR_COMMON_channels_t *cc; NR_COMMON_channels_t *cc;
nfapi_nr_dl_tti_request_t *dl_tti_request;
nfapi_nr_dl_tti_request_body_t *dl_req; nfapi_nr_dl_tti_request_body_t *dl_req;
NR_MIB_t *mib = RC.nrrrc[module_idP]->carrier.mib.message.choice.mib; NR_MIB_t *mib = RC.nrrrc[module_idP]->carrier.mib.message.choice.mib;
uint8_t num_tdd_period,num_ssb; uint8_t num_tdd_period,num_ssb;
...@@ -103,8 +103,7 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) ...@@ -103,8 +103,7 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
cc = &gNB->common_channels[CC_id]; cc = &gNB->common_channels[CC_id];
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
const int slots_per_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; const int slots_per_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
dl_tti_request = &gNB->DL_req[CC_id]; dl_req = &DL_req->dl_tti_request_body;
dl_req = &dl_tti_request->dl_tti_request_body;
// get MIB every 8 frames // get MIB every 8 frames
if(((slotP == 0) && (frameP & 7) == 0) || if(((slotP == 0) && (frameP & 7) == 0) ||
...@@ -255,7 +254,6 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) ...@@ -255,7 +254,6 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
} }
} }
void schedule_nr_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { void schedule_nr_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) {
//---------------------------------------- //----------------------------------------
} }
...@@ -520,8 +518,12 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, ...@@ -520,8 +518,12 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
} }
void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) { void schedule_nr_sib1(module_id_t module_idP,
frame_t frameP,
sub_frame_t slotP,
nfapi_nr_dl_tti_request_t *DL_req,
nfapi_nr_tx_data_request_t *TX_req)
{
// TODO: Get these values from RRC // TODO: Get these values from RRC
const int CC_id = 0; const int CC_id = 0;
uint8_t candidate_idx = 0; uint8_t candidate_idx = 0;
...@@ -586,12 +588,12 @@ void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) ...@@ -586,12 +588,12 @@ void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
candidate_idx, candidate_idx,
sib1_sdu_length); sib1_sdu_length);
nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body; nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body;
int pdu_index = gNB_mac->pdu_index[0]++; int pdu_index = gNB_mac->pdu_index[0]++;
nr_fill_nfapi_dl_sib1_pdu(module_idP, dl_req, pdu_index, type0_PDCCH_CSS_config, TBS, tda_info.startSymbolIndex, tda_info.nrOfSymbols); nr_fill_nfapi_dl_sib1_pdu(module_idP, dl_req, pdu_index, type0_PDCCH_CSS_config, TBS, tda_info.startSymbolIndex, tda_info.nrOfSymbols);
const int ntx_req = gNB_mac->TX_req[CC_id].Number_of_PDUs; const int ntx_req = TX_req->Number_of_PDUs;
nfapi_nr_pdu_t *tx_req = &gNB_mac->TX_req[CC_id].pdu_list[ntx_req]; nfapi_nr_pdu_t *tx_req = &TX_req->pdu_list[ntx_req];
// Data to be transmitted // Data to be transmitted
memcpy(tx_req->TLVs[0].value.direct, sib1_payload, TBS); memcpy(tx_req->TLVs[0].value.direct, sib1_payload, TBS);
...@@ -600,9 +602,9 @@ void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) ...@@ -600,9 +602,9 @@ void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
tx_req->PDU_index = pdu_index; tx_req->PDU_index = pdu_index;
tx_req->num_TLV = 1; tx_req->num_TLV = 1;
tx_req->TLVs[0].length = TBS + 2; tx_req->TLVs[0].length = TBS + 2;
gNB_mac->TX_req[CC_id].Number_of_PDUs++; TX_req->Number_of_PDUs++;
gNB_mac->TX_req[CC_id].SFN = frameP; TX_req->SFN = frameP;
gNB_mac->TX_req[CC_id].Slot = slotP; TX_req->Slot = slotP;
type0_PDCCH_CSS_config->active = false; type0_PDCCH_CSS_config->active = false;
} }
......
...@@ -873,8 +873,10 @@ nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(int CC_id) { ...@@ -873,8 +873,10 @@ nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(int CC_id) {
void nr_schedule_ue_spec(module_id_t module_id, void nr_schedule_ue_spec(module_id_t module_id,
frame_t frame, frame_t frame,
sub_frame_t slot) { sub_frame_t slot,
nfapi_nr_dl_tti_request_t *DL_req,
nfapi_nr_tx_data_request_t *TX_req)
{
gNB_MAC_INST *gNB_mac = RC.nrmac[module_id]; gNB_MAC_INST *gNB_mac = RC.nrmac[module_id];
if (!is_xlsch_in_slot(gNB_mac->dlsch_slot_bitmap[slot / 64], slot)) if (!is_xlsch_in_slot(gNB_mac->dlsch_slot_bitmap[slot / 64], slot))
...@@ -885,7 +887,7 @@ void nr_schedule_ue_spec(module_id_t module_id, ...@@ -885,7 +887,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
const int CC_id = 0; const int CC_id = 0;
NR_ServingCellConfigCommon_t *scc = gNB_mac->common_channels[CC_id].ServingCellConfigCommon; NR_ServingCellConfigCommon_t *scc = gNB_mac->common_channels[CC_id].ServingCellConfigCommon;
NR_UEs_t *UE_info = &gNB_mac->UE_info; NR_UEs_t *UE_info = &gNB_mac->UE_info;
nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body; nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body;
UE_iterator(UE_info->list, UE) { UE_iterator(UE_info->list, UE) {
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
...@@ -1326,16 +1328,16 @@ void nr_schedule_ue_spec(module_id_t module_id, ...@@ -1326,16 +1328,16 @@ void nr_schedule_ue_spec(module_id_t module_id,
T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_BUFFER(harq->transportBlock, TBS)); T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_BUFFER(harq->transportBlock, TBS));
} }
const int ntx_req = gNB_mac->TX_req[CC_id].Number_of_PDUs; const int ntx_req = TX_req->Number_of_PDUs;
nfapi_nr_pdu_t *tx_req = &gNB_mac->TX_req[CC_id].pdu_list[ntx_req]; nfapi_nr_pdu_t *tx_req = &TX_req->pdu_list[ntx_req];
tx_req->PDU_length = TBS; tx_req->PDU_length = TBS;
tx_req->PDU_index = pduindex; tx_req->PDU_index = pduindex;
tx_req->num_TLV = 1; tx_req->num_TLV = 1;
tx_req->TLVs[0].length = TBS + 2; tx_req->TLVs[0].length = TBS + 2;
memcpy(tx_req->TLVs[0].value.direct, harq->transportBlock, TBS); memcpy(tx_req->TLVs[0].value.direct, harq->transportBlock, TBS);
gNB_mac->TX_req[CC_id].Number_of_PDUs++; TX_req->Number_of_PDUs++;
gNB_mac->TX_req[CC_id].SFN = frame; TX_req->SFN = frame;
gNB_mac->TX_req[CC_id].Slot = slot; TX_req->Slot = slot;
/* mark UE as scheduled */ /* mark UE as scheduled */
sched_pdsch->rbSize = 0; sched_pdsch->rbSize = 0;
} }
......
...@@ -2538,11 +2538,8 @@ int get_pdsch_to_harq_feedback(NR_PUCCH_Config_t *pucch_Config, ...@@ -2538,11 +2538,8 @@ int get_pdsch_to_harq_feedback(NR_PUCCH_Config_t *pucch_Config,
} }
} }
void nr_csirs_scheduling(int Mod_idP, void nr_csirs_scheduling(int Mod_idP, frame_t frame, sub_frame_t slot, int n_slots_frame, nfapi_nr_dl_tti_request_t *DL_req)
frame_t frame, {
sub_frame_t slot,
int n_slots_frame){
int CC_id = 0; int CC_id = 0;
NR_UEs_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; NR_UEs_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
gNB_MAC_INST *gNB_mac = RC.nrmac[Mod_idP]; gNB_MAC_INST *gNB_mac = RC.nrmac[Mod_idP];
...@@ -2581,7 +2578,7 @@ void nr_csirs_scheduling(int Mod_idP, ...@@ -2581,7 +2578,7 @@ void nr_csirs_scheduling(int Mod_idP,
NR_NZP_CSI_RS_Resource_t *nzpcsi; NR_NZP_CSI_RS_Resource_t *nzpcsi;
int period, offset; int period, offset;
nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body; nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body;
for (int id = 0; id < csi_measconfig->nzp_CSI_RS_ResourceToAddModList->list.count; id++){ for (int id = 0; id < csi_measconfig->nzp_CSI_RS_ResourceToAddModList->list.count; id++){
nzpcsi = csi_measconfig->nzp_CSI_RS_ResourceToAddModList->list.array[id]; nzpcsi = csi_measconfig->nzp_CSI_RS_ResourceToAddModList->list.array[id];
......
...@@ -1997,7 +1997,7 @@ nr_pp_impl_ul nr_init_fr1_ulsch_preprocessor(int CC_id) ...@@ -1997,7 +1997,7 @@ nr_pp_impl_ul nr_init_fr1_ulsch_preprocessor(int CC_id)
return nr_fr1_ulsch_preprocessor; return nr_fr1_ulsch_preprocessor;
} }
void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot, nfapi_nr_ul_dci_request_t *ul_dci_req)
{ {
gNB_MAC_INST *nr_mac = RC.nrmac[module_id]; gNB_MAC_INST *nr_mac = RC.nrmac[module_id];
/* Uplink data ONLY can be scheduled when the current slot is downlink slot, /* Uplink data ONLY can be scheduled when the current slot is downlink slot,
...@@ -2010,8 +2010,6 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) ...@@ -2010,8 +2010,6 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
if (!do_sched) if (!do_sched)
return; return;
const int CC_id = 0;
nfapi_nr_ul_dci_request_t *ul_dci_req = &nr_mac->UL_dci_req[CC_id];
ul_dci_req->SFN = frame; ul_dci_req->SFN = frame;
ul_dci_req->Slot = slot; ul_dci_req->Slot = slot;
/* a PDCCH PDU groups DCIs per BWP and CORESET. Save a pointer to each /* a PDCCH PDU groups DCIs per BWP and CORESET. Save a pointer to each
......
...@@ -60,17 +60,19 @@ bool nr_mac_prepare_ra_nsa_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupCo ...@@ -60,17 +60,19 @@ bool nr_mac_prepare_ra_nsa_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupCo
bool nr_mac_update_cellgroup(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup); bool nr_mac_update_cellgroup(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup);
bool nr_mac_update_RA(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup); bool nr_mac_update_RA(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup);
void clear_nr_nfapi_information(gNB_MAC_INST * gNB, void clear_nr_nfapi_information(gNB_MAC_INST *gNB,
int CC_idP, int CC_idP,
frame_t frameP, frame_t frameP,
sub_frame_t subframeP); sub_frame_t slotP,
nfapi_nr_dl_tti_request_t *DL_req,
nfapi_nr_tx_data_request_t *TX_req,
nfapi_nr_ul_dci_request_t *UL_dci_req);
void nr_mac_update_timers(module_id_t module_id, void nr_mac_update_timers(module_id_t module_id,
frame_t frame, frame_t frame,
sub_frame_t slot); sub_frame_t slot);
void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame_rxP, sub_frame_t slot_rxP, NR_Sched_Rsp_t *sched_info);
frame_t frame_rxP, sub_frame_t slot_rxP);
void schedule_nr_bwp_switch(module_id_t module_id, void schedule_nr_bwp_switch(module_id_t module_id,
frame_t frame, frame_t frame,
...@@ -81,7 +83,9 @@ void schedule_nr_bwp_switch(module_id_t module_id, ...@@ -81,7 +83,9 @@ void schedule_nr_bwp_switch(module_id_t module_id,
* messages, statistics, HARQ handling, CEs, ... */ * messages, statistics, HARQ handling, CEs, ... */
void nr_schedule_ue_spec(module_id_t module_id, void nr_schedule_ue_spec(module_id_t module_id,
frame_t frame, frame_t frame,
sub_frame_t slot); sub_frame_t slot,
nfapi_nr_dl_tti_request_t *DL_req,
nfapi_nr_tx_data_request_t *TX_req);
uint32_t schedule_control_sib1(module_id_t module_id, uint32_t schedule_control_sib1(module_id_t module_id,
int CC_id, int CC_id,
...@@ -95,21 +99,30 @@ uint32_t schedule_control_sib1(module_id_t module_id, ...@@ -95,21 +99,30 @@ uint32_t schedule_control_sib1(module_id_t module_id,
/* \brief default FR1 DL preprocessor init routine, returns preprocessor to call */ /* \brief default FR1 DL preprocessor init routine, returns preprocessor to call */
nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(int CC_id); nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(int CC_id);
void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP); void schedule_nr_sib1(module_id_t module_idP,
frame_t frameP,
sub_frame_t slotP,
nfapi_nr_dl_tti_request_t *DL_req,
nfapi_nr_tx_data_request_t *TX_req);
void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP); void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, nfapi_nr_dl_tti_request_t *DL_req);
/* \brief main UL scheduler function. Calls a preprocessor to decide on /* \brief main UL scheduler function. Calls a preprocessor to decide on
* resource allocation, then "post-processes" resource allocation (nFAPI * resource allocation, then "post-processes" resource allocation (nFAPI
* messages, statistics, HARQ handling, ... */ * messages, statistics, HARQ handling, ... */
void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot); void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot, nfapi_nr_ul_dci_request_t *ul_dci_req);
/* \brief default FR1 UL preprocessor init routine, returns preprocessor to call */ /* \brief default FR1 UL preprocessor init routine, returns preprocessor to call */
nr_pp_impl_ul nr_init_fr1_ulsch_preprocessor(int CC_id); nr_pp_impl_ul nr_init_fr1_ulsch_preprocessor(int CC_id);
/////// Random Access MAC-PHY interface functions and primitives /////// /////// Random Access MAC-PHY interface functions and primitives ///////
void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP); void nr_schedule_RA(module_id_t module_idP,
frame_t frameP,
sub_frame_t slotP,
nfapi_nr_ul_dci_request_t *ul_dci_req,
nfapi_nr_dl_tti_request_t *DL_req,
nfapi_nr_tx_data_request_t *TX_req);
/* \brief Function to indicate a received preamble on PRACH. It initiates the RA procedure. /* \brief Function to indicate a received preamble on PRACH. It initiates the RA procedure.
@param module_idP Instance ID of gNB @param module_idP Instance ID of gNB
...@@ -134,7 +147,12 @@ void nr_get_Msg3alloc(module_id_t module_id, ...@@ -134,7 +147,12 @@ void nr_get_Msg3alloc(module_id_t module_id,
NR_RA_t *ra, NR_RA_t *ra,
int16_t *tdd_beam_association); int16_t *tdd_beam_association);
void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra); void nr_generate_Msg3_retransmission(module_id_t module_idP,
int CC_id,
frame_t frameP,
sub_frame_t slotP,
NR_RA_t *ra,
nfapi_nr_ul_dci_request_t *ul_dci_req);
/* \brief Function in gNB to fill RAR pdu when requested by PHY. /* \brief Function in gNB to fill RAR pdu when requested by PHY.
@param ra Instance of RA resources of gNB @param ra Instance of RA resources of gNB
...@@ -201,10 +219,7 @@ void nr_srs_ri_computation(const nfapi_nr_srs_normalized_channel_iq_matrix_t *nr ...@@ -201,10 +219,7 @@ void nr_srs_ri_computation(const nfapi_nr_srs_normalized_channel_iq_matrix_t *nr
void nr_schedule_srs(int module_id, frame_t frame, int slot); void nr_schedule_srs(int module_id, frame_t frame, int slot);
void nr_csirs_scheduling(int Mod_idP, void nr_csirs_scheduling(int Mod_idP, frame_t frame, sub_frame_t slot, int n_slots_frame, nfapi_nr_dl_tti_request_t *DL_req);
frame_t frame,
sub_frame_t slot,
int n_slots_frame);
void nr_csi_meas_reporting(int Mod_idP, void nr_csi_meas_reporting(int Mod_idP,
frame_t frameP, frame_t frameP,
...@@ -365,13 +380,31 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP, ...@@ -365,13 +380,31 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP,
unsigned char drx_cmd, unsigned char drx_cmd,
unsigned char *ue_cont_res_id); unsigned char *ue_cont_res_id);
void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra); void nr_generate_Msg2(module_id_t module_idP,
int CC_id,
frame_t frameP,
sub_frame_t slotP,
NR_RA_t *ra,
nfapi_nr_dl_tti_request_t *dl_req,
nfapi_nr_tx_data_request_t *TX_req);
void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra); void nr_generate_Msg4(module_id_t module_idP,
int CC_id,
frame_t frameP,
sub_frame_t slotP,
NR_RA_t *ra,
nfapi_nr_dl_tti_request_t *DL_req,
nfapi_nr_tx_data_request_t *TX_req);
void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_frame_t slot, NR_RA_t *ra); void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_frame_t slot, NR_RA_t *ra);
void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra); void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP,
int CC_id,
frame_t frameP,
sub_frame_t slotP,
NR_RA_t *ra,
nfapi_nr_dl_tti_request_t *DL_req,
nfapi_nr_tx_data_request_t *TX_req);
int binomial(int n, int k); int binomial(int n, int k);
......
...@@ -719,24 +719,15 @@ typedef struct gNB_MAC_INST_s { ...@@ -719,24 +719,15 @@ typedef struct gNB_MAC_INST_s {
uint16_t ulprbbl[MAX_BWP_SIZE]; uint16_t ulprbbl[MAX_BWP_SIZE];
/// NFAPI Config Request Structure /// NFAPI Config Request Structure
nfapi_nr_config_request_scf_t config[NFAPI_CC_MAX]; nfapi_nr_config_request_scf_t config[NFAPI_CC_MAX];
/// NFAPI DL Config Request Structure
nfapi_nr_dl_tti_request_t DL_req[NFAPI_CC_MAX];
/// a PDCCH PDU groups DCIs per BWP and CORESET. The following structure /// a PDCCH PDU groups DCIs per BWP and CORESET. The following structure
/// keeps pointers to PDCCH PDUs within DL_req so that we can easily track /// keeps pointers to PDCCH PDUs within DL_req so that we can easily track
/// PDCCH PDUs per CC/BWP/CORESET /// PDCCH PDUs per CC/BWP/CORESET
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_idx[NFAPI_CC_MAX][MAX_NUM_CORESET]; nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_idx[NFAPI_CC_MAX][MAX_NUM_CORESET];
/// NFAPI UL TTI Request Structure, simple pointer into structure
/// UL_tti_req_ahead for current frame/slot
nfapi_nr_ul_tti_request_t *UL_tti_req[NFAPI_CC_MAX];
/// NFAPI UL TTI Request Structure for future TTIs, dynamically allocated /// NFAPI UL TTI Request Structure for future TTIs, dynamically allocated
/// because length depends on number of slots /// because length depends on number of slots
nfapi_nr_ul_tti_request_t *UL_tti_req_ahead[NFAPI_CC_MAX]; nfapi_nr_ul_tti_request_t *UL_tti_req_ahead[NFAPI_CC_MAX];
int UL_tti_req_ahead_size; int UL_tti_req_ahead_size;
int vrb_map_UL_size; int vrb_map_UL_size;
/// NFAPI HI/DCI0 Config Request Structure
nfapi_nr_ul_dci_request_t UL_dci_req[NFAPI_CC_MAX];
/// NFAPI DL PDU structure
nfapi_nr_tx_data_request_t TX_req[NFAPI_CC_MAX];
NR_UEs_t UE_info; NR_UEs_t UE_info;
......
...@@ -39,12 +39,12 @@ ...@@ -39,12 +39,12 @@
#include "nfapi/oai_integration/vendor_ext.h" #include "nfapi/oai_integration/vendor_ext.h"
#include "nfapi/oai_integration/gnb_ind_vars.h" #include "nfapi/oai_integration/gnb_ind_vars.h"
#include "openair2/PHY_INTERFACE/queue_t.h" #include "openair2/PHY_INTERFACE/queue_t.h"
#include "openair2/NR_PHY_INTERFACE/nr_sched_response.h"
#define MAX_IF_MODULES 100 #define MAX_IF_MODULES 100
//#define UL_HARQ_PRINT //#define UL_HARQ_PRINT
static NR_IF_Module_t *nr_if_inst[MAX_IF_MODULES]; static NR_IF_Module_t *nr_if_inst[MAX_IF_MODULES];
static NR_Sched_Rsp_t NR_Sched_INFO[MAX_IF_MODULES][MAX_NUM_CCs];
extern int oai_nfapi_harq_indication(nfapi_harq_indication_t *harq_ind); extern int oai_nfapi_harq_indication(nfapi_harq_indication_t *harq_ind);
extern int oai_nfapi_crc_indication(nfapi_crc_indication_t *crc_ind); extern int oai_nfapi_crc_indication(nfapi_crc_indication_t *crc_ind);
extern int oai_nfapi_cqi_indication(nfapi_cqi_indication_t *cqi_ind); extern int oai_nfapi_cqi_indication(nfapi_cqi_indication_t *cqi_ind);
...@@ -389,7 +389,7 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) { ...@@ -389,7 +389,7 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
AssertFatal(UL_info!=NULL,"UL_info is null\n"); AssertFatal(UL_info!=NULL,"UL_info is null\n");
module_id_t module_id = UL_info->module_id; module_id_t module_id = UL_info->module_id;
int CC_id = UL_info->CC_id; int CC_id = UL_info->CC_id;
NR_Sched_Rsp_t *sched_info = &NR_Sched_INFO[module_id][CC_id]; NR_Sched_Rsp_t *sched_info;
NR_IF_Module_t *ifi = nr_if_inst[module_id]; NR_IF_Module_t *ifi = nr_if_inst[module_id];
LOG_D(NR_PHY,"SFN/SLOT:%d.%d module_id:%d CC_id:%d UL_info[rach_pdus:%zu rx_ind:%zu crcs:%zu]\n", LOG_D(NR_PHY,"SFN/SLOT:%d.%d module_id:%d CC_id:%d UL_info[rach_pdus:%zu rx_ind:%zu crcs:%zu]\n",
...@@ -451,8 +451,6 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) { ...@@ -451,8 +451,6 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
} }
if (NFAPI_MODE != NFAPI_MODE_PNF) { if (NFAPI_MODE != NFAPI_MODE_PNF) {
gNB_MAC_INST *mac = RC.nrmac[module_id]; gNB_MAC_INST *mac = RC.nrmac[module_id];
// clear UL DCI prior to handling ULSCH
mac->UL_dci_req[CC_id].numPdus = 0;
if (ifi->CC_mask==0) { if (ifi->CC_mask==0) {
ifi->current_frame = UL_info->frame; ifi->current_frame = UL_info->frame;
ifi->current_slot = UL_info->slot; ifi->current_slot = UL_info->slot;
...@@ -471,21 +469,20 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) { ...@@ -471,21 +469,20 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
*/ */
nfapi_nr_config_request_scf_t *cfg = &mac->config[CC_id]; nfapi_nr_config_request_scf_t *cfg = &mac->config[CC_id];
int spf = get_spf(cfg); int spf = get_spf(cfg);
sched_info = allocate_sched_response();
// clear UL DCI prior to handling ULSCH
sched_info->UL_dci_req.numPdus = 0;
gNB_dlsch_ulsch_scheduler(module_id, gNB_dlsch_ulsch_scheduler(module_id,
(UL_info->frame+((UL_info->slot>(spf-1-ifi->sl_ahead))?1:0)) % 1024, (UL_info->frame + ((UL_info->slot > (spf - 1 - ifi->sl_ahead)) ? 1 : 0)) % 1024,
(UL_info->slot+ifi->sl_ahead)%spf); (UL_info->slot + ifi->sl_ahead) % spf,
sched_info);
ifi->CC_mask = 0; ifi->CC_mask = 0;
sched_info->module_id = module_id; sched_info->module_id = module_id;
sched_info->CC_id = CC_id; sched_info->CC_id = CC_id;
sched_info->frame = (UL_info->frame + ((UL_info->slot>(spf-1-ifi->sl_ahead)) ? 1 : 0)) % 1024; sched_info->frame = (UL_info->frame + ((UL_info->slot>(spf-1-ifi->sl_ahead)) ? 1 : 0)) % 1024;
sched_info->slot = (UL_info->slot+ifi->sl_ahead)%spf; sched_info->slot = (UL_info->slot+ifi->sl_ahead)%spf;
sched_info->DL_req = &mac->DL_req[CC_id];
sched_info->UL_dci_req = &mac->UL_dci_req[CC_id];
sched_info->UL_tti_req = mac->UL_tti_req[CC_id];
sched_info->TX_req = &mac->TX_req[CC_id];
#ifdef DUMP_FAPI #ifdef DUMP_FAPI
dump_dl(sched_info); dump_dl(sched_info);
#endif #endif
...@@ -496,10 +493,11 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) { ...@@ -496,10 +493,11 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
CC_id); CC_id);
ifi->NR_Schedule_response(sched_info); ifi->NR_Schedule_response(sched_info);
LOG_D(NR_PHY,"NR_Schedule_response: SFN SLOT:%d %d dl_pdus:%d\n", LOG_D(NR_PHY,
sched_info->frame, "NR_Schedule_response: SFN SLOT:%d %d dl_pdus:%d\n",
sched_info->slot, sched_info->frame,
sched_info->DL_req->dl_tti_request_body.nPDUs); sched_info->slot,
sched_info->DL_req.dl_tti_request_body.nPDUs);
} }
} }
} }
...@@ -520,5 +518,7 @@ NR_IF_Module_t *NR_IF_Module_init(int Mod_id) { ...@@ -520,5 +518,7 @@ NR_IF_Module_t *NR_IF_Module_init(int Mod_id) {
"allocation of nr_if_inst[%d]->if_mutex fails\n",Mod_id); "allocation of nr_if_inst[%d]->if_mutex fails\n",Mod_id);
} }
init_sched_response();
return nr_if_inst[Mod_id]; return nr_if_inst[Mod_id];
} }
...@@ -83,6 +83,8 @@ typedef struct { ...@@ -83,6 +83,8 @@ typedef struct {
typedef struct { typedef struct {
/// the ID of this sched_response - used by sched_reponse memory management
int sched_response_id;
/// Module ID /// Module ID
module_id_t module_id; module_id_t module_id;
/// CC ID /// CC ID
...@@ -92,13 +94,13 @@ typedef struct { ...@@ -92,13 +94,13 @@ typedef struct {
/// slot /// slot
slot_t slot; slot_t slot;
/// nFAPI DL Config Request /// nFAPI DL Config Request
nfapi_nr_dl_tti_request_t *DL_req; nfapi_nr_dl_tti_request_t DL_req;
/// nFAPI UL Config Request /// nFAPI UL Config Request
nfapi_nr_ul_tti_request_t *UL_tti_req; nfapi_nr_ul_tti_request_t UL_tti_req;
/// nFAPI UL_DCI Request /// nFAPI UL_DCI Request
nfapi_nr_ul_dci_request_t *UL_dci_req; nfapi_nr_ul_dci_request_t UL_dci_req;
/// Pointers to DL SDUs /// Pointers to DL SDUs
nfapi_nr_tx_data_request_t *TX_req; nfapi_nr_tx_data_request_t TX_req;
} NR_Sched_Rsp_t; } NR_Sched_Rsp_t;
typedef struct { typedef struct {
......
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/* sched response memory management */
/* A system with reference counting is implemented.
* It is needed because several threads will access the structure,
* which has to be released only when all the threads are done with it.
* So the main thread allocates a sched_response with allocate_sched_response()
* which allocates a sched_response with a reference counter == 1
* and then for each other thread that will access sched_response, a
* call to inc_ref_sched_response() is done. When a thread has finished
* using the sched_response, it calls deref_sched_response() which will
* in turn call release_sched_response() when the reference counter becomes 0.
*
* The several threads in question are accessing the _same_ sched_response,
* it has not to be confused with the various TX processes that may run in
* parallel and which are accessing _different_ sched_response (the maximum
* number of parallel processes is N_RESP).
*/
#include "nr_sched_response.h"
#include <pthread.h>
#include <stdlib.h>
#include "common/utils/LOG/log.h"
#include "common/utils/assertions.h"
#define N_RESP 3
static NR_Sched_Rsp_t resp[N_RESP];
static int resp_refcount[N_RESP];
static int resp_freelist_next[N_RESP];
static int resp_freelist_head;
static pthread_mutex_t resp_mutex = PTHREAD_MUTEX_INITIALIZER;
static bool resp_freelist_inited = false;
void init_sched_response(void)
{
/* init only once */
if (pthread_mutex_lock(&resp_mutex))
AssertFatal(0, "pthread_mutex_lock failed\n");
if (resp_freelist_inited) {
if (pthread_mutex_unlock(&resp_mutex))
AssertFatal(0, "pthread_mutex_unlock failed\n");
return;
}
resp_freelist_inited = true;
if (pthread_mutex_unlock(&resp_mutex))
AssertFatal(0, "pthread_mutex_unlock failed\n");
int i;
for (i = 0; i < N_RESP - 1; i++)
resp_freelist_next[i] = i + 1;
resp_freelist_next[N_RESP - 1] = -1;
resp_freelist_head = 0;
}
NR_Sched_Rsp_t *allocate_sched_response(void)
{
NR_Sched_Rsp_t *ret;
int new_head;
if (pthread_mutex_lock(&resp_mutex))
AssertFatal(0, "pthread_mutex_lock failed\n");
AssertFatal(resp_freelist_inited, "sched_response used before init\n");
if (resp_freelist_head == -1) {
LOG_E(PHY, "fatal: sched_response cannot be allocated, increase N_RESP\n");
exit(1);
}
ret = &resp[resp_freelist_head];
ret->sched_response_id = resp_freelist_head;
resp_refcount[resp_freelist_head] = 1;
new_head = resp_freelist_next[resp_freelist_head];
resp_freelist_next[resp_freelist_head] = -1;
resp_freelist_head = new_head;
if (pthread_mutex_unlock(&resp_mutex))
AssertFatal(0, "pthread_mutex_unlock failed\n");
return ret;
}
static void release_sched_response(int sched_response_id)
{
resp_freelist_next[sched_response_id] = resp_freelist_head;
resp_freelist_head = sched_response_id;
}
void deref_sched_response(int sched_response_id)
{
/* simulators (ulsim/dlsim) deal with their own sched_response but call
* functions that call this one, let's handle this case with a special
* value -1 where we do nothing (yes it's a hack)
*/
if (sched_response_id == -1)
return;
if (pthread_mutex_lock(&resp_mutex))
AssertFatal(0, "pthread_mutex_lock failed\n");
AssertFatal(resp_freelist_inited, "sched_response used before init\n");
AssertFatal(resp_refcount[sched_response_id] > 0, "sched_reponse decreased too much\n");
resp_refcount[sched_response_id]--;
if (resp_refcount[sched_response_id] == 0)
release_sched_response(sched_response_id);
if (pthread_mutex_unlock(&resp_mutex))
AssertFatal(0, "pthread_mutex_unlock failed\n");
}
void inc_ref_sched_response(int sched_response_id)
{
/* simulators (ulsim/dlsim) deal with their own sched_response but call
* functions that call this one, let's handle this case with a special
* value -1 where we do nothing (yes it's a hack)
*/
if (sched_response_id == -1)
return;
if (pthread_mutex_lock(&resp_mutex))
AssertFatal(0, "pthread_mutex_lock failed\n");
AssertFatal(resp_freelist_inited, "sched_response used before init\n");
resp_refcount[sched_response_id]++;
if (pthread_mutex_unlock(&resp_mutex))
AssertFatal(0, "pthread_mutex_unlock failed\n");
}
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef OPENAIR2_NR_PHY_INTERFACE_NR_SCHED_RESPONSE_H
#define OPENAIR2_NR_PHY_INTERFACE_NR_SCHED_RESPONSE_H
#include "NR_IF_Module.h"
void init_sched_response(void);
NR_Sched_Rsp_t *allocate_sched_response(void);
void deref_sched_response(int sched_response_id);
void inc_ref_sched_response(int sched_response_id);
#endif /* OPENAIR2_NR_PHY_INTERFACE_NR_SCHED_RESPONSE_H */
This diff is collapsed.
...@@ -271,6 +271,40 @@ typedef struct pdu_session_param_s { ...@@ -271,6 +271,40 @@ typedef struct pdu_session_param_s {
uint8_t cause_value; uint8_t cause_value;
} rrc_pdu_session_param_t; } rrc_pdu_session_param_t;
typedef struct drb_s {
int status;
int defaultDRBid;
int drb_id;
int reestablishPDCP;
int recoverPDCP;
int daps_Config_r16;
struct cnAssociation_s {
int present;
int eps_BearerIdentity;
struct sdap_config_s {
bool defaultDRB;
int pdusession_id;
int sdap_HeaderDL;
int sdap_HeaderUL;
int mappedQoS_FlowsToAdd[QOSFLOW_MAX_VALUE];
} sdap_config;
} cnAssociation;
struct pdcp_config_s {
int discardTimer;
int pdcp_SN_SizeUL;
int pdcp_SN_SizeDL;
int t_Reordering;
int integrityProtection;
struct headerCompression_s {
int NotUsed;
int present;
} headerCompression;
struct ext1_s {
int cipheringDisabled;
} ext1;
} pdcp_config;
} drb_t;
typedef struct gNB_RRC_UE_s { typedef struct gNB_RRC_UE_s {
uint8_t primaryCC_id; uint8_t primaryCC_id;
NR_SRB_ToAddModList_t *SRB_configList; NR_SRB_ToAddModList_t *SRB_configList;
...@@ -278,6 +312,7 @@ typedef struct gNB_RRC_UE_s { ...@@ -278,6 +312,7 @@ typedef struct gNB_RRC_UE_s {
NR_DRB_ToAddModList_t *DRB_configList; NR_DRB_ToAddModList_t *DRB_configList;
NR_DRB_ToAddModList_t *DRB_configList2[NR_RRC_TRANSACTION_IDENTIFIER_NUMBER]; NR_DRB_ToAddModList_t *DRB_configList2[NR_RRC_TRANSACTION_IDENTIFIER_NUMBER];
NR_DRB_ToReleaseList_t *DRB_Release_configList2[NR_RRC_TRANSACTION_IDENTIFIER_NUMBER]; NR_DRB_ToReleaseList_t *DRB_Release_configList2[NR_RRC_TRANSACTION_IDENTIFIER_NUMBER];
drb_t established_drbs[NGAP_MAX_DRBS_PER_UE];
uint8_t DRB_active[NGAP_MAX_DRBS_PER_UE]; uint8_t DRB_active[NGAP_MAX_DRBS_PER_UE];
NR_SRB_INFO_TABLE_ENTRY Srb[maxSRBs]; // 3gpp max is 3 SRBs, number 1..3, we waste the entry 0 for code simplicity NR_SRB_INFO_TABLE_ENTRY Srb[maxSRBs]; // 3gpp max is 3 SRBs, number 1..3, we waste the entry 0 for code simplicity
......
This diff is collapsed.
...@@ -36,65 +36,109 @@ rrc_pdu_session_param_t *find_pduSession(gNB_RRC_UE_t *ue, int id, bool create) ...@@ -36,65 +36,109 @@ rrc_pdu_session_param_t *find_pduSession(gNB_RRC_UE_t *ue, int id, bool create)
return ue->pduSession + j; return ue->pduSession + j;
} }
NR_DRB_ToAddMod_t *generateDRB(gNB_RRC_UE_t *ue, uint8_t drb_id, rrc_pdu_session_param_t *pduSession, bool enable_sdap, int do_drb_integrity, int do_drb_ciphering) void generateDRB(gNB_RRC_UE_t *ue,
uint8_t drb_id,
rrc_pdu_session_param_t *pduSession,
bool enable_sdap,
int do_drb_integrity,
int do_drb_ciphering)
{ {
NR_DRB_ToAddMod_t *DRB_config = CALLOC(1, sizeof(*DRB_config)); int i;
DRB_config->drb_Identity = drb_id; int qos_flow_index;
asn1cCalloc(DRB_config->cnAssociation, association); drb_t *est_drb = &ue->established_drbs[drb_id - 1];
association->present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config; if (est_drb->status == DRB_INACTIVE) {
/* DRB Management */
est_drb->drb_id = drb_id;
est_drb->reestablishPDCP = -1;
est_drb->recoverPDCP = -1;
for (i = 0; i < NGAP_MAX_DRBS_PER_UE; i++) {
if ((est_drb->cnAssociation.sdap_config.pdusession_id == 0
|| est_drb->cnAssociation.sdap_config.pdusession_id == pduSession->param.pdusession_id)
&& est_drb->defaultDRBid == 0) {
est_drb->cnAssociation.sdap_config.defaultDRB = true;
est_drb->defaultDRBid = drb_id;
}
}
/* SDAP Configuration */
est_drb->cnAssociation.present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config;
est_drb->cnAssociation.sdap_config.pdusession_id = pduSession->param.pdusession_id;
if (enable_sdap) {
est_drb->cnAssociation.sdap_config.sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_present;
est_drb->cnAssociation.sdap_config.sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_present;
} else {
est_drb->cnAssociation.sdap_config.sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_absent;
est_drb->cnAssociation.sdap_config.sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_absent;
}
for (qos_flow_index = 0; qos_flow_index < pduSession->param.nb_qos; qos_flow_index++) {
est_drb->cnAssociation.sdap_config.mappedQoS_FlowsToAdd[qos_flow_index] = pduSession->param.qos[qos_flow_index].qfi;
if (pduSession->param.qos[qos_flow_index].fiveQI > 5)
est_drb->status = DRB_ACTIVE_NONGBR;
else
est_drb->status = DRB_ACTIVE;
}
/* PDCP Configuration */
est_drb->pdcp_config.discardTimer = NR_PDCP_Config__drb__discardTimer_infinity;
est_drb->pdcp_config.pdcp_SN_SizeDL = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits;
est_drb->pdcp_config.pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits;
est_drb->pdcp_config.t_Reordering = NR_PDCP_Config__t_Reordering_ms100;
est_drb->pdcp_config.headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed;
est_drb->pdcp_config.headerCompression.NotUsed = 0;
if (do_drb_integrity)
est_drb->pdcp_config.integrityProtection = NR_PDCP_Config__drb__integrityProtection_enabled;
else
est_drb->pdcp_config.integrityProtection = 1;
if (do_drb_ciphering)
est_drb->pdcp_config.ext1.cipheringDisabled = 1;
else
est_drb->pdcp_config.ext1.cipheringDisabled = NR_PDCP_Config__ext1__cipheringDisabled_true;
}
}
/* SDAP Configuration */ NR_DRB_ToAddMod_t *generateDRB_ASN1(const drb_t *drb_asn1)
{
NR_DRB_ToAddMod_t *DRB_config = CALLOC(1, sizeof(*DRB_config));
NR_SDAP_Config_t *SDAP_config = CALLOC(1, sizeof(NR_SDAP_Config_t)); NR_SDAP_Config_t *SDAP_config = CALLOC(1, sizeof(NR_SDAP_Config_t));
asn1cCalloc(DRB_config->cnAssociation, association);
asn1cCalloc(SDAP_config->mappedQoS_FlowsToAdd, sdapFlows); asn1cCalloc(SDAP_config->mappedQoS_FlowsToAdd, sdapFlows);
asn1cCalloc(DRB_config->pdcp_Config, pdcpConfig);
asn1cCalloc(pdcpConfig->drb, drb);
SDAP_config->pdu_Session = pduSession->param.pdusession_id; DRB_config->drb_Identity = drb_asn1->drb_id;
association->present = drb_asn1->cnAssociation.present;
if (enable_sdap) {
SDAP_config->sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_present; /* SDAP Configuration */
SDAP_config->sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_present; SDAP_config->pdu_Session = drb_asn1->cnAssociation.sdap_config.pdusession_id;
} else { SDAP_config->sdap_HeaderDL = drb_asn1->cnAssociation.sdap_config.sdap_HeaderDL;
SDAP_config->sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_absent; SDAP_config->sdap_HeaderUL = drb_asn1->cnAssociation.sdap_config.sdap_HeaderUL;
SDAP_config->sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_absent; SDAP_config->defaultDRB = drb_asn1->cnAssociation.sdap_config.defaultDRB;
}
for (int qos_flow_index = 0; qos_flow_index < QOSFLOW_MAX_VALUE; qos_flow_index++) {
SDAP_config->defaultDRB = true; if (drb_asn1->cnAssociation.sdap_config.mappedQoS_FlowsToAdd[qos_flow_index] != 0) {
asn1cSequenceAdd(sdapFlows->list, NR_QFI_t, qfi);
for (int qos_flow_index = 0; qos_flow_index < pduSession->param.nb_qos; qos_flow_index++) *qfi = drb_asn1->cnAssociation.sdap_config.mappedQoS_FlowsToAdd[qos_flow_index];
{ }
asn1cSequenceAdd(sdapFlows->list, NR_QFI_t, qfi);
*qfi = pduSession->param.qos[qos_flow_index].qfi;
if(pduSession->param.qos[qos_flow_index].fiveQI > 5)
pduSession->param.used_drbs[drb_id - 1] = DRB_ACTIVE_NONGBR;
else
pduSession->param.used_drbs[drb_id - 1] = DRB_ACTIVE;
} }
association->choice.sdap_Config = SDAP_config; association->choice.sdap_Config = SDAP_config;
/* PDCP Configuration */ /* PDCP Configuration */
asn1cCalloc(DRB_config->pdcp_Config, pdcpConfig); asn1cCallocOne(drb->discardTimer, drb_asn1->pdcp_config.discardTimer);
asn1cCalloc(pdcpConfig->drb, drb); asn1cCallocOne(drb->pdcp_SN_SizeUL, drb_asn1->pdcp_config.pdcp_SN_SizeUL);
asn1cCallocOne(drb->pdcp_SN_SizeDL, drb_asn1->pdcp_config.pdcp_SN_SizeDL);
asn1cCallocOne(drb->discardTimer, NR_PDCP_Config__drb__discardTimer_infinity); asn1cCallocOne(pdcpConfig->t_Reordering, drb_asn1->pdcp_config.t_Reordering);
asn1cCallocOne(drb->pdcp_SN_SizeUL, NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits); drb->headerCompression.present = drb_asn1->pdcp_config.headerCompression.present;
asn1cCallocOne(drb->pdcp_SN_SizeDL, NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits); drb->headerCompression.choice.notUsed = drb_asn1->pdcp_config.headerCompression.NotUsed;
drb->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed; if (!drb_asn1->pdcp_config.integrityProtection) {
drb->headerCompression.choice.notUsed = 0; asn1cCallocOne(drb->integrityProtection, drb_asn1->pdcp_config.integrityProtection);
asn1cCallocOne(pdcpConfig->t_Reordering, NR_PDCP_Config__t_Reordering_ms100);
if (do_drb_integrity) {
asn1cCallocOne(drb->integrityProtection, NR_PDCP_Config__drb__integrityProtection_enabled);
} }
if (!do_drb_ciphering) { if (!drb_asn1->pdcp_config.ext1.cipheringDisabled) {
asn1cCalloc(pdcpConfig->ext1, ext1); asn1cCalloc(pdcpConfig->ext1, ext1);
asn1cCallocOne(ext1->cipheringDisabled, NR_PDCP_Config__ext1__cipheringDisabled_true); asn1cCallocOne(ext1->cipheringDisabled, drb_asn1->pdcp_config.ext1.cipheringDisabled);
} }
ue->DRB_active[drb_id-1] = DRB_ACTIVE;
return DRB_config; return DRB_config;
} }
......
...@@ -35,7 +35,24 @@ ...@@ -35,7 +35,24 @@
#define GBR_FLOW (1) #define GBR_FLOW (1)
#define NONGBR_FLOW (0) #define NONGBR_FLOW (0)
NR_DRB_ToAddMod_t *generateDRB(gNB_RRC_UE_t *rrc_ue, uint8_t drb_id, rrc_pdu_session_param_t *pduSession, bool enable_sdap, int do_drb_integrity, int do_drb_ciphering); /// @brief Generates an ASN1 DRB-ToAddMod, from the established_drbs in gNB_RRC_UE_t.
/// @param drb_t drb_asn1
/// @return Returns the ASN1 DRB-ToAddMod structs.
NR_DRB_ToAddMod_t *generateDRB_ASN1(const drb_t *drb_asn1);
/// @brief Creates and stores a DRB in the gNB_RRC_UE_t struct, it doesn't create the actual entity,
/// to create the actual entity use the generateDRB_ASN1.
/// @param ue The gNB_RRC_UE_t struct that holds information for the UEs
/// @param drb_id The Data Radio Bearer Identity to be created for the established DRB.
/// @param pduSession The PDU Session that the DRB is created for.
/// @param enable_sdap If true the SDAP header will be added to the packet, else it will not add or search for SDAP header.
/// @param do_drb_integrity
/// @param do_drb_ciphering
void generateDRB(gNB_RRC_UE_t *ue,
uint8_t drb_id,
rrc_pdu_session_param_t *pduSession,
bool enable_sdap,
int do_drb_integrity,
int do_drb_ciphering);
uint8_t next_available_drb(gNB_RRC_UE_t *ue, rrc_pdu_session_param_t *pdusession, bool is_gbr); uint8_t next_available_drb(gNB_RRC_UE_t *ue, rrc_pdu_session_param_t *pdusession, bool is_gbr);
bool drb_is_active(gNB_RRC_UE_t *ue, uint8_t drb_id); bool drb_is_active(gNB_RRC_UE_t *ue, uint8_t drb_id);
......
...@@ -622,7 +622,7 @@ static void decodeRegistrationAccept(uint8_t *buf, int len, nr_ue_nas_t *nas) ...@@ -622,7 +622,7 @@ static void decodeRegistrationAccept(uint8_t *buf, int len, nr_ue_nas_t *nas)
AssertFatal(reg_acc.guti->guti.typeofidentity == FGS_MOBILE_IDENTITY_5G_GUTI, AssertFatal(reg_acc.guti->guti.typeofidentity == FGS_MOBILE_IDENTITY_5G_GUTI,
"registration accept 5GS Mobile Identity is not GUTI, but %d\n", "registration accept 5GS Mobile Identity is not GUTI, but %d\n",
reg_acc.guti->guti.typeofidentity); reg_acc.guti->guti.typeofidentity);
nas->guti = malloc(sizeof(nas->guti)); nas->guti = malloc(sizeof(*nas->guti));
AssertFatal(nas->guti, "out of memory\n"); AssertFatal(nas->guti, "out of memory\n");
*nas->guti = reg_acc.guti->guti; *nas->guti = reg_acc.guti->guti;
free(reg_acc.guti); /* no proper memory management for NAS decoded messages */ free(reg_acc.guti); /* no proper memory management for NAS decoded messages */
......
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