diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index bd2d8e3b1e587a6f9cf3866e03e749561907c18d..e11c850b8e732a85c262062b531160a2ffc3b5b8 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1968,6 +1968,7 @@ set(NR_PDCP_SRC ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_entity.c ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c + ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c ${OPENAIR2_DIR}/LAYER2/nr_pdcp/asn1_utils.c ) diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index 6d3424b42024109d74b0f43a28fb1d19fb68d30c..089d0503fdf02a7b0726223adec38c78e343a7c5 100644 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -1292,7 +1292,9 @@ (Test8: DMRS Type B, 3 DMRS, 2 PTRS, 3 Interpolated Symbols), (Test9: SC-FDMA, 50 PRBs), (Test10: SC-FDMA, 75 PRBs), - (Test11: SC-FDMA, 3 DMRS)</desc> + (Test11: SC-FDMA, 216 PRBs), + (Test12: SC-FDMA, 273 PRBs), + (Test13: SC-FDMA, 3 DMRS)</desc> <pre_compile_prog></pre_compile_prog> <compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog> <compile_prog_args> --phy_simulators -c </compile_prog_args> @@ -1307,10 +1309,13 @@ -n100 -s5 -T 2 1 2 -U 2 0 2 -n100 -s5 -T 2 2 2 -U 2 1 2 -n100 -s5 -a4 -b8 -T 2 1 2 -U 2 1 3 - -n100 -s20 -Z - -n100 -s20 -Z -r75 - -n100 -s20 -Z -U 2 0 2</main_exec_args> - <tags>nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 nr_ulsim.test6 nr_ulsim.test7 nr_ulsim.test8 nr_ulsim.test9 nr_ulsim.test10 nr_ulsim.test11</tags> + -n100 -s2 -Z + -n100 -s2 -Z -r75 + -n100 -s2 -Z -r216 -R217 + -n100 -s2 -Z -r270 -R273 + -n100 -s2 -Z -U 2 0 2</main_exec_args> + + <tags>nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 nr_ulsim.test6 nr_ulsim.test7 nr_ulsim.test8 nr_ulsim.test9 nr_ulsim.test10 nr_ulsim.test11 nr_ulsim.test12 nr_ulsim.test13</tags> <search_expr_true>PUSCH test OK</search_expr_true> <search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false> <nruns>3</nruns> diff --git a/common/config/config_load_configmodule.c b/common/config/config_load_configmodule.c index 03b380ee2fc8246fc7c5b529c19f37baadbf4ccc..740c6e240bc77c61c99fbc08982d83ec30ba3fcd 100644 --- a/common/config/config_load_configmodule.c +++ b/common/config/config_load_configmodule.c @@ -331,9 +331,10 @@ void end_configmodule(void) { printf ("[CONFIG] free %u config value pointers\n",cfgptr->numptrs); for(int i=0; i<cfgptr->numptrs ; i++) { - if (cfgptr->ptrs[i] != NULL) { + if (cfgptr->ptrs[i] != NULL && cfgptr->ptrsAllocated[i] == true) { free(cfgptr->ptrs[i]); cfgptr->ptrs[i]=NULL; + cfgptr->ptrsAllocated[i] = false; } } diff --git a/common/config/config_load_configmodule.h b/common/config/config_load_configmodule.h index d0309c62c3b66fde19ac8ea6338ce7f05993cef2..8baaa99bb8074f90e9fa42aac5d18506c65a2f40 100644 --- a/common/config/config_load_configmodule.h +++ b/common/config/config_load_configmodule.h @@ -36,6 +36,8 @@ #include <string.h> #include <stdlib.h> +#include <stdint.h> +#include <stdbool.h> #include "common/config/config_paramdesc.h" #include "common/utils/T/T.h" #define CONFIG_MAX_OOPT_PARAMS 10 // maximum number of parameters in the -O option (-O <cfgmode>:P1:P2... @@ -74,6 +76,7 @@ typedef struct configmodule_interface { uint32_t numptrs; uint32_t rtflags; char *ptrs[CONFIG_MAX_ALLOCATEDPTRS]; + bool ptrsAllocated[CONFIG_MAX_ALLOCATEDPTRS]; } configmodule_interface_t; #ifdef CONFIG_LOADCONFIG_MAIN diff --git a/common/config/config_userapi.c b/common/config/config_userapi.c index 33d6408828439cd4b596255d49cc83178fa088ae..af70cae71eccf889a3618ed152f5f1138ac28627 100644 --- a/common/config/config_userapi.c +++ b/common/config/config_userapi.c @@ -62,6 +62,7 @@ char *config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) { if ( (cfgoptions->paramflags & PARAMFLAG_NOFREE) == 0) { config_get_if()->ptrs[config_get_if()->numptrs] = (char *)ptr; + config_get_if()->ptrsAllocated[config_get_if()->numptrs] = true; config_get_if()->numptrs++; } } else { @@ -82,7 +83,9 @@ char *config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) { } if (*ptr == NULL) { - *ptr = malloc(length>40?length:40); // LTS: dummy fix, waiting Francois full fix in 4G branch + *ptr = malloc(length>40?length:40); + // LTS: dummy fix, waiting Francois full fix in 4G branch + // the issue is we don't know at this point the size we will get if ( *ptr != NULL) { memset(*ptr,0,length); diff --git a/common/config/libconfig/config_libconfig.c b/common/config/libconfig/config_libconfig.c index 2e9fd614c504e286f5eeb728a4b03ab198ec1cf0..eb08a70183f5f699253450d460be22e607938c59 100644 --- a/common/config/libconfig/config_libconfig.c +++ b/common/config/libconfig/config_libconfig.c @@ -346,6 +346,7 @@ int config_libconfig_init(char *cfgP[], int numP) { libconfig_privdata.configfile = strdup((char *)cfgP[0]); config_get_if()->numptrs=0; memset(config_get_if()->ptrs,0,sizeof(void *) * CONFIG_MAX_ALLOCATEDPTRS); + memset(config_get_if()->ptrsAllocated, 0, sizeof(config_get_if()->ptrsAllocated)); /* Read the file. If there is an error, report it and exit. */ if(! config_read_file(&(libconfig_privdata.cfg), libconfig_privdata.configfile)) { diff --git a/common/utils/LOG/log.c b/common/utils/LOG/log.c index 2340c78bf18f4ea1cc56bc65ef6d4fd4950b3f9c..9fd67a6dbb9cf6a0f3f385b4df81788c465601b9 100644 --- a/common/utils/LOG/log.c +++ b/common/utils/LOG/log.c @@ -88,16 +88,19 @@ int write_file_matlab(const char *fname, void *data, int length, int dec, - char format) + unsigned int format) { FILE *fp=NULL; int i; + AssertFatal((format&~MATLAB_RAW) <16,""); + if (data == NULL) return -1; //printf("Writing %d elements of type %d to %s\n",length,format,fname); + if (format == 10 || format ==11 || format == 12 || format == 13 || format == 14) { fp = fopen(fname,"a+"); } else if (format != 10 && format !=11 && format != 12 && format != 13 && format != 14) { @@ -109,6 +112,32 @@ int write_file_matlab(const char *fname, return(-1); } + if ( (format&MATLAB_RAW) == MATLAB_RAW ) { + int sz[16]={sizeof(short), 2*sizeof(short), + sizeof(int), 2*sizeof(int), + sizeof(char), 2*sizeof(char), + sizeof(long long), + sizeof(double), 2*sizeof(double), + sizeof(unsigned char), + sizeof(short), + sizeof(short), + sizeof(short), + sizeof(short), + sizeof(short), + sizeof(short) + }; + int eltSz= sz[format&~MATLAB_RAW]; + if (dec==1) + fwrite(data, eltSz, length, fp); + else + for (i=0; i<length; i+=dec) + fwrite(data+i*eltSz, eltSz, 1, fp); + + fclose(fp); + return(0); + } + + if (format != 10 && format !=11 && format != 12 && format != 13 && format != 14) fprintf(fp,"%s = [",vname); @@ -214,6 +243,8 @@ int write_file_matlab(const char *fname, case 12 : // case eren for log2_maxh real unsigned 8 bit fprintf(fp,"%d \n",((unsigned char *)&data)[0]); break; + default: + AssertFatal(false, "unknown dump format: %d\n", format); } if (format != 10 && format !=11 && format !=12 && format != 13 && format != 15) { diff --git a/common/utils/LOG/log.h b/common/utils/LOG/log.h index d893708a8b5327d6af0fdd72852c6d374eb832d4..49c6bdfd4c32bf696995dd66192fef781125b7f2 100644 --- a/common/utils/LOG/log.h +++ b/common/utils/LOG/log.h @@ -336,7 +336,25 @@ typedef struct { @param dec decimation level @param format data format (0 = real 16-bit, 1 = complex 16-bit,2 real 32-bit, 3 complex 32-bit,4 = real 8-bit, 5 = complex 8-bit) */ -int32_t write_file_matlab(const char *fname, const char *vname, void *data, int length, int dec, char format); +#define MATLAB_RAW (1<<31) +#define MATLAB_SHORT 0 +#define MATLAB_CSHORT 1 +#define MATLAB_INT 2 +#define MATLAB_CINT 3 +#define MATLAB_INT8 4 +#define MATLAB_CINT8 5 +#define MATLAB_LLONG 6 +#define MATLAB_DOUBLE 7 +#define MATLAB_CDOUBLE 8 +#define MATLAB_UINT8 9 +#define MATLEB_EREN1 10 +#define MATLEB_EREN2 11 +#define MATLEB_EREN3 12 +#define MATLAB_CSHORT_BRACKET1 13 +#define MATLAB_CSHORT_BRACKET2 14 +#define MATLAB_CSHORT_BRACKET3 15 + +int32_t write_file_matlab(const char *fname, const char *vname, void *data, int length, int dec, unsigned int format); /*----------------macro definitions for reading log configuration from the config module */ #define CONFIG_STRING_LOG_PREFIX "log_config" diff --git a/common/utils/T/T_defs.h b/common/utils/T/T_defs.h index 7b5304b1cb144fdeb3ffdac617c27a45d398aba1..11c816f002a409c8befb42ff7381126a5e3b00a9 100644 --- a/common/utils/T/T_defs.h +++ b/common/utils/T/T_defs.h @@ -44,7 +44,7 @@ /* let's have 100 RBs functional for the basic simulator */ # define T_BUFFER_MAX (1024*64*2) #else -# define T_BUFFER_MAX (1024*64) +# define T_BUFFER_MAX (1024*64*2) #endif /* size of the local cache for messages (must be pow(2,something)) */ @@ -52,7 +52,7 @@ /* we don't need much space for the basic simulator */ # define T_CACHE_SIZE 1024 #else -# define T_CACHE_SIZE (8192 * 2) +# define T_CACHE_SIZE (8192) #endif /* maximum number of bytes a message can contain */ diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 06ee5bf12bb6d43a254f215419f29c74d0293298..bad6444e1303d385c9808608a599cf6e43330bab 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -1,3 +1,7 @@ +ID = BENETEL + GROUP = ALL + FORMAT = int,frame : int,slot : buffer,rxdataF + #general logs ID = ENB_MASTER_TICK DESC = eNodeB master tick - one tick per ms, to be used as "reference clock", mostly for ticktime view diff --git a/doc/TESTING_GNB_W_COTS_UE.md b/doc/TESTING_GNB_W_COTS_UE.md index 610cc5bdd47539b823c00917c530911fc211b093..73ae18351f2f1458a687ea41408321c3cc36180f 100644 --- a/doc/TESTING_GNB_W_COTS_UE.md +++ b/doc/TESTING_GNB_W_COTS_UE.md @@ -30,8 +30,6 @@ http://www.saelig.com/MFR00066/ste2300.htm ## Configuration Overview * Non Standalone (NSA) configuration : initial Control Plane established between UE and RAN eNB, then User Plane established between UE and gNB, Core network is 4G based supporting rel 15 - -* Commercial UE: Oppo Reno 5G * OAI Software Defined gNB and eNB * eNB RF front end: USRP (ETTUS) B200 Mini or B210 * gNB RF front end: USRP (ETTUS) B200 Mini or B210 (N310 will be needed for MIMO and wider BW's) @@ -40,6 +38,17 @@ http://www.saelig.com/MFR00066/ste2300.htm * BW: 40MHz * Antenna scheme: SISO +## COTS UEs + +Our code might not work with all 5G phones yet, but we are constantly improving it. Here is a list of COTS UEs that we know that work with OAI. + +* Oppo Reno 5G +* Samsung A90 5G +* Google Pixel 5G +* Simcom SIMCOM8200EA +* Quectel RM500Q-GL + + ## Repository https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 8ed4ac2e1cc21693316440175040f904299ef005..5a53c69063f64d069af19ec29af340b062f9b61b 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -1026,7 +1026,13 @@ void init_eNB_afterRU(void) { for (i=0; i<gNB->RU_list[ru_id]->nb_rx; aa++,i++) { LOG_I(PHY,"Attaching RU %d antenna %d to gNB antenna %d\n",gNB->RU_list[ru_id]->idx,i,aa); gNB->prach_vars.rxsigF[aa] = gNB->RU_list[ru_id]->prach_rxsigF[0][i]; +#if 0 +printf("before %p\n", gNB->common_vars.rxdataF[aa]); +#endif gNB->common_vars.rxdataF[aa] = gNB->RU_list[ru_id]->common.rxdataF[i]; +#if 0 +printf("after %p\n", gNB->common_vars.rxdataF[aa]); +#endif } } diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 87cd157948d5aac3a843daa3f432317d88f4ddd1..5d651344d608e606bb6d7d76512c9fe730edd99d 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -557,11 +557,14 @@ int main( int argc, char **argv ) { init_NR_UE_threads(1); - config_check_unknown_cmdlineopt(CONFIG_CHECKALLSECTIONS); printf("UE threads created by %ld\n", gettid()); // wait for end of program printf("TYPE <CTRL-C> TO TERMINATE\n"); + // Sleep a while before checking all parameters have been used + // Some are used directly in external threads, asynchronously + sleep(20); + config_check_unknown_cmdlineopt(CONFIG_CHECKALLSECTIONS); while(true) sleep(3600); diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h index ebe5c26bf6617c0a95101f94fdbac0fcac8efb71..bc5e7af45fb98e4c50c938457fed1afec386e7f0 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h @@ -715,8 +715,10 @@ typedef struct { uint16_t prgSize; /// Number of STD ant ports (parallel streams) feeding into the digBF Value: 0->255 uint8_t digBFInterfaces; + // Depends on numPRGs uint16_t PMIdx[275]; - uint16_t *beamIdx[275]; + // Depends on digBFInterfaces + uint16_t beamIdx[256]; } nfapi_nr_tx_precoding_and_beamforming_t; //table 3-37 diff --git a/openair1/PHY/MODULATION/nr_modulation.c b/openair1/PHY/MODULATION/nr_modulation.c index 0a7088ba398a1ef814e79084ba77e4dff72714d4..ed9a859fb64673c67faded9b0e33d4948b567a22 100644 --- a/openair1/PHY/MODULATION/nr_modulation.c +++ b/openair1/PHY/MODULATION/nr_modulation.c @@ -325,10 +325,10 @@ void nr_ue_layer_mapping(NR_UE_ULSCH_t **ulsch_ue, void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH) { -#if defined(__x86_64__) || defined(__i386__) - __m128i dft_in128[1][1200], dft_out128[1][1200]; +#if defined(__x86_64__) || +defined(__i386__) + __m128i dft_in128[1][3240], dft_out128[1][3240]; #elif defined(__arm__) - int16x8_t dft_in128[1][1200], dft_out128[1][1200]; + int16x8_t dft_in128[1][3240], dft_out128[1][3240]; #endif uint32_t *dft_in0 = (uint32_t*)dft_in128[0], *dft_out0 = (uint32_t*)dft_out128[0]; @@ -340,8 +340,10 @@ void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH) int16x8_t norm128; #endif - for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) { - dft_in0[ip] = d[i]; + if ((Msc_PUSCH % 1536) > 0) { + for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) { + dft_in0[ip] = d[i]; + } } switch (Msc_PUSCH) { @@ -480,7 +482,7 @@ void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH) break; case 972: - dft(DFT_960,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + dft(DFT_972,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); break; case 1080: @@ -494,11 +496,98 @@ void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH) case 1200: dft(DFT_1200,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); break; + + case 1296: + dft(DFT_1296,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 1440: + dft(DFT_1440,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 1500: + dft(DFT_1500,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 1536: + //dft(DFT_1536,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + dft(DFT_1536,(int16_t*)d, (int16_t*)z, 1); + break; + + case 1620: + dft(DFT_1620,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 1728: + dft(DFT_1728,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 1800: + dft(DFT_1800,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 1920: + dft(DFT_1920,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 1944: + dft(DFT_1944,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 2160: + dft(DFT_2160,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 2304: + dft(DFT_2304,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 2400: + dft(DFT_2400,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 2592: + dft(DFT_2592,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 2700: + dft(DFT_2700,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 2880: + dft(DFT_2880,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 2916: + dft(DFT_2916,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 3000: + dft(DFT_3000,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 3072: + //dft(DFT_3072,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + dft(DFT_3072,(int16_t*)d, (int16_t*)z, 1); + break; + + case 3240: + dft(DFT_3240,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + default: + // should not be reached + LOG_E( PHY, "Unsupported Msc_PUSCH value of %"PRIu16"\n", Msc_PUSCH ); + return; + } - for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) { - z[i] = dft_out0[ip]; + + if ((Msc_PUSCH % 1536) > 0) { + for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) + z[i] = dft_out0[ip]; } + } diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 713e71674b979f47fb4040a7712d7a875a1afc51..38b35dcf6d39a93969b7b3f1ee3cbb73158e7622 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -158,6 +158,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, #endif for (aarx=0; aarx<gNB->frame_parms.nb_antennas_rx; aarx++) { + re_offset = k; /* Initializing the Resource element offset for each Rx antenna */ + pil = (int16_t *)&pilot[0]; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)]; ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset]; diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index 7e6becb4a8b1213ccb062e7847517179d7210478..42d6cfad7a3e7ac19c3128fe86317628bc46269c 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -16,10 +16,10 @@ void nr_idft(int32_t *z, uint32_t Msc_PUSCH) { #if defined(__x86_64__) || defined(__i386__) - __m128i idft_in128[1][1200], idft_out128[1][1200]; + __m128i idft_in128[1][3240], idft_out128[1][3240]; __m128i norm128; #elif defined(__arm__) - int16x8_t idft_in128[1][1200], idft_out128[1][1200]; + int16x8_t idft_in128[1][3240], idft_out128[1][3240]; int16x8_t norm128; #endif int16_t *idft_in0 = (int16_t*)idft_in128[0], *idft_out0 = (int16_t*)idft_out128[0]; @@ -28,20 +28,19 @@ void nr_idft(int32_t *z, uint32_t Msc_PUSCH) LOG_T(PHY,"Doing lte_idft for Msc_PUSCH %d\n",Msc_PUSCH); - // conjugate input - for (i = 0; i < (Msc_PUSCH>>2); i++) { + if ((Msc_PUSCH % 1536) > 0) { + // conjugate input + for (i = 0; i < (Msc_PUSCH>>2); i++) { #if defined(__x86_64__)||defined(__i386__) - *&(((__m128i*)z)[i]) = _mm_sign_epi16(*&(((__m128i*)z)[i]), *(__m128i*)&conjugate2[0]); + *&(((__m128i*)z)[i]) = _mm_sign_epi16(*&(((__m128i*)z)[i]), *(__m128i*)&conjugate2[0]); #elif defined(__arm__) - *&(((int16x8_t*)z)[i]) = vmulq_s16(*&(((int16x8_t*)z)[i]), *(int16x8_t*)&conjugate2[0]); + *&(((int16x8_t*)z)[i]) = vmulq_s16(*&(((int16x8_t*)z)[i]), *(int16x8_t*)&conjugate2[0]); #endif + } + for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) + ((uint32_t*)idft_in0)[ip+0] = z[i]; } - for (i=0,ip=0; i<Msc_PUSCH; i++, ip+=4) { - ((int32_t*)idft_in0)[ip+0] = z[i]; - } - - switch (Msc_PUSCH) { case 12: dft(DFT_12,(int16_t *)idft_in0, (int16_t *)idft_out0,0); @@ -194,25 +193,102 @@ void nr_idft(int32_t *z, uint32_t Msc_PUSCH) dft(DFT_1200,idft_in0, idft_out0, 1); break; + case 1296: + dft(DFT_1296,(int16_t*)idft_in0, (int16_t*)idft_out0, 1); + break; + + case 1440: + dft(DFT_1440,(int16_t*)idft_in0, (int16_t*)idft_out0, 1); + break; + + case 1500: + dft(DFT_1500,(int16_t*)idft_in0, (int16_t*)idft_out0, 1); + break; + + case 1536: + //dft(DFT_1536,(int16_t*)idft_in0, (int16_t*)idft_out0, 1); + idft(IDFT_1536,(int16_t*)z, (int16_t*)z, 1); + break; + + case 1620: + dft(DFT_1620,(int16_t*)idft_in0, (int16_t*)idft_out0, 1); + break; + + case 1728: + dft(DFT_1728,(int16_t*)idft_in0, (int16_t*)idft_out0, 1); + break; + + case 1800: + dft(DFT_1800,(int16_t*)idft_in0, (int16_t*)idft_out0, 1); + break; + + case 1920: + dft(DFT_1920,(int16_t*)idft_in0, (int16_t*)idft_out0, 1); + break; + + case 1944: + dft(DFT_1944,(int16_t*)idft_in0, (int16_t*)idft_out0, 1); + break; + + case 2160: + dft(DFT_2160,(int16_t*)idft_in0, (int16_t*)idft_out0, 1); + break; + + case 2304: + dft(DFT_2304,(int16_t*)idft_in0, (int16_t*)idft_out0, 1); + break; + + case 2400: + dft(DFT_2400,(int16_t*)idft_in0, (int16_t*)idft_out0, 1); + break; + + case 2592: + dft(DFT_2592,(int16_t*)idft_in0, (int16_t*)idft_out0, 1); + break; + + case 2700: + dft(DFT_2700,(int16_t*)idft_in0, (int16_t*)idft_out0, 1); + break; + + case 2880: + dft(DFT_2880,(int16_t*)idft_in0, (int16_t*)idft_out0, 1); + break; + + case 2916: + dft(DFT_2916,(int16_t*)idft_in0, (int16_t*)idft_out0, 1); + break; + + case 3000: + dft(DFT_3000,(int16_t*)idft_in0, (int16_t*)idft_out0, 1); + break; + + case 3072: + //dft(DFT_3072,(int16_t*)idft_in0, (int16_t*)idft_out0, 1); + idft(IDFT_3072,(int16_t*)z, (int16_t*)z, 1); + break; + + case 3240: + dft(DFT_3240,(int16_t*)idft_in0, (int16_t*)idft_out0, 1); + break; + default: // should not be reached LOG_E( PHY, "Unsupported Msc_PUSCH value of %"PRIu16"\n", Msc_PUSCH ); return; } + if ((Msc_PUSCH % 1536) > 0) { + for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) + z[i] = ((uint32_t*)idft_out0)[ip]; - - for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) { - z[i] = ((int32_t*)idft_out0)[ip]; - } - - // conjugate output - for (i = 0; i < (Msc_PUSCH>>2); i++) { + // conjugate output + for (i = 0; i < (Msc_PUSCH>>2); i++) { #if defined(__x86_64__) || defined(__i386__) - ((__m128i*)z)[i] = _mm_sign_epi16(((__m128i*)z)[i], *(__m128i*)&conjugate2[0]); + ((__m128i*)z)[i] = _mm_sign_epi16(((__m128i*)z)[i], *(__m128i*)&conjugate2[0]); #elif defined(__arm__) - *&(((int16x8_t*)z)[i]) = vmulq_s16(*&(((int16x8_t*)z)[i]), *(int16x8_t*)&conjugate2[0]); + *&(((int16x8_t*)z)[i]) = vmulq_s16(*&(((int16x8_t*)z)[i]), *(int16x8_t*)&conjugate2[0]); #endif + } } #if defined(__x86_64__) || defined(__i386__) @@ -222,6 +298,7 @@ void nr_idft(int32_t *z, uint32_t Msc_PUSCH) } + void nr_ulsch_extract_rbs_single(int32_t **rxdataF, NR_gNB_PUSCH *pusch_vars, unsigned char symbol, diff --git a/openair1/PHY/TOOLS/nr_phy_scope.c b/openair1/PHY/TOOLS/nr_phy_scope.c index f6cb93ed037dbc9e93fdfea1eca32e506ec54728..cb6152385260942df9ebe89fd11ae3bd0f5cafa0 100644 --- a/openair1/PHY/TOOLS/nr_phy_scope.c +++ b/openair1/PHY/TOOLS/nr_phy_scope.c @@ -225,6 +225,8 @@ static void oai_xygraph(OAIgraph_t *graph, float *x, float *y, int len, int laye } static void genericWaterFall (OAIgraph_t *graph, scopeSample_t *values, const int datasize, const int divisions, const char *label) { + if ( values == NULL ) + return; fl_winset(FL_ObjWin(graph->graph)); const int samplesPerPixel=datasize/graph->w; int displayPart=graph->waterFallh-ScaleZone; diff --git a/openair1/PHY/TOOLS/oai_dfts.c b/openair1/PHY/TOOLS/oai_dfts.c index e4e85f7ba9ce3207a2ef8a70b45f87153b2060ce..6569f7eab5be3b4b92c92b951bd73ef360fd1329 100644 --- a/openair1/PHY/TOOLS/oai_dfts.c +++ b/openair1/PHY/TOOLS/oai_dfts.c @@ -5952,8 +5952,6 @@ void idft32768(int16_t *x,int16_t *y,unsigned char scale) #endif - - int16_t twa1536[1024],twb1536[1024]; // 512 x 3 @@ -9471,145 +9469,1058 @@ void dft1200(int16_t *x,int16_t *y,unsigned char scale_flag) } -void init_rad4(int N,int16_t *tw) { - int16_t *twa = tw; - int16_t *twb = twa+(N/2); - int16_t *twc = twb+(N/2); - int i; +static int16_t twa1296[431*2*4]; +static int16_t twb1296[431*2*4]; - for (i=0;i<(N/4);i++) { - *twa = (int16_t)round(32767.0*cos(2*M_PI*i/N)); twa++; - *twa = -(int16_t)round(32767.0*sin(2*M_PI*i/N)); twa++; - *twb = (int16_t)round(32767.0*cos(2*M_PI*2*i/N)); twb++; - *twb = -(int16_t)round(32767.0*sin(2*M_PI*2*i/N)); twb++; - *twc = (int16_t)round(32767.0*cos(2*M_PI*3*i/N)); twc++; - *twc = -(int16_t)round(32767.0*sin(2*M_PI*3*i/N)); twc++; - } -} -void init_rad4_rep(int N,int16_t *twa,int16_t *twb,int16_t *twc) { +void dft1296(int16_t *x,int16_t *y,unsigned char scale_flag) //432 * 3 +{ int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa1296[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb1296[0]; + simd_q15_t x2128[1296];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[1296];//=&ytmp128array3[0]; - for (i=1;i<(N/4);i++) { - twa[0] = (int16_t)round(32767.0*cos(2*M_PI*i/N)); - twa[1] = -(int16_t)round(32767.0*sin(2*M_PI*i/N)); - twb[0] = (int16_t)round(32767.0*cos(2*M_PI*2*i/N)); - twb[1] = -(int16_t)round(32767.0*sin(2*M_PI*2*i/N)); - twc[0] = (int16_t)round(32767.0*cos(2*M_PI*3*i/N)); - twc[1] = -(int16_t)round(32767.0*sin(2*M_PI*3*i/N)); - for (j=1;j<4;j++) { - ((int32_t*)twa)[j]=((int32_t*)twa)[0]; - ((int32_t*)twb)[j]=((int32_t*)twb)[0]; - ((int32_t*)twc)[j]=((int32_t*)twc)[0]; - } - twa+=8; - twb+=8; - twc+=8; + + + for (i=0,j=0; i<432; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+432] = x128[j+1]; + x2128[i+864] = x128[j+2]; } -} -void init_rad2(int N,int16_t *tw) { + dft432((int16_t *)x2128,(int16_t *)ytmp128,1); + dft432((int16_t *)(x2128+432),(int16_t *)(ytmp128+432),1); + dft432((int16_t *)(x2128+864),(int16_t *)(ytmp128+864),1); - int16_t *twa = tw; - int i; + bfly3_tw1(ytmp128,ytmp128+432,ytmp128+864,y128,y128+432,y128+864); - for (i=0;i<(N>>1);i++) { - *twa = (int16_t)round(32767.0*cos(2*M_PI*i/N)); twa++; - *twa = -(int16_t)round(32767.0*sin(2*M_PI*i/N)); twa++; + for (i=1,j=0; i<432; i++,j++) { + bfly3(ytmp128+i, + ytmp128+432+i, + ytmp128+864+i, + y128+i, + y128+432+i, + y128+864+i, + twa128+j, + twb128+j); } -} -void init_rad2_rep(int N,int16_t *twa) { + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<1296; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa1440[479*2*4]; +static int16_t twb1440[479*2*4]; + +void dft1440(int16_t *x,int16_t *y,unsigned char scale_flag) // 480 x 3 +{ int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa1440[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb1440[0]; + simd_q15_t x2128[1440];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[1440];//=&ytmp128array3[0]; - for (i=1;i<(N/2);i++) { - twa[0] = (int16_t)round(32767.0*cos(2*M_PI*i/N)); - twa[1] = -(int16_t)round(32767.0*sin(2*M_PI*i/N)); - for (j=1;j<4;j++) { - ((int32_t*)twa)[j]=((int32_t*)twa)[0]; + + + for (i=0,j=0; i<480; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+480] = x128[j+1]; + x2128[i+960] = x128[j+2]; + } + + dft480((int16_t *)x2128,(int16_t *)ytmp128,1); + dft480((int16_t *)(x2128+480),(int16_t *)(ytmp128+480),1); + dft480((int16_t *)(x2128+960),(int16_t *)(ytmp128+960),1); + + bfly3_tw1(ytmp128,ytmp128+480,ytmp128+960,y128,y128+480,y128+960); + + for (i=1,j=0; i<480; i++,j++) { + bfly3(ytmp128+i, + ytmp128+480+i, + ytmp128+960+i, + y128+i, + y128+480+i, + y128+960+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<1440; i++) { + y128[i] = mulhi_int16(y128[i],norm128); } - twa+=8; } -} -void init_rad3(int N,int16_t *twa,int16_t *twb) { + _mm_empty(); + _m_empty(); - int i; +}; - for (i=0;i<(N/3);i++) { - *twa = (int16_t)round(32767.0*cos(2*M_PI*i/N)); twa++; - *twa = -(int16_t)round(32767.0*sin(2*M_PI*i/N)); twa++; - *twb = (int16_t)round(32767.0*cos(2*M_PI*2*i/N)); twb++; - *twb = -(int16_t)round(32767.0*sin(2*M_PI*2*i/N)); twb++; +static int16_t twa1500[2392]__attribute__((aligned(32))); +static int16_t twb1500[2392]__attribute__((aligned(32))); +static int16_t twc1500[2392]__attribute__((aligned(32))); +static int16_t twd1500[2392]__attribute__((aligned(32))); + +void dft1500(int16_t *x,int16_t *y,unsigned char scale_flag) +{ + + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa1500[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb1500[0]; + simd_q15_t *twc128=(simd_q15_t *)&twc1500[0]; + simd_q15_t *twd128=(simd_q15_t *)&twd1500[0]; + simd_q15_t x2128[1500];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[1500];//=&ytmp128array2[0]; + + + + for (i=0,j=0; i<300; i++,j+=5) { + x2128[i] = x128[j]; + x2128[i+300] = x128[j+1]; + x2128[i+600] = x128[j+2]; + x2128[i+900] = x128[j+3]; + x2128[i+1200] = x128[j+4]; + } + + dft300((int16_t *)x2128,(int16_t *)ytmp128,1); + dft300((int16_t *)(x2128+300),(int16_t *)(ytmp128+300),1); + dft300((int16_t *)(x2128+600),(int16_t *)(ytmp128+600),1); + dft300((int16_t *)(x2128+900),(int16_t *)(ytmp128+900),1); + dft300((int16_t *)(x2128+1200),(int16_t *)(ytmp128+1200),1); + + bfly5_tw1(ytmp128,ytmp128+300,ytmp128+600,ytmp128+900,ytmp128+1200,y128,y128+300,y128+600,y128+900,y128+1200); + + for (i=1,j=0; i<300; i++,j++) { + bfly5(ytmp128+i, + ytmp128+300+i, + ytmp128+600+i, + ytmp128+900+i, + ytmp128+1200+i, + y128+i, + y128+300+i, + y128+600+i, + y128+900+i, + y128+1200+i, + twa128+j, + twb128+j, + twc128+j, + twd128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[15]); + + for (i=0; i<1500; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } } + + _mm_empty(); + _m_empty(); + } -void init_rad3_rep(int N,int16_t *twa,int16_t *twb) { +static int16_t twa1620[539*2*4]; +static int16_t twb1620[539*2*4]; +void dft1620(int16_t *x,int16_t *y,unsigned char scale_flag) // 540 x 3 +{ int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa1620[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb1620[0]; + simd_q15_t x2128[1620];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[1620];//=&ytmp128array3[0]; - for (i=1;i<(N/3);i++) { - twa[0] = (int16_t)round(32767.0*cos(2*M_PI*i/N)); - twa[1] = -(int16_t)round(32767.0*sin(2*M_PI*i/N)); - twb[0] = (int16_t)round(32767.0*cos(2*M_PI*2*i/N)); - twb[1] = -(int16_t)round(32767.0*sin(2*M_PI*2*i/N)); - for (j=1;j<4;j++) { - ((int32_t*)twa)[j]=((int32_t*)twa)[0]; - ((int32_t*)twb)[j]=((int32_t*)twb)[0]; + + + for (i=0,j=0; i<540; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+540] = x128[j+1]; + x2128[i+1080] = x128[j+2]; + } + + dft540((int16_t *)x2128,(int16_t *)ytmp128,1); + dft540((int16_t *)(x2128+540),(int16_t *)(ytmp128+540),1); + dft540((int16_t *)(x2128+1080),(int16_t *)(ytmp128+1080),1); + + bfly3_tw1(ytmp128,ytmp128+540,ytmp128+1080,y128,y128+540,y128+1080); + + for (i=1,j=0; i<540; i++,j++) { + bfly3(ytmp128+i, + ytmp128+540+i, + ytmp128+1080+i, + y128+i, + y128+540+i, + y128+1080+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<1620; i++) { + y128[i] = mulhi_int16(y128[i],norm128); } - twa+=8; - twb+=8; } -} -void init_rad5_rep(int N,int16_t *twa,int16_t *twb,int16_t *twc,int16_t *twd) { + _mm_empty(); + _m_empty(); + +}; +static int16_t twa1728[575*2*4]; +static int16_t twb1728[575*2*4]; + +void dft1728(int16_t *x,int16_t *y,unsigned char scale_flag) // 576 x 3 +{ int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa1728[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb1728[0]; + simd_q15_t x2128[1728];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[1728];//=&ytmp128array3[0]; - for (i=1;i<(N/5);i++) { - twa[0] = (int16_t)round(32767.0*cos(2*M_PI*i/N)); - twa[1] = -(int16_t)round(32767.0*sin(2*M_PI*i/N)); - twb[0] = (int16_t)round(32767.0*cos(2*M_PI*2*i/N)); - twb[1] = -(int16_t)round(32767.0*sin(2*M_PI*2*i/N)); - twc[0] = (int16_t)round(32767.0*cos(2*M_PI*3*i/N)); - twc[1] = -(int16_t)round(32767.0*sin(2*M_PI*3*i/N)); - twd[0] = (int16_t)round(32767.0*cos(2*M_PI*4*i/N)); - twd[1] = -(int16_t)round(32767.0*sin(2*M_PI*4*i/N)); - for (j=1;j<4;j++) { - ((int32_t*)twa)[j]=((int32_t*)twa)[0]; - ((int32_t*)twb)[j]=((int32_t*)twb)[0]; - ((int32_t*)twc)[j]=((int32_t*)twc)[0]; - ((int32_t*)twd)[j]=((int32_t*)twd)[0]; + + + for (i=0,j=0; i<576; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+576] = x128[j+1]; + x2128[i+1152] = x128[j+2]; + } + + dft576((int16_t *)x2128,(int16_t *)ytmp128,1); + dft576((int16_t *)(x2128+576),(int16_t *)(ytmp128+576),1); + dft576((int16_t *)(x2128+1152),(int16_t *)(ytmp128+1152),1); + + bfly3_tw1(ytmp128,ytmp128+576,ytmp128+1152,y128,y128+576,y128+1152); + + for (i=1,j=0; i<576; i++,j++) { + bfly3(ytmp128+i, + ytmp128+576+i, + ytmp128+1152+i, + y128+i, + y128+576+i, + y128+1152+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<1728; i++) { + y128[i] = mulhi_int16(y128[i],norm128); } - twa+=8; - twb+=8; - twc+=8; - twd+=8; } -} -/*----------------------------------------------------------------*/ -/* dft library entry points: */ -int dfts_autoinit(void) + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa1800[599*2*4]; +static int16_t twb1800[599*2*4]; + +void dft1800(int16_t *x,int16_t *y,unsigned char scale_flag) // 600 x 3 { - init_rad4(1024,tw1024); - init_rad2(2048,tw2048); - init_rad4(4096,tw4096); - init_rad2(8192,tw8192); - init_rad4(16384,tw16384); - init_rad2(32768,tw32768); - - init_rad3(1536,twa1536,twb1536); - init_rad3(3072,twa3072,twb3072); - init_rad3(6144,twa6144,twb6144); - init_rad3(12288,twa12288,twb12288); - init_rad3(18432,twa18432,twb18432); - init_rad3(24576,twa24576,twb24576); - init_rad3(36864,twa36864,twb36864); - init_rad3(49152,twa49152,twb49152); - init_rad3(98304,twa98304,twb98304); + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa1800[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb1800[0]; + simd_q15_t x2128[1800];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[1800];//=&ytmp128array3[0]; + + + + for (i=0,j=0; i<600; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+600] = x128[j+1]; + x2128[i+1200] = x128[j+2]; + } + + dft600((int16_t *)x2128,(int16_t *)ytmp128,1); + dft600((int16_t *)(x2128+600),(int16_t *)(ytmp128+600),1); + dft600((int16_t *)(x2128+1200),(int16_t *)(ytmp128+1200),1); + + bfly3_tw1(ytmp128,ytmp128+600,ytmp128+1200,y128,y128+600,y128+1200); + + for (i=1,j=0; i<600; i++,j++) { + bfly3(ytmp128+i, + ytmp128+600+i, + ytmp128+1200+i, + y128+i, + y128+600+i, + y128+1200+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<1800; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa1920[479*2*4]; +static int16_t twb1920[479*2*4]; +static int16_t twc1920[479*2*4]; + +void dft1920(int16_t *x,int16_t *y,unsigned char scale_flag) // 480 x 4 +{ + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa1920[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb1920[0]; + simd_q15_t *twc128=(simd_q15_t *)&twc1920[0]; + simd_q15_t x2128[1920];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[1920];//=&ytmp128array2[0]; + + + + for (i=0,j=0; i<480; i++,j+=4) { + x2128[i] = x128[j]; + x2128[i+480] = x128[j+1]; + x2128[i+960] = x128[j+2]; + x2128[i+1440] = x128[j+3]; + } + + dft480((int16_t *)x2128,(int16_t *)ytmp128,1); + dft480((int16_t *)(x2128+480),(int16_t *)(ytmp128+480),1); + dft480((int16_t *)(x2128+960),(int16_t *)(ytmp128+960),1); + dft480((int16_t *)(x2128+1440),(int16_t *)(ytmp128+1440),1); + + bfly4_tw1(ytmp128,ytmp128+480,ytmp128+960,ytmp128+1440,y128,y128+480,y128+960,y128+1440); + + for (i=1,j=0; i<480; i++,j++) { + bfly4(ytmp128+i, + ytmp128+480+i, + ytmp128+960+i, + ytmp128+1440+i, + y128+i, + y128+480+i, + y128+960+i, + y128+1440+i, + twa128+j, + twb128+j, + twc128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[13]); + for (i=0; i<1920; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa1944[647*2*4]; +static int16_t twb1944[647*2*4]; + +void dft1944(int16_t *x,int16_t *y,unsigned char scale_flag) // 648 x 3 +{ + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa1944[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb1944[0]; + simd_q15_t x2128[1944];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[1944];//=&ytmp128array3[0]; + + + + for (i=0,j=0; i<648; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+648] = x128[j+1]; + x2128[i+1296] = x128[j+2]; + } + + dft648((int16_t *)x2128,(int16_t *)ytmp128,1); + dft648((int16_t *)(x2128+648),(int16_t *)(ytmp128+648),1); + dft648((int16_t *)(x2128+1296),(int16_t *)(ytmp128+1296),1); + + bfly3_tw1(ytmp128,ytmp128+648,ytmp128+1296,y128,y128+648,y128+1296); + + for (i=1,j=0; i<648; i++,j++) { + bfly3(ytmp128+i, + ytmp128+648+i, + ytmp128+1296+i, + y128+i, + y128+648+i, + y128+1296+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<1944; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa2160[719*2*4]; +static int16_t twb2160[719*2*4]; + +void dft2160(int16_t *x,int16_t *y,unsigned char scale_flag) // 720 x 3 +{ + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa2160[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb2160[0]; + simd_q15_t x2128[2160];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[2160];//=&ytmp128array3[0]; + + + + for (i=0,j=0; i<720; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+720] = x128[j+1]; + x2128[i+1440] = x128[j+2]; + } + + dft720((int16_t *)x2128,(int16_t *)ytmp128,1); + dft720((int16_t *)(x2128+720),(int16_t *)(ytmp128+720),1); + dft720((int16_t *)(x2128+1440),(int16_t *)(ytmp128+1440),1); + + bfly3_tw1(ytmp128,ytmp128+720,ytmp128+1440,y128,y128+720,y128+1440); + + for (i=1,j=0; i<720; i++,j++) { + bfly3(ytmp128+i, + ytmp128+720+i, + ytmp128+1440+i, + y128+i, + y128+720+i, + y128+1440+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<2160; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa2304[767*2*4]; +static int16_t twb2304[767*2*4]; + +void dft2304(int16_t *x,int16_t *y,unsigned char scale_flag) // 768 x 3 +{ + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa2304[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb2304[0]; + simd_q15_t x2128[2304];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[2304];//=&ytmp128array3[0]; + + + + for (i=0,j=0; i<768; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+768] = x128[j+1]; + x2128[i+1536] = x128[j+2]; + } + + dft768((int16_t *)x2128,(int16_t *)ytmp128,1); + dft768((int16_t *)(x2128+768),(int16_t *)(ytmp128+768),1); + dft768((int16_t *)(x2128+1536),(int16_t *)(ytmp128+1536),1); + + bfly3_tw1(ytmp128,ytmp128+768,ytmp128+1536,y128,y128+768,y128+1536); + + for (i=1,j=0; i<768; i++,j++) { + bfly3(ytmp128+i, + ytmp128+768+i, + ytmp128+1536+i, + y128+i, + y128+768+i, + y128+1536+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<2304; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa2400[599*2*4]; +static int16_t twb2400[599*2*4]; +static int16_t twc2400[599*2*4]; + +void dft2400(int16_t *x,int16_t *y,unsigned char scale_flag) // 600 x 4 +{ + + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa2400[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb2400[0]; + simd_q15_t *twc128=(simd_q15_t *)&twc2400[0]; + simd_q15_t x2128[2400];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[2400];//=&ytmp128array2[0]; + + + + for (i=0,j=0; i<600; i++,j+=4) { + x2128[i] = x128[j]; + x2128[i+600] = x128[j+1]; + x2128[i+1200] = x128[j+2]; + x2128[i+1800] = x128[j+3]; + } + + dft600((int16_t *)x2128,(int16_t *)ytmp128,1); + dft600((int16_t *)(x2128+600),(int16_t *)(ytmp128+600),1); + dft600((int16_t *)(x2128+1200),(int16_t *)(ytmp128+1200),1); + dft600((int16_t *)(x2128+1800),(int16_t *)(ytmp128+1800),1); + + bfly4_tw1(ytmp128,ytmp128+600,ytmp128+1200,ytmp128+1800,y128,y128+600,y128+1200,y128+1800); + + for (i=1,j=0; i<600; i++,j++) { + bfly4(ytmp128+i, + ytmp128+600+i, + ytmp128+1200+i, + ytmp128+1800+i, + y128+i, + y128+600+i, + y128+1200+i, + y128+1800+i, + twa128+j, + twb128+j, + twc128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[13]); + for (i=0; i<2400; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa2592[863*2*4]; +static int16_t twb2592[863*2*4]; + +void dft2592(int16_t *x,int16_t *y,unsigned char scale_flag) // 864 x 3 +{ + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa2592[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb2592[0]; + simd_q15_t x2128[2592];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[2592];//=&ytmp128array3[0]; + + + + for (i=0,j=0; i<864; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+864] = x128[j+1]; + x2128[i+1728] = x128[j+2]; + } + + dft864((int16_t *)x2128,(int16_t *)ytmp128,1); + dft864((int16_t *)(x2128+864),(int16_t *)(ytmp128+864),1); + dft864((int16_t *)(x2128+1728),(int16_t *)(ytmp128+1728),1); + + bfly3_tw1(ytmp128,ytmp128+864,ytmp128+1728,y128,y128+864,y128+1728); + + for (i=1,j=0; i<864; i++,j++) { + bfly3(ytmp128+i, + ytmp128+864+i, + ytmp128+1728+i, + y128+i, + y128+864+i, + y128+1728+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<2592; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa2700[899*2*4]; +static int16_t twb2700[899*2*4]; + +void dft2700(int16_t *x,int16_t *y,unsigned char scale_flag) // 900 x 3 +{ + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa2700[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb2700[0]; + simd_q15_t x2128[2700];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[2700];//=&ytmp128array3[0]; + + + + for (i=0,j=0; i<900; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+900] = x128[j+1]; + x2128[i+1800] = x128[j+2]; + } + + dft900((int16_t *)x2128,(int16_t *)ytmp128,1); + dft900((int16_t *)(x2128+900),(int16_t *)(ytmp128+900),1); + dft900((int16_t *)(x2128+1800),(int16_t *)(ytmp128+1800),1); + + bfly3_tw1(ytmp128,ytmp128+900,ytmp128+1800,y128,y128+900,y128+1800); + + for (i=1,j=0; i<900; i++,j++) { + bfly3(ytmp128+i, + ytmp128+900+i, + ytmp128+1800+i, + y128+i, + y128+900+i, + y128+1800+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<2700; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa2880[959*2*4]; +static int16_t twb2880[959*2*4]; + +void dft2880(int16_t *x,int16_t *y,unsigned char scale_flag) // 960 x 3 +{ + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa2880[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb2880[0]; + simd_q15_t x2128[2880];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[2880];//=&ytmp128array3[0]; + + + + for (i=0,j=0; i<960; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+960] = x128[j+1]; + x2128[i+1920] = x128[j+2]; + } + + dft960((int16_t *)x2128,(int16_t *)ytmp128,1); + dft960((int16_t *)(x2128+960),(int16_t *)(ytmp128+960),1); + dft960((int16_t *)(x2128+1920),(int16_t *)(ytmp128+1920),1); + + bfly3_tw1(ytmp128,ytmp128+960,ytmp128+1920,y128,y128+960,y128+1920); + + for (i=1,j=0; i<960; i++,j++) { + bfly3(ytmp128+i, + ytmp128+960+i, + ytmp128+1920+i, + y128+i, + y128+960+i, + y128+1920+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<2880; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa2916[971*2*4]; +static int16_t twb2916[971*2*4]; + +void dft2916(int16_t *x,int16_t *y,unsigned char scale_flag) // 972 x 3 +{ + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa2916[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb2916[0]; + simd_q15_t x2128[2916];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[2916];//=&ytmp128array3[0]; + + + + for (i=0,j=0; i<972; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+972] = x128[j+1]; + x2128[i+1944] = x128[j+2]; + } + + dft972((int16_t *)x2128,(int16_t *)ytmp128,1); + dft972((int16_t *)(x2128+972),(int16_t *)(ytmp128+972),1); + dft972((int16_t *)(x2128+1944),(int16_t *)(ytmp128+1944),1); + + bfly3_tw1(ytmp128,ytmp128+972,ytmp128+1944,y128,y128+972,y128+1944); + + for (i=1,j=0; i<972; i++,j++) { + bfly3(ytmp128+i, + ytmp128+972+i, + ytmp128+1944+i, + y128+i, + y128+972+i, + y128+1944+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<2916; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa3000[599*8]__attribute__((aligned(32))); +static int16_t twb3000[599*8]__attribute__((aligned(32))); +static int16_t twc3000[599*8]__attribute__((aligned(32))); +static int16_t twd3000[599*8]__attribute__((aligned(32))); + +void dft3000(int16_t *x,int16_t *y,unsigned char scale_flag) // 600 * 5 +{ + + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa3000[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb3000[0]; + simd_q15_t *twc128=(simd_q15_t *)&twc3000[0]; + simd_q15_t *twd128=(simd_q15_t *)&twd3000[0]; + simd_q15_t x2128[3000];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[3000];//=&ytmp128array2[0]; + + + + for (i=0,j=0; i<600; i++,j+=5) { + x2128[i] = x128[j]; + x2128[i+600] = x128[j+1]; + x2128[i+1200] = x128[j+2]; + x2128[i+1800] = x128[j+3]; + x2128[i+2400] = x128[j+4]; + } + + dft600((int16_t *)x2128,(int16_t *)ytmp128,1); + dft600((int16_t *)(x2128+600),(int16_t *)(ytmp128+600),1); + dft600((int16_t *)(x2128+1200),(int16_t *)(ytmp128+1200),1); + dft600((int16_t *)(x2128+1800),(int16_t *)(ytmp128+1800),1); + dft600((int16_t *)(x2128+2400),(int16_t *)(ytmp128+2400),1); + + bfly5_tw1(ytmp128,ytmp128+600,ytmp128+1200,ytmp128+1800,ytmp128+2400,y128,y128+600,y128+1200,y128+1800,y128+2400); + + for (i=1,j=0; i<600; i++,j++) { + bfly5(ytmp128+i, + ytmp128+600+i, + ytmp128+1200+i, + ytmp128+1800+i, + ytmp128+2400+i, + y128+i, + y128+600+i, + y128+1200+i, + y128+1800+i, + y128+2400+i, + twa128+j, + twb128+j, + twc128+j, + twd128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[15]); + + for (i=0; i<3000; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +} + +static int16_t twa3240[1079*2*4]; +static int16_t twb3240[1079*2*4]; + +void dft3240(int16_t *x,int16_t *y,unsigned char scale_flag) // 1080 x 3 +{ + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa3240[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb3240[0]; + simd_q15_t x2128[3240];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[3240];//=&ytmp128array3[0]; + + + + for (i=0,j=0; i<1080; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+1080] = x128[j+1]; + x2128[i+2160] = x128[j+2]; + } + + dft1080((int16_t *)x2128,(int16_t *)ytmp128,1); + dft1080((int16_t *)(x2128+1080),(int16_t *)(ytmp128+1080),1); + dft1080((int16_t *)(x2128+2160),(int16_t *)(ytmp128+2160),1); + + bfly3_tw1(ytmp128,ytmp128+1080,ytmp128+2160,y128,y128+1080,y128+2160); + + for (i=1,j=0; i<1080; i++,j++) { + bfly3(ytmp128+i, + ytmp128+1080+i, + ytmp128+2160+i, + y128+i, + y128+1080+i, + y128+2160+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<3240; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +void init_rad4(int N,int16_t *tw) { + + int16_t *twa = tw; + int16_t *twb = twa+(N/2); + int16_t *twc = twb+(N/2); + int i; + + for (i=0;i<(N/4);i++) { + *twa = (int16_t)round(32767.0*cos(2*M_PI*i/N)); twa++; + *twa = -(int16_t)round(32767.0*sin(2*M_PI*i/N)); twa++; + *twb = (int16_t)round(32767.0*cos(2*M_PI*2*i/N)); twb++; + *twb = -(int16_t)round(32767.0*sin(2*M_PI*2*i/N)); twb++; + *twc = (int16_t)round(32767.0*cos(2*M_PI*3*i/N)); twc++; + *twc = -(int16_t)round(32767.0*sin(2*M_PI*3*i/N)); twc++; + } +} +void init_rad4_rep(int N,int16_t *twa,int16_t *twb,int16_t *twc) { + + int i,j; + + for (i=1;i<(N/4);i++) { + twa[0] = (int16_t)round(32767.0*cos(2*M_PI*i/N)); + twa[1] = -(int16_t)round(32767.0*sin(2*M_PI*i/N)); + twb[0] = (int16_t)round(32767.0*cos(2*M_PI*2*i/N)); + twb[1] = -(int16_t)round(32767.0*sin(2*M_PI*2*i/N)); + twc[0] = (int16_t)round(32767.0*cos(2*M_PI*3*i/N)); + twc[1] = -(int16_t)round(32767.0*sin(2*M_PI*3*i/N)); + for (j=1;j<4;j++) { + ((int32_t*)twa)[j]=((int32_t*)twa)[0]; + ((int32_t*)twb)[j]=((int32_t*)twb)[0]; + ((int32_t*)twc)[j]=((int32_t*)twc)[0]; + } + twa+=8; + twb+=8; + twc+=8; + } +} + +void init_rad2(int N,int16_t *tw) { + + int16_t *twa = tw; + int i; + + for (i=0;i<(N>>1);i++) { + *twa = (int16_t)round(32767.0*cos(2*M_PI*i/N)); twa++; + *twa = -(int16_t)round(32767.0*sin(2*M_PI*i/N)); twa++; + } +} + +void init_rad2_rep(int N,int16_t *twa) { + + int i,j; + + for (i=1;i<(N/2);i++) { + twa[0] = (int16_t)round(32767.0*cos(2*M_PI*i/N)); + twa[1] = -(int16_t)round(32767.0*sin(2*M_PI*i/N)); + for (j=1;j<4;j++) { + ((int32_t*)twa)[j]=((int32_t*)twa)[0]; + } + twa+=8; + } +} + +void init_rad3(int N,int16_t *twa,int16_t *twb) { + + int i; + + for (i=0;i<(N/3);i++) { + *twa = (int16_t)round(32767.0*cos(2*M_PI*i/N)); twa++; + *twa = -(int16_t)round(32767.0*sin(2*M_PI*i/N)); twa++; + *twb = (int16_t)round(32767.0*cos(2*M_PI*2*i/N)); twb++; + *twb = -(int16_t)round(32767.0*sin(2*M_PI*2*i/N)); twb++; + } +} + +void init_rad3_rep(int N,int16_t *twa,int16_t *twb) { + + int i,j; + + for (i=1;i<(N/3);i++) { + twa[0] = (int16_t)round(32767.0*cos(2*M_PI*i/N)); + twa[1] = -(int16_t)round(32767.0*sin(2*M_PI*i/N)); + twb[0] = (int16_t)round(32767.0*cos(2*M_PI*2*i/N)); + twb[1] = -(int16_t)round(32767.0*sin(2*M_PI*2*i/N)); + for (j=1;j<4;j++) { + ((int32_t*)twa)[j]=((int32_t*)twa)[0]; + ((int32_t*)twb)[j]=((int32_t*)twb)[0]; + } + twa+=8; + twb+=8; + } +} + +void init_rad5_rep(int N,int16_t *twa,int16_t *twb,int16_t *twc,int16_t *twd) { + + int i,j; + + for (i=1;i<(N/5);i++) { + twa[0] = (int16_t)round(32767.0*cos(2*M_PI*i/N)); + twa[1] = -(int16_t)round(32767.0*sin(2*M_PI*i/N)); + twb[0] = (int16_t)round(32767.0*cos(2*M_PI*2*i/N)); + twb[1] = -(int16_t)round(32767.0*sin(2*M_PI*2*i/N)); + twc[0] = (int16_t)round(32767.0*cos(2*M_PI*3*i/N)); + twc[1] = -(int16_t)round(32767.0*sin(2*M_PI*3*i/N)); + twd[0] = (int16_t)round(32767.0*cos(2*M_PI*4*i/N)); + twd[1] = -(int16_t)round(32767.0*sin(2*M_PI*4*i/N)); + for (j=1;j<4;j++) { + ((int32_t*)twa)[j]=((int32_t*)twa)[0]; + ((int32_t*)twb)[j]=((int32_t*)twb)[0]; + ((int32_t*)twc)[j]=((int32_t*)twc)[0]; + ((int32_t*)twd)[j]=((int32_t*)twd)[0]; + } + twa+=8; + twb+=8; + twc+=8; + twd+=8; + } +} +/*----------------------------------------------------------------*/ +/* dft library entry points: */ + +int dfts_autoinit(void) +{ + init_rad4(1024,tw1024); + init_rad2(2048,tw2048); + init_rad4(4096,tw4096); + init_rad2(8192,tw8192); + init_rad4(16384,tw16384); + init_rad2(32768,tw32768); + + init_rad3(1536,twa1536,twb1536); + init_rad3(3072,twa3072,twb3072); + init_rad3(6144,twa6144,twb6144); + init_rad3(12288,twa12288,twb12288); + init_rad3(18432,twa18432,twb18432); + init_rad3(24576,twa24576,twb24576); + init_rad3(36864,twa36864,twb36864); + init_rad3(49152,twa49152,twb49152); + init_rad3(98304,twa98304,twb98304); init_rad2_rep(24,tw24); @@ -9645,6 +10556,24 @@ int dfts_autoinit(void) init_rad3_rep(1080,twa1080,twb1080); init_rad4_rep(1152,twa1152,twb1152,twc1152); init_rad4_rep(1200,twa1200,twb1200,twc1200); + init_rad3_rep(1296,twa1296,twb1296); + init_rad3_rep(1440,twa1440,twb1440); + init_rad5_rep(1500,twa1500,twb1500,twc1500,twd1500); + init_rad3_rep(1620,twa1620,twb1620); + init_rad3_rep(1728,twa1728,twb1728); + init_rad3_rep(1800,twa1800,twb1800); + init_rad4_rep(1920,twa1920,twb1920, twc1920); + init_rad3_rep(1944,twa1944,twb1944); + init_rad3_rep(2160,twa2160,twb2160); + init_rad3_rep(2304,twa2304,twb2304); + init_rad4_rep(2400,twa2400,twb2400,twc2400); + init_rad3_rep(2592,twa2592,twb2592); + init_rad3_rep(2700,twa2700,twb2700); + init_rad3_rep(2880,twa2880,twb2880); + init_rad3_rep(2916,twa2916,twb2916); + init_rad5_rep(3000,twa3000,twb3000,twc3000,twd3000); + init_rad3_rep(3240,twa3240,twb3240); + return 0; } diff --git a/openair1/PHY/TOOLS/tools_defs.h b/openair1/PHY/TOOLS/tools_defs.h index 12467e1fdc226fe701827223deaf964c4ae47413..db7ac3d813cb6266cc99b41dd0681db4a70d3d7c 100644 --- a/openair1/PHY/TOOLS/tools_defs.h +++ b/openair1/PHY/TOOLS/tools_defs.h @@ -226,9 +226,26 @@ void dft1024(int16_t *x,int16_t *y,uint8_t scale_flag); void dft1080(int16_t *x,int16_t *y,uint8_t scale_flag); void dft1152(int16_t *x,int16_t *y,uint8_t scale_flag); void dft1200(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft1296(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft1440(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft1500(int16_t *x,int16_t *y,uint8_t scale_flag); void dft1536(int16_t *sigF,int16_t *sig,uint8_t scale_flag); +void dft1620(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft1728(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft1800(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft1920(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft1944(int16_t *x,int16_t *y,uint8_t scale_flag); void dft2048(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft2160(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft2304(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft2400(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft2592(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft2700(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft2880(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft2916(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft3000(int16_t *x,int16_t *y,uint8_t scale_flag); void dft3072(int16_t *sigF,int16_t *sig,uint8_t scale_flag); +void dft3240(int16_t *x,int16_t *y,uint8_t scale_flag); void dft4096(int16_t *x,int16_t *y,uint8_t scale_flag); void dft6144(int16_t *sigF,int16_t *sig,uint8_t scale_flag); void dft8192(int16_t *x,int16_t *y,uint8_t scale_flag); @@ -283,21 +300,25 @@ typedef enum DFT_size_idx { DFT_108, DFT_120, DFT_128, DFT_144, DFT_180, DFT_192, DFT_216, DFT_240, DFT_256, DFT_288, DFT_300, DFT_324, DFT_360, DFT_384, DFT_432, DFT_480, DFT_512, DFT_540, DFT_576, DFT_600, DFT_648, DFT_720, DFT_768, DFT_864, - DFT_900, DFT_960, DFT_972, DFT_1024, DFT_1080, DFT_1152, DFT_1200, DFT_1536, - DFT_2048, DFT_3072, DFT_4096, DFT_6144, DFT_8192, DFT_9216, DFT_12288, DFT_18432, - DFT_24576, DFT_36864, DFT_49152, DFT_73728, DFT_98304, + DFT_900, DFT_960, DFT_972, DFT_1024, DFT_1080, DFT_1152, DFT_1200, DFT_1296, + DFT_1440, DFT_1500, DFT_1536, DFT_1620, DFT_1728, DFT_1800, DFT_1920, DFT_1944, + DFT_2048, DFT_2160, DFT_2304, DFT_2400, DFT_2592, DFT_2700, DFT_2880, DFT_2916, + DFT_3000, DFT_3072, DFT_3240, DFT_4096, DFT_6144, DFT_8192, DFT_9216, DFT_12288, + DFT_18432, DFT_24576, DFT_36864, DFT_49152, DFT_73728, DFT_98304, DFT_SIZE_IDXTABLESIZE } dft_size_idx_t; #ifdef OAIDFTS_MAIN adftfunc_t dft_ftab[]={ dft12, dft24, dft36, dft48, dft60, dft72, dft96, - dft108, dft120, dft128, dft144, dft180, dft192, dft216, dft240, + dft108, dft120, dft128, dft144, dft180, dft192, dft216, dft240, dft256, dft288, dft300, dft324, dft360, dft384, dft432, dft480, dft512, dft540, dft576, dft600, dft648, dft720, dft768, dft864, - dft900, dft960, dft972, dft1024, dft1080, dft1152, dft1200, dft1536, - dft2048, dft3072, dft4096, dft6144, dft8192, dft9216, dft12288, dft18432, - dft24576, dft36864, dft49152, dft73728, dft98304 + dft900, dft960, dft972, dft1024, dft1080, dft1152, dft1200, dft1296, + dft1440, dft1500, dft1536, dft1620, dft1728, dft1800, dft1920, dft1944, + dft2048, dft2160, dft2304, dft2400, dft2592, dft2700, dft2880, dft2916, + dft3000, dft3072, dft3240, dft4096, dft6144, dft8192, dft9216, dft12288, + dft18432, dft24576, dft36864, dft49152, dft73728, dft98304 }; #endif @@ -309,9 +330,9 @@ typedef enum idft_size_idx { } idft_size_idx_t; #ifdef OAIDFTS_MAIN aidftfunc_t idft_ftab[]={ - idft128, idft256, idft512, idft1024, idft1536, idft2048, idft3072, idft4096, - idft6144, idft8192, idft9216, idft12288, idft18432, idft24576, idft36864, idft49152, - idft73728, idft98304 + idft128, idft256, idft512, idft1024, idft1536, idft2048, idft3072, idft4096, + idft6144, idft8192, idft9216, idft12288, idft18432, idft24576, idft36864, idft49152, + idft73728, idft98304 }; #endif diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 55626e386ecd361dd6ec2608c8d3274339a2cc06..9f97b7eadf30232bb3281a811b99a616aa3ea060 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -552,6 +552,11 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) gNB_I0_measurements(gNB); + // measure enegry in SS=10 L=4, nb_rb = 18, first_rb = 0 (corresponds to msg3) + int offset = 10*gNB->frame_parms.ofdm_symbol_size + gNB->frame_parms.first_carrier_offset; + int power_rxF = signal_energy_nodc(&gNB->common_vars.rxdataF[0][offset],12*18); + LOG_D(PHY,"frame %d, slot %d: UL signal energy %d\n",frame_rx,slot_rx,power_rxF); + for (int i=0;i<NUMBER_OF_NR_PUCCH_MAX;i++){ NR_gNB_PUCCH_t *pucch = gNB->pucch[i]; if (pucch) { @@ -647,6 +652,8 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) } #endif +T(T_BENETEL, T_INT(frame_rx), T_INT(slot_rx), T_BUFFER(&gNB->common_vars.rxdataF[0][0], 2048*4*14)); + uint8_t symbol_start = ulsch_harq->ulsch_pdu.start_symbol_index; uint8_t symbol_end = symbol_start + ulsch_harq->ulsch_pdu.nr_of_symbols; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RX_PUSCH,1); diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index babcf67227d6ece10ee453615841de7d3229a3e3..678453539143a1a76faaccfaecc1d674fc9124c6 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -151,6 +151,12 @@ nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( return 0; } +int nr_derive_key(int alg_type, uint8_t alg_id, + const uint8_t key[32], uint8_t **out) +{ + return 0; +} + void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigCommon_t *scc diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index 3fce86c88019bf424243876683a1473c268263f5..c90bcf1395d9dbd7755b30a3bd3b0b8c503de9e9 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -142,6 +142,12 @@ int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index return 0; } +int nr_derive_key(int alg_type, uint8_t alg_id, + const uint8_t key[32], uint8_t **out) +{ + return 0; +} + int main(int argc, char **argv){ char c; diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 997e2ba4008d71c4b935c530f3b9716104f8bb19..443ee6e1c0ccef6c04e347c99f8365902dc456ee 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -165,6 +165,12 @@ int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index return 0; } +int nr_derive_key(int alg_type, uint8_t alg_id, + const uint8_t key[32], uint8_t **out) +{ + return 0; +} + // needed for some functions uint16_t n_rnti = 0x1234; openair0_config_t openair0_cfg[MAX_CARDS]; diff --git a/openair2/COMMON/s1ap_messages_types.h b/openair2/COMMON/s1ap_messages_types.h index f6b4f3c4e2a99dae1df8a3942a45e23a866db2ef..bd0788d2d0efd6353df7ea996e78dfddcbe62fa0 100644 --- a/openair2/COMMON/s1ap_messages_types.h +++ b/openair2/COMMON/s1ap_messages_types.h @@ -155,6 +155,11 @@ typedef struct security_capabilities_s { uint16_t integrity_algorithms; } security_capabilities_t; +typedef struct nr_security_capabilities_s { + uint16_t encryption_algorithms; + uint16_t integrity_algorithms; +} nr_security_capabilities_t; + /* Provides the establishment cause for the RRC connection request as provided * by the upper layers. W.r.t. the cause value names: highPriorityAccess * concerns AC11..AC15, ‘mt’ stands for ‘Mobile Terminating’ and ‘mo’ for @@ -538,6 +543,9 @@ typedef struct s1ap_initial_context_setup_req_s { uint8_t nb_of_e_rabs; /* list of e_rab to be setup by RRC layers */ e_rab_t e_rab_param[S1AP_MAX_E_RAB]; + + /* NR Security algorithms (if any, set to 0 if not present) */ + nr_security_capabilities_t nr_security_capabilities; } s1ap_initial_context_setup_req_t; typedef struct tai_plmn_identity_s { diff --git a/openair2/COMMON/x2ap_messages_types.h b/openair2/COMMON/x2ap_messages_types.h index 0c55764d6e2602b9dd94948e0fcc1960e150df6a..f4911c47dc6bf112c06ba2df289785d95f89da71 100644 --- a/openair2/COMMON/x2ap_messages_types.h +++ b/openair2/COMMON/x2ap_messages_types.h @@ -338,7 +338,7 @@ typedef struct x2ap_ENDC_sgnb_addition_req_s { /* used for RRC->X2AP in source eNB */ int rnti; - security_capabilities_t security_capabilities; + nr_security_capabilities_t security_capabilities; /* SgNB Security Key */ uint8_t kgnb[32]; diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 4ee676a49e8344514cb6b0e47def35458838e904..957485a9923341f75b8373efc4a05fbd3a183d66 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -163,6 +163,8 @@ void prepare_scc(NR_ServingCellConfigCommon_t *scc) { // scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rsrp_ThresholdSSB_SUL = CALLOC(1,sizeof(NR_RSRP_Range_t)); scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing = CALLOC(1,sizeof(NR_SubcarrierSpacing_t)); scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder = CALLOC(1,sizeof(long)); + // 0 - ENABLE, 1 - DISABLE, hence explicitly setting to DISABLED. + *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder = NR_PUSCH_Config__transformPrecoder_disabled; scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon = CALLOC(1,sizeof(NR_SetupRelease_PUSCH_ConfigCommon_t)); scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->present = NR_SetupRelease_PUSCH_ConfigCommon_PR_setup; scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup = CALLOC(1,sizeof(struct NR_PUSCH_ConfigCommon)); @@ -513,6 +515,101 @@ void RCconfig_nr_macrlc() { } +void config_security(gNB_RRC_INST *rrc) +{ + paramdef_t logparams_defaults[] = SECURITY_GLOBALPARAMS_DESC; + int ret = config_get(logparams_defaults, + sizeof(logparams_defaults) / sizeof(paramdef_t), + CONFIG_STRING_SECURITY); + int i; + + if (ret < 0) { + LOG_W(RRC, "configuration file does not contain a \"security\" section, applying default parameters (no security)\n"); + rrc->security.ciphering_algorithms[0] = 0; /* nea0 = no ciphering */ + rrc->security.ciphering_algorithms_count = 1; + rrc->security.integrity_algorithms[0] = 0; /* nia0 = no integrity */ + rrc->security.integrity_algorithms_count = 1; + return; + } + + if (logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].numelt > 4) { + LOG_E(RRC, "too much ciphering algorithms in section \"security\" of the configuration file, maximum is 4\n"); + exit(1); + } + if (logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].numelt > 4) { + LOG_E(RRC, "too much integrity algorithms in section \"security\" of the configuration file, maximum is 4\n"); + exit(1); + } + + /* get ciphering algorithms */ + rrc->security.ciphering_algorithms_count = 0; + for (i = 0; i < logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].numelt; i++) { + if (!strcmp(logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].strlistptr[i], "nea0")) { + rrc->security.ciphering_algorithms[rrc->security.ciphering_algorithms_count] = 0; + rrc->security.ciphering_algorithms_count++; + continue; + } + if (!strcmp(logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].strlistptr[i], "nea1")) { + rrc->security.ciphering_algorithms[rrc->security.ciphering_algorithms_count] = 1; + rrc->security.ciphering_algorithms_count++; + continue; + } + if (!strcmp(logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].strlistptr[i], "nea2")) { + rrc->security.ciphering_algorithms[rrc->security.ciphering_algorithms_count] = 2; + rrc->security.ciphering_algorithms_count++; + continue; + } + if (!strcmp(logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].strlistptr[i], "nea3")) { + rrc->security.ciphering_algorithms[rrc->security.ciphering_algorithms_count] = 3; + rrc->security.ciphering_algorithms_count++; + continue; + } + LOG_E(RRC, "unknown ciphering algorithm \"%s\" in section \"security\" of the configuration file\n", + logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].strlistptr[i]); + exit(1); + } + + /* get integrity algorithms */ + rrc->security.integrity_algorithms_count = 0; + for (i = 0; i < logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].numelt; i++) { + if (!strcmp(logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].strlistptr[i], "nia0")) { + rrc->security.integrity_algorithms[rrc->security.integrity_algorithms_count] = 0; + rrc->security.integrity_algorithms_count++; + continue; + } + if (!strcmp(logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].strlistptr[i], "nia1")) { + rrc->security.integrity_algorithms[rrc->security.integrity_algorithms_count] = 1; + rrc->security.integrity_algorithms_count++; + continue; + } + if (!strcmp(logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].strlistptr[i], "nia2")) { + rrc->security.integrity_algorithms[rrc->security.integrity_algorithms_count] = 2; + rrc->security.integrity_algorithms_count++; + continue; + } + if (!strcmp(logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].strlistptr[i], "nia3")) { + rrc->security.integrity_algorithms[rrc->security.integrity_algorithms_count] = 3; + rrc->security.integrity_algorithms_count++; + continue; + } + LOG_E(RRC, "unknown integrity algorithm \"%s\" in section \"security\" of the configuration file\n", + logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].strlistptr[i]); + exit(1); + } + + if (rrc->security.ciphering_algorithms_count == 0) { + LOG_W(RRC, "no preferred ciphering algorithm set in configuration file, applying default parameters (no security)\n"); + rrc->security.ciphering_algorithms[0] = 0; /* nea0 = no ciphering */ + rrc->security.ciphering_algorithms_count = 1; + } + + if (rrc->security.integrity_algorithms_count == 0) { + LOG_W(RRC, "no preferred integrity algorithm set in configuration file, applying default parameters (no security)\n"); + rrc->security.integrity_algorithms[0] = 0; /* nia0 = no integrity */ + rrc->security.integrity_algorithms_count = 1; + } +} + void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { int num_gnbs = 0; @@ -679,7 +776,7 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { }//End for (k=0; k <num_gnbs ; k++) }//End if (num_gnbs>0) - + config_security(rrc); }//End RCconfig_NRRRC function int RCconfig_nr_gtpu(void ) { diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h index f1fe0c97c9128be73e3758fe0e0eacfcac73eeb2..403602c109ff6ce4899c02268223bee6b610be44 100644 --- a/openair2/GNB_APP/gnb_paramdef.h +++ b/openair2/GNB_APP/gnb_paramdef.h @@ -452,4 +452,27 @@ typedef enum { #define CONFIG_HLP_WORKER "coding and FEP worker thread WORKER_DISABLE or WORKER_ENABLE\n" #define CONFIG_HLP_PARALLEL "PARALLEL_SINGLE_THREAD, PARALLEL_RU_L1_SPLIT, or PARALLEL_RU_L1_TRX_SPLIT(RU_L1_TRX_SPLIT by defult)\n" /*-------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + + +/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* security configuration */ +/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +#define CONFIG_STRING_SECURITY "security" + +#define SECURITY_CONFIG_CIPHERING "ciphering_algorithms" +#define SECURITY_CONFIG_INTEGRITY "integrity_algorithms" + +/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* security configuration */ +/* optname help paramflags XXXptr defXXXval type numelt */ +/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +#define SECURITY_GLOBALPARAMS_DESC { \ + {SECURITY_CONFIG_CIPHERING, "preferred ciphering algorithms\n", 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST, 0}, \ + {SECURITY_CONFIG_INTEGRITY, "preferred integrity algorithms\n", 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST, 0}, \ +} + +#define SECURITY_CONFIG_CIPHERING_IDX 0 +#define SECURITY_CONFIG_INTEGRITY_IDX 1 +/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + #endif diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index efdc031038f9bea5e767b9e980d28657e6f99cc5..bce07195562851925fb7901b74f79f6c9bb9a55a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -401,21 +401,37 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, const int UE_id = add_new_nr_ue(Mod_idP, rnti, secondaryCellGroup); LOG_I(PHY,"Added new UE_id %d/%x with initial secondaryCellGroup\n",UE_id,rnti); } else if (add_ue == 1 && !get_softmodem_params()->phy_test) { - /* TODO: should check for free RA process */ const int CC_id = 0; - NR_RA_t *ra = &RC.nrmac[Mod_idP]->common_channels[CC_id].ra[0]; - ra->state = RA_IDLE; + NR_COMMON_channels_t *cc = &RC.nrmac[Mod_idP]->common_channels[CC_id]; + uint8_t ra_index = 0; + /* checking for free RA process */ + for(; ra_index < NR_NB_RA_PROC_MAX; ra_index++) { + if((cc->ra[ra_index].state == RA_IDLE) && (!cc->ra[ra_index].cfra)) break; + } + if (ra_index == NR_NB_RA_PROC_MAX) { + LOG_E(MAC, "%s() %s:%d RA processes are not available for CFRA RNTI :%x\n", __FUNCTION__, __FILE__, __LINE__, rnti); + return -1; + } + NR_RA_t *ra = &cc->ra[ra_index]; ra->secondaryCellGroup = secondaryCellGroup; if (secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated!=NULL) { if (secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra != NULL) { ra->cfra = true; ra->rnti = rnti; - struct NR_CFRA cfra = *secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra; - uint8_t num_preamble = cfra.resources.choice.ssb->ssb_ResourceList.list.count; + struct NR_CFRA *cfra = secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra; + uint8_t num_preamble = cfra->resources.choice.ssb->ssb_ResourceList.list.count; ra->preambles.num_preambles = num_preamble; ra->preambles.preamble_list = (uint8_t *) malloc(num_preamble*sizeof(uint8_t)); - for (int i = 0; i < num_preamble; i++) - ra->preambles.preamble_list[i] = cfra.resources.choice.ssb->ssb_ResourceList.list.array[i]->ra_PreambleIndex; + for(int i=0; i<cc->num_active_ssb; i++) { + for(int j=0; j<num_preamble; j++) { + if (cc->ssb_index[i] == cfra->resources.choice.ssb->ssb_ResourceList.list.array[j]->ssb) { + // one dedicated preamble for each beam + ra->preambles.preamble_list[i] = + cfra->resources.choice.ssb->ssb_ResourceList.list.array[j]->ra_PreambleIndex; + break; + } + } + } } } LOG_I(PHY,"Added new RA process for UE RNTI %04x with initial secondaryCellGroup\n", rnti); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index e356afb339b41379bfc824b5abd6da7c0e41c213..e2d5db0799ee61a84f8fb87629d92e93e4504a0d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -372,7 +372,13 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, #define BIT(x) (1 << (x)) const uint64_t dlsch_in_slot_bitmap = BIT( 1) | BIT( 2) | BIT( 3) | BIT( 4) | BIT( 5) | BIT( 6) | BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(15) | BIT(16); - const uint64_t ulsch_in_slot_bitmap = BIT( 8) | BIT(18); + + uint8_t prach_config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex; + uint64_t ulsch_in_slot_bitmap; + if (prach_config_index==4) //this is the PRACH config used in the Benetel RRU. TODO: make this generic for any PRACH config. + ulsch_in_slot_bitmap = BIT( 8) | BIT( 9); + else + ulsch_in_slot_bitmap = BIT( 8) | BIT(18); memset(RC.nrmac[module_idP]->cce_list[bwp_id][0],0,MAX_NUM_CCE*sizeof(int)); // coreset0 memset(RC.nrmac[module_idP]->cce_list[bwp_id][1],0,MAX_NUM_CCE*sizeof(int)); // coresetid 1 diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index b914e80d23bc04ebd13e8ba268bc9df1dc9633b2..ac3a4e77d236626f371e93313d1c6105008da7bc 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -151,6 +151,38 @@ void find_SSB_and_RO_available(module_id_t module_idP) { uint8_t num_active_ssb = 0; uint8_t max_association_period = 1; + struct NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB *ssb_perRACH_OccasionAndCB_PreamblesPerSSB = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB; + + switch (ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present){ + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneEighth: + cc->cb_preambles_per_ssb = 4 * (ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneEighth + 1); + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneFourth: + cc->cb_preambles_per_ssb = 4 * (ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneFourth + 1); + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneHalf: + cc->cb_preambles_per_ssb = 4 * (ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneHalf + 1); + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_one: + cc->cb_preambles_per_ssb = 4 * (ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.one + 1); + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_two: + cc->cb_preambles_per_ssb = 4 * (ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.two + 1); + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_four: + cc->cb_preambles_per_ssb = ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.four; + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_eight: + cc->cb_preambles_per_ssb = ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.eight; + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_sixteen: + cc->cb_preambles_per_ssb = ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.sixteen; + break; + default: + AssertFatal(1 == 0, "Unsupported ssb_perRACH_config %d\n", ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present); + break; + } + if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing) mu = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing; else @@ -181,25 +213,28 @@ void find_SSB_and_RO_available(module_id_t module_idP) { } } - for(int i = 1; (1 << (i-1)) <= max_association_period;i++) { + cc->total_prach_occasions_per_config_period = total_RA_occasions; + for(int i=1; (1 << (i-1)) < max_association_period; i++) { + cc->max_association_period = (1 <<(i-1)); + total_RA_occasions = total_RA_occasions * cc->max_association_period; if(total_RA_occasions >= (int) (num_active_ssb/num_ssb_per_RO)) { repetition = (uint16_t)((total_RA_occasions * num_ssb_per_RO )/num_active_ssb); break; } - else { - total_RA_occasions = total_RA_occasions * i; - cc->max_association_period = i; - } } - if(cc->max_association_period == 0) - cc->max_association_period = 1; unused_RA_occasion = total_RA_occasions - (int)((num_active_ssb * repetition)/num_ssb_per_RO); cc->total_prach_occasions = total_RA_occasions - unused_RA_occasion; cc->num_active_ssb = num_active_ssb; - LOG_I(MAC, "Total available RO %d, num of active SSB %d: unused RO = %d max_association_period %u N_RA_sfn %u \n", - cc->total_prach_occasions, cc->num_active_ssb, unused_RA_occasion, max_association_period, N_RA_sfn); + LOG_I(MAC, + "Total available RO %d, num of active SSB %d: unused RO = %d association_period %u N_RA_sfn %u total_prach_occasions_per_config_period %u\n", + cc->total_prach_occasions, + cc->num_active_ssb, + unused_RA_occasion, + cc->max_association_period, + N_RA_sfn, + cc->total_prach_occasions_per_config_period); } void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) @@ -439,139 +474,167 @@ void nr_initiate_ra_proc(module_id_t module_idP, gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - NR_RA_t *ra = &cc->ra[0]; - - uint16_t ra_rnti; - - // ra_rnti from 5.1.3 in 38.321 - // FK: in case of long PRACH the phone seems to expect the subframe number instead of the slot number here. - if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present==NR_RACH_ConfigCommon__prach_RootSequenceIndex_PR_l839) - ra_rnti=1+symbol+(9/*slotP*/*14)+(freq_index*14*80)+(ul_carrier_id*14*80*8); - else - ra_rnti=1+symbol+(slotP*14)+(freq_index*14*80)+(ul_carrier_id*14*80*8); - - // if the preamble received correspond to one of the listed - // the UE sent a RACH either for starting RA procedure or RA procedure failed and UE retries - int pr_found=0; - for (int i = 0; i < ra->preambles.num_preambles; i++) { - if (preamble_index == ra->preambles.preamble_list[i]) { - pr_found=1; - break; - } - } - - if (!pr_found) { - LOG_E(MAC, "[gNB %d][RAPROC] FAILURE: preamble %d does not correspond to any of the ones in rach_ConfigDedicated\n", - module_idP, preamble_index); + uint8_t total_RApreambles = 64; + uint8_t num_ssb_per_RO = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present; + int pr_found; - return; // if the PRACH preamble does not correspond to any of the ones sent through RRC abort RA proc + if( scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles != NULL) + total_RApreambles = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles; + + if(num_ssb_per_RO > 3) { /*num of ssb per RO >= 1*/ + num_ssb_per_RO -= 3; + total_RApreambles = total_RApreambles/num_ssb_per_RO ; } - // This should be handled differently when we use the initialBWP for RA - ra->bwp_id=1; - NR_BWP_Downlink_t *bwp=ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id-1]; - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 1); - - LOG_I(MAC, "[gNB %d][RAPROC] CC_id %d Frame %d, Slot %d Initiating RA procedure for preamble index %d\n", module_idP, CC_id, frameP, slotP, preamble_index); - - if (ra->state == RA_IDLE) { - uint8_t beam_index = ssb_index_from_prach(module_idP, - frameP, - slotP, - preamble_index, - freq_index, - symbol); - int loop = 0; - LOG_D(MAC, "Frame %d, Slot %d: Activating RA process \n", frameP, slotP); - ra->state = Msg2; - ra->timing_offset = timing_offset; - ra->preamble_slot = slotP; - - struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList; - AssertFatal(commonSearchSpaceList->list.count>0, - "common SearchSpace list has 0 elements\n"); - // Common searchspace list - for (int i=0;i<commonSearchSpaceList->list.count;i++) { - ss=commonSearchSpaceList->list.array[i]; - if(ss->searchSpaceId == *bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace) - ra->ra_ss=ss; - } - - // retrieving ra pdcch monitoring period and offset - find_monitoring_periodicity_offset_common(ra->ra_ss, - &monitoring_slot_period, - &monitoring_offset); + for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { + NR_RA_t *ra = &cc->ra[i]; + pr_found = 0; + if (ra->state == RA_IDLE) { + for(int j = 0; j < ra->preambles.num_preambles; j++) { + //check if the preamble received correspond to one of the listed or configured preambles + if (preamble_index == ra->preambles.preamble_list[j]) { + pr_found=1; + break; + } + } - nr_schedule_msg2(frameP, slotP, &msg2_frame, &msg2_slot, scc, monitoring_slot_period, monitoring_offset,beam_index,cc->num_active_ssb); + if (pr_found == 0) { + continue; + } - ra->Msg2_frame = msg2_frame; - ra->Msg2_slot = msg2_slot; + uint16_t ra_rnti; - LOG_I(MAC, "%s() Msg2[%04d%d] SFN/SF:%04d%d\n", __FUNCTION__, ra->Msg2_frame, ra->Msg2_slot, frameP, slotP); - if (!ra->cfra) { - do { - ra->rnti = (taus() % 65518) + 1; - loop++; + // ra_rnti from 5.1.3 in 38.321 + // FK: in case of long PRACH the phone seems to expect the subframe number instead of the slot number here. + if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present + == NR_RACH_ConfigCommon__prach_RootSequenceIndex_PR_l839) + ra_rnti = 1 + symbol + (9 /*slotP*/ * 14) + (freq_index * 14 * 80) + (ul_carrier_id * 14 * 80 * 8); + else + ra_rnti = 1 + symbol + (slotP * 14) + (freq_index * 14 * 80) + (ul_carrier_id * 14 * 80 * 8); + + // This should be handled differently when we use the initialBWP for RA + ra->bwp_id = 1; + NR_BWP_Downlink_t *bwp = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList + ->list.array[ra->bwp_id - 1]; + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 1); + + LOG_I(MAC, + "[gNB %d][RAPROC] CC_id %d Frame %d, Slot %d Initiating RA procedure for preamble index %d\n", + module_idP, + CC_id, + frameP, + slotP, + preamble_index); + + uint8_t beam_index = ssb_index_from_prach(module_idP, frameP, slotP, preamble_index, freq_index, symbol); + + // the UE sent a RACH either for starting RA procedure or RA procedure failed and UE retries + if (ra->cfra) { + // if the preamble received correspond to one of the listed + if (!(preamble_index == ra->preambles.preamble_list[beam_index])) { + LOG_E( + MAC, + "[gNB %d][RAPROC] FAILURE: preamble %d does not correspond to any of the ones in rach_ConfigDedicated\n", + module_idP, + preamble_index); + continue; // if the PRACH preamble does not correspond to any of the ones sent through RRC abort RA proc + } } - while (loop != 100 && !((find_nr_UE_id(module_idP, ra->rnti) == -1) && (find_nr_RA_id(module_idP, CC_id, ra->rnti) == -1) && ra->rnti >= 1 && ra->rnti <= 65519)); - if (loop == 100) { - LOG_E(MAC,"%s:%d:%s: [RAPROC] initialisation random access aborted\n", __FILE__, __LINE__, __FUNCTION__); - abort(); + int loop = 0; + LOG_D(MAC, "Frame %d, Slot %d: Activating RA process \n", frameP, slotP); + ra->state = Msg2; + ra->timing_offset = timing_offset; + ra->preamble_slot = slotP; + + struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = + bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList; + AssertFatal(commonSearchSpaceList->list.count > 0, "common SearchSpace list has 0 elements\n"); + // Common searchspace list + for (int i = 0; i < commonSearchSpaceList->list.count; i++) { + ss = commonSearchSpaceList->list.array[i]; + if (ss->searchSpaceId == *bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace) + ra->ra_ss = ss; } - } - ra->RA_rnti = ra_rnti; - ra->preamble_index = preamble_index; - ra->beam_id = beam_index; - - LOG_I(MAC,"[gNB %d][RAPROC] CC_id %d Frame %d Activating Msg2 generation in frame %d, slot %d using RA rnti %x SSB index %u\n", - module_idP, - CC_id, - frameP, - ra->Msg2_frame, - ra->Msg2_slot, - ra->RA_rnti, - cc->ssb_index[beam_index]); - return; + // retrieving ra pdcch monitoring period and offset + find_monitoring_periodicity_offset_common(ra->ra_ss, &monitoring_slot_period, &monitoring_offset); + + nr_schedule_msg2(frameP, + slotP, + &msg2_frame, + &msg2_slot, + scc, + monitoring_slot_period, + monitoring_offset, + beam_index, + cc->num_active_ssb); + + ra->Msg2_frame = msg2_frame; + ra->Msg2_slot = msg2_slot; + + LOG_I(MAC, "%s() Msg2[%04d%d] SFN/SF:%04d%d\n", __FUNCTION__, ra->Msg2_frame, ra->Msg2_slot, frameP, slotP); + if (!ra->cfra) { + do { + ra->rnti = (taus() % 65518) + 1; + loop++; + } while (loop != 100 + && !((find_nr_UE_id(module_idP, ra->rnti) == -1) && (find_nr_RA_id(module_idP, CC_id, ra->rnti) == -1) + && ra->rnti >= 1 && ra->rnti <= 65519)); + if (loop == 100) { + LOG_E(MAC, "%s:%d:%s: [RAPROC] initialisation random access aborted\n", __FILE__, __LINE__, __FUNCTION__); + abort(); + } + } + ra->RA_rnti = ra_rnti; + ra->preamble_index = preamble_index; + ra->beam_id = beam_index; + + LOG_I(MAC, + "[gNB %d][RAPROC] CC_id %d Frame %d Activating Msg2 generation in frame %d, slot %d using RA rnti %x SSB " + "index %u\n", + module_idP, + CC_id, + frameP, + ra->Msg2_frame, + ra->Msg2_slot, + ra->RA_rnti, + cc->ssb_index[beam_index]); + + return; + } } LOG_E(MAC, "[gNB %d][RAPROC] FAILURE: CC_id %d Frame %d initiating RA procedure for preamble index %d\n", module_idP, CC_id, frameP, preamble_index); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0); } -void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){ - - //uint8_t i = 0; - int CC_id = 0; +void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) +{ gNB_MAC_INST *mac = RC.nrmac[module_idP]; - NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; start_meas(&mac->schedule_ra); - -// for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { -// for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { - -// NR_RA_t *ra = &cc->ra[i]; - NR_RA_t *ra = &cc->ra[0]; - - LOG_D(MAC,"RA[state:%d]\n",ra->state); - switch (ra->state){ - case Msg2: - nr_generate_Msg2(module_idP, CC_id, frameP, slotP); - break; - case Msg4: - //generate_Msg4(module_idP, CC_id, frameP, slotP); - break; - case WAIT_Msg4_ACK: - //check_Msg4_retransmission(module_idP, CC_id, frameP, slotP); - break; - default: - break; + for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; + for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { + NR_RA_t *ra = &cc->ra[i]; + LOG_D(MAC, "RA[state:%d]\n", ra->state); + switch (ra->state) { + case Msg2: + nr_generate_Msg2(module_idP, CC_id, frameP, slotP, ra); + break; + case Msg4: + // generate_Msg4(module_idP, CC_id, frameP, slotP); + break; + case WAIT_Msg4_ACK: + // check_Msg4_retransmission(module_idP, CC_id, frameP, slotP); + break; + default: + break; + } + } } -// } -// } stop_meas(&mac->schedule_ra); } @@ -632,12 +695,11 @@ void nr_get_Msg3alloc(module_id_t module_id, ra->msg3_first_rb = rbStart; } -void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP){ - +void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra, uint8_t *RAR_pdu) +{ gNB_MAC_INST *mac = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - NR_RA_t *ra = &cc->ra[0]; if (ra->state == RA_IDLE) { LOG_W(MAC,"RA is not active for RA %X. skipping msg3 scheduling\n", ra->rnti); @@ -752,27 +814,25 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t pusch_pdu->nrOfLayers = 1)>>3; // calling function to fill rar message - nr_fill_rar(module_idP, ra, cc->RAR_pdu.payload, pusch_pdu); - + nr_fill_rar(module_idP, ra, RAR_pdu, pusch_pdu); } -// WIP -// todo: -// - fix me -// - get msg3 alloc (see nr_process_rar) -void nr_generate_Msg2(module_id_t module_idP, - int CC_id, - frame_t frameP, - sub_frame_t slotP) +void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra) { - int mcsIndex; int startSymbolAndLength = 0, StartSymbolIndex = -1, NrOfSymbols = 14, StartSymbolIndex_tmp, NrOfSymbols_tmp, x_Overhead, time_domain_assignment = 0; gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; - NR_RA_t *ra = &cc->ra[CC_id]; NR_SearchSpace_t *ss = ra->ra_ss; + // This code from this point on will not work on initialBWP or CORESET0 + AssertFatal(ra->bwp_id > 0, "cannot work on initialBWP for now\n"); + + AssertFatal(ra->secondaryCellGroup, "no secondaryCellGroup for RNTI %04x\n", ra->crnti); + AssertFatal(ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1, + "downlinkBWP_ToAddModList has %d BWP!\n", + ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count); + uint16_t RA_rnti = ra->RA_rnti; long locationAndBandwidth; @@ -780,7 +840,7 @@ void nr_generate_Msg2(module_id_t module_idP, // get the BW of the PDCCH for PDCCH size and RAR PDSCH size NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - int dci10_bw; + int dci10_bw = 0; if (ra->coreset0_configured == 1) { AssertFatal(1==0,"This is a standalone condition\n"); @@ -792,8 +852,24 @@ void nr_generate_Msg2(module_id_t module_idP, if ((ra->Msg2_frame == frameP) && (ra->Msg2_slot == slotP)) { + uint16_t *vrb_map = cc[CC_id].vrb_map; + int rbStart = 0, rbSize = 6; + for (int i = 0; (i < rbSize) && (rbStart <= (dci10_bw - rbSize)); i++) { + if (vrb_map[rbStart + i]) { + rbStart += i; + i = 0; + } + } + if (rbStart > (dci10_bw - rbSize)) { + LOG_E(MAC, "%s(): cannot find free vrb_map for RA RNTI %04x!\n", __func__, ra->RA_rnti); + return; + } + nfapi_nr_dl_tti_request_body_t *dl_req = &nr_mac->DL_req[CC_id].dl_tti_request_body; - // Checking if the DCI allocation is feasible in current subframe + // Checking if the DCI allocation is feasible in current subframe: we might + // need to need up to two (PDCCH + PDSCH) messages, so check that we can + // always allocate both (this might be an overestimation, since the PDCCH + // message might already exist) if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) { LOG_I(MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, RA_rnti); return; @@ -816,8 +892,6 @@ void nr_generate_Msg2(module_id_t module_idP, return; } - nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs]; - /* look up the PDCCH PDU for this CC, BWP, and CORESET. If it does not * exist, create it. This is especially important if we have multiple RAs, * and the DLSCH has to reuse them, so we need to mark them */ @@ -844,14 +918,6 @@ void nr_generate_Msg2(module_id_t module_idP, LOG_I(MAC,"[gNB %d] [RAPROC] CC_id %d Frame %d, slotP %d: Generating RAR DCI, state %d\n", module_idP, CC_id, frameP, slotP, ra->state); - // This code from this point on will not work on initialBWP or CORESET0 - AssertFatal(ra->bwp_id>0,"cannot work on initialBWP for now\n"); - - AssertFatal(ra->secondaryCellGroup, - "no secondaryCellGroup for RNTI %04x\n", - ra->crnti); - AssertFatal(ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1, - "downlinkBWP_ToAddModList has %d BWP!\n", ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count); NR_BWP_Uplink_t *ubwp=ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id-1]; LOG_I(MAC, "[RAPROC] Scheduling common search space DCI type 1 dlBWP BW %d\n", dci10_bw); @@ -898,8 +964,8 @@ void nr_generate_Msg2(module_id_t module_idP, pdsch_pdu_rel15->numDmrsCdmGrpsNoData = 2; pdsch_pdu_rel15->dmrsPorts = 1; pdsch_pdu_rel15->resourceAlloc = 1; - pdsch_pdu_rel15->rbStart = 0; - pdsch_pdu_rel15->rbSize = 6; + pdsch_pdu_rel15->rbStart = rbStart; + pdsch_pdu_rel15->rbSize = rbSize; pdsch_pdu_rel15->VRBtoPRBMapping = 0; // non interleaved for (int i=0; i<bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count; i++) { @@ -974,17 +1040,8 @@ void nr_generate_Msg2(module_id_t module_idP, dci10_bw, ra->bwp_id); - // Program UL processing for Msg3 - nr_get_Msg3alloc(module_idP, CC_id, scc, ubwp, slotP, frameP, ra); - LOG_I(MAC, "Frame %d, Subframe %d: Setting Msg3 reception for Frame %d Subframe %d\n", frameP, slotP, ra->Msg3_frame, ra->Msg3_slot); - nr_add_msg3(module_idP, CC_id, frameP, slotP); - ra->state = WAIT_Msg3; - LOG_I(MAC,"[gNB %d][RAPROC] Frame %d, Subframe %d: RA state %d\n", module_idP, frameP, slotP, ra->state); - - x_Overhead = 0; - nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, x_Overhead, pdsch_pdu_rel15->numDmrsCdmGrpsNoData, dci_payload.tb_scaling); - // DL TX request + nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs]; tx_req->PDU_length = pdsch_pdu_rel15->TBSize[0]; tx_req->PDU_index = pduindex; tx_req->num_TLV = 1; @@ -992,16 +1049,24 @@ void nr_generate_Msg2(module_id_t module_idP, nr_mac->TX_req[CC_id].SFN = frameP; nr_mac->TX_req[CC_id].Number_of_PDUs++; nr_mac->TX_req[CC_id].Slot = slotP; - memcpy((void*)&tx_req->TLVs[0].value.direct[0], (void*)&cc[CC_id].RAR_pdu.payload[0], tx_req->TLVs[0].length); + + // Program UL processing for Msg3 + nr_get_Msg3alloc(module_idP, CC_id, scc, ubwp, slotP, frameP, ra); + LOG_I(MAC, "Frame %d, Subframe %d: Setting Msg3 reception for Frame %d Subframe %d\n", frameP, slotP, ra->Msg3_frame, ra->Msg3_slot); + nr_add_msg3(module_idP, CC_id, frameP, slotP, ra, (uint8_t *) &tx_req->TLVs[0].value.direct[0]); + ra->state = WAIT_Msg3; + LOG_I(MAC,"[gNB %d][RAPROC] Frame %d, Subframe %d: RA state %d\n", module_idP, frameP, slotP, ra->state); + + x_Overhead = 0; + nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, x_Overhead, pdsch_pdu_rel15->numDmrsCdmGrpsNoData, dci_payload.tb_scaling); T(T_GNB_MAC_DL_RAR_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(RA_rnti), T_INT(frameP), T_INT(slotP), T_INT(0) /* harq pid, meaningful? */, - T_BUFFER(&cc[CC_id].RAR_pdu.payload[0], tx_req->TLVs[0].length)); + T_BUFFER(&tx_req->TLVs[0].value.direct[0], tx_req->TLVs[0].length)); /* mark the corresponding RBs as used */ - uint16_t *vrb_map = cc[CC_id].vrb_map; - for (int rb = 0; rb < pdsch_pdu_rel15->rbSize; rb++) - vrb_map[rb + pdsch_pdu_rel15->rbStart] = 1; + for (int rb = 0; rb < rbSize; rb++) + vrb_map[rb + rbStart] = 1; } } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 9587e3b0bb8c717a7ed92864c81de44e34a89d4f..6487f391b9198bfb489dba0471ba670f53e3fa84 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -245,7 +245,9 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, TX_req->PDU_index = nr_mac->pdu_index[CC_id]++; TX_req->num_TLV = 1; TX_req->TLVs[0].length = 8; - memcpy((void*)&TX_req->TLVs[0].value.direct[0],(void*)&cc[CC_id].RAR_pdu.payload[0],TX_req->TLVs[0].length); + // why do we copy from RAR_pdu here? Shouldn't we fill some more or less + // meaningful data, e.g., padding + random data? + //memcpy((void *)&TX_req->TLVs[0].value.direct[0], (void *)&cc[CC_id].RAR_pdu[0].payload[0], TX_req->TLVs[0].length); nr_mac->TX_req[CC_id].Number_of_PDUs++; nr_mac->TX_req[CC_id].SFN=frameP; nr_mac->TX_req[CC_id].Slot=slotP; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 4a47e4d894600601026384aa48988d41f8ea8692..db7dde014034c74352921098c32a63a14aa924d5 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -396,7 +396,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, T_BUFFER(sduP, sdu_lenP)); UE_info->mac_stats[UE_id].ulsch_total_bytes_rx += sdu_lenP; - LOG_D(MAC, "[gNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu from PHY (rnti %x, UE_id %d) ul_cqi %d\n", + LOG_D(MAC, "[gNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu from PHY (rnti %x, UE_id %d) ul_cqi %d sduP %p\n", gnb_mod_idP, harq_pid, CC_idP, @@ -404,7 +404,8 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, slotP, current_rnti, UE_id, - ul_cqi); + ul_cqi, + sduP); // if not missed detection (10dB threshold for now) if (UE_scheduling_control->ul_rssi < (100+rssi)) { @@ -433,7 +434,8 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, if (sduP != NULL){ LOG_D(MAC, "Received PDU at MAC gNB \n"); - UE_scheduling_control->sched_ul_bytes -= UE_info->mac_stats[UE_id].ulsch_current_bytes; + const uint32_t tb_size = UE_scheduling_control->ul_harq_processes[harq_pid].sched_pusch.tb_size; + UE_scheduling_control->sched_ul_bytes -= tb_size; if (UE_scheduling_control->sched_ul_bytes < 0) UE_scheduling_control->sched_ul_bytes = 0; @@ -443,7 +445,8 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, NR_UE_ul_harq_t *cur_harq = &UE_scheduling_control->ul_harq_processes[harq_pid]; /* reduce sched_ul_bytes when cur_harq->round == 3 */ if (cur_harq->round == 3){ - UE_scheduling_control->sched_ul_bytes -= UE_info->mac_stats[UE_id].ulsch_current_bytes; + const uint32_t tb_size = UE_scheduling_control->ul_harq_processes[harq_pid].sched_pusch.tb_size; + UE_scheduling_control->sched_ul_bytes -= tb_size; if (UE_scheduling_control->sched_ul_bytes < 0) UE_scheduling_control->sched_ul_bytes = 0; } @@ -863,7 +866,7 @@ void nr_schedule_ulsch(module_id_t module_id, /* a PDCCH PDU groups DCIs per BWP and CORESET. Save a pointer to each * allocated PDCCH so we can easily allocate UE's DCIs independent of any * CORESET order */ - nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_bwp_coreset[MAX_NUM_BWP][MAX_NUM_CORESET] = {0}; + nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_bwp_coreset[MAX_NUM_BWP][MAX_NUM_CORESET] = {{0}}; NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon; NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info; @@ -919,6 +922,7 @@ void nr_schedule_ulsch(module_id_t module_id, /* Save information on MCS, TBS etc for the current initial transmission * so we have access to it when retransmitting */ cur_harq->sched_pusch = *sched_pusch; + sched_ctrl->sched_ul_bytes += sched_pusch->tb_size; } else { LOG_D(MAC, "%d.%2d UL retransmission RNTI %04x sched %d.%2d HARQ PID %d round %d NDI %d\n", @@ -932,7 +936,6 @@ void nr_schedule_ulsch(module_id_t module_id, cur_harq->ndi); } UE_info->mac_stats[UE_id].ulsch_current_bytes = sched_pusch->tb_size; - sched_ctrl->sched_ul_bytes += sched_pusch->tb_size; LOG_D(MAC, "%4d.%2d RNTI %04x UL sched %4d.%2d start %d RBS %d MCS %d TBS %d HARQ PID %d round %d NDI %d\n", diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 26d29f9412815a4e778887a9cd909869bb1cda10..3502a11580cf75af67805070267e34d5044f1b0c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -346,11 +346,7 @@ void config_nr_mib(int Mod_idP, int cellBarred, int intraFreqReselection); - -void nr_generate_Msg2(module_id_t module_idP, - int CC_id, - frame_t frameP, - sub_frame_t slotP); +void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra); void nr_process_mac_pdu( module_id_t module_idP, diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index bca974a00f08644028788cbc97a99cc67844c293..63587d58a4f118935ff4f0e38477e25c8e46e3ec 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -194,8 +194,6 @@ typedef struct { uint32_t PCCH_alloc_pdu; /// Outgoing PCCH pdu for PHY PCCH_PDU PCCH_pdu; - /// Outgoing RAR pdu for PHY - RAR_PDU RAR_pdu; /// Template for RA computations NR_RA_t ra[NR_NB_RA_PROC_MAX]; /// VRB map for common channels @@ -215,6 +213,8 @@ typedef struct { uint8_t max_association_period; //SSB index uint8_t ssb_index[MAX_NUM_OF_SSB]; + //CB preambles for each SSB + uint8_t cb_preambles_per_ssb; } NR_COMMON_channels_t; diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c index f3d4b1613099765430c8825047d0686f7cdfde82..ffc669a46169740fdaf7cab79921a4864165f9e7 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c @@ -22,11 +22,12 @@ #include "nr_pdcp_entity.h" #include "nr_pdcp_entity_drb_am.h" +#include "nr_pdcp_security_nea2.h" #include "LOG/log.h" nr_pdcp_entity_t *new_nr_pdcp_entity_srb( - int rb_id, + int is_gnb, int rb_id, void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, char *buf, int size), void *deliver_sdu_data, @@ -38,7 +39,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_srb( } nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am( - int rb_id, + int is_gnb, int rb_id, void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, char *buf, int size), void *deliver_sdu_data, @@ -47,7 +48,11 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am( void *deliver_pdu_data, int sn_size, int t_reordering, - int discard_timer) + int discard_timer, + int ciphering_algorithm, + int integrity_algorithm, + unsigned char *ciphering_key, + unsigned char *integrity_key) { nr_pdcp_entity_drb_am_t *ret; @@ -76,5 +81,25 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am( ret->common.maximum_nr_pdcp_sn = (1 << sn_size) - 1; + if (ciphering_key != NULL && ciphering_algorithm != 0) { + if (ciphering_algorithm != 2) { + LOG_E(PDCP, "FATAL: only nea2 supported for the moment\n"); + exit(1); + } + ret->common.has_ciphering = 1; + ret->common.ciphering_algorithm = ciphering_algorithm; + memcpy(ret->common.ciphering_key, ciphering_key, 16); + + ret->common.security_context = nr_pdcp_security_nea2_init(ciphering_key); + ret->common.cipher = nr_pdcp_security_nea2_cipher; + ret->common.free_security = nr_pdcp_security_nea2_free_security; + } + ret->common.is_gnb = is_gnb; + + if (integrity_key != NULL) { + printf("%s:%d:%s: TODO\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + return (nr_pdcp_entity_t *)ret; } diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h index ce5dd300e96c2dc28ba7a42f03d903a495a80720..58d79835ecbc588524526887624ecea47c15632e 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h @@ -42,10 +42,28 @@ typedef struct nr_pdcp_entity_t { int tx_hfn; int next_nr_pdcp_tx_sn; int maximum_nr_pdcp_sn; + + /* security */ + int has_ciphering; + int has_integrity; + int ciphering_algorithm; + int integrity_algorithm; + unsigned char ciphering_key[16]; + unsigned char integrity_key[16]; + void *security_context; + void (*cipher)(void *security_context, + unsigned char *buffer, int length, + int bearer, int count, int direction); + void (*free_security)(void *security_context); + /* security algorithms need to know uplink/downlink information + * which is reverse for gnb and ue, so we need to know if this + * pdcp entity is for a gnb or an ue + */ + int is_gnb; } nr_pdcp_entity_t; nr_pdcp_entity_t *new_nr_pdcp_entity_srb( - int rb_id, + int is_gnb, int rb_id, void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, char *buf, int size), void *deliver_sdu_data, @@ -54,7 +72,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_srb( void *deliver_pdu_data); nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am( - int rb_id, + int is_gnb, int rb_id, void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, char *buf, int size), void *deliver_sdu_data, @@ -63,7 +81,11 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am( void *deliver_pdu_data, int sn_size, int t_reordering, - int discard_timer); + int discard_timer, + int ciphering_algorithm, + int integrity_algorithm, + unsigned char *ciphering_key, + unsigned char *integrity_key); void nr_DRB_preconfiguration(uint16_t crnti); diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c index f2f849b9e36e301eafd17688381de37da4400259..62881c184e8cf3f35198b54f2893e2b4c4bb3eeb 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c @@ -29,12 +29,21 @@ void nr_pdcp_entity_drb_am_recv_pdu(nr_pdcp_entity_t *_entity, char *buffer, int size) { nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity; + int sn; if (size < 3) abort(); if (!(buffer[0] & 0x80)) LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + sn = (((unsigned char)buffer[0] & 0x3) << 16) | + ((unsigned char)buffer[1] << 8) | + (unsigned char)buffer[2]; + + if (entity->common.has_ciphering) + entity->common.cipher(entity->common.security_context, (unsigned char *)buffer+3, size-3, + entity->rb_id, sn, entity->common.is_gnb ? 0 : 1); + entity->common.deliver_sdu(entity->common.deliver_sdu_data, (nr_pdcp_entity_t *)entity, buffer+3, size-3); } @@ -59,6 +68,10 @@ void nr_pdcp_entity_drb_am_recv_sdu(nr_pdcp_entity_t *_entity, char *buffer, int buf[2] = sn & 0xff; memcpy(buf+3, buffer, size); + if (entity->common.has_ciphering) + entity->common.cipher(entity->common.security_context, (unsigned char *)buf+3, size, + entity->rb_id, sn, entity->common.is_gnb ? 1 : 0); + entity->common.deliver_pdu(entity->common.deliver_pdu_data, (nr_pdcp_entity_t *)entity, buf, size+3, sdu_id); } @@ -71,5 +84,7 @@ void nr_pdcp_entity_drb_am_set_integrity_key(nr_pdcp_entity_t *_entity, char *ke void nr_pdcp_entity_drb_am_delete(nr_pdcp_entity_t *_entity) { nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity; + if (entity->common.free_security != NULL) + entity->common.free_security(entity->common.security_context); free(entity); } diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index 6195a91ea26037c7585768b6fde262223d24c8ee..f14d25b145a72c4b3534e05ff46cce5752478edc 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -591,7 +591,11 @@ static void add_srb(int rnti, struct NR_SRB_ToAddMod *s) TODO; } -static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s) +static void add_drb_am(int is_gnb, int rnti, struct NR_DRB_ToAddMod *s, + int ciphering_algorithm, + int integrity_algorithm, + unsigned char *ciphering_key, + unsigned char *integrity_key) { nr_pdcp_entity_t *pdcp_drb; nr_pdcp_ue_t *ue; @@ -621,8 +625,11 @@ static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s) LOG_D(PDCP, "%s:%d:%s: warning DRB %d already exist for ue %d, do nothing\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); } else { - pdcp_drb = new_nr_pdcp_entity_drb_am(drb_id, deliver_sdu_drb, ue, deliver_pdu_drb, ue, - sn_size_dl, t_reordering, discard_timer); + pdcp_drb = new_nr_pdcp_entity_drb_am(is_gnb, drb_id, + deliver_sdu_drb, ue, deliver_pdu_drb, ue, + sn_size_dl, t_reordering, discard_timer, + ciphering_algorithm, integrity_algorithm, + ciphering_key, integrity_key); nr_pdcp_ue_add_drb_pdcp_entity(ue, drb_id, pdcp_drb); LOG_D(PDCP, "%s:%d:%s: added drb %d to ue rnti %x\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); @@ -630,16 +637,23 @@ static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s) nr_pdcp_manager_unlock(nr_pdcp_ue_manager); } -static void add_drb(int rnti, struct NR_DRB_ToAddMod *s, NR_RLC_Config_t *rlc_Config) +static void add_drb(int is_gnb, int rnti, struct NR_DRB_ToAddMod *s, + NR_RLC_Config_t *rlc_Config, + int ciphering_algorithm, + int integrity_algorithm, + unsigned char *ciphering_key, + unsigned char *integrity_key) { switch (rlc_Config->present) { case NR_RLC_Config_PR_am: - add_drb_am(rnti, s); + add_drb_am(is_gnb, rnti, s, ciphering_algorithm, integrity_algorithm, + ciphering_key, integrity_key); break; case NR_RLC_Config_PR_um_Bi_Directional: //add_drb_um(rnti, s); /* hack */ - add_drb_am(rnti, s); + add_drb_am(is_gnb, rnti, s, ciphering_algorithm, integrity_algorithm, + ciphering_key, integrity_key); break; default: LOG_E(PDCP, "%s:%d:%s: fatal: unhandled DRB type\n", @@ -657,7 +671,8 @@ boolean_t nr_rrc_pdcp_config_asn1_req( const uint8_t security_modeP, uint8_t *const kRRCenc, uint8_t *const kRRCint, - uint8_t *const kUPenc + uint8_t *const kUPenc, + uint8_t *const kUPint #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 #endif @@ -676,7 +691,7 @@ boolean_t nr_rrc_pdcp_config_asn1_req( //srb2add_list == NULL || //drb2add_list != NULL || drb2release_list != NULL || - security_modeP != 255 || + //security_modeP != 255 || //kRRCenc != NULL || //kRRCint != NULL || //kUPenc != NULL || @@ -693,7 +708,10 @@ boolean_t nr_rrc_pdcp_config_asn1_req( if (drb2add_list != NULL) { for (i = 0; i < drb2add_list->list.count; i++) { - add_drb(rnti, drb2add_list->list.array[i], rlc_bearer2add_list->list.array[i]->rlc_Config); + add_drb(ctxt_pP->enb_flag, rnti, drb2add_list->list.array[i], + rlc_bearer2add_list->list.array[i]->rlc_Config, + security_modeP & 0x0f, (security_modeP >> 4) & 0x0f, + kUPenc, kUPint); } } @@ -705,6 +723,7 @@ boolean_t nr_rrc_pdcp_config_asn1_req( free(kRRCenc); free(kRRCint); free(kUPenc); + free(kUPint); return 0; } @@ -805,6 +824,7 @@ void nr_DRB_preconfiguration(uint16_t crnti) NULL, NULL, NULL, + NULL, Rlc_Bearer_ToAdd_list); nr_rrc_rlc_config_asn1_req (&ctxt, diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c new file mode 100644 index 0000000000000000000000000000000000000000..fc07f661dd590ee486a2a5d850a2256a66e62ceb --- /dev/null +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c @@ -0,0 +1,65 @@ +/* + * 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 + */ + +#include "nr_pdcp_security_nea2.h" + +#include <stdlib.h> +#include <string.h> +#include <nettle/nettle-meta.h> +#include <nettle/aes.h> +#include <nettle/ctr.h> + +void *nr_pdcp_security_nea2_init(unsigned char *ciphering_key) +{ + void *ctx = calloc(1, nettle_aes128.context_size); + if (ctx == NULL) exit(1); + +#if NETTLE_VERSION_MAJOR < 3 + nettle_aes128.set_encrypt_key(ctx, 16, ciphering_key); +#else + nettle_aes128.set_encrypt_key(ctx, ciphering_key); +#endif + + return ctx; +} + +void nr_pdcp_security_nea2_cipher(void *security_context, + unsigned char *buffer, int length, + int bearer, int count, int direction) +{ + unsigned char t[16]; + + t[0] = (count >> 24) & 255; + t[1] = (count >> 16) & 255; + t[2] = (count >> 8) & 255; + t[3] = (count ) & 255; + t[4] = ((bearer-1) << 3) | (direction << 2); + memset(&t[5], 0, 16-5); + + nettle_ctr_crypt(security_context, nettle_aes128.encrypt, + nettle_aes128.block_size, t, + length, buffer, buffer); +} + +void nr_pdcp_security_nea2_free_security(void *security_context) +{ + free(security_context); +} diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.h new file mode 100644 index 0000000000000000000000000000000000000000..c3667c93d4c850dac7e5da0d82ef1c56e60b3a0e --- /dev/null +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.h @@ -0,0 +1,33 @@ +/* + * 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 + */ + +#ifndef _NR_PDCP_SECURITY_NEA2_H_ +#define _NR_PDCP_SECURITY_NEA2_H_ + +void *nr_pdcp_security_nea2_init(unsigned char *ciphering_key); + +void nr_pdcp_security_nea2_cipher(void *security_context, + unsigned char *buffer, int length, + int bearer, int count, int direction); + +void nr_pdcp_security_nea2_free_security(void *security_context); + +#endif /* _NR_PDCP_SECURITY_NEA2_H_ */ diff --git a/openair2/NETWORK_DRIVER/UE_IP/device.c b/openair2/NETWORK_DRIVER/UE_IP/device.c index 63184eb6da60ff04fbde92ce2e4217a07fc28593..0ff9a73925789f7f26be0f0e6a6e5226a10bf305 100644 --- a/openair2/NETWORK_DRIVER/UE_IP/device.c +++ b/openair2/NETWORK_DRIVER/UE_IP/device.c @@ -302,6 +302,7 @@ void ue_ip_change_rx_flags(struct net_device *dev_pP, int flagsP) { } //--------------------------------------------------------------------------- + #if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0) void ue_ip_tx_timeout(struct net_device *dev_pP, unsigned int txqueue) #else diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index 7602e9ca64b61291e4bbf1c7910e654b131ddaca..4f55f94121f1b63c0e64978de42b9cd6aba1652a 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -546,6 +546,13 @@ typedef struct rrc_gummei_s { uint16_t mme_group_id; } rrc_gummei_t; +typedef struct { + uint16_t ciphering_algorithms; + uint16_t integrity_algorithms; + uint16_t sk_counter; + uint8_t kgNB[32]; +} lte_rrc_nr_security_t; + typedef struct eNB_RRC_UE_s { uint8_t primaryCC_id; LTE_SCellToAddMod_r10_t sCell_config[2]; @@ -615,6 +622,9 @@ typedef struct eNB_RRC_UE_s { security_capabilities_t security_capabilities; + /* security capabilities and settings for an UE in ENDC mode */ + lte_rrc_nr_security_t nr_security; + int next_hop_chain_count; uint8_t next_security_key[SECURITY_KEY_LENGTH]; diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 6d39fb222112148ecc55b6d27d5b9517369ddc7d..526ce129b1e43302ab8e5161e4282c0baba224e9 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -4426,69 +4426,11 @@ static int encode_CG_ConfigInfo( struct NR_RadioBearerConfig *rb_config = NULL; asn_enc_rval_t enc_rval; int RRC_OK = 1; - int index = 0; char temp_buff[ASN_MAX_ENCODE_SIZE]; NR_UE_CapabilityRAT_ContainerList_t *ue_cap_rat_container_list = NULL; NR_UE_CapabilityRAT_Container_t *ue_cap_rat_container_MRDC = NULL; NR_UE_CapabilityRAT_Container_t *ue_cap_rat_container_nr = NULL; int RAT_Container_count = 0; - rb_config = calloc(1,sizeof(struct NR_RadioBearerConfig)); - AssertFatal(rb_config != NULL,"failed to allocate memory for rb_config"); - - if(ue_context_pP->ue_context.DRB_configList->list.count != 0) { - rb_config->drb_ToAddModList = calloc(1,sizeof(struct NR_DRB_ToAddModList )); - AssertFatal(rb_config->drb_ToAddModList != NULL,"failed to allocated memory for drbtoaddmodlist"); - rb_config->drb_ToAddModList->list.count = NUMBEROF_DRBS_TOBE_ADDED; - rb_config->drb_ToAddModList->list.array - = calloc(NUMBEROF_DRBS_TOBE_ADDED, sizeof(struct NR_DRB_ToAddMod *)); - AssertFatal( rb_config->drb_ToAddModList->list.array != NULL, - "falied to allocate memory for list.array"); - - for(index = 0; index < NUMBEROF_DRBS_TOBE_ADDED; index++) { - rb_config->drb_ToAddModList->list.array[index] - = calloc(1,sizeof(struct NR_DRB_ToAddMod)); - AssertFatal(rb_config->drb_ToAddModList->list.array[index] != NULL, - "failed to allocate memory for drb_toaddmod"); - rb_config->drb_ToAddModList->list.array[index]->drb_Identity - = ue_context_pP->ue_context.DRB_configList->list.array[index]->drb_Identity; - - if(ue_context_pP->ue_context.DRB_configList->list.array[index]->eps_BearerIdentity) { - rb_config->drb_ToAddModList->list.array[index]->cnAssociation - = calloc(1,sizeof(struct NR_DRB_ToAddMod__cnAssociation)); - AssertFatal(rb_config->drb_ToAddModList->list.array[index]->cnAssociation != NULL, - "failed to allocate memory cnAssociation"); - rb_config->drb_ToAddModList->list.array[index]->cnAssociation->present - = NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity; - rb_config->drb_ToAddModList->list.array[index]->cnAssociation->choice.eps_BearerIdentity - = *(ue_context_pP->ue_context.DRB_configList->list.array[index]->eps_BearerIdentity); - } - - rb_config->drb_ToAddModList->list.array[index]->pdcp_Config = calloc(1,sizeof(struct NR_PDCP_Config)); - rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb = calloc(1,sizeof(struct NR_PDCP_Config__drb)); - rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->discardTimer = calloc(1,sizeof(long)); - *rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->discardTimer - = *(ue_context_pP->ue_context.DRB_configList->list.array[index]->pdcp_Config->discardTimer); - rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->pdcp_SN_SizeUL = calloc(1,sizeof(long)); - *rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->pdcp_SN_SizeUL - = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits; - rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->pdcp_SN_SizeDL = calloc(1,sizeof(long)); - *rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->pdcp_SN_SizeDL - = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits; - rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->headerCompression.present - = NR_PDCP_Config__drb__headerCompression_PR_notUsed; - rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->headerCompression.choice.notUsed = 0; - rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->t_Reordering = calloc(1,sizeof(long)); - *rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->t_Reordering - = NR_PDCP_Config__t_Reordering_ms0; - } - - rb_config->securityConfig = calloc(1,sizeof(struct NR_SecurityConfig )); - rb_config->securityConfig->securityAlgorithmConfig = calloc(1,sizeof(struct NR_SecurityAlgorithmConfig)); - rb_config->securityConfig->securityAlgorithmConfig->cipheringAlgorithm = NR_CipheringAlgorithm_nea0; - rb_config->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm = NULL; - rb_config->securityConfig->keyToUse = calloc(1,sizeof(long)); - *rb_config->securityConfig->keyToUse = NR_SecurityConfig__keyToUse_master; - } cg_configinfo = calloc(1,sizeof(struct NR_CG_ConfigInfo)); AssertFatal(cg_configinfo != NULL,"failed to allocate memory for cg_configinfo"); @@ -4548,15 +4490,6 @@ static int encode_CG_ConfigInfo( (const char *)temp_buff, (enc_rval.encoded+7)>>3); } - cg_configinfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo->mcg_RB_Config - = calloc(1,sizeof(OCTET_STRING_t)); - AssertFatal(cg_configinfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo-> - mcg_RB_Config != NULL, "failed to allocate memory for mcg_rb_config"); - enc_rval = uper_encode_to_buffer(&asn_DEF_NR_RadioBearerConfig,NULL,(void *)rb_config,temp_buff,ASN_MAX_ENCODE_SIZE); - AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n", - enc_rval.failed_type->name, enc_rval.encoded); - OCTET_STRING_fromBuf(cg_configinfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo->mcg_RB_Config, - (const char *)temp_buff, (enc_rval.encoded+7)>>3); // this xer_fprint can be enabled for additional debugging messages // xer_fprint(stdout,&asn_DEF_NR_CG_ConfigInfo,(void *)cg_configinfo); enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CG_ConfigInfo,NULL,(void *)cg_configinfo, @@ -4665,11 +4598,20 @@ rrc_eNB_process_MeasurementReport( msg = itti_alloc_new_message(TASK_RRC_ENB, 0, X2AP_ENDC_SGNB_ADDITION_REQ); memset(&(X2AP_ENDC_SGNB_ADDITION_REQ(msg)), 0, sizeof(x2ap_ENDC_sgnb_addition_req_t)); + X2AP_ENDC_SGNB_ADDITION_REQ(msg).rnti = ctxt_pP->rnti; + + X2AP_ENDC_SGNB_ADDITION_REQ(msg).security_capabilities.encryption_algorithms = ue_context_pP->ue_context.nr_security.ciphering_algorithms; + X2AP_ENDC_SGNB_ADDITION_REQ(msg).security_capabilities.integrity_algorithms = ue_context_pP->ue_context.nr_security.integrity_algorithms; + + memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).kgnb, ue_context_pP->ue_context.nr_security.kgNB, 32); + memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer,enc_buf,enc_size); X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer_size = enc_size; + X2AP_ENDC_SGNB_ADDITION_REQ(msg).target_physCellId = measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[0]->physCellId; + //For the moment we have a single E-RAB which will be the one to be added to the gNB //Not sure how to select bearers to be added if there are multiple. X2AP_ENDC_SGNB_ADDITION_REQ(msg).nb_e_rabs_tobeadded = 1; diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index 320004a361409ebc0dcd2cb0ac68badd3dadd4ba..d34b4164a204dbf299f28b6e02f15c5dd03beda8 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -1045,6 +1045,15 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char } } + ue_context_p->ue_context.nr_security.ciphering_algorithms = S1AP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nr_security_capabilities.encryption_algorithms; + ue_context_p->ue_context.nr_security.integrity_algorithms = S1AP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nr_security_capabilities.integrity_algorithms; + /* let's initialize sk_counter to 0 */ + ue_context_p->ue_context.nr_security.sk_counter = 0; + /* let's compute kgNB */ + derive_skgNB(ue_context_p->ue_context.kenb, + ue_context_p->ue_context.nr_security.sk_counter, + ue_context_p->ue_context.nr_security.kgNB); + // in case, send the S1SP initial context response if it is not sent with the attach complete message if (ue_context_p->ue_context.Status == RRC_RECONFIGURED) { LOG_I(RRC, "Sending rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP, cause %ld\n", ue_context_p->ue_context.reestablishment_cause); diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index c53d44983cb9a6166f61d704156f71130de293e3..36d9bdee60c44f18ed419aa729ca5881685ffd6c 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -447,6 +447,15 @@ typedef struct { //--------------------------------------------------- +typedef struct { + /* nea0 = 0, nea1 = 1, ... */ + int ciphering_algorithms[4]; + int ciphering_algorithms_count; + + /* nia0 = 0, nia1 = 1, ... */ + int integrity_algorithms[4]; + int integrity_algorithms_count; +} nr_security_configuration_t; //---NR---(completely change)--------------------- typedef struct gNB_RRC_INST_s { @@ -479,6 +488,8 @@ typedef struct gNB_RRC_INST_s { int srb1_timer_status_prohibit; int srs_enable[MAX_NUM_CCs]; + // security configuration (preferred algorithms) + nr_security_configuration_t security; } gNB_RRC_INST; #include "nr_rrc_proto.h" //should be put here otherwise compilation error diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index 9b7d734e2c0c587a21ae24834e8a299bb1bb3d66..6d876a0eefacbfa7dcb94474849e2a40fa186025 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -39,6 +39,7 @@ #include "LTE_UE-CapabilityRAT-ContainerList.h" #include "NR_CG-Config.h" #include "NR_CG-ConfigInfo.h" +#include "NR_SecurityConfig.h" int rrc_init_nr_global_param(void); @@ -90,7 +91,10 @@ void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon int n_physical_antenna_ports, int initial_csi_index); -void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig); +void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig, + int eps_bearer_id, int rb_id, + e_NR_CipheringAlgorithm ciphering_algorithm, + e_NR_SecurityConfig__keyToUse key_to_use); int generate_CG_Config(gNB_RRC_INST *rrc, NR_CG_Config_t *cg_Config, diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index abf85a805b6b1e7f67bc3b73099d973be350d779..6d430d722370c71d0c0351e0a87fade5d2f49d2d 100755 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -103,7 +103,8 @@ extern boolean_t nr_rrc_pdcp_config_asn1_req( const uint8_t security_modeP, uint8_t *const kRRCenc, uint8_t *const kRRCint, - uint8_t *const kUPenc + uint8_t *const kUPenc, + uint8_t *const kUPint #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 #endif @@ -887,6 +888,7 @@ rrc_gNB_process_RRCReconfigurationComplete( kUPenc, NULL, NULL, + NULL, NULL); /* Refresh SRBs/DRBs */ nr_rrc_rlc_config_asn1_req(ctxt_pP, @@ -1702,6 +1704,7 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, // NULL, // NULL, // NULL, + // NULL, // NULL); // if (!NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)) { diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index a390d05a0894f6efcfc46fe5612478b8e8ad867b..5ea02c78322f1b9d377f9d127baf6f1d9a20e2e6 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -39,6 +39,7 @@ #include "openair2/RRC/LTE/rrc_eNB_GTPV1U.h" #include "executables/softmodem-common.h" #include <openair2/RRC/NR/rrc_gNB_UE_context.h> +#include "UTIL/OSA/osa_defs.h" extern boolean_t nr_rrc_pdcp_config_asn1_req( const protocol_ctxt_t *const ctxt_pP, @@ -48,7 +49,8 @@ extern boolean_t nr_rrc_pdcp_config_asn1_req( const uint8_t security_modeP, uint8_t *const kRRCenc, uint8_t *const kRRCint, - uint8_t *const kUPenc + uint8_t *const kUPenc, + uint8_t *const kUPint #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 #endif @@ -115,28 +117,14 @@ void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc, NR_UE_CapabilityRAT_ContainerL // dump ue_capabilities - if ( LOG_DEBUGFLAG(DEBUG_ASN1 && ueCapabilityRAT_Container_nr != NULL) ) { + if ( LOG_DEBUGFLAG(DEBUG_ASN1) && ueCapabilityRAT_Container_nr != NULL ) { xer_fprint(stdout, &asn_DEF_NR_UE_NR_Capability, ue_context_p->ue_context.UE_Capability_nr); } - if ( LOG_DEBUGFLAG(DEBUG_ASN1 && ueCapabilityRAT_Container_MRDC != NULL) ) { + if ( LOG_DEBUGFLAG(DEBUG_ASN1) && ueCapabilityRAT_Container_MRDC != NULL ) { xer_fprint(stdout, &asn_DEF_NR_UE_MRDC_Capability, ue_context_p->ue_context.UE_Capability_MRDC); } - if(cg_config_info && cg_config_info->mcg_RB_Config) { - asn_dec_rval_t dec_rval = uper_decode(NULL, - &asn_DEF_NR_RadioBearerConfig, - (void **)&ue_context_p->ue_context.rb_config, - cg_config_info->mcg_RB_Config->buf, - cg_config_info->mcg_RB_Config->size, 0, 0); - - if((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { - AssertFatal(1==0,"[InterNode] Failed to decode mcg_rb_config (%zu bits), size of OCTET_STRING %lu\n", - dec_rval.consumed, cg_config_info->mcg_RB_Config->size); - } - } - - xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void *)ue_context_p->ue_context.rb_config); rrc_add_nsa_user(rrc,ue_context_p, m); } @@ -152,6 +140,8 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ gtpv1u_enb_create_tunnel_req_t create_tunnel_req; gtpv1u_enb_create_tunnel_resp_t create_tunnel_resp; protocol_ctxt_t ctxt={0}; + unsigned char *kUPenc = NULL; + int i; // NR RRCReconfiguration AssertFatal(rrc->Nb_ue < MAX_NR_RRC_UE_CONTEXTS,"cannot add another UE\n"); ue_context_p->ue_context.reconfig = calloc(1,sizeof(NR_RRCReconfiguration_t)); @@ -162,9 +152,91 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ NR_RRCReconfiguration_IEs_t *reconfig_ies=calloc(1,sizeof(NR_RRCReconfiguration_IEs_t)); ue_context_p->ue_context.reconfig->criticalExtensions.choice.rrcReconfiguration = reconfig_ies; carrier->initial_csi_index[rrc->Nb_ue] = 0; + ue_context_p->ue_context.rb_config = calloc(1,sizeof(NR_RRCReconfiguration_t)); if (get_softmodem_params()->phy_test == 1 || get_softmodem_params()->do_ra == 1 || get_softmodem_params()->sa == 1){ - ue_context_p->ue_context.rb_config = calloc(1,sizeof(NR_RRCReconfiguration_t)); - fill_default_rbconfig(ue_context_p->ue_context.rb_config); + fill_default_rbconfig(ue_context_p->ue_context.rb_config, + 5 /* EPS bearer ID */, + 1 /* drb ID */, + NR_CipheringAlgorithm_nea0, + NR_SecurityConfig__keyToUse_master); + } else { + /* TODO: handle more than one bearer */ + if (m == NULL) { + LOG_E(RRC, "fatal: m==NULL\n"); + exit(1); + } + if (m->nb_e_rabs_tobeadded != 1) { + LOG_E(RRC, "fatal: m->nb_e_rabs_tobeadded = %d, should be 1\n", m->nb_e_rabs_tobeadded); + exit(1); + } + + /* store security key and security capabilities */ + memcpy(ue_context_p->ue_context.kgnb, m->kgnb, 32); + ue_context_p->ue_context.security_capabilities.nRencryption_algorithms = m->security_capabilities.encryption_algorithms; + ue_context_p->ue_context.security_capabilities.nRintegrity_algorithms = m->security_capabilities.integrity_algorithms; + + /* Select ciphering algorithm based on gNB configuration file and + * UE's supported algorithms. + * We take the first from the list that is supported by the UE. + * The ordering of the list comes from the configuration file. + */ + /* preset nea0 as fallback */ + ue_context_p->ue_context.ciphering_algorithm = 0; + for (i = 0; i < rrc->security.ciphering_algorithms_count; i++) { + int nea_mask[4] = { + 0, + 0x8000, /* nea1 */ + 0x4000, /* nea2 */ + 0x2000 /* nea3 */ + }; + if (rrc->security.ciphering_algorithms[i] == 0) { + /* nea0 already preselected */ + break; + } + if (ue_context_p->ue_context.security_capabilities.nRencryption_algorithms & nea_mask[rrc->security.ciphering_algorithms[i]]) { + ue_context_p->ue_context.ciphering_algorithm = rrc->security.ciphering_algorithms[i]; + break; + } + } + + LOG_I(RRC, "selecting ciphering algorithm %d\n", (int)ue_context_p->ue_context.ciphering_algorithm); + + /* integrity: no integrity protection for DRB in ENDC mode + * as written in 38.331: "If UE is connected to E-UTRA/EPC, this field + * indicates the integrity protection algorithm to be used for SRBs + * configured with NR PDCP, as specified in TS 33.501" + * So nothing for DRB. Plus a test with a COTS UE revealed that it + * did not apply integrity on the DRB. + */ + ue_context_p->ue_context.integrity_algorithm = 0; + + LOG_I(RRC, "selecting integrity algorithm %d\n", ue_context_p->ue_context.integrity_algorithm); + + /* derive UP security key */ + unsigned char *kUPenc_kdf; + nr_derive_key_up_enc(ue_context_p->ue_context.ciphering_algorithm, + ue_context_p->ue_context.kgnb, + &kUPenc_kdf); + /* kUPenc: last 128 bits of key derivation function which returns 256 bits */ + kUPenc = malloc(16); + if (kUPenc == NULL) exit(1); + memcpy(kUPenc, kUPenc_kdf+16, 16); + free(kUPenc_kdf); + + e_NR_CipheringAlgorithm cipher_algo; + switch (ue_context_p->ue_context.ciphering_algorithm) { + case 0: cipher_algo = NR_CipheringAlgorithm_nea0; break; + case 1: cipher_algo = NR_CipheringAlgorithm_nea1; break; + case 2: cipher_algo = NR_CipheringAlgorithm_nea2; break; + case 3: cipher_algo = NR_CipheringAlgorithm_nea3; break; + default: LOG_E(RRC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); exit(1); + } + + fill_default_rbconfig(ue_context_p->ue_context.rb_config, + m->e_rabs_tobeadded[0].e_rab_id, + m->e_rabs_tobeadded[0].drb_ID, + cipher_algo, + NR_SecurityConfig__keyToUse_secondary); } fill_default_reconfig(carrier->servingcellconfigcommon, reconfig_ies, @@ -285,10 +357,11 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ (NR_SRB_ToAddModList_t *) NULL, ue_context_p->ue_context.rb_config->drb_ToAddModList , ue_context_p->ue_context.rb_config->drb_ToReleaseList, - 0xff, - NULL, - NULL, - NULL, + (ue_context_p->ue_context.integrity_algorithm << 4) | ue_context_p->ue_context.ciphering_algorithm, + NULL, /* kRRCenc - unused */ + NULL, /* kRRCint - unused */ + kUPenc, /* kUPenc */ + NULL, /* kUPint - unused */ NULL, NULL, ue_context_p->ue_context.secondaryCellGroup->rlc_BearerToAddModList); diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c index aebdc2f1cc9b260dda194bbae0fcc96e3461ab87..ab3f19227622cbcb9b26f3339bfc448fcdc32997 100644 --- a/openair2/RRC/NR/rrc_gNB_reconfig.c +++ b/openair2/RRC/NR/rrc_gNB_reconfig.c @@ -1329,7 +1329,10 @@ void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon reconfig->nonCriticalExtension = NULL; } -void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig) { +void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig, + int eps_bearer_id, int rb_id, + e_NR_CipheringAlgorithm ciphering_algorithm, + e_NR_SecurityConfig__keyToUse key_to_use) { rbconfig->srb_ToAddModList = NULL; rbconfig->srb3_ToRelease = NULL; @@ -1337,8 +1340,8 @@ void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig) { NR_DRB_ToAddMod_t *drb_ToAddMod = calloc(1,sizeof(*drb_ToAddMod)); drb_ToAddMod->cnAssociation = calloc(1,sizeof(*drb_ToAddMod->cnAssociation)); drb_ToAddMod->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity; - drb_ToAddMod->cnAssociation->choice.eps_BearerIdentity= 5; - drb_ToAddMod->drb_Identity = 1; + drb_ToAddMod->cnAssociation->choice.eps_BearerIdentity= eps_bearer_id; + drb_ToAddMod->drb_Identity = rb_id; drb_ToAddMod->reestablishPDCP = NULL; drb_ToAddMod->recoverPDCP = NULL; drb_ToAddMod->pdcp_Config = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config)); @@ -1367,12 +1370,12 @@ void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig) { rbconfig->securityConfig = calloc(1,sizeof(*rbconfig->securityConfig)); rbconfig->securityConfig->securityAlgorithmConfig = calloc(1,sizeof(*rbconfig->securityConfig->securityAlgorithmConfig)); - rbconfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm = NR_CipheringAlgorithm_nea0; + rbconfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm = ciphering_algorithm; rbconfig->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm=NULL; rbconfig->securityConfig->keyToUse = calloc(1,sizeof(*rbconfig->securityConfig->keyToUse)); - *rbconfig->securityConfig->keyToUse = NR_SecurityConfig__keyToUse_master; + *rbconfig->securityConfig->keyToUse = key_to_use; - xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void*)rbconfig); +// xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void*)rbconfig); } /* Function to set or overwrite PTRS DL RRC parameters */ void rrc_config_dl_ptrs_params(NR_BWP_Downlink_t *bwp, int *ptrsNrb, int *ptrsMcs, int *epre_Ratio, int * reOffset) diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index b6c0ae4b453cd57f82c4450bb85e470a2d87d070..460dbf1d22b5f06a6ff41b9da7f2d2d370cec00a 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -186,7 +186,8 @@ extern boolean_t nr_rrc_pdcp_config_asn1_req( const uint8_t security_modeP, uint8_t *const kRRCenc, uint8_t *const kRRCint, - uint8_t *const kUPenc + uint8_t *const kUPenc, + uint8_t *const kUPint #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 #endif @@ -2085,6 +2086,7 @@ nr_sa_rrc_ue_process_radioBearerConfig( // NULL, // NULL, // NULL, + // NULL, // NULL); // Refresh SRBs // nr_rrc_rlc_config_asn1_req(ctxt_pP, @@ -2176,6 +2178,7 @@ nr_sa_rrc_ue_process_radioBearerConfig( // NULL, // kUPenc, // NULL, + // NULL, // NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB, // NULL); // Refresh DRBs diff --git a/openair2/UTIL/OSA/osa_defs.h b/openair2/UTIL/OSA/osa_defs.h index 304dd07042d4dca0259a6164014b2ddf371f07b6..633465868380bba098f25dfbe385873baa050765 100644 --- a/openair2/UTIL/OSA/osa_defs.h +++ b/openair2/UTIL/OSA/osa_defs.h @@ -53,6 +53,8 @@ typedef enum { //int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t **keNB); +int derive_skgNB(const uint8_t *keNB, const uint16_t sk_counter, uint8_t *skgNB); + int derive_key(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id, const uint8_t key[32], uint8_t **out); int nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id, diff --git a/openair2/UTIL/OSA/osa_key_deriver.c b/openair2/UTIL/OSA/osa_key_deriver.c index 71c7793fa084c451a73223218b95e133f9602d0e..159ee7f159b93f9ce1c791edc263ff5787a247eb 100644 --- a/openair2/UTIL/OSA/osa_key_deriver.c +++ b/openair2/UTIL/OSA/osa_key_deriver.c @@ -159,3 +159,27 @@ int derive_keNB(const uint8_t key[32], const uint32_t nas_count, uint8_t **keNB) return 0; } */ + +int derive_skgNB(const uint8_t *keNB, const uint16_t sk_counter, uint8_t *skgNB) +{ + uint8_t *out; + uint8_t s[5]; + + /* FC is 0x1c (see 3gpp 33.401 annex A.15) */ + s[0] = 0x1c; + + /* put sk_counter */ + s[1] = (sk_counter >> 8) & 0xff; + s[2] = sk_counter & 0xff; + + /* put length of sk_counter (2) */ + s[3] = 0x00; + s[4] = 0x02; + + kdf(s, 5, keNB, 32, &out, 32); + + memcpy(skgNB, out, 32); + free(out); + + return 0; +} diff --git a/openair3/S1AP/s1ap_eNB_handlers.c b/openair3/S1AP/s1ap_eNB_handlers.c index 7c233d9e14d83e4a1a7c592a49643c40be391d1f..370d34868b577e7428a68d5e70ac49dad397124a 100644 --- a/openair3/S1AP/s1ap_eNB_handlers.c +++ b/openair3/S1AP/s1ap_eNB_handlers.c @@ -864,22 +864,36 @@ int s1ap_eNB_handle_initial_context_request(uint32_t assoc_id, BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.encryptionAlgorithms); S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_capabilities.integrity_algorithms = BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.integrityProtectionAlgorithms); - /* id-SecurityKey : Copy the security key */ } else {/* ie != NULL */ return -1; } + /* id-SecurityKey : Copy the security key */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_InitialContextSetupRequestIEs_t, ie, container, S1AP_ProtocolIE_ID_id_SecurityKey, true); if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ memcpy(&S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_key, ie->value.choice.SecurityKey.buf, ie->value.choice.SecurityKey.size); - itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p); } else {/* ie != NULL */ return -1; } + /* id-NRUESecurityCapabilities */ + S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_InitialContextSetupRequestIEs_t, ie, container, + S1AP_ProtocolIE_ID_id_NRUESecurityCapabilities, false); + if (ie != NULL) { + S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nr_security_capabilities.encryption_algorithms = + BIT_STRING_to_uint16(&ie->value.choice.NRUESecurityCapabilities.nRencryptionAlgorithms); + S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nr_security_capabilities.integrity_algorithms = + BIT_STRING_to_uint16(&ie->value.choice.NRUESecurityCapabilities.nRintegrityProtectionAlgorithms); + } else { + S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nr_security_capabilities.encryption_algorithms = 0; + S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nr_security_capabilities.integrity_algorithms = 0; + } + + itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p); + return 0; } diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h index 85ee80ea7cdf443a01559cb27cdc265f09ababa2..93e9ffb52f8d908c5f6da1dbcf56bdd68db50aad 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/targets/ARCH/COMMON/common_lib.h @@ -105,9 +105,10 @@ typedef enum { ADRV9371_ZC706_DEV, /*!\brief device is UEDv2 */ UEDv2_DEV, + RFSIMULATOR, MAX_RF_DEV_TYPE } dev_type_t; -#define DEVTYPE_NAMES {"","EXMIMO","USRP B200","USRP X300","USRP N300","BLADERF","LMSSDR","IRIS","No HW","ADRV9371_ZC706","UEDv2"} +#define DEVTYPE_NAMES {"","EXMIMO","USRP B200","USRP X300","USRP N300","BLADERF","LMSSDR","IRIS","No HW","ADRV9371_ZC706","UEDv2", "RFSIMULATOR"} /*!\brief transport protocol types */ typedef enum { @@ -491,15 +492,11 @@ struct openair0_device_t { typedef int(*oai_device_initfunc_t)(openair0_device *device, openair0_config_t *openair0_cfg); /* type of transport init function, implemented in shared lib */ typedef int(*oai_transport_initfunc_t)(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t *eth_params); -#define UE_MAGICDL_FDD 0xA5A5A5A5A5A5A5A5 // UE DL FDD record -#define UE_MAGICUL_FDD 0x5A5A5A5A5A5A5A5A // UE UL FDD record -#define UE_MAGICDL_TDD 0xA6A6A6A6A6A6A6A6 // UE DL TDD record -#define UE_MAGICUL_TDD 0x6A6A6A6A6A6A6A6A // UE UL TDD record +#define UE_MAGICDL 0xA5A5A5A5A5A5A5A5 // UE DL FDD record +#define UE_MAGICUL 0x5A5A5A5A5A5A5A5A // UE UL FDD record -#define ENB_MAGICDL_FDD 0xB5B5B5B5B5B5B5B5 // eNB DL FDD record -#define ENB_MAGICUL_FDD 0x5B5B5B5B5B5B5B5B // eNB UL FDD record -#define ENB_MAGICDL_TDD 0xB6B6B6B6B6B6B6B6 // eNB DL TDD record -#define ENB_MAGICUL_TDD 0x6B6B6B6B6B6B6B6B // eNB UL TDD record +#define ENB_MAGICDL 0xB5B5B5B5B5B5B5B5 // eNB DL FDD record +#define ENB_MAGICUL 0x5B5B5B5B5B5B5B5B // eNB UL FDD record #define OPTION_LZ4 0x00000001 // LZ4 compression (option_value is set to compressed size) @@ -516,19 +513,6 @@ typedef struct { uint32_t option_flag; // Option flag } samplesBlockHeader_t; -#define UE_MAGICDL_FDD 0xA5A5A5A5A5A5A5A5 // UE DL FDD record -#define UE_MAGICUL_FDD 0x5A5A5A5A5A5A5A5A // UE UL FDD record -#define UE_MAGICDL_TDD 0xA6A6A6A6A6A6A6A6 // UE DL TDD record -#define UE_MAGICUL_TDD 0x6A6A6A6A6A6A6A6A // UE UL TDD record - -#define ENB_MAGICDL_FDD 0xB5B5B5B5B5B5B5B5 // eNB DL FDD record -#define ENB_MAGICUL_FDD 0x5B5B5B5B5B5B5B5B // eNB UL FDD record -#define ENB_MAGICDL_TDD 0xB6B6B6B6B6B6B6B6 // eNB DL TDD record -#define ENB_MAGICUL_TDD 0x6B6B6B6B6B6B6B6B // eNB UL TDD record - -#define OPTION_LZ4 0x00000001 // LZ4 compression (option_value is set to compressed size) - - #ifdef __cplusplus extern "C" { diff --git a/targets/ARCH/ETHERNET/benetel/4g/benetel.c b/targets/ARCH/ETHERNET/benetel/4g/benetel.c index 76855111e11828389e24b04aa0b59cbaa4a44a0c..d3b72463b495a1cfd4579cf770350a12f94dd5c1 100644 --- a/targets/ARCH/ETHERNET/benetel/4g/benetel.c +++ b/targets/ARCH/ETHERNET/benetel/4g/benetel.c @@ -163,8 +163,8 @@ int trx_benetel_ctlrecv(openair0_device *device, void *msg, ssize_t msg_len) cap->FH_fmt = OAI_IF4p5_only; cap->num_bands = 1; cap->band_list[0] = 7; - cap->nb_rx[0] = 1; - cap->nb_tx[0] = 1; + cap->nb_rx[0] = device->openair0_cfg->rx_num_channels; + cap->nb_tx[0] = device->openair0_cfg->tx_num_channels; cap->max_pdschReferenceSignalPower[0] = -27; cap->max_rxgain[0] = 90; @@ -194,11 +194,12 @@ void benetel_fh_if4p5_south_in(RU_t *ru, LTE_DL_FRAME_PARMS *fp; int symbol; int32_t *rxdata; - int antenna = 0; + int antenna; lock_ul_buffer(&s->buffers, *subframe); next: - while (!(s->buffers.ul_busy[*subframe] == 0x3fff || + while (!((s->buffers.ul_busy[0][*subframe] == 0x3fff && + s->buffers.ul_busy[1][*subframe] == 0x3fff) || s->buffers.prach_busy[*subframe] == 1)) wait_ul_buffer(&s->buffers, *subframe); if (s->buffers.prach_busy[*subframe] == 1) { @@ -217,24 +218,27 @@ next: eNB = eNB_list[0]; fp = &eNB->frame_parms; - for (symbol = 0; symbol < 14; symbol++) { - int i; - uint16_t *p = (uint16_t *)(&s->buffers.ul[*subframe][symbol*1200*4]); - for (i = 0; i < 1200*2; i++) { - p[i] = htons(p[i]); - } - rxdata = &ru->common.rxdataF[antenna][symbol * fp->ofdm_symbol_size]; + for (antenna = 0; antenna < ru->nb_rx; antenna++) { + for (symbol = 0; symbol < 14; symbol++) { + int i; + uint16_t *p = (uint16_t *)(&s->buffers.ul[antenna][*subframe][symbol*1200*4]); + for (i = 0; i < 1200*2; i++) { + p[i] = htons(p[i]); + } + rxdata = &ru->common.rxdataF[antenna][symbol * fp->ofdm_symbol_size]; #if 1 - memcpy(rxdata + 2048 - 600, - &s->buffers.ul[*subframe][symbol*1200*4], - 600 * 4); - memcpy(rxdata, - &s->buffers.ul[*subframe][symbol*1200*4] + 600*4, - 600 * 4); + memcpy(rxdata + 2048 - 600, + &s->buffers.ul[antenna][*subframe][symbol*1200*4], + 600 * 4); + memcpy(rxdata, + &s->buffers.ul[antenna][*subframe][symbol*1200*4] + 600*4, + 600 * 4); #endif + } } - s->buffers.ul_busy[*subframe] = 0; + s->buffers.ul_busy[0][*subframe] = 0; + s->buffers.ul_busy[1][*subframe] = 0; signal_ul_buffer(&s->buffers, *subframe); unlock_ul_buffer(&s->buffers, *subframe); @@ -272,45 +276,49 @@ void benetel_fh_if4p5_south_out(RU_t *ru, LTE_DL_FRAME_PARMS *fp; int symbol; int32_t *txdata; - int aa = 0; + int aa; //printf("BENETEL: %s (f.sf %d.%d ts %ld)\n", __FUNCTION__, frame, subframe, timestamp); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff ); lock_dl_buffer(&s->buffers, subframe); - if (s->buffers.dl_busy[subframe]) { + if (s->buffers.dl_busy[0][subframe] || + s->buffers.dl_busy[1][subframe]) { printf("%s: fatal: DL buffer busy for subframe %d\n", __FUNCTION__, subframe); unlock_dl_buffer(&s->buffers, subframe); return; } eNB = eNB_list[0]; fp = &eNB->frame_parms; - if (ru->num_eNB != 1 || ru->nb_tx != 1 || fp->ofdm_symbol_size != 2048 || + if (ru->num_eNB != 1 || fp->ofdm_symbol_size != 2048 || fp->Ncp != NORMAL || fp->symbols_per_tti != 14) { printf("%s:%d:%s: unsupported configuration\n", __FILE__, __LINE__, __FUNCTION__); exit(1); } - for (symbol = 0; symbol < 14; symbol++) { - txdata = &ru->common.txdataF_BF[aa][symbol * fp->ofdm_symbol_size]; + for (aa = 0; aa < ru->nb_tx; aa++) { + for (symbol = 0; symbol < 14; symbol++) { + txdata = &ru->common.txdataF_BF[aa][symbol * fp->ofdm_symbol_size]; #if 1 - memcpy(&s->buffers.dl[subframe][symbol*1200*4], - txdata + 2048 - 600, - 600 * 4); - memcpy(&s->buffers.dl[subframe][symbol*1200*4] + 600*4, - txdata + 1, - 600 * 4); + memcpy(&s->buffers.dl[aa][subframe][symbol*1200*4], + txdata + 2048 - 600, + 600 * 4); + memcpy(&s->buffers.dl[aa][subframe][symbol*1200*4] + 600*4, + txdata + 1, + 600 * 4); #endif - int i; - uint16_t *p = (uint16_t *)(&s->buffers.dl[subframe][symbol*1200*4]); - for (i = 0; i < 1200*2; i++) { - p[i] = htons(p[i]); + int i; + uint16_t *p = (uint16_t *)(&s->buffers.dl[aa][subframe][symbol*1200*4]); + for (i = 0; i < 1200*2; i++) { + p[i] = htons(p[i]); + } } } - s->buffers.dl_busy[subframe] = 0x3fff; + s->buffers.dl_busy[0][subframe] = 0x3fff; + s->buffers.dl_busy[1][subframe] = 0x3fff; unlock_dl_buffer(&s->buffers, subframe); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_IF4P5_SOUTH_OUT_RU+ru->idx, ru->proc.frame_tx); diff --git a/targets/ARCH/ETHERNET/benetel/4g/dpdk_driver.c b/targets/ARCH/ETHERNET/benetel/4g/dpdk_driver.c index 42953d1d4a8be829135d4c80332f6b253fbf9270..2b6ef37e6fa0c242688a9f9f6598b8f1cc9ef9b6 100644 --- a/targets/ARCH/ETHERNET/benetel/4g/dpdk_driver.c +++ b/targets/ARCH/ETHERNET/benetel/4g/dpdk_driver.c @@ -233,19 +233,20 @@ l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs) } - if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce && ANT_NUM == 0x00) { + if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce) { p.frame = FRAME; p.subframe = SUBFRAME >> 4; p.slot = 0; /* unused */ p.symbol = SYMBOL; - p.antenna = 0; + p.antenna = ANT_NUM; memcpy(p.iq, IQ_ptr, 4800); store_ul(bs, &p); } - // U-PLANE UL ANT_0 PROCESSING - if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce && ANT_NUM == 0x00 && dl_start == 1) + // U-PLANE UL PROCESSING + if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce && dl_start == 1) { + int a = ANT_NUM; int tx_frame = FRAME; int tx_subframe = SUBFRAME >> 4; int tx_symbol = SYMBOL + 5; @@ -266,33 +267,20 @@ l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs) SUBFRAME = tx_subframe << 4; SYMBOL = tx_symbol; - /* antenna 0 - send actual DL data (if available) */ + /* send actual DL data (if available) */ lock_dl_buffer(bs->buffers, tx_subframe); - if (!(bs->buffers->dl_busy[tx_subframe] & (1 << tx_symbol))) { - printf("%s: warning, DL underflow (sf.symbol %d.%d)\n", __FUNCTION__, + if (!(bs->buffers->dl_busy[a][tx_subframe] & (1 << tx_symbol))) { + printf("%s: warning, DL underflow (antenna %d sf.symbol %d.%d)\n", + __FUNCTION__, + a, tx_subframe, tx_symbol); memset(IQ_ptr, 0, 1200 * 4); } else { - memcpy(IQ_ptr, bs->buffers->dl[tx_subframe] + tx_symbol * 1200*4, + memcpy(IQ_ptr, bs->buffers->dl[a][tx_subframe] + tx_symbol * 1200*4, 1200*4); } - bs->buffers->dl_busy[tx_subframe] &= ~(1 << tx_symbol); + bs->buffers->dl_busy[a][tx_subframe] &= ~(1 << tx_symbol); unlock_dl_buffer(bs->buffers, tx_subframe); - - // fill DL Data for ant 0 with 0 value -// memset(IQ_ptr, 0, 4800); - } - - // U-PLANE UL ANT_1 PROCESSING - else if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce && ANT_NUM == 0x01 && dl_start == 1) - { - -// ANT_NUM = 0x01; - SYMBOL = (SYMBOL + 5) % 14; - PAYLOAD_2 = 0xc8; - - // fill DL Data for ant 1 with 0 value - memset(IQ_ptr, 0, 4800); } // U-PLANE PRACH PROCESSING diff --git a/targets/ARCH/ETHERNET/benetel/4g/low.c b/targets/ARCH/ETHERNET/benetel/4g/low.c index 038592d596c4cac0d21a4f1a79afe1014174f59c..14783a700b46a97dd6d02cd3fae2959a2b0c89f6 100644 --- a/targets/ARCH/ETHERNET/benetel/4g/low.c +++ b/targets/ARCH/ETHERNET/benetel/4g/low.c @@ -27,37 +27,36 @@ void store_ul(benetel_t *bs, ul_packet_t *ul) { - /* only antenna 0 for the moment */ - if (ul->antenna != 0) - return; + int a = ul->antenna; - if (ul->subframe != bs->next_subframe || - ul->symbol != bs->next_symbol) { - printf("%s: fatal, expected frame.sf.symbol %d.%d.%d, got %d.%d.%d\n", + if (ul->subframe != bs->next_subframe[a] || + ul->symbol != bs->next_symbol[a]) { + printf("%s: fatal, antenna %d expected frame.sf.symbol %d.%d.%d, got %d.%d.%d\n", __FUNCTION__, - bs->expected_benetel_frame, bs->next_subframe, bs->next_symbol, + a, + bs->expected_benetel_frame[a], bs->next_subframe[a], bs->next_symbol[a], ul->frame, ul->subframe, ul->symbol); exit(1); } - lock_ul_buffer(bs->buffers, bs->next_subframe); - if (bs->buffers->ul_busy[bs->next_subframe] & (1 << bs->next_symbol)) { + lock_ul_buffer(bs->buffers, bs->next_subframe[a]); + if (bs->buffers->ul_busy[a][bs->next_subframe[a]] & (1 << bs->next_symbol[a])) { printf("%s: warning, UL overflow (sf.symbol %d.%d)\n", __FUNCTION__, - bs->next_subframe, bs->next_symbol); + bs->next_subframe[a], bs->next_symbol[a]); } - memcpy(bs->buffers->ul[bs->next_subframe] + bs->next_symbol * 1200*4, + memcpy(bs->buffers->ul[a][bs->next_subframe[a]] + bs->next_symbol[a] * 1200*4, ul->iq, 1200*4); - bs->buffers->ul_busy[bs->next_subframe] |= (1 << bs->next_symbol); - signal_ul_buffer(bs->buffers, bs->next_subframe); - unlock_ul_buffer(bs->buffers, bs->next_subframe); + bs->buffers->ul_busy[a][bs->next_subframe[a]] |= (1 << bs->next_symbol[a]); + signal_ul_buffer(bs->buffers, bs->next_subframe[a]); + unlock_ul_buffer(bs->buffers, bs->next_subframe[a]); - bs->next_symbol++; - if (bs->next_symbol == 14) { - bs->next_symbol = 0; - bs->next_subframe = (bs->next_subframe + 1) % 10; - if (bs->next_subframe == 0) { - bs->expected_benetel_frame++; - bs->expected_benetel_frame &= 255; + bs->next_symbol[a]++; + if (bs->next_symbol[a] == 14) { + bs->next_symbol[a] = 0; + bs->next_subframe[a] = (bs->next_subframe[a] + 1) % 10; + if (bs->next_subframe[a] == 0) { + bs->expected_benetel_frame[a]++; + bs->expected_benetel_frame[a] &= 255; } } } diff --git a/targets/ARCH/ETHERNET/benetel/4g/low.h b/targets/ARCH/ETHERNET/benetel/4g/low.h index 5e75d9181e84f06447a6631373c043fe3d9779eb..e74bf89163bc54d2a34a0cfb7e9d065fbd2b47eb 100644 --- a/targets/ARCH/ETHERNET/benetel/4g/low.h +++ b/targets/ARCH/ETHERNET/benetel/4g/low.h @@ -26,9 +26,10 @@ typedef struct { shared_buffers *buffers; - int next_subframe; - int next_symbol; - int expected_benetel_frame; + /* [2] is for two antennas */ + int next_subframe[2]; + int next_symbol[2]; + int expected_benetel_frame[2]; char *dpdk_main_command_line; } benetel_t; diff --git a/targets/ARCH/ETHERNET/benetel/4g/low_dpdk.c b/targets/ARCH/ETHERNET/benetel/4g/low_dpdk.c index ecff473010c34f1bfae5ab166ca3c83f663cb5b8..edf62a67e07ab71cda2f6e3f32e9d70ac9c2f565 100644 --- a/targets/ARCH/ETHERNET/benetel/4g/low_dpdk.c +++ b/targets/ARCH/ETHERNET/benetel/4g/low_dpdk.c @@ -68,7 +68,8 @@ void *benetel_start_dpdk(char *ifname, shared_buffers *buffers, char *dpdk_main_ bs->buffers = buffers; - bs->expected_benetel_frame = 255; + bs->expected_benetel_frame[0] = 255; + bs->expected_benetel_frame[1] = 255; bs->dpdk_main_command_line = dpdk_main_command_line; diff --git a/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.c b/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.c index 492a15dfc3833e85b38d196b32903615f8618114..380cbabc73bf618201f7e4864c24afec9521e156 100644 --- a/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.c +++ b/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.c @@ -44,9 +44,12 @@ void init_buffers(shared_buffers *s) /* in FDD the eNB's first transmitted DL subframe is 4 but the device * needs to have subframes 1, 2 and 3 ready. Let's pretend there are ready. */ - s->dl_busy[1] = 0x3fff; - s->dl_busy[2] = 0x3fff; - s->dl_busy[3] = 0x3fff; + s->dl_busy[0][1] = 0x3fff; + s->dl_busy[0][2] = 0x3fff; + s->dl_busy[0][3] = 0x3fff; + s->dl_busy[1][1] = 0x3fff; + s->dl_busy[1][2] = 0x3fff; + s->dl_busy[1][3] = 0x3fff; } void lock_dl_buffer(shared_buffers *s, int subframe) diff --git a/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.h b/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.h index 1d5040b95b55d3ef76fd6d40ede97f7ea686acca..ed174265c5d4fbff11f212b2ae2b0eb1883c5e66 100644 --- a/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.h +++ b/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.h @@ -26,10 +26,11 @@ #include <stdint.h> typedef struct { - unsigned char dl[10][14*1200*4]; - unsigned char ul[10][14*1200*4]; - uint16_t dl_busy[10]; - uint16_t ul_busy[10]; + /* [2] is for two antennas */ + unsigned char dl[2][10][14*1200*4]; + unsigned char ul[2][10][14*1200*4]; + uint16_t dl_busy[2][10]; + uint16_t ul_busy[2][10]; pthread_mutex_t m_ul[10]; pthread_cond_t c_ul[10]; diff --git a/targets/ARCH/ETHERNET/benetel/5g/benetel.c b/targets/ARCH/ETHERNET/benetel/5g/benetel.c index 2f60e7dc49efe15a25325565744cd916744d3bdc..cededa968eddd8c06bfdfcb1f44a8dcf86cfb362 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/benetel.c +++ b/targets/ARCH/ETHERNET/benetel/5g/benetel.c @@ -162,8 +162,9 @@ int trx_benetel_ctlrecv(openair0_device *device, void *msg, ssize_t msg_len) cap->FH_fmt = OAI_IF4p5_only; cap->num_bands = 1; cap->band_list[0] = 78; - cap->nb_rx[0] = 1; - cap->nb_tx[0] = 1; + /* TODO: hardcoded to 1 for the moment, get the real value somehow... */ + cap->nb_rx[0] = 1; //device->openair0_cfg->rx_num_channels; + cap->nb_tx[0] = 1; //device->openair0_cfg->tx_num_channels; cap->max_pdschReferenceSignalPower[0] = -27; cap->max_rxgain[0] = 90; @@ -201,12 +202,13 @@ void benetel_fh_if4p5_south_in(RU_t *ru, NR_DL_FRAME_PARMS *fp; int symbol; int32_t *rxdata; - int antenna = 0; + int antenna; lock_ul_buffer(&s->buffers, *slot); #if 1 next: - while (!(s->buffers.ul_busy[*slot] == 0x3fff || + while (!((s->buffers.ul_busy[0][*slot] == 0x3fff && + s->buffers.ul_busy[1][*slot] == 0x3fff) || s->buffers.prach_busy[*slot] == 1)) wait_ul_buffer(&s->buffers, *slot); if (s->buffers.prach_busy[*slot] == 1) { @@ -226,24 +228,31 @@ next: #endif fp = ru->nr_frame_parms; - for (symbol = 0; symbol < 14; symbol++) { - int i; - uint16_t *p = (uint16_t *)(&s->buffers.ul[*slot][symbol*1272*4]); - for (i = 0; i < 1272*2; i++) { - p[i] = htons(p[i]); - } - rxdata = &ru->common.rxdataF[antenna][symbol * fp->ofdm_symbol_size]; + for (antenna = 0; antenna < ru->nb_rx; antenna++) { + for (symbol = 0; symbol < 14; symbol++) { + int i; + int16_t *p = (int16_t *)(&s->buffers.ul[antenna][*slot][symbol*1272*4]); + for (i = 0; i < 1272*2; i++) { + p[i] = (int16_t)(ntohs(p[i])) / 16; + } + rxdata = &ru->common.rxdataF[antenna][symbol * fp->ofdm_symbol_size]; +#if 0 +if (*slot == 0 && symbol == 0) +printf("rxdata in benetel_fh_if4p5_south_in %p\n", &ru->common.rxdataF[antenna][0]); +#endif #if 1 - memcpy(rxdata + 2048 - 1272/2, - &s->buffers.ul[*slot][symbol*1272*4], - (1272/2) * 4); - memcpy(rxdata, - &s->buffers.ul[*slot][symbol*1272*4] + (1272/2)*4, - (1272/2) * 4); + memcpy(rxdata + 2048 - 1272/2, + &s->buffers.ul[antenna][*slot][symbol*1272*4], + (1272/2) * 4); + memcpy(rxdata, + &s->buffers.ul[antenna][*slot][symbol*1272*4] + (1272/2)*4, + (1272/2) * 4); #endif + } } - s->buffers.ul_busy[*slot] = 0; + s->buffers.ul_busy[0][*slot] = 0; + s->buffers.ul_busy[1][*slot] = 0; signal_ul_buffer(&s->buffers, *slot); unlock_ul_buffer(&s->buffers, *slot); @@ -281,43 +290,47 @@ void benetel_fh_if4p5_south_out(RU_t *ru, NR_DL_FRAME_PARMS *fp; int symbol; int32_t *txdata; - int aa = 0; + int aa; //printf("BENETEL: %s (f.sf %d.%d ts %ld)\n", __FUNCTION__, frame, slot, timestamp); lock_dl_buffer(&s->buffers, slot); - if (s->buffers.dl_busy[slot]) { + if (s->buffers.dl_busy[0][slot] || + s->buffers.dl_busy[1][slot]) { printf("%s: fatal: DL buffer busy for subframe %d\n", __FUNCTION__, slot); unlock_dl_buffer(&s->buffers, slot); return; } fp = ru->nr_frame_parms; - if (ru->num_gNB != 1 || ru->nb_tx != 1 || fp->ofdm_symbol_size != 2048 || + if (ru->num_gNB != 1 || fp->ofdm_symbol_size != 2048 || fp->Ncp != NORMAL || fp->symbols_per_slot != 14) { printf("%s:%d:%s: unsupported configuration\n", __FILE__, __LINE__, __FUNCTION__); exit(1); } - for (symbol = 0; symbol < 14; symbol++) { - txdata = &ru->common.txdataF_BF[aa][symbol * fp->ofdm_symbol_size]; + for (aa = 0; aa < ru->nb_tx; aa++) { + for (symbol = 0; symbol < 14; symbol++) { + txdata = &ru->common.txdataF_BF[aa][symbol * fp->ofdm_symbol_size]; #if 1 - memcpy(&s->buffers.dl[slot][symbol*1272*4], - txdata + 2048 - (1272/2), - (1272/2) * 4); - memcpy(&s->buffers.dl[slot][symbol*1272*4] + (1272/2)*4, - txdata, - (1272/2) * 4); + memcpy(&s->buffers.dl[aa][slot][symbol*1272*4], + txdata + 2048 - (1272/2), + (1272/2) * 4); + memcpy(&s->buffers.dl[aa][slot][symbol*1272*4] + (1272/2)*4, + txdata, + (1272/2) * 4); #endif - int i; - uint16_t *p = (uint16_t *)(&s->buffers.dl[slot][symbol*1272*4]); - for (i = 0; i < 1272*2; i++) { - p[i] = htons(p[i]); + int i; + uint16_t *p = (uint16_t *)(&s->buffers.dl[aa][slot][symbol*1272*4]); + for (i = 0; i < 1272*2; i++) { + p[i] = htons(p[i]); + } } } - s->buffers.dl_busy[slot] = 0x3fff; + s->buffers.dl_busy[0][slot] = 0x3fff; + s->buffers.dl_busy[1][slot] = 0x3fff; unlock_dl_buffer(&s->buffers, slot); } diff --git a/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c b/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c index dd50603ec544fc91868c1735d23dd3003863d404..88f4ecb4cdebde52d1f8ce2997ad34762c1b5364 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c +++ b/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c @@ -243,21 +243,22 @@ l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs) } - if(PAYLOAD_1 == 0x13 && PAYLOAD_2 == 0xe4 && ANT_NUM == 0x00) { + if(PAYLOAD_1 == 0x13 && PAYLOAD_2 == 0xe4) { int subframe = SUBFRAME >> 4; int slot = ((SUBFRAME & 0x0f) << 2) | ((SYMBOL >> 6) & 0x03); p.frame = FRAME; p.slot = subframe * 2 + slot; p.symbol = SYMBOL & 0x3f; - p.antenna = 0; + p.antenna = ANT_NUM; memcpy(p.iq, IQ_ptr, 5088); store_ul(bs, &p); // if (p.symbol==0) printf("store ul f.sl.sy %d.%d.%d\n", p.frame, p.slot, p.symbol); } - // U-PLANE UL ANT_0 PROCESSING - if(PAYLOAD_1 == 0x13 && PAYLOAD_2 == 0xe4 && ANT_NUM == 0x00 && dl_start == 1) + // U-PLANE UL PROCESSING + if(PAYLOAD_1 == 0x13 && PAYLOAD_2 == 0xe4 && dl_start == 1) { + int a = ANT_NUM & 0x01; int frame = FRAME; int subframe = SUBFRAME >> 4; int slot = ((SUBFRAME & 0x0f) << 2) | ((SYMBOL >> 6) & 0x03); @@ -282,66 +283,45 @@ l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs) } } - ANT_NUM = 0x00; - // Mask the symbol bits from UL packet received and apply the shift. SYMBOL = ((SYMBOL & 0b00111111) + 10) % 14; - ANT_NUM = 0x00; + ANT_NUM = a; SUBFRAME = sf; + if (a == 1) + slot_id_ctrl++; + // Slot id control for DL - if(slot_id_ctrl > 13){ - SYMBOL = SYMBOL | 0b01000000; + if (slot_id_ctrl > 13) { + SYMBOL = SYMBOL | 0b01000000; + + if (a == 1) { + if (slot_id_ctrl > 27) { + slot_id_ctrl = 0; + sf = sf + 0x10; + + if (sf > 0x90){ + sf = 0; + } + } + } } - /* antenna 0 - send actual DL data (if available) */ + /* send actual DL data (if available) */ oai_slot = tx_subframe * 2 + tx_slot; lock_dl_buffer(bs->buffers, oai_slot); - if (!(bs->buffers->dl_busy[oai_slot] & (1 << tx_symbol))) { - printf("%s: warning, DL underflow (sl.symbol %d.%d)\n", __FUNCTION__, - oai_slot, tx_symbol); + if (!(bs->buffers->dl_busy[a][oai_slot] & (1 << tx_symbol))) { + printf("%s: warning, DL underflow (antenna %d sl.symbol %d.%d)\n", __FUNCTION__, + a, oai_slot, tx_symbol); memset(IQ_ptr, 0, 1272 * 4); } else { - memcpy(IQ_ptr, bs->buffers->dl[oai_slot] + tx_symbol * 1272*4, + memcpy(IQ_ptr, bs->buffers->dl[a][oai_slot] + tx_symbol * 1272*4, 1272*4); } //printf("DL buffer f sf slot symbol %d %d %d %d (sf %d)\n", tx_frame, tx_subframe, tx_slot, tx_symbol, (int)sf); - bs->buffers->dl_busy[oai_slot] &= ~(1 << tx_symbol); + bs->buffers->dl_busy[a][oai_slot] &= ~(1 << tx_symbol); unlock_dl_buffer(bs->buffers, oai_slot); - - // fill DL Data for ant 0 with 0 value -// memset(IQ_ptr, 0, 5088); - } - - // U-PLANE UL ANT_1 PROCESSING - if(PAYLOAD_1 == 0x13 && PAYLOAD_2 == 0xe4 && ANT_NUM == 0x01 && dl_start == 1) - { - - // Mask the symbol bits from UL packet received and apply the shift. - SYMBOL = ((SYMBOL & 0b00111111) +10) % 14; - - ANT_NUM = 0x01; - SUBFRAME = sf; - - slot_id_ctrl++; - - // Slot id control for DL - if(slot_id_ctrl > 13){ - SYMBOL = SYMBOL | 0b01000000; - - if(slot_id_ctrl > 27){ - slot_id_ctrl = 0; - sf = sf + 0x10; - - if (sf >0x90){ - sf = 0; - } - } - } - - // fill DL Data for ant 1 with 0 value - memset(IQ_ptr, 0, 5088); } // U-PLANE PRACH PROCESSING diff --git a/targets/ARCH/ETHERNET/benetel/5g/low.c b/targets/ARCH/ETHERNET/benetel/5g/low.c index 52c9f24127ce279d67b82cfa3f4fae4b22de852e..b34d69784f119db177c144c4d42542a798eccdd4 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/low.c +++ b/targets/ARCH/ETHERNET/benetel/5g/low.c @@ -35,63 +35,61 @@ printf("store_ul %d.%ld (%ld)\n", (int)(t.tv_sec % 60), t.tv_nsec, t.tv_nsec - o old = t; #endif - /* only antenna 0 for the moment */ - if (ul->antenna != 0) - return; + int a = ul->antenna; - if (ul->slot != bs->next_slot || - ul->symbol != bs->next_symbol) { - printf("%s: error, expected frame.sl.symbol %d.%d.%d, got %d.%d.%d\n", + if (ul->slot != bs->next_slot[a] || + ul->symbol != bs->next_symbol[a]) { + printf("%s: error, antenna %d expected frame.sl.symbol %d.%d.%d, got %d.%d.%d\n", __FUNCTION__, - bs->expected_benetel_frame, bs->next_slot, bs->next_symbol, + a, bs->expected_benetel_frame[a], bs->next_slot[a], bs->next_symbol[a], ul->frame, ul->slot, ul->symbol); } /* fill missing data with 0s */ - while (ul->slot != bs->next_slot || - ul->symbol != bs->next_symbol) { - lock_ul_buffer(bs->buffers, bs->next_slot); - if (bs->buffers->ul_busy[bs->next_slot] & (1 << bs->next_symbol)) { - printf("%s: warning, UL overflow (sl.symbol %d.%d)\n", __FUNCTION__, - bs->next_slot, bs->next_symbol); + while (ul->slot != bs->next_slot[a] || + ul->symbol != bs->next_symbol[a]) { + lock_ul_buffer(bs->buffers, bs->next_slot[a]); + if (bs->buffers->ul_busy[a][bs->next_slot[a]] & (1 << bs->next_symbol[a])) { + printf("%s: warning, antenna %d UL overflow (sl.symbol %d.%d)\n", __FUNCTION__, + a, bs->next_slot[a], bs->next_symbol[a]); } - memset(bs->buffers->ul[bs->next_slot] + bs->next_symbol * 1272*4, + memset(bs->buffers->ul[a][bs->next_slot[a]] + bs->next_symbol[a] * 1272*4, 0, 1272*4); - bs->buffers->ul_busy[bs->next_slot] |= (1 << bs->next_symbol); - signal_ul_buffer(bs->buffers, bs->next_slot); - unlock_ul_buffer(bs->buffers, bs->next_slot); - - bs->next_symbol++; - if (bs->next_symbol == 14) { - bs->next_symbol = 0; - bs->next_slot = (bs->next_slot + 1) % 20; - if (bs->next_slot == 0) { - bs->expected_benetel_frame++; - bs->expected_benetel_frame &= 255; + bs->buffers->ul_busy[a][bs->next_slot[a]] |= (1 << bs->next_symbol[a]); + signal_ul_buffer(bs->buffers, bs->next_slot[a]); + unlock_ul_buffer(bs->buffers, bs->next_slot[a]); + + bs->next_symbol[a]++; + if (bs->next_symbol[a] == 14) { + bs->next_symbol[a] = 0; + bs->next_slot[a] = (bs->next_slot[a] + 1) % 20; + if (bs->next_slot[a] == 0) { + bs->expected_benetel_frame[a]++; + bs->expected_benetel_frame[a] &= 255; } } } - lock_ul_buffer(bs->buffers, bs->next_slot); - if (bs->buffers->ul_busy[bs->next_slot] & (1 << bs->next_symbol)) { - printf("%s: warning, UL overflow (sl.symbol %d.%d)\n", __FUNCTION__, - bs->next_slot, bs->next_symbol); + lock_ul_buffer(bs->buffers, bs->next_slot[a]); + if (bs->buffers->ul_busy[a][bs->next_slot[a]] & (1 << bs->next_symbol[a])) { + printf("%s: warning, antenna %d UL overflow (sl.symbol %d.%d)\n", __FUNCTION__, + a, bs->next_slot[a], bs->next_symbol[a]); } - memcpy(bs->buffers->ul[bs->next_slot] + bs->next_symbol * 1272*4, + memcpy(bs->buffers->ul[a][bs->next_slot[a]] + bs->next_symbol[a] * 1272*4, ul->iq, 1272*4); - bs->buffers->ul_busy[bs->next_slot] |= (1 << bs->next_symbol); - signal_ul_buffer(bs->buffers, bs->next_slot); - unlock_ul_buffer(bs->buffers, bs->next_slot); - - bs->next_symbol++; - if (bs->next_symbol == 14) { - bs->next_symbol = 0; - bs->next_slot = (bs->next_slot + 1) % 20; - if (bs->next_slot == 0) { - bs->expected_benetel_frame++; - bs->expected_benetel_frame &= 255; + bs->buffers->ul_busy[a][bs->next_slot[a]] |= (1 << bs->next_symbol[a]); + signal_ul_buffer(bs->buffers, bs->next_slot[a]); + unlock_ul_buffer(bs->buffers, bs->next_slot[a]); + + bs->next_symbol[a]++; + if (bs->next_symbol[a] == 14) { + bs->next_symbol[a] = 0; + bs->next_slot[a] = (bs->next_slot[a] + 1) % 20; + if (bs->next_slot[a] == 0) { + bs->expected_benetel_frame[a]++; + bs->expected_benetel_frame[a] &= 255; } } } diff --git a/targets/ARCH/ETHERNET/benetel/5g/low.h b/targets/ARCH/ETHERNET/benetel/5g/low.h index 5e1daee9d1ceaf005e957426526a752291ecaeda..659819296af298b3cdc86e99df4d64238e1c4671 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/low.h +++ b/targets/ARCH/ETHERNET/benetel/5g/low.h @@ -26,9 +26,10 @@ typedef struct { shared_buffers *buffers; - int next_slot; - int next_symbol; - int expected_benetel_frame; + /* [2] is for two antennas */ + int next_slot[2]; + int next_symbol[2]; + int expected_benetel_frame[2]; char *dpdk_main_command_line; } benetel_t; diff --git a/targets/ARCH/ETHERNET/benetel/5g/low_dpdk.c b/targets/ARCH/ETHERNET/benetel/5g/low_dpdk.c index 5e26f6782ea737e0b6b18c23b39bc86a01d74839..b26df0772375afebb7cf327f8fd3546348ef4a08 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/low_dpdk.c +++ b/targets/ARCH/ETHERNET/benetel/5g/low_dpdk.c @@ -68,7 +68,8 @@ void *benetel_start_dpdk(char *ifname, shared_buffers *buffers, char *dpdk_main_ bs->buffers = buffers; - bs->expected_benetel_frame = 255; + bs->expected_benetel_frame[0] = 255; + bs->expected_benetel_frame[1] = 255; bs->dpdk_main_command_line = dpdk_main_command_line; diff --git a/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.c b/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.c index b9da10b380687819a643f0593c152e6879ab9e69..a302400eb41c835e3820c5cb2ae6d5a375ef090c 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.c +++ b/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.c @@ -45,11 +45,16 @@ void init_buffers(shared_buffers *s) * needs to have slots 1, 2 and 3, 4 and 5 ready. Let's pretend * they are ready. */ - s->dl_busy[1] = 0x3fff; - s->dl_busy[2] = 0x3fff; - s->dl_busy[3] = 0x3fff; - s->dl_busy[4] = 0x3fff; - s->dl_busy[5] = 0x3fff; + s->dl_busy[0][1] = 0x3fff; + s->dl_busy[0][2] = 0x3fff; + s->dl_busy[0][3] = 0x3fff; + s->dl_busy[0][4] = 0x3fff; + s->dl_busy[0][5] = 0x3fff; + s->dl_busy[1][1] = 0x3fff; + s->dl_busy[1][2] = 0x3fff; + s->dl_busy[1][3] = 0x3fff; + s->dl_busy[1][4] = 0x3fff; + s->dl_busy[1][5] = 0x3fff; } void lock_dl_buffer(shared_buffers *s, int slot) diff --git a/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.h b/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.h index ca7dbd9c8f92aef059813f721462812f8e87efc1..9d51b8138dafb5721462c730256c8db3e0d6095a 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.h +++ b/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.h @@ -26,10 +26,11 @@ #include <stdint.h> typedef struct { - unsigned char dl[20][14*1272*4]; - unsigned char ul[20][14*1272*4]; - uint16_t dl_busy[20]; - uint16_t ul_busy[20]; + /* [2] is for two antennas */ + unsigned char dl[2][20][14*1272*4]; + unsigned char ul[2][20][14*1272*4]; + uint16_t dl_busy[2][20]; + uint16_t ul_busy[2][20]; pthread_mutex_t m_ul[20]; pthread_cond_t c_ul[20]; diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c index 79bf3dd0772f7c5dbdc61505b3cdb33201884cf4..cd35c46a15a40c882e7c393adbe55ea527599792 100644 --- a/targets/ARCH/rfsimulator/simulator.c +++ b/targets/ARCH/rfsimulator/simulator.c @@ -76,15 +76,16 @@ extern RAN_CONTEXT_t RC; /* configuration parameters for the rfsimulator device */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ /*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ -#define RFSIMULATOR_PARAMS_DESC {\ - {"serveraddr", "<ip address to connect to>\n", 0, strptr:&(rfsimulator->ip), defstrval:"127.0.0.1", TYPE_STRING, 0 },\ - {"serverport", "<port to connect to>\n", 0, u16ptr:&(rfsimulator->port), defuintval:PORT, TYPE_UINT16, 0 },\ - {RFSIMU_OPTIONS_PARAMNAME, RFSIM_CONFIG_HELP_OPTIONS, 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST,0 },\ - {"IQfile", "<file path to use when saving IQs>\n", 0, strptr:&(saveF), defstrval:"/tmp/rfsimulator.iqs",TYPE_STRING, 0 },\ - {"modelname", "<channel model name>\n", 0, strptr:&(modelname), defstrval:"AWGN", TYPE_STRING, 0 },\ - {"ploss", "<channel path loss in dB>\n", 0, dblptr:&(rfsimulator->chan_pathloss), defdblval:0, TYPE_DOUBLE, 0 },\ - {"forgetfact", "<channel forget factor ((0 to 1)>\n", 0, dblptr:&(rfsimulator->chan_forgetfact), defdblval:0, TYPE_DOUBLE, 0 },\ - {"offset", "<channel offset in samps>\n", 0, iptr:&(rfsimulator->chan_offset), defintval:0, TYPE_INT, 0 }\ +#define simOpt PARAMFLAG_NOFREE|PARAMFLAG_CMDLINE_NOPREFIXENABLED +#define RFSIMULATOR_PARAMS_DESC { \ + {"serveraddr", "<ip address to connect to>\n", simOpt , strptr:&(rfsimulator->ip), defstrval:"127.0.0.1", TYPE_STRING, 0 },\ + {"serverport", "<port to connect to>\n", simOpt, u16ptr:&(rfsimulator->port), defuintval:PORT, TYPE_UINT16, 0 },\ + {RFSIMU_OPTIONS_PARAMNAME, RFSIM_CONFIG_HELP_OPTIONS, 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST,0 },\ + {"IQfile", "<file path to use when saving IQs>\n",simOpt, strptr:&(saveF), defstrval:"/tmp/rfsimulator.iqs",TYPE_STRING, 0 },\ + {"modelname", "<channel model name>\n", simOpt, strptr:&(modelname), defstrval:"AWGN", TYPE_STRING, 0 },\ + {"ploss", "<channel path loss in dB>\n", simOpt, dblptr:&(rfsimulator->chan_pathloss), defdblval:0, TYPE_DOUBLE, 0 },\ + {"forgetfact", "<channel forget factor ((0 to 1)>\n", simOpt, dblptr:&(rfsimulator->chan_forgetfact), defdblval:0, TYPE_DOUBLE, 0 },\ + {"offset", "<channel offset in samps>\n", simOpt, iptr:&(rfsimulator->chan_offset), defintval:0, TYPE_INT, 0 }\ }; @@ -137,7 +138,7 @@ typedef struct { } rfsimulator_state_t; -void allocCirBuf(rfsimulator_state_t *bridge, int sock) { +static void allocCirBuf(rfsimulator_state_t *bridge, int sock) { buffer_t *ptr=&bridge->buf[sock]; AssertFatal ( (ptr->circularBuf=(sample_t *) malloc(sampleToByte(CirSize,1))) != NULL, ""); ptr->circularBufEnd=((char *)ptr->circularBuf)+sampleToByte(CirSize,1); @@ -195,7 +196,7 @@ void allocCirBuf(rfsimulator_state_t *bridge, int sock) { } } -void removeCirBuf(rfsimulator_state_t *bridge, int sock) { +static void removeCirBuf(rfsimulator_state_t *bridge, int sock) { AssertFatal( epoll_ctl(bridge->epollfd, EPOLL_CTL_DEL, sock, NULL) != -1, ""); close(sock); free(bridge->buf[sock].circularBuf); @@ -206,12 +207,12 @@ void removeCirBuf(rfsimulator_state_t *bridge, int sock) { bridge->buf[sock].conn_sock=-1; } -void socketError(rfsimulator_state_t *bridge, int sock) { +static void socketError(rfsimulator_state_t *bridge, int sock) { if (bridge->buf[sock].conn_sock!=-1) { LOG_W(HW,"Lost socket \n"); removeCirBuf(bridge, sock); - if (bridge->typeStamp==UE_MAGICDL_FDD) + if (bridge->typeStamp==UE_MAGICDL) exit(1); } } @@ -229,7 +230,7 @@ enum blocking_t { blocking }; -void setblocking(int sock, enum blocking_t active) { +static void setblocking(int sock, enum blocking_t active) { int opts; AssertFatal( (opts = fcntl(sock, F_GETFL)) >= 0,""); @@ -243,7 +244,7 @@ void setblocking(int sock, enum blocking_t active) { static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps); -void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t) { +static void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t) { if (t->saveIQfile != -1) { if (write(t->saveIQfile, _buf, count) != count ) LOG_E(HW,"write in save iq file failed (%s)\n",strerror(errno)); @@ -277,7 +278,7 @@ void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t) { } } -void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) { +static void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) { char *saveF=NULL; char *modelname=NULL; paramdef_t rfsimu_params[] = RFSIMULATOR_PARAMS_DESC; @@ -312,9 +313,9 @@ void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) { if ( strncasecmp(rfsimulator->ip,"enb",3) == 0 || strncasecmp(rfsimulator->ip,"server",3) == 0 ) - rfsimulator->typeStamp = ENB_MAGICDL_FDD; + rfsimulator->typeStamp = ENB_MAGICDL; else - rfsimulator->typeStamp = UE_MAGICDL_FDD; + rfsimulator->typeStamp = UE_MAGICDL; } static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt, void *arg) { @@ -358,9 +359,9 @@ static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt, return CMDSTATUS_FOUND; } -int server_start(openair0_device *device) { +static int startServer(openair0_device *device) { rfsimulator_state_t *t = (rfsimulator_state_t *) device->priv; - t->typeStamp=ENB_MAGICDL_FDD; + t->typeStamp=ENB_MAGICDL; AssertFatal((t->listen_sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, ""); int enable = 1; AssertFatal(setsockopt(t->listen_sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) == 0, ""); @@ -381,9 +382,9 @@ sin_addr: return 0; } -int start_ue(openair0_device *device) { +static int startClient(openair0_device *device) { rfsimulator_state_t *t = device->priv; - t->typeStamp=UE_MAGICDL_FDD; + t->typeStamp=UE_MAGICDL; int sock; AssertFatal((sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, ""); struct sockaddr_in addr = { @@ -458,7 +459,7 @@ static int rfsimulator_write_internal(rfsimulator_state_t *t, openair0_timestamp return nsamps; } -int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, void **samplesVoid, int nsamps, int nbAnt, int flags) { +static int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, void **samplesVoid, int nsamps, int nbAnt, int flags) { return rfsimulator_write_internal(device->priv, timestamp, samplesVoid, nsamps, nbAnt, flags, false); } @@ -483,7 +484,7 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi AssertFatal( (conn_sock = accept(t->listen_sock,NULL,NULL)) != -1, ""); setblocking(conn_sock, notBlocking); allocCirBuf(t, conn_sock); - LOG_I(HW,"A ue connected, sending the current time\n"); + LOG_I(HW,"A client connected, sending the current time\n"); struct complex16 v= {0}; void *samplesVoid[t->tx_num_channels]; @@ -534,8 +535,8 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi // check the header and start block transfer if ( b->headerMode==true && b->remainToTransfer==0) { - AssertFatal( (t->typeStamp == UE_MAGICDL_FDD && b->th.magic==ENB_MAGICDL_FDD) || - (t->typeStamp == ENB_MAGICDL_FDD && b->th.magic==UE_MAGICDL_FDD), "Socket Error in protocol"); + AssertFatal( (t->typeStamp == UE_MAGICDL && b->th.magic==ENB_MAGICDL) || + (t->typeStamp == ENB_MAGICDL && b->th.magic==UE_MAGICDL), "Socket Error in protocol"); b->headerMode=false; if ( t->nextTimestamp == 0 ) { // First block in UE, resync with the eNB current TS @@ -606,7 +607,7 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi return nfds>0; } -int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, void **samplesVoid, int nsamps, int nbAnt) { +static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, void **samplesVoid, int nsamps, int nbAnt) { if (nbAnt != 1) { LOG_W(HW, "rfsimulator: only 1 antenna tested\n"); } @@ -748,31 +749,24 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo signal_energy(samplesVoid[0], nsamps)); return nsamps; } -int rfsimulator_request(openair0_device *device, void *msg, ssize_t msg_len) { - abort(); - return 0; -} -int rfsimulator_reply(openair0_device *device, void *msg, ssize_t msg_len) { - abort(); - return 0; -} -int rfsimulator_get_stats(openair0_device *device) { + +static int rfsimulator_get_stats(openair0_device *device) { return 0; } -int rfsimulator_reset_stats(openair0_device *device) { +static int rfsimulator_reset_stats(openair0_device *device) { return 0; } -void rfsimulator_end(openair0_device *device) {} -int rfsimulator_stop(openair0_device *device) { +static void rfsimulator_end(openair0_device *device) {} +static int rfsimulator_stop(openair0_device *device) { return 0; } -int rfsimulator_set_freq(openair0_device *device, openair0_config_t *openair0_cfg,int exmimo_dump_config) { +static int rfsimulator_set_freq(openair0_device *device, openair0_config_t *openair0_cfg,int exmimo_dump_config) { return 0; } -int rfsimulator_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) { +static int rfsimulator_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) { return 0; } -int rfsimulator_write_init(openair0_device *device) { +static int rfsimulator_write_init(openair0_device *device) { return 0; } __attribute__((__visibility__("default"))) @@ -782,10 +776,10 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { rfsimulator_state_t *rfsimulator = (rfsimulator_state_t *)calloc(sizeof(rfsimulator_state_t),1); rfsimulator_readconfig(rfsimulator); pthread_mutex_init(&Sockmutex, NULL); - LOG_I(HW,"rfsimulator: running as %s\n", rfsimulator-> typeStamp == ENB_MAGICDL_FDD ? "(eg)NB" : "UE"); - device->trx_start_func = rfsimulator->typeStamp == ENB_MAGICDL_FDD ? - server_start : - start_ue; + LOG_I(HW,"rfsimulator: running as %s\n", rfsimulator-> typeStamp == ENB_MAGICDL ? "server waiting opposite rfsimulators to connect" : "client: will connect to a rfsimulator server side"); + device->trx_start_func = rfsimulator->typeStamp == ENB_MAGICDL ? + startServer : + startClient; device->trx_get_stats_func = rfsimulator_get_stats; device->trx_reset_stats_func = rfsimulator_reset_stats; device->trx_end_func = rfsimulator_end; @@ -795,7 +789,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { device->trx_write_func = rfsimulator_write; device->trx_read_func = rfsimulator_read; /* let's pretend to be a b2x0 */ - device->type = USRP_B200_DEV; + device->type = RFSIMULATOR; device->openair0_cfg=&openair0_cfg[0]; device->priv = rfsimulator; device->trx_write_init = rfsimulator_write_init; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-4g.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-4g.conf index 49b4e4441e298b5cb2283a5e5bccbff249630921..aab3876d96355f60c890815876e06132544b4809 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-4g.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-4g.conf @@ -230,12 +230,12 @@ RUs = ( local_if_name = "dpdk"; sdr_addrs = "softmodem -m 2048 -l 35 -n 2 -b 0000:81:00.3 --proc-type auto --file-prefix ggg -- -p 0x1"; #sdr_addrs = "softmodem -l 8 -n 2 -- -p 0x2"; - remote_address = "127.0.0.2"; - local_address = "127.0.0.1"; - local_portc = 50000; - remote_portc = 50000; - local_portd = 50001; - remote_portd = 50001; + #remote_address = "127.0.0.2"; + #local_address = "127.0.0.1"; + #local_portc = 50000; + #remote_portc = 50000; + #local_portd = 50001; + #remote_portd = 50001; local_rf = "no" tr_preference = "raw_if4p5" nb_tx = 1 diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf index 037de199dfdc18af5e7f1df666d8d46f6e9e3e93..504d5e7b349d48fb9c047cbcd196d4da020158ee 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf @@ -23,6 +23,8 @@ gNBs = ssb_SubcarrierOffset = 31; //0; pdsch_AntennaPorts = 1; + #pusch_TargetSNRx10 = 200; + #pucch_TargetSNRx10 = 200; pusch_TargetSNRx10 = 200; pucch_TargetSNRx10 = 200; @@ -102,8 +104,9 @@ gNBs = prach_msg1_FDM = 0; prach_msg1_FrequencyStart = 74; zeroCorrelationZoneConfig = 13; - #preambleReceivedTargetPower = -118; - preambleReceivedTargetPower = -104; + preambleReceivedTargetPower = -118; + #preambleReceivedTargetPower = -104; + #preambleReceivedTargetPower = -108; #preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) preambleTransMax = 6; #powerRampingStep @@ -149,14 +152,16 @@ gNBs = initialULBWPstartSymbolAndLength_2 = 52; msg3_DeltaPreamble = 1; - p0_NominalWithGrant =-90; + #p0_NominalWithGrant =-90; + p0_NominalWithGrant =-118; # pucch-ConfigCommon setup : # pucchGroupHopping # 0 = neither, 1= group hopping, 2=sequence hopping pucchGroupHopping = 0; hoppingId = 40; - p0_nominal = -90; + #p0_nominal = -90; + p0_nominal = -118; # ssb_PositionsInBurs_BitmapPR # 1=short, 2=medium, 3=long ssb_PositionsInBurst_PR = 2; @@ -189,7 +194,7 @@ gNBs = nrofUplinkSymbols = 4; //0; //4; #ssPBCH_BlockPower = 10; - ssPBCH_BlockPower = 10; + ssPBCH_BlockPower = -35; } ); @@ -229,9 +234,9 @@ gNBs = { GNB_INTERFACE_NAME_FOR_S1_MME = "eth0"; - GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.18.195/24"; + GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.18.187/24"; GNB_INTERFACE_NAME_FOR_S1U = "eth0"; - GNB_IPV4_ADDRESS_FOR_S1U = "192.168.18.195/24"; + GNB_IPV4_ADDRESS_FOR_S1U = "192.168.18.187/24"; GNB_PORT_FOR_S1U = 2152; # Spec 2152 GNB_IPV4_ADDRESS_FOR_X2C = "127.0.0.2/24"; GNB_PORT_FOR_X2C = 36422; # Spec 36422 @@ -251,6 +256,7 @@ L1s = ( { num_cc = 1; tr_n_preference = "local_mac"; + pusch_proc_threads = 8; } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf index 0659641607ec43618b5a3d992b7fb37942ff0714..40361aaf4e8ffa042fec8f82965afe156c668bbc 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf @@ -33,7 +33,7 @@ gNBs = # downlinkConfigCommon #frequencyInfoDL # this is 3600 MHz + 84 PRBs@30kHz SCS (same as initial BWP) - absoluteFrequencySSB = 642364; + absoluteFrequencySSB = 642016;#642364; dl_frequencyBand = 78; # this is 3600 MHz dl_absoluteFrequencyPointA = 640000; @@ -130,16 +130,21 @@ gNBs = # 0=unrestricted, 1=restricted type A, 2=restricted type B restrictedSetConfig = 0, # pusch-ConfigCommon (up to 16 elements) - initialULBWPk2_0 = 2; + initialULBWPk2_0 = 6; #2; initialULBWPmappingType_0 = 1 # this is SS=0 L=11 initialULBWPstartSymbolAndLength_0 = 55; - initialULBWPk2_1 = 2; + initialULBWPk2_1 = 6; #2; initialULBWPmappingType_1 = 1; # this is SS=0 L=12 initialULBWPstartSymbolAndLength_1 = 69; + initialULBWPk2_2 = 7; + initialULBWPmappingType_2 = 1; + # this is SS=10 L=4 + initialULBWPstartSymbolAndLength_2 = 52; + msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf index 0a6268f8a85b856ac572f95db8c7874363130389..a899845cb8913e82a529bed2b0809215be7c3f6e 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf @@ -130,16 +130,21 @@ gNBs = # 0=unrestricted, 1=restricted type A, 2=restricted type B restrictedSetConfig = 0, # pusch-ConfigCommon (up to 16 elements) - initialULBWPk2_0 = 2; + initialULBWPk2_0 = 6;#2; initialULBWPmappingType_0 = 1 # this is SS=0 L=11 initialULBWPstartSymbolAndLength_0 = 55; - initialULBWPk2_1 = 2; + initialULBWPk2_1 = 6;#2; initialULBWPmappingType_1 = 1; # this is SS=0 L=12 initialULBWPstartSymbolAndLength_1 = 69; + initialULBWPk2_2 = 7; + initialULBWPmappingType_2 = 1; + # this is SS=10 L=4 + initialULBWPstartSymbolAndLength_2 = 52; + msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf index 555af5835d368647559077be618610c792dfe52a..c46ea98ec24cb204ca326f25d25b9fb1815a39d8 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf @@ -278,6 +278,18 @@ THREAD_STRUCT = ( } ); +security = { + # preferred ciphering algorithms + # the first one of the list that an UE supports in chosen + # valid values: nea0, nea1, nea2, nea3 + ciphering_algorithms = ( "nea0", "nea2" ); + + # preferred integrity algorithms + # the first one of the list that an UE supports in chosen + # valid values: nia0, nia1, nia2, nia3 + integrity_algorithms = ( "nia0" ); +}; + log_config : { global_log_level ="info"; diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 56c2cb23dd43114975300a5c41b160c38c6a8551..368fd78f9e8c01230ef5f957efb2398e64c03b32 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -2986,6 +2986,7 @@ void RCconfig_RU(void) { RC.ru[j]->if_south = LOCAL_RF; RC.ru[j]->function = NGFI_RRU_IF4p5; RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE; + RC.ru[j]->has_ctrl_prt =1; LOG_I(PHY,"Setting function for RU %d to NGFI_RRU_IF4p5 (raw)\n",j); } @@ -3039,6 +3040,7 @@ else { RC.ru[j]->if_south = REMOTE_IF4p5; RC.ru[j]->function = NGFI_RAU_IF4p5; RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE; + RC.ru[j]->has_ctrl_prt = 1; if (strcmp(*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr), "yes") == 0) RC.ru[j]->is_slave=1; else RC.ru[j]->is_slave=0;