merge develop, first version of 5g simple main()
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+44
-44
@@ -178,14 +178,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;
|
||||
@@ -205,8 +205,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);
|
||||
@@ -316,7 +316,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;
|
||||
|
||||
@@ -412,7 +412,7 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot
|
||||
|
||||
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
|
||||
// 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;
|
||||
@@ -434,27 +434,27 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -475,10 +475,10 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
@@ -496,7 +496,7 @@ int wakeup_tx(PHY_VARS_gNB *gNB,int frame_rx,int slot_rx,int frame_tx,int slot_t
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -512,7 +512,7 @@ int wakeup_tx(PHY_VARS_gNB *gNB,int frame_rx,int slot_rx,int frame_tx,int slot_t
|
||||
|
||||
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
|
||||
// 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");
|
||||
|
||||
@@ -532,11 +532,11 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -563,19 +563,19 @@ 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
|
||||
// and proc->slot_tx = proc->slot_rx+sl_ahead
|
||||
L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sl_ahead*fp->samples_per_slot);
|
||||
L1_proc->frame_rx = ru_proc->frame_rx;
|
||||
L1_proc->slot_rx = ru_proc->tti_rx;
|
||||
@@ -592,7 +592,7 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) {
|
||||
exit_fun( "ERROR pthread_cond_signal" );
|
||||
return(-1);
|
||||
}
|
||||
|
||||
|
||||
return(0);
|
||||
}
|
||||
/*
|
||||
@@ -696,9 +696,9 @@ 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) {
|
||||
static void *process_stats_thread(void *param) {
|
||||
|
||||
PHY_VARS_gNB *gNB = (PHY_VARS_gNB*)param;
|
||||
PHY_VARS_gNB *gNB = (PHY_VARS_gNB *)param;
|
||||
|
||||
reset_meas(&gNB->dlsch_encoding_stats);
|
||||
reset_meas(&gNB->dlsch_scrambling_stats);
|
||||
@@ -902,7 +902,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];
|
||||
}
|
||||
}
|
||||
|
||||
+20
-20
@@ -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) {
|
||||
|
||||
+66
-66
@@ -107,7 +107,7 @@ static int wait_for_sync = 0;
|
||||
unsigned int mmapped_dma=0;
|
||||
int single_thread_flag=1;
|
||||
|
||||
static int8_t threequarter_fs=0;
|
||||
int8_t threequarter_fs=0;
|
||||
|
||||
uint32_t downlink_frequency[MAX_NUM_CCs][4];
|
||||
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
@@ -170,6 +170,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);
|
||||
@@ -713,13 +717,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");
|
||||
@@ -762,23 +762,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);
|
||||
}*/
|
||||
@@ -831,7 +831,7 @@ int main( int argc, char **argv )
|
||||
MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX);
|
||||
|
||||
|
||||
init_opt();
|
||||
init_opt();
|
||||
|
||||
|
||||
#ifdef PDCP_USE_NETLINK
|
||||
@@ -848,7 +848,7 @@ if(!IS_SOFTMODEM_NOS1)
|
||||
LOG_I(HW, "Version: %s\n", PACKAGE_VERSION);
|
||||
|
||||
if(IS_SOFTMODEM_NOS1)
|
||||
init_pdcp();
|
||||
init_pdcp();
|
||||
|
||||
if (RC.nb_nr_inst > 0) {
|
||||
// don't create if node doesn't connect to RRC/S1/GTP
|
||||
@@ -871,37 +871,37 @@ if(!IS_SOFTMODEM_NOS1)
|
||||
mlockall(MCL_CURRENT | MCL_FUTURE);
|
||||
pthread_cond_init(&sync_cond,NULL);
|
||||
pthread_mutex_init(&sync_mutex, NULL);
|
||||
/*#ifdef XFORMS
|
||||
int UE_id;
|
||||
/*#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");
|
||||
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);
|
||||
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 (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) {
|
||||
@@ -999,27 +999,27 @@ if(!IS_SOFTMODEM_NOS1)
|
||||
printf("oai_exit=%d\n",oai_exit);
|
||||
|
||||
// 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);
|
||||
|
||||
+55
-55
@@ -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;
|
||||
@@ -426,7 +426,7 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// no UL for now
|
||||
// no UL for now
|
||||
/*
|
||||
if (UE->mac_enabled==1) {
|
||||
@@ -464,7 +464,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;
|
||||
@@ -474,24 +474,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;
|
||||
@@ -500,7 +500,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];
|
||||
|
||||
@@ -565,7 +565,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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -578,24 +578,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 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 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]);
|
||||
for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
|
||||
free(dummy_tx[i]);
|
||||
|
||||
}
|
||||
|
||||
@@ -726,7 +726,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]);
|
||||
}*/
|
||||
@@ -762,29 +762,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 - 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)%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
|
||||
|
||||
@@ -215,7 +215,7 @@ int emulate_rf = 0;
|
||||
|
||||
tpool_t *Tpool;
|
||||
#ifdef UE_DLSCH_PARALLELISATION
|
||||
tpool_t *Tpool_dl;
|
||||
tpool_t *Tpool_dl;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -309,8 +309,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);
|
||||
}
|
||||
|
||||
@@ -381,9 +381,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);
|
||||
|
||||
@@ -510,12 +510,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");
|
||||
@@ -523,12 +523,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;
|
||||
@@ -537,15 +537,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;
|
||||
@@ -620,7 +620,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();*/
|
||||
@@ -630,6 +630,11 @@ void init_pdcp(void) {
|
||||
LOG_I(PDCP, "Before getting out from init_pdcp() \n");
|
||||
}
|
||||
|
||||
// Stupid function addition because UE itti messages queues definition is common with eNB
|
||||
void *rrc_enb_process_itti_msg(void *notUsed) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int main( int argc, char **argv ) {
|
||||
//uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2;
|
||||
@@ -657,12 +662,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();
|
||||
@@ -670,21 +675,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);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -81,9 +81,9 @@ char *get_softmodem_function(uint64_t *sofmodemfunc_mask_ptr) {
|
||||
}
|
||||
|
||||
void get_common_options(uint32_t execmask) {
|
||||
uint32_t online_log_messages;
|
||||
uint32_t glog_level ;
|
||||
uint32_t start_telnetsrv = 0;
|
||||
uint32_t online_log_messages=0;
|
||||
uint32_t glog_level =0;
|
||||
uint32_t start_telnetsrv=0;
|
||||
uint32_t noS1 = 0, nokrnmod = 0, nonbiot = 0;
|
||||
uint32_t rfsim = 0, basicsim = 0, do_forms = 0;
|
||||
char *logmem_filename = NULL;
|
||||
@@ -146,27 +146,27 @@ void get_common_options(uint32_t execmask) {
|
||||
}
|
||||
|
||||
void softmodem_printresources(int sig, telnet_printfunc_t pf) {
|
||||
struct rusage usage;
|
||||
struct timespec stop;
|
||||
struct rusage usage;
|
||||
struct timespec stop;
|
||||
|
||||
clock_gettime(CLOCK_BOOTTIME, &stop);
|
||||
clock_gettime(CLOCK_BOOTTIME, &stop);
|
||||
|
||||
uint64_t elapse = (stop.tv_sec - start.tv_sec) ; // in seconds
|
||||
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);
|
||||
}
|
||||
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) {
|
||||
@@ -181,9 +181,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");
|
||||
}
|
||||
@@ -193,7 +193,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;
|
||||
@@ -202,5 +202,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);
|
||||
}
|
||||
|
||||
@@ -38,6 +38,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 ""
|
||||
@@ -88,6 +93,8 @@ 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
|
||||
#define SINGLE_THREAD_FLAG softmodem_params.single_thread_flag
|
||||
@@ -103,6 +110,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}, \
|
||||
@@ -191,6 +200,8 @@ 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;
|
||||
int emulate_rf;
|
||||
|
||||
@@ -0,0 +1,309 @@
|
||||
/*
|
||||
Author: Laurent THOMAS, Open Cells Project company, funded by IRT SystemX
|
||||
copyleft: OpenAirInterface Software Alliance and it's licence
|
||||
*/
|
||||
#ifndef __SPLIT_HEADERS_H
|
||||
#define __SPLIT_HEADERS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <openair1/PHY/defs_eNB.h>
|
||||
|
||||
#define CU_PORT "7878"
|
||||
#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)
|
||||
// linux may timeout for a much longer time (up to 10ms)
|
||||
#define blockAlign 32 //bytes to align memory for SIMD copy (256 bits vectors)
|
||||
|
||||
// FS6 transport configuration and handler
|
||||
typedef struct {
|
||||
char *sourceIP;
|
||||
char *sourcePort;
|
||||
char *destIP;
|
||||
char *destPort;
|
||||
struct addrinfo *destAddr;
|
||||
int sockHandler;
|
||||
} UDPsock_t;
|
||||
|
||||
#define CTsentCUv0 0xA500
|
||||
#define CTsentDUv0 0x5A00
|
||||
|
||||
// Main FS6 transport layer header
|
||||
// All packets starts with this header
|
||||
typedef struct commonUDP_s {
|
||||
uint64_t timestamp; // id of the group (subframe for LTE)
|
||||
uint16_t nbBlocks; // total number of blocks for this timestamp
|
||||
uint16_t blockID; // id: 0..nbBocks-1
|
||||
uint16_t contentType; // defines the content format
|
||||
uint16_t contentBytes; // will be sent in a UDP packet, so must be < 2^16 bytes
|
||||
uint64_t senderClock;
|
||||
} commonUDP_t;
|
||||
|
||||
// FS6 UL common header (DU to CU)
|
||||
// gives the RACH detection data and is always sent to inform the CU that a subframe arrived
|
||||
typedef struct {
|
||||
uint16_t max_preamble[4];
|
||||
uint16_t max_preamble_energy[4];
|
||||
uint16_t max_preamble_delay[4];
|
||||
uint16_t avg_preamble_energy[4];
|
||||
} fs6_ul_t;
|
||||
|
||||
// FS6 DL common header (CU to DU)
|
||||
// gives the DCI configuration from each subframe
|
||||
typedef struct {
|
||||
uint8_t pbch_pdu[4];
|
||||
int num_pdcch_symbols;
|
||||
int num_dci;
|
||||
DCI_ALLOC_t dci_alloc[8];
|
||||
int num_mdci;
|
||||
int amp;
|
||||
LTE_eNB_PHICH phich_vars;
|
||||
uint64_t DuClock;
|
||||
uint64_t CuSpentMicroSec;
|
||||
} fs6_dl_t;
|
||||
|
||||
// a value to type all sub packets,
|
||||
// to detect errors, and to be able to extend to other versions
|
||||
// the first byte of each sub structure should match one of these values
|
||||
enum pckType {
|
||||
fs6UlConfig=25,
|
||||
fs6DlConfig=26,
|
||||
fs6ULConfigCCH=27,
|
||||
fs6ULsch=28,
|
||||
fs6ULcch=29,
|
||||
fs6ULindicationHarq=40,
|
||||
fs6ULindicationSr=41,
|
||||
};
|
||||
|
||||
// CU to DU definition of a future UL subframe decode
|
||||
// defines a UE future data plane
|
||||
typedef struct {
|
||||
enum pckType type:8;
|
||||
uint16_t UE_id;
|
||||
int8_t harq_pid;
|
||||
UE_type_t ue_type;
|
||||
|
||||
uint8_t dci_alloc;
|
||||
uint8_t rar_alloc;
|
||||
SCH_status_t status;
|
||||
uint8_t Msg3_flag;
|
||||
uint8_t subframe;
|
||||
uint32_t frame;
|
||||
uint8_t handled;
|
||||
uint8_t phich_active;
|
||||
uint8_t phich_ACK;
|
||||
uint16_t previous_first_rb;
|
||||
uint32_t B;
|
||||
uint32_t G;
|
||||
UCI_format_t uci_format;
|
||||
uint8_t Or2;
|
||||
uint8_t o_RI[2];
|
||||
uint8_t o_ACK[4];
|
||||
uint8_t O_ACK;
|
||||
uint8_t o_RCC;
|
||||
int16_t q_ACK[MAX_ACK_PAYLOAD];
|
||||
int16_t q_RI[MAX_RI_PAYLOAD];
|
||||
uint32_t RTC[MAX_NUM_ULSCH_SEGMENTS];
|
||||
uint8_t ndi;
|
||||
uint8_t round;
|
||||
uint8_t rvidx;
|
||||
uint8_t Nl;
|
||||
uint8_t n_DMRS;
|
||||
uint8_t previous_n_DMRS;
|
||||
uint8_t n_DMRS2;
|
||||
int32_t delta_TF;
|
||||
uint32_t repetition_number ;
|
||||
uint32_t total_number_of_repetitions;
|
||||
|
||||
uint16_t harq_mask;
|
||||
uint16_t nb_rb;
|
||||
uint8_t Qm;
|
||||
uint16_t first_rb;
|
||||
uint8_t O_RI;
|
||||
uint8_t Or1;
|
||||
uint16_t Msc_initial;
|
||||
uint8_t Nsymb_initial;
|
||||
uint8_t V_UL_DAI;
|
||||
uint8_t srs_active;
|
||||
uint32_t TBS;
|
||||
uint8_t Nsymb_pusch;
|
||||
uint8_t Mlimit;
|
||||
uint8_t max_turbo_iterations;
|
||||
uint8_t bundling;
|
||||
uint16_t beta_offset_cqi_times8;
|
||||
uint16_t beta_offset_ri_times8;
|
||||
uint16_t beta_offset_harqack_times8;
|
||||
uint8_t Msg3_active;
|
||||
uint16_t rnti;
|
||||
uint8_t cyclicShift;
|
||||
uint8_t cooperation_flag;
|
||||
uint8_t num_active_cba_groups;
|
||||
uint16_t cba_rnti[4];//NUM_MAX_CBA_GROUP];
|
||||
} fs6_dl_ulsched_t;
|
||||
|
||||
// CU to DU defintion of a DL packet for a given UE
|
||||
// The data itself is padded at the end of this structure
|
||||
typedef struct {
|
||||
enum pckType type:8;
|
||||
int UE_id;
|
||||
int8_t harq_pid;
|
||||
uint16_t rnti;
|
||||
int16_t sqrt_rho_a;
|
||||
int16_t sqrt_rho_b;
|
||||
CEmode_t CEmode:8;
|
||||
uint16_t nb_rb;
|
||||
uint8_t Qm;
|
||||
int8_t Nl;
|
||||
uint8_t pdsch_start;
|
||||
uint8_t sib1_br_flag;
|
||||
uint16_t i0;
|
||||
uint32_t rb_alloc[4];
|
||||
int dataLen;
|
||||
} fs6_dl_uespec_t;
|
||||
|
||||
// CU to DU definition of CCH channel
|
||||
typedef struct {
|
||||
int16_t UE_id;
|
||||
LTE_eNB_UCI cch_vars;
|
||||
} fs6_dl_uespec_ulcch_element_t;
|
||||
|
||||
// header to group all UE CCH channels definitions in one UDP packet
|
||||
typedef struct {
|
||||
enum pckType type:8;
|
||||
int16_t nb_active_ue;
|
||||
} fs6_dl_uespec_ulcch_t;
|
||||
|
||||
// code internal, not transmitted as this
|
||||
typedef struct {
|
||||
int ta;
|
||||
} ul_propagation_t;
|
||||
|
||||
// One UE UL data, data plane, UE data appended after the header
|
||||
typedef struct {
|
||||
enum pckType type:8;
|
||||
short UE_id;
|
||||
uint8_t harq_id;
|
||||
uint8_t segment;
|
||||
int segLen;
|
||||
int r_offset;
|
||||
int G;
|
||||
int ulsch_power[2];
|
||||
uint8_t o_ACK[4];
|
||||
uint8_t O_ACK;
|
||||
int ta;
|
||||
uint8_t o[MAX_CQI_BYTES];
|
||||
uint8_t cqi_crc_status;
|
||||
} fs6_ul_uespec_t;
|
||||
|
||||
// UL UCI (control plane), per UE
|
||||
typedef struct {
|
||||
enum pckType type:8;
|
||||
int UEid;
|
||||
int frame;
|
||||
int subframe;
|
||||
LTE_eNB_UCI uci;
|
||||
uint8_t harq_ack[4];
|
||||
uint8_t tdd_mapping_mode;
|
||||
uint16_t tdd_multiplexing_mask;
|
||||
unsigned short n0_subband_power_dB;
|
||||
uint16_t rnti;
|
||||
int32_t stat;
|
||||
} fs6_ul_uespec_uci_element_t;
|
||||
|
||||
// all segments UCI grouped in one UDP packet
|
||||
typedef struct {
|
||||
enum pckType type:8;
|
||||
int16_t nb_active_ue;
|
||||
} fs6_ul_uespec_uci_t;
|
||||
|
||||
|
||||
bool createUDPsock (char *sourceIP, char *sourcePort, char *destIP, char *destPort, UDPsock_t *result);
|
||||
int receiveSubFrame(UDPsock_t *sock, void *bufferZone, int bufferSize, uint16_t contentType);
|
||||
int sendSubFrame(UDPsock_t *sock, void *bufferZone, ssize_t secondHeaderSize, uint16_t contentType);
|
||||
|
||||
#define initBufferZone(xBuf) \
|
||||
uint8_t xBuf[FS6_BUF_SIZE]; \
|
||||
((commonUDP_t *)xBuf)->nbBlocks=0;
|
||||
|
||||
#define hUDP(xBuf) ((commonUDP_t *)xBuf)
|
||||
#define hDL(xBuf) ((fs6_dl_t*)(((commonUDP_t *)xBuf)+1))
|
||||
#define hUL(xBuf) ((fs6_ul_t*)(((commonUDP_t *)xBuf)+1))
|
||||
#define hDLUE(xBuf) ((fs6_dl_uespec_t*) (((fs6_dl_t*)(((commonUDP_t *)xBuf)+1))+1))
|
||||
#define hTxULUE(xBuf) ((fs6_dl_ulsched_t*) (((fs6_dl_t*)(((commonUDP_t *)xBuf)+1))+1))
|
||||
#define hTxULcch(xBuf) ((fs6_dl_uespec_ulcch_t*) (((fs6_dl_t*)(((commonUDP_t *)xBuf)+1))+1))
|
||||
#define hULUE(xBuf) ((fs6_ul_uespec_t*) (((fs6_ul_t*)(((commonUDP_t *)xBuf)+1))+1))
|
||||
#define hULUEuci(xBuf) ((fs6_ul_uespec_uci_t*) (((fs6_ul_t*)(((commonUDP_t *)xBuf)+1))+1))
|
||||
|
||||
static inline size_t alignedSize(uint8_t *ptr) {
|
||||
commonUDP_t *header=(commonUDP_t *) ptr;
|
||||
return ((header->contentBytes+sizeof(commonUDP_t)+blockAlign-1)/blockAlign)*blockAlign;
|
||||
}
|
||||
|
||||
static inline void *commonUDPdata(uint8_t *ptr) {
|
||||
return (void *) (((commonUDP_t *)ptr)+1);
|
||||
}
|
||||
|
||||
void setAllfromTS(uint64_t TS, L1_rxtx_proc_t *proc);
|
||||
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);
|
||||
void sendFs6Ul(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int segmentID, int16_t *data, int dataLen, int r_offset);
|
||||
void *cu_fs6(void *arg);
|
||||
void *du_fs6(void *arg);
|
||||
void fill_rf_config(RU_t *ru, char *rf_config_file);
|
||||
int init_rf(RU_t *ru);
|
||||
void rx_rf(RU_t *ru, L1_rxtx_proc_t *proc);
|
||||
void tx_rf(RU_t *ru, L1_rxtx_proc_t *proc);
|
||||
void common_signal_procedures (PHY_VARS_eNB *eNB,int frame, int subframe);
|
||||
void pmch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc);
|
||||
bool dlsch_procedures(PHY_VARS_eNB *eNB,
|
||||
L1_rxtx_proc_t *proc,
|
||||
int harq_pid,
|
||||
LTE_eNB_DLSCH_t *dlsch,
|
||||
LTE_eNB_UE_stats *ue_stats) ;
|
||||
void postDecode(L1_rxtx_proc_t *proc, notifiedFIFO_elt_t *req);
|
||||
void pdsch_procedures(PHY_VARS_eNB *eNB,
|
||||
L1_rxtx_proc_t *proc,
|
||||
int harq_pid,
|
||||
LTE_eNB_DLSCH_t *dlsch,
|
||||
LTE_eNB_DLSCH_t *dlsch1);
|
||||
void srs_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc);
|
||||
void uci_procedures(PHY_VARS_eNB *eNB,
|
||||
L1_rxtx_proc_t *proc);
|
||||
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);
|
||||
void rx_prach0(PHY_VARS_eNB *eNB,
|
||||
RU_t *ru,
|
||||
int frame_prach,
|
||||
int subframe,
|
||||
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,
|
||||
uint8_t ce_level
|
||||
);
|
||||
void ocp_tx_rf(RU_t *ru, L1_rxtx_proc_t *proc);
|
||||
|
||||
// mistakes in main OAI
|
||||
void phy_init_RU(RU_t *);
|
||||
void fep_full(RU_t *ru, int subframe);
|
||||
void feptx_prec(RU_t *ru,int frame,int subframe);
|
||||
void feptx_ofdm(RU_t *ru, int frame, int subframe);
|
||||
void oai_subframe_ind(uint16_t sfn, uint16_t sf);
|
||||
extern uint16_t sf_ahead;
|
||||
#endif
|
||||
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
Author: Laurent THOMAS, Open Cells Project company, funded by IRT SystemX
|
||||
copyleft: OpenAirInterface Software Alliance and it's licence
|
||||
*/
|
||||
#include <executables/split_headers.h>
|
||||
#include <sys/types.h> /* See NOTES */
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/udp.h>
|
||||
#include <netdb.h>
|
||||
#include <targets/RT/USER/lte-softmodem.h>
|
||||
|
||||
bool createUDPsock (char *sourceIP, char *sourcePort, char *destIP, char *destPort, UDPsock_t *result) {
|
||||
struct addrinfo hints= {0}, *servinfo, *p;
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
int status;
|
||||
|
||||
if ((status = getaddrinfo(sourceIP, sourcePort, &hints, &servinfo)) != 0) {
|
||||
LOG_E(GTPU,"getaddrinfo error: %s\n", gai_strerror(status));
|
||||
return false;
|
||||
}
|
||||
|
||||
// loop through all the results and bind to the first we can
|
||||
for(p = servinfo; p != NULL; p = p->ai_next) {
|
||||
if ((result->sockHandler = socket(p->ai_family, p->ai_socktype,
|
||||
p->ai_protocol)) == -1) {
|
||||
LOG_W(GTPU,"socket: %s\n", strerror(errno));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bind(result->sockHandler, p->ai_addr, p->ai_addrlen) == -1) {
|
||||
close(result->sockHandler);
|
||||
LOG_W(GTPU,"bind: %s\n", strerror(errno));
|
||||
continue;
|
||||
}
|
||||
|
||||
break; // if we get here, we must have connected successfully
|
||||
}
|
||||
|
||||
if (p == NULL) {
|
||||
// looped off the end of the list with no successful bind
|
||||
LOG_E(GTPU,"failed to bind socket: %s %s \n",sourceIP,sourcePort);
|
||||
return false;
|
||||
}
|
||||
|
||||
freeaddrinfo(servinfo); // all done with this structure
|
||||
|
||||
if ((status = getaddrinfo(destIP, destPort, &hints, &servinfo)) != 0) {
|
||||
LOG_E(GTPU,"getaddrinfo error: %s\n", gai_strerror(status));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (servinfo) {
|
||||
result->destAddr=servinfo;
|
||||
} else {
|
||||
LOG_E(PHY,"No valid UDP addr: %s:%s\n",destIP, destPort);
|
||||
return false;
|
||||
}
|
||||
|
||||
int enable=1;
|
||||
AssertFatal(setsockopt(result->sockHandler, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable))==0,"");
|
||||
struct timeval tv= {0,UDP_TIMEOUT};
|
||||
|
||||
if (IS_SOFTMODEM_RFSIM)
|
||||
tv.tv_sec=2; //debug: wait 2 seconds for human understanding
|
||||
|
||||
AssertFatal(setsockopt(result->sockHandler, 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(result->sockHandler, SOL_SOCKET, SO_SNDBUF, &buff, sizeof(buff)) == 0, "");
|
||||
AssertFatal ( setsockopt(result->sockHandler, SOL_SOCKET, SO_RCVBUF, &buff, sizeof(buff)) == 0, "");
|
||||
return true;
|
||||
}
|
||||
|
||||
// sock: udp socket
|
||||
// bufferZone: a reception area of bufferSize
|
||||
int receiveSubFrame(UDPsock_t *sock, void *bufferZone, int bufferSize, uint16_t contentType) {
|
||||
int rcved=0;
|
||||
commonUDP_t *bufOrigin=(commonUDP_t *)bufferZone;
|
||||
static uint8_t crossData[65536];
|
||||
static int crossDataSize=0;
|
||||
|
||||
if (crossDataSize) {
|
||||
LOG_D(HW,"copy a block received in previous subframe\n");
|
||||
memcpy(bufferZone, crossData, crossDataSize);
|
||||
rcved=1;
|
||||
bufferZone+=crossDataSize;
|
||||
crossDataSize=0;
|
||||
}
|
||||
|
||||
do {
|
||||
//read all subframe data from the control unit
|
||||
int ret=recv(sock->sockHandler, bufferZone, bufferSize, 0);
|
||||
|
||||
if ( ret==-1) {
|
||||
if ( errno == EWOULDBLOCK || errno== EINTR ) {
|
||||
LOG_I(HW,"Received: Timeout, subframe incomplete\n");
|
||||
return rcved;
|
||||
} else {
|
||||
LOG_E(HW,"Critical issue in socket: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (hUDP(bufferZone)->contentType != contentType)
|
||||
abort();
|
||||
|
||||
if (rcved && bufOrigin->timestamp != hUDP(bufferZone)->timestamp ) {
|
||||
if ( hUDP(bufferZone)->timestamp > bufOrigin->timestamp ) {
|
||||
LOG_W(HW,"Received data for TS: %lu before end of TS : %lu completion\n",
|
||||
hUDP(bufferZone)->timestamp,
|
||||
bufOrigin->timestamp);
|
||||
memcpy(crossData, bufferZone, ret );
|
||||
crossDataSize=ret;
|
||||
return rcved;
|
||||
} else {
|
||||
LOG_W(HW,"Dropping late packet\n");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
rcved++;
|
||||
bufferZone+=ret;
|
||||
}
|
||||
|
||||
LOG_D(HW,"Received: blocks: %d/%d, size %d, TS: %lu\n",
|
||||
rcved, bufOrigin->nbBlocks, ret, bufOrigin->timestamp);
|
||||
} while ( rcved == 0 || rcved < bufOrigin->nbBlocks );
|
||||
|
||||
return rcved;
|
||||
}
|
||||
|
||||
int sendSubFrame(UDPsock_t *sock, void *bufferZone, ssize_t secondHeaderSize, uint16_t contentType) {
|
||||
commonUDP_t *UDPheader=(commonUDP_t *)bufferZone ;
|
||||
UDPheader->contentType=contentType;
|
||||
UDPheader->senderClock=rdtsc();
|
||||
int nbBlocks=UDPheader->nbBlocks;
|
||||
int blockId=0;
|
||||
|
||||
if (nbBlocks <= 0 ) {
|
||||
LOG_E(PHY,"FS6: can't send blocks: %d\n", nbBlocks);
|
||||
return 0;
|
||||
}
|
||||
|
||||
do {
|
||||
if (blockId > 0 ) {
|
||||
commonUDP_t *currentHeader=(commonUDP_t *)bufferZone;
|
||||
currentHeader->timestamp=UDPheader->timestamp;
|
||||
currentHeader->nbBlocks=UDPheader->nbBlocks;
|
||||
currentHeader->blockID=blockId;
|
||||
currentHeader->contentType=UDPheader->contentType;
|
||||
memcpy(commonUDPdata((void *)currentHeader), commonUDPdata(bufferZone), secondHeaderSize);
|
||||
}
|
||||
|
||||
blockId++;
|
||||
int sz=alignedSize(bufferZone);
|
||||
// Let's use the first address returned by getaddrinfo()
|
||||
int ret=sendto(sock->sockHandler, bufferZone, sz, 0,
|
||||
sock->destAddr->ai_addr, sock->destAddr->ai_addrlen);
|
||||
|
||||
if ( ret != sz )
|
||||
LOG_W(HW,"Wrote socket doesn't return size %d (val: %d, errno:%d, %s)\n",
|
||||
sz, ret, errno, strerror(errno));
|
||||
|
||||
LOG_D(HW,"Sent: TS: %lu, blocks %d/%d, block size : %d \n",
|
||||
UDPheader->timestamp, UDPheader->nbBlocks-nbBlocks, UDPheader->nbBlocks, sz);
|
||||
bufferZone+=sz;
|
||||
nbBlocks--;
|
||||
} while (nbBlocks);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user