Skip to content
Snippets Groups Projects
lte-ru.c 123 KiB
Newer Older
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */

/*! \file lte-ru.c
 * \brief Top-level threads for RU entity
 * \author R. Knopp, F. Kaltenberger, Navid Nikaein
 * \date 2019
 * \version 0.1
 * \company Eurecom
 * \email: {knopp, florian.kaltenberger, navid.nikaein}@eurecom.fr
 * \note
 * \warning
 */

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sched.h>
#include <linux/sched.h>
#include <signal.h>
#include <execinfo.h>
#include <getopt.h>
#include <sys/sysinfo.h>

#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all

#include "assertions.h"
#include "PHY/defs_common.h"
#include "PHY/types.h"
#include "PHY/INIT/phy_init.h"
#include "PHY/phy_extern.h"
#include "PHY/LTE_ESTIMATION/lte_estimation.h"
#include "PHY/LTE_REFSIG/lte_refsig.h"
#include "PHY/LTE_TRANSPORT/if4_tools.h"
#include "PHY/LTE_TRANSPORT/transport_proto.h"
#include "SCHED/sched_common.h"
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "radio/COMMON/common_lib.h"
#include "radio/ETHERNET/ethernet_lib.h"

/* these variables have to be defined before including ENB_APP/enb_paramdef.h */
static int DEFBANDS[] = {7};
static int DEFENBS[] = {0};
static int DEFBFW[] = {0x00007fff};
static int DEFRUTPCORES[] = {2,4,6,8};


#include "ENB_APP/enb_paramdef.h"
#include "common/config/config_userapi.h"

#include "SIMULATION/ETH_TRANSPORT/proto.h"

#include "T.h"

#include "executables/softmodem-common.h"

#define MBMS_EXPERIMENTAL

extern int oai_exit;
extern clock_source_t clock_source;
#include "executables/thread-common.h"
//extern PARALLEL_CONF_t get_thread_parallel_conf(void);
//extern WORKER_CONF_t   get_thread_worker_conf(void);
extern void phy_init_RU(RU_t *);

void prach_procedures(PHY_VARS_eNB *eNB,int br_flag);

void stop_RU(RU_t **rup,int nb_ru);

static void do_ru_synch(RU_t *ru);

void configure_ru(int idx,
                  void *arg);

void configure_rru(int idx,
                   void *arg);

void reset_proc(RU_t *ru);
int connect_rau(RU_t *ru);

void wait_eNBs(void);

const char ru_states[6][9] = {"RU_IDLE","RU_CONFIG","RU_READY","RU_RUN","RU_ERROR","RU_SYNC"};

#if defined(PRE_SCD_THREAD)
#include "common/ran_context.h"
#include "nfapi/oai_integration/vendor_ext.h"
#include "openair2/LAYER2/MAC/mac_extern.h"
  extern uint8_t dlsch_ue_select_tbl_in_use;
  void init_ru_vnf(void);
  extern RAN_CONTEXT_t RC;
#endif

RU_t **RCconfig_RU(int nb_RU,int nb_L1_inst,PHY_VARS_eNB ***eNB,uint64_t *ru_mask,pthread_mutex_t *ru_mutex,pthread_cond_t *ru_cond);

/*************************************************************/
/* Functions to attach and configure RRU                     */


/*************************************************************/
/* Southbound Fronthaul functions, RCC/RAU                   */

// southbound IF5 fronthaul for 16-bit OAI format
static inline void fh_if5_south_out(RU_t *ru,int frame, int subframe, uint64_t timestamp) {
  if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff );

  ru->south_out_cnt++;
  int offset = subframe*ru->frame_parms->samples_per_tti;
  void *buffs[ru->nb_tx]; 
  for (int aid=0;aid<ru->nb_tx;aid++) buffs[aid] = (void*)&ru->common.txdata[aid][offset]; 

  ru->ifdevice.trx_write_func2(&ru->ifdevice,
  		               timestamp,
                               buffs,
			       0,
			       ru->frame_parms->samples_per_tti,
			       0,
			       ru->nb_tx); 

}


// southbound IF4p5 fronthaul
static inline void fh_if4p5_south_out(RU_t *ru,
                                      int frame,
                                      int subframe,
                                      uint64_t timestamp) {
  if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff );

  LOG_D(PHY,"ENTERED fh_if4p5_south_out   Sending IF4p5 for frame %d subframe %d ru %d\n",ru->proc.frame_tx,ru->proc.tti_tx,ru->idx);

  if (subframe_select(ru->frame_parms, subframe)!=SF_UL) {
    send_IF4p5(ru, frame, subframe, IF4p5_PDLFFT);
    ru->south_out_cnt++;
    LOG_D(PHY,"south_out_cnt %d\n",ru->south_out_cnt);
  }

  /*if (ru->idx == 0 || ru->idx == ru) {
      VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU+ru->idx, ru->proc.frame_tx );
      VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_RU+ru->idx, ru->proc.subframe_tx );
    }*/
  VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_IF4P5_SOUTH_OUT_RU+ru->idx, ru->proc.frame_tx);
  VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_IF4P5_SOUTH_OUT_RU+ru->idx, ru->proc.tti_tx);
}


/*************************************************************/
/* Input Fronthaul from south RCC/RAU                        */

// Synchronous if5 from south
void fh_if5_south_in(RU_t *ru,
                     int *frame,
                     int *subframe) {
  LTE_DL_FRAME_PARMS *fp = ru->frame_parms;
  RU_proc_t *proc = &ru->proc;
  ru->ifdevice.trx_read_func2(&ru->ifdevice,&proc->timestamp_rx,NULL,fp->samples_per_tti);
  proc->frame_rx    = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023;
  proc->tti_rx = (proc->timestamp_rx / fp->samples_per_tti)%10;
  
  if (proc->first_rx == 0) {
    if (proc->tti_rx != *subframe) {
      LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->tti_rx %d, subframe %d), resynching\n",proc->tti_rx,*subframe);
      *frame=proc->frame_rx;
      *subframe=proc->tti_rx;
    }

    if (proc->frame_rx != *frame) {
      LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",proc->frame_rx,*frame);
      exit_fun("Exiting");
    }
  } else {
    proc->first_rx = 0;
    *frame = proc->frame_rx;
    *subframe = proc->tti_rx;
  }

Loading
Loading full blame...