add simple main
This commit is contained in:
@@ -2115,6 +2115,40 @@ target_link_libraries (lte-softmodem
|
||||
NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
|
||||
-Wl,--end-group z dl)
|
||||
|
||||
|
||||
add_executable(simple-softmodem
|
||||
${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c
|
||||
${OPENAIR_DIR}/executables/simple_main.c
|
||||
${OPENAIR_TARGETS}/RT/USER/lte-softmodem.c
|
||||
${OPENAIR_TARGETS}/RT/USER/lte-softmodem-common.c
|
||||
${OPENAIR2_DIR}/ENB_APP/NB_IoT_interface.c
|
||||
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
|
||||
${OPENAIR_TARGETS}/COMMON/create_tasks.c
|
||||
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
|
||||
${OPENAIR2_DIR}/RRC/NAS/nas_config.c
|
||||
${OPENAIR2_DIR}/RRC/NAS/rb_config.c
|
||||
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
|
||||
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/multicast_link.c
|
||||
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/socket.c
|
||||
${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c
|
||||
${OPENAIR_DIR}/common/utils/utils.c
|
||||
${OPENAIR_DIR}/common/utils/system.c
|
||||
${GTPU_need_ITTI}
|
||||
${XFORMSINTERFACE_SOURCE}
|
||||
${T_SOURCE}
|
||||
${CONFIG_SOURCES}
|
||||
${SHLIB_LOADER_SOURCES}
|
||||
)
|
||||
add_dependencies(simple-softmodem rrc_flag s1ap_flag x2_flag)
|
||||
|
||||
target_link_libraries (simple-softmodem
|
||||
-Wl,--start-group
|
||||
RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP X2AP_LIB X2AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB PHY_COMMON PHY PHY_RU LFDS L2
|
||||
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB} LFDS7
|
||||
NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
|
||||
-Wl,--end-group z dl)
|
||||
target_link_libraries (simple-softmodem ${LIBXML2_LIBRARIES} pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${LIB_LMS_LIBRARIES} ${T_LIB})
|
||||
|
||||
add_executable(cu_test
|
||||
${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/cu_test.c
|
||||
${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/proto_agent_handler.c
|
||||
|
||||
+63
-67
@@ -8,7 +8,6 @@ void pdsch_procedures(PHY_VARS_eNB *eNB,
|
||||
LTE_eNB_DLSCH_t *dlsch1,
|
||||
LTE_eNB_UE_stats *ue_stats,
|
||||
int ra_flag) {
|
||||
|
||||
int frame=proc->frame_tx;
|
||||
int subframe=proc->subframe_tx;
|
||||
LTE_DL_eNB_HARQ_t *dlsch_harq=dlsch->harq_processes[harq_pid];
|
||||
@@ -16,24 +15,22 @@ void pdsch_procedures(PHY_VARS_eNB *eNB,
|
||||
|
||||
// 36-212
|
||||
if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) { // monolthic OR PNF - do not need turbo encoding on VNF
|
||||
|
||||
// Replace dlsch_encoding
|
||||
// data is in
|
||||
// data is in
|
||||
// dlsch->harq_processes[harq_pid]->e
|
||||
feedDlschBuffers(eNB,
|
||||
dlsch_harq->pdu,
|
||||
dlsch_harq->pdsch_start,
|
||||
dlsch,
|
||||
frame,
|
||||
subframe,
|
||||
&eNB->dlsch_rate_matching_stats,
|
||||
&eNB->dlsch_turbo_encoding_stats,
|
||||
&eNB->dlsch_turbo_encoding_waiting_stats,
|
||||
&eNB->dlsch_turbo_encoding_main_stats,
|
||||
&eNB->dlsch_turbo_encoding_wakeup_stats0,
|
||||
&eNB->dlsch_turbo_encoding_wakeup_stats1,
|
||||
&eNB->dlsch_interleaving_stats);
|
||||
|
||||
dlsch_harq->pdu,
|
||||
dlsch_harq->pdsch_start,
|
||||
dlsch,
|
||||
frame,
|
||||
subframe,
|
||||
&eNB->dlsch_rate_matching_stats,
|
||||
&eNB->dlsch_turbo_encoding_stats,
|
||||
&eNB->dlsch_turbo_encoding_waiting_stats,
|
||||
&eNB->dlsch_turbo_encoding_main_stats,
|
||||
&eNB->dlsch_turbo_encoding_wakeup_stats0,
|
||||
&eNB->dlsch_turbo_encoding_wakeup_stats1,
|
||||
&eNB->dlsch_interleaving_stats);
|
||||
// 36-211
|
||||
dlsch_scrambling(fp,
|
||||
0,
|
||||
@@ -65,7 +62,6 @@ void pdsch_procedures(PHY_VARS_eNB *eNB,
|
||||
}
|
||||
|
||||
phy_procedures_eNB_TX_fs6() {
|
||||
|
||||
receiveSubFrame();
|
||||
|
||||
// We got
|
||||
@@ -74,10 +70,10 @@ phy_procedures_eNB_TX_fs6() {
|
||||
|
||||
for (aa = 0; aa < fp->nb_antenna_ports_eNB; aa++) {
|
||||
memset (&eNB->common_vars.txdataF[aa][subframe * fp->ofdm_symbol_size * fp->symbols_per_tti],
|
||||
0,
|
||||
fp->ofdm_symbol_size * (fp->symbols_per_tti) * sizeof (int32_t));
|
||||
0,
|
||||
fp->ofdm_symbol_size * (fp->symbols_per_tti) * sizeof (int32_t));
|
||||
}
|
||||
|
||||
|
||||
if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) {
|
||||
if (is_pmch_subframe(frame,subframe,fp)) {
|
||||
pmch_procedures(eNB,proc);
|
||||
@@ -88,59 +84,60 @@ phy_procedures_eNB_TX_fs6() {
|
||||
}
|
||||
|
||||
if (ul_subframe < 10)if (ul_subframe < 10) { // This means that there is a potential UL subframe that will be scheduled here
|
||||
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
|
||||
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
|
||||
|
||||
if (eNB->ulsch[i] && eNB->ulsch[i]->ue_type >0) harq_pid = 0;
|
||||
else
|
||||
if (eNB->ulsch[i] && eNB->ulsch[i]->ue_type >0) harq_pid = 0;
|
||||
else
|
||||
#endif
|
||||
harq_pid = subframe2harq_pid(fp,ul_frame,ul_subframe);
|
||||
harq_pid = subframe2harq_pid(fp,ul_frame,ul_subframe);
|
||||
|
||||
if (eNB->ulsch[i]) {
|
||||
ulsch_harq = eNB->ulsch[i]->harq_processes[harq_pid];
|
||||
/* Store first_rb and n_DMRS for correct PHICH generation below.
|
||||
* For PHICH generation we need "old" values of last scheduling
|
||||
* for this HARQ process. 'generate_eNB_dlsch_params' below will
|
||||
* overwrite first_rb and n_DMRS and 'generate_phich_top', done
|
||||
* after 'generate_eNB_dlsch_params', would use the "new" values
|
||||
* instead of the "old" ones.
|
||||
*
|
||||
* This has been tested for FDD only, may be wrong for TDD.
|
||||
*
|
||||
* TODO: maybe we should restructure the code to be sure it
|
||||
* is done correctly. The main concern is if the code
|
||||
* changes and first_rb and n_DMRS are modified before
|
||||
* we reach here, then the PHICH processing will be wrong,
|
||||
* using wrong first_rb and n_DMRS values to compute
|
||||
* ngroup_PHICH and nseq_PHICH.
|
||||
*
|
||||
* TODO: check if that works with TDD.
|
||||
*/
|
||||
ulsch_harq->previous_first_rb = ulsch_harq->first_rb;
|
||||
ulsch_harq->previous_n_DMRS = ulsch_harq->n_DMRS;
|
||||
if (eNB->ulsch[i]) {
|
||||
ulsch_harq = eNB->ulsch[i]->harq_processes[harq_pid];
|
||||
/* Store first_rb and n_DMRS for correct PHICH generation below.
|
||||
* For PHICH generation we need "old" values of last scheduling
|
||||
* for this HARQ process. 'generate_eNB_dlsch_params' below will
|
||||
* overwrite first_rb and n_DMRS and 'generate_phich_top', done
|
||||
* after 'generate_eNB_dlsch_params', would use the "new" values
|
||||
* instead of the "old" ones.
|
||||
*
|
||||
* This has been tested for FDD only, may be wrong for TDD.
|
||||
*
|
||||
* TODO: maybe we should restructure the code to be sure it
|
||||
* is done correctly. The main concern is if the code
|
||||
* changes and first_rb and n_DMRS are modified before
|
||||
* we reach here, then the PHICH processing will be wrong,
|
||||
* using wrong first_rb and n_DMRS values to compute
|
||||
* ngroup_PHICH and nseq_PHICH.
|
||||
*
|
||||
* TODO: check if that works with TDD.
|
||||
*/
|
||||
ulsch_harq->previous_first_rb = ulsch_harq->first_rb;
|
||||
ulsch_harq->previous_n_DMRS = ulsch_harq->n_DMRS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
num_pdcch_symbols = eNB->pdcch_vars[subframe&1].num_pdcch_symbols;
|
||||
num_dci = eNB->pdcch_vars[subframe&1].num_dci;
|
||||
|
||||
if (num_dci > 0)
|
||||
if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) {
|
||||
generate_dci_top(num_pdcch_symbols,
|
||||
num_dci,
|
||||
&eNB->pdcch_vars[subframe&1].dci_alloc[0],
|
||||
0,
|
||||
AMP,
|
||||
fp,
|
||||
eNB->common_vars.txdataF,
|
||||
subframe);
|
||||
num_dci,
|
||||
&eNB->pdcch_vars[subframe&1].dci_alloc[0],
|
||||
0,
|
||||
AMP,
|
||||
fp,
|
||||
eNB->common_vars.txdataF,
|
||||
subframe);
|
||||
num_mdci = eNB->mpdcch_vars[subframe &1].num_dci;
|
||||
|
||||
|
||||
if (num_mdci > 0) {
|
||||
generate_mdci_top (eNB, frame, subframe, AMP, eNB->common_vars.txdataF);
|
||||
generate_mdci_top (eNB, frame, subframe, AMP, eNB->common_vars.txdataF);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Now scan UE specific DLSCH
|
||||
LTE_eNB_DLSCH_t *dlsch0,*dlsch1;
|
||||
|
||||
@@ -158,16 +155,16 @@ phy_procedures_eNB_TX_fs6() {
|
||||
if (harq_pid>=8) {
|
||||
if (dlsch0->ue_type==0)
|
||||
LOG_E(PHY,"harq_pid:%d corrupt must be 0-7 UE_id:%d frame:%d subframe:%d rnti:%x \n",
|
||||
harq_pid,UE_id,frame,subframe,dlsch0->rnti);
|
||||
harq_pid,UE_id,frame,subframe,dlsch0->rnti);
|
||||
} else {
|
||||
// generate pdsch
|
||||
pdsch_procedures_fs6(eNB,
|
||||
proc,
|
||||
harq_pid,
|
||||
dlsch0,
|
||||
dlsch1,
|
||||
&eNB->UE_stats[(uint32_t)UE_id],
|
||||
0);
|
||||
proc,
|
||||
harq_pid,
|
||||
dlsch0,
|
||||
dlsch1,
|
||||
&eNB->UE_stats[(uint32_t)UE_id],
|
||||
0);
|
||||
}
|
||||
} else if ((dlsch0)&&(dlsch0->rnti>0)&&
|
||||
(dlsch0->active == 0)
|
||||
@@ -176,10 +173,10 @@ phy_procedures_eNB_TX_fs6() {
|
||||
dlsch0->subframe_tx[subframe]=0;
|
||||
}
|
||||
}
|
||||
|
||||
generate_phich_top(eNB,
|
||||
proc,
|
||||
AMP);
|
||||
|
||||
}
|
||||
|
||||
DL_thread_fs6() {
|
||||
@@ -194,5 +191,4 @@ DL_thread_fs6() {
|
||||
|
||||
DL_thread_frequency() {
|
||||
frequency_t header;
|
||||
|
||||
full_read(&header,
|
||||
full_read(&header,
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,63 +3,70 @@
|
||||
int createListner (port) {
|
||||
int sock;
|
||||
AssertFatal((sock=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) >= 0, "");
|
||||
struct sockaddr_in addr = {
|
||||
struct sockaddr_in addr = {
|
||||
sin_family:
|
||||
AF_INET,
|
||||
sin_port:
|
||||
htons(port),
|
||||
htons(port),
|
||||
sin_addr:
|
||||
{ s_addr: INADDR_ANY }
|
||||
};
|
||||
int enable=1;
|
||||
AssertFatal(setsockopt(eth->sockfdc, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable))==0,"");
|
||||
AssertFatal(bind(sock, const struct sockaddr *addr, socklen_t addrlen)==0,"");
|
||||
struct timeval tv={0,UDP_TIMEOUT};
|
||||
AssertFatal(setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,&tv,sizeof(tv)) ==0,"");
|
||||
// Make a send/recv buffer larger than a a couple of subframe
|
||||
// so the kernel will store for us in and out paquets
|
||||
int buff=1000*1000*10;
|
||||
AssertFatal ( setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &buff, sizeof(buff)) == 0, "");
|
||||
AssertFatal ( setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &buff, sizeof(buff)) == 0, "");
|
||||
};
|
||||
int enable=1;
|
||||
AssertFatal(setsockopt(eth->sockfdc, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable))==0,"");
|
||||
AssertFatal(bind(sock, const struct sockaddr *addr, socklen_t addrlen)==0,"");
|
||||
struct timeval tv= {0,UDP_TIMEOUT};
|
||||
AssertFatal(setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,&tv,sizeof(tv)) ==0,"");
|
||||
// Make a send/recv buffer larger than a a couple of subframe
|
||||
// so the kernel will store for us in and out paquets
|
||||
int buff=1000*1000*10;
|
||||
AssertFatal ( setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &buff, sizeof(buff)) == 0, "");
|
||||
AssertFatal ( setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &buff, sizeof(buff)) == 0, "");
|
||||
}
|
||||
|
||||
// sock: udp socket
|
||||
// expectedTS: the expected timestamp, 0 if unknown
|
||||
// bufferZone: a reception area of bufferSize
|
||||
int receiveSubFrame(int sock, uint64_t expectedTS, void* bufferZone, int bufferSize) {
|
||||
int receiveSubFrame(int sock, uint64_t expectedTS, void *bufferZone, int bufferSize) {
|
||||
int rcved=0;
|
||||
|
||||
do {
|
||||
//read all subframe data from the control unit
|
||||
int ret=recv(sock, bufferZone, bufferSize, 0);
|
||||
|
||||
if ( ret==-1) {
|
||||
if ( errno == EWOULDBLOCK || errno== EINTR ) {
|
||||
return rcved; // Timeout, subframe incomplete
|
||||
return rcved; // Timeout, subframe incomplete
|
||||
} else {
|
||||
LOG_E(HW,"Critical issue in socket: %s\n", strerror(errno));
|
||||
return -1;
|
||||
LOG_E(HW,"Critical issue in socket: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
commonUDP_t * tmp=(commonUDP_t *)bufferZone;
|
||||
commonUDP_t *tmp=(commonUDP_t *)bufferZone;
|
||||
|
||||
if ( expectedTS && tmp->timestamp != expectedTS) {
|
||||
LOG_W(HW,"Received a paquet in mixed subframes, dropping it\n");
|
||||
LOG_W(HW,"Received a paquet in mixed subframes, dropping it\n");
|
||||
} else {
|
||||
rcved++;
|
||||
bufferZone+=ret;
|
||||
rcved++;
|
||||
bufferZone+=ret;
|
||||
}
|
||||
}
|
||||
} while ( !recved || recved < tmp->nbBlocks);
|
||||
|
||||
return recv;
|
||||
}
|
||||
|
||||
int sendSubFrame(int sock, void* bufferZone, int nbBlocks) {
|
||||
int sendSubFrame(int sock, void *bufferZone, int nbBlocks) {
|
||||
do {
|
||||
int sz=alignedSize(bufferZone);
|
||||
int ret=send(sock, bufferZone, sz, 0);
|
||||
|
||||
if ( ret != sz )
|
||||
LOG_W(HW,"Wrote socket doesn't return size %d (val: %d, errno:%d)\n",
|
||||
sz, ret, errno);
|
||||
sz, ret, errno);
|
||||
|
||||
bufferZone+=sz;
|
||||
nbBlocks--;
|
||||
} while (nbBlocks);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -135,9 +135,6 @@ void rxAddInput( struct complex16 *input_sig, struct complex16 *after_channel_si
|
||||
}
|
||||
|
||||
out_ptr->r += round(rx_tmp.x*pathLossLinear + noise_per_sample*gaussdouble(0.0,1.0));
|
||||
printf("in: %d, out %d= %f*%f + %f*%f\n",
|
||||
input_sig[((TS+i)*nbTx)%CirSize].r, out_ptr->r , rx_tmp.x,
|
||||
pathLossLinear, noise_per_sample,gaussdouble(0.0,1.0));
|
||||
out_ptr->i += round(rx_tmp.y*pathLossLinear + noise_per_sample*gaussdouble(0.0,1.0));
|
||||
out_ptr++;
|
||||
}
|
||||
|
||||
@@ -1146,7 +1146,7 @@ void init_eNB_afterRU(void) {
|
||||
|
||||
for (CC_id=0; CC_id<RC.nb_CC[inst]; CC_id++) {
|
||||
LOG_I(PHY,"RC.nb_CC[inst:%d][CC_id:%d]:%p\n", inst, CC_id, RC.eNB[inst][CC_id]);
|
||||
eNB = RC.eNB[inst][CC_id];
|
||||
eNB = RC.eNB[inst][CC_id];
|
||||
phy_init_lte_eNB(eNB,0,0);
|
||||
|
||||
// map antennas and PRACH signals to eNB RX
|
||||
|
||||
+23
-103
@@ -983,11 +983,9 @@ void wakeup_slaves(RU_proc_t *proc) {
|
||||
|
||||
// wake up slave FH thread
|
||||
// lock the FH mutex and make sure the thread is ready
|
||||
if (pthread_mutex_timedlock(&slave_proc->mutex_FH,&wait) != 0) {
|
||||
LOG_E( PHY, "ERROR pthread_mutex_lock for RU %d slave %d (IC %d)\n",proc->ru->idx,slave_proc->ru->idx,slave_proc->instance_cnt_FH);
|
||||
exit_fun( "error locking mutex_rxtx" );
|
||||
break;
|
||||
}
|
||||
AssertFatal(pthread_mutex_timedlock(&slave_proc->mutex_FH,&wait) == 0,
|
||||
"ERROR pthread_mutex_lock for RU %d slave %d (IC %d)\n",
|
||||
proc->ru->idx,slave_proc->ru->idx,slave_proc->instance_cnt_FH);
|
||||
|
||||
int cnt_slave = ++slave_proc->instance_cnt_FH;
|
||||
slave_proc->frame_rx = proc->frame_rx;
|
||||
@@ -1628,7 +1626,6 @@ static void *ru_thread( void *param ) {
|
||||
pthread_cond_signal(&proc->cond_FH1);
|
||||
wait_sync("ru_thread");
|
||||
|
||||
if(!(get_softmodem_params()->emulate_rf)) {
|
||||
// Start RF device if any
|
||||
if (ru->start_rf) {
|
||||
if (ru->start_rf(ru) != 0)
|
||||
@@ -1648,12 +1645,9 @@ static void *ru_thread( void *param ) {
|
||||
|
||||
// if this is a slave RRU, try to synchronize on the DL frequency
|
||||
if ((ru->is_slave) && (ru->if_south == LOCAL_RF)) do_ru_synch(ru);
|
||||
}
|
||||
|
||||
// This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices
|
||||
while (!oai_exit) {
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_CPUID_RU_THREAD,sched_getcpu());
|
||||
LOG_ENTER(PHY);
|
||||
// these are local subframe/frame counters to check that we are in synch with the fronthaul timing.
|
||||
// They are set on the first rx/tx in the underly FH routines.
|
||||
if (subframe==9) {
|
||||
@@ -1665,37 +1659,9 @@ static void *ru_thread( void *param ) {
|
||||
}
|
||||
|
||||
// synchronization on input FH interface, acquire signals/data and block
|
||||
if (ru->fh_south_in) ru->fh_south_in(ru,&frame,&subframe);
|
||||
else AssertFatal(1==0, "No fronthaul interface at south port");
|
||||
AssertFatal(ru->fh_south_in, "No fronthaul interface at south port");
|
||||
ru->fh_south_in(ru,&frame,&subframe);
|
||||
|
||||
#ifdef PHY_TX_THREAD
|
||||
|
||||
if(first_phy_tx == 0) {
|
||||
phy_tx_end = 0;
|
||||
phy_tx_txdataF_end = 0;
|
||||
|
||||
if(pthread_mutex_lock(&ru->proc.mutex_phy_tx) != 0) {
|
||||
LOG_E( PHY, "[RU] ERROR pthread_mutex_lock for phy tx thread (IC %d)\n", ru->proc.instance_cnt_phy_tx);
|
||||
exit_fun( "error locking mutex_rxtx" );
|
||||
}
|
||||
|
||||
if (ru->proc.instance_cnt_phy_tx==-1) {
|
||||
++ru->proc.instance_cnt_phy_tx;
|
||||
// the thread can now be woken up
|
||||
AssertFatal(pthread_cond_signal(&ru->proc.cond_phy_tx) == 0, "ERROR pthread_cond_signal for phy_tx thread\n");
|
||||
} else {
|
||||
LOG_E(PHY,"phy tx thread busy, skipping\n");
|
||||
++ru->proc.instance_cnt_phy_tx;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock( &ru->proc.mutex_phy_tx );
|
||||
} else {
|
||||
phy_tx_end = 1;
|
||||
phy_tx_txdataF_end = 1;
|
||||
}
|
||||
|
||||
first_phy_tx = 0;
|
||||
#endif
|
||||
LOG_D(PHY,"RU thread (do_prach %d, is_prach_subframe %d), received frame %d, subframe %d\n",
|
||||
ru->do_prach,
|
||||
is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx),
|
||||
@@ -1720,72 +1686,26 @@ static void *ru_thread( void *param ) {
|
||||
|
||||
// At this point, all information for subframe has been received on FH interface
|
||||
// If this proc is to provide synchronization, do so
|
||||
wakeup_slaves(proc);
|
||||
#if defined(PRE_SCD_THREAD)
|
||||
new_dlsch_ue_select_tbl_in_use = dlsch_ue_select_tbl_in_use;
|
||||
dlsch_ue_select_tbl_in_use = !dlsch_ue_select_tbl_in_use;
|
||||
memcpy(&pre_scd_eNB_UE_stats,&RC.mac[ru->eNB_list[0]->Mod_id]->UE_list.eNB_UE_stats, sizeof(eNB_UE_STATS)*MAX_NUM_CCs*NUMBER_OF_UE_MAX);
|
||||
memcpy(&pre_scd_activeUE, &RC.mac[ru->eNB_list[0]->Mod_id]->UE_list.active, sizeof(boolean_t)*NUMBER_OF_UE_MAX);
|
||||
|
||||
if (pthread_mutex_lock(&ru->proc.mutex_pre_scd)!= 0) {
|
||||
LOG_E( PHY, "[eNB] error locking proc mutex for eNB pre scd\n");
|
||||
exit_fun("error locking mutex_time");
|
||||
// Fixme: not used
|
||||
// wakeup_slaves(proc);
|
||||
for (int i=0; i<ru->num_eNB; i++) {
|
||||
char string[20];
|
||||
sprintf(string,"Incoming RU %d",ru->idx);
|
||||
ru->eNB_top(ru->eNB_list[i],ru->proc.frame_rx,ru->proc.subframe_rx,string,ru);
|
||||
}
|
||||
|
||||
ru->proc.instance_pre_scd++;
|
||||
|
||||
if (ru->proc.instance_pre_scd == 0) {
|
||||
if (pthread_cond_signal(&ru->proc.cond_pre_scd) != 0) {
|
||||
LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB pre scd\n" );
|
||||
exit_fun( "ERROR pthread_cond_signal cond_pre_scd" );
|
||||
}
|
||||
} else {
|
||||
LOG_E( PHY, "[eNB] frame %d subframe %d rxtx busy instance_pre_scd %d\n",
|
||||
frame,subframe,ru->proc.instance_pre_scd );
|
||||
}
|
||||
|
||||
if (pthread_mutex_unlock(&ru->proc.mutex_pre_scd)!= 0) {
|
||||
LOG_E( PHY, "[eNB] error unlocking mutex_pre_scd mutex for eNB pre scd\n");
|
||||
exit_fun("error unlocking mutex_pre_scd");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// wakeup all eNB processes waiting for this RU
|
||||
if (ru->num_eNB>0) wakeup_L1s(ru);
|
||||
|
||||
#ifndef PHY_TX_THREAD
|
||||
|
||||
if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD || ru->num_eNB==0) {
|
||||
// do TX front-end processing if needed (precoding and/or IDFTs)
|
||||
if (ru->feptx_prec) ru->feptx_prec(ru);
|
||||
|
||||
// do OFDM if needed
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru);
|
||||
|
||||
if(!(get_softmodem_params()->emulate_rf)) {
|
||||
// do outgoing fronthaul (south) if needed
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru);
|
||||
|
||||
if (ru->fh_north_out) ru->fh_north_out(ru);
|
||||
}
|
||||
|
||||
proc->emulate_rf_busy = 0;
|
||||
}
|
||||
|
||||
#else
|
||||
struct timespec time_req, time_rem;
|
||||
time_req.tv_sec = 0;
|
||||
time_req.tv_nsec = 10000;
|
||||
|
||||
while((!oai_exit)&&(phy_tx_end == 0)) {
|
||||
nanosleep(&time_req,&time_rem);
|
||||
continue;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// do TX front-end processing if needed (precoding and/or IDFTs)
|
||||
if (ru->feptx_prec) ru->feptx_prec(ru);
|
||||
|
||||
// do OFDM if needed
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru);
|
||||
// do outgoing fronthaul (south) if needed
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru);
|
||||
|
||||
if (ru->fh_north_out) ru->fh_north_out(ru);
|
||||
|
||||
}
|
||||
|
||||
|
||||
printf( "Exiting ru_thread \n");
|
||||
|
||||
if (!(get_softmodem_params()->emulate_rf)) {
|
||||
|
||||
@@ -505,9 +505,7 @@ int main( int argc, char **argv ) {
|
||||
}
|
||||
|
||||
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);
|
||||
openair_rrc_eNB_configuration(enb_id, &RC.rrc[enb_id]->configuration);
|
||||
}
|
||||
} else {
|
||||
printf("RC.nb_inst = 0, Initializing L1\n");
|
||||
@@ -530,12 +528,9 @@ int main( int argc, char **argv ) {
|
||||
// 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);
|
||||
mlockall(MCL_CURRENT | MCL_FUTURE);
|
||||
pthread_cond_init(&sync_cond,NULL);
|
||||
pthread_mutex_init(&sync_mutex, NULL);
|
||||
|
||||
|
||||
|
||||
rt_sleep_ns(10*100000000ULL);
|
||||
|
||||
if (NFAPI_MODE!=NFAPI_MONOLITHIC) {
|
||||
@@ -563,9 +558,10 @@ int main( int argc, char **argv ) {
|
||||
// for (CC_id=0;CC_id<RC.nb_L1_CC[inst];CC_id++) phy_init_lte_eNB(RC.eNB[inst][CC_id],0,0);
|
||||
}
|
||||
|
||||
printf("wait_eNBs()\n");
|
||||
wait_eNBs();
|
||||
printf("About to Init RU threads RC.nb_RU:%d\n", RC.nb_RU);
|
||||
// no need to wait: openair_rrc_eNB_configuration() is called earlier from this thread
|
||||
// openair_rrc_eNB_configuration()->init_SI()->rrc_mac_config_req_eNB ()->phy_config_request () sets the wait_eNBs() tested flag
|
||||
// wait_eNBs();
|
||||
// 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.
|
||||
@@ -588,6 +584,9 @@ int main( int argc, char **argv ) {
|
||||
|
||||
printf("wait RUs\n");
|
||||
// end of CI modifications
|
||||
// fixme: very weird usage of bitmask
|
||||
// lack of mutex in: ru_thread_prach(),...
|
||||
// wait_RUs() is wrong and over complex!
|
||||
wait_RUs();
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user