From 69a7658c545a33189d573701babee2e87fb57240 Mon Sep 17 00:00:00 2001 From: frtabu <francois.taburet@nokia-bell-labs.com> Date: Mon, 16 Dec 2019 17:53:22 +0100 Subject: [PATCH] USRP device cleanup including record player as config option + some cppcheck warning/errors fixes --- cmake_targets/CMakeLists.txt | 1 + common/config/config_userapi.c | 5 +- openair1/PHY/NR_TRANSPORT/nr_ulsch.h | 2 +- openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c | 25 +- .../PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c | 53 +- openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c | 9 +- .../NR_UE_TRANSPORT/nr_transport_proto_ue.h | 2 +- openair1/PHY/NR_UE_TRANSPORT/pbch_nr.c | 2 +- openair1/SCHED_NR_UE/fapi_nr_ue_l1.c | 14 +- openair1/SIMULATION/NR_PHY/dlschsim.c | 2 +- openair2/COMMON/platform_types.h | 7 + openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 10 +- openair2/NETWORK_DRIVER/UE_IP/common.c | 6 +- openair2/UTIL/OTG/otg_rx_socket.c | 2 +- targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp | 926 ++++++++---------- targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.h | 68 +- .../ARCH/USRP/USERSPACE/LIB/usrp_lib_config.c | 73 ++ 17 files changed, 584 insertions(+), 623 deletions(-) create mode 100644 targets/ARCH/USRP/USERSPACE/LIB/usrp_lib_config.c diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index a0620d8345..e429b9e58f 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -529,6 +529,7 @@ set (SHLIB_LOADER_SOURCES include_directories("${OPENAIR_TARGETS}/ARCH/USRP/USERSPACE/LIB/") set(HWLIB_USRP_SOURCE ${OPENAIR_TARGETS}/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp + ${OPENAIR_TARGETS}/ARCH/USRP/USERSPACE/LIB/usrp_lib_config.c ) add_library(oai_usrpdevif MODULE ${HWLIB_USRP_SOURCE} ) target_link_libraries(oai_usrpdevif uhd) diff --git a/common/config/config_userapi.c b/common/config/config_userapi.c index 56c3c0951f..67fdc2c920 100644 --- a/common/config/config_userapi.c +++ b/common/config/config_userapi.c @@ -386,13 +386,12 @@ int config_setdefault_string(paramdef_t *cfgoptions, char *prefix) { status=1; if (cfgoptions->numelt == 0 ) { - config_check_valptr(cfgoptions, (char **)(cfgoptions->strptr), sizeof(char *)); config_check_valptr(cfgoptions, cfgoptions->strptr, strlen(cfgoptions->defstrval)+1); sprintf(*(cfgoptions->strptr), "%s",cfgoptions->defstrval); printf_params("[CONFIG] %s.%s set to default value \"%s\"\n", ((prefix == NULL) ? "" : prefix), cfgoptions->optname, *(cfgoptions->strptr)); } else { - sprintf((char *)*(cfgoptions->strptr), "%s",cfgoptions->defstrval); - printf_params("[CONFIG] %s.%s set to default value \"%s\"\n", ((prefix == NULL) ? "" : prefix), cfgoptions->optname, (char *)*(cfgoptions->strptr)); + sprintf((char *)(cfgoptions->strptr), "%s",cfgoptions->defstrval); + printf_params("[CONFIG] %s.%s set to default value \"%s\"\n", ((prefix == NULL) ? "" : prefix), cfgoptions->optname, (char *)(cfgoptions->strptr)); } } diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h index dc7489ea51..b3a4948a2a 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h @@ -32,7 +32,7 @@ #include "PHY/defs_gNB.h" -void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch); +void free_gNB_ulsch(NR_gNB_ULSCH_t **ulsch); NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint8_t N_RB_UL, uint8_t abstraction_flag); diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index db0c601b25..2e8f2af5f5 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -58,10 +58,9 @@ static uint64_t nb_error_decod =0; //extern double cpuf; -void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch) -{ - +void free_gNB_ulsch(NR_gNB_ULSCH_t **ulschptr) { int i,r; + NR_gNB_ULSCH_t *ulsch = *ulschptr; if (ulsch) { for (i=0; i<NR_MAX_ULSCH_HARQ_PROCESSES; i++) { @@ -92,7 +91,7 @@ void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch) } } free16(ulsch,sizeof(NR_gNB_ULSCH_t)); - ulsch = NULL; + *ulschptr = NULL; } } @@ -168,8 +167,7 @@ NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint8_t N_RB_UL, uint8 } printf("new_gNB_ulsch with size %zu: exit_flag = %u\n",sizeof(NR_UL_gNB_HARQ_t), exit_flag); - free_gNB_ulsch(ulsch); - + free_gNB_ulsch(&ulsch); return(NULL); } @@ -307,6 +305,10 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, t_nrLDPC_dec_params* p_decParams = &decParams; t_nrLDPC_time_stats procTime; t_nrLDPC_time_stats* p_procTime = &procTime ; + if (!harq_process) { + printf("ulsch_decoding.c: NULL harq_process pointer\n"); + return (ulsch->max_ldpc_iterations + 1); + } t_nrLDPC_procBuf** p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf; int16_t z [68*384]; @@ -338,11 +340,6 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, return (ulsch->max_ldpc_iterations + 1); } - if (!harq_process) { - printf("ulsch_decoding.c: NULL harq_process pointer\n"); - return (ulsch->max_ldpc_iterations + 1); - } - if (!frame_parms) { printf("ulsch_decoding.c: NULL frame_parms pointer\n"); return (ulsch->max_ldpc_iterations + 1); @@ -531,7 +528,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, write_output("decoder_in.m","dec",&harq_process->d[0][0],(3*8*Kr_bytes)+12,1,0); } - printf("decoder input(segment %d) :",r); + printf("decoder input(segment %u) :",r); int i; for (i=0;i<(3*8*Kr_bytes)+12;i++) printf("%d : %d\n",i,harq_process->d[r][i]); @@ -620,7 +617,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, //printf("output decoder %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]); for (int k=0;k<A>>3;k++) printf("output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]); - printf("no_iterations_ldpc %d (ret %d)\n",no_iteration_ldpc,ret); + printf("no_iterations_ldpc %d (ret %u)\n",no_iteration_ldpc,ret); //write_output("dec_output.m","dec0",harq_process->c[0],Kr_bytes,1,4); #endif @@ -708,7 +705,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0)); #ifdef DEBUG_ULSCH_DECODING - printf("Segment %d : Kr= %d bytes\n",r,Kr_bytes); + printf("Segment %u : Kr= %u bytes\n",r,Kr_bytes); printf("copied %d bytes to b sequence (harq_pid %d)\n", (Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid); printf("b[0] = %x,c[%d] = %x\n", diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index 53d481919e..6a277cdc42 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -56,11 +56,11 @@ notifiedFIFO_elt_t *msgToPush; //extern double cpuf; -void free_nr_ue_dlsch(NR_UE_DLSCH_t *dlsch) +void free_nr_ue_dlsch(NR_UE_DLSCH_t **dlschptr) { int i,r; - + NR_UE_DLSCH_t *dlsch=*dlschptr; if (dlsch) { for (i=0; i<dlsch->Mdlharq; i++) { if (dlsch->harq_processes[i]) { @@ -175,7 +175,7 @@ NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint } printf("new_ue_dlsch with size %zu: exit_flag = %u\n",sizeof(NR_DL_UE_HARQ_t), exit_flag); - free_nr_ue_dlsch(dlsch); + free_nr_ue_dlsch(&dlsch); return(NULL); } @@ -232,6 +232,11 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, t_nrLDPC_dec_params* p_decParams = &decParams; t_nrLDPC_time_stats procTime; t_nrLDPC_time_stats* p_procTime =&procTime ; + + if (!harq_process) { + printf("dlsch_decoding.c: NULL harq_process pointer\n"); + return(dlsch->max_ldpc_iterations + 1); + } t_nrLDPC_procBuf** p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf; int16_t z [68*384]; @@ -260,11 +265,6 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, return(dlsch->max_ldpc_iterations + 1); } - if (!harq_process) { - printf("dlsch_decoding.c: NULL harq_process pointer\n"); - return(dlsch->max_ldpc_iterations + 1); - } - if (!frame_parms) { printf("dlsch_decoding.c: NULL frame_parms pointer\n"); return(dlsch->max_ldpc_iterations + 1); @@ -498,7 +498,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, write_output("decoder_in.m","dec",&harq_process->d[0][0],(3*8*Kr_bytes)+12,1,0); } - printf("decoder input(segment %d) :",r); + printf("decoder input(segment %u) :",r); int i; for (i=0;i<(3*8*Kr_bytes)+12;i++) printf("%d : %d\n",i,harq_process->d[r][i]); @@ -564,7 +564,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, // Fixme: correct type is unsigned, but nrLDPC_decoder and all called behind use signed int if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) { - printf("\x1B[34m" "Segment %d CRC OK\n\033[0m",r); + printf("\x1B[34m" "Segment %u CRC OK\n\033[0m",r); //Temporary hack no_iteration_ldpc = dlsch->max_ldpc_iterations; ret = no_iteration_ldpc; @@ -594,7 +594,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, //printf("output decoder %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]); for (int k=0;k<A>>3;k++) printf("output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]); - printf("no_iterations_ldpc %d (ret %d)\n",no_iteration_ldpc,ret); + printf("no_iterations_ldpc %d (ret %u)\n",no_iteration_ldpc,ret); //write_output("dec_output.m","dec0",harq_process->c[0],Kr_bytes,1,4); #endif @@ -696,7 +696,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0)); #ifdef DEBUG_DLSCH_DECODING - printf("Segment %d : Kr= %d bytes\n",r,Kr_bytes); + printf("Segment %u : Kr= %u bytes\n",r,Kr_bytes); printf("copied %d bytes to b sequence (harq_pid %d)\n", (Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid); printf("b[0] = %x,c[%d] = %x\n", @@ -766,6 +766,10 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, t_nrLDPC_time_stats procTime; t_nrLDPC_time_stats* p_procTime =&procTime ; int8_t llrProcBuf[OAI_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32))); + if (!harq_process) { + printf("dlsch_decoding.c: NULL harq_process pointer\n"); + return(dlsch->max_ldpc_iterations); + } t_nrLDPC_procBuf* p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf[0]; uint8_t Nl=4; int16_t z [68*384]; @@ -796,10 +800,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, return(dlsch->max_ldpc_iterations); } - if (!harq_process) { - printf("dlsch_decoding.c: NULL harq_process pointer\n"); - return(dlsch->max_ldpc_iterations); - } + if (!frame_parms) { printf("dlsch_decoding.c: NULL frame_parms pointer\n"); @@ -1006,7 +1007,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, #ifdef DEBUG_DLSCH_DECODING for (int i =0; i<16; i++) - printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,harq_process->w[r][i], r_offset); + printf("rx output deinterleaving w[%d]= %d r_offset %u\n", i,harq_process->w[r][i], r_offset); #endif #if UE_TIMING_TRACE @@ -1065,7 +1066,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, #ifdef DEBUG_DLSCH_DECODING for (int i =0; i<16; i++) - printf("rx output ratematching d[%d]= %d r_offset %d\n", i,harq_process->d[r][i], r_offset); + printf("rx output ratematching d[%d]= %d r_offset %u\n", i,harq_process->d[r][i], r_offset); #endif #ifdef DEBUG_DLSCH_DECODING @@ -1075,7 +1076,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, write_output("decoder_in.m","dec",&harq_process->d[0][96],(3*8*Kr_bytes)+12,1,0); } - printf("decoder input(segment %d) :",r); + printf("decoder input(segment %u) :",r); for (int i=0;i<(3*8*Kr_bytes);i++) printf("%d : %d\n",i,harq_process->d[r][i]); printf("\n"); @@ -1153,7 +1154,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, } if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) { - printf("Segment %d CRC OK\n",r); + printf("Segment %u CRC OK\n",r); ret = 2; } else { @@ -1162,7 +1163,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, } //if (!nb_total_decod%10000){ - printf("Error number of iteration LPDC %d %ld/%ld \n", no_iteration_ldpc, nb_error_decod,nb_total_decod);fflush(stdout); + printf("Error number of iteration LPDC %d %lu/%lu \n", no_iteration_ldpc, nb_error_decod,nb_total_decod);fflush(stdout); //} //else @@ -1303,7 +1304,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0)); #ifdef DEBUG_DLSCH_DECODING - printf("Segment %d : Kr= %d bytes\n",r,Kr_bytes); + printf("Segment %u : Kr= %u bytes\n",r,Kr_bytes); printf("copied %d bytes to b sequence (harq_pid %d)\n", (Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid); printf("b[0] = %x,c[%d] = %x\n", @@ -1391,7 +1392,7 @@ void *nr_dlsch_decoding_process(void *arg) //printf("2thread0 llr flag %d tdp flag %d\n",llr8_flag1, tdp->llr8_flag); p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf[r]; nb_symb_sch = harq_process->nb_symbols; - printf("dlsch decoding process frame %d slot %d segment %d r %d nb symb %d \n", frame, proc->nr_tti_rx, proc->num_seg, r, harq_process->nb_symbols); + printf("dlsch decoding process frame %d slot %d segment %d r %u nb symb %d \n", frame, proc->nr_tti_rx, proc->num_seg, r, harq_process->nb_symbols); /* @@ -1554,7 +1555,7 @@ void *nr_dlsch_decoding_process(void *arg) #ifdef DEBUG_DLSCH_DECODING for (int i =0; i<16; i++) - printf("rx output thread 0 deinterleaving w[%d]= %d r_offset %d\n", i,harq_process->w[r][i], r_offset); + printf("rx output thread 0 deinterleaving w[%d]= %d r_offset %u\n", i,harq_process->w[r][i], r_offset); #endif #if UE_TIMING_TRACE @@ -1615,7 +1616,7 @@ void *nr_dlsch_decoding_process(void *arg) write_output("decoder_in.m","dec",&harq_process->d[0][0],(3*8*Kr_bytes)+12,1,0); } - printf("decoder input(segment %d) :",r); + printf("decoder input(segment %u) :",r); int i; for (i=0;i<(3*8*Kr_bytes)+12;i++) printf("%d : %d\n",i,harq_process->d[r][i]); printf("\n"); @@ -1684,7 +1685,7 @@ void *nr_dlsch_decoding_process(void *arg) // Fixme: correct type is unsigned, but nrLDPC_decoder and all called behind use signed int if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) { - printf("Segment %d CRC OK\n",r); + printf("Segment %u CRC OK\n",r); ret = 2; } else { diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c index 1e17f6dab0..a744bb1ef4 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c @@ -71,7 +71,7 @@ uint16_t nr_pbch_extract(int **rxdataF, rxF = &rxdataF[aarx][(symbol+s_offset)*frame_parms->ofdm_symbol_size]; rxF_ext = &rxdataF_ext[aarx][symbol*20*12]; #ifdef DEBUG_PBCH - printf("extract_rbs (nushift %d): rx_offset=%d, symbol %d\n",frame_parms->nushift, + printf("extract_rbs (nushift %d): rx_offset=%d, symbol %u\n",frame_parms->nushift, (rx_offset + ((symbol+s_offset)*(frame_parms->ofdm_symbol_size))),symbol); int16_t *p = (int16_t *)rxF; @@ -425,7 +425,8 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, int max_h=0; int symbol; //uint8_t pbch_a[64]; - uint8_t *pbch_a = malloc(sizeof(uint8_t) * 32); +//FT ?? cppcheck doesn't like pbch_a allocation because of line 525..and i don't get what this variable is for.. +//uint8_t *pbch_a = malloc(sizeof(uint8_t) * NR_POLAR_PBCH_PAYLOAD_BITS); //uint32_t pbch_a_prime; int16_t *pbch_e_rx; uint8_t *decoded_output = nr_ue_pbch_vars->decoded_output; @@ -438,7 +439,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, //uint8_t decoderListSize = 8, pathMetricAppr = 0; //time_stats_t polar_decoder_init,polar_rate_matching,decoding,bit_extraction,deinterleaving; //time_stats_t path_metric,sorting,update_LLR; - memset(&pbch_a[0], 0, sizeof(uint8_t) * NR_POLAR_PBCH_PAYLOAD_BITS); +// FT ?? cppcheck fix memset(&pbch_a[0], 0, sizeof(uint8_t) * NR_POLAR_PBCH_PAYLOAD_BITS); //printf("nr_pbch_ue nid_cell %d\n",frame_parms->Nid_cell); pbch_e_rx = &nr_ue_pbch_vars->llr[0]; @@ -522,7 +523,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, #endif pbch_e_rx = nr_ue_pbch_vars->llr; //demod_pbch_e = nr_ue_pbch_vars->demod_pbch_e; - pbch_a = nr_ue_pbch_vars->pbch_a; +// FT?? cppcheck fix - pbch_a = nr_ue_pbch_vars->pbch_a; #ifdef DEBUG_PBCH //pbch_e_rx = &nr_ue_pbch_vars->llr[0]; short *p = (short *)&(nr_ue_pbch_vars->rxdataF_comp[0][20*12]); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index 7559115a29..a4a329b2cf 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -47,7 +47,7 @@ \brief This function frees memory allocated for a particular DLSCH at UE @param dlsch Pointer to DLSCH to be removed */ -void free_nr_ue_dlsch(NR_UE_DLSCH_t *dlsch); +void free_nr_ue_dlsch(NR_UE_DLSCH_t **dlsch); /** \fn new_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t abstraction_flag) \brief This function allocates structures for a particular DLSCH at UE diff --git a/openair1/PHY/NR_UE_TRANSPORT/pbch_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pbch_nr.c index 334faafecd..4012322111 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pbch_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pbch_nr.c @@ -59,7 +59,7 @@ uint32_t *pseudo_random_gold_sequence(length M_PN, uint32_t cinit) { int size = M_PN * sizeof(uint32_t); - int size_x = (sizeof(int)*M_PN + size; + int size_x = sizeof(int)*M_PN + size; int *x1 = malloc(size_x); int *x2 = malloc(size_x); diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index 1bd7071b99..1b61260d10 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -42,14 +42,16 @@ extern PHY_VARS_NR_UE ***PHY_vars_UE_g; int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response) { - /// module id - module_id_t module_id = scheduled_response->module_id; - /// component carrier id - uint8_t cc_id = scheduled_response->CC_id; - uint32_t i; - int slot = scheduled_response->slot; + if(scheduled_response != NULL){ + /// module id + module_id_t module_id = scheduled_response->module_id; + /// component carrier id + uint8_t cc_id = scheduled_response->CC_id; + uint32_t i; + int slot = scheduled_response->slot; + // Note: we have to handle the thread IDs for this. To be revisited completely. uint8_t thread_id = PHY_vars_UE_g[module_id][cc_id]->current_thread_id[slot]; NR_UE_PDCCH *pdcch_vars2 = PHY_vars_UE_g[module_id][cc_id]->pdcch_vars[thread_id][0]; diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c index aab762b9e2..2980187c42 100644 --- a/openair1/SIMULATION/NR_PHY/dlschsim.c +++ b/openair1/SIMULATION/NR_PHY/dlschsim.c @@ -623,7 +623,7 @@ int main(int argc, char **argv) printf("gNB %d\n", i); free_gNB_dlsch(gNB->dlsch[0][i]); printf("UE %d\n", i); - free_nr_ue_dlsch(UE->dlsch[0][0][i]); + free_nr_ue_dlsch(&(UE->dlsch[0][0][i])); } for (i = 0; i < 2; i++) { diff --git a/openair2/COMMON/platform_types.h b/openair2/COMMON/platform_types.h index 49c1b340a6..2555be081a 100644 --- a/openair2/COMMON/platform_types.h +++ b/openair2/COMMON/platform_types.h @@ -302,5 +302,12 @@ typedef struct protocol_ctxt_s { #define CHECK_CTXT_ARGS(CTXT_Pp) #define exit_fun(msg) exit_function(__FILE__,__FUNCTION__,__LINE__,msg) +#ifdef __cplusplus +extern "C" +{ +#endif void exit_function(const char *file, const char *function, const int line, const char *s); +#ifdef __cplusplus +} +#endif #endif diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index b56e8b11e9..8ee8cdc1c0 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -221,7 +221,7 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP, nr_rlc_ue_t *ue; nr_rlc_entity_t *rb; - LOG_D(RLC, "%s rnti %d srb_flag %d rb_id %d mui %d confirm %d sdu_size %d MBMS_flag %d\n", + LOG_D(RLC, "%s rnti %d srb_flag %d rb_id %ld mui %d confirm %d sdu_size %d MBMS_flag %d\n", __FUNCTION__, rnti, srb_flagP, rb_idP, muiP, confirmP, sdu_sizeP, MBMS_flagP); @@ -824,24 +824,24 @@ rlc_op_status_t rrc_rlc_config_req ( } if ((srb_flagP && !(rb_idP >= 1 && rb_idP <= 2)) || (!srb_flagP && !(rb_idP >= 1 && rb_idP <= 5))) { - LOG_E(RLC, "%s:%d:%s: bad rb_id (%d) (is_srb %d)\n", __FILE__, __LINE__, __FUNCTION__, rb_idP, srb_flagP); + LOG_E(RLC, "%s:%d:%s: bad rb_id (%ld) (is_srb %d)\n", __FILE__, __LINE__, __FUNCTION__, rb_idP, srb_flagP); exit(1); } nr_rlc_manager_lock(nr_rlc_ue_manager); - LOG_D(RLC, "%s:%d:%s: remove rb %d (is_srb %d) for UE %d\n", __FILE__, __LINE__, __FUNCTION__, rb_idP, srb_flagP, ctxt_pP->rnti); + LOG_D(RLC, "%s:%d:%s: remove rb %ld (is_srb %d) for UE %d\n", __FILE__, __LINE__, __FUNCTION__, rb_idP, srb_flagP, ctxt_pP->rnti); ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ctxt_pP->rnti); if (srb_flagP) { if (ue->srb[rb_idP-1] != NULL) { ue->srb[rb_idP-1]->delete(ue->srb[rb_idP-1]); ue->srb[rb_idP-1] = NULL; } else - LOG_W(RLC, "removing non allocated SRB %d, do nothing\n", rb_idP); + LOG_W(RLC, "removing non allocated SRB %ld, do nothing\n", rb_idP); } else { if (ue->drb[rb_idP-1] != NULL) { ue->drb[rb_idP-1]->delete(ue->drb[rb_idP-1]); ue->drb[rb_idP-1] = NULL; } else - LOG_W(RLC, "removing non allocated DRB %d, do nothing\n", rb_idP); + LOG_W(RLC, "removing non allocated DRB %ld, do nothing\n", rb_idP); } /* remove UE if it has no more RB configured */ for (i = 0; i < 2; i++) diff --git a/openair2/NETWORK_DRIVER/UE_IP/common.c b/openair2/NETWORK_DRIVER/UE_IP/common.c index 0d66f42357..86e00ef674 100644 --- a/openair2/NETWORK_DRIVER/UE_IP/common.c +++ b/openair2/NETWORK_DRIVER/UE_IP/common.c @@ -193,7 +193,7 @@ ue_ip_common_class_wireless2ip( break; default: - printk("[UE_IP_DRV][%s] begin RB %d Inst %d Length %d bytes\n",__FUNCTION__,rb_idP,instP,data_lenP); + printk("[UE_IP_DRV][%s] begin RB %ld Inst %d Length %d bytes\n",__FUNCTION__,rb_idP,instP,data_lenP); printk("[UE_IP_DRV][%s] Inst %d: receive unknown message (version=%d)\n",__FUNCTION__,instP,ipv_p->version); } @@ -318,7 +318,7 @@ ue_ip_common_ip2wireless( if (bytes_wrote != UE_IP_PDCPH_SIZE) { printk("[UE_IP_DRV][%s] problem while writing PDCP's header (bytes wrote = %d)\n",__FUNCTION__,bytes_wrote); - printk("rb_id %d, Wrote %d, Header Size %d \n", pdcph.rb_id, bytes_wrote, UE_IP_PDCPH_SIZE); + printk("rb_id %ld, Wrote %d, Header Size %d \n", pdcph.rb_id, bytes_wrote, UE_IP_PDCPH_SIZE); priv_p->stats.tx_dropped ++; return; } @@ -326,7 +326,7 @@ ue_ip_common_ip2wireless( bytes_wrote += ue_ip_netlink_send((char *)skb_pP->data,skb_pP->len); if (bytes_wrote != skb_pP->len+UE_IP_PDCPH_SIZE) { - printk("[UE_IP_DRV][%s] Inst %d, RB_ID %d: problem while writing PDCP's data, bytes_wrote = %d, Data_len %d, PDCPH_SIZE %d\n", + printk("[UE_IP_DRV][%s] Inst %d, RB_ID %ld: problem while writing PDCP's data, bytes_wrote = %d, Data_len %d, PDCPH_SIZE %d\n", __FUNCTION__, instP, pdcph.rb_id, diff --git a/openair2/UTIL/OTG/otg_rx_socket.c b/openair2/UTIL/OTG/otg_rx_socket.c index 9e9b6bf4a1..a343910efd 100644 --- a/openair2/UTIL/OTG/otg_rx_socket.c +++ b/openair2/UTIL/OTG/otg_rx_socket.c @@ -195,7 +195,7 @@ void server_socket_tcp_ip4() /* create new thread for the new connection */ - threadCreate(&id, (void *)recv_ip4_tcp, (void*)csock), "OTG", -1, OAI_PRIORITY_RT_LOW); + threadCreate(&id, (void *)recv_ip4_tcp, (void*)csock, "OTG", -1, OAI_PRIORITY_RT_LOW); LOG_I(OTG,"SOCKET:: TCP-IP4 :: Client n=%d finish transmission\n", cmpt_cl); cmpt_cl+=1; } diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index 8cfa398615..bb05808142 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -30,9 +30,9 @@ #include <stdio.h> #include <uhd/version.hpp> #if UHD_VERSION < 3110000 -#include <uhd/utils/thread_priority.hpp> + #include <uhd/utils/thread_priority.hpp> #else -#include <uhd/utils/thread.hpp> + #include <uhd/utils/thread.hpp> #endif #include <uhd/usrp/multi_usrp.hpp> #include <uhd/version.hpp> @@ -48,26 +48,28 @@ #include "common/utils/LOG/log.h" #include "common_lib.h" #include "assertions.h" -#include <sys/sysinfo.h> + #include <sys/resource.h> +#include "usrp_lib.h" + #ifdef __SSE4_1__ -# include <smmintrin.h> + #include <smmintrin.h> #endif #ifdef __AVX2__ -# include <immintrin.h> + #include <immintrin.h> #endif #ifdef __arm__ -# include <arm_neon.h> + #include <arm_neon.h> #endif /** @addtogroup _USRP_PHY_RF_INTERFACE_ * @{ */ -/*! \brief USRP Configuration */ + typedef struct { // -------------------------------- @@ -106,7 +108,8 @@ typedef struct { int first_tx; //! timestamp of RX packet openair0_timestamp rx_timestamp; - + uint32_t recplay_mode; + recplay_state_t *recplay_state; } usrp_state_t; //void print_notes(void) @@ -128,10 +131,10 @@ int check_ref_locked(usrp_state_t *s,size_t mboard) { for (int i = 0; i < 30 and not ref_locked; i++) { ref_locked = s->usrp->get_mboard_sensor("ref_locked", mboard).to_bool(); - + if (not ref_locked) { - std::cout << "." << std::flush; - boost::this_thread::sleep(boost::posix_time::seconds(1)); + std::cout << "." << std::flush; + boost::this_thread::sleep(boost::posix_time::seconds(1)); } } @@ -140,13 +143,11 @@ int check_ref_locked(usrp_state_t *s,size_t mboard) { } else { std::cout << "FAILED" << std::endl; } - } else { std::cout << boost::format("ref_locked sensor not present on this board.\n"); } return ref_locked; - } static int sync_to_gps(openair0_device *device) { @@ -179,14 +180,13 @@ static int sync_to_gps(openair0_device *device) { for (size_t mboard = 0; mboard < num_mboards; mboard++) { std::cout << "Synchronizing mboard " << mboard << ": " << s->usrp->get_mboard_name(mboard) << std::endl; - bool ref_locked = check_ref_locked(s,mboard); if (ref_locked) { - std::cout << boost::format("Ref Locked\n"); + std::cout << boost::format("Ref Locked\n"); } else { - std::cout << "Failed to lock to GPSDO 10 MHz Reference. Exiting." << std::endl; - exit(EXIT_FAILURE); + std::cout << "Failed to lock to GPSDO 10 MHz Reference. Exiting." << std::endl; + exit(EXIT_FAILURE); } //Wait for GPS lock @@ -265,175 +265,134 @@ static int sync_to_gps(openair0_device *device) { return EXIT_SUCCESS; } -#if defined(USRP_REC_PLAY) -#include "usrp_lib.h" -static FILE *pFile = NULL; -int mmapfd = 0; -int iqfd = 0; -int use_mmap = 1; // default is to use mmap -struct stat sb; -iqrec_t *ms_sample = NULL; // memory for all subframes -unsigned int nb_samples = 0; -unsigned int cur_samples = 0; -int64_t wrap_count = 0; -int64_t wrap_ts = 0; -unsigned int u_sf_mode = 0; // 1=record, 2=replay -unsigned int u_sf_record = 0; // record mode -unsigned int u_sf_replay = 0; // replay mode -char u_sf_filename[1024] = ""; // subframes file path -unsigned int u_sf_max = DEF_NB_SF; // max number of recorded subframes -unsigned int u_sf_loops = DEF_SF_NB_LOOP; // number of loops in replay mode -unsigned int u_sf_read_delay = DEF_SF_DELAY_READ; // read delay in replay mode -unsigned int u_sf_write_delay = DEF_SF_DELAY_WRITE; // write delay in replay mode - -char config_opt_sf_file[] = CONFIG_OPT_SF_FILE; -char config_def_sf_file[] = DEF_SF_FILE; -char config_hlp_sf_file[] = CONFIG_HLP_SF_FILE; -char config_opt_sf_rec[] = CONFIG_OPT_SF_REC; -char config_hlp_sf_rec[] = CONFIG_HLP_SF_REC; -char config_opt_sf_rep[] = CONFIG_OPT_SF_REP; -char config_hlp_sf_rep[] = CONFIG_HLP_SF_REP; -char config_opt_sf_max[] = CONFIG_OPT_SF_MAX; -char config_hlp_sf_max[] = CONFIG_HLP_SF_MAX; -char config_opt_sf_loops[] = CONFIG_OPT_SF_LOOPS; -char config_hlp_sf_loops[] = CONFIG_HLP_SF_LOOPS; -char config_opt_sf_rdelay[] = CONFIG_OPT_SF_RDELAY; -char config_hlp_sf_rdelay[] = CONFIG_HLP_SF_RDELAY; -char config_opt_sf_wdelay[] = CONFIG_OPT_SF_WDELAY; -char config_hlp_sf_wdelay[] = CONFIG_HLP_SF_WDELAY; - -#endif - /*! \brief Called to start the USRP transceiver. Return 0 if OK, < 0 if error @param device pointer to the device structure specific to the RF hardware target */ static int trx_usrp_start(openair0_device *device) { -#if defined(USRP_REC_PLAY) + usrp_state_t *s = (usrp_state_t *)device->priv; - if (u_sf_mode != 2) { // not replay mode -#endif - uhd::set_thread_priority_safe(1.0); - usrp_state_t *s = (usrp_state_t *)device->priv; - // setup GPIO for TDD, GPIO(4) = ATR_RX - //set data direction register (DDR) to output - s->usrp->set_gpio_attr("FP0", "DDR", 0x7f, 0x7f); - //set control register to ATR - s->usrp->set_gpio_attr("FP0", "CTRL", 0x7f,0x7f); - //set ATR register - s->usrp->set_gpio_attr("FP0", "ATR_RX", (1<<4)|(1<<6), 0x7f); - // init recv and send streaming - uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS); - LOG_I(HW,"Time in secs now: %llu \n", s->usrp->get_time_now().to_ticks(s->sample_rate)); - LOG_I(HW,"Time in secs last pps: %llu \n", s->usrp->get_time_last_pps().to_ticks(s->sample_rate)); - - if (s->use_gps == 1 || device->openair0_cfg[0].time_source == external) { - s->wait_for_first_pps = 1; - cmd.time_spec = s->usrp->get_time_last_pps() + uhd::time_spec_t(1.0); - } else { - s->wait_for_first_pps = 0; - cmd.time_spec = s->usrp->get_time_now() + uhd::time_spec_t(0.005); - } + if ( s->recplay_mode == RECPLAY_REPLAYMODE) + return 0; - cmd.stream_now = false; // start at constant delay - s->rx_stream->issue_stream_cmd(cmd); - /*s->tx_md.time_spec = cmd.time_spec + uhd::time_spec_t(1-(double)s->tx_forward_nsamps/s->sample_rate); - s->tx_md.has_time_spec = true; - s->tx_md.start_of_burst = true; - s->tx_md.end_of_burst = false;*/ - s->rx_count = 0; - s->tx_count = 0; - s->rx_timestamp = 0; -#if defined(USRP_REC_PLAY) + // setup GPIO for TDD, GPIO(4) = ATR_RX + //set data direction register (DDR) to output + s->usrp->set_gpio_attr("FP0", "DDR", 0x7f, 0x7f); + //set control register to ATR + s->usrp->set_gpio_attr("FP0", "CTRL", 0x7f,0x7f); + //set ATR register + s->usrp->set_gpio_attr("FP0", "ATR_RX", (1<<4)|(1<<6), 0x7f); + // init recv and send streaming + uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS); + LOG_I(HW,"Time in secs now: %llu \n", s->usrp->get_time_now().to_ticks(s->sample_rate)); + LOG_I(HW,"Time in secs last pps: %llu \n", s->usrp->get_time_last_pps().to_ticks(s->sample_rate)); + + if (s->use_gps == 1 || device->openair0_cfg[0].time_source == external) { + s->wait_for_first_pps = 1; + cmd.time_spec = s->usrp->get_time_last_pps() + uhd::time_spec_t(1.0); + } else { + s->wait_for_first_pps = 0; + cmd.time_spec = s->usrp->get_time_now() + uhd::time_spec_t(0.005); } -#endif + cmd.stream_now = false; // start at constant delay + s->rx_stream->issue_stream_cmd(cmd); + /*s->tx_md.time_spec = cmd.time_spec + uhd::time_spec_t(1-(double)s->tx_forward_nsamps/s->sample_rate); + s->tx_md.has_time_spec = true; + s->tx_md.start_of_burst = true; + s->tx_md.end_of_burst = false;*/ + s->rx_count = 0; + s->tx_count = 0; + s->rx_timestamp = 0; return 0; } /*! \brief Terminate operation of the USRP transceiver -- free all associated resources * \param device the hardware to use */ static void trx_usrp_end(openair0_device *device) { -#if defined(USRP_REC_PLAY) // For some ugly reason, this can be called several times... - static int done = 0; + if (device == NULL) + return; - if (done == 1) return; - - done = 1; + usrp_state_t *s = (usrp_state_t *)device->priv; + if (s == NULL) + return; - if (u_sf_mode != 2) { // not subframes replay -#endif - usrp_state_t *s = (usrp_state_t *)device->priv; + if (s->recplay_mode != RECPLAY_REPLAYMODE) { // not subframes replay s->rx_stream->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS); //send a mini EOB packet s->tx_md.end_of_burst = true; s->tx_stream->send("", 0, s->tx_md); s->tx_md.end_of_burst = false; sleep(1); -#if defined(USRP_REC_PLAY) } -#endif -#if defined(USRP_REC_PLAY) - - if (u_sf_mode == 1) { // subframes store - pFile = fopen (u_sf_filename,"wb+"); + if (s->recplay_mode == RECPLAY_RECORDMODE) { // subframes store + s->recplay_state->pFile = fopen (s->recplay_state->u_sf_filename,"wb+"); - if (pFile == NULL) { - std::cerr << "Cannot open " << u_sf_filename << std::endl; + if (s->recplay_state->pFile == NULL) { + std::cerr << "Cannot open " << s->recplay_state->u_sf_filename << std::endl; } else { unsigned int i = 0; unsigned int modu = 0; - if ((modu = nb_samples % 10) != 0) { - nb_samples -= modu; // store entire number of frames + if ((modu = s->recplay_state->nb_samples % 10) != 0) { + s->recplay_state->nb_samples -= modu; // store entire number of frames } - std::cerr << "Writing " << nb_samples << " subframes to " << u_sf_filename << " ..." << std::endl; + std::cerr << "Writing " << s->recplay_state->nb_samples << " subframes to " << s->recplay_state->u_sf_filename << " ..." << std::endl; - for (i = 0; i < nb_samples; i++) { - fwrite(ms_sample+i, sizeof(unsigned char), sizeof(iqrec_t), pFile); + for (i = 0; i < s->recplay_state->nb_samples; i++) { + fwrite(s->recplay_state->ms_sample+i, sizeof(unsigned char), sizeof(iqrec_t), s->recplay_state->pFile); } - fclose (pFile); - std::cerr << "File " << u_sf_filename << " closed." << std::endl; + fclose (s->recplay_state->pFile); + std::cerr << "File " << s->recplay_state->u_sf_filename << " closed." << std::endl; } - } - if (u_sf_mode == 1) { // record - if (ms_sample != NULL) { - free((void *)ms_sample); - ms_sample = NULL; + if (s->recplay_state->ms_sample != NULL) { + free((void *)s->recplay_state->ms_sample); + s->recplay_state->ms_sample = NULL; } - } - - if (u_sf_mode == 2) { // replay - if (use_mmap) { - if (ms_sample != MAP_FAILED) { - munmap(ms_sample, sb.st_size); - ms_sample = NULL; + } else if (s->recplay_mode == RECPLAY_REPLAYMODE) { // replay + if (s->recplay_state->use_mmap) { + if (s->recplay_state->ms_sample != MAP_FAILED) { + munmap(s->recplay_state->ms_sample, s->recplay_state->mapsize); + s->recplay_state->ms_sample = NULL; } - if (mmapfd != 0) { - close(mmapfd); - mmapfd = 0; + if (s->recplay_state->mmapfd != 0) { + close(s->recplay_state->mmapfd); + s->recplay_state->mmapfd = 0; } } else { - if (ms_sample != NULL) { - free(ms_sample); - ms_sample = NULL; + if (s->recplay_state->ms_sample != NULL) { + free(s->recplay_state->ms_sample); + s->recplay_state->ms_sample = NULL; } - if (iqfd != 0) { - close(iqfd); - iqfd = 0; + if (s->recplay_state->iqfd != 0) { + close(s->recplay_state->iqfd); + s->recplay_state->iqfd = 0; } } } - -#endif } - +/*! \brief Write iqs function when in replay mode, just introduce a delay, as configured at init time, + @param device pointer to the device structure specific to the RF hardware target + @param timestamp The timestamp at which the first sample MUST be sent + @param buff Buffer which holds the samples + @param nsamps number of samples to be sent + @param antenna_id index of the antenna if the device has multiple antennas + @param flags flags must be set to TRUE if timestamp parameter needs to be applied +*/ +static int trx_usrp_write_recplay(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) { + struct timespec req; + usrp_state_t *s = (usrp_state_t *)device->priv; + req.tv_sec = 0; + req.tv_nsec = s->recplay_state->u_sf_write_delay * 1000; + nanosleep(&req, NULL); + return nsamps; +} /*! \brief Called to send samples to the USRP RF target @param device pointer to the device structure specific to the RF hardware target @param timestamp The timestamp at which the first sample MUST be sent @@ -444,14 +403,8 @@ static void trx_usrp_end(openair0_device *device) { */ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) { int ret=0; -#if defined(USRP_REC_PLAY) - - if (u_sf_mode != 2) { // not replay mode -#endif - usrp_state_t *s = (usrp_state_t *)device->priv; - - int nsamps2; // aligned to upper 32 or 16 byte boundary - + usrp_state_t *s = (usrp_state_t *)device->priv; + int nsamps2; // aligned to upper 32 or 16 byte boundary #if defined(__x86_64) || defined(__i386__) #ifdef __AVX2__ nsamps2 = (nsamps+7)>>3; @@ -464,23 +417,24 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, nsamps2 = (nsamps+3)>>2; int16x8_t buff_tx[8][nsamps2]; #else - #error Unsupported CPU architecture, USRP device cannot be built +#error Unsupported CPU architecture, USRP device cannot be built #endif - // bring RX data into 12 LSBs for softmodem RX - for (int i=0; i<cc; i++) { - for (int j=0; j<nsamps2; j++) { + // bring RX data into 12 LSBs for softmodem RX + for (int i=0; i<cc; i++) { + for (int j=0; j<nsamps2; j++) { #if defined(__x86_64__) || defined(__i386__) #ifdef __AVX2__ - buff_tx[i][j] = _mm256_slli_epi16(((__m256i *)buff[i])[j],4); + buff_tx[i][j] = _mm256_slli_epi16(((__m256i *)buff[i])[j],4); #else - buff_tx[i][j] = _mm_slli_epi16(((__m128i *)buff[i])[j],4); + buff_tx[i][j] = _mm_slli_epi16(((__m128i *)buff[i])[j],4); #endif #elif defined(__arm__) - buff_tx[i][j] = vshlq_n_s16(((int16x8_t *)buff[i])[j],4); + buff_tx[i][j] = vshlq_n_s16(((int16x8_t *)buff[i])[j],4); #endif - } } + } + boolean_t first_packet_state=false,last_packet_state=false; @@ -495,56 +449,43 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, first_packet_state = false; last_packet_state = true; } else if (flags == 4) { // start and end - // s->tx_md.start_of_burst = true; - // s->tx_md.end_of_burst = true; + // s->tx_md.start_of_burst = true; + // s->tx_md.end_of_burst = true; first_packet_state = true; last_packet_state = true; } else if (flags==1) { // middle of burst - // s->tx_md.start_of_burst = false; - // s->tx_md.end_of_burst = false; + // s->tx_md.start_of_burst = false; + // s->tx_md.end_of_burst = false; first_packet_state = false; last_packet_state = false; - } - else if (flags==10) { // fail safe mode - // s->tx_md.has_time_spec = false; - // s->tx_md.start_of_burst = false; - // s->tx_md.end_of_burst = true; - first_packet_state = false; - last_packet_state = true; + } else if (flags==10) { // fail safe mode + // s->tx_md.has_time_spec = false; + // s->tx_md.start_of_burst = false; + // s->tx_md.end_of_burst = true; + first_packet_state = false; + last_packet_state = true; } s->tx_md.has_time_spec = true; - s->tx_md.start_of_burst = (s->tx_count==0) ? true : first_packet_state; + s->tx_md.start_of_burst = (s->tx_count==0) ? true : first_packet_state; s->tx_md.end_of_burst = last_packet_state; s->tx_md.time_spec = uhd::time_spec_t::from_ticks(timestamp, s->sample_rate); - s->tx_count++; if (cc>1) { - std::vector<void *> buff_ptrs; + std::vector<void *> buff_ptrs; - for (int i=0; i<cc; i++) - buff_ptrs.push_back(&(((int16_t*)buff_tx[i])[0])); + for (int i=0; i<cc; i++) + buff_ptrs.push_back(&(((int16_t *)buff_tx[i])[0])); - ret = (int)s->tx_stream->send(buff_ptrs, nsamps, s->tx_md); + ret = (int)s->tx_stream->send(buff_ptrs, nsamps, s->tx_md); } else ret = (int)s->tx_stream->send(&(((int16_t *)buff_tx[0])[0]), nsamps, s->tx_md); + if (ret != nsamps) LOG_E(HW,"[xmit] tx samples %d != %d\n",ret,nsamps); - if (ret != nsamps) LOG_E(HW,"[xmit] tx samples %d != %d\n",ret,nsamps); - -#if defined(USRP_REC_PLAY) - } else { - struct timespec req; - req.tv_sec = 0; - req.tv_nsec = u_sf_write_delay * 1000; - nanosleep(&req, NULL); - ret = nsamps; - } - -#endif return ret; } -/*! \brief Receive samples from hardware. +/*! \brief Receive samples from iq file. * Read \ref nsamps samples from each channel to buffers. buff[0] is the array for * the first channel. *ptimestamp is the time at which the first sample * was received. @@ -555,190 +496,206 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, * \param antenna_id Index of antenna for which to receive samples * \returns the number of sample read */ -static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) { - usrp_state_t *s = (usrp_state_t *)device->priv; +static int trx_usrp_read_recplay(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) { int samples_received=0; - int nsamps2; // aligned to upper 32 or 16 byte boundary -#if defined(USRP_REC_PLAY) + static unsigned int cur_samples; + static int64_t wrap_count; + static int64_t wrap_ts; + usrp_state_t *s = (usrp_state_t *)device->priv; - if (u_sf_mode != 2) { // not replay mode -#endif -#if defined(__x86_64) || defined(__i386__) -#ifdef __AVX2__ - nsamps2 = (nsamps+7)>>3; - __m256i buff_tmp[8][nsamps2]; -#else - nsamps2 = (nsamps+3)>>2; - __m128i buff_tmp[8][nsamps2]; -#endif -#elif defined(__arm__) - nsamps2 = (nsamps+3)>>2; - int16x8_t buff_tmp[8][nsamps2]; -#endif - if (device->type == USRP_B200_DEV) { - if (cc>1) { - // receive multiple channels (e.g. RF A and RF B) - std::vector<void *> buff_ptrs; + if (cur_samples == s->recplay_state->nb_samples) { + cur_samples = 0; + wrap_count++; + if (wrap_count == s->recplay_state->u_sf_loops) { + std::cerr << "USRP device terminating subframes replay mode after " << s->recplay_state->u_sf_loops << " loops." << std::endl; + exit_function(__FILE__, __FUNCTION__, __LINE__,"replay ended, triggering process termination\n"); + } - for (int i=0; i<cc; i++) buff_ptrs.push_back(buff_tmp[i]); + wrap_ts = wrap_count * (s->recplay_state->nb_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000)); - samples_received = s->rx_stream->recv(buff_ptrs, nsamps, s->rx_md); + if (!s->recplay_state->use_mmap) { + if (lseek(s->recplay_state->iqfd, 0, SEEK_SET) == 0) { + std::cerr << "Seeking at the beginning of IQ file" << std::endl; } else { - // receive a single channel (e.g. from connector RF A) - samples_received=0; + std::cerr << "Problem seeking at the beginning of IQ file" << std::endl; + } + } + } - while (samples_received != nsamps) { - samples_received += s->rx_stream->recv(buff_tmp[0]+samples_received, - nsamps-samples_received, s->rx_md); + if (s->recplay_state->use_mmap) { + if (cur_samples < s->recplay_state->nb_samples) { + *ptimestamp = (s->recplay_state->ms_sample[0].ts + (cur_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000))) + wrap_ts; - if ((s->wait_for_first_pps == 0) && (s->rx_md.error_code!=uhd::rx_metadata_t::ERROR_CODE_NONE)) - break; + if (cur_samples == 0) { + std::cerr << "starting subframes file with wrap_count=" << wrap_count << " wrap_ts=" << wrap_ts + << " ts=" << *ptimestamp << std::endl; + } - if ((s->wait_for_first_pps == 1) && (samples_received != nsamps)) { - printf("sleep...\n"); //usleep(100); - } - } + memcpy(buff[0], &s->recplay_state->ms_sample[cur_samples].samples[0], nsamps*4); + cur_samples++; + } + } else { + // read sample from file + if (read(s->recplay_state->iqfd, s->recplay_state->ms_sample, sizeof(iqrec_t)) != sizeof(iqrec_t)) { + std::cerr << "pb reading iqfile at index " << sizeof(iqrec_t)*cur_samples << std::endl; + close(s->recplay_state->iqfd); + free(s->recplay_state->ms_sample); + s->recplay_state->ms_sample = NULL; + s->recplay_state->iqfd = 0; + exit(-1); + } - if (samples_received == nsamps) s->wait_for_first_pps=0; + if (cur_samples < s->recplay_state->nb_samples) { + static int64_t ts0 = 0; + + if ((cur_samples == 0) && (wrap_count == 0)) { + ts0 = s->recplay_state->ms_sample->ts; } - // bring RX data into 12 LSBs for softmodem RX - for (int i=0; i<cc; i++) { - for (int j=0; j<nsamps2; j++) { -#if defined(__x86_64__) || defined(__i386__) -#ifdef __AVX2__ - // FK: in some cases the buffer might not be 32 byte aligned, so we cannot use avx2 - - if ((((uintptr_t) buff[i])&0x1F)==0) { - ((__m256i *)buff[i])[j] = _mm256_srai_epi16(buff_tmp[i][j],4); - } - else { - ((__m128i *)buff[i])[2*j] = _mm_srai_epi16(((__m128i*)buff_tmp[i])[2*j],4); - ((__m128i *)buff[i])[2*j+1] = _mm_srai_epi16(((__m128i*)buff_tmp[i])[2*j+1],4); - } -#else - ((__m128i *)buff[i])[j] = _mm_srai_epi16(buff_tmp[i][j],4); -#endif -#elif defined(__arm__) - ((int16x8_t *)buff[i])[j] = vshrq_n_s16(buff_tmp[i][j],4); -#endif - } + *ptimestamp = ts0 + (cur_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000)) + wrap_ts; + + if (cur_samples == 0) { + std::cerr << "starting subframes file with wrap_count=" << wrap_count << " wrap_ts=" << wrap_ts + << " ts=" << *ptimestamp << std::endl; } - } else if (device->type == USRP_X300_DEV) { - if (cc>1) { - // receive multiple channels (e.g. RF A and RF B) - std::vector<void *> buff_ptrs; - for (int i=0; i<cc; i++) buff_ptrs.push_back(buff[i]); + memcpy(buff[0], &s->recplay_state->ms_sample->samples[0], nsamps*4); + cur_samples++; + // Prepare for next read + off_t where = lseek(s->recplay_state->iqfd, cur_samples * sizeof(iqrec_t), SEEK_SET); - samples_received = s->rx_stream->recv(buff_ptrs, nsamps, s->rx_md,1.0); - } else { - // receive a single channel (e.g. from connector RF A) - samples_received = s->rx_stream->recv(buff[0], nsamps, s->rx_md,1.0); + if (where < 0) { + LOG_E(HW,"Cannot lseek in iqfile: %s\n",strerror(errno)); } } + } - if (samples_received < nsamps) - LOG_E(HW,"[recv] received %d samples out of %d\n",samples_received,nsamps); + struct timespec req; - if ( s->rx_md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) - LOG_E(HW, "%s\n", s->rx_md.to_pp_string(true).c_str()); + req.tv_sec = 0; - s->rx_count += nsamps; - s->rx_timestamp = s->rx_md.time_spec.to_ticks(s->sample_rate); - *ptimestamp = s->rx_timestamp; -#if defined (USRP_REC_PLAY) - } + req.tv_nsec = s->recplay_state->u_sf_read_delay * 1000; -#endif -#if defined(USRP_REC_PLAY) + nanosleep(&req, NULL); - if (u_sf_mode == 1) { // record mode - // Copy subframes to memory (later dump on a file) - if (nb_samples < u_sf_max) { - (ms_sample+nb_samples)->header = BELL_LABS_IQ_HEADER; - (ms_sample+nb_samples)->ts = *ptimestamp; - memcpy((ms_sample+nb_samples)->samples, buff[0], nsamps*4); - nb_samples++; - } - } else if (u_sf_mode == 2) { // replay mode - if (cur_samples == nb_samples) { - cur_samples = 0; - wrap_count++; - - if (wrap_count == u_sf_loops) { - std::cerr << "USRP device terminating subframes replay mode after " << u_sf_loops << " loops." << std::endl; - return 0; // should make calling process exit - } + return nsamps; + + return samples_received; +} - wrap_ts = wrap_count * (nb_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000)); - if (!use_mmap) { - if (lseek(iqfd, 0, SEEK_SET) == 0) { - std::cerr << "Seeking at the beginning of IQ file" << std::endl; - } else { - std::cerr << "Problem seeking at the beginning of IQ file" << std::endl; - } - } - } +/*! \brief Receive samples from hardware. + * Read \ref nsamps samples from each channel to buffers. buff[0] is the array for + * the first channel. *ptimestamp is the time at which the first sample + * was received. + * \param device the hardware to use + * \param[out] ptimestamp the time at which the first sample was received. + * \param[out] buff An array of pointers to buffers for received samples. The buffers must be large enough to hold the number of samples \ref nsamps. + * \param nsamps Number of samples. One sample is 2 byte I + 2 byte Q => 4 byte. + * \param antenna_id Index of antenna for which to receive samples + * \returns the number of sample read +*/ +static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) { + usrp_state_t *s = (usrp_state_t *)device->priv; + int samples_received=0; + int nsamps2; // aligned to upper 32 or 16 byte boundary +#if defined(__x86_64) || defined(__i386__) +#ifdef __AVX2__ + nsamps2 = (nsamps+7)>>3; + __m256i buff_tmp[2][nsamps2]; +#else + nsamps2 = (nsamps+3)>>2; + __m128i buff_tmp[2][nsamps2]; +#endif +#elif defined(__arm__) + nsamps2 = (nsamps+3)>>2; + int16x8_t buff_tmp[2][nsamps2]; +#endif - if (use_mmap) { - if (cur_samples < nb_samples) { - *ptimestamp = (ms_sample[0].ts + (cur_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000))) + wrap_ts; + if (device->type == USRP_B200_DEV) { + if (cc>1) { + // receive multiple channels (e.g. RF A and RF B) + std::vector<void *> buff_ptrs; - if (cur_samples == 0) { - std::cerr << "starting subframes file with wrap_count=" << wrap_count << " wrap_ts=" << wrap_ts - << " ts=" << *ptimestamp << std::endl; - } + for (int i=0; i<cc; i++) buff_ptrs.push_back(buff_tmp[i]); - memcpy(buff[0], &ms_sample[cur_samples].samples[0], nsamps*4); - cur_samples++; - } + samples_received = s->rx_stream->recv(buff_ptrs, nsamps, s->rx_md); } else { - // read sample from file - if (read(iqfd, ms_sample, sizeof(iqrec_t)) != sizeof(iqrec_t)) { - std::cerr << "pb reading iqfile at index " << sizeof(iqrec_t)*cur_samples << std::endl; - close(iqfd); - free(ms_sample); - ms_sample = NULL; - iqfd = 0; - exit(-1); - } + // receive a single channel (e.g. from connector RF A) + samples_received=0; + + while (samples_received != nsamps) { + samples_received += s->rx_stream->recv(buff_tmp[0]+samples_received, + nsamps-samples_received, s->rx_md); - if (cur_samples < nb_samples) { - static int64_t ts0 = 0; + if ((s->wait_for_first_pps == 0) && (s->rx_md.error_code!=uhd::rx_metadata_t::ERROR_CODE_NONE)) + break; - if ((cur_samples == 0) && (wrap_count == 0)) { - ts0 = ms_sample->ts; + if ((s->wait_for_first_pps == 1) && (samples_received != nsamps)) { + printf("sleep...\n"); //usleep(100); } + } - *ptimestamp = ts0 + (cur_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000)) + wrap_ts; + if (samples_received == nsamps) s->wait_for_first_pps=0; + } + + // bring RX data into 12 LSBs for softmodem RX + for (int i=0; i<cc; i++) { + for (int j=0; j<nsamps2; j++) { +#if defined(__x86_64__) || defined(__i386__) +#ifdef __AVX2__ + // FK: in some cases the buffer might not be 32 byte aligned, so we cannot use avx2 - if (cur_samples == 0) { - std::cerr << "starting subframes file with wrap_count=" << wrap_count << " wrap_ts=" << wrap_ts - << " ts=" << *ptimestamp << std::endl; + if ((((uintptr_t) buff[i])&0x1F)==0) { + ((__m256i *)buff[i])[j] = _mm256_srai_epi16(buff_tmp[i][j],4); + } else { + ((__m128i *)buff[i])[2*j] = _mm_srai_epi16(((__m128i *)buff_tmp[i])[2*j],4); + ((__m128i *)buff[i])[2*j+1] = _mm_srai_epi16(((__m128i *)buff_tmp[i])[2*j+1],4); } - memcpy(buff[0], &ms_sample->samples[0], nsamps*4); - cur_samples++; - // Prepare for next read - off_t where = lseek(iqfd, cur_samples * sizeof(iqrec_t), SEEK_SET); +#else + ((__m128i *)buff[i])[j] = _mm_srai_epi16(buff_tmp[i][j],4); +#endif +#elif defined(__arm__) + ((int16x8_t *)buff[i])[j] = vshrq_n_s16(buff_tmp[i][j],4); +#endif } } + } else if (device->type == USRP_X300_DEV) { + if (cc>1) { + // receive multiple channels (e.g. RF A and RF B) + std::vector<void *> buff_ptrs; - struct timespec req; + for (int i=0; i<cc; i++) buff_ptrs.push_back(buff[i]); - req.tv_sec = 0; + samples_received = s->rx_stream->recv(buff_ptrs, nsamps, s->rx_md,1.0); + } else { + // receive a single channel (e.g. from connector RF A) + samples_received = s->rx_stream->recv(buff[0], nsamps, s->rx_md,1.0); + } + } - req.tv_nsec = u_sf_read_delay * 1000; + if (samples_received < nsamps) + LOG_E(HW,"[recv] received %d samples out of %d\n",samples_received,nsamps); - nanosleep(&req, NULL); + if ( s->rx_md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) + LOG_E(HW, "%s\n", s->rx_md.to_pp_string(true).c_str()); - return nsamps; + s->rx_count += nsamps; + s->rx_timestamp = s->rx_md.time_spec.to_ticks(s->sample_rate); + *ptimestamp = s->rx_timestamp; + + if (s->recplay_mode == RECPLAY_RECORDMODE) { // record mode + // Copy subframes to memory (later dump on a file) + if (s->recplay_state->nb_samples < s->recplay_state->u_sf_max) { + (s->recplay_state->ms_sample+s->recplay_state->nb_samples)->header = BELL_LABS_IQ_HEADER; + (s->recplay_state->ms_sample+s->recplay_state->nb_samples)->ts = *ptimestamp; + memcpy((s->recplay_state->ms_sample+s->recplay_state->nb_samples)->samples, buff[0], nsamps*4); + s->recplay_state->nb_samples++; + } else exit_function(__FILE__, __FUNCTION__, __LINE__,"Recording reaches max iq limit\n"); } -#endif return samples_received; } @@ -868,7 +825,6 @@ void set_rx_gain_offset(openair0_config_t *openair0_cfg, int chain_index,int bw_ if (bw_gain_adjust==1) { switch ((int)openair0_cfg[0].sample_rate) { - case 46080000: break; @@ -940,117 +896,37 @@ static void uhd_set_thread_priority(void) { uhd::set_thread_priority_safe(1.0); } -#if defined(USRP_REC_PLAY) -extern "C" { - /*! \brief Initializer for USRP record/playback config - * \param parameter array description - * \returns 0 on success - */ - int trx_usrp_recplay_config_init(paramdef_t *usrp_recplay_params) { - // --subframes-file - memcpy(usrp_recplay_params[0].optname, config_opt_sf_file, strlen(config_opt_sf_file)); - usrp_recplay_params[0].helpstr = config_hlp_sf_file; - usrp_recplay_params[0].paramflags=PARAMFLAG_NOFREE; - usrp_recplay_params[0].strptr=(char **)&u_sf_filename; - usrp_recplay_params[0].defstrval = NULL; - usrp_recplay_params[0].type=TYPE_STRING; - usrp_recplay_params[0].numelt=sizeof(u_sf_filename); - // --subframes-record - memcpy(usrp_recplay_params[1].optname, config_opt_sf_rec, strlen(config_opt_sf_rec)); - usrp_recplay_params[1].helpstr = config_hlp_sf_rec; - usrp_recplay_params[1].paramflags=PARAMFLAG_BOOL; - usrp_recplay_params[1].uptr=&u_sf_record; - usrp_recplay_params[1].defuintval=0; - usrp_recplay_params[1].type=TYPE_UINT; - usrp_recplay_params[1].numelt=0; - // --subframes-replay - memcpy(usrp_recplay_params[2].optname, config_opt_sf_rep, strlen(config_opt_sf_rep)); - usrp_recplay_params[2].helpstr = config_hlp_sf_rep; - usrp_recplay_params[2].paramflags=PARAMFLAG_BOOL; - usrp_recplay_params[2].uptr=&u_sf_replay; - usrp_recplay_params[2].defuintval=0; - usrp_recplay_params[2].type=TYPE_UINT; - usrp_recplay_params[2].numelt=0; - // --subframes-max - memcpy(usrp_recplay_params[3].optname, config_opt_sf_max, strlen(config_opt_sf_max)); - usrp_recplay_params[3].helpstr = config_hlp_sf_max; - usrp_recplay_params[3].paramflags=0; - usrp_recplay_params[3].uptr=&u_sf_max; - usrp_recplay_params[3].defuintval=DEF_NB_SF; - usrp_recplay_params[3].type=TYPE_UINT; - usrp_recplay_params[3].numelt=0; - // --subframes-loops - memcpy(usrp_recplay_params[4].optname, config_opt_sf_loops, strlen(config_opt_sf_loops)); - usrp_recplay_params[4].helpstr = config_hlp_sf_loops; - usrp_recplay_params[4].paramflags=0; - usrp_recplay_params[4].uptr=&u_sf_loops; - usrp_recplay_params[4].defuintval=DEF_SF_NB_LOOP; - usrp_recplay_params[4].type=TYPE_UINT; - usrp_recplay_params[4].numelt=0; - // --subframes-read-delay - memcpy(usrp_recplay_params[5].optname, config_opt_sf_rdelay, strlen(config_opt_sf_rdelay)); - usrp_recplay_params[5].helpstr = config_hlp_sf_rdelay; - usrp_recplay_params[5].paramflags=0; - usrp_recplay_params[5].uptr=&u_sf_read_delay; - usrp_recplay_params[5].defuintval=DEF_SF_DELAY_READ; - usrp_recplay_params[5].type=TYPE_UINT; - usrp_recplay_params[5].numelt=0; - // --subframes-write-delay - memcpy(usrp_recplay_params[6].optname, config_opt_sf_wdelay, strlen(config_opt_sf_wdelay)); - usrp_recplay_params[6].helpstr = config_hlp_sf_wdelay; - usrp_recplay_params[6].paramflags=0; - usrp_recplay_params[6].uptr=&u_sf_write_delay; - usrp_recplay_params[6].defuintval=DEF_SF_DELAY_WRITE; - usrp_recplay_params[6].type=TYPE_UINT; - usrp_recplay_params[6].numelt=0; - return 0; // always ok - } +void noop_func(void) { + return; } -#endif - extern "C" { int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { -#if defined(USRP_REC_PLAY) - paramdef_t usrp_recplay_params[7]; - struct sysinfo systeminfo; - // to check - static int done = 0; - - if (done == 1) { + LOG_D(HW, "openair0_cfg[0].sdr_addrs == '%s'\n", openair0_cfg[0].sdr_addrs); + LOG_D(HW, "openair0_cfg[0].clock_source == '%d'\n", openair0_cfg[0].clock_source); + usrp_state_t *s ; + + if ( device->priv == NULL) { + s=(usrp_state_t *)calloc(sizeof(usrp_state_t),1); + device->priv=s; + AssertFatal( s!=NULL,"USRP device: memory allocation failure\n"); + } else { + LOG_E(HW, "multiple device init detected\n"); return 0; - } // prevent from multiple init - - done = 1; - // end to check - // Use mmap for IQ files for systems with less than 6GB total RAM - sysinfo(&systeminfo); - - if (systeminfo.totalram < 6144000000) { - use_mmap = 0; - } - - memset(usrp_recplay_params, 0, 7*sizeof(paramdef_t)); - memset(&u_sf_filename[0], 0, 1024); - - if (trx_usrp_recplay_config_init(usrp_recplay_params) != 0) { - std::cerr << "USRP device record/replay mode configuration error exiting" << std::endl; - return -1; - } - - config_process_cmdline(usrp_recplay_params,sizeof(usrp_recplay_params)/sizeof(paramdef_t),NULL); - - if (strlen(u_sf_filename) == 0) { - (void) strcpy(u_sf_filename, DEF_SF_FILE); } - if (u_sf_replay == 1) u_sf_mode = 2; - - if (u_sf_record == 1) u_sf_mode = 1; - - if (u_sf_mode == 2) { + device->openair0_cfg = openair0_cfg; + read_usrpconfig(&(s->recplay_mode), &(s->recplay_state)); + device->trx_start_func = trx_usrp_start; + device->trx_get_stats_func = trx_usrp_get_stats; + device->trx_reset_stats_func = trx_usrp_reset_stats; + device->trx_end_func = trx_usrp_end; + device->trx_stop_func = trx_usrp_stop; + device->trx_set_freq_func = trx_usrp_set_freq; + device->trx_set_gains_func = trx_usrp_set_gains; + + if ( s->recplay_mode == RECPLAY_REPLAYMODE) { // Replay subframes from from file int bw_gain_adjust=0; - device->openair0_cfg = openair0_cfg; device->type = USRP_B200_DEV; openair0_cfg[0].rx_gain_calib_table = calib_table_b210_38; bw_gain_adjust=1; @@ -1060,45 +936,30 @@ extern "C" { openair0_cfg[0].iq_txshift = 4;//shift openair0_cfg[0].iq_rxrescale = 15;//rescale iqs set_rx_gain_offset(&openair0_cfg[0],0,bw_gain_adjust); - device->priv = NULL; - device->trx_start_func = trx_usrp_start; - device->trx_write_func = trx_usrp_write; - device->trx_read_func = trx_usrp_read; - device->trx_get_stats_func = trx_usrp_get_stats; - device->trx_reset_stats_func = trx_usrp_reset_stats; - device->trx_end_func = trx_usrp_end; - device->trx_stop_func = trx_usrp_stop; - device->trx_set_freq_func = trx_usrp_set_freq; - device->trx_set_gains_func = trx_usrp_set_gains; - device->openair0_cfg = openair0_cfg; - device->uhd_set_thread_priority = uhd_set_thread_priority; - std::cerr << "USRP device initialized in subframes replay mode for " << u_sf_loops << " loops. Use mmap=" - << use_mmap << std::endl; + device->trx_write_func = trx_usrp_write_recplay; + device->trx_read_func = trx_usrp_read_recplay; + device->uhd_set_thread_priority = noop_func; + std::cerr << "USRP device initialized in subframes replay mode for " << s->recplay_state->u_sf_loops << " loops. Use mmap=" + << s->recplay_state->use_mmap << std::endl; } else { -#endif - usrp_state_t *s = (usrp_state_t *)calloc(sizeof(usrp_state_t),1); - // Initialize USRP device - device->openair0_cfg = openair0_cfg; int vers=0,subvers=0,subsubvers=0; int bw_gain_adjust=0; -#if defined(USRP_REC_PLAY) - if (u_sf_mode == 1) { + if (s->recplay_mode == RECPLAY_RECORDMODE) { std::cerr << "USRP device initialized in subframes record mode" << std::endl; } -#endif sscanf(uhd::get_version_string().c_str(),"%d.%d.%d",&vers,&subvers,&subsubvers); LOG_I(HW,"UHD version %s (%d.%d.%d)\n", uhd::get_version_string().c_str(),vers,subvers,subsubvers); - std::string args; + if (openair0_cfg[0].sdr_addrs == NULL) { args = "type=b200"; } else { args = openair0_cfg[0].sdr_addrs; - LOG_I(HW,"Checking for USRP with args %s\n",openair0_cfg[0].sdr_addrs); + LOG_I(HW,"Checking for USRP with args %s\n",openair0_cfg[0].sdr_addrs); } uhd::device_addrs_t device_adds = uhd::device::find(args); @@ -1109,8 +970,8 @@ extern "C" { return -1; } else if (device_adds.size() > 1) { LOG_E(HW,"More than one USRP Device Found. Please specify device more precisely in config file.\n"); - free(s); - return -1; + free(s); + return -1; } LOG_I(HW,"Found USRP %s\n", device_adds[0].get("type").c_str()); @@ -1123,6 +984,7 @@ extern "C" { args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock); args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=7680, recv_frame_size=7680" ; } + if (device_adds[0].get("type") == "n3xx") { printf("Found USRP n300\n"); device->type=USRP_X300_DEV; //treat it as X300 for now @@ -1136,60 +998,55 @@ extern "C" { device->type=USRP_X300_DEV; usrp_master_clock = 184.32e6; args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock); + // USRP recommended: https://files.ettus.com/manual/page_usrp_x3x0_config.html if ( 0 != system("sysctl -w net.core.rmem_max=33554432 net.core.wmem_max=33554432") ) - LOG_W(HW,"Can't set kernel parameters for X3xx\n"); + LOG_W(HW,"Can't set kernel parameters for X3xx\n"); } s->usrp = uhd::usrp::multi_usrp::make(args); - device->priv = s; if (args.find("clock_source")==std::string::npos) { - LOG_I(HW, "Using clock_source == '%d'\n", openair0_cfg[0].clock_source); - - if (openair0_cfg[0].clock_source == internal) { - //in UHD 3.14 we could use - //s->usrp->set_sync_source("clock_source=internal","time_source=internal"); - s->usrp->set_time_source("internal"); - s->usrp->set_clock_source("internal"); - } - else if (openair0_cfg[0].clock_source == external ) { - //s->usrp->set_sync_source("clock_source=external","time_source=external"); - s->usrp->set_time_source("external"); - s->usrp->set_clock_source("external"); - } - else if (openair0_cfg[0].clock_source==gpsdo) { - s->usrp->set_clock_source("gpsdo"); - s->usrp->set_time_source("gpsdo"); - } + LOG_I(HW, "Using clock_source == '%d'\n", openair0_cfg[0].clock_source); + + if (openair0_cfg[0].clock_source == internal) { + //in UHD 3.14 we could use + //s->usrp->set_sync_source("clock_source=internal","time_source=internal"); + s->usrp->set_time_source("internal"); + s->usrp->set_clock_source("internal"); + } else if (openair0_cfg[0].clock_source == external ) { + //s->usrp->set_sync_source("clock_source=external","time_source=external"); + s->usrp->set_time_source("external"); + s->usrp->set_clock_source("external"); + } else if (openair0_cfg[0].clock_source==gpsdo) { + s->usrp->set_clock_source("gpsdo"); + s->usrp->set_time_source("gpsdo"); + } } else { - LOG_W(HW, "clock_source already specified in device arguments! Ignoring command line parameter\n"); + LOG_W(HW, "clock_source already specified in device arguments! Ignoring command line parameter\n"); } if (s->usrp->get_clock_source(0) == "gpsdo") { - s->use_gps = 1; + s->use_gps = 1; + if (sync_to_gps(device)==EXIT_SUCCESS) { LOG_I(HW,"USRP synced with GPS!\n"); - } - else { + } else { LOG_I(HW,"USRP fails to sync with GPS. Exiting.\n"); exit(EXIT_FAILURE); } - } else if (s->usrp->get_clock_source(0) == "external") { - if (check_ref_locked(s,0)) { - LOG_I(HW,"USRP locked to external reference!\n"); - } else { - LOG_I(HW,"Failed to lock to external reference. Exiting.\n"); - exit(EXIT_FAILURE); - } + } else if (s->usrp->get_clock_source(0) == "external") { + if (check_ref_locked(s,0)) { + LOG_I(HW,"USRP locked to external reference!\n"); + } else { + LOG_I(HW,"Failed to lock to external reference. Exiting.\n"); + exit(EXIT_FAILURE); + } } - - + if (device->type==USRP_X300_DEV) { openair0_cfg[0].rx_gain_calib_table = calib_table_x310; -#if defined(USRP_REC_PLAY) std::cerr << "-- Using calibration table: calib_table_x310" << std::endl; // Bell Labs info -#endif LOG_I(HW,"%s() sample_rate:%u\n", __FUNCTION__, (int)openair0_cfg[0].sample_rate); switch ((int)openair0_cfg[0].sample_rate) { @@ -1208,7 +1065,7 @@ extern "C" { openair0_cfg[0].tx_bw = 80e6; openair0_cfg[0].rx_bw = 80e6; break; - + case 61440000: // from usrp_time_offset //openair0_cfg[0].samples_per_packet = 2048; @@ -1264,19 +1121,15 @@ extern "C" { if ((vers == 3) && (subvers == 9) && (subsubvers>=2)) { openair0_cfg[0].rx_gain_calib_table = calib_table_b210; bw_gain_adjust=0; -#if defined(USRP_REC_PLAY) std::cerr << "-- Using calibration table: calib_table_b210" << std::endl; // Bell Labs info -#endif } else { openair0_cfg[0].rx_gain_calib_table = calib_table_b210_38; bw_gain_adjust=1; -#if defined(USRP_REC_PLAY) std::cerr << "-- Using calibration table: calib_table_b210_38" << std::endl; // Bell Labs info -#endif } switch ((int)openair0_cfg[0].sample_rate) { - case 46080000: + case 46080000: s->usrp->set_master_clock_rate(46.08e6); //openair0_cfg[0].samples_per_packet = 1024; openair0_cfg[0].tx_sample_advance = 115; @@ -1284,7 +1137,7 @@ extern "C" { openair0_cfg[0].rx_bw = 40e6; break; - case 30720000: + case 30720000: s->usrp->set_master_clock_rate(30.72e6); //openair0_cfg[0].samples_per_packet = 1024; openair0_cfg[0].tx_sample_advance = 115; @@ -1373,7 +1226,6 @@ extern "C" { // display USRP settings LOG_I(HW,"Actual master clock: %fMHz...\n",s->usrp->get_master_clock_rate()/1e6); sleep(1); - // create tx & rx streamer uhd::stream_args_t stream_args_rx("sc16", "sc16"); int samples=openair0_cfg[0].sample_rate; @@ -1422,21 +1274,12 @@ extern "C" { LOG_I(HW," Actual TX gain: %f...\n", s->usrp->get_tx_gain(i)); LOG_I(HW," Actual TX bandwidth: %fM...\n", s->usrp->get_tx_bandwidth(i)/1e6); LOG_I(HW," Actual TX antenna: %s...\n", s->usrp->get_tx_antenna(i).c_str()); - LOG_I(HW," Actual TX packet size: %lu\n",s->tx_stream->get_max_num_samps()); + LOG_I(HW," Actual TX packet size: %lu\n",s->tx_stream->get_max_num_samps()); } LOG_I(HW,"Device timestamp: %f...\n", s->usrp->get_time_now().get_real_secs()); - device->priv = s; - device->trx_start_func = trx_usrp_start; device->trx_write_func = trx_usrp_write; device->trx_read_func = trx_usrp_read; - device->trx_get_stats_func = trx_usrp_get_stats; - device->trx_reset_stats_func = trx_usrp_reset_stats; - device->trx_end_func = trx_usrp_end; - device->trx_stop_func = trx_usrp_stop; - device->trx_set_freq_func = trx_usrp_set_freq; - device->trx_set_gains_func = trx_usrp_set_gains; - device->openair0_cfg = openair0_cfg; device->uhd_set_thread_priority = uhd_set_thread_priority; s->sample_rate = openair0_cfg[0].sample_rate; @@ -1450,87 +1293,82 @@ extern "C" { if(is_equal(s->sample_rate, (double)7.68e6)) s->tx_forward_nsamps = 50; - - -#if defined(USRP_REC_PLAY) } -#endif -#if defined(USRP_REC_PLAY) - - if (u_sf_mode == 1) { // record mode - ms_sample = (iqrec_t *) malloc(u_sf_max * sizeof(iqrec_t)); + if (s->recplay_mode == RECPLAY_RECORDMODE) { // record mode + s->recplay_state->ms_sample = (iqrec_t *) malloc(s->recplay_state->u_sf_max * sizeof(iqrec_t)); - if (ms_sample == NULL) { + if (s->recplay_state->ms_sample == NULL) { std::cerr<< "Memory allocation failed for subframe record or replay mode." << std::endl; exit(-1); } - memset(ms_sample, 0, u_sf_max * BELL_LABS_IQ_BYTES_PER_SF); - } - - if (u_sf_mode == 2) { - if (use_mmap) { + memset(s->recplay_state->ms_sample, 0, s->recplay_state->u_sf_max * BELL_LABS_IQ_BYTES_PER_SF); + } else if (s->recplay_mode == RECPLAY_REPLAYMODE) { + if (s->recplay_state->use_mmap) { // use mmap - mmapfd = open(u_sf_filename, O_RDONLY | O_LARGEFILE); + s->recplay_state->mmapfd = open(s->recplay_state->u_sf_filename, O_RDONLY | O_LARGEFILE); - if (mmapfd != 0) { - fstat(mmapfd, &sb); - std::cerr << "Loading subframes using mmap() from " << u_sf_filename << " size=" << (uint64_t)sb.st_size << " bytes ..." << std::endl; - ms_sample = (iqrec_t *) mmap(NULL, sb.st_size, PROT_WRITE, MAP_PRIVATE, mmapfd, 0); + if (s->recplay_state->mmapfd != 0) { + struct stat sb; + fstat(s->recplay_state->mmapfd, &sb); + s->recplay_state->mapsize=sb.st_size; + std::cerr << "Loading subframes using mmap() from " << s->recplay_state->u_sf_filename << " size=" << (uint64_t)sb.st_size << " bytes ..." << std::endl; + s->recplay_state->ms_sample = (iqrec_t *) mmap(NULL, sb.st_size, PROT_WRITE, MAP_PRIVATE, s->recplay_state->mmapfd, 0); - if (ms_sample != MAP_FAILED) { - nb_samples = (sb.st_size / sizeof(iqrec_t)); - int aligned = (((unsigned long)ms_sample & 31) == 0)? 1:0; - std::cerr<< "Loaded "<< nb_samples << " subframes." << std::endl; + if (s->recplay_state->ms_sample != MAP_FAILED) { + s->recplay_state->nb_samples = (sb.st_size / sizeof(iqrec_t)); + int aligned = (((unsigned long)s->recplay_state->ms_sample & 31) == 0)? 1:0; + std::cerr<< "Loaded "<< s->recplay_state->nb_samples << " subframes." << std::endl; if (aligned == 0) { std::cerr<< "mmap address is not 32 bytes aligned, exiting." << std::endl; - close(mmapfd); + close(s->recplay_state->mmapfd); exit(-1); } } else { std::cerr << "Cannot mmap file, exiting." << std::endl; - close(mmapfd); + close(s->recplay_state->mmapfd); exit(-1); } } else { - std::cerr << "Cannot open " << u_sf_filename << " , exiting." << std::endl; + std::cerr << "Cannot open " << s->recplay_state->u_sf_filename << " , exiting." << std::endl; exit(-1); } } else { - iqfd = open(u_sf_filename, O_RDONLY | O_LARGEFILE); - - if (iqfd != 0) { - fstat(iqfd, &sb); - nb_samples = (sb.st_size / sizeof(iqrec_t)); - std::cerr << "Loading " << nb_samples << " subframes from " << u_sf_filename + s->recplay_state->iqfd = open(s->recplay_state->u_sf_filename, O_RDONLY | O_LARGEFILE); + + if (s->recplay_state->iqfd != 0) { + struct stat sb; + fstat(s->recplay_state->iqfd, &sb); + s->recplay_state->mapsize=sb.st_size; + s->recplay_state->nb_samples = (sb.st_size / sizeof(iqrec_t)); + std::cerr << "Loading " << s->recplay_state->nb_samples << " subframes from " << s->recplay_state->u_sf_filename << " size=" << (uint64_t)sb.st_size << " bytes ..." << std::endl; // allocate buffer for 1 sample at a time - ms_sample = (iqrec_t *) malloc(sizeof(iqrec_t)); + s->recplay_state->ms_sample = (iqrec_t *) malloc(sizeof(iqrec_t)); - if (ms_sample == NULL) { + if (s->recplay_state->ms_sample == NULL) { std::cerr<< "Memory allocation failed for individual subframe replay mode." << std::endl; - close(iqfd); + close(s->recplay_state->iqfd); exit(-1); } - memset(ms_sample, 0, sizeof(iqrec_t)); + memset(s->recplay_state->ms_sample, 0, sizeof(iqrec_t)); // point at beginning of file - if (lseek(iqfd, 0, SEEK_SET) == 0) { + if (lseek(s->recplay_state->iqfd, 0, SEEK_SET) == 0) { std::cerr << "Initial seek at beginning of the file" << std::endl; } else { std::cerr << "Problem initial seek at beginning of the file" << std::endl; } } else { - std::cerr << "Cannot open " << u_sf_filename << " , exiting." << std::endl; + std::cerr << "Cannot open " << s->recplay_state->u_sf_filename << " , exiting." << std::endl; exit(-1); } } } -#endif return 0; } diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.h b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.h index 228d3a5857..d29cf41db2 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.h +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.h @@ -26,8 +26,6 @@ * \author: bruno.mongazon-cazavet@nokia-bell-labs.com */ -#if defined (USRP_REC_PLAY) - #include <sys/mman.h> #include <sys/types.h> #include <sys/stat.h> @@ -35,6 +33,29 @@ #include "common/config/config_paramdesc.h" #include "common/config/config_userapi.h" +#ifdef __cplusplus +extern "C" +{ +#endif +#define CONFIG_OPT_RECPLAY "enable_recplay" + +#define CONFIG_HLP_RECPLAY "Allow record player" +#define USRP_SECTION "device.usrp" +/* inclusion for device configuration */ +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* command line parameters for USRP record/playback */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +#define USRP_DEVICE_PARAMS_DESC { \ + {CONFIG_OPT_RECPLAY, CONFIG_HLP_RECPLAY, PARAMFLAG_BOOL, uptr:&enable_recplay, defuintval:0, TYPE_UINT, 0} \ + } + + +/* inclusions for record player */ +#define RECPLAY_DISABLED 0 +#define RECPLAY_RECORDMODE 1 +#define RECPLAY_REPLAYMODE 2 + #define BELL_LABS_IQ_HEADER 0xabababababababab #define BELL_LABS_IQ_PER_SF 7680 // Up to 5MHz bw for now #define BELL_LABS_IQ_BYTES_PER_SF (BELL_LABS_IQ_PER_SF * 4) @@ -46,13 +67,13 @@ typedef struct { unsigned char samples[BELL_LABS_IQ_BYTES_PER_SF]; // iq's for one subframe } iqrec_t; #define DEF_NB_SF 120000 // default nb of sf or ms to capture (2 minutes at 5MHz) -#define DEF_SF_FILE "/home/nokia/iqfile" // default subframes file name +#define DEF_SF_FILE "/tmp/iqfile" // default subframes file name #define DEF_SF_DELAY_READ 700 // default read delay µs (860=real) #define DEF_SF_DELAY_WRITE 15 // default write delay µs (15=real) #define DEF_SF_NB_LOOP 5 // default nb loops -/* help strings definition for command line options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */ +/* help strings definition for config options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */ #define CONFIG_HLP_SF_FILE "Path of the file used for subframes record or replay" #define CONFIG_HLP_SF_REC "Record subframes from USRP driver into a file for later replay" #define CONFIG_HLP_SF_REP "Replay subframes into USRP driver from a file" @@ -61,7 +82,7 @@ typedef struct { #define CONFIG_HLP_SF_RDELAY "Delay in microseconds to read a subframe in replay mode" #define CONFIG_HLP_SF_WDELAY "Delay in microseconds to write a subframe in replay mode" -/* keyword strings for command line options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */ +/* keyword strings for config options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */ #define CONFIG_OPT_SF_FILE "subframes-file" #define CONFIG_OPT_SF_REC "subframes-record" #define CONFIG_OPT_SF_REP "subframes-replay" @@ -70,20 +91,41 @@ typedef struct { #define CONFIG_OPT_SF_RDELAY "subframes-read-delay" #define CONFIG_OPT_SF_WDELAY "subframes-write-delay" +#define USRP_RECPLAY_SECTION "device.recplay" /* For information only - the macro is not usable in C++ */ /*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ /* command line parameters for USRP record/playback */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ /*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ #define USRP_RECPLAY_PARAMS_DESC { \ -{"subframes-file", CONFIG_HLP_SF_FILE, 0, strptr:(char **)&u_sf_filename, defstrval:DEF_SF_FILE, TYPE_STRING, sizeof(u_sf_filename)}, \ -{"subframes-record", CONFIG_HLP_SF_REC, PARAMFLAG_BOOL, uptr:&u_sf_record, defuintval:0, TYPE_UINT, 0}, \ -{"subframes-replay", CONFIG_HLP_SF_REP, PARAMFLAG_BOOL, uptr:&u_sf_replay, defuintval:0, TYPE_UINT, 0}, \ -{"subframes-max", CONFIG_HLP_SF_MAX, 0, uptr:&u_sf_max, defintval:DEF_NB_SF, TYPE_UINT, 0}, \ -{"subframes-loops", CONFIG_HLP_SF_LOOPS, 0, uptr:&u_sf_loops, defintval:DEF_SF_NB_LOOP, TYPE_UINT, 0}, \ -{"subframes-read-delay", CONFIG_HLP_SF_RDELAY, 0, uptr:&u_sf_read_delay, defintval:DEF_SF_DELAY_READ, TYPE_UINT, 0}, \ -{"subframes-write-delay", CONFIG_HLP_SF_WDELAY, 0, uptr:&u_sf_write_delay, defintval:DEF_SF_DELAY_WRITE, TYPE_UINT, 0}, \ + {CONFIG_OPT_SF_FILE, CONFIG_HLP_SF_FILE, 0, strptr:(char **)((*recplay_state)->u_sf_filename), defstrval:DEF_SF_FILE, TYPE_STRING, 1024}, \ + {CONFIG_OPT_SF_REC, CONFIG_HLP_SF_REC, PARAMFLAG_BOOL, uptr:&(u_sf_record), defuintval:0, TYPE_UINT, 0}, \ + {CONFIG_OPT_SF_REP, CONFIG_HLP_SF_REP, PARAMFLAG_BOOL, uptr:&(u_sf_replay), defuintval:0, TYPE_UINT, 0}, \ + {CONFIG_OPT_SF_MAX, CONFIG_HLP_SF_MAX, 0, uptr:&((*recplay_state)->u_sf_max), defintval:DEF_NB_SF, TYPE_UINT, 0}, \ + {CONFIG_OPT_SF_LOOPS, CONFIG_HLP_SF_LOOPS, 0, uptr:&((*recplay_state)->u_sf_loops), defintval:DEF_SF_NB_LOOP, TYPE_UINT, 0}, \ + {CONFIG_OPT_SF_RDELAY, CONFIG_HLP_SF_RDELAY, 0, uptr:&((*recplay_state)->u_sf_read_delay), defintval:DEF_SF_DELAY_READ, TYPE_UINT, 0}, \ + {CONFIG_OPT_SF_WDELAY, CONFIG_HLP_SF_WDELAY, 0, uptr:&((*recplay_state)->u_sf_write_delay), defintval:DEF_SF_DELAY_WRITE, TYPE_UINT, 0}, \ + }/*! \brief USRP Configuration and state */ + +typedef struct { + FILE *pFile; + int mmapfd; + int iqfd; + int use_mmap; // default is to use mmap + size_t mapsize; + iqrec_t *ms_sample; // memory for all subframes + unsigned int nb_samples; + char u_sf_filename[1024]; // subframes file path + unsigned int u_sf_max ; // max number of recorded subframes + unsigned int u_sf_loops ; // number of loops in replay mode + unsigned int u_sf_read_delay; // read delay in replay mode + unsigned int u_sf_write_delay ; // write delay in replay mode +} recplay_state_t; + + +extern int read_usrpconfig(uint32_t *recplay_mode, recplay_state_t **recplay_state); +#ifdef __cplusplus } -#endif // BELL_LABS_MUST +#endif #endif // __USRP_LIB_H diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib_config.c b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib_config.c new file mode 100644 index 0000000000..ebf1d61eed --- /dev/null +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib_config.c @@ -0,0 +1,73 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/** usrp_lib_config.c + * + * \author: HongliangXU : hong-liang-xu@agilent.com + */ + +#include <string.h> +#include <unistd.h> +#include <stdio.h> +#include <sys/sysinfo.h> +#include <sys/resource.h> +#include "common/utils/LOG/log.h" +#include "assertions.h" +#include "common_lib.h" +#include "usrp_lib.h" + + +int read_usrpconfig(uint32_t *recplay_mode, recplay_state_t **recplay_state) { +unsigned int u_sf_record = 0; // record mode +unsigned int u_sf_replay = 0; // replay mode +uint32_t enable_recplay; + + paramdef_t usrp_params[] = USRP_DEVICE_PARAMS_DESC; + config_get(usrp_params,sizeof(usrp_params)/sizeof(paramdef_t),USRP_SECTION); + if (enable_recplay) { + *recplay_state = calloc(sizeof(recplay_state_t),1); + paramdef_t usrp_recplay_params[]=USRP_RECPLAY_PARAMS_DESC ; + struct sysinfo systeminfo; + + // Use mmap for IQ files for systems with less than 6GB total RAM + sysinfo(&systeminfo); + + if (systeminfo.totalram < 6144000000) { + (*recplay_state)->use_mmap = 0; + } else { + (*recplay_state)->use_mmap = 1; + } + + memset((*recplay_state)->u_sf_filename, 0, 1024); + config_get(usrp_recplay_params,sizeof(usrp_recplay_params)/sizeof(paramdef_t),USRP_RECPLAY_SECTION); + + if (strlen((*recplay_state)->u_sf_filename) == 0) { + (void) strcpy(( + *recplay_state)->u_sf_filename, DEF_SF_FILE); + } + } /* record player enabled */ + if (u_sf_replay == 1) *recplay_mode = RECPLAY_REPLAYMODE; + + if (u_sf_record == 1) *recplay_mode = RECPLAY_RECORDMODE; + + + return 0; + } \ No newline at end of file -- 2.26.2