Commit 53db39b8 authored by laurent's avatar laurent

split 7.3 ready for merge

parent 3d15918c
......@@ -1181,9 +1181,6 @@ set(SCHED_SRC
add_library(SCHED_LIB ${SCHED_SRC})
add_dependencies(SCHED_LIB rrc_flag)
add_library(SCHED_LIB_FS6 ${SCHED_SRC})
target_compile_definitions(SCHED_LIB_FS6 PRIVATE FS6=1)
add_dependencies(SCHED_LIB_FS6 rrc_flag)
set(SCHED_NR_SRC
${OPENAIR1_DIR}/SCHED_NR/fapi_nr_l1.c
${OPENAIR1_DIR}/SCHED_NR/phy_procedures_nr_common.c
......@@ -1563,8 +1560,6 @@ endif ()
add_library(PHY_COMMON ${PHY_SRC_COMMON})
add_dependencies(PHY_COMMON rrc_flag)
add_library(PHY ${PHY_SRC})
add_library(PHY_FS6 ${PHY_SRC})
target_compile_definitions(PHY_FS6 PRIVATE FS6=1)
add_dependencies(PHY rrc_flag)
add_library(PHY_UE ${PHY_SRC_UE})
......@@ -2485,13 +2480,11 @@ target_link_libraries (lte-softmodem ${T_LIB})
add_executable(ocp-softmodem
${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c
${OPENAIR_DIR}/executables/main-ocp.c
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
${OPENAIR_DIR}/executables/softmodem-common.c
${OPENAIR_DIR}/executables/main-fs6.c
${OPENAIR_DIR}/executables/transport_split.c
${OPENAIR_TARGETS}/RT/USER/lte-softmodem.c
${OPENAIR2_DIR}/ENB_APP/NB_IoT_interface.c
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
${OPENAIR_TARGETS}/COMMON/create_tasks.c
......@@ -2511,7 +2504,6 @@ add_executable(ocp-softmodem
${CONFIG_SOURCES}
${SHLIB_LOADER_SOURCES}
)
target_compile_definitions(ocp-softmodem PRIVATE FS6=1)
add_dependencies(ocp-softmodem rrc_flag s1ap_flag x2_flag)
target_link_libraries (ocp-softmodem
......
......@@ -243,6 +243,8 @@ void configure_linux(void) {
// Set CPU frequency to it's maximum
if ( 0 != system("for d in /sys/devices/system/cpu/cpu[0-9]*; do cat $d/cpufreq/cpuinfo_max_freq > $d/cpufreq/scaling_min_freq; done"))
LOG_W(HW,"Can't set cpu frequency\n");
LOG_E(HW,"Can't set cpu frequency\n");
mlockall(MCL_CURRENT | MCL_FUTURE);
}
......@@ -258,26 +258,22 @@ lte-softmodem.
The functionality and parameters is the same, enhanced with FS6 mode.
The environment variable “fs6” enables the fs6 mode and decided to be cu
or du from the fs6 variable content.
A example configuration file is: $OPENAIR_DIR/enb.fs6.example.conf
The IP addresses in this file should be updated for each network.
The end line option “--split73” enables the fs6 (also called split 7.3) mode and decided to be cu or du.
Example:
`fs6=cu ./ocp-softmodem -O $OPENAIR_DIR/enb.fs6.example.conf --rfsim --log_config.phy_log_level debug
./ocp-softmodem -O $OPENAIR_DIR/enb.fs6.example.conf --rfsim --log_config.phy_log_level debug --split73 cu:127.0.0.1
`
Run the CU init of the split 6 eNB, that will call du on 127.0.0.1 address
Run the CU init of the split 6 eNB.
./ocp-softmodem -O $OPENAIR_DIR/enb.fs6.example.conf --rfsim --log_config.phy_log_level debug --split73 du:127.0.0.1
`fs6=du ./ocp-softmodem -O $OPENAIR_DIR/enb.fs6.example.conf --rfsim --log_config.phy_log_level debug
will run the du, calling the cu on 127.0.0.1
`
If the CU and the DU are not on the same machine, the remote address of each side need to be specified as per this example
`fs6=du FS6_REMOTE_IP=192.168.2.211 ./ocp-softmodem -O $OPENAIR_DIR/enb.fs6.example.conf --rfsim --log_config.phy_log_level debug
./ocp-softmodem -O $OPENAIR_DIR/enb.fs6.example.conf --rfsim --log_config.phy_log_level debug --split73 du:192.168.1.55
`
runs the functional split 6 DU
`./lte-uesoftmodem -C 2685000000 -r 50 --rfsim --rfsimulator.serveraddr 192.168.1.1 -d
......@@ -285,10 +281,7 @@ runs the functional split 6 DU
Runs the UE (to have the UE signal scope, compile it with make uescope)
CU and DU IP address and port are configurable in the eNB configuration
file (as X2, GTP, … interfaces).
CU+DU+UE can run with option --noS1 to avoid to use a EPC.
CU+DU+UE can run with option --noS1 to avoid to use a EPC and/or with --rfsim to simulate RF board
##5G and F1
......
Active_eNBs = ( "eNB-Eurecom-LTEBox");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
eNBs =
(
{
////////// Identification parameters:
eNB_ID = 0xe00;
cell_type = "CELL_MACRO_ENB";
eNB_name = "eNB-Eurecom-LTEBox";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
tr_s_preference = "local_mac"
////////// Physical parameters:
component_carriers = (
{
node_function = "3GPP_eNODEB";
node_timing = "synch_to_ext_device";
node_synch_ref = 0;
frame_type = "FDD";
tdd_config = 3;
tdd_config_s = 0;
prefix_type = "NORMAL";
eutra_band = 7;
downlink_frequency = 2685000000L;
uplink_frequency_offset = -120000000;
Nid_cell = 0;
N_RB_DL = 50;
Nid_cell_mbsfn = 0;
nb_antenna_ports = 1;
nb_antennas_tx = 1;
nb_antennas_rx = 1;
tx_gain = 90;
rx_gain = 125;
pbch_repetition = "FALSE";
prach_root = 0;
prach_config_index = 0;
prach_high_speed = "DISABLE";
prach_zero_correlation = 1;
prach_freq_offset = 2;
pucch_delta_shift = 1;
pucch_nRB_CQI = 0;
pucch_nCS_AN = 0;
pucch_n1_AN = 0;
pdsch_referenceSignalPower = -27;
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 = -104;
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";
drx_Config_present = "prSetup"; //"prSetup" "prRelease"
drx_onDurationTimer = "psf1"; // "psfX": X=1,2,3,4,5,6,8,10,20,30,40,50,60,80,100
drx_InactivityTimer = "psf1"; // "psfX": X=1,2,3,4,5,6,8,10,20,30,40,50,60,80,100,200,300,500,750,1280,1920,2560
drx_RetransmissionTimer = "psf1"; // "psfX": X=1,2,4,6,8,16,24,33
drx_longDrx_CycleStartOffset_present = "prSf128"; // "psfX": X=10,20,32,40,64,80,128,160,256,320,512,640,1024,1280,2048,2560
drx_longDrx_CycleStartOffset = 0; // X >= 0 && X < drx_longDrx_CycleStartOffset_present
drx_shortDrx_Cycle = "sf16"; // "sfX": X=2,5,8,10,16,20,32,40,64,80,128,160,256,320,512,640
drx_shortDrx_ShortCycleTimer = 3; // 1..16 integer. Total duration in short cycle = drx_shortDrx_Cycle*drx_shortDrx_ShortCycleTimer [subframe]
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;
//Parameters for SIB18
rxPool_sc_CP_Len = "normal";
rxPool_sc_Period = "sf40";
rxPool_data_CP_Len = "normal";
rxPool_ResourceConfig_prb_Num = 20;
rxPool_ResourceConfig_prb_Start = 5;
rxPool_ResourceConfig_prb_End = 44;
rxPool_ResourceConfig_offsetIndicator_present = "prSmall";
rxPool_ResourceConfig_offsetIndicator_choice = 0;
rxPool_ResourceConfig_subframeBitmap_present = "prBs40";
rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000";
rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5;
rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0;
/* rxPool_dataHoppingConfig_hoppingParameter = 0;
rxPool_dataHoppingConfig_numSubbands = "ns1";
rxPool_dataHoppingConfig_rbOffset = 0;
rxPool_commTxResourceUC-ReqAllowed = "TRUE";
*/
// Parameters for SIB19
discRxPool_cp_Len = "normal"
discRxPool_discPeriod = "rf32"
discRxPool_numRetx = 1;
discRxPool_numRepetition = 2;
discRxPool_ResourceConfig_prb_Num = 5;
discRxPool_ResourceConfig_prb_Start = 3;
discRxPool_ResourceConfig_prb_End = 21;
discRxPool_ResourceConfig_offsetIndicator_present = "prSmall";
discRxPool_ResourceConfig_offsetIndicator_choice = 0;
discRxPool_ResourceConfig_subframeBitmap_present = "prBs40";
discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff";
discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5;
discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0;
}
);
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 = "127.0.0.20";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
enable_measurement_reports = "no";
///X2
enable_x2 = "no";
t_reloc_prep = 1000; /* unit: millisecond */
tx2_reloc_overall = 2000; /* unit: millisecond */
NETWORK_INTERFACES :
{
ENB_INTERFACE_NAME_FOR_S1_MME = "lo";
ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.10";
ENB_INTERFACE_NAME_FOR_S1U = "lo";
ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.10";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
ENB_IPV4_ADDRESS_FOR_X2C = "127.0.0.1";
ENB_PORT_FOR_X2C = 36422; # Spec 36422
};
}
);
MACRLCs = (
{
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
//scheduler_mode = "fairRR";
phy_test_mode = 0;
puSch10xSnr = 160;
puCch10xSnr = 160;
}
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
}
);
RUs = (
{
local_rf = "yes"
nb_tx = 1
nb_rx = 1
att_tx = 0
att_rx = 0;
bands = [7];
max_pdschReferenceSignalPower = -27;
max_rxgain = 108;
eNB_instances = [0];
}
);
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";
};
THREAD_STRUCT = (
{
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
parallel_config = "PARALLEL_SINGLE_THREAD";
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
worker_config = "WORKER_DISABLE";
}
);
#example config for rfsimulator
rfsimulator :
{
serveraddr = "enb";
serverport = "4043";
options = (); #("saviq");
modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs";
};
log_config :
{
global_log_level ="info";
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";
};
......@@ -165,16 +165,16 @@ void prach_eNB_tosplit(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *eNB, L1_r
}
ocp_rx_prach(eNB,
proc,
eNB->RU_list[0],
header->max_preamble,
header->max_preamble_energy,
header->max_preamble_delay,
header->avg_preamble_energy,
proc->frame_prach,
0,
false
);
proc,
eNB->RU_list[0],
header->max_preamble,
header->max_preamble_energy,
header->max_preamble_delay,
header->avg_preamble_energy,
proc->frame_prach,
0,
false
);
// run PRACH detection for CE-level 0 only for now when br_flag is set
/* fixme: seems not operational and may overwrite regular LTE prach detection
* OAI code can call is sequence
......@@ -513,15 +513,12 @@ void fill_rx_indication_from_split(uint8_t *bufferZone, PHY_VARS_eNB *eNB,int UE
nfapi_rx_indication_pdu_t *pdu;
int timing_advance_update;
uint32_t harq_pid;
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
if (eNB->ulsch[UE_id]->ue_type > 0) harq_pid = 0;
if (eNB->ulsch[UE_id]->ue_type > 0)
harq_pid = 0;
else
#endif
{
harq_pid = subframe2harq_pid (&eNB->frame_parms,
frame, subframe);
}
pthread_mutex_lock(&eNB->UL_INFO_mutex);
eNB->UL_INFO.rx_ind.sfn_sf = frame<<4| subframe;
......@@ -533,7 +530,7 @@ void fill_rx_indication_from_split(uint8_t *bufferZone, PHY_VARS_eNB *eNB,int UE
pdu->rx_indication_rel8.tl.tag = NFAPI_RX_INDICATION_REL8_TAG;
pdu->rx_indication_rel8.length = eNB->ulsch[UE_id]->harq_processes[harq_pid]->TBS>>3;
pdu->rx_indication_rel8.offset = 1; // DJP - I dont understand - but broken unless 1 ???? 0; // filled in at the end of the UL_INFO formation
pdu->data = eNB->ulsch[UE_id]->harq_processes[harq_pid]->b;
pdu->data = eNB->ulsch[UE_id]->harq_processes[harq_pid]->decodedBytes;
// estimate timing advance for MAC
timing_advance_update = ul_propa[UE_id].ta;
......@@ -662,7 +659,7 @@ void pusch_procedures_fromsplit(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *
} // for (i=0; i<NUMBER_OF_UE_MAX; i++)
while (proc->nbDecode > 0) {
notifiedFIFO_elt_t *req=pullTpool(&proc->respDecode, &proc->threadPool);
notifiedFIFO_elt_t *req=pullTpool(proc->respDecode, proc->threadPool);
postDecode(proc, req);
delNotifiedFIFO_elt(req);
}
......@@ -678,7 +675,7 @@ void recvFs6Ul(uint8_t *bufferZone, int nbBlocks, PHY_VARS_eNB *eNB, ul_propagat
if ( type == fs6ULsch) {
LTE_eNB_ULSCH_t *ulsch =eNB->ulsch[hULUE(bufPtr)->UE_id];
LTE_UL_eNB_HARQ_t *ulsch_harq=ulsch->harq_processes[hULUE(bufPtr)->harq_id];
memcpy(ulsch_harq->e+hULUE(bufPtr)->r_offset,
memcpy(ulsch_harq->eUL+hULUE(bufPtr)->r_offset,
hULUE(bufPtr)+1,
hULUE(bufPtr)->segLen);
memcpy(eNB->pusch_vars[hULUE(bufPtr)->UE_id]->ulsch_power,
......@@ -691,7 +688,7 @@ void recvFs6Ul(uint8_t *bufferZone, int nbBlocks, PHY_VARS_eNB *eNB, ul_propagat
sizeof(ulsch_harq->o_ACK));
memcpy(ulsch_harq->o,hULUE(bufPtr)->o, sizeof(ulsch_harq->o));
ul_propa[hULUE(bufPtr)->UE_id].ta=hULUE(bufPtr)->ta;
LOG_D(PHY,"Received ulsch data for: rnti:%x, cqi_crc_status %d O_ACK: %di, segment: %di, seglen: %d \n",
LOG_D(PHY,"Received ulsch data for: rnti:%x, cqi_crc_status %d O_ACK: %d, segment: %d, seglen: %d \n",
ulsch->rnti, ulsch_harq->cqi_crc_status, ulsch_harq->O_ACK,hULUE(bufPtr)->segment, hULUE(bufPtr)->segLen);
} else if ( type == fs6ULcch ) {
int nb_uci=hULUEuci(bufPtr)->nb_active_ue;
......@@ -771,10 +768,10 @@ void rcvFs6DL(uint8_t *bufferZone, int nbBlocks, PHY_VARS_eNB *eNB, int frame, i
dlsch0->i0=hDLUE(bufPtr)->i0;
dlsch0->sib1_br_flag=hDLUE(bufPtr)->sib1_br_flag;
#endif
fs6Dlunpack(dlsch_harq->e,
fs6Dlunpack(dlsch_harq->eDL,
hDLUE(bufPtr)+1, hDLUE(bufPtr)->dataLen);
LOG_D(PHY,"received %d bits, in harq id: %di fsf: %d.%d, sum %d\n",
hDLUE(bufPtr)->dataLen, hDLUE(bufPtr)->harq_pid, frame, subframe, sum(dlsch_harq->e, hDLUE(bufPtr)->dataLen));
hDLUE(bufPtr)->dataLen, hDLUE(bufPtr)->harq_pid, frame, subframe, sum(dlsch_harq->eDL, hDLUE(bufPtr)->dataLen));
} else if (type == fs6UlConfig) {
int nbUE=(((commonUDP_t *)bufPtr)->contentBytes - sizeof(fs6_dl_t)) / sizeof( fs6_dl_ulsched_t ) ;
#define cpyVal(a) memcpy(&ulsch_harq->a,&hTxULUE(bufPtr)->a, sizeof(ulsch_harq->a))
......@@ -1103,9 +1100,9 @@ void appendFs6DLUE(uint8_t *bufferZone, LTE_DL_FRAME_PARMS *fp, int UE_id, int8_
hDLUE(newUDPheader)->sib1_br_flag=dlsch0->sib1_br_flag;
#endif
hDLUE(newUDPheader)->dataLen=UEdataLen;
fs6Dlpack(hDLUE(newUDPheader)+1, harqData->e, UEdataLen);
fs6Dlpack(hDLUE(newUDPheader)+1, harqData->eDL, UEdataLen);
LOG_D(PHY,"sending %d bits, in harq id: %di fsf: %d.%d, sum %d\n",
UEdataLen, harq_pid, frame, subframe, sum(harqData->e, UEdataLen));
UEdataLen, harq_pid, frame, subframe, sum(harqData->eDL, UEdataLen));
//for (int i=0; i < UEdataLen; i++)
//LOG_D(PHY,"buffer ei[%d]:%hhx\n", i, ( (uint8_t *)(hDLUE(newUDPheader)+1) )[i]);
}
......@@ -1322,7 +1319,11 @@ void phy_procedures_eNB_TX_tosplit(uint8_t *bufferZone, PHY_VARS_eNB *eNB, L1_rx
void *DL_du_fs6(void *arg) {
RU_t *ru=(RU_t *)arg;
static uint64_t lastTS;
L1_rxtx_proc_t L1_proc= {0};
L1_rxtx_proc_t L1proc= {0};
// We pick the global thread pool from the legacy code global vars
L1proc.threadPool=RC.eNB[0][0]->proc.L1_proc.threadPool;
L1proc.respEncode=RC.eNB[0][0]->proc.L1_proc.respEncode;
L1proc.respDecode=RC.eNB[0][0]->proc.L1_proc.respDecode;
initStaticTime(begingWait);
initStaticTime(begingProcessing);
initRefTimes(fullLoop);
......@@ -1338,27 +1339,31 @@ void *DL_du_fs6(void *arg) {
updateTimesReset(begingWait, &fullLoop, 1000, false, "DU wait CU");
if (nb_blocks > 0) {
if ( lastTS+ru->eNB_list[i]->frame_parms.samples_per_tti != hUDP(bufferZone)->timestamp) {
if ( lastTS+ru->eNB_list[i]->frame_parms.samples_per_tti < hUDP(bufferZone)->timestamp) {
LOG_E(HW,"Missed a subframe: expecting: %lu, received %lu\n",
lastTS+ru->eNB_list[i]->frame_parms.samples_per_tti,
hUDP(bufferZone)->timestamp);
} else if ( lastTS+ru->eNB_list[i]->frame_parms.samples_per_tti > hUDP(bufferZone)->timestamp) {
LOG_E(HW,"Received a subframe in past time from CU (dropping it): expecting: %lu, received %lu\n",
lastTS+ru->eNB_list[i]->frame_parms.samples_per_tti,
hUDP(bufferZone)->timestamp);
}
pickStaticTime(begingProcessing);
lastTS=hUDP(bufferZone)->timestamp;
setAllfromTS(hUDP(bufferZone)->timestamp - sf_ahead*ru->eNB_list[i]->frame_parms.samples_per_tti, &L1_proc);
setAllfromTS(hUDP(bufferZone)->timestamp - sf_ahead*ru->eNB_list[i]->frame_parms.samples_per_tti, &L1proc);
measTransportTime(hDL(bufferZone)->DuClock, hDL(bufferZone)->CuSpentMicroSec,
&transportTime, 1000, false, "Transport time, to CU + from CU for one subframe");
phy_procedures_eNB_TX_fromsplit( bufferZone, nb_blocks, ru->eNB_list[i], &L1_proc, 1);
phy_procedures_eNB_TX_fromsplit( bufferZone, nb_blocks, ru->eNB_list[i], &L1proc, 1);
updateTimesReset(begingProcessing, &DuHigh, 1000, false, "DU high layer1 processing for DL");
} else
LOG_E(PHY,"DL not received for subframe\n");
}
pickStaticTime(begingProcessing);
feptx_prec(ru, L1_proc.frame_tx,L1_proc.subframe_tx );
feptx_ofdm(ru, L1_proc.frame_tx,L1_proc.subframe_tx );
ocp_tx_rf(ru, &L1_proc);
feptx_prec(ru, L1proc.frame_tx,L1proc.subframe_tx );
feptx_ofdm(ru, L1proc.frame_tx,L1proc.subframe_tx );
ocp_tx_rf(ru, &L1proc);
updateTimesReset(begingProcessing, &DuLow, 1000, false, "DU low layer1 processing for DL");
if ( IS_SOFTMODEM_RFSIM )
......@@ -1374,7 +1379,6 @@ void UL_du_fs6(RU_t *ru, L1_rxtx_proc_t *proc) {
pickStaticTime(begingWait);
rx_rf(ru, proc);
updateTimesReset(begingWait, &fullLoop, 1000, false, "DU wait USRP");
setAllfromTS(proc->timestamp_rx, proc);
// front end processing: convert from time domain to frequency domain
// fills rxdataF buffer
fep_full(ru, proc->subframe_rx);
......@@ -1480,23 +1484,22 @@ void *cu_fs6(void *arg) {
init_frame_parms(ru->frame_parms,1);
phy_init_RU(ru);
wait_sync("ru_thread");
char *remoteIP;
if ( getenv("FS6_REMOTE_IP") )
remoteIP=getenv("FS6_REMOTE_IP");
else
remoteIP=DU_IP;
AssertFatal(createUDPsock(NULL, CU_PORT, remoteIP, DU_PORT, &sockFS6), "");
char remoteIP[1024];
strncpy(remoteIP,get_softmodem_params()->split73+3, 1023); //three first char should be cu: or du:
char port_def[256]=DU_PORT;
for (int i=0; i <1000; i++)
if (remoteIP[i]==':') {
strncpy(port_def,remoteIP+i+1,255);
remoteIP[i]=0;
break;
}
AssertFatal(createUDPsock(NULL, CU_PORT, remoteIP, port_def, &sockFS6), "");
L1_rxtx_proc_t L1proc= {0};
if ( strlen(get_softmodem_params()->threadPoolConfig) > 0 )
initTpool(get_softmodem_params()->threadPoolConfig, &L1proc.threadPool, true);
else
initTpool("n", &L1proc.threadPool, true);
initNotifiedFIFO(&L1proc.respEncode);
initNotifiedFIFO(&L1proc.respDecode);
// We pick the global thread pool from the legacy code global vars
L1proc.threadPool=RC.eNB[0][0]->proc.L1_proc.threadPool;
L1proc.respEncode=RC.eNB[0][0]->proc.L1_proc.respEncode;
L1proc.respDecode=RC.eNB[0][0]->proc.L1_proc.respDecode;
uint64_t timeStamp=0;
initStaticTime(begingWait);
initStaticTime(begingWait2);
......@@ -1529,14 +1532,16 @@ void *du_fs6(void *arg) {
phy_init_RU(ru);
init_rf(ru);
wait_sync("ru_thread");
char *remoteIP;
if ( getenv("FS6_REMOTE_IP") )
remoteIP=getenv("FS6_REMOTE_IP");
else
remoteIP=CU_IP;
AssertFatal(createUDPsock(NULL, DU_PORT, remoteIP, CU_PORT, &sockFS6), "");
char remoteIP[1024];
strncpy(remoteIP,get_softmodem_params()->split73+3,1023); //three first char should be cu: or du:
char port_def[256]=CU_PORT;
for (int i=0; i <1000; i++)
if (remoteIP[i]==':') {
strncpy(port_def,remoteIP+i+1,255);
remoteIP[i]=0;
break;
}
AssertFatal(createUDPsock(NULL, DU_PORT, remoteIP, port_def, &sockFS6), "");
if (ru->rfdevice.trx_start_func(&ru->rfdevice) != 0)
LOG_E(HW,"Could not start the RF device\n");
......@@ -1551,8 +1556,13 @@ void *du_fs6(void *arg) {
if ( !IS_SOFTMODEM_RFSIM )
threadCreate(&t, DL_du_fs6, (void *)ru, "MainDuTx", -1, OAI_PRIORITY_RT_MAX);
while(oai_exit) {
L1_rxtx_proc_t L1proc;
L1_rxtx_proc_t L1proc= {0};
// We pick the global thread pool from the legacy code global vars
L1proc.threadPool=RC.eNB[0][0]->proc.L1_proc.threadPool;
L1proc.respEncode=RC.eNB[0][0]->proc.L1_proc.respEncode;
L1proc.respDecode=RC.eNB[0][0]->proc.L1_proc.respDecode;
while(!oai_exit) {
updateTimesReset(begingWait, &fullLoop, 1000, true,"DU for full SubFrame (must be less 1ms)");
pickStaticTime(begingWait);
UL_du_fs6(ru, &L1proc);
......@@ -1562,7 +1572,7 @@ void *du_fs6(void *arg) {
updateTimesReset(begingWait, &waitRxAndProcessingUL, 1000, true,"DU Time in wait Rx + Ul processing");
}
ru->rfdevice.trx_end_func(&ru->rfdevice);
LOG_I(PHY,"RU %d rf device stopped\n",ru->idx);
return NULL;
......
......@@ -5,8 +5,11 @@
/*
* This file replaces
* targets/RT/USER/lte-softmodem.c
* targets/RT/USER/rt_wrapper.c
* targets/RT/USER/lte-ru.c
* targets/RT/USER/lte-enb.c
* targets/RT/USER/ru_control.c
* openair1/SCHED/prach_procedures.c
* The merger of OpenAir central code to this branch
* should check if these 3 files are modified and analyze if code code has to be copied in here
......@@ -16,6 +19,7 @@
#include <common/utils/LOG/log.h>
#include <common/utils/system.h>
#include <common/utils/assertions.h>
static int DEFBANDS[] = {7};
static int DEFENBS[] = {0};
#include <common/config/config_userapi.h>
......@@ -30,8 +34,33 @@ static int DEFENBS[] = {0};
#include <nfapi/oai_integration/nfapi_pnf.h>
#include <executables/split_headers.h>
#include <common/utils/threadPool/thread-pool.h>
extern uint16_t sf_ahead;
#include <openair2/ENB_APP/NB_IoT_interface.h>
#include <common/utils/load_module_shlib.h>
#include <targets/COMMON/create_tasks.h>
#include <openair1/PHY/TOOLS/phy_scope_interface.h>
#include <openair2/UTIL/OPT/opt.h>
#include <openair1/SIMULATION/TOOLS/sim.h>
#include <openair1/PHY/phy_vars.h>
#include <openair1/SCHED/sched_common_vars.h>
#include <openair2/LAYER2/MAC/mac_vars.h>
#include <openair2/RRC/LTE/rrc_vars.h>
pthread_cond_t nfapi_sync_cond;
pthread_mutex_t nfapi_sync_mutex;
int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex
pthread_cond_t sync_cond;
pthread_mutex_t sync_mutex;
int sync_var=-1; //!< protected by mutex \ref sync_mutex.
int config_sync_var=-1;
volatile int oai_exit = 0;
double cpuf;
uint16_t sf_ahead=4;
int otg_enabled;
uint32_t downlink_frequency[MAX_NUM_CCs][4];
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
int split73;
char * split73_config;
int split73;
static void *ru_thread( void *param );
void kill_RU_proc(RU_t *ru) {
......@@ -42,6 +71,34 @@ void free_transport(PHY_VARS_eNB *eNB) {
}
void reset_opp_meas(void) {
}
extern void phy_free_RU(RU_t *);
void exit_function(const char *file, const char *function, const int line, const char *s) {
if (s != NULL) {
printf("%s:%d %s() Exiting OAI softmodem: %s\n",file,line, function, s);
}
close_log_mem();
oai_exit = 1;
if (RC.ru == NULL)
exit(-1); // likely init not completed, prevent crash or hang, exit now...
for (int ru_id=0; ru_id<RC.nb_RU; ru_id++) {
if (RC.ru[ru_id] && RC.ru[ru_id]->rfdevice.trx_end_func) {
RC.ru[ru_id]->rfdevice.trx_end_func(&RC.ru[ru_id]->rfdevice);
RC.ru[ru_id]->rfdevice.trx_end_func = NULL;
}
if (RC.ru[ru_id] && RC.ru[ru_id]->ifdevice.trx_end_func) {
RC.ru[ru_id]->ifdevice.trx_end_func(&RC.ru[ru_id]->ifdevice);
RC.ru[ru_id]->ifdevice.trx_end_func = NULL;
}
}
sleep(1); //allow lte-softmodem threads to exit first
exit(1);
}
// Fixme: there are many mistakes in the datamodel and in redondant variables
// TDD is also mode complex
......@@ -67,92 +124,47 @@ void setAllfromTS(uint64_t TS, L1_rxtx_proc_t *proc) {
return;
}
void init_eNB_proc(int inst) {
/*int i=0;*/
int CC_id;
PHY_VARS_eNB *eNB;
for (CC_id=0; CC_id<RC.nb_CC[inst]; CC_id++) {
eNB = RC.eNB[inst][CC_id];
pthread_mutex_init( &eNB->UL_INFO_mutex, NULL);
}
//for multiple CCs: setup master and slaves
/*
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
eNB = PHY_vars_eNB_g[inst][CC_id];
if (eNB->node_timing == synch_to_ext_device) { //master
proc->num_slaves = MAX_NUM_CCs-1;
proc->slave_proc = (L1_proc_t**)malloc(proc->num_slaves*sizeof(L1_proc_t*));
for (i=0; i< eNB->proc.num_slaves; i++) {
if (i < CC_id) eNB->proc.slave_proc[i] = &(PHY_vars_eNB_g[inst][i]->proc);
if (i >= CC_id) eNB->proc.slave_proc[i] = &(PHY_vars_eNB_g[inst][i+1]->proc);
}
}
}
*/
}
void init_RU_proc(RU_t *ru) {
pthread_t t;
char *fs6=getenv("fs6");
if (fs6) {
if ( strncasecmp(fs6,"cu", 2) == 0 )
threadCreate(&t, cu_fs6, (void *)ru, "MainCu", -1, OAI_PRIORITY_RT_MAX);
else if ( strncasecmp(fs6,"du", 2) == 0 ) {
threadCreate(&t, du_fs6, (void *)ru, "MainDuRx", -1, OAI_PRIORITY_RT_MAX);
} else
AssertFatal(false, "environement variable fs6 is not cu or du");
} else
switch(split73) {
case SPLIT73_CU:
threadCreate(&t, cu_fs6, (void *)ru, "MainCu", -1, OAI_PRIORITY_RT_MAX);
break;
case SPLIT73_DU:
threadCreate(&t, du_fs6, (void *)ru, "MainDuRx", -1, OAI_PRIORITY_RT_MAX);
break;
default:
threadCreate(&t, ru_thread, (void *)ru, "MainRu", -1, OAI_PRIORITY_RT_MAX);
}
}
// Create per UE structures
void init_transport(PHY_VARS_eNB *eNB) {
int i;
int j;
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
LOG_I(PHY, "Initialise transport\n");
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
for (int i=0; i<NUMBER_OF_UE_MAX; i++) {
LOG_D(PHY,"Allocating Transport Channel Buffers for DLSCH, UE %d\n",i);
for (j=0; j<2; j++) {
eNB->dlsch[i][j] = new_eNB_dlsch(1,8,NSOFT,fp->N_RB_DL,0,fp);
if (!eNB->dlsch[i][j]) {
LOG_E(PHY,"Can't get eNB dlsch structures for UE %d \n", i);
exit(-1);
} else {
eNB->dlsch[i][j]->rnti=0;
LOG_D(PHY,"dlsch[%d][%d] => %p rnti:%d\n",i,j,eNB->dlsch[i][j], eNB->dlsch[i][j]->rnti);
}
for (int j=0; j<2; j++) {
AssertFatal( (eNB->dlsch[i][j] = new_eNB_dlsch(1,8,NSOFT,fp->N_RB_DL,0,fp)) != NULL,
"Can't get eNB dlsch structures for UE %d \n", i);
eNB->dlsch[i][j]->rnti=0;
LOG_D(PHY,"dlsch[%d][%d] => %p rnti:%d\n",i,j,eNB->dlsch[i][j], eNB->dlsch[i][j]->rnti);
}
LOG_D(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n",i);
eNB->ulsch[1+i] = new_eNB_ulsch(MAX_TURBO_ITERATIONS,fp->N_RB_UL, 0);
if (!eNB->ulsch[1+i]) {
LOG_E(PHY,"Can't get eNB ulsch structures\n");
exit(-1);
}
AssertFatal((eNB->ulsch[1+i] = new_eNB_ulsch(MAX_TURBO_ITERATIONS,fp->N_RB_UL, 0)) != NULL,
"Can't get eNB ulsch structures\n");
// this is the transmission mode for the signalling channels
// this will be overwritten with the real transmission mode by the RRC once the UE is connected
eNB->transmission_mode[i] = fp->nb_antenna_ports_eNB==1 ? 1 : 2;
}
// ULSCH for RA
eNB->ulsch[0] = new_eNB_ulsch(MAX_TURBO_ITERATIONS, fp->N_RB_UL, 0);
if (!eNB->ulsch[0]) {
LOG_E(PHY,"Can't get eNB ulsch structures\n");
exit(-1);
}
AssertFatal( (eNB->ulsch[0] = new_eNB_ulsch(MAX_TURBO_ITERATIONS, fp->N_RB_UL, 0)) !=NULL,
"Can't get eNB ulsch structures\n");
eNB->dlsch_SI = new_eNB_dlsch(1,8,NSOFT,fp->N_RB_DL, 0, fp);
LOG_D(PHY,"eNB %d.%d : SI %p\n",eNB->Mod_id,eNB->CC_id,eNB->dlsch_SI);
eNB->dlsch_ra = new_eNB_dlsch(1,8,NSOFT,fp->N_RB_DL, 0, fp);
......@@ -161,7 +173,7 @@ void init_transport(PHY_VARS_eNB *eNB) {
LOG_D(PHY,"eNB %d.%d : MCH %p\n",eNB->Mod_id,eNB->CC_id,eNB->dlsch_MCH);
eNB->rx_total_gain_dB=130;
for(i=0; i<NUMBER_OF_UE_MAX; i++)
for(int i=0; i<NUMBER_OF_UE_MAX; i++)
eNB->mu_mimo_mode[i].dl_pow_off = 2;
eNB->check_for_total_transmissions = 0;
......@@ -172,23 +184,19 @@ void init_transport(PHY_VARS_eNB *eNB) {
}
void init_eNB_afterRU(void) {
int inst,CC_id,ru_id,i,aa;
PHY_VARS_eNB *eNB;
for (inst=0; inst<RC.nb_inst; inst++) {
for (CC_id=0; CC_id<RC.nb_CC[inst]; CC_id++) {
eNB = RC.eNB[inst][CC_id];
for (int inst=0; inst<RC.nb_inst; inst++) {
for (int CC_id=0; CC_id<RC.nb_CC[inst]; CC_id++) {
PHY_VARS_eNB *eNB = RC.eNB[inst][CC_id];
phy_init_lte_eNB(eNB,0,0);
eNB->frame_parms.nb_antennas_rx = 0;
eNB->frame_parms.nb_antennas_tx = 0;
eNB->prach_vars.rxsigF[0] = (int16_t **)malloc16(64*sizeof(int16_t *));
for (int ce_level=0; ce_level<4; ce_level++) {
LOG_I(PHY,"Overwriting eNB->prach_vars_br.rxsigF.rxsigF[0]:%p\n", eNB->prach_vars_br.rxsigF[ce_level]);
eNB->prach_vars_br.rxsigF[ce_level] = (int16_t **)malloc16(64*sizeof(int16_t *));
}
for (ru_id=0,aa=0; ru_id<eNB->num_RU; ru_id++) {
for (int 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;
eNB->frame_parms.nb_antennas_tx += eNB->RU_list[ru_id]->nb_tx;
AssertFatal(eNB->RU_list[ru_id]->common.rxdataF!=NULL,
......@@ -198,7 +206,7 @@ void init_eNB_afterRU(void) {
"RU %d : prach_rxsigF is NULL\n",
eNB->RU_list[ru_id]->idx);
for (i=0; i<eNB->RU_list[ru_id]->nb_rx; aa++,i++) {
for (int i=0; i<eNB->RU_list[ru_id]->nb_rx; aa++,i++) {
LOG_I(PHY,"Attaching RU %d antenna %d to eNB antenna %d\n",eNB->RU_list[ru_id]->idx,i,aa);
eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[ru_id]->prach_rxsigF[i];
......@@ -209,35 +217,24 @@ void init_eNB_afterRU(void) {
}
}
/* TODO: review this code, there is something wrong.
* In monolithic mode, we come here with nb_antennas_rx == 0
* (not tested in other modes).
*/
AssertFatal( eNB->frame_parms.nb_antennas_rx > 0 && eNB->frame_parms.nb_antennas_rx < 4, "");
AssertFatal( eNB->frame_parms.nb_antennas_tx > 0 && eNB->frame_parms.nb_antennas_rx < 4, "");
LOG_I(PHY,"inst %d, CC_id %d : nb_antennas_rx %d\n",inst,CC_id,eNB->frame_parms.nb_antennas_rx);
init_transport(eNB);
//init_precoding_weights(RC.eNB[inst][CC_id]);
}
init_eNB_proc(inst);
}
}
void init_eNB(int single_thread_flag,int wait_for_sync) {
int CC_id;
int inst;
PHY_VARS_eNB *eNB;
AssertFatal(RC.eNB != NULL,"RC.eNB must have been allocated\n");
if (RC.eNB == NULL) RC.eNB = (PHY_VARS_eNB ** *) malloc(RC.nb_L1_inst*sizeof(PHY_VARS_eNB **));
for (int inst=0; inst<RC.nb_L1_inst; inst++) {
AssertFatal(RC.eNB[inst] != NULL,"RC.eNB[%d] must have been allocated\n", inst);
for (inst=0; inst<RC.nb_L1_inst; inst++) {
if (RC.eNB[inst] == NULL) RC.eNB[inst] = (PHY_VARS_eNB **) malloc(RC.nb_CC[inst]*sizeof(PHY_VARS_eNB *));
for (CC_id=0; CC_id<RC.nb_L1_CC[inst]; CC_id++) {
if (RC.eNB[inst][CC_id] == NULL) RC.eNB[inst][CC_id] = (PHY_VARS_eNB *) malloc(sizeof(PHY_VARS_eNB));
eNB = RC.eNB[inst][CC_id];
for (int CC_id=0; CC_id<RC.nb_L1_CC[inst]; CC_id++) {
AssertFatal(RC.eNB[inst][CC_id] != NULL,"RC.eNB[%d][%d] must have been allocated\n", inst, CC_id);
PHY_VARS_eNB *eNB = RC.eNB[inst][CC_id];
eNB->abstraction_flag = 0;
eNB->single_thread_flag = single_thread_flag;
AssertFatal((eNB->if_inst = IF_Module_init(inst))!=NULL,"Cannot register interface");
......@@ -245,6 +242,7 @@ void init_eNB(int single_thread_flag,int wait_for_sync) {
eNB->if_inst->PHY_config_req = phy_config_request;
memset((void *)&eNB->UL_INFO,0,sizeof(eNB->UL_INFO));
memset((void *)&eNB->Sched_INFO,0,sizeof(eNB->Sched_INFO));
pthread_mutex_init( &eNB->UL_INFO_mutex, NULL);
LOG_I(PHY,"Setting indication lists\n");
eNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list = eNB->rx_pdu_list;
eNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list = eNB->crc_pdu_list;
......@@ -381,7 +379,6 @@ int setup_RU_buffers(RU_t *ru) {
return(0);
}
void init_precoding_weights(PHY_VARS_eNB *eNB) {
int layer,ru_id,aa,re,ue,tb;
LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
......@@ -416,21 +413,21 @@ void init_precoding_weights(PHY_VARS_eNB *eNB) {
}
void ocp_rx_prach(PHY_VARS_eNB *eNB,
L1_rxtx_proc_t *proc,
RU_t *ru,
uint16_t *max_preamble,
uint16_t *max_preamble_energy,
uint16_t *max_preamble_delay,
uint16_t *avg_preamble_energy,
uint16_t Nf,
uint8_t tdd_mapindex,
uint8_t br_flag) {
L1_rxtx_proc_t *proc,
RU_t *ru,
uint16_t *max_preamble,
uint16_t *max_preamble_energy,
uint16_t *max_preamble_delay,
uint16_t *avg_preamble_energy,
uint16_t Nf,
uint8_t tdd_mapindex,
uint8_t br_flag) {
int i;
int prach_mask=0;
if (br_flag == 0) {
rx_prach0(eNB,ru,proc->frame_prach, proc->subframe_prach,
max_preamble,max_preamble_energy,max_preamble_delay,avg_preamble_energy,Nf,tdd_mapindex,0,0);
max_preamble,max_preamble_energy,max_preamble_delay,avg_preamble_energy,Nf,tdd_mapindex,0,0);
} else { // This is procedure for eMTC, basically handling the repetitions
prach_mask = is_prach_subframe(&eNB->frame_parms,proc->frame_prach_br,proc->subframe_prach_br);
......@@ -445,7 +442,7 @@ void ocp_rx_prach(PHY_VARS_eNB *eNB,
eNB->prach_vars_br.repetition_number[i]++;
// do basic PRACH reception
rx_prach0(eNB,ru,proc->frame_prach, proc->subframe_prach_br,
max_preamble,max_preamble_energy,max_preamble_delay,avg_preamble_energy,Nf,tdd_mapindex,1,i);
max_preamble,max_preamble_energy,max_preamble_delay,avg_preamble_energy,Nf,tdd_mapindex,1,i);
// if last repetition, clear counter
if (eNB->prach_vars_br.repetition_number[i] == eNB->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[i]) {
......@@ -477,16 +474,16 @@ void prach_procedures_ocp(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc, int br_flag)
// run PRACH detection for CE-level 0 only for now when br_flag is set
ocp_rx_prach(eNB,
proc,
eNB->RU_list[0],
&max_preamble[0],
&max_preamble_energy[0],
&max_preamble_delay[0],
&avg_preamble_energy[0],
proc->frame_prach,
0
,br_flag
);
proc,
eNB->RU_list[0],
&max_preamble[0],
&max_preamble_energy[0],
&max_preamble_delay[0],
&avg_preamble_energy[0],
proc->frame_prach,
0
,br_flag
);
LOG_D(PHY,"RACH detection index 0: max preamble: %u, energy: %u, delay: %u, avg energy: %u\n",
max_preamble[0],
max_preamble_energy[0],
......@@ -531,7 +528,7 @@ void prach_procedures_ocp(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc, int br_flag)
/*
ind++;
}
} */// ce_level
} */// ce_level
} else if ((eNB->prach_energy_counter == 100) &&
(max_preamble_energy[0] > eNB->measurements.prach_I0+eNB->prach_DTX_threshold)) {
LOG_I(PHY,"[eNB %d/%d][RAPROC] Frame %d, subframe %d Initiating RA procedure with preamble %d, energy %d.%d dB, delay %d\n",
......@@ -616,13 +613,6 @@ static inline int rxtx(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, char *thread_name
return(0);
}
void eNB_top(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc, int dummy1, int dummy2, char *string,RU_t *ru) {
if (!oai_exit) {
if (rxtx(eNB,proc,string) < 0)
LOG_E(PHY,"eNB %d CC_id %d failed during execution\n",eNB->Mod_id,eNB->CC_id);
}
}
void rx_rf(RU_t *ru, L1_rxtx_proc_t *proc) {
LTE_DL_FRAME_PARMS *fp = ru->frame_parms;
void *rxp[ru->nb_rx];
......@@ -728,42 +718,36 @@ void ocp_tx_rf(RU_t *ru, L1_rxtx_proc_t *proc) {
static void *ru_thread( void *param ) {
setbuf(stdout, NULL);
setbuf(stderr, NULL);
RU_t *ru = (RU_t *)param;
RU_t *ru = (RU_t *)param;
L1_rxtx_proc_t L1proc= {0};
L1_rxtx_proc_t *proc=&L1proc;
if ( strlen(get_softmodem_params()->threadPoolConfig) > 0 )
initTpool(get_softmodem_params()->threadPoolConfig, &L1proc.threadPool, true);
else
initTpool("n", &L1proc.threadPool, true);
initNotifiedFIFO(&L1proc.respEncode);
initNotifiedFIFO(&L1proc.respDecode);
// We pick the global thread pool from the legacy code global vars
L1proc.threadPool=RC.eNB[0][0]->proc.L1_proc.threadPool;
L1proc.respEncode=RC.eNB[0][0]->proc.L1_proc.respEncode;
L1proc.respDecode=RC.eNB[0][0]->proc.L1_proc.respDecode;
if (ru->if_south == LOCAL_RF) { // configure RF parameters only
fill_rf_config(ru,ru->rf_config_file);
init_frame_parms(ru->frame_parms,1);
phy_init_RU(ru);
init_rf(ru);
}
AssertFatal(setup_RU_buffers(ru)==0, "Exiting, cannot initialize RU Buffers\n");
LOG_I(PHY, "Signaling main thread that RU %d is ready\n",ru->idx);
wait_sync("ru_thread");
// Start RF device if any
if (ru->rfdevice.trx_start_func(&ru->rfdevice) != 0)
LOG_E(HW,"Could not start the RF device\n");
else LOG_I(PHY,"RU %d rf device ready\n",ru->idx);
// This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices
while (!oai_exit) {
// synchronization on input FH interface, acquire signals/data and block
rx_rf(ru, proc);
rx_rf(ru, &L1proc);
// do RX front-end processing (frequency-shift, dft) if needed
fep_full(ru, proc->subframe_rx);
fep_full(ru, L1proc.subframe_rx);
// At this point, all information for subframe has been received on FH interface
// If this proc is to provide synchronization, do so
// Fixme: not used
......@@ -771,24 +755,23 @@ static void *ru_thread( void *param ) {
for (int i=0; i<ru->num_eNB; i++) {
char string[20];
sprintf(string,"Incoming RU %d",ru->idx);
eNB_top(ru->eNB_list[i],proc, proc->frame_rx,proc->subframe_rx,string,ru);
if (rxtx(ru->eNB_list[i],&L1proc,string) < 0)
LOG_E(PHY,"eNB %d CC_id %d failed during execution\n",
ru->eNB_list[i]->Mod_id,ru->eNB_list[i]->CC_id);
}
// do TX front-end processing if needed (precoding and/or IDFTs)
feptx_prec(ru, proc->frame_tx, proc->subframe_tx);
feptx_prec(ru, L1proc.frame_tx, L1proc.subframe_tx);
// do OFDM if needed
feptx_ofdm(ru, proc->frame_tx, proc->subframe_tx);
feptx_ofdm(ru, L1proc.frame_tx, L1proc.subframe_tx);
// do outgoing fronthaul (south) if needed
ocp_tx_rf(ru, proc);
ocp_tx_rf(ru, &L1proc);
}
LOG_W(PHY,"Exiting ru_thread \n");
ru->rfdevice.trx_end_func(&ru->rfdevice);
LOG_I(PHY,"RU %d rf device stopped\n",ru->idx);
return NULL;
}
......@@ -801,34 +784,24 @@ int init_rf(RU_t *ru) {
return ret;
}
void set_function_spec_param(RU_t *ru) {
}
//extern void RCconfig_RU(void);
void init_RU(char *rf_config_file, clock_source_t clock_source,clock_source_t time_source,int send_dmrssync) {
int ru_id;
RU_t *ru;
PHY_VARS_eNB *eNB0= (PHY_VARS_eNB *)NULL;
int i;
int CC_id;
// create status mask
pthread_mutex_init(&RC.ru_mutex,NULL);
pthread_cond_init(&RC.ru_cond,NULL);
// read in configuration file)
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());
if (RC.nb_CC != 0)
for (i=0; i<RC.nb_L1_inst; i++)
for (CC_id=0; CC_id<RC.nb_CC[i]; CC_id++) RC.eNB[i][CC_id]->num_RU=0;
for (CC_id=0; CC_id<RC.nb_CC[i]; CC_id++)
RC.eNB[i][CC_id]->num_RU=0;
LOG_D(PHY,"Process RUs RC.nb_RU:%d\n",RC.nb_RU);
for (ru_id=0; ru_id<RC.nb_RU; ru_id++) {
for (int ru_id=0; ru_id<RC.nb_RU; ru_id++) {
LOG_D(PHY,"Process RC.ru[%d]\n",ru_id);
ru = RC.ru[ru_id];
ru->rf_config_file = rf_config_file;
......@@ -862,43 +835,23 @@ void init_RU(char *rf_config_file, clock_source_t clock_source,clock_source_t ti
if (ru->num_eNB > 0) {
LOG_D(PHY, "%s() RC.ru[%d].num_eNB:%d ru->eNB_list[0]:%p RC.eNB[0][0]:%p rf_config_file:%s\n",
__FUNCTION__, ru_id, ru->num_eNB, ru->eNB_list[0], RC.eNB[0][0], ru->rf_config_file);
if (ru->eNB_list[0] == 0) {
LOG_E(PHY,"%s() DJP - ru->eNB_list ru->num_eNB are not initialized - so do it manually\n",
__FUNCTION__);
ru->eNB_list[0] = RC.eNB[0][0];
ru->num_eNB=1;
//
// DJP - feptx_prec() / feptx_ofdm() parses the eNB_list (based on num_eNB) and copies the txdata_F to txdata in RU
//
} else {
LOG_E(PHY,"DJP - delete code above this %s:%d\n", __FILE__, __LINE__);
}
AssertFatal(ru->eNB_list[0], "ru->eNB_list is not initialized\n");
} else {
LOG_E(PHY,"Wrong data model, assigning eNB 0, carrier 0 to RU 0\n");
ru->eNB_list[0] = RC.eNB[0][0];
ru->num_eNB=1;
}
eNB0 = ru->eNB_list[0];
LOG_D(PHY, "RU FUnction:%d ru->if_south:%d\n", ru->function, ru->if_south);
LOG_D(PHY, "eNB0:%p\n", eNB0);
if (eNB0) {
LOG_I(PHY,"Copying frame parms from eNB %d to ru %d\n",eNB0->Mod_id,ru->idx);
ru->frame_parms=&eNB0->frame_parms;
// datamodel error in regular OAI: a RU uses one single eNB carrier parameters!
ru->frame_parms = &eNB0->frame_parms;
for (i=0; i<ru->num_eNB; i++) {
eNB0 = ru->eNB_list[i];
eNB0->RU_list[eNB0->num_RU++] = ru;
}
for (i=0; i<ru->num_eNB; i++) {
eNB0 = ru->eNB_list[i];
int ruIndex=eNB0->num_RU++;
eNB0->RU_list[ruIndex] = ru;
}
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);
LOG_I(PHY,"Starting ru_thread %d\n",ru_id);
init_RU_proc(ru);
} // for ru_id
// sleep(1);
LOG_D(HW,"[lte-softmodem.c] RU threads created\n");
}
void stop_RU(int nb_ru) {
......@@ -912,20 +865,25 @@ void stop_RU(int nb_ru) {
/* from here function to use configuration module */
static int DEFBFW[] = {0x00007fff};
void RCconfig_RU(void) {
int j = 0;
int i = 0;
paramdef_t RUParams[] = RUPARAMS_DESC;
paramlist_def_t RUParamList = {CONFIG_STRING_RU_LIST,NULL,0};
config_getlist( &RUParamList,RUParams,sizeof(RUParams)/sizeof(paramdef_t), NULL);
if ( RUParamList.numelt == 0 ) {
if ( RUParamList.numelt == 0 ) {
LOG_W(PHY, "Calling RCconfig_RU while no ru\n");
RC.nb_RU = 0;
return;
} // setting != NULL
if ( RC.ru != NULL ) {
LOG_W(PHY, "Calling RCconfig_RU twice (nb ru=%d), ignoring the second call data structure is %p\n",
RUParamList.numelt,RC.ru);
return;
}
RC.ru = (RU_t **)malloc(RC.nb_RU*sizeof(RU_t *));
for (j = 0; j < RC.nb_RU; j++) {
for (int j = 0; j < RC.nb_RU; j++) {
RC.ru[j] = (RU_t *)calloc(sizeof(RU_t), 1);
RC.ru[j]->idx = j;
LOG_I(PHY,"Creating RC.ru[%d]:%p\n", j, RC.ru[j]);
......@@ -937,7 +895,7 @@ void RCconfig_RU(void) {
else
RC.ru[j]->num_eNB = 0;
for (i=0; i<RC.ru[j]->num_eNB; i++)
for (int i=0; i<RC.ru[j]->num_eNB; i++)
RC.ru[j]->eNB_list[i] = RC.eNB[vals[RU_ENB_LIST_IDX].iptr[i]][0];
if (config_isparamset(vals, RU_SDR_ADDRS)) {
......@@ -981,7 +939,7 @@ void RCconfig_RU(void) {
RC.ru[j]->sf_extension = *(vals[RU_SF_EXTENSION_IDX].uptr);
RC.ru[j]->end_of_burst_delay = *(vals[RU_END_OF_BURST_DELAY_IDX].uptr);
for (i=0; i<RC.ru[j]->num_bands; i++) RC.ru[j]->band[i] = vals[RU_BAND_LIST_IDX].iptr[i];
for (int i=0; i<RC.ru[j]->num_bands; i++) RC.ru[j]->band[i] = vals[RU_BAND_LIST_IDX].iptr[i];
} else {
LOG_I(PHY,"RU %d: Transport %s\n",j,*(vals[RU_TRANSPORT_PREFERENCE_IDX].strptr));
RC.ru[j]->eth_params.local_if_name = strdup(*(vals[RU_LOCAL_IF_NAME_IDX].strptr));
......@@ -1001,3 +959,430 @@ void RCconfig_RU(void) {
return;
}
static void get_options(void) {
CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP);
get_common_options();
CONFIG_CLEARRTFLAG(CONFIG_NOEXITONHELP);
if ( !(CONFIG_ISFLAGSET(CONFIG_ABORT)) ) {
memset((void *)&RC,0,sizeof(RC));
/* Read RC configuration file */
RCConfig();
NB_eNB_INST = RC.nb_inst;
printf("Configuration: nb_rrc_inst %d, nb_L1_inst %d, nb_ru %d\n",NB_eNB_INST,RC.nb_L1_inst,RC.nb_RU);
if (!IS_SOFTMODEM_NONBIOT) {
load_NB_IoT();
printf(" nb_nbiot_rrc_inst %d, nb_nbiot_L1_inst %d, nb_nbiot_macrlc_inst %d\n",
RC.nb_nb_iot_rrc_inst, RC.nb_nb_iot_L1_inst, RC.nb_nb_iot_macrlc_inst);
} else {
printf("All Nb-IoT instances disabled\n");
RC.nb_nb_iot_rrc_inst=RC.nb_nb_iot_L1_inst=RC.nb_nb_iot_macrlc_inst=0;
}
}
}
void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) {
int CC_id;
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
frame_parms[CC_id] = (LTE_DL_FRAME_PARMS *) malloc(sizeof(LTE_DL_FRAME_PARMS));
/* Set some default values that may be overwritten while reading options */
frame_parms[CC_id]->frame_type = FDD;
frame_parms[CC_id]->tdd_config = 3;
frame_parms[CC_id]->tdd_config_S = 0;
frame_parms[CC_id]->N_RB_DL = 100;
frame_parms[CC_id]->N_RB_UL = 100;
frame_parms[CC_id]->Ncp = NORMAL;
frame_parms[CC_id]->Ncp_UL = NORMAL;
frame_parms[CC_id]->Nid_cell = 0;
frame_parms[CC_id]->num_MBSFN_config = 0;
frame_parms[CC_id]->nb_antenna_ports_eNB = 1;
frame_parms[CC_id]->nb_antennas_tx = 1;
frame_parms[CC_id]->nb_antennas_rx = 1;
frame_parms[CC_id]->nushift = 0;
frame_parms[CC_id]->phich_config_common.phich_resource = oneSixth;
frame_parms[CC_id]->phich_config_common.phich_duration = normal;
// UL RS Config
frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift = 0;//n_DMRS1 set to 0
frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 0;
frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0;
frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0;
frame_parms[CC_id]->prach_config_common.rootSequenceIndex=22;
frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig=1;
frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_ConfigIndex=0;
frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.highSpeedFlag=0;
frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_FreqOffset=0;
// downlink_frequency[CC_id][0] = 2680000000; // Use float to avoid issue with frequency over 2^31.
// downlink_frequency[CC_id][1] = downlink_frequency[CC_id][0];
// downlink_frequency[CC_id][2] = downlink_frequency[CC_id][0];
// downlink_frequency[CC_id][3] = downlink_frequency[CC_id][0];
//printf("Downlink for CC_id %d frequency set to %u\n", CC_id, downlink_frequency[CC_id][0]);
frame_parms[CC_id]->dl_CarrierFreq=downlink_frequency[CC_id][0];
}
}
void init_pdcp(void) {
if (!NODE_IS_DU(RC.rrc[0]->node_type)) {
pdcp_layer_init();
uint32_t pdcp_initmask = (IS_SOFTMODEM_NOS1) ?
(PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT) : LINK_ENB_PDCP_TO_GTPV1U_BIT;
if (IS_SOFTMODEM_NOS1)
pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_BIT | SOFTMODEM_NOKRNMOD_BIT ;
pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_W_MBMS_BIT;
if ( split73!=SPLIT73_DU)
pdcp_module_init(pdcp_initmask);
if (NODE_IS_CU(RC.rrc[0]->node_type)) {
pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t)proto_agent_send_rlc_data_req);
} else {
pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t) rlc_data_req);
pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) pdcp_data_ind);
}
} else {
pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) proto_agent_send_pdcp_data_ind);
}
}
static void wait_nfapi_init(char *thread_name) {
printf( "waiting for NFAPI PNF connection and population of global structure (%s)\n",thread_name);
pthread_mutex_lock( &nfapi_sync_mutex );
while (nfapi_sync_var<0)
pthread_cond_wait( &nfapi_sync_cond, &nfapi_sync_mutex );
pthread_mutex_unlock(&nfapi_sync_mutex);
printf( "NFAPI: got sync (%s)\n", thread_name);
}
void terminate_task(module_id_t mod_id, task_id_t from, task_id_t to) {
LOG_I(ENB_APP, "sending TERMINATE_MESSAGE from task %s (%d) to task %s (%d)\n",
itti_get_task_name(from), from, itti_get_task_name(to), to);
MessageDef *msg;
msg = itti_alloc_new_message (from, TERMINATE_MESSAGE);
itti_send_msg_to_task (to, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg);
}
int stop_L1L2(module_id_t enb_id) {
LOG_W(ENB_APP, "stopping lte-softmodem\n");
if (!RC.ru) {
LOG_UI(ENB_APP, "no RU configured\n");
return -1;
}
/* these tasks need to pick up new configuration */
terminate_task(enb_id, TASK_ENB_APP, TASK_RRC_ENB);
oai_exit = 1;
LOG_I(ENB_APP, "calling kill_RU_proc() for instance %d\n", enb_id);
kill_RU_proc(RC.ru[enb_id]);
LOG_I(ENB_APP, "calling kill_eNB_proc() for instance %d\n", enb_id);
kill_eNB_proc(enb_id);
oai_exit = 0;
for (int cc_id = 0; cc_id < RC.nb_CC[enb_id]; cc_id++) {
free_transport(RC.eNB[enb_id][cc_id]);
phy_free_lte_eNB(RC.eNB[enb_id][cc_id]);
}
phy_free_RU(RC.ru[enb_id]);
free_lte_top();
return 0;
}
/*
* Restart the lte-softmodem after it has been soft-stopped with stop_L1L2()
*/
int restart_L1L2(module_id_t enb_id) {
RU_t *ru = RC.ru[enb_id];
MessageDef *msg_p = NULL;
LOG_W(ENB_APP, "restarting lte-softmodem\n");
/* block threads */
pthread_mutex_lock(&sync_mutex);
sync_var = -1;
pthread_mutex_unlock(&sync_mutex);
RC.ru_mask |= (1 << ru->idx);
/* copy the changed frame parameters to the RU */
/* TODO this should be done for all RUs associated to this eNB */
memcpy(&ru->frame_parms, &RC.eNB[enb_id][0]->frame_parms, sizeof(LTE_DL_FRAME_PARMS));
/* reset the list of connected UEs in the MAC, since in this process with
* loose all UEs (have to reconnect) */
init_UE_list(&RC.mac[enb_id]->UE_list);
LOG_I(ENB_APP, "attempting to create ITTI tasks\n");
// No more rrc thread, as many race conditions are hidden behind
rrc_enb_init();
itti_mark_task_ready(TASK_RRC_ENB);
/* pass a reconfiguration request which will configure everything down to
* RC.eNB[i][j]->frame_parms, too */
msg_p = itti_alloc_new_message(TASK_ENB_APP, RRC_CONFIGURATION_REQ);
RRC_CONFIGURATION_REQ(msg_p) = RC.rrc[enb_id]->configuration;
itti_send_msg_to_task(TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p);
/* TODO XForms might need to be restarted, but it is currently (09/02/18)
* broken, so we cannot test it */
init_RU_proc(ru);
ru->rf_map.card = 0;
ru->rf_map.chain = 0; /* CC_id + chain_offset;*/
init_eNB_afterRU();
printf("Sending sync to all threads\n");
pthread_mutex_lock(&sync_mutex);
sync_var=0;
pthread_cond_broadcast(&sync_cond);
pthread_mutex_unlock(&sync_mutex);
return 0;
}
int main ( int argc, char **argv ) {
int i;
int CC_id = 0;
int node_type = ngran_eNB;
AssertFatal(load_configmodule(argc,argv,0), "[SOFTMODEM] Error, configuration module init failed\n");
logInit();
printf("Reading in command-line options\n");
get_options ();
AssertFatal(!CONFIG_ISFLAGSET(CONFIG_ABORT),"Getting configuration failed\n");
EPC_MODE_ENABLED = !IS_SOFTMODEM_NOS1;
#if T_TRACER
T_Config_Init();
#endif
configure_linux();
cpuf=get_cpu_freq_GHz();
set_taus_seed (0);
if (opp_enabled ==1)
reset_opp_meas();
itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info);
init_opt();
#ifndef PACKAGE_VERSION
# define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL"
#endif
LOG_I(HW, "Version: %s\n", PACKAGE_VERSION);
/* Read configuration */
if (RC.nb_inst > 0) {
// Allocate memory from RC variable
read_config_and_init();
} else {
printf("RC.nb_inst = 0, Initializing L1\n");
RCconfig_L1();
}
/* We need to read RU configuration before FlexRAN starts so it knows what
* splits to report. Actual RU start comes later. */
if (RC.nb_RU > 0 && NFAPI_MODE != NFAPI_MODE_VNF) {
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());
}
if ( strlen(get_softmodem_params()->split73) > 0 ) {
char tmp[1024]={0};
strncpy(tmp,get_softmodem_params()->split73, 1023);
tmp[2]=0;
if ( strncasecmp(tmp,"cu", 2)==0 )
split73=SPLIT73_CU;
else if ( strncasecmp(tmp,"du", 2)==0 )
split73=SPLIT73_DU;
else
AssertFatal(false,"split73 syntax: <cu|du>:<remote ip addr>[:<ip port>] (string found: %s) \n",get_softmodem_params()->split73);
}
if (RC.nb_inst > 0) {
/* Start the agent. If it is turned off in the configuration, it won't start */
for (i = 0; i < RC.nb_inst; i++) {
flexran_agent_start(i);
}
/* initializes PDCP and sets correct RLC Request/PDCP Indication callbacks
* for monolithic/F1 modes */
init_pdcp();
AssertFatal(create_tasks(1)==0,"cannot create ITTI tasks\n");
for (int enb_id = 0; enb_id < RC.nb_inst; enb_id++) {
MessageDef *msg_p = itti_alloc_new_message (TASK_ENB_APP, RRC_CONFIGURATION_REQ);
RRC_CONFIGURATION_REQ(msg_p) = RC.rrc[enb_id]->configuration;
itti_send_msg_to_task (TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p);
}
node_type = RC.rrc[0]->node_type;
}
if (RC.nb_inst > 0 && NODE_IS_CU(node_type)) {
protocol_ctxt_t ctxt;
ctxt.module_id = 0 ;
ctxt.instance = 0;
ctxt.rnti = 0;
ctxt.enb_flag = 1;
ctxt.frame = 0;
ctxt.subframe = 0;
pdcp_run(&ctxt);
}
/* start threads if only L1 or not a CU */
if (RC.nb_inst == 0 || !NODE_IS_CU(node_type) || NFAPI_MODE == NFAPI_MODE_PNF || NFAPI_MODE == NFAPI_MODE_VNF) {
// init UE_PF_PO and mutex lock
pthread_mutex_init(&ue_pf_po_mutex, NULL);
memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*MAX_MOBILES_PER_ENB*MAX_NUM_CCs);
pthread_cond_init(&sync_cond,NULL);
pthread_mutex_init(&sync_mutex, NULL);
if (NFAPI_MODE!=NFAPI_MONOLITHIC) {
LOG_I(ENB_APP,"NFAPI*** - mutex and cond created - will block shortly for completion of PNF connection\n");
pthread_cond_init(&sync_cond,NULL);
pthread_mutex_init(&sync_mutex, NULL);
}
if (NFAPI_MODE==NFAPI_MODE_VNF) {// VNF
#if defined(PRE_SCD_THREAD)
init_ru_vnf(); // ru pointer is necessary for pre_scd.
#endif
wait_nfapi_init("main?");
}
LOG_I(ENB_APP,"START MAIN THREADS\n");
// start the main threads
number_of_cards = 1;
printf("RC.nb_L1_inst:%d\n", RC.nb_L1_inst);
if (RC.nb_L1_inst > 0) {
printf("Initializing eNB threads single_thread_flag:%d wait_for_sync:%d\n",
get_softmodem_params()->single_thread_flag,
get_softmodem_params()->wait_for_sync);
init_eNB(get_softmodem_params()->single_thread_flag,
get_softmodem_params()->wait_for_sync);
}
for (int x=0; x < RC.nb_L1_inst; x++)
for (int CC_id=0; CC_id<RC.nb_L1_CC[x]; CC_id++) {
L1_rxtx_proc_t *L1proc= &RC.eNB[x][CC_id]->proc.L1_proc;
L1proc->threadPool=(tpool_t *)malloc(sizeof(tpool_t));
L1proc->respEncode=(notifiedFIFO_t *) malloc(sizeof(notifiedFIFO_t));
L1proc->respDecode=(notifiedFIFO_t *) malloc(sizeof(notifiedFIFO_t));
if ( strlen(get_softmodem_params()->threadPoolConfig) > 0 )
initTpool(get_softmodem_params()->threadPoolConfig, L1proc->threadPool, true);
else
initTpool("n", L1proc->threadPool, true);
initNotifiedFIFO(L1proc->respEncode);
initNotifiedFIFO(L1proc->respDecode);
}
}
printf("About to Init RU threads RC.nb_RU:%d\n", RC.nb_RU);
// RU thread and some L1 procedure aren't necessary in VNF or L2 FAPI simulator.
// but RU thread deals with pre_scd and this is necessary in VNF and simulator.
// some initialization is necessary and init_ru_vnf do this.
if (RC.nb_RU >0 && NFAPI_MODE!=NFAPI_MODE_VNF) {
printf("Initializing RU threads\n");
init_RU(get_softmodem_params()->rf_config_file,
get_softmodem_params()->clock_source,
get_softmodem_params()->timing_source,
get_softmodem_params()->send_dmrs_sync);
for (int ru_id=0; ru_id<RC.nb_RU; ru_id++) {
RC.ru[ru_id]->rf_map.card=0;
RC.ru[ru_id]->rf_map.chain=CC_id+(get_softmodem_params()->chain_offset);
LOG_I(PHY,"Starting ru_thread %d\n",ru_id);
init_RU_proc(RC.ru[ru_id]);
}
config_sync_var=0;
if (NFAPI_MODE==NFAPI_MODE_PNF) { // PNF
wait_nfapi_init("main?");
}
LOG_I(ENB_APP,"RC.nb_RU:%d\n", RC.nb_RU);
// once all RUs are ready intiailize the rest of the eNBs ((dependence on final RU parameters after configuration)
printf("ALL RUs ready - init eNBs\n");
if (NFAPI_MODE!=NFAPI_MODE_PNF && NFAPI_MODE!=NFAPI_MODE_VNF) {
LOG_I(ENB_APP,"Not NFAPI mode - call init_eNB_afterRU()\n");
init_eNB_afterRU();
} else {
LOG_I(ENB_APP,"NFAPI mode - DO NOT call init_eNB_afterRU()\n");
}
LOG_UI(ENB_APP,"ALL RUs ready - ALL eNBs ready\n");
// connect the TX/RX buffers
sleep(1); /* wait for thread activation */
LOG_I(ENB_APP,"Sending sync to all threads\n");
pthread_mutex_lock(&sync_mutex);
sync_var=0;
pthread_cond_broadcast(&sync_cond);
pthread_mutex_unlock(&sync_mutex);
config_check_unknown_cmdlineopt(CONFIG_CHECKALLSECTIONS);
}
create_tasks_mbms(1);
// wait for end of program
LOG_UI(ENB_APP,"TYPE <CTRL-C> TO TERMINATE\n");
// CI -- Flushing the std outputs for the previous marker to show on the eNB / DU / CU log file
fflush(stdout);
fflush(stderr);
// end of CI modifications
//getchar();
if(IS_SOFTMODEM_DOFORMS)
load_softscope("enb");
itti_wait_tasks_end();
oai_exit=1;
LOG_I(ENB_APP,"oai_exit=%d\n",oai_exit);
// stop threads
if (RC.nb_inst == 0 || !NODE_IS_CU(node_type)) {
if(IS_SOFTMODEM_DOFORMS)
end_forms();
LOG_I(ENB_APP,"stopping MODEM threads\n");
stop_eNB(NB_eNB_INST);
stop_RU(RC.nb_RU);
/* release memory used by the RU/eNB threads (incomplete), after all
* threads have been stopped (they partially use the same memory) */
for (int inst = 0; inst < NB_eNB_INST; inst++) {
for (int cc_id = 0; cc_id < RC.nb_CC[inst]; cc_id++) {
free_transport(RC.eNB[inst][cc_id]);
phy_free_lte_eNB(RC.eNB[inst][cc_id]);
}
}
for (int inst = 0; inst < RC.nb_RU; inst++) {
phy_free_RU(RC.ru[inst]);
}
free_lte_top();
end_configmodule();
pthread_cond_destroy(&sync_cond);
pthread_mutex_destroy(&sync_mutex);
pthread_cond_destroy(&nfapi_sync_cond);
pthread_mutex_destroy(&nfapi_sync_mutex);
pthread_mutex_destroy(&ue_pf_po_mutex);
for(int ru_id=0; ru_id<RC.nb_RU; ru_id++) {
if (RC.ru[ru_id]->rfdevice.trx_end_func) {
RC.ru[ru_id]->rfdevice.trx_end_func(&RC.ru[ru_id]->rfdevice);
RC.ru[ru_id]->rfdevice.trx_end_func = NULL;
}
if (RC.ru[ru_id]->ifdevice.trx_end_func) {
RC.ru[ru_id]->ifdevice.trx_end_func(&RC.ru[ru_id]->ifdevice);
RC.ru[ru_id]->ifdevice.trx_end_func = NULL;
}
}
}
terminate_opt();
logClean();
printf("Bye.\n");
return 0;
}
......@@ -180,14 +180,14 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t
// ****************************************
// Common RX procedures subframe n
T(T_GNB_PHY_DL_TICK, T_INT(gNB->Mod_id), T_INT(frame_tx), T_INT(slot_tx));
/*
// if this is IF5 or 3GPP_gNB
if (gNB && gNB->RU_list && gNB->RU_list[0] && gNB->RU_list[0]->function < NGFI_RAU_IF4p5) {
wakeup_prach_gNB(gNB,NULL,proc->frame_rx,proc->slot_rx);
}
/*
// if this is IF5 or 3GPP_gNB
if (gNB && gNB->RU_list && gNB->RU_list[0] && gNB->RU_list[0]->function < NGFI_RAU_IF4p5) {
wakeup_prach_gNB(gNB,NULL,proc->frame_rx,proc->slot_rx);
}
// UE-specific RX processing for subframe n
if (nfapi_mode == 0 || nfapi_mode == 1) */
// UE-specific RX processing for subframe n
if (nfapi_mode == 0 || nfapi_mode == 1) */
pthread_mutex_lock(&gNB->UL_INFO_mutex);
gNB->UL_INFO.frame = frame_rx;
......@@ -207,8 +207,8 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t
if (oai_exit) return(-1);
//if (slot_rx == NR_UPLINK_SLOT || gNB->frame_parms.frame_type == FDD)
phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx);
//if (slot_rx == NR_UPLINK_SLOT || gNB->frame_parms.frame_type == FDD)
phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx);
if(get_thread_parallel_conf() != PARALLEL_RU_L1_TRX_SPLIT) {
phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1);
......@@ -318,7 +318,7 @@ static void *gNB_L1_thread( void *param ) {
gNB_L1_rxtx_proc_t *L1_proc = &gNB_proc->L1_proc;
//PHY_VARS_gNB *gNB = RC.gNB[0][proc->CC_id];
char thread_name[100];
// set default return value
// set default return value
gNB_thread_rxtx_status = 0;
......@@ -327,16 +327,15 @@ static void *gNB_L1_thread( void *param ) {
while (!oai_exit) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX0, 0 );
if (wait_on_condition(&L1_proc->mutex,&L1_proc->cond,&L1_proc->instance_cnt,thread_name)<0) break;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX0, 1 );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX0, 1 );
int frame_rx = L1_proc->frame_rx;
int slot_rx = L1_proc->slot_rx;
int frame_tx = L1_proc->frame_tx;
int slot_tx = L1_proc->slot_tx;
uint64_t timestamp_tx = L1_proc->timestamp_tx;
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX0_GNB,slot_tx);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX0_GNB,slot_rx);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_GNB,frame_tx);
......@@ -408,17 +407,15 @@ void gNB_top(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, char *string, struct
}
int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot_tx,uint64_t timestamp_tx) {
RU_t *ru;
RU_proc_t *ru_proc;
int waitret = 0, ret = 0, time_ns = 1000*1000;
struct timespec now, abstime;
// note this should depend on the numerology used by the TX L1 thread, set here for 500us slot time
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL,1);
time_ns = time_ns/gNB->frame_parms.slots_per_subframe;
AssertFatal((ret = pthread_mutex_lock(&proc->mutex_RUs_tx))==0,"mutex_lock returns %d\n",ret);
while (proc->instance_cnt_RUs < 0) {
clock_gettime(CLOCK_REALTIME, &now);
abstime.tv_sec = now.tv_sec;
......@@ -428,35 +425,32 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot
abstime.tv_nsec -= 1000*1000*1000;
abstime.tv_sec += 1;
}
if((waitret = pthread_cond_timedwait(&proc->cond_RUs,&proc->mutex_RUs_tx,&abstime)) == 0) break; // this unlocks mutex_rxtx while waiting and then locks it again
}
proc->instance_cnt_RUs = -1;
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,proc->instance_cnt_RUs);
AssertFatal((ret = pthread_mutex_unlock(&proc->mutex_RUs_tx))==0,"mutex_unlock returns %d\n",ret);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL,0);
if (waitret == ETIMEDOUT) {
LOG_W(PHY,"Dropping TX slot (%d.%d) because FH is blocked more than 1 slot times (500us)\n",frame_tx,slot_tx);
AssertFatal((ret=pthread_mutex_lock(&gNB->proc.mutex_RU_tx))==0,"mutex_lock returns %d\n",ret);
gNB->proc.RU_mask_tx = 0;
AssertFatal((ret=pthread_mutex_unlock(&gNB->proc.mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret);
AssertFatal((ret=pthread_mutex_lock(&proc->mutex_RUs_tx))==0,"mutex_lock returns %d\n",ret);
proc->instance_cnt_RUs = 0;
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,proc->instance_cnt_RUs);
AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_RUs_tx))==0,"mutex_unlock returns %d\n",ret);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_UE,1);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_UE,0);
return(-1);
}
for(int i=0; i<gNB->num_RU; i++)
{
LOG_W(PHY,"Dropping TX slot (%d.%d) because FH is blocked more than 1 slot times (500us)\n",frame_tx,slot_tx);
AssertFatal((ret=pthread_mutex_lock(&gNB->proc.mutex_RU_tx))==0,"mutex_lock returns %d\n",ret);
gNB->proc.RU_mask_tx = 0;
AssertFatal((ret=pthread_mutex_unlock(&gNB->proc.mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret);
AssertFatal((ret=pthread_mutex_lock(&proc->mutex_RUs_tx))==0,"mutex_lock returns %d\n",ret);
proc->instance_cnt_RUs = 0;
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,proc->instance_cnt_RUs);
AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_RUs_tx))==0,"mutex_unlock returns %d\n",ret);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_UE,1);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_UE,0);
return(-1);
}
for(int i=0; i<gNB->num_RU; i++) {
ru = gNB->RU_list[i];
ru_proc = &ru->proc;
if (ru_proc->instance_cnt_gNBs == 0) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST_UE, 1);
......@@ -464,62 +458,46 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot
AssertFatal((ret=pthread_mutex_lock(&gNB->proc.mutex_RU_tx))==0,"mutex_lock returns %d\n",ret);
gNB->proc.RU_mask_tx = 0;
AssertFatal((ret=pthread_mutex_unlock(&gNB->proc.mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST_UE, 0);
return(-1);
}
AssertFatal((ret = pthread_mutex_lock(&ru_proc->mutex_gNBs))==0,"ERROR pthread_mutex_lock failed on mutex_gNBs L1_thread_tx with ret=%d\n",ret);
AssertFatal((ret = pthread_mutex_lock(&ru_proc->mutex_gNBs))==0,"ERROR pthread_mutex_lock failed on mutex_gNBs L1_thread_tx with ret=%d\n",ret);
ru_proc->instance_cnt_gNBs = 0;
ru_proc->timestamp_tx = timestamp_tx;
ru_proc->tti_tx = slot_tx;
ru_proc->frame_tx = frame_tx;
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX1_UE, ru_proc->instance_cnt_gNBs);
LOG_D(PHY,"Signaling tx_thread_fh for %d.%d\n",frame_tx,slot_tx);
LOG_D(PHY,"Signaling tx_thread_fh for %d.%d\n",frame_tx,slot_tx);
// the thread can now be woken up
AssertFatal(pthread_cond_signal(&ru_proc->cond_gNBs) == 0,
"[gNB] ERROR pthread_cond_signal for gNB TXnp4 thread\n");
"[gNB] ERROR pthread_cond_signal for gNB TXnp4 thread\n");
AssertFatal((ret=pthread_mutex_unlock(&ru_proc->mutex_gNBs))==0,"mutex_unlock returned %d\n",ret);
}
return(0);
}
int wakeup_tx(PHY_VARS_gNB *gNB,int frame_rx,int slot_rx,int frame_tx,int slot_tx,uint64_t timestamp_tx) {
gNB_L1_rxtx_proc_t *L1_proc_tx = &gNB->proc.L1_proc_tx;
int ret;
AssertFatal((ret = pthread_mutex_lock(&L1_proc_tx->mutex))==0,"mutex_lock returns %d\n",ret);
while(L1_proc_tx->instance_cnt == 0){
while(L1_proc_tx->instance_cnt == 0) {
pthread_cond_wait(&L1_proc_tx->cond,&L1_proc_tx->mutex);
}
L1_proc_tx->instance_cnt = 0;
L1_proc_tx->slot_rx = slot_rx;
L1_proc_tx->frame_rx = frame_rx;
L1_proc_tx->slot_tx = slot_tx;
L1_proc_tx->frame_tx = frame_tx;
L1_proc_tx->timestamp_tx = timestamp_tx;
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_UE,1);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_UE,0);
// the thread can now be woken up
AssertFatal(pthread_cond_signal(&L1_proc_tx->cond) == 0, "ERROR pthread_cond_signal for gNB L1 thread\n");
AssertFatal((ret=pthread_mutex_unlock(&L1_proc_tx->mutex))==0,"mutex_unlock returns %d\n",ret);
return(0);
}
......@@ -532,22 +510,23 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) {
int i;
struct timespec abstime;
int time_ns = 50000;
AssertFatal((ret=pthread_mutex_lock(&proc->mutex_RU))==0,"mutex_lock returns %d\n",ret);
for (i=0;i<gNB->num_RU;i++) {
for (i=0; i<gNB->num_RU; i++) {
if (ru == gNB->RU_list[i]) {
if ((proc->RU_mask&(1<<i)) > 0)
LOG_E(PHY,"gNB %d frame %d, subframe %d : previous information from RU %d (num_RU %d,mask %x) has not been served yet!\n",
gNB->Mod_id,proc->frame_rx,proc->slot_rx,ru->idx,gNB->num_RU,proc->RU_mask);
LOG_E(PHY,"gNB %d frame %d, subframe %d : previous information from RU %d (num_RU %d,mask %x) has not been served yet!\n",
gNB->Mod_id,proc->frame_rx,proc->slot_rx,ru->idx,gNB->num_RU,proc->RU_mask);
proc->RU_mask |= (1<<i);
}
}
if (proc->RU_mask != (1<<gNB->num_RU)-1) { // not all RUs have provided their information so return
LOG_E(PHY,"Not all RUs have provided their info\n");
AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_RU))==0,"mutex_unlock returns %d\n",ret);
return(0);
}
else { // all RUs have provided their information so continue on and wakeup gNB processing
} else { // all RUs have provided their information so continue on and wakeup gNB processing
proc->RU_mask = 0;
AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_RU))==0,"muex_unlock returns %d\n",ret);
}
......@@ -565,17 +544,16 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) {
AssertFatal((ret=pthread_mutex_timedlock(&L1_proc->mutex, &abstime)) == 0,"mutex_lock returns %d\n", ret);
if (L1_proc->instance_cnt == 0) { // L1_thread is busy so abort the subframe
AssertFatal((ret=pthread_mutex_unlock( &L1_proc->mutex))==0,"muex_unlock return %d\n",ret);
LOG_W(PHY,"L1_thread isn't ready in %d.%d, aborting RX processing\n",ru_proc->frame_rx,ru_proc->tti_rx);
return(-1);
AssertFatal((ret=pthread_mutex_unlock( &L1_proc->mutex))==0,"muex_unlock return %d\n",ret);
LOG_W(PHY,"L1_thread isn't ready in %d.%d, aborting RX processing\n",ru_proc->frame_rx,ru_proc->tti_rx);
return(-1);
}
++L1_proc->instance_cnt;
// We have just received and processed the common part of a subframe, say n.
// TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired
// We have just received and processed the common part of a subframe, say n.
// TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired
// transmitted timestamp of the next TX slot (first).
// The last (TS_rx mod samples_per_frame) was n*samples_per_tti,
// The last (TS_rx mod samples_per_frame) was n*samples_per_tti,
// we want to generate subframe (n+sl_ahead), so TS_tx = TX_rx+sl_ahead*samples_per_tti,
// and proc->slot_tx = proc->slot_rx+sl_ahead
L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sl_ahead*fp->samples_per_slot);
......@@ -583,9 +561,7 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) {
L1_proc->slot_rx = ru_proc->tti_rx;
L1_proc->frame_tx = (L1_proc->slot_rx > (fp->slots_per_frame-1-sl_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx;
L1_proc->slot_tx = (L1_proc->slot_rx + sl_ahead)%fp->slots_per_frame;
LOG_D(PHY,"wakeupL1: passing parameter IC = %d, RX: %d.%d, TX: %d.%d to L1 sl_ahead = %d\n", L1_proc->instance_cnt, L1_proc->frame_rx, L1_proc->slot_rx, L1_proc->frame_tx, L1_proc->slot_tx, sl_ahead);
pthread_mutex_unlock( &L1_proc->mutex );
// the thread can now be woken up
......@@ -594,7 +570,7 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) {
exit_fun( "ERROR pthread_cond_signal" );
return(-1);
}
return(0);
}
/*
......@@ -698,23 +674,20 @@ static void* gNB_thread_prach( void* param ) {
extern void init_td_thread(PHY_VARS_gNB *);
extern void init_te_thread(PHY_VARS_gNB *);
static void* process_stats_thread(void* param) {
PHY_VARS_gNB *gNB = (PHY_VARS_gNB*)param;
static void *process_stats_thread(void *param) {
PHY_VARS_gNB *gNB = (PHY_VARS_gNB *)param;
reset_meas(&gNB->dlsch_encoding_stats);
reset_meas(&gNB->dlsch_scrambling_stats);
reset_meas(&gNB->dlsch_modulation_stats);
wait_sync("process_stats_thread");
while(!oai_exit)
{
while(!oai_exit) {
sleep(1);
print_meas(&gNB->dlsch_encoding_stats, "pdsch_encoding", NULL, NULL);
print_meas(&gNB->dlsch_scrambling_stats, "pdsch_scrambling", NULL, NULL);
print_meas(&gNB->dlsch_modulation_stats, "pdsch_modulation", NULL, NULL);
}
return(NULL);
}
......@@ -767,6 +740,7 @@ void init_gNB_proc(int inst) {
}
if(opp_enabled == 1) threadCreate(&proc->L1_stats_thread, process_stats_thread,(void *)gNB, "time_meas", -1, OAI_PRIORITY_RT_LOW);
//pthread_create( &proc->pthread_prach, attr_prach, gNB_thread_prach, gNB );
char name[16];
......@@ -904,7 +878,7 @@ void init_eNB_afterRU(void) {
for (i=0; i<gNB->RU_list[ru_id]->nb_rx; aa++,i++) {
LOG_I(PHY,"Attaching RU %d antenna %d to gNB antenna %d\n",gNB->RU_list[ru_id]->idx,i,aa);
// gNB->prach_vars.rxsigF[0][aa] = gNB->RU_list[ru_id]->prach_rxsigF[i];
// gNB->prach_vars.rxsigF[0][aa] = gNB->RU_list[ru_id]->prach_rxsigF[i];
gNB->common_vars.rxdataF[aa] = gNB->RU_list[ru_id]->common.rxdataF[i];
}
}
......@@ -968,7 +942,6 @@ void init_gNB(int single_thread_flag,int wait_for_sync) {
gNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = gNB->harq_pdu_list;
gNB->UL_INFO.cqi_ind.cqi_pdu_list = gNB->cqi_pdu_list;
gNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = gNB->cqi_raw_pdu_list;
gNB->prach_energy_counter = 0;
}
}
......
......@@ -92,7 +92,7 @@ unsigned short config_frames[4] = {2,9,11,13};
static int DEFBANDS[] = {7};
static int DEFENBS[] = {0};
static int DEFBFW[] = {0x00007fff};
//static int DEFNRBANDS[] = {7};
//static int DEFGNBS[] = {0};
......@@ -712,7 +712,7 @@ void rx_rf(RU_t *ru,int *frame,int *slot) {
}
void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
RU_proc_t *proc = &ru->proc;
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
//nfapi_nr_config_request_t *cfg = &ru->gNB_list[0]->gNB_config;
......@@ -758,7 +758,7 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, slot );
for (i=0; i<ru->nb_tx; i++){
for (i=0; i<ru->nb_tx; i++) {
txp[i] = (void *)&ru->common.txdata[i][(slot*fp->samples_per_slot)-sf_extension];
}
......@@ -870,7 +870,7 @@ static void *ru_thread_prach( void *param ) {
0,0
);
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 0 );*/
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 0 );*/
if (release_thread(&proc->mutex_prach,&proc->instance_cnt_prach,"ru_prach_thread") < 0) break;
}
......@@ -1097,16 +1097,16 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) {
}
} else if(N_RB == 106) {
if (fp->threequarter_fs) {
cfg->sample_rate=46.08e6;
cfg->samples_per_frame = 460800;
cfg->tx_bw = 40e6;
cfg->rx_bw = 40e6;
cfg->sample_rate=46.08e6;
cfg->samples_per_frame = 460800;
cfg->tx_bw = 40e6;
cfg->rx_bw = 40e6;
}
else {
cfg->sample_rate=61.44e6;
cfg->samples_per_frame = 614400;
cfg->tx_bw = 40e6;
cfg->rx_bw = 40e6;
cfg->sample_rate=61.44e6;
cfg->samples_per_frame = 614400;
cfg->tx_bw = 40e6;
cfg->rx_bw = 40e6;
}
} else {
AssertFatal(0==1,"N_RB %d not yet supported for numerology %d\n",N_RB,mu);
......@@ -1210,7 +1210,7 @@ static void *ru_stats_thread(void *param) {
if (ru->feprx) print_meas(&ru->ofdm_demod_stats,"feprx",NULL,NULL);
if (ru->feptx_ofdm){
if (ru->feptx_ofdm) {
print_meas(&ru->precoding_stats,"feptx_prec",NULL,NULL);
print_meas(&ru->txdataF_copy_stats,"txdataF_copy",NULL,NULL);
print_meas(&ru->ofdm_mod_stats,"feptx_ofdm",NULL,NULL);
......@@ -1219,7 +1219,7 @@ static void *ru_stats_thread(void *param) {
if (ru->fh_north_asynch_in) print_meas(&ru->rx_fhaul,"rx_fhaul",NULL,NULL);
print_meas(&ru->tx_fhaul,"tx_fhaul",NULL,NULL);
print_meas(&ru->tx_fhaul,"tx_fhaul",NULL,NULL);
if (ru->fh_north_out) {
print_meas(&ru->compression,"compression",NULL,NULL);
print_meas(&ru->transport,"transport",NULL,NULL);
......@@ -1346,7 +1346,7 @@ static void *ru_thread_tx( void *param ) {
if (L1_proc->instance_cnt_RUs == -1) {
L1_proc->instance_cnt_RUs = 0;
AssertFatal(pthread_cond_signal(&L1_proc->cond_RUs) == 0,
"ERROR pthread_cond_signal for gNB_L1_thread\n");
"ERROR pthread_cond_signal for gNB_L1_thread\n");
} //else AssertFatal(1==0,"gNB TX thread is not ready\n");
ret = pthread_mutex_unlock(&L1_proc->mutex_RUs_tx);
AssertFatal(ret == 0,"mutex_unlock returns %d\n",ret);
......@@ -1371,7 +1371,7 @@ static void *ru_thread( void *param ) {
int print_frame = 8;
int i = 0;
int aa;
// set default return value
// set default return value
ru_thread_status = 0;
// set default return value
......@@ -1499,9 +1499,9 @@ static void *ru_thread( void *param ) {
LOG_D(PHY,"RU proc: frame_rx = %d, tti_rx = %d\n", proc->frame_rx, proc->tti_rx);
LOG_D(PHY,"Copying rxdataF from RU to gNB\n");
for (aa=0;aa<ru->nb_rx;aa++)
memcpy((void*)RC.gNB[0][0]->common_vars.rxdataF[aa],
(void*)ru->common.rxdataF[aa], fp->symbols_per_slot*fp->ofdm_symbol_size*sizeof(int32_t));
for (aa=0; aa<ru->nb_rx; aa++)
memcpy((void *)RC.gNB[0][0]->common_vars.rxdataF[aa],
(void *)ru->common.rxdataF[aa], fp->symbols_per_slot*fp->ofdm_symbol_size*sizeof(int32_t));
// At this point, all information for subframe has been received on FH interface
......@@ -2260,7 +2260,7 @@ void RCconfig_RU(void)
}
}
else {
RC.ru[j]->openair0_cfg.clock_source = unset;
RC.ru[j]->openair0_cfg.clock_source = unset;
}
if (strcmp(*(RUParamList.paramarray[j][RU_LOCAL_RF_IDX].strptr), "yes") == 0) {
......
......@@ -176,6 +176,10 @@ uint32_t target_ul_mcs = 20;
uint32_t timing_advance = 0;
uint64_t num_missed_slots=0; // counter for the number of missed slots
int split73=0;
void sendFs6Ul(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int segmentID, int16_t *data, int dataLen, int r_offset) {
AssertFatal(false, "Must not be called in this context\n");
}
extern void reset_opp_meas(void);
extern void print_opp_meas(void);
......@@ -721,13 +725,9 @@ int restart_L1L2(module_id_t gnb_id) {
memcpy(&ru->nr_frame_parms, &RC.gNB[gnb_id][0]->frame_parms, sizeof(NR_DL_FRAME_PARMS));
set_function_spec_param(RC.ru[gnb_id]);
LOG_I(GNB_APP, "attempting to create ITTI tasks\n");
if (itti_create_task (TASK_RRC_ENB, rrc_enb_task, NULL) < 0) {
LOG_E(RRC, "Create task for RRC eNB failed\n");
return -1;
} else {
LOG_I(RRC, "Re-created task for RRC gNB successfully\n");
}
// No more rrc thread, as many race conditions are hidden behind
rrc_enb_init();
itti_mark_task_ready(TASK_RRC_ENB);
if (itti_create_task (TASK_L2L1, l2l1_task, NULL) < 0) {
LOG_E(PDCP, "Create task for L2L1 failed\n");
......@@ -771,23 +771,23 @@ static void wait_nfapi_init(char *thread_name) {
void init_pdcp(void) {
//if (!NODE_IS_DU(RC.rrc[0]->node_type)) {
pdcp_layer_init();
uint32_t pdcp_initmask = (IS_SOFTMODEM_NOS1) ?
(PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT) : LINK_ENB_PDCP_TO_GTPV1U_BIT;
pdcp_layer_init();
uint32_t pdcp_initmask = (IS_SOFTMODEM_NOS1) ?
(PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT) : LINK_ENB_PDCP_TO_GTPV1U_BIT;
if (IS_SOFTMODEM_NOS1){
printf("IS_SOFTMODEM_NOS1 option enabled \n");
pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_BIT | SOFTMODEM_NOKRNMOD_BIT ;
}
if (IS_SOFTMODEM_NOS1) {
printf("IS_SOFTMODEM_NOS1 option enabled \n");
pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_BIT | SOFTMODEM_NOKRNMOD_BIT ;
}
pdcp_module_init(pdcp_initmask);
pdcp_module_init(pdcp_initmask);
/*if (NODE_IS_CU(RC.rrc[0]->node_type)) {
pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t)proto_agent_send_rlc_data_req);
} else {*/
pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t) rlc_data_req);
pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) pdcp_data_ind);
//}
/*if (NODE_IS_CU(RC.rrc[0]->node_type)) {
pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t)proto_agent_send_rlc_data_req);
} else {*/
pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t) rlc_data_req);
pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) pdcp_data_ind);
//}
/*} else {
pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) proto_agent_send_pdcp_data_ind);
}*/
......@@ -841,7 +841,7 @@ int main( int argc, char **argv )
MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX);
#endif
init_opt();
init_opt();
#ifdef PDCP_USE_NETLINK
......@@ -857,7 +857,7 @@ init_opt();
LOG_I(HW, "Version: %s\n", PACKAGE_VERSION);
if(IS_SOFTMODEM_NOS1)
init_pdcp();
init_pdcp();
#if defined(ENABLE_ITTI)
......@@ -883,37 +883,37 @@ init_opt();
mlockall(MCL_CURRENT | MCL_FUTURE);
pthread_cond_init(&sync_cond,NULL);
pthread_mutex_init(&sync_mutex, NULL);
/*#ifdef XFORMS
int UE_id;
if (do_forms==1) {
fl_initialize (&argc, argv, NULL, 0, 0);
form_stats_l2 = create_form_stats_form();
fl_show_form (form_stats_l2->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "l2 stats");
form_stats = create_form_stats_form();
fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats");
/*#ifdef XFORMS
int UE_id;
for(UE_id=0; UE_id<scope_enb_num_ue; UE_id++) {
for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
form_gnb[CC_id][UE_id] = create_phy_scope_gnb();
sprintf (title, "LTE UL SCOPE eNB for CC_id %d, UE %d",CC_id,UE_id);
fl_show_form (form_gnb[CC_id][UE_id]->phy_scope_gnb, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
if (otg_enabled) {
fl_set_button(form_gnb[CC_id][UE_id]->button_0,1);
fl_set_object_label(form_gnb[CC_id][UE_id]->button_0,"DL Traffic ON");
} else {
fl_set_button(form_gnb[CC_id][UE_id]->button_0,0);
fl_set_object_label(form_gnb[CC_id][UE_id]->button_0,"DL Traffic OFF");
}
} // CC_id
} // UE_id
if (do_forms==1) {
fl_initialize (&argc, argv, NULL, 0, 0);
form_stats_l2 = create_form_stats_form();
fl_show_form (form_stats_l2->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "l2 stats");
form_stats = create_form_stats_form();
fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats");
for(UE_id=0; UE_id<scope_enb_num_ue; UE_id++) {
for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
form_gnb[CC_id][UE_id] = create_phy_scope_gnb();
sprintf (title, "LTE UL SCOPE eNB for CC_id %d, UE %d",CC_id,UE_id);
fl_show_form (form_gnb[CC_id][UE_id]->phy_scope_gnb, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
if (otg_enabled) {
fl_set_button(form_gnb[CC_id][UE_id]->button_0,1);
fl_set_object_label(form_gnb[CC_id][UE_id]->button_0,"DL Traffic ON");
} else {
fl_set_button(form_gnb[CC_id][UE_id]->button_0,0);
fl_set_object_label(form_gnb[CC_id][UE_id]->button_0,"DL Traffic OFF");
}
} // CC_id
} // UE_id
threadCreate(&forms_thread, scope_thread, NULL, "scope", -1, OAI_PRIORITY_RT_LOW);
printf("Scope thread created, ret=%d\n",ret);
}
threadCreate(&forms_thread, scope_thread, NULL, "scope", -1, OAI_PRIORITY_RT_LOW);
printf("Scope thread created, ret=%d\n",ret);
}
#endif*/
#endif*/
usleep(10*1000);
if (nfapi_mode) {
......@@ -1018,27 +1018,27 @@ init_opt();
printf("Terminating application - oai_exit=%d\n",oai_exit);
#endif
// stop threads
/*#ifdef XFORMS
/*#ifdef XFORMS
printf("waiting for XFORMS thread\n");
printf("waiting for XFORMS thread\n");
if (do_forms==1) {
pthread_join(forms_thread,&status);
fl_hide_form(form_stats->stats_form);
fl_free_form(form_stats->stats_form);
if (do_forms==1) {
pthread_join(forms_thread,&status);
fl_hide_form(form_stats->stats_form);
fl_free_form(form_stats->stats_form);
fl_hide_form(form_stats_l2->stats_form);
fl_free_form(form_stats_l2->stats_form);
fl_hide_form(form_stats_l2->stats_form);
fl_free_form(form_stats_l2->stats_form);
for(UE_id=0; UE_id<scope_enb_num_ue; UE_id++) {
for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
fl_hide_form(form_enb[CC_id][UE_id]->phy_scope_gNB);
fl_free_form(form_enb[CC_id][UE_id]->phy_scope_gNB);
}
}
}
for(UE_id=0; UE_id<scope_enb_num_ue; UE_id++) {
for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
fl_hide_form(form_enb[CC_id][UE_id]->phy_scope_gNB);
fl_free_form(form_enb[CC_id][UE_id]->phy_scope_gNB);
}
}
}
#endif*/
#endif*/
printf("stopping MODEM threads\n");
// cleanup
stop_gNB(NB_gNB_INST);
......
......@@ -148,7 +148,7 @@ PHY_VARS_NR_UE *init_nr_ue_vars(NR_DL_FRAME_PARMS *frame_parms,
ue->Mod_id = UE_id;
ue->mac_enabled = 1;
// initialize all signal buffers
// initialize all signal buffers
init_nr_ue_signal(ue,1,abstraction_flag);
// intialize transport
......@@ -380,7 +380,7 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
scheduled_response.CC_id = 0;
scheduled_response.frame = proc->frame_rx;
scheduled_response.slot = proc->nr_tti_rx;
//--------------------------Temporary configuration-----------------------------//
//--------------------------Temporary configuration-----------------------------//
n_rnti = 0x1234;
nb_rb = 50;
......@@ -391,7 +391,7 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
mcs = 9;
harq_pid = 0;
rvidx = 0;
//------------------------------------------------------------------------------//
//------------------------------------------------------------------------------//
scheduled_response.ul_config->sfn_slot = NR_UPLINK_SLOT;
scheduled_response.ul_config->number_pdus = 1;
......@@ -416,18 +416,18 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
LOG_D(PHY,"phy_procedures_nrUE_RX: slot:%d, time %lu\n", proc->nr_tti_rx, (rdtsc()-a)/3500);
//printf(">>> nr_ue_pdcch_procedures ended\n");
#endif
if(IS_SOFTMODEM_NOS1){ //&& proc->nr_tti_rx==1
//Hardcoded rnti value
protocol_ctxt_t ctxt;
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, UE->Mod_id, ENB_FLAG_NO,
0x1234, proc->frame_rx,
proc->nr_tti_rx, 0);
pdcp_run(&ctxt);
pdcp_fifo_flush_sdus(&ctxt);
}
if(IS_SOFTMODEM_NOS1) { //&& proc->nr_tti_rx==1
//Hardcoded rnti value
protocol_ctxt_t ctxt;
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, UE->Mod_id, ENB_FLAG_NO,
0x1234, proc->frame_rx,
proc->nr_tti_rx, 0);
pdcp_run(&ctxt);
pdcp_fifo_flush_sdus(&ctxt);
}
}
// no UL for now
// no UL for now
/*
if (UE->mac_enabled==1) {
......@@ -465,7 +465,7 @@ void UE_processing(void *arg) {
PHY_VARS_NR_UE *UE = rxtxD->UE;
processSlotRX(UE, proc);
uint8_t gNB_id = 0;
// params for UL time alignment procedure
// params for UL time alignment procedure
NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &UE->ul_time_alignment[gNB_id];
uint8_t numerology = UE->frame_parms.numerology_index;
......@@ -475,24 +475,24 @@ void UE_processing(void *arg) {
//printf(">>> mac ended\n");
// Prepare the future Tx data
/*
#ifndef NO_RAT_NR
/*
#ifndef NO_RAT_NR
if (slot_select_nr(&UE->frame_parms, proc->frame_tx, proc->nr_tti_tx) & NR_UPLINK_SLOT)
#else
if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) ||
(UE->frame_parms.frame_type == FDD) )
#endif
*/
if (slot_select_nr(&UE->frame_parms, proc->frame_tx, proc->nr_tti_tx) & NR_UPLINK_SLOT)
#else
if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) ||
(UE->frame_parms.frame_type == FDD) )
#endif
*/
/* UL time alignment
// If the current tx frame and slot match the TA configuration in ul_time_alignment
// then timing advance is processed and set to be applied in the next UL transmission */
if (UE->mac_enabled == 1) {
if (frame_tx == ul_time_alignment->ta_frame && slot_tx == ul_time_alignment->ta_slot){
if (frame_tx == ul_time_alignment->ta_frame && slot_tx == ul_time_alignment->ta_slot) {
LOG_D(PHY,"Applying timing advance -- frame %d -- slot %d\n", frame_tx, slot_tx);
//if (nfapi_mode!=3){
//if (nfapi_mode!=3){
nr_process_timing_advance(UE->Mod_id, UE->CC_id, ul_time_alignment->ta_command, numerology, bwp_ul_NB_RB);
ul_time_alignment->ta_frame = -1;
......@@ -501,7 +501,7 @@ void UE_processing(void *arg) {
}
}
if (proc->nr_tti_tx == NR_UPLINK_SLOT || UE->frame_parms.frame_type == FDD){
if (proc->nr_tti_tx == NR_UPLINK_SLOT || UE->frame_parms.frame_type == FDD) {
thread_id = PHY_vars_UE_g[UE->Mod_id][0]->current_thread_id[proc->nr_tti_tx];
......@@ -566,7 +566,7 @@ void trashFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) {
UE->frame_parms.samples_per_subframe,
UE->frame_parms.nb_antennas_rx);
if (IS_SOFTMODEM_RFSIM ) {
usleep(1000); // slow down, as would do actual rf to let cpu for the synchro thread
usleep(1000); // slow down, as would do actual rf to let cpu for the synchro thread
}
}
......@@ -579,24 +579,24 @@ void trashFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) {
void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) {
LOG_I(PHY,"Resynchronizing RX by %d samples (mode = %d)\n",UE->rx_offset,UE->mode);
void *dummy_tx[UE->frame_parms.nb_antennas_tx];
LOG_I(PHY,"Resynchronizing RX by %d samples (mode = %d)\n",UE->rx_offset,UE->mode);
void *dummy_tx[UE->frame_parms.nb_antennas_tx];
for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
dummy_tx[i]=malloc16_clear(UE->frame_parms.samples_per_subframe*4);
for ( int size=UE->rx_offset ; size > 0 ; size -= UE->frame_parms.samples_per_subframe ) {
int unitTransfer=size>UE->frame_parms.samples_per_subframe ? UE->frame_parms.samples_per_subframe : size ;
AssertFatal(unitTransfer ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
timestamp,
(void **)UE->common_vars.rxdata,
unitTransfer,
UE->frame_parms.nb_antennas_rx),"");
}
for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
dummy_tx[i]=malloc16_clear(UE->frame_parms.samples_per_subframe*4);
for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
free(dummy_tx[i]);
for ( int size=UE->rx_offset ; size > 0 ; size -= UE->frame_parms.samples_per_subframe ) {
int unitTransfer=size>UE->frame_parms.samples_per_subframe ? UE->frame_parms.samples_per_subframe : size ;
AssertFatal(unitTransfer ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
timestamp,
(void **)UE->common_vars.rxdata,
unitTransfer,
UE->frame_parms.nb_antennas_rx),"");
}
for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
free(dummy_tx[i]);
}
......@@ -727,7 +727,7 @@ void *UE_thread(void *arg) {
#ifdef OAI_ADRV9371_ZC706
/*uint32_t total_gain_dB_prev = 0;
if (total_gain_dB_prev != UE->rx_total_gain_dB) {
total_gain_dB_prev = UE->rx_total_gain_dB;
total_gain_dB_prev = UE->rx_total_gain_dB;
openair0_cfg[0].rx_gain[0] = UE->rx_total_gain_dB;
UE->rfdevice.trx_set_gains_func(&UE->rfdevice,&openair0_cfg[0]);
}*/
......@@ -763,29 +763,29 @@ void *UE_thread(void *arg) {
readBlockSize,
UE->frame_parms.nb_antennas_rx),"");
if (slot_nr == (20+NR_UPLINK_SLOT-DURATION_RX_TO_TX - 1)%20)
AssertFatal( writeBlockSize ==
UE->rfdevice.trx_write_func(&UE->rfdevice,
timestamp+
(DURATION_RX_TO_TX*UE->frame_parms.samples_per_slot) -
UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 -
openair0_cfg[0].tx_sample_advance,
txp,
writeBlockSize,
UE->frame_parms.nb_antennas_tx,
2),"");
if (slot_nr == (20+NR_UPLINK_SLOT-DURATION_RX_TO_TX)%20)
AssertFatal( writeBlockSize ==
UE->rfdevice.trx_write_func(&UE->rfdevice,
timestamp+
(DURATION_RX_TO_TX*UE->frame_parms.samples_per_slot) -
UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 -
openair0_cfg[0].tx_sample_advance,
txp,
writeBlockSize,
UE->frame_parms.nb_antennas_tx,
3),"");
if (slot_nr == (20+NR_UPLINK_SLOT-DURATION_RX_TO_TX - 1)%20)
AssertFatal( writeBlockSize ==
UE->rfdevice.trx_write_func(&UE->rfdevice,
timestamp+
(DURATION_RX_TO_TX*UE->frame_parms.samples_per_slot) -
UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 -
openair0_cfg[0].tx_sample_advance,
txp,
writeBlockSize,
UE->frame_parms.nb_antennas_tx,
2),"");
if (slot_nr == (20+NR_UPLINK_SLOT-DURATION_RX_TO_TX)%20)
AssertFatal( writeBlockSize ==
UE->rfdevice.trx_write_func(&UE->rfdevice,
timestamp+
(DURATION_RX_TO_TX*UE->frame_parms.samples_per_slot) -
UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 -
openair0_cfg[0].tx_sample_advance,
txp,
writeBlockSize,
UE->frame_parms.nb_antennas_tx,
3),"");
if( slot_nr==(nb_slot_frame-1)) {
// read in first symbol of next frame and adjust for timing drift
......
......@@ -214,7 +214,7 @@ int emulate_rf = 0;
tpool_t *Tpool;
#ifdef UE_DLSCH_PARALLELISATION
tpool_t *Tpool_dl;
tpool_t *Tpool_dl;
#endif
......@@ -308,8 +308,8 @@ static void *scope_thread(void *arg) {
while (!oai_exit) {
phy_scope_nrUE(form_nrue[0],
PHY_vars_UE_g[0][0],
0,0,1);
PHY_vars_UE_g[0][0],
0,0,1);
usleep(100*1000);
}
......@@ -382,9 +382,9 @@ static void get_options(void) {
int tddflag=0, nonbiotflag, vcdflag=0;
char *loopfile=NULL;
int dumpframe=0;
//uint32_t noS1;
//uint32_t nokrnmod;
//uint32_t nokrnmod;
paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC_UE ;
config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL);
......@@ -511,12 +511,12 @@ void init_openair0(void) {
else {
openair0_cfg[card].sample_rate=122.88e6;
openair0_cfg[card].samples_per_frame = 1228800;
}
}
} else {
LOG_E(PHY,"Unsupported numerology!\n");
exit(-1);
}
}else if(frame_parms[0]->N_RB_DL == 273) {
} else if(frame_parms[0]->N_RB_DL == 273) {
if (numerology==1) {
if (frame_parms[0]->threequarter_fs) {
AssertFatal(0 == 1,"three quarter sampling not supported for N_RB 273\n");
......@@ -524,12 +524,12 @@ void init_openair0(void) {
else {
openair0_cfg[card].sample_rate=122.88e6;
openair0_cfg[card].samples_per_frame = 1228800;
}
}
} else {
LOG_E(PHY,"Unsupported numerology!\n");
exit(-1);
}
}else if(frame_parms[0]->N_RB_DL == 106) {
} else if(frame_parms[0]->N_RB_DL == 106) {
if (numerology==0) {
if (frame_parms[0]->threequarter_fs) {
openair0_cfg[card].sample_rate=23.04e6;
......@@ -538,15 +538,15 @@ void init_openair0(void) {
openair0_cfg[card].sample_rate=30.72e6;
openair0_cfg[card].samples_per_frame = 307200;
}
} else if (numerology==1) {
} else if (numerology==1) {
if (frame_parms[0]->threequarter_fs) {
openair0_cfg[card].sample_rate=46.08e6;
openair0_cfg[card].samples_per_frame = 460800;
openair0_cfg[card].sample_rate=46.08e6;
openair0_cfg[card].samples_per_frame = 460800;
}
else {
openair0_cfg[card].sample_rate=61.44e6;
openair0_cfg[card].samples_per_frame = 614400;
}
openair0_cfg[card].sample_rate=61.44e6;
openair0_cfg[card].samples_per_frame = 614400;
}
} else if (numerology==2) {
openair0_cfg[card].sample_rate=122.88e6;
openair0_cfg[card].samples_per_frame = 1228800;
......@@ -621,7 +621,7 @@ void init_pdcp(void) {
pdcp_initmask = pdcp_initmask | UE_NAS_USE_TUN_BIT;
/*if (rlc_module_init() != 0) {
LOG_I(RLC, "Problem at RLC initiation \n");
LOG_I(RLC, "Problem at RLC initiation \n");
}
pdcp_layer_init();
nr_ip_over_LTE_DRB_preconfiguration();*/
......@@ -633,7 +633,7 @@ void init_pdcp(void) {
// Stupid function addition because UE itti messages queues definition is common with eNB
void *rrc_enb_process_itti_msg(void *notUsed) {
return NULL;
return NULL;
}
......@@ -663,12 +663,12 @@ int main( int argc, char **argv ) {
set_taus_seed (0);
tpool_t pool;
Tpool = &pool;
char params[]="-1,-1";
char params[]="-1,-1";
initTpool(params, Tpool, false);
#ifdef UE_DLSCH_PARALLELISATION
tpool_t pool_dl;
Tpool_dl = &pool_dl;
char params_dl[]="-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1";
char params_dl[]="-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1";
initTpool(params_dl, Tpool_dl, false);
#endif
cpuf=get_cpu_freq_GHz();
......@@ -676,21 +676,21 @@ int main( int argc, char **argv ) {
init_opt() ;
if(IS_SOFTMODEM_NOS1)
init_pdcp();
init_pdcp();
if (ouput_vcd) {
vcd_signal_dumper_init("/tmp/openair_dump_nrUE.vcd");
}
/*
#ifdef PDCP_USE_NETLINK
netlink_init();
#if defined(PDCP_USE_NETLINK_QUEUES)
pdcp_netlink_init();
#endif
#endif
*/
#ifndef PACKAGE_VERSION
/*
#ifdef PDCP_USE_NETLINK
netlink_init();
#if defined(PDCP_USE_NETLINK_QUEUES)
pdcp_netlink_init();
#endif
#endif
*/
#ifndef PACKAGE_VERSION
# define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL"
#endif
LOG_I(HW, "Version: %s\n", PACKAGE_VERSION);
......
......@@ -125,27 +125,27 @@ void get_common_options(void) {
}
void softmodem_printresources(int sig, telnet_printfunc_t pf) {
struct rusage usage;
struct timespec stop;
clock_gettime(CLOCK_BOOTTIME, &stop);
uint64_t elapse = (stop.tv_sec - start.tv_sec) ; // in seconds
int st = getrusage(RUSAGE_SELF,&usage);
if (!st) {
pf("\nRun time: %lluh %llus\n",(unsigned long long)elapse/3600,(unsigned long long)(elapse - (elapse/3600)));
pf("\tTime executing user inst.: %lds %ldus\n",(long)usage.ru_utime.tv_sec,(long)usage.ru_utime.tv_usec);
pf("\tTime executing system inst.: %lds %ldus\n",(long)usage.ru_stime.tv_sec,(long)usage.ru_stime.tv_usec);
pf("\tMax. Phy. memory usage: %ldkB\n",(long)usage.ru_maxrss);
pf("\tPage fault number (no io): %ld\n",(long)usage.ru_minflt);
pf("\tPage fault number (requiring io): %ld\n",(long)usage.ru_majflt);
pf("\tNumber of file system read: %ld\n",(long)usage.ru_inblock);
pf("\tNumber of filesystem write: %ld\n",(long)usage.ru_oublock);
pf("\tNumber of context switch (process origin, io...): %ld\n",(long)usage.ru_nvcsw);
pf("\tNumber of context switch (os origin, priority...): %ld\n",(long)usage.ru_nivcsw);
}
struct rusage usage;
struct timespec stop;
clock_gettime(CLOCK_BOOTTIME, &stop);
uint64_t elapse = (stop.tv_sec - start.tv_sec) ; // in seconds
int st = getrusage(RUSAGE_SELF,&usage);
if (!st) {
pf("\nRun time: %lluh %llus\n",(unsigned long long)elapse/3600,(unsigned long long)(elapse - (elapse/3600)));
pf("\tTime executing user inst.: %lds %ldus\n",(long)usage.ru_utime.tv_sec,(long)usage.ru_utime.tv_usec);
pf("\tTime executing system inst.: %lds %ldus\n",(long)usage.ru_stime.tv_sec,(long)usage.ru_stime.tv_usec);
pf("\tMax. Phy. memory usage: %ldkB\n",(long)usage.ru_maxrss);
pf("\tPage fault number (no io): %ld\n",(long)usage.ru_minflt);
pf("\tPage fault number (requiring io): %ld\n",(long)usage.ru_majflt);
pf("\tNumber of file system read: %ld\n",(long)usage.ru_inblock);
pf("\tNumber of filesystem write: %ld\n",(long)usage.ru_oublock);
pf("\tNumber of context switch (process origin, io...): %ld\n",(long)usage.ru_nvcsw);
pf("\tNumber of context switch (os origin, priority...): %ld\n",(long)usage.ru_nivcsw);
}
}
void signal_handler(int sig) {
......@@ -160,9 +160,9 @@ void signal_handler(int sig) {
backtrace_symbols_fd(array, size, 2);
exit(-1);
} else {
if(sig==SIGINT ||sig==SOFTMODEM_RTSIGNAL)
softmodem_printresources(sig,(telnet_printfunc_t)printf);
if (sig != SOFTMODEM_RTSIGNAL) {
if(sig==SIGINT ||sig==SOFTMODEM_RTSIGNAL)
softmodem_printresources(sig,(telnet_printfunc_t)printf);
if (sig != SOFTMODEM_RTSIGNAL) {
printf("Linux signal %s...\n",strsignal(sig));
exit_function(__FILE__, __FUNCTION__, __LINE__,"softmodem starting exit procedure\n");
}
......@@ -172,7 +172,7 @@ void signal_handler(int sig) {
void set_softmodem_sighandler(void) {
struct sigaction act,oldact;
struct sigaction act,oldact;
clock_gettime(CLOCK_BOOTTIME, &start);
memset(&act,0,sizeof(act));
act.sa_handler=signal_handler;
......@@ -181,5 +181,5 @@ void set_softmodem_sighandler(void) {
signal(SIGSEGV, signal_handler);
signal(SIGINT, signal_handler);
signal(SIGTERM, signal_handler);
signal(SIGABRT, signal_handler);
signal(SIGABRT, signal_handler);
}
......@@ -37,6 +37,11 @@ extern "C"
#endif
/* help strings definition for command line options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */
#define CONFIG_HLP_RFCFGF "Configuration file for front-end (e.g. LMS7002M)\n"
#define CONFIG_HLP_SPLIT73 "Split 7.3 (below rate matching) option: <cu|du>:<remote ip address>:<remote port>"
#define CONFIG_HLP_TPOOL "Thread pool configuration: \n\
default no pool (runs in calling thread),\n\
list of cores, comma separated (negative value is no core affinity)\n\
example: -1,3 launches two working threads one floating, the second set on core 3"
#define CONFIG_HLP_ULMAXE "set the eNodeB max ULSCH erros\n"
#define CONFIG_HLP_CALUER "set UE RX calibration\n"
#define CONFIG_HLP_CALUERM ""
......@@ -87,6 +92,7 @@ extern "C"
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*-----------------------------------------------------------------------------------------------------------------------------------------------------*/
#define RF_CONFIG_FILE softmodem_params.rf_config_file
#define SPLIT73 softmodem_params.split73
#define TP_CONFIG softmodem_params.threadPoolConfig
#define PHY_TEST softmodem_params.phy_test
#define WAIT_FOR_SYNC softmodem_params.wait_for_sync
......@@ -103,6 +109,8 @@ extern "C"
#define CMDLINE_PARAMS_DESC { \
{"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&RF_CONFIG_FILE, defstrval:NULL, TYPE_STRING, sizeof(RF_CONFIG_FILE)},\
{"split73", CONFIG_HLP_SPLIT73, 0, strptr:(char **)&SPLIT73, defstrval:NULL, TYPE_STRING, sizeof(SPLIT73)},\
{"thread-pool", CONFIG_HLP_TPOOL, 0, strptr:(char **)&TP_CONFIG, defstrval:"n", TYPE_STRING, sizeof(TP_CONFIG)}, \
{"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&PHY_TEST, defintval:0, TYPE_INT, 0}, \
{"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&USIM_TEST, defintval:0, TYPE_UINT8, 0}, \
{"clock", CONFIG_HLP_CLK, 0, uptr:&CLOCK_SOURCE, defintval:0, TYPE_UINT, 0}, \
......@@ -179,6 +187,7 @@ typedef struct {
uint64_t optmask;
THREAD_STRUCT thread_struct;
char rf_config_file[1024];
char split73[1024];
char threadPoolConfig[1024];
int phy_test;
uint8_t usim_test;
......
......@@ -5,10 +5,11 @@
#include <stdbool.h>
#include <openair1/PHY/defs_eNB.h>
#define CU_IP "127.0.0.1"
#define CU_PORT "7878"
#define DU_IP "127.0.0.1"
#define DU_PORT "8787"
#define SPLIT73_CU 1
#define SPLIT73_DU 2
extern int split73;
#define MTU 65536
#define UDP_TIMEOUT 900000L // in micro second (struct timeval, NOT struct timespec)
......
......@@ -310,7 +310,7 @@ static void TPencode(void * arg) {
lte_rate_matching_turbo(hadlsch->RTC[rdata->r],
rdata->G, //G
hadlsch->w[rdata->r],
hadlsch->e+rdata->r_offset,
hadlsch->eDL+rdata->r_offset,
hadlsch->C, // C
rdata->dlsch->Nsoft, // Nsoft,
rdata->dlsch->Mdlharq,
......@@ -389,7 +389,7 @@ int dlsch_encoding(PHY_VARS_eNB *eNB,
for (int r=0, r_offset=0; r<hadlsch->C; r++) {
union turboReqUnion id= {.s={dlsch->rnti,frame,subframe,r,0}};
notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(turboEncode_t), id.p, &proc->respEncode, TPencode);
notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(turboEncode_t), id.p, proc->respEncode, TPencode);
turboEncode_t * rdata=(turboEncode_t *) NotifiedFifoData(req);
rdata->input=hadlsch->c[r];
rdata->Kr_bytes= ( r<hadlsch->Cminus ? hadlsch->Kminus : hadlsch->Kplus) >>3;
......@@ -404,8 +404,8 @@ int dlsch_encoding(PHY_VARS_eNB *eNB,
rdata->r_offset=r_offset;
rdata->G=G;
if ( proc->threadPool.activated) {
pushTpool(&proc->threadPool,req);
if ( proc->threadPool->activated ) {
pushTpool(proc->threadPool,req);
proc->nbEncode++;
} else {
TPencode(rdata);
......
......@@ -158,7 +158,7 @@ int allocate_REs_in_RB_no_pilots_QPSK_siso(PHY_VARS_eNB* phy_vars_eNB,
{
LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->frame_parms;
uint8_t *x0 = dlsch0_harq->e;
uint8_t *x0 = dlsch0_harq->eDL;
uint32_t qpsk_table_offset_re = 0;
uint32_t qpsk_table_offset_im = 0;
......@@ -248,7 +248,7 @@ int allocate_REs_in_RB_pilots_QPSK_siso(PHY_VARS_eNB* phy_vars_eNB,
LTE_DL_FRAME_PARMS *frame_parms=&phy_vars_eNB->frame_parms;
uint8_t *x0 = dlsch0_harq->e;
uint8_t *x0 = dlsch0_harq->eDL;
uint32_t qpsk_table_offset_re = 0;
uint32_t qpsk_table_offset_im = 0;
......@@ -343,7 +343,7 @@ int allocate_REs_in_RB_no_pilots_16QAM_siso(PHY_VARS_eNB* phy_vars_eNB,
{
LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->frame_parms;
uint8_t *x0 = dlsch0_harq->e;
uint8_t *x0 = dlsch0_harq->eDL;
uint32_t qam16_table_offset_re = 0;
uint32_t qam16_table_offset_im = 0;
......@@ -439,7 +439,7 @@ int allocate_REs_in_RB_pilots_16QAM_siso(PHY_VARS_eNB* phy_vars_eNB,
LTE_DL_FRAME_PARMS *frame_parms=&phy_vars_eNB->frame_parms;
uint8_t *x0 = dlsch0_harq->e;
uint8_t *x0 = dlsch0_harq->eDL;
uint32_t qam16_table_offset_re = 0;
uint32_t qam16_table_offset_im = 0;
......@@ -542,7 +542,7 @@ int allocate_REs_in_RB_no_pilots_64QAM_siso(PHY_VARS_eNB* phy_vars_eNB,
LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->frame_parms;
uint8_t *x0 = dlsch0_harq->e;
uint8_t *x0 = dlsch0_harq->eDL;
uint32_t qam64_table_offset_re = 0;
uint32_t qam64_table_offset_im = 0;
......@@ -699,7 +699,7 @@ int allocate_REs_in_RB_pilots_64QAM_siso(PHY_VARS_eNB* phy_vars_eNB,
LTE_DL_FRAME_PARMS *frame_parms=&phy_vars_eNB->frame_parms;
uint8_t *x0 = dlsch0_harq->e;
uint8_t *x0 = dlsch0_harq->eDL;
uint32_t qam64_table_offset_re = 0;
uint32_t qam64_table_offset_im = 0;
......@@ -866,12 +866,12 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB,
if ((dlsch0_harq != NULL) && (dlsch1_harq != NULL)) { //this is for TM3, TM4
x0 = dlsch0_harq->e;
x0 = dlsch0_harq->eDL;
mimo_mode = dlsch0_harq->mimo_mode;
first_layer0 = dlsch0_harq->first_layer;
Nlayers0 = dlsch0_harq->Nlayers;
mod_order0 = dlsch0_harq->Qm;
x1 = dlsch1_harq->e;
x1 = dlsch1_harq->eDL;
// Fill these in later for TM8-10
// Nlayers1 = dlsch1_harq->Nlayers;
// first_layer1 = dlsch1_harq->first_layer;
......@@ -879,7 +879,7 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB,
} else if ((dlsch0_harq != NULL) && (dlsch1_harq == NULL)){ //This is for SIS0 TM1, TM6, etc
x0 = dlsch0_harq->e;
x0 = dlsch0_harq->eDL;
mimo_mode = dlsch0_harq->mimo_mode;
first_layer0 = dlsch0_harq->first_layer;
Nlayers0 = dlsch0_harq->Nlayers;
......@@ -887,7 +887,7 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB,
} else if ((dlsch0_harq == NULL) && (dlsch1_harq != NULL)){ // This is for TM4 retransmission
x0 = dlsch1_harq->e;
x0 = dlsch1_harq->eDL;
mimo_mode = dlsch1_harq->mimo_mode;
first_layer0 = dlsch1_harq->first_layer;
Nlayers0 = dlsch1_harq->Nlayers;
......@@ -2692,7 +2692,7 @@ int dlsch_modulation_SIC(int32_t **sic_buffer,
LTE_DL_eNB_HARQ_t *dlsch0_harq = dlsch0->harq_processes[harq_pid];
uint32_t i,jj,re_allocated=0;
uint8_t mod_order0 = dlsch0_harq->Qm;
uint8_t *x0 = dlsch0_harq->e;
uint8_t *x0 = dlsch0_harq->eDL;
uint8_t qam64_table_offset_re = 0;
uint8_t qam64_table_offset_im = 0;
uint8_t qam16_table_offset_re = 0;
......@@ -2883,7 +2883,7 @@ int mch_modulation(int32_t **txdataF,
&jj,
re_offset,
symbol_offset,
dlsch->harq_processes[0]->e,
dlsch->harq_processes[0]->eDL,
l,
mod_order,
amp,
......
......@@ -52,7 +52,7 @@ void dlsch_scrambling(LTE_DL_FRAME_PARMS *frame_parms,
int n;
// uint8_t reset;
uint32_t x1, x2, s=0;
uint8_t *dlsch_e=dlsch->harq_processes[harq_pid]->e;
uint8_t *dlsch_e=dlsch->harq_processes[harq_pid]->eDL;
uint8_t *e=dlsch_e;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_SCRAMBLING, VCD_FUNCTION_IN);
// Rule for accumulation of subframes for BL/CE UEs
......
......@@ -100,7 +100,7 @@ typedef struct {
/// start symbold of pdsch
uint8_t pdsch_start;
/// Concatenated "e"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18)
uint8_t e[MAX_NUM_CHANNEL_BITS] __attribute__((aligned(32)));
uint8_t eDL[MAX_NUM_CHANNEL_BITS] __attribute__((aligned(32)));
/// Turbo-code outputs (36-212 V8.6 2009-03, p.12
uint8_t *d[MAX_NUM_DLSCH_SEGMENTS];//[(96+3+(3*6144))];
/// Sub-block interleaver outputs (36-212 V8.6 2009-03, p.16-17)
......@@ -261,11 +261,11 @@ typedef struct {
/// coded RI bits
int16_t q_RI[MAX_RI_PAYLOAD];
/// Concatenated "e"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18)
int16_t e[MAX_NUM_CHANNEL_BITS] __attribute__((aligned(32)));
int16_t eUL[MAX_NUM_CHANNEL_BITS] __attribute__((aligned(32)));
/// Temporary h sequence to flag PUSCH_x/PUSCH_y symbols which are not scrambled
uint8_t h[MAX_NUM_CHANNEL_BITS];
/// Pointer to the payload
uint8_t *b;
uint8_t *decodedBytes;
/// Pointers to transport block segments
//TBD
uint8_t *c[MAX_NUM_ULSCH_SEGMENTS];
......
......@@ -54,9 +54,9 @@ void free_eNB_ulsch(LTE_eNB_ULSCH_t *ulsch) {
if (ulsch) {
for (i=0; i<8; i++) {
if (ulsch->harq_processes[i]) {
if (ulsch->harq_processes[i]->b) {
free16(ulsch->harq_processes[i]->b,MAX_ULSCH_PAYLOAD_BYTES);
ulsch->harq_processes[i]->b = NULL;
if (ulsch->harq_processes[i]->decodedBytes) {
free16(ulsch->harq_processes[i]->decodedBytes,MAX_ULSCH_PAYLOAD_BYTES);
ulsch->harq_processes[i]->decodedBytes = NULL;
}
for (r=0; r<MAX_NUM_ULSCH_SEGMENTS; r++) {
......@@ -115,10 +115,10 @@ LTE_eNB_ULSCH_t *new_eNB_ulsch(uint8_t max_turbo_iterations,uint8_t N_RB_UL, uin
if (ulsch->harq_processes[i]) {
memset(ulsch->harq_processes[i],0,sizeof(LTE_UL_eNB_HARQ_t));
ulsch->harq_processes[i]->b = (uint8_t *)malloc16(MAX_ULSCH_PAYLOAD_BYTES/bw_scaling);
ulsch->harq_processes[i]->decodedBytes = (uint8_t *)malloc16(MAX_ULSCH_PAYLOAD_BYTES/bw_scaling);
if (ulsch->harq_processes[i]->b)
memset(ulsch->harq_processes[i]->b,0,MAX_ULSCH_PAYLOAD_BYTES/bw_scaling);
if (ulsch->harq_processes[i]->decodedBytes)
memset(ulsch->harq_processes[i]->decodedBytes,0,MAX_ULSCH_PAYLOAD_BYTES/bw_scaling);
else
exit_flag=3;
......@@ -229,7 +229,7 @@ void processULSegment(void * arg) {
G,
ulsch_harq->w[r],
(uint8_t *) &dummy_w[0],
ulsch_harq->e+rdata->r_offset,
ulsch_harq->eUL+rdata->r_offset,
ulsch_harq->C,
NSOFT,
0, //Uplink
......@@ -327,19 +327,15 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc,
E = ulsch_harq->Qm * (Gp/ulsch_harq->C);
else
E = ulsch_harq->Qm * ((GpmodC==0?0:1) + (Gp/ulsch_harq->C));
#ifdef FS6
if ( getenv("fs6") != NULL && strncasecmp( getenv("fs6"), "du", 2) == 0 ) {
sendFs6Ul(eNB, UE_id, harq_pid, r, ulsch_harq->e+r_offset, E*sizeof(int16_t), r_offset);
if ( split73 == SPLIT73_DU ) {
sendFs6Ul(eNB, UE_id, harq_pid, r, ulsch_harq->eUL+r_offset, E*sizeof(int16_t), r_offset);
r_offset += E;
continue;
}
#endif
union turboReqUnion id= {.s={ulsch->rnti,proc->frame_rx,proc->subframe_rx,0,0}};
notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(turboDecode_t), id.p, &proc->respDecode, processULSegment);
notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(turboDecode_t), id.p, proc->respDecode, processULSegment);
turboDecode_t * rdata=(turboDecode_t *) NotifiedFifoData(req);
rdata->eNB=eNB;
......@@ -359,7 +355,7 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc,
rdata->function=td;
int Fbytes=(r==0) ? rdata->Fbits>>3 : 0;
int sz=Kr_bytes - Fbytes - ((ulsch_harq->C>1)?3:0);
pushTpool(&proc->threadPool,req);
pushTpool(proc->threadPool,req);
proc->nbDecode++;
LOG_D(PHY,"Added a block to decode, in pipe: %d\n",proc->nbDecode);
r_offset+=E;
......@@ -892,8 +888,8 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,
j2+=2;
}
ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->eUL[iprime++] = y[j2++];
ulsch_harq->eUL[iprime++] = y[j2++];
}
break;
......@@ -905,10 +901,10 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,
j2+=4;
}
ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->eUL[iprime++] = y[j2++];
ulsch_harq->eUL[iprime++] = y[j2++];
ulsch_harq->eUL[iprime++] = y[j2++];
ulsch_harq->eUL[iprime++] = y[j2++];
}
break;
......@@ -920,12 +916,12 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,
j2+=6;
}
ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->eUL[iprime++] = y[j2++];
ulsch_harq->eUL[iprime++] = y[j2++];
ulsch_harq->eUL[iprime++] = y[j2++];
ulsch_harq->eUL[iprime++] = y[j2++];
ulsch_harq->eUL[iprime++] = y[j2++];
ulsch_harq->eUL[iprime++] = y[j2++];
}
break;
......@@ -963,7 +959,7 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,
*/
int16_t *yp,*ep;
for (iprime=0,yp=&y[j2],ep=&ulsch_harq->e[0];
for (iprime=0,yp=&y[j2],ep=&ulsch_harq->eUL[0];
iprime<G;
iprime+=8,j2+=8,ep+=8,yp+=8) {
ep[0] = yp[0];
......
......@@ -793,7 +793,7 @@ int dlsch_encoding_SIC(PHY_VARS_UE *ue,
r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r],
G, //G
dlsch->harq_processes[harq_pid]->w[r],
dlsch->harq_processes[harq_pid]->e+r_offset,
dlsch->harq_processes[harq_pid]->eDL+r_offset,
dlsch->harq_processes[harq_pid]->C, // C
dlsch->Nsoft, // Nsoft,
dlsch->Mdlharq,
......
......@@ -2032,7 +2032,7 @@ uint16_t nr_dci_format_size (PHY_VARS_NR_UE *ue,
ul_res_alloc_type_1 = 1;
}
uint8_t n_bits_freq_dom_res_assign_ul=0,n_ul_RGB_tmp;
uint8_t n_bits_freq_dom_res_assign_ul=0,n_ul_RGB_tmp=0;
if (ul_res_alloc_type_0 == 1) { // implementation of Table 6.1.2.2.1-1 TC 38.214 subclause 6.1.2.2.1
// config1: PUSCH-Config IE contains rbg-Size ENUMERATED {config1 config2}
......
......@@ -320,10 +320,10 @@ bool dlsch_procedures(PHY_VARS_eNB *eNB,
&eNB->dlsch_interleaving_stats);
stop_meas(&eNB->dlsch_encoding_stats);
if ( proc->threadPool.activated ) {
if ( proc->threadPool->activated ) {
// Wait all other threads finish to process
while (proc->nbEncode) {
delNotifiedFIFO_elt(pullTpool(&proc->respEncode, &proc->threadPool));
delNotifiedFIFO_elt(pullTpool(proc->respEncode, proc->threadPool));
proc->nbEncode--;
}
}
......@@ -604,12 +604,11 @@ void srs_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
}
void fill_sr_indication(int UEid, PHY_VARS_eNB *eNB,uint16_t rnti,int frame,int subframe,uint32_t stat) {
#ifdef FS6
if ( getenv("fs6") != NULL && strncasecmp( getenv("fs6"), "du", 2) == 0 ) {
if ( split73 == SPLIT73_DU ) {
sendFs6Ulharq(fs6ULindicationSr, UEid, eNB, NULL, frame, subframe, NULL,0,0, rnti, stat);
return;
}
#endif
pthread_mutex_lock(&eNB->UL_INFO_mutex);
nfapi_sr_indication_t *sr_ind = &eNB->UL_INFO.sr_ind;
nfapi_sr_indication_body_t *sr_ind_body = &sr_ind->sr_indication_body;
......@@ -1175,13 +1174,13 @@ void postDecode(L1_rxtx_proc_t *proc, notifiedFIFO_elt_t *req) {
if (decodeSucess) {
int Fbytes=(rdata->segment_r==0) ? rdata->Fbits>>3 : 0;
int sz=(rdata->Kr>>3) - Fbytes - ((ulsch_harq->C>1)?3:0);
memcpy(ulsch_harq->b+rdata->offset,
memcpy(ulsch_harq->decodedBytes+rdata->offset,
rdata->decoded_bytes+Fbytes,
sz);
} else {
if ( rdata->nbSegments != ulsch_harq->processedSegments ) {
int nb=abortTpool(&proc->threadPool, req->key);
nb+=abortNotifiedFIFO(&proc->respDecode, req->key);
int nb=abortTpool(proc->threadPool, req->key);
nb+=abortNotifiedFIFO(proc->respDecode, req->key);
proc->nbDecode-=nb;
LOG_I(PHY,"uplink segment error %d/%d, aborted %d segments\n",rdata->segment_r,rdata->nbSegments, nb);
AssertFatal(ulsch_harq->processedSegments+nb == rdata->nbSegments,"processed: %d, aborted: %d, total %d\n",
......@@ -1329,7 +1328,7 @@ void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
} // for (i=0; i<NUMBER_OF_UE_MAX; i++)
while (proc->nbDecode > 0) {
notifiedFIFO_elt_t *req=pullTpool(&proc->respDecode, &proc->threadPool);
notifiedFIFO_elt_t *req=pullTpool(proc->respDecode, proc->threadPool);
postDecode(proc, req);
delNotifiedFIFO_elt(req);
}
......@@ -1415,7 +1414,7 @@ void fill_rx_indication(PHY_VARS_eNB *eNB,
pdu->rx_indication_rel8.tl.tag = NFAPI_RX_INDICATION_REL8_TAG;
pdu->rx_indication_rel8.length = eNB->ulsch[UE_id]->harq_processes[harq_pid]->TBS>>3;
pdu->rx_indication_rel8.offset = 1; // DJP - I dont understand - but broken unless 1 ???? 0; // filled in at the end of the UL_INFO formation
pdu->data = eNB->ulsch[UE_id]->harq_processes[harq_pid]->b;
pdu->data = eNB->ulsch[UE_id]->harq_processes[harq_pid]->decodedBytes;
// estimate timing advance for MAC
sync_pos = lte_est_timing_advance_pusch(eNB,UE_id);
timing_advance_update = sync_pos; // - eNB->frame_parms.nb_prefix_samples/4; //to check
......@@ -1749,12 +1748,10 @@ void fill_ulsch_harq_indication (PHY_VARS_eNB *eNB, LTE_UL_eNB_HARQ_t *ulsch_har
}
void fill_uci_harq_indication (int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, int frame, int subframe, uint8_t *harq_ack, uint8_t tdd_mapping_mode, uint16_t tdd_multiplexing_mask) {
#ifdef FS6
if ( getenv("fs6") != NULL && strncasecmp( getenv("fs6"), "du", 2) == 0 ) {
if ( split73 == SPLIT73_DU ) {
sendFs6Ulharq(fs6ULindicationHarq, UEid, eNB, uci, frame, subframe, harq_ack, tdd_mapping_mode, tdd_multiplexing_mask, 0, 0);
return;
}
#endif
int UE_id=find_dlsch(uci->rnti,eNB,SEARCH_EXIST);
......
......@@ -1266,9 +1266,12 @@ int main(int argc, char **argv) {
}
L1_rxtx_proc_t *proc_eNB = &eNB->proc.L1_proc;
initTpool("n", &proc_eNB->threadPool, true);
initNotifiedFIFO(&proc_eNB->respEncode);
initNotifiedFIFO(&proc_eNB->respDecode);
proc_eNB->threadPool=(tpool_t*)malloc(sizeof(tpool_t));
proc_eNB->respEncode=(notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
proc_eNB->respDecode=(notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
initTpool("n", proc_eNB->threadPool, true);
initNotifiedFIFO(proc_eNB->respEncode);
initNotifiedFIFO(proc_eNB->respDecode);
proc_eNB->frame_tx=0;
......
......@@ -793,9 +793,12 @@ int main(int argc, char **argv) {
proc_rxtx_ue->frame_rx = (subframe<4)?(proc_rxtx->frame_tx-1):(proc_rxtx->frame_tx);
proc_rxtx_ue->subframe_tx = proc_rxtx->subframe_rx;
proc_rxtx_ue->subframe_rx = (proc_rxtx->subframe_tx+6)%10;
initTpool("n", &proc_rxtx->threadPool, true);
initNotifiedFIFO(&proc_rxtx->respEncode);
initNotifiedFIFO(&proc_rxtx->respDecode);
proc_rxtx->threadPool=(tpool_t*)malloc(sizeof(tpool_t));
proc_rxtx->respEncode=(notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
proc_rxtx->respDecode=(notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
initTpool("n",proc_rxtx->threadPool, true);
initNotifiedFIFO(proc_rxtx->respEncode);
initNotifiedFIFO(proc_rxtx->respDecode);
printf("Init UL hopping UE\n");
init_ul_hopping(&UE->frame_parms);
......
......@@ -176,11 +176,11 @@ typedef struct {
pthread_cond_t cond_RUs;
/// mutex for RXn-TXnp4 processing thread
pthread_mutex_t mutex_RUs;
tpool_t threadPool;
tpool_t *threadPool;
int nbEncode;
int nbDecode;
notifiedFIFO_t respEncode;
notifiedFIFO_t respDecode;
notifiedFIFO_t *respEncode;
notifiedFIFO_t *respDecode;
pthread_mutex_t mutex_emulateRF;
int instance_cnt_emulateRF;
pthread_t pthread_emulateRF;
......
......@@ -346,7 +346,7 @@ static int rfsimulator_write_internal(rfsimulator_state_t *t, openair0_timestamp
if ( t->lastWroteTS != 0 && abs((double)t->lastWroteTS-timestamp) > (double)CirSize)
LOG_E(HW,"Discontinuous TX gap too large Tx:%lu, %lu\n", t->lastWroteTS, timestamp);
if (t->lastWroteTS >= timestamp+1)
if (t->lastWroteTS > timestamp+nsamps)
LOG_E(HW,"Not supported to send Tx out of order (same in USRP) %lu, %lu\n",
t->lastWroteTS, timestamp);
t->lastWroteTS=timestamp+nsamps;
......@@ -468,8 +468,8 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi
} else if ( b->lastReceivedTS == b->th.timestamp ) {
// normal case
} else {
abort();
AssertFatal(false, "received data in past: current is %lu, new reception: %lu!\n", b->lastReceivedTS, b->th.timestamp);
LOG_E(HW, "received data in past: current is %lu, new reception: %lu!\n", b->lastReceivedTS, b->th.timestamp);
b->trashingPacket=true;
}
pthread_mutex_lock(&Sockmutex);
......
......@@ -41,6 +41,7 @@
# include "f1ap_du_task.h"
# include "enb_app.h"
# include "openair2/LAYER2/MAC/mac_proto.h"
#include <executables/split_headers.h>
extern RAN_CONTEXT_t RC;
......@@ -50,25 +51,21 @@ int create_tasks(uint32_t enb_nb) {
int rc;
if (enb_nb == 0) return 0;
bool fs6Du=false;
if ( getenv("fs6") != NULL && strncasecmp( getenv("fs6"), "du", 2) == 0 )
fs6Du=true;
LOG_I(ENB_APP, "Creating ENB_APP eNB Task\n");
rc = itti_create_task (TASK_ENB_APP, eNB_app_task, NULL);
AssertFatal(rc >= 0, "Create task for eNB APP failed\n");
LOG_I(RRC,"Creating RRC eNB Task\n");
rc = itti_create_task (TASK_RRC_ENB, rrc_enb_task, NULL);
AssertFatal(rc >= 0, "Create task for RRC eNB failed\n");
// No more rrc thread, as many race conditions are hidden behind
rrc_enb_init();
itti_mark_task_ready(TASK_RRC_ENB);
if (EPC_MODE_ENABLED && !fs6Du ) {
if (EPC_MODE_ENABLED && ! ( split73==SPLIT73_DU ) ) {
rc = itti_create_task(TASK_SCTP, sctp_eNB_task, NULL);
AssertFatal(rc >= 0, "Create task for SCTP failed\n");
}
if (EPC_MODE_ENABLED && !NODE_IS_DU(type) && !fs6Du ) {
if (EPC_MODE_ENABLED && !NODE_IS_DU(type) && ! ( split73==SPLIT73_DU ) ) {
rc = itti_create_task(TASK_S1AP, s1ap_eNB_task, NULL);
AssertFatal(rc >= 0, "Create task for S1AP failed\n");
if (!(get_softmodem_params()->emulate_rf)){
......
......@@ -93,6 +93,7 @@ unsigned short config_frames[4] = {2,9,11,13};
#include "lte-softmodem.h"
#include "NB_IoT_interface.h"
#include <executables/split_headers.h>
pthread_cond_t nfapi_sync_cond;
......@@ -152,6 +153,13 @@ int otg_enabled;
uint64_t num_missed_slots=0; // counter for the number of missed slots
int split73=0;
void sendFs6Ul(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int segmentID, int16_t *data, int dataLen, int r_offset) {
AssertFatal(false, "Must not be called in this context\n");
}
void sendFs6Ulharq(enum pckType type, int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, int frame, int subframe, uint8_t *harq_ack, uint8_t tdd_mapping_mode, uint16_t tdd_multiplexing_mask, uint16_t rnti, int32_t stat) {
AssertFatal(false, "Must not be called in this context\n");
}
extern void reset_opp_meas(void);
extern void print_opp_meas(void);
......@@ -438,12 +446,9 @@ int restart_L1L2(module_id_t enb_id) {
init_UE_list(&RC.mac[enb_id]->UE_list);
LOG_I(ENB_APP, "attempting to create ITTI tasks\n");
if (itti_create_task (TASK_RRC_ENB, rrc_enb_task, NULL) < 0) {
LOG_E(RRC, "Create task for RRC eNB failed\n");
return -1;
} else {
LOG_I(RRC, "Re-created task for RRC eNB successfully\n");
}
// No more rrc thread, as many race conditions are hidden behind
rrc_enb_init();
itti_mark_task_ready(TASK_RRC_ENB);
/* pass a reconfiguration request which will configure everything down to
* RC.eNB[i][j]->frame_parms, too */
......@@ -477,8 +482,7 @@ void init_pdcp(void) {
pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_W_MBMS_BIT;
if ( getenv("fs6") != NULL && strncasecmp( getenv("fs6"), "du", 2) == 0 )
pdcp_module_init(pdcp_initmask);
pdcp_module_init(pdcp_initmask);
if (NODE_IS_CU(RC.rrc[0]->node_type)) {
pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t)proto_agent_send_rlc_data_req);
......@@ -643,12 +647,15 @@ int main ( int argc, char **argv )
for (int x=0; x < RC.nb_L1_inst; x++)
for (int CC_id=0; CC_id<RC.nb_L1_CC[x]; CC_id++) {
L1_rxtx_proc_t *L1proc= &RC.eNB[x][CC_id]->proc.L1_proc;
L1proc->threadPool=(tpool_t*)malloc(sizeof(tpool_t));
L1proc->respEncode=(notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
L1proc->respDecode=(notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
if ( strlen(get_softmodem_params()->threadPoolConfig) > 0 )
initTpool(get_softmodem_params()->threadPoolConfig, &L1proc->threadPool, true);
initTpool(get_softmodem_params()->threadPoolConfig, L1proc->threadPool, true);
else
initTpool("n", &L1proc->threadPool, true);
initNotifiedFIFO(&L1proc->respEncode);
initNotifiedFIFO(&L1proc->respDecode);
initTpool("n", L1proc->threadPool, true);
initNotifiedFIFO(L1proc->respEncode);
initNotifiedFIFO(L1proc->respDecode);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment