diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c index 12bd06bb8154f7b31f68451df3f47010a5dab8cd..3aa40e2183ef20ef1e1402afa14017db50a23268 100644 --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -29,7 +29,7 @@ #include "LAYER2/MAC/extern.h" #include "MBSFN-SubframeConfigList.h" #include "UTIL/LOG/vcd_signal_dumper.h" -//#define DEBUG_PHY +#define DEBUG_PHY #include "assertions.h" #include <math.h> @@ -1304,25 +1304,26 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, common_vars->txdataF[eNB_id] = (int32_t **)malloc16(NB_ANTENNA_PORTS_ENB*sizeof(int32_t*)); common_vars->txdataF_BF[eNB_id] = (int32_t **)malloc16(fp->nb_antennas_tx*sizeof(int32_t*)); - for (i=0; i<14; i++) { - common_vars->txdataF[eNB_id][i] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*fp->symbols_per_tti*10*sizeof(int32_t) ); + if (eNB->node_function != NGFI_RRU_IF5) { + for (i=0; i<((eNB->do_precoding==0)?fp->nb_antennas_tx:14); i++) { + common_vars->txdataF[eNB_id][i] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*fp->symbols_per_tti*10*sizeof(int32_t) ); #ifdef DEBUG_PHY - msg("[openair][LTE_PHY][INIT] lte_common_vars->txdataF[%d][%d] = %p (%d bytes)\n", - eNB_id,i,common_vars->txdataF[eNB_id][i], - fp->ofdm_symbol_size*fp->symbols_per_tti*10*sizeof(int32_t)); + printf("[openair][LTE_PHY][INIT] common_vars->txdataF[%d][%d] = %p (%lu bytes)\n", + eNB_id,i,common_vars->txdataF[eNB_id][i], + fp->ofdm_symbol_size*fp->symbols_per_tti*10*sizeof(int32_t)); #endif + } } - for (i=0; i<fp->nb_antennas_tx; i++) { common_vars->txdataF_BF[eNB_id][i] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t) ); if (eNB->node_function != NGFI_RCC_IF4p5) - common_vars->txdata[eNB_id][i] = (int32_t*)malloc16_clear(fp->samples_per_tti*10*sizeof(int32_t) ); + + // Allocate 10 subframes of I/Q TX signal data (time) if not + common_vars->txdata[eNB_id][i] = (int32_t*)malloc16_clear( fp->samples_per_tti*10*sizeof(int32_t) ); #ifdef DEBUG_PHY - msg("[openair][LTE_PHY][INIT] lte_common_vars->txdataF_BF[%d][%d] = %p (%d bytes)\n", - eNB_id,i,common_vars->txdataF_BF[eNB_id][i], - fp->ofdm_symbol_size*sizeof(int32_t)); - msg("[openair][LTE_PHY][INIT] lte_common_vars->txdata[%d][%d] = %p\n",eNB_id,i,common_vars->txdata[eNB_id][i]); + printf("[openair][LTE_PHY][INIT] common_vars->txdata[%d][%d] = %p (%lu bytes)\n",eNB_id,i,common_vars->txdata[eNB_id][i], + fp->samples_per_tti*10*sizeof(int32_t)); #endif } @@ -1358,17 +1359,25 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, for (i=0; i<fp->nb_antennas_rx; i++) { if (eNB->node_function != NGFI_RCC_IF4p5) { + // allocate 2 subframes of I/Q signal data (time) if not an RCC (no time-domain signals) common_vars->rxdata[eNB_id][i] = (int32_t*)malloc16_clear( fp->samples_per_tti*10*sizeof(int32_t) ); - common_vars->rxdata_7_5kHz[eNB_id][i] = (int32_t*)malloc16_clear( fp->samples_per_tti*sizeof(int32_t) ); + + if (eNB->node_function != NGFI_RRU_IF5) + // allocate 2 subframes of I/Q signal data (time, 7.5 kHz offset) + common_vars->rxdata_7_5kHz[eNB_id][i] = (int32_t*)malloc16_clear( 2*fp->samples_per_tti*2*sizeof(int32_t) ); + } + if (eNB->node_function != NGFI_RRU_IF5) + // allocate 2 subframes of I/Q signal data (frequency) + common_vars->rxdataF[eNB_id][i] = (int32_t*)malloc16_clear(sizeof(int32_t)*(2*fp->ofdm_symbol_size*fp->symbols_per_tti) ); #ifdef DEBUG_PHY - printf("[openair][LTE_PHY][INIT] common_vars->rxdata[%d][%d] = %p\n",eNB_id,i,common_vars->rxdata[eNB_id][i]); - printf("[openair][LTE_PHY][INIT] common_vars->rxdata_7_5kHz[%d][%d] = %p\n",eNB_id,i,common_vars->rxdata_7_5kHz[eNB_id][i]); + printf("[openair][LTE_PHY][INIT] common_vars->rxdata[%d][%d] = %p (%lu bytes)\n",eNB_id,i,common_vars->rxdata[eNB_id][i],fp->samples_per_tti*10*sizeof(int32_t)); + if (eNB->node_function != NGFI_RRU_IF5) + printf("[openair][LTE_PHY][INIT] common_vars->rxdata_7_5kHz[%d][%d] = %p (%lu bytes)\n",eNB_id,i,common_vars->rxdata_7_5kHz[eNB_id][i],fp->samples_per_tti*2*sizeof(int32_t)); #endif - } common_vars->rxdataF[eNB_id][i] = (int32_t*)malloc16_clear(sizeof(int32_t)*(fp->ofdm_symbol_size*fp->symbols_per_tti) ); } - if (eNB->node_function != NGFI_RRU_IF4p5) { + if ((eNB->node_function != NGFI_RRU_IF4p5)&&(eNB->node_function != NGFI_RRU_IF5)) { // Channel estimates for SRS for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) { @@ -1383,7 +1392,8 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, common_vars->sync_corr[eNB_id] = (uint32_t*)malloc16_clear( LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(uint32_t)*fp->samples_per_tti ); } - } else { //UPLINK abstraction = 1 + } // abstraction_flag = 0 + else { //UPLINK abstraction = 1 eNB->sinr_dB = (double*) malloc16_clear( fp->N_RB_DL*12*sizeof(double) ); } } //eNB_id @@ -1391,7 +1401,7 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, if (abstraction_flag==0) { - if (eNB->node_function != NGFI_RRU_IF4p5) { + if ((eNB->node_function != NGFI_RRU_IF4p5)&&(eNB->node_function != NGFI_RRU_IF5)) { generate_ul_ref_sigs_rx(); // SRS @@ -1405,7 +1415,7 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, // ULSCH VARS, skip if NFGI_RRU_IF4 - if (eNB->node_function!=NGFI_RRU_IF4p5) + if ((eNB->node_function!=NGFI_RRU_IF4p5)&&(eNB->node_function != NGFI_RRU_IF5)) prach_vars->prachF = (int16_t*)malloc16_clear( 1024*2*sizeof(int16_t) ); /* number of elements of an array X is computed as sizeof(X) / sizeof(X[0]) */ @@ -1418,7 +1428,7 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, #endif } - if (eNB->node_function != NGFI_RRU_IF4p5) { + if ((eNB->node_function != NGFI_RRU_IF4p5)&&(eNB->node_function != NGFI_RRU_IF5)) { AssertFatal(fp->nb_antennas_rx <= sizeof(prach_vars->prach_ifft) / sizeof(prach_vars->prach_ifft[0]), "nb_antennas_rx too large"); for (i=0; i<fp->nb_antennas_rx; i++) { diff --git a/openair1/PHY/INIT/lte_parms.c b/openair1/PHY/INIT/lte_parms.c index cd879b1a90e6634ef02de54d2adea067e6bdb7ee..f0c63df9e6c2caebc13fd5e7b7366c80dc44518a 100644 --- a/openair1/PHY/INIT/lte_parms.c +++ b/openair1/PHY/INIT/lte_parms.c @@ -22,6 +22,23 @@ #include "defs.h" #include "log.h" +uint16_t dl_S_table_normal[10]={3,9,10,11,12,3,9,10,11,6}; +uint16_t dl_S_table_extended[10]={3,8,9,10,3,8,9,5,0,0}; + +void set_S_config(LTE_DL_FRAME_PARMS *fp) { + + int X = fp->srsX; + + fp->ul_symbols_in_S_subframe=(1+X); + + if ((fp->Ncp==EXTENDED) && (fp->tdd_config_S>7)) + AssertFatal(1==0,"Illegal S subframe configuration for Extended Prefix mode\n"); + + fp->dl_symbols_in_S_subframe = (fp->Ncp==NORMAL)?dl_S_table_normal[fp->tdd_config_S] : dl_S_table_extended[fp->tdd_config_S]; + + +} + int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf) { @@ -29,7 +46,7 @@ int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf) LOG_I(PHY,"Initializing frame parms for N_RB_DL %d, Ncp %d, osf %d\n",frame_parms->N_RB_DL,frame_parms->Ncp,osf); - if (frame_parms->Ncp==1) { + if (frame_parms->Ncp==EXTENDED) { frame_parms->nb_prefix_samples0=512; frame_parms->nb_prefix_samples = 512; frame_parms->symbols_per_tti = 12; @@ -37,8 +54,10 @@ int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf) frame_parms->nb_prefix_samples0 = 160; frame_parms->nb_prefix_samples = 144; frame_parms->symbols_per_tti = 14; + } + switch(osf) { case 1: log2_osf = 0; @@ -167,6 +186,8 @@ int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf) printf("lte_parms.c: Setting N_RB_DL to %d, ofdm_symbol_size %d\n",frame_parms->N_RB_DL, frame_parms->ofdm_symbol_size); + if (frame_parms->frame_type == TDD) set_S_config(frame_parms); + // frame_parms->tdd_config=3; return(0); } diff --git a/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c b/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c index 6c7399fcbec215509cd49a20cfaa2a4360c244b9..e6551033f31fc1891dda98b0401cc1da959b63b4 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c @@ -510,14 +510,15 @@ int lte_sync_time_eNB(int32_t **rxdata, ///rx data in time domain // perform a time domain correlation using the oversampled sync sequence - unsigned int n, ar, peak_val, peak_pos, mean_val; + unsigned int n, ar, peak_val, peak_pos; + uint64_t mean_val; int result; short *primary_synch_time; int eNB_id = frame_parms->Nid_cell%3; // msg("[SYNC TIME] Calling sync_time_eNB(%p,%p,%d,%d)\n",rxdata,frame_parms,eNB_id,length); if (sync_corr_eNB == NULL) { - msg("[SYNC TIME] sync_corr_eNB not yet allocated! Exiting.\n"); + LOG_E(PHY,"[SYNC TIME] sync_corr_eNB not yet allocated! Exiting.\n"); return(-1); } @@ -535,7 +536,7 @@ int lte_sync_time_eNB(int32_t **rxdata, ///rx data in time domain break; default: - msg("[SYNC TIME] Illegal eNB_id!\n"); + LOG_E(PHY,"[SYNC TIME] Illegal eNB_id!\n"); return (-1); } @@ -567,7 +568,7 @@ int lte_sync_time_eNB(int32_t **rxdata, ///rx data in time domain peak_val); } */ - mean_val += (sync_corr_eNB[n]>>10); + mean_val += sync_corr_eNB[n]; if (sync_corr_eNB[n]>peak_val) { peak_val = sync_corr_eNB[n]; @@ -575,17 +576,15 @@ int lte_sync_time_eNB(int32_t **rxdata, ///rx data in time domain } } + mean_val/=length; + *peak_val_out = peak_val; - if (peak_val <= (40*mean_val)) { -#ifdef DEBUG_PHY - msg("[SYNC TIME] No peak found (%u,%u,%u,%u)\n",peak_pos,peak_val,mean_val,40*mean_val); -#endif + if (peak_val <= (40*(uint32_t)mean_val)) { + LOG_D(PHY,"[SYNC TIME] No peak found (%u,%u,%u,%u)\n",peak_pos,peak_val,mean_val,40*mean_val); return(-1); } else { -#ifdef DEBUG_PHY - msg("[SYNC TIME] Peak found at pos %u, val = %u, mean_val = %u\n",peak_pos,peak_val,mean_val); -#endif + LOG_D(PHY,"[SYNC TIME] Peak found at pos %u, val = %u, mean_val = %u\n",peak_pos,peak_val,mean_val); return(peak_pos); } diff --git a/openair1/PHY/LTE_TRANSPORT/if4_tools.c b/openair1/PHY/LTE_TRANSPORT/if4_tools.c old mode 100644 new mode 100755 index 68bf46da789e1c42d32ea55c2e9f40d56ae6e3c5..924eef11b97a562a4fa7913b9db80ee54c63294e --- a/openair1/PHY/LTE_TRANSPORT/if4_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/if4_tools.c @@ -32,16 +32,20 @@ #include "PHY/defs.h" #include "PHY/TOOLS/alaw_lut.h" +#include "PHY/extern.h" +#include "SCHED/defs.h" -#include "targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h" +//#include "targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h" +#include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h" #include "UTIL/LOG/vcd_signal_dumper.h" void send_IF4p5(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type, int k) { LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; - int32_t **txdataF = eNB->common_vars.txdataF[0]; - int32_t **rxdataF = eNB->common_vars.rxdataF[0]; - int16_t **rxsigF = eNB->prach_vars.rxsigF; - void *tx_buffer = eNB->ifbuffer.tx; + int32_t **txdataF = (eNB->CC_id==0) ? eNB->common_vars.txdataF[0] : PHY_vars_eNB_g[0][0]->common_vars.txdataF[0]; + int32_t **rxdataF = eNB->common_vars.rxdataF[0]; + int16_t **rxsigF = eNB->prach_vars.rxsigF; + void *tx_buffer = eNB->ifbuffer.tx[subframe&1]; + void *tx_buffer_prach = eNB->ifbuffer.tx_prach; uint16_t symbol_id=0, element_id=0; uint16_t db_fulllength, db_halflength; @@ -49,31 +53,44 @@ void send_IF4p5(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type uint16_t *data_block=NULL, *i=NULL; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF4, 1 ); + IF4p5_header_t *packet_header=NULL; + eth_state_t *eth = (eth_state_t*) (eNB->ifdevice.priv); + int nsym = fp->symbols_per_tti; + + if (eNB->CC_id==0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF4, 1 ); if (packet_type == IF4p5_PDLFFT) { + if (subframe_select(fp,subframe)==SF_S) + nsym=fp->dl_symbols_in_S_subframe; + db_fulllength = 12*fp->N_RB_DL; db_halflength = (db_fulllength)>>1; slotoffsetF = (subframe)*(fp->ofdm_symbol_size)*((fp->Ncp==1) ? 12 : 14) + 1; blockoffsetF = slotoffsetF + fp->ofdm_symbol_size - db_halflength - 1; - IF4p5_header_t *dl_header = (IF4p5_header_t *)(tx_buffer + MAC_HEADER_SIZE_BYTES); - data_block = (uint16_t*)(tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t); - gen_IF4p5_dl_header(dl_header, frame, subframe); + if (eth->flags == ETH_RAW_IF4p5_MODE) { + packet_header = (IF4p5_header_t *)(tx_buffer + MAC_HEADER_SIZE_BYTES); + data_block = (uint16_t*)(tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t); + } else { + packet_header = (IF4p5_header_t *)(tx_buffer); + data_block = (uint16_t*)(tx_buffer + sizeof_IF4p5_header_t); + } + gen_IF4p5_dl_header(packet_header, frame, subframe); - for (symbol_id=0; symbol_id<fp->symbols_per_tti; symbol_id++) { + for (symbol_id=0; symbol_id<nsym; symbol_id++) { + if (eNB->CC_id==1) LOG_I(PHY,"DL_IF4p5: CC_id %d : frame %d, subframe %d, symbol %d\n",eNB->CC_id,frame,subframe,symbol_id); for (element_id=0; element_id<db_halflength; element_id++) { - i = (uint16_t*) &txdataF[0][blockoffsetF+element_id]; + i = (uint16_t*) &txdataF[eNB->CC_id][blockoffsetF+element_id]; data_block[element_id] = ((uint16_t) lin2alaw[*i]) | (lin2alaw[*(i+1)]<<8); - i = (uint16_t*) &txdataF[0][slotoffsetF+element_id]; + i = (uint16_t*) &txdataF[eNB->CC_id][slotoffsetF+element_id]; data_block[element_id+db_halflength] = ((uint16_t) lin2alaw[*i]) | (lin2alaw[*(i+1)]<<8); } - dl_header->frame_status &= ~(0x000f<<26); - dl_header->frame_status |= (symbol_id&0x000f)<<26; + packet_header->frame_status &= ~(0x000f<<26); + packet_header->frame_status |= (symbol_id&0x000f)<<26; if ((eNB->ifdevice.trx_write_func(&eNB->ifdevice, symbol_id, @@ -87,58 +104,92 @@ void send_IF4p5(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type slotoffsetF += fp->ofdm_symbol_size; blockoffsetF += fp->ofdm_symbol_size; } - } else if (packet_type == IF4p5_PULFFT) { + } else if ((packet_type == IF4p5_PULFFT)|| + (packet_type == IF4p5_PULTICK)){ db_fulllength = 12*fp->N_RB_UL; db_halflength = (db_fulllength)>>1; slotoffsetF = 1; blockoffsetF = slotoffsetF + fp->ofdm_symbol_size - db_halflength - 1; - IF4p5_header_t *ul_header = (IF4p5_header_t *)(tx_buffer + MAC_HEADER_SIZE_BYTES); - data_block = (uint16_t*)(tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t); - - gen_IF4p5_ul_header(ul_header, frame, subframe); - - for (symbol_id=0; symbol_id<fp->symbols_per_tti; symbol_id++) { - - for (element_id=0; element_id<db_halflength; element_id++) { - i = (uint16_t*) &rxdataF[0][blockoffsetF+element_id]; - data_block[element_id] = ((uint16_t) lin2alaw[*i]) | (lin2alaw[*(i+1)]<<8); + if (subframe_select(fp,subframe)==SF_S) { + nsym=fp->ul_symbols_in_S_subframe; + slotoffsetF += (fp->ofdm_symbol_size*(fp->symbols_per_tti-nsym)); + blockoffsetF += (fp->ofdm_symbol_size*(fp->symbols_per_tti-nsym)); + } - i = (uint16_t*) &rxdataF[0][slotoffsetF+element_id]; - data_block[element_id+db_halflength] = ((uint16_t) lin2alaw[*i]) | (lin2alaw[*(i+1)]<<8); - } - - ul_header->frame_status &= ~(0x000f<<26); - ul_header->frame_status |= (symbol_id&0x000f)<<26; - + if (eth->flags == ETH_RAW_IF4p5_MODE) { + packet_header = (IF4p5_header_t *)(tx_buffer + MAC_HEADER_SIZE_BYTES); + data_block = (uint16_t*)(tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t); + } else { + packet_header = (IF4p5_header_t *)(tx_buffer); + data_block = (uint16_t*)(tx_buffer + sizeof_IF4p5_header_t); + } + gen_IF4p5_ul_header(packet_header, packet_type, frame, subframe); + + if (packet_type == IF4p5_PULFFT) { + for (symbol_id=fp->symbols_per_tti-nsym; symbol_id<fp->symbols_per_tti; symbol_id++) { + LOG_D(PHY,"IF4p5_PULFFT: frame %d, subframe %d, symbol %d\n",frame,subframe,symbol_id); + for (element_id=0; element_id<db_halflength; element_id++) { + i = (uint16_t*) &rxdataF[0][blockoffsetF+element_id]; + data_block[element_id] = ((uint16_t) lin2alaw[*i]) | (lin2alaw[*(i+1)]<<8); + + i = (uint16_t*) &rxdataF[0][slotoffsetF+element_id]; + data_block[element_id+db_halflength] = ((uint16_t) lin2alaw[*i]) | (lin2alaw[*(i+1)]<<8); + } + + packet_header->frame_status &= ~(0x000f<<26); + packet_header->frame_status |= (symbol_id&0x000f)<<26; + + if ((eNB->ifdevice.trx_write_func(&eNB->ifdevice, + symbol_id, + &tx_buffer, + db_fulllength, + 1, + IF4p5_PULFFT)) < 0) { + perror("ETHERNET write for IF4p5_PULFFT\n"); + } + + slotoffsetF += fp->ofdm_symbol_size; + blockoffsetF += fp->ofdm_symbol_size; + } + } + else { if ((eNB->ifdevice.trx_write_func(&eNB->ifdevice, - symbol_id, - &tx_buffer, - db_fulllength, - 1, - IF4p5_PULFFT)) < 0) { - perror("ETHERNET write for IF4p5_PULFFT\n"); + 0, + &tx_buffer, + 0, + 1, + IF4p5_PULTICK)) < 0) { + perror("ETHERNET write for IF4p5_PULFFT\n"); } - - slotoffsetF += fp->ofdm_symbol_size; - blockoffsetF += fp->ofdm_symbol_size; - } + } } else if (packet_type == IF4p5_PRACH) { // FIX: hard coded prach samples length - db_fulllength = 840*2; - - IF4p5_header_t *prach_header = (IF4p5_header_t *)(tx_buffer + MAC_HEADER_SIZE_BYTES); - data_block = (uint16_t*)(tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t); + LOG_D(PHY,"IF4p5_PRACH: frame %d, subframe %d\n",frame,subframe); + db_fulllength = PRACH_HARD_CODED_NUM_SAMPLES; + + if (eth->flags == ETH_RAW_IF4p5_MODE) { + packet_header = (IF4p5_header_t *)(tx_buffer_prach + MAC_HEADER_SIZE_BYTES); + data_block = (uint16_t*)(tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t); + } else { + packet_header = (IF4p5_header_t *)(tx_buffer_prach); + data_block = (uint16_t*)(tx_buffer_prach + sizeof_IF4p5_header_t); + } + gen_IF4p5_prach_header(packet_header, frame, subframe); + + if (eth->flags == ETH_RAW_IF4p5_MODE) { + memcpy((int16_t*)(tx_buffer_prach + MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t), + (&rxsigF[0][k]), + PRACH_BLOCK_SIZE_BYTES); + } else { + memcpy((int16_t*)(tx_buffer_prach + sizeof_IF4p5_header_t), + (&rxsigF[0][k]), + PRACH_BLOCK_SIZE_BYTES); + } - gen_IF4p5_prach_header(prach_header, frame, subframe); - - memcpy((int16_t*)(tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t), - (&rxsigF[0][k]), - db_fulllength*sizeof(int16_t)); - if ((eNB->ifdevice.trx_write_func(&eNB->ifdevice, symbol_id, - &tx_buffer, + &tx_buffer_prach, db_fulllength, 1, IF4p5_PRACH)) < 0) { @@ -148,7 +199,7 @@ void send_IF4p5(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type AssertFatal(1==0, "send_IF4p5 - Unknown packet_type %x", packet_type); } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF4, 0 ); + if (eNB->CC_id==0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF4, 0 ); return; } @@ -163,8 +214,9 @@ void recv_IF4p5(PHY_VARS_eNB *eNB, int *frame, int *subframe, uint16_t *packet_t uint16_t element_id; uint16_t db_fulllength, db_halflength; int slotoffsetF=0, blockoffsetF=0; + eth_state_t *eth = (eth_state_t*) (eNB->ifdevice.priv); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 1 ); + if (eNB->CC_id==0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 1 ); if (eNB->node_function == NGFI_RRU_IF4p5) { db_fulllength = (12*fp->N_RB_DL); @@ -183,17 +235,28 @@ void recv_IF4p5(PHY_VARS_eNB *eNB, int *frame, int *subframe, uint16_t *packet_t 0) < 0) { perror("ETHERNET read"); } - - packet_header = (IF4p5_header_t*) (rx_buffer+MAC_HEADER_SIZE_BYTES); - data_block = (uint16_t*) (rx_buffer+MAC_HEADER_SIZE_BYTES+sizeof_IF4p5_header_t); + if (eth->flags == ETH_RAW_IF4p5_MODE) { + packet_header = (IF4p5_header_t*) (rx_buffer+MAC_HEADER_SIZE_BYTES); + data_block = (uint16_t*) (rx_buffer+MAC_HEADER_SIZE_BYTES+sizeof_IF4p5_header_t); + } else { + packet_header = (IF4p5_header_t*) (rx_buffer); + data_block = (uint16_t*) (rx_buffer+sizeof_IF4p5_header_t); + } + + + *frame = ((packet_header->frame_status)>>6)&0xffff; - *subframe = ((packet_header->frame_status)>>22)&0x000f; + *subframe = ((packet_header->frame_status)>>22)&0x000f; + + *packet_type = packet_header->sub_type; if (*packet_type == IF4p5_PDLFFT) { *symbol_number = ((packet_header->frame_status)>>26)&0x000f; + LOG_D(PHY,"DL_IF4p5: CC_id %d : frame %d, subframe %d, symbol %d\n",eNB->CC_id,*frame,*subframe,*symbol_number); + slotoffsetF = (*symbol_number)*(fp->ofdm_symbol_size) + (*subframe)*(fp->ofdm_symbol_size)*((fp->Ncp==1) ? 12 : 14) + 1; blockoffsetF = slotoffsetF + fp->ofdm_symbol_size - db_halflength - 1; @@ -210,6 +273,8 @@ void recv_IF4p5(PHY_VARS_eNB *eNB, int *frame, int *subframe, uint16_t *packet_t } else if (*packet_type == IF4p5_PULFFT) { *symbol_number = ((packet_header->frame_status)>>26)&0x000f; + if (eNB->CC_id==1) LOG_I(PHY,"UL_IF4p5: CC_id %d : frame %d, subframe %d, symbol %d\n",eNB->CC_id,*frame,*subframe,*symbol_number); + slotoffsetF = (*symbol_number)*(fp->ofdm_symbol_size) + 1; blockoffsetF = slotoffsetF + fp->ofdm_symbol_size - db_halflength - 1; @@ -224,18 +289,27 @@ void recv_IF4p5(PHY_VARS_eNB *eNB, int *frame, int *subframe, uint16_t *packet_t } } else if (*packet_type == IF4p5_PRACH) { + if (eNB->CC_id==1) LOG_I(PHY,"PRACH_IF4p5: CC_id %d : frame %d, subframe %d, symbol %d\n",eNB->CC_id,*frame,*subframe); + // FIX: hard coded prach samples length - db_fulllength = 840*2; - - memcpy((&rxsigF[0][0]), - (int16_t*) (rx_buffer+MAC_HEADER_SIZE_BYTES+sizeof_IF4p5_header_t), - db_fulllength*sizeof(int16_t)); - + db_fulllength = PRACH_HARD_CODED_NUM_SAMPLES; + + if (eth->flags == ETH_RAW_IF4p5_MODE) { + memcpy((&rxsigF[0][0]), + (int16_t*) (rx_buffer+MAC_HEADER_SIZE_BYTES+sizeof_IF4p5_header_t), + PRACH_BLOCK_SIZE_BYTES); + } else { + memcpy((&rxsigF[0][0]), + (int16_t*) (rx_buffer+sizeof_IF4p5_header_t), + PRACH_BLOCK_SIZE_BYTES); + } + } else if (*packet_type == IF4p5_PULTICK) { + } else { AssertFatal(1==0, "recv_IF4p5 - Unknown packet_type %x", *packet_type); } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 0 ); + if (eNB->CC_id==0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 0 ); return; } @@ -253,10 +327,10 @@ void gen_IF4p5_dl_header(IF4p5_header_t *dl_packet, int frame, int subframe) { } -void gen_IF4p5_ul_header(IF4p5_header_t *ul_packet, int frame, int subframe) { +void gen_IF4p5_ul_header(IF4p5_header_t *ul_packet, uint16_t packet_subtype, int frame, int subframe) { ul_packet->type = IF4p5_PACKET_TYPE; - ul_packet->sub_type = IF4p5_PULFFT; + ul_packet->sub_type = packet_subtype; ul_packet->rsvd = 0; @@ -282,6 +356,18 @@ void gen_IF4p5_prach_header(IF4p5_header_t *prach_packet, int frame, int subfram void malloc_IF4p5_buffer(PHY_VARS_eNB *eNB) { // Keep the size large enough - eNB->ifbuffer.tx = malloc(RAW_IF4p5_PRACH_SIZE_BYTES); - eNB->ifbuffer.rx = malloc(RAW_IF4p5_PRACH_SIZE_BYTES); + eth_state_t *eth = (eth_state_t*) (eNB->ifdevice.priv); + int i; + + if (eth->flags == ETH_RAW_IF4p5_MODE) { + for (i=0;i<10;i++) + eNB->ifbuffer.tx[i] = malloc(RAW_IF4p5_PRACH_SIZE_BYTES); + eNB->ifbuffer.tx_prach = malloc(RAW_IF4p5_PRACH_SIZE_BYTES); + eNB->ifbuffer.rx = malloc(RAW_IF4p5_PRACH_SIZE_BYTES); + } else { + for (i=0;i<10;i++) + eNB->ifbuffer.tx[i] = malloc(UDP_IF4p5_PRACH_SIZE_BYTES); + eNB->ifbuffer.tx_prach = malloc(UDP_IF4p5_PRACH_SIZE_BYTES); + eNB->ifbuffer.rx = malloc(UDP_IF4p5_PRACH_SIZE_BYTES); + } } diff --git a/openair1/PHY/LTE_TRANSPORT/if4_tools.h b/openair1/PHY/LTE_TRANSPORT/if4_tools.h index 1f78e7f77afea2f8bdb43fc988fe36e239d0cf62..e2d4f1f7de0b6cb413eb4479664ebabd0fc53db7 100644 --- a/openair1/PHY/LTE_TRANSPORT/if4_tools.h +++ b/openair1/PHY/LTE_TRANSPORT/if4_tools.h @@ -37,6 +37,7 @@ #define IF4p5_PULFFT 0x0019 #define IF4p5_PDLFFT 0x0020 #define IF4p5_PRACH 0x0021 +#define IF4p5_PULTICK 0x0022 struct IF4p5_header { /// Type @@ -55,7 +56,7 @@ typedef struct IF4p5_header IF4p5_header_t; void gen_IF4p5_dl_header(IF4p5_header_t*, int, int); -void gen_IF4p5_ul_header(IF4p5_header_t*, int, int); +void gen_IF4p5_ul_header(IF4p5_header_t*, uint16_t, int, int); void gen_IF4p5_prach_header(IF4p5_header_t*, int, int); diff --git a/openair1/PHY/LTE_TRANSPORT/if5_tools.c b/openair1/PHY/LTE_TRANSPORT/if5_tools.c index 7be4c8d1df9051e0e86adaa59e91019bf1318a52..5b1c8347053e5bd0e1a1c5709f053bc8f2430eff 100644 --- a/openair1/PHY/LTE_TRANSPORT/if5_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/if5_tools.c @@ -21,11 +21,11 @@ /*! \file PHY/LTE_TRANSPORT/if5_tools.c * \brief -* \author S. Sandeep Kumar, Raymond Knopp +* \author S. Sandeep Kumar, Raymond Knopp, Tien-Thinh Nguyen * \date 2016 * \version 0.1 * \company Eurecom -* \email: ee13b1025@iith.ac.in, knopp@eurecom.fr +* \email: ee13b1025@iith.ac.in, knopp@eurecom.fr, tien-thinh.nguyen@eurecom.fr * \note * \warning */ @@ -34,13 +34,21 @@ #include "targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h" #include "UTIL/LOG/vcd_signal_dumper.h" +//#define DEBUG_DL_MOBIPASS +//#define DEBUG_UL_MOBIPASS +#define SUBFRAME_SKIP_NUM_MOBIPASS 8 +int dummy_cnt = 0; +int subframe_skip_extra = 0; +int start_flag = 1; +int offset_cnt = 1; void send_IF5(PHY_VARS_eNB *eNB, openair0_timestamp proc_timestamp, int subframe, uint8_t *seqno, uint16_t packet_type) { LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; int32_t *txp[fp->nb_antennas_tx], *rxp[fp->nb_antennas_rx]; int32_t *tx_buffer=NULL; + int8_t dummy_buffer[fp->samples_per_tti*2]; uint16_t packet_id=0, i=0; uint32_t spp_eth = (uint32_t) eNB->ifdevice.openair0_cfg->samples_per_packet; @@ -89,17 +97,18 @@ void send_IF5(PHY_VARS_eNB *eNB, openair0_timestamp proc_timestamp, int subframe } } else if (packet_type == IF5_MOBIPASS) { - uint16_t db_fulllength=640; + uint16_t db_fulllength = PAYLOAD_MOBIPASS_NUM_SAMPLES; __m128i *data_block=NULL, *data_block_head=NULL; __m128i *txp128; __m128i t0, t1; - tx_buffer = memalign(16, MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t)); + // tx_buffer = memalign(16, MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t)); + tx_buffer = malloc(MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t)); IF5_mobipass_header_t *header = (IF5_mobipass_header_t *)((uint8_t *)tx_buffer + MAC_HEADER_SIZE_BYTES); - data_block_head = (__m128i *)((uint8_t *)tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + 4); - + data_block_head = (__m128i *)((uint8_t *)tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t); + header->flags = 0; header->fifo_status = 0; header->seqno = *seqno; @@ -110,14 +119,14 @@ void send_IF5(PHY_VARS_eNB *eNB, openair0_timestamp proc_timestamp, int subframe txp128 = (__m128i *) txp[0]; for (packet_id=0; packet_id<fp->samples_per_tti/db_fulllength; packet_id++) { - header->time_stamp = (uint32_t)(proc_timestamp + packet_id*db_fulllength); + header->time_stamp = htonl((uint32_t)(proc_timestamp + packet_id*db_fulllength)); data_block = data_block_head; for (i=0; i<db_fulllength>>2; i+=2) { t0 = _mm_srai_epi16(*txp128++, 4); t1 = _mm_srai_epi16(*txp128++, 4); - - *data_block++ = _mm_packs_epi16(t0, t1); +// *data_block++ = _mm_packs_epi16(t0, t1); + _mm_storeu_si128(data_block++, _mm_packs_epi16(t0, t1)); } // Write the packet to the fronthaul @@ -129,18 +138,38 @@ void send_IF5(PHY_VARS_eNB *eNB, openair0_timestamp proc_timestamp, int subframe IF5_MOBIPASS)) < 0) { perror("ETHERNET write for IF5_MOBIPASS\n"); } - +#ifdef DEBUG_DL_MOBIPASS + if ((subframe==0)&&(dummy_cnt == 100)) { + memcpy((void*)&dummy_buffer[packet_id*db_fulllength*2],(void*)data_block_head,db_fulllength*2); + } +#endif header->seqno += 1; } *seqno = header->seqno; - + +#ifdef DEBUG_DL_MOBIPASS + uint8_t txe; + txe = dB_fixed(signal_energy(txp[0],fp->samples_per_tti)); + if (txe > 0){ + LOG_D(PHY,"[Mobipass] frame:%d, subframe:%d, energy %d\n", (proc_timestamp/(10*fp->samples_per_tti))&1023,subframe, txe); + } +#endif } else { AssertFatal(1==0, "send_IF5 - Unknown packet_type %x", packet_type); } free(tx_buffer); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 0 ); - +#ifdef DEBUG_DL_MOBIPASS + if(subframe==0) { + if (dummy_cnt==100) { + write_output("txsigmb.m","txs",(void*)dummy_buffer, fp->samples_per_tti,1, 5); + exit(-1); + } else { + dummy_cnt++; + } + } +#endif return; } @@ -151,6 +180,8 @@ void recv_IF5(PHY_VARS_eNB *eNB, openair0_timestamp *proc_timestamp, int subfram int32_t *txp[fp->nb_antennas_tx], *rxp[fp->nb_antennas_rx]; uint16_t packet_id=0, i=0; + int8_t dummy_buffer_rx[fp->samples_per_tti*2]; + uint8_t rxe; int32_t spp_eth = (int32_t) eNB->ifdevice.openair0_cfg->samples_per_packet; int32_t spsf = (int32_t) eNB->ifdevice.openair0_cfg->samples_per_frame/10; @@ -202,7 +233,128 @@ void recv_IF5(PHY_VARS_eNB *eNB, openair0_timestamp *proc_timestamp, int subfram } else if (packet_type == IF5_MOBIPASS) { - + uint16_t db_fulllength = PAYLOAD_MOBIPASS_NUM_SAMPLES; + openair0_timestamp timestamp_mobipass[fp->samples_per_tti/db_fulllength]; + int lower_offset = 0; + int upper_offset = 70000; + int subframe_skip = 0; + int reset_flag = 0; + int32_t *rx_buffer=NULL; + __m128i *data_block=NULL, *data_block_head=NULL; + __m128i *rxp128; + __m128i r0, r1; + + //rx_buffer = memalign(16, MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t)); + rx_buffer = malloc(MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t)); + IF5_mobipass_header_t *header = (IF5_mobipass_header_t *)((uint8_t *)rx_buffer + MAC_HEADER_SIZE_BYTES); + data_block_head = (__m128i *)((uint8_t *)rx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t); + + rxp[0] = (void*)&eNB->common_vars.rxdata[0][0][subframe*eNB->frame_parms.samples_per_tti]; + rxp128 = (__m128i *) (rxp[0]); + + eNB_proc_t *proc = &eNB->proc; +/* + // while(packet_id<fp->samples_per_tti/db_fulllength) { + data_block = data_block_head; + + eNB->ifdevice.trx_read_func(&eNB->ifdevice, + &ts0, + (void**)&rx_buffer, + db_fulllength, + 1 + ); + + if ((header->seqno == 1)&&(first_packet==1)) { + first_packet = 0; //ignore the packets before synchnorization + packet_id = 0; + ts_offset = ntohl(ts0); + } + if (first_packet==0) { + packet_cnt++; + ts = ntohl(ts0); + packet_id = (ts-ts_offset)/db_fulllength; + packet_id = packet_id % (fp->samples_per_tti/db_fulllength); + + printf("[IF5_tools]packet_id:%d\n", packet_id); + // if (ts_stored == 0) { + // ts_stored = 1; + *proc_timestamp = ntohl(ts - (packet_id*db_fulllength)); + // } + rxp[0] = (void*)&eNB->common_vars.rxdata[0][0][(subframe*eNB->frame_parms.samples_per_tti)+packet_id*db_fulllength]; + rxp128 = (__m128i *) (rxp[0]); + + for (i=0; i<db_fulllength>>2; i+=2) { + r0 = _mm_loadu_si128(data_block++); + *rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpacklo_epi8(r0,r0),8),4); + *rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpackhi_epi8(r0,r0),8),4); + } + } + // }//end while +*/ + + + packet_id=0; + while(packet_id<fp->samples_per_tti/db_fulllength) { + data_block = data_block_head; + + eNB->ifdevice.trx_read_func(&eNB->ifdevice, + ×tamp_mobipass[packet_id], + (void**)&rx_buffer, + db_fulllength, + 1 + ); +#ifdef DEBUG_UL_MOBIPASS + if (((proc->timestamp_tx + lower_offset) > ntohl(timestamp_mobipass[packet_id])) || ((proc->timestamp_tx + upper_offset) < ntohl(timestamp_mobipass[packet_id]))) { + //ignore the packet + subframe_skip_extra = (subframe_skip_extra + 1)%67; + LOG_D("[Mobipass] ignored packet, id:[%d,%d], proc->timestamp_tx:%llu, proc->timestamp_rx:%llu, seqno:%d\n", packet_id,subframe_skip_extra, proc->timestamp_tx, ntohl(timestamp_mobipass[packet_id]), header->seqno); + } +#endif + //skip SUBFRAME_SKIP_NUM_MOBIPASS additional UL packets + if ((start_flag == 1) && (subframe_skip < SUBFRAME_SKIP_NUM_MOBIPASS)){ + subframe_skip++; + offset_cnt = header->seqno; + } else { + if ((offset_cnt != header->seqno) && (start_flag == 0) && (proc->first_rx > 3)){ +#ifdef DEBUG_UL_MOBIPASS + LOG_D(PHY,"[Mobipass] Reset sequence number, offset_cnt:%d, header->seqno:%d, packet_id:%d\n", offset_cnt, header->seqno, packet_id); +#endif + reset_flag=1; + } + if ((reset_flag == 1) && (proc->first_rx > 3 ) && (start_flag == 0) && (packet_id == 0)) { + packet_id = 1; + reset_flag = 0; + } + start_flag = 0; + + //store rxdata and increase packet_id + rxp[0] = (void*)&eNB->common_vars.rxdata[0][0][(subframe*eNB->frame_parms.samples_per_tti)+packet_id*db_fulllength]; + rxp128 = (__m128i *) (rxp[0]); + for (i=0; i<db_fulllength>>2; i+=2) { + r0 = _mm_loadu_si128(data_block++); + *rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpacklo_epi8(r0,r0),8),4); + *rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpackhi_epi8(r0,r0),8),4); + } + packet_id++; + offset_cnt = (header->seqno+1)&255; + } + }//end while + + *proc_timestamp = ntohl(timestamp_mobipass[0]); +#ifdef DEBUG_UL_MOBIPASS + LOG_I(PHY,"[Mobipass][Recv_MOBIPASS] timestamp: %llu\n ", *proc_timestamp); +if (eNB->CC_id>0) { + rxe = dB_fixed(signal_energy(rxp[0],fp->samples_per_tti)); + if (rxe > 0){ + LOG_I(PHY,"[Mobipass] frame:%d, subframe:%d, energy %d\n", (*proc_timestamp/(10*fp->samples_per_tti))&1023,subframe, rxe); +// write_output("rxsigmb.m","rxs",(void*)dummy_buffer_rx, fp->samples_per_tti,1, 5); +// exit(-1); + } +} +#endif + + + } else { AssertFatal(1==0, "recv_IF5 - Unknown packet_type %x", packet_type); } diff --git a/openair1/PHY/LTE_TRANSPORT/pcfich.c b/openair1/PHY/LTE_TRANSPORT/pcfich.c index 08a3d80904fb886948898cd227f45842f0e56d42..3b141372f03dd0e12e7077c69903c0033862b9e2 100644 --- a/openair1/PHY/LTE_TRANSPORT/pcfich.c +++ b/openair1/PHY/LTE_TRANSPORT/pcfich.c @@ -191,7 +191,7 @@ void generate_pcfich(uint8_t num_pdcch_symbols, // mapping nsymb = (frame_parms->Ncp==0) ? 14:12; - symbol_offset = (uint32_t)frame_parms->ofdm_symbol_size*((subframe*nsymb)); + symbol_offset = (uint32_t)frame_parms->ofdm_symbol_size*(subframe*nsymb); re_offset = frame_parms->first_carrier_offset; // loop over 4 quadruplets and lookup REGs diff --git a/openair1/PHY/LTE_TRANSPORT/prach.c b/openair1/PHY/LTE_TRANSPORT/prach.c index 33780a7defc05282a7f465088aa8c188a206b26f..489fdb0f71dae676914243a7d93c2ed59f4eb8eb 100644 --- a/openair1/PHY/LTE_TRANSPORT/prach.c +++ b/openair1/PHY/LTE_TRANSPORT/prach.c @@ -1185,9 +1185,7 @@ void rx_prach(PHY_VARS_eNB *eNB, break; } - if (eNB->frame_parms.threequarter_fs == 1) - Ncp=(Ncp*3)>>2; - + // Adjust CP length based on UL bandwidth switch (eNB->frame_parms.N_RB_UL) { case 6: Ncp>>=4; @@ -1208,6 +1206,11 @@ void rx_prach(PHY_VARS_eNB *eNB, case 75: Ncp=(Ncp*3)>>2; break; + + case 100: + if (eNB->frame_parms.threequarter_fs == 1) + Ncp=(Ncp*3)>>2; + break; } diff --git a/openair1/PHY/MODULATION/beamforming.c b/openair1/PHY/MODULATION/beamforming.c index 6557a47ee7a35c6d31ea267cdb7762c0ffede9d5..4f2f7535e91d1cf47bd6eaa02bda316bd34f3ac3 100644 --- a/openair1/PHY/MODULATION/beamforming.c +++ b/openair1/PHY/MODULATION/beamforming.c @@ -66,24 +66,25 @@ int beam_precoding(int32_t **txdataF, for (p=0; p<14; p++) { //if (p==0 || p==1 || p==5 || p>7) // mult_cpx_conj_vector((int16_t*)txdataF[p], (int16_t*)beam_weights[p][aa], (int16_t*)txdataF_BF[aa], frame_parms->ofdm_symbol_size, 15); - for (re=0;re<frame_parms->ofdm_symbol_size;re++) { - if ((p==0 || p==1 || p==5 || p>=7) && txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re]!=0) { + if (txdataF[p]) {//[slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re]!=0) { + + for (re=0;re<frame_parms->ofdm_symbol_size;re++) { ((int16_t*)&txdataF_BF[aa][re])[0] += (int16_t)((((int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re])[0]*((int16_t*)&beam_weights[p][aa][re])[0])>>15); ((int16_t*)&txdataF_BF[aa][re])[0] -= (int16_t)((((int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re])[1]*((int16_t*)&beam_weights[p][aa][re])[1])>>15); ((int16_t*)&txdataF_BF[aa][re])[1] += (int16_t)((((int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re])[0]*((int16_t*)&beam_weights[p][aa][re])[1])>>15); ((int16_t*)&txdataF_BF[aa][re])[1] += (int16_t)((((int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re])[1]*((int16_t*)&beam_weights[p][aa][re])[0])>>15); - - /* + + /* printf("beamforming.c:txdataF[%d][%d]=%d+j%d, beam_weights[%d][%d][%d]=%d+j%d,txdata_BF[%d][%d]=%d+j%d\n", - p,slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re, - ((int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re])[0], - ((int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re])[1], - p,aa,re, - ((int16_t*)&beam_weights[p][aa][re])[0],((int16_t*)&beam_weights[p][aa][re])[1], - aa,re, - ((int16_t*)&txdataF_BF[aa][re])[0], - ((int16_t*)&txdataF_BF[aa][re])[1]); - */ + p,slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re, + ((int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re])[0], + ((int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re])[1], + p,aa,re, + ((int16_t*)&beam_weights[p][aa][re])[0],((int16_t*)&beam_weights[p][aa][re])[1], + aa,re, + ((int16_t*)&txdataF_BF[aa][re])[0], + ((int16_t*)&txdataF_BF[aa][re])[1]); + */ } } } diff --git a/openair1/PHY/MODULATION/defs.h b/openair1/PHY/MODULATION/defs.h index 6937db6d9bb19241c282ac115d82aa8a88f754d6..da599114a91919c05cb66631bc751c2dc1ce3ab4 100644 --- a/openair1/PHY/MODULATION/defs.h +++ b/openair1/PHY/MODULATION/defs.h @@ -82,7 +82,7 @@ void normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,LTE_DL_FRA void do_OFDM_mod(int32_t **txdataF, int32_t **txdata, uint32_t frame,uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms); -void do_OFDM_mod_symbol(LTE_eNB_COMMON *eNB_common_vars, int eNB_id, uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms); +void do_OFDM_mod_symbol(LTE_eNB_COMMON *eNB_common_vars, int eNB_id, uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms,int do_precoding); void remove_7_5_kHz(PHY_VARS_eNB *phy_vars_eNB,uint8_t subframe); diff --git a/openair1/PHY/MODULATION/ofdm_mod.c b/openair1/PHY/MODULATION/ofdm_mod.c index 74037b4a6e0f9ba04432beacb239e1b8ac8bd368..8e09cea1ec7a5ab0a534d00c37b35e895d19287e 100644 --- a/openair1/PHY/MODULATION/ofdm_mod.c +++ b/openair1/PHY/MODULATION/ofdm_mod.c @@ -285,16 +285,16 @@ void do_OFDM_mod(int32_t **txdataF, int32_t **txdata, uint32_t frame,uint16_t ne } // OFDM modulation for each symbol -void do_OFDM_mod_symbol(LTE_eNB_COMMON *eNB_common_vars, int eNB_id, uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms) +void do_OFDM_mod_symbol(LTE_eNB_COMMON *eNB_common_vars, int eNB_id, uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms,int do_precoding) { - int aa, l, slot_offset; - int32_t **txdataF = eNB_common_vars->txdataF[eNB_id]; + int aa, l, slot_offset, slot_offsetF; + int32_t **txdataF = eNB_common_vars->txdataF[eNB_id]; int32_t **txdataF_BF = eNB_common_vars->txdataF_BF[eNB_id]; - int32_t **txdata = eNB_common_vars->txdata[eNB_id]; - - slot_offset = (next_slot)*(frame_parms->samples_per_tti>>1); + int32_t **txdata = eNB_common_vars->txdata[eNB_id]; + slot_offset = (next_slot)*(frame_parms->samples_per_tti>>1); + slot_offsetF = (next_slot)*(frame_parms->ofdm_symbol_size)*((frame_parms->Ncp==EXTENDED) ? 6 : 7); //printf("Thread %d starting ... aa %d (%llu)\n",omp_get_thread_num(),aa,rdtsc()); for (l=0; l<frame_parms->symbols_per_tti>>1; l++) { @@ -302,13 +302,13 @@ void do_OFDM_mod_symbol(LTE_eNB_COMMON *eNB_common_vars, int eNB_id, uint16_t ne //printf("do_OFDM_mod_l, slot=%d, l=%d, NUMBER_OF_OFDM_CARRIERS=%d,OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES=%d\n",next_slot, l,NUMBER_OF_OFDM_CARRIERS,OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_BEAM_PRECODING,1); - beam_precoding(txdataF,txdataF_BF,frame_parms,eNB_common_vars->beam_weights[eNB_id],next_slot,l,aa); + if (do_precoding==1) beam_precoding(txdataF,txdataF_BF,frame_parms,eNB_common_vars->beam_weights[eNB_id],next_slot,l,aa); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_BEAM_PRECODING,0); //PMCH case not implemented... - if (frame_parms->Ncp == 1) - PHY_ofdm_mod(txdataF_BF[aa], // input + if (frame_parms->Ncp == EXTENDED) + PHY_ofdm_mod((do_precoding == 1)?txdataF_BF[aa]:&txdataF[aa][slot_offsetF+l*frame_parms->ofdm_symbol_size], // input &txdata[aa][slot_offset+l*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES], // output frame_parms->ofdm_symbol_size, 1, // number of symbols @@ -316,7 +316,7 @@ void do_OFDM_mod_symbol(LTE_eNB_COMMON *eNB_common_vars, int eNB_id, uint16_t ne CYCLIC_PREFIX); else { if (l==0) { - PHY_ofdm_mod(txdataF_BF[aa], // input + PHY_ofdm_mod((do_precoding==1)?txdataF_BF[aa]:&txdataF[aa][slot_offsetF+l*frame_parms->ofdm_symbol_size], // input &txdata[aa][slot_offset], // output frame_parms->ofdm_symbol_size, 1, // number of symbols @@ -324,7 +324,7 @@ void do_OFDM_mod_symbol(LTE_eNB_COMMON *eNB_common_vars, int eNB_id, uint16_t ne CYCLIC_PREFIX); } else { - PHY_ofdm_mod(txdataF_BF[aa], // input + PHY_ofdm_mod((do_precoding==1)?txdataF_BF[aa]:&txdataF[aa][slot_offsetF+l*frame_parms->ofdm_symbol_size], // input &txdata[aa][slot_offset+OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES0+(l-1)*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES], // output frame_parms->ofdm_symbol_size, 1, // number of symbols diff --git a/openair1/PHY/MODULATION/slot_fep_ul.c b/openair1/PHY/MODULATION/slot_fep_ul.c index b0798965807c1a8ac8511f775fded7dd2bff0615..e05f5361de0d21de4e198d91e6c5c34c724e475c 100644 --- a/openair1/PHY/MODULATION/slot_fep_ul.c +++ b/openair1/PHY/MODULATION/slot_fep_ul.c @@ -79,10 +79,10 @@ int slot_fep_ul(LTE_DL_FRAME_PARMS *frame_parms, if (no_prefix) { // subframe_offset = frame_parms->ofdm_symbol_size * frame_parms->symbols_per_tti * (Ns>>1); - slot_offset = frame_parms->ofdm_symbol_size * (frame_parms->symbols_per_tti>>1) * (Ns%2); + slot_offset = frame_parms->ofdm_symbol_size * (frame_parms->symbols_per_tti>>1) * (Ns&1); } else { // subframe_offset = frame_parms->samples_per_tti * (Ns>>1); - slot_offset = (frame_parms->samples_per_tti>>1) * (Ns%2); + slot_offset = (frame_parms->samples_per_tti>>1) * (Ns&1); } if (l<0 || l>=7-frame_parms->Ncp) { @@ -108,18 +108,22 @@ int slot_fep_ul(LTE_DL_FRAME_PARMS *frame_parms, 1 ); } else { + rx_offset += (frame_parms->ofdm_symbol_size+nb_prefix_samples)*l; + /* should never happen for eNB if(rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size)) { memcpy((void *)&eNB_common_vars->rxdata_7_5kHz[eNB_id][aa][frame_length_samples], (void *)&eNB_common_vars->rxdata_7_5kHz[eNB_id][aa][0], frame_parms->ofdm_symbol_size*sizeof(int)); } + */ - if( (rx_offset & 7) != 0){ + // check for 256-bit alignment of input buffer and do DFT directly, else do via intermediate buffer + if( (rx_offset & 15) != 0){ memcpy((void *)&tmp_dft_in, - (void *)&eNB_common_vars->rxdata_7_5kHz[eNB_id][aa][(rx_offset % frame_length_samples)], - frame_parms->ofdm_symbol_size*sizeof(int)); + (void *)&eNB_common_vars->rxdata_7_5kHz[eNB_id][aa][(rx_offset % frame_length_samples)], + frame_parms->ofdm_symbol_size*sizeof(int)); dft( (short *) tmp_dft_in, (short*) &eNB_common_vars->rxdataF[eNB_id][aa][frame_parms->ofdm_symbol_size*symbol], 1 diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h index d462fe58cb35df1c4873c9547a61f239c41eda76..a679644b8b452d4908f1c504c43eeca18a4ef680 100644 --- a/openair1/PHY/defs.h +++ b/openair1/PHY/defs.h @@ -241,10 +241,16 @@ typedef struct eNB_proc_t_s { openair0_timestamp timestamp_tx; /// subframe to act upon for reception int subframe_rx; + /// symbol mask for IF4p5 reception per subframe + uint32_t symbol_mask[10]; /// subframe to act upon for PRACH int subframe_prach; /// frame to act upon for reception int frame_rx; + /// frame to act upon for transmission + int frame_tx; + /// frame offset for secondary eNBs (to correct for frame asynchronism at startup) + int frame_offset; /// frame to act upon for PRACH int frame_prach; /// \internal This variable is protected by \ref mutex_fep. @@ -259,6 +265,8 @@ typedef struct eNB_proc_t_s { /// \brief Instance count for rx processing thread. /// \internal This variable is protected by \ref mutex_prach. int instance_cnt_prach; + // instance count for over-the-air eNB synchronization + int instance_cnt_synch; /// \internal This variable is protected by \ref mutex_asynch_rxtx. int instance_cnt_asynch_rxtx; /// pthread structure for FH processing thread @@ -283,6 +291,8 @@ typedef struct eNB_proc_t_s { pthread_attr_t attr_single; /// pthread attributes for prach processing thread pthread_attr_t attr_prach; + /// pthread attributes for over-the-air synch thread + pthread_attr_t attr_synch; /// pthread attributes for asynchronous RX thread pthread_attr_t attr_asynch_rxtx; /// scheduling parameters for parallel fep thread @@ -297,6 +307,8 @@ typedef struct eNB_proc_t_s { struct sched_param sched_param_single; /// scheduling parameters for prach thread struct sched_param sched_param_prach; + /// scheduling parameters for over-the-air synchronization thread + struct sched_param sched_param_synch; /// scheduling parameters for asynch_rxtx thread struct sched_param sched_param_asynch_rxtx; /// pthread structure for parallel fep thread @@ -307,6 +319,8 @@ typedef struct eNB_proc_t_s { pthread_t pthread_te; /// pthread structure for PRACH thread pthread_t pthread_prach; + /// pthread structure for eNB synch thread + pthread_t pthread_synch; /// condition variable for parallel fep thread pthread_cond_t cond_fep; /// condition variable for parallel turbo-decoder thread @@ -317,6 +331,8 @@ typedef struct eNB_proc_t_s { pthread_cond_t cond_FH; /// condition variable for PRACH processing thread; pthread_cond_t cond_prach; + // condition variable for over-the-air eNB synchronization + pthread_cond_t cond_synch; /// condition variable for asynch RX/TX thread pthread_cond_t cond_asynch_rxtx; /// mutex for parallel fep thread @@ -329,6 +345,8 @@ typedef struct eNB_proc_t_s { pthread_mutex_t mutex_FH; /// mutex for PRACH thread pthread_mutex_t mutex_prach; + // mutex for over-the-air eNB synchronization + pthread_mutex_t mutex_synch; /// mutex for asynch RX/TX thread pthread_mutex_t mutex_asynch_rxtx; /// parameters for turbo-decoding worker thread @@ -415,8 +433,15 @@ typedef struct PHY_VARS_eNB_s { int single_thread_flag; openair0_rf_map rf_map; int abstraction_flag; - void (*do_prach)(struct PHY_VARS_eNB_s *eNB); - void (*fep)(struct PHY_VARS_eNB_s *eNB); + openair0_timestamp ts_offset; + // indicator for synchronization state of eNB + int in_synch; + // indicator for master/slave (RRU) + int is_slave; + // indicator for precoding function (eNB,3GPP_eNB_BBU) + int do_precoding; + void (*do_prach)(struct PHY_VARS_eNB_s *eNB,int frame,int subframe); + void (*fep)(struct PHY_VARS_eNB_s *eNB,eNB_rxtx_proc_t *proc); int (*td)(struct PHY_VARS_eNB_s *eNB,int UE_id,int harq_pid,int llr8_flag); int (*te)(struct PHY_VARS_eNB_s *,uint8_t *,uint8_t,LTE_eNB_DLSCH_t *,int,uint8_t,time_stats_t *,time_stats_t *,time_stats_t *); void (*proc_uespec_rx)(struct PHY_VARS_eNB_s *eNB,eNB_rxtx_proc_t *proc,const relaying_type_t r_type); diff --git a/openair1/PHY/impl_defs_lte.h b/openair1/PHY/impl_defs_lte.h index 6635573779fc9cc8e1addf122e0232c27eebc24a..05c36c3f7e08eb5ddc70b8ad0c352e6c13b2c468 100644 --- a/openair1/PHY/impl_defs_lte.h +++ b/openair1/PHY/impl_defs_lte.h @@ -504,6 +504,8 @@ typedef struct { uint8_t tdd_config; /// TDD S-subframe configuration (0-9) uint8_t tdd_config_S; + /// srs extra symbol flag for TDD + uint8_t srsX; /// indicates if node is a UE (NODE=2) or eNB (PRIMARY_CH=0). uint8_t node_id; /// Frequency index of CBMIMO1 card @@ -542,6 +544,10 @@ typedef struct { uint32_t samples_per_tti; /// Number of OFDM/SC-FDMA symbols in one subframe (to be modified to account for potential different in UL/DL) uint16_t symbols_per_tti; + /// Number of OFDM symbols in DL portion of S-subframe + uint16_t dl_symbols_in_S_subframe; + /// Number of SC-FDMA symbols in UL portion of S-subframe + uint16_t ul_symbols_in_S_subframe; /// Number of Physical transmit antennas in node uint8_t nb_antennas_tx; /// Number of Receive antennas in node diff --git a/openair1/SCHED/defs.h b/openair1/SCHED/defs.h index 5f3e1a59e561ab64f9f9ffd94c3a39b7961d82f5..3fcd25ad7342c1c4656402c9c2c950bf8af115d0 100644 --- a/openair1/SCHED/defs.h +++ b/openair1/SCHED/defs.h @@ -182,7 +182,7 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *pr @param phy_vars_eNB Pointer to eNB variables on which to act @param abstraction_flag Indicator of PHY abstraction */ -void phy_procedures_eNB_common_RX(PHY_VARS_eNB *phy_vars_eNB); +void phy_procedures_eNB_common_RX(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc); /*! \brief Scheduling for eNB TX procedures in TDD S-subframes. @param phy_vars_eNB Pointer to eNB variables on which to act diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 4b9f48e1bb634347b78b738a53522276f0783d59..cad508c7c225d7bc90d5b6a1316b5a89096d1cc4 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -1146,7 +1146,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; DCI_ALLOC_t *dci_alloc=(DCI_ALLOC_t *)NULL; - int offset = proc == &eNB->proc.proc_rxtx[0] ? 0 : 1; + int offset = eNB->CC_id;//proc == &eNB->proc.proc_rxtx[0] ? 0 : 1; #if defined(SMBV) // counts number of allocations in subframe @@ -2032,8 +2032,8 @@ void prach_procedures(PHY_VARS_eNB *eNB) { T_INT(preamble_max), T_INT(preamble_energy_max), T_INT(preamble_delay_list[preamble_max])); if (eNB->mac_enabled==1) { - uint8_t update_TA=4; - + uint8_t update_TA = 4; + uint8_t update_TA2 = 1; switch (fp->N_RB_DL) { case 6: update_TA = 16; @@ -2047,8 +2047,11 @@ void prach_procedures(PHY_VARS_eNB *eNB) { update_TA = 2; break; + case 75: + update_TA = 3; + update_TA2 = 2; case 100: - update_TA = 1; + update_TA = 1; break; } @@ -2056,7 +2059,7 @@ void prach_procedures(PHY_VARS_eNB *eNB) { eNB->CC_id, frame, preamble_max, - preamble_delay_list[preamble_max]*update_TA, + preamble_delay_list[preamble_max]*update_TA/update_TA2, 0,subframe,0); } @@ -2670,7 +2673,7 @@ void init_te_thread(PHY_VARS_eNB *eNB,pthread_attr_t *attr_te) { } -void eNB_fep_full_2thread(PHY_VARS_eNB *eNB) { +void eNB_fep_full_2thread(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc_rxtx) { eNB_proc_t *proc = &eNB->proc; @@ -2716,28 +2719,27 @@ void eNB_fep_full_2thread(PHY_VARS_eNB *eNB) { -void eNB_fep_full(PHY_VARS_eNB *eNB) { +void eNB_fep_full(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc_rxtx) { - eNB_proc_t *proc = &eNB->proc; int l; LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_SLOT_FEP,1); start_meas(&eNB->ofdm_demod_stats); - remove_7_5_kHz(eNB,proc->subframe_rx<<1); - remove_7_5_kHz(eNB,1+(proc->subframe_rx<<1)); + remove_7_5_kHz(eNB,proc_rxtx->subframe_rx<<1); + remove_7_5_kHz(eNB,1+(proc_rxtx->subframe_rx<<1)); for (l=0; l<fp->symbols_per_tti/2; l++) { slot_fep_ul(fp, &eNB->common_vars, l, - proc->subframe_rx<<1, + (proc_rxtx->subframe_rx)<<1, 0, 0 ); slot_fep_ul(fp, &eNB->common_vars, l, - 1+(proc->subframe_rx<<1), + 1+((proc_rxtx->subframe_rx)<<1), 0, 0 ); @@ -2748,11 +2750,11 @@ void eNB_fep_full(PHY_VARS_eNB *eNB) { if (eNB->node_function == NGFI_RRU_IF4p5) { /// **** send_IF4 of rxdataF to RCC (no prach now) **** /// - send_IF4p5(eNB, proc->frame_rx, proc->subframe_rx, IF4p5_PULFFT, 0); + send_IF4p5(eNB, proc_rxtx->frame_rx, proc_rxtx->subframe_rx, IF4p5_PULFFT, 0); } } -void eNB_fep_rru_if5(PHY_VARS_eNB *eNB) { +void eNB_fep_rru_if5(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc_rxtx) { eNB_proc_t *proc=&eNB->proc; uint8_t seqno=0; @@ -2764,17 +2766,17 @@ void eNB_fep_rru_if5(PHY_VARS_eNB *eNB) { } -void do_prach(PHY_VARS_eNB *eNB) { +void do_prach(PHY_VARS_eNB *eNB,int frame,int subframe) { eNB_proc_t *proc = &eNB->proc; LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; // check if we have to detect PRACH first - if (is_prach_subframe(fp,proc->frame_rx,proc->subframe_rx)>0) { + if (is_prach_subframe(fp,frame,subframe)>0) { /* accept some delay in processing - up to 5ms */ int i; for (i = 0; i < 10 && proc->instance_cnt_prach == 0; i++) { - LOG_W(PHY,"[eNB] Frame %d Subframe %d, eNB PRACH thread busy (IC %d)!!\n", proc->frame_rx,proc->subframe_rx,proc->instance_cnt_prach); + LOG_W(PHY,"[eNB] Frame %d Subframe %d, eNB PRACH thread busy (IC %d)!!\n", frame,subframe,proc->instance_cnt_prach); usleep(500); } if (proc->instance_cnt_prach == 0) { @@ -2791,8 +2793,8 @@ void do_prach(PHY_VARS_eNB *eNB) { ++proc->instance_cnt_prach; // set timing for prach thread - proc->frame_prach = proc->frame_rx; - proc->subframe_prach = proc->subframe_rx; + proc->frame_prach = frame; + proc->subframe_prach = subframe; // the thread can now be woken up if (pthread_cond_signal(&proc->cond_prach) != 0) { @@ -2806,28 +2808,34 @@ void do_prach(PHY_VARS_eNB *eNB) { } -void phy_procedures_eNB_common_RX(PHY_VARS_eNB *eNB){ +void phy_procedures_eNB_common_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc){ - eNB_proc_t *proc = &eNB->proc; + // eNB_proc_t *proc = &eNB->proc; LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; const int subframe = proc->subframe_rx; const int frame = proc->frame_rx; int offset = (eNB->single_thread_flag==1) ? 0 : (subframe&1); - if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)!=SF_UL)) return; - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_ENB+offset, proc->frame_rx ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX0_ENB+offset, proc->subframe_rx ); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_COMMON+offset, 1 ); - + + if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)!=SF_UL)) { + + if (eNB->node_function == NGFI_RRU_IF4p5) { + /// **** in TDD during DL send_IF4 of ULTICK to RCC **** /// + send_IF4p5(eNB, proc->frame_rx, proc->subframe_rx, IF4p5_PULTICK, 0); + } + return; + } + + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_COMMON+offset, 1 ); start_meas(&eNB->phy_proc_rx); LOG_D(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_common_RX(%d)\n",eNB->Mod_id,frame,subframe); - if (eNB->fep) eNB->fep(eNB); - - if (eNB->do_prach) eNB->do_prach(eNB); + if (eNB->fep) eNB->fep(eNB,proc); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_COMMON+offset, 0 ); } @@ -2847,7 +2855,7 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const const int subframe = proc->subframe_rx; const int frame = proc->frame_rx; - int offset = (proc == &eNB->proc.proc_rxtx[0]) ? 0 : 1; + int offset = eNB->CC_id;//(proc == &eNB->proc.proc_rxtx[0]) ? 0 : 1; if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)!=SF_UL)) return; diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index f9a8acfa85cbcd5ffac2014489e83e62472c2e48..879573525a33f83108521fef330cd9bf1156bf50 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -1812,6 +1812,11 @@ int main(int argc, char **argv) eNB->common_vars.beam_weights[0][0][aa][re] = 0x00007fff/eNB->frame_parms.nb_antennas_tx; } + if (transmission_mode<7) + eNB->do_precoding=0; + else + eNB->do_precoding=1; + eNB->mac_enabled=1; if (two_thread_flag == 0) { eNB->te = dlsch_encoding; @@ -2409,12 +2414,14 @@ int main(int argc, char **argv) do_OFDM_mod_symbol(&eNB->common_vars, eNB_id, (subframe*2), - &eNB->frame_parms); + &eNB->frame_parms, + eNB->do_precoding); do_OFDM_mod_symbol(&eNB->common_vars, eNB_id, (subframe*2)+1, - &eNB->frame_parms); + &eNB->frame_parms, + eNB->do_precoding); stop_meas(&eNB->ofdm_mod_stats); diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index e8ed8b8f5e350da3fac7bc516a08dea2a6ffd279..c2098d537a38106013a45d9d331612c209c0f763 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -128,8 +128,9 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, rnti = UE_RNTI(module_idP, i); CC_id = UE_PCCID(module_idP, i); if ((frameP==0)&&(subframeP==0)) - LOG_I(MAC,"UE rnti %x : %s\n", rnti, - UE_list->UE_sched_ctrl[i].ul_out_of_sync==0 ? "in synch" : "out of sync"); + LOG_I(MAC,"UE rnti %x : %s, PHR %d dB\n", rnti, + UE_list->UE_sched_ctrl[i].ul_out_of_sync==0 ? "in synch" : "out of sync", + UE_list->UE_template[CC_id][i].phr_info); next_i= UE_list->next[i]; diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index ed12d322c10d43a7a1cd7eb3b34288b401fdf979..f0679098da6478450dd4093c339b85789e250fd7 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -759,6 +759,10 @@ void dlsch_scheduler_pre_processor_reset (int module_idP, #endif LTE_eNB_UE_stats *eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti); // initialize harq_pid and round + + if (eNB_UE_stats == NULL) + return; + mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti, frameP,subframeP, &ue_sched_ctl->harq_pid[CC_id], @@ -791,7 +795,10 @@ void dlsch_scheduler_pre_processor_reset (int module_idP, break; case 100: - ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/16; + if (PHY_vars_eNB_g[module_idP][CC_id]->frame_parms.threequarter_fs == 0) + ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/16; + else + ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/12; break; } // clear the update in case PHY does not have a new measurement after timer expiry diff --git a/openair2/UTIL/LOG/vcd_signal_dumper.c b/openair2/UTIL/LOG/vcd_signal_dumper.c index 0997eea162c0e08c5de378520f76bde61734eae5..96f173833ae9d911070280faed4b13ca6a986f85 100644 --- a/openair2/UTIL/LOG/vcd_signal_dumper.c +++ b/openair2/UTIL/LOG/vcd_signal_dumper.c @@ -98,6 +98,7 @@ const char* eurecomVariablesNames[] = { "rxcnt", "trx_ts", "trx_tst", + "trx_write_flags", "tx_ts", "rx_ts", "hw_cnt_rx", diff --git a/openair2/UTIL/LOG/vcd_signal_dumper.h b/openair2/UTIL/LOG/vcd_signal_dumper.h index 7b6fb0e0d1f6781abd6945bd0eda46522a42d869..e1bcff39fcb63c69aed24ff5a1da9e26830284a1 100644 --- a/openair2/UTIL/LOG/vcd_signal_dumper.h +++ b/openair2/UTIL/LOG/vcd_signal_dumper.h @@ -70,6 +70,7 @@ typedef enum { VCD_SIGNAL_DUMPER_VARIABLES_RXCNT, VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, + VCD_SIGNAL_DUMPER_VARIABLES_TRX_WRITE_FLAGS, VCD_SIGNAL_DUMPER_VARIABLES_TX_TS, VCD_SIGNAL_DUMPER_VARIABLES_RX_TS, VCD_SIGNAL_DUMPER_VARIABLES_RX_HWCNT, diff --git a/openair3/COMMON/as_message.h b/openair3/COMMON/as_message.h deleted file mode 120000 index 3bfc76865acee46a60802c21105d4fa1822373d0..0000000000000000000000000000000000000000 --- a/openair3/COMMON/as_message.h +++ /dev/null @@ -1 +0,0 @@ -../../openair2/COMMON/as_message.h \ No newline at end of file diff --git a/openair3/COMMON/as_message.h b/openair3/COMMON/as_message.h new file mode 100644 index 0000000000000000000000000000000000000000..30810a325eace63c944b947bfb8c0a6487094e80 --- /dev/null +++ b/openair3/COMMON/as_message.h @@ -0,0 +1,578 @@ +/* + * Copyright (c) 2015, EURECOM (www.eurecom.fr) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of the FreeBSD Project. + */ + + +/***************************************************************************** + +Source as_message.h + +Version 0.1 + +Date 2012/10/18 + +Product NAS stack + +Subsystem Application Programming Interface + +Author Frederic Maurel + +Description Defines the messages supported by the Access Stratum sublayer + protocol (usually RRC and S1AP for E-UTRAN) and functions used + to encode and decode + +*****************************************************************************/ +#ifndef __AS_MESSAGE_H__ +#define __AS_MESSAGE_H__ + +#include "commonDef.h" +#include "networkDef.h" + +/****************************************************************************/ +/********************* G L O B A L C O N S T A N T S *******************/ +/****************************************************************************/ + +/* + * -------------------------------------------------------------------------- + * Access Stratum message types + * -------------------------------------------------------------------------- + */ +#define AS_REQUEST 0x0100 +#define AS_RESPONSE 0x0200 +#define AS_INDICATION 0x0400 +#define AS_CONFIRM 0x0800 + +/* + * -------------------------------------------------------------------------- + * Access Stratum message identifiers + * -------------------------------------------------------------------------- + */ + +/* Broadcast information */ +#define AS_BROADCAST_INFO 0x01 +#define AS_BROADCAST_INFO_IND (AS_BROADCAST_INFO | AS_INDICATION) + +/* Cell information relevant for cell selection processing */ +#define AS_CELL_INFO 0x02 +#define AS_CELL_INFO_REQ (AS_CELL_INFO | AS_REQUEST) +#define AS_CELL_INFO_CNF (AS_CELL_INFO | AS_CONFIRM) +#define AS_CELL_INFO_IND (AS_CELL_INFO | AS_INDICATION) + +/* Paging information */ +#define AS_PAGING 0x03 +#define AS_PAGING_REQ (AS_PAGING | AS_REQUEST) +#define AS_PAGING_IND (AS_PAGING | AS_INDICATION) + +/* NAS signalling connection establishment */ +#define AS_NAS_ESTABLISH 0x04 +#define AS_NAS_ESTABLISH_REQ (AS_NAS_ESTABLISH | AS_REQUEST) +#define AS_NAS_ESTABLISH_IND (AS_NAS_ESTABLISH | AS_INDICATION) +#define AS_NAS_ESTABLISH_RSP (AS_NAS_ESTABLISH | AS_RESPONSE) +#define AS_NAS_ESTABLISH_CNF (AS_NAS_ESTABLISH | AS_CONFIRM) + +/* NAS signalling connection release */ +#define AS_NAS_RELEASE 0x05 +#define AS_NAS_RELEASE_REQ (AS_NAS_RELEASE | AS_REQUEST) +#define AS_NAS_RELEASE_IND (AS_NAS_RELEASE | AS_INDICATION) + +/* Uplink information transfer */ +#define AS_UL_INFO_TRANSFER 0x06 +#define AS_UL_INFO_TRANSFER_REQ (AS_UL_INFO_TRANSFER | AS_REQUEST) +#define AS_UL_INFO_TRANSFER_CNF (AS_UL_INFO_TRANSFER | AS_CONFIRM) +#define AS_UL_INFO_TRANSFER_IND (AS_UL_INFO_TRANSFER | AS_INDICATION) + +/* Downlink information transfer */ +#define AS_DL_INFO_TRANSFER 0x07 +#define AS_DL_INFO_TRANSFER_REQ (AS_DL_INFO_TRANSFER | AS_REQUEST) +#define AS_DL_INFO_TRANSFER_CNF (AS_DL_INFO_TRANSFER | AS_CONFIRM) +#define AS_DL_INFO_TRANSFER_IND (AS_DL_INFO_TRANSFER | AS_INDICATION) + +/* Radio Access Bearer establishment */ +#define AS_RAB_ESTABLISH 0x08 +#define AS_RAB_ESTABLISH_REQ (AS_RAB_ESTABLISH | AS_REQUEST) +#define AS_RAB_ESTABLISH_IND (AS_RAB_ESTABLISH | AS_INDICATION) +#define AS_RAB_ESTABLISH_RSP (AS_RAB_ESTABLISH | AS_RESPONSE) +#define AS_RAB_ESTABLISH_CNF (AS_RAB_ESTABLISH | AS_CONFIRM) + +/* Radio Access Bearer release */ +#define AS_RAB_RELEASE 0x09 +#define AS_RAB_RELEASE_REQ (AS_RAB_RELEASE | AS_REQUEST) +#define AS_RAB_RELEASE_IND (AS_RAB_RELEASE | AS_INDICATION) + +/* NAS Cause */ +#define EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED (8) +#define EPS_SERVICES_NOT_ALLOWED (7) +#define PLMN_NOT_ALLOWED (11) +#define TRACKING_AREA_NOT_ALLOWED (12) +#define ROAMING_NOT_ALLOWED_IN_THIS_TRACKING_AREA (13) +#define EPS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN (14) +#define NO_SUITABLE_CELLS_IN_TRACKING_AREA (15) +#define NETWORK_FAILURE (17) +#define ESM_FAILURE (19) + +typedef enum nas_cause_s { + NAS_CAUSE_EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED = EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED, + NAS_CAUSE_EPS_SERVICES_NOT_ALLOWED = EPS_SERVICES_NOT_ALLOWED, + NAS_CAUSE_PLMN_NOT_ALLOWED = PLMN_NOT_ALLOWED, + NAS_CAUSE_TRACKING_AREA_NOT_ALLOWED = TRACKING_AREA_NOT_ALLOWED, + NAS_CAUSE_ROAMING_NOT_ALLOWED_IN_THIS_TRACKING_AREA = ROAMING_NOT_ALLOWED_IN_THIS_TRACKING_AREA, + NAS_CAUSE_EPS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN = EPS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN, + NAS_CAUSE_NO_SUITABLE_CELLS_IN_TRACKING_AREA = NO_SUITABLE_CELLS_IN_TRACKING_AREA, + NAS_CAUSE_NETWORK_FAILURE = NETWORK_FAILURE, + NAS_CAUSE_ESM_FAILURE = ESM_FAILURE +} nas_cause_t; + +/* + * -------------------------------------------------------------------------- + * Access Stratum message global parameters + * -------------------------------------------------------------------------- + */ + +/* Error code */ +typedef enum nas_error_code_s { + AS_SUCCESS = 1, /* Success code, transaction is going on */ + AS_TERMINATED_NAS, /* Transaction terminated by NAS */ + AS_TERMINATED_AS, /* Transaction terminated by AS */ + AS_FAILURE /* Failure code */ +} nas_error_code_t; + +/* Core network domain */ +typedef enum core_network_s { + AS_PS = 1, /* Packet-Switched */ + AS_CS /* Circuit-Switched */ +} core_network_t; + +/* SAE Temporary Mobile Subscriber Identity */ +typedef struct as_stmsi_s { + uint8_t MMEcode; /* MME code that allocated the GUTI */ + uint32_t m_tmsi; /* M-Temporary Mobile Subscriber Identity */ +} as_stmsi_t; + +/* Dedicated NAS information */ +typedef struct as_nas_info_s { + uint32_t length; /* Length of the NAS information data */ + Byte_t* data; /* Dedicated NAS information data container */ +} as_nas_info_t; + +/* Radio Access Bearer identity */ +typedef uint8_t as_rab_id_t; + +/****************************************************************************/ +/************************ G L O B A L T Y P E S ************************/ +/****************************************************************************/ + +/* + * -------------------------------------------------------------------------- + * Broadcast information + * -------------------------------------------------------------------------- + */ + +/* + * AS->NAS - Broadcast information indication + * AS may asynchronously report to NAS available PLMNs within specific + * location area + */ +typedef struct broadcast_info_ind_s { +#define PLMN_LIST_MAX_SIZE 6 + PLMN_LIST_T(PLMN_LIST_MAX_SIZE) plmnIDs; /* List of PLMN identifiers */ + ci_t cellID; /* Identity of the cell serving the listed PLMNs */ + tac_t tac; /* Code of the tracking area the cell belongs to */ +} broadcast_info_ind_t; + +/* + * -------------------------------------------------------------------------- + * Cell information relevant for cell selection processing + * -------------------------------------------------------------------------- + */ + +/* Radio access technologies supported by the network */ +#define AS_GSM (1 << NET_ACCESS_GSM) +#define AS_COMPACT (1 << NET_ACCESS_COMPACT) +#define AS_UTRAN (1 << NET_ACCESS_UTRAN) +#define AS_EGPRS (1 << NET_ACCESS_EGPRS) +#define AS_HSDPA (1 << NET_ACCESS_HSDPA) +#define AS_HSUPA (1 << NET_ACCESS_HSUPA) +#define AS_HSDUPA (1 << NET_ACCESS_HSDUPA) +#define AS_EUTRAN (1 << NET_ACCESS_EUTRAN) + +/* + * NAS->AS - Cell Information request + * NAS request AS to search for a suitable cell belonging to the selected + * PLMN to camp on. + */ +typedef struct cell_info_req_s { + plmn_t plmnID; /* Selected PLMN identity */ + Byte_t rat; /* Bitmap - set of radio access technologies */ +} cell_info_req_t; + +/* + * AS->NAS - Cell Information confirm + * AS search for a suitable cell and respond to NAS. If found, the cell + * is selected to camp on. + */ +typedef struct cell_info_cnf_s { + uint8_t errCode; /* Error code */ + ci_t cellID; /* Identity of the cell serving the selected PLMN */ + tac_t tac; /* Code of the tracking area the cell belongs to */ + AcT_t rat; /* Radio access technology supported by the cell */ + uint8_t rsrq; /* Reference signal received quality */ + uint8_t rsrp; /* Reference signal received power */ +} cell_info_cnf_t; + +/* + * AS->NAS - Cell Information indication + * AS may change cell selection if a more suitable cell is found. + */ +typedef struct cell_info_ind_s { + ci_t cellID; /* Identity of the new serving cell */ + tac_t tac; /* Code of the tracking area the cell belongs to */ +} cell_info_ind_t; + +/* + * -------------------------------------------------------------------------- + * Paging information + * -------------------------------------------------------------------------- + */ + +/* Paging cause */ +typedef enum paging_cause_s { + AS_CONNECTION_ESTABLISH, /* Establish NAS signalling connection */ + AS_EPS_ATTACH, /* Perform local detach and initiate EPS + * attach procedure */ + AS_CS_FALLBACK /* Inititate CS fallback procedure */ +} paging_cause_t; + +/* + * NAS->AS - Paging Information request + * NAS requests the AS that NAS signalling messages or user data is pending + * to be sent. + */ +typedef struct paging_req_s { + as_stmsi_t s_tmsi; /* UE identity */ + uint8_t CN_domain; /* Core network domain */ +} paging_req_t; + +/* + * AS->NAS - Paging Information indication + * AS reports to the NAS that appropriate procedure has to be initiated. + */ +typedef struct paging_ind_s { + paging_cause_t cause; /* Paging cause */ +} paging_ind_t; + +/* + * -------------------------------------------------------------------------- + * NAS signalling connection establishment + * -------------------------------------------------------------------------- + */ + +/* Cause of RRC connection establishment */ +typedef enum as_cause_s { + AS_CAUSE_UNKNOWN = 0, + AS_CAUSE_EMERGENCY = NET_ESTABLISH_CAUSE_EMERGENCY, + AS_CAUSE_HIGH_PRIO = NET_ESTABLISH_CAUSE_HIGH_PRIO, + AS_CAUSE_MT_ACCESS = NET_ESTABLISH_CAUSE_MT_ACCESS, + AS_CAUSE_MO_SIGNAL = NET_ESTABLISH_CAUSE_MO_SIGNAL, + AS_CAUSE_MO_DATA = NET_ESTABLISH_CAUSE_MO_DATA, + AS_CAUSE_V1020 = NET_ESTABLISH_CAUSE_V1020 +} as_cause_t; + +/* Type of the call associated to the RRC connection establishment */ +typedef enum as_call_type_s { + AS_TYPE_ORIGINATING_SIGNAL = NET_ESTABLISH_TYPE_ORIGINATING_SIGNAL, + AS_TYPE_EMERGENCY_CALLS = NET_ESTABLISH_TYPE_EMERGENCY_CALLS, + AS_TYPE_ORIGINATING_CALLS = NET_ESTABLISH_TYPE_ORIGINATING_CALLS, + AS_TYPE_TERMINATING_CALLS = NET_ESTABLISH_TYPE_TERMINATING_CALLS, + AS_TYPE_MO_CS_FALLBACK = NET_ESTABLISH_TYPE_MO_CS_FALLBACK +} as_call_type_t; + +/* + * NAS->AS - NAS signalling connection establishment request + * NAS requests the AS to perform the RRC connection establishment procedure + * to transfer initial NAS message to the network while UE is in IDLE mode. + */ +typedef struct nas_establish_req_s { + as_cause_t cause; /* RRC connection establishment cause */ + as_call_type_t type; /* RRC associated call type */ + as_stmsi_t s_tmsi; /* UE identity */ + plmn_t plmnID; /* Selected PLMN identity */ + as_nas_info_t initialNasMsg; /* Initial NAS message to transfer */ +} nas_establish_req_t; + +/* + * AS->NAS - NAS signalling connection establishment indication + * AS transfers the initial NAS message to the NAS. + */ +typedef struct nas_establish_ind_s { + uint32_t UEid; /* UE lower layer identifier */ + tac_t tac; /* Code of the tracking area the initiating + * UE belongs to */ + as_cause_t asCause; /* Establishment cause */ + as_nas_info_t initialNasMsg; /* Initial NAS message to transfer */ +} nas_establish_ind_t; + +/* + * NAS->AS - NAS signalling connection establishment response + * NAS responds to the AS that initial answer message has to be provided to + * the UE. + */ +typedef struct nas_establish_rsp_s { + uint32_t UEid; /* UE lower layer identifier */ + as_stmsi_t s_tmsi; /* UE identity */ + nas_error_code_t errCode; /* Transaction status */ + as_nas_info_t nasMsg; /* NAS message to transfer */ + uint32_t nas_ul_count; /* UL NAS COUNT */ + uint16_t selected_encryption_algorithm; + uint16_t selected_integrity_algorithm; +} nas_establish_rsp_t; + +/* + * AS->NAS - NAS signalling connection establishment confirm + * AS transfers the initial answer message to the NAS. + */ +typedef struct nas_establish_cnf_s { + uint32_t UEid; /* UE lower layer identifier */ + nas_error_code_t errCode; /* Transaction status */ + as_nas_info_t nasMsg; /* NAS message to transfer */ + uint32_t ul_nas_count; + uint16_t selected_encryption_algorithm; + uint16_t selected_integrity_algorithm; +} nas_establish_cnf_t; + +/* + * -------------------------------------------------------------------------- + * NAS signalling connection release + * -------------------------------------------------------------------------- + */ + +/* Release cause */ +typedef enum release_cause_s { + AS_AUTHENTICATION_FAILURE = 1, /* Authentication procedure failed */ + AS_DETACH /* Detach requested */ +} release_cause_t; + +/* + * NAS->AS - NAS signalling connection release request + * NAS requests the termination of the connection with the UE. + */ +typedef struct nas_release_req_s { + uint32_t UEid; /* UE lower layer identifier */ + as_stmsi_t s_tmsi; /* UE identity */ + release_cause_t cause; /* Release cause */ +} nas_release_req_t; + +/* + * AS->NAS - NAS signalling connection release indication + * AS reports that connection has been terminated by the network. + */ +typedef struct nas_release_ind_s { + release_cause_t cause; /* Release cause */ +} nas_release_ind_t; + +/* + * -------------------------------------------------------------------------- + * NAS information transfer + * -------------------------------------------------------------------------- + */ + +/* + * NAS->AS - Uplink data transfer request + * NAS requests the AS to transfer uplink information to the NAS that + * operates at the network side. + */ +typedef struct ul_info_transfer_req_s { + uint32_t UEid; /* UE lower layer identifier */ + as_stmsi_t s_tmsi; /* UE identity */ + as_nas_info_t nasMsg; /* Uplink NAS message */ +} ul_info_transfer_req_t; + +/* + * AS->NAS - Uplink data transfer confirm + * AS immediately notifies the NAS whether uplink information has been + * successfully sent to the network or not. + */ +typedef struct ul_info_transfer_cnf_s { + uint32_t UEid; /* UE lower layer identifier */ + nas_error_code_t errCode; /* Transaction status */ +} ul_info_transfer_cnf_t; + +/* + * AS->NAS - Uplink data transfer indication + * AS delivers the uplink information message to the NAS that operates + * at the network side. + */ +typedef struct ul_info_transfer_ind_s { + uint32_t UEid; /* UE lower layer identifier */ + as_nas_info_t nasMsg; /* Uplink NAS message */ +} ul_info_transfer_ind_t; + +/* + * NAS->AS - Downlink data transfer request + * NAS requests the AS to transfer downlink information to the NAS that + * operates at the UE side. + */ +typedef ul_info_transfer_req_t dl_info_transfer_req_t; + +/* + * AS->NAS - Downlink data transfer confirm + * AS immediately notifies the NAS whether downlink information has been + * successfully sent to the network or not. + */ +typedef ul_info_transfer_cnf_t dl_info_transfer_cnf_t; + +/* + * AS->NAS - Downlink data transfer indication + * AS delivers the downlink information message to the NAS that operates + * at the UE side. + */ +typedef ul_info_transfer_ind_t dl_info_transfer_ind_t; + +/* + * -------------------------------------------------------------------------- + * Radio Access Bearer establishment + * -------------------------------------------------------------------------- + */ + +/* TODO: Quality of Service parameters */ +typedef struct {} as_qos_t; + +/* + * NAS->AS - Radio access bearer establishment request + * NAS requests the AS to allocate transmission resources to radio access + * bearer initialized at the network side. + */ +typedef struct rab_establish_req_s { + as_stmsi_t s_tmsi; /* UE identity */ + as_rab_id_t rabID; /* Radio access bearer identity */ + as_qos_t QoS; /* Requested Quality of Service */ +} rab_establish_req_t; + +/* + * AS->NAS - Radio access bearer establishment indication + * AS notifies the NAS that specific radio access bearer has to be setup. + */ +typedef struct rab_establish_ind_s { + as_rab_id_t rabID; /* Radio access bearer identity */ +} rab_establish_ind_t; + +/* + * NAS->AS - Radio access bearer establishment response + * NAS responds to AS whether the specified radio access bearer has been + * successfully setup or not. + */ +typedef struct rab_establish_rsp_s { + as_stmsi_t s_tmsi; /* UE identity */ + as_rab_id_t rabID; /* Radio access bearer identity */ + nas_error_code_t errCode; /* Transaction status */ +} rab_establish_rsp_t; + +/* + * AS->NAS - Radio access bearer establishment confirm + * AS notifies NAS whether the specified radio access bearer has been + * successfully setup at the UE side or not. + */ +typedef struct rab_establish_cnf_s { + as_rab_id_t rabID; /* Radio access bearer identity */ + nas_error_code_t errCode; /* Transaction status */ +} rab_establish_cnf_t; + +/* + * -------------------------------------------------------------------------- + * Radio Access Bearer release + * -------------------------------------------------------------------------- + */ + +/* + * NAS->AS - Radio access bearer release request + * NAS requests the AS to release transmission resources previously allocated + * to specific radio access bearer at the network side. + */ +typedef struct rab_release_req_s { + as_stmsi_t s_tmsi; /* UE identity */ + as_rab_id_t rabID; /* Radio access bearer identity */ +} rab_release_req_t; + +/* + * AS->NAS - Radio access bearer release indication + * AS notifies NAS that specific radio access bearer has been released. + */ +typedef struct rab_release_ind_s { + as_rab_id_t rabID; /* Radio access bearer identity */ +} rab_release_ind_t; + +/* + * -------------------------------------------------------------------------- + * Structure of the AS messages handled by the network sublayer + * -------------------------------------------------------------------------- + */ +typedef struct as_message_s { + uint16_t msgID; + union { + broadcast_info_ind_t broadcast_info_ind; + cell_info_req_t cell_info_req; + cell_info_cnf_t cell_info_cnf; + cell_info_ind_t cell_info_ind; + paging_req_t paging_req; + paging_ind_t paging_ind; + nas_establish_req_t nas_establish_req; + nas_establish_ind_t nas_establish_ind; + nas_establish_rsp_t nas_establish_rsp; + nas_establish_cnf_t nas_establish_cnf; + nas_release_req_t nas_release_req; + nas_release_ind_t nas_release_ind; + ul_info_transfer_req_t ul_info_transfer_req; + ul_info_transfer_cnf_t ul_info_transfer_cnf; + ul_info_transfer_ind_t ul_info_transfer_ind; + dl_info_transfer_req_t dl_info_transfer_req; + dl_info_transfer_cnf_t dl_info_transfer_cnf; + dl_info_transfer_ind_t dl_info_transfer_ind; + rab_establish_req_t rab_establish_req; + rab_establish_ind_t rab_establish_ind; + rab_establish_rsp_t rab_establish_rsp; + rab_establish_cnf_t rab_establish_cnf; + rab_release_req_t rab_release_req; + rab_release_ind_t rab_release_ind; + } __attribute__((__packed__)) msg; +} as_message_t; + +/****************************************************************************/ +/******************** G L O B A L V A R I A B L E S ********************/ +/****************************************************************************/ + +/****************************************************************************/ +/****************** E X P O R T E D F U N C T I O N S ******************/ +/****************************************************************************/ + +int as_message_decode(const char* buffer, as_message_t* msg, int length); + +int as_message_encode(char* buffer, as_message_t* msg, int length); + +/* Implemented in the network_api.c body file */ +int as_message_send(as_message_t* as_msg); + +#endif /* __AS_MESSAGE_H__*/ diff --git a/openair3/NAS/COMMON/API/NETWORK/as_message.h b/openair3/NAS/COMMON/API/NETWORK/as_message.h deleted file mode 120000 index ef8d3686fd6b2b4f53bde09c5085a41cb523c0f0..0000000000000000000000000000000000000000 --- a/openair3/NAS/COMMON/API/NETWORK/as_message.h +++ /dev/null @@ -1 +0,0 @@ -../../../../../openair2/COMMON/as_message.h \ No newline at end of file diff --git a/openair3/NAS/COMMON/API/NETWORK/as_message.h b/openair3/NAS/COMMON/API/NETWORK/as_message.h new file mode 100644 index 0000000000000000000000000000000000000000..30810a325eace63c944b947bfb8c0a6487094e80 --- /dev/null +++ b/openair3/NAS/COMMON/API/NETWORK/as_message.h @@ -0,0 +1,578 @@ +/* + * Copyright (c) 2015, EURECOM (www.eurecom.fr) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of the FreeBSD Project. + */ + + +/***************************************************************************** + +Source as_message.h + +Version 0.1 + +Date 2012/10/18 + +Product NAS stack + +Subsystem Application Programming Interface + +Author Frederic Maurel + +Description Defines the messages supported by the Access Stratum sublayer + protocol (usually RRC and S1AP for E-UTRAN) and functions used + to encode and decode + +*****************************************************************************/ +#ifndef __AS_MESSAGE_H__ +#define __AS_MESSAGE_H__ + +#include "commonDef.h" +#include "networkDef.h" + +/****************************************************************************/ +/********************* G L O B A L C O N S T A N T S *******************/ +/****************************************************************************/ + +/* + * -------------------------------------------------------------------------- + * Access Stratum message types + * -------------------------------------------------------------------------- + */ +#define AS_REQUEST 0x0100 +#define AS_RESPONSE 0x0200 +#define AS_INDICATION 0x0400 +#define AS_CONFIRM 0x0800 + +/* + * -------------------------------------------------------------------------- + * Access Stratum message identifiers + * -------------------------------------------------------------------------- + */ + +/* Broadcast information */ +#define AS_BROADCAST_INFO 0x01 +#define AS_BROADCAST_INFO_IND (AS_BROADCAST_INFO | AS_INDICATION) + +/* Cell information relevant for cell selection processing */ +#define AS_CELL_INFO 0x02 +#define AS_CELL_INFO_REQ (AS_CELL_INFO | AS_REQUEST) +#define AS_CELL_INFO_CNF (AS_CELL_INFO | AS_CONFIRM) +#define AS_CELL_INFO_IND (AS_CELL_INFO | AS_INDICATION) + +/* Paging information */ +#define AS_PAGING 0x03 +#define AS_PAGING_REQ (AS_PAGING | AS_REQUEST) +#define AS_PAGING_IND (AS_PAGING | AS_INDICATION) + +/* NAS signalling connection establishment */ +#define AS_NAS_ESTABLISH 0x04 +#define AS_NAS_ESTABLISH_REQ (AS_NAS_ESTABLISH | AS_REQUEST) +#define AS_NAS_ESTABLISH_IND (AS_NAS_ESTABLISH | AS_INDICATION) +#define AS_NAS_ESTABLISH_RSP (AS_NAS_ESTABLISH | AS_RESPONSE) +#define AS_NAS_ESTABLISH_CNF (AS_NAS_ESTABLISH | AS_CONFIRM) + +/* NAS signalling connection release */ +#define AS_NAS_RELEASE 0x05 +#define AS_NAS_RELEASE_REQ (AS_NAS_RELEASE | AS_REQUEST) +#define AS_NAS_RELEASE_IND (AS_NAS_RELEASE | AS_INDICATION) + +/* Uplink information transfer */ +#define AS_UL_INFO_TRANSFER 0x06 +#define AS_UL_INFO_TRANSFER_REQ (AS_UL_INFO_TRANSFER | AS_REQUEST) +#define AS_UL_INFO_TRANSFER_CNF (AS_UL_INFO_TRANSFER | AS_CONFIRM) +#define AS_UL_INFO_TRANSFER_IND (AS_UL_INFO_TRANSFER | AS_INDICATION) + +/* Downlink information transfer */ +#define AS_DL_INFO_TRANSFER 0x07 +#define AS_DL_INFO_TRANSFER_REQ (AS_DL_INFO_TRANSFER | AS_REQUEST) +#define AS_DL_INFO_TRANSFER_CNF (AS_DL_INFO_TRANSFER | AS_CONFIRM) +#define AS_DL_INFO_TRANSFER_IND (AS_DL_INFO_TRANSFER | AS_INDICATION) + +/* Radio Access Bearer establishment */ +#define AS_RAB_ESTABLISH 0x08 +#define AS_RAB_ESTABLISH_REQ (AS_RAB_ESTABLISH | AS_REQUEST) +#define AS_RAB_ESTABLISH_IND (AS_RAB_ESTABLISH | AS_INDICATION) +#define AS_RAB_ESTABLISH_RSP (AS_RAB_ESTABLISH | AS_RESPONSE) +#define AS_RAB_ESTABLISH_CNF (AS_RAB_ESTABLISH | AS_CONFIRM) + +/* Radio Access Bearer release */ +#define AS_RAB_RELEASE 0x09 +#define AS_RAB_RELEASE_REQ (AS_RAB_RELEASE | AS_REQUEST) +#define AS_RAB_RELEASE_IND (AS_RAB_RELEASE | AS_INDICATION) + +/* NAS Cause */ +#define EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED (8) +#define EPS_SERVICES_NOT_ALLOWED (7) +#define PLMN_NOT_ALLOWED (11) +#define TRACKING_AREA_NOT_ALLOWED (12) +#define ROAMING_NOT_ALLOWED_IN_THIS_TRACKING_AREA (13) +#define EPS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN (14) +#define NO_SUITABLE_CELLS_IN_TRACKING_AREA (15) +#define NETWORK_FAILURE (17) +#define ESM_FAILURE (19) + +typedef enum nas_cause_s { + NAS_CAUSE_EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED = EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED, + NAS_CAUSE_EPS_SERVICES_NOT_ALLOWED = EPS_SERVICES_NOT_ALLOWED, + NAS_CAUSE_PLMN_NOT_ALLOWED = PLMN_NOT_ALLOWED, + NAS_CAUSE_TRACKING_AREA_NOT_ALLOWED = TRACKING_AREA_NOT_ALLOWED, + NAS_CAUSE_ROAMING_NOT_ALLOWED_IN_THIS_TRACKING_AREA = ROAMING_NOT_ALLOWED_IN_THIS_TRACKING_AREA, + NAS_CAUSE_EPS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN = EPS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN, + NAS_CAUSE_NO_SUITABLE_CELLS_IN_TRACKING_AREA = NO_SUITABLE_CELLS_IN_TRACKING_AREA, + NAS_CAUSE_NETWORK_FAILURE = NETWORK_FAILURE, + NAS_CAUSE_ESM_FAILURE = ESM_FAILURE +} nas_cause_t; + +/* + * -------------------------------------------------------------------------- + * Access Stratum message global parameters + * -------------------------------------------------------------------------- + */ + +/* Error code */ +typedef enum nas_error_code_s { + AS_SUCCESS = 1, /* Success code, transaction is going on */ + AS_TERMINATED_NAS, /* Transaction terminated by NAS */ + AS_TERMINATED_AS, /* Transaction terminated by AS */ + AS_FAILURE /* Failure code */ +} nas_error_code_t; + +/* Core network domain */ +typedef enum core_network_s { + AS_PS = 1, /* Packet-Switched */ + AS_CS /* Circuit-Switched */ +} core_network_t; + +/* SAE Temporary Mobile Subscriber Identity */ +typedef struct as_stmsi_s { + uint8_t MMEcode; /* MME code that allocated the GUTI */ + uint32_t m_tmsi; /* M-Temporary Mobile Subscriber Identity */ +} as_stmsi_t; + +/* Dedicated NAS information */ +typedef struct as_nas_info_s { + uint32_t length; /* Length of the NAS information data */ + Byte_t* data; /* Dedicated NAS information data container */ +} as_nas_info_t; + +/* Radio Access Bearer identity */ +typedef uint8_t as_rab_id_t; + +/****************************************************************************/ +/************************ G L O B A L T Y P E S ************************/ +/****************************************************************************/ + +/* + * -------------------------------------------------------------------------- + * Broadcast information + * -------------------------------------------------------------------------- + */ + +/* + * AS->NAS - Broadcast information indication + * AS may asynchronously report to NAS available PLMNs within specific + * location area + */ +typedef struct broadcast_info_ind_s { +#define PLMN_LIST_MAX_SIZE 6 + PLMN_LIST_T(PLMN_LIST_MAX_SIZE) plmnIDs; /* List of PLMN identifiers */ + ci_t cellID; /* Identity of the cell serving the listed PLMNs */ + tac_t tac; /* Code of the tracking area the cell belongs to */ +} broadcast_info_ind_t; + +/* + * -------------------------------------------------------------------------- + * Cell information relevant for cell selection processing + * -------------------------------------------------------------------------- + */ + +/* Radio access technologies supported by the network */ +#define AS_GSM (1 << NET_ACCESS_GSM) +#define AS_COMPACT (1 << NET_ACCESS_COMPACT) +#define AS_UTRAN (1 << NET_ACCESS_UTRAN) +#define AS_EGPRS (1 << NET_ACCESS_EGPRS) +#define AS_HSDPA (1 << NET_ACCESS_HSDPA) +#define AS_HSUPA (1 << NET_ACCESS_HSUPA) +#define AS_HSDUPA (1 << NET_ACCESS_HSDUPA) +#define AS_EUTRAN (1 << NET_ACCESS_EUTRAN) + +/* + * NAS->AS - Cell Information request + * NAS request AS to search for a suitable cell belonging to the selected + * PLMN to camp on. + */ +typedef struct cell_info_req_s { + plmn_t plmnID; /* Selected PLMN identity */ + Byte_t rat; /* Bitmap - set of radio access technologies */ +} cell_info_req_t; + +/* + * AS->NAS - Cell Information confirm + * AS search for a suitable cell and respond to NAS. If found, the cell + * is selected to camp on. + */ +typedef struct cell_info_cnf_s { + uint8_t errCode; /* Error code */ + ci_t cellID; /* Identity of the cell serving the selected PLMN */ + tac_t tac; /* Code of the tracking area the cell belongs to */ + AcT_t rat; /* Radio access technology supported by the cell */ + uint8_t rsrq; /* Reference signal received quality */ + uint8_t rsrp; /* Reference signal received power */ +} cell_info_cnf_t; + +/* + * AS->NAS - Cell Information indication + * AS may change cell selection if a more suitable cell is found. + */ +typedef struct cell_info_ind_s { + ci_t cellID; /* Identity of the new serving cell */ + tac_t tac; /* Code of the tracking area the cell belongs to */ +} cell_info_ind_t; + +/* + * -------------------------------------------------------------------------- + * Paging information + * -------------------------------------------------------------------------- + */ + +/* Paging cause */ +typedef enum paging_cause_s { + AS_CONNECTION_ESTABLISH, /* Establish NAS signalling connection */ + AS_EPS_ATTACH, /* Perform local detach and initiate EPS + * attach procedure */ + AS_CS_FALLBACK /* Inititate CS fallback procedure */ +} paging_cause_t; + +/* + * NAS->AS - Paging Information request + * NAS requests the AS that NAS signalling messages or user data is pending + * to be sent. + */ +typedef struct paging_req_s { + as_stmsi_t s_tmsi; /* UE identity */ + uint8_t CN_domain; /* Core network domain */ +} paging_req_t; + +/* + * AS->NAS - Paging Information indication + * AS reports to the NAS that appropriate procedure has to be initiated. + */ +typedef struct paging_ind_s { + paging_cause_t cause; /* Paging cause */ +} paging_ind_t; + +/* + * -------------------------------------------------------------------------- + * NAS signalling connection establishment + * -------------------------------------------------------------------------- + */ + +/* Cause of RRC connection establishment */ +typedef enum as_cause_s { + AS_CAUSE_UNKNOWN = 0, + AS_CAUSE_EMERGENCY = NET_ESTABLISH_CAUSE_EMERGENCY, + AS_CAUSE_HIGH_PRIO = NET_ESTABLISH_CAUSE_HIGH_PRIO, + AS_CAUSE_MT_ACCESS = NET_ESTABLISH_CAUSE_MT_ACCESS, + AS_CAUSE_MO_SIGNAL = NET_ESTABLISH_CAUSE_MO_SIGNAL, + AS_CAUSE_MO_DATA = NET_ESTABLISH_CAUSE_MO_DATA, + AS_CAUSE_V1020 = NET_ESTABLISH_CAUSE_V1020 +} as_cause_t; + +/* Type of the call associated to the RRC connection establishment */ +typedef enum as_call_type_s { + AS_TYPE_ORIGINATING_SIGNAL = NET_ESTABLISH_TYPE_ORIGINATING_SIGNAL, + AS_TYPE_EMERGENCY_CALLS = NET_ESTABLISH_TYPE_EMERGENCY_CALLS, + AS_TYPE_ORIGINATING_CALLS = NET_ESTABLISH_TYPE_ORIGINATING_CALLS, + AS_TYPE_TERMINATING_CALLS = NET_ESTABLISH_TYPE_TERMINATING_CALLS, + AS_TYPE_MO_CS_FALLBACK = NET_ESTABLISH_TYPE_MO_CS_FALLBACK +} as_call_type_t; + +/* + * NAS->AS - NAS signalling connection establishment request + * NAS requests the AS to perform the RRC connection establishment procedure + * to transfer initial NAS message to the network while UE is in IDLE mode. + */ +typedef struct nas_establish_req_s { + as_cause_t cause; /* RRC connection establishment cause */ + as_call_type_t type; /* RRC associated call type */ + as_stmsi_t s_tmsi; /* UE identity */ + plmn_t plmnID; /* Selected PLMN identity */ + as_nas_info_t initialNasMsg; /* Initial NAS message to transfer */ +} nas_establish_req_t; + +/* + * AS->NAS - NAS signalling connection establishment indication + * AS transfers the initial NAS message to the NAS. + */ +typedef struct nas_establish_ind_s { + uint32_t UEid; /* UE lower layer identifier */ + tac_t tac; /* Code of the tracking area the initiating + * UE belongs to */ + as_cause_t asCause; /* Establishment cause */ + as_nas_info_t initialNasMsg; /* Initial NAS message to transfer */ +} nas_establish_ind_t; + +/* + * NAS->AS - NAS signalling connection establishment response + * NAS responds to the AS that initial answer message has to be provided to + * the UE. + */ +typedef struct nas_establish_rsp_s { + uint32_t UEid; /* UE lower layer identifier */ + as_stmsi_t s_tmsi; /* UE identity */ + nas_error_code_t errCode; /* Transaction status */ + as_nas_info_t nasMsg; /* NAS message to transfer */ + uint32_t nas_ul_count; /* UL NAS COUNT */ + uint16_t selected_encryption_algorithm; + uint16_t selected_integrity_algorithm; +} nas_establish_rsp_t; + +/* + * AS->NAS - NAS signalling connection establishment confirm + * AS transfers the initial answer message to the NAS. + */ +typedef struct nas_establish_cnf_s { + uint32_t UEid; /* UE lower layer identifier */ + nas_error_code_t errCode; /* Transaction status */ + as_nas_info_t nasMsg; /* NAS message to transfer */ + uint32_t ul_nas_count; + uint16_t selected_encryption_algorithm; + uint16_t selected_integrity_algorithm; +} nas_establish_cnf_t; + +/* + * -------------------------------------------------------------------------- + * NAS signalling connection release + * -------------------------------------------------------------------------- + */ + +/* Release cause */ +typedef enum release_cause_s { + AS_AUTHENTICATION_FAILURE = 1, /* Authentication procedure failed */ + AS_DETACH /* Detach requested */ +} release_cause_t; + +/* + * NAS->AS - NAS signalling connection release request + * NAS requests the termination of the connection with the UE. + */ +typedef struct nas_release_req_s { + uint32_t UEid; /* UE lower layer identifier */ + as_stmsi_t s_tmsi; /* UE identity */ + release_cause_t cause; /* Release cause */ +} nas_release_req_t; + +/* + * AS->NAS - NAS signalling connection release indication + * AS reports that connection has been terminated by the network. + */ +typedef struct nas_release_ind_s { + release_cause_t cause; /* Release cause */ +} nas_release_ind_t; + +/* + * -------------------------------------------------------------------------- + * NAS information transfer + * -------------------------------------------------------------------------- + */ + +/* + * NAS->AS - Uplink data transfer request + * NAS requests the AS to transfer uplink information to the NAS that + * operates at the network side. + */ +typedef struct ul_info_transfer_req_s { + uint32_t UEid; /* UE lower layer identifier */ + as_stmsi_t s_tmsi; /* UE identity */ + as_nas_info_t nasMsg; /* Uplink NAS message */ +} ul_info_transfer_req_t; + +/* + * AS->NAS - Uplink data transfer confirm + * AS immediately notifies the NAS whether uplink information has been + * successfully sent to the network or not. + */ +typedef struct ul_info_transfer_cnf_s { + uint32_t UEid; /* UE lower layer identifier */ + nas_error_code_t errCode; /* Transaction status */ +} ul_info_transfer_cnf_t; + +/* + * AS->NAS - Uplink data transfer indication + * AS delivers the uplink information message to the NAS that operates + * at the network side. + */ +typedef struct ul_info_transfer_ind_s { + uint32_t UEid; /* UE lower layer identifier */ + as_nas_info_t nasMsg; /* Uplink NAS message */ +} ul_info_transfer_ind_t; + +/* + * NAS->AS - Downlink data transfer request + * NAS requests the AS to transfer downlink information to the NAS that + * operates at the UE side. + */ +typedef ul_info_transfer_req_t dl_info_transfer_req_t; + +/* + * AS->NAS - Downlink data transfer confirm + * AS immediately notifies the NAS whether downlink information has been + * successfully sent to the network or not. + */ +typedef ul_info_transfer_cnf_t dl_info_transfer_cnf_t; + +/* + * AS->NAS - Downlink data transfer indication + * AS delivers the downlink information message to the NAS that operates + * at the UE side. + */ +typedef ul_info_transfer_ind_t dl_info_transfer_ind_t; + +/* + * -------------------------------------------------------------------------- + * Radio Access Bearer establishment + * -------------------------------------------------------------------------- + */ + +/* TODO: Quality of Service parameters */ +typedef struct {} as_qos_t; + +/* + * NAS->AS - Radio access bearer establishment request + * NAS requests the AS to allocate transmission resources to radio access + * bearer initialized at the network side. + */ +typedef struct rab_establish_req_s { + as_stmsi_t s_tmsi; /* UE identity */ + as_rab_id_t rabID; /* Radio access bearer identity */ + as_qos_t QoS; /* Requested Quality of Service */ +} rab_establish_req_t; + +/* + * AS->NAS - Radio access bearer establishment indication + * AS notifies the NAS that specific radio access bearer has to be setup. + */ +typedef struct rab_establish_ind_s { + as_rab_id_t rabID; /* Radio access bearer identity */ +} rab_establish_ind_t; + +/* + * NAS->AS - Radio access bearer establishment response + * NAS responds to AS whether the specified radio access bearer has been + * successfully setup or not. + */ +typedef struct rab_establish_rsp_s { + as_stmsi_t s_tmsi; /* UE identity */ + as_rab_id_t rabID; /* Radio access bearer identity */ + nas_error_code_t errCode; /* Transaction status */ +} rab_establish_rsp_t; + +/* + * AS->NAS - Radio access bearer establishment confirm + * AS notifies NAS whether the specified radio access bearer has been + * successfully setup at the UE side or not. + */ +typedef struct rab_establish_cnf_s { + as_rab_id_t rabID; /* Radio access bearer identity */ + nas_error_code_t errCode; /* Transaction status */ +} rab_establish_cnf_t; + +/* + * -------------------------------------------------------------------------- + * Radio Access Bearer release + * -------------------------------------------------------------------------- + */ + +/* + * NAS->AS - Radio access bearer release request + * NAS requests the AS to release transmission resources previously allocated + * to specific radio access bearer at the network side. + */ +typedef struct rab_release_req_s { + as_stmsi_t s_tmsi; /* UE identity */ + as_rab_id_t rabID; /* Radio access bearer identity */ +} rab_release_req_t; + +/* + * AS->NAS - Radio access bearer release indication + * AS notifies NAS that specific radio access bearer has been released. + */ +typedef struct rab_release_ind_s { + as_rab_id_t rabID; /* Radio access bearer identity */ +} rab_release_ind_t; + +/* + * -------------------------------------------------------------------------- + * Structure of the AS messages handled by the network sublayer + * -------------------------------------------------------------------------- + */ +typedef struct as_message_s { + uint16_t msgID; + union { + broadcast_info_ind_t broadcast_info_ind; + cell_info_req_t cell_info_req; + cell_info_cnf_t cell_info_cnf; + cell_info_ind_t cell_info_ind; + paging_req_t paging_req; + paging_ind_t paging_ind; + nas_establish_req_t nas_establish_req; + nas_establish_ind_t nas_establish_ind; + nas_establish_rsp_t nas_establish_rsp; + nas_establish_cnf_t nas_establish_cnf; + nas_release_req_t nas_release_req; + nas_release_ind_t nas_release_ind; + ul_info_transfer_req_t ul_info_transfer_req; + ul_info_transfer_cnf_t ul_info_transfer_cnf; + ul_info_transfer_ind_t ul_info_transfer_ind; + dl_info_transfer_req_t dl_info_transfer_req; + dl_info_transfer_cnf_t dl_info_transfer_cnf; + dl_info_transfer_ind_t dl_info_transfer_ind; + rab_establish_req_t rab_establish_req; + rab_establish_ind_t rab_establish_ind; + rab_establish_rsp_t rab_establish_rsp; + rab_establish_cnf_t rab_establish_cnf; + rab_release_req_t rab_release_req; + rab_release_ind_t rab_release_ind; + } __attribute__((__packed__)) msg; +} as_message_t; + +/****************************************************************************/ +/******************** G L O B A L V A R I A B L E S ********************/ +/****************************************************************************/ + +/****************************************************************************/ +/****************** E X P O R T E D F U N C T I O N S ******************/ +/****************************************************************************/ + +int as_message_decode(const char* buffer, as_message_t* msg, int length); + +int as_message_encode(char* buffer, as_message_t* msg, int length); + +/* Implemented in the network_api.c body file */ +int as_message_send(as_message_t* as_msg); + +#endif /* __AS_MESSAGE_H__*/ diff --git a/openair3/NAS/COMMON/commonDef.h b/openair3/NAS/COMMON/commonDef.h deleted file mode 120000 index 19553e9b6485b5e512d086e2f72abf1a1f387b97..0000000000000000000000000000000000000000 --- a/openair3/NAS/COMMON/commonDef.h +++ /dev/null @@ -1 +0,0 @@ -../../../openair2/COMMON/commonDef.h \ No newline at end of file diff --git a/openair3/NAS/COMMON/commonDef.h b/openair3/NAS/COMMON/commonDef.h new file mode 100644 index 0000000000000000000000000000000000000000..64216b009465119c56e0d357dab48875b7c4be08 --- /dev/null +++ b/openair3/NAS/COMMON/commonDef.h @@ -0,0 +1,342 @@ +/* + * Copyright (c) 2015, EURECOM (www.eurecom.fr) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of the FreeBSD Project. + */ +/* + +Source commonDef.h + +Version 0.1 + +Date 2012/02/27 + +Product NAS stack + +Subsystem include + +Author Frederic Maurel + +Description Contains global common definitions + +*****************************************************************************/ +#ifndef __COMMONDEF_H__ +#define __COMMONDEF_H__ + +#include <stdint.h> +#include <stddef.h> +#include <stdbool.h> + +typedef signed char boolean_t; + +#if !defined(TRUE) +#define TRUE (boolean_t)0x01 +#endif + +#if !defined(FALSE) +#define FALSE (boolean_t)0x00 +#endif + +#define BOOL_NOT(b) (b^TRUE) + +#define NAS_UE_ID_FMT "0x%06x" + +/****************************************************************************/ +/********************* G L O B A L C O N S T A N T S *******************/ +/****************************************************************************/ + +#define RETURNok (0) +#define RETURNerror (-1) + +/* + * Name of the environment variable which defines the default directory + * where the NAS application is executed and where are located files + * where non-volatile data are stored + */ +#define DEFAULT_NAS_PATH "PWD" + +/****************************************************************************/ +/************************ G L O B A L T Y P E S ************************/ +/****************************************************************************/ + +/* +----------------------------------------------------------------------------- + Standard data type definitions +----------------------------------------------------------------------------- +*/ +typedef int8_t SByte_t; /* 8 bit signed integer */ +typedef uint8_t Byte_t; /* 8 bit unsigned integer */ + + +/* +----------------------------------------------------------------------------- + Common NAS data type definitions +----------------------------------------------------------------------------- +*/ + +typedef uint8_t Stat_t; /* Registration status */ +typedef uint16_t lac_t; /* Location Area Code */ +typedef uint8_t rac_t; /* Routing Area Code */ +typedef uint16_t tac_t; /* Tracking Area Code */ +typedef uint32_t ci_t; /* Cell Identifier */ +typedef uint8_t AcT_t; /* Access Technology */ + +/* + * International Mobile Subscriber Identity + */ +typedef struct { + Byte_t length; + union { + struct { + Byte_t digit2:4; + Byte_t digit1:4; + Byte_t digit4:4; + Byte_t digit3:4; + Byte_t digit6:4; + Byte_t digit5:4; + Byte_t digit8:4; + Byte_t digit7:4; + Byte_t digit10:4; + Byte_t digit9:4; + Byte_t digit12:4; + Byte_t digit11:4; + Byte_t digit14:4; + Byte_t digit13:4; +#define EVEN_PARITY 0 +#define ODD_PARITY 1 + Byte_t parity:4; + Byte_t digit15:4; + } num; +#define IMSI_SIZE 8 + Byte_t value[IMSI_SIZE]; + } u; +} imsi_t; + +#define NAS_IMSI2STR(iMsI_t_PtR,iMsI_sTr, MaXlEn) \ + {\ + int l_offset = 0;\ + int l_ret = 0;\ + l_ret = snprintf(iMsI_sTr + l_offset, MaXlEn - l_offset, "%u%u%u%u%u",\ + iMsI_t_PtR->u.num.digit1, iMsI_t_PtR->u.num.digit2,\ + iMsI_t_PtR->u.num.digit3, iMsI_t_PtR->u.num.digit4,\ + iMsI_t_PtR->u.num.digit5);\ + if ((iMsI_t_PtR->u.num.digit6 != 0xf) && (l_ret > 0)) {\ + l_offset += l_ret;\ + l_ret = snprintf(iMsI_sTr + l_offset, MaXlEn - l_offset, "%u", iMsI_t_PtR->u.num.digit6);\ + }\ + if (l_ret > 0) {\ + l_offset += l_ret;\ + l_ret = snprintf(iMsI_sTr + l_offset, MaXlEn - l_offset, "%u%u%u%u%u%u%u%u",\ + iMsI_t_PtR->u.num.digit7, iMsI_t_PtR->u.num.digit8,\ + iMsI_t_PtR->u.num.digit9, iMsI_t_PtR->u.num.digit10,\ + iMsI_t_PtR->u.num.digit11, iMsI_t_PtR->u.num.digit12,\ + iMsI_t_PtR->u.num.digit13, iMsI_t_PtR->u.num.digit14);\ + }\ + if ((iMsI_t_PtR->u.num.digit15 != 0xf) && (l_ret > 0)) {\ + l_offset += l_ret;\ + l_ret = snprintf(iMsI_sTr + l_offset, MaXlEn - l_offset, "%u", iMsI_t_PtR->u.num.digit15);\ + }\ + } + +/* + * Mobile subscriber dialing number + */ +typedef struct { + Byte_t ext:1; + /* Type Of Number */ +#define MSISDN_TON_UNKNOWKN 0b000 +#define MSISDN_TON_INTERNATIONAL 0b001 +#define MSISDN_TON_NATIONAL 0b010 +#define MSISDN_TON_NETWORK 0b011 +#define MSISDN_TON_SUBCRIBER 0b100 +#define MSISDN_TON_ABBREVIATED 0b110 +#define MSISDN_TON_RESERVED 0b111 + Byte_t ton:3; + /* Numbering Plan Identification */ +#define MSISDN_NPI_UNKNOWN 0b0000 +#define MSISDN_NPI_ISDN_TELEPHONY 0b0001 +#define MSISDN_NPI_GENERIC 0b0010 +#define MSISDN_NPI_DATA 0b0011 +#define MSISDN_NPI_TELEX 0b0100 +#define MSISDN_NPI_MARITIME_MOBILE 0b0101 +#define MSISDN_NPI_LAND_MOBILE 0b0110 +#define MSISDN_NPI_ISDN_MOBILE 0b0111 +#define MSISDN_NPI_PRIVATE 0b1110 +#define MSISDN_NPI_RESERVED 0b1111 + Byte_t npi:4; + /* Dialing Number */ + struct { + Byte_t lsb:4; + Byte_t msb:4; +#define MSISDN_DIGIT_SIZE 10 + } digit[MSISDN_DIGIT_SIZE]; +} msisdn_t; + +/* + * International Mobile Equipment Identity + */ +typedef imsi_t imei_t; + +/* + * Public Land Mobile Network identifier + * PLMN = BCD encoding (Mobile Country Code + Mobile Network Code) + */ +typedef struct { + Byte_t MCCdigit2:4; + Byte_t MCCdigit1:4; + Byte_t MNCdigit3:4; + Byte_t MCCdigit3:4; + Byte_t MNCdigit2:4; + Byte_t MNCdigit1:4; +} plmn_t; + +/* + * Location Area Identification + */ +typedef struct { + plmn_t plmn; /* <MCC> + <MNC> */ + lac_t lac; /* Location Area Code */ +} lai_t; + +/* + * GPRS Routing Area Identification + */ +typedef struct { + plmn_t plmn; /* <MCC> + <MNC> */ + lac_t lac; /* Location Area Code */ + rac_t rac; /* Routing Area Code */ +} RAI_t; + +/* + * EPS Tracking Area Identification + */ +typedef struct { + plmn_t plmn; /* <MCC> + <MNC> */ + tac_t tac; /* Tracking Area Code */ +} tai_t; + +/* + * EPS Globally Unique MME Identity + */ +typedef struct { + plmn_t plmn; /* <MCC> + <MNC> */ + uint16_t MMEgid; /* MME group identifier */ + uint8_t MMEcode; /* MME code */ +} gummei_t; + +/* + * EPS Globally Unique Temporary UE Identity + */ +typedef struct { + gummei_t gummei; /* Globally Unique MME Identity */ + uint32_t m_tmsi; /* M-Temporary Mobile Subscriber Identity */ +} GUTI_t; +#define GUTI2STR(GuTi_PtR, GuTi_StR, MaXlEn) \ + {\ + int l_offset = 0;\ + int l_ret = 0;\ + l_ret += snprintf(GuTi_StR + l_offset,MaXlEn-l_offset, "%03u.",\ + GuTi_PtR->gummei.plmn.MCCdigit3 * 100 +\ + GuTi_PtR->gummei.plmn.MCCdigit2 * 10 +\ + GuTi_PtR->gummei.plmn.MCCdigit1);\ + if (l_ret > 0) {\ + l_offset += l_ret;\ + } else {\ + l_offset = MaXlEn;\ + }\ + if (GuTi_PtR->gummei.plmn.MNCdigit1 != 0xf) {\ + l_ret += snprintf(GuTi_StR + l_offset,MaXlEn-l_offset, "%03u|%04x|%02x|%08x",\ + GuTi_PtR->gummei.plmn.MNCdigit3 * 100 +\ + GuTi_PtR->gummei.plmn.MNCdigit2 * 10 +\ + GuTi_PtR->gummei.plmn.MNCdigit1,\ + GuTi_PtR->gummei.MMEgid,\ + GuTi_PtR->gummei.MMEcode,\ + GuTi_PtR->m_tmsi);\ + } else {\ + l_ret += snprintf(GuTi_StR + l_offset,MaXlEn-l_offset, "%02u|%04x|%02x|%08x",\ + GuTi_PtR->gummei.plmn.MNCdigit2 * 10 +\ + GuTi_PtR->gummei.plmn.MNCdigit1,\ + GuTi_PtR->gummei.MMEgid,\ + GuTi_PtR->gummei.MMEcode,\ + GuTi_PtR->m_tmsi);\ + }\ + } + + + + +/* Checks PLMN validity */ +#define PLMN_IS_VALID(plmn) (((plmn).MCCdigit1 & \ + (plmn).MCCdigit2 & \ + (plmn).MCCdigit3) != 0x0F) + +/* Checks TAC validity */ +#define TAC_IS_VALID(tac) (((tac) != 0x0000) && ((tac) != 0xFFF0)) + +/* Checks TAI validity */ +#define TAI_IS_VALID(tai) (PLMN_IS_VALID((tai).plmn) && \ + TAC_IS_VALID((tai).tac)) +/* + * A list of PLMNs + */ +#define PLMN_LIST_T(SIZE) struct {Byte_t n_plmns; plmn_t plmn[SIZE];} + +/* + * A list of TACs + */ +#define TAC_LIST_T(SIZE) struct {Byte_t n_tacs; TAC_t tac[SIZE];} + +/* + * A list of TAIs + */ +#define TAI_LIST_T(SIZE) struct {Byte_t n_tais; tai_t tai[SIZE];} + +/* + * User notification callback, executed whenever a change of data with + * respect of network information (e.g. network registration and/or + * location change, new PLMN becomes available) is notified by the + * EPS Mobility Management sublayer + */ +typedef int (*emm_indication_callback_t) (Stat_t, tac_t, ci_t, AcT_t, + const char*, size_t); + +typedef enum eps_protocol_discriminator_e { + /* Protocol discriminator identifier for EPS Mobility Management */ + EPS_MOBILITY_MANAGEMENT_MESSAGE = 0x7, + + /* Protocol discriminator identifier for EPS Session Management */ + EPS_SESSION_MANAGEMENT_MESSAGE = 0x2, +} eps_protocol_discriminator_t; + +/****************************************************************************/ +/******************** G L O B A L V A R I A B L E S ********************/ +/****************************************************************************/ + +/****************************************************************************/ +/****************** E X P O R T E D F U N C T I O N S ******************/ +/****************************************************************************/ + +#endif /* __COMMONDEF_H__*/ diff --git a/openair3/NAS/COMMON/networkDef.h b/openair3/NAS/COMMON/networkDef.h deleted file mode 120000 index 2648b55e992973fc58c9c2c0e12b99733fba0010..0000000000000000000000000000000000000000 --- a/openair3/NAS/COMMON/networkDef.h +++ /dev/null @@ -1 +0,0 @@ -../../../openair2/COMMON/networkDef.h \ No newline at end of file diff --git a/openair3/NAS/COMMON/networkDef.h b/openair3/NAS/COMMON/networkDef.h new file mode 100644 index 0000000000000000000000000000000000000000..46716bee24714ab2273744c4634a0924d9320207 --- /dev/null +++ b/openair3/NAS/COMMON/networkDef.h @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2015, EURECOM (www.eurecom.fr) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of the FreeBSD Project. + */ + +/***************************************************************************** + +Source networkDef.h + +Version 0.1 + +Date 2012/09/21 + +Product NAS stack + +Subsystem include + +Author Frederic Maurel + +Description Contains network's global definitions + +*****************************************************************************/ +#ifndef __NETWORKDEF_H__ +#define __NETWORKDEF_H__ + +/****************************************************************************/ +/********************* G L O B A L C O N S T A N T S *******************/ +/****************************************************************************/ + +/* + * ---------------------- + * Network selection mode + * ---------------------- + */ +#define NET_PLMN_AUTO 0 +#define NET_PLMN_MANUAL 1 + +/* + * --------------------------- + * Network registration status + * --------------------------- + */ +/* not registered, not currently searching an operator to register to */ +#define NET_REG_STATE_OFF 0 +/* registered, home network */ +#define NET_REG_STATE_HN 1 +/* not registered, currently trying to attach or searching an operator + * to register to */ +#define NET_REG_STATE_ON 2 +/* registration denied */ +#define NET_REG_STATE_DENIED 3 +/* unknown (e.g. out of GERAN/UTRAN/E-UTRAN coverage) */ +#define NET_REG_STATE_UNKNOWN 4 +/* registered, roaming */ +#define NET_REG_STATE_ROAMING 5 +/* registered for "SMS only", home network */ +#define NET_REG_STATE_SMS_HN 6 +/* registered, for "SMS only", roaming */ +#define NET_REG_STATE_SMS_ROAMING 7 +/* attached for emergency bearer services only (applicable to UTRAN) */ +#define NET_REG_STATE_EMERGENCY 8 + +/* + * ------------------------------------ + * Network access technology indicators + * ------------------------------------ + */ +#define NET_ACCESS_UNAVAILABLE (-1) /* Not available */ +#define NET_ACCESS_GSM 0 /* GSM */ +#define NET_ACCESS_COMPACT 1 /* GSM Compact */ +#define NET_ACCESS_UTRAN 2 /* UTRAN */ +#define NET_ACCESS_EGPRS 3 /* GSM w/EGPRS */ +#define NET_ACCESS_HSDPA 4 /* UTRAN w/HSDPA */ +#define NET_ACCESS_HSUPA 5 /* UTRAN w/HSUPA */ +#define NET_ACCESS_HSDUPA 6 /* UTRAN w/HSDPA and HSUPA */ +#define NET_ACCESS_EUTRAN 7 /* E-UTRAN */ + +/* + * --------------------------------------- + * Network operator representation formats + * --------------------------------------- + */ +#define NET_FORMAT_LONG 0 /* long format alphanumeric */ +#define NET_FORMAT_SHORT 1 /* short format alphanumeric */ +#define NET_FORMAT_NUM 2 /* numeric format */ + +#define NET_FORMAT_MAX_SIZE NET_FORMAT_LONG_SIZE + +/* + * ----------------------------- + * Network operator availability + * ----------------------------- + */ +#define NET_OPER_UNKNOWN 0 /* unknown operator */ +#define NET_OPER_AVAILABLE 1 /* available operator */ +#define NET_OPER_CURRENT 2 /* currently selected operator */ +#define NET_OPER_FORBIDDEN 3 /* forbidden operator */ + +/* + * -------------------------------------- + * Network connection establishment cause + * -------------------------------------- + */ +#define NET_ESTABLISH_CAUSE_EMERGENCY 0x01 +#define NET_ESTABLISH_CAUSE_HIGH_PRIO 0x02 +#define NET_ESTABLISH_CAUSE_MT_ACCESS 0x03 +#define NET_ESTABLISH_CAUSE_MO_SIGNAL 0x04 +#define NET_ESTABLISH_CAUSE_MO_DATA 0x05 +#define NET_ESTABLISH_CAUSE_V1020 0x06 + +/* + * -------------------------------------- + * Network connection establishment type + * -------------------------------------- + */ +#define NET_ESTABLISH_TYPE_ORIGINATING_SIGNAL 0x10 +#define NET_ESTABLISH_TYPE_EMERGENCY_CALLS 0x20 +#define NET_ESTABLISH_TYPE_ORIGINATING_CALLS 0x30 +#define NET_ESTABLISH_TYPE_TERMINATING_CALLS 0x40 +#define NET_ESTABLISH_TYPE_MO_CS_FALLBACK 0x50 + +/* + * ------------------- + * PDN connection type + * ------------------- + */ +#define NET_PDN_TYPE_IPV4 (0 + 1) +#define NET_PDN_TYPE_IPV6 (1 + 1) +#define NET_PDN_TYPE_IPV4V6 (2 + 1) + +/****************************************************************************/ +/************************ G L O B A L T Y P E S ************************/ +/****************************************************************************/ + +/* + * --------------------- + * PDN connection status + * --------------------- + */ +typedef enum { + /* MT = The Mobile Terminal, NW = The Network */ + NET_PDN_MT_DEFAULT_ACT = 1, /* MT has activated a PDN connection */ + NET_PDN_NW_DEFAULT_DEACT, /* NW has deactivated a PDN connection */ + NET_PDN_MT_DEFAULT_DEACT, /* MT has deactivated a PDN connection */ + NET_PDN_NW_DEDICATED_ACT, /* NW has activated an EPS bearer context */ + NET_PDN_MT_DEDICATED_ACT, /* MT has activated an EPS bearer context */ + NET_PDN_NW_DEDICATED_DEACT, /* NW has deactivated an EPS bearer context */ + NET_PDN_MT_DEDICATED_DEACT, /* MT has deactivated an EPS bearer context */ +} network_pdn_state_t; + +/* + * --------------------------- + * Network operator identifier + * --------------------------- + */ +typedef struct { +#define NET_FORMAT_LONG_SIZE 16 /* Long alphanumeric format */ +#define NET_FORMAT_SHORT_SIZE 8 /* Short alphanumeric format */ +#define NET_FORMAT_NUM_SIZE 6 /* Numeric format (PLMN identifier */ + union { + unsigned char alpha_long[NET_FORMAT_LONG_SIZE+1]; + unsigned char alpha_short[NET_FORMAT_SHORT_SIZE+1]; + unsigned char num[NET_FORMAT_NUM_SIZE+1]; + } id; +} network_plmn_t; + +/* + * ------------------------------- + * EPS bearer level QoS parameters + * ------------------------------- + */ +typedef struct { + int gbrUL; /* Guaranteed Bit Rate for uplink */ + int gbrDL; /* Guaranteed Bit Rate for downlink */ + int mbrUL; /* Maximum Bit Rate for uplink */ + int mbrDL; /* Maximum Bit Rate for downlink */ + int qci; /* QoS Class Identifier */ +} network_qos_t; + +/* + * ----------------------------- + * IPv4 packet filter parameters + * ----------------------------- + */ +typedef struct { + unsigned char protocol; /* Protocol identifier */ + unsigned char tos; /* Type of service */ +#define NET_PACKET_FILTER_IPV4_ADDR_SIZE 4 + unsigned char addr[NET_PACKET_FILTER_IPV4_ADDR_SIZE]; + unsigned char mask[NET_PACKET_FILTER_IPV4_ADDR_SIZE]; +} network_ipv4_data_t; + +/* + * ----------------------------- + * IPv6 packet filter parameters + * ----------------------------- + */ +typedef struct { + unsigned char nh; /* Next header type */ + unsigned char tf; /* Traffic class */ +#define NET_PACKET_FILTER_IPV6_ADDR_SIZE 16 + unsigned char addr[NET_PACKET_FILTER_IPV6_ADDR_SIZE]; + unsigned char mask[NET_PACKET_FILTER_IPV6_ADDR_SIZE]; + unsigned int ipsec; /* IPSec security parameter index */ + unsigned int fl; /* Flow label */ +} network_ipv6_data_t; + +/* + * ------------- + * Packet Filter + * ------------- + */ +typedef struct { + unsigned char id; /* Packet filter identifier */ +#define NET_PACKET_FILTER_DOWNLINK 0x01 +#define NET_PACKET_FILTER_UPLINK 0x02 +#define NET_PACKET_FILTER_BIDIR 0x03 + unsigned char dir; /* Packet filter direction */ + unsigned char precedence; /* Evaluation precedence */ + union { + network_ipv4_data_t ipv4; + network_ipv6_data_t ipv6; + } data; + unsigned short lport; /* Local (UE) port number */ + unsigned short rport; /* Remote (network) port number */ +} network_pkf_t; + +/* + * --------------------- + * Traffic Flow Template + * --------------------- + */ +typedef struct { + int n_pkfs; +#define NET_PACKET_FILTER_MAX 16 + network_pkf_t* pkf[NET_PACKET_FILTER_MAX]; +} network_tft_t; + +/* + * User notification callback, executed whenever a change of status with + * respect of PDN connection or EPS bearer context is notified by the EPS + * Session Management sublayer + */ +typedef int (*esm_indication_callback_t) (int, network_pdn_state_t); + +/****************************************************************************/ +/******************** G L O B A L V A R I A B L E S ********************/ +/****************************************************************************/ + +/****************************************************************************/ +/****************** E X P O R T E D F U N C T I O N S ******************/ +/****************************************************************************/ + +#endif /* __NETWORKDEF_H__*/ diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h index a366b54023bd86ab8bbe882e21ab9eb274e457ad..2eb0a506be8f840c34ac5de1cb7f7a5ca9763fc3 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/targets/ARCH/COMMON/common_lib.h @@ -135,6 +135,14 @@ typedef struct { double offset; } rx_gain_calib_table_t; +/*! \brief Clock source types */ +typedef enum { + //! This tells the underlying hardware to use the internal reference + internal=0, + //! This tells the underlying hardware to use the external reference + external=1 +} clock_source_t; + /*! \brief RF frontend parameters set by application */ typedef struct { //! Module ID for this configuration @@ -187,6 +195,8 @@ typedef struct { double rx_bw; //! TX bandwidth in Hz double tx_bw; + //! clock source + clock_source_t clock_source; //! Auto calibration flag int autocal[4]; //! rf devices work with x bits iqs when oai have its own iq format @@ -238,8 +248,10 @@ typedef struct { typedef struct { - //! Tx buffer for if device - void *tx; + //! Tx buffer for if device, keep one per subframe now to allow multithreading + void *tx[10]; + //! Tx buffer (PRACH) for if device + void *tx_prach; //! Rx buffer for if device void *rx; } if_buffer_t; diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c index 1f8bab415c9998abc1d7809e7764ab01b6b5158a..5815f2b1a66797cadd6544bbfab7f6a0dce398c7 100644 --- a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c +++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c @@ -21,7 +21,7 @@ /*! \file ethernet_lib.c * \brief API to stream I/Q samples over standard ethernet - * \author add alcatel Katerina Trilyraki, Navid Nikaein, Pedro Dinis, Lucio Ferreira, Raymond Knopp + * \author add alcatel Katerina Trilyraki, Navid Nikaein, Pedro Dinis, Lucio Ferreira, Raymond Knopp, Tien-Thinh Nguyen * \date 2015 * \version 0.2 * \company Eurecom @@ -45,18 +45,16 @@ #include "common_lib.h" #include "ethernet_lib.h" -#define DEBUG 0 +//#define DEBUG 0 -struct sockaddr_ll dest_addr[MAX_INST]; -struct sockaddr_ll local_addr[MAX_INST]; -int addr_len[MAX_INST]; -struct ifreq if_index[MAX_INST]; +//struct sockaddr_ll dest_addr[MAX_INST]; +//struct sockaddr_ll local_addr[MAX_INST]; +//int addr_len[MAX_INST]; +//struct ifreq if_index[MAX_INST]; int eth_socket_init_raw(openair0_device *device) { - int i = 0; eth_state_t *eth = (eth_state_t*)device->priv; - int Mod_id = device->Mod_id; const char *local_mac, *remote_mac; int sock_dom=0; int sock_type=0; @@ -78,30 +76,33 @@ int eth_socket_init_raw(openair0_device *device) { sock_dom=AF_PACKET; sock_type=SOCK_RAW; sock_proto=IPPROTO_RAW; - if ((eth->sockfd[Mod_id] = socket(sock_dom, sock_type, sock_proto)) == -1) { + if ((eth->sockfd = socket(sock_dom, sock_type, sock_proto)) == -1) { perror("ETHERNET: Error opening RAW socket"); exit(0); } /* initialize destination address */ - for (i=0; i< MAX_INST; i++) { - bzero((void *)&(local_addr[i]), sizeof(struct sockaddr_ll)); - bzero((void *)&(if_index[i]), sizeof(struct ifreq)); - } + bzero((void *)&(eth->local_addr_ll), sizeof(struct sockaddr_ll)); + bzero((void *)&(eth->if_index), sizeof(struct ifreq)); + /* Get the index of the interface to send on */ - strcpy(if_index[Mod_id].ifr_name,eth->if_name[Mod_id]); - if (ioctl(eth->sockfd[Mod_id], SIOCGIFINDEX, &(if_index[Mod_id])) < 0) + strcpy(eth->if_index.ifr_name,eth->if_name); + if (ioctl(eth->sockfd, SIOCGIFINDEX, &(eth->if_index)) < 0) perror("SIOCGIFINDEX"); - local_addr[Mod_id].sll_family = AF_PACKET; - local_addr[Mod_id].sll_ifindex = if_index[Mod_id].ifr_ifindex; + eth->local_addr_ll.sll_family = AF_PACKET; + eth->local_addr_ll.sll_ifindex = eth->if_index.ifr_ifindex; /* hear traffic from specific protocol*/ - local_addr[Mod_id].sll_protocol = htons((short)device->openair0_cfg->my_port); - local_addr[Mod_id].sll_halen = ETH_ALEN; - local_addr[Mod_id].sll_pkttype = PACKET_OTHERHOST; - addr_len[Mod_id] = sizeof(struct sockaddr_ll); + if (eth->flags == ETH_RAW_IF5_MOBIPASS) { + eth->local_addr_ll.sll_protocol = htons(0xbffe); + } else{ + eth->local_addr_ll.sll_protocol = htons((short)device->openair0_cfg->my_port); + } + eth->local_addr_ll.sll_halen = ETH_ALEN; + eth->local_addr_ll.sll_pkttype = PACKET_OTHERHOST; + eth->addr_len = sizeof(struct sockaddr_ll); - if (bind(eth->sockfd[Mod_id],(struct sockaddr *)&local_addr[Mod_id],addr_len[Mod_id])<0) { + if (bind(eth->sockfd,(struct sockaddr *)ð->local_addr_ll,eth->addr_len)<0) { perror("ETHERNET: Cannot bind to socket"); exit(0); } @@ -114,7 +115,7 @@ int eth_socket_init_raw(openair0_device *device) { } else { eth->eh.ether_type = htons((short)device->openair0_cfg->my_port); } - printf("[%s] binding mod_%d to hardware address %x:%x:%x:%x:%x:%x\n",((device->host_type == BBU_HOST) ? "BBU": "RRH"),Mod_id,eth->eh.ether_shost[0],eth->eh.ether_shost[1],eth->eh.ether_shost[2],eth->eh.ether_shost[3],eth->eh.ether_shost[4],eth->eh.ether_shost[5]); + printf("[%s] binding to hardware address %x:%x:%x:%x:%x:%x\n",((device->host_type == BBU_HOST) ? "BBU": "RRH"),eth->eh.ether_shost[0],eth->eh.ether_shost[1],eth->eh.ether_shost[2],eth->eh.ether_shost[3],eth->eh.ether_shost[4],eth->eh.ether_shost[5]); return 0; } @@ -124,7 +125,6 @@ int trx_eth_write_raw(openair0_device *device, openair0_timestamp timestamp, voi int bytes_sent=0; eth_state_t *eth = (eth_state_t*)device->priv; - int Mod_id = device->Mod_id; int sendto_flag =0; int i=0; //sendto_flag|=flags; @@ -157,7 +157,7 @@ int trx_eth_write_raw(openair0_device *device, openair0_timestamp timestamp, voi bytes_sent); #endif /* Send packet */ - bytes_sent += send(eth->sockfd[Mod_id], + bytes_sent += send(eth->sockfd, buff2, RAW_PACKET_SIZE_BYTES(nsamps), sendto_flag); @@ -195,7 +195,6 @@ int trx_eth_write_raw_IF4p5(openair0_device *device, openair0_timestamp timestam int bytes_sent = 0; eth_state_t *eth = (eth_state_t*)device->priv; - int Mod_id = device->Mod_id; ssize_t packet_size; @@ -203,6 +202,8 @@ int trx_eth_write_raw_IF4p5(openair0_device *device, openair0_timestamp timestam packet_size = RAW_IF4p5_PDLFFT_SIZE_BYTES(nblocks); } else if (flags == IF4p5_PULFFT) { packet_size = RAW_IF4p5_PULFFT_SIZE_BYTES(nblocks); + } else if (flags == IF4p5_PULTICK) { + packet_size = RAW_IF4p5_PULTICK_SIZE_BYTES; } else if (flags == IF5_MOBIPASS) { packet_size = RAW_IF5_MOBIPASS_SIZE_BYTES; } else { @@ -214,7 +215,7 @@ int trx_eth_write_raw_IF4p5(openair0_device *device, openair0_timestamp timestam memcpy(buff[0], (void*)ð->eh, MAC_HEADER_SIZE_BYTES); - bytes_sent = send(eth->sockfd[Mod_id], + bytes_sent = send(eth->sockfd, buff[0], packet_size, 0); @@ -238,7 +239,6 @@ int trx_eth_read_raw(openair0_device *device, openair0_timestamp *timestamp, voi int bytes_received=0; int i=0; eth_state_t *eth = (eth_state_t*)device->priv; - int Mod_id = device->Mod_id; int rcvfrom_flag =0; eth->rx_nsamps=nsamps; @@ -256,7 +256,7 @@ int trx_eth_read_raw(openair0_device *device, openair0_timestamp *timestamp, voi bytes_received=0; while(bytes_received < RAW_PACKET_SIZE_BYTES(nsamps)) { - bytes_received +=recv(eth->sockfd[Mod_id], + bytes_received +=recv(eth->sockfd, buff2, RAW_PACKET_SIZE_BYTES(nsamps), rcvfrom_flag); @@ -300,13 +300,15 @@ int trx_eth_read_raw_IF4p5(openair0_device *device, openair0_timestamp *timestam int nblocks = nsamps; int bytes_received=0; eth_state_t *eth = (eth_state_t*)device->priv; - int Mod_id = device->Mod_id; ssize_t packet_size = MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t; IF4p5_header_t *test_header = (IF4p5_header_t*)(buff[0] + MAC_HEADER_SIZE_BYTES); +#ifdef DEBUG + printf("Reading from device %p, eth %p, sockfd %d\n",device,eth,eth->sockfd); +#endif - bytes_received = recv(eth->sockfd[Mod_id], + bytes_received = recv(eth->sockfd, buff[0], packet_size, MSG_PEEK); @@ -315,7 +317,12 @@ int trx_eth_read_raw_IF4p5(openair0_device *device, openair0_timestamp *timestam perror("ETHERNET IF4p5 READ (header): "); exit(-1); } - +#ifdef DEBUG + for (int i=0;i<packet_size;i++) + printf("%2x.",((uint8_t*)buff[0])[i]); + printf("\n"); +#endif + *timestamp = test_header->sub_type; if (test_header->sub_type == IF4p5_PDLFFT) { @@ -328,7 +335,7 @@ int trx_eth_read_raw_IF4p5(openair0_device *device, openair0_timestamp *timestam while(bytes_received < packet_size) { - bytes_received = recv(eth->sockfd[Mod_id], + bytes_received = recv(eth->sockfd, buff[0], packet_size, 0); @@ -347,10 +354,81 @@ int trx_eth_read_raw_IF4p5(openair0_device *device, openair0_timestamp *timestam } +int trx_eth_read_raw_IF5_mobipass(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc) { + // Read nblocks info from packet itself + + int nblocks = nsamps; + int bytes_received=0; + eth_state_t *eth = (eth_state_t*)device->priv; + + ssize_t packet_size = 28; //MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t ; +// ssize_t packet_size = MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + 640*sizeof(int16_t); + + bytes_received = recv(eth->sockfd, + buff[0], + packet_size, + MSG_PEEK); + + if (bytes_received ==-1) { + eth->num_rx_errors++; + perror("[MOBIPASS]ETHERNET IF5 READ (header): "); + exit(-1); + } + + IF5_mobipass_header_t *test_header = (IF5_mobipass_header_t*)((uint8_t *)buff[0] + MAC_HEADER_SIZE_BYTES); + *timestamp = test_header->time_stamp; + packet_size = MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + 640*sizeof(int16_t); + + while(bytes_received < packet_size) { + bytes_received = recv(eth->sockfd, + buff[0], + packet_size, + 0); + if (bytes_received ==-1) { + eth->num_rx_errors++; + perror("[MOBIPASS] ETHERNET IF5 READ (payload): "); + exit(-1); + } else { + eth->rx_actual_nsamps = bytes_received>>1; + eth->rx_count++; + } + } + + eth->rx_nsamps = nsamps; + return(bytes_received); + + +/* + if (bytes_received > 0) { + while(bytes_received < packet_size) { + bytes_received = recv(eth->sockfd, + buff[0], + packet_size, + 0); + if (bytes_received ==-1) { + eth->num_rx_errors++; + perror("ETHERNET IF5_MOBIPASS READ (payload): "); + exit(-1); + } else { + eth->rx_actual_nsamps = bytes_received>>1; + eth->rx_count++; + } + } + if (bytes_received == packet_size){ + IF5_mobipass_header_t *test_header = (IF5_mobipass_header_t*)((uint8_t *)buff[0] + MAC_HEADER_SIZE_BYTES); + *timestamp = test_header->time_stamp; + } + + eth->rx_nsamps = nsamps; + } + + return(bytes_received); +*/ +} + int eth_set_dev_conf_raw(openair0_device *device) { - int Mod_id = device->Mod_id; eth_state_t *eth = (eth_state_t*)device->priv; void *msg; ssize_t msg_len; @@ -366,7 +444,7 @@ int eth_set_dev_conf_raw(openair0_device *device) { memcpy(msg,(void*)ð->eh,MAC_HEADER_SIZE_BYTES); memcpy((msg+MAC_HEADER_SIZE_BYTES),(void*)device->openair0_cfg,sizeof(openair0_config_t)); - if (send(eth->sockfd[Mod_id], + if (send(eth->sockfd, msg, msg_len, 0)==-1) { @@ -382,7 +460,6 @@ int eth_set_dev_conf_raw(openair0_device *device) { int eth_set_dev_conf_raw_IF4p5(openair0_device *device) { // use for cc_id info - int Mod_id = device->Mod_id; eth_state_t *eth = (eth_state_t*)device->priv; void *msg; ssize_t msg_len; @@ -398,7 +475,7 @@ int eth_set_dev_conf_raw_IF4p5(openair0_device *device) { memcpy(msg,(void*)ð->eh,MAC_HEADER_SIZE_BYTES); memcpy((msg+MAC_HEADER_SIZE_BYTES),(void*)device->openair0_cfg,sizeof(openair0_config_t)); - if (send(eth->sockfd[Mod_id], + if (send(eth->sockfd, msg, msg_len, 0)==-1) { @@ -413,7 +490,6 @@ int eth_set_dev_conf_raw_IF4p5(openair0_device *device) { int eth_get_dev_conf_raw(openair0_device *device) { eth_state_t *eth = (eth_state_t*)device->priv; - int Mod_id = device->Mod_id; void *msg; ssize_t msg_len; @@ -421,7 +497,7 @@ int eth_get_dev_conf_raw(openair0_device *device) { msg_len = MAC_HEADER_SIZE_BYTES + sizeof(openair0_config_t); /* RRH receives from BBU openair0_config_t */ - if (recv(eth->sockfd[Mod_id], + if (recv(eth->sockfd, msg, msg_len, 0)==-1) { @@ -433,7 +509,7 @@ int eth_get_dev_conf_raw(openair0_device *device) { memcpy(eth->eh.ether_dhost,(msg+ETH_ALEN),ETH_ALEN); //memcpy((void*)&device->openair0_cfg,(msg + MAC_HEADER_SIZE_BYTES), sizeof(openair0_config_t)); device->openair0_cfg=(openair0_config_t *)(msg + MAC_HEADER_SIZE_BYTES); - printf("[%s] binding mod_%d to hardware address %x:%x:%x:%x:%x:%x hardware address %x:%x:%x:%x:%x:%x\n",((device->host_type == BBU_HOST) ? "BBU": "RRH"),Mod_id,eth->eh.ether_shost[0],eth->eh.ether_shost[1],eth->eh.ether_shost[2],eth->eh.ether_shost[3],eth->eh.ether_shost[4],eth->eh.ether_shost[5],eth->eh.ether_dhost[0],eth->eh.ether_dhost[1],eth->eh.ether_dhost[2],eth->eh.ether_dhost[3],eth->eh.ether_dhost[4],eth->eh.ether_dhost[5]); + printf("[%s] binding mod to hardware address %x:%x:%x:%x:%x:%x hardware address %x:%x:%x:%x:%x:%x\n",((device->host_type == BBU_HOST) ? "BBU": "RRH"),eth->eh.ether_shost[0],eth->eh.ether_shost[1],eth->eh.ether_shost[2],eth->eh.ether_shost[3],eth->eh.ether_shost[4],eth->eh.ether_shost[5],eth->eh.ether_dhost[0],eth->eh.ether_dhost[1],eth->eh.ether_dhost[2],eth->eh.ether_dhost[3],eth->eh.ether_dhost[4],eth->eh.ether_dhost[5]); return 0; } @@ -443,7 +519,6 @@ int eth_get_dev_conf_raw_IF4p5(openair0_device *device) { // use for cc_id info eth_state_t *eth = (eth_state_t*)device->priv; - int Mod_id = device->Mod_id; void *msg; ssize_t msg_len; @@ -451,7 +526,7 @@ int eth_get_dev_conf_raw_IF4p5(openair0_device *device) { msg_len = MAC_HEADER_SIZE_BYTES + sizeof(openair0_config_t); /* RRH receives from BBU openair0_config_t */ - if (recv(eth->sockfd[Mod_id], + if (recv(eth->sockfd, msg, msg_len, 0)==-1) { @@ -463,7 +538,7 @@ int eth_get_dev_conf_raw_IF4p5(openair0_device *device) { memcpy(eth->eh.ether_dhost,(msg+ETH_ALEN),ETH_ALEN); //memcpy((void*)&device->openair0_cfg,(msg + MAC_HEADER_SIZE_BYTES), sizeof(openair0_config_t)); //device->openair0_cfg=(openair0_config_t *)(msg + MAC_HEADER_SIZE_BYTES); - printf("[%s] binding mod_%d to hardware address %x:%x:%x:%x:%x:%x hardware address %x:%x:%x:%x:%x:%x\n",((device->host_type == BBU_HOST) ? "BBU": "RRH"),Mod_id,eth->eh.ether_shost[0],eth->eh.ether_shost[1],eth->eh.ether_shost[2],eth->eh.ether_shost[3],eth->eh.ether_shost[4],eth->eh.ether_shost[5],eth->eh.ether_dhost[0],eth->eh.ether_dhost[1],eth->eh.ether_dhost[2],eth->eh.ether_dhost[3],eth->eh.ether_dhost[4],eth->eh.ether_dhost[5]); + printf("[%s] binding mod to hardware address %x:%x:%x:%x:%x:%x hardware address %x:%x:%x:%x:%x:%x\n",((device->host_type == BBU_HOST) ? "BBU": "RRH"),eth->eh.ether_shost[0],eth->eh.ether_shost[1],eth->eh.ether_shost[2],eth->eh.ether_shost[3],eth->eh.ether_shost[4],eth->eh.ether_shost[5],eth->eh.ether_dhost[0],eth->eh.ether_dhost[1],eth->eh.ether_dhost[2],eth->eh.ether_dhost[3],eth->eh.ether_dhost[4],eth->eh.ether_dhost[5]); return 0; } diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c index 6ee1b879d1e90783aeea54b21584dd2a849ead2a..898382cf6a480ebea27429f4c6a1f5592c632140 100644 --- a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c +++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c @@ -47,9 +47,9 @@ #include "ethernet_lib.h" #define DEBUG 0 -struct sockaddr_in dest_addr[MAX_INST]; -struct sockaddr_in local_addr[MAX_INST]; -int addr_len[MAX_INST]; +//struct sockaddr_in dest_addr[MAX_INST]; +//struct sockaddr_in local_addr[MAX_INST]; +//int addr_len[MAX_INST]; uint16_t pck_seq_num = 1; @@ -58,9 +58,7 @@ uint16_t pck_seq_num_prev=0; int eth_socket_init_udp(openair0_device *device) { - int i = 0; eth_state_t *eth = (eth_state_t*)device->priv; - int Mod_id = device->Mod_id; char str_local[INET_ADDRSTRLEN]; char str_remote[INET_ADDRSTRLEN]; const char *local_ip, *remote_ip; @@ -89,43 +87,42 @@ int eth_socket_init_udp(openair0_device *device) { sock_type=SOCK_DGRAM; sock_proto=IPPROTO_UDP; - if ((eth->sockfd[Mod_id] = socket(sock_dom, sock_type, sock_proto)) == -1) { + if ((eth->sockfd = socket(sock_dom, sock_type, sock_proto)) == -1) { perror("ETHERNET: Error opening socket"); exit(0); } /* initialize addresses */ - for (i=0; i< MAX_INST; i++) { - bzero((void *)&(dest_addr[i]), sizeof(dest_addr[i])); - bzero((void *)&(local_addr[i]), sizeof(local_addr[i])); - } + bzero((void *)&(eth->dest_addr), sizeof(eth->dest_addr)); + bzero((void *)&(eth->local_addr), sizeof(eth->local_addr)); + - addr_len[Mod_id] = sizeof(struct sockaddr_in); + eth->addr_len = sizeof(struct sockaddr_in); - dest_addr[Mod_id].sin_family = AF_INET; - inet_pton(AF_INET,remote_ip,&(dest_addr[Mod_id].sin_addr.s_addr)); - dest_addr[Mod_id].sin_port=htons(remote_port); - inet_ntop(AF_INET, &(dest_addr[Mod_id].sin_addr), str_remote, INET_ADDRSTRLEN); + eth->dest_addr.sin_family = AF_INET; + inet_pton(AF_INET,remote_ip,&(eth->dest_addr.sin_addr.s_addr)); + eth->dest_addr.sin_port=htons(remote_port); + inet_ntop(AF_INET, &(eth->dest_addr.sin_addr), str_remote, INET_ADDRSTRLEN); - local_addr[Mod_id].sin_family = AF_INET; - inet_pton(AF_INET,local_ip,&(local_addr[Mod_id].sin_addr.s_addr)); - local_addr[Mod_id].sin_port=htons(local_port); - inet_ntop(AF_INET, &(local_addr[Mod_id].sin_addr), str_local, INET_ADDRSTRLEN); + eth->local_addr.sin_family = AF_INET; + inet_pton(AF_INET,local_ip,&(eth->local_addr.sin_addr.s_addr)); + eth->local_addr.sin_port=htons(local_port); + inet_ntop(AF_INET, &(eth->local_addr.sin_addr), str_local, INET_ADDRSTRLEN); /* set reuse address flag */ - if (setsockopt(eth->sockfd[Mod_id], SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int))) { + if (setsockopt(eth->sockfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int))) { perror("ETHERNET: Cannot set SO_REUSEADDR option on socket"); exit(0); } /* want to receive -> so bind */ - if (bind(eth->sockfd[Mod_id],(struct sockaddr *)&local_addr[Mod_id],addr_len[Mod_id])<0) { + if (bind(eth->sockfd,(struct sockaddr *)ð->local_addr,eth->addr_len)<0) { perror("ETHERNET: Cannot bind to socket"); exit(0); } else { - printf("[%s] binding mod_%d to %s:%d\n","RRH",Mod_id,str_local,ntohs(local_addr[Mod_id].sin_port)); + printf("[%s] binding to %s:%d\n","RRH",str_local,ntohs(eth->local_addr.sin_port)); } return 0; @@ -135,54 +132,62 @@ int trx_eth_read_udp_IF4p5(openair0_device *device, openair0_timestamp *timestam // Read nblocks info from packet itself int nblocks = nsamps; - int bytes_received=0; + int bytes_received=-1; eth_state_t *eth = (eth_state_t*)device->priv; - int Mod_id = device->Mod_id; - + ssize_t packet_size = sizeof_IF4p5_header_t; IF4p5_header_t *test_header = (IF4p5_header_t*)(buff[0]); - - - bytes_received = recvfrom(eth->sockfd[Mod_id], - buff[0], - packet_size, - 0, - (struct sockaddr *)&dest_addr[Mod_id], - (socklen_t *)&addr_len[Mod_id]); - - if (bytes_received ==-1) { - eth->num_rx_errors++; - perror("ETHERNET IF4p5 READ (header): "); - exit(-1); - } - - *timestamp = test_header->sub_type; - if (test_header->sub_type == IF4p5_PDLFFT) { - packet_size = UDP_IF4p5_PDLFFT_SIZE_BYTES(nblocks); - } else if (test_header->sub_type == IF4p5_PULFFT) { - packet_size = UDP_IF4p5_PULFFT_SIZE_BYTES(nblocks); - } else { - packet_size = UDP_IF4p5_PRACH_SIZE_BYTES; - } - - - while(bytes_received < packet_size) { - bytes_received = recvfrom(eth->sockfd[Mod_id], - buff[0], - packet_size, - 0, - (struct sockaddr *)&dest_addr[Mod_id], - (socklen_t *)&addr_len[Mod_id]); + int block_cnt=0; + int again_cnt=0; + packet_size = max(UDP_IF4p5_PRACH_SIZE_BYTES, max(UDP_IF4p5_PULFFT_SIZE_BYTES(nblocks), UDP_IF4p5_PDLFFT_SIZE_BYTES(nblocks))); + + while(bytes_received == -1) { + again: + bytes_received = recvfrom(eth->sockfd, + buff[0], + packet_size, + 0, + (struct sockaddr *)ð->dest_addr, + (socklen_t *)ð->addr_len); if (bytes_received ==-1) { eth->num_rx_errors++; - perror("ETHERNET IF4p5 READ (payload): "); - exit(-1); + if (errno == EAGAIN) { + /* + again_cnt++; + usleep(10); + if (again_cnt == 1000) { + perror("ETHERNET IF4p5 READ (EAGAIN): "); + exit(-1); + } else { + printf("AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN \n"); + goto again; + } + */ + printf("Lost IF4p5 connection with %s\n", inet_ntoa(eth->dest_addr.sin_addr)); + exit(-1); + } else if (errno == EWOULDBLOCK) { + block_cnt++; + usleep(10); + if (block_cnt == 1000) { + perror("ETHERNET IF4p5 READ (EWOULDBLOCK): "); + exit(-1); + } else { + printf("BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK \n"); + goto again; + } + } else { + perror("ETHERNET IF4p5 READ"); + printf("(%s):\n", strerror(errno)); + exit(-1); + } } else { - eth->rx_actual_nsamps = bytes_received>>1; + *timestamp = test_header->sub_type; + eth->rx_actual_nsamps = bytes_received>>1; eth->rx_count++; } } + //printf("size of third %d subtype %d frame %d subframe %d symbol %d \n", bytes_received, test_header->sub_type, ((test_header->frame_status)>>6)&0xffff, ((test_header->frame_status)>>22)&0x000f, ((test_header->frame_status)>>26)&0x000f) ; eth->rx_nsamps = nsamps; return(bytes_received); @@ -194,7 +199,6 @@ int trx_eth_write_udp_IF4p5(openair0_device *device, openair0_timestamp timestam int bytes_sent = 0; eth_state_t *eth = (eth_state_t*)device->priv; - int Mod_id = device->Mod_id; ssize_t packet_size; @@ -202,6 +206,8 @@ int trx_eth_write_udp_IF4p5(openair0_device *device, openair0_timestamp timestam packet_size = UDP_IF4p5_PDLFFT_SIZE_BYTES(nblocks); } else if (flags == IF4p5_PULFFT) { packet_size = UDP_IF4p5_PULFFT_SIZE_BYTES(nblocks); + } else if (flags == IF4p5_PULTICK) { + packet_size = UDP_IF4p5_PULTICK_SIZE_BYTES; } else if (flags == IF4p5_PRACH) { packet_size = UDP_IF4p5_PRACH_SIZE_BYTES; } else { @@ -211,12 +217,12 @@ int trx_eth_write_udp_IF4p5(openair0_device *device, openair0_timestamp timestam eth->tx_nsamps = nblocks; - bytes_sent = sendto(eth->sockfd[Mod_id], + bytes_sent = sendto(eth->sockfd, buff[0], packet_size, 0, - (struct sockaddr*)&dest_addr[Mod_id], - addr_len[Mod_id]); + (struct sockaddr*)ð->dest_addr, + eth->addr_len); if (bytes_sent == -1) { eth->num_tx_errors++; @@ -234,7 +240,6 @@ int trx_eth_write_udp(openair0_device *device, openair0_timestamp timestamp, voi int bytes_sent=0; eth_state_t *eth = (eth_state_t*)device->priv; - int Mod_id = device->Mod_id; int sendto_flag =0; int i=0; //sendto_flag|=flags; @@ -268,12 +273,12 @@ int trx_eth_write_udp(openair0_device *device, openair0_timestamp timestamp, voi bytes_sent); #endif /* Send packet */ - bytes_sent += sendto(eth->sockfd[Mod_id], + bytes_sent += sendto(eth->sockfd, buff2, UDP_PACKET_SIZE_BYTES(nsamps), sendto_flag, - (struct sockaddr*)&dest_addr[Mod_id], - addr_len[Mod_id]); + (struct sockaddr*)ð->dest_addr, + eth->addr_len); if ( bytes_sent == -1) { eth->num_tx_errors++; @@ -291,7 +296,7 @@ int trx_eth_write_udp(openair0_device *device, openair0_timestamp timestamp, voi eth->tx_actual_nsamps=bytes_sent>>2; eth->tx_count++; pck_seq_num++; - if ( pck_seq_num > MAX_PACKET_SEQ_NUM(nsamps,76800) ) pck_seq_num = 1; + if ( pck_seq_num > MAX_PACKET_SEQ_NUM(nsamps,device->openair0_cfg->samples_per_frame) ) pck_seq_num = 1; } } /* tx buffer values restored */ @@ -309,7 +314,6 @@ int trx_eth_read_udp(openair0_device *device, openair0_timestamp *timestamp, voi int bytes_received=0; eth_state_t *eth = (eth_state_t*)device->priv; // openair0_timestamp prev_timestamp = -1; - int Mod_id = device->Mod_id; int rcvfrom_flag =0; int block_cnt=0; int again_cnt=0; @@ -338,12 +342,12 @@ int trx_eth_read_udp(openair0_device *device, openair0_timestamp *timestamp, voi UDP_PACKET_SIZE_BYTES(nsamps) - bytes_received, bytes_received); #endif - bytes_received +=recvfrom(eth->sockfd[Mod_id], + bytes_received +=recvfrom(eth->sockfd, buff2, UDP_PACKET_SIZE_BYTES(nsamps), rcvfrom_flag, - (struct sockaddr *)&dest_addr[Mod_id], - (socklen_t *)&addr_len[Mod_id]); + (struct sockaddr *)ð->dest_addr, + (socklen_t *)ð->addr_len); if (bytes_received ==-1) { eth->num_rx_errors++; @@ -389,7 +393,7 @@ int trx_eth_read_udp(openair0_device *device, openair0_timestamp *timestamp, voi /* get the packet sequence number from packet's header */ pck_seq_num_cur = *(uint16_t *)buff2; //printf("cur=%d prev=%d buff=%d\n",pck_seq_num_cur,pck_seq_num_prev,*(uint16_t *)(buff2)); - if ( ( pck_seq_num_cur != (pck_seq_num_prev + 1) ) && !((pck_seq_num_prev==75) && (pck_seq_num_cur==1 ))){ + if ( ( pck_seq_num_cur != (pck_seq_num_prev + 1) ) && !((pck_seq_num_prev==MAX_PACKET_SEQ_NUM(nsamps,device->openair0_cfg->samples_per_frame)) && (pck_seq_num_cur==1 )) && !((pck_seq_num_prev==1) && (pck_seq_num_cur==1))) { printf("out of order packet received1! %d|%d|%d\n",pck_seq_num_cur,pck_seq_num_prev,(int)*timestamp); } VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RX_SEQ_NUM,pck_seq_num_cur); @@ -412,7 +416,6 @@ int trx_eth_read_udp(openair0_device *device, openair0_timestamp *timestamp, voi int eth_set_dev_conf_udp(openair0_device *device) { - int Mod_id = device->Mod_id; eth_state_t *eth = (eth_state_t*)device->priv; void *msg; ssize_t msg_len; @@ -425,9 +428,10 @@ int eth_set_dev_conf_udp(openair0_device *device) { msg=malloc(sizeof(openair0_config_t)); msg_len=sizeof(openair0_config_t); memcpy(msg,(void*)device->openair0_cfg,msg_len); - - if (sendto(eth->sockfd[Mod_id],msg,msg_len,0,(struct sockaddr *)&dest_addr[Mod_id],addr_len[Mod_id])==-1) { - perror("ETHERNET: "); + + if (sendto(eth->sockfd,msg,msg_len,0,(struct sockaddr *)ð->dest_addr,eth->addr_len)==-1) { + perror("ETHERNET: sendto conf_udp"); + printf("addr_len : %d, msg_len %d\n",eth->addr_len,msg_len); exit(0); } @@ -437,7 +441,6 @@ int eth_set_dev_conf_udp(openair0_device *device) { int eth_get_dev_conf_udp(openair0_device *device) { eth_state_t *eth = (eth_state_t*)device->priv; - int Mod_id = device->Mod_id; char str1[INET_ADDRSTRLEN],str[INET_ADDRSTRLEN]; void *msg; ssize_t msg_len; @@ -445,31 +448,31 @@ int eth_get_dev_conf_udp(openair0_device *device) { msg=malloc(sizeof(openair0_config_t)); msg_len=sizeof(openair0_config_t); - inet_ntop(AF_INET, &(local_addr[Mod_id].sin_addr), str, INET_ADDRSTRLEN); - inet_ntop(AF_INET, &(dest_addr[Mod_id].sin_addr), str1, INET_ADDRSTRLEN); + inet_ntop(AF_INET, &(eth->local_addr.sin_addr), str, INET_ADDRSTRLEN); + inet_ntop(AF_INET, &(eth->dest_addr.sin_addr), str1, INET_ADDRSTRLEN); /* RRH receives from BBU openair0_config_t */ - if (recvfrom(eth->sockfd[Mod_id], + if (recvfrom(eth->sockfd, msg, msg_len, 0, - (struct sockaddr *)&dest_addr[Mod_id], - (socklen_t *)&addr_len[Mod_id])==-1) { - perror("ETHERNET: "); + (struct sockaddr *)ð->dest_addr, + (socklen_t *)ð->addr_len)==-1) { + perror("ETHERNET: recv_from conf_udp"); exit(0); } device->openair0_cfg=(openair0_config_t *)msg; /* get remote ip address and port */ - /* inet_ntop(AF_INET, &(dest_addr[Mod_id].sin_addr), str1, INET_ADDRSTRLEN); */ - /* device->openair0_cfg->remote_port =ntohs(dest_addr[Mod_id].sin_port); */ + /* inet_ntop(AF_INET, &(eth->dest_addr.sin_addr), str1, INET_ADDRSTRLEN); */ + /* device->openair0_cfg->remote_port =ntohs(eth->dest_addr.sin_port); */ /* device->openair0_cfg->remote_addr =str1; */ /* /\* restore local ip address and port *\/ */ - /* inet_ntop(AF_INET, &(local_addr[Mod_id].sin_addr), str, INET_ADDRSTRLEN); */ - /* device->openair0_cfg->my_port =ntohs(local_addr[Mod_id].sin_port); */ + /* inet_ntop(AF_INET, &(eth->local_addr.sin_addr), str, INET_ADDRSTRLEN); */ + /* device->openair0_cfg->my_port =ntohs(eth->local_addr.sin_port); */ /* device->openair0_cfg->my_addr =str; */ - /* printf("[RRH] mod_%d socket %d connected to BBU %s:%d %s:%d\n", Mod_id, eth->sockfd[Mod_id],str1, device->openair0_cfg->remote_port, str, device->openair0_cfg->my_port); */ + /* printf("[RRH] mod_%d socket %d connected to BBU %s:%d %s:%d\n", Mod_id, eth->sockfd,str1, device->openair0_cfg->remote_port, str, device->openair0_cfg->my_port); */ return 0; } diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c index 1880719c508ac95e63576f1ad34868d93a69116f..6f93ba4853d3fa209246871d57abf65f62f3493a 100644 --- a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c +++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c @@ -45,117 +45,114 @@ #include "common_lib.h" #include "ethernet_lib.h" -int num_devices_eth = 0; -struct sockaddr_in dest_addr[MAX_INST]; -int dest_addr_len[MAX_INST]; - - int trx_eth_start(openair0_device *device) { - eth_state_t *eth = (eth_state_t*)device->priv; - - /* initialize socket */ - if (eth->flags == ETH_RAW_MODE) { - printf("Setting ETHERNET to ETH_RAW_IF5_MODE\n"); - if (eth_socket_init_raw(device)!=0) return -1; - /* RRH gets openair0 device configuration - BBU sets openair0 device configuration*/ - if (device->host_type == BBU_HOST) { - if(eth_set_dev_conf_raw(device)!=0) return -1; - } else { - if(eth_get_dev_conf_raw(device)!=0) return -1; - } - /* adjust MTU wrt number of samples per packet */ - if(ethernet_tune (device,MTU_SIZE,RAW_PACKET_SIZE_BYTES(device->openair0_cfg->samples_per_packet))!=0) return -1; - if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1; - } else if (eth->flags == ETH_RAW_IF4p5_MODE) { - - printf("Setting ETHERNET to ETH_RAW_IF4p5_MODE\n"); - if (eth_socket_init_raw(device)!=0) return -1; - /* RRH gets openair0 device configuration - BBU sets openair0 device configuration*/ - if (device->host_type == BBU_HOST) { - if(eth_set_dev_conf_raw_IF4p5(device)!=0) return -1; - } else { - if(eth_get_dev_conf_raw_IF4p5(device)!=0) return -1; - } - /* adjust MTU wrt number of samples per packet */ - if(ethernet_tune (device,MTU_SIZE,RAW_IF4p5_PRACH_SIZE_BYTES)!=0) return -1; - - if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1; - } else if (eth->flags == ETH_UDP_IF4p5_MODE) { - printf("Setting ETHERNET to UDP_IF4p5_MODE\n"); - if (eth_socket_init_udp(device)!=0) return -1; - if (device->host_type == BBU_HOST) { - if(eth_set_dev_conf_udp(device)!=0) return -1; - } else { - if(eth_get_dev_conf_udp(device)!=0) return -1; - } - } else if (eth->flags == ETH_RAW_IF5_MOBIPASS) { - printf("Setting ETHERNET to RAW_IF5_MODE\n"); - if (eth_socket_init_raw(device)!=0) return -1; + eth_state_t *eth = (eth_state_t*)device->priv; + + /* initialize socket */ + if (eth->flags == ETH_RAW_MODE) { + printf("Setting ETHERNET to ETH_RAW_IF5_MODE\n"); + if (eth_socket_init_raw(device)!=0) return -1; + /* RRH gets openair0 device configuration - BBU sets openair0 device configuration*/ + if (device->host_type == BBU_HOST) { + if(eth_set_dev_conf_raw(device)!=0) return -1; } else { - if (eth_socket_init_udp(device)!=0) return -1; - /* RRH gets openair0 device configuration - BBU sets openair0 device configuration*/ - if (device->host_type == BBU_HOST) { - if(eth_set_dev_conf_udp(device)!=0) return -1; - } else { - if(eth_get_dev_conf_udp(device)!=0) return -1; - } + if(eth_get_dev_conf_raw(device)!=0) return -1; } - /* apply additional configuration */ - if(ethernet_tune (device, SND_BUF_SIZE,2000000000)!=0) return -1; - if(ethernet_tune (device, RCV_BUF_SIZE,2000000000)!=0) return -1; - - return 0; + /* adjust MTU wrt number of samples per packet */ + if(ethernet_tune (device,MTU_SIZE,RAW_PACKET_SIZE_BYTES(device->openair0_cfg->samples_per_packet))!=0) return -1; + if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1; + } else if (eth->flags == ETH_RAW_IF4p5_MODE) { + + printf("Setting ETHERNET to ETH_RAW_IF4p5_MODE\n"); + if (eth_socket_init_raw(device)!=0) return -1; + /* RRH gets openair0 device configuration - BBU sets openair0 device configuration*/ + if (device->host_type == BBU_HOST) { + if(eth_set_dev_conf_raw_IF4p5(device)!=0) return -1; + } else { + if(eth_get_dev_conf_raw_IF4p5(device)!=0) return -1; + } + /* adjust MTU wrt number of samples per packet */ + if(ethernet_tune (device,MTU_SIZE,RAW_IF4p5_PRACH_SIZE_BYTES)!=0) return -1; + + if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1; + } else if (eth->flags == ETH_UDP_IF4p5_MODE) { + printf("Setting ETHERNET to UDP_IF4p5_MODE\n"); + if (eth_socket_init_udp(device)!=0) return -1; + if (device->host_type == BBU_HOST) { + if(eth_set_dev_conf_udp(device)!=0) return -1; + } else { + if(eth_get_dev_conf_udp(device)!=0) return -1; + } + } else if (eth->flags == ETH_RAW_IF5_MOBIPASS) { + printf("Setting ETHERNET to RAW_IF5_MODE\n"); + if (eth_socket_init_raw(device)!=0) return -1; + if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1; + + } else { + printf("Setting ETHERNET to UDP_IF5_MODE\n"); + if (eth_socket_init_udp(device)!=0) return -1; + /* RRH gets openair0 device configuration - BBU sets openair0 device configuration*/ + if (device->host_type == BBU_HOST) { + if(eth_set_dev_conf_udp(device)!=0) return -1; + } else { + if(eth_get_dev_conf_udp(device)!=0) return -1; + } + } + /* apply additional configuration */ + if(ethernet_tune (device, SND_BUF_SIZE,2000000000)!=0) return -1; + if(ethernet_tune (device, RCV_BUF_SIZE,2000000000)!=0) return -1; + + return 0; } void trx_eth_end(openair0_device *device) { - eth_state_t *eth = (eth_state_t*)device->priv; - int Mod_id = device->Mod_id; - /* destroys socket only for the processes that call the eth_end fuction-- shutdown() for beaking the pipe */ - if ( close(eth->sockfd[Mod_id]) <0 ) { - perror("ETHERNET: Failed to close socket"); - exit(0); - } else { - printf("[%s] socket for mod_id %d has been successfully closed.\n",(device->host_type == BBU_HOST)? "BBU":"RRH",Mod_id); - } - + eth_state_t *eth = (eth_state_t*)device->priv; + /* destroys socket only for the processes that call the eth_end fuction-- shutdown() for beaking the pipe */ + if ( close(eth->sockfd) <0 ) { + perror("ETHERNET: Failed to close socket"); + exit(0); + } else { + printf("[%s] socket has been successfully closed.\n",(device->host_type == BBU_HOST)? "BBU":"RRH"); + } } int trx_eth_request(openair0_device *device, void *msg, ssize_t msg_len) { - int Mod_id = device->Mod_id; - eth_state_t *eth = (eth_state_t*)device->priv; - - /* BBU sends a message to RRH */ - if (sendto(eth->sockfd[Mod_id],msg,msg_len,0,(struct sockaddr *)&dest_addr[Mod_id],dest_addr_len[Mod_id])==-1) { - perror("ETHERNET: "); - exit(0); - } - - return 0; + eth_state_t *eth = (eth_state_t*)device->priv; + + /* BBU sends a message to RRH */ + + if (sendto(eth->sockfd,msg,msg_len,0,(struct sockaddr *)ð->dest_addr,eth->addr_len)==-1) { + perror("ETHERNET: "); + exit(0); + } + return 0; } int trx_eth_reply(openair0_device *device, void *msg, ssize_t msg_len) { - eth_state_t *eth = (eth_state_t*)device->priv; - int Mod_id = device->Mod_id; - - /* RRH receives from BBU a message */ - if (recvfrom(eth->sockfd[Mod_id], - msg, - msg_len, - 0, - (struct sockaddr *)&dest_addr[Mod_id], - (socklen_t *)&dest_addr_len[Mod_id])==-1) { - perror("ETHERNET: "); - exit(0); - } + eth_state_t *eth = (eth_state_t*)device->priv; + + /* RRH receives from BBU a message */ + + if (recvfrom(eth->sockfd, + msg, + msg_len, + 0, + (struct sockaddr *)ð->dest_addr, + (socklen_t *)ð->addr_len)==-1) { + perror("ETHERNET: recv_from in trx_eth_reply "); + exit(0); + } + + - return 0; + return 0; } @@ -182,236 +179,233 @@ int trx_eth_reset_stats(openair0_device* device) { int ethernet_tune(openair0_device *device, unsigned int option, int value) { - - eth_state_t *eth = (eth_state_t*)device->priv; - int Mod_id=device->Mod_id; - struct timeval timeout; - struct ifreq ifr; - char system_cmd[256]; - // char* if_name=DEFAULT_IF; - // struct in_addr ia; - // struct if_nameindex *ids; - int ret=0; - // int i=0; - - /****************** socket level options ************************/ - switch(option) { - case SND_BUF_SIZE: /* transmit socket buffer size */ - if (setsockopt(eth->sockfd[Mod_id], - SOL_SOCKET, - SO_SNDBUF, - &value,sizeof(value))) { - perror("[ETHERNET] setsockopt()"); - } else { - printf("send buffer size= %d bytes\n",value); - } - break; - - case RCV_BUF_SIZE: /* receive socket buffer size */ - if (setsockopt(eth->sockfd[Mod_id], - SOL_SOCKET, - SO_RCVBUF, - &value,sizeof(value))) { - perror("[ETHERNET] setsockopt()"); - } else { - printf("receive bufffer size= %d bytes\n",value); - } - break; - - case RCV_TIMEOUT: - timeout.tv_sec = value/1000000; - timeout.tv_usec = value%1000000;//less than rt_period? - if (setsockopt(eth->sockfd[Mod_id], - SOL_SOCKET, - SO_RCVTIMEO, - (char *)&timeout,sizeof(timeout))) { - perror("[ETHERNET] setsockopt()"); - } else { - printf( "receive timeout= %u usec\n",(unsigned int)timeout.tv_usec); - } - break; - - case SND_TIMEOUT: - timeout.tv_sec = value/1000000000; - timeout.tv_usec = value%1000000000;//less than rt_period? - if (setsockopt(eth->sockfd[Mod_id], - SOL_SOCKET, - SO_SNDTIMEO, - (char *)&timeout,sizeof(timeout))) { - perror("[ETHERNET] setsockopt()"); - } else { - printf( "send timeout= %d,%d sec\n",(int)timeout.tv_sec,(int)timeout.tv_usec); - } - break; - - + + eth_state_t *eth = (eth_state_t*)device->priv; + struct timeval timeout; + struct ifreq ifr; + char system_cmd[256]; + // char* if_name=DEFAULT_IF; + // struct in_addr ia; + // struct if_nameindex *ids; + int ret=0; + // int i=0; + + /****************** socket level options ************************/ + switch(option) { + case SND_BUF_SIZE: /* transmit socket buffer size */ + if (setsockopt(eth->sockfd, + SOL_SOCKET, + SO_SNDBUF, + &value,sizeof(value))) { + perror("[ETHERNET] setsockopt()"); + } else { + printf("send buffer size= %d bytes\n",value); + } + break; + + case RCV_BUF_SIZE: /* receive socket buffer size */ + if (setsockopt(eth->sockfd, + SOL_SOCKET, + SO_RCVBUF, + &value,sizeof(value))) { + perror("[ETHERNET] setsockopt()"); + } else { + printf("receive bufffer size= %d bytes\n",value); + } + break; + + case RCV_TIMEOUT: + timeout.tv_sec = value/1000000; + timeout.tv_usec = value%1000000;//less than rt_period? + if (setsockopt(eth->sockfd, + SOL_SOCKET, + SO_RCVTIMEO, + (char *)&timeout,sizeof(timeout))) { + perror("[ETHERNET] setsockopt()"); + } else { + printf( "receive timeout= %u usec\n",(unsigned int)timeout.tv_usec); + } + break; + + case SND_TIMEOUT: + timeout.tv_sec = value/1000000000; + timeout.tv_usec = value%1000000000;//less than rt_period? + if (setsockopt(eth->sockfd, + SOL_SOCKET, + SO_SNDTIMEO, + (char *)&timeout,sizeof(timeout))) { + perror("[ETHERNET] setsockopt()"); + } else { + printf( "send timeout= %d,%d sec\n",(int)timeout.tv_sec,(int)timeout.tv_usec); + } + break; + + /******************* interface level options *************************/ - case MTU_SIZE: /* change MTU of the eth interface */ - ifr.ifr_addr.sa_family = AF_INET; - strncpy(ifr.ifr_name,eth->if_name[Mod_id], sizeof(ifr.ifr_name)); - ifr.ifr_mtu =value; - if (ioctl(eth->sockfd[Mod_id],SIOCSIFMTU,(caddr_t)&ifr) < 0 ) - perror ("[ETHERNET] Can't set the MTU"); - else - printf("[ETHERNET] %s MTU size has changed to %d\n",eth->if_name[Mod_id],ifr.ifr_mtu); - break; - - case TX_Q_LEN: /* change TX queue length of eth interface */ - ifr.ifr_addr.sa_family = AF_INET; - strncpy(ifr.ifr_name,eth->if_name[Mod_id], sizeof(ifr.ifr_name)); - ifr.ifr_qlen =value; - if (ioctl(eth->sockfd[Mod_id],SIOCSIFTXQLEN,(caddr_t)&ifr) < 0 ) - perror ("[ETHERNET] Can't set the txqueuelen"); - else - printf("[ETHERNET] %s txqueuelen size has changed to %d\n",eth->if_name[Mod_id],ifr.ifr_qlen); - break; - + case MTU_SIZE: /* change MTU of the eth interface */ + ifr.ifr_addr.sa_family = AF_INET; + strncpy(ifr.ifr_name,eth->if_name, sizeof(ifr.ifr_name)); + ifr.ifr_mtu =value; + if (ioctl(eth->sockfd,SIOCSIFMTU,(caddr_t)&ifr) < 0 ) + perror ("[ETHERNET] Can't set the MTU"); + else + printf("[ETHERNET] %s MTU size has changed to %d\n",eth->if_name,ifr.ifr_mtu); + break; + + case TX_Q_LEN: /* change TX queue length of eth interface */ + ifr.ifr_addr.sa_family = AF_INET; + strncpy(ifr.ifr_name,eth->if_name, sizeof(ifr.ifr_name)); + ifr.ifr_qlen =value; + if (ioctl(eth->sockfd,SIOCSIFTXQLEN,(caddr_t)&ifr) < 0 ) + perror ("[ETHERNET] Can't set the txqueuelen"); + else + printf("[ETHERNET] %s txqueuelen size has changed to %d\n",eth->if_name,ifr.ifr_qlen); + break; + /******************* device level options *************************/ - case COALESCE_PAR: - ret=snprintf(system_cmd,sizeof(system_cmd),"ethtool -C %s rx-usecs %d",eth->if_name[Mod_id],value); - if (ret > 0) { - ret=system(system_cmd); - if (ret == -1) { - fprintf (stderr,"[ETHERNET] Can't start shell to execute %s %s",system_cmd, strerror(errno)); - } else { - printf ("[ETHERNET] status of %s is %i\n",WEXITSTATUS(ret)); - } - printf("[ETHERNET] Coalesce parameters %s\n",system_cmd); - } else { - perror("[ETHERNET] Can't set coalesce parameters\n"); - } - break; - - case PAUSE_PAR: - if (value==1) ret=snprintf(system_cmd,sizeof(system_cmd),"ethtool -A %s autoneg off rx off tx off",eth->if_name[Mod_id]); - else if (value==0) ret=snprintf(system_cmd,sizeof(system_cmd),"ethtool -A %s autoneg on rx on tx on",eth->if_name[Mod_id]); - else break; - if (ret > 0) { - ret=system(system_cmd); - if (ret == -1) { - fprintf (stderr,"[ETHERNET] Can't start shell to execute %s %s",system_cmd, strerror(errno)); - } else { - printf ("[ETHERNET] status of %s is %i\n",WEXITSTATUS(ret)); - } - printf("[ETHERNET] Pause parameters %s\n",system_cmd); - } else { - perror("[ETHERNET] Can't set pause parameters\n"); - } - break; - - case RING_PAR: - ret=snprintf(system_cmd,sizeof(system_cmd),"ethtool -G %s val %d",eth->if_name[Mod_id],value); - if (ret > 0) { - ret=system(system_cmd); - if (ret == -1) { - fprintf (stderr,"[ETHERNET] Can't start shell to execute %s %s",system_cmd, strerror(errno)); - } else { - printf ("[ETHERNET] status of %s is %i\n",WEXITSTATUS(ret)); - } - printf("[ETHERNET] Ring parameters %s\n",system_cmd); - } else { - perror("[ETHERNET] Can't set ring parameters\n"); - } - break; - - default: - break; + case COALESCE_PAR: + ret=snprintf(system_cmd,sizeof(system_cmd),"ethtool -C %s rx-usecs %d",eth->if_name,value); + if (ret > 0) { + ret=system(system_cmd); + if (ret == -1) { + fprintf (stderr,"[ETHERNET] Can't start shell to execute %s %s",system_cmd, strerror(errno)); + } else { + printf ("[ETHERNET] status of %s is %i\n",WEXITSTATUS(ret)); + } + printf("[ETHERNET] Coalesce parameters %s\n",system_cmd); + } else { + perror("[ETHERNET] Can't set coalesce parameters\n"); } - - return 0; -} - - - -int transport_init(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * eth_params ) { - - eth_state_t *eth = (eth_state_t*)malloc(sizeof(eth_state_t)); - memset(eth, 0, sizeof(eth_state_t)); - - if (eth_params->transp_preference == 1) { - eth->flags = ETH_RAW_MODE; - } else if (eth_params->transp_preference == 0) { - eth->flags = ETH_UDP_MODE; - } else if (eth_params->transp_preference == 3) { - eth->flags = ETH_RAW_IF4p5_MODE; - } else if (eth_params->transp_preference == 2) { - eth->flags = ETH_UDP_IF4p5_MODE; - } else if (eth_params->transp_preference == 4) { - eth->flags = ETH_RAW_IF5_MOBIPASS; + break; + + case PAUSE_PAR: + if (value==1) ret=snprintf(system_cmd,sizeof(system_cmd),"ethtool -A %s autoneg off rx off tx off",eth->if_name); + else if (value==0) ret=snprintf(system_cmd,sizeof(system_cmd),"ethtool -A %s autoneg on rx on tx on",eth->if_name); + else break; + if (ret > 0) { + ret=system(system_cmd); + if (ret == -1) { + fprintf (stderr,"[ETHERNET] Can't start shell to execute %s %s",system_cmd, strerror(errno)); + } else { + printf ("[ETHERNET] status of %s is %i\n",WEXITSTATUS(ret)); + } + printf("[ETHERNET] Pause parameters %s\n",system_cmd); } else { - printf("transport_init: Unknown transport preference %d - default to RAW", eth_params->transp_preference); - eth->flags = ETH_RAW_MODE; + perror("[ETHERNET] Can't set pause parameters\n"); } - - printf("[ETHERNET]: Initializing openair0_device for %s ...\n", ((device->host_type == BBU_HOST) ? "BBU": "RRH")); - device->Mod_id = num_devices_eth++; - device->transp_type = ETHERNET_TP; - device->trx_start_func = trx_eth_start; - device->trx_request_func = trx_eth_request; - device->trx_reply_func = trx_eth_reply; - device->trx_get_stats_func = trx_eth_get_stats; - device->trx_reset_stats_func = trx_eth_reset_stats; - device->trx_end_func = trx_eth_end; - device->trx_stop_func = trx_eth_stop; - device->trx_set_freq_func = trx_eth_set_freq; - device->trx_set_gains_func = trx_eth_set_gains; - - if (eth->flags == ETH_RAW_MODE) { - device->trx_write_func = trx_eth_write_raw; - device->trx_read_func = trx_eth_read_raw; - } else if (eth->flags == ETH_UDP_MODE) { - device->trx_write_func = trx_eth_write_udp; - device->trx_read_func = trx_eth_read_udp; - } else if (eth->flags == ETH_RAW_IF4p5_MODE) { - device->trx_write_func = trx_eth_write_raw_IF4p5; - device->trx_read_func = trx_eth_read_raw_IF4p5; - } else if (eth->flags == ETH_UDP_IF4p5_MODE) { - device->trx_write_func = trx_eth_write_udp_IF4p5; - device->trx_read_func = trx_eth_read_udp_IF4p5; - } else if (eth->flags == ETH_RAW_IF5_MOBIPASS) { - device->trx_write_func = trx_eth_write_raw_IF4p5; - device->trx_read_func = trx_eth_read_raw_IF4p5; + break; + + case RING_PAR: + ret=snprintf(system_cmd,sizeof(system_cmd),"ethtool -G %s val %d",eth->if_name,value); + if (ret > 0) { + ret=system(system_cmd); + if (ret == -1) { + fprintf (stderr,"[ETHERNET] Can't start shell to execute %s %s",system_cmd, strerror(errno)); + } else { + printf ("[ETHERNET] status of %s is %i\n",WEXITSTATUS(ret)); + } + printf("[ETHERNET] Ring parameters %s\n",system_cmd); } else { - //device->trx_write_func = trx_eth_write_udp_IF4p5; - //device->trx_read_func = trx_eth_read_udp_IF4p5; + perror("[ETHERNET] Can't set ring parameters\n"); } + break; - eth->if_name[device->Mod_id] = eth_params->local_if_name; - device->priv = eth; + default: + break; + } + + return 0; +} - /* device specific */ - openair0_cfg[0].iq_rxrescale = 15;//rescale iqs - openair0_cfg[0].iq_txshift = eth_params->iq_txshift;// shift - openair0_cfg[0].tx_sample_advance = eth_params->tx_sample_advance; - /* RRH does not have any information to make this configuration atm */ - if (device->host_type == BBU_HOST) { - /*Note scheduling advance values valid only for case 7680000 */ - switch ((int)openair0_cfg[0].sample_rate) { - case 30720000: - openair0_cfg[0].samples_per_packet = 3840; - break; - case 23040000: - openair0_cfg[0].samples_per_packet = 2880; - break; - case 15360000: - openair0_cfg[0].samples_per_packet = 1920; - break; - case 7680000: - openair0_cfg[0].samples_per_packet = 960; - break; - case 1920000: - openair0_cfg[0].samples_per_packet = 240; - break; - default: - printf("Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); - exit(-1); - break; - } - } +int transport_init(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * eth_params ) { - device->openair0_cfg=&openair0_cfg[0]; - return 0; + eth_state_t *eth = (eth_state_t*)malloc(sizeof(eth_state_t)); + memset(eth, 0, sizeof(eth_state_t)); + + if (eth_params->transp_preference == 1) { + eth->flags = ETH_RAW_MODE; + } else if (eth_params->transp_preference == 0) { + eth->flags = ETH_UDP_MODE; + } else if (eth_params->transp_preference == 3) { + eth->flags = ETH_RAW_IF4p5_MODE; + } else if (eth_params->transp_preference == 2) { + eth->flags = ETH_UDP_IF4p5_MODE; + } else if (eth_params->transp_preference == 4) { + eth->flags = ETH_RAW_IF5_MOBIPASS; + } else { + printf("transport_init: Unknown transport preference %d - default to RAW", eth_params->transp_preference); + eth->flags = ETH_RAW_MODE; + } + + printf("[ETHERNET]: Initializing openair0_device for %s ...\n", ((device->host_type == BBU_HOST) ? "BBU": "RRH")); + device->Mod_id = 0;//num_devices_eth++; + device->transp_type = ETHERNET_TP; + device->trx_start_func = trx_eth_start; + device->trx_request_func = trx_eth_request; + device->trx_reply_func = trx_eth_reply; + device->trx_get_stats_func = trx_eth_get_stats; + device->trx_reset_stats_func = trx_eth_reset_stats; + device->trx_end_func = trx_eth_end; + device->trx_stop_func = trx_eth_stop; + device->trx_set_freq_func = trx_eth_set_freq; + device->trx_set_gains_func = trx_eth_set_gains; + + if (eth->flags == ETH_RAW_MODE) { + device->trx_write_func = trx_eth_write_raw; + device->trx_read_func = trx_eth_read_raw; + } else if (eth->flags == ETH_UDP_MODE) { + device->trx_write_func = trx_eth_write_udp; + device->trx_read_func = trx_eth_read_udp; + } else if (eth->flags == ETH_RAW_IF4p5_MODE) { + device->trx_write_func = trx_eth_write_raw_IF4p5; + device->trx_read_func = trx_eth_read_raw_IF4p5; + } else if (eth->flags == ETH_UDP_IF4p5_MODE) { + device->trx_write_func = trx_eth_write_udp_IF4p5; + device->trx_read_func = trx_eth_read_udp_IF4p5; + } else if (eth->flags == ETH_RAW_IF5_MOBIPASS) { + device->trx_write_func = trx_eth_write_raw_IF4p5; + device->trx_read_func = trx_eth_read_raw_IF5_mobipass; + } else { + //device->trx_write_func = trx_eth_write_udp_IF4p5; + //device->trx_read_func = trx_eth_read_udp_IF4p5; + } + + eth->if_name = eth_params->local_if_name; + device->priv = eth; + + /* device specific */ + openair0_cfg[0].iq_rxrescale = 15;//rescale iqs + openair0_cfg[0].iq_txshift = eth_params->iq_txshift;// shift + openair0_cfg[0].tx_sample_advance = eth_params->tx_sample_advance; + + /* RRH does not have any information to make this configuration atm */ + if (device->host_type == BBU_HOST) { + /*Note scheduling advance values valid only for case 7680000 */ + switch ((int)openair0_cfg[0].sample_rate) { + case 30720000: + openair0_cfg[0].samples_per_packet = 3840; + break; + case 23040000: + openair0_cfg[0].samples_per_packet = 2880; + break; + case 15360000: + openair0_cfg[0].samples_per_packet = 1920; + break; + case 7680000: + openair0_cfg[0].samples_per_packet = 960; + break; + case 1920000: + openair0_cfg[0].samples_per_packet = 240; + break; + default: + printf("Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); + exit(-1); + break; + } + } + device->openair0_cfg=&openair0_cfg[0]; + return 0; } diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h index c23528196858821027245a42672a0a6db3ca25df..9f555beaa9dea29bc862ed5a54953051eff09496 100644 --- a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h +++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h @@ -55,11 +55,23 @@ typedef struct { /*!\brief socket file desc */ - int sockfd[MAX_INST]; + int sockfd; /*!\brief interface name */ - char *if_name[MAX_INST]; + char *if_name; /*!\brief buffer size */ unsigned int buffer_size; + /*!\brief destination address for UDP socket*/ + struct sockaddr_in dest_addr; + /*!\brief local address for UDP socket*/ + struct sockaddr_in local_addr; + /*!\brief address length for both UDP and RAW socket*/ + int addr_len; + /*!\brief destination address for RAW socket*/ + struct sockaddr_ll dest_addr_ll; + /*!\brief local address for RAW socket*/ + struct sockaddr_ll local_addr_ll; + /*!\brief inteface index for RAW socket*/ + struct ifreq if_index; /*!\brief timeout ms */ unsigned int rx_timeout_ms; /*!\brief timeout ms */ @@ -218,6 +230,7 @@ int trx_eth_write_raw(openair0_device *device, openair0_timestamp timestamp, voi int trx_eth_read_raw(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc); int trx_eth_write_raw_IF4p5(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int cc, int flags); int trx_eth_read_raw_IF4p5(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc); +int trx_eth_read_raw_IF5_mobipass(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc); int trx_eth_write_udp_IF4p5(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int cc, int flags); int trx_eth_read_udp_IF4p5(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc); int eth_get_dev_conf_raw(openair0_device *device); diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h b/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h index e96282a7113ef4c6d9ccee73cd0182b1386b3334..5fdb962b09019470b6f5840f5bbacd890df1b2ee 100644 --- a/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h +++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h @@ -56,15 +56,19 @@ // Packet sizes for IF4p5 interface format #define DATA_BLOCK_SIZE_BYTES(scaled_nblocks) (sizeof(uint16_t)*scaled_nblocks) -#define PRACH_BLOCK_SIZE_BYTES (sizeof(int16_t)*839*2) // FIX hard coded prach size (uncompressed) +#define PRACH_HARD_CODED_NUM_SAMPLES (839*2) +#define PRACH_BLOCK_SIZE_BYTES (sizeof(int16_t)*PRACH_HARD_CODED_NUM_SAMPLES) // FIX hard coded prach size #define RAW_IF4p5_PDLFFT_SIZE_BYTES(nblocks) (MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t + DATA_BLOCK_SIZE_BYTES(nblocks)) #define RAW_IF4p5_PULFFT_SIZE_BYTES(nblocks) (MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t + DATA_BLOCK_SIZE_BYTES(nblocks)) +#define RAW_IF4p5_PULTICK_SIZE_BYTES (MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t) #define RAW_IF4p5_PRACH_SIZE_BYTES (MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t + PRACH_BLOCK_SIZE_BYTES) #define UDP_IF4p5_PDLFFT_SIZE_BYTES(nblocks) (sizeof_IF4p5_header_t + DATA_BLOCK_SIZE_BYTES(nblocks)) #define UDP_IF4p5_PULFFT_SIZE_BYTES(nblocks) (sizeof_IF4p5_header_t + DATA_BLOCK_SIZE_BYTES(nblocks)) +#define UDP_IF4p5_PULTICK_SIZE_BYTES (sizeof_IF4p5_header_t) #define UDP_IF4p5_PRACH_SIZE_BYTES (sizeof_IF4p5_header_t + PRACH_BLOCK_SIZE_BYTES) // Mobipass packet sizes #define RAW_IF5_MOBIPASS_BLOCK_SIZE_BYTES 1280 #define RAW_IF5_MOBIPASS_SIZE_BYTES (MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + RAW_IF5_MOBIPASS_BLOCK_SIZE_BYTES) +#define PAYLOAD_MOBIPASS_NUM_SAMPLES 640 diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index 0161761d97f3b70b94fa27f4720757a1ea60863d..2a2e09f40cbe800e7cd7fb654d059f88b1ff3113 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -177,10 +177,27 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, s->tx_md.time_spec = uhd::time_spec_t::from_ticks(timestamp, s->sample_rate); - if(flags) + if(flags>0) s->tx_md.has_time_spec = true; else s->tx_md.has_time_spec = false; + + if (flags == 2) { // start of burst + s->tx_md.start_of_burst = true; + s->tx_md.end_of_burst = false; + } + else if (flags == 3) { // end of burst + s->tx_md.start_of_burst = false; + s->tx_md.end_of_burst = true; + } + else if (flags == 4) { // start and end + s->tx_md.start_of_burst = true; + s->tx_md.end_of_burst = true; + } + else if (flags==1) { // middle of burst + s->tx_md.start_of_burst = false; + s->tx_md.end_of_burst = false; + } if (cc>1) { std::vector<void *> buff_ptrs; @@ -190,7 +207,7 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, else ret = (int)s->tx_stream->send(buff[0], nsamps, s->tx_md,1e-3); - s->tx_md.start_of_burst = false; + if (ret != nsamps) { printf("[xmit] tx samples %d != %d\n",ret,nsamps); @@ -352,19 +369,34 @@ static bool is_equal(double a, double b) return std::fabs(a-b) < std::numeric_limits<double>::epsilon(); } -/*! \brief Set frequencies (TX/RX) +void *freq_thread(void *arg) { + + openair0_device *device=(openair0_device *)arg; + usrp_state_t *s = (usrp_state_t*)device->priv; + + s->usrp->set_tx_freq(device->openair0_cfg[0].tx_freq[0]); + s->usrp->set_rx_freq(device->openair0_cfg[0].rx_freq[0]); +} +/*! \brief Set frequencies (TX/RX). Spawns a thread to handle the frequency change to not block the calling thread * \param device the hardware to use * \param openair0_cfg RF frontend parameters set by application * \param dummy dummy variable not used * \returns 0 in success */ -int trx_usrp_set_freq(openair0_device* device, openair0_config_t *openair0_cfg, int dummy) { +int trx_usrp_set_freq(openair0_device* device, openair0_config_t *openair0_cfg, int dont_block) { usrp_state_t *s = (usrp_state_t*)device->priv; + pthread_t f_thread; printf("Setting USRP TX Freq %f, RX Freq %f\n",openair0_cfg[0].tx_freq[0],openair0_cfg[0].rx_freq[0]); - s->usrp->set_tx_freq(openair0_cfg[0].tx_freq[0]); - s->usrp->set_rx_freq(openair0_cfg[0].rx_freq[0]); + + // spawn a thread to handle the frequency change to not block the calling thread + if (dont_block == 1) + pthread_create(&f_thread,NULL,freq_thread,(void*)device); + else { + s->usrp->set_tx_freq(device->openair0_cfg[0].tx_freq[0]); + s->usrp->set_rx_freq(device->openair0_cfg[0].rx_freq[0]); + } return(0); @@ -579,7 +611,10 @@ extern "C" { // s->usrp->set_tx_subdev_spec(tx_subdev); // lock mboard clocks - s->usrp->set_clock_source("internal"); + if (openair0_cfg[0].clock_source == internal) + s->usrp->set_clock_source("internal"); + else + s->usrp->set_clock_source("external"); //Setting device type to USRP X300/X310 device->type=USRP_X300_DEV; @@ -635,6 +670,12 @@ extern "C" { // s->usrp->set_clock_source("internal"); // set master clock rate and sample rate for tx & rx for streaming + // lock mboard clocks + if (openair0_cfg[0].clock_source == internal) + s->usrp->set_clock_source("internal"); + else + s->usrp->set_clock_source("external"); + device->type = USRP_B200_DEV; @@ -735,7 +776,10 @@ extern "C" { // create tx & rx streamer uhd::stream_args_t stream_args_rx("sc16", "sc16"); - //stream_args_rx.args["spp"] = str(boost::format("%d") % 2048);//(openair0_cfg[0].rx_num_channels*openair0_cfg[0].samples_per_packet)); + int samples=openair0_cfg[0].sample_rate; + samples/=24000; + // stream_args_rx.args["spp"] = str(boost::format("%d") % samples); + for (i = 0; i<openair0_cfg[0].rx_num_channels; i++) stream_args_rx.channels.push_back(i); s->rx_stream = s->usrp->get_rx_stream(stream_args_rx); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpb210.conf index f4ed76a21e178ef824c0211f1d0d1003e46b490d..c974345888ead5524830608fd7f5d7b30b1e5833 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpb210.conf @@ -31,7 +31,7 @@ eNBs = tdd_config_s = 0; prefix_type = "NORMAL"; eutra_band = 7; - downlink_frequency = 2660000000L; + downlink_frequency = 2680000000L; uplink_frequency_offset = -120000000; Nid_cell = 0; N_RB_DL = 100; @@ -70,7 +70,7 @@ eNBs = pusch_p0_Nominal = -96; pusch_alpha = "AL1"; - pucch_p0_Nominal = -100; + pucch_p0_Nominal = -104; msg3_delta_Preamble = 6; pucch_deltaF_Format1 = "deltaF2"; pucch_deltaF_Format1b = "deltaF3"; @@ -149,7 +149,7 @@ eNBs = ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.2/24"; ENB_INTERFACE_NAME_FOR_S1U = "lo"; - ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.4/24"; + ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.5/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 }; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf index 1dfb0eeb9fb3397b1dc8b6855008a283fdb31fbe..3cf1e7d15b48efdc4c4bd90085eb756b2625ba4a 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf @@ -31,7 +31,7 @@ eNBs = tdd_config_s = 0; prefix_type = "NORMAL"; eutra_band = 7; - downlink_frequency = 2660000000L; + downlink_frequency = 2685000000L; uplink_frequency_offset = -120000000; Nid_cell = 0; N_RB_DL = 50; @@ -40,7 +40,7 @@ eNBs = nb_antennas_tx = 1; nb_antennas_rx = 1; tx_gain = 90; - rx_gain = 125; + rx_gain = 120; prach_root = 0; prach_config_index = 0; prach_high_speed = "DISABLE"; @@ -70,7 +70,7 @@ eNBs = pusch_p0_Nominal = -96; pusch_alpha = "AL1"; - pucch_p0_Nominal = -100; + pucch_p0_Nominal = -104; msg3_delta_Preamble = 6; pucch_deltaF_Format1 = "deltaF2"; pucch_deltaF_Format1b = "deltaF3"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.if4p5-ercom.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.if4p5-ercom.conf index 9ce8fac59fdc740aace0286b6f2f139a0009e06b..1afa860c16366d7d46632f5b6424902061bfcbb3 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.if4p5-ercom.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.if4p5-ercom.conf @@ -17,7 +17,7 @@ eNBs = mobile_country_code = "208"; - mobile_network_code = "93"; + mobile_network_code = "92"; ////////// Physical parameters: @@ -129,7 +129,7 @@ eNBs = prach_root = 0; prach_config_index = 0; prach_high_speed = "DISABLE"; - prach_zero_correlation = 1; + prach_zero_correlation = 3; prach_freq_offset = 2; pucch_delta_shift = 1; pucch_nRB_CQI = 1; @@ -265,7 +265,7 @@ eNBs = rrh_gw_active = "yes"; tr_preference = "raw_if5_mobipass"; rf_preference = "usrp_b200"; - iq_txshift = 4; + iq_txshift = 0; tx_sample_advance = 80; tx_scheduling_advance = 9; } diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.100PRB.if4p5.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.100PRB.conf similarity index 96% rename from targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.100PRB.if4p5.conf rename to targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.100PRB.conf index d97dc0c00210342fced2e5cae007dcbda0412e30..e52a36542fc005d63bf8ccfa91724d895f476172 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.100PRB.if4p5.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.100PRB.conf @@ -31,11 +31,12 @@ eNBs = tdd_config_s = 0; prefix_type = "NORMAL"; eutra_band = 7; - downlink_frequency = 2660000000L; + downlink_frequency = 2680000000L; uplink_frequency_offset = -120000000; Nid_cell = 0; N_RB_DL = 100; Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; nb_antennas_tx = 1; nb_antennas_rx = 1; tx_gain = 90; @@ -100,7 +101,7 @@ eNBs = ue_TimersAndConstants_t311 = 10000; ue_TimersAndConstants_n310 = 20; ue_TimersAndConstants_n311 = 1; - + ue_TransmissionMode = 1; } ); @@ -156,12 +157,12 @@ eNBs = rrh_gw_config = ( { local_if_name = "eth0"; - remote_address = "74:d4:35:cc:8d:15"; - local_address = "34:e6:d7:3c:ae:fc"; + remote_address = "10.10.10.60"; + local_address = "10.10.10.215"; local_port = 50000; #for raw option local port must be the same to remote remote_port = 50000; rrh_gw_active = "yes"; - tr_preference = "raw_if4p5"; + tr_preference = "udp_if4p5"; rf_preference = "usrp_b200"; iq_txshift = 4; tx_sample_advance = 80; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.25PRB.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.25PRB.conf index e8ffde20b627961259c9e188a677a414864dce19..f9ebec3ab53561789e5cbf9b81130c0cf7640c38 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.25PRB.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.25PRB.conf @@ -31,11 +31,12 @@ eNBs = tdd_config_s = 0; prefix_type = "NORMAL"; eutra_band = 7; - downlink_frequency = 2660000000L; + downlink_frequency = 2685000000L; uplink_frequency_offset = -120000000; Nid_cell = 0; N_RB_DL = 25; Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; nb_antennas_tx = 1; nb_antennas_rx = 1; tx_gain = 90; @@ -67,9 +68,9 @@ eNBs = srs_ackNackST =; srs_MaxUpPts =;*/ - pusch_p0_Nominal = -90; + pusch_p0_Nominal = -96; pusch_alpha = "AL1"; - pucch_p0_Nominal = -96; + pucch_p0_Nominal = -104; msg3_delta_Preamble = 6; pucch_deltaF_Format1 = "deltaF2"; pucch_deltaF_Format1b = "deltaF3"; @@ -100,7 +101,7 @@ eNBs = ue_TimersAndConstants_t311 = 10000; ue_TimersAndConstants_n310 = 20; ue_TimersAndConstants_n311 = 1; - + ue_TransmissionMode = 1; } ); @@ -149,19 +150,19 @@ eNBs = ENB_INTERFACE_NAME_FOR_S1_MME = "lo"; ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.2/24"; ENB_INTERFACE_NAME_FOR_S1U = "lo"; - ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.4/24"; + ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.5/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 }; rrh_gw_config = ( { local_if_name = "eth0"; - remote_address = "74:d4:35:cc:8d:15"; - local_address = "34:e6:d7:3c:ae:fc"; + remote_address = "10.10.10.60"; + local_address = "10.10.10.215"; local_port = 50000; #for raw option local port must be the same to remote remote_port = 50000; rrh_gw_active = "yes"; - tr_preference = "raw_if4p5"; + tr_preference = "udp_if4p5"; rf_preference = "usrp_b200"; iq_txshift = 4; tx_sample_advance = 80; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.if4p5.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf similarity index 93% rename from targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.if4p5.conf rename to targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf index b264993dd42eac40ba811c260f103484d2778394..4ad5767ce9a8343a5c117b8bcf1001636b4b12dc 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.if4p5.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf @@ -31,11 +31,12 @@ eNBs = tdd_config_s = 0; prefix_type = "NORMAL"; eutra_band = 7; - downlink_frequency = 2660000000L; + downlink_frequency = 2685000000L; uplink_frequency_offset = -120000000; Nid_cell = 0; N_RB_DL = 50; Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; nb_antennas_tx = 1; nb_antennas_rx = 1; tx_gain = 90; @@ -49,7 +50,7 @@ eNBs = pucch_nRB_CQI = 1; pucch_nCS_AN = 0; pucch_n1_AN = 32; - pdsch_referenceSignalPower = -29; + pdsch_referenceSignalPower = -27; pdsch_p_b = 0; pusch_n_SB = 1; pusch_enable64QAM = "DISABLE"; @@ -67,9 +68,9 @@ eNBs = srs_ackNackST =; srs_MaxUpPts =;*/ - pusch_p0_Nominal = -90; + pusch_p0_Nominal = -96; pusch_alpha = "AL1"; - pucch_p0_Nominal = -96; + pucch_p0_Nominal = -104; msg3_delta_Preamble = 6; pucch_deltaF_Format1 = "deltaF2"; pucch_deltaF_Format1b = "deltaF3"; @@ -100,6 +101,7 @@ eNBs = ue_TimersAndConstants_t311 = 10000; ue_TimersAndConstants_n310 = 20; ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 1; } ); @@ -149,19 +151,19 @@ eNBs = ENB_INTERFACE_NAME_FOR_S1_MME = "lo"; ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.2/24"; ENB_INTERFACE_NAME_FOR_S1U = "lo"; - ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.4/24"; + ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.5/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 }; rrh_gw_config = ( { local_if_name = "eth0"; - remote_address = "74:d4:35:cc:8d:15"; - local_address = "34:e6:d7:3c:ae:fc"; + remote_address = "10.10.10.60"; + local_address = "10.10.10.215"; local_port = 50000; #for raw option local port must be the same to remote remote_port = 50000; rrh_gw_active = "yes"; - tr_preference = "raw_if4p5"; + tr_preference = "udp_if4p5"; rf_preference = "usrp_b200"; iq_txshift = 4; tx_sample_advance = 80; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if5.25PRB.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if5.25PRB.conf new file mode 100644 index 0000000000000000000000000000000000000000..7541fa1ee14abc9beab14d1bec662397867b191e --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if5.25PRB.conf @@ -0,0 +1,191 @@ +Active_eNBs = ( "eNB_Eurecom_LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB_Eurecom_LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = "1"; + + mobile_country_code = "208"; + + mobile_network_code = "93"; + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "eNodeB_3GPP_BBU"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2685000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 25; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 125; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 1; + pucch_nCS_AN = 0; + pucch_n1_AN = 32; + pdsch_referenceSignalPower = -29; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -96; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -104; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -104; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 1; + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "127.0.0.3"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + ENB_INTERFACE_NAME_FOR_S1_MME = "lo"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.2/24"; + ENB_INTERFACE_NAME_FOR_S1U = "lo"; + ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.5/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + rrh_gw_config = ( + { + local_if_name = "eth0"; + remote_address = "10.10.10.60"; + local_address = "10.10.10.215"; + local_port = 50000; #for raw option local port must be the same to remote + remote_port = 50000; + rrh_gw_active = "yes"; + tr_preference = "udp"; + rf_preference = "usrp_b200"; + iq_txshift = 4; + tx_sample_advance = 80; + tx_scheduling_advance = 9; + } + ); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + } +); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.if5.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if5.50PRB.conf similarity index 96% rename from targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.if5.usrpb210.conf rename to targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if5.50PRB.conf index 4929f39b3bc52f73674e552b594bbd96bb36d46f..1044726c265738f2081f05e00923c469479cfde2 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.if5.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if5.50PRB.conf @@ -36,6 +36,7 @@ eNBs = Nid_cell = 0; N_RB_DL = 50; Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; nb_antennas_tx = 1; nb_antennas_rx = 1; tx_gain = 90; @@ -100,6 +101,10 @@ eNBs = ue_TimersAndConstants_t311 = 10000; ue_TimersAndConstants_n310 = 20; ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 1; + + + } ); @@ -155,13 +160,13 @@ eNBs = rrh_gw_config = ( { - local_if_name = "eth0"; - remote_address = "74:d4:35:cc:8d:15"; - local_address = "34:e6:d7:3c:ae:fc"; + local_if_name = "eth2"; + remote_address = "10.10.10.60"; + local_address = "10.10.10.215"; local_port = 50000; #for raw option local port must be the same to remote remote_port = 50000; rrh_gw_active = "yes"; - tr_preference = "raw_if5"; + tr_preference = "udp"; rf_preference = "usrp_b200"; iq_txshift = 4; tx_sample_advance = 80; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.50PRB.if5.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.50PRB.if5.usrpb210.conf index 902420ae08be1d0736c9ca02dc3b5c328d6960a7..6c309df4db831ceca7394635cf30a28f4442e416 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.50PRB.if5.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.50PRB.if5.usrpb210.conf @@ -155,9 +155,9 @@ eNBs = rrh_gw_config = ( { - local_if_name = "eth0"; - remote_address = "34:e6:d7:3c:ae:fc"; - local_address = "74:d4:35:cc:8d:15"; + local_if_name = "eth0"; + remote_address = "90:e2:ba:c5:fc:04"; + local_address = "00:13:95:1f:a0:af"; local_port = 50000; #for raw option local port must be the same to remote remote_port = 50000; rrh_gw_active = "yes"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.100PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.100PRB.usrpb210.conf index b1c4298104181a08db7f262f0ce51a3ee4417f18..aa731c8d8a23ee2e269682c3ccf3f2fc522b31e3 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.100PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.100PRB.usrpb210.conf @@ -31,15 +31,16 @@ eNBs = tdd_config_s = 0; prefix_type = "NORMAL"; eutra_band = 7; - downlink_frequency = 2660000000L; + downlink_frequency = 2680000000L; uplink_frequency_offset = -120000000; Nid_cell = 0; N_RB_DL = 100; Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; nb_antennas_tx = 1; nb_antennas_rx = 1; - tx_gain = 90; - rx_gain = 125; + tx_gain = 90; + rx_gain = 120; prach_root = 0; prach_config_index = 0; prach_high_speed = "DISABLE"; @@ -67,9 +68,9 @@ eNBs = srs_ackNackST =; srs_MaxUpPts =;*/ - pusch_p0_Nominal = -90; + pusch_p0_Nominal = -95; pusch_alpha = "AL1"; - pucch_p0_Nominal = -96; + pucch_p0_Nominal = -104; msg3_delta_Preamble = 6; pucch_deltaF_Format1 = "deltaF2"; pucch_deltaF_Format1b = "deltaF3"; @@ -85,7 +86,7 @@ eNBs = rach_messagePowerOffsetGroupB = ; */ rach_powerRampingStep = 4; - rach_preambleInitialReceivedTargetPower = -108; + rach_preambleInitialReceivedTargetPower = -104; rach_preambleTransMax = 10; rach_raResponseWindowSize = 10; rach_macContentionResolutionTimer = 48; @@ -101,6 +102,8 @@ eNBs = ue_TimersAndConstants_n310 = 20; ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 1; + } ); @@ -156,12 +159,12 @@ eNBs = rrh_gw_config = ( { local_if_name = "eth0"; - remote_address = "34:e6:d7:3c:ae:fc"; - local_address = "74:d4:35:cc:8d:15"; + remote_address = "10.10.10.215"; + local_address = "10.10.10.60"; local_port = 50000; #for raw option local port must be the same to remote remote_port = 50000; rrh_gw_active = "yes"; - tr_preference = "raw_if4p5"; + tr_preference = "udp_if4p5"; rf_preference = "usrp_b200"; iq_txshift = 4; tx_sample_advance = 80; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.25PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.25PRB.usrpb210.conf new file mode 100644 index 0000000000000000000000000000000000000000..c97b215c77bc10e3a4305a2c33c3f02c49f99d2f --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.25PRB.usrpb210.conf @@ -0,0 +1,193 @@ +Active_eNBs = ( "eNB_Eurecom_LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB_Eurecom_LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = "1"; + + mobile_country_code = "208"; + + mobile_network_code = "93"; + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "NGFI_RRU_IF4p5"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2685000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 25; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 120; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 1; + pucch_nCS_AN = 0; + pucch_n1_AN = 32; + pdsch_referenceSignalPower = -29; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -95; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -104; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -104; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + + ue_TransmissionMode = 1; + + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.12.11"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + ENB_INTERFACE_NAME_FOR_S1_MME = "eth3"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.215/24"; + ENB_INTERFACE_NAME_FOR_S1U = "eth3"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.215/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + rrh_gw_config = ( + { + local_if_name = "eth0"; + remote_address = "10.10.10.155"; + local_address = "10.10.10.60"; + local_port = 50000; #for raw option local port must be the same to remote + remote_port = 50000; + rrh_gw_active = "yes"; + tr_preference = "udp_if4p5"; + rf_preference = "usrp_b200"; + iq_txshift = 4; + tx_sample_advance = 80; + tx_scheduling_advance = 9; + } + ); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + } +); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.50PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.50PRB.usrpb210.conf index 831010a89a35b42bb594b031620b8cc596cf524d..d40b9017856958d26ed6d9a408ec059a0b7fa778 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.50PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.50PRB.usrpb210.conf @@ -31,15 +31,16 @@ eNBs = tdd_config_s = 0; prefix_type = "NORMAL"; eutra_band = 7; - downlink_frequency = 2660000000L; + downlink_frequency = 2685000000L; uplink_frequency_offset = -120000000; Nid_cell = 0; N_RB_DL = 50; Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; nb_antennas_tx = 1; nb_antennas_rx = 1; tx_gain = 90; - rx_gain = 125; + rx_gain = 120; prach_root = 0; prach_config_index = 0; prach_high_speed = "DISABLE"; @@ -67,9 +68,9 @@ eNBs = srs_ackNackST =; srs_MaxUpPts =;*/ - pusch_p0_Nominal = -90; + pusch_p0_Nominal = -95; pusch_alpha = "AL1"; - pucch_p0_Nominal = -96; + pucch_p0_Nominal = -104; msg3_delta_Preamble = 6; pucch_deltaF_Format1 = "deltaF2"; pucch_deltaF_Format1b = "deltaF3"; @@ -85,7 +86,7 @@ eNBs = rach_messagePowerOffsetGroupB = ; */ rach_powerRampingStep = 4; - rach_preambleInitialReceivedTargetPower = -108; + rach_preambleInitialReceivedTargetPower = -104; rach_preambleTransMax = 10; rach_raResponseWindowSize = 10; rach_macContentionResolutionTimer = 48; @@ -101,6 +102,8 @@ eNBs = ue_TimersAndConstants_n310 = 20; ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 1; + } ); @@ -156,12 +159,12 @@ eNBs = rrh_gw_config = ( { local_if_name = "eth0"; - remote_address = "34:e6:d7:3c:ae:fc"; - local_address = "74:d4:35:cc:8d:15"; + remote_address = "10.10.10.215"; + local_address = "10.10.10.60"; local_port = 50000; #for raw option local port must be the same to remote remote_port = 50000; rrh_gw_active = "yes"; - tr_preference = "raw_if4p5"; + tr_preference = "udp_if4p5"; rf_preference = "usrp_b200"; iq_txshift = 4; tx_sample_advance = 80; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if5.25PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if5.25PRB.usrpb210.conf new file mode 100644 index 0000000000000000000000000000000000000000..71e435e2f41a34c16655417eb3444d9c6f038f6a --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if5.25PRB.usrpb210.conf @@ -0,0 +1,193 @@ +Active_eNBs = ( "eNB_Eurecom_LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB_Eurecom_LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = "1"; + + mobile_country_code = "208"; + + mobile_network_code = "93"; + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "NGFI_RRU_IF5"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2685000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 25; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 120; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 1; + pucch_nCS_AN = 0; + pucch_n1_AN = 32; + pdsch_referenceSignalPower = -29; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -95; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -104; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -104; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + + ue_TransmissionMode = 1; + + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.12.11"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + ENB_INTERFACE_NAME_FOR_S1_MME = "eth3"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.215/24"; + ENB_INTERFACE_NAME_FOR_S1U = "eth3"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.215/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + rrh_gw_config = ( + { + local_if_name = "eth0"; + remote_address = "10.10.10.155"; + local_address = "10.10.10.60"; + local_port = 50000; #for raw option local port must be the same to remote + remote_port = 50000; + rrh_gw_active = "yes"; + tr_preference = "udp"; + rf_preference = "usrp_b200"; + iq_txshift = 4; + tx_sample_advance = 80; + tx_scheduling_advance = 9; + } + ); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + } +); diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index a3d6d96e03c7ca42314aafb43176db7a9560adfa..4cf3346b242935bd8fd23b8c79167a1e6b5bfc79 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -157,7 +157,7 @@ extern double cpuf; void exit_fun(const char* s); -void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst,eth_params_t *,int); +void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst,eth_params_t *,int,int); void stop_eNB(int nb_inst); @@ -279,6 +279,7 @@ static inline void wait_sync(char *thread_name) { void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) { + int CC_id = phy_vars_eNB->proc.CC_id; unsigned int aa,slot_offset; //int dummy_tx_b[7680*4] __attribute__((aligned(32))); int i, tx_offset; @@ -298,14 +299,16 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) do_OFDM_mod_symbol(&phy_vars_eNB->common_vars, 0, subframe<<1, - &phy_vars_eNB->frame_parms); + &phy_vars_eNB->frame_parms, + phy_vars_eNB->do_precoding); // if S-subframe generate first slot only if (subframe_select(&phy_vars_eNB->frame_parms,subframe) == SF_DL) { do_OFDM_mod_symbol(&phy_vars_eNB->common_vars, 0, 1+(subframe<<1), - &phy_vars_eNB->frame_parms); + &phy_vars_eNB->frame_parms, + phy_vars_eNB->do_precoding); } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_OFDM_MODULATION,0); @@ -368,9 +371,9 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) ((short*)&phy_vars_eNB->common_vars.txdata[0][aa][tx_offset])[1] = ((short*)dummy_tx_b)[2*i+1]<<openair0_cfg[0].iq_txshift; */ - ((short*)&phy_vars_eNB->common_vars.txdata[0][aa][tx_offset])[0] = ((short*)&phy_vars_eNB->common_vars.txdata[0][aa][tx_offset])[0]<<openair0_cfg[0].iq_txshift; + ((short*)&phy_vars_eNB->common_vars.txdata[0][aa][tx_offset])[0] = ((short*)&phy_vars_eNB->common_vars.txdata[0][aa][tx_offset])[0]<<openair0_cfg[CC_id].iq_txshift; - ((short*)&phy_vars_eNB->common_vars.txdata[0][aa][tx_offset])[1] = ((short*)&phy_vars_eNB->common_vars.txdata[0][aa][tx_offset])[1]<<openair0_cfg[0].iq_txshift; + ((short*)&phy_vars_eNB->common_vars.txdata[0][aa][tx_offset])[1] = ((short*)&phy_vars_eNB->common_vars.txdata[0][aa][tx_offset])[1]<<openair0_cfg[CC_id].iq_txshift; } // if S-subframe switch to RX in second subframe if (subframe_select(&phy_vars_eNB->frame_parms,subframe) == SF_S) { @@ -404,16 +407,25 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) void tx_fh_if5(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) { VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, proc->timestamp_tx&0xffffffff ); - send_IF5(eNB, proc->timestamp_tx, proc->subframe_tx, &seqno, IF5_RRH_GW_DL); + if ((eNB->frame_parms.frame_type==FDD) || + ((eNB->frame_parms.frame_type==TDD) && + (subframe_select(&eNB->frame_parms,proc->subframe_tx) != SF_UL))) + send_IF5(eNB, proc->timestamp_tx, proc->subframe_tx, &seqno, IF5_RRH_GW_DL); } void tx_fh_if5_mobipass(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) { VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, proc->timestamp_tx&0xffffffff ); - send_IF5(eNB, proc->timestamp_tx, proc->subframe_tx, &seqno, IF5_MOBIPASS); + if ((eNB->frame_parms.frame_type==FDD) || + ((eNB->frame_parms.frame_type==TDD) && + (subframe_select(&eNB->frame_parms,proc->subframe_tx) != SF_UL))) + send_IF5(eNB, proc->timestamp_tx, proc->subframe_tx, &seqno, IF5_MOBIPASS); } -void tx_fh_if4p5(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) { - send_IF4p5(eNB,proc->frame_tx, proc->subframe_tx, IF4p5_PDLFFT, 0); +void tx_fh_if4p5(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) { + if ((eNB->frame_parms.frame_type==FDD) || + ((eNB->frame_parms.frame_type==TDD) && + (subframe_select(&eNB->frame_parms,proc->subframe_tx) != SF_UL))) + send_IF4p5(eNB,proc->frame_tx,proc->subframe_tx, IF4p5_PDLFFT, 0); } void proc_tx_high0(PHY_VARS_eNB *eNB, @@ -551,9 +563,12 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam start_meas(&softmodem_stats_rxtx_sf); -// **************************************** + // **************************************** // Common RX procedures subframe n - phy_procedures_eNB_common_RX(eNB); + + if ((eNB->do_prach)&&((eNB->node_function != NGFI_RCC_IF4p5))) + eNB->do_prach(eNB,proc->frame_rx,proc->subframe_rx); + phy_procedures_eNB_common_RX(eNB,proc); // UE-specific RX processing for subframe n if (eNB->proc_uespec_rx) eNB->proc_uespec_rx(eNB, proc, no_relay ); @@ -609,7 +624,8 @@ static void* eNB_thread_rxtx( void* param ) { if (oai_exit) break; - if (rxtx(eNB,proc,thread_name) < 0) break; + if (eNB->CC_id==0) + if (rxtx(eNB,proc,thread_name) < 0) break; } // while !oai_exit @@ -641,32 +657,43 @@ static void wait_system_ready (char *message, volatile int *start_flag) { #endif -// asynchronous UL with IF4p5 (RCC,RAU,eNodeB_BBU) +// asynchronous UL with IF5 (RCC,RAU,eNodeB_BBU) void fh_if5_asynch_UL(PHY_VARS_eNB *eNB,int *frame,int *subframe) { eNB_proc_t *proc = &eNB->proc; LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; - recv_IF5(eNB, &proc->timestamp_rx, *subframe, IF5_RRH_GW_UL); - - proc->subframe_rx = (proc->timestamp_rx/fp->samples_per_tti)%10; - proc->frame_rx = (proc->timestamp_rx/(10*fp->samples_per_tti))&1023; + recv_IF5(eNB, &proc->timestamp_rx, *subframe, IF5_MOBIPASS); - if (proc->first_rx != 0) { - proc->first_rx = 0; + int offset_mobipass = 40120; + pthread_mutex_lock(&proc->mutex_asynch_rxtx); + proc->subframe_rx = ((proc->timestamp_rx-offset_mobipass)/fp->samples_per_tti)%10; + proc->frame_rx = ((proc->timestamp_rx-offset_mobipass)/(fp->samples_per_tti*10))&1023; + + if (proc->first_rx == 1) { + proc->first_rx =2; *subframe = proc->subframe_rx; *frame = proc->frame_rx; + LOG_E(PHY,"[Mobipass]timestamp_rx:%llu, frame_rx %d, subframe: %d\n",proc->timestamp_rx,proc->frame_rx,proc->subframe_rx); } else { if (proc->subframe_rx != *subframe) { - LOG_E(PHY,"subframe_rx %d is not what we expect %d\n",proc->subframe_rx,*subframe); - exit_fun("Exiting"); + proc->first_rx++; + LOG_E(PHY,"[Mobipass]timestamp:%llu, subframe_rx %d is not what we expect %d, first_rx:%d\n",proc->timestamp_rx, proc->subframe_rx,*subframe, proc->first_rx); + //exit_fun("Exiting"); } if (proc->frame_rx != *frame) { - LOG_E(PHY,"subframe_rx %d is not what we expect %d\n",proc->frame_rx,*frame); - exit_fun("Exiting"); + proc->first_rx++; + LOG_E(PHY,"[Mobipass]timestamp:%llu, frame_rx %d is not what we expect %d, first_rx:%d\n",proc->timestamp_rx,proc->frame_rx,*frame, proc->first_rx); + // exit_fun("Exiting"); } + // temporary solution + *subframe = proc->subframe_rx; + *frame = proc->frame_rx; } + + pthread_mutex_unlock(&proc->mutex_asynch_rxtx); + } // eNodeB_3GPP_BBU // asynchronous UL with IF4p5 (RCC,RAU,eNodeB_BBU) @@ -693,11 +720,11 @@ void fh_if4p5_asynch_UL(PHY_VARS_eNB *eNB,int *frame,int *subframe) { } else { if (proc->frame_rx != *frame) { - LOG_E(PHY,"frame_rx %d is not what we expect %d\n",proc->frame_rx,*frame); + LOG_E(PHY,"fh_if4p5_asynch_UL: frame_rx %d is not what we expect %d\n",proc->frame_rx,*frame); exit_fun("Exiting"); } if (proc->subframe_rx != *subframe) { - LOG_E(PHY,"subframe_rx %d is not what we expect %d\n",proc->subframe_rx,*subframe); + LOG_E(PHY,"fh_if4p5_asynch_UL: subframe_rx %d is not what we expect %d\n",proc->subframe_rx,*subframe); exit_fun("Exiting"); } } @@ -721,11 +748,14 @@ void fh_if5_asynch_DL(PHY_VARS_eNB *eNB,int *frame,int *subframe) { openair0_timestamp timestamp_tx; recv_IF5(eNB, ×tamp_tx, *subframe, IF5_RRH_GW_DL); - // printf("Received subframe %d (TS %llu) from RCC\n",subframe_tx,timestamp_tx); + //printf("Received subframe %d (TS %llu) from RCC\n",subframe_tx,timestamp_tx); subframe_tx = (timestamp_tx/fp->samples_per_tti)%10; frame_tx = (timestamp_tx/(fp->samples_per_tti*10))&1023; + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_ENB, frame_tx ); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_ENB, subframe_tx ); + if (proc->first_tx != 0) { *subframe = subframe_tx; *frame = frame_tx; @@ -733,11 +763,11 @@ void fh_if5_asynch_DL(PHY_VARS_eNB *eNB,int *frame,int *subframe) { } else { if (subframe_tx != *subframe) { - LOG_E(PHY,"subframe_tx %d is not what we expect %d\n",subframe_tx,*subframe); + LOG_E(PHY,"fh_if5_asynch_DL: subframe_tx %d is not what we expect %d\n",subframe_tx,*subframe); exit_fun("Exiting"); } if (frame_tx != *frame) { - LOG_E(PHY,"frame_tx %d is not what we expect %d\n",frame_tx,*frame); + LOG_E(PHY,"fh_if5_asynch_DL: frame_tx %d is not what we expect %d\n",frame_tx,*frame); exit_fun("Exiting"); } } @@ -749,40 +779,67 @@ void fh_if4p5_asynch_DL(PHY_VARS_eNB *eNB,int *frame,int *subframe) { eNB_proc_t *proc = &eNB->proc; uint16_t packet_type; - uint32_t symbol_number,symbol_mask,symbol_mask_full; + uint32_t symbol_number,symbol_mask_full; int subframe_tx,frame_tx; symbol_number = 0; - symbol_mask = 0; - symbol_mask_full = (1<<fp->symbols_per_tti)-1; + LOG_D(PHY,"fh_asynch_DL_IF4p5: in, frame %d, subframe %d\n",*frame,*subframe); + + // correct for TDD + if (fp->frame_type == TDD) { + while (subframe_select(fp,*subframe) == SF_UL) { + *subframe=*subframe+1; + if (*subframe==10) { + *subframe=0; + *frame=*frame+1; + } + } + } + + LOG_D(PHY,"fh_asynch_DL_IF4p5: after TDD correction, frame %d, subframe %d\n",*frame,*subframe); + + symbol_mask_full = ((subframe_select(fp,*subframe) == SF_S) ? (1<<fp->dl_symbols_in_S_subframe) : (1<<fp->symbols_per_tti))-1; do { // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!! recv_IF4p5(eNB, &frame_tx, &subframe_tx, &packet_type, &symbol_number); if (proc->first_tx != 0) { *frame = frame_tx; *subframe = subframe_tx; proc->first_tx = 0; + proc->frame_offset = frame_tx - proc->frame_tx; + symbol_mask_full = ((subframe_select(fp,*subframe) == SF_S) ? (1<<fp->dl_symbols_in_S_subframe) : (1<<fp->symbols_per_tti))-1; + } else { if (frame_tx != *frame) { - LOG_E(PHY,"frame_tx %d is not what we expect %d\n",frame_tx,*frame); + LOG_E(PHY,"fh_if4p5_asynch_DL: frame_tx %d is not what we expect %d\n",frame_tx,*frame); exit_fun("Exiting"); } if (subframe_tx != *subframe) { - LOG_E(PHY,"subframe_tx %d is not what we expect %d\n",subframe_tx,*subframe); + LOG_E(PHY,"fh_if4p5_asynch_DL: (frame %d) subframe_tx %d is not what we expect %d\n",frame_tx,subframe_tx,*subframe); + //*subframe = subframe_tx; exit_fun("Exiting"); } } if (packet_type == IF4p5_PDLFFT) { - symbol_mask = symbol_mask | (1<<symbol_number); + proc->symbol_mask[subframe_tx] =proc->symbol_mask[subframe_tx] | (1<<symbol_number); } else { LOG_E(PHY,"Illegal IF4p5 packet type (should only be IF4p5_PDLFFT%d\n",packet_type); exit_fun("Exiting"); } - } while (symbol_mask != symbol_mask_full); + } while (proc->symbol_mask[*subframe] != symbol_mask_full); + + *frame = frame_tx; + + + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_ENB, frame_tx ); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_ENB, subframe_tx ); + + // intialize this to zero after we're done with the subframe + proc->symbol_mask[*subframe] = 0; - do_OFDM_mod_rt(subframe_tx, eNB); + do_OFDM_mod_rt(*subframe, eNB); } /*! @@ -848,61 +905,113 @@ void rx_rf(PHY_VARS_eNB *eNB,int *frame,int *subframe) { void *rxp[fp->nb_antennas_rx],*txp[fp->nb_antennas_tx]; unsigned int rxs,txs; int i; - int tx_sfoffset = 3;//(eNB->single_thread_flag == 1) ? 3 : 3; + int tx_sfoffset = (eNB->single_thread_flag == 1) ? 3 : 2; + openair0_timestamp ts,old_ts; + if (proc->first_rx==0) { // Transmit TX buffer based on timestamp from RX // printf("trx_write -> USRP TS %llu (sf %d)\n", (proc->timestamp_rx+(3*fp->samples_per_tti)),(proc->subframe_rx+2)%10); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (proc->timestamp_rx+(tx_sfoffset*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance)&0xffffffff ); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); // prepare tx buffer pointers - - for (i=0; i<fp->nb_antennas_tx; i++) - txp[i] = (void*)&eNB->common_vars.txdata[0][i][((proc->subframe_rx+tx_sfoffset)%10)*fp->samples_per_tti]; - - txs = eNB->rfdevice.trx_write_func(&eNB->rfdevice, - proc->timestamp_rx+(tx_sfoffset*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance, - txp, - fp->samples_per_tti, - fp->nb_antennas_tx, - 1); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 ); - - - - if (txs != fp->samples_per_tti) { - LOG_E(PHY,"TX : Timeout (sent %d/%d)\n",txs, fp->samples_per_tti); - exit_fun( "problem transmitting samples" ); - } + + lte_subframe_t SF_type = subframe_select(fp,(proc->subframe_rx+tx_sfoffset)%10); + lte_subframe_t prevSF_type = subframe_select(fp,(proc->subframe_rx+tx_sfoffset+9)%10); + lte_subframe_t nextSF_type = subframe_select(fp,(proc->subframe_rx+tx_sfoffset+1)%10); + if ((SF_type == SF_DL) || + (SF_type == SF_S)) { + + for (i=0; i<fp->nb_antennas_tx; i++) + txp[i] = (void*)&eNB->common_vars.txdata[0][i][((proc->subframe_rx+tx_sfoffset)%10)*fp->samples_per_tti]; + + int siglen=fp->samples_per_tti,flags=1; + + if (SF_type == SF_S) { + siglen = fp->dl_symbols_in_S_subframe*(fp->ofdm_symbol_size+fp->nb_prefix_samples0); + flags=3; // end of burst + } + if ((fp->frame_type == TDD) && + (SF_type == SF_DL)&& + (prevSF_type == SF_UL) && + (nextSF_type == SF_DL)) + flags = 2; // start of burst + + if ((fp->frame_type == TDD) && + (SF_type == SF_DL)&& + (prevSF_type == SF_UL) && + (nextSF_type == SF_UL)) + flags = 4; // start of burst and end of burst (only one DL SF between two UL) + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_WRITE_FLAGS,flags); + txs = eNB->rfdevice.trx_write_func(&eNB->rfdevice, + proc->timestamp_rx+eNB->ts_offset+(tx_sfoffset*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance, + txp, + siglen, + fp->nb_antennas_tx, + flags); + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 ); + + + + if (txs != siglen) { + LOG_E(PHY,"TX : Timeout (sent %d/%d)\n",txs, fp->samples_per_tti); + exit_fun( "problem transmitting samples" ); + } + } } - + for (i=0; i<fp->nb_antennas_rx; i++) rxp[i] = (void*)&eNB->common_vars.rxdata[0][i][*subframe*fp->samples_per_tti]; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 ); + old_ts = proc->timestamp_rx; + rxs = eNB->rfdevice.trx_read_func(&eNB->rfdevice, - &(proc->timestamp_rx), + &ts, rxp, fp->samples_per_tti, fp->nb_antennas_rx); + proc->timestamp_rx = ts-eNB->ts_offset; + + if (rxs != fp->samples_per_tti) + LOG_E(PHY,"rx_rf: Asked for %d samples, got %d from USRP\n",fp->samples_per_tti,rxs); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 ); - + + if (proc->first_rx == 1) { + eNB->ts_offset = proc->timestamp_rx; + proc->timestamp_rx=0; + } + else { + + if (proc->timestamp_rx - old_ts != fp->samples_per_tti) { + LOG_I(PHY,"rx_rf: rfdevice timing drift of %d samples\n",proc->timestamp_rx - old_ts - fp->samples_per_tti); + eNB->ts_offset += (proc->timestamp_rx - old_ts - fp->samples_per_tti); + proc->timestamp_rx = ts-eNB->ts_offset; + } + } proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023; proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10; + proc->frame_rx = (proc->frame_rx+proc->frame_offset)&1023; + proc->frame_tx = proc->frame_rx; + if (proc->subframe_rx > 5) proc->frame_tx=(proc->frame_tx+1)&1023; + // synchronize first reception to frame 0 subframe 0 + proc->timestamp_tx = proc->timestamp_rx+(4*fp->samples_per_tti); - //printf("trx_read <- RX TS %llu (sf %d, first_rx %d)\n", proc->timestamp_rx,proc->subframe_rx,proc->first_rx); + // printf("trx_read <- USRP TS %lu (offset %d sf %d, f %d, first_rx %d)\n", proc->timestamp_rx,eNB->ts_offset,proc->subframe_rx,proc->frame_rx,proc->first_rx); if (proc->first_rx == 0) { if (proc->subframe_rx != *subframe){ - LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->subframe_rx,*subframe); + LOG_E(PHY,"rx_rf: Received Timestamp (%llu) doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->timestamp_rx,proc->subframe_rx,*subframe); exit_fun("Exiting"); } - - 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); + int f2 = (*frame+proc->frame_offset)&1023; + if (proc->frame_rx != f2) { + LOG_E(PHY,"rx_rf: Received Timestamp (%llu) doesn't correspond to the time we think it is (proc->frame_rx %d frame %d, frame_offset %d, f2 %d)\n",proc->timestamp_rx,proc->frame_rx,*frame,proc->frame_offset,f2); exit_fun("Exiting"); } } else { @@ -934,12 +1043,12 @@ void rx_fh_if5(PHY_VARS_eNB *eNB,int *frame, int *subframe) { if (proc->first_rx == 0) { if (proc->subframe_rx != *subframe){ - LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->subframe_rx,*subframe); + LOG_E(PHY,"rx_fh_if5: Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->subframe_rx,*subframe); exit_fun("Exiting"); } 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); + LOG_E(PHY,"rx_fh_if5: 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 { @@ -947,6 +1056,10 @@ void rx_fh_if5(PHY_VARS_eNB *eNB,int *frame, int *subframe) { *frame = proc->frame_rx; *subframe = proc->subframe_rx; } + + + + proc->timestamp_tx = proc->timestamp_rx + (4*fp->samples_per_tti); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff ); @@ -957,50 +1070,80 @@ void rx_fh_if4p5(PHY_VARS_eNB *eNB,int *frame,int *subframe) { LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; eNB_proc_t *proc = &eNB->proc; - - int prach_rx; + int f,sf; uint16_t packet_type; uint32_t symbol_number=0; - uint32_t symbol_mask, symbol_mask_full; + uint32_t symbol_mask_full; - symbol_mask = 0; - symbol_mask_full = (1<<fp->symbols_per_tti)-1; - prach_rx = 0; + if ((fp->frame_type == TDD) && (subframe_select(fp,*subframe)==SF_S)) + symbol_mask_full = (1<<fp->ul_symbols_in_S_subframe)-1; + else + symbol_mask_full = (1<<fp->symbols_per_tti)-1; + if (eNB->CC_id==1) LOG_I(PHY,"rx_fh_if4p5: frame %d, subframe %d\n",*frame,*subframe); do { // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!! - recv_IF4p5(eNB, &proc->frame_rx, &proc->subframe_rx, &packet_type, &symbol_number); + recv_IF4p5(eNB, &f, &sf, &packet_type, &symbol_number); + //proc->frame_rx = (proc->frame_rx + proc->frame_offset)&1023; if (packet_type == IF4p5_PULFFT) { - symbol_mask = symbol_mask | (1<<symbol_number); - prach_rx = (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)>0) ? 1 : 0; + LOG_D(PHY,"rx_fh_if4p5: frame %d, subframe %d, PULFFT symbol %d\n",f,sf,symbol_number); + + proc->symbol_mask[sf] = proc->symbol_mask[sf] | (1<<symbol_number); + } else if (packet_type == IF4p5_PULTICK) { + + if ((proc->first_rx==0) && (f!=*frame)) + LOG_E(PHY,"rx_fh_if4p5: PULTICK received frame %d != expected %d\n",f,*frame); + if ((proc->first_rx==0) && (sf!=*subframe)) + LOG_E(PHY,"rx_fh_if4p5: PULTICK received subframe %d != expected %d (first_rx %d)\n",sf,*subframe,proc->first_rx); + break; } else if (packet_type == IF4p5_PRACH) { - prach_rx = 0; + LOG_D(PHY,"rx_fh:if4p5: frame %d, subframe %d, PRACH\n",f,sf); + // wakeup prach processing + if (eNB->do_prach) eNB->do_prach(eNB,f,sf); } - } while( (symbol_mask != symbol_mask_full) || (prach_rx == 1)); + if (eNB->CC_id==1) LOG_I(PHY,"rx_fh_if4p5: symbol_mask[%d] %x\n",*subframe,proc->symbol_mask[*subframe]); + + } while(proc->symbol_mask[*subframe] != symbol_mask_full); + + proc->subframe_rx = sf; + proc->frame_rx = f; + + proc->symbol_mask[*subframe] = 0; + proc->symbol_mask[(9+*subframe)%10]= 0; // to handle a resynchronization event + + if (eNB->CC_id==1) LOG_I(PHY,"Clearing symbol_mask[%d]\n",*subframe); //caculate timestamp_rx, timestamp_tx based on frame and subframe - proc->timestamp_rx = ((proc->frame_rx * 10) + proc->subframe_rx ) * fp->samples_per_tti ; - proc->timestamp_tx = proc->timestamp_rx + (4*fp->samples_per_tti); - + proc->timestamp_rx = ((proc->frame_rx * 10) + proc->subframe_rx ) * fp->samples_per_tti ; + proc->timestamp_tx = proc->timestamp_rx + (4*fp->samples_per_tti); + if (proc->first_rx == 0) { if (proc->subframe_rx != *subframe){ - LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->subframe_rx,*subframe); - exit_fun("Exiting"); + LOG_E(PHY,"rx_fh_if4p5, CC_id %d: Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d,CCid %d)\n",eNB->CC_id,proc->subframe_rx,*subframe,eNB->CC_id); } 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"); + if (proc->frame_rx == proc->frame_offset) // This means that the RRU has adjusted its frame timing + proc->frame_offset = 0; + else + LOG_E(PHY,"rx_fh_if4p5: Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d,CCid %d)\n",proc->frame_rx,*frame,eNB->CC_id); } } else { - proc->first_rx--; - *frame = proc->frame_rx; + proc->first_rx = 0; + if (eNB->CC_id==0) + proc->frame_offset = 0; + else + proc->frame_offset = PHY_vars_eNB_g[0][0]->proc.frame_rx; + + *frame = proc->frame_rx;//(proc->frame_rx + proc->frame_offset)&1023; *subframe = proc->subframe_rx; } - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff ); + + + if (eNB->CC_id==0) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff ); } @@ -1089,11 +1232,16 @@ void wakeup_slaves(eNB_proc_t *proc) { exit_fun( "error locking mutex_rxtx" ); break; } - + + while (slave_proc->instance_cnt_FH == 0) { + // LOG_W( PHY,"[eNB] Frame:%d , eNB rx_fh_slave thread busy!! (cnt_FH %i)\n", proc->frame_rx,slave_proc->instance_cnt_FH ); + usleep(500); + } + int cnt_slave = ++slave_proc->instance_cnt_FH; slave_proc->frame_rx = proc->frame_rx; slave_proc->subframe_rx = proc->subframe_rx; - slave_proc->timestamp_rx = proc->timestamp_rx; + //slave_proc->timestamp_rx = proc->timestamp_rx; slave_proc->timestamp_tx = proc->timestamp_tx; pthread_mutex_unlock( &slave_proc->mutex_FH ); @@ -1113,6 +1261,117 @@ void wakeup_slaves(eNB_proc_t *proc) { } } +uint32_t sync_corr[307200] __attribute__((aligned(32))); + +// This thread run the initial synchronization like a UE +void *eNB_thread_synch(void *arg) { + + PHY_VARS_eNB *eNB = (PHY_VARS_eNB*)arg; + LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; + int32_t sync_pos,sync_pos2; + uint32_t peak_val; + + thread_top_init("eNB_thread_synch",0,5000000,10000000,10000000); + + wait_sync("eNB_thread_synch"); + + // initialize variables for PSS detection + lte_sync_time_init(&eNB->frame_parms); + + while (!oai_exit) { + + // wait to be woken up + pthread_mutex_lock(&eNB->proc.mutex_synch); + while (eNB->proc.instance_cnt_synch < 0) + pthread_cond_wait(&eNB->proc.cond_synch,&eNB->proc.mutex_synch); + pthread_mutex_unlock(&eNB->proc.mutex_synch); + + // if we're not in synch, then run initial synch + if (eNB->in_synch == 0) { + // run intial synch like UE + LOG_I(PHY,"Running initial synchronization\n"); + + sync_pos = lte_sync_time_eNB(eNB->common_vars.rxdata[0], + fp, + fp->samples_per_tti*5, + &peak_val, + sync_corr); + LOG_I(PHY,"eNB synch: %d, val %d\n",sync_pos,peak_val); + + if (sync_pos >= 0) { + if (sync_pos >= fp->nb_prefix_samples) + sync_pos2 = sync_pos - fp->nb_prefix_samples; + else + sync_pos2 = sync_pos + (fp->samples_per_tti*10) - fp->nb_prefix_samples; + + if (fp->frame_type == FDD) { + + // PSS is hypothesized in last symbol of first slot in Frame + int sync_pos_slot = (fp->samples_per_tti>>1) - fp->ofdm_symbol_size - fp->nb_prefix_samples; + + if (sync_pos2 >= sync_pos_slot) + eNB->rx_offset = sync_pos2 - sync_pos_slot; + else + eNB->rx_offset = (fp->samples_per_tti*10) + sync_pos2 - sync_pos_slot; + } + else { + + } + + LOG_I(PHY,"Estimated sync_pos %d, peak_val %d => timing offset %d\n",sync_pos,peak_val,eNB->rx_offset); + + /* + if ((peak_val > 300000) && (sync_pos > 0)) { + // if (sync_pos++ > 3) { + write_output("eNB_sync.m","sync",(void*)&sync_corr[0],fp->samples_per_tti*5,1,2); + write_output("eNB_rx.m","rxs",(void*)eNB->common_vars.rxdata[0][0],fp->samples_per_tti*10,1,1); + exit(-1); + } + */ + eNB->in_synch=1; + } + } + + // release thread + pthread_mutex_lock(&eNB->proc.mutex_synch); + eNB->proc.instance_cnt_synch--; + pthread_mutex_unlock(&eNB->proc.mutex_synch); + } // oai_exit + + lte_sync_time_free(); + + return NULL; +} + +int wakeup_synch(PHY_VARS_eNB *eNB){ + + struct timespec wait; + + wait.tv_sec=0; + wait.tv_nsec=5000000L; + + // wake up synch thread + // lock the synch mutex and make sure the thread is ready + if (pthread_mutex_timedlock(&eNB->proc.mutex_synch,&wait) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB synch thread (IC %d)\n", eNB->proc.instance_cnt_synch ); + exit_fun( "error locking mutex_synch" ); + return(-1); + } + + ++eNB->proc.instance_cnt_synch; + + // the thread can now be woken up + if (pthread_cond_signal(&eNB->proc.cond_synch) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB synch thread\n"); + exit_fun( "ERROR pthread_cond_signal" ); + return(-1); + } + + pthread_mutex_unlock( &eNB->proc.mutex_synch ); + + return(0); +} + /*! * \brief The Fronthaul thread of RRU/RAU/RCC/eNB * In the case of RRU/eNB, handles interface with external RF @@ -1233,6 +1492,8 @@ static void* eNB_thread_prach( void* param ) { return &eNB_thread_prach_status; } + + static void* eNB_thread_single( void* param ) { static int eNB_thread_single_status; @@ -1240,9 +1501,25 @@ static void* eNB_thread_single( void* param ) { eNB_proc_t *proc = (eNB_proc_t*)param; eNB_rxtx_proc_t *proc_rxtx = &proc->proc_rxtx[0]; PHY_VARS_eNB *eNB = PHY_vars_eNB_g[0][proc->CC_id]; + LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; + eNB->CC_id = proc->CC_id; + + void *rxp[2],*rxp2[2]; int subframe=0, frame=0; + int32_t dummy_rx[fp->nb_antennas_rx][fp->samples_per_tti] __attribute__((aligned(32))); + + int ic; + + int rxs; + + int i; + + // initialize the synchronization buffer to the common_vars.rxdata + for (int i=0;i<fp->nb_antennas_rx;i++) + rxp[i] = &eNB->common_vars.rxdata[0][i][0]; + // set default return value eNB_thread_single_status = 0; @@ -1271,6 +1548,74 @@ static void* eNB_thread_single( void* param ) { pthread_mutex_unlock(&proc->mutex_asynch_rxtx); pthread_cond_signal(&proc->cond_asynch_rxtx); + + + // if this is a slave eNB, try to synchronize on the DL frequency + if ((eNB->is_slave) && + ((eNB->node_function >= NGFI_RRU_IF5))) { + // if FDD, switch RX on DL frequency + + double temp_freq1 = eNB->rfdevice.openair0_cfg->rx_freq[0]; + double temp_freq2 = eNB->rfdevice.openair0_cfg->tx_freq[0]; + for (i=0;i<4;i++) { + eNB->rfdevice.openair0_cfg->rx_freq[i] = eNB->rfdevice.openair0_cfg->tx_freq[i]; + eNB->rfdevice.openair0_cfg->tx_freq[i] = temp_freq1; + } + eNB->rfdevice.trx_set_freq_func(&eNB->rfdevice,eNB->rfdevice.openair0_cfg,0); + + while ((eNB->in_synch ==0)&&(!oai_exit)) { + // read in frame + rxs = eNB->rfdevice.trx_read_func(&eNB->rfdevice, + &(proc->timestamp_rx), + rxp, + fp->samples_per_tti*10, + fp->nb_antennas_rx); + + if (rxs != (fp->samples_per_tti*10)) + exit_fun("Problem receiving samples\n"); + + // wakeup synchronization processing thread + wakeup_synch(eNB); + ic=0; + + while ((ic>=0)&&(!oai_exit)) { + // continuously read in frames, 1ms at a time, + // until we are done with the synchronization procedure + + for (i=0; i<fp->nb_antennas_rx; i++) + rxp2[i] = (void*)&dummy_rx[i][0]; + for (i=0;i<10;i++) + rxs = eNB->rfdevice.trx_read_func(&eNB->rfdevice, + &(proc->timestamp_rx), + rxp2, + fp->samples_per_tti, + fp->nb_antennas_rx); + if (rxs != fp->samples_per_tti) + exit_fun( "problem receiving samples" ); + + pthread_mutex_lock(&eNB->proc.mutex_synch); + ic = eNB->proc.instance_cnt_synch; + pthread_mutex_unlock(&eNB->proc.mutex_synch); + } // ic>=0 + } // in_synch==0 + // read in rx_offset samples + LOG_I(PHY,"Resynchronizing by %d samples\n",eNB->rx_offset); + rxs = eNB->rfdevice.trx_read_func(&eNB->rfdevice, + &(proc->timestamp_rx), + rxp, + eNB->rx_offset, + fp->nb_antennas_rx); + if (rxs != eNB->rx_offset) + exit_fun( "problem receiving samples" ); + + for (i=0;i<4;i++) { + eNB->rfdevice.openair0_cfg->rx_freq[i] = temp_freq1; + eNB->rfdevice.openair0_cfg->tx_freq[i] = temp_freq2; + } + eNB->rfdevice.trx_set_freq_func(&eNB->rfdevice,eNB->rfdevice.openair0_cfg,1); + } // if RRU and slave + + // This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices while (!oai_exit) { @@ -1284,7 +1629,9 @@ static void* eNB_thread_single( void* param ) { subframe++; } - LOG_D(PHY,"eNB Fronthaul thread, frame %d, subframe %d\n",frame,subframe); + if (eNB->CC_id==1) + LOG_D(PHY,"eNB thread single %p (proc %p, CC_id %d), frame %d (%p), subframe %d (%p)\n", + pthread_self(), proc, eNB->CC_id, frame,&frame,subframe,&subframe); // synchronization on FH interface, acquire signals/data and block if (eNB->rx_fh) eNB->rx_fh(eNB,&frame,&subframe); @@ -1295,8 +1642,11 @@ static void* eNB_thread_single( void* param ) { proc_rxtx->subframe_rx = proc->subframe_rx; proc_rxtx->frame_rx = proc->frame_rx; proc_rxtx->subframe_tx = (proc->subframe_rx+4)%10; - proc_rxtx->frame_tx = (proc->subframe_rx < 6) ? proc->frame_rx : (proc->frame_rx+1)&1023; + proc_rxtx->frame_tx = (proc->subframe_rx>5) ? (1+proc->frame_rx)&1023 : proc->frame_rx; + proc->frame_tx = proc_rxtx->frame_tx; proc_rxtx->timestamp_tx = proc->timestamp_tx; + // adjust for timing offset between RRU + if (eNB->CC_id!=0) proc_rxtx->frame_tx = (proc_rxtx->frame_tx+proc->frame_offset)&1023; // At this point, all information for subframe has been received on FH interface // If this proc is to provide synchronization, do so @@ -1324,7 +1674,7 @@ void init_eNB_proc(int inst) { PHY_VARS_eNB *eNB; eNB_proc_t *proc; eNB_rxtx_proc_t *proc_rxtx; - pthread_attr_t *attr0=NULL,*attr1=NULL,*attr_FH=NULL,*attr_prach=NULL,*attr_asynch=NULL,*attr_single=NULL,*attr_fep=NULL,*attr_td=NULL,*attr_te; + pthread_attr_t *attr0=NULL,*attr1=NULL,*attr_FH=NULL,*attr_prach=NULL,*attr_asynch=NULL,*attr_single=NULL,*attr_fep=NULL,*attr_td=NULL,*attr_te=NULL,*attr_synch=NULL; for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { eNB = PHY_vars_eNB_g[inst][CC_id]; @@ -1340,9 +1690,13 @@ void init_eNB_proc(int inst) { proc->instance_cnt_FH = -1; proc->instance_cnt_asynch_rxtx = -1; proc->CC_id = CC_id; - - proc->first_rx=4; + proc->instance_cnt_synch = -1; + + proc->first_rx=1; proc->first_tx=1; + proc->frame_offset = 0; + + for (i=0;i<10;i++) proc->symbol_mask[i]=0; pthread_mutex_init( &proc_rxtx[0].mutex_rxtx, NULL); pthread_mutex_init( &proc_rxtx[1].mutex_rxtx, NULL); @@ -1351,13 +1705,16 @@ void init_eNB_proc(int inst) { pthread_mutex_init( &proc->mutex_prach, NULL); pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL); + pthread_mutex_init( &proc->mutex_synch,NULL); pthread_cond_init( &proc->cond_prach, NULL); pthread_cond_init( &proc->cond_FH, NULL); pthread_cond_init( &proc->cond_asynch_rxtx, NULL); + pthread_cond_init( &proc->cond_synch,NULL); pthread_attr_init( &proc->attr_FH); pthread_attr_init( &proc->attr_prach); + pthread_attr_init( &proc->attr_synch); pthread_attr_init( &proc->attr_asynch_rxtx); pthread_attr_init( &proc->attr_single); pthread_attr_init( &proc->attr_fep); @@ -1370,6 +1727,7 @@ void init_eNB_proc(int inst) { attr1 = &proc_rxtx[1].attr_rxtx; attr_FH = &proc->attr_FH; attr_prach = &proc->attr_prach; + attr_synch = &proc->attr_synch; attr_asynch = &proc->attr_asynch_rxtx; attr_single = &proc->attr_single; attr_fep = &proc->attr_fep; @@ -1389,6 +1747,7 @@ void init_eNB_proc(int inst) { init_te_thread(eNB,attr_te); } pthread_create( &proc->pthread_prach, attr_prach, eNB_thread_prach, &eNB->proc ); + pthread_create( &proc->pthread_synch, attr_synch, eNB_thread_synch, eNB); if ((eNB->node_timing == synch_to_other) || (eNB->node_function == NGFI_RRU_IF5) || (eNB->node_function == NGFI_RRU_IF4p5)) @@ -1412,6 +1771,7 @@ void init_eNB_proc(int inst) { } //for multiple CCs: setup master and slaves + /* for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { eNB = PHY_vars_eNB_g[inst][CC_id]; @@ -1424,8 +1784,8 @@ void init_eNB_proc(int inst) { if (i >= CC_id) eNB->proc.slave_proc[i] = &(PHY_vars_eNB_g[inst][i+1]->proc); } } - } - + } +*/ /* setup PHY proc TX sync mechanism */ pthread_mutex_init(&sync_phy_proc.mutex_phy_proc_tx, NULL); @@ -1610,12 +1970,12 @@ int start_rf(PHY_VARS_eNB *eNB) { return(eNB->rfdevice.trx_start_func(&eNB->rfdevice)); } -extern void eNB_fep_rru_if5(PHY_VARS_eNB *eNB); -extern void eNB_fep_full(PHY_VARS_eNB *eNB); -extern void eNB_fep_full_2thread(PHY_VARS_eNB *eNB); -extern void do_prach(PHY_VARS_eNB *eNB); +extern void eNB_fep_rru_if5(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc); +extern void eNB_fep_full(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc); +extern void eNB_fep_full_2thread(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc); +extern void do_prach(PHY_VARS_eNB *eNB,int frame,int subframe); -void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst,eth_params_t *eth_params,int single_thread_flag) { +void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst,eth_params_t *eth_params,int single_thread_flag,int wait_for_sync) { int CC_id; int inst; @@ -1629,6 +1989,11 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst eNB->node_timing = node_timing[CC_id]; eNB->abstraction_flag = 0; eNB->single_thread_flag = single_thread_flag; + eNB->ts_offset = 0; + eNB->in_synch = 0; + eNB->is_slave = (wait_for_sync>0) ? 1 : 0; + + #ifndef OCP_FRAMEWORK LOG_I(PHY,"Initializing eNB %d CC_id %d : (%s,%s)\n",inst,CC_id,eNB_functions[node_function[CC_id]],eNB_timing[node_timing[CC_id]]); #endif @@ -1636,6 +2001,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst switch (node_function[CC_id]) { case NGFI_RRU_IF5: eNB->do_prach = NULL; + eNB->do_precoding = 0; eNB->fep = eNB_fep_rru_if5; eNB->td = NULL; eNB->te = NULL; @@ -1661,6 +2027,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst } break; case NGFI_RRU_IF4p5: + eNB->do_precoding = 0; eNB->do_prach = do_prach; eNB->fep = eNB_fep_full;//(single_thread_flag==1) ? eNB_fep_full_2thread : eNB_fep_full; eNB->td = NULL; @@ -1679,6 +2046,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst } eNB->rfdevice.host_type = RRH_HOST; eNB->ifdevice.host_type = RRH_HOST; + printf("loading transport interface ...\n"); ret = openair0_transport_load(&eNB->ifdevice, &openair0_cfg[CC_id], (eth_params+CC_id)); printf("openair0_transport_init returns %d for CC_id %d\n",ret,CC_id); if (ret<0) { @@ -1690,6 +2058,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst break; case eNodeB_3GPP: + eNB->do_precoding = (eNB->frame_parms.nb_antennas_tx==1) ? 0 : 1; eNB->do_prach = do_prach; eNB->fep = eNB_fep_full;//(single_thread_flag==1) ? eNB_fep_full_2thread : eNB_fep_full; eNB->td = ulsch_decoding_data;//(single_thread_flag==1) ? ulsch_decoding_data_2thread : ulsch_decoding_data; @@ -1710,26 +2079,27 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst eNB->ifdevice.host_type = BBU_HOST; break; case eNodeB_3GPP_BBU: - eNB->do_prach = do_prach; - eNB->fep = eNB_fep_full;//(single_thread_flag==1) ? eNB_fep_full_2thread : eNB_fep_full; - eNB->td = ulsch_decoding_data;//(single_thread_flag==1) ? ulsch_decoding_data_2thread : ulsch_decoding_data; - eNB->te = dlsch_encoding;//(single_thread_flag==1) ? dlsch_encoding_2threads : dlsch_encoding; - eNB->proc_uespec_rx = phy_procedures_eNB_uespec_RX; - eNB->proc_tx = proc_tx_full; + eNB->do_precoding = (eNB->frame_parms.nb_antennas_tx==1) ? 0 : 1; + eNB->do_prach = do_prach; + eNB->fep = eNB_fep_full;//(single_thread_flag==1) ? eNB_fep_full_2thread : eNB_fep_full; + eNB->td = ulsch_decoding_data;//(single_thread_flag==1) ? ulsch_decoding_data_2thread : ulsch_decoding_data; + eNB->te = dlsch_encoding;//(single_thread_flag==1) ? dlsch_encoding_2threads : dlsch_encoding; + eNB->proc_uespec_rx = phy_procedures_eNB_uespec_RX; + eNB->proc_tx = proc_tx_full; if (eNB->node_timing == synch_to_other) { - eNB->tx_fh = tx_fh_if5_mobipass; - eNB->rx_fh = rx_fh_slave; - eNB->fh_asynch = fh_if5_asynch_UL; + eNB->tx_fh = tx_fh_if5_mobipass; + eNB->rx_fh = rx_fh_slave; + eNB->fh_asynch = fh_if5_asynch_UL; } else { - eNB->tx_fh = tx_fh_if5; - eNB->rx_fh = rx_fh_if5; - eNB->fh_asynch = NULL; + eNB->tx_fh = tx_fh_if5; + eNB->rx_fh = rx_fh_if5; + eNB->fh_asynch = NULL; } - eNB->start_rf = NULL; - eNB->start_if = start_if; + eNB->start_rf = NULL; + eNB->start_if = start_if; eNB->rfdevice.host_type = BBU_HOST; eNB->ifdevice.host_type = BBU_HOST; @@ -1742,6 +2112,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst } break; case NGFI_RCC_IF4p5: + eNB->do_precoding = 0; eNB->do_prach = do_prach; eNB->fep = NULL; eNB->td = ulsch_decoding_data;//(single_thread_flag==1) ? ulsch_decoding_data_2thread : ulsch_decoding_data; @@ -1765,6 +2136,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst break; case NGFI_RAU_IF4p5: + eNB->do_precoding = 0; eNB->do_prach = do_prach; eNB->fep = NULL; @@ -1792,7 +2164,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst } } - if (setup_eNB_buffers(PHY_vars_eNB_g[inst],&openair0_cfg[0])!=0) { + if (setup_eNB_buffers(PHY_vars_eNB_g[inst],&openair0_cfg[CC_id])!=0) { printf("Exiting, cannot initialize eNodeB Buffers\n"); exit(-1); } diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 1988686901b7edd1b73292862b31ebef5671b47b..6a2aa28d7a4c19a1c0838a534e9850e2d6c39bdc 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -112,7 +112,7 @@ extern int netlink_init(void); // In lte-enb.c extern int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_cfg); -extern void init_eNB(eNB_func_t *, eNB_timing_t *,int,eth_params_t *,int); +extern void init_eNB(eNB_func_t *, eNB_timing_t *,int,eth_params_t *,int,int); extern void stop_eNB(int); extern void kill_eNB_proc(void); @@ -160,6 +160,9 @@ volatile int oai_exit = 0; +static clock_source_t clock_source = internal; + +static wait_for_sync = 0; static char UE_flag=0; unsigned int mmapped_dma=0; @@ -379,6 +382,7 @@ void help (void) { printf(" --ue-scan_carrier set UE to scan around carrier\n"); printf(" --loop-memory get softmodem (UE) to loop through memory instead of acquiring from HW\n"); printf(" --mmapped-dma sets flag for improved EXMIMO UE performance\n"); + printf(" --external-clock tells hardware to use an external clock reference\n"); printf(" --usim-test use XOR autentication algo in case of test usim mode\n"); printf(" --single-thread-disable. Disables single-thread mode in lte-softmodem\n"); printf(" -C Set the downlink frequency for all component carriers\n"); @@ -652,7 +656,7 @@ void *l2l1_task(void *arg) #endif - + static void get_options (int argc, char **argv) { @@ -689,6 +693,8 @@ static void get_options (int argc, char **argv) LONG_OPTION_PHYTEST, LONG_OPTION_USIMTEST, LONG_OPTION_MMAPPED_DMA, + LONG_OPTION_EXTERNAL_CLOCK, + LONG_OPTION_WAIT_FOR_SYNC, LONG_OPTION_SINGLE_THREAD_DISABLE, #if T_TRACER LONG_OPTION_T_PORT, @@ -716,6 +722,8 @@ static void get_options (int argc, char **argv) {"phy-test", no_argument, NULL, LONG_OPTION_PHYTEST}, {"usim-test", no_argument, NULL, LONG_OPTION_USIMTEST}, {"mmapped-dma", no_argument, NULL, LONG_OPTION_MMAPPED_DMA}, + {"external-clock", no_argument, NULL, LONG_OPTION_EXTERNAL_CLOCK}, + {"wait-for-sync", no_argument, NULL, LONG_OPTION_WAIT_FOR_SYNC}, {"single-thread-disable", no_argument, NULL, LONG_OPTION_SINGLE_THREAD_DISABLE}, #if T_TRACER {"T_port", required_argument, 0, LONG_OPTION_T_PORT}, @@ -824,7 +832,15 @@ static void get_options (int argc, char **argv) case LONG_OPTION_SINGLE_THREAD_DISABLE: single_thread_flag = 0; break; - + + case LONG_OPTION_EXTERNAL_CLOCK: + clock_source = external; + break; + + case LONG_OPTION_WAIT_FOR_SYNC: + wait_for_sync = 1; + break; + #if T_TRACER case LONG_OPTION_T_PORT: { extern int T_port; @@ -1335,6 +1351,7 @@ void init_openair0() { openair0_cfg[card].num_rb_dl=frame_parms[0]->N_RB_DL; + openair0_cfg[card].clock_source = clock_source; openair0_cfg[card].tx_num_channels=min(2,((UE_flag==0) ? PHY_vars_eNB_g[0][0]->frame_parms.nb_antennas_tx : PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_tx)); openair0_cfg[card].rx_num_channels=min(2,((UE_flag==0) ? PHY_vars_eNB_g[0][0]->frame_parms.nb_antennas_rx : PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx)); @@ -1618,14 +1635,11 @@ int main( int argc, char **argv ) PHY_vars_eNB_g[0] = malloc(sizeof(PHY_VARS_eNB*)); for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - PHY_vars_eNB_g[0][CC_id] = init_lte_eNB(frame_parms[CC_id],0,frame_parms[CC_id]->Nid_cell,abstraction_flag); - PHY_vars_eNB_g[0][CC_id]->CC_id = CC_id; - + PHY_vars_eNB_g[0][CC_id] = init_lte_eNB(frame_parms[CC_id],0,frame_parms[CC_id]->Nid_cell,node_function[CC_id],abstraction_flag); PHY_vars_eNB_g[0][CC_id]->ue_dl_rb_alloc=0x1fff; PHY_vars_eNB_g[0][CC_id]->target_ue_dl_mcs=target_dl_mcs; PHY_vars_eNB_g[0][CC_id]->ue_ul_nb_rb=6; PHY_vars_eNB_g[0][CC_id]->target_ue_ul_mcs=target_ul_mcs; - // initialization for phy-test for (k=0;k<NUMBER_OF_UE_MAX;k++) { PHY_vars_eNB_g[0][CC_id]->transmission_mode[k] = transmission_mode; @@ -1637,41 +1651,43 @@ int main( int argc, char **argv ) for (re=0; re<frame_parms[CC_id]->ofdm_symbol_size; re++) PHY_vars_eNB_g[0][CC_id]->common_vars.beam_weights[0][0][j][re] = 0x00007fff/frame_parms[CC_id]->nb_antennas_tx; } + if (phy_test==1) PHY_vars_eNB_g[0][CC_id]->mac_enabled = 0; else PHY_vars_eNB_g[0][CC_id]->mac_enabled = 1; - + if (PHY_vars_eNB_g[0][CC_id]->mac_enabled == 0) { //set default parameters for testing mode for (i=0; i<NUMBER_OF_UE_MAX; i++) { - PHY_vars_eNB_g[0][CC_id]->pusch_config_dedicated[i].betaOffset_ACK_Index = beta_ACK; - PHY_vars_eNB_g[0][CC_id]->pusch_config_dedicated[i].betaOffset_RI_Index = beta_RI; - PHY_vars_eNB_g[0][CC_id]->pusch_config_dedicated[i].betaOffset_CQI_Index = beta_CQI; - - PHY_vars_eNB_g[0][CC_id]->scheduling_request_config[i].sr_PUCCH_ResourceIndex = i; - PHY_vars_eNB_g[0][CC_id]->scheduling_request_config[i].sr_ConfigIndex = 7+(i%3); - PHY_vars_eNB_g[0][CC_id]->scheduling_request_config[i].dsr_TransMax = sr_n4; + PHY_vars_eNB_g[0][CC_id]->pusch_config_dedicated[i].betaOffset_ACK_Index = beta_ACK; + PHY_vars_eNB_g[0][CC_id]->pusch_config_dedicated[i].betaOffset_RI_Index = beta_RI; + PHY_vars_eNB_g[0][CC_id]->pusch_config_dedicated[i].betaOffset_CQI_Index = beta_CQI; + + PHY_vars_eNB_g[0][CC_id]->scheduling_request_config[i].sr_PUCCH_ResourceIndex = i; + PHY_vars_eNB_g[0][CC_id]->scheduling_request_config[i].sr_ConfigIndex = 7+(i%3); + PHY_vars_eNB_g[0][CC_id]->scheduling_request_config[i].dsr_TransMax = sr_n4; } } - + compute_prach_seq(&PHY_vars_eNB_g[0][CC_id]->frame_parms.prach_config_common, - PHY_vars_eNB_g[0][CC_id]->frame_parms.frame_type, - PHY_vars_eNB_g[0][CC_id]->X_u); - + PHY_vars_eNB_g[0][CC_id]->frame_parms.frame_type, + PHY_vars_eNB_g[0][CC_id]->X_u); + + PHY_vars_eNB_g[0][CC_id]->rx_total_gain_dB = (int)rx_gain[CC_id][0]; if (frame_parms[CC_id]->frame_type==FDD) { - PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 0; + PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 0; } else { - if (frame_parms[CC_id]->N_RB_DL == 100) - PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 624; - else if (frame_parms[CC_id]->N_RB_DL == 50) - PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 624/2; - else if (frame_parms[CC_id]->N_RB_DL == 25) - PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 624/4; + if (frame_parms[CC_id]->N_RB_DL == 100) + PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 624; + else if (frame_parms[CC_id]->N_RB_DL == 50) + PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 624/2; + else if (frame_parms[CC_id]->N_RB_DL == 25) + PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 624/4; } } - + NB_eNB_INST=1; NB_INST=1; @@ -1851,9 +1867,9 @@ int main( int argc, char **argv ) } } else { - init_eNB(node_function,node_timing,1,eth_params,single_thread_flag); - // Sleep to allow all threads to setup - + printf("Initializing eNB threads\n"); + init_eNB(node_function,node_timing,1,eth_params,single_thread_flag,wait_for_sync); + number_of_cards = 1; for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { diff --git a/targets/RT/USER/rru_if4p5_usrp.gtkw b/targets/RT/USER/rru_if4p5_usrp.gtkw index df8de754db63657dad91a994779180c2e6dae4a8..1a13e6d15f1e243af267b137390b0145a2956bec 100644 --- a/targets/RT/USER/rru_if4p5_usrp.gtkw +++ b/targets/RT/USER/rru_if4p5_usrp.gtkw @@ -1,15 +1,15 @@ [*] [*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI -[*] Mon Aug 1 18:43:22 2016 +[*] Sun Jan 15 07:26:50 2017 [*] [dumpfile] "/tmp/openair_dump_eNB.vcd" -[dumpfile_mtime] "Mon Aug 1 18:41:49 2016" -[dumpfile_size] 22622 -[savefile] "/home/papillon/openairinterface5g/targets/RT/USER/rru_if4p5_usrp.gtkw" -[timestart] 0 +[dumpfile_mtime] "Sun Jan 15 07:04:19 2017" +[dumpfile_size] 18140627 +[savefile] "/home/uprru1/oai/openairinterface5g/targets/RT/USER/rru_if4p5_usrp.gtkw" +[timestart] 29977510000 [size] 1301 716 [pos] 309 0 -*-19.793451 29983948856 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +*-21.793451 29983948856 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 [sst_width] 284 [signals_width] 262 [sst_expanded] 1 @@ -17,10 +17,12 @@ @28 functions.trx_read functions.trx_write +@25 +variables.trx_write_flags[63:0] +@28 functions.trx_write_if functions.send_if4 functions.trx_read_if -@29 functions.recv_if4 @24 variables.trx_ts[63:0] @@ -40,121 +42,8 @@ variables.subframe_number_RX1_eNB[63:0] variables.frame_number_TX1_eNB[63:0] variables.subframe_number_TX1_eNB[63:0] @28 -functions.phy_enb_sfgen +functions.phy_eNB_ofdm_mod_l functions.phy_eNB_slot_fep functions.phy_enb_prach_rx -@24 -variables.dci_info[63:0] -variables.ue0_BO[63:0] -@420 -variables.ue0_BSR[63:0] -variables.ue0_timing_advance[63:0] -@28 -functions.macxface_initiate_ra_proc -functions.macxface_terminate_ra_proc -functions.phy_enb_ulsch_msg3 -functions.macxface_SR_indication -@420 -variables.ue0_SR_ENERGY[63:0] -variables.ue0_SR_THRES[63:0] -@28 -functions.phy_enb_ulsch_decoding0 -@24 -variables.ue0_res0[63:0] -@420 -variables.ue0_rssi0[63:0] -variables.ue0_MCS0[63:0] -variables.ue0_RB0[63:0] -@24 -variables.ue0_ROUND0[63:0] -variables.ue0_SFN0[63:0] -@28 -functions.phy_enb_ulsch_decoding1 -@24 -variables.ue0_res1[63:0] -@420 -variables.ue0_rssi1[63:0] -variables.ue0_MCS1[63:0] -variables.ue0_RB1[63:0] -@24 -variables.ue0_ROUND1[63:0] -variables.ue0_SFN1[63:0] -@28 -functions.phy_enb_ulsch_decoding2 -@24 -variables.ue0_res2[63:0] -@420 -variables.ue0_rssi2[63:0] -variables.ue0_MCS2[63:0] -variables.ue0_RB2[63:0] -@24 -variables.ue0_ROUND2[63:0] -variables.ue0_SFN2[63:0] -@28 -functions.phy_enb_ulsch_decoding3 -@24 -variables.ue0_res3[63:0] -@420 -variables.ue0_rssi3[63:0] -variables.ue0_MCS3[63:0] -variables.ue0_RB3[63:0] -@24 -variables.ue0_ROUND3[63:0] -variables.ue0_SFN3[63:0] -@28 -functions.phy_enb_ulsch_decoding4 -@420 -variables.ue0_rssi4[63:0] -@24 -variables.ue0_res4[63:0] -@420 -variables.ue0_MCS4[63:0] -variables.ue0_RB4[63:0] -@24 -variables.ue0_ROUND4[63:0] -variables.ue0_SFN4[63:0] -@28 -functions.phy_enb_ulsch_decoding5 -@24 -variables.ue0_res5[63:0] -@420 -variables.ue0_rssi5[63:0] -variables.ue0_MCS5[63:0] -variables.ue0_RB5[63:0] -@24 -variables.ue0_ROUND5[63:0] -variables.ue0_SFN5[63:0] -@28 -functions.phy_enb_ulsch_decoding6 -@24 -variables.ue0_res6[63:0] -@420 -variables.ue0_rssi6[63:0] -variables.ue0_MCS6[63:0] -variables.ue0_RB6[63:0] -@24 -variables.ue0_ROUND6[63:0] -variables.ue0_SFN6[63:0] -@28 -functions.phy_enb_ulsch_decoding7 -@24 -variables.ue0_res7[63:0] -@420 -variables.ue0_rssi7[63:0] -variables.ue0_MCS7[63:0] -variables.ue0_RB7[63:0] -@24 -variables.ue0_ROUND7[63:0] -variables.ue0_SFN7[63:0] -@28 -functions.phy_enb_prach_rx -functions.phy_eNB_dlsch_encoding -functions.phy_eNB_dlsch_modulation -functions.phy_eNB_dlsch_scrambling -functions.phy_enb_pdcch_tx -functions.phy_enb_rs_tx -functions.rrc_mac_config_req -functions.rlc_data_req -functions.udp_enb_task [pattern_trace] 1 [pattern_trace] 0 diff --git a/targets/SIMU/USER/init_lte.c b/targets/SIMU/USER/init_lte.c index 3e0936451f202221c8fbbbeb2e9eee152a6edb53..62273185b23445b689c6ae6774cbc763aa420253 100644 --- a/targets/SIMU/USER/init_lte.c +++ b/targets/SIMU/USER/init_lte.c @@ -41,6 +41,7 @@ PHY_VARS_eNB* init_lte_eNB(LTE_DL_FRAME_PARMS *frame_parms, uint8_t eNB_id, uint8_t Nid_cell, + eNB_func_t node_function, uint8_t abstraction_flag) { @@ -54,6 +55,7 @@ PHY_VARS_eNB* init_lte_eNB(LTE_DL_FRAME_PARMS *frame_parms, PHY_vars_eNB->frame_parms.nushift = PHY_vars_eNB->frame_parms.Nid_cell%6; phy_init_lte_eNB(PHY_vars_eNB,0,abstraction_flag); + LOG_I(PHY,"init eNB: Node Function %d\n",node_function); LOG_I(PHY,"init eNB: Nid_cell %d\n", frame_parms->Nid_cell); LOG_I(PHY,"init eNB: frame_type %d,tdd_config %d\n", frame_parms->frame_type,frame_parms->tdd_config); LOG_I(PHY,"init eNB: number of ue max %d number of enb max %d number of harq pid max %d\n", @@ -61,27 +63,32 @@ PHY_VARS_eNB* init_lte_eNB(LTE_DL_FRAME_PARMS *frame_parms, LOG_I(PHY,"init eNB: N_RB_DL %d\n", frame_parms->N_RB_DL); LOG_I(PHY,"init eNB: prach_config_index %d\n", frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex); + if (node_function >= NGFI_RRU_IF5) + // For RRU, don't allocate DLSCH/ULSCH Transport channel buffers + return (PHY_vars_eNB); + for (i=0; i<NUMBER_OF_UE_MAX; i++) { + LOG_I(PHY,"Allocating Transport Channel Buffers for DLSCH, UE %d\n",i); for (j=0; j<2; j++) { PHY_vars_eNB->dlsch[i][j] = new_eNB_dlsch(1,8,NSOFT,frame_parms->N_RB_DL,abstraction_flag,frame_parms); - if (!PHY_vars_eNB->dlsch[i][j]) { - LOG_E(PHY,"Can't get eNB dlsch structures for UE %d \n", i); - exit(-1); + LOG_E(PHY,"Can't get eNB dlsch structures for UE %d \n", i); + exit(-1); } else { - LOG_D(PHY,"dlsch[%d][%d] => %p\n",i,j,PHY_vars_eNB->dlsch[i][j]); - PHY_vars_eNB->dlsch[i][j]->rnti=0; + LOG_D(PHY,"dlsch[%d][%d] => %p\n",i,j,PHY_vars_eNB->dlsch[i][j]); + PHY_vars_eNB->dlsch[i][j]->rnti=0; } } - + + LOG_I(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n"); PHY_vars_eNB->ulsch[1+i] = new_eNB_ulsch(MAX_TURBO_ITERATIONS,frame_parms->N_RB_UL, abstraction_flag); - + if (!PHY_vars_eNB->ulsch[1+i]) { LOG_E(PHY,"Can't get eNB ulsch structures\n"); exit(-1); } - + // this is the transmission mode for the signalling channels // this will be overwritten with the real transmission mode by the RRC once the UE is connected PHY_vars_eNB->transmission_mode[i] = frame_parms->nb_antenna_ports_eNB==1 ? 1 : 2; @@ -91,7 +98,7 @@ PHY_VARS_eNB* init_lte_eNB(LTE_DL_FRAME_PARMS *frame_parms, gettimeofday(&ts, NULL); PHY_vars_eNB->ulsch[1+i]->reference_timestamp_ms = ts.tv_sec * 1000 + ts.tv_usec / 1000; int j; - + for (j=0; j<10; j++) { initialize(&PHY_vars_eNB->ulsch[1+i]->loc_rss_list[j]); initialize(&PHY_vars_eNB->ulsch[1+i]->loc_rssi_list[j]); @@ -99,7 +106,7 @@ PHY_VARS_eNB* init_lte_eNB(LTE_DL_FRAME_PARMS *frame_parms, initialize(&PHY_vars_eNB->ulsch[1+i]->loc_timing_advance_list[j]); initialize(&PHY_vars_eNB->ulsch[1+i]->loc_timing_update_list[j]); } - + initialize(&PHY_vars_eNB->ulsch[1+i]->tot_loc_rss_list); initialize(&PHY_vars_eNB->ulsch[1+i]->tot_loc_rssi_list); initialize(&PHY_vars_eNB->ulsch[1+i]->tot_loc_subcarrier_rss_list); @@ -107,37 +114,36 @@ PHY_VARS_eNB* init_lte_eNB(LTE_DL_FRAME_PARMS *frame_parms, initialize(&PHY_vars_eNB->ulsch[1+i]->tot_loc_timing_update_list); #endif } - + // ULSCH for RA PHY_vars_eNB->ulsch[0] = new_eNB_ulsch(MAX_TURBO_ITERATIONS, frame_parms->N_RB_UL, abstraction_flag); - + if (!PHY_vars_eNB->ulsch[0]) { LOG_E(PHY,"Can't get eNB ulsch structures\n"); exit(-1); } - PHY_vars_eNB->dlsch_SI = new_eNB_dlsch(1,8,NSOFT,frame_parms->N_RB_DL, abstraction_flag, frame_parms); LOG_D(PHY,"eNB %d : SI %p\n",eNB_id,PHY_vars_eNB->dlsch_SI); PHY_vars_eNB->dlsch_ra = new_eNB_dlsch(1,8,NSOFT,frame_parms->N_RB_DL, abstraction_flag, frame_parms); LOG_D(PHY,"eNB %d : RA %p\n",eNB_id,PHY_vars_eNB->dlsch_ra); PHY_vars_eNB->dlsch_MCH = new_eNB_dlsch(1,8,NSOFT,frame_parms->N_RB_DL, 0, frame_parms); LOG_D(PHY,"eNB %d : MCH %p\n",eNB_id,PHY_vars_eNB->dlsch_MCH); - - + + PHY_vars_eNB->rx_total_gain_dB=130; - + for(i=0; i<NUMBER_OF_UE_MAX; i++) PHY_vars_eNB->mu_mimo_mode[i].dl_pow_off = 2; - + PHY_vars_eNB->check_for_total_transmissions = 0; - + PHY_vars_eNB->check_for_MUMIMO_transmissions = 0; - + PHY_vars_eNB->FULL_MUMIMO_transmissions = 0; - + PHY_vars_eNB->check_for_SUMIMO_transmissions = 0; - - PHY_vars_eNB->frame_parms.pucch_config_common.deltaPUCCH_Shift = 1; + + PHY_vars_eNB->frame_parms.pucch_config_common.deltaPUCCH_Shift = 1; return (PHY_vars_eNB); } @@ -271,7 +277,7 @@ void init_lte_vars(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs], PHY_vars_eNB_g[eNB_id] = (PHY_VARS_eNB**) malloc(MAX_NUM_CCs*sizeof(PHY_VARS_eNB*)); for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - PHY_vars_eNB_g[eNB_id][CC_id] = init_lte_eNB(frame_parms[CC_id],eNB_id,Nid_cell,abstraction_flag); + PHY_vars_eNB_g[eNB_id][CC_id] = init_lte_eNB(frame_parms[CC_id],eNB_id,Nid_cell,eNodeB_3GPP,abstraction_flag); PHY_vars_eNB_g[eNB_id][CC_id]->Mod_id=eNB_id; PHY_vars_eNB_g[eNB_id][CC_id]->CC_id=CC_id; } diff --git a/targets/SIMU/USER/init_lte.h b/targets/SIMU/USER/init_lte.h index bcb257056502c0bcab711555e3e93a805a2b0745..e49c24a15b75c82a568ccdfd4ea79d9aa64a39e0 100644 --- a/targets/SIMU/USER/init_lte.h +++ b/targets/SIMU/USER/init_lte.h @@ -25,6 +25,7 @@ PHY_VARS_eNB* init_lte_eNB(LTE_DL_FRAME_PARMS *frame_parms, uint8_t eNB_id, uint8_t Nid_cell, + eNB_func_t node_function, uint8_t abstraction_flag); PHY_VARS_UE* init_lte_UE(LTE_DL_FRAME_PARMS *frame_parms,