diff --git a/openair1/PHY/LTE_TRANSPORT/if4_tools.c b/openair1/PHY/LTE_TRANSPORT/if4_tools.c index 88312e4a46..27e1e2a6cb 100644 --- a/openair1/PHY/LTE_TRANSPORT/if4_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/if4_tools.c @@ -293,6 +293,8 @@ void recv_IF4p5(RU_t *ru, int *frame, int *subframe, uint16_t *packet_type, uint db_fulllength, 0) < 0) { perror("ETHERNET read"); + ru->state = RU_IDLE; + return; } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 0 ); if (eth->flags == ETH_RAW_IF4p5_MODE) { diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h index 55dbab6f71..e244cb7a3a 100644 --- a/openair1/PHY/defs.h +++ b/openair1/PHY/defs.h @@ -751,6 +751,8 @@ typedef struct RU_t_s{ void (*fh_south_asynch_in)(struct RU_t_s *ru,int *frame, int *subframe); /// function pointer to initialization function for radio interface int (*start_rf)(struct RU_t_s *ru); + /// function pointer to stop radio interface + int (*stop_rf)(struct RU_t_s *ru); /// function pointer to initialization function for radio interface int (*start_if)(struct RU_t_s *ru,struct PHY_VARS_eNB_s *eNB); /// function pointer to RX front-end processing routine (DFTs/prefix removal or NULL) diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c index ad5bbda3fe..a74a57b359 100644 --- a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c +++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c @@ -190,6 +190,7 @@ int trx_eth_read_udp_IF4p5(openair0_device *device, openair0_timestamp *timestam eth->num_rx_errors++; if (errno == EAGAIN) { printf("Lost IF4p5 connection with %s\n", inet_ntoa(eth->dest_addrd.sin_addr)); + return -1; } else if (errno == EWOULDBLOCK) { block_cnt++; usleep(10); diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 439728429c..d447f11476 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -681,6 +681,17 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *subframe) { symbol_mask_full = ((subframe_select(fp,*subframe) == SF_S) ? (1<dl_symbols_in_S_subframe) : (1<symbols_per_tti))-1; do { recv_IF4p5(ru, &frame_tx, &subframe_tx, &packet_type, &symbol_number); + if (ru->state != RU_RUN){ + pthread_mutex_lock(&proc->mutex_ru); + proc->instance_cnt_ru = -1; + pthread_mutex_unlock(&proc->mutex_ru); + if (ru->stop_rf) { + ru->stop_rf(ru); + LOG_I(PHY,"RU %d rf device stopped\n",ru->idx); + } + else LOG_D(PHY,"RU %d no rf device\n",ru->idx); + return; + } if ((subframe_select(fp,subframe_tx) == SF_DL) && (symbol_number == 0)) start_meas(&ru->rx_fhaul); LOG_D(PHY,"subframe %d (%d): frame %d, subframe %d, symbol %d\n", *subframe,subframe_select(fp,*subframe),frame_tx,subframe_tx,symbol_number); @@ -901,7 +912,7 @@ void tx_rf(RU_t *ru) { ru->nb_tx, flags); - LOG_D(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, unwrapped_frame %d, subframe %d\n",ru->idx, + LOG_I(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, unwrapped_frame %d, subframe %d\n",ru->idx, (long long unsigned int)proc->timestamp_tx,proc->frame_tx,proc->frame_tx_unwrap,proc->subframe_tx); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 ); @@ -1614,7 +1625,9 @@ static void* ru_thread_control( void* param ) { AssertFatal((ru->ifdevice.trx_ctlsend_func(&ru->ifdevice,&rru_config_msg,rru_config_msg.len)!=-1),"Failed to send msg to RU %d\n",ru->idx); - proc->instance_cnt_ru = 1; + pthread_mutex_lock(&proc->mutex_ru); + proc->instance_cnt_ru = 1; + pthread_mutex_unlock(&proc->mutex_ru); if (pthread_cond_signal(&proc->cond_ru_thread) != 0) { LOG_E( PHY, "ERROR pthread_cond_signal for RU %d\n",ru->idx); exit_fun( "ERROR pthread_cond_signal" ); @@ -1638,8 +1651,10 @@ static void* ru_thread_control( void* param ) { wait_sync("ru_thread"); ru->state = (ru->is_slave == 1) ? RU_SYNC : RU_RUN ; - + + pthread_mutex_lock(&proc->mutex_ru); proc->instance_cnt_ru = 1; + pthread_mutex_unlock(&proc->mutex_ru); if (pthread_cond_signal(&proc->cond_ru_thread) != 0) { LOG_E( PHY, "ERROR pthread_cond_signal for RU %d\n",ru->idx); exit_fun( "ERROR pthread_cond_signal" ); @@ -1730,7 +1745,7 @@ static void* ru_thread( void* param ) { // wait to be woken up if (wait_on_condition(&ru->proc.mutex_ru,&ru->proc.cond_ru_thread,&ru->proc.instance_cnt_ru,"ru_thread")<0) break; - + // Start RF device if any if (ru->start_rf) { if (ru->start_rf(ru) != 0) @@ -1773,7 +1788,7 @@ 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); + if (ru->fh_south_in && ru->state == RU_RUN) ru->fh_south_in(ru,&frame,&subframe); else AssertFatal(1==0, "No fronthaul interface at south port"); @@ -1936,6 +1951,10 @@ int start_rf(RU_t *ru) { return(ru->rfdevice.trx_start_func(&ru->rfdevice)); } +void stop_rf(RU_t *ru){ + ru->rfdevice.trx_end_func(&ru->rfdevice); +} + extern void fep_full(RU_t *ru); extern void ru_fep_full_2thread(RU_t *ru); extern void feptx_ofdm(RU_t *ru); @@ -2343,6 +2362,7 @@ void init_RU(char *rf_config_file, clock_source_t clock_source,clock_source_t ti ru->fh_south_in = rx_rf; // local synchronous RF RX ru->fh_south_out = tx_rf; // local synchronous RF TX ru->start_rf = start_rf; // need to start the local RF interface + ru->stop_rf = stop_rf; printf("configuring ru_id %d (start_rf %p)\n",ru_id,start_rf); /* if (ru->function == eNodeB_3GPP) { // configure RF parameters only for 3GPP eNodeB, we need to get them from RAU otherwise