Merge branch 'develop' into 'fix_do_ra_data'

# Conflicts:
#   openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
#   openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
This commit is contained in:
Thomas Schlichter
2020-12-10 13:40:08 +01:00
82 changed files with 2798 additions and 2010 deletions
+1 -1
View File
@@ -185,7 +185,7 @@ class OaiCiTest():
SSH.command('mkdir -p log', '\$', 5)
SSH.command('chmod 777 log', '\$', 5)
# no need to remove in log (git clean did the trick)
SSH.command('stdbuf -o0 ./build_oai ' + self.Build_OAI_UE_args + ' 2>&1 | stdbuf -o0 tee compile_oai_ue.log', 'Bypassing the Tests|build have failed', 900)
SSH.command('stdbuf -o0 ./build_oai ' + self.Build_OAI_UE_args + ' 2>&1 | stdbuf -o0 tee compile_oai_ue.log', 'Bypassing the Tests|build have failed', 1200)
SSH.command('ls ran_build/build', '\$', 3)
SSH.command('ls ran_build/build', '\$', 3)
buildStatus = True
@@ -266,7 +266,7 @@ RUs = (
max_pdschReferenceSignalPower = -27;
max_rxgain = 118;
eNB_instances = [0];
clock_src = "external";
# clock_src = "external";
}
);
@@ -1,6 +1,8 @@
Active_gNBs = ( "gNB-Eurecom-5GNRBox");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
Num_Threads_PUSCH = 8
gNBs =
(
@@ -21,7 +23,10 @@ gNBs =
ssb_SubcarrierOffset = 31; //0;
pdsch_AntennaPorts = 1;
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200;
servingCellConfigCommon = (
{
#spCellConfigCommon
@@ -260,7 +265,7 @@ RUs = (
max_pdschReferenceSignalPower = -27;
max_rxgain = 114;
eNB_instances = [0];
clock_src = "external";
# clock_src = "external";
}
);
@@ -32,7 +32,7 @@
<testCase id="090101">
<class>Build_OAI_UE</class>
<desc>Build OAI UE</desc>
<Build_OAI_UE_args>-w USRP --UE</Build_OAI_UE_args>
<Build_OAI_UE_args>-w USRP --UE --ninja</Build_OAI_UE_args>
</testCase>
</testCaseList>
+1 -1
View File
@@ -32,7 +32,7 @@
<testCase id="090101">
<class>Build_OAI_UE</class>
<desc>Build OAI UE</desc>
<Build_OAI_UE_args>-w USRP --UE</Build_OAI_UE_args>
<Build_OAI_UE_args>-w USRP --UE --ninja</Build_OAI_UE_args>
</testCase>
</testCaseList>
+2 -1
View File
@@ -1968,6 +1968,7 @@ set(NR_PDCP_SRC
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_entity.c
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c
${OPENAIR2_DIR}/LAYER2/nr_pdcp/asn1_utils.c
)
set(L2_SRC
@@ -3434,7 +3435,7 @@ if (${T_TRACER})
SECU_OSA SECU_CN SCHED_LIB SCHED_NR_LIB SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB default_sched remote_sched RAL
NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_VNF_LIB NFAPI_USER_LIB
PHY_COMMON PHY PHY_UE PHY_NR PHY_NR_COMMON PHY_NR_UE PHY_RU PHY_MEX
L2 L2_LTE L2_NR L2_LTE_NR L2_UE NR_L2_UE L2_UE_LTE_NR MAC_NR_COMMON MAC_NR MAC_UE_NR
L2 L2_LTE L2_NR L2_LTE_NR L2_UE NR_L2_UE L2_UE_LTE_NR MAC_NR_COMMON MAC_NR MAC_UE_NR NGAP_GNB
CN_UTILS GTPV1U NR_GTPV1U SCTP_CLIENT MME_APP UDP LIB_NAS_UE NB_IoT LFDS LFDS7 SIMU_COMMON SIMU SIMU_ETH OPENAIR0_LIB
ldpc_orig ldpc_optim ldpc_optim8seg ldpc PROTO_AGENT dfts)
if (TARGET ${i})
+66 -10
View File
@@ -70,7 +70,7 @@ if the input is a UE RACH detection
* nr_schedule_msg2()
{: .func4}
* handle_nr_uci()
????
handles uplink control information, i.e., for the moment HARQ feedback.
{: .func4}
* handle_nr_ulsch()
handles ulsch data prepared by nr_fill_indication()
@@ -143,7 +143,8 @@ the samples numbers are the future time for these samples emission on-air
{: .func3}
# Scheduler
The scheduler is called by the chain: nr_ul_indication()=>gNB_dlsch_ulsch_scheduler()
The main scheduler function is called by the chain: nr_ul_indication()=>gNB_dlsch_ulsch_scheduler()
It calls sub functions to process each physical channel (rach, ...)
The scheduler uses and internal map of used RB: vrb_map and vrb_map_UL, so each specific channel scheduler can see the already filled RB in each subframe (the function gNB_dlsch_ulsch_scheduler() clears these two arrays when it starts)
@@ -153,16 +154,71 @@ it sends a iiti message to activate the thread for RRC, the answer will be async
Calls schedule_nr_mib() that calls mac_rrc_nr_data_req() to fill MIB,
Calls each channel allocation: schedule SI, schedule_ul, schedule_dl, ...
this is a major entry for "phy-test" mode: in this mode, the allocation is fixed
all these channels goes to mac_rrc_nr_data_req() to get the data to transmit
Calls schedule_nr_prach() which schedules the (fixed) PRACH region one frame in
advance.
nr_schedule_ue_spec() is called
* calls nr_simple_dlsch_preprocessor()=> mac_rlc_status_ind() mac_rlc_status_ind() locks and checks directly inside rlc data the quantity of waiting data. So, the scheduler can allocate RBs
* calls nr_update_pucch_scheduling()
* get_pdsch_to_harq_feedback() to schedule retransmission in DL
Calls nr_csi_meas_reporting() to check when to schedule CSI in PUCCH.
Calls nr_fill_nfapi_dl_pdu() to actually populate what should be done by the lower layers to make the Tx subframe
Calls nr_schedule_RA(): checks RA process 0's state. Schedules Msg.2 via
nr_generate_Msg2() if an RA process is ongoing, and pre-allocates the Msg. 3
for PUSCH as well.
Calls nr_schedule_ulsch(): It is divided into the "preprocessor" and the
"postprocessor": the first makes the scheduling decisions, the second fills
nFAPI structures to indicate to the PHY what it is supposed to do. To signal
which users have how many resources, the preprocessor populates the
NR_sched_pusch_t (for values changing every TTI, e.g., frequency domain
allocation) and NR_sched_pusch_save_t (for values changing less frequently, at
least in FR1 [to my understanding], e.g., DMRS fields when the time domain
allocation stays between TTIs) structures. Furthermore, the preprocessor is an
exchangeable module that might schedule differently, e.g., one user for
phytest, multiple users in FR1, or maybe FR2: phytest is in
nr_ul_preprocessor_phytest(), for FR1 is nr_simple_ulsch_preprocessor() [under
development], for FR2 does not exist yet.
* calls preprocessor via pre_processor_ul(): the preprocessor is responsible
for allocating CCEs (using allocate_nr_CCEs()). Note that we do not yet have
scheduling requests or buffer status reports, and only one UE. E.g.,
nr_simple_ulsch_preprocessor():
1) check whether the current frame/slot plus K2 is an UL slot, and return if
not.
2) Find first free start RB in vrb_map_UL, and as many free consecutive RBs
as possible.
3) allocate a CCE for the UE (and return if it is not possible)
4) Calculate DMRS stuff (nr_save_pusch_fields()) and the TBS.
5) Mark used resources in vrb_map_UL.
* loop through all users: get a free HARQ PID using select_ul_harq_pid() and
update statistics. Fill nFAPI structures directly for PUSCH, and call
config_uldci() and fill_dci_pdu_rel15() for DCI filling and PDCCH messages.
Calls nr_schedule_ue_spec(). It is divided into the "preprocessor" and the
"postprocessor": the first makes the scheduling decisions, the second fills
nFAPI structures to indicate to the PHY what it is supposed to do. To signal
which users have how many resources, the preprocessor populates the
NR_UE_sched_ctrl_t structure of affected users. In particular, the field rbSize
decides whether a user is to be allocated. Furthermore, the preprocessor is an
exchangeable module that might schedule differently, e.g., one user for
phytest, multiple users in FR1, or maybe FR2: phytest is in
nr_preprocessor_phytest(), for FR1 is nr_simple_dlsch_preprocessor() [under
development], for FR2 does not exist yet.
* calls preprocessor via pre_processor_dl(): the preprocessor is responsible
for allocating CCEs and PUCCH (using allocate_nr_CCEs() and
nr_acknack_scheduling()) and deciding on the frequency/time domain
allocation. E.g., nr_simple_dlsch_preprocessor():
1) mac_rlc_status_ind() locks and checks directly inside rlc data the
quantity of waiting data.
2) return from the preprocessor if there is no data and no timing advance to
send,
3) otherwise, allocate a CCE for the UE (and return if it is not possible)
4) find a PUCCH occasion for HARQ
5a) check if there is a retransmission: if yes, find free resources to
transmit using the same resources, else
5b) calculate the necessary RBs needed to get a TBS large enough to hold all
data, or until no more resources are available
6) Mark taken resources in the vrb_map
* loop through all users: check if a new TA is necessary. Then, if a user has
allocated resources, compute its TBS, and fill nFAPI structures
(nr_fill_nfapi_dl_pdu() to populate what should be done by the lower layers
to make the Tx subframe). Update statistics (round, sent bytes).
# RRC
RRC is a regular thread with itti loop on queue: TASK_RRC_GNB
+14 -1
View File
@@ -72,6 +72,7 @@
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "UTIL/OPT/opt.h"
#include "enb_config.h"
#include "gnb_paramdef.h"
#ifndef OPENAIR2
@@ -101,6 +102,7 @@ extern int transmission_mode;
extern uint16_t sf_ahead;
extern uint16_t sl_ahead;
//pthread_t main_gNB_thread;
time_stats_t softmodem_stats_mt; // main thread
@@ -870,7 +872,18 @@ void init_gNB_proc(int inst) {
gNB->threadPool = (tpool_t*)malloc(sizeof(tpool_t));
gNB->respDecode = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
char ul_pool[] = "-1,-1";
int numCPU = sysconf(_SC_NPROCESSORS_ONLN);
uint32_t num_threads_pusch;
paramdef_t PUSCHThreads[] = NUM_THREADS_DESC;
config_get( PUSCHThreads,sizeof(PUSCHThreads)/sizeof(paramdef_t),NULL);
int threadCnt = min(numCPU, num_threads_pusch);
char ul_pool[80];
sprintf(ul_pool,"-1");
int s_offset = 0;
for (int icpu=1; icpu<threadCnt; icpu++) {
sprintf(ul_pool+2+s_offset,",-1");
s_offset += 3;
}
initTpool(ul_pool, gNB->threadPool, false);
initNotifiedFIFO(gNB->respDecode);
}
+10 -2
View File
@@ -407,8 +407,16 @@ int nr_rate_matching_ldpc(uint8_t Ilbrm,
#ifdef RM_DEBUG
printf("nr_rate_matching_ldpc: E %d, F %d, Foffset %d, k0 %d, Ncb %d, rvidx %d\n", E, F, Foffset,ind, Ncb, rvidx);
#endif
AssertFatal(Foffset <= E,"Foffset %d > E %d\n",Foffset,E);
AssertFatal(Foffset <= Ncb,"Foffset %d > Ncb %d\n",Foffset,Ncb);
AssertFatal(Foffset <= E,
"Foffset %d > E %d "
"(Ilbrm %d, Tbslbrm %d, Z %d, BG %d, C %d)\n",
Foffset, E,
Ilbrm, Tbslbrm, Z, BG, C);
AssertFatal(Foffset <= Ncb,
"Foffset %d > Ncb %d "
"(Ilbrm %d, Tbslbrm %d, Z %d, BG %d, C %d)\n",
Foffset, Ncb,
Ilbrm, Tbslbrm, Z, BG, C);
if (ind >= Foffset && ind < (F+Foffset)) ind = F+Foffset;
+26 -32
View File
@@ -41,38 +41,32 @@ int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp)
int case_E[8] = {8, 12, 16, 20, 32, 36, 40, 44};
switch(mu) {
case NR_MU_0: // case A
n = i_ssb >> 1;
symbol = case_AC[i_ssb % 2] + 14*n;
break;
case NR_MU_1:
if (type == 1){ // case B
n = i_ssb >> 2;
symbol = case_BD[i_ssb % 4] + 28*n;
}
if (type == 2){ // case C
n = i_ssb >> 1;
symbol = case_AC[i_ssb % 2] + 14*n;
}
break;
case NR_MU_3: // case D
n_temp = i_ssb >> 2;
n = n_temp + (n_temp >> 2);
symbol = case_BD[i_ssb % 4] + 28*n;
break;
case NR_MU_4: // case E
n_temp = i_ssb >> 3;
n = n_temp + (n_temp >> 2);
symbol = case_E[i_ssb % 8] + 56*n;
break;
default:
AssertFatal(0==1, "Invalid numerology index %d for the synchronization block\n", mu);
case NR_MU_0: // case A
n = i_ssb >> 1;
symbol = case_AC[i_ssb % 2] + 14*n;
break;
case NR_MU_1:
if (type == 1){ // case B
n = i_ssb >> 2;
symbol = case_BD[i_ssb % 4] + 28*n;
}
if (type == 2){ // case C
n = i_ssb >> 1;
symbol = case_AC[i_ssb % 2] + 14*n;
}
break;
case NR_MU_3: // case D
n_temp = i_ssb >> 2;
n = n_temp + (n_temp >> 2);
symbol = case_BD[i_ssb % 4] + 28*n;
break;
case NR_MU_4: // case E
n_temp = i_ssb >> 3;
n = n_temp + (n_temp >> 2);
symbol = case_E[i_ssb % 8] + 56*n;
break;
default:
AssertFatal(0==1, "Invalid numerology index %d for the synchronization block\n", mu);
}
if (half_frame_index)
@@ -47,6 +47,7 @@ void lte_eNB_I0_measurements(PHY_VARS_eNB *eNB,
uint32_t rb;
int32_t *ul_ch;
int32_t n0_power_tot;
int64_t n0_power_tot2;
int len;
int offset;
// noise measurements
@@ -75,43 +76,47 @@ void lte_eNB_I0_measurements(PHY_VARS_eNB *eNB,
}
n0_power_tot2=0;
int nb_rb=0;
for (rb=0; rb<frame_parms->N_RB_UL; rb++) {
n0_power_tot=0;
n0_power_tot=0;
int offset0= (frame_parms->first_carrier_offset + (rb*12))%frame_parms->ofdm_symbol_size;
if ((rb_mask[rb>>5]&(1<<(rb&31))) == 0) { // check that rb was not used in this subframe
nb_rb++;
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
measurements->n0_subband_power[aarx][rb] = 0;
for (int s=0;s<14-(frame_parms->Ncp<<1);s++) {
// select the 7th symbol in an uplink subframe
offset = (frame_parms->first_carrier_offset + (rb*12))%frame_parms->ofdm_symbol_size;
offset += (7*frame_parms->ofdm_symbol_size);
ul_ch = &common_vars->rxdataF[aarx][offset];
len = 12;
offset = offset0 + (s*frame_parms->ofdm_symbol_size);
ul_ch = &common_vars->rxdataF[aarx][offset];
len = 12;
// just do first half of middle PRB for odd number of PRBs
if (((frame_parms->N_RB_UL&1) == 1) &&
(rb==(frame_parms->N_RB_UL>>1))) {
len=6;
}
if (clear == 1)
measurements->n0_subband_power[aarx][rb]=0;
if (((frame_parms->N_RB_UL&1) == 1) &&
(rb==(frame_parms->N_RB_UL>>1))) {
len=6;
}
AssertFatal(ul_ch, "RX signal buffer (freq) problem");
AssertFatal(ul_ch, "RX signal buffer (freq) problem");
measurements->n0_subband_power[aarx][rb] = signal_energy_nodc(ul_ch,len);
//((k1*(signal_energy_nodc(ul_ch,len)))
// + (k2*measurements->n0_subband_power[aarx][rb]));
measurements->n0_subband_power[aarx][rb] += signal_energy_nodc(ul_ch,len);
measurements->n0_subband_power_dB[aarx][rb] = dB_fixed(measurements->n0_subband_power[aarx][rb]);
// printf("subframe %d (%d): eNB %d, aarx %d, rb %d len %d: energy %d (%d dB)\n",subframe,offset,eNB_id,aarx,rb,len,signal_energy_nodc(ul_ch,len),
// measurements->n0_subband_power_dB[aarx][rb]);
n0_power_tot += measurements->n0_subband_power[aarx][rb];
}
measurements->n0_subband_power[aarx][rb]/=(14-(frame_parms->Ncp<<1));
measurements->n0_subband_power_dB[aarx][rb] = dB_fixed(measurements->n0_subband_power[aarx][rb]);
n0_power_tot += measurements->n0_subband_power[aarx][rb];
}
measurements->n0_subband_power_tot_dB[rb] = dB_fixed(n0_power_tot);
n0_power_tot/=frame_parms->nb_antennas_rx;
n0_power_tot2 += n0_power_tot;
measurements->n0_subband_power_tot_dB[rb] = dB_fixed(n0_power_tot/frame_parms->nb_antennas_rx);
measurements->n0_subband_power_tot_dBm[rb] = measurements->n0_subband_power_tot_dB[rb] - eNB->rx_total_gain_dB - dB_fixed(frame_parms->N_RB_UL);
}
}
if (nb_rb>0) measurements->n0_subband_power_avg_dB = dB_fixed(n0_power_tot2/nb_rb);
}
void lte_eNB_srs_measurements(PHY_VARS_eNB *eNB,
+82 -212
View File
@@ -1070,6 +1070,8 @@ void send_IF5(RU_t *ru, openair0_timestamp proc_timestamp, int subframe, uint8_t
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 1 );
if (packet_type == IF5_RRH_GW_DL) {
if (eth->compression == ALAW_COMPRESS) {
AssertFatal(1==0,"IF5 compression needs reworking\n");
/*
if (eth->flags == ETH_RAW_MODE) {
data_block = (uint16_t*)(alaw_buffer + APP_HEADER_SIZE_BYTES + MAC_HEADER_SIZE_BYTES);
} else {
@@ -1100,28 +1102,31 @@ void send_IF5(RU_t *ru, openair0_timestamp proc_timestamp, int subframe, uint8_t
LOG_D(HW,"[SF %d] IF_Write_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_comp, end_comp));
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF0, 0 );
}
*/
} else if (eth->compression == NO_COMPRESS) {
for (i=0; i < fp->nb_antennas_tx; i++)
txp[i] = (void*)&ru->common.txdata[i][subframe*fp->samples_per_tti];
for (i=0; i < ru->nb_tx; i++)
txp[i] = (int32_t*)&ru->common.txdata[i][subframe*fp->samples_per_tti];
for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID, packet_id );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF0, 1 );
clock_gettime( CLOCK_MONOTONIC, &start_comp);
ru->ifdevice.trx_write_func(&ru->ifdevice,
(proc_timestamp + packet_id*spp_eth),
(void**)txp,
spp_eth,
fp->nb_antennas_tx,
0);
clock_gettime( CLOCK_MONOTONIC, &end_comp);
LOG_D(HW,"[SF %d] IF_Write_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_comp, end_comp));
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF0, 0 );
for (i=0; i < fp->nb_antennas_tx; i++)
txp[i] += spp_eth;
for (int aid=0; aid<ru->nb_tx;aid++) {
//VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID, packet_id );
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF0, 1 );
clock_gettime( CLOCK_MONOTONIC, &start_comp);
ru->ifdevice.trx_write_func2(&ru->ifdevice,
(proc_timestamp + packet_id*spp_eth-500)*(30720/spsf),
(void*)txp[aid],
spp_eth,
aid,
0);
LOG_D(HW,"SF %d : packet %d, TS %llu\n",subframe,packet_id,(unsigned long long)(proc_timestamp+packet_id*spp_eth));
clock_gettime( CLOCK_MONOTONIC, &end_comp);
LOG_D(HW,"[SF %d] IF_Write_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_comp, end_comp));
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF0, 0 );
txp[aid] += spp_eth;
}
}
}
}
} else if (packet_type == IF5_RRH_GW_UL) {
if (eth->compression == ALAW_COMPRESS) {
@@ -1131,8 +1136,8 @@ void send_IF5(RU_t *ru, openair0_timestamp proc_timestamp, int subframe, uint8_t
data_block = (uint16_t*)(alaw_buffer + APP_HEADER_SIZE_BYTES);
}
for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID, packet_id );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_COMPR_IF, 1 );
//VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID, packet_id );
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_COMPR_IF, 1 );
clock_gettime( CLOCK_MONOTONIC, &start_comp);
for (i=0; i < fp->nb_antennas_rx; i++) {
for (element_id=0; element_id< spp_eth; element_id++){
@@ -1142,8 +1147,8 @@ void send_IF5(RU_t *ru, openair0_timestamp proc_timestamp, int subframe, uint8_t
}
clock_gettime( CLOCK_MONOTONIC, &end_comp);
LOG_D(HW,"[SF %d] Compress_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_comp, end_comp));
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_COMPR_IF, 0 );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF0, 1 );
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_COMPR_IF, 0 );
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF0, 1 );
clock_gettime( CLOCK_MONOTONIC, &start_comp);
ru->ifdevice.trx_write_func(&ru->ifdevice,
(proc_timestamp + packet_id*spp_eth),
@@ -1310,9 +1315,9 @@ void send_IF5(RU_t *ru, openair0_timestamp proc_timestamp, int subframe, uint8_t
void recv_IF5(RU_t *ru, openair0_timestamp *proc_timestamp, int subframe, uint16_t packet_type) {
LTE_DL_FRAME_PARMS *fp=ru->frame_parms;
int32_t *txp[fp->nb_antennas_tx], *rxp[fp->nb_antennas_rx];
int32_t *txp[ru->nb_tx], *rxp[ru->nb_rx];
uint16_t packet_id=0, i=0, element_id=0;
uint16_t packet_id=0, i=0;
#ifdef DEBUG_UL_MOBIPASS
//int8_t dummy_buffer_rx[fp->samples_per_tti*2];
uint8_t rxe;
@@ -1321,11 +1326,12 @@ void recv_IF5(RU_t *ru, openair0_timestamp *proc_timestamp, int subframe, uint16
int32_t spp_eth = (int32_t) ru->ifdevice.openair0_cfg->samples_per_packet;
int32_t spsf = (int32_t) ru->ifdevice.openair0_cfg->samples_per_frame/10;
void *alaw_buffer = ru->ifbuffer.rx;
uint16_t *data_block = NULL;
uint16_t *j = NULL;
openair0_timestamp timestamp[spsf / spp_eth];
openair0_timestamp timestamp[ru->nb_rx*spsf / spp_eth];
long timein[ru->nb_rx*spsf/spp_eth];
long timeout[ru->nb_rx*spsf/spp_eth];
struct timespec if_time;
memset(timestamp, 0, sizeof(timestamp));
eth_state_t *eth = (eth_state_t*) (ru->ifdevice.priv);
@@ -1333,6 +1339,9 @@ void recv_IF5(RU_t *ru, openair0_timestamp *proc_timestamp, int subframe, uint16
if (packet_type == IF5_RRH_GW_DL) {
if (eth->compression == ALAW_COMPRESS) {
AssertFatal(1==0,"IF5 compression needs reworking\n");
/*
if (eth->flags == ETH_RAW_MODE) {
data_block = (uint16_t*)(alaw_buffer + APP_HEADER_SIZE_BYTES + MAC_HEADER_SIZE_BYTES);
} else {
@@ -1364,13 +1373,14 @@ void recv_IF5(RU_t *ru, openair0_timestamp *proc_timestamp, int subframe, uint16
LOG_D(HW,"[SF %d] Decomperss_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_decomp, end_decomp));
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, 0 );
}
*/
} else if (eth->compression == NO_COMPRESS) {
for (i=0; i < fp->nb_antennas_tx; i++)
txp[i] = (void*)&ru->common.txdata[i][subframe*fp->samples_per_tti];
for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RECV_IF5_PKT_ID, packet_id );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF0, 1 );
//VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RECV_IF5_PKT_ID, packet_id );
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF0, 1 );
clock_gettime( CLOCK_MONOTONIC, &start_decomp);
ru->ifdevice.trx_read_func(&ru->ifdevice,
&timestamp[packet_id],
@@ -1379,7 +1389,7 @@ void recv_IF5(RU_t *ru, openair0_timestamp *proc_timestamp, int subframe, uint16
fp->nb_antennas_tx);
clock_gettime( CLOCK_MONOTONIC, &end_decomp);
LOG_D(HW,"[SF %d] IF_Read_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_decomp, end_decomp));
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF0, 0 );
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF0, 0 );
for (i=0; i < fp->nb_antennas_tx; i++)
txp[i] += spp_eth;
@@ -1389,6 +1399,8 @@ void recv_IF5(RU_t *ru, openair0_timestamp *proc_timestamp, int subframe, uint16
} else if (packet_type == IF5_RRH_GW_UL) {
if (eth->compression == ALAW_COMPRESS) {
AssertFatal(1==0,"IF5 compression needs reworking\n");
/*
if (eth->flags == ETH_RAW_MODE) {
data_block = (uint16_t*)(alaw_buffer + APP_HEADER_SIZE_BYTES + MAC_HEADER_SIZE_BYTES);
} else {
@@ -1419,197 +1431,55 @@ void recv_IF5(RU_t *ru, openair0_timestamp *proc_timestamp, int subframe, uint16
LOG_D(HW,"[SF %d] Decomperss_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_decomp, end_decomp));
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, 0 );
}
*/
} else if (eth->compression == NO_COMPRESS) {
for (i=0; i < fp->nb_antennas_rx; i++)
rxp[i] = (void*)&ru->common.rxdata[i][subframe*fp->samples_per_tti];
for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID, packet_id );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF0, 1 );
clock_gettime( CLOCK_MONOTONIC, &start_decomp);
ru->ifdevice.trx_read_func(&ru->ifdevice,
int16_t temp_rx[spp_eth*2] __attribute__((aligned(32)));
for (i=0; i < ru->nb_rx; i++)
rxp[i] = &ru->common.rxdata[i][subframe*fp->samples_per_tti];
int aid;
int firstTS=1;
openair0_timestamp oldTS=0;
for (packet_id=0; packet_id < ru->nb_rx*spsf / spp_eth; packet_id++) {
//VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID, packet_id );
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF0, 1 );
clock_gettime( CLOCK_MONOTONIC, &if_time);
timein[packet_id] = if_time.tv_nsec;
ru->ifdevice.trx_read_func2(&ru->ifdevice,
&timestamp[packet_id],
(void**)rxp,
(void*)temp_rx,
spp_eth,
fp->nb_antennas_rx);
&aid);
clock_gettime( CLOCK_MONOTONIC, &if_time);
timeout[packet_id] = if_time.tv_nsec;
timestamp[packet_id] /= (30720/spsf);
LOG_D(PHY,"subframe %d: Received packet %d: aid %d, TS %llu, oldTS %llu, diff %lld, \n",subframe,packet_id,aid,(unsigned long long)timestamp[packet_id],(unsigned long long)oldTS,(unsigned long long)(timestamp[packet_id]-timestamp[0]));
if (aid==0) {
if (firstTS==1) firstTS=0;
else if (oldTS + 256 != timestamp[packet_id]) {
LOG_I(PHY,"oldTS %llu, newTS %llu, diff %llu, timein %lu, timeout %lu\n",(long long unsigned int)oldTS,(long long unsigned int)timestamp[packet_id],(long long unsigned int)timestamp[packet_id]-oldTS,timein[packet_id],timeout[packet_id]);
for (int i=0;i<=packet_id;i++) LOG_I(PHY,"packet %d TS %llu, timein %lu, timeout %lu\n",i,(long long unsigned int)timestamp[i],timein[i],timeout[i]);
AssertFatal(1==0,"fronthaul problem\n");
}
oldTS = timestamp[packet_id];
}
// HYPOTHESIS: first packet per subframe has lowest timestamp of subframe
// should detect out of order and act accordingly ....
AssertFatal(aid==0 || aid==1,"aid %d != 0 or 1\n",aid);
//LOG_I(PHY,"rxp[%d] %p, dest %p, offset %d (%lld,%lld)\n",aid,rxp[aid],rxp[aid]+(timestamp[packet_id]-timestamp[0]),(timestamp[packet_id]-timestamp[0]),timestamp[packet_id],timestamp[0]);
memcpy((void*)(rxp[aid]+(timestamp[packet_id]-timestamp[0])),
(void*)temp_rx,
spp_eth<<2);
clock_gettime( CLOCK_MONOTONIC, &end_decomp);
LOG_D(HW,"[SF %d] IF_Read_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_decomp, end_decomp));
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF0, 0 );
for (i=0; i < fp->nb_antennas_rx; i++)
rxp[i] += spp_eth;
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF0, 0 );
}
}
*proc_timestamp = timestamp[0];
} else if (packet_type == IF5_MOBIPASS) {
if (ru->if_timing == synch_to_mobipass_standalone) {
uint16_t db_fulllength = PAYLOAD_MOBIPASS_NUM_SAMPLES;
openair0_timestamp timestamp_mobipass[fp->samples_per_tti/db_fulllength];
int32_t *rx_buffer=NULL;
__m128i *data_block=NULL, *data_block_head=NULL;
__m128i *rxp128;
__m128i r0;
unsigned char _rx_buffer[MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t)];
rx_buffer = (int32_t *)_rx_buffer;
data_block_head = (__m128i *)((uint8_t *)rx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t);
rxp[0] = (void*)&ru->common.rxdata[0][subframe*ru->frame_parms->samples_per_tti];
rxp128 = (__m128i *) (rxp[0]);
packet_id=0;
while(packet_id<fp->samples_per_tti/db_fulllength) {
data_block = data_block_head;
ru->ifdevice.trx_read_func(&ru->ifdevice,
&timestamp_mobipass[packet_id],
(void**)&rx_buffer,
db_fulllength,
1
);
//store rxdata and increase packet_id
rxp[0] = (void*)&ru->common.rxdata[0][(subframe*ru->frame_parms->samples_per_tti)+packet_id*db_fulllength];
rxp128 = (__m128i *) (rxp[0]);
for (i=0; i<db_fulllength>>2; i+=2) {
r0 = _mm_loadu_si128(data_block++);
*rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpacklo_epi8(r0,r0),8),4);
*rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpackhi_epi8(r0,r0),8),4);
}
packet_id++;
}//end while
*proc_timestamp = ntohl(timestamp_mobipass[0]);
} else {
uint16_t db_fulllength = PAYLOAD_MOBIPASS_NUM_SAMPLES;
openair0_timestamp timestamp_mobipass[fp->samples_per_tti/db_fulllength];
#ifdef DEBUG_UL_MOBIPASS
int lower_offset = 0;
int upper_offset = 70000;
#endif
int subframe_skip = 0;
int reset_flag = 0;
int32_t *rx_buffer=NULL;
__m128i *data_block=NULL, *data_block_head=NULL;
__m128i *rxp128;
__m128i r0;
//rx_buffer = memalign(16, MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t));
rx_buffer = malloc(MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t));
IF5_mobipass_header_t *header = (IF5_mobipass_header_t *)((uint8_t *)rx_buffer + MAC_HEADER_SIZE_BYTES);
data_block_head = (__m128i *)((uint8_t *)rx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t);
rxp[0] = (void*)&ru->common.rxdata[0][subframe*ru->frame_parms->samples_per_tti];
rxp128 = (__m128i *) (rxp[0]);
RU_proc_t *proc = &ru->proc;
/*
// while(packet_id<fp->samples_per_tti/db_fulllength) {
data_block = data_block_head;
eNB->ifdevice.trx_read_func(&eNB->ifdevice,
&ts0,
(void**)&rx_buffer,
db_fulllength,
1
);
if ((header->seqno == 1)&&(first_packet==1)) {
first_packet = 0; //ignore the packets before synchnorization
packet_id = 0;
ts_offset = ntohl(ts0);
}
if (first_packet==0) {
packet_cnt++;
ts = ntohl(ts0);
packet_id = (ts-ts_offset)/db_fulllength;
packet_id = packet_id % (fp->samples_per_tti/db_fulllength);
printf("[IF5_tools]packet_id:%d\n", packet_id);
// if (ts_stored == 0) {
// ts_stored = 1;
*proc_timestamp = ntohl(ts - (packet_id*db_fulllength));
// }
rxp[0] = (void*)&eNB->common_vars.rxdata[0][0][(subframe*eNB->frame_parms.samples_per_tti)+packet_id*db_fulllength];
rxp128 = (__m128i *) (rxp[0]);
for (i=0; i<db_fulllength>>2; i+=2) {
r0 = _mm_loadu_si128(data_block++);
*rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpacklo_epi8(r0,r0),8),4);
*rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpackhi_epi8(r0,r0),8),4);
}
}
// }//end while
*/
packet_id=0;
while(packet_id<fp->samples_per_tti/db_fulllength) {
data_block = data_block_head;
ru->ifdevice.trx_read_func(&ru->ifdevice,
&timestamp_mobipass[packet_id],
(void**)&rx_buffer,
db_fulllength,
1
);
#ifdef DEBUG_UL_MOBIPASS
if (((proc->timestamp_tx + lower_offset) > ntohl(timestamp_mobipass[packet_id])) || ((proc->timestamp_tx + upper_offset) < ntohl(timestamp_mobipass[packet_id]))) {
//ignore the packet
subframe_skip_extra = (subframe_skip_extra + 1)%67;
LOG_D("[Mobipass] ignored packet, id:[%d,%d], proc->timestamp_tx:%llu, proc->timestamp_rx:%llu, seqno:%d\n", packet_id,subframe_skip_extra, proc->timestamp_tx, ntohl(timestamp_mobipass[packet_id]), header->seqno);
}
#endif
//skip SUBFRAME_SKIP_NUM_MOBIPASS additional UL packets
if ((start_flag == 1) && (subframe_skip < SUBFRAME_SKIP_NUM_MOBIPASS)){
subframe_skip++;
offset_cnt = header->seqno;
} else {
if ((offset_cnt != header->seqno) && (start_flag == 0) && (proc->first_rx > 3)){
#ifdef DEBUG_UL_MOBIPASS
LOG_D(PHY,"[Mobipass] Reset sequence number, offset_cnt:%d, header->seqno:%d, packet_id:%d\n", offset_cnt, header->seqno, packet_id);
#endif
reset_flag=1;
}
if ((reset_flag == 1) && (proc->first_rx > 3 ) && (start_flag == 0) && (packet_id == 0)) {
packet_id = 1;
reset_flag = 0;
}
start_flag = 0;
//store rxdata and increase packet_id
rxp[0] = (void*)&ru->common.rxdata[0][(subframe*ru->frame_parms->samples_per_tti)+packet_id*db_fulllength];
rxp128 = (__m128i *) (rxp[0]);
for (i=0; i<db_fulllength>>2; i+=2) {
r0 = _mm_loadu_si128(data_block++);
*rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpacklo_epi8(r0,r0),8),4);
*rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpackhi_epi8(r0,r0),8),4);
}
packet_id++;
offset_cnt = (header->seqno+1)&255;
}
}//end while
*proc_timestamp = ntohl(timestamp_mobipass[0]);
#ifdef DEBUG_UL_MOBIPASS
LOG_I(PHY,"[Mobipass][Recv_MOBIPASS] timestamp: %llu\n ", *proc_timestamp);
if (eNB->CC_id>0) {
rxe = dB_fixed(signal_energy(rxp[0],fp->samples_per_tti));
if (rxe > 0){
LOG_I(PHY,"[Mobipass] frame:%d, subframe:%d, energy %d\n", (*proc_timestamp/(10*fp->samples_per_tti))&1023,subframe, rxe);
// LOG_M("rxsigmb.m","rxs",(void*)dummy_buffer_rx, fp->samples_per_tti,1, 5);
// exit(-1);
}
}
#endif
free(rx_buffer);
}
} else {
AssertFatal(1==0, "recv_IF5 - Unknown packet_type %x", packet_type);
}
+27 -25
View File
@@ -89,7 +89,7 @@ void rx_prach0(PHY_VARS_eNB *eNB,
int32_t *prach_ifft=(int32_t *)NULL;
int32_t **prach_ifftp=(int32_t **)NULL;
int prach_ifft_cnt=0;
int exit_flag=0;
LTE_DL_FRAME_PARMS *fp;
int nb_rx;
if(eNB) {
@@ -177,32 +177,33 @@ void rx_prach0(PHY_VARS_eNB *eNB,
}
AssertFatal(ru!=NULL,"ru is null\n");
int8_t dBEn0=0;
for (aa=0; aa<nb_rx; aa++) {
if (ru->if_south == LOCAL_RF) { // set the time-domain signal if we have to use it in this node
if (ru->if_south == LOCAL_RF || ru->function == NGFI_RAU_IF5) { // set the time-domain signal if we have to use it in this node
// DJP - indexing below in subframe zero takes us off the beginning of the array???
prach[aa] = (int16_t *)&ru->common.rxdata[aa][(subframe*fp->samples_per_tti)-ru->N_TA_offset];
if (LOG_DUMPFLAG(PRACH)) {
int32_t en0=signal_energy((int32_t *)prach[aa],fp->samples_per_tti);
int8_t dbEn0 = dB_fixed(en0);
int8_t rach_dBm = dbEn0 - ru->rx_total_gain_dB;
dBEn0 = dB_fixed(en0);
int8_t rach_dBm = dBEn0 - ru->rx_total_gain_dB;
char buffer[80];
if (dbEn0>32 && prach[0]!= NULL) {
if (dBEn0>30 && prach[0]!= NULL) {
static int counter=0;
sprintf(buffer, "%s%d", "/tmp/prach_rx",counter);
LOG_M(buffer,"prach_rx",prach[0],fp->samples_per_tti,1,13);
sprintf(buffer, "%s%d", "/tmp/prach_rx.m",counter);
LOG_M(buffer,"prach_rx",prach[0],fp->samples_per_tti,1,1);
exit_flag=1;
}
if (dB_fixed(en0)>32) {
if (dBEn0>30) {
sprintf(buffer, "rach_dBm:%d",rach_dBm);
if (prach[0]!= NULL) LOG_M("prach_rx","prach_rx",prach[0],fp->samples_per_tti,1,1);
if (prach[0]!= NULL) LOG_M("prach_rx.m","prach_rx",prach[0],fp->samples_per_tti,1,1);
LOG_I(PHY,"RU %d, br_flag %d ce_level %d frame %d subframe %d per_tti:%d prach:%p (energy %d) TA:%d %s rxdata:%p index:%d\n",
ru->idx,br_flag,ce_level,frame_prach,subframe,fp->samples_per_tti,
prach[aa],dbEn0,ru->N_TA_offset,buffer,ru->common.rxdata[aa],
prach[aa],dBEn0,ru->N_TA_offset,buffer,ru->common.rxdata[aa],
(subframe*fp->samples_per_tti)-ru->N_TA_offset);
}
}
@@ -415,7 +416,7 @@ void rx_prach0(PHY_VARS_eNB *eNB,
if ( LOG_DEBUGFLAG(PRACH)) {
int en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840));
if ((en > 60)&&(br_flag==1)) LOG_I(PHY,"PRACH (br_flag %d,ce_level %d, n_ra_prb %d, k %d): Frame %d, Subframe %d => %d dB\n",br_flag,ce_level,n_ra_prb,k,frame_prach,subframe,en);
if ((en > 10)&&(br_flag==1)) LOG_I(PHY,"PRACH (br_flag %d,ce_level %d, n_ra_prb %d, k %d): Frame %d, Subframe %d => %d dB\n",br_flag,ce_level,n_ra_prb,k,frame_prach,subframe,en);
}
}
@@ -454,9 +455,9 @@ void rx_prach0(PHY_VARS_eNB *eNB,
for (preamble_index=0 ; preamble_index<64 ; preamble_index++) {
if (LOG_DEBUGFLAG(PRACH)) {
int en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840));
// int en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840));
if (en>60) LOG_I(PHY,"frame %d, subframe %d : Trying preamble %d (br_flag %d)\n",frame_prach,subframe,preamble_index,br_flag);
if (dBEn0>30) LOG_I(PHY,"frame %d, subframe %d : Trying preamble %d (br_flag %d)\n",frame_prach,subframe,preamble_index,br_flag);
}
if (restricted_set == 0) {
@@ -539,10 +540,10 @@ void rx_prach0(PHY_VARS_eNB *eNB,
// Compute DFT of RX signal (conjugate input, results in conjugate output) for each new rootSequenceIndex
if (LOG_DEBUGFLAG(PRACH)) {
int en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840));
//en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840));
if (en>60) LOG_I(PHY,"frame %d, subframe %d : preamble index %d: offset %d, preamble shift %d (br_flag %d, en %d)\n",
frame_prach,subframe,preamble_index,preamble_offset,preamble_shift,br_flag,en);
if (dBEn0>30) LOG_I(PHY,"frame %d, subframe %d : preamble index %d: offset %d, preamble shift %d (br_flag %d, en %d)\n",
frame_prach,subframe,preamble_index,preamble_offset,preamble_shift,br_flag,dBEn0);
}
log2_ifft_size = 10;
@@ -564,13 +565,13 @@ void rx_prach0(PHY_VARS_eNB *eNB,
memset(prachF, 0, sizeof(int16_t)*2*1024 );
if (LOG_DUMPFLAG(PRACH)) {
if (LOG_DUMPFLAG(PRACH)) {
if (prach[0]!= NULL) LOG_M("prach_rx0.m","prach_rx0",prach[0],6144+792,1,1);
LOG_M("prach_rx1.m","prach_rx1",prach[1],6144+792,1,1);
LOG_M("prach_rxF0.m","prach_rxF0",rxsigF[0],12288,1,1);
LOG_M("prach_rxF1.m","prach_rxF1",rxsigF[1],12288,1,1);
}
}
for (aa=0; aa<nb_rx; aa++) {
// Do componentwise product with Xu* on each antenna
@@ -633,9 +634,9 @@ void rx_prach0(PHY_VARS_eNB *eNB,
*max_preamble = preamble_index;
if (LOG_DEBUGFLAG(PRACH)) {
int en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840));
// int en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840));
if ((en>60) && (br_flag==1))
if (dBEn0>30)
LOG_D(PHY,"frame %d, subframe %d : max_preamble_energy %d, max_preamble_delay %d, max_preamble %d (br_flag %d,ce_level %d, levdB %d, lev %d)\n",
frame_prach,subframe,
*max_preamble_energy,*max_preamble_delay,
@@ -648,10 +649,10 @@ void rx_prach0(PHY_VARS_eNB *eNB,
*avg_preamble_energy=dB_fixed(avg_en/64);
if (LOG_DUMPFLAG(PRACH)) {
if (exit_flag==1) {
int en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840));
if (en>60) {
if (en>30) {
k = (12*n_ra_prb) - 6*fp->N_RB_UL;
if (k<0) k+=fp->ofdm_symbol_size;
@@ -665,19 +666,20 @@ void rx_prach0(PHY_VARS_eNB *eNB,
LOG_M("prach_rxF_comp0.m","prach_rxF_comp0",prachF,1024,1,1);
LOG_M("Xu.m","xu",Xu,N_ZC,1,1);
LOG_M("prach_ifft0.m","prach_t0",prach_ifft,1024,1,1);
exit(-1);
LOG_M("SF2_3.m","sf2_3",&ru->common.rxdata[0][2*fp->samples_per_tti],2*fp->samples_per_tti,1,1);
} else {
LOG_E(PHY,"Dumping prach (br_flag %d), k = %d (n_ra_prb %d)\n",br_flag,k,n_ra_prb);
LOG_M("rxsigF_br.m","prach_rxF_br",&rxsigF[0][0],12288,1,1);
LOG_M("prach_rxF_comp0_br.m","prach_rxF_comp0_br",prachF,1024,1,1);
LOG_M("Xu_br.m","xu_br",Xu,N_ZC,1,1);
LOG_M("prach_ifft0_br.m","prach_t0_br",prach_ifft,1024,1,1);
exit(-1);
}
}
} /* LOG_DUMPFLAG(PRACH) */
if (eNB) stop_meas(&eNB->rx_prach);
AssertFatal(exit_flag==0,"exiting\n");
}
+4 -14
View File
@@ -90,9 +90,8 @@ void PHY_ofdm_mod(int *input, /// pointer to complex input
if(nb_symbols == 0) return;
short temp[2*2*6144*4] __attribute__((aligned(32)));
unsigned short i,j;
short k;
int16_t temp[2*2*6144*4] __attribute__((aligned(32)));
int i,j;
volatile int *output_ptr=(int*)0;
@@ -190,18 +189,9 @@ void PHY_ofdm_mod(int *input, /// pointer to complex input
if (fftsize==128)
#endif
{
/*for (j=0; j<fftsize ; j++) {
output_ptr[j] = temp_ptr[j];
}*/
memcpy1((void*)output_ptr,(void*)temp_ptr,fftsize<<2);
memcpy((void*)output_ptr,(void*)temp_ptr,fftsize<<2);
}
j=fftsize;
for (k=-1; k>=-nb_prefix_samples; k--) {
output_ptr[k] = output_ptr[--j];
}
memcpy((void*)&output_ptr[-nb_prefix_samples],(void*)&output_ptr[fftsize-nb_prefix_samples],nb_prefix_samples<<2);
break;
case CYCLIC_SUFFIX:
@@ -33,12 +33,12 @@
// last channel estimate of the receiver
void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
PHY_VARS_NR_UE *ue,
module_id_t gNB_id,
uint8_t frame,
uint8_t subframe,
unsigned char clear,
short coef)
PHY_VARS_NR_UE *ue,
module_id_t gNB_id,
uint8_t frame,
uint8_t subframe,
unsigned char clear,
short coef)
{
static int max_pos_fil = 0;
@@ -47,6 +47,7 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
int temp = 0, i, aa, max_val = 0, max_pos = 0;
int diff;
short Re,Im,ncoef;
uint8_t sync_offset = 0;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_IN);
@@ -80,11 +81,14 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
// do not filter to have proactive timing adjustment
//max_pos_fil = max_pos;
if(subframe == 0)
{
diff = max_pos_fil - (frame_parms->nb_prefix_samples>>3);
if ( abs(diff) < SYNCH_HYST )
if (frame_parms->freq_range==nr_FR2)
sync_offset = 2;
else
sync_offset = 0;
if ( abs(diff) < (SYNCH_HYST+sync_offset) )
ue->rx_offset = 0;
else
ue->rx_offset = diff;
@@ -134,5 +138,5 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
#endif //DEBUG_PHY
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_OUT);
}
}
@@ -243,7 +243,7 @@ void nr_ue_rsrp_measurements(PHY_VARS_NR_UE *ue,
unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier;
if (ssb_offset>= ue->frame_parms.ofdm_symbol_size) ssb_offset-=ue->frame_parms.ofdm_symbol_size;
symbol_offset = ue->frame_parms.ofdm_symbol_size*(ue->symbol_offset+1);
symbol_offset = ue->frame_parms.ofdm_symbol_size*((ue->symbol_offset+1)%(ue->frame_parms.symbols_per_slot));
ue->measurements.rsrp[eNB_offset] = 0;
+4 -1
View File
@@ -373,7 +373,10 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF,
for (int rb=0;rb<coreset_nbr_rb;rb++,c_rb++) {
c_rb_by6 = c_rb/6;
// skip zeros in frequency domain bitmap
while ((coreset_freq_dom[c_rb_by6>>3] & (1<<(c_rb_by6&7))) == 0) c_rb+=6;
while ((coreset_freq_dom[c_rb_by6>>3] & (1<<(7-(c_rb_by6&7)))) == 0) {
c_rb+=6;
c_rb_by6 = c_rb/6;
}
LOG_DDD("c_rb=%d\n",c_rb);
rxF=NULL;
@@ -304,8 +304,11 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode,
if (ret == 0) {
// sync at symbol ue->symbol_offset
// computing the offset wrt the beginning of the frame
sync_pos_frame = (fp->ofdm_symbol_size + fp->nb_prefix_samples0)+((ue->symbol_offset)-1)*(fp->ofdm_symbol_size + fp->nb_prefix_samples);
int mu = fp->numerology_index;
// number of symbols with different prefix length
// every 7*(1<<mu) symbols there is a different prefix length (38.211 5.3.1)
int n_symb_prefix0 = (ue->symbol_offset/(7*(1<<mu)))+1;
sync_pos_frame = n_symb_prefix0*(fp->ofdm_symbol_size + fp->nb_prefix_samples0)+(ue->symbol_offset-n_symb_prefix0)*(fp->ofdm_symbol_size + fp->nb_prefix_samples);
if (ue->ssb_offset < sync_pos_frame)
ue->rx_offset = fp->samples_per_frame - sync_pos_frame + ue->ssb_offset;
else
+2 -1
View File
@@ -62,7 +62,7 @@ uint16_t nr_pbch_extract(int **rxdataF,
unsigned int rx_offset = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier; //and
// if (rx_offset>= frame_parms->ofdm_symbol_size) rx_offset-=frame_parms->ofdm_symbol_size;
rx_offset=(rx_offset)%(frame_parms->ofdm_symbol_size);
rx_offset=(rx_offset)%(frame_parms->ofdm_symbol_size);
AssertFatal(symbol>=1 && symbol<5,
"symbol %d illegal for PBCH extraction\n",
@@ -538,6 +538,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
M = NR_POLAR_PBCH_E;
nushift = (Lmax==4)? i_ssb&3 : i_ssb&7;
uint32_t unscrambling_mask = (Lmax==64)?0x100006D:0x1000041;
nr_pbch_unscrambling(nr_ue_pbch_vars,frame_parms->Nid_cell,nushift,M,NR_POLAR_PBCH_E,0,0);
//polar decoding de-rate matching
const t_nrPolar_params *currentPtr = nr_polar_params( NR_POLAR_PBCH_MESSAGE_TYPE, NR_POLAR_PBCH_PAYLOAD_BITS, NR_POLAR_PBCH_AGGREGATION_LEVEL,1,&ue->polarList);
+2
View File
@@ -389,6 +389,8 @@ typedef struct {
short n0_subband_power_tot_dB[100];
//! estimated avg noise power per RB (dBm)
short n0_subband_power_tot_dBm[100];
//! etimated avg noise power over all RB (dB)
short n0_subband_power_avg_dB;
// eNB measurements (per user)
//! estimated received spatial signal power (linear)
unsigned int rx_spatial_power[NUMBER_OF_UE_MAX][2][2];
+1 -1
View File
@@ -228,7 +228,7 @@ typedef struct {
/// Pointer to Msg3 payload for UL-grant
uint8_t *Msg3;
/// Frame of last completed synch
uint8_t sync_frame;
uint16_t sync_frame;
/// Flag to indicate that prach is ready to start: it is enabled with an initial delay after the sync
uint8_t init_msg1;
} NR_PRACH_RESOURCES_t;
+12 -12
View File
@@ -757,8 +757,8 @@ void fill_sr_indication(int UEid, PHY_VARS_eNB *eNB,uint16_t rnti,int frame,int
// pdu->rx_ue_information.handle = handle;
pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG;
pdu->rx_ue_information.rnti = rnti;
int SNRtimes10 = dB_fixed_times10(stat) - 10 * eNB->measurements.n0_subband_power_dB[0][0];
LOG_D(PHY,"stat %d subbandpower %d, SNRtimes10 %d\n", stat, eNB->measurements.n0_subband_power_dB[0][0], SNRtimes10);
int SNRtimes10 = dB_fixed_times10(stat) - 10 * eNB->measurements.n0_subband_power_avg_dB;
LOG_D(PHY,"stat %d subband n0 %d, SNRtimes10 %d\n", stat, eNB->measurements.n0_subband_power_avg_dB, SNRtimes10);
pdu->ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG;
if (SNRtimes10 < -640) pdu->ul_cqi_information.ul_cqi=0;
@@ -1604,8 +1604,8 @@ void fill_rx_indication(PHY_VARS_eNB *eNB,
timing_advance_update = 63;
pdu->rx_indication_rel8.timing_advance = timing_advance_update;
// estimate UL_CQI for MAC (from antenna port 0 only)
int SNRtimes10 = dB_fixed_times10(eNB->pusch_vars[UE_id]->ulsch_power[0]) - 10 * eNB->measurements.n0_subband_power_dB[0][0];
// estimate UL_CQI for MAC
int SNRtimes10 = dB_fixed_times10(eNB->pusch_vars[UE_id]->ulsch_power[0] + ((eNB->frame_parms.nb_antennas_rx>1) ?eNB->pusch_vars[UE_id]->ulsch_power[1] : 0 )) - 10 * eNB->measurements.n0_subband_power_avg_dB;
if (SNRtimes10 < -640)
pdu->rx_indication_rel8.ul_cqi = 0;
@@ -1614,8 +1614,8 @@ void fill_rx_indication(PHY_VARS_eNB *eNB,
else
pdu->rx_indication_rel8.ul_cqi = (640 + SNRtimes10) / 5;
LOG_D(PHY,"[PUSCH %d] Frame %d Subframe %d Filling RX_indication with SNR %d (%d), timing_advance %d (update %d)\n",
harq_pid,frame,subframe,SNRtimes10,pdu->rx_indication_rel8.ul_cqi,pdu->rx_indication_rel8.timing_advance,
LOG_D(PHY,"[PUSCH %d] Frame %d Subframe %d Filling RX_indication with SNR %d (%d,%d), timing_advance %d (update %d)\n",
harq_pid,frame,subframe,SNRtimes10,pdu->rx_indication_rel8.ul_cqi,eNB->measurements.n0_subband_power_avg_dB,pdu->rx_indication_rel8.timing_advance,
timing_advance_update);
eNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus++;
eNB->UL_INFO.rx_ind.sfn_sf = frame<<4 | subframe;
@@ -1919,7 +1919,7 @@ void fill_uci_harq_indication (int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, in
pdu->rx_ue_information.rnti = uci->rnti;
// estimate UL_CQI for MAC (from antenna port 0 only)
pdu->ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG;
int SNRtimes10 = dB_fixed_times10(uci->stat) - 10 * eNB->measurements.n0_subband_power_dB[0][0];
int SNRtimes10 = dB_fixed_times10(uci->stat) - 10 * eNB->measurements.n0_subband_power_avg_dB;
if (SNRtimes10 < -100)
LOG_I (PHY, "uci->stat %d \n", uci->stat);
@@ -2132,17 +2132,17 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
lte_eNB_I0_measurements (eNB, subframe, 0, eNB->first_run_I0_measurements);
int min_I0=1000,max_I0=0;
if ((frame==0) && (subframe==4)) {
int amin=0,amax=0;
if ((frame==0) && (subframe==3)) {
for (int i=0; i<eNB->frame_parms.N_RB_UL; i++) {
if (i==(eNB->frame_parms.N_RB_UL>>1) - 1) i+=2;
if (eNB->measurements.n0_subband_power_tot_dB[i]<min_I0) min_I0 = eNB->measurements.n0_subband_power_tot_dB[i];
if (eNB->measurements.n0_subband_power_tot_dB[i]<min_I0) {min_I0 = eNB->measurements.n0_subband_power_tot_dB[i]; amin=i;}
if (eNB->measurements.n0_subband_power_tot_dB[i]>max_I0) max_I0 = eNB->measurements.n0_subband_power_tot_dB[i];
if (eNB->measurements.n0_subband_power_tot_dB[i]>max_I0) {max_I0 = eNB->measurements.n0_subband_power_tot_dB[i]; amax=i;}
}
LOG_I (PHY, "max_I0 %d, min_I0 %d\n", max_I0, min_I0);
LOG_I (PHY, "max_I0 %d (rb %d), min_I0 %d (rb %d), avg I0 %d\n", max_I0, amax, min_I0, amin, eNB->measurements.n0_subband_power_avg_dB);
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_UESPEC, 0 );
+1 -1
View File
@@ -239,7 +239,7 @@ void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) {
if (decodeSuccess) {
memcpy(ulsch_harq->b+rdata->offset,
ulsch_harq->c[r],
rdata->Kr_bytes- - (ulsch_harq->F>>3) -((ulsch_harq->C>1)?3:0));
rdata->Kr_bytes - (ulsch_harq->F>>3) -((ulsch_harq->C>1)?3:0));
} else {
if ( rdata->nbSegments != ulsch_harq->processedSegments ) {
+25 -25
View File
@@ -311,7 +311,6 @@ void nr_ue_pbch_procedures(uint8_t gNB_id,
{
// int i;
//int pbch_tx_ant=0;
//uint8_t pbch_phase;
int ret = 0;
//static uint8_t first_run = 1;
//uint8_t pbch_trials = 0;
@@ -323,7 +322,7 @@ void nr_ue_pbch_procedures(uint8_t gNB_id,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_IN);
//LOG_I(PHY,"[UE %d] Frame %d, Trying PBCH %d (NidCell %d, gNB_id %d)\n",ue->Mod_id,frame_rx,pbch_phase,ue->frame_parms.Nid_cell,gNB_id);
LOG_D(PHY,"[UE %d] Frame %d, Trying PBCH (NidCell %d, gNB_id %d)\n",ue->Mod_id,frame_rx,ue->frame_parms.Nid_cell,gNB_id);
ret = nr_rx_pbch(ue, proc,
ue->pbch_vars[gNB_id],
@@ -1710,7 +1709,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
int frame_rx = proc->frame_rx;
int nr_slot_rx = proc->nr_slot_rx;
int slot_pbch;
//int slot_ssb;
int slot_ssb;
NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[proc->thread_id][0];
fapi_nr_config_request_t *cfg = &ue->nrUE_config;
@@ -1734,38 +1733,38 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
if (pdcch_vars->nb_search_space > 0)
get_coreset_rballoc(pdcch_vars->pdcch_config[0].coreset.frequency_domain_resource,&coreset_nb_rb,&coreset_start_rb);
slot_pbch = is_pbch_in_slot(cfg, frame_rx, nr_slot_rx, fp);
//slot_ssb = is_ssb_in_slot(cfg, frame_rx, nr_slot_rx, fp);
slot_ssb = is_ssb_in_slot(cfg, frame_rx, nr_slot_rx, fp);
// looking for pbch only in slot where it is supposed to be
if ((ue->decode_MIB == 1) && slot_pbch)
{
LOG_D(PHY," ------ PBCH ChannelComp/LLR: frame.slot %d.%d ------ \n", frame_rx%1024, nr_slot_rx);
for (int i=1; i<4; i++) {
if (slot_ssb) {
LOG_D(PHY," ------ PBCH ChannelComp/LLR: frame.slot %d.%d ------ \n", frame_rx%1024, nr_slot_rx);
for (int i=1; i<4; i++) {
nr_slot_fep(ue,
proc,
(ue->symbol_offset+i)%(fp->symbols_per_slot),
nr_slot_rx,
0,
0);
nr_slot_fep(ue,
proc,
(ue->symbol_offset+i)%(fp->symbols_per_slot),
nr_slot_rx,
0,
0);
#if UE_TIMING_TRACE
start_meas(&ue->dlsch_channel_estimation_stats);
start_meas(&ue->dlsch_channel_estimation_stats);
#endif
nr_pbch_channel_estimation(ue,proc,0,nr_slot_rx,(ue->symbol_offset+i)%(fp->symbols_per_slot),i-1,(fp->ssb_index)&7,fp->half_frame_bit);
nr_pbch_channel_estimation(ue,proc,0,nr_slot_rx,(ue->symbol_offset+i)%(fp->symbols_per_slot),i-1,(fp->ssb_index)&7,fp->half_frame_bit);
#if UE_TIMING_TRACE
stop_meas(&ue->dlsch_channel_estimation_stats);
stop_meas(&ue->dlsch_channel_estimation_stats);
#endif
}
}
//if (mac->csirc->reportQuantity.choice.ssb_Index_RSRP){
nr_ue_rsrp_measurements(ue, proc, nr_slot_rx, 0);
//}
//if (mac->csirc->reportQuantity.choice.ssb_Index_RSRP){
nr_ue_rsrp_measurements(ue,proc,nr_slot_rx,0);
//}
if ((ue->decode_MIB == 1) && slot_pbch) {
LOG_D(PHY," ------ Decode MIB: frame.slot %d.%d ------ \n", frame_rx%1024, nr_slot_rx);
nr_ue_pbch_procedures(gNB_id, ue, proc, 0);
if (ue->no_timing_correction==0) {
@@ -1779,6 +1778,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
16384);
}
}
}
if ((frame_rx%64 == 0) && (nr_slot_rx==0)) {
printf("============================================\n");
@@ -2165,7 +2165,7 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_IN);
if (!prach_resources->init_msg1 && (frame_tx == (ue->prach_resources[gNB_id]->sync_frame + 150) % MAX_FRAME_NUMBER)){
if (!prach_resources->init_msg1 && ((MAX_FRAME_NUMBER+frame_tx-ue->prach_resources[gNB_id]->sync_frame)% MAX_FRAME_NUMBER)>150){
ue->prach_cnt = 0;
prach_resources->init_msg1 = 1;
}
+2 -2
View File
@@ -487,7 +487,7 @@ int n_ch_rlz = 1;
int rx_sample_offset = 0;
int xforms=0;
int dump_table=0;
int loglvl=OAILOG_WARNING;
int loglvl=OAILOG_INFO;
int mcs1=0,mcs2=0,mcs_i=0,dual_stream_UE = 0,awgn_flag=0;
int two_thread_flag=0;
int num_rounds = 4;//,fix_rounds=0;
@@ -670,7 +670,7 @@ int main(int argc, char **argv) {
{ "XForms", "Display the soft scope", PARAMFLAG_BOOL, iptr:&xforms, defintval:0, TYPE_INT, 0 },
{ "Yperfect_ce","Perfect CE", PARAMFLAG_BOOL, iptr:&perfect_ce, defintval:0, TYPE_INT, 0 },
{ "Zdump", "dump table",PARAMFLAG_BOOL, iptr:&dump_table, defintval:0, TYPE_INT, 0 },
{ "Loglvl", "log level",0, iptr:&loglvl, defintval:OAILOG_DEBUG, TYPE_INT, 0 },
{ "Loglvl", "log level",0, iptr:&loglvl, defintval:OAILOG_INFO, TYPE_INT, 0 },
{ "zn_rx", "Number of RX antennas used in UE",0, iptr:NULL, defintval:2, TYPE_INT, 0 },
{ "gchannel", "[A:M] Use 3GPP 25.814 SCM-A/B/C/D('A','B','C','D') or 36-101 EPA('E'), EVA ('F'),ETU('G') models (ignores delay spread and Ricean factor), Rayghleigh8 ('H'), Rayleigh1('I'), Rayleigh1_corr('J'), Rayleigh1_anticorr ('K'), Rice8('L'), Rice1('M')",0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0 },
{ "verbose", "display debug text", PARAMFLAG_BOOL, iptr:&verbose, defintval:0, TYPE_INT, 0 },
+1 -2
View File
@@ -860,7 +860,6 @@ int main(int argc, char **argv)
UE_info->UE_sched_ctrl[0].harq_processes[harq_pid].round = round;
UE_info->UE_sched_ctrl[0].current_harq_pid = harq_pid;
gNB->dlsch[0][0]->harq_processes[harq_pid]->round = round;
for (int i=0; i<MAX_NUM_CORESET; i++)
gNB_mac->UE_info.num_pdcch_cand[0][i] = 0;
@@ -878,7 +877,7 @@ int main(int argc, char **argv)
Sched_INFO.frame = frame;
Sched_INFO.slot = slot;
Sched_INFO.DL_req = &gNB_mac->DL_req[0];
Sched_INFO.UL_tti_req = &gNB_mac->UL_tti_req[0];
Sched_INFO.UL_tti_req = gNB_mac->UL_tti_req_ahead[slot];
Sched_INFO.UL_dci_req = NULL;
Sched_INFO.TX_req = &gNB_mac->TX_req[0];
nr_schedule_response(&Sched_INFO);
+1 -1
View File
@@ -81,7 +81,7 @@ int nr_postDecode_sim(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) {
if (decodeSuccess) {
memcpy(ulsch_harq->b+rdata->offset,
ulsch_harq->c[r],
rdata->Kr_bytes- - (ulsch_harq->F>>3) -((ulsch_harq->C>1)?3:0));
rdata->Kr_bytes - (ulsch_harq->F>>3) -((ulsch_harq->C>1)?3:0));
} else {
if ( rdata->nbSegments != ulsch_harq->processedSegments ) {
int nb=abortTpool(gNB->threadPool, req->key);
+2
View File
@@ -122,6 +122,8 @@ typedef struct x2ap_register_enb_req_s {
* CC Params
*/
int16_t eutra_band[MAX_NUM_CCs];
int32_t nr_band[MAX_NUM_CCs];
int32_t nrARFCN[MAX_NUM_CCs];
uint32_t downlink_frequency[MAX_NUM_CCs];
int32_t uplink_frequency_offset[MAX_NUM_CCs];
uint32_t Nid_cell[MAX_NUM_CCs];
+35 -21
View File
@@ -34,6 +34,7 @@
#include "common/utils/LOG/log_extern.h"
#include "assertions.h"
#include "gnb_config.h"
#include "gnb_paramdef.h"
#include "UTIL/OTG/otg.h"
#include "UTIL/OTG/otg_externs.h"
#include "intertask_interface.h"
@@ -232,8 +233,8 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc,uint64_t ssbmap) {
scc->ssb_PositionsInBurst->choice.shortBitmap.buf[0] |= curr_bit<<i;
}
}else if(ssbmaplen==NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_mediumBitmap){
scc->ssb_PositionsInBurst->choice.mediumBitmap.size = 1;
scc->ssb_PositionsInBurst->choice.mediumBitmap.bits_unused = 0;
scc->ssb_PositionsInBurst->choice.mediumBitmap.size = 1;
scc->ssb_PositionsInBurst->choice.mediumBitmap.bits_unused = 0;
scc->ssb_PositionsInBurst->choice.mediumBitmap.buf = CALLOC(1,1);
scc->ssb_PositionsInBurst->choice.mediumBitmap.buf[0] = 0;
for (int i=0; i<8; i++)
@@ -243,10 +244,10 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc,uint64_t ssbmap) {
scc->ssb_PositionsInBurst->choice.longBitmap.bits_unused = 0;
scc->ssb_PositionsInBurst->choice.longBitmap.buf = CALLOC(1,8);
for (int j=0; j<8; j++) {
scc->ssb_PositionsInBurst->choice.longBitmap.buf[7-j] = 0;
scc->ssb_PositionsInBurst->choice.longBitmap.buf[j] = 0;
curr_bit = (ssbmap>>(j<<3))&(0xff);
for (int i=0; i<8; i++)
scc->ssb_PositionsInBurst->choice.longBitmap.buf[7-j] |= (((curr_bit>>(7-i))&0x01)<<i);
scc->ssb_PositionsInBurst->choice.longBitmap.buf[j] |= (((curr_bit>>(7-i))&0x01)<<i);
}
}
@@ -1031,27 +1032,32 @@ void NRRCConfig(void) {
}
int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i) {
int J, l;
char *address = NULL;
char *cidr = NULL;
//int num_gnbs = 0;
//int num_component_carriers = 0;
int j,k = 0;
int32_t gnb_id = 0;
paramdef_t GNBSParams[] = GNBSPARAMS_DESC;
////////// Identification parameters
paramdef_t GNBParams[] = GNBPARAMS_DESC;
paramlist_def_t GNBParamList = {GNB_CONFIG_STRING_GNB_LIST,NULL,0};
/* get global parameters, defined outside any section in the config file */
config_get( GNBSParams,sizeof(GNBSParams)/sizeof(paramdef_t),NULL);
//paramlist_def_t SCCsParamList = {GNB_CONFIG_STRING_SERVINGCELLCONFIGCOMMON, NULL, 0};
NR_ServingCellConfigCommon_t *scc = calloc(1,sizeof(NR_ServingCellConfigCommon_t));
uint64_t ssb_bitmap=0xff;
memset((void*)scc,0,sizeof(NR_ServingCellConfigCommon_t));
prepare_scc(scc);
paramdef_t SCCsParams[] = SCCPARAMS_DESC(scc);
paramlist_def_t SCCsParamList = {GNB_CONFIG_STRING_SERVINGCELLCONFIGCOMMON, NULL, 0};
AssertFatal(i < GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt,
"Failed to parse config file %s, %uth attribute %s \n",
RC.config_file_name, i, ENB_CONFIG_STRING_ACTIVE_ENBS);
RC.config_file_name, i, GNB_CONFIG_STRING_ACTIVE_GNBS);
if (GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt > 0) {
// Output a list of all gNBs.
@@ -1121,19 +1127,28 @@ int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i) {
"MNC %d cannot be encoded in two digits as requested (change mnc_digit_length to 3)\n",
X2AP_REGISTER_ENB_REQ(msg_p).mnc);
X2AP_REGISTER_ENB_REQ (msg_p).num_cc = 1;
J = 0;
X2AP_REGISTER_ENB_REQ (msg_p).eutra_band[J] = 78; //ccparams_nr_x2.nr_band; //78
X2AP_REGISTER_ENB_REQ (msg_p).downlink_frequency[J] = 3600000000; //ccparams_nr_x2.downlink_frequency; //3600000000
X2AP_REGISTER_ENB_REQ (msg_p).uplink_frequency_offset[J] = 0; //(unsigned int) ccparams_nr_x2.uplink_frequency_offset; //0
X2AP_REGISTER_ENB_REQ (msg_p).Nid_cell[J]= 0; //ccparams_nr_x2.Nid_cell; //0
X2AP_REGISTER_ENB_REQ (msg_p).N_RB_DL[J]= 106; //ccparams_nr_x2.N_RB_DL; //106
sprintf(aprefix, "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, 0);
X2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = TDD;
//Temp out
/*X2AP_REGISTER_ENB_REQ (msg_p).fdd_earfcn_DL[J] = to_earfcn_DL(ccparams_lte.eutra_band, ccparams_lte.downlink_frequency, ccparams_lte.N_RB_DL);
X2AP_REGISTER_ENB_REQ (msg_p).fdd_earfcn_UL[J] = to_earfcn_UL(ccparams_lte.eutra_band, ccparams_lte.downlink_frequency + ccparams_lte.uplink_frequency_offset, ccparams_lte.N_RB_DL);*/
config_getlist(&SCCsParamList, NULL, 0, aprefix);
if (SCCsParamList.numelt > 0) {
sprintf(aprefix, "%s.[%i].%s.[%i]", GNB_CONFIG_STRING_GNB_LIST,0,GNB_CONFIG_STRING_SERVINGCELLCONFIGCOMMON, 0);
config_get( SCCsParams,sizeof(SCCsParams)/sizeof(paramdef_t),aprefix);
fix_scc(scc,ssb_bitmap);
}
X2AP_REGISTER_ENB_REQ (msg_p).num_cc = SCCsParamList.numelt;
for (J = 0; J < SCCsParamList.numelt ; J++) {
X2AP_REGISTER_ENB_REQ (msg_p).nr_band[J] = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; //nr_band; //78
X2AP_REGISTER_ENB_REQ (msg_p).nrARFCN[J] = scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA;
X2AP_REGISTER_ENB_REQ (msg_p).uplink_frequency_offset[J] = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier; //0
X2AP_REGISTER_ENB_REQ (msg_p).Nid_cell[J]= *scc->physCellId; //0
X2AP_REGISTER_ENB_REQ (msg_p).N_RB_DL[J]= scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;//106
X2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = TDD;
LOG_I(X2AP, "gNB configuration parameters: nr_band: %d, nr_ARFCN: %d, DL_RBs: %d, num_cc: %d \n",
X2AP_REGISTER_ENB_REQ (msg_p).nr_band[J],
X2AP_REGISTER_ENB_REQ (msg_p).nrARFCN[J],
X2AP_REGISTER_ENB_REQ (msg_p).N_RB_DL[J],
X2AP_REGISTER_ENB_REQ (msg_p).num_cc);
}
sprintf(aprefix,"%s.[%i]",GNB_CONFIG_STRING_GNB_LIST,k);
config_getlist( &X2ParamList,X2Params,sizeof(X2Params)/sizeof(paramdef_t),aprefix);
@@ -1222,4 +1237,3 @@ int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i) {
return 0;
}
+6 -24
View File
@@ -83,6 +83,7 @@ typedef enum {
/* global parameters, not under a specific section */
#define GNB_CONFIG_STRING_ASN1_VERBOSITY "Asn1_verbosity"
#define GNB_CONFIG_STRING_ACTIVE_GNBS "Active_gNBs"
#define GNB_CONFIG_PUSCH_THREADS "Num_Threads_PUSCH"
/*--------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* global configuration parameters */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
@@ -91,6 +92,11 @@ typedef enum {
{GNB_CONFIG_STRING_ASN1_VERBOSITY, NULL, 0, uptr:NULL, defstrval:GNB_CONFIG_STRING_ASN1_VERBOSITY_NONE, TYPE_STRING, 0}, \
{GNB_CONFIG_STRING_ACTIVE_GNBS, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRINGLIST, 0} \
}
#define NUM_THREADS_DESC { \
{GNB_CONFIG_PUSCH_THREADS, NULL, 0, uptr:&num_threads_pusch, defuintval:1, TYPE_UINT, 0} \
}
#define GNB_ASN1_VERBOSITY_IDX 0
#define GNB_ACTIVE_GNBS_IDX 1
@@ -118,30 +124,6 @@ typedef enum {
#define GNB_CONFIG_STRING_PUSCHTARGETPOWX10 "pusch_TargetSNRx10"
#define GNB_CONFIG_STRING_PUCCHTARGETPOWX10 "pucch_TargetSNRx10"
typedef struct ccparams_nr_x2 {
char *frame_type;
int32_t tdd_config;
int32_t tdd_config_s;
int32_t nr_band;
long long int downlink_frequency;
int32_t uplink_frequency_offset;
int32_t Nid_cell;
int32_t N_RB_DL;
} ccparams_nr_x2_t;
#define CCPARAMS_NR_X2_DESC(ccparams) { \
{ENB_CONFIG_STRING_FRAME_TYPE, NULL, 0, strptr:&ccparams.frame_type, defstrval:"TDD", TYPE_STRING, 0}, \
{ENB_CONFIG_STRING_TDD_CONFIG, NULL, 0, iptr:&ccparams.tdd_config, defintval:3, TYPE_UINT, 0}, \
{ENB_CONFIG_STRING_TDD_CONFIG_S, NULL, 0, iptr:&ccparams.tdd_config_s, defintval:0, TYPE_UINT, 0}, \
{ENB_CONFIG_STRING_EUTRA_BAND, NULL, 0, iptr:&ccparams.nr_band, defintval:78, TYPE_UINT, 0}, \
{ENB_CONFIG_STRING_DOWNLINK_FREQUENCY, NULL, 0, i64ptr:(int64_t *)&ccparams.downlink_frequency, defint64val:3600000000, TYPE_UINT64, 0}, \
{ENB_CONFIG_STRING_UPLINK_FREQUENCY_OFFSET, NULL, 0, iptr:&ccparams.uplink_frequency_offset, defintval:0, TYPE_INT, 0}, \
{ENB_CONFIG_STRING_NID_CELL, NULL, 0, iptr:&ccparams.Nid_cell, defintval:0, TYPE_UINT, 0}, \
{ENB_CONFIG_STRING_N_RB_DL, NULL, 0, iptr:&ccparams.N_RB_DL, defintval:106, TYPE_UINT, 0} \
}
/*-----------------------------------------------------------------------------------------------------------------------------------------*/
/* cell configuration parameters */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
+2
View File
@@ -914,7 +914,9 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP,
#if (!defined(PRE_SCD_THREAD))
if (!NODE_IS_DU(RC.rrc[module_idP]->node_type)) {
void rlc_tick(int, int);
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frameP, subframeP, module_idP);
rlc_tick(frameP, subframeP);
pdcp_run(&ctxt);
pdcp_mbms_run(&ctxt);
rrc_rx_tx(&ctxt, CC_id);
+1 -1
View File
@@ -182,7 +182,7 @@ rx_sdu(const module_id_t enb_mod_idP,
UE_template_ptr->scheduled_ul_bytes = 0;
}
} else { // sduP == NULL => error
LOG_W(MAC, "[eNB %d][PUSCH %d] CC_id %d %d.%d ULSCH in error in round %d, ul_cqi %d, UE_id %d, RNTI %x (len %d)\n",
LOG_D(MAC, "[eNB %d][PUSCH %d] CC_id %d %d.%d ULSCH in error in round %d, ul_cqi %d, UE_id %d, RNTI %x (len %d)\n",
enb_mod_idP,
harq_pid,
CC_idP,
+3
View File
@@ -3099,6 +3099,9 @@ ue_scheduler(const module_id_t module_idP,
}
}
void rlc_tick(int, int);
rlc_tick(rxFrameP % 1024, rxSubframeP);
//#endif
UE_mac_inst[module_idP].txFrame = txFrameP;
UE_mac_inst[module_idP].txSubframe = txSubframeP;
+17 -8
View File
@@ -937,14 +937,22 @@ int64_t table_6_3_3_2_4_prachConfig_Index [256][10] = {
int get_format0(uint8_t index,
uint8_t unpaired){
uint8_t unpaired,
frequency_range_t frequency_range){
uint16_t format;
if (unpaired)
format = table_6_3_3_2_3_prachConfig_Index[index][0];
else
format = table_6_3_3_2_2_prachConfig_Index[index][0];
if (unpaired) {
if (frequency_range==FR1)
format = table_6_3_3_2_3_prachConfig_Index[index][0];
else
format = table_6_3_3_2_4_prachConfig_Index[index][0];
}
else {
if (frequency_range==FR1)
format = table_6_3_3_2_2_prachConfig_Index[index][0];
else
AssertFatal(0==1,"no paired spectrum for FR2\n");
}
return format;
}
@@ -1402,11 +1410,12 @@ uint16_t table_63313[838] = {
uint8_t compute_nr_root_seq(NR_RACH_ConfigCommon_t *rach_config,
uint8_t nb_preambles,
uint8_t unpaired) {
uint8_t unpaired,
frequency_range_t frequency_range) {
uint8_t config_index = rach_config->rach_ConfigGeneric.prach_ConfigurationIndex;
uint8_t ncs_index = rach_config->rach_ConfigGeneric.zeroCorrelationZoneConfig;
uint16_t format0 = get_format0(config_index, unpaired);
uint16_t format0 = get_format0(config_index, unpaired, frequency_range);
uint16_t NCS = get_NCS(ncs_index, format0, rach_config->restrictedSetConfig);
uint16_t L_ra = (rach_config->prach_RootSequenceIndex.present==NR_RACH_ConfigCommon__prach_RootSequenceIndex_PR_l139) ? 139 : 839;
uint16_t r,u,index,q,d_u,n_shift_ra,n_shift_ra_bar,d_start;
@@ -44,6 +44,11 @@
#define MAX_TDM (7) // Maximum nb of PRACH occasions TDMed in a slot
#define MAX_FDM (8) // Maximum nb of PRACH occasions FDMed in a slot
typedef enum frequency_range_e {
FR1 = 0,
FR2
} frequency_range_t;
// PRACH occasion details
typedef struct prach_occasion_info {
uint8_t start_symbol; // 0 - 13 (14 symbols in a slot)
@@ -159,11 +164,12 @@ uint8_t get_pusch_mcs_table(long *mcs_Table,
uint8_t compute_nr_root_seq(NR_RACH_ConfigCommon_t *rach_config,
uint8_t nb_preambles,
uint8_t unpaired);
uint8_t unpaired,
frequency_range_t);
int ul_ant_bits(NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig,long transformPrecoder);
int get_format0(uint8_t index, uint8_t unpaired);
int get_format0(uint8_t index, uint8_t unpaired,frequency_range_t);
int64_t *get_prach_config_info(uint32_t pointa,
uint8_t index,
@@ -37,6 +37,8 @@
/*#include "PHY/defs_common.h"*/
extern const uint8_t nr_slots_per_frame[5];
/* extern const uint32_t BSR_TABLE[BSR_TABLE_SIZE];
extern const uint32_t Extended_BSR_TABLE[BSR_TABLE_SIZE];
extern const uint8_t cqi2fmt0_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE];
+7 -4
View File
@@ -147,7 +147,6 @@ void config_common_ue(NR_UE_MAC_INST_t *mac,
fapi_nr_config_request_t *cfg = &mac->phy_config.config_req;
NR_ServingCellConfigCommon_t *scc = mac->scc;
int i;
lte_frame_type_t frame_type;
mac->phy_config.Mod_id = module_id;
mac->phy_config.CC_id = cc_idP;
@@ -201,6 +200,10 @@ void config_common_ue(NR_UE_MAC_INST_t *mac,
}
}
uint32_t band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
frequency_range_t frequency_range = band<100?FR1:FR2;
lte_frame_type_t frame_type;
get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing, &frame_type);
// cell config
@@ -236,8 +239,8 @@ void config_common_ue(NR_UE_MAC_INST_t *mac,
cfg->ssb_table.ssb_mask_list[0].ssb_mask = 0;
cfg->ssb_table.ssb_mask_list[1].ssb_mask = 0;
for (i=0; i<4; i++) {
cfg->ssb_table.ssb_mask_list[0].ssb_mask += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[i]<<i*8);
cfg->ssb_table.ssb_mask_list[1].ssb_mask += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[i+4]<<i*8);
cfg->ssb_table.ssb_mask_list[0].ssb_mask += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[3-i]<<i*8);
cfg->ssb_table.ssb_mask_list[1].ssb_mask += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[7-i]<<i*8);
}
break;
default:
@@ -310,7 +313,7 @@ void config_common_ue(NR_UE_MAC_INST_t *mac,
cfg->prach_config.num_prach_fd_occasions_list[i].k1 = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart;
cfg->prach_config.num_prach_fd_occasions_list[i].prach_zero_corr_conf = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig;
cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences = compute_nr_root_seq(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup, nb_preambles, frame_type);
cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences = compute_nr_root_seq(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup, nb_preambles, frame_type,frequency_range);
//cfg->prach_config.num_prach_fd_occasions_list[i].num_unused_root_sequences = ???
}
+1 -5
View File
@@ -205,7 +205,7 @@ typedef struct {
/// Random-access procedure flag
uint8_t RA_active;
/// Random-access window counter
int8_t RA_window_cnt;
int16_t RA_window_cnt;
/// Random-access Msg3 size in bytes
uint8_t RA_Msg3_size;
/// Random-access prachMaskIndex
@@ -292,10 +292,6 @@ typedef enum channel_bandwidth_e {
bw_100MHz = 0x32
} channel_bandwidth_t;
typedef enum frequency_range_e {
FR1 = 0,
FR2
} frequency_range_t;
typedef struct {
uint8_t identifier_dci_formats ; // 0 IDENTIFIER_DCI_FORMATS:
-2
View File
@@ -37,8 +37,6 @@
#include "assertions.h"
#include "PHY/types.h"
#include "PHY/defs_UE.h"
#include "openair2/LAYER2/RLC/rlc.h"
#include "openair2/LAYER2/PDCP_v10.1.0/pdcp.h"
#include "openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h"
#include "executables/softmodem-common.h"
@@ -63,7 +63,6 @@
#include "LAYER2/NR_MAC_UE/mac_proto.h"
extern int64_t table_6_3_3_2_3_prachConfig_Index [256][9];
extern const uint8_t nr_slots_per_frame[5];
//extern uint8_t nfapi_mode;
+14 -20
View File
@@ -142,7 +142,6 @@ static ssb_list_info_t ssb_list;
extern int bwp_id;
extern dci_pdu_rel15_t *def_dci_pdu_rel15;
extern const uint8_t nr_slots_per_frame[5];
extern void mac_rlc_data_ind (
const module_id_t module_idP,
@@ -971,35 +970,30 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
uint16_t frame_number_4lsb = 0;
for (int i=0; i<4; i++)
frame_number_4lsb |= ((extra_bits>>i)&1)<<(3-i);
//uint8_t half_frame_bit = ( extra_bits >> 4 ) & 0x1; // extra bits[4]
uint8_t half_frame_bit = ( extra_bits >> 4 ) & 0x1; // extra bits[4]
uint8_t ssb_subcarrier_offset_msb = ( extra_bits >> 5 ) & 0x1; // extra bits[5]
uint8_t ssb_subcarrier_offset = (uint8_t)mac->mib->ssb_SubcarrierOffset;
//uint32_t ssb_index = 0; // TODO: ssb_index should obtain from L1 in case Lssb != 64
frame = frame << 4;
frame = frame | frame_number_4lsb;
if(ssb_length == 64){
ssb_index = ssb_index & (( extra_bits >> 2 ) & 0x1C ); // { extra_bits[5:7], ssb_index[2:0] }
for (int i=0; i<3; i++)
ssb_index += (((extra_bits>>(7-i))&0x01)<<(3+i));
}else{
if(ssb_subcarrier_offset_msb){
ssb_subcarrier_offset = ssb_subcarrier_offset | 0x10;
}
}
#ifdef DEBUG_MIB
LOG_I(MAC,"system frame number(6 MSB bits): %d\n", mac->mib->systemFrameNumber.buf[0]);
LOG_I(MAC,"system frame number(with LSB): %d\n", (int)frame);
LOG_I(MAC,"subcarrier spacing (0=15or60, 1=30or120): %d\n", (int)mac->mib->subCarrierSpacingCommon);
LOG_I(MAC,"ssb carrier offset(with MSB): %d\n", (int)ssb_subcarrier_offset);
LOG_I(MAC,"dmrs type A position (0=pos2,1=pos3): %d\n", (int)mac->mib->dmrs_TypeA_Position);
LOG_I(MAC,"pdcch config sib1: %d\n", (int)mac->mib->pdcch_ConfigSIB1);
LOG_I(MAC,"cell barred (0=barred,1=notBarred): %d\n", (int)mac->mib->cellBarred);
LOG_I(MAC,"intra frequency reselection (0=allowed,1=notAllowed): %d\n", (int)mac->mib->intraFreqReselection);
LOG_I(MAC,"half frame bit(extra bits): %d\n", (int)half_frame_bit);
LOG_I(MAC,"ssb index(extra bits): %d\n", (int)ssb_index);
#endif
LOG_D(MAC,"system frame number(6 MSB bits): %d\n", mac->mib->systemFrameNumber.buf[0]);
LOG_D(MAC,"system frame number(with LSB): %d\n", (int)frame);
LOG_D(MAC,"subcarrier spacing (0=15or60, 1=30or120): %d\n", (int)mac->mib->subCarrierSpacingCommon);
LOG_D(MAC,"ssb carrier offset(with MSB): %d\n", (int)ssb_subcarrier_offset);
LOG_D(MAC,"dmrs type A position (0=pos2,1=pos3): %d\n", (int)mac->mib->dmrs_TypeA_Position);
LOG_D(MAC,"cell barred (0=barred,1=notBarred): %d\n", (int)mac->mib->cellBarred);
LOG_D(MAC,"intra frequency reselection (0=allowed,1=notAllowed): %d\n", (int)mac->mib->intraFreqReselection);
LOG_D(MAC,"half frame bit(extra bits): %d\n", (int)half_frame_bit);
LOG_D(MAC,"ssb index(extra bits): %d\n", (int)ssb_index);
subcarrier_spacing_t scs_ssb = scs_30kHz; // default for
//const uint32_t scs_index = 0;
@@ -1022,8 +1016,8 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
int32_t num_rbs = -1;
int32_t num_symbols = -1;
int32_t rb_offset = -1;
//LOG_I(MAC,"<<<<<<<<<configSIB1 %d index_4msb %d index_4lsb %d scs_ssb %d scs_pdcch %d switch %d ",
//mac->mib->pdcch_ConfigSIB1,index_4msb,index_4lsb,scs_ssb,scs_pdcch, (scs_ssb << 5)|scs_pdcch);
LOG_D(MAC,"<<<<<<<<<configSIB1: controlResourceSetZero %d searchSpaceZero %d scs_ssb %d scs_pdcch %d switch %d ",
index_4msb,index_4lsb,scs_ssb,scs_pdcch, (scs_ssb << 5)|scs_pdcch);
// type0-pdcch coreset
switch( (scs_ssb << 5)|scs_pdcch ){
+37 -3
View File
@@ -124,6 +124,9 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
}
}
uint32_t band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
frequency_range_t frequency_range = band<100?FR1:FR2;
lte_frame_type_t frame_type;
get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing, &frame_type);
RC.nrmac[Mod_idP]->common_channels[0].frame_type = frame_type;
@@ -213,7 +216,7 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
cfg->prach_config.num_prach_fd_occasions_list[i].prach_zero_corr_conf.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig;
cfg->prach_config.num_prach_fd_occasions_list[i].prach_zero_corr_conf.tl.tag = NFAPI_NR_CONFIG_PRACH_ZERO_CORR_CONF_TAG;
cfg->num_tlv++;
cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences.value = compute_nr_root_seq(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup,nb_preambles, frame_type);
cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences.value = compute_nr_root_seq(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup,nb_preambles, frame_type, frequency_range);
cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences.tl.tag = NFAPI_NR_CONFIG_NUM_ROOT_SEQUENCES_TAG;
cfg->num_tlv++;
cfg->prach_config.num_prach_fd_occasions_list[i].num_unused_root_sequences.value = 1;
@@ -252,8 +255,8 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
cfg->ssb_table.ssb_mask_list[0].ssb_mask.value = 0;
cfg->ssb_table.ssb_mask_list[1].ssb_mask.value = 0;
for (i=0; i<4; i++) {
cfg->ssb_table.ssb_mask_list[0].ssb_mask.value += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[i+4]<<i*8);
cfg->ssb_table.ssb_mask_list[1].ssb_mask.value += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[i]<<i*8);
cfg->ssb_table.ssb_mask_list[0].ssb_mask.value += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[3-i]<<i*8);
cfg->ssb_table.ssb_mask_list[1].ssb_mask.value += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[7-i]<<i*8);
}
break;
default:
@@ -309,6 +312,7 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
extern uint16_t sl_ahead;
int rrc_mac_config_req_gNB(module_id_t Mod_idP,
int ssb_SubcarrierOffset,
int pdsch_AntennaPorts,
@@ -322,6 +326,30 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
if (scc != NULL ) {
AssertFatal((scc->ssb_PositionsInBurst->present > 0) && (scc->ssb_PositionsInBurst->present < 4), "SSB Bitmap type %d is not valid\n",scc->ssb_PositionsInBurst->present);
/* dimension UL_tti_req_ahead for number of slots in frame */
const uint8_t slots_per_frame[5] = {10, 20, 40, 80, 160};
const int n = slots_per_frame[*scc->ssbSubcarrierSpacing];
RC.nrmac[Mod_idP]->UL_tti_req_ahead[0] = calloc(n, sizeof(nfapi_nr_ul_tti_request_t));
AssertFatal(RC.nrmac[Mod_idP]->UL_tti_req_ahead[0],
"could not allocate memory for RC.nrmac[]->UL_tti_req_ahead[]\n");
/* fill in slot/frame numbers: slot is fixed, frame will be updated by
* scheduler */
for (int i = 0; i < n; ++i) {
nfapi_nr_ul_tti_request_t *req = &RC.nrmac[Mod_idP]->UL_tti_req_ahead[0][i];
/* consider that scheduler runs sl_ahead: the first sl_ahead slots are
* already "in the past" and thus we put frame 1 instead of 0! Note that
* variable sl_ahead seems to not be correctly initialized, but I leave
* it for information purposes here (the fix would always put 0, what
* happens now, too) */
req->SFN = i < sl_ahead;
req->Slot = i;
}
RC.nrmac[Mod_idP]->common_channels[0].vrb_map_UL =
calloc(n * 275, sizeof(uint16_t));
AssertFatal(RC.nrmac[Mod_idP]->common_channels[0].vrb_map_UL,
"could not allocate memory for RC.nrmac[]->common_channels[0].vrb_map_UL\n");
LOG_I(MAC,"Configuring common parameters from NR ServingCellConfig\n");
config_common(Mod_idP,
@@ -369,6 +397,12 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
bwpList->list.count);
const int bwp_id = 1;
UE_info->UE_sched_ctrl[UE_id].active_bwp = bwpList->list.array[bwp_id - 1];
struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList =
secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList;
AssertFatal(ubwpList->list.count == 1,
"uplinkBWP_ToAddModList has %d BWP!\n",
ubwpList->list.count);
UE_info->UE_sched_ctrl[UE_id].active_ubwp = ubwpList->list.array[bwp_id - 1];
LOG_I(PHY,"Added new UE_id %d/%x with initial secondaryCellGroup\n",UE_id,rnti);
} else if (add_ue == 1 && !get_softmodem_params()->phy_test) {
/* TODO: should check for free RA process */
+39 -88
View File
@@ -32,9 +32,7 @@
#include "assertions.h"
#include "LAYER2/MAC/mac.h"
#include "NR_MAC_COMMON/nr_mac_extern.h"
#include "LAYER2/MAC/mac_proto.h"
#include "NR_MAC_gNB/mac_proto.h"
#include "common/utils/LOG/log.h"
@@ -51,15 +49,10 @@
#include "openair1/PHY/defs_gNB.h"
#include "openair1/PHY/NR_TRANSPORT/nr_dlsch.h"
//Agent-related headers
#include "flexran_agent_extern.h"
#include "flexran_agent_mac.h"
#include "intertask_interface.h"
#include "executables/softmodem-common.h"
const uint8_t slots_per_frame[5] = {10, 20, 40, 80, 160};
uint16_t nr_pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 };
void clear_mac_stats(gNB_MAC_INST *gNB) {
@@ -92,9 +85,12 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
int CC_idP,
frame_t frameP,
sub_frame_t slotP){
NR_ServingCellConfigCommon_t *scc = gNB->common_channels->ServingCellConfigCommon;
const int num_slots = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
nfapi_nr_dl_tti_request_t *DL_req = &gNB->DL_req[0];
nfapi_nr_ul_tti_request_t *UL_tti_req = &gNB->UL_tti_req[0];
nfapi_nr_ul_tti_request_t *future_ul_tti_req =
&gNB->UL_tti_req_ahead[CC_idP][(slotP + num_slots - 1) % num_slots];
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];
@@ -112,12 +108,17 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
UL_dci_req[CC_idP].Slot = slotP;
UL_dci_req[CC_idP].numPdus = 0;
UL_tti_req[CC_idP].SFN = frameP;
UL_tti_req[CC_idP].Slot = slotP;
UL_tti_req[CC_idP].n_pdus = 0;
UL_tti_req[CC_idP].n_ulsch = 0;
UL_tti_req[CC_idP].n_ulcch = 0;
UL_tti_req[CC_idP].n_group = 0;
/* advance last round's future UL_tti_req to be ahead of current frame/slot */
future_ul_tti_req->SFN = (slotP == 0 ? frameP : frameP + 1) % 1024;
/* future_ul_tti_req->Slot is fixed! */
future_ul_tti_req->n_pdus = 0;
future_ul_tti_req->n_ulsch = 0;
future_ul_tti_req->n_ulcch = 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 */
gNB->UL_tti_req[CC_idP] = &gNB->UL_tti_req_ahead[CC_idP][slotP];
TX_req[CC_idP].Number_of_PDUs = 0;
@@ -285,58 +286,6 @@ void schedule_nr_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subfram
*/
/*
void copy_nr_ulreq(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
{
int CC_id;
gNB_MAC_INST *mac = RC.nrmac[module_idP];
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
nfapi_ul_config_request_t *ul_req = &mac->UL_tti_req[CC_id];
*ul_req = *ul_req_tmp;
// Restore the pointer
ul_req->ul_config_request_body.ul_config_pdu_list = ul_req_pdu;
ul_req->sfn_sf = (frameP<<7) + slotP;
ul_req_tmp->ul_config_request_body.number_of_pdus = 0;
if (ul_req->ul_config_request_body.number_of_pdus>0)
{
LOG_D(PHY, "%s() active NOW (frameP:%d slotP:%d) pdus:%d\n", __FUNCTION__, frameP, slotP, ul_req->ul_config_request_body.number_of_pdus);
}
memcpy((void*)ul_req->ul_config_request_body.ul_config_pdu_list,
(void*)ul_req_tmp->ul_config_request_body.ul_config_pdu_list,
ul_req->ul_config_request_body.number_of_pdus*sizeof(nfapi_ul_config_request_pdu_t));
}
}
*/
void nr_schedule_pusch(int Mod_idP,
int UE_id,
int num_slots_per_tdd,
int ul_slots,
frame_t frameP,
sub_frame_t slotP) {
nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[Mod_idP]->UL_tti_req[0];
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
int k = slotP + ul_slots - num_slots_per_tdd;
NR_sched_pusch *pusch = &UE_info->UE_sched_ctrl[UE_id].sched_pusch[k];
if ((pusch->active == true) && (frameP == pusch->frame) && (slotP == pusch->slot)) {
UL_tti_req->SFN = pusch->frame;
UL_tti_req->Slot = pusch->slot;
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE;
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t);
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pusch_pdu = pusch->pusch_pdu;
UL_tti_req->n_pdus+=1;
memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pusch[k],
0, sizeof(NR_sched_pusch));
}
}
bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot) {
return (bitmap >> slot) & 0x01;
}
@@ -355,7 +304,6 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
gNB_MAC_INST *gNB = RC.nrmac[module_idP];
NR_UE_info_t *UE_info = &gNB->UE_info;
NR_UE_sched_ctrl_t *ue_sched_ctl = &UE_info->UE_sched_ctrl[UE_id];
NR_COMMON_channels_t *cc = gNB->common_channels;
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
NR_TDD_UL_DL_Pattern_t *tdd_pattern = &scc->tdd_UL_DL_ConfigurationCommon->pattern1;
@@ -397,7 +345,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
AssertFatal(1==0,"Undefined tdd period %ld\n", scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity);
}
int num_slots_per_tdd = (slots_per_frame[*scc->ssbSubcarrierSpacing])/nb_periods_per_frame;
int num_slots_per_tdd = (nr_slots_per_frame[*scc->ssbSubcarrierSpacing])/nb_periods_per_frame;
const int nr_ulmix_slots = tdd_pattern->nrofUplinkSlots + (tdd_pattern->nrofUplinkSymbols!=0);
@@ -424,7 +372,11 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
// clear vrb_maps
memset(cc[CC_id].vrb_map, 0, sizeof(uint16_t) * 275);
memset(cc[CC_id].vrb_map_UL, 0, sizeof(uint16_t) * 275);
// clear last scheduled slot's content (only)!
const int num_slots = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
const int last_slot = (slot + num_slots - 1) % num_slots;
uint16_t *vrb_map_UL = cc[CC_id].vrb_map_UL;
memset(&vrb_map_UL[last_slot * 275], 0, sizeof(uint16_t) * 275);
clear_nr_nfapi_information(RC.nrmac[module_idP], CC_id, frame, slot);
}
@@ -434,44 +386,43 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
// This schedules MIB
schedule_nr_mib(module_idP, frame, slot, slots_per_frame[*scc->ssbSubcarrierSpacing]);
schedule_nr_mib(module_idP, frame, slot, nr_slots_per_frame[*scc->ssbSubcarrierSpacing]);
// This schedule PRACH if we are not in phy_test mode
if (get_softmodem_params()->phy_test == 0)
schedule_nr_prach(module_idP, frame, slot);
if (get_softmodem_params()->phy_test == 0) {
/* we need to make sure that resources for PRACH are free. To avoid that
e.g. PUSCH has already been scheduled, make sure we schedule before
anything else: below, we simply assume an advance one frame (minus one
slot, because otherwise we would allocate the current slot in
UL_tti_req_ahead), but be aware that, e.g., K2 is allowed to be larger
(schedule_nr_prach will assert if resources are not free). */
const sub_frame_t n_slots_ahead = nr_slots_per_frame[*scc->ssbSubcarrierSpacing] - 1;
const frame_t f = (frame + (slot + n_slots_ahead) / nr_slots_per_frame[*scc->ssbSubcarrierSpacing]) % 1024;
const sub_frame_t s = (slot + n_slots_ahead) % nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
schedule_nr_prach(module_idP, f, s);
}
// This schedule SR
// TODO
// This schedule CSI measurement reporting
if (UE_info->active[UE_id])
nr_csi_meas_reporting(module_idP, UE_id, frame, slot, num_slots_per_tdd, nr_ulmix_slots, slots_per_frame[*scc->ssbSubcarrierSpacing]);
nr_csi_meas_reporting(module_idP, UE_id, frame, slot, num_slots_per_tdd, nr_ulmix_slots, nr_slots_per_frame[*scc->ssbSubcarrierSpacing]);
// This schedule RA procedure if not in phy_test mode
// Otherwise already consider 5G already connected
RC.nrmac[module_idP]->current_slot=slot;
if (get_softmodem_params()->phy_test == 0) {
nr_schedule_RA(module_idP, frame, slot);
nr_schedule_reception_msg3(module_idP, 0, frame, slot);
}
// This schedules the DCI for Uplink and subsequently PUSCH
// The decision about whether to schedule is done for each UE independently
// inside
if (UE_info->active[UE_id] && slot < 10) {
int tda = 1; // time domain assignment hardcoded for now
schedule_fapi_ul_pdu(module_idP, frame, slot, num_slots_per_tdd, nr_ulmix_slots, tda, ulsch_in_slot_bitmap);
nr_schedule_pusch(module_idP, UE_id, num_slots_per_tdd, nr_ulmix_slots, frame, slot);
if (slot < 10) {
nr_schedule_ulsch(module_idP, frame, slot, num_slots_per_tdd, nr_ulmix_slots, ulsch_in_slot_bitmap);
}
if (UE_info->active[UE_id]
&& (is_xlsch_in_slot(dlsch_in_slot_bitmap, slot % num_slots_per_tdd))
// This schedules the DCI for Downlink and PDSCH
if (is_xlsch_in_slot(dlsch_in_slot_bitmap, slot % num_slots_per_tdd)
&& slot < 10) {
ue_sched_ctl->current_harq_pid = slot % num_slots_per_tdd;
nr_schedule_ue_spec(module_idP, frame, slot, num_slots_per_tdd);
}
+246 -211
View File
@@ -43,6 +43,7 @@
extern RAN_CONTEXT_t RC;
extern const uint8_t nr_slots_per_frame[5];
extern uint16_t sl_ahead;
uint8_t DELTA[4]= {2,3,4,6};
@@ -62,19 +63,19 @@ int16_t ssb_index_from_prach(module_id_t module_idP,
nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[module_idP]->config[0];
uint8_t config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex;
uint8_t fdm = cfg->prach_config.num_prach_fd_occasions.value;
uint8_t fdm = cfg->prach_config.num_prach_fd_occasions.value;
uint8_t total_RApreambles = 64;
if( scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles != NULL)
uint8_t total_RApreambles = 64;
if( scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles != NULL)
total_RApreambles = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles;
float num_ssb_per_RO = ssb_per_rach_occasion[cfg->prach_config.ssb_per_rach.value];
float num_ssb_per_RO = ssb_per_rach_occasion[cfg->prach_config.ssb_per_rach.value];
uint16_t start_symbol_index = 0;
uint8_t mu,N_dur=0,N_t_slot=0,start_symbol = 0, temp_start_symbol = 0, N_RA_slot=0;
uint16_t format,RA_sfn_index = -1;
uint8_t config_period = 1;
uint8_t config_period = 1;
uint16_t prach_occasion_id = -1;
uint8_t num_active_ssb = cc->num_active_ssb;
uint8_t num_active_ssb = cc->num_active_ssb;
if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing)
mu = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing;
@@ -95,45 +96,51 @@ int16_t ssb_index_from_prach(module_id_t module_idP,
&N_RA_slot,
&config_period);
uint8_t index = 0,slot_index = 0;
for (slot_index = 0;slot_index < N_RA_slot; slot_index++) {
for (slot_index = 0;slot_index < N_RA_slot; slot_index++) {
if (N_RA_slot <= 1) { //1 PRACH slot in a subframe
if((mu == 1) || (mu == 3))
slot_index = 1; //For scs = 30khz and 120khz
}
for (int i=0; i< N_t_slot; i++) {
temp_start_symbol = (start_symbol + i * N_dur + 14 * slot_index) % 14;
if(symbol == temp_start_symbol) {
start_symbol_index = i;
break;
}
}
}
if(symbol == temp_start_symbol) {
start_symbol_index = i;
break;
}
}
}
if (N_RA_slot <= 1) { //1 PRACH slot in a subframe
if((mu == 1) || (mu == 3))
slot_index = 0; //For scs = 30khz and 120khz
}
// prach_occasion_id = subframe_index * N_t_slot * N_RA_slot * fdm + N_RA_slot_index * N_t_slot * fdm + freq_index + fdm * start_symbol_index;
prach_occasion_id = (((frameP % (cc->max_association_period * config_period))/config_period)*cc->total_prach_occasions_per_config_period) + (RA_sfn_index + slot_index) * N_t_slot * fdm + start_symbol_index * fdm + freq_index;
//one RO is shared by one or more SSB
if(num_ssb_per_RO <= 1 )
index = (int) (prach_occasion_id / (int)(1/num_ssb_per_RO)) % num_active_ssb;
//one SSB have more than one continuous RO
else if ( num_ssb_per_RO > 1) {
index = (prach_occasion_id * (int)num_ssb_per_RO)% num_active_ssb ;
for(int j = 0;j < num_ssb_per_RO;j++) {
if(preamble_index < (((j+1) * total_RApreambles) / num_ssb_per_RO))
index = index + j;
}
}
LOG_D(MAC, "Frame %d, Slot %d: Prach Occasion id = %d ssb per RO = %f number of active SSB %u index = %d fdm %u symbol index %u freq_index %u total_RApreambles %u\n", frameP, slotP, prach_occasion_id, num_ssb_per_RO, num_active_ssb, index, fdm, start_symbol_index, freq_index, total_RApreambles);
// prach_occasion_id = subframe_index * N_t_slot * N_RA_slot * fdm + N_RA_slot_index * N_t_slot * fdm + freq_index + fdm * start_symbol_index;
prach_occasion_id = (((frameP % (cc->max_association_period * config_period))/config_period)*cc->total_prach_occasions_per_config_period) +
(RA_sfn_index + slot_index) * N_t_slot * fdm + start_symbol_index * fdm + freq_index;
//one RO is shared by one or more SSB
if(num_ssb_per_RO <= 1 )
index = (int) (prach_occasion_id / (int)(1/num_ssb_per_RO)) % num_active_ssb;
//one SSB have more than one continuous RO
else if ( num_ssb_per_RO > 1) {
index = (prach_occasion_id * (int)num_ssb_per_RO)% num_active_ssb ;
for(int j = 0;j < num_ssb_per_RO;j++) {
if(preamble_index < (((j+1) * total_RApreambles) / num_ssb_per_RO))
index = index + j;
}
}
LOG_D(MAC, "Frame %d, Slot %d: Prach Occasion id = %d ssb per RO = %f number of active SSB %u index = %d fdm %u symbol index %u freq_index %u total_RApreambles %u\n",
frameP, slotP, prach_occasion_id, num_ssb_per_RO, num_active_ssb, index, fdm, start_symbol_index, freq_index, total_RApreambles);
return index;
}
//Compute Total active SSBs and RO available
void find_SSB_and_RO_available(module_id_t module_idP) {
gNB_MAC_INST *gNB = RC.nrmac[module_idP];
gNB_MAC_INST *gNB = RC.nrmac[module_idP];
NR_COMMON_channels_t *cc = &gNB->common_channels[0];
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[module_idP]->config[0];
@@ -141,7 +148,7 @@ void find_SSB_and_RO_available(module_id_t module_idP) {
uint8_t config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex;
uint8_t mu,N_dur=0,N_t_slot=0,start_symbol=0,N_RA_slot = 0;
uint16_t format,N_RA_sfn = 0,unused_RA_occasion,repetition = 0;
uint8_t num_active_ssb = 0;
uint8_t num_active_ssb = 0;
uint8_t max_association_period = 1;
if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing)
@@ -151,190 +158,190 @@ void find_SSB_and_RO_available(module_id_t module_idP) {
// prach is scheduled according to configuration index and tables 6.3.3.2.2 to 6.3.3.2.4
get_nr_prach_occasion_info_from_index(config_index,
scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA,
mu,
cc->frame_type,
&format,
&start_symbol,
&N_t_slot,
&N_dur,
&N_RA_slot,
&N_RA_sfn,
&max_association_period);
scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA,
mu,
cc->frame_type,
&format,
&start_symbol,
&N_t_slot,
&N_dur,
&N_RA_slot,
&N_RA_sfn,
&max_association_period);
float num_ssb_per_RO = ssb_per_rach_occasion[cfg->prach_config.ssb_per_rach.value];
uint8_t fdm = cfg->prach_config.num_prach_fd_occasions.value;
uint8_t fdm = cfg->prach_config.num_prach_fd_occasions.value;
uint64_t L_ssb = (((uint64_t) cfg->ssb_table.ssb_mask_list[0].ssb_mask.value)<<32) | cfg->ssb_table.ssb_mask_list[1].ssb_mask.value ;
uint32_t total_RA_occasions = N_RA_sfn * N_t_slot * N_RA_slot * fdm;
uint32_t total_RA_occasions = N_RA_sfn * N_t_slot * N_RA_slot * fdm;
for(int i = 0;i < 64;i++) {
for(int i = 0;i < 64;i++) {
if ((L_ssb >> (63-i)) & 0x01) { // only if the bit of L_ssb at current ssb index is 1
cc->ssb_index[num_active_ssb] = i;
num_active_ssb++;
num_active_ssb++;
}
}
}
for(int i = 1; (1 << (i-1)) <= max_association_period;i++) {
for(int i = 1; (1 << (i-1)) <= max_association_period;i++) {
if(total_RA_occasions >= (int) (num_active_ssb/num_ssb_per_RO)) {
repetition = (uint16_t)((total_RA_occasions * num_ssb_per_RO )/num_active_ssb);
break;
}
else {
total_RA_occasions = total_RA_occasions * i;
cc->max_association_period = i;
}
}
repetition = (uint16_t)((total_RA_occasions * num_ssb_per_RO )/num_active_ssb);
break;
}
else {
total_RA_occasions = total_RA_occasions * i;
cc->max_association_period = i;
}
}
if(cc->max_association_period == 0)
cc->max_association_period = 1;
cc->max_association_period = 1;
unused_RA_occasion = total_RA_occasions - (int)((num_active_ssb * repetition)/num_ssb_per_RO);
cc->total_prach_occasions = total_RA_occasions - unused_RA_occasion;
cc->num_active_ssb = num_active_ssb;
LOG_I(MAC, "Total available RO %d, num of active SSB %d: unused RO = %d max_association_period %u N_RA_sfn %u \n", cc->total_prach_occasions, cc->num_active_ssb, unused_RA_occasion, max_association_period, N_RA_sfn);
unused_RA_occasion = total_RA_occasions - (int)((num_active_ssb * repetition)/num_ssb_per_RO);
cc->total_prach_occasions = total_RA_occasions - unused_RA_occasion;
cc->num_active_ssb = num_active_ssb;
LOG_I(MAC, "Total available RO %d, num of active SSB %d: unused RO = %d max_association_period %u N_RA_sfn %u \n",
cc->total_prach_occasions, cc->num_active_ssb, unused_RA_occasion, max_association_period, N_RA_sfn);
}
void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) {
void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
{
gNB_MAC_INST *gNB = RC.nrmac[module_idP];
NR_COMMON_channels_t *cc = gNB->common_channels;
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[module_idP]->UL_tti_req[0];
nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[module_idP]->UL_tti_req_ahead[0][slotP];
nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[module_idP]->config[0];
if (is_nr_UL_slot(scc,slotP)) {
uint8_t config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex;
uint8_t mu,N_dur,N_t_slot,start_symbol = 0,N_RA_slot;
uint16_t RA_sfn_index = -1;
uint8_t config_period = 1;
uint16_t format;
int slot_index = 0;
uint16_t prach_occasion_id = -1;
uint8_t config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex;
uint8_t mu,N_dur,N_t_slot,start_symbol = 0,N_RA_slot;
uint16_t RA_sfn_index = -1;
uint8_t config_period = 1;
uint16_t format;
int slot_index = 0;
uint16_t prach_occasion_id = -1;
if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing)
mu = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing;
else
mu = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing)
mu = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing;
else
mu = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
uint8_t fdm = cfg->prach_config.num_prach_fd_occasions.value;
// prach is scheduled according to configuration index and tables 6.3.3.2.2 to 6.3.3.2.4
if ( get_nr_prach_info_from_index(config_index,
(int)frameP,
(int)slotP,
scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA,
mu,
cc->frame_type,
&format,
&start_symbol,
&N_t_slot,
&N_dur,
&RA_sfn_index,
&N_RA_slot,
&config_period) ) {
uint16_t format0 = format&0xff; // first column of format from table
uint16_t format1 = (format>>8)&0xff; // second column of format from table
uint8_t fdm = cfg->prach_config.num_prach_fd_occasions.value;
// prach is scheduled according to configuration index and tables 6.3.3.2.2 to 6.3.3.2.4
if ( get_nr_prach_info_from_index(config_index,
(int)frameP,
(int)slotP,
scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA,
mu,
cc->frame_type,
&format,
&start_symbol,
&N_t_slot,
&N_dur,
&RA_sfn_index,
&N_RA_slot,
&config_period) ) {
if (N_RA_slot > 1) { //more than 1 PRACH slot in a subframe
if (slotP%2 == 1){
slot_index = 1;
}
else {
slot_index = 0;
}
}else if (N_RA_slot <= 1) { //1 PRACH slot in a subframe
slot_index = 0;
}
uint16_t format0 = format&0xff; // first column of format from table
uint16_t format1 = (format>>8)&0xff; // second column of format from table
if (N_RA_slot > 1) { //more than 1 PRACH slot in a subframe
if (slotP%2 == 1)
slot_index = 1;
else
slot_index = 0;
}else if (N_RA_slot <= 1) { //1 PRACH slot in a subframe
slot_index = 0;
}
UL_tti_req->SFN = frameP;
UL_tti_req->Slot = slotP;
for (int fdm_index=0; fdm_index < fdm; fdm_index++) { // one structure per frequency domain occasion
for (int td_index=0; td_index<N_t_slot; td_index++) {
UL_tti_req->SFN = frameP;
UL_tti_req->Slot = slotP;
for (int fdm_index=0; fdm_index < fdm; fdm_index++) { // one structure per frequency domain occasion
for (int td_index=0; td_index<N_t_slot; td_index++) {
prach_occasion_id = (((frameP % (cc->max_association_period * config_period))/config_period) * cc->total_prach_occasions_per_config_period) + (RA_sfn_index + slot_index) * N_t_slot * fdm + td_index * fdm + fdm_index;
if((prach_occasion_id < cc->total_prach_occasions) && (td_index == 0)){
prach_occasion_id = (((frameP % (cc->max_association_period * config_period))/config_period) * cc->total_prach_occasions_per_config_period) +
(RA_sfn_index + slot_index) * N_t_slot * fdm + td_index * fdm + fdm_index;
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE;
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_prach_pdu_t);
nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[UL_tti_req->n_pdus].prach_pdu;
memset(prach_pdu,0,sizeof(nfapi_nr_prach_pdu_t));
UL_tti_req->n_pdus+=1;
if((prach_occasion_id < cc->total_prach_occasions) && (td_index == 0)){
// filling the prach fapi structure
prach_pdu->phys_cell_id = *scc->physCellId;
prach_pdu->num_prach_ocas = N_t_slot;
prach_pdu->prach_start_symbol = start_symbol;
prach_pdu->num_ra = fdm_index;
prach_pdu->num_cs = get_NCS(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig,
format0,
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig);
LOG_D(MAC, "Frame %d, Slot %d: Prach Occasion id = %u fdm index = %u start symbol = %u slot index = %u subframe index = %u \n",
frameP, slotP,
prach_occasion_id, prach_pdu->num_ra,
prach_pdu->prach_start_symbol,
slot_index, RA_sfn_index);
// SCF PRACH PDU format field does not consider A1/B1 etc. possibilities
// We added 9 = A1/B1 10 = A2/B2 11 A3/B3
if (format1!=0xff) {
switch(format0) {
case 0xa1:
prach_pdu->prach_format = 11;
break;
case 0xa2:
prach_pdu->prach_format = 12;
break;
case 0xa3:
prach_pdu->prach_format = 13;
break;
default:
AssertFatal(1==0,"Only formats A1/B1 A2/B2 A3/B3 are valid for dual format");
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE;
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_prach_pdu_t);
nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[UL_tti_req->n_pdus].prach_pdu;
memset(prach_pdu,0,sizeof(nfapi_nr_prach_pdu_t));
UL_tti_req->n_pdus+=1;
// filling the prach fapi structure
prach_pdu->phys_cell_id = *scc->physCellId;
prach_pdu->num_prach_ocas = N_t_slot;
prach_pdu->prach_start_symbol = start_symbol;
prach_pdu->num_ra = fdm_index;
prach_pdu->num_cs = get_NCS(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig,
format0,
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig);
LOG_D(MAC, "Frame %d, Slot %d: Prach Occasion id = %u fdm index = %u start symbol = %u slot index = %u subframe index = %u \n",
frameP, slotP,
prach_occasion_id, prach_pdu->num_ra,
prach_pdu->prach_start_symbol,
slot_index, RA_sfn_index);
// SCF PRACH PDU format field does not consider A1/B1 etc. possibilities
// We added 9 = A1/B1 10 = A2/B2 11 A3/B3
if (format1!=0xff) {
switch(format0) {
case 0xa1:
prach_pdu->prach_format = 11;
break;
case 0xa2:
prach_pdu->prach_format = 12;
break;
case 0xa3:
prach_pdu->prach_format = 13;
break;
default:
AssertFatal(1==0,"Only formats A1/B1 A2/B2 A3/B3 are valid for dual format");
}
}
else{
switch(format0) {
case 0:
prach_pdu->prach_format = 0;
break;
case 1:
prach_pdu->prach_format = 1;
break;
case 2:
prach_pdu->prach_format = 2;
break;
case 3:
prach_pdu->prach_format = 3;
break;
case 0xa1:
prach_pdu->prach_format = 4;
break;
case 0xa2:
prach_pdu->prach_format = 5;
break;
case 0xa3:
prach_pdu->prach_format = 6;
break;
case 0xb1:
prach_pdu->prach_format = 7;
break;
case 0xb4:
prach_pdu->prach_format = 8;
break;
case 0xc0:
prach_pdu->prach_format = 9;
break;
case 0xc2:
prach_pdu->prach_format = 10;
break;
default:
AssertFatal(1==0,"Invalid PRACH format");
}
}
}
}
}
else{
switch(format0) {
case 0:
prach_pdu->prach_format = 0;
break;
case 1:
prach_pdu->prach_format = 1;
break;
case 2:
prach_pdu->prach_format = 2;
break;
case 3:
prach_pdu->prach_format = 3;
break;
case 0xa1:
prach_pdu->prach_format = 4;
break;
case 0xa2:
prach_pdu->prach_format = 5;
break;
case 0xa3:
prach_pdu->prach_format = 6;
break;
case 0xb1:
prach_pdu->prach_format = 7;
break;
case 0xb4:
prach_pdu->prach_format = 8;
break;
case 0xc0:
prach_pdu->prach_format = 9;
break;
case 0xc2:
prach_pdu->prach_format = 10;
break;
default:
AssertFatal(1==0,"Invalid PRACH format");
}
}
}
}
}
}
}
}
@@ -363,7 +370,14 @@ void nr_schedule_msg2(uint16_t rach_frame, uint16_t rach_slot,
uint8_t start_next_period = (rach_slot-(rach_slot%tdd_period_slot)+tdd_period_slot)%nr_slots_per_frame[mu];
*msg2_slot = start_next_period + last_dl_slot_period; // initializing scheduling of slot to next mixed (or last dl) slot
*msg2_frame = (*msg2_slot>(rach_slot))? rach_frame : (rach_frame +1);
// we can't schedule msg2 before sl_ahead since prach
int eff_slot = *msg2_slot+(*msg2_frame-rach_frame)*nr_slots_per_frame[mu];
if ((eff_slot-rach_slot)<=sl_ahead) {
*msg2_slot = (*msg2_slot+tdd_period_slot)%nr_slots_per_frame[mu];
*msg2_frame = (*msg2_slot>(rach_slot))? rach_frame : (rach_frame +1);
}
switch(response_window){
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl1:
slot_window = 1;
@@ -396,12 +410,11 @@ void nr_schedule_msg2(uint16_t rach_frame, uint16_t rach_slot,
// slot and frame limit to transmit msg2 according to response window
uint8_t slot_limit = (rach_slot + slot_window)%nr_slots_per_frame[mu];
//uint8_t frame_limit = (slot_limit>(rach_slot))? rach_frame : (rach_frame +1);
uint8_t frame_limit = (slot_limit>(rach_slot))? rach_frame : (rach_frame +1);
// go to previous slot if the current scheduled slot is beyond the response window
// and if the slot is not among the PDCCH monitored ones (38.213 10.1)
while ((*msg2_slot>slot_limit) || ((*msg2_frame*nr_slots_per_frame[mu]+*msg2_slot-monitoring_offset)%monitoring_slot_period !=0)) {
while (((*msg2_slot>slot_limit)&&(*msg2_frame>frame_limit)) || ((*msg2_frame*nr_slots_per_frame[mu]+*msg2_slot-monitoring_offset)%monitoring_slot_period !=0)) {
if((*msg2_slot%tdd_period_slot) > 0)
(*msg2_slot)--;
else
@@ -562,7 +575,9 @@ void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){
stop_meas(&mac->schedule_ra);
}
void nr_get_Msg3alloc(NR_ServingCellConfigCommon_t *scc,
void nr_get_Msg3alloc(module_id_t module_id,
int CC_id,
NR_ServingCellConfigCommon_t *scc,
NR_BWP_Uplink_t *ubwp,
sub_frame_t current_slot,
frame_t current_frame,
@@ -596,27 +611,25 @@ void nr_get_Msg3alloc(NR_ServingCellConfigCommon_t *scc,
ra->Msg3_frame = current_frame + (temp_slot/nr_slots_per_frame[mu]);
LOG_I(MAC, "[RAPROC] Msg3 slot %d: current slot %u Msg3 frame %u k2 %u Msg3_tda_id %u start symbol index %u\n", ra->Msg3_slot, current_slot, ra->Msg3_frame, k2,ra->Msg3_tda_id, StartSymbolIndex);
ra->msg3_nb_rb = 18;
ra->msg3_first_rb = 0;
}
void nr_schedule_reception_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP){
gNB_MAC_INST *mac = RC.nrmac[module_idP];
nfapi_nr_ul_tti_request_t *ul_req = &mac->UL_tti_req[0];
NR_COMMON_channels_t *cc = &mac->common_channels[CC_id];
NR_RA_t *ra = &cc->ra[0];
if (ra->state == WAIT_Msg3) {
if ((frameP == ra->Msg3_frame) && (slotP == ra->Msg3_slot) ){
ul_req->SFN = ra->Msg3_frame;
ul_req->Slot = ra->Msg3_slot;
ul_req->pdus_list[ul_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE;
ul_req->pdus_list[ul_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t);
ul_req->pdus_list[ul_req->n_pdus].pusch_pdu = ra->pusch_pdu;
ul_req->n_pdus+=1;
}
uint16_t *vrb_map_UL =
&RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[ra->Msg3_slot * 275];
const uint16_t bwpSize = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, 275);
/* search 18 free RBs */
int rbSize = 0;
int rbStart = 0;
while (rbSize < 18) {
rbStart += rbSize; /* last iteration rbSize was not enough, skip it */
rbSize = 0;
while (rbStart < bwpSize && vrb_map_UL[rbStart])
rbStart++;
AssertFatal(rbStart < bwpSize - 18, "no space to allocate Msg 3 for RA!\n");
while (rbStart + rbSize < bwpSize
&& !vrb_map_UL[rbStart + rbSize]
&& rbSize < 18)
rbSize++;
}
ra->msg3_nb_rb = 18;
ra->msg3_first_rb = rbStart;
}
void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP){
@@ -631,10 +644,32 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
return;
}
uint16_t *vrb_map_UL =
&RC.nrmac[module_idP]->common_channels[CC_id].vrb_map_UL[ra->Msg3_slot * 275];
for (int i = 0; i < ra->msg3_nb_rb; ++i) {
AssertFatal(!vrb_map_UL[i + ra->msg3_first_rb],
"RB %d in %4d.%2d is already taken, cannot allocate Msg3!\n",
i + ra->msg3_first_rb,
ra->Msg3_frame,
ra->Msg3_slot);
vrb_map_UL[i + ra->msg3_first_rb] = 1;
}
LOG_I(MAC, "[gNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA is active, Msg3 in (%d,%d)\n", module_idP, frameP, slotP, CC_id, ra->Msg3_frame, ra->Msg3_slot);
nfapi_nr_pusch_pdu_t *pusch_pdu = &ra->pusch_pdu;
nfapi_nr_ul_tti_request_t *future_ul_tti_req = &RC.nrmac[module_idP]->UL_tti_req_ahead[CC_id][ra->Msg3_slot];
AssertFatal(future_ul_tti_req->SFN == ra->Msg3_frame
&& future_ul_tti_req->Slot == ra->Msg3_slot,
"future UL_tti_req's frame.slot %d.%d does not match PUSCH %d.%d\n",
future_ul_tti_req->SFN,
future_ul_tti_req->Slot,
ra->Msg3_frame,
ra->Msg3_slot);
future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE;
future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t);
nfapi_nr_pusch_pdu_t *pusch_pdu = &future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pusch_pdu;
memset(pusch_pdu, 0, sizeof(nfapi_nr_pusch_pdu_t));
future_ul_tti_req->n_pdus += 1;
AssertFatal(ra->secondaryCellGroup,
"no secondaryCellGroup for RNTI %04x\n",
@@ -913,7 +948,7 @@ void nr_generate_Msg2(module_id_t module_idP,
dl_req->nPDUs+=2;
// Program UL processing for Msg3
nr_get_Msg3alloc(scc, ubwp, slotP, frameP, ra);
nr_get_Msg3alloc(module_idP, CC_id, scc, ubwp, slotP, frameP, ra);
LOG_I(MAC, "Frame %d, Subframe %d: Setting Msg3 reception for Frame %d Subframe %d\n", frameP, slotP, ra->Msg3_frame, ra->Msg3_slot);
nr_add_msg3(module_idP, CC_id, frameP, slotP);
ra->state = WAIT_Msg3;
@@ -990,7 +1025,7 @@ void nr_fill_rar(uint8_t Mod_idP,
uint8_t * dlsch_buffer,
nfapi_nr_pusch_pdu_t *pusch_pdu){
LOG_I(MAC, "[gNB] Generate RAR MAC PDU frame %d slot %d preamble index %u", ra->Msg2_frame, ra-> Msg2_slot, ra->preamble_index);
LOG_I(MAC, "[gNB] Generate RAR MAC PDU frame %d slot %d preamble index %u\n", ra->Msg2_frame, ra-> Msg2_slot, ra->preamble_index);
NR_RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) dlsch_buffer;
NR_MAC_RAR *rar = (NR_MAC_RAR *) (dlsch_buffer + 1);
unsigned char csi_req = 0, tpc_command;
@@ -38,7 +38,6 @@
#include "NR_MAC_COMMON/nr_mac.h"
#include "NR_MAC_gNB/nr_mac_gNB.h"
#include "NR_MAC_COMMON/nr_mac_extern.h"
#include "LAYER2/MAC/mac.h"
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
/*NFAPI*/
@@ -455,7 +454,8 @@ void nr_simple_dlsch_preprocessor(module_id_t module_id,
AssertFatal(sched_ctrl->pucch_sched_idx >= 0, "no uplink slot for PUCCH found!\n");
uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map;
const int current_harq_pid = sched_ctrl->current_harq_pid;
// for now HARQ PID is fixed and should be the same as in post-processor
const int current_harq_pid = slot % num_slots_per_tdd;
NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid];
NR_UE_ret_info_t *retInfo = &sched_ctrl->retInfo[current_harq_pid];
const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, 275);
@@ -589,7 +589,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
1 /* nrOfLayers */)
>> 3;
const int current_harq_pid = sched_ctrl->current_harq_pid;
const int current_harq_pid = slot % num_slots_per_tdd;
NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid];
NR_sched_pucch *pucch = &sched_ctrl->sched_pucch[sched_ctrl->pucch_sched_idx][sched_ctrl->pucch_occ_idx];
harq->feedback_slot = pucch->ul_slot;
@@ -642,7 +642,15 @@ void nr_schedule_ue_spec(module_id_t module_id,
retInfo->numDmrsCdmGrpsNoData);
/* we do not have to do anything, since we do not require to get data
* from RLC, encode MAC CEs, or copy data to FAPI structures */
LOG_W(MAC, "%d.%2d retransmission UE %d/RNTI %04x\n", frame, slot, UE_id, rnti);
LOG_W(MAC,
"%d.%2d DL retransmission UE %d/RNTI %04x HARQ PID %d round %d NDI %d\n",
frame,
slot,
UE_id,
rnti,
current_harq_pid,
harq->round,
harq->ndi);
} else { /* initial transmission */
LOG_D(MAC, "[%s] Initial HARQ transmission in %d.%d\n", __FUNCTION__, frame, slot);
+118 -446
View File
@@ -258,8 +258,6 @@ void nr_preprocessor_phytest(module_id_t module_id,
sub_frame_t slot,
int num_slots_per_tdd)
{
if (slot != 1)
return; /* only schedule in slot 1 for now */
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
const int UE_id = 0;
const int CC_id = 0;
@@ -317,7 +315,7 @@ void nr_preprocessor_phytest(module_id_t module_id,
sched_ctrl->coreset = get_coreset(
sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */);
const int cid = sched_ctrl->coreset->controlResourceSetId;
const uint16_t Y = UE_info->Y[UE_id][cid][RC.nrmac[module_id]->current_slot];
const uint16_t Y = UE_info->Y[UE_id][cid][slot];
const int m = UE_info->num_pdcch_cand[UE_id][cid];
sched_ctrl->cce_index = allocate_nr_CCEs(RC.nrmac[module_id],
sched_ctrl->active_bwp,
@@ -352,457 +350,131 @@ void nr_preprocessor_phytest(module_id_t module_id,
vrb_map[rb + sched_ctrl->rbStart] = 1;
}
void config_uldci(NR_BWP_Uplink_t *ubwp,
nfapi_nr_pusch_pdu_t *pusch_pdu,
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
dci_pdu_rel15_t *dci_pdu_rel15,
int *dci_formats, int *rnti_types,
int time_domain_assignment, uint8_t tpc,
int n_ubwp, int bwp_id) {
void nr_ul_preprocessor_phytest(module_id_t module_id,
frame_t frame,
sub_frame_t slot,
int num_slots_per_tdd,
uint64_t ulsch_in_slot_bitmap) {
gNB_MAC_INST *nr_mac = RC.nrmac[module_id];
NR_COMMON_channels_t *cc = nr_mac->common_channels;
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
const int mu = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing;
NR_UE_info_t *UE_info = &nr_mac->UE_info;
switch(dci_formats[(pdcch_pdu_rel15->numDlDci)-1]) {
case NR_UL_DCI_FORMAT_0_0:
dci_pdu_rel15->frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(pusch_pdu->rb_size,
pusch_pdu->rb_start,
NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275));
AssertFatal(UE_info->num_UEs <= 1,
"%s() cannot handle more than one UE, but found %d\n",
__func__,
UE_info->num_UEs);
if (UE_info->num_UEs == 0)
return;
dci_pdu_rel15->time_domain_assignment.val = time_domain_assignment;
dci_pdu_rel15->frequency_hopping_flag.val = pusch_pdu->frequency_hopping;
dci_pdu_rel15->mcs = 9;
const int UE_id = 0;
const int CC_id = 0;
dci_pdu_rel15->format_indicator = 0;
dci_pdu_rel15->ndi = 1;
dci_pdu_rel15->rv = 0;
dci_pdu_rel15->harq_pid = 0;
dci_pdu_rel15->tpc = 1;
break;
case NR_UL_DCI_FORMAT_0_1:
dci_pdu_rel15->ndi = pusch_pdu->pusch_data.new_data_indicator;
dci_pdu_rel15->rv = pusch_pdu->pusch_data.rv_index;
dci_pdu_rel15->harq_pid = pusch_pdu->pusch_data.harq_process_id;
dci_pdu_rel15->frequency_hopping_flag.val = pusch_pdu->frequency_hopping;
dci_pdu_rel15->dai[0].val = 0; //TODO
// bwp indicator
if (n_ubwp < 4)
dci_pdu_rel15->bwp_indicator.val = bwp_id;
else
dci_pdu_rel15->bwp_indicator.val = bwp_id - 1; // as per table 7.3.1.1.2-1 in 38.212
// frequency domain assignment
if (ubwp->bwp_Dedicated->pusch_Config->choice.setup->resourceAllocation==NR_PUSCH_Config__resourceAllocation_resourceAllocationType1)
dci_pdu_rel15->frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(pusch_pdu->rb_size,
pusch_pdu->rb_start,
NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275));
else
AssertFatal(1==0,"Only frequency resource allocation type 1 is currently supported\n");
// time domain assignment
dci_pdu_rel15->time_domain_assignment.val = time_domain_assignment;
// mcs
dci_pdu_rel15->mcs = pusch_pdu->mcs_index;
// tpc command for pusch
dci_pdu_rel15->tpc = tpc;
// SRS resource indicator
if (ubwp->bwp_Dedicated->pusch_Config->choice.setup->txConfig != NULL) {
if (*ubwp->bwp_Dedicated->pusch_Config->choice.setup->txConfig == NR_PUSCH_Config__txConfig_codebook)
dci_pdu_rel15->srs_resource_indicator.val = 0; // taking resource 0 for SRS
else
AssertFatal(1==0,"Non Codebook configuration non supported\n");
}
// Antenna Ports
dci_pdu_rel15->antenna_ports.val = 0; // TODO for now it is hardcoded, it should depends on cdm group no data and rank
// DMRS sequence initialization
dci_pdu_rel15->dmrs_sequence_initialization.val = pusch_pdu->scid;
break;
default :
AssertFatal(1==0,"Valid UL formats are 0_0 and 0_1 \n");
}
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
LOG_D(MAC, "[gNB scheduler phytest] ULDCI type 0 payload: PDCCH CCEIndex %d, freq_alloc %d, time_alloc %d, freq_hop_flag %d, mcs %d tpc %d ndi %d rv %d\n",
pdcch_pdu_rel15->dci_pdu.CceIndex[pdcch_pdu_rel15->numDlDci],
dci_pdu_rel15->frequency_domain_assignment.val,
dci_pdu_rel15->time_domain_assignment.val,
dci_pdu_rel15->frequency_hopping_flag.val,
dci_pdu_rel15->mcs,
dci_pdu_rel15->tpc,
dci_pdu_rel15->ndi,
dci_pdu_rel15->rv);
}
int8_t select_ul_harq_pid(NR_UE_sched_ctrl_t *sched_ctrl) {
uint8_t hrq_id;
uint8_t max_ul_harq_pids = 3; // temp: for testing
// schedule active harq processes
NR_UE_ul_harq_t cur_harq;
for (hrq_id=0; hrq_id < max_ul_harq_pids; hrq_id++) {
cur_harq = sched_ctrl->ul_harq_processes[hrq_id];
if (cur_harq.state==ACTIVE_NOT_SCHED) {
#ifdef UL_HARQ_PRINT
printf("[SCHED] Found ulharq id %d, scheduling it for retransmission\n",hrq_id);
#endif
return hrq_id;
}
}
// schedule new harq processes
for (hrq_id=0; hrq_id < max_ul_harq_pids; hrq_id++) {
cur_harq = sched_ctrl->ul_harq_processes[hrq_id];
if (cur_harq.state==INACTIVE) {
#ifdef UL_HARQ_PRINT
printf("[SCHED] Found new ulharq id %d, scheduling it\n",hrq_id);
#endif
return hrq_id;
}
}
LOG_E(MAC,"All UL HARQ processes are busy. Cannot schedule ULSCH\n");
return -1;
}
long get_K2(NR_BWP_Uplink_t *ubwp, int time_domain_assignment, int mu) {
DevAssert(ubwp);
const NR_PUSCH_TimeDomainResourceAllocation_t *tda_list = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment];
if (tda_list->k2)
return *tda_list->k2;
else if (mu < 2)
return 1;
else if (mu == 2)
return 2;
else
return 3;
}
void schedule_fapi_ul_pdu(int Mod_idP,
frame_t frameP,
sub_frame_t slotP,
int num_slots_per_tdd,
int ul_slots,
int time_domain_assignment,
uint64_t ulsch_in_slot_bitmap) {
gNB_MAC_INST *nr_mac = RC.nrmac[Mod_idP];
NR_COMMON_channels_t *cc = nr_mac->common_channels;
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
int bwp_id=1;
int mu = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing;
int UE_id = 0;
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
AssertFatal(UE_info->active[UE_id],"Cannot find UE_id %d is not active\n",UE_id);
NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id];
AssertFatal(secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
"downlinkBWP_ToAddModList has %d BWP!\n",
secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1];
int n_ubwp = secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.count;
NR_BWP_Downlink_t *bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1];
NR_PUSCH_Config_t *pusch_Config = ubwp->bwp_Dedicated->pusch_Config->choice.setup;
AssertFatal(time_domain_assignment<ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.count,
"time_domain_assignment %d>=%d\n",time_domain_assignment,ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.count);
int K2 = get_K2(ubwp, time_domain_assignment,mu);
/* check if slot is UL, and for phy test verify that it is in first TDD
* period, slot 8 (for K2=2, this is at slot 6 in the gNB; because of UE
const int tda = 1;
const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList =
sched_ctrl->active_ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
AssertFatal(tda < tdaList->list.count,
"time domain assignment %d >= %d\n",
tda,
tdaList->list.count);
int K2 = get_K2(sched_ctrl->active_ubwp, tda, mu);
const int sched_frame = frame + (slot + K2 >= num_slots_per_tdd);
const int sched_slot = (slot + K2) % num_slots_per_tdd;
/* check if slot is UL, and that slot is 8 (assuming K2=6 because of UE
* limitations). Note that if K2 or the TDD configuration is changed, below
* conditions might exclude each other and never be true */
const int slot_idx = (slotP + K2) % num_slots_per_tdd;
if (is_xlsch_in_slot(ulsch_in_slot_bitmap, slot_idx)
&& (!get_softmodem_params()->phy_test || slot_idx == 8)) {
if (!(is_xlsch_in_slot(ulsch_in_slot_bitmap, sched_slot) && sched_slot == 8))
return;
nfapi_nr_ul_dci_request_t *UL_dci_req = &RC.nrmac[Mod_idP]->UL_dci_req[0];
UL_dci_req->SFN = frameP;
UL_dci_req->Slot = slotP;
nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu;
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n");
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0,
"searchPsacesToAddModList is empty\n");
uint16_t rnti = UE_info->rnti[UE_id];
int first_ul_slot = num_slots_per_tdd - ul_slots;
NR_sched_pusch *pusch_sched = &UE_info->UE_sched_ctrl[UE_id].sched_pusch[slotP+K2-first_ul_slot];
pusch_sched->frame = frameP;
pusch_sched->slot = slotP + K2;
pusch_sched->active = true;
nfapi_nr_pusch_pdu_t *pusch_pdu = &pusch_sched->pusch_pdu;
memset(pusch_pdu,0,sizeof(nfapi_nr_pusch_pdu_t));
LOG_D(MAC, "Scheduling UE specific PUSCH\n");
//UL_tti_req = &nr_mac->UL_tti_req[CC_id];
int dci_formats[2];
int rnti_types[2];
NR_SearchSpace_t *ss;
int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n");
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0,
"searchPsacesToAddModList is empty\n");
int found=0;
for (int i=0;i<bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count;i++) {
ss=bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[i];
AssertFatal(ss->controlResourceSetId != NULL,"ss->controlResourceSetId is null\n");
AssertFatal(ss->searchSpaceType != NULL,"ss->searchSpaceType is null\n");
if (ss->searchSpaceType->present == target_ss) {
found=1;
break;
}
}
AssertFatal(found==1,"Couldn't find an adequate searchspace\n");
if (ss->searchSpaceType->choice.ue_Specific->dci_Formats)
dci_formats[0] = NR_UL_DCI_FORMAT_0_1;
else
dci_formats[0] = NR_UL_DCI_FORMAT_0_0;
rnti_types[0] = NR_RNTI_C;
//Resource Allocation in time domain
int startSymbolAndLength=0;
int StartSymbolIndex,NrOfSymbols,mapping_type;
startSymbolAndLength = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment]->startSymbolAndLength;
SLIV2SL(startSymbolAndLength,&StartSymbolIndex,&NrOfSymbols);
pusch_pdu->start_symbol_index = StartSymbolIndex;
pusch_pdu->nr_of_symbols = NrOfSymbols;
mapping_type = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment]->mappingType;
pusch_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA;
pusch_pdu->rnti = rnti;
pusch_pdu->handle = 0; //not yet used
pusch_pdu->bwp_size = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275);
pusch_pdu->bwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275);
pusch_pdu->subcarrier_spacing = ubwp->bwp_Common->genericParameters.subcarrierSpacing;
pusch_pdu->cyclic_prefix = 0;
if (pusch_Config->transformPrecoder == NULL) {
if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder == NULL)
pusch_pdu->transform_precoding = 1;
else
pusch_pdu->transform_precoding = 0;
}
else
pusch_pdu->transform_precoding = *pusch_Config->transformPrecoder;
if (pusch_Config->dataScramblingIdentityPUSCH != NULL)
pusch_pdu->data_scrambling_id = *pusch_Config->dataScramblingIdentityPUSCH;
else
pusch_pdu->data_scrambling_id = *scc->physCellId;
pusch_pdu->mcs_index = 9;
if (pusch_pdu->transform_precoding)
pusch_pdu->mcs_table = get_pusch_mcs_table(pusch_Config->mcs_Table, 0,
dci_formats[0], rnti_types[0], target_ss, false);
else
pusch_pdu->mcs_table = get_pusch_mcs_table(pusch_Config->mcs_TableTransformPrecoder, 1,
dci_formats[0], rnti_types[0], target_ss, false);
pusch_pdu->target_code_rate = nr_get_code_rate_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table);
pusch_pdu->qam_mod_order = nr_get_Qm_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table);
if (pusch_Config->tp_pi2BPSK!=NULL) {
if(((pusch_pdu->mcs_table==3)&&(pusch_pdu->mcs_index<2)) ||
((pusch_pdu->mcs_table==4)&&(pusch_pdu->mcs_index<6))) {
pusch_pdu->target_code_rate = pusch_pdu->target_code_rate>>1;
pusch_pdu->qam_mod_order = pusch_pdu->qam_mod_order<<1;
}
}
pusch_pdu->nrOfLayers = 1;
//Pusch Allocation in frequency domain [TS38.214, sec 6.1.2.2]
if (pusch_Config->resourceAllocation==NR_PUSCH_Config__resourceAllocation_resourceAllocationType1) {
pusch_pdu->resource_alloc = 1; //type 1
pusch_pdu->rb_start = 0;
if (get_softmodem_params()->phy_test==1)
pusch_pdu->rb_size = min(pusch_pdu->bwp_size,50);
else
pusch_pdu->rb_size = pusch_pdu->bwp_size;
}
else
AssertFatal(1==0,"Only frequency resource allocation type 1 is currently supported\n");
pusch_pdu->vrb_to_prb_mapping = 0;
if (pusch_Config->frequencyHopping==NULL)
pusch_pdu->frequency_hopping = 0;
else
pusch_pdu->frequency_hopping = 1;
//pusch_pdu->tx_direct_current_location;//The uplink Tx Direct Current location for the carrier. Only values in the value range of this field between 0 and 3299, which indicate the subcarrier index within the carrier corresponding 1o the numerology of the corresponding uplink BWP and value 3300, which indicates "Outside the carrier" and value 3301, which indicates "Undetermined position within the carrier" are used. [TS38.331, UplinkTxDirectCurrentBWP IE]
//pusch_pdu->uplink_frequency_shift_7p5khz = 0;
// --------------------
// ------- DMRS -------
// --------------------
NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig;
if (mapping_type == NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeA)
NR_DMRS_UplinkConfig = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup;
else
NR_DMRS_UplinkConfig = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup;
if (NR_DMRS_UplinkConfig->dmrs_Type == NULL)
pusch_pdu->dmrs_config_type = 0;
else
pusch_pdu->dmrs_config_type = 1;
pusch_pdu->scid = 0; // DMRS sequence initialization [TS38.211, sec 6.4.1.1.1]
if (pusch_pdu->transform_precoding) { // transform precoding disabled
long *scramblingid;
if (pusch_pdu->scid == 0)
scramblingid = NR_DMRS_UplinkConfig->transformPrecodingDisabled->scramblingID0;
else
scramblingid = NR_DMRS_UplinkConfig->transformPrecodingDisabled->scramblingID1;
if (scramblingid == NULL)
pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId;
else
pusch_pdu->ul_dmrs_scrambling_id = *scramblingid;
}
else {
pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId;
if (NR_DMRS_UplinkConfig->transformPrecodingEnabled->nPUSCH_Identity != NULL)
pusch_pdu->pusch_identity = *NR_DMRS_UplinkConfig->transformPrecodingEnabled->nPUSCH_Identity;
else
pusch_pdu->pusch_identity = *scc->physCellId;
}
pusch_dmrs_AdditionalPosition_t additional_pos;
if (NR_DMRS_UplinkConfig->dmrs_AdditionalPosition == NULL)
additional_pos = 2;
else {
if (*NR_DMRS_UplinkConfig->dmrs_AdditionalPosition == NR_DMRS_UplinkConfig__dmrs_AdditionalPosition_pos3)
additional_pos = 3;
else
additional_pos = *NR_DMRS_UplinkConfig->dmrs_AdditionalPosition;
}
pusch_maxLength_t pusch_maxLength;
if (NR_DMRS_UplinkConfig->maxLength == NULL)
pusch_maxLength = 1;
else
pusch_maxLength = 2;
uint16_t l_prime_mask = get_l_prime(pusch_pdu->nr_of_symbols, mapping_type, additional_pos, pusch_maxLength);
pusch_pdu->ul_dmrs_symb_pos = l_prime_mask << pusch_pdu->start_symbol_index;
pusch_pdu->num_dmrs_cdm_grps_no_data = 1;
pusch_pdu->dmrs_ports = 1;
// --------------------------------------------------------------------------------------------------------------------------------------------
// --------------------
// ------- PTRS -------
// --------------------
if (NR_DMRS_UplinkConfig->phaseTrackingRS != NULL) {
// TODO to be fixed from RRC config
uint8_t ptrs_mcs1 = 2; // higher layer parameter in PTRS-UplinkConfig
uint8_t ptrs_mcs2 = 4; // higher layer parameter in PTRS-UplinkConfig
uint8_t ptrs_mcs3 = 10; // higher layer parameter in PTRS-UplinkConfig
uint16_t n_rb0 = 25; // higher layer parameter in PTRS-UplinkConfig
uint16_t n_rb1 = 75; // higher layer parameter in PTRS-UplinkConfig
pusch_pdu->pusch_ptrs.ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, pusch_pdu->mcs_index, pusch_pdu->mcs_table);
pusch_pdu->pusch_ptrs.ptrs_freq_density = get_K_ptrs(n_rb0, n_rb1, pusch_pdu->rb_size);
pusch_pdu->pusch_ptrs.ptrs_ports_list = (nfapi_nr_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ptrs_ports_t));
pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0;
pusch_pdu->pdu_bit_map |= PUSCH_PDU_BITMAP_PUSCH_PTRS; // enable PUSCH PTRS
}
else{
pusch_pdu->pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS
}
// --------------------------------------------------------------------------------------------------------------------------------------------
//Pusch Allocation in frequency domain [TS38.214, sec 6.1.2.2]
//Optional Data only included if indicated in pduBitmap
int8_t harq_id = select_ul_harq_pid(&UE_info->UE_sched_ctrl[UE_id]);
if (harq_id < 0) return;
NR_UE_ul_harq_t *cur_harq = &UE_info->UE_sched_ctrl[UE_id].ul_harq_processes[harq_id];
pusch_pdu->pusch_data.harq_process_id = harq_id;
pusch_pdu->pusch_data.new_data_indicator = cur_harq->ndi;
pusch_pdu->pusch_data.rv_index = nr_rv_round_map[cur_harq->round];
cur_harq->state = ACTIVE_SCHED;
cur_harq->last_tx_slot = pusch_sched->slot;
uint8_t num_dmrs_symb = 0;
for(int dmrs_counter = pusch_pdu->start_symbol_index; dmrs_counter < pusch_pdu->start_symbol_index + pusch_pdu->nr_of_symbols; dmrs_counter++)
num_dmrs_symb += ((pusch_pdu->ul_dmrs_symb_pos >> dmrs_counter) & 1);
uint8_t N_PRB_DMRS;
if (pusch_pdu->dmrs_config_type == 0) {
N_PRB_DMRS = pusch_pdu->num_dmrs_cdm_grps_no_data*6;
}
else {
N_PRB_DMRS = pusch_pdu->num_dmrs_cdm_grps_no_data*4;
}
pusch_pdu->pusch_data.tb_size = nr_compute_tbs(pusch_pdu->qam_mod_order,
pusch_pdu->target_code_rate,
pusch_pdu->rb_size,
pusch_pdu->nr_of_symbols,
N_PRB_DMRS * num_dmrs_symb,
0, //nb_rb_oh
0,
pusch_pdu->nrOfLayers)>>3;
UE_info->mac_stats[UE_id].ulsch_rounds[cur_harq->round]++;
if (cur_harq->round == 0) UE_info->mac_stats[UE_id].ulsch_total_bytes_scheduled+=pusch_pdu->pusch_data.tb_size;
pusch_pdu->pusch_data.num_cb = 0; //CBG not supported
//pusch_pdu->pusch_data.cb_present_and_position;
//pusch_pdu->pusch_uci;
//pusch_pdu->pusch_ptrs;
//pusch_pdu->dfts_ofdm;
//beamforming
//pusch_pdu->beamforming; //not used for now
ul_dci_request_pdu = &UL_dci_req->ul_dci_pdu_list[UL_dci_req->numPdus];
memset((void*)ul_dci_request_pdu,0,sizeof(nfapi_nr_ul_dci_request_pdus_t));
ul_dci_request_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE;
ul_dci_request_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15;
UL_dci_req->numPdus+=1;
LOG_D(MAC,"Configuring ULDCI/PDCCH in %d.%d\n", frameP,slotP);
uint8_t nr_of_candidates, aggregation_level;
find_aggregation_candidates(&aggregation_level, &nr_of_candidates, ss);
NR_ControlResourceSet_t *coreset = get_coreset(bwp, ss, 1 /* dedicated */);
const int cid = coreset->controlResourceSetId;
const uint16_t Y = UE_info->Y[UE_id][cid][nr_mac->current_slot];
const int m = UE_info->num_pdcch_cand[UE_id][cid];
int CCEIndex = allocate_nr_CCEs(nr_mac,
bwp,
coreset,
aggregation_level,
Y,
m,
nr_of_candidates);
if (CCEIndex < 0) {
LOG_E(MAC, "%s(): CCE list not empty, couldn't schedule PUSCH\n", __func__);
pusch_sched->active = false;
const uint16_t rbStart = 0;
const uint16_t rbSize = 50; /* due to OAI UE limitations */
uint16_t *vrb_map_UL =
&RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[sched_slot * 275];
for (int i = rbStart; i < rbStart + rbSize; ++i) {
if (vrb_map_UL[i]) {
LOG_E(MAC,
"%s(): %4d.%2d RB %d is already reserved, cannot schedule UE\n",
__func__,
frame,
slot,
i);
return;
}
else {
UE_info->num_pdcch_cand[UE_id][cid]++;
nr_configure_pdcch(nr_mac,
pdcch_pdu_rel15,
UE_info->rnti[UE_id],
ss,
coreset,
scc,
bwp,
aggregation_level,
CCEIndex);
dci_pdu_rel15_t *dci_pdu_rel15 = calloc(MAX_DCI_CORESET,sizeof(dci_pdu_rel15_t));
config_uldci(ubwp,pusch_pdu,pdcch_pdu_rel15,&dci_pdu_rel15[0],dci_formats,rnti_types,time_domain_assignment,UE_info->UE_sched_ctrl[UE_id].tpc0,n_ubwp,bwp_id);
fill_dci_pdu_rel15(scc,secondaryCellGroup,pdcch_pdu_rel15,dci_pdu_rel15,dci_formats,rnti_types,pusch_pdu->bwp_size,bwp_id);
free(dci_pdu_rel15);
}
}
}
sched_ctrl->sched_pusch.slot = sched_slot;
sched_ctrl->sched_pusch.frame = sched_frame;
const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
sched_ctrl->search_space = get_searchspace(sched_ctrl->active_bwp, target_ss);
uint8_t nr_of_candidates;
find_aggregation_candidates(&sched_ctrl->aggregation_level,
&nr_of_candidates,
sched_ctrl->search_space);
sched_ctrl->coreset = get_coreset(
sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */);
const int cid = sched_ctrl->coreset->controlResourceSetId;
const uint16_t Y = UE_info->Y[UE_id][cid][slot];
const int m = UE_info->num_pdcch_cand[UE_id][cid];
sched_ctrl->cce_index = allocate_nr_CCEs(RC.nrmac[module_id],
sched_ctrl->active_bwp,
sched_ctrl->coreset,
sched_ctrl->aggregation_level,
Y,
m,
nr_of_candidates);
if (sched_ctrl->cce_index < 0) {
LOG_E(MAC, "%s(): CCE list not empty, couldn't schedule PUSCH\n", __func__);
return;
}
UE_info->num_pdcch_cand[UE_id][cid]++;
sched_ctrl->sched_pusch.time_domain_allocation = tda;
const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats;
const int dci_format = f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0;
const uint8_t num_dmrs_cdm_grps_no_data = 1;
/* we want to avoid a lengthy deduction of DMRS and other parameters in
* every TTI if we can save it, so check whether dci_format, TDA, or
* num_dmrs_cdm_grps_no_data has changed and only then recompute */
NR_sched_pusch_save_t *ps = &sched_ctrl->pusch_save;
if (ps->time_domain_allocation != tda
|| ps->dci_format != dci_format
|| ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data)
nr_save_pusch_fields(scc,
sched_ctrl->active_ubwp,
dci_format,
tda,
num_dmrs_cdm_grps_no_data,
ps);
const int mcs = 9;
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
sched_pusch->mcs = mcs;
sched_pusch->rbStart = rbStart;
sched_pusch->rbSize = rbSize;
/* Calculate TBS from MCS */
sched_pusch->R = nr_get_code_rate_ul(mcs, ps->mcs_table);
sched_pusch->Qm = nr_get_Qm_ul(mcs, ps->mcs_table);
if (ps->pusch_Config->tp_pi2BPSK
&& ((ps->mcs_table == 3 && mcs < 2) || (ps->mcs_table == 4 && mcs < 6))) {
sched_pusch->R >>= 1;
sched_pusch->Qm <<= 1;
}
sched_pusch->tb_size = nr_compute_tbs(sched_pusch->Qm,
sched_pusch->R,
sched_pusch->rbSize,
ps->nrOfSymbols,
ps->N_PRB_DMRS * ps->num_dmrs_symb,
0, // nb_rb_oh
0,
1 /* NrOfLayers */)
>> 3;
/* mark the corresponding RBs as used */
for (int rb = rbStart; rb < rbStart + rbSize; rb++)
vrb_map_UL[rb] = 1;
}
@@ -32,7 +32,6 @@
#include "assertions.h"
#include "LAYER2/MAC/mac.h"
#include "NR_MAC_gNB/nr_mac_gNB.h"
#include "NR_MAC_COMMON/nr_mac_extern.h"
@@ -48,9 +47,6 @@
#include "RRC/NR/nr_rrc_extern.h"
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
//#include "LAYER2/MAC/pre_processor.c"
#include "pdcp.h"
#include "intertask_interface.h"
#include "T.h"
@@ -213,6 +209,75 @@ int allocate_nr_CCEs(gNB_MAC_INST *nr_mac,
}
void nr_save_pusch_fields(const NR_ServingCellConfigCommon_t *scc,
const NR_BWP_Uplink_t *ubwp,
long dci_format,
int tda,
uint8_t num_dmrs_cdm_grps_no_data,
NR_sched_pusch_save_t *ps)
{
ps->dci_format = dci_format;
ps->time_domain_allocation = tda;
ps->num_dmrs_cdm_grps_no_data = num_dmrs_cdm_grps_no_data;
const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList =
ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength;
SLIV2SL(startSymbolAndLength,
&ps->startSymbolIndex,
&ps->nrOfSymbols);
ps->pusch_Config = ubwp->bwp_Dedicated->pusch_Config->choice.setup;
if (!ps->pusch_Config->transformPrecoder)
ps->transform_precoding = !scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder;
else
ps->transform_precoding = *ps->pusch_Config->transformPrecoder;
const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
if (ps->transform_precoding)
ps->mcs_table = get_pusch_mcs_table(ps->pusch_Config->mcs_Table,
0,
ps->dci_format,
NR_RNTI_C,
target_ss,
false);
else
ps->mcs_table = get_pusch_mcs_table(ps->pusch_Config->mcs_TableTransformPrecoder,
1,
ps->dci_format,
NR_RNTI_C,
target_ss,
false);
/* DMRS calculations */
ps->mapping_type = tdaList->list.array[tda]->mappingType;
ps->NR_DMRS_UplinkConfig =
ps->mapping_type == NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeA
? ps->pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup
: ps->pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup;
ps->dmrs_config_type = ps->NR_DMRS_UplinkConfig->dmrs_Type == NULL ? 0 : 1;
const pusch_dmrs_AdditionalPosition_t additional_pos =
ps->NR_DMRS_UplinkConfig->dmrs_AdditionalPosition == NULL
? 2
: (*ps->NR_DMRS_UplinkConfig->dmrs_AdditionalPosition ==
NR_DMRS_UplinkConfig__dmrs_AdditionalPosition_pos3
? 3
: *ps->NR_DMRS_UplinkConfig->dmrs_AdditionalPosition);
const pusch_maxLength_t pusch_maxLength =
ps->NR_DMRS_UplinkConfig->maxLength == NULL ? 1 : 2;
const uint16_t l_prime_mask = get_l_prime(ps->nrOfSymbols,
ps->mapping_type,
additional_pos,
pusch_maxLength);
ps->ul_dmrs_symb_pos = l_prime_mask << ps->startSymbolIndex;
uint8_t num_dmrs_symb = 0;
for(int i = ps->startSymbolIndex; i < ps->startSymbolIndex + ps->nrOfSymbols; i++)
num_dmrs_symb += (ps->ul_dmrs_symb_pos >> i) & 1;
ps->num_dmrs_symb = num_dmrs_symb;
ps->N_PRB_DMRS = ps->dmrs_config_type == 0
? num_dmrs_cdm_grps_no_data * 6
: num_dmrs_cdm_grps_no_data * 4;
}
void nr_configure_css_dci_initial(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu,
nr_scs_e scs_common,
nr_scs_e pdcch_scs,
@@ -637,6 +702,81 @@ void nr_fill_nfapi_dl_pdu(int Mod_idP,
dl_req->nPDUs += 2;
}
void config_uldci(NR_BWP_Uplink_t *ubwp,
nfapi_nr_pusch_pdu_t *pusch_pdu,
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
dci_pdu_rel15_t *dci_pdu_rel15,
int *dci_formats,
int time_domain_assignment, uint8_t tpc,
int n_ubwp, int bwp_id) {
const int bw = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, 275);
switch (dci_formats[(pdcch_pdu_rel15->numDlDci) - 1]) {
case NR_UL_DCI_FORMAT_0_0:
dci_pdu_rel15->frequency_domain_assignment.val =
PRBalloc_to_locationandbandwidth0(pusch_pdu->rb_size, pusch_pdu->rb_start, bw);
dci_pdu_rel15->time_domain_assignment.val = time_domain_assignment;
dci_pdu_rel15->frequency_hopping_flag.val = pusch_pdu->frequency_hopping;
dci_pdu_rel15->mcs = pusch_pdu->mcs_index;
dci_pdu_rel15->format_indicator = 0;
dci_pdu_rel15->ndi = pusch_pdu->pusch_data.new_data_indicator;
dci_pdu_rel15->rv = pusch_pdu->pusch_data.rv_index;
dci_pdu_rel15->harq_pid = pusch_pdu->pusch_data.harq_process_id;
dci_pdu_rel15->tpc = tpc;
break;
case NR_UL_DCI_FORMAT_0_1:
dci_pdu_rel15->ndi = pusch_pdu->pusch_data.new_data_indicator;
dci_pdu_rel15->rv = pusch_pdu->pusch_data.rv_index;
dci_pdu_rel15->harq_pid = pusch_pdu->pusch_data.harq_process_id;
dci_pdu_rel15->frequency_hopping_flag.val = pusch_pdu->frequency_hopping;
dci_pdu_rel15->dai[0].val = 0; //TODO
// bwp indicator
if (n_ubwp < 4)
dci_pdu_rel15->bwp_indicator.val = bwp_id;
else
dci_pdu_rel15->bwp_indicator.val = bwp_id - 1; // as per table 7.3.1.1.2-1 in 38.212
// frequency domain assignment
AssertFatal(ubwp->bwp_Dedicated->pusch_Config->choice.setup->resourceAllocation
== NR_PUSCH_Config__resourceAllocation_resourceAllocationType1,
"Only frequency resource allocation type 1 is currently supported\n");
dci_pdu_rel15->frequency_domain_assignment.val =
PRBalloc_to_locationandbandwidth0(pusch_pdu->rb_size, pusch_pdu->rb_start, bw);
// time domain assignment
dci_pdu_rel15->time_domain_assignment.val = time_domain_assignment;
// mcs
dci_pdu_rel15->mcs = pusch_pdu->mcs_index;
// tpc command for pusch
dci_pdu_rel15->tpc = tpc;
// SRS resource indicator
if (ubwp->bwp_Dedicated->pusch_Config->choice.setup->txConfig != NULL) {
AssertFatal(*ubwp->bwp_Dedicated->pusch_Config->choice.setup->txConfig == NR_PUSCH_Config__txConfig_codebook,
"Non Codebook configuration non supported\n");
dci_pdu_rel15->srs_resource_indicator.val = 0; // taking resource 0 for SRS
}
// Antenna Ports
dci_pdu_rel15->antenna_ports.val = 0; // TODO for now it is hardcoded, it should depends on cdm group no data and rank
// DMRS sequence initialization
dci_pdu_rel15->dmrs_sequence_initialization.val = pusch_pdu->scid;
break;
default :
AssertFatal(0, "Valid UL formats are 0_0 and 0_1\n");
}
LOG_D(MAC,
"%s() ULDCI type 0 payload: PDCCH CCEIndex %d, freq_alloc %d, "
"time_alloc %d, freq_hop_flag %d, mcs %d tpc %d ndi %d rv %d\n",
__func__,
pdcch_pdu_rel15->dci_pdu.CceIndex[pdcch_pdu_rel15->numDlDci],
dci_pdu_rel15->frequency_domain_assignment.val,
dci_pdu_rel15->time_domain_assignment.val,
dci_pdu_rel15->frequency_hopping_flag.val,
dci_pdu_rel15->mcs,
dci_pdu_rel15->tpc,
dci_pdu_rel15->ndi,
dci_pdu_rel15->rv);
}
void nr_configure_pdcch(gNB_MAC_INST *nr_mac,
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
uint16_t rnti,
@@ -1721,20 +1861,17 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP){
UE_info->UE_sched_ctrl[UE_id].ta_update = 31;
UE_info->UE_sched_ctrl[UE_id].ta_apply = false;
UE_info->UE_sched_ctrl[UE_id].ul_rssi = 0;
/* set illegal time domain allocation to force recomputation of all fields */
UE_info->UE_sched_ctrl[UE_id].pusch_save.time_domain_allocation = -1;
UE_info->UE_sched_ctrl[UE_id].sched_pucch = (NR_sched_pucch **)malloc(num_slots_ul*sizeof(NR_sched_pucch *));
for (int s=0; s<num_slots_ul;s++)
UE_info->UE_sched_ctrl[UE_id].sched_pucch[s] = (NR_sched_pucch *)malloc(2*sizeof(NR_sched_pucch));
UE_info->UE_sched_ctrl[UE_id].sched_pusch = (NR_sched_pusch *)malloc(num_slots_ul*sizeof(NR_sched_pusch));
for (int k=0; k<num_slots_ul; k++) {
for (int l=0; l<2; l++)
memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k][l],
0,
sizeof(NR_sched_pucch));
memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pusch[k],
0,
sizeof(NR_sched_pusch));
}
LOG_I(MAC, "gNB %d] Add NR UE_id %d : rnti %x\n",
mod_idP,
@@ -1776,7 +1913,6 @@ void mac_remove_nr_ue(module_id_t mod_id, rnti_t rnti)
UE_info->rnti[UE_id] = 0;
remove_nr_ue_list(&UE_info->list, UE_id);
free(UE_info->UE_sched_ctrl[UE_id].sched_pucch);
free(UE_info->UE_sched_ctrl[UE_id].sched_pusch);
memset((void *) &UE_info->UE_sched_ctrl[UE_id],
0,
sizeof(NR_UE_sched_ctrl_t));
+92 -52
View File
@@ -39,51 +39,59 @@ void nr_schedule_pucch(int Mod_idP,
int nr_ulmix_slots,
frame_t frameP,
sub_frame_t slotP) {
uint16_t O_csi, O_ack, O_uci;
uint8_t O_sr = 0; // no SR in PUCCH implemented for now
NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon;
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
AssertFatal(UE_info->active[UE_id],"Cannot find UE_id %d is not active\n",UE_id);
NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id];
int bwp_id=1;
NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1];
nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[Mod_idP]->UL_tti_req[0];
NR_sched_pucch *curr_pucch;
for (int k=0; k<nr_ulmix_slots; k++) {
for (int l=0; l<2; l++) {
curr_pucch = &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k][l];
O_ack = curr_pucch->dai_c;
O_csi = curr_pucch->csi_bits;
O_uci = O_ack + O_csi + O_sr;
if ((O_uci>0) && (frameP == curr_pucch->frame) && (slotP == curr_pucch->ul_slot)) {
UL_tti_req->SFN = curr_pucch->frame;
UL_tti_req->Slot = curr_pucch->ul_slot;
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE;
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pucch_pdu_t);
nfapi_nr_pucch_pdu_t *pucch_pdu = &UL_tti_req->pdus_list[UL_tti_req->n_pdus].pucch_pdu;
memset(pucch_pdu,0,sizeof(nfapi_nr_pucch_pdu_t));
UL_tti_req->n_pdus+=1;
NR_sched_pucch *curr_pucch = &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k][l];
const uint16_t O_ack = curr_pucch->dai_c;
const uint16_t O_csi = curr_pucch->csi_bits;
const uint8_t O_sr = 0; // no SR in PUCCH implemented for now
if (O_ack + O_csi + O_sr == 0
|| frameP != curr_pucch->frame
|| slotP != curr_pucch->ul_slot)
continue;
LOG_D(MAC,"Scheduling pucch reception for frame %d slot %d with (%d, %d, %d) (SR ACK, CSI) bits\n",
frameP,slotP,O_sr,O_ack,curr_pucch->csi_bits);
nfapi_nr_ul_tti_request_t *future_ul_tti_req =
&RC.nrmac[Mod_idP]->UL_tti_req_ahead[0][curr_pucch->ul_slot];
AssertFatal(future_ul_tti_req->SFN == curr_pucch->frame
&& future_ul_tti_req->Slot == curr_pucch->ul_slot,
"future UL_tti_req's frame.slot %d.%d does not match PUCCH %d.%d\n",
future_ul_tti_req->SFN,
future_ul_tti_req->Slot,
curr_pucch->frame,
curr_pucch->ul_slot);
future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE;
future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pucch_pdu_t);
nfapi_nr_pucch_pdu_t *pucch_pdu = &future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pucch_pdu;
memset(pucch_pdu, 0, sizeof(nfapi_nr_pucch_pdu_t));
future_ul_tti_req->n_pdus += 1;
nr_configure_pucch(pucch_pdu,
scc,
ubwp,
UE_info->rnti[UE_id],
curr_pucch->resource_indicator,
O_csi,
O_ack,
O_sr);
LOG_D(MAC,
"%4d.%2d Scheduling pucch reception in %4d.%2d: bits SR %d, ACK %d, CSI %d, k %d l %d\n",
frameP,
slotP,
curr_pucch->frame,
curr_pucch->ul_slot,
O_sr,
O_ack,
O_csi,
k, l);
memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k][l],
0,
sizeof(NR_sched_pucch));
}
NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon;
nr_configure_pucch(pucch_pdu,
scc,
UE_info->UE_sched_ctrl[UE_id].active_ubwp,
UE_info->rnti[UE_id],
curr_pucch->resource_indicator,
O_csi,
O_ack,
O_sr);
memset(&UE_info->UE_sched_ctrl[UE_id].sched_pucch[k][l],
0,
sizeof(NR_sched_pucch));
}
}
}
@@ -147,7 +155,7 @@ void compute_csi_bitlen (NR_CellGroupConfig_t *secondaryCellGroup, NR_UE_info_t
UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].diff_rsrp_bitlen =0;
}
LOG_I (MAC, "UCI: CSI_bit len : ssbri %d, rsrp: %d, diff_rsrp: %d",
LOG_I (MAC, "UCI: CSI_bit len : ssbri %d, rsrp: %d, diff_rsrp: %d\n",
UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].cri_ssbri_bitlen,
UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].rsrp_bitlen,
UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].diff_rsrp_bitlen);
@@ -213,7 +221,7 @@ void nr_csi_meas_reporting(int Mod_idP,
if ( (frame%(period/n_slots_frame)==(offset/n_slots_frame)) && (slot==((sched_slot/slots_per_tdd)*slots_per_tdd))) {
// we are scheduling pucch for csi in the first pucch occasion (this comes before ack/nack)
curr_pucch = &UE_info->UE_sched_ctrl[UE_id].sched_pucch[sched_slot-slots_per_tdd+ul_slots][0];
curr_pucch = &UE_info->UE_sched_ctrl[UE_id].sched_pucch[(sched_slot%slots_per_tdd)-slots_per_tdd+ul_slots][0];
NR_PUCCH_CSI_Resource_t *pucchcsires = csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list.array[0];
@@ -266,15 +274,27 @@ void nr_csi_meas_reporting(int Mod_idP,
}
void nr_rx_acknack(nfapi_nr_uci_pusch_pdu_t *uci_pusch,
nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_01,
nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_234,
NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats) {
void handle_nr_uci_pucch_0_1(module_id_t mod_id,
frame_t frame,
sub_frame_t slot,
const nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_01)
{
int UE_id = find_nr_UE_id(mod_id, uci_01->rnti);
if (UE_id < 0) {
LOG_E(MAC, "%s(): unknown RNTI %04x in PUCCH UCI\n", __func__, uci_01->rnti);
return;
}
NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info;
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
// tpc (power control)
sched_ctrl->tpc1 = nr_get_tpc(RC.nrmac[mod_id]->pucch_target_snrx10,
uci_01->ul_cqi,
30);
// TODO
int max_harq_rounds = 4; // TODO define macro
if (uci_01 != NULL) {
if (((uci_01->pduBitmap >> 1) & 0x01)) {
// handle harq
int harq_idx_s = 0;
@@ -283,7 +303,7 @@ void nr_rx_acknack(nfapi_nr_uci_pusch_pdu_t *uci_pusch,
// search for the right harq process
for (int harq_idx = harq_idx_s; harq_idx < NR_MAX_NB_HARQ_PROCESSES; harq_idx++) {
// if the gNB received ack with a good confidence
if ((UL_info->slot-1) == sched_ctrl->harq_processes[harq_idx].feedback_slot) {
if ((slot - 1) == sched_ctrl->harq_processes[harq_idx].feedback_slot) {
sched_ctrl->harq_processes[harq_idx].feedback_slot = -1;
if ((uci_01->harq->harq_list[harq_bit].harq_value == 1) &&
(uci_01->harq->harq_confidence_level == 0)) {
@@ -299,13 +319,13 @@ void nr_rx_acknack(nfapi_nr_uci_pusch_pdu_t *uci_pusch,
if (sched_ctrl->harq_processes[harq_idx].round == max_harq_rounds) {
sched_ctrl->harq_processes[harq_idx].ndi ^= 1;
sched_ctrl->harq_processes[harq_idx].round = 0;
stats->dlsch_errors++;
UE_info->mac_stats[UE_id].dlsch_errors++;
}
break;
}
// if feedback slot processing is aborted
else if (sched_ctrl->harq_processes[harq_idx].feedback_slot != -1
&& (UL_info->slot-1) > sched_ctrl->harq_processes[harq_idx].feedback_slot
&& (slot - 1) > sched_ctrl->harq_processes[harq_idx].feedback_slot
&& sched_ctrl->harq_processes[harq_idx].is_waiting) {
sched_ctrl->harq_processes[harq_idx].feedback_slot = -1;
sched_ctrl->harq_processes[harq_idx].round++;
@@ -318,9 +338,29 @@ void nr_rx_acknack(nfapi_nr_uci_pusch_pdu_t *uci_pusch,
}
}
}
}
void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
frame_t frame,
sub_frame_t slot,
const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_234)
{
int UE_id = find_nr_UE_id(mod_id, uci_234->rnti);
if (UE_id < 0) {
LOG_E(MAC, "%s(): unknown RNTI %04x in PUCCH UCI\n", __func__, uci_234->rnti);
return;
}
NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info;
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
if (uci_234 != NULL) {
// tpc (power control)
sched_ctrl->tpc1 = nr_get_tpc(RC.nrmac[mod_id]->pucch_target_snrx10,
uci_234->ul_cqi,
30);
// TODO
int max_harq_rounds = 4; // TODO define macro
if ((uci_234->pduBitmap >> 1) & 0x01) {
int harq_idx_s = 0;
int acknack;
@@ -329,7 +369,7 @@ void nr_rx_acknack(nfapi_nr_uci_pusch_pdu_t *uci_pusch,
acknack = ((uci_234->harq.harq_payload[harq_bit>>3])>>harq_bit)&0x01;
for (int harq_idx = harq_idx_s; harq_idx < NR_MAX_NB_HARQ_PROCESSES-1; harq_idx++) {
// if the gNB received ack with a good confidence or if the max harq rounds was reached
if ((UL_info->slot-1) == sched_ctrl->harq_processes[harq_idx].feedback_slot) {
if ((slot - 1) == sched_ctrl->harq_processes[harq_idx].feedback_slot) {
// TODO add some confidence level for when there is no CRC
sched_ctrl->harq_processes[harq_idx].feedback_slot = -1;
if ((uci_234->harq.harq_crc != 1) && acknack) {
@@ -345,13 +385,13 @@ void nr_rx_acknack(nfapi_nr_uci_pusch_pdu_t *uci_pusch,
if (sched_ctrl->harq_processes[harq_idx].round == max_harq_rounds) {
sched_ctrl->harq_processes[harq_idx].ndi ^= 1;
sched_ctrl->harq_processes[harq_idx].round = 0;
stats->dlsch_errors++;
UE_info->mac_stats[UE_id].dlsch_errors++;
}
break;
}
// if feedback slot processing is aborted
else if (sched_ctrl->harq_processes[harq_idx].feedback_slot != -1
&& (UL_info->slot-1) > sched_ctrl->harq_processes[harq_idx].feedback_slot
&& (slot - 1) > sched_ctrl->harq_processes[harq_idx].feedback_slot
&& sched_ctrl->harq_processes[harq_idx].is_waiting) {
sched_ctrl->harq_processes[harq_idx].feedback_slot = -1;
sched_ctrl->harq_processes[harq_idx].round++;
+420 -13
View File
@@ -31,7 +31,7 @@
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "executables/softmodem-common.h"
//#define ENABLE_MAC_PAYLOAD_DEBUG 1
#include "common/utils/nr/nr_common.h"
void nr_process_mac_pdu(
@@ -246,37 +246,58 @@ void nr_process_mac_pdu(
}
}
void handle_nr_ul_harq(uint16_t slot, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats, nfapi_nr_crc_t crc_pdu) {
void handle_nr_ul_harq(module_id_t mod_id,
frame_t frame,
sub_frame_t slot,
const nfapi_nr_crc_t *crc_pdu)
{
int UE_id = find_nr_UE_id(mod_id, crc_pdu->rnti);
if (UE_id < 0) {
LOG_E(MAC, "%s(): unknown RNTI %04x in PUSCH\n", __func__, crc_pdu->rnti);
return;
}
NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info;
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
int max_harq_rounds = 4; // TODO define macro
uint8_t hrq_id = crc_pdu.harq_id;
uint8_t hrq_id = crc_pdu->harq_id;
NR_UE_ul_harq_t *cur_harq = &sched_ctrl->ul_harq_processes[hrq_id];
if (cur_harq->state==ACTIVE_SCHED) {
if (!crc_pdu.tb_crc_status) {
if (!crc_pdu->tb_crc_status) {
cur_harq->ndi ^= 1;
cur_harq->round = 0;
cur_harq->state = INACTIVE; // passed -> make inactive. can be used by scheduder for next grant
#ifdef UL_HARQ_PRINT
printf("[HARQ HANDLER] Ulharq id %d crc passed, freeing it for scheduler\n",hrq_id);
#endif
LOG_D(MAC,
"Ulharq id %d crc passed for RNTI %04x\n",
hrq_id,
crc_pdu->rnti);
} else {
cur_harq->round++;
cur_harq->state = ACTIVE_NOT_SCHED;
#ifdef UL_HARQ_PRINT
printf("[HARQ HANDLER] Ulharq id %d crc failed, requesting retransmission\n",hrq_id);
#endif
LOG_D(MAC,
"Ulharq id %d crc failed for RNTI %04x\n",
hrq_id,
crc_pdu->rnti);
}
if (!(cur_harq->round<max_harq_rounds)) {
cur_harq->ndi ^= 1;
cur_harq->state = INACTIVE; // failed after 4 rounds -> make inactive
cur_harq->round = 0;
LOG_D(MAC,"[HARQ HANDLER] RNTI %x: Ulharq id %d crc failed in all round, freeing it for scheduler\n",crc_pdu.rnti,hrq_id);
stats->ulsch_errors++;
LOG_D(MAC,
"RNTI %04x: Ulharq id %d crc failed in all rounds\n",
crc_pdu->rnti,
hrq_id);
UE_info->mac_stats[UE_id].ulsch_errors++;
}
return;
} else
LOG_W(MAC,"Incorrect ULSCH HARQ process %d or invalid state %d (ignore this warning for RA)\n",hrq_id,cur_harq->state);
LOG_W(MAC,
"Incorrect ULSCH HARQ PID %d or invalid state %d for RNTI %04x "
"(ignore this warning for RA)\n",
hrq_id,
cur_harq->state,
crc_pdu->rnti);
}
/*
@@ -384,6 +405,11 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
bwpList->list.count);
const int bwp_id = 1;
UE_info->UE_sched_ctrl[UE_id].active_bwp = bwpList->list.array[bwp_id - 1];
struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList;
AssertFatal(ubwpList->list.count == 1,
"uplinkBWP_ToAddModList has %d BWP!\n",
ubwpList->list.count);
UE_info->UE_sched_ctrl[UE_id].active_ubwp = ubwpList->list.array[bwp_id - 1];
LOG_I(MAC,
"[gNB %d][RAPROC] PUSCH with TC_RNTI %x received correctly, "
"adding UE MAC Context UE_id %d/RNTI %04x\n",
@@ -400,8 +426,389 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
"reset RA state information for RA-RNTI %04x/index %d\n",
ra->rnti,
i);
return;
}
}
}
long get_K2(NR_BWP_Uplink_t *ubwp, int time_domain_assignment, int mu) {
DevAssert(ubwp);
const NR_PUSCH_TimeDomainResourceAllocation_t *tda_list = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment];
if (tda_list->k2)
return *tda_list->k2;
else if (mu < 2)
return 1;
else if (mu == 2)
return 2;
else
return 3;
}
int8_t select_ul_harq_pid(NR_UE_sched_ctrl_t *sched_ctrl) {
const uint8_t max_ul_harq_pids = 3; // temp: for testing
// schedule active harq processes
for (uint8_t hrq_id = 0; hrq_id < max_ul_harq_pids; hrq_id++) {
NR_UE_ul_harq_t *cur_harq = &sched_ctrl->ul_harq_processes[hrq_id];
if (cur_harq->state == ACTIVE_NOT_SCHED) {
LOG_D(MAC, "Found ulharq id %d, scheduling it for retransmission\n", hrq_id);
return hrq_id;
}
}
// schedule new harq processes
for (uint8_t hrq_id=0; hrq_id < max_ul_harq_pids; hrq_id++) {
NR_UE_ul_harq_t *cur_harq = &sched_ctrl->ul_harq_processes[hrq_id];
if (cur_harq->state == INACTIVE) {
LOG_D(MAC, "Found new ulharq id %d, scheduling it\n", hrq_id);
return hrq_id;
}
}
LOG_E(MAC, "All UL HARQ processes are busy. Cannot schedule ULSCH\n");
return -1;
}
void nr_simple_ulsch_preprocessor(module_id_t module_id,
frame_t frame,
sub_frame_t slot,
int num_slots_per_tdd,
uint64_t ulsch_in_slot_bitmap) {
gNB_MAC_INST *nr_mac = RC.nrmac[module_id];
NR_COMMON_channels_t *cc = nr_mac->common_channels;
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
const int mu = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing;
NR_UE_info_t *UE_info = &nr_mac->UE_info;
AssertFatal(UE_info->num_UEs <= 1,
"%s() cannot handle more than one UE, but found %d\n",
__func__,
UE_info->num_UEs);
if (UE_info->num_UEs == 0)
return;
const int UE_id = 0;
const int CC_id = 0;
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
const int tda = 1;
const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList =
sched_ctrl->active_ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
AssertFatal(tda < tdaList->list.count,
"time domain assignment %d >= %d\n",
tda,
tdaList->list.count);
int K2 = get_K2(sched_ctrl->active_ubwp, tda, mu);
const int sched_frame = frame + (slot + K2 >= num_slots_per_tdd);
const int sched_slot = (slot + K2) % num_slots_per_tdd;
if (!is_xlsch_in_slot(ulsch_in_slot_bitmap, sched_slot))
return;
/* get first, largest unallocated region */
uint16_t *vrb_map_UL =
&RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[sched_slot * 275];
uint16_t rbStart = 0;
while (vrb_map_UL[rbStart]) rbStart++;
const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth,275);
uint16_t rbSize = 1;
while (rbStart + rbSize < bwpSize && !vrb_map_UL[rbStart+rbSize])
rbSize++;
sched_ctrl->sched_pusch.slot = sched_slot;
sched_ctrl->sched_pusch.frame = sched_frame;
const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
sched_ctrl->search_space = get_searchspace(sched_ctrl->active_bwp, target_ss);
uint8_t nr_of_candidates;
find_aggregation_candidates(&sched_ctrl->aggregation_level,
&nr_of_candidates,
sched_ctrl->search_space);
sched_ctrl->coreset = get_coreset(
sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */);
const int cid = sched_ctrl->coreset->controlResourceSetId;
const uint16_t Y = UE_info->Y[UE_id][cid][slot];
const int m = UE_info->num_pdcch_cand[UE_id][cid];
sched_ctrl->cce_index = allocate_nr_CCEs(RC.nrmac[module_id],
sched_ctrl->active_bwp,
sched_ctrl->coreset,
sched_ctrl->aggregation_level,
Y,
m,
nr_of_candidates);
if (sched_ctrl->cce_index < 0) {
LOG_E(MAC, "%s(): CCE list not empty, couldn't schedule PUSCH\n", __func__);
return;
}
UE_info->num_pdcch_cand[UE_id][cid]++;
sched_ctrl->sched_pusch.time_domain_allocation = tda;
const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats;
const int dci_format = f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0;
const uint8_t num_dmrs_cdm_grps_no_data = 1;
/* we want to avoid a lengthy deduction of DMRS and other parameters in
* every TTI if we can save it, so check whether dci_format, TDA, or
* num_dmrs_cdm_grps_no_data has changed and only then recompute */
NR_sched_pusch_save_t *ps = &sched_ctrl->pusch_save;
if (ps->time_domain_allocation != tda
|| ps->dci_format != dci_format
|| ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data)
nr_save_pusch_fields(scc,
sched_ctrl->active_ubwp,
dci_format,
tda,
num_dmrs_cdm_grps_no_data,
ps);
const int mcs = 9;
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
sched_pusch->mcs = mcs;
sched_pusch->rbStart = rbStart;
sched_pusch->rbSize = rbSize;
/* Calculate TBS from MCS */
sched_pusch->R = nr_get_code_rate_ul(mcs, ps->mcs_table);
sched_pusch->Qm = nr_get_Qm_ul(mcs, ps->mcs_table);
if (ps->pusch_Config->tp_pi2BPSK
&& ((ps->mcs_table == 3 && mcs < 2) || (ps->mcs_table == 4 && mcs < 6))) {
sched_pusch->R >>= 1;
sched_pusch->Qm <<= 1;
}
sched_pusch->tb_size = nr_compute_tbs(sched_pusch->Qm,
sched_pusch->R,
sched_pusch->rbSize,
ps->nrOfSymbols,
ps->N_PRB_DMRS * ps->num_dmrs_symb,
0, // nb_rb_oh
0,
1 /* NrOfLayers */)
>> 3;
/* mark the corresponding RBs as used */
for (int rb = 0; rb < sched_ctrl->sched_pusch.rbSize; rb++)
vrb_map_UL[rb + sched_ctrl->sched_pusch.rbStart] = 1;
}
void nr_schedule_ulsch(module_id_t module_id,
frame_t frame,
sub_frame_t slot,
int num_slots_per_tdd,
int ul_slots,
uint64_t ulsch_in_slot_bitmap) {
RC.nrmac[module_id]->pre_processor_ul(
module_id, frame, slot, num_slots_per_tdd, ulsch_in_slot_bitmap);
NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon;
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
const NR_UE_list_t *UE_list = &UE_info->list;
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
/* dynamic PUSCH values (RB alloc, MCS, hence R, Qm, TBS) that change in
* every TTI are pre-populated by the preprocessor and used below */
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
if (sched_pusch->rbSize <= 0)
continue;
uint16_t rnti = UE_info->rnti[UE_id];
int8_t harq_id = select_ul_harq_pid(sched_ctrl);
if (harq_id < 0) return;
NR_UE_ul_harq_t *cur_harq = &sched_ctrl->ul_harq_processes[harq_id];
cur_harq->state = ACTIVE_SCHED;
cur_harq->last_tx_slot = sched_pusch->slot;
int rnti_types[2] = { NR_RNTI_C, 0 };
/* pre-computed PUSCH values that only change if time domain allocation,
* DCI format, or DMRS parameters change. Updated in the preprocessor
* through nr_save_pusch_fields() */
NR_sched_pusch_save_t *ps = &sched_ctrl->pusch_save;
/* Statistics */
UE_info->mac_stats[UE_id].ulsch_rounds[cur_harq->round]++;
if (cur_harq->round == 0) {
UE_info->mac_stats[UE_id].ulsch_total_bytes_scheduled += sched_pusch->tb_size;
} else {
LOG_W(MAC,
"%d.%2d UL retransmission RNTI %04x sched %d.%2d HARQ PID %d round %d NDI %d\n",
frame,
slot,
rnti,
sched_pusch->frame,
sched_pusch->slot,
harq_id,
cur_harq->round,
cur_harq->ndi);
}
LOG_D(MAC,
"%4d.%2d RNTI %04x UL sched %4d.%2d start %d RBS %d MCS %d TBS %d HARQ PID %d round %d NDI %d\n",
frame,
slot,
rnti,
sched_pusch->frame,
sched_pusch->slot,
sched_pusch->rbStart,
sched_pusch->rbSize,
sched_pusch->mcs,
sched_pusch->tb_size,
harq_id,
cur_harq->round,
cur_harq->ndi);
/* PUSCH in a later slot, but corresponding DCI now! */
nfapi_nr_ul_tti_request_t *future_ul_tti_req = &RC.nrmac[module_id]->UL_tti_req_ahead[0][sched_pusch->slot];
AssertFatal(future_ul_tti_req->SFN == sched_pusch->frame
&& future_ul_tti_req->Slot == sched_pusch->slot,
"%d.%d future UL_tti_req's frame.slot %d.%d does not match PUSCH %d.%d\n",
frame, slot,
future_ul_tti_req->SFN,
future_ul_tti_req->Slot,
sched_pusch->frame,
sched_pusch->slot);
future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE;
future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t);
nfapi_nr_pusch_pdu_t *pusch_pdu = &future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pusch_pdu;
memset(pusch_pdu, 0, sizeof(nfapi_nr_pusch_pdu_t));
future_ul_tti_req->n_pdus += 1;
LOG_D(MAC, "%4d.%2d Scheduling UE specific PUSCH\n", frame, slot);
pusch_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA;
pusch_pdu->rnti = rnti;
pusch_pdu->handle = 0; //not yet used
/* FAPI: BWP */
pusch_pdu->bwp_size = NRRIV2BW(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth,275);
pusch_pdu->bwp_start = NRRIV2PRBOFFSET(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth,275);
pusch_pdu->subcarrier_spacing = sched_ctrl->active_ubwp->bwp_Common->genericParameters.subcarrierSpacing;
pusch_pdu->cyclic_prefix = 0;
/* FAPI: PUSCH information always included */
pusch_pdu->target_code_rate = sched_pusch->R;
pusch_pdu->qam_mod_order = sched_pusch->Qm;
pusch_pdu->mcs_index = sched_pusch->mcs;
pusch_pdu->mcs_table = ps->mcs_table;
pusch_pdu->transform_precoding = ps->transform_precoding;
if (ps->pusch_Config->dataScramblingIdentityPUSCH)
pusch_pdu->data_scrambling_id = *ps->pusch_Config->dataScramblingIdentityPUSCH;
else
pusch_pdu->data_scrambling_id = *scc->physCellId;
pusch_pdu->nrOfLayers = 1;
/* FAPI: DMRS */
pusch_pdu->ul_dmrs_symb_pos = ps->ul_dmrs_symb_pos;
pusch_pdu->dmrs_config_type = ps->dmrs_config_type;
if (pusch_pdu->transform_precoding) { // transform precoding disabled
long *scramblingid;
if (pusch_pdu->scid == 0)
scramblingid = ps->NR_DMRS_UplinkConfig->transformPrecodingDisabled->scramblingID0;
else
scramblingid = ps->NR_DMRS_UplinkConfig->transformPrecodingDisabled->scramblingID1;
if (scramblingid == NULL)
pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId;
else
pusch_pdu->ul_dmrs_scrambling_id = *scramblingid;
}
else {
pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId;
if (ps->NR_DMRS_UplinkConfig->transformPrecodingEnabled->nPUSCH_Identity != NULL)
pusch_pdu->pusch_identity = *ps->NR_DMRS_UplinkConfig->transformPrecodingEnabled->nPUSCH_Identity;
else
pusch_pdu->pusch_identity = *scc->physCellId;
}
pusch_pdu->scid = 0; // DMRS sequence initialization [TS38.211, sec 6.4.1.1.1]
pusch_pdu->num_dmrs_cdm_grps_no_data = ps->num_dmrs_cdm_grps_no_data;
pusch_pdu->dmrs_ports = 1;
/* FAPI: Pusch Allocation in frequency domain */
AssertFatal(ps->pusch_Config->resourceAllocation == NR_PUSCH_Config__resourceAllocation_resourceAllocationType1,
"Only frequency resource allocation type 1 is currently supported\n");
pusch_pdu->resource_alloc = 1; //type 1
pusch_pdu->rb_start = sched_pusch->rbStart;
pusch_pdu->rb_size = sched_pusch->rbSize;
pusch_pdu->vrb_to_prb_mapping = 0;
if (ps->pusch_Config->frequencyHopping==NULL)
pusch_pdu->frequency_hopping = 0;
else
pusch_pdu->frequency_hopping = 1;
/* FAPI: Resource Allocation in time domain */
pusch_pdu->start_symbol_index = ps->startSymbolIndex;
pusch_pdu->nr_of_symbols = ps->nrOfSymbols;
/* PUSCH PDU */
pusch_pdu->pusch_data.rv_index = nr_rv_round_map[cur_harq->round];
pusch_pdu->pusch_data.harq_process_id = harq_id;
pusch_pdu->pusch_data.new_data_indicator = cur_harq->ndi;
pusch_pdu->pusch_data.tb_size = sched_pusch->tb_size;
pusch_pdu->pusch_data.num_cb = 0; //CBG not supported
/* PUSCH PTRS */
if (ps->NR_DMRS_UplinkConfig->phaseTrackingRS != NULL) {
// TODO to be fixed from RRC config
uint8_t ptrs_mcs1 = 2; // higher layer parameter in PTRS-UplinkConfig
uint8_t ptrs_mcs2 = 4; // higher layer parameter in PTRS-UplinkConfig
uint8_t ptrs_mcs3 = 10; // higher layer parameter in PTRS-UplinkConfig
uint16_t n_rb0 = 25; // higher layer parameter in PTRS-UplinkConfig
uint16_t n_rb1 = 75; // higher layer parameter in PTRS-UplinkConfig
pusch_pdu->pusch_ptrs.ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, pusch_pdu->mcs_index, pusch_pdu->mcs_table);
pusch_pdu->pusch_ptrs.ptrs_freq_density = get_K_ptrs(n_rb0, n_rb1, pusch_pdu->rb_size);
pusch_pdu->pusch_ptrs.ptrs_ports_list = (nfapi_nr_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ptrs_ports_t));
pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0;
pusch_pdu->pdu_bit_map |= PUSCH_PDU_BITMAP_PUSCH_PTRS; // enable PUSCH PTRS
}
else{
pusch_pdu->pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS
}
nfapi_nr_ul_dci_request_t *ul_dci_req = &RC.nrmac[module_id]->UL_dci_req[0];
ul_dci_req->SFN = frame;
ul_dci_req->Slot = slot;
nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu = &ul_dci_req->ul_dci_pdu_list[ul_dci_req->numPdus];
memset(ul_dci_request_pdu, 0, sizeof(nfapi_nr_ul_dci_request_pdus_t));
ul_dci_request_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE;
ul_dci_request_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15;
ul_dci_req->numPdus += 1;
LOG_D(MAC,"Configuring ULDCI/PDCCH in %d.%d\n", frame,slot);
nr_configure_pdcch(RC.nrmac[0],
pdcch_pdu_rel15,
rnti,
sched_ctrl->search_space,
sched_ctrl->coreset,
scc,
sched_ctrl->active_bwp,
sched_ctrl->aggregation_level,
sched_ctrl->cce_index);
dci_pdu_rel15_t dci_pdu_rel15[MAX_DCI_CORESET];
memset(dci_pdu_rel15, 0, sizeof(dci_pdu_rel15));
NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id];
const int n_ubwp = secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.count;
// NOTE: below functions assume that dci_formats is an array corresponding
// to all UL DCIs in the PDCCH, but for us it is a simple int. So before
// having multiple UEs, the below need to be changed (IMO the functions
// should fill for one DCI only and not handle all of them).
config_uldci(sched_ctrl->active_ubwp,
pusch_pdu,
pdcch_pdu_rel15,
&dci_pdu_rel15[0],
&ps->dci_format,
ps->time_domain_allocation,
UE_info->UE_sched_ctrl[UE_id].tpc0,
n_ubwp,
sched_ctrl->active_bwp->bwp_Id);
fill_dci_pdu_rel15(scc,
secondaryCellGroup,
pdcch_pdu_rel15,
dci_pdu_rel15,
&ps->dci_format,
rnti_types,
pusch_pdu->bwp_size,
sched_ctrl->active_bwp->bwp_Id);
memset(sched_pusch, 0, sizeof(*sched_pusch));
}
}
+47 -25
View File
@@ -88,6 +88,20 @@ void nr_simple_dlsch_preprocessor(module_id_t module_id,
void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, uint8_t slots_per_frame);
/// uplink scheduler
void nr_schedule_ulsch(module_id_t module_id,
frame_t frame,
sub_frame_t slot,
int num_slots_per_tdd,
int ul_slots,
uint64_t ulsch_in_slot_bitmap);
void nr_simple_ulsch_preprocessor(module_id_t module_id,
frame_t frame,
sub_frame_t slot,
int num_slots_per_tdd,
uint64_t ulsch_in_slot_bitmap);
/////// Random Access MAC-PHY interface functions and primitives ///////
void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP);
@@ -107,7 +121,9 @@ void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP);
int nr_allocate_CCEs(int module_idP, int CC_idP, frame_t frameP, sub_frame_t slotP, int test_only);
void nr_get_Msg3alloc(NR_ServingCellConfigCommon_t *scc,
void nr_get_Msg3alloc(module_id_t module_id,
int CC_id,
NR_ServingCellConfigCommon_t *scc,
NR_BWP_Uplink_t *ubwp,
sub_frame_t current_subframe,
frame_t current_frame,
@@ -136,6 +152,13 @@ void nr_preprocessor_phytest(module_id_t module_id,
frame_t frame,
sub_frame_t slot,
int num_slots_per_tdd);
/* \brief UL preprocessor for phytest: schedules UE_id 0 with fixed MCS on a
* fixed set of resources */
void nr_ul_preprocessor_phytest(module_id_t module_id,
frame_t frame,
sub_frame_t slot,
int num_slots_per_tdd,
uint64_t ulsch_in_slot_bitmap);
void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
frame_t frameP,
@@ -157,26 +180,24 @@ void nr_fill_nfapi_dl_pdu(int Mod_id,
int ndi,
int round);
void nr_rx_acknack(nfapi_nr_uci_pusch_pdu_t *uci_pusch,
nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_01,
nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_234,
NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats);
void handle_nr_uci_pucch_0_1(module_id_t mod_id,
frame_t frame,
sub_frame_t slot,
const nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_01);
void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
frame_t frame,
sub_frame_t slot,
const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_234);
void config_uldci(NR_BWP_Uplink_t *ubwp,
nfapi_nr_pusch_pdu_t *pusch_pdu,
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
dci_pdu_rel15_t *dci_pdu_rel15,
int *dci_formats, int *rnti_types,
int *dci_formats,
int time_domain_assignment, uint8_t tpc,
int n_ubwp, int bwp_id);
void nr_schedule_pusch(int Mod_idP,
int UE_id,
int num_slots_per_tdd,
int ul_slots,
frame_t frameP,
sub_frame_t slotP);
void nr_schedule_pucch(int Mod_idP,
int UE_id,
int nr_ulmix_slots,
@@ -279,6 +300,15 @@ void find_aggregation_candidates(uint8_t *aggregation_level,
uint8_t *nr_of_candidates,
NR_SearchSpace_t *ss);
long get_K2(NR_BWP_Uplink_t *ubwp, int time_domain_assignment, int mu);
void nr_save_pusch_fields(const NR_ServingCellConfigCommon_t *scc,
const NR_BWP_Uplink_t *ubwp,
long dci_format,
int tda,
uint8_t num_dmrs_cdm_grps_no_data,
NR_sched_pusch_save_t *ps);
uint8_t nr_get_tpc(int target, uint8_t cqi, int incr);
int get_spf(nfapi_nr_config_request_scf_t *cfg);
@@ -353,16 +383,6 @@ void nr_generate_Msg2(module_id_t module_idP,
frame_t frameP,
sub_frame_t slotP);
void nr_schedule_reception_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP);
void schedule_fapi_ul_pdu(int Mod_idP,
frame_t frameP,
sub_frame_t slotP,
int num_slots_per_tdd,
int ul_slots,
int time_domain_assignment,
uint64_t ulsch_in_slot_bitmap);
void nr_process_mac_pdu(
module_id_t module_idP,
rnti_t rnti,
@@ -398,7 +418,10 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
const uint8_t ul_cqi,
const uint16_t rssi);
void handle_nr_ul_harq(uint16_t slot, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats, nfapi_nr_crc_t crc_pdu);
void handle_nr_ul_harq(module_id_t mod_id,
frame_t frame,
sub_frame_t slot,
const nfapi_nr_crc_t *crc_pdu);
int16_t ssb_index_from_prach(module_id_t module_idP,
frame_t frameP,
@@ -409,5 +432,4 @@ int16_t ssb_index_from_prach(module_id_t module_idP,
void find_SSB_and_RO_available(module_id_t module_idP);
void handle_nr_uci(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats, int target_snrx10);
#endif /*__LAYER2_NR_MAC_PROTO_H__*/
+5 -3
View File
@@ -34,7 +34,6 @@
#include "NR_MAC_COMMON/nr_mac_extern.h"
#include "assertions.h"
#include "LAYER2/PDCP_v10.1.0/pdcp.h"
#include "LAYER2/nr_pdcp/nr_pdcp_entity.h"
#include "RRC/NR/nr_rrc_defs.h"
#include "common/utils/LOG/log.h"
@@ -82,10 +81,13 @@ void mac_top_init_gNB(void)
RC.nrmac[i]->ul_handle = 0;
if (get_softmodem_params()->phy_test)
if (get_softmodem_params()->phy_test) {
RC.nrmac[i]->pre_processor_dl = nr_preprocessor_phytest;
else
RC.nrmac[i]->pre_processor_ul = nr_ul_preprocessor_phytest;
} else {
RC.nrmac[i]->pre_processor_dl = nr_simple_dlsch_preprocessor;
RC.nrmac[i]->pre_processor_ul = nr_simple_ulsch_preprocessor;
}
}//END for (i = 0; i < RC.nb_nr_macrlc_inst; i++)
+61 -16
View File
@@ -62,8 +62,6 @@
#include "NR_PHY_INTERFACE/NR_IF_Module.h"
/* MAC */
#include "LAYER2/MAC/mac.h"
#include "LAYER2/MAC/mac_proto.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
#include "NR_TAG.h"
@@ -142,8 +140,6 @@ typedef struct {
uint8_t msg3_cqireq;
/// Round of Msg3 HARQ
uint8_t msg3_round;
/// Msg3 pusch pdu
nfapi_nr_pusch_pdu_t pusch_pdu;
/// TBS used for Msg4
int msg4_TBsize;
/// MCS used for Msg4
@@ -192,8 +188,9 @@ typedef struct {
NR_RA_t ra[NR_NB_RA_PROC_MAX];
/// VRB map for common channels
uint16_t vrb_map[275];
/// VRB map for common channels and retransmissions by PHICH
uint16_t vrb_map_UL[275];
/// VRB map for common channels and PUSCH, dynamically allocated because
/// length depends on number of slots and RBs
uint16_t *vrb_map_UL;
/// number of subframe allocation pattern available for MBSFN sync area
uint8_t num_sf_allocation_pattern;
///Number of active SSBs
@@ -285,12 +282,49 @@ typedef struct NR_sched_pucch {
uint8_t resource_indicator;
} NR_sched_pucch;
/* this struct is a helper: as long as the TDA and DCI format remain the same
* over the same uBWP and search space, there is no need to recalculate all
* S/L, MCS table, or DMRS-related parameters over and over again. Hence, we
* store them in this struct for easy reference. */
typedef struct NR_sched_pusch_save {
int dci_format;
int time_domain_allocation;
uint8_t num_dmrs_cdm_grps_no_data;
int startSymbolIndex;
int nrOfSymbols;
NR_PUSCH_Config_t *pusch_Config;
uint8_t transform_precoding;
uint8_t mcs_table;
long mapping_type;
NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig;
uint16_t dmrs_config_type;
uint16_t ul_dmrs_symb_pos;
uint8_t num_dmrs_symb;
uint8_t N_PRB_DMRS;
} NR_sched_pusch_save_t;
typedef struct NR_sched_pusch {
int frame;
int slot;
bool active;
nfapi_nr_pusch_pdu_t pusch_pdu;
} NR_sched_pusch;
/// RB allocation within active uBWP
uint16_t rbSize;
uint16_t rbStart;
// time-domain allocation for scheduled RBs
int time_domain_allocation;
/// MCS
uint8_t mcs;
/// TBS-related info
uint16_t R;
uint8_t Qm;
uint32_t tb_size;
} NR_sched_pusch_t;
typedef struct NR_UE_harq {
uint8_t is_waiting;
@@ -348,11 +382,15 @@ typedef struct {
/// the currently active BWP in DL
NR_BWP_Downlink_t *active_bwp;
/// the currently active BWP in UL
NR_BWP_Uplink_t *active_ubwp;
NR_sched_pucch **sched_pucch;
/// selected PUCCH index, if scheduled
int pucch_sched_idx;
int pucch_occ_idx;
NR_sched_pusch *sched_pusch;
NR_sched_pusch_save_t pusch_save;
NR_sched_pusch_t sched_pusch;
/// CCE index and aggregation, should be coherent with cce_list
NR_SearchSpace_t *search_space;
@@ -381,7 +419,6 @@ typedef struct {
uint8_t tpc0;
uint8_t tpc1;
uint16_t ul_rssi;
uint8_t current_harq_pid;
NR_UE_harq_t harq_processes[NR_MAX_NB_HARQ_PROCESSES];
NR_UE_ul_harq_t ul_harq_processes[NR_MAX_NB_HARQ_PROCESSES];
int dummy;
@@ -418,7 +455,6 @@ typedef struct {
/*! \brief UE list used by gNB to order UEs/CC for scheduling*/
#define MAX_CSI_REPORTCONFIG 48
typedef struct {
DLSCH_PDU DLSCH_pdu[4][MAX_MOBILES_PER_GNB];
/// scheduling control info
nr_csi_report_t csi_report_template[MAX_MOBILES_PER_GNB][MAX_CSI_REPORTCONFIG];
NR_UE_sched_ctrl_t UE_sched_ctrl[MAX_MOBILES_PER_GNB];
@@ -441,6 +477,11 @@ typedef void (*nr_pp_impl_dl)(module_id_t mod_id,
frame_t frame,
sub_frame_t slot,
int num_slots_per_tdd);
typedef void (*nr_pp_impl_ul)(module_id_t mod_id,
frame_t frame,
sub_frame_t slot,
int num_slots_per_tdd,
uint64_t ulsch_in_slot_bitmap);
/*! \brief top level eNB MAC structure */
typedef struct gNB_MAC_INST_s {
@@ -467,8 +508,12 @@ typedef struct gNB_MAC_INST_s {
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];
/// NFAPI UL TTI Request Structure (this is from the new SCF specs)
nfapi_nr_ul_tti_request_t UL_tti_req[NFAPI_CC_MAX];
/// 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
/// because length depends on number of slots
nfapi_nr_ul_tti_request_t *UL_tti_req_ahead[NFAPI_CC_MAX];
/// NFAPI HI/DCI0 Config Request Structure
nfapi_nr_ul_dci_request_t UL_dci_req[NFAPI_CC_MAX];
/// NFAPI DL PDU structure
@@ -502,11 +547,11 @@ typedef struct gNB_MAC_INST_s {
time_stats_t schedule_pch;
/// CCE lists
int cce_list[MAX_NUM_BWP][MAX_NUM_CORESET][MAX_NUM_CCE];
/// current slot
int current_slot;
/// DL preprocessor for differentiated scheduling
nr_pp_impl_dl pre_processor_dl;
/// UL preprocessor for differentiated scheduling
nr_pp_impl_ul pre_processor_ul;
} gNB_MAC_INST;
#endif /*__LAYER2_NR_MAC_GNB_H__ */
+68
View File
@@ -0,0 +1,68 @@
/*
* 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
*/
#include "pdcp.h"
int decode_t_reordering(int v)
{
static int tab[36] = {
0, 1, 2, 4, 5, 8, 10, 15, 20, 30, 40, 50, 60, 80, 100, 120, 140, 160, 180,
200, 220, 240, 260, 280, 300, 500, 750, 1000, 1250, 1500, 1750, 2000,
2250, 2500, 2750, 3000
};
if (v < 0 || v > 35) {
LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
return tab[v];
}
int decode_sn_size_ul(long s)
{
if (s == 0) return 12;
if (s == 1) return 18;
LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
int decode_sn_size_dl(long s)
{
if (s == 0) return 12;
if (s == 1) return 18;
LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
int decode_discard_timer(long v)
{
static int tab[16] = {
10, 20, 30, 40, 50, 60, 75, 100, 150, 200, 250, 300, 500, 750, 1500, -1,
};
if (v < 0 || v > 15) {
LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
return tab[v];
}
+30
View File
@@ -0,0 +1,30 @@
/*
* 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_LAYER2_NR_PDCP_ASN1_UTILS_H_
#define _OPENAIR2_LAYER2_NR_PDCP_ASN1_UTILS_H_
int decode_t_reordering(int v);
int decode_sn_size_ul(long s);
int decode_sn_size_dl(long s);
int decode_discard_timer(long v);
#endif /* _OPENAIR2_LAYER2_NR_PDCP_ASN1_UTILS_H_ */
+9 -3
View File
@@ -44,7 +44,10 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am(
void *deliver_sdu_data,
void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity,
char *buf, int size, int sdu_id),
void *deliver_pdu_data)
void *deliver_pdu_data,
int sn_size,
int t_reordering,
int discard_timer)
{
nr_pdcp_entity_drb_am_t *ret;
@@ -66,9 +69,12 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am(
ret->common.deliver_pdu = deliver_pdu;
ret->common.deliver_pdu_data = deliver_pdu_data;
ret->rb_id = rb_id;
ret->rb_id = rb_id;
ret->sn_size = sn_size;
ret->t_reordering = t_reordering;
ret->discard_timer = discard_timer;
ret->common.maximum_nr_pdcp_sn = 4095;
ret->common.maximum_nr_pdcp_sn = (1 << sn_size) - 1;
return (nr_pdcp_entity_t *)ret;
}
+4 -1
View File
@@ -60,7 +60,10 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am(
void *deliver_sdu_data,
void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity,
char *buf, int size, int sdu_id),
void *deliver_pdu_data);
void *deliver_pdu_data,
int sn_size,
int t_reordering,
int discard_timer);
void nr_DRB_preconfiguration(uint16_t crnti);
@@ -44,7 +44,7 @@ void nr_pdcp_entity_drb_am_recv_sdu(nr_pdcp_entity_t *_entity, char *buffer, int
{
nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity;
int sn;
char buf[size+2];
char buf[size+3];
sn = entity->common.next_nr_pdcp_tx_sn;
@@ -27,6 +27,9 @@
typedef struct {
nr_pdcp_entity_t common;
int rb_id;
int sn_size; /* unit: bits */
int t_reordering; /* unit: ms */
int discard_timer; /* unit: ms, -1 means infinity */
} nr_pdcp_entity_drb_am_t;
void nr_pdcp_entity_drb_am_recv_pdu(nr_pdcp_entity_t *entity, char *buffer, int size);
+13 -2
View File
@@ -22,6 +22,7 @@
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include "asn1_utils.h"
#include "nr_pdcp_ue_manager.h"
#include "NR_RadioBearerConfig.h"
#include "NR_RLC-BearerConfig.h"
@@ -596,8 +597,17 @@ static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s)
nr_pdcp_ue_t *ue;
int drb_id = s->drb_Identity;
int t_reordering = decode_t_reordering(*s->pdcp_Config->t_Reordering);
int sn_size_ul = decode_sn_size_ul(*s->pdcp_Config->drb->pdcp_SN_SizeUL);
int sn_size_dl = decode_sn_size_dl(*s->pdcp_Config->drb->pdcp_SN_SizeDL);
int discard_timer = decode_discard_timer(*s->pdcp_Config->drb->discardTimer);
LOG_I(PDCP, "%s: adding drb %d for rnti %x\n", __FUNCTION__, drb_id, rnti);
/* TODO(?): accept different UL and DL SN sizes? */
if (sn_size_ul != sn_size_dl) {
LOG_E(PDCP, "%s:%d:%s: fatal, bad SN sizes, must be same. ul=%d, dl=%d\n",
__FILE__, __LINE__, __FUNCTION__, sn_size_ul, sn_size_dl);
exit(1);
}
if (drb_id != 1) {
LOG_E(PDCP, "%s:%d:%s: fatal, bad drb id %d\n",
@@ -611,7 +621,8 @@ static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s)
LOG_D(PDCP, "%s:%d:%s: warning DRB %d already exist for ue %d, do nothing\n",
__FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
} else {
pdcp_drb = new_nr_pdcp_entity_drb_am(drb_id, deliver_sdu_drb, ue, deliver_pdu_drb, ue);
pdcp_drb = new_nr_pdcp_entity_drb_am(drb_id, deliver_sdu_drb, ue, deliver_pdu_drb, ue,
sn_size_dl, t_reordering, discard_timer);
nr_pdcp_ue_add_drb_pdcp_entity(ue, drb_id, pdcp_drb);
LOG_D(PDCP, "%s:%d:%s: added drb %d to ue rnti %x\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
+10
View File
@@ -991,3 +991,13 @@ void nr_rlc_tick(int frame, int subframe)
nr_rlc_current_time++;
}
}
/* This is a hack, to compile the gNB.
* TODO: remove it. The solution is to cleanup cmake_targets/CMakeLists.txt
*/
void rlc_tick(int a, int b)
{
LOG_E(RLC, "%s:%d:%s: this code should not be reached\n",
__FILE__, __LINE__, __FUNCTION__);
exit(1);
}
+24 -16
View File
@@ -177,14 +177,6 @@ mac_rlc_status_resp_t mac_rlc_status_ind(
mac_rlc_status_resp_t ret;
rlc_entity_t *rb;
/* TODO: handle time a bit more properly */
if (rlc_current_time_last_frame != frameP ||
rlc_current_time_last_subframe != subframeP) {
rlc_current_time++;
rlc_current_time_last_frame = frameP;
rlc_current_time_last_subframe = subframeP;
}
rlc_manager_lock(rlc_ue_manager);
ue = rlc_manager_get_ue(rlc_ue_manager, rntiP);
@@ -244,14 +236,6 @@ rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind(
exit(1);
}
/* TODO: handle time a bit more properly */
if (rlc_current_time_last_frame != frameP ||
rlc_current_time_last_subframe != subframeP) {
rlc_current_time++;
rlc_current_time_last_frame = frameP;
rlc_current_time_last_subframe = subframeP;
}
rlc_manager_lock(rlc_ue_manager);
ue = rlc_manager_get_ue(rlc_ue_manager, rntiP);
@@ -1024,3 +1008,27 @@ rlc_op_status_t rrc_rlc_remove_ue (const protocol_ctxt_t* const x)
return RLC_OP_STATUS_OK;
}
void rlc_tick(int frame, int subframe)
{
int expected_next_frame;
int expected_next_subframe;
if (frame != rlc_current_time_last_frame ||
subframe != rlc_current_time_last_subframe) {
/* warn if discontinuity in ticks */
expected_next_subframe = (rlc_current_time_last_subframe + 1) % 10;
if (expected_next_subframe == 0)
expected_next_frame = (rlc_current_time_last_frame + 1) % 1024;
else
expected_next_frame = rlc_current_time_last_frame;
if (expected_next_frame != frame || expected_next_subframe != subframe)
LOG_W(RLC, "rlc_tick: discontinuity (expected %d.%d, got %d.%d)\n",
expected_next_frame, expected_next_subframe,
frame, subframe);
rlc_current_time++;
rlc_current_time_last_frame = frame;
rlc_current_time_last_subframe = subframe;
}
}
+67 -92
View File
@@ -30,12 +30,9 @@
* \warning
*/
#include "openair1/PHY/defs_eNB.h"
#include "openair1/PHY/phy_extern.h"
#include "openair1/SCHED_NR/fapi_nr_l1.h"
#include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
#include "LAYER2/MAC/mac_proto.h"
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "common/ran_context.h"
#include "executables/softmodem-common.h"
@@ -79,35 +76,28 @@ void handle_nr_rach(NR_UL_IND_t *UL_info) {
}
void handle_nr_uci(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats, int target_snrx10) {
void handle_nr_uci(NR_UL_IND_t *UL_info)
{
const module_id_t mod_id = UL_info->module_id;
const frame_t frame = UL_info->frame;
const sub_frame_t slot = UL_info->slot;
int num_ucis = UL_info->uci_ind.num_ucis;
nfapi_nr_uci_t *uci_list = UL_info->uci_ind.uci_list;
for (int i = 0; i < num_ucis; i++) {
switch (uci_list[i].pdu_type) {
case NFAPI_NR_UCI_PUSCH_PDU_TYPE: break;
case NFAPI_NR_UCI_PUSCH_PDU_TYPE:
LOG_E(MAC, "%s(): unhandled NFAPI_NR_UCI_PUSCH_PDU_TYPE\n", __func__);
break;
case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: {
nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu = &uci_list[i].pucch_pdu_format_0_1;
// tpc (power control)
sched_ctrl->tpc1 = nr_get_tpc(target_snrx10,uci_pdu->ul_cqi,30);
if( (uci_pdu->pduBitmap>>1) & 0x01)
nr_rx_acknack(NULL,uci_pdu,NULL,UL_info,sched_ctrl,stats);
const nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu = &uci_list[i].pucch_pdu_format_0_1;
handle_nr_uci_pucch_0_1(mod_id, frame, slot, uci_pdu);
break;
}
case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: {
nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu = &uci_list[i].pucch_pdu_format_2_3_4;
// tpc (power control)
sched_ctrl->tpc1 = nr_get_tpc(target_snrx10,uci_pdu->ul_cqi,30);
if( (uci_pdu->pduBitmap>>1) & 0x01)
nr_rx_acknack(NULL,NULL,uci_pdu,UL_info,sched_ctrl,stats);
const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu = &uci_list[i].pucch_pdu_format_2_3_4;
handle_nr_uci_pucch_2_3_4(mod_id, frame, slot, uci_pdu);
break;
}
}
@@ -117,75 +107,62 @@ void handle_nr_uci(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_
}
void handle_nr_ulsch(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats) {
void handle_nr_ulsch(NR_UL_IND_t *UL_info)
{
if (UL_info->rx_ind.number_of_pdus > 0 && UL_info->crc_ind.number_crcs > 0) {
for (int i = 0; i < UL_info->rx_ind.number_of_pdus; i++) {
for (int j = 0; j < UL_info->crc_ind.number_crcs; j++) {
// find crc_indication j corresponding rx_indication i
const nfapi_nr_rx_data_pdu_t *rx = &UL_info->rx_ind.pdu_list[i];
const nfapi_nr_crc_t *crc = &UL_info->crc_ind.crc_list[j];
LOG_D(PHY,
"UL_info->crc_ind.pdu_list[%d].rnti:%04x "
"UL_info->rx_ind.pdu_list[%d].rnti:%04x\n",
j,
crc->rnti,
i,
rx->rnti);
if(nfapi_mode == 1) {
if (UL_info->crc_ind.number_crcs>0) {
//LOG_D(PHY,"UL_info->crc_ind.crc_indication_body.number_of_crcs:%d CRC_IND:SFN/SF:%d\n", UL_info->crc_ind.crc_indication_body.number_of_crcs, NFAPI_SFNSF2DEC(UL_info->crc_ind.sfn_sf));
// oai_nfapi_crc_indication(&UL_info->crc_ind);
if (crc->rnti != rx->rnti)
continue;
UL_info->crc_ind.number_crcs = 0;
}
LOG_D(MAC,
"%4d.%2d Calling rx_sdu (CRC %s/tb_crc_status %d)\n",
UL_info->frame,
UL_info->slot,
crc->tb_crc_status ? "error" : "ok",
crc->tb_crc_status);
if (UL_info->rx_ind.number_of_pdus>0) {
//LOG_D(PHY,"UL_info->rx_ind.number_of_pdus:%d RX_IND:SFN/SF:%d\n", UL_info->rx_ind.rx_indication_body.number_of_pdus, NFAPI_SFNSF2DEC(UL_info->rx_ind.sfn_sf));
// oai_nfapi_rx_ind(&UL_info->rx_ind);
UL_info->rx_ind.number_of_pdus = 0;
}
} else {
/* if CRC passes, pass PDU, otherwise pass NULL as error indication */
nr_rx_sdu(UL_info->module_id,
UL_info->CC_id,
UL_info->rx_ind.sfn,
UL_info->rx_ind.slot,
rx->rnti,
crc->tb_crc_status ? NULL : rx->pdu,
rx->pdu_length,
rx->timing_advance,
rx->ul_cqi,
rx->rssi);
handle_nr_ul_harq(UL_info->module_id, UL_info->frame, UL_info->slot, crc);
break;
} // for (j=0;j<UL_info->crc_ind.number_crcs;j++)
} // for (i=0;i<UL_info->rx_ind.number_of_pdus;i++)
if (UL_info->rx_ind.number_of_pdus>0 && UL_info->crc_ind.number_crcs>0) {
for (int i=0; i<UL_info->rx_ind.number_of_pdus; i++) {
for (int j=0; j<UL_info->crc_ind.number_crcs; j++) {
// find crc_indication j corresponding rx_indication i
LOG_D(PHY,"UL_info->crc_ind.crc_indication_body.crc_pdu_list[%d].rx_ue_information.rnti:%04x UL_info->rx_ind.rx_indication_body.rx_pdu_list[%d].rx_ue_information.rnti:%04x\n", j,
UL_info->crc_ind.crc_list[j].rnti, i, UL_info->rx_ind.pdu_list[i].rnti);
if (UL_info->crc_ind.crc_list[j].rnti ==
UL_info->rx_ind.pdu_list[i].rnti) {
LOG_D(PHY, "UL_info->crc_ind.crc_indication_body.crc_pdu_list[%d].crc_indication_rel8.crc_flag:%d\n", j, UL_info->crc_ind.crc_list[j].tb_crc_status);
handle_nr_ul_harq(UL_info->slot, sched_ctrl, stats, UL_info->crc_ind.crc_list[j]);
if (UL_info->crc_ind.crc_list[j].tb_crc_status == 1) { // CRC error indication
LOG_D(MAC,"Frame %d, Slot %d Calling rx_sdu (CRC error) \n",UL_info->frame,UL_info->slot);
nr_rx_sdu(UL_info->module_id,
UL_info->CC_id,
UL_info->rx_ind.sfn, //UL_info->frame,
UL_info->rx_ind.slot, //UL_info->slot,
UL_info->rx_ind.pdu_list[i].rnti,
(uint8_t *)NULL,
UL_info->rx_ind.pdu_list[i].pdu_length,
UL_info->rx_ind.pdu_list[i].timing_advance,
UL_info->rx_ind.pdu_list[i].ul_cqi,
UL_info->rx_ind.pdu_list[i].rssi);
} else {
LOG_D(MAC,"Frame %d, Slot %d Calling rx_sdu (CRC ok) \n",UL_info->frame,UL_info->slot);
nr_rx_sdu(UL_info->module_id,
UL_info->CC_id,
UL_info->rx_ind.sfn, //UL_info->frame,
UL_info->rx_ind.slot, //UL_info->slot,
UL_info->rx_ind.pdu_list[i].rnti,
UL_info->rx_ind.pdu_list[i].pdu,
UL_info->rx_ind.pdu_list[i].pdu_length,
UL_info->rx_ind.pdu_list[i].timing_advance,
UL_info->rx_ind.pdu_list[i].ul_cqi,
UL_info->rx_ind.pdu_list[i].rssi);
}
break;
}
} // for (j=0;j<UL_info->crc_ind.number_crcs;j++)
} // for (i=0;i<UL_info->rx_ind.number_of_pdus;i++)
UL_info->crc_ind.number_crcs=0;
UL_info->rx_ind.number_of_pdus = 0;
}
else if (UL_info->rx_ind.number_of_pdus!=0 || UL_info->crc_ind.number_crcs!=0) {
LOG_E(PHY,"hoping not to have mis-match between CRC ind and RX ind - hopefully the missing message is coming shortly rx_ind:%d(SFN/SL:%d/%d) crc_ind:%d(SFN/SL:%d/%d) \n",
UL_info->rx_ind.number_of_pdus, UL_info->rx_ind.sfn, UL_info->rx_ind.slot,
UL_info->crc_ind.number_crcs, UL_info->rx_ind.sfn, UL_info->rx_ind.slot);
}
UL_info->crc_ind.number_crcs = 0;
UL_info->rx_ind.number_of_pdus = 0;
} else if (UL_info->rx_ind.number_of_pdus != 0
|| UL_info->crc_ind.number_crcs != 0) {
LOG_E(PHY,
"hoping not to have mis-match between CRC ind and RX ind - "
"hopefully the missing message is coming shortly "
"rx_ind:%d(SFN/SL:%d/%d) crc_ind:%d(SFN/SL:%d/%d) \n",
UL_info->rx_ind.number_of_pdus,
UL_info->rx_ind.sfn,
UL_info->rx_ind.slot,
UL_info->crc_ind.number_crcs,
UL_info->rx_ind.sfn,
UL_info->rx_ind.slot);
}
}
@@ -216,14 +193,12 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
ifi->CC_mask |= (1<<CC_id);
}
// clear DL/UL info for new scheduling round
clear_nr_nfapi_information(mac,CC_id,UL_info->frame,UL_info->slot);
handle_nr_rach(UL_info);
handle_nr_uci(UL_info,&mac->UE_info.UE_sched_ctrl[0],&mac->UE_info.mac_stats[0],mac->pucch_target_snrx10);
handle_nr_uci(UL_info);
// clear HI prior to handling ULSCH
mac->UL_dci_req[CC_id].numPdus = 0;
handle_nr_ulsch(UL_info, &mac->UE_info.UE_sched_ctrl[0],&mac->UE_info.mac_stats[0]);
handle_nr_ulsch(UL_info);
if (nfapi_mode != 1) {
if (ifi->CC_mask == ((1<<MAX_NUM_CCs)-1)) {
@@ -246,7 +221,7 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
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->UL_tti_req = mac->UL_tti_req[CC_id];
sched_info->TX_req = &mac->TX_req[CC_id];
#ifdef DUMP_FAPI
+57 -61
View File
@@ -58,9 +58,22 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
AssertFatal(servingcellconfigcommon!=NULL,"servingcellconfigcommon is null\n");
AssertFatal(secondaryCellGroup!=NULL,"secondaryCellGroup is null\n");
if(servingcellconfigcommon->ssb_PositionsInBurst->present !=2)
AssertFatal(1==0,"Currenrly implemented only for medium size SSB bitmap\n");
uint8_t bitmap = servingcellconfigcommon->ssb_PositionsInBurst->choice.mediumBitmap.buf[0];
uint64_t bitmap=0;
switch (servingcellconfigcommon->ssb_PositionsInBurst->present) {
case 1 :
bitmap = ((uint64_t) servingcellconfigcommon->ssb_PositionsInBurst->choice.shortBitmap.buf[0])<<56;
break;
case 2 :
bitmap = ((uint64_t) servingcellconfigcommon->ssb_PositionsInBurst->choice.mediumBitmap.buf[0])<<56;
break;
case 3 :
for (int i=0; i<8; i++) {
bitmap |= (((uint64_t) servingcellconfigcommon->ssb_PositionsInBurst->choice.longBitmap.buf[i])<<((7-i)*8));
}
break;
default:
AssertFatal(1==0,"SSB bitmap size value %d undefined (allowed values 1,2,3) \n", servingcellconfigcommon->ssb_PositionsInBurst->present);
}
memset(secondaryCellGroup,0,sizeof(NR_CellGroupConfig_t));
secondaryCellGroup->cellGroupId = scg_id;
@@ -206,9 +219,9 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList=calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList));
int n_ssb = 0;
NR_TCI_State_t *tcic[8];
for (int i=0;i<8;i++) {
if ((bitmap>>(7-i))&0x01){
NR_TCI_State_t *tcic[64];
for (int i=0;i<64;i++) {
if ((bitmap>>(63-i))&0x01){
tcic[i]=calloc(1,sizeof(*tcic[i]));
tcic[i]->tci_StateId=n_ssb;
tcic[i]->qcl_Type1.cell=NULL;
@@ -367,12 +380,21 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->controlResourceSetZero=NULL;
bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet=calloc(1,sizeof(*bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet));
int curr_bwp = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275);
NR_ControlResourceSet_t *coreset = calloc(1,sizeof(*coreset));
coreset->controlResourceSetId=1;
// frequencyDomainResources '11111111 11111111 00000000 00000000 00000000 00000'B,
// frequency domain resources depends on BWP size
// options are 24, 48 or 96
coreset->frequencyDomainResources.buf = calloc(1,6);
coreset->frequencyDomainResources.buf[0] = 0xff;
coreset->frequencyDomainResources.buf[1] = 0xff;
if (curr_bwp < 48)
coreset->frequencyDomainResources.buf[0] = 0xf0;
else
coreset->frequencyDomainResources.buf[0] = 0xff;
if (curr_bwp < 96)
coreset->frequencyDomainResources.buf[1] = 0;
else
coreset->frequencyDomainResources.buf[1] = 0xff;
coreset->frequencyDomainResources.buf[2] = 0;
coreset->frequencyDomainResources.buf[3] = 0;
coreset->frequencyDomainResources.buf[4] = 0;
@@ -384,9 +406,9 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
coreset->precoderGranularity = NR_ControlResourceSet__precoderGranularity_sameAsREG_bundle;
coreset->tci_StatesPDCCH_ToAddList=calloc(1,sizeof(*coreset->tci_StatesPDCCH_ToAddList));
NR_TCI_StateId_t *tci[8];
for (int i=0;i<8;i++) {
if ((bitmap>>(7-i))&0x01){
NR_TCI_StateId_t *tci[64];
for (int i=0;i<64;i++) {
if ((bitmap>>(63-i))&0x01){
tci[i]=calloc(1,sizeof(*tci[i]));
*tci[i] = i;
ASN_SEQUENCE_ADD(&coreset->tci_StatesPDCCH_ToAddList->list,tci[i]);
@@ -486,7 +508,12 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
ss2->nrofCandidates=calloc(1,sizeof(*ss2->nrofCandidates));
ss2->nrofCandidates->aggregationLevel1 = NR_SearchSpace__nrofCandidates__aggregationLevel1_n0;
ss2->nrofCandidates->aggregationLevel2 = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0;
ss2->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n4;
if (curr_bwp < 48)
ss2->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n1;
else if (curr_bwp < 96)
ss2->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n2;
else
ss2->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n4;
ss2->nrofCandidates->aggregationLevel8 = NR_SearchSpace__nrofCandidates__aggregationLevel8_n0;
ss2->nrofCandidates->aggregationLevel16 = NR_SearchSpace__nrofCandidates__aggregationLevel16_n0;
ss2->searchSpaceType=calloc(1,sizeof(*ss2->searchSpaceType));
@@ -608,9 +635,9 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
n_ssb = 0;
NR_TCI_State_t *tcid[8];
for (int i=0;i<8;i++) {
if ((bitmap>>(7-i))&0x01){
NR_TCI_State_t *tcid[64];
for (int i=0;i<64;i++) {
if ((bitmap>>(63-i))&0x01){
tcid[i]=calloc(1,sizeof(*tcid[i]));
tcid[i]->tci_StateId=n_ssb;
tcid[i]->qcl_Type1.cell=NULL;
@@ -870,7 +897,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
NR_PUCCH_Resource_t *pucchres2=calloc(1,sizeof(*pucchres2));
NR_PUCCH_Resource_t *pucchres3=calloc(1,sizeof(*pucchres3));
pucchres0->pucch_ResourceId=1;
pucchres0->startingPRB=48;
pucchres0->startingPRB=8;
pucchres0->intraSlotFrequencyHopping=NULL;
pucchres0->secondHopPRB=NULL;
pucchres0->format.present= NR_PUCCH_Resource__format_PR_format0;
@@ -881,7 +908,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres0);
pucchres1->pucch_ResourceId=2;
pucchres1->startingPRB=48;
pucchres1->startingPRB=8;
pucchres1->intraSlotFrequencyHopping=NULL;
pucchres1->secondHopPRB=NULL;
pucchres1->format.present= NR_PUCCH_Resource__format_PR_format0;
@@ -892,23 +919,23 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres1);
pucchres2->pucch_ResourceId=3;
pucchres2->startingPRB=40;
pucchres2->startingPRB=0;
pucchres2->intraSlotFrequencyHopping=NULL;
pucchres2->secondHopPRB=NULL;
pucchres2->format.present= NR_PUCCH_Resource__format_PR_format2;
pucchres2->format.choice.format2=calloc(1,sizeof(*pucchres2->format.choice.format2));
pucchres2->format.choice.format2->nrofPRBs=4;
pucchres2->format.choice.format2->nrofPRBs=8;
pucchres2->format.choice.format2->nrofSymbols=1;
pucchres2->format.choice.format2->startingSymbolIndex=13;
ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres2);
pucchres3->pucch_ResourceId=4;
pucchres3->startingPRB=40;
pucchres3->startingPRB=0;
pucchres3->intraSlotFrequencyHopping=NULL;
pucchres3->secondHopPRB=NULL;
pucchres3->format.present= NR_PUCCH_Resource__format_PR_format2;
pucchres3->format.choice.format2=calloc(1,sizeof(*pucchres3->format.choice.format2));
pucchres3->format.choice.format2->nrofPRBs=4;
pucchres3->format.choice.format2->nrofPRBs=8;
pucchres3->format.choice.format2->nrofSymbols=1;
pucchres3->format.choice.format2->startingSymbolIndex=12;
ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres3);
@@ -1031,45 +1058,14 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
NR_CSI_SSB_ResourceSet_t *ssbresset0 = calloc(1,sizeof(*ssbresset0));
ssbresset0->csi_SSB_ResourceSetId=0;
if ((bitmap>>7)&0x01){
NR_SSB_Index_t *ssbresset00=calloc(1,sizeof(*ssbresset00));
*ssbresset00=0;
ASN_SEQUENCE_ADD(&ssbresset0->csi_SSB_ResourceList.list,ssbresset00);
}
if ((bitmap>>6)&0x01) {
NR_SSB_Index_t *ssbresset01=calloc(1,sizeof(*ssbresset01));
*ssbresset01=1;
ASN_SEQUENCE_ADD(&ssbresset0->csi_SSB_ResourceList.list,ssbresset01);
}
if ((bitmap>>5)&0x01) {
NR_SSB_Index_t *ssbresset02=calloc(1,sizeof(*ssbresset02));
*ssbresset02=2;
ASN_SEQUENCE_ADD(&ssbresset0->csi_SSB_ResourceList.list,ssbresset02);
}
if ((bitmap>>4)&0x01) {
NR_SSB_Index_t *ssbresset03=calloc(1,sizeof(*ssbresset03));
*ssbresset03=3;
ASN_SEQUENCE_ADD(&ssbresset0->csi_SSB_ResourceList.list,ssbresset03);
}
if ((bitmap>>3)&0x01) {
NR_SSB_Index_t *ssbresset04=calloc(1,sizeof(*ssbresset04));
*ssbresset04=4;
ASN_SEQUENCE_ADD(&ssbresset0->csi_SSB_ResourceList.list,ssbresset04);
}
if ((bitmap>>2)&0x01) {
NR_SSB_Index_t *ssbresset05=calloc(1,sizeof(*ssbresset05));
*ssbresset05=5;
ASN_SEQUENCE_ADD(&ssbresset0->csi_SSB_ResourceList.list,ssbresset05);
}
if ((bitmap>>1)&0x01) {
NR_SSB_Index_t *ssbresset06=calloc(1,sizeof(*ssbresset06));
*ssbresset06=6;
ASN_SEQUENCE_ADD(&ssbresset0->csi_SSB_ResourceList.list,ssbresset06);
}
if ((bitmap)&0x01) {
NR_SSB_Index_t *ssbresset07=calloc(1,sizeof(*ssbresset07));
*ssbresset07=7;
ASN_SEQUENCE_ADD(&ssbresset0->csi_SSB_ResourceList.list,ssbresset07);
NR_SSB_Index_t *ssbresset[64];
for (int i=0;i<64;i++) {
if ((bitmap>>(63-i))&0x01){
ssbresset[i]=calloc(1,sizeof(*ssbresset[i]));
*ssbresset[i] = i;
ASN_SEQUENCE_ADD(&ssbresset0->csi_SSB_ResourceList.list,ssbresset[i]);
}
}
ASN_SEQUENCE_ADD(&csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list,ssbresset0);
+11 -4
View File
@@ -310,14 +310,21 @@ void x2ap_eNB_handle_register_eNB(instance_t instance,
x2ap_register_eNB->t_dc_overall);
for (int i = 0; i< x2ap_register_eNB->num_cc; i++) {
new_instance->eutra_band[i] = x2ap_register_eNB->eutra_band[i];
new_instance->downlink_frequency[i] = x2ap_register_eNB->downlink_frequency[i];
if(new_instance->cell_type == CELL_MACRO_GNB){
new_instance->nr_band[i] = x2ap_register_eNB->nr_band[i];
new_instance->tdd_nRARFCN[i] = x2ap_register_eNB->nrARFCN[i];
}
else{
new_instance->eutra_band[i] = x2ap_register_eNB->eutra_band[i];
new_instance->downlink_frequency[i] = x2ap_register_eNB->downlink_frequency[i];
new_instance->fdd_earfcn_DL[i] = x2ap_register_eNB->fdd_earfcn_DL[i];
new_instance->fdd_earfcn_UL[i] = x2ap_register_eNB->fdd_earfcn_UL[i];
}
new_instance->uplink_frequency_offset[i] = x2ap_register_eNB->uplink_frequency_offset[i];
new_instance->Nid_cell[i] = x2ap_register_eNB->Nid_cell[i];
new_instance->N_RB_DL[i] = x2ap_register_eNB->N_RB_DL[i];
new_instance->frame_type[i] = x2ap_register_eNB->frame_type[i];
new_instance->fdd_earfcn_DL[i] = x2ap_register_eNB->fdd_earfcn_DL[i];
new_instance->fdd_earfcn_UL[i] = x2ap_register_eNB->fdd_earfcn_UL[i];
}
DevCheck(x2ap_register_eNB->nb_x2 <= X2AP_MAX_NB_ENB_IP_ADDRESS,
+1
View File
@@ -179,6 +179,7 @@ typedef struct x2ap_eNB_instance_s {
uint32_t specialSubframe[MAX_NUM_CCs];
//#ifdef Rel15
int32_t nr_band[MAX_NUM_CCs];
uint32_t tdd_nRARFCN[MAX_NUM_CCs];
int16_t nr_SCS[MAX_NUM_CCs];
//#endif
+127 -40
View File
@@ -39,7 +39,6 @@
#include "x2ap_ids.h"
#include "x2ap_eNB_itti_messaging.h"
#include "X2AP_SupportedSULFreqBandItem.h"
#include "msc.h"
#include "assertions.h"
@@ -1236,7 +1235,6 @@ int x2ap_gNB_generate_ENDC_x2_setup_request(
X2AP_En_gNB_ENDCX2SetupReqIEs_t *ie_GNB_ENDC;
X2AP_PLMN_Identity_t *plmn;
ServedNRcellsENDCX2ManagementList__Member *servedCellMember;
X2AP_SupportedSULFreqBandItem_t *SULFreqBandItem;
uint8_t *buffer;
uint32_t len;
@@ -1284,8 +1282,8 @@ MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length
ie_GNB_ENDC->value.present = X2AP_En_gNB_ENDCX2SetupReqIEs__value_PR_ServedNRcellsENDCX2ManagementList;
{
for (int i = 0; i<instance_p->num_cc; i++){
servedCellMember = (ServedNRcellsENDCX2ManagementList__Member *)calloc(1,sizeof(ServedNRcellsENDCX2ManagementList__Member));
for (int i = 0; i<instance_p->num_cc; i++){
servedCellMember = (ServedNRcellsENDCX2ManagementList__Member *)calloc(1,sizeof(ServedNRcellsENDCX2ManagementList__Member));
{
servedCellMember->servedNRCellInfo.nrpCI = instance_p->Nid_cell[i];
@@ -1299,60 +1297,63 @@ MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length
NR_FIVEGS_TAC_ID_TO_BIT_STRING(instance_p->tac, servedCellMember->servedNRCellInfo.fiveGS_TAC);
X2AP_INFO("TAC: %d -> %02x%02x%02x\n", instance_p->tac,
servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[0],
servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[1],
servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[2]);
servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[0],
servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[1],
servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[2]);
plmn = (X2AP_PLMN_Identity_t *)calloc(1,sizeof(X2AP_PLMN_Identity_t));
{
MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn);
ASN_SEQUENCE_ADD(&servedCellMember->servedNRCellInfo.broadcastPLMNs.list, plmn);
}
if (instance_p->frame_type[i] == TDD) {
if (instance_p->frame_type[i] == TDD) {
X2AP_FreqBandNrItem_t *freq_band;
servedCellMember->servedNRCellInfo.nrModeInfo.present = X2AP_ServedNRCell_Information__nrModeInfo_PR_tdd;
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nRFreqInfo.nRARFCN = 0; //instance_p->tdd_nRARFCN[i];
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nRFreqInfo.nRARFCN = instance_p->tdd_nRARFCN[i];
/* addition of Frequency Band List */
freq_band = calloc(1, sizeof(X2AP_FreqBandNrItem_t));
if (freq_band == NULL)
exit(1);
freq_band->freqBandIndicatorNr = instance_p->eutra_band[0];
SULFreqBandItem = calloc(1, sizeof(X2AP_SupportedSULFreqBandItem_t));
SULFreqBandItem->freqBandIndicatorNr=80; /* TODO: put correct value */
ASN_SEQUENCE_ADD(&freq_band->supportedSULBandList.list, SULFreqBandItem);
freq_band->freqBandIndicatorNr = instance_p->nr_band[i];
ASN_SEQUENCE_ADD(&servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nRFreqInfo.freqBandListNr, freq_band);
switch (instance_p->N_RB_DL[i]) {
case 50:
//This is not correct. Just to be able to test X2 only using an eNB instead of gNB
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb51;
case 32:
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb32;
break;
case 66:
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb66;
break;
case 93 :
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb93;
break;
case 106:
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb106;
break;
case 121:
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb121;
break;
case 217:
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb217;
break;
case 273:
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb273;
break;
/*More cases to be added */
default:
AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL");
break;
case 93 :
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb93;
break;
case 106:
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb106;
break;
case 121:
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb121;
break;
/*More cases to be added */
default:
AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL");
break;
}
}
}
}
else {
AssertFatal(0,"ENDC_X2Setuprequest not supported for FDD!");
}
/*Don't know where to extract the value of measurementTimingConfiguration from. Set it to 0 for now */
INT8_TO_OCTET_STRING(0, &servedCellMember->servedNRCellInfo.measurementTimingConfiguration);
/*Don't know where to extract the value of measurementTimingConfiguration from. Set it to 0 for now */
INT8_TO_OCTET_STRING(0, &servedCellMember->servedNRCellInfo.measurementTimingConfiguration);
}
ASN_SEQUENCE_ADD(&ie_GNB_ENDC->value.choice.ServedNRcellsENDCX2ManagementList.list, servedCellMember);
}
}
}
ASN_SEQUENCE_ADD(&ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_en_gNB.list, ie_GNB_ENDC);
@@ -1438,7 +1439,7 @@ int x2ap_eNB_generate_ENDC_x2_setup_response(
}
if (instance_p->frame_type[i] == FDD) {
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.present = X2AP_EUTRA_Mode_Info_PR_fDD;
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.present = X2AP_EUTRA_Mode_Info_PR_fDD;
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.dL_EARFCN = instance_p->fdd_earfcn_DL[i];
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.uL_EARFCN = instance_p->fdd_earfcn_UL[i];
switch (instance_p->N_RB_DL[i]) {
@@ -1472,12 +1473,98 @@ int x2ap_eNB_generate_ENDC_x2_setup_response(
}
}
else {
AssertFatal(0,"X2Setupresponse not supported for TDD!");
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.present = X2AP_EUTRA_Mode_Info_PR_tDD;
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.eARFCN = instance_p->fdd_earfcn_DL[i];
switch (instance_p->subframeAssignment[i]) {
case 0:
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa0;
break;
case 1:
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa1;
break;
case 2:
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa2;
break;
case 3:
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa3;
break;
case 4:
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa4;
break;
case 5:
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa5;
break;
case 6:
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa6;
break;
default:
AssertFatal(0,"Failed: Check value for subframeAssignment");
break;
}
switch (instance_p->specialSubframe[i]) {
case 0:
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp0;
break;
case 1:
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp1;
break;
case 2:
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp2;
break;
case 3:
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp3;
break;
case 4:
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp4;
break;
case 5:
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp5;
break;
case 6:
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp6;
break;
case 7:
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp7;
break;
case 8:
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp8;
break;
default:
AssertFatal(0,"Failed: Check value for subframeAssignment");
break;
}
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.cyclicPrefixDL=X2AP_CyclicPrefixDL_normal;
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.cyclicPrefixUL=X2AP_CyclicPrefixUL_normal;
switch (instance_p->N_RB_DL[i]) {
case 6:
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw6;
break;
case 15:
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw15;
break;
case 25:
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw25;
break;
case 50:
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw50;
break;
case 75:
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw75;
break;
case 100:
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw100;
break;
default:
AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL");
break;
}
}
}
ASN_SEQUENCE_ADD(&ie_ENB_ENDC->value.choice.ServedEUTRAcellsENDCX2ManagementList.list, servedCellMember);
ASN_SEQUENCE_ADD(&ie_ENB_ENDC->value.choice.ServedEUTRAcellsENDCX2ManagementList.list, servedCellMember);
}
}
}
ASN_SEQUENCE_ADD(&ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_eNB.list, ie_ENB_ENDC);
+3
View File
@@ -112,6 +112,9 @@ int load_lib(openair0_device *device,
else
deflibname=OAI_RF_LIBNAME;
shlib_fdesc[0].fname="device_init";
} else if (flag == RAU_REMOTE_THIRDPARTY_RADIO_HEAD) {
deflibname=OAI_THIRDPARTY_TP_LIBNAME;
shlib_fdesc[0].fname="transport_init";
} else {
deflibname=OAI_TP_LIBNAME;
shlib_fdesc[0].fname="transport_init";
+50 -6
View File
@@ -41,6 +41,8 @@
#define OAI_RF_LIBNAME "oai_device"
/* name of shared library implementing the transport */
#define OAI_TP_LIBNAME "oai_transpro"
/* name of shared library implementing a third-party transport */
#define OAI_THIRDPARTY_TP_LIBNAME "thirdparty_transpro"
/* name of shared library implementing the rf simulator */
#define OAI_RFSIM_LIBNAME "rfsimulator"
/* name of shared library implementing the basic simulator */
@@ -51,10 +53,9 @@
/* flags for BBU to determine whether the attached radio head is local or remote */
#define RAU_LOCAL_RADIO_HEAD 0
#define RAU_REMOTE_RADIO_HEAD 1
#define RAU_REMOTE_THIRDPARTY_RADIO_HEAD 2
#define MAX_WRITE_THREAD_PACKAGE 10
#define MAX_WRITE_THREAD_BUFFER_SIZE 8
#ifndef MAX_CARDS
#define MAX_CARDS 8
#endif
@@ -367,12 +368,22 @@ struct openair0_device_t {
/*! \brief Called to send samples to the RF target
@param device pointer to the device structure specific to the RF hardware target
@param timestamp The timestamp at whicch the first sample MUST be sent
@param buff Buffer which holds the samples
@param buff Buffer which holds the samples (2 dimensional)
@param nsamps number of samples to be sent
@param number of antennas
@param flags flags must be set to TRUE if timestamp parameter needs to be applied
*/
int (*trx_write_func)(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int antenna_id, int flags);
/*! \brief Called to send samples to the RF target
@param device pointer to the device structure specific to the RF hardware target
@param timestamp The timestamp at whicch the first sample MUST be sent
@param buff Buffer which holds the samples (1 dimensional)
@param nsamps number of samples to be sent
@param antenna_id index of the antenna if the device has multiple anteannas
@param flags flags must be set to TRUE if timestamp parameter needs to be applied
*/
int (*trx_write_func)(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int antenna_id, int flags);
int (*trx_write_func2)(openair0_device *device, openair0_timestamp timestamp, void *buff, int nsamps,int antenna_id, int flags);
/*! \brief Receive samples from hardware.
* Read \ref nsamps samples from each channel to buffers. buff[0] is the array for
@@ -382,10 +393,24 @@ struct openair0_device_t {
* \param[out] ptimestamp the time at which the first sample was received.
* \param[out] buff An array of pointers to buffers for received samples. The buffers must be large enough to hold the number of samples \ref nsamps.
* \param nsamps Number of samples. One sample is 2 byte I + 2 byte Q => 4 byte.
* \param antenna_id Index of antenna for which to receive samples
* \param num_antennas number of antennas from which to receive samples
* \returns the number of sample read
*/
int (*trx_read_func)(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps,int antenna_id);
int (*trx_read_func)(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps,int num_antennas);
/*! \brief Receive samples from hardware, this version provides a single antenna at a time and returns.
* Read \ref nsamps samples from each channel to buffers. buff[0] is the array for
* the first channel. *ptimestamp is the time at which the first sample
* was received.
* \param device the hardware to use
* \param[out] ptimestamp the time at which the first sample was received.
* \param[out] buff A pointers to a buffer for received samples. The buffer must be large enough to hold the number of samples \ref nsamps.
* \param nsamps Number of samples. One sample is 2 byte I + 2 byte Q => 4 byte.
* \param antenna_id Index of antenna from which samples were received
* \returns the number of sample read
*/
int (*trx_read_func2)(openair0_device *device, openair0_timestamp *ptimestamp, void *buff, int nsamps,int *antenna_id);
/*! \brief print the device statistics
* \param device the hardware to use
@@ -431,6 +456,25 @@ struct openair0_device_t {
*/
void (*configure_rru)(int idx, void *arg);
/*! \brief Pointer to generic RRU private information
*/
void *thirdparty_priv;
/*! \brief Callback for Third-party RRU Initialization routine
\param device the hardware configuration to use
*/
int (*thirdparty_init)(openair0_device *device);
/*! \brief Callback for Third-party RRU Cleanup routine
\param device the hardware configuration to use
*/
int (*thirdparty_cleanup)(openair0_device *device);
/*! \brief Callback for Third-party start streaming routine
\param device the hardware configuration to use
*/
int (*thirdparty_startstreaming)(openair0_device *device);
/*! \brief RRU Configuration callback
* \param idx RU index
* \param arg pointer to capabilities or configuration
+6 -66
View File
@@ -102,23 +102,15 @@ int eth_socket_init_raw(openair0_device *device) {
eth->local_addrd_ll.sll_family = AF_PACKET;
eth->local_addrd_ll.sll_ifindex = eth->if_index.ifr_ifindex;
/* hear traffic from specific protocol*/
if (eth->flags == ETH_RAW_IF5_MOBIPASS) {
eth->local_addrd_ll.sll_protocol = htons(0xbffe);
} else{
eth->local_addrc_ll.sll_protocol = htons((short)device->eth_params->my_portc);
eth->local_addrd_ll.sll_protocol = htons((short)device->eth_params->my_portd);
}
eth->local_addrc_ll.sll_protocol = htons((short)device->eth_params->my_portc);
eth->local_addrd_ll.sll_protocol = htons((short)device->eth_params->my_portd);
eth->local_addrc_ll.sll_halen = ETH_ALEN;
eth->local_addrc_ll.sll_pkttype = PACKET_OTHERHOST;
eth->local_addrd_ll.sll_halen = ETH_ALEN;
eth->local_addrd_ll.sll_pkttype = PACKET_OTHERHOST;
eth->addr_len = sizeof(struct sockaddr_ll);
if ((eth->flags != ETH_RAW_IF5_MOBIPASS ) &&
(bind(eth->sockfdc,(struct sockaddr *)&eth->local_addrc_ll,eth->addr_len)<0)) {
perror("ETHERNET: Cannot bind to socket (control)");
exit(0);
}
if (bind(eth->sockfdd,(struct sockaddr *)&eth->local_addrd_ll,eth->addr_len)<0) {
perror("ETHERNET: Cannot bind to socket (user)");
exit(0);
@@ -127,12 +119,9 @@ int eth_socket_init_raw(openair0_device *device) {
/* Construct the Ethernet header */
ether_aton_r(local_mac, (struct ether_addr *)(&(eth->ehd.ether_shost)));
ether_aton_r(remote_mac, (struct ether_addr *)(&(eth->ehd.ether_dhost)));
if (eth->flags == ETH_RAW_IF5_MOBIPASS) {
eth->ehd.ether_type = htons(0xbffe);
} else {
eth->ehc.ether_type = htons((short)device->eth_params->my_portc);
eth->ehd.ether_type = htons((short)device->eth_params->my_portd);
}
eth->ehc.ether_type = htons((short)device->eth_params->my_portc);
eth->ehd.ether_type = htons((short)device->eth_params->my_portd);
printf("[%s] binding to hardware address %x:%x:%x:%x:%x:%x\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"),eth->ehd.ether_shost[0],eth->ehd.ether_shost[1],eth->ehd.ether_shost[2],eth->ehd.ether_shost[3],eth->ehd.ether_shost[4],eth->ehd.ether_shost[5]);
return 0;
@@ -216,8 +205,6 @@ int trx_eth_write_raw_IF4p5(openair0_device *device, openair0_timestamp timestam
packet_size = RAW_IF4p5_PULFFT_SIZE_BYTES(nblocks);
} else if (flags == IF4p5_PULTICK) {
packet_size = RAW_IF4p5_PULTICK_SIZE_BYTES;
} else if (flags == IF5_MOBIPASS) {
packet_size = RAW_IF5_MOBIPASS_SIZE_BYTES;
} else {
packet_size = RAW_IF4p5_PRACH_SIZE_BYTES;
}
@@ -430,53 +417,6 @@ int trx_eth_read_raw_IF4p5(openair0_device *device, openair0_timestamp *timestam
}
int trx_eth_read_raw_IF5_mobipass(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc) {
// Read nblocks info from packet itself
int bytes_received=0;
eth_state_t *eth = (eth_state_t*)device->priv;
int ret;
ssize_t packet_size = 28; //MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t ;
// ssize_t packet_size = MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + 640*sizeof(int16_t);
bytes_received = recv(eth->sockfdd,
buff[0],
packet_size,
MSG_PEEK);
if (bytes_received ==-1) {
eth->num_rx_errors++;
perror("[MOBIPASS]ETHERNET IF5 READ (header): ");
exit(-1);
}
IF5_mobipass_header_t *test_header = (IF5_mobipass_header_t*)((uint8_t *)buff[0] + MAC_HEADER_SIZE_BYTES);
*timestamp = test_header->time_stamp;
packet_size = MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + 640*sizeof(int16_t);
while(bytes_received < packet_size) {
ret = recv(eth->sockfdd,
buff[0],
packet_size,
0);
if (bytes_received ==-1) {
eth->num_rx_errors++;
perror("[MOBIPASS] ETHERNET IF5 READ (payload): ");
return(-1);
} else {
bytes_received+=ret;
eth->rx_actual_nsamps = bytes_received>>1;
eth->rx_count++;
}
}
eth->rx_nsamps = nsamps;
return(bytes_received);
}
int eth_set_dev_conf_raw(openair0_device *device) {
eth_state_t *eth = (eth_state_t*)device->priv;
+156 -120
View File
@@ -47,7 +47,7 @@
#include "ethernet_lib.h"
#include "common/ran_context.h"
#define DEBUG 0
//#define DEBUG 1
// These are for IF5 and must be put into the device structure if multiple RUs in the same RAU !!!!!!!!!!!!!!!!!
uint16_t pck_seq_num = 1;
@@ -142,8 +142,8 @@ int eth_socket_init_udp(openair0_device *device) {
perror("ETHERNET: Cannot set SO_REUSEADDR option on socket (control)");
exit(0);
}
if (setsockopt(eth->sockfdd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int))) {
perror("ETHERNET: Cannot set SO_REUSEADDR option on socket (user)");
if (setsockopt(eth->sockfdd, SOL_SOCKET, SO_NO_CHECK, &enable, sizeof(int))) {
perror("ETHERNET: Cannot set SO_NO_CHECK option on socket (user)");
exit(0);
}
@@ -202,8 +202,9 @@ int trx_eth_read_udp_IF4p5(openair0_device *device, openair0_timestamp *timestam
goto again;
}
} else {
perror("ETHERNET IF4p5 READ");
printf("(%s):\n", strerror(errno));
return(-1);
//perror("ETHERNET IF4p5 READ");
//printf("(%s):\n", strerror(errno));
}
} else {
*timestamp = test_header->sub_type;
@@ -264,36 +265,82 @@ int trx_eth_write_udp_IF4p5(openair0_device *device, openair0_timestamp timestam
return (bytes_sent);
}
int trx_eth_write_udp(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int cc, int flags) {
int trx_eth_write_udp(openair0_device *device, openair0_timestamp timestamp, void *buff, int nsamps,int cc, int flags) {
int bytes_sent=0;
eth_state_t *eth = (eth_state_t*)device->priv;
int sendto_flag =0;
int i=0;
//sendto_flag|=flags;
eth->tx_nsamps=nsamps;
for (i=0;i<cc;i++) {
/* buff[i] points to the position in tx buffer where the payload to be sent is
int nsamps2; // aligned to upper 32 or 16 byte boundary
#if defined(__x86_64) || defined(__i386__)
#ifdef __AVX2__
nsamps2 = (nsamps+7)>>3;
__m256i buff_tx[nsamps2+1];
__m256i *buff_tx2=buff_tx+1;
#else
nsamps2 = (nsamps+3)>>2;
__m128i buff_tx[nsamps2+2];
__m128i *buff_tx2=buff_tx+2;
#endif
#elif defined(__arm__) || defined(__aarch64__)
nsamps2 = (nsamps+3)>>2;
int16x8_t buff_tx[nsamps2+2];
int16x8_t *buff_tx2=buff_tx+2;
#else
#error Unsupported CPU architecture, ethernet device cannot be built
#endif
// bring TX data into 12 LSBs for softmodem RX
for (int j=0; j<nsamps2; j++) {
#if defined(__x86_64__) || defined(__i386__)
#ifdef __AVX2__
buff_tx2[j] = _mm256_slli_epi16(((__m256i *)buff)[j],4);
#else
buff_tx2[j] = _mm_slli_epi16(((__m128i *)buff)[j],4);
#endif
#elif defined(__arm__)
buff_tx2[j] = vshlq_n_s16(((int16x8_t *)buff)[j],4);
#endif
}
/* buff[i] points to the position in tx buffer where the payload to be sent is
buff2 points to the position in tx buffer where the packet header will be placed */
void *buff2 = (void*)(buff[i]- APP_HEADER_SIZE_BYTES);
/* we don't want to ovewrite with the header info the previous tx buffer data so we store it*/
int32_t temp0 = *(int32_t *)buff2;
openair0_timestamp temp1 = *(openair0_timestamp *)(buff2 + sizeof(int32_t));
void *buff2 = ((void*)buff_tx2)- APP_HEADER_SIZE_BYTES;
bytes_sent = 0;
/* constract application header */
// eth->pck_header.seq_num = pck_seq_num;
//eth->pck_header.antenna_id = 1+(i<<1);
//eth->pck_header.timestamp = timestamp;
*(uint16_t *)buff2 = eth->pck_seq_num;
*(uint16_t *)(buff2 + sizeof(uint16_t)) = 1+(i<<1);
*(openair0_timestamp *)(buff2 + sizeof(int32_t)) = timestamp;
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TX_SEQ_NUM, eth->pck_seq_num);
// ECPRI Protocol revision + reserved bits (1 byte)
*(uint8_t *)buff2 = ECPRIREV;
// ECPRI Message type (1 byte)
*(uint8_t *)(buff2 + 1) = 64;
// ECPRI Payload Size (2 bytes)
AssertFatal(nsamps<16381,"nsamps > 16381\n");
*(uint8_t *)(buff2 + 2) = (nsamps<<2)>>8;
*(uint8_t *)(buff2 + 3) = (nsamps<<2)&0xff;
// ECPRI PC_ID (2 bytes)
*(uint16_t *)(buff2 + 4) = cc;
// OAI modified SEQ_ID (4 bytes)
*(uint64_t *)(buff2 + 6) = ((uint64_t )timestamp)*6;
/*
printf("ECPRI TX (REV %x, MessType %d, Payload size %d, PC_ID %d, TS %llu\n",
*(uint8_t *)buff2,
*(uint8_t *)(buff2+1),
*(uint16_t *)(buff2+2),
*(uint16_t *)(buff2+4),
*(uint64_t *)(buff2+6));
*/
int sent_byte;
if (eth->compression == ALAW_COMPRESS) {
@@ -311,7 +358,7 @@ int trx_eth_write_udp(openair0_device *device, openair0_timestamp timestamp, voi
bytes_sent);
#endif
/* Send packet */
bytes_sent += sendto(eth->sockfdd,
bytes_sent = sendto(eth->sockfdd,
buff2,
sent_byte,
sendto_flag,
@@ -339,17 +386,13 @@ int trx_eth_write_udp(openair0_device *device, openair0_timestamp timestamp, voi
}
//}
/* tx buffer values restored */
*(int32_t *)buff2 = temp0;
*(openair0_timestamp *)(buff2 + sizeof(int32_t)) = temp1;
}
return (bytes_sent-APP_HEADER_SIZE_BYTES)>>2;
}
#define NOSHIFT 1
int trx_eth_read_udp(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc) {
int trx_eth_read_udp(openair0_device *device, openair0_timestamp *timestamp, void *buff, int nsamps, int *cc) {
int bytes_received=0;
eth_state_t *eth = (eth_state_t*)device->priv;
@@ -357,105 +400,98 @@ int trx_eth_read_udp(openair0_device *device, openair0_timestamp *timestamp, voi
int rcvfrom_flag =0;
int block_cnt=0;
int again_cnt=0;
int i=0;
static int packet_cnt=0;
int payload_size = UDP_PACKET_SIZE_BYTES(nsamps);
#if defined(__x86_64__) || defined(__i386__)
#ifdef __AVX2__
int nsamps2 = (payload_size>>5)+1;
__m256i temp_rx[nsamps2];
char *temp_rx0 = ((char *)&temp_rx[1])-APP_HEADER_SIZE_BYTES;
#else
int nsamps2 = (payload_size>>4)+1;
__m128i temp_rx[nsamps2];
char *temp_rx0 = ((char *)&temp_rx[1])-APP_HEADER_SIZE_BYTES;
#endif
#elif defined(__arm__) || defined(__aarch64__)
int nsamps2 = (payload_size>>4)+1
int16x8_t temp_rx[nsamps2];
char *temp_rx0 = ((char *)&temp_rx[1])-APP_HEADER_SIZE_BYTES;
#else
#error Unsupported CPU architecture device cannot be built
int nsamps2 = (payload_size>>2)+1;
int32_t temp_rx[payload_size>>2];
char* *temp_rx0 = ((char *)&temp_rx[1]) - APP_HEADER_SIZE_BYTES;
#endif
eth->rx_nsamps=nsamps;
for (i=0;i<cc;i++) {
/* buff[i] points to the position in rx buffer where the payload to be received will be placed
buff2 points to the position in rx buffer where the packet header will be placed */
void *buff2 = (void*)(buff[i]- APP_HEADER_SIZE_BYTES);
/* we don't want to ovewrite with the header info the previous rx buffer data so we store it*/
int32_t temp0 = *(int32_t *)buff2;
openair0_timestamp temp1 = *(openair0_timestamp *)(buff2 + sizeof(int32_t));
bytes_received=0;
block_cnt=0;
int receive_bytes;
if (eth->compression == ALAW_COMPRESS) {
receive_bytes = UDP_PACKET_SIZE_BYTES_ALAW(nsamps);
} else {
receive_bytes = UDP_PACKET_SIZE_BYTES(nsamps);
}
while(bytes_received < receive_bytes) {
again:
#if DEBUG
printf("------- RX------: buff2 current position=%d remaining_bytes=%d bytes_recv=%d \n",
(void *)(buff2+bytes_received),
receive_bytes - bytes_received,
bytes_received);
#endif
bytes_received +=recvfrom(eth->sockfdd,
buff2,
receive_bytes,
rcvfrom_flag,
(struct sockaddr *)&eth->dest_addrd,
(socklen_t *)&eth->addr_len);
if (bytes_received ==-1) {
eth->num_rx_errors++;
if (errno == EAGAIN) {
again_cnt++;
usleep(10);
if (again_cnt == 1000) {
bytes_received=0;
block_cnt=0;
AssertFatal(eth->compression == NO_COMPRESS, "IF5 compression not supported for now\n");
while(bytes_received < payload_size) {
again:
bytes_received +=recvfrom(eth->sockfdd,
temp_rx0,
payload_size,
rcvfrom_flag,
(struct sockaddr *)&eth->dest_addrd,
(socklen_t *)&eth->addr_len);
packet_cnt++;
if (bytes_received ==-1) {
eth->num_rx_errors++;
if (errno == EAGAIN) {
again_cnt++;
usleep(10);
if (again_cnt == 1000) {
perror("ETHERNET READ: ");
exit(-1);
} else {
printf("AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN \n");
goto again;
}
} else if (errno == EWOULDBLOCK) {
block_cnt++;
usleep(10);
if (block_cnt == 1000) {
perror("ETHERNET READ: ");
exit(-1);
} else {
printf("BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK \n");
goto again;
}
} else {
bytes_received=0;
goto again;
}
} else if (errno == EWOULDBLOCK) {
block_cnt++;
usleep(10);
if (block_cnt == 1000) {
perror("ETHERNET READ: ");
exit(-1);
} else {
printf("BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK \n");
goto again;
}
} else {
#if DEBUG
printf("------- RX------: nu=%d an_id=%d ts%d bytes_recv=%d\n",
*(int16_t *)buff2,
*(int16_t *)(buff2 + sizeof(int16_t)),
*(openair0_timestamp *)(buff2 + sizeof(int32_t)),
bytes_received);
dump_packet((device->host_type == RAU_HOST)? "RAU":"RRU", buff2, UDP_PACKET_SIZE_BYTES(nsamps),RX_FLAG);
#endif
/* store the timestamp value from packet's header */
*timestamp = *(openair0_timestamp *)(buff2 + sizeof(int32_t));
/* store the sequence number of the previous packet received */
if (eth->pck_seq_num_cur == 0) {
eth->pck_seq_num_prev = *(uint16_t *)buff2;
} else {
eth->pck_seq_num_prev = eth->pck_seq_num_cur;
}
/* get the packet sequence number from packet's header */
eth->pck_seq_num_cur = *(uint16_t *)buff2;
if ( ( eth->pck_seq_num_cur != (eth->pck_seq_num_prev + 1) ) && !((eth->pck_seq_num_prev==MAX_PACKET_SEQ_NUM(nsamps,device->openair0_cfg->samples_per_frame)) && (eth->pck_seq_num_cur==1 )) && !((eth->pck_seq_num_prev==1) && (eth->pck_seq_num_cur==1))) {
//#if DEBUG
printf("Out of order packet received: current_packet=%d previous_packet=%d timestamp=%"PRId64"\n",eth->pck_seq_num_cur,eth->pck_seq_num_prev,*timestamp);
//#endif
}
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RX_SEQ_NUM,eth->pck_seq_num_cur);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RX_SEQ_NUM_PRV,eth->pck_seq_num_prev);
eth->rx_actual_nsamps=bytes_received>>2;
eth->rx_count++;
}
}
/* tx buffer values restored */
*(int32_t *)buff2 = temp0;
*(openair0_timestamp *)(buff2 + sizeof(int32_t)) = temp1;
}
return (bytes_received-APP_HEADER_SIZE_BYTES)>>2;
} else {
/* store the timestamp value from packet's header */
*timestamp = *(openair0_timestamp *)(temp_rx0 + ECPRICOMMON_BYTES+ECPRIPCID_BYTES);
// convert TS to samples, /3 for 30.72 Ms/s, /6 for 15.36 Ms/s, /12 for 7.68 Ms/s, etc.
*timestamp = *timestamp/6;
// handle 1.4,3,5,10,15 MHz cases
*cc = *(uint16_t*)(temp_rx0 + ECPRICOMMON_BYTES);
}
eth->rx_actual_nsamps=payload_size>>2;
eth->rx_count++;
}
#ifdef NOSHIFT
memcpy(buff,(void*)(temp_rx+1),payload_size);
#else
// populate receive buffer in lower 12-bits from 16-bit representation
for (int j=1; j<nsamps2; j++) {
#if defined(__x86_64__) || defined(__i386__)
#ifdef __AVX2__
((__m256i *)buff)[j-1] = _mm256_srai_epi16(temp_rx[j],2);
#else
((__m128i *)buff)[j-1] = _mm_srai_epi16(temp_rx[j],2);
#endif
#elif defined(__arm__)
((int16x8_t *)buff)[j] = vshrq_n_s16(temp_rx[i][j],2);
#endif
}
#endif
return (payload_size>>2);
}
@@ -52,11 +52,20 @@ int num_devices_eth = 0;
struct sockaddr_in dest_addr[MAX_INST];
int dest_addr_len[MAX_INST];
int load_lib(openair0_device *device,
openair0_config_t *openair0_cfg,
eth_params_t *cfg,
uint8_t flag);
int trx_eth_start(openair0_device *device)
{
eth_state_t *eth = (eth_state_t*)device->priv;
if (eth->flags == ETH_UDP_IF5_ECPRI_MODE) {
AssertFatal(device->thirdparty_init != NULL, "device->thirdparty_init is null\n");
AssertFatal(device->thirdparty_init(device) == 0, "third-party init failed\n");
device->openair0_cfg->samples_per_packet = 256;
}
/* initialize socket */
if (eth->flags == ETH_RAW_MODE) {
printf("Setting ETHERNET to ETH_RAW_IF5_MODE\n");
@@ -121,11 +130,6 @@ int trx_eth_start(openair0_device *device)
} else if (eth->flags == ETH_RAW_IF5_MOBIPASS) {
printf("Setting ETHERNET to RAW_IF5_MODE\n");
if (eth_socket_init_raw(device)!=0) return -1;
if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1;
} else {
printf("Setting ETHERNET to UDP_IF5_MODE\n");
if (eth_socket_init_udp(device)!=0) return -1;
@@ -137,8 +141,7 @@ int trx_eth_start(openair0_device *device)
if(eth_get_dev_conf_udp(device)!=0) return -1;
}*/
/* adjust MTU wrt number of samples per packet */
if(ethernet_tune (device,MTU_SIZE,UDP_IF4p5_PRACH_SIZE_BYTES)!=0) return -1;
//if(ethernet_tune (device,MTU_SIZE,UDP_IF4p5_PRACH_SIZE_BYTES)!=0) return -1;
if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1;
}
@@ -166,9 +169,15 @@ void trx_eth_end(openair0_device *device)
}
int trx_eth_stop(openair0_device *device)
{
return(0);
int trx_eth_stop(openair0_device *device) {
eth_state_t *eth = (eth_state_t*)device->priv;
if (eth->flags == ETH_UDP_IF5_ECPRI_MODE) {
AssertFatal(device->thirdparty_cleanup != NULL, "device->thirdparty_cleanup is null\n");
AssertFatal(device->thirdparty_cleanup(device) == 0, "third-party cleanup failed\n");
}
return(0);
}
@@ -387,20 +396,11 @@ int transport_init(openair0_device *device,
eth_state_t *eth = (eth_state_t*)malloc(sizeof(eth_state_t));
memset(eth, 0, sizeof(eth_state_t));
if (eth_params->transp_preference == 1) {
eth->flags = ETH_RAW_MODE;
} else if (eth_params->transp_preference == 0) {
eth->flags = ETH_UDP_MODE;
} else if (eth_params->transp_preference == 3) {
eth->flags = ETH_RAW_IF4p5_MODE;
} else if (eth_params->transp_preference == 2) {
eth->flags = ETH_UDP_IF4p5_MODE;
} else if (eth_params->transp_preference == 4) {
eth->flags = ETH_RAW_IF5_MOBIPASS;
} else {
printf("transport_init: Unknown transport preference %d - default to RAW", eth_params->transp_preference);
eth->flags = ETH_RAW_MODE;
}
eth->flags = eth_params->transp_preference;
// load third-party driver
if (eth->flags == ETH_UDP_IF5_ECPRI_MODE) load_lib(device,openair0_cfg,eth_params,RAU_REMOTE_THIRDPARTY_RADIO_HEAD);
if (eth_params->if_compress == 0) {
eth->compression = NO_COMPRESS;
@@ -423,12 +423,17 @@ int transport_init(openair0_device *device,
device->trx_set_gains_func = trx_eth_set_gains;
device->trx_write_init = trx_eth_write_init;
if (eth->flags == ETH_RAW_MODE) {
device->trx_read_func2 = NULL;
device->trx_read_func = NULL;
device->trx_write_func2 = NULL;
device->trx_write_func = NULL;
if (eth->flags == ETH_RAW_MODE) {
device->trx_write_func = trx_eth_write_raw;
device->trx_read_func = trx_eth_read_raw;
} else if (eth->flags == ETH_UDP_MODE) {
device->trx_write_func = trx_eth_write_udp;
device->trx_read_func = trx_eth_read_udp;
} else if (eth->flags == ETH_UDP_MODE || eth->flags == ETH_UDP_IF5_ECPRI_MODE) {
device->trx_write_func2 = trx_eth_write_udp;
device->trx_read_func2 = trx_eth_read_udp;
device->trx_ctlsend_func = trx_eth_ctlsend_udp;
device->trx_ctlrecv_func = trx_eth_ctlrecv_udp;
} else if (eth->flags == ETH_RAW_IF4p5_MODE) {
@@ -439,9 +444,6 @@ int transport_init(openair0_device *device,
device->trx_read_func = trx_eth_read_udp_IF4p5;
device->trx_ctlsend_func = trx_eth_ctlsend_udp;
device->trx_ctlrecv_func = trx_eth_ctlrecv_udp;
} else if (eth->flags == ETH_RAW_IF5_MOBIPASS) {
device->trx_write_func = trx_eth_write_raw_IF4p5;
device->trx_read_func = trx_eth_read_raw_IF5_mobipass;
} else {
//device->trx_write_func = trx_eth_write_udp_IF4p5;
//device->trx_read_func = trx_eth_read_udp_IF4p5;
@@ -49,7 +49,10 @@
#define RX_FLAG 0
#include "if_defs.h"
#define APP_HEADER_SIZE_BYTES (sizeof(int32_t) + sizeof(openair0_timestamp))
#define ECPRICOMMON_BYTES 4
#define ECPRIPCID_BYTES 2
#define APP_HEADER_SIZE_BYTES (ECPRICOMMON_BYTES + ECPRIPCID_BYTES + sizeof(openair0_timestamp))
#define ECPRIREV 1 // ECPRI Version 1, C=0 - single ECPRI message per OAI TX packet
/*!\brief opaque ethernet data structure */
typedef struct {
@@ -234,8 +237,8 @@ int ethernet_tune(openair0_device *device, unsigned int option, int value);
* @ingroup _oai
*/
int eth_socket_init_udp(openair0_device *device);
int trx_eth_write_udp(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int cc, int flags);
int trx_eth_read_udp(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc);
int trx_eth_write_udp(openair0_device *device, openair0_timestamp timestamp, void *buff, int nsamps,int cc, int flags);
int trx_eth_read_udp(openair0_device *device, openair0_timestamp *timestamp, void *buff, int nsamps, int *cc);
int eth_socket_init_raw(openair0_device *device);
@@ -36,15 +36,17 @@
#include <netinet/ether.h>
#include <stdint.h>
#ifndef LITE_COMPILATION
#include "PHY/LTE_TRANSPORT/if4_tools.h"
#include "PHY/LTE_TRANSPORT/if5_tools.h"
#endif
// ETH transport preference modes
#define ETH_UDP_MODE 0
#define ETH_RAW_MODE 1
#define ETH_UDP_MODE 0
#define ETH_RAW_MODE 1
#define ETH_UDP_IF4p5_MODE 2
#define ETH_RAW_IF4p5_MODE 3
#define ETH_RAW_IF5_MOBIPASS 4
#define ETH_UDP_IF5_ECPRI_MODE 4
// COMMOM HEADER LENGTHS
@@ -71,6 +71,11 @@ gNBs =
initialDLBWPmappingType_2 = 0;
#this is SS=1,L=12
initialDLBWPstartSymbolAndLength_2 = 54;
initialDLBWPk0_3 = 0;
initialDLBWPmappingType_3 = 0;
#this is SS=1,L=4 //5 (4 is for 43, 5 is for 57)
initialDLBWPstartSymbolAndLength_3 = 57; //43; //57;
#uplinkConfigCommon
#frequencyInfoUL
ul_frequencyBand = 257;
@@ -89,7 +94,7 @@ gNBs =
initialULBWPsubcarrierSpacing = 3;
#rach-ConfigCommon
#rach-ConfigGeneric
prach_ConfigurationIndex = 98;
prach_ConfigurationIndex = 52;
#prach_msg1_FDM
#0 = one, 1=two, 2=four, 3=eight
prach_msg1_FDM = 0;
@@ -103,12 +108,12 @@ gNBs =
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
ra_ResponseWindow = 7;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
#0=oneeighth,1=onefourth,2=half,3=one,4=two,5=four,6=eight,7=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
#oneHalf (0..15) 4,8,12,16,...60,64
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15;
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 7;
#ra_ContentionResolutionTimer
#(0..7) 8,16,24,32,40,48,56,64
ra_ContentionResolutionTimer = 7;
@@ -119,22 +124,26 @@ gNBs =
prach_RootSequenceIndex = 1;
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
#
msg1_SubcarrierSpacing = 1,
msg1_SubcarrierSpacing = 3,
# restrictedSetConfig
# 0=unrestricted, 1=restricted type A, 2=restricted type B
restrictedSetConfig = 0,
# pusch-ConfigCommon (up to 16 elements)
initialULBWPk2_0 = 2;
initialULBWPk2_0 = 6;
initialULBWPmappingType_0 = 1
# this is SS=0 L=11
initialULBWPstartSymbolAndLength_0 = 55;
initialULBWPk2_1 = 2;
initialULBWPk2_1 = 6;
initialULBWPmappingType_1 = 1;
# this is SS=0 L=12
initialULBWPstartSymbolAndLength_1 = 69;
initialULBWPk2_2 = 7;
initialULBWPmappingType_2 = 1;
# this is SS=10 L=4
initialULBWPstartSymbolAndLength_2 = 52;
msg3_DeltaPreamble = 1;
p0_NominalWithGrant =-90;
@@ -47,7 +47,7 @@ gNBs =
dl_carrierBandwidth = 32;
#initialDownlinkBWP
#genericParameters
# this is RBstart=0,L=50 (275*(L-1))+RBstart
# this is RBstart=0,L=32 (275*(L-1))+RBstart
initialDLBWPlocationAndBandwidth = 8525;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
@@ -121,8 +121,8 @@ gNBs =
ra_ContentionResolutionTimer = 7;
rsrp_ThresholdSSB = 19;
#prach-RootSequenceIndex_PR
#0 = 839, 1 = 139
prach_RootSequenceIndex_PR = 1;
#1 = 839, 2 = 139
prach_RootSequenceIndex_PR = 2;
prach_RootSequenceIndex = 1;
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
#
@@ -132,12 +132,12 @@ gNBs =
# 0=unrestricted, 1=restricted type A, 2=restricted type B
restrictedSetConfig = 0,
# pusch-ConfigCommon (up to 16 elements)
initialULBWPk2_0 = 2;
initialULBWPk2_0 = 6;
initialULBWPmappingType_0 = 1
# this is SS=0 L=11
initialULBWPstartSymbolAndLength_0 = 55;
initialULBWPk2_1 = 2;
initialULBWPk2_1 = 6;
initialULBWPmappingType_1 = 1;
# this is SS=0 L=12
initialULBWPstartSymbolAndLength_1 = 69;
@@ -211,7 +211,7 @@ gNBs =
);
///X2
enable_x2 = "yes";
enable_x2 = "no";
t_reloc_prep = 1000; /* unit: millisecond */
tx2_reloc_overall = 2000; /* unit: millisecond */
t_dc_prep = 1000; /* unit: millisecond */
@@ -1,6 +1,7 @@
Active_gNBs = ( "gNB-Eurecom-5GNRBox");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
Num_Threads_PUSCH = 8;
gNBs =
(
@@ -0,0 +1,243 @@
Active_eNBs = ( "eNB_Eurecom_VCO_B38");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
eNBs =
(
{
# real_time choice in {hard, rt-preempt, no}
real_time = "no";
////////// Identification parameters:
eNB_ID = 0xe00;
cell_type = "CELL_MACRO_ENB";
eNB_name = "eNB_Eurecom_VCO_B38";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ( { mcc = 222; mnc = 01; mnc_length = 2; } );
////////// Physical parameters:
component_carriers = (
{
node_function = "NGFI_RCC_IF5";
node_timing = "synch_to_ext_device";
node_synch_ref = 0;
frame_type = "TDD";
tdd_config = 1;
tdd_config_s = 0;
prefix_type = "NORMAL";
eutra_band = 38;
downlink_frequency = 2585000000L;
uplink_frequency_offset = 0;
Nid_cell = 0;
N_RB_DL = 100;
Nid_cell_mbsfn = 0;
nb_antenna_ports = 1;
nb_antennas_tx = 1;
nb_antennas_rx = 1;
tx_gain = 90;
rx_gain = 125;
prach_root = 0;
prach_config_index = 0;
prach_high_speed = "DISABLE";
prach_zero_correlation = 5;
prach_freq_offset = 2;
pucch_delta_shift = 1;
pucch_nRB_CQI = 1;
pucch_nCS_AN = 0;
pucch_n1_AN = 0;
pdsch_referenceSignalPower = 10;
pdsch_p_b = 0;
pusch_n_SB = 1;
pusch_enable64QAM = "DISABLE";
pusch_hoppingMode = "interSubFrame";
pusch_hoppingOffset = 0;
pusch_groupHoppingEnabled = "ENABLE";
pusch_groupAssignment = 0;
pusch_sequenceHoppingEnabled = "DISABLE";
pusch_nDMRS1 = 1;
phich_duration = "NORMAL";
phich_resource = "ONESIXTH";
srs_enable = "DISABLE";
/* srs_BandwidthConfig =;
srs_SubframeConfig =;
srs_ackNackST =;
srs_MaxUpPts =;*/
pusch_p0_Nominal = -96;
pusch_alpha = "AL1";
pucch_p0_Nominal = -106;
msg3_delta_Preamble = 6;
pucch_deltaF_Format1 = "deltaF2";
pucch_deltaF_Format1b = "deltaF3";
pucch_deltaF_Format2 = "deltaF0";
pucch_deltaF_Format2a = "deltaF0";
pucch_deltaF_Format2b = "deltaF0";
rach_numberOfRA_Preambles = 64;
rach_preamblesGroupAConfig = "DISABLE";
/*
rach_sizeOfRA_PreamblesGroupA = ;
rach_messageSizeGroupA = ;
rach_messagePowerOffsetGroupB = ;
*/
rach_powerRampingStep = 4;
rach_preambleInitialReceivedTargetPower = -108;
rach_preambleTransMax = 10;
rach_raResponseWindowSize = 10;
rach_macContentionResolutionTimer = 48;
rach_maxHARQ_Msg3Tx = 4;
pcch_default_PagingCycle = 128;
pcch_nB = "oneT";
bcch_modificationPeriodCoeff = 2;
ue_TimersAndConstants_t300 = 1000;
ue_TimersAndConstants_t301 = 1000;
ue_TimersAndConstants_t310 = 1000;
ue_TimersAndConstants_t311 = 10000;
ue_TimersAndConstants_n310 = 20;
ue_TimersAndConstants_n311 = 1;
ue_TransmissionMode = 1;
}
);
srb1_parameters :
{
# timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
timer_poll_retransmit = 80;
# timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
timer_reordering = 35;
# timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
timer_status_prohibit = 0;
# poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
poll_pdu = 4;
# poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
poll_byte = 99999;
# max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
max_retx_threshold = 4;
}
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// MME parameters:
mme_ip_address = ( { ipv4 = "192.168.18.150";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
enable_measurement_reports = "no";
///X2
enable_x2 = "yes";
t_reloc_prep = 1000; /* unit: millisecond */
tx2_reloc_overall = 2000; /* unit: millisecond */
t_dc_prep = 1000;
t_dc_overall = 2000;
NETWORK_INTERFACES :
{
ENB_INTERFACE_NAME_FOR_S1_MME = "bond0";
ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.18.203/24";
ENB_INTERFACE_NAME_FOR_S1U = "bond0";
ENB_IPV4_ADDRESS_FOR_S1U = "192.168.18.203/24";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
ENB_IPV4_ADDRESS_FOR_X2C = "192.168.18.203/24";
ENB_PORT_FOR_X2C = 36422; # Spec 36422
};
log_config :
{
global_log_level ="debug";
global_log_verbosity ="medium";
hw_log_level ="info";
hw_log_verbosity ="medium";
phy_log_level ="info";
phy_log_verbosity ="medium";
mac_log_level ="info";
mac_log_verbosity ="high";
rlc_log_level ="info";
rlc_log_verbosity ="medium";
pdcp_log_level ="info";
pdcp_log_verbosity ="medium";
rrc_log_level ="info";
rrc_log_verbosity ="medium";
};
}
);
MACRLCs = (
{
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
scheduler_mode = "fairRR";
puSch10xSnr = 100;
puCch10xSnr = 100;
}
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
prach_dtx_threshold = 150;
}
);
RUs = (
{
local_if_name = "bond0";
remote_address = "192.168.18.222";
local_address = "192.168.18.203";
local_portc = 50000;
remote_portc = 55444;
local_portd = 52001;
remote_portd = 52183;
local_rf = "no"
tr_preference = "udp_ecpri_if5"
nb_tx = 1
nb_rx = 1
att_tx = 5
att_rx = 0;
eNB_instances = [0];
}
);
THREAD_STRUCT = (
{
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
parallel_config = "PARALLEL_RU_L1_TRX_SPLIT";
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
worker_config = "WORKER_ENABLE";
}
);
NETWORK_CONTROLLER :
{
FLEXRAN_ENABLED = "no";
FLEXRAN_INTERFACE_NAME = "lo";
FLEXRAN_IPV4_ADDRESS = "127.0.0.1";
FLEXRAN_PORT = 2210;
FLEXRAN_CACHE = "/mnt/oai_agent_cache";
FLEXRAN_AWAIT_RECONF = "no";
};
@@ -1,6 +1,7 @@
Active_gNBs = ( "gNB-Eurecom-5GNRBox");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
Num_Threads_PUSCH = 8;
gNBs =
(
+3 -3
View File
@@ -461,10 +461,9 @@ void eNB_top(PHY_VARS_eNB *eNB,
L1_proc->subframe_rx = ru_proc->tti_rx;
L1_proc->frame_tx = (L1_proc->subframe_rx > (9-sf_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx;
L1_proc->subframe_tx = (L1_proc->subframe_rx + sf_ahead)%10;
if (rxtx(eNB,L1_proc,string) < 0)
LOG_E(PHY,"eNB %d CC_id %d failed during execution\n",eNB->Mod_id,eNB->CC_id);
LOG_E(PHY,"eNB %d CC_id %d failed during execution\n",eNB->Mod_id,eNB->CC_id);
ru_proc->timestamp_tx = L1_proc->timestamp_tx;
ru_proc->tti_tx = L1_proc->subframe_tx;
ru_proc->frame_tx = L1_proc->frame_tx;
@@ -1168,6 +1167,7 @@ void init_eNB_afterRU(void) {
for (ru_id=0,aa=0; ru_id<eNB->num_RU; ru_id++) {
eNB->frame_parms.nb_antennas_rx += eNB->RU_list[ru_id]->nb_rx;
AssertFatal(eNB->RU_list[ru_id]->common.rxdataF!=NULL,
"RU %d : common.rxdataF is NULL\n",
eNB->RU_list[ru_id]->idx);
+136 -181
View File
@@ -120,6 +120,8 @@ void configure_rru(int idx,
void reset_proc(RU_t *ru);
int connect_rau(RU_t *ru);
void wait_eNBs(void);
const char ru_states[6][9] = {"RU_IDLE","RU_CONFIG","RU_READY","RU_RUN","RU_ERROR","RU_SYNC"};
extern uint16_t sf_ahead;
@@ -141,16 +143,12 @@ extern uint16_t sf_ahead;
static inline void fh_if5_south_out(RU_t *ru,int frame, int subframe, uint64_t timestamp) {
if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff );
ru->south_out_cnt++;
send_IF5(ru, timestamp, subframe, &ru->seqno, IF5_RRH_GW_DL);
}
// southbound IF5 fronthaul for Mobipass packet format
static inline void fh_if5_mobipass_south_out(RU_t *ru,int frame, int subframe, uint64_t timestamp) {
if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff );
send_IF5(ru, timestamp, subframe, &ru->seqno, IF5_MOBIPASS);
}
// southbound IF4p5 fronthaul
@@ -189,11 +187,12 @@ void fh_if5_south_in(RU_t *ru,
recv_IF5(ru, &proc->timestamp_rx, *subframe, IF5_RRH_GW_UL);
proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023;
proc->tti_rx = (proc->timestamp_rx / fp->samples_per_tti)%10;
if (proc->first_rx == 0) {
if (proc->tti_rx != *subframe) {
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,*subframe);
exit_fun("Exiting");
LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->tti_rx %d, subframe %d), resynching\n",proc->tti_rx,*subframe);
*frame=proc->frame_rx;
*subframe=proc->tti_rx;
}
if (proc->frame_rx != *frame) {
@@ -324,48 +323,6 @@ void fh_slave_south_in(RU_t *ru,
}
// asynchronous inbound if5 fronthaul from south (Mobipass)
void fh_if5_south_asynch_in_mobipass(RU_t *ru,
int *frame,
int *subframe) {
RU_proc_t *proc = &ru->proc;
LTE_DL_FRAME_PARMS *fp = ru->frame_parms;
recv_IF5(ru, &proc->timestamp_rx, *subframe, IF5_MOBIPASS);
pthread_mutex_lock(&proc->mutex_asynch_rxtx);
int offset_mobipass = 40120;
pthread_mutex_lock(&proc->mutex_asynch_rxtx);
proc->tti_rx = ((proc->timestamp_rx-offset_mobipass)/fp->samples_per_tti)%10;
proc->frame_rx = ((proc->timestamp_rx-offset_mobipass)/(fp->samples_per_tti*10))&1023;
proc->tti_rx = (proc->timestamp_rx/fp->samples_per_tti)%10;
proc->frame_rx = (proc->timestamp_rx/(10*fp->samples_per_tti))&1023;
if (proc->first_rx == 1) {
proc->first_rx =2;
*subframe = proc->tti_rx;
*frame = proc->frame_rx;
LOG_E(PHY,"[Mobipass]timestamp_rx:%llu, frame_rx %d, subframe: %d\n",(unsigned long long int)proc->timestamp_rx,proc->frame_rx,proc->tti_rx);
} else {
if (proc->tti_rx != *subframe) {
proc->first_rx++;
LOG_E(PHY,"[Mobipass]timestamp:%llu, tti_rx %d is not what we expect %d, first_rx:%d\n",(unsigned long long int)proc->timestamp_rx, proc->tti_rx,*subframe, proc->first_rx);
//exit_fun("Exiting");
}
if (proc->frame_rx != *frame) {
proc->first_rx++;
LOG_E(PHY,"[Mobipass]timestamp:%llu, frame_rx %d is not what we expect %d, first_rx:%d\n",(unsigned long long int)proc->timestamp_rx,proc->frame_rx,*frame, proc->first_rx);
// exit_fun("Exiting");
}
// temporary solution
*subframe = proc->tti_rx;
*frame = proc->frame_rx;
}
pthread_mutex_unlock(&proc->mutex_asynch_rxtx);
} // eNodeB_3GPP_BBU
// asynchronous inbound if4p5 fronthaul from south
void fh_if4p5_south_asynch_in(RU_t *ru,
int *frame,
@@ -456,7 +413,7 @@ void fh_if5_north_asynch_in(RU_t *ru,
int tti_tx,frame_tx;
openair0_timestamp timestamp_tx;
recv_IF5(ru, &timestamp_tx, *subframe, IF5_RRH_GW_DL);
// printf("Received subframe %d (TS %llu) from RCC\n",tti_tx,timestamp_tx);
// LOG_I(PHY,"Received subframe %d (TS %llu) from RCC\n",tti_tx,timestamp_tx);
tti_tx = (timestamp_tx/fp->samples_per_tti)%10;
frame_tx = (timestamp_tx/(fp->samples_per_tti*10))&1023;
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, proc->frame_tx );
@@ -696,7 +653,7 @@ void rx_rf(RU_t *ru,
ru->ts_offset = proc->timestamp_rx;
proc->timestamp_rx = 0;
} else if (resynch==0 && (proc->timestamp_rx - old_ts != fp->samples_per_tti)) {
LOG_I(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - fp->samples_per_tti,ru->ts_offset);
LOG_D(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - fp->samples_per_tti,ru->ts_offset);
ru->ts_offset += (proc->timestamp_rx - old_ts - fp->samples_per_tti);
proc->timestamp_rx = ts-ru->ts_offset;
}
@@ -761,7 +718,7 @@ void rx_rf(RU_t *ru,
*subframe = proc->tti_rx;
}
//printf("timestamp_rx %lu, frame %d(%d), subframe %d(%d)\n",ru->timestamp_rx,proc->frame_rx,frame,proc->tti_rx,subframe);
//LOG_I(PHY,"timestamp_rx %lu, frame %d(%d), subframe %d(%d)\n",ru->timestamp_rx,proc->frame_rx,frame,proc->tti_rx,subframe);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff );
if (rxs != fp->samples_per_tti) {
@@ -929,12 +886,8 @@ static void *ru_thread_asynch_rxtx( void *param ) {
LOG_D(PHY,"ru_thread_asynch_rxtx: Waiting on incoming fronthaul\n");
// asynchronous receive from south (Mobipass)
if (ru->fh_south_asynch_in) {
ru->fh_south_asynch_in(ru, &frame, &subframe);
}
// asynchronous receive from north (RRU IF4/IF5)
else if (ru->fh_north_asynch_in) {
if (ru->fh_north_asynch_in) {
if (subframe_select(ru->frame_parms,subframe)!=SF_UL)
ru->fh_north_asynch_in(ru, &frame, &subframe);
} else
@@ -1185,21 +1138,22 @@ void wakeup_L1s(RU_t *ru) {
L1_proc_t *proc = &eNB->proc;
struct timespec t;
LOG_D(PHY, "wakeup_L1s (num %d) for RU %d (%d.%d) ru->eNB_top:%p\n", ru->num_eNB, ru->idx, ru->proc.frame_rx, ru->proc.tti_rx, ru->eNB_top);
// call eNB function directly
char string[20];
sprintf(string, "Incoming RU %d", ru->idx);
// call eNB function directly
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_WAKEUP_L1S_RU+ru->idx, ru->proc.frame_rx);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_WAKEUP_L1S_RU+ru->idx, ru->proc.tti_rx);
AssertFatal(0==pthread_mutex_lock(&proc->mutex_RU),"");
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LOCK_MUTEX_RU+ru->idx, 1);
//printf("wakeup_L1s: Frame %d, Subframe %d: RU %d done (wait_cnt %d),RU_mask[%d] %x\n",
// ru->proc.frame_rx,ru->proc.subframe_rx,ru->idx,ru->wait_cnt,ru->proc.subframe_rx,proc->RU_mask[ru->proc.subframe_rx]);
//LOG_I(PHY,"wakeup_L1s: Frame %d, Subframe %d: RU %d done (wait_cnt %d),RU_mask[%d] %x\n",
// ru->proc.frame_rx,ru->proc.tti_rx,ru->idx,ru->wait_cnt,ru->proc.tti_rx,proc->RU_mask[ru->proc.tti_rx]);
//VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_WAKEUP_L1S_RU+ru->idx, ru->proc.frame_rx);
//VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_WAKEUP_L1S_RU+ru->idx, ru->proc.subframe_rx);
//VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_WAKEUP_L1S_RU+ru->idx, ru->proc.tti_rx);
clock_gettime(CLOCK_MONOTONIC, &ru->proc.t[ru->proc.tti_rx]);
if (proc->RU_mask[ru->proc.tti_rx] == 0) {
//clock_gettime(CLOCK_MONOTONIC,&proc->t[ru->proc.subframe_rx]);
//clock_gettime(CLOCK_MONOTONIC,&proc->t[ru->proc.tti_rx]);
proc->t[ru->proc.tti_rx] = ru->proc.t[ru->proc.tti_rx];
//start_meas(&proc->ru_arrival_time);
LOG_D(PHY,"RU %d starting timer for frame %d subframe %d\n", ru->idx, ru->proc.frame_rx, ru->proc.tti_rx);
@@ -1212,13 +1166,13 @@ void wakeup_L1s(RU_t *ru) {
eNB->RU_list[i]->idx, eNB->RU_list[i]->proc.frame_rx, eNB->RU_list[i]->proc.tti_rx, ru_states[eNB->RU_list[i]->state]);
if (ru == eNB->RU_list[i] && eNB->RU_list[i]->wait_cnt == 0) {
//AssertFatal((proc->RU_mask&(1<<i)) == 0, "eNB %d frame %d, subframe %d : previous information from RU %d (num_RU %d,mask %x) has not been served yet!\n", eNB->Mod_id,ru->proc.frame_rx,ru->proc.subframe_rx,ru->idx,eNB->num_RU,proc->RU_mask);
//AssertFatal((proc->RU_mask&(1<<i)) == 0, "eNB %d frame %d, subframe %d : previous information from RU %d (num_RU %d,mask %x) has not been served yet!\n", eNB->Mod_id,ru->proc.frame_rx,ru->proc.tti_rx,ru->idx,eNB->num_RU,proc->RU_mask);
proc->RU_mask[ru->proc.tti_rx] |= (1<<i);
} else if (/*eNB->RU_list[i]->state == RU_SYNC ||*/(eNB->RU_list[i]->is_slave==1 && eNB->RU_list[i]->wait_cnt>0 && ru!=eNB->RU_list[i] && ru->is_slave==0) ) {
proc->RU_mask[ru->proc.tti_rx] |= (1<<i);
}
//printf("RU %d, RU_mask[%d] %d, i %d, frame %d, slave %d, ru->cnt %d, i->cnt %d\n",ru->idx,ru->proc.subframe_rx,proc->RU_mask[ru->proc.subframe_rx],i,ru->proc.frame_rx,ru->is_slave,ru->wait_cnt,eNB->RU_list[i]->wait_cnt);
//LOG_I(PHY,"RU %d, RU_mask[%d] %d, i %d, frame %d, slave %d, ru->cnt %d, i->cnt %d\n",ru->idx,ru->proc.tti_rx,proc->RU_mask[ru->proc.tti_rx],i,ru->proc.frame_rx,ru->is_slave,ru->wait_cnt,eNB->RU_list[i]->wait_cnt);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_MASK_RU, proc->RU_mask[ru->proc.tti_rx]);
if (ru->is_slave == 0 && ( (proc->RU_mask[ru->proc.tti_rx]&(1<<i)) == 1 ) && eNB->RU_list[i]->state == RU_RUN) { //This is master & the RRU has already been received
@@ -1233,21 +1187,21 @@ void wakeup_L1s(RU_t *ru) {
}
//clock_gettime(CLOCK_MONOTONIC,&t);
//LOG_I(PHY,"RU mask is now %x, time is %lu\n",proc->RU_mask[ru->proc.subframe_rx], t.tv_nsec - proc->t[ru->proc.subframe_rx].tv_nsec);
//LOG_I(PHY,"RU mask is now %x, time is %lu\n",proc->RU_mask[ru->proc.tti_rx], t.tv_nsec - proc->t[ru->proc.tti_rx].tv_nsec);
if (proc->RU_mask[ru->proc.tti_rx] == (1<<eNB->num_RU)-1) { // all RUs have provided their information so continue on and wakeup eNB top
LOG_D(PHY,"ru_mask is %d \n ", proc->RU_mask[ru->proc.tti_rx]);
LOG_D(PHY,"the number of RU is %d, the current ru is RU %d \n ", (1<<eNB->num_RU)-1, ru->idx);
LOG_D(PHY,"ru->proc.subframe_rx is %d \n", ru->proc.tti_rx);
LOG_D(PHY,"ru->proc.tti_rx is %d \n", ru->proc.tti_rx);
LOG_D(PHY,"Resetting mask frame %d, subframe %d, this is RU %d\n", ru->proc.frame_rx, ru->proc.tti_rx, ru->idx);
proc->RU_mask[ru->proc.tti_rx] = 0;
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_MASK_RU, proc->RU_mask[ru->proc.tti_rx]);
clock_gettime(CLOCK_MONOTONIC,&t);
//stop_meas(&proc->ru_arrival_time);
/*AssertFatal(t.tv_nsec < proc->t[ru->proc.subframe_rx].tv_nsec+5000000, "Time difference for subframe %d (Frame %d) => %lu > 5ms, this is RU %d\n",
ru->proc.subframe_rx, ru->proc.frame_rx, t.tv_nsec - proc->t[ru->proc.subframe_rx].tv_nsec, ru->idx);*/
/*AssertFatal(t.tv_nsec < proc->t[ru->proc.tti_rx].tv_nsec+5000000, "Time difference for subframe %d (Frame %d) => %lu > 5ms, this is RU %d\n",
ru->proc.tti_rx, ru->proc.frame_rx, t.tv_nsec - proc->t[ru->proc.tti_rx].tv_nsec, ru->idx);*/
//VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_WAKEUP_L1S_RU+ru->idx, ru->proc.frame_rx);
//VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_WAKEUP_L1S_RU+ru->idx, ru->proc.subframe_rx);
//VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_WAKEUP_L1S_RU+ru->idx, ru->proc.tti_rx);
AssertFatal(0==pthread_mutex_unlock(&proc->mutex_RU),"");
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_LOCK_MUTEX_RU+ru->idx, 0 );
// unlock RUs that are waiting for eNB processing to be completed
@@ -1280,8 +1234,8 @@ void wakeup_L1s(RU_t *ru) {
}
// pthread_mutex_unlock(&proc->mutex_RU);
// LOG_D(PHY,"wakeup eNB top for for subframe %d\n", ru->proc.subframe_rx);
// ru->eNB_top(eNB_list[0],ru->proc.frame_rx,ru->proc.subframe_rx,string);
// LOG_D(PHY,"wakeup eNB top for for subframe %d\n", ru->proc.tti_rx);
// ru->eNB_top(eNB_list[0],ru->proc.frame_rx,ru->proc.tti_rx,string);
ru->proc.emulate_rf_busy = 0;
}
@@ -1350,7 +1304,7 @@ void fill_rf_config(RU_t *ru,
char *rf_config_file) {
LTE_DL_FRAME_PARMS *fp = ru->frame_parms;
openair0_config_t *cfg = &ru->openair0_cfg;
//printf("////////////////numerology in config = %d\n",numerology);
//LOG_I(PHY,"////////////////numerology in config = %d\n",numerology);
int numerology = get_softmodem_params()->numerology;
if(fp->N_RB_DL == 100) {
@@ -1377,7 +1331,7 @@ void fill_rf_config(RU_t *ru,
cfg->tx_bw = 40e6;
cfg->rx_bw = 40e6;
} else {
printf("Wrong input for numerology %d\n setting to 20MHz normal CP configuration",numerology);
LOG_I(PHY,"Wrong input for numerology %d\n setting to 20MHz normal CP configuration",numerology);
cfg->sample_rate=30.72e6;
cfg->samples_per_frame = 307200;
cfg->tx_bw = 10e6;
@@ -1416,7 +1370,7 @@ void fill_rf_config(RU_t *ru,
cfg->tx_gain[i] = (double)ru->att_tx;
cfg->rx_gain[i] = ru->max_rxgain-(double)ru->att_rx;
cfg->configFilename = rf_config_file;
printf("channel %d, Setting tx_gain offset %f, rx_gain offset %f, tx_freq %f, rx_freq %f\n",
LOG_I(PHY,"channel %d, Setting tx_gain offset %f, rx_gain offset %f, tx_freq %f, rx_freq %f\n",
i, cfg->tx_gain[i],
cfg->rx_gain[i],
cfg->tx_freq[i],
@@ -1437,9 +1391,9 @@ int setup_RU_buffers(RU_t *ru) {
if (ru) {
frame_parms = ru->frame_parms;
printf("setup_RU_buffers: frame_parms = %p\n",frame_parms);
LOG_I(PHY,"setup_RU_buffers: frame_parms = %p\n",frame_parms);
} else {
printf("RU not initialized (NULL pointer)\n");
LOG_I(PHY,"RU not initialized (NULL pointer)\n");
return(-1);
}
@@ -1462,7 +1416,7 @@ int setup_RU_buffers(RU_t *ru) {
ru->sf_extension /= 4;
ru->end_of_burst_delay /= 4;
} else {
printf("not handled, todo\n");
LOG_I(PHY,"not handled, todo\n");
exit(1);
}
} else {
@@ -1476,13 +1430,13 @@ int setup_RU_buffers(RU_t *ru) {
for (i=0; i<ru->nb_rx; i++) {
card = i/4;
ant = i%4;
printf("Mapping RU id %d, rx_ant %d, on card %d, chain %d\n",ru->idx,i,ru->rf_map.card+card, ru->rf_map.chain+ant);
LOG_I(PHY,"Mapping RU id %d, rx_ant %d, on card %d, chain %d\n",ru->idx,i,ru->rf_map.card+card, ru->rf_map.chain+ant);
free(ru->common.rxdata[i]);
ru->common.rxdata[i] = ru->openair0_cfg.rxbase[ru->rf_map.chain+ant];
printf("rxdata[%d] @ %p\n",i,ru->common.rxdata[i]);
LOG_I(PHY,"rxdata[%d] @ %p\n",i,ru->common.rxdata[i]);
for (j=0; j<16; j++) {
printf("rxbuffer %d: %x\n",j,ru->common.rxdata[i][j]);
LOG_I(PHY,"rxbuffer %d: %x\n",j,ru->common.rxdata[i][j]);
ru->common.rxdata[i][j] = 16-j;
}
}
@@ -1490,13 +1444,13 @@ int setup_RU_buffers(RU_t *ru) {
for (i=0; i<ru->nb_tx; i++) {
card = i/4;
ant = i%4;
printf("Mapping RU id %d, tx_ant %d, on card %d, chain %d\n",ru->idx,i,ru->rf_map.card+card, ru->rf_map.chain+ant);
LOG_I(PHY,"Mapping RU id %d, tx_ant %d, on card %d, chain %d\n",ru->idx,i,ru->rf_map.card+card, ru->rf_map.chain+ant);
free(ru->common.txdata[i]);
ru->common.txdata[i] = ru->openair0_cfg.txbase[ru->rf_map.chain+ant];
printf("txdata[%d] @ %p\n",i,ru->common.txdata[i]);
LOG_I(PHY,"txdata[%d] @ %p\n",i,ru->common.txdata[i]);
for (j=0; j<16; j++) {
printf("txbuffer %d: %x\n",j,ru->common.txdata[i][j]);
LOG_I(PHY,"txbuffer %d: %x\n",j,ru->common.txdata[i][j]);
ru->common.txdata[i][j] = 16-j;
}
}
@@ -1623,7 +1577,7 @@ static void *ru_thread_tx( void *param ) {
}
if (eNB_proc->RU_mask_tx != (1<<eNB->num_RU)-1) { // not all RUs have provided their information so return
//printf("Not all RUs have provided their info (mask = %d), RU %d, num_RUs %d\n", eNB_proc->RU_mask_tx,ru->idx,eNB->num_RU);
//LOG_I(PHY,"Not all RUs have provided their info (mask = %d), RU %d, num_RUs %d\n", eNB_proc->RU_mask_tx,ru->idx,eNB->num_RU);
AssertFatal((ret=pthread_mutex_unlock(&eNB_proc->mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret);
} else { // all RUs TX are finished so send the ready signal to eNB processing
eNB_proc->RU_mask_tx = 0;
@@ -1644,7 +1598,7 @@ static void *ru_thread_tx( void *param ) {
}
}
//printf("ru_thread_tx: Frame %d, Subframe %d: RU %d done (wait_cnt %d),RU_mask_tx %d\n",
//LOG_I(PHY,"ru_thread_tx: Frame %d, Subframe %d: RU %d done (wait_cnt %d),RU_mask_tx %d\n",
//eNB_proc->frame_rx,eNB_proc->subframe_rx,ru->idx,ru->wait_cnt,eNB_proc->RU_mask_tx);
}
@@ -1676,12 +1630,10 @@ static void *ru_thread( void *param ) {
LOG_I(PHY,"Starting RU %d (%s,%s),\n", ru->idx, NB_functions[ru->function], NB_timing[ru->if_timing]);
if(get_softmodem_params()->emulate_rf) {
fill_rf_config(ru,ru->rf_config_file);
init_frame_parms(ru->frame_parms,1);
phy_init_RU(ru);
if (setup_RU_buffers(ru)!=0) {
printf("Exiting, cannot initialize RU Buffers\n");
LOG_I(PHY,"Exiting, cannot initialize RU Buffers\n");
exit(-1);
}
@@ -1693,24 +1645,20 @@ static void *ru_thread( void *param ) {
ru->state = RU_RUN;
} else if (ru->has_ctrl_prt == 0) {
// There is no control port: start everything here
LOG_I(PHY, "RU %d has not ctrl port\n",ru->idx);
LOG_I(PHY, "RU %d has no OAI ctrl port\n",ru->idx);
if (ru->if_south == LOCAL_RF) {
fill_rf_config(ru,ru->rf_config_file);
init_frame_parms(ru->frame_parms,1);
ru->frame_parms->nb_antennas_rx = ru->nb_rx;
phy_init_RU(ru);
openair0_device_load(&ru->rfdevice,&ru->openair0_cfg);
fill_rf_config(ru,ru->rf_config_file);
init_frame_parms(ru->frame_parms,1);
ru->frame_parms->nb_antennas_rx = ru->nb_rx;
if (setup_RU_buffers(ru)!=0) {
printf("Exiting, cannot initialize RU Buffers\n");
exit(-1);
}
if (ru->if_south == LOCAL_RF) openair0_device_load(&ru->rfdevice,&ru->openair0_cfg);
AssertFatal((ret=pthread_mutex_lock(&RC.ru_mutex))==0,"mutex_lock returns %d\n",ret);
RC.ru_mask &= ~(1<<ru->idx);
pthread_cond_signal(&RC.ru_cond);
AssertFatal((ret=pthread_mutex_unlock(&RC.ru_mutex))==0,"mutex_unlock returns %d\n",ret);
phy_init_RU(ru);
if (setup_RU_buffers(ru)!=0) {
LOG_I(PHY,"Exiting, cannot initialize RU Buffers\n");
exit(-1);
}
AssertFatal((ret=pthread_mutex_lock(&RC.ru_mutex))==0,"mutex_lock returns %d\n",ret);
@@ -1745,9 +1693,9 @@ static void *ru_thread( void *param ) {
// Start RF device if any
if (ru->start_rf) {
if (ru->start_rf(ru) != 0)
LOG_E(HW,"Could not start the RF device\n");
else LOG_I(PHY,"RU %d rf device ready\n",ru->idx);
if (ru->start_rf(ru) != 0)
AssertFatal(1==0,"Could not start the RF device\n");
else LOG_I(PHY,"RU %d rf device ready\n",ru->idx);
} else LOG_D(PHY,"RU %d no rf device\n",ru->idx);
}
@@ -1781,7 +1729,6 @@ static void *ru_thread( void *param ) {
// synchronization on input FH interface, acquire signals/data and block
if (ru->fh_south_in) ru->fh_south_in(ru,&frame,&subframe);
else AssertFatal(1==0, "No fronthaul interface at south port");
#ifdef PHY_TX_THREAD
if(first_phy_tx == 0) {
@@ -1945,7 +1892,7 @@ static void *ru_thread( void *param ) {
} // ru->state = RU_RUN
} // while !oai_exit
printf( "Exiting ru_thread \n");
LOG_I(PHY, "Exiting ru_thread \n");
if (!(get_softmodem_params()->emulate_rf)) {
if (ru->stop_rf != NULL) {
@@ -2017,6 +1964,7 @@ void *ru_thread_synch(void *arg) {
#if defined(PRE_SCD_THREAD)
void *pre_scd_thread( void *param ) {
void rlc_tick(int, int);
static int eNB_pre_scd_status;
protocol_ctxt_t ctxt;
int frame;
@@ -2051,6 +1999,7 @@ void *pre_scd_thread( void *param ) {
AssertFatal((ret=pthread_mutex_unlock(&ru->proc.mutex_pre_scd))==0,"mutex_unlock returns %d\n",ret);
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, Mod_id, ENB_FLAG_YES,
NOT_A_RNTI, frame, subframe,Mod_id);
rlc_tick(frame, subframe);
pdcp_run(&ctxt);
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
@@ -2188,6 +2137,12 @@ static void *rf_tx( void *param ) {
#endif
int start_streaming(RU_t *ru) {
LOG_I(PHY,"Starting streaming on third-party RRU\n");
return(ru->ifdevice.thirdparty_startstreaming(&ru->ifdevice));
}
int start_if(struct RU_t_s *ru,struct PHY_VARS_eNB_s *eNB) {
return(ru->ifdevice.trx_start_func(&ru->ifdevice));
}
@@ -2233,7 +2188,7 @@ void reset_proc(RU_t *ru) {
void init_RU_proc(RU_t *ru) {
int i=0, ret;
int i=0;
RU_proc_t *proc;
pthread_attr_t *attr_FH=NULL, *attr_FH1=NULL, *attr_prach=NULL, *attr_asynch=NULL, *attr_synch=NULL, *attr_emulateRF=NULL, *attr_ctrl=NULL, *attr_prach_br=NULL;
//pthread_attr_t *attr_fep=NULL;
@@ -2302,7 +2257,17 @@ void init_RU_proc(RU_t *ru) {
attr_prach_br = &proc->attr_prach_br;
#endif
if (ru->function!=eNodeB_3GPP) pthread_create( &proc->pthread_ctrl, attr_ctrl, ru_thread_control, (void *)ru );
if (ru->has_ctrl_prt == 1) pthread_create( &proc->pthread_ctrl, attr_ctrl, ru_thread_control, (void*)ru );
else {
if (ru->start_if) {
LOG_I(PHY,"Starting IF interface for RU %d\n",ru->idx);
AssertFatal(
ru->start_if(ru,NULL) == 0, "Could not start the IF device\n");
if (ru->if_south != LOCAL_RF) wait_eNBs();
}
}
pthread_create( &proc->pthread_FH, attr_FH, ru_thread, (void *)ru );
#if defined(PRE_SCD_THREAD)
@@ -2341,23 +2306,6 @@ void init_RU_proc(RU_t *ru) {
LOG_I(PHY,"%s() DJP - added creation of pthread_prach\n", __FUNCTION__);
pthread_create( &proc->pthread_prach, attr_prach, ru_thread_prach, (void *)ru );
ru->state=RU_RUN;
if(!get_softmodem_params()->emulate_rf)
{
fill_rf_config(ru,ru->rf_config_file);
init_frame_parms(ru->frame_parms,1);
ru->frame_parms->nb_antennas_rx = ru->nb_rx;
phy_init_RU(ru);
ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg);
if (ret < 0) {
LOG_I(PHY,"Exiting, cannot load device. Make sure that your SDR board is connected!\n");
exit(1);
}
if (setup_RU_buffers(ru)!=0) {
LOG_I(PHY,"Exiting, cannot initialize RU Buffers\n");
exit(1);
}
}
}
if (get_thread_worker_conf() == WORKER_ENABLE) {
@@ -2366,7 +2314,7 @@ void init_RU_proc(RU_t *ru) {
}
if (opp_enabled == 1) pthread_create(&ru->ru_stats_thread,NULL,ru_stats_thread,(void *)ru);
/*
if (ru->function == eNodeB_3GPP) {
usleep(10000);
LOG_I(PHY, "Signaling main thread that RU %d (is_slave %d,send_dmrs %d) is ready in state %s\n",ru->idx,ru->is_slave,ru->generate_dmrs_sync,ru_states[ru->state]);
@@ -2375,6 +2323,7 @@ void init_RU_proc(RU_t *ru) {
pthread_cond_signal(&RC.ru_cond);
AssertFatal((ret=pthread_mutex_unlock(&RC.ru_mutex))==0,"mutex_unlock returns %d\n",ret);
}
*/
}
@@ -2537,6 +2486,7 @@ void init_precoding_weights(PHY_VARS_eNB *eNB) {
void set_function_spec_param(RU_t *ru) {
int ret;
switch (ru->if_south) {
case LOCAL_RF: // this is an RU with integrated RF (RRU, eNB)
if (ru->function == NGFI_RRU_IF5) { // IF5 RRU
@@ -2557,10 +2507,10 @@ void set_function_spec_param(RU_t *ru) {
reset_meas(&ru->compression);
reset_meas(&ru->transport);
ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params);
printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx);
LOG_I(PHY,"NGFI_RRU_IF5: openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx);
if (ret<0) {
printf("Exiting, cannot initialize transport protocol\n");
LOG_I(PHY,"Exiting, cannot initialize transport protocol\n");
exit(-1);
}
} else if (ru->function == NGFI_RRU_IF4p5) {
@@ -2581,10 +2531,10 @@ void set_function_spec_param(RU_t *ru) {
reset_meas(&ru->compression);
reset_meas(&ru->transport);
ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params);
printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx);
LOG_I(PHY,"NGFI_RRU_if4p5 : openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx);
if (ret<0) {
printf("Exiting, cannot initialize transport protocol\n");
LOG_I(PHY,"Exiting, cannot initialize transport protocol\n");
exit(-1);
}
@@ -2604,7 +2554,7 @@ void set_function_spec_param(RU_t *ru) {
ru->fh_south_out = tx_rf; // local synchronous RF TX
ru->start_rf = start_rf; // need to start the local RF interface
ru->stop_rf = stop_rf;
printf("configuring ru_id %d (start_rf %p)\n", ru->idx, start_rf);
LOG_I(PHY,"NFGI_RRU_IF4p5: configuring ru_id %d (start_rf %p)\n", ru->idx, start_rf);
/*
if (ru->function == eNodeB_3GPP) { // configure RF parameters only for 3GPP eNodeB, we need to get them from RAU otherwise
fill_rf_config(ru,rf_config_file);
@@ -2614,7 +2564,7 @@ void set_function_spec_param(RU_t *ru) {
ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg);
if (setup_RU_buffers(ru)!=0) {
printf("Exiting, cannot initialize RU Buffers\n");
LOG_I(PHY,"Exiting, cannot initialize RU Buffers\n");
exit(-1);
}*/
break;
@@ -2627,25 +2577,22 @@ void set_function_spec_param(RU_t *ru) {
if (ru->if_timing == synch_to_other) {
ru->fh_south_in = fh_slave_south_in; // synchronize to master
ru->fh_south_out = fh_if5_mobipass_south_out; // use send_IF5 for mobipass
ru->fh_south_asynch_in = fh_if5_south_asynch_in_mobipass; // UL is asynchronous
} else {
ru->fh_south_in = fh_if5_south_in; // synchronous IF5 reception
ru->fh_south_out = fh_if5_south_out; // synchronous IF5 transmission
ru->fh_south_asynch_in = NULL; // no asynchronous UL
}
ru->start_rf = NULL; // no local RF
ru->start_rf = ru->eth_params.transp_preference == ETH_UDP_IF5_ECPRI_MODE ? start_streaming : NULL;
ru->stop_rf = NULL;
ru->start_if = start_if; // need to start if interface for IF5
ru->ifdevice.host_type = RAU_HOST;
ru->ifdevice.eth_params = &ru->eth_params;
ru->ifdevice.configure_rru = configure_ru;
ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params);
printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx);
LOG_I(PHY,"REMOTE_IF5: openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx);
if (ret<0) {
printf("Exiting, cannot initialize transport protocol\n");
LOG_I(PHY,"Exiting, cannot initialize transport protocol\n");
exit(-1);
}
@@ -2668,10 +2615,10 @@ void set_function_spec_param(RU_t *ru) {
ru->ifdevice.eth_params = &ru->eth_params;
ru->ifdevice.configure_rru = configure_ru;
ret = openair0_transport_load(&ru->ifdevice, &ru->openair0_cfg, &ru->eth_params);
printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx);
LOG_I(PHY,"REMOTE IF4p5: openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx);
if (ret<0) {
printf("Exiting, cannot initialize transport protocol\n");
LOG_I(PHY,"Exiting, cannot initialize transport protocol\n");
exit(-1);
}
@@ -2685,12 +2632,14 @@ void set_function_spec_param(RU_t *ru) {
}
malloc_IF4p5_buffer(ru);
break;
default:
LOG_E(PHY,"RU with invalid or unknown southbound interface type %d\n",ru->if_south);
break;
} // switch on interface type
}
//extern void RCconfig_RU(void);
@@ -2780,6 +2729,11 @@ void init_RU(char *rf_config_file, int send_dmrssync) {
LOG_I(PHY, "Initializing RRU descriptor %d : (%s,%s,%d)\n", ru_id, ru_if_types[ru->if_south], NB_timing[ru->if_timing], ru->function);
set_function_spec_param(ru);
if (ru->function != NGFI_RRU_IF4p5 && ru->function != NGFI_RRU_IF5) {
fill_rf_config(ru,ru->rf_config_file);
init_frame_parms(ru->frame_parms,1);
}
LOG_I(PHY, "Starting ru_thread %d, is_slave %d, send_dmrs %d\n", ru_id, ru->is_slave, ru->generate_dmrs_sync);
init_RU_proc(ru);
} // for ru_id
@@ -2793,7 +2747,7 @@ void stop_ru(RU_t *ru) {
#if defined(PRE_SCD_THREAD) || defined(PHY_TX_THREAD)
int *status;
#endif
printf("Stopping RU %p processing threads\n",(void *)ru);
LOG_I(PHY,"Stopping RU %p processing threads\n",(void *)ru);
#if defined(PRE_SCD_THREAD)
if(ru) {
@@ -2847,7 +2801,7 @@ void init_ru_vnf(void) {
pthread_mutex_init(&RC.ru_mutex,NULL);
pthread_cond_init(&RC.ru_cond,NULL);
// read in configuration file)
printf("configuring RU from file\n");
LOG_I(PHY,"configuring RU from file\n");
RCconfig_RU();
LOG_I(PHY,"number of L1 instances %d, number of RU %d, number of CPU cores %d\n",RC.nb_L1_inst,RC.nb_RU,get_nprocs());
@@ -2937,7 +2891,7 @@ void RCconfig_RU(void) {
RC.ru[j] = (RU_t *)malloc(sizeof(RU_t));
memset((void *)RC.ru[j],0,sizeof(RU_t));
RC.ru[j]->idx = j;
printf("Creating RC.ru[%d]:%p\n", j, RC.ru[j]);
LOG_I(PHY,"Creating RC.ru[%d]:%p\n", j, RC.ru[j]);
RC.ru[j]->if_timing = synch_to_ext_device;
if (RC.nb_L1_inst >0)
@@ -2947,7 +2901,7 @@ void RCconfig_RU(void) {
for (i=0; i<RC.ru[j]->num_eNB; i++) RC.ru[j]->eNB_list[i] = RC.eNB[RUParamList.paramarray[j][RU_ENB_LIST_IDX].iptr[i]][0];
RC.ru[j]->has_ctrl_prt = 1;
RC.ru[j]->has_ctrl_prt = 0;
if (config_isparamset(RUParamList.paramarray[j], RU_SDR_ADDRS)) {
RC.ru[j]->openair0_cfg.sdr_addrs = strdup(*(RUParamList.paramarray[j][RU_SDR_ADDRS].strptr));
@@ -2994,7 +2948,7 @@ void RCconfig_RU(void) {
RC.ru[j]->if_south = LOCAL_RF;
RC.ru[j]->function = eNodeB_3GPP;
RC.ru[j]->state = RU_RUN;
printf("Setting function for RU %d to eNodeB_3GPP\n",j);
LOG_I(PHY,"Setting function for RU %d to eNodeB_3GPP\n",j);
} else {
RC.ru[j]->eth_params.local_if_name = strdup(*(RUParamList.paramarray[j][RU_LOCAL_IF_NAME_IDX].strptr));
RC.ru[j]->eth_params.my_addr = strdup(*(RUParamList.paramarray[j][RU_LOCAL_ADDRESS_IDX].strptr));
@@ -3004,42 +2958,43 @@ void RCconfig_RU(void) {
// Check if control port set
if (!(config_isparamset(RUParamList.paramarray[j],RU_REMOTE_PORTC_IDX)) ) {
printf("Removing control port for RU %d\n",j);
LOG_I(PHY,"Removing control port for RU %d\n",j);
RC.ru[j]->has_ctrl_prt = 0;
} else {
RC.ru[j]->eth_params.my_portc = *(RUParamList.paramarray[j][RU_LOCAL_PORTC_IDX].uptr);
RC.ru[j]->eth_params.remote_portc = *(RUParamList.paramarray[j][RU_REMOTE_PORTC_IDX].uptr);
printf(" Control port %u \n",RC.ru[j]->eth_params.my_portc);
LOG_I(PHY," Control port %u \n",RC.ru[j]->eth_params.my_portc);
}
if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp") == 0) {
RC.ru[j]->if_south = LOCAL_RF;
RC.ru[j]->function = NGFI_RRU_IF5;
RC.ru[j]->eth_params.transp_preference = ETH_UDP_MODE;
printf("Setting function for RU %d to NGFI_RRU_IF5 (udp)\n",j);
LOG_I(PHY,"Setting function for RU %d to NGFI_RRU_IF5 (udp)\n",j);
} else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw") == 0) {
RC.ru[j]->if_south = LOCAL_RF;
RC.ru[j]->function = NGFI_RRU_IF5;
RC.ru[j]->eth_params.transp_preference = ETH_RAW_MODE;
printf("Setting function for RU %d to NGFI_RRU_IF5 (raw)\n",j);
LOG_I(PHY,"Setting function for RU %d to NGFI_RRU_IF5 (raw)\n",j);
} else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_if4p5") == 0) {
RC.ru[j]->if_south = LOCAL_RF;
RC.ru[j]->function = NGFI_RRU_IF4p5;
RC.ru[j]->eth_params.transp_preference = ETH_UDP_IF4p5_MODE;
printf("Setting function for RU %d to NGFI_RRU_IF4p5 (udp)\n",j);
RC.ru[j]->has_ctrl_prt =1;
LOG_I(PHY,"Setting function for RU %d to NGFI_RRU_IF4p5 (udp)\n",j);
} else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if4p5") == 0) {
RC.ru[j]->if_south = LOCAL_RF;
RC.ru[j]->function = NGFI_RRU_IF4p5;
RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE;
printf("Setting function for RU %d to NGFI_RRU_IF4p5 (raw)\n",j);
LOG_I(PHY,"Setting function for RU %d to NGFI_RRU_IF4p5 (raw)\n",j);
}
printf("RU %d is_slave=%s\n",j,*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr));
LOG_I(PHY,"RU %d is_slave=%s\n",j,*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr));
if (strcmp(*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr), "yes") == 0) RC.ru[j]->is_slave=1;
else RC.ru[j]->is_slave=0;
printf("RU %d ota_sync_enabled=%s\n",j,*(RUParamList.paramarray[j][RU_OTA_SYNC_ENABLE_IDX].strptr));
LOG_I(PHY,"RU %d ota_sync_enabled=%s\n",j,*(RUParamList.paramarray[j][RU_OTA_SYNC_ENABLE_IDX].strptr));
if (strcmp(*(RUParamList.paramarray[j][RU_OTA_SYNC_ENABLE_IDX].strptr), "yes") == 0) RC.ru[j]->ota_sync_enable=1;
else RC.ru[j]->ota_sync_enable=0;
@@ -3053,8 +3008,8 @@ void RCconfig_RU(void) {
for (i=0; i<RC.ru[j]->num_bands; i++) RC.ru[j]->band[i] = RUParamList.paramarray[j][RU_BAND_LIST_IDX].iptr[i];
} //strcmp(local_rf, "yes") == 0
else {
printf("RU %d: Transport %s\n",j,*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr));
else {
LOG_I(PHY,"RU %d: Transport %s\n",j,*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr));
RC.ru[j]->eth_params.local_if_name = strdup(*(RUParamList.paramarray[j][RU_LOCAL_IF_NAME_IDX].strptr));
RC.ru[j]->eth_params.my_addr = strdup(*(RUParamList.paramarray[j][RU_LOCAL_ADDRESS_IDX].strptr));
RC.ru[j]->eth_params.remote_addr = strdup(*(RUParamList.paramarray[j][RU_REMOTE_ADDRESS_IDX].strptr));
@@ -3062,34 +3017,34 @@ void RCconfig_RU(void) {
RC.ru[j]->eth_params.remote_portc = *(RUParamList.paramarray[j][RU_REMOTE_PORTC_IDX].uptr);
RC.ru[j]->eth_params.my_portd = *(RUParamList.paramarray[j][RU_LOCAL_PORTD_IDX].uptr);
RC.ru[j]->eth_params.remote_portd = *(RUParamList.paramarray[j][RU_REMOTE_PORTD_IDX].uptr);
if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp") == 0) {
RC.ru[j]->if_south = REMOTE_IF5;
RC.ru[j]->function = NGFI_RAU_IF5;
RC.ru[j]->eth_params.transp_preference = ETH_UDP_MODE;
RC.ru[j]->if_south = REMOTE_IF5;
RC.ru[j]->function = NGFI_RAU_IF5;
RC.ru[j]->eth_params.transp_preference = ETH_UDP_MODE;
} else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_ecpri_if5") == 0) {
RC.ru[j]->if_south = REMOTE_IF5;
RC.ru[j]->function = NGFI_RAU_IF5;
RC.ru[j]->eth_params.transp_preference = ETH_UDP_IF5_ECPRI_MODE;
} else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw") == 0) {
RC.ru[j]->if_south = REMOTE_IF5;
RC.ru[j]->function = NGFI_RAU_IF5;
RC.ru[j]->eth_params.transp_preference = ETH_RAW_MODE;
RC.ru[j]->if_south = REMOTE_IF5;
RC.ru[j]->function = NGFI_RAU_IF5;
RC.ru[j]->eth_params.transp_preference = ETH_RAW_MODE;
} else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_if4p5") == 0) {
RC.ru[j]->if_south = REMOTE_IF4p5;
RC.ru[j]->function = NGFI_RAU_IF4p5;
RC.ru[j]->eth_params.transp_preference = ETH_UDP_IF4p5_MODE;
RC.ru[j]->if_south = REMOTE_IF4p5;
RC.ru[j]->function = NGFI_RAU_IF4p5;
RC.ru[j]->eth_params.transp_preference = ETH_UDP_IF4p5_MODE;
RC.ru[j]->has_ctrl_prt = 1;
} else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if4p5") == 0) {
RC.ru[j]->if_south = REMOTE_IF4p5;
RC.ru[j]->function = NGFI_RAU_IF4p5;
RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE;
} else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if5_mobipass") == 0) {
RC.ru[j]->if_south = REMOTE_IF5;
RC.ru[j]->function = NGFI_RAU_IF5;
RC.ru[j]->if_timing = synch_to_other;
RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF5_MOBIPASS;
RC.ru[j]->if_south = REMOTE_IF4p5;
RC.ru[j]->function = NGFI_RAU_IF4p5;
RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE;
if (strcmp(*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr), "yes") == 0) RC.ru[j]->is_slave=1;
else RC.ru[j]->is_slave=0;
}
if (strcmp(*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr), "yes") == 0) RC.ru[j]->is_slave=1;
else RC.ru[j]->is_slave=0;
} /* strcmp(local_rf, "yes") != 0 */
RC.ru[j]->nb_tx = *(RUParamList.paramarray[j][RU_NB_TX_IDX].uptr);
RC.ru[j]->nb_rx = *(RUParamList.paramarray[j][RU_NB_RX_IDX].uptr);
RC.ru[j]->att_tx = *(RUParamList.paramarray[j][RU_ATT_TX_IDX].uptr);
+44 -18
View File
@@ -1,41 +1,67 @@
[*]
[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI
[*] Sun Jul 31 13:30:42 2016
[*] GTKWave Analyzer v3.3.66 (w)1999-2015 BSI
[*] Tue Sep 24 06:59:08 2019
[*]
[dumpfile] "/tmp/openair_dump_eNB.vcd"
[dumpfile_mtime] "Sun Jul 31 13:21:59 2016"
[dumpfile_size] 18273240
[savefile] "/home/fourmi/openairinterface5g/targets/RT/USER/rcc_if5.gtkw"
[timestart] 24070893000
[size] 1301 716
[pos] 309 0
*-19.793451 29026062100 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[sst_width] 284
[signals_width] 262
[dumpfile_mtime] "Mon Sep 23 20:04:56 2019"
[dumpfile_size] 1625759
[savefile] "/home/orange/aw2s/openairinterface5g/targets/RT/USER/rcc_if5.gtkw"
[timestart] 12600104000
[size] 1215 1000
[pos] 0 22
*-19.506693 12600920638 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[sst_width] 386
[signals_width] 344
[sst_expanded] 1
[sst_vpaned_height] 294
[sst_vpaned_height] 303
@29
functions.send_if5
@28
functions.recv_if5
@24
variables.trx_ts[63:0]
variables.trx_tst[63:0]
@28
functions.send_if5
functions.recv_if5
functions.eNB_thread_rxtx0
@24
variables.frame_number_RX0_RU[63:0]
variables.subframe_number_RX0_RU[63:0]
variables.frame_number_TX0_RU[63:0]
variables.subframe_number_TX0_RU[63:0]
@28
functions.mac_schedule_dlsch
functions.macxface_eNB_dlsch_ulsch_scheduler
functions.macxface_ue_scheduler
functions.phy_eNB_ofdm_mod_l
@24
variables.frame_number_RX0_eNB[63:0]
variables.subframe_number_RX0_eNB[63:0]
variables.frame_number_TX0_eNB[63:0]
variables.subframe_number_TX0_eNB[63:0]
@28
functions.eNB_thread_rxtx1
@24
variables.frame_number_RX1_eNB[63:0]
variables.subframe_number_RX1_eNB[63:0]
variables.frame_number_TX1_eNB[63:0]
variables.subframe_number_TX1_eNB[63:0]
@28
functions.phy_eNB_dlsch_modulation
functions.phy_eNB_dlsch_encoding
functions.phy_eNB_dlsch_scrambling
functions.phy_eNB_beam_precoding
functions.phy_enb_pdcch_tx
functions.phy_enb_prach_rx
functions.phy_procedures_ru_feprx0
functions.phy_procedures_eNb_rx_uespec0
functions.phy_procedures_eNb_rx_uespec1
functions.phy_enb_sfgen
functions.phy_procedures_eNb_tx0
functions.phy_procedures_eNb_tx1
functions.phy_procedures_ru_feprx1
functions.phy_procedures_ru_feptx_ofdm0
functions.phy_procedures_ru_feptx_ofdm1
functions.phy_procedures_ru_feptx_prec0
functions.phy_procedures_ru_feptx_prec1
functions.eNB_thread_rxtx1
functions.phy_enb_sfgen
functions.phy_eNB_slot_fep
functions.phy_enb_prach_rx
@24
variables.dci_info[63:0]
+1 -1
View File
@@ -524,7 +524,7 @@ void* ru_thread_control( void* param )
}
ru->state = (ru->function==eNodeB_3GPP)? RU_RUN : RU_IDLE;
ru->state = (ru->function==eNodeB_3GPP || ru->if_south == REMOTE_IF5)? RU_RUN : RU_IDLE;
LOG_I(PHY,"Control channel ON for RU %d\n", ru->idx);
while (!oai_exit) // Change the cond