diff --git a/README.md b/README.md index 04cb4e8db06f343f0466c64536707e71dcba3a1d..b5d3dc46c0fd67afb53d36d36f8cfb72f876b328 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ Please see [NOTICE](NOTICE.md) file for third party software that is included in * [General overview of documentation](./doc/README.md) * [The implemented features](./doc/FEATURE_SET.md) + * [System Requirements for Using OAI Stack](./doc/system_requirements.md) * [How to build](./doc/BUILD.md) * [How to run the modems](./doc/RUNMODEM.md) diff --git a/ci-scripts/conf_files/gnb-du.sa.band78.106prb.usrpb200.conf b/ci-scripts/conf_files/gnb-du.sa.band78.106prb.usrpb200.conf index 3bcdcf156d15d3622b7401fc20ff0755139e6493..e977edd5f3dcfd1a20228d766758aa4de895d66c 100644 --- a/ci-scripts/conf_files/gnb-du.sa.band78.106prb.usrpb200.conf +++ b/ci-scripts/conf_files/gnb-du.sa.band78.106prb.usrpb200.conf @@ -22,8 +22,9 @@ gNBs = ////////// Physical parameters: - min_rxtxtime = 6; - + min_rxtxtime = 2; + do_CSIRS = 1; + do_SRS = 1; servingCellConfigCommon = ( { @@ -183,7 +184,7 @@ L1s = ( num_cc = 1; tr_n_preference = "local_mac"; prach_dtx_threshold = 200; - pucch0_dtx_threshold = 100; + pucch0_dtx_threshold = 30; ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 } ); @@ -193,8 +194,8 @@ RUs = ( local_rf = "yes" nb_tx = 1 nb_rx = 1 - att_tx = 0 - att_rx = 0; + att_tx = 10; + att_rx = 10; bands = [78]; max_pdschReferenceSignalPower = -27; max_rxgain = 114; diff --git a/ci-scripts/conf_files/gnb.sa.band78.106prb.usrpb200.sc-fdma.conf b/ci-scripts/conf_files/gnb.sa.band78.106prb.usrpb200.sc-fdma.conf index 725e02d615ceaebdc7ee79774b9ac625923b3519..dc5c30fe502fc71a986459afd91a16e84aff7728 100644 --- a/ci-scripts/conf_files/gnb.sa.band78.106prb.usrpb200.sc-fdma.conf +++ b/ci-scripts/conf_files/gnb.sa.band78.106prb.usrpb200.sc-fdma.conf @@ -184,7 +184,7 @@ L1s = ( num_cc = 1; tr_n_preference = "local_mac"; prach_dtx_threshold = 120; - pucch0_dtx_threshold = 100; + pucch0_dtx_threshold = 30; ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 } ); @@ -194,8 +194,8 @@ RUs = ( local_rf = "yes" nb_tx = 1 nb_rx = 1 - att_tx = 14; - att_rx = 14; + att_tx = 10; + att_rx = 10; bands = [78]; max_pdschReferenceSignalPower = -27; max_rxgain = 114; diff --git a/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz.xml b/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz.xml index a60a8e2d4dba57a64063e90b24bcf3944109da8d..3b0b58d8ba8d9379b331c6c80f3634e2640d012e 100644 --- a/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz.xml +++ b/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz.xml @@ -108,14 +108,14 @@ <class>Attach_UE</class> <desc>Attach OAI UE (Wait for IP)</desc> <id>rfsim4g_ue</id> - <nodes>obelix</nodes> + <nodes>cacofonix</nodes> </testCase> <testCase id="020011"> <class>Ping</class> <desc>Ping Traffic-Gen from LTE-UE</desc> <id>rfsim4g_ue</id> - <nodes>obelix</nodes> + <nodes>cacofonix</nodes> <ping_args> -c 20 192.168.61.11</ping_args> <ping_packetloss_threshold>5</ping_packetloss_threshold> </testCase> @@ -125,7 +125,7 @@ <desc>Ping LTE-UE from Traffic-Gen</desc> <id>rfsim4g_ext_dn</id> <ping_args>-c 20 12.0.0.2</ping_args> - <nodes>obelix</nodes> + <nodes>cacofonix</nodes> <ping_packetloss_threshold>5</ping_packetloss_threshold> </testCase> @@ -137,8 +137,8 @@ <iperf_args>-u -t 30 -b 2M -R</iperf_args> <iperf_packetloss_threshold>25</iperf_packetloss_threshold> <iperf_bitrate_threshold>80</iperf_bitrate_threshold> - <nodes>obelix</nodes> - <svr_node>obelix</svr_node> + <nodes>cacofonix</nodes> + <svr_node>cacofonix</svr_node> </testCase> <testCase id="030011"> @@ -149,8 +149,8 @@ <iperf_args>-u -t 30 -b 1M</iperf_args> <iperf_packetloss_threshold>25</iperf_packetloss_threshold> <iperf_bitrate_threshold>80</iperf_bitrate_threshold> - <nodes>obelix</nodes> - <svr_node>obelix</svr_node> + <nodes>cacofonix</nodes> + <svr_node>cacofonix</svr_node> </testCase> <testCase id="100011"> diff --git a/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz_noS1.xml b/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz_noS1.xml index d5c67c9835bd82f8f45356ad3aff3beafb105f19..abe07fa1cef21e2a791bd5b384ef544b10dda72b 100644 --- a/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz_noS1.xml +++ b/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz_noS1.xml @@ -86,7 +86,7 @@ <class>Ping</class> <desc>Ping Traffic-Gen from LTE-UE</desc> <id>rfsim4g_ue</id> - <nodes>obelix</nodes> + <nodes>cacofonix</nodes> <ping_args> -c 20 10.0.1.1</ping_args> <ping_packetloss_threshold>5</ping_packetloss_threshold> </testCase> @@ -95,7 +95,7 @@ <class>Ping</class> <desc>Ping LTE-UE from eNB</desc> <id>rfsim4g_enb_nos1</id> - <nodes>obelix</nodes> + <nodes>cacofonix</nodes> <ping_args> -c 20 10.0.1.2</ping_args> <ping_packetloss_threshold>5</ping_packetloss_threshold> </testCase> @@ -104,9 +104,9 @@ <class>Iperf</class> <desc>Iperf UDP DL</desc> <id>rfsim4g_ue</id> - <nodes>obelix</nodes> + <nodes>cacofonix</nodes> <svr_id>rfsim4g_enb_nos1</svr_id> - <svr_node>obelix</svr_node> + <svr_node>cacofonix</svr_node> <iperf_args>-u -t 30 -b 2M -R</iperf_args> <iperf_packetloss_threshold>25</iperf_packetloss_threshold> <iperf_bitrate_threshold>80</iperf_bitrate_threshold> @@ -116,9 +116,9 @@ <class>Iperf</class> <desc>Iperf UDP UL</desc> <id>rfsim4g_ue</id> - <nodes>obelix</nodes> + <nodes>cacofonix</nodes> <svr_id>rfsim4g_enb_nos1</svr_id> - <svr_node>obelix</svr_node> + <svr_node>cacofonix</svr_node> <iperf_args>-u -t 30 -b 1M</iperf_args> <iperf_packetloss_threshold>25</iperf_packetloss_threshold> <iperf_bitrate_threshold>80</iperf_bitrate_threshold> diff --git a/ci-scripts/xml_files/container_4g_rfsim_fdd_10MHz.xml b/ci-scripts/xml_files/container_4g_rfsim_fdd_10MHz.xml index 50e53c8624eeeff84ad22abd889a0d5f02762689..68879cc622ed9f5f576ab6261847d2a4c49616a9 100644 --- a/ci-scripts/xml_files/container_4g_rfsim_fdd_10MHz.xml +++ b/ci-scripts/xml_files/container_4g_rfsim_fdd_10MHz.xml @@ -108,14 +108,14 @@ <class>Attach_UE</class> <desc>Attach OAI UE (Wait for IP)</desc> <id>rfsim4g_ue</id> - <nodes>obelix</nodes> + <nodes>cacofonix</nodes> </testCase> <testCase id="020011"> <class>Ping</class> <desc>Ping Traffic-Gen from LTE-UE</desc> <id>rfsim4g_ue</id> - <nodes>obelix</nodes> + <nodes>cacofonix</nodes> <ping_args> -c 20 192.168.61.11</ping_args> <ping_packetloss_threshold>5</ping_packetloss_threshold> </testCase> @@ -124,7 +124,7 @@ <class>Ping</class> <desc>Ping LTE-UE from Traffic-Gen</desc> <id>rfsim4g_ext_dn</id> - <nodes>obelix</nodes> + <nodes>cacofonix</nodes> <ping_args>-c 20 12.0.0.2</ping_args> <ping_packetloss_threshold>5</ping_packetloss_threshold> </testCase> @@ -133,9 +133,9 @@ <class>Iperf</class> <desc>Iperf UDP DL</desc> <id>rfsim4g_ue</id> - <nodes>obelix</nodes> + <nodes>cacofonix</nodes> <svr_id>rfsim4g_ext_dn</svr_id> - <svr_node>obelix</svr_node> + <svr_node>cacofonix</svr_node> <iperf_args>-u -t 30 -b 2M -R</iperf_args> <iperf_packetloss_threshold>25</iperf_packetloss_threshold> <iperf_bitrate_threshold>80</iperf_bitrate_threshold> @@ -145,9 +145,9 @@ <class>Iperf</class> <desc>Iperf UDP UL</desc> <id>rfsim4g_ue</id> - <nodes>obelix</nodes> + <nodes>cacofonix</nodes> <svr_id>rfsim4g_ext_dn</svr_id> - <svr_node>obelix</svr_node> + <svr_node>cacofonix</svr_node> <iperf_args>-u -t 30 -b 1M</iperf_args> <iperf_packetloss_threshold>25</iperf_packetloss_threshold> <iperf_bitrate_threshold>80</iperf_bitrate_threshold> diff --git a/ci-scripts/xml_files/container_4g_rfsim_fdd_20MHz.xml b/ci-scripts/xml_files/container_4g_rfsim_fdd_20MHz.xml index 12bf5533ba690c5e0ba7a8c8dcb7c29495693cf6..5a58cad5f20a6c7da53a35344a3b94962d240575 100644 --- a/ci-scripts/xml_files/container_4g_rfsim_fdd_20MHz.xml +++ b/ci-scripts/xml_files/container_4g_rfsim_fdd_20MHz.xml @@ -108,14 +108,14 @@ <class>Attach_UE</class> <desc>Attach OAI UE (Wait for IP)</desc> <id>rfsim4g_ue</id> - <nodes>obelix</nodes> + <nodes>cacofonix</nodes> </testCase> <testCase id="020011"> <class>Ping</class> <desc>Ping Traffic-Gen from LTE-UE</desc> <id>rfsim4g_ue</id> - <nodes>obelix</nodes> + <nodes>cacofonix</nodes> <ping_args> -c 20 192.168.61.11</ping_args> <ping_packetloss_threshold>5</ping_packetloss_threshold> </testCase> @@ -124,7 +124,7 @@ <class>Ping</class> <desc>Ping LTE-UE from Traffic-Gen</desc> <id>rfsim4g_ext_dn</id> - <nodes>obelix</nodes> + <nodes>cacofonix</nodes> <ping_args>-c 20 12.0.0.2</ping_args> <ping_packetloss_threshold>5</ping_packetloss_threshold> </testCase> @@ -133,9 +133,9 @@ <class>Iperf</class> <desc>Iperf UDP DL</desc> <id>rfsim4g_ue</id> - <nodes>obelix</nodes> + <nodes>cacofonix</nodes> <svr_id>rfsim4g_ext_dn</svr_id> - <svr_node>obelix</svr_node> + <svr_node>cacofonix</svr_node> <iperf_args>-u -t 30 -b 2M -R</iperf_args> <iperf_packetloss_threshold>25</iperf_packetloss_threshold> <iperf_bitrate_threshold>80</iperf_bitrate_threshold> @@ -145,9 +145,9 @@ <class>Iperf</class> <desc>Iperf UDP UL</desc> <id>rfsim4g_ue</id> - <nodes>obelix</nodes> + <nodes>cacofonix</nodes> <svr_id>rfsim4g_ext_dn</svr_id> - <svr_node>obelix</svr_node> + <svr_node>cacofonix</svr_node> <iperf_args>-u -t 30 -b 1M</iperf_args> <iperf_packetloss_threshold>25</iperf_packetloss_threshold> <iperf_bitrate_threshold>80</iperf_bitrate_threshold> diff --git a/ci-scripts/xml_files/container_4g_rfsim_fembms.xml b/ci-scripts/xml_files/container_4g_rfsim_fembms.xml index 48f740b873d204377327ac3aaba6ff49e28af00f..e63c4fac5e85b6c0ea11a69a045ac0a98c2d15fe 100644 --- a/ci-scripts/xml_files/container_4g_rfsim_fembms.xml +++ b/ci-scripts/xml_files/container_4g_rfsim_fembms.xml @@ -83,9 +83,9 @@ <class>Iperf2_Unidir</class> <desc>Iperf2 UDP DL</desc> <id>rfsim4g_ue_fembms</id> - <nodes>obelix</nodes> + <nodes>cacofonix</nodes> <svr_id>rfsim4g_enb_fembms</svr_id> - <svr_node>obelix</svr_node> + <svr_node>cacofonix</svr_node> <iperf_args>-u -t 30 -b 2M</iperf_args> <iperf_packetloss_threshold>25</iperf_packetloss_threshold> <iperf_bitrate_threshold>80</iperf_bitrate_threshold> diff --git a/ci-scripts/xml_files/container_4g_rfsim_mbms.xml b/ci-scripts/xml_files/container_4g_rfsim_mbms.xml index 4abf69fb3e5905aa75e411292d7d4173a8ad2f57..c26cb06878d43ff4f55c2207fde8315e48d01d05 100644 --- a/ci-scripts/xml_files/container_4g_rfsim_mbms.xml +++ b/ci-scripts/xml_files/container_4g_rfsim_mbms.xml @@ -83,9 +83,9 @@ <class>Iperf</class> <desc>Iperf UDP DL</desc> <id>rfsim4g_ue</id> - <nodes>obelix</nodes> + <nodes>cacofonix</nodes> <svr_id>rfsim4g_enb_nos1</svr_id> - <svr_node>obelix</svr_node> + <svr_node>cacofonix</svr_node> <iperf_args>-u -t 30 -b 2M -R</iperf_args> <iperf_packetloss_threshold>25</iperf_packetloss_threshold> <iperf_bitrate_threshold>80</iperf_bitrate_threshold> diff --git a/ci-scripts/xml_files/container_4g_rfsim_tdd_05MHz.xml b/ci-scripts/xml_files/container_4g_rfsim_tdd_05MHz.xml index fa3c6862b71d9a0086561bde86e3e2a64a37782a..77d9f19ee9865c793a2cdc1ad69272b20a0108d4 100644 --- a/ci-scripts/xml_files/container_4g_rfsim_tdd_05MHz.xml +++ b/ci-scripts/xml_files/container_4g_rfsim_tdd_05MHz.xml @@ -108,7 +108,7 @@ <class>Ping</class> <desc>Ping Traffic-Gen from LTE-UE</desc> <id>rfsim4g_ue</id> - <nodes>obelix</nodes> + <nodes>cacofonix</nodes> <ping_args> -c 20 192.168.61.11</ping_args> <ping_packetloss_threshold>5</ping_packetloss_threshold> </testCase> @@ -117,7 +117,7 @@ <class>Ping</class> <desc>Ping LTE-UE from Traffic-Gen</desc> <id>rfsim4g_ext_dn</id> - <nodes>obelix</nodes> + <nodes>cacofonix</nodes> <ping_args>-c 20 12.0.0.2</ping_args> <ping_packetloss_threshold>5</ping_packetloss_threshold> </testCase> @@ -126,9 +126,9 @@ <class>Iperf</class> <desc>Iperf UDP DL</desc> <id>rfsim4g_ue</id> - <nodes>obelix</nodes> + <nodes>cacofonix</nodes> <svr_id>rfsim4g_ext_dn</svr_id> - <svr_node>obelix</svr_node> + <svr_node>cacofonix</svr_node> <iperf_args>-u -t 30 -b 2M -R</iperf_args> <iperf_packetloss_threshold>25</iperf_packetloss_threshold> <iperf_bitrate_threshold>80</iperf_bitrate_threshold> @@ -138,9 +138,9 @@ <class>Iperf</class> <desc>Iperf UDP UL</desc> <id>rfsim4g_ue</id> - <nodes>obelix</nodes> + <nodes>cacofonix</nodes> <svr_id>rfsim4g_ext_dn</svr_id> - <svr_node>obelix</svr_node> + <svr_node>cacofonix</svr_node> <iperf_args>-u -t 30 -b 1M</iperf_args> <iperf_packetloss_threshold>25</iperf_packetloss_threshold> <iperf_bitrate_threshold>80</iperf_bitrate_threshold> diff --git a/ci-scripts/xml_files/container_sa_aw2s_asue.xml b/ci-scripts/xml_files/container_sa_aw2s_asue.xml index 0e4e967c52ff84222d6d92b76f4093c76960cf5a..71789cca52e5409e78558c71c563c65eceef9ca0 100644 --- a/ci-scripts/xml_files/container_sa_aw2s_asue.xml +++ b/ci-scripts/xml_files/container_sa_aw2s_asue.xml @@ -222,7 +222,7 @@ <desc>Ping: 20pings in 20sec, multi-ue</desc> <id>amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15</id> <ping_args>-c 20 %cn_ip%</ping_args> - <ping_packetloss_threshold>1</ping_packetloss_threshold> + <ping_packetloss_threshold>5</ping_packetloss_threshold> <ping_rttavg_threshold>25</ping_rttavg_threshold> </testCase> diff --git a/ci-scripts/yaml_files/sa_e1_b200_gnb/docker-compose.yml b/ci-scripts/yaml_files/sa_e1_b200_gnb/docker-compose.yml index 83b8360b8fab601205878a8f74d9a4c1f214550f..e1893765d10b1988568f78def137c86d5d50392f 100644 --- a/ci-scripts/yaml_files/sa_e1_b200_gnb/docker-compose.yml +++ b/ci-scripts/yaml_files/sa_e1_b200_gnb/docker-compose.yml @@ -67,8 +67,6 @@ services: --RUs.[0].sdr_addrs serial=30C51D4 --continuous-tx -E --telnetsrv --telnetsrv.listenport 9091 --telnetsrv.shrmod ci - --gNBs.[0].min_rxtxtime 2 --gNBs.[0].do_CSIRS 1 --gNBs.[0].do_SRS 1 - --RUs.[0].att_rx 14 --RUs.[0].att_tx 14 --log_config.global_log_options level,nocolor,time,line_num,function devices: - /dev/bus/usb/:/dev/bus/usb/ diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c index fafc1bcd4739ae4375aa09075e389fb94bd4023a..09dd5e7d94ffa725657105992e4721b2a5f1d4b8 100644 --- a/common/utils/nr/nr_common.c +++ b/common/utils/nr/nr_common.c @@ -36,6 +36,79 @@ #include "nr_common.h" #include <complex.h> +#define C_SRS_NUMBER (64) +#define B_SRS_NUMBER (4) + +/* TS 38.211 Table 6.4.1.4.3-1: SRS bandwidth configuration */ +static const unsigned short srs_bandwidth_config[C_SRS_NUMBER][B_SRS_NUMBER][2] = { + /* B_SRS = 0 B_SRS = 1 B_SRS = 2 B_SRS = 3 */ + /* C SRS m_srs0 N_0 m_srs1 N_1 m_srs2 N_2 m_srs3 N_3 */ + /* 0 */ {{4, 1}, {4, 1}, {4, 1}, {4, 1}}, + /* 1 */ {{8, 1}, {4, 2}, {4, 1}, {4, 1}}, + /* 2 */ {{12, 1}, {4, 3}, {4, 1}, {4, 1}}, + /* 3 */ {{16, 1}, {4, 4}, {4, 1}, {4, 1}}, + /* 4 */ {{16, 1}, {8, 2}, {4, 2}, {4, 1}}, + /* 5 */ {{20, 1}, {4, 5}, {4, 1}, {4, 1}}, + /* 6 */ {{24, 1}, {4, 6}, {4, 1}, {4, 1}}, + /* 7 */ {{24, 1}, {12, 2}, {4, 3}, {4, 1}}, + /* 8 */ {{28, 1}, {4, 7}, {4, 1}, {4, 1}}, + /* 9 */ {{32, 1}, {16, 2}, {8, 2}, {4, 2}}, + /* 10 */ {{36, 1}, {12, 3}, {4, 3}, {4, 1}}, + /* 11 */ {{40, 1}, {20, 2}, {4, 5}, {4, 1}}, + /* 12 */ {{48, 1}, {16, 3}, {8, 2}, {4, 2}}, + /* 13 */ {{48, 1}, {24, 2}, {12, 2}, {4, 3}}, + /* 14 */ {{52, 1}, {4, 13}, {4, 1}, {4, 1}}, + /* 15 */ {{56, 1}, {28, 2}, {4, 7}, {4, 1}}, + /* 16 */ {{60, 1}, {20, 3}, {4, 5}, {4, 1}}, + /* 17 */ {{64, 1}, {32, 2}, {16, 2}, {4, 4}}, + /* 18 */ {{72, 1}, {24, 3}, {12, 2}, {4, 3}}, + /* 19 */ {{72, 1}, {36, 2}, {12, 3}, {4, 3}}, + /* 20 */ {{76, 1}, {4, 19}, {4, 1}, {4, 1}}, + /* 21 */ {{80, 1}, {40, 2}, {20, 2}, {4, 5}}, + /* 22 */ {{88, 1}, {44, 2}, {4, 11}, {4, 1}}, + /* 23 */ {{96, 1}, {32, 3}, {16, 2}, {4, 4}}, + /* 24 */ {{96, 1}, {48, 2}, {24, 2}, {4, 6}}, + /* 25 */ {{104, 1}, {52, 2}, {4, 13}, {4, 1}}, + /* 26 */ {{112, 1}, {56, 2}, {28, 2}, {4, 7}}, + /* 27 */ {{120, 1}, {60, 2}, {20, 3}, {4, 5}}, + /* 28 */ {{120, 1}, {40, 3}, {8, 5}, {4, 2}}, + /* 29 */ {{120, 1}, {24, 5}, {12, 2}, {4, 3}}, + /* 30 */ {{128, 1}, {64, 2}, {32, 2}, {4, 8}}, + /* 31 */ {{128, 1}, {64, 2}, {16, 4}, {4, 4}}, + /* 32 */ {{128, 1}, {16, 8}, {8, 2}, {4, 2}}, + /* 33 */ {{132, 1}, {44, 3}, {4, 11}, {4, 1}}, + /* 34 */ {{136, 1}, {68, 2}, {4, 17}, {4, 1}}, + /* 35 */ {{144, 1}, {72, 2}, {36, 2}, {4, 9}}, + /* 36 */ {{144, 1}, {48, 3}, {24, 2}, {12, 2}}, + /* 37 */ {{144, 1}, {48, 3}, {16, 3}, {4, 4}}, + /* 38 */ {{144, 1}, {16, 9}, {8, 2}, {4, 2}}, + /* 39 */ {{152, 1}, {76, 2}, {4, 19}, {4, 1}}, + /* 40 */ {{160, 1}, {80, 2}, {40, 2}, {4, 10}}, + /* 41 */ {{160, 1}, {80, 2}, {20, 4}, {4, 5}}, + /* 42 */ {{160, 1}, {32, 5}, {16, 2}, {4, 4}}, + /* 43 */ {{168, 1}, {84, 2}, {28, 3}, {4, 7}}, + /* 44 */ {{176, 1}, {88, 2}, {44, 2}, {4, 11}}, + /* 45 */ {{184, 1}, {92, 2}, {4, 23}, {4, 1}}, + /* 46 */ {{192, 1}, {96, 2}, {48, 2}, {4, 12}}, + /* 47 */ {{192, 1}, {96, 2}, {24, 4}, {4, 6}}, + /* 48 */ {{192, 1}, {64, 3}, {16, 4}, {4, 4}}, + /* 49 */ {{192, 1}, {24, 8}, {8, 3}, {4, 2}}, + /* 50 */ {{208, 1}, {104, 2}, {52, 2}, {4, 13}}, + /* 51 */ {{216, 1}, {108, 2}, {36, 3}, {4, 9}}, + /* 52 */ {{224, 1}, {112, 2}, {56, 2}, {4, 14}}, + /* 53 */ {{240, 1}, {120, 2}, {60, 2}, {4, 15}}, + /* 54 */ {{240, 1}, {80, 3}, {20, 4}, {4, 5}}, + /* 55 */ {{240, 1}, {48, 5}, {16, 3}, {8, 2}}, + /* 56 */ {{240, 1}, {24, 10}, {12, 2}, {4, 3}}, + /* 57 */ {{256, 1}, {128, 2}, {64, 2}, {4, 16}}, + /* 58 */ {{256, 1}, {128, 2}, {32, 4}, {4, 8}}, + /* 59 */ {{256, 1}, {16, 16}, {8, 2}, {4, 2}}, + /* 60 */ {{264, 1}, {132, 2}, {44, 3}, {4, 11}}, + /* 61 */ {{272, 1}, {136, 2}, {68, 2}, {4, 17}}, + /* 62 */ {{272, 1}, {68, 4}, {4, 17}, {4, 1}}, + /* 63 */ {{272, 1}, {16, 17}, {8, 2}, {4, 2}}, +}; + const char *duplex_mode[]={"FDD","TDD"}; static const uint8_t bit_reverse_table_256[] = { @@ -1212,3 +1285,11 @@ void nr_timer_setup(NR_timer_t *timer, const uint32_t target, const uint32_t ste timer->step = step; nr_timer_stop(timer); } + +unsigned short get_m_srs(int c_srs, int b_srs) { + return srs_bandwidth_config[c_srs][b_srs][0]; +} + +unsigned short get_N_b_srs(int c_srs, int b_srs) { + return srs_bandwidth_config[c_srs][b_srs][1]; +} diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h index 1e4fecc4f567e4ea5d53cecfdd7d39ee4dd2d1fd..9087f335c58898bf99ee19696b808ea08657c244 100644 --- a/common/utils/nr/nr_common.h +++ b/common/utils/nr/nr_common.h @@ -250,6 +250,8 @@ int get_scan_ssb_first_sc(const double fc, void check_ssb_raster(uint64_t freq, int band, int scs); int get_smallest_supported_bandwidth_index(int scs, frequency_range_t frequency_range, int n_rbs); +unsigned short get_m_srs(int c_srs, int b_srs); +unsigned short get_N_b_srs(int c_srs, int b_srs); #define CEILIDIV(a,b) ((a+b-1)/b) #define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1)) diff --git a/doc/ORAN_FHI7.2_Tutorial.md b/doc/ORAN_FHI7.2_Tutorial.md index a7bfe56a0b714b8a8d4eede8674beaad6bfbad59..1b74e6cdd3930d9ac8730b7614f980c793e73c59 100644 --- a/doc/ORAN_FHI7.2_Tutorial.md +++ b/doc/ORAN_FHI7.2_Tutorial.md @@ -26,7 +26,12 @@ The hardware on which we have tried this tutorial: |Intel(R) Xeon(R) Gold 6354 36-Core, 128GB|Ubuntu 22.04.3 LTS (5.15.0-1033-realtime) |Intel X710, i40e, 9.00 0x8000cfeb 21.5.9 | |AMD EPYC 9374F 32-Core Processor, 128GB |Ubuntu 22.04.2 LTS (5.15.0-1038-realtime) |Intel E810 ,ice, 4.00 0x8001184e 1.3236.0| -**NOTE**: These are not minimum hardware requirements. This is the configuration of our servers. The NIC card should support hardware PTP time stamping. +**NOTE**: + +- These are not minimum hardware requirements. This is the configuration of our servers. +- The NIC card should support hardware PTP time stamping. +- If you are using Intel servers then use only Ice Lake or newer generations. In case of AMD use only 4th generation, Genoa or newer. +- If you try on any other server apart from the above listed, then choose a desktop/server with clock speed higher than 3.0 GHz and `avx512` capabilities. NICs we have tested so far: diff --git a/doc/clang-format.md b/doc/clang-format.md index fa751b303dcbf14ecc3152a905e557c57d626002..5e2f14c0b68d99fc8bdf0415b8d81656e778ec01 100644 --- a/doc/clang-format.md +++ b/doc/clang-format.md @@ -64,3 +64,7 @@ When this is done, you are set up. How to use: 6) Commit. It won't work if code is not properly formatted due to the pre-commit hook. Force committing with `git commit --no-verify` + +# Checking errors introduced by a branch + +Here is the script that can be used to detect any clang-format errors introduced by a branch [here](../tools/formatting/README.md) diff --git a/doc/system_requirements.md b/doc/system_requirements.md new file mode 100644 index 0000000000000000000000000000000000000000..f231f9c39858777906973c24af264087dc17b511 --- /dev/null +++ b/doc/system_requirements.md @@ -0,0 +1,135 @@ +<table style="border-collapse: collapse; border: none;"> + <tr style="border-collapse: collapse; border: none;"> + <td style="border-collapse: collapse; border: none;"> + <a href="http://www.openairinterface.org/"> + <img src="./images/oai_final_logo.png" alt="" border=3 height=50 width=150> + </img> + </a> + </td> + <td style="border-collapse: collapse; border: none; vertical-align: center;"> + <b><font size = "5">System Requirements for Using OAI Stack</font></b> + </td> + </tr> +</table> + +This document describes the minimal and performant system requirements for OpenAirInterface (OAI) 4G/5G software stack (UE and gNB stack). The information provided in this document is based on experimentation, if you have a feedback then open an issue or send an email on the mailing list. + +**Table of Contents** + +[[_TOC_]] + +# Supported CPU Architecture + +|Architecture | +|------------------------------------------ | +|x86_64 (Intel, AMD) | +|aarch64 (Neoverse-N1, N2 and Grace hopper) | + +**Note**: + +- On `x86_64` platform the CPU should support `avx2` instruction set (Minimum requirement). + +# Supported Operating System + +|Operating System | +|-----------------| +|Ubuntu 20/22/24 | +|RHEL 9 | +|Fedora 40 | +|Debian 11 | +|Rocky 9 | + + +# Minimum Hardware Requirement for x86_64 Platforms + +The minimum hardware requirements depends on the radio unit you would like to use or the test case that you would like to execute. + +## Simulated Radio + +OAI offers an inbuilt simulated radio, [RFSimulator](../radio/rfsimulator/README.md). It can be used to familiarize oneself with OAI, for development and debugging, and offers the possibility to use basic channel models. It is not designed to do high performance testing. The below requirements are valid for both 4G and 5G RAN and UE Stack. + +The following requirements are minimum requirements for all use cases: + +### Minimum requirements for gNB Stack + +- CPU: 2 +- Minimum frequency > 2GHz +- Memory: 4Gi +- `avx2` instruction set +- `sctp` protocol should be enabled + +**NOTE**: We have not tested on Intel Atom or Celeron processors, and they +likely won't work well. + +### Minimum requirements for UE Stack + +- CPU: 2 +- Minimum frequency > 2GHz +- Memory: 3Gi +- `avx2` instruction set + +**NOTE**: We have not tested on Intel Atom or Celeron processors + +## USRP B2XX or Blade RF + +USRP B2XX or Blade RF are USB based radios recommended to use with USB 3.0. You can choose a minimum hardware to do functional testing and performance hardware for performance testing. This hardware you can find in Mini-PCs or laptops. + +The minimum requirements stated in [simulated radio](.##simulated-radio) apply. + +### Minimum requirements for both gNB and UE Stack + +- CPU: 3 +- Memory: 5Gi +- Disable CPU sleep states +- USB 3.0 +- Intel i5, AMD Ryzen 5 + +### Recommended for performance for gNB and UE Stack + +- CPU: 4 +- Boost Frequency > 3GHz +- Use only performance cores +- Disable hyper-threading +- Disable CPU sleep states +- DDR4 or DDR5 RAM, minimum 5Gi +- USB 3.0 + +Apart from this you should follow [tuning and security tips](./tuning_and_security.md) to +tune your system to get high performance. + +## USRP N3XX/X3XX/X4XX/AW2S + +USRP N3XX/X3XX/X4XX requires two dedicated 10G SFP+ connections. For these radios we only recommend having performance hardware. This hardware you can find in Desktop servers or rack/blade servers. For the gNB, the same applies in case of using AW2S radios. + +The minimum requirements stated in [simulated radio](.##simulated-radio) apply. + +Apart from this you should follow [tuning and security tips](./tuning_and_security.md) to +tune your system to get high performance. + +**NOTE**: In case you are using Mellanox NIC cards then you have to download `mlnx-ofed` and configure your NIC for performance. + +### Recommended for performance for gNB Stack + +- CPU: 8-10 +- Boost Frequency > 4GHz +- Use only performance cores +- Disable CPU sleep states +- DDR4 or DDR5 RAM, 5 Gi +- (Optional) Realtime kernel to have better Jitter statistics +- Intel x710/xx710/E-810 or Mellanox connect 5x or 6x + +### Recommended for performance for UE Stack + +- CPU: 4 +- Boost Frequency > 4GHz +- DDR4 or DDR5 RAM, 5Gi +- Use only performance cores +- Disable CPU sleep states +- (Optional) Realtime kernel to have better Jitter statistics +- Intel x710/xx710/E-810 or Mellanox connect 5x or 6x + +## O-RAN Radio Units + +We have dedicated documentation for O-RAN Radio Units. [Refer to 7.2 FH documentation](./ORAN_FHI7.2_Tutorial.md) before purchasing a Desktop server or rack/blade server. + +The minimum requirements stated in [simulated radio](.##simulated-radio) apply. diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h index f0d9b73e631c4424316aec5eb7231d36feef17a9..d0d9fc9093e5333424b8d4b63547ba31b419d80c 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h @@ -391,6 +391,7 @@ typedef struct { uint16_t t_srs; // SRS-Periodicity in slots [3GPP TS 38.211, Sec 6.4.1.4.4], Value: 1,2,3,4,5,8,10,16,20,32,40,64,80,160,320,640,1280,2560 uint16_t t_offset; // Slot offset value [3GPP TS 38.211, Sec 6.4.1.4.3], Value:0->2559 nfapi_nr_ue_ul_beamforming_t beamforming; + int16_t tx_power; } fapi_nr_ul_config_srs_pdu; typedef struct { diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index fea6b930ac233dac1c80486ca65276a3b1e758f7..7a46cd1b20dda3e4bfc302540cb670a56df6b50d 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -631,7 +631,7 @@ int nr_srs_channel_estimation( const uint8_t N_ap = 1<<srs_pdu->num_ant_ports; const uint8_t K_TC = 2<<srs_pdu->comb_size; - const uint16_t m_SRS_b = srs_bandwidth_config[srs_pdu->config_index][srs_pdu->bandwidth_index][0]; + const uint16_t m_SRS_b = get_m_srs(srs_pdu->config_index, srs_pdu->bandwidth_index); const uint16_t M_sc_b_SRS = m_SRS_b * NR_NB_SC_PER_RB/K_TC; uint8_t fd_cdm = N_ap; if (N_ap == 4 && ((K_TC == 2 && srs_pdu->cyclic_shift >= 4) || (K_TC == 4 && srs_pdu->cyclic_shift >= 6))) { diff --git a/openair1/PHY/NR_TRANSPORT/srs_rx.c b/openair1/PHY/NR_TRANSPORT/srs_rx.c index a7d975dbb77bf8909a047c48b73e0e49e8cbc5d1..037528b4072d47751f9888da5333649c6c64590d 100644 --- a/openair1/PHY/NR_TRANSPORT/srs_rx.c +++ b/openair1/PHY/NR_TRANSPORT/srs_rx.c @@ -80,7 +80,7 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB, const uint8_t N_ap = 1<<srs_pdu->num_ant_ports; const uint8_t N_symb_SRS = 1 << srs_pdu->num_symbols; const uint8_t K_TC = 2 << srs_pdu->comb_size; - const uint16_t M_sc_b_SRS = srs_bandwidth_config[srs_pdu->config_index][srs_pdu->bandwidth_index][0] * NR_NB_SC_PER_RB/K_TC; + const uint16_t M_sc_b_SRS = get_m_srs(srs_pdu->config_index, srs_pdu->bandwidth_index) * NR_NB_SC_PER_RB / K_TC; int32_t *rx_signal; bool no_srs_signal = true; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 40e8395b147bae4df434bd49cb43a4bcd3274d9d..f17e309a6d2adf9201d3b66d159dda6b2be72732 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -1255,7 +1255,7 @@ static void nr_dlsch_extract_rbs(uint32_t rxdataF_sz, } static void nr_dlsch_detection_mrc(uint32_t rx_size_symbol, - short n_tx, + short nl, short n_rx, int32_t rxdataF_comp[][n_rx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], int ***rho, @@ -1266,19 +1266,19 @@ static void nr_dlsch_detection_mrc(uint32_t rx_size_symbol, int length) { simde__m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b,*dl_ch_mag128_0r,*dl_ch_mag128_1r; - uint32_t nb_rb_0 = length/12 + ((length%12)?1:0); + uint32_t nb_rb_0 = length / 12 + ((length % 12) ? 1 : 0); if (n_rx > 1) { - for (int aatx = 0; aatx < n_tx; aatx++) { - rxdataF_comp128_0 = (simde__m128i *)(rxdataF_comp[aatx][0] + symbol * rx_size_symbol); - dl_ch_mag128_0 = (simde__m128i *)dl_ch_mag[aatx][0]; - dl_ch_mag128_0b = (simde__m128i *)dl_ch_magb[aatx][0]; - dl_ch_mag128_0r = (simde__m128i *)dl_ch_magr[aatx][0]; + for (int l = 0; l < nl; l++) { + rxdataF_comp128_0 = (simde__m128i *)(rxdataF_comp[l][0] + symbol * rx_size_symbol); + dl_ch_mag128_0 = (simde__m128i *)dl_ch_mag[l][0]; + dl_ch_mag128_0b = (simde__m128i *)dl_ch_magb[l][0]; + dl_ch_mag128_0r = (simde__m128i *)dl_ch_magr[l][0]; for (int aarx = 1; aarx < n_rx; aarx++) { - rxdataF_comp128_1 = (simde__m128i *)(rxdataF_comp[aatx][aarx] + symbol * rx_size_symbol); - dl_ch_mag128_1 = (simde__m128i *)dl_ch_mag[aatx][aarx]; - dl_ch_mag128_1b = (simde__m128i *)dl_ch_magb[aatx][aarx]; - dl_ch_mag128_1r = (simde__m128i *)dl_ch_magr[aatx][aarx]; + rxdataF_comp128_1 = (simde__m128i *)(rxdataF_comp[l][aarx] + symbol * rx_size_symbol); + dl_ch_mag128_1 = (simde__m128i *)dl_ch_mag[l][aarx]; + dl_ch_mag128_1b = (simde__m128i *)dl_ch_magb[l][aarx]; + dl_ch_mag128_1r = (simde__m128i *)dl_ch_magr[l][aarx]; // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM/256 llr computation) for (int i = 0; i < nb_rb_0 * 3; i++) { @@ -1291,7 +1291,7 @@ static void nr_dlsch_detection_mrc(uint32_t rx_size_symbol, } #ifdef DEBUG_DLSCH_DEMOD for (int i = 0; i < nb_rb_0 * 3; i++) { - printf("symbol%d RB %d\n", symbol,i / 3); + printf("symbol%d RB %d\n", symbol, i / 3); rxdataF_comp128_0 = (simde__m128i *)(rxdataF_comp[0][0] + symbol * rx_size_symbol); rxdataF_comp128_1 = (simde__m128i *)(rxdataF_comp[0][n_rx] + symbol * rx_size_symbol); print_shorts("tx 1 mrc_re/mrc_Im:",(int16_t*)&rxdataF_comp128_0[i]); @@ -1675,7 +1675,7 @@ void nr_conjch0_mult_ch1(int *ch0, */ static void nr_dlsch_mmse(uint32_t rx_size_symbol, unsigned char n_rx, - unsigned char n_tx, // number of layer + unsigned char nl, // number of layer int32_t rxdataF_comp[][n_rx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], int32_t dl_ch_mag[][n_rx][rx_size_symbol], int32_t dl_ch_magb[][n_rx][rx_size_symbol], @@ -1688,25 +1688,24 @@ static void nr_dlsch_mmse(uint32_t rx_size_symbol, int length, uint32_t noise_var) { - int *ch0r, *ch0c; - uint32_t nb_rb_0 = length/12 + ((length%12)?1:0); + uint32_t nb_rb_0 = length / 12 + ((length % 12) ? 1 : 0); c16_t determ_fin[12 * nb_rb_0] __attribute__((aligned(32))); ///Allocate H^*H matrix elements and sub elements - c16_t conjH_H_elements_data[n_rx][n_tx][n_tx][12 * nb_rb_0]; + c16_t conjH_H_elements_data[n_rx][nl][nl][12 * nb_rb_0]; memset(conjH_H_elements_data, 0, sizeof(conjH_H_elements_data)); - c16_t *conjH_H_elements[n_rx][n_tx][n_tx]; + c16_t *conjH_H_elements[n_rx][nl][nl]; for (int aarx = 0; aarx < n_rx; aarx++) - for (int rtx = 0; rtx < n_tx; rtx++) - for (int ctx = 0; ctx < n_tx; ctx++) + for (int rtx = 0; rtx < nl; rtx++) + for (int ctx = 0; ctx < nl; ctx++) conjH_H_elements[aarx][rtx][ctx] = conjH_H_elements_data[aarx][rtx][ctx]; //Compute H^*H matrix elements and sub elements:(1/2^log2_maxh)*conjH_H_elements - for (int rtx=0;rtx<n_tx;rtx++) {//row - for (int ctx=0;ctx<n_tx;ctx++) {//column - for (int aarx=0;aarx<n_rx;aarx++) { - ch0r = (int *)dl_ch_estimates_ext[rtx*n_rx+aarx]; - ch0c = (int *)dl_ch_estimates_ext[ctx*n_rx+aarx]; + for (int rtx = 0; rtx < nl; rtx++) {//row + for (int ctx = 0; ctx < nl; ctx++) {//column + for (int aarx = 0; aarx < n_rx; aarx++) { + int *ch0r = (int *)dl_ch_estimates_ext[rtx * n_rx + aarx]; + int *ch0c = (int *)dl_ch_estimates_ext[ctx * n_rx + aarx]; nr_conjch0_mult_ch1(ch0r, ch0c, (int32_t *)conjH_H_elements[aarx][ctx][rtx], // sic @@ -1721,7 +1720,7 @@ static void nr_dlsch_mmse(uint32_t rx_size_symbol, // Add noise_var such that: H^h * H + noise_var * I if (noise_var != 0) { simde__m128i nvar_128i = simde_mm_set1_epi32(noise_var >> 3); - for (int p = 0; p < n_tx; p++) { + for (int p = 0; p < nl; p++) { simde__m128i *conjH_H_128i = (simde__m128i *)conjH_H_elements[0][p][p]; for (int k = 0; k < 3 * nb_rb_0; k++) { conjH_H_128i[0] = simde_mm_add_epi32(conjH_H_128i[0], nvar_128i); @@ -1732,15 +1731,15 @@ static void nr_dlsch_mmse(uint32_t rx_size_symbol, //Compute the inverse and determinant of the H^*H matrix //Allocate the inverse matrix - c16_t *inv_H_h_H[n_tx][n_tx]; - c16_t inv_H_h_H_data[n_tx][n_tx][12 * nb_rb_0]; + c16_t *inv_H_h_H[nl][nl]; + c16_t inv_H_h_H_data[nl][nl][12 * nb_rb_0]; memset(inv_H_h_H_data, 0, sizeof(inv_H_h_H_data)); - for (int rtx = 0; rtx < n_tx; rtx++) - for (int ctx = 0; ctx < n_tx; ctx++) + for (int rtx = 0; rtx < nl; rtx++) + for (int ctx = 0; ctx < nl; ctx++) inv_H_h_H[ctx][rtx] = inv_H_h_H_data[ctx][rtx]; int fp_flag = 1;//0: float point calc 1: Fixed point calc - nr_matrix_inverse(n_tx, + nr_matrix_inverse(nl, conjH_H_elements[0], // Input matrix inv_H_h_H, // Inverse determ_fin, // determin @@ -1751,30 +1750,33 @@ static void nr_dlsch_mmse(uint32_t rx_size_symbol, // multiply Matrix inversion pf H_h_H by the rx signal vector c16_t outtemp[12 * nb_rb_0] __attribute__((aligned(32))); //Allocate rxdataF for zforcing out - c16_t rxdataF_zforcing[n_tx][12 * nb_rb_0]; + c16_t rxdataF_zforcing[nl][12 * nb_rb_0]; memset(rxdataF_zforcing, 0, sizeof(rxdataF_zforcing)); - for (int rtx=0;rtx<n_tx;rtx++) {//Output Layers row + for (int rtx = 0; rtx < nl; rtx++) {//Output Layers row // loop over Layers rtx=0,...,N_Layers-1 - for (int ctx = 0; ctx < n_tx; ctx++) { // column multi + for (int ctx = 0; ctx < nl; ctx++) { // column multi // printf("Computing r_%d c_%d\n",rtx,ctx); - // print_shorts(" H_h_H=",(int16_t*)&conjH_H_elements[ctx*n_tx+rtx][0][0]); - // print_shorts(" Inv_H_h_H=",(int16_t*)&inv_H_h_H[ctx*n_tx+rtx][0]); - nr_a_mult_b(inv_H_h_H[ctx][rtx], (c16_t *)(rxdataF_comp[ctx][0] + symbol * nb_rb * 12), outtemp, nb_rb_0, shift - (fp_flag == 1 ? 2 : 0)); - nr_a_sum_b(rxdataF_zforcing[rtx], outtemp, - nb_rb_0); // a =a + b + // print_shorts(" H_h_H=",(int16_t*)&conjH_H_elements[ctx*nl+rtx][0][0]); + // print_shorts(" Inv_H_h_H=",(int16_t*)&inv_H_h_H[ctx*nl+rtx][0]); + nr_a_mult_b(inv_H_h_H[ctx][rtx], + (c16_t *)(rxdataF_comp[ctx][0] + symbol * rx_size_symbol), + outtemp, + nb_rb_0, + shift - (fp_flag == 1 ? 2 : 0)); + nr_a_sum_b(rxdataF_zforcing[rtx], outtemp, nb_rb_0); // a = a + b } #ifdef DEBUG_DLSCH_DEMOD - printf("Computing layer_%d \n",rtx);; - print_shorts(" Rx signal:=",(int16_t*)&rxdataF_zforcing[rtx][0]); - print_shorts(" Rx signal:=",(int16_t*)&rxdataF_zforcing[rtx][4]); - print_shorts(" Rx signal:=",(int16_t*)&rxdataF_zforcing[rtx][8]); + printf("Computing layer_%d \n", rtx); + print_shorts(" Rx signal:=", (int16_t*)&rxdataF_zforcing[rtx][0]); + print_shorts(" Rx signal:=", (int16_t*)&rxdataF_zforcing[rtx][4]); + print_shorts(" Rx signal:=", (int16_t*)&rxdataF_zforcing[rtx][8]); #endif } //Copy zero_forcing out to output array - for (int rtx=0;rtx<n_tx;rtx++) - nr_element_sign(rxdataF_zforcing[rtx], (c16_t *)(rxdataF_comp[rtx][0] + symbol * nb_rb * 12), nb_rb_0, +1); + for (int rtx = 0; rtx < nl; rtx++) + nr_element_sign(rxdataF_zforcing[rtx], (c16_t *)(rxdataF_comp[rtx][0] + symbol * rx_size_symbol), nb_rb_0, + 1); //Update LLR thresholds with the Matrix determinant simde__m128i *dl_ch_mag128_0=NULL,*dl_ch_mag128b_0=NULL,*dl_ch_mag128r_0=NULL,*determ_fin_128; @@ -1783,7 +1785,7 @@ static void nr_dlsch_mmse(uint32_t rx_size_symbol, short nr_realpart[8]__attribute__((aligned(16))) = {1,0,1,0,1,0,1,0}; determ_fin_128 = (simde__m128i *)&determ_fin[0]; - if (mod_order>2) { + if (mod_order > 2) { if (mod_order == 4) { QAM_amp128 = simde_mm_set1_epi16(QAM16_n1); //2/sqrt(10) QAM_amp128b = simde_mm_setzero_si128(); @@ -1801,25 +1803,24 @@ static void nr_dlsch_mmse(uint32_t rx_size_symbol, dl_ch_mag128b_0 = (simde__m128i *)dl_ch_magb[0][0]; dl_ch_mag128r_0 = (simde__m128i *)dl_ch_magr[0][0]; - for (int rb=0; rb<3*nb_rb_0; rb++) { + for (int rb = 0; rb < 3 * nb_rb_0; rb++) { //for symmetric H_h_H matrix, the determinant is only real values - mmtmpD2 = simde_mm_sign_epi16(determ_fin_128[0],*(simde__m128i*)&nr_realpart[0]);//set imag part to 0 - mmtmpD3 = simde_mm_shufflelo_epi16(mmtmpD2,SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD3 = simde_mm_shufflehi_epi16(mmtmpD3,SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD2 = simde_mm_add_epi16(mmtmpD2,mmtmpD3); - - dl_ch_mag128_0[0] = mmtmpD2; - dl_ch_mag128b_0[0] = mmtmpD2; - dl_ch_mag128r_0[0] = mmtmpD2; - - dl_ch_mag128_0[0] = simde_mm_mulhi_epi16(dl_ch_mag128_0[0],QAM_amp128); - dl_ch_mag128_0[0] = simde_mm_slli_epi16(dl_ch_mag128_0[0],1); - - dl_ch_mag128b_0[0] = simde_mm_mulhi_epi16(dl_ch_mag128b_0[0],QAM_amp128b); - dl_ch_mag128b_0[0] = simde_mm_slli_epi16(dl_ch_mag128b_0[0],1); - dl_ch_mag128r_0[0] = simde_mm_mulhi_epi16(dl_ch_mag128r_0[0],QAM_amp128r); - dl_ch_mag128r_0[0] = simde_mm_slli_epi16(dl_ch_mag128r_0[0],1); - + mmtmpD2 = simde_mm_sign_epi16(determ_fin_128[0],*(simde__m128i*)&nr_realpart[0]);//set imag part to 0 + mmtmpD3 = simde_mm_shufflelo_epi16(mmtmpD2,SIMDE_MM_SHUFFLE(2,3,0,1)); + mmtmpD3 = simde_mm_shufflehi_epi16(mmtmpD3,SIMDE_MM_SHUFFLE(2,3,0,1)); + mmtmpD2 = simde_mm_add_epi16(mmtmpD2,mmtmpD3); + + dl_ch_mag128_0[0] = mmtmpD2; + dl_ch_mag128b_0[0] = mmtmpD2; + dl_ch_mag128r_0[0] = mmtmpD2; + + dl_ch_mag128_0[0] = simde_mm_mulhi_epi16(dl_ch_mag128_0[0],QAM_amp128); + dl_ch_mag128_0[0] = simde_mm_slli_epi16(dl_ch_mag128_0[0],1); + + dl_ch_mag128b_0[0] = simde_mm_mulhi_epi16(dl_ch_mag128b_0[0],QAM_amp128b); + dl_ch_mag128b_0[0] = simde_mm_slli_epi16(dl_ch_mag128b_0[0],1); + dl_ch_mag128r_0[0] = simde_mm_mulhi_epi16(dl_ch_mag128r_0[0],QAM_amp128r); + dl_ch_mag128r_0[0] = simde_mm_slli_epi16(dl_ch_mag128r_0[0],1); determ_fin_128 += 1; dl_ch_mag128_0 += 1; diff --git a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c index 02ad38cc0e72e4a6c6fb72863ee29d0253063c7a..f362e3f218cdcf9574fae5c98da8078cd6e1f66e 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c @@ -110,17 +110,17 @@ uint16_t compute_F_b(frame_t frame_number, uint16_t product_N_b = 1; for (unsigned int b_prime = b_hop; b_prime < B_SRS; b_prime++) { if (b_prime != b_hop) { - product_N_b *= srs_bandwidth_config[C_SRS][b_prime][1]; + product_N_b *= get_N_b_srs(C_SRS, b_prime); } } uint16_t F_b = 0; - uint8_t N_b = srs_bandwidth_config[C_SRS][b][1]; + uint8_t N_b = get_N_b_srs(C_SRS, b); if (N_b & 1) { // Nb odd F_b = (N_b/2)*(n_SRS/product_N_b); } else { // Nb even uint16_t product_N_b_B_SRS = product_N_b; - product_N_b_B_SRS *= srs_bandwidth_config[C_SRS][B_SRS][1]; /* product for b_hop to b */ + product_N_b_B_SRS *= get_N_b_srs(C_SRS, B_SRS); /* product for b_hop to b */ F_b = (N_b/2)*((n_SRS%product_N_b_B_SRS)/product_N_b) + ((n_SRS%product_N_b_B_SRS)/2*product_N_b); } @@ -142,8 +142,8 @@ uint16_t compute_n_b(frame_t frame_number, uint8_t l_line, uint8_t b) { - uint8_t N_b = srs_bandwidth_config[C_SRS][b][1]; - uint16_t m_SRS_b = srs_bandwidth_config[C_SRS][B_SRS][0]; + uint8_t N_b = get_N_b_srs(C_SRS, b); + uint16_t m_SRS_b = get_m_srs(C_SRS, B_SRS); uint16_t n_b = 0; if (b_hop >= B_SRS) { @@ -211,7 +211,7 @@ int generate_srs_nr(nfapi_nr_srs_pdu_t *srs_config_pdu, uint8_t N_symb_SRS = 1<<srs_config_pdu->num_symbols; // Number of consecutive OFDM symbols uint8_t l0 = frame_parms->symbols_per_slot - 1 - l_offset; // Starting symbol position in the time domain uint8_t n_SRS_cs_max = srs_max_number_cs[srs_config_pdu->comb_size]; - uint16_t m_SRS_b = srs_bandwidth_config[C_SRS][B_SRS][0]; // Number of resource blocks + uint16_t m_SRS_b = get_m_srs(C_SRS, B_SRS); // Number of resource blocks uint16_t M_sc_b_SRS = m_SRS_b * NR_NB_SC_PER_RB/K_TC; // Length of the SRS sequence #ifdef SRS_DEBUG @@ -273,7 +273,7 @@ int generate_srs_nr(nfapi_nr_srs_pdu_t *srs_config_pdu, } uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_config_pdu->bwp_start*NR_NB_SC_PER_RB; double sqrt_N_ap = sqrt(N_ap); - uint16_t n_b[B_SRS_NUMBER]; + uint16_t n_b[B_SRS + 1]; // Find index of table which is for this SRS length uint16_t M_sc_b_SRS_index = 0; diff --git a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.h b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.h index a017d79730084f1c5ec387f2a2ee9a3fe5ba36e6..dba339d14be3c5c21ad44614cd56865e32e0575c 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.h +++ b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.h @@ -35,83 +35,6 @@ #include "PHY/defs_nr_UE.h" -/************** DEFINE ********************************************/ - -#define C_SRS_NUMBER (64) -#define B_SRS_NUMBER (4) - -/************** VARIABLES *****************************************/ - -/* TS 38.211 Table 6.4.1.4.3-1: SRS bandwidth configuration */ -static const unsigned short srs_bandwidth_config[C_SRS_NUMBER][B_SRS_NUMBER][2] = { - /* B_SRS = 0 B_SRS = 1 B_SRS = 2 B_SRS = 3 */ - /* C SRS m_srs0 N_0 m_srs1 N_1 m_srs2 N_2 m_srs3 N_3 */ - /* 0 */ {{4, 1}, {4, 1}, {4, 1}, {4, 1}}, - /* 1 */ {{8, 1}, {4, 2}, {4, 1}, {4, 1}}, - /* 2 */ {{12, 1}, {4, 3}, {4, 1}, {4, 1}}, - /* 3 */ {{16, 1}, {4, 4}, {4, 1}, {4, 1}}, - /* 4 */ {{16, 1}, {8, 2}, {4, 2}, {4, 1}}, - /* 5 */ {{20, 1}, {4, 5}, {4, 1}, {4, 1}}, - /* 6 */ {{24, 1}, {4, 6}, {4, 1}, {4, 1}}, - /* 7 */ {{24, 1}, {12, 2}, {4, 3}, {4, 1}}, - /* 8 */ {{28, 1}, {4, 7}, {4, 1}, {4, 1}}, - /* 9 */ {{32, 1}, {16, 2}, {8, 2}, {4, 2}}, - /* 10 */ {{36, 1}, {12, 3}, {4, 3}, {4, 1}}, - /* 11 */ {{40, 1}, {20, 2}, {4, 5}, {4, 1}}, - /* 12 */ {{48, 1}, {16, 3}, {8, 2}, {4, 2}}, - /* 13 */ {{48, 1}, {24, 2}, {12, 2}, {4, 3}}, - /* 14 */ {{52, 1}, {4, 13}, {4, 1}, {4, 1}}, - /* 15 */ {{56, 1}, {28, 2}, {4, 7}, {4, 1}}, - /* 16 */ {{60, 1}, {20, 3}, {4, 5}, {4, 1}}, - /* 17 */ {{64, 1}, {32, 2}, {16, 2}, {4, 4}}, - /* 18 */ {{72, 1}, {24, 3}, {12, 2}, {4, 3}}, - /* 19 */ {{72, 1}, {36, 2}, {12, 3}, {4, 3}}, - /* 20 */ {{76, 1}, {4, 19}, {4, 1}, {4, 1}}, - /* 21 */ {{80, 1}, {40, 2}, {20, 2}, {4, 5}}, - /* 22 */ {{88, 1}, {44, 2}, {4, 11}, {4, 1}}, - /* 23 */ {{96, 1}, {32, 3}, {16, 2}, {4, 4}}, - /* 24 */ {{96, 1}, {48, 2}, {24, 2}, {4, 6}}, - /* 25 */ {{104, 1}, {52, 2}, {4, 13}, {4, 1}}, - /* 26 */ {{112, 1}, {56, 2}, {28, 2}, {4, 7}}, - /* 27 */ {{120, 1}, {60, 2}, {20, 3}, {4, 5}}, - /* 28 */ {{120, 1}, {40, 3}, {8, 5}, {4, 2}}, - /* 29 */ {{120, 1}, {24, 5}, {12, 2}, {4, 3}}, - /* 30 */ {{128, 1}, {64, 2}, {32, 2}, {4, 8}}, - /* 31 */ {{128, 1}, {64, 2}, {16, 4}, {4, 4}}, - /* 32 */ {{128, 1}, {16, 8}, {8, 2}, {4, 2}}, - /* 33 */ {{132, 1}, {44, 3}, {4, 11}, {4, 1}}, - /* 34 */ {{136, 1}, {68, 2}, {4, 17}, {4, 1}}, - /* 35 */ {{144, 1}, {72, 2}, {36, 2}, {4, 9}}, - /* 36 */ {{144, 1}, {48, 3}, {24, 2}, {12, 2}}, - /* 37 */ {{144, 1}, {48, 3}, {16, 3}, {4, 4}}, - /* 38 */ {{144, 1}, {16, 9}, {8, 2}, {4, 2}}, - /* 39 */ {{152, 1}, {76, 2}, {4, 19}, {4, 1}}, - /* 40 */ {{160, 1}, {80, 2}, {40, 2}, {4, 10}}, - /* 41 */ {{160, 1}, {80, 2}, {20, 4}, {4, 5}}, - /* 42 */ {{160, 1}, {32, 5}, {16, 2}, {4, 4}}, - /* 43 */ {{168, 1}, {84, 2}, {28, 3}, {4, 7}}, - /* 44 */ {{176, 1}, {88, 2}, {44, 2}, {4, 11}}, - /* 45 */ {{184, 1}, {92, 2}, {4, 23}, {4, 1}}, - /* 46 */ {{192, 1}, {96, 2}, {48, 2}, {4, 12}}, - /* 47 */ {{192, 1}, {96, 2}, {24, 4}, {4, 6}}, - /* 48 */ {{192, 1}, {64, 3}, {16, 4}, {4, 4}}, - /* 49 */ {{192, 1}, {24, 8}, {8, 3}, {4, 2}}, - /* 50 */ {{208, 1}, {104, 2}, {52, 2}, {4, 13}}, - /* 51 */ {{216, 1}, {108, 2}, {36, 3}, {4, 9}}, - /* 52 */ {{224, 1}, {112, 2}, {56, 2}, {4, 14}}, - /* 53 */ {{240, 1}, {120, 2}, {60, 2}, {4, 15}}, - /* 54 */ {{240, 1}, {80, 3}, {20, 4}, {4, 5}}, - /* 55 */ {{240, 1}, {48, 5}, {16, 3}, {8, 2}}, - /* 56 */ {{240, 1}, {24, 10}, {12, 2}, {4, 3}}, - /* 57 */ {{256, 1}, {128, 2}, {64, 2}, {4, 16}}, - /* 58 */ {{256, 1}, {128, 2}, {32, 4}, {4, 8}}, - /* 59 */ {{256, 1}, {16, 16}, {8, 2}, {4, 2}}, - /* 60 */ {{264, 1}, {132, 2}, {44, 3}, {4, 11}}, - /* 61 */ {{272, 1}, {136, 2}, {68, 2}, {4, 17}}, - /* 62 */ {{272, 1}, {68, 4}, {4, 17}, {4, 1}}, - /* 63 */ {{272, 1}, {16, 17}, {8, 2}, {4, 2}}, -}; - #define SRS_PERIODICITY (17) static const uint16_t srs_periodicity[SRS_PERIODICITY] = {1, 2, 4, 5, 8, 10, 16, 20, 32, 40, 64, 80, 160, 320, 640, 1280, 2560}; diff --git a/openair1/PHY/TOOLS/tests/CMakeLists.txt b/openair1/PHY/TOOLS/tests/CMakeLists.txt index 591dfcd4306823209bd3a116ee9bc74af54243dc..2b846a8cd3bd0a53a7e43ec7c299491c885f9008 100644 --- a/openair1/PHY/TOOLS/tests/CMakeLists.txt +++ b/openair1/PHY/TOOLS/tests/CMakeLists.txt @@ -14,4 +14,4 @@ add_executable(test_log2_approx test_log2_approx.cpp ../log2_approx.c) target_link_libraries(test_log2_approx PRIVATE GTest::gtest LOG minimal_lib) add_dependencies(tests test_log2_approx) add_test(NAME test_log2_approx - COMMAND ./test_log2_approx) + COMMAND ./test_log2_approx --gtest_filter=-log2_approx.complete) diff --git a/openair1/PHY/TOOLS/tests/test_log2_approx.cpp b/openair1/PHY/TOOLS/tests/test_log2_approx.cpp index c05540b61c2f8f8bd6110513ecd374ab15fc936c..6728041c52eca25ed34956c75528f22f3e493227 100644 --- a/openair1/PHY/TOOLS/tests/test_log2_approx.cpp +++ b/openair1/PHY/TOOLS/tests/test_log2_approx.cpp @@ -10,25 +10,27 @@ uint8_t log2_approx_ref(uint32_t x) return std::round(std::log2(x)); } -uint8_t log2_approx64_ref(unsigned long long int x) -{ - return std::round(std::log2(static_cast<long double>(x))); -} - TEST(log2_approx, complete) { for (uint32_t i = 0; i < UINT32_MAX; i++) EXPECT_EQ(log2_approx(i), log2_approx_ref(i)); } +TEST(log2_approx, boundaries) +{ + for (int i = 0; i < 32; i++) { + uint32_t i2 = std::pow(2.0, i + 0.5); + EXPECT_EQ(log2_approx(i2), i) << "log2(" << i2 << ")"; + EXPECT_EQ(log2_approx(i2 + 1), i + 1) << "log2(" << i2 + 1 << ")"; + } +} + TEST(log2_approx64, boundaries) { - for (long double i = 0; i < 64; i++) { - unsigned long long i2 = std::pow(2.0L, i + 0.5L); - for (unsigned long long j = -10; j <= 10; j++) { - unsigned long long x = i2 + j; - EXPECT_EQ(log2_approx64(x), log2_approx64_ref(x)); - } + for (int i = 0; i < 64; i++) { + unsigned long long int i2 = std::pow(2.0L, i + 0.5L); + EXPECT_EQ(log2_approx64(i2), i) << "log2(" << i2 << ")"; + EXPECT_EQ(log2_approx64(i2 + 1), i + 1) << "log2(" << i2 + 1 << ")"; } } diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index f3a272330b004152a0775bfd656bd875557777b1..1dff70618e0cb81f35f5c4e287e429598959850e 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -577,6 +577,9 @@ typedef struct NR_UE_UL_BWP { int channel_bandwidth; // Minimum transmission power according to 38.101 6.3.1 float P_CMIN; + // SRS power control adjustment state + int h_b_f_c; + bool srs_power_control_initialized; } NR_UE_UL_BWP_t; // non-BWP serving cell configuration diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index fab0fb7a7c3edcf1ed57cc9e08dfc7a55ad801c7..de8fa49d4831dfadb6f62b8095812b141faf3d77 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -1280,7 +1280,7 @@ static void handle_aperiodic_srs_type(struct NR_SRS_ResourceSet__resourceType__a struct NR_SRS_ResourceSet__resourceType__aperiodic__ext1__aperiodicSRS_ResourceTriggerList); } -static void setup_srsresourceset(NR_SRS_ResourceSet_t *target, NR_SRS_ResourceSet_t *source) +static void setup_srsresourceset(NR_UE_UL_BWP_t *bwp, NR_SRS_ResourceSet_t *target, NR_SRS_ResourceSet_t *source) { target->srs_ResourceSetId = source->srs_ResourceSetId; if (source->srs_ResourceIdList) @@ -1311,15 +1311,20 @@ static void setup_srsresourceset(NR_SRS_ResourceSet_t *target, NR_SRS_ResourceSe } } target->usage = source->usage; + if (source->alpha) { + bwp->h_b_f_c = 0; + } UPDATE_IE(target->alpha, source->alpha, NR_Alpha_t); - if (source->p0) + if (source->p0) { + bwp->h_b_f_c = 0; UPDATE_IE(target->p0, source->p0, long); + } if (source->pathlossReferenceRS) UPDATE_IE(target->pathlossReferenceRS, source->pathlossReferenceRS, struct NR_PathlossReferenceRS_Config); UPDATE_IE(target->srs_PowerControlAdjustmentStates, source->srs_PowerControlAdjustmentStates, long); } -static void setup_srsconfig(NR_SRS_Config_t *source, NR_SRS_Config_t *target) +static void setup_srsconfig(NR_UE_UL_BWP_t *bwp, NR_SRS_Config_t *source, NR_SRS_Config_t *target) { UPDATE_IE(target->tpc_Accumulation, source->tpc_Accumulation, long); // SRS-Resource @@ -1337,14 +1342,25 @@ static void setup_srsconfig(NR_SRS_Config_t *source, NR_SRS_Config_t *target) srs_ResourceId); } // SRS-ResourceSet - if (source->srs_ResourceSetToAddModList) { + struct NR_SRS_Config__srs_ResourceSetToAddModList *source_srs_list = source->srs_ResourceSetToAddModList; + if (source_srs_list) { if (!target->srs_ResourceSetToAddModList) target->srs_ResourceSetToAddModList = calloc(1, sizeof(*target->srs_ResourceSetToAddModList)); - ADDMOD_IE_FROMLIST_WFUNCTION(source->srs_ResourceSetToAddModList, - target->srs_ResourceSetToAddModList, - srs_ResourceSetId, - NR_SRS_ResourceSet_t, - setup_srsresourceset); + struct NR_SRS_Config__srs_ResourceSetToAddModList *target_srs_list = target->srs_ResourceSetToAddModList; + + for (int i = 0; i < source_srs_list->list.count; i++) { + long srs_resource_id = source_srs_list->list.array[i]->srs_ResourceSetId; + int j; + for (j = 0; j < target_srs_list->list.count; j++) { + if (srs_resource_id == target_srs_list->list.array[j]->srs_ResourceSetId) + break; + } + if (j == target_srs_list->list.count) { + NR_SRS_ResourceSet_t *new = calloc(1, sizeof(*new)); + ASN_SEQUENCE_ADD(&target_srs_list->list, new); + } + setup_srsresourceset(bwp, target_srs_list->list.array[j], source_srs_list->list.array[i]); + } } if (source->srs_ResourceSetToReleaseList) { RELEASE_IE_FROMLIST(source->srs_ResourceSetToReleaseList, @@ -1459,7 +1475,7 @@ static void configure_dedicated_BWP_ul(NR_UE_MAC_INST_t *mac, int bwp_id, NR_BWP if (ul_dedicated->srs_Config->present == NR_SetupRelease_SRS_Config_PR_setup) { if (!bwp->srs_Config) bwp->srs_Config = calloc(1, sizeof(*bwp->srs_Config)); - setup_srsconfig(ul_dedicated->srs_Config->choice.setup, bwp->srs_Config); + setup_srsconfig(bwp, ul_dedicated->srs_Config->choice.setup, bwp->srs_Config); } } AssertFatal(!ul_dedicated->configuredGrantConfig, "configuredGrantConfig not supported\n"); @@ -1513,6 +1529,7 @@ static void configure_common_BWP_ul(NR_UE_MAC_INST_t *mac, int bwp_id, NR_BWP_Up bwp->channel_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index); // Minumum transmission power depends on bandwidth, precalculate it here bwp->P_CMIN = nr_get_Pcmin(bw_index); + bwp->srs_power_control_initialized = false; if (bwp_id == 0) { mac->sc_info.initial_ul_BWPSize = bwp->BWPSize; mac->sc_info.initial_ul_BWPStart = bwp->BWPStart; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index d9c5fa2345712700052b36b97b98b76ffe4713cb..c913321f80d8f792becfcefcddc843bf2faedfdb 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -609,6 +609,7 @@ typedef struct NR_UE_MAC_INST_s { bool pucch_power_control_initialized; int f_b_f_c; bool pusch_power_control_initialized; + int delta_msg2; } NR_UE_MAC_INST_t; /*@}*/ diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index e2d61251450793d0640986658212a741ef74ffa8..1f53812dec234fed796011e55728ca6abc749827 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -240,6 +240,12 @@ int get_pusch_tx_power_ue( bool is_rar_tx_retx, bool transform_precoding); +int get_srs_tx_power_ue(NR_UE_MAC_INST_t *mac, + NR_SRS_Resource_t *srs_resource, + NR_SRS_ResourceSet_t *srs_resource_set, + int delta_srs, + bool is_configured_for_pusch_on_current_bwp); + int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, int slot, frame_t frame, diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c index 36fbf3a527c9188d76df57135ce049958cf996bf..70d3aacb66957850403df417e249bff6eb0d9cd9 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c @@ -578,6 +578,7 @@ int get_pusch_tx_power_ue(NR_UE_MAC_INST_t *mac, DELTA_P_rampup = min(DELTA_P_rampup_requested, max(0, DELTA_P_rampup)); mac->f_b_f_c = DELTA_P_rampup + delta_pusch; mac->pusch_power_control_initialized = true; + mac->delta_msg2 = delta_pusch; } else { if (!((pusch_power_without_f_b_f_c + mac->f_b_f_c >= P_CMAX && delta_pusch > 0) || (pusch_power_without_f_b_f_c + mac->f_b_f_c <= P_CMIN && delta_pusch < 0))) { @@ -595,3 +596,84 @@ int get_pusch_tx_power_ue(NR_UE_MAC_INST_t *mac, f_b_f_c); return min(P_CMAX, P_O_PUSCH + M_pusch_component + alpha * pathloss + DELTA_TF + f_b_f_c); } + +int get_srs_tx_power_ue(NR_UE_MAC_INST_t *mac, + NR_SRS_Resource_t *srs_resource, + NR_SRS_ResourceSet_t *srs_resource_set, + int delta_srs, + bool is_configured_for_pusch_on_current_bwp) +{ + NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; + AssertFatal(current_UL_BWP, "Missing configuration: need UL_BWP to calculate SRS tx power\n"); + AssertFatal(srs_resource_set->p0, "P0 mantatory present at configuration\n"); + int P_0_SRS = *srs_resource_set->p0; + + // alpha is optional, use same default as PUSCH + const float alpha_factor_table[8] = {0.0f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f}; + float alpha = srs_resource_set->alpha ? alpha_factor_table[*srs_resource_set->alpha] : 1.0f; + int m_srs_component = + 10 * log10(pow(2, current_UL_BWP->scs) * get_m_srs(srs_resource->freqHopping.c_SRS, srs_resource->freqHopping.b_SRS)); + + // The allowed MPR for SRS, PUCCH formats 0, 1, 3 and 4, and PRACH shall be as specified for QPSK modulated DFTs-OFDM of + // equivalent RB allocation. The allowed MPR for PUCCH format 2 shall be as specified for QPSK modulated CP-OFDM of equivalent RB + // allocation. + int P_CMAX = nr_get_Pcmax(mac->p_Max, + mac->nr_band, + mac->frame_type, + mac->frequency_range, + mac->current_UL_BWP->channel_bandwidth, + 2, + false, + mac->current_UL_BWP->scs, + mac->current_UL_BWP->BWPSize, + true, + get_m_srs(srs_resource->freqHopping.c_SRS, srs_resource->freqHopping.b_SRS), + 0); // TODO: Determine SRS start RB + + int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm); + + int srs_power_without_h_b_f_c = P_0_SRS + alpha * pathloss + m_srs_component; + + // Power adjustment state + int h_b_f_c = 0; + bool use_pusch_power_adjustment_state = srs_resource_set->srs_PowerControlAdjustmentStates == NULL; + if (is_configured_for_pusch_on_current_bwp && use_pusch_power_adjustment_state) { + // Case 1: Use PUSCH power control adjustment state + h_b_f_c = mac->f_b_f_c; + } else { + // Case 2: Separate power control adjustment state + AssertFatal(srs_resource_set->srs_PowerControlAdjustmentStates == NULL + || *srs_resource_set->srs_PowerControlAdjustmentStates + != NR_SRS_ResourceSet__srs_PowerControlAdjustmentStates_sameAsFci2, + "Two PUSCH power adjustment states not supported"); + + bool is_tpc_accumulation_provided = current_UL_BWP->srs_Config != NULL && current_UL_BWP->srs_Config->tpc_Accumulation != NULL; + bool separate_pc_adjustment_state = srs_resource_set->srs_PowerControlAdjustmentStates + && *srs_resource_set->srs_PowerControlAdjustmentStates + == NR_SRS_ResourceSet__srs_PowerControlAdjustmentStates_separateClosedLoop; + + if (!is_tpc_accumulation_provided && (!is_configured_for_pusch_on_current_bwp || separate_pc_adjustment_state)) { + if (!current_UL_BWP->srs_power_control_initialized) { + NR_PRACH_RESOURCES_t *prach_resources = &mac->ra.prach_resources; + float DELTA_P_rampup_requested = + (prach_resources->RA_PREAMBLE_POWER_RAMPING_COUNTER - 1) * prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP; + float DELTA_P_rampup = P_CMAX - (P_0_SRS + m_srs_component + alpha * pathloss); + DELTA_P_rampup = min(DELTA_P_rampup_requested, max(0, DELTA_P_rampup)); + current_UL_BWP->srs_power_control_initialized = true; + current_UL_BWP->h_b_f_c = DELTA_P_rampup + mac->delta_msg2; + } else { + int P_CMIN = mac->current_UL_BWP->P_CMIN; + if (!((srs_power_without_h_b_f_c + current_UL_BWP->h_b_f_c >= P_CMAX && delta_srs > 0) + || (srs_power_without_h_b_f_c + current_UL_BWP->h_b_f_c <= P_CMIN && delta_srs < 0))) { + current_UL_BWP->h_b_f_c += delta_srs; + } + } + h_b_f_c = current_UL_BWP->h_b_f_c; + } else { + // Case 3: No accumulation + h_b_f_c = delta_srs; + } + } + + return min(P_CMAX, srs_power_without_h_b_f_c + h_b_f_c); +} diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 84a35dcf52442eee874727868e6a15097b269370..a076829a8a3fab58404bf16eed8426ce9bd67b08 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -1058,7 +1058,8 @@ int configure_srs_pdu(NR_UE_MAC_INST_t *mac, NR_SRS_Resource_t *srs_resource, fapi_nr_ul_config_srs_pdu *srs_config_pdu, int period, - int offset) + int offset, + NR_SRS_ResourceSet_t *srs_resource_set) { NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; @@ -1100,6 +1101,11 @@ int configure_srs_pdu(NR_UE_MAC_INST_t *mac, srs_config_pdu->t_offset = offset; } + bool is_configured_for_pusch_on_current_bwp = true; + int delta_srs = 0; // DCI format 2_3 not implemented + srs_config_pdu->tx_power = + get_srs_tx_power_ue(mac, srs_resource, srs_resource_set, delta_srs, is_configured_for_pusch_on_current_bwp); + #ifdef SRS_DEBUG LOG_I(NR_MAC,"Frame = %i, slot = %i\n", frame, slot); LOG_I(NR_MAC,"srs_config_pdu->rnti = 0x%04x\n", srs_config_pdu->rnti); @@ -1142,10 +1148,11 @@ void nr_ue_aperiodic_srs_scheduling(NR_UE_MAC_INST_t *mac, long resource_trigger int slot_offset = 0; NR_SRS_Resource_t *srs_resource = NULL; + NR_SRS_ResourceSet_t *srs_resource_set = NULL; for(int rs = 0; rs < srs_config->srs_ResourceSetToAddModList->list.count; rs++) { // Find aperiodic resource set - NR_SRS_ResourceSet_t *srs_resource_set = srs_config->srs_ResourceSetToAddModList->list.array[rs]; + srs_resource_set = srs_config->srs_ResourceSetToAddModList->list.array[rs]; if(srs_resource_set->resourceType.present != NR_SRS_ResourceSet__resourceType_PR_aperiodic) continue; // the resource trigger need to match the DCI one @@ -1186,7 +1193,7 @@ void nr_ue_aperiodic_srs_scheduling(NR_UE_MAC_INST_t *mac, long resource_trigger fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, sched_frame, sched_slot, FAPI_NR_UL_CONFIG_TYPE_SRS); if (!pdu) return; - int ret = configure_srs_pdu(mac, srs_resource, &pdu->srs_config_pdu, 0, 0); + int ret = configure_srs_pdu(mac, srs_resource, &pdu->srs_config_pdu, 0, 0, srs_resource_set); if (ret != 0) remove_ul_config_last_item(pdu); release_ul_config(pdu, false); @@ -1204,9 +1211,10 @@ static bool nr_ue_periodic_srs_scheduling(NR_UE_MAC_INST_t *mac, frame_t frame, } bool srs_scheduled = false; + NR_SRS_ResourceSet_t *srs_resource_set = NULL; for(int rs = 0; rs < srs_config->srs_ResourceSetToAddModList->list.count; rs++) { // Find periodic resource set - NR_SRS_ResourceSet_t *srs_resource_set = srs_config->srs_ResourceSetToAddModList->list.array[rs]; + srs_resource_set = srs_config->srs_ResourceSetToAddModList->list.array[rs]; if(srs_resource_set->resourceType.present != NR_SRS_ResourceSet__resourceType_PR_periodic) { continue; } @@ -1237,7 +1245,7 @@ static bool nr_ue_periodic_srs_scheduling(NR_UE_MAC_INST_t *mac, frame_t frame, fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, frame, slot, FAPI_NR_UL_CONFIG_TYPE_SRS); if (!pdu) return false; - int ret = configure_srs_pdu(mac, srs_resource, &pdu->srs_config_pdu, period, offset); + int ret = configure_srs_pdu(mac, srs_resource, &pdu->srs_config_pdu, period, offset, srs_resource_set); if (ret != 0) remove_ul_config_last_item(pdu); else diff --git a/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_power_procedures.cpp b/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_power_procedures.cpp index c8467241b8ef1f51b15b7d42257b8eade0ca70d1..760de0df3d2c4d192b20ec943872689ba2e9f560 100644 --- a/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_power_procedures.cpp +++ b/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_power_procedures.cpp @@ -594,6 +594,125 @@ TEST(test_pcmax, test_non_obvious_bwp_size) nr_get_Pcmax(23, nr_band, frame_type, FR1, channel_bandwidth, 2, false, 1, N_RB_UL, false, 6, prb_start)); } +TEST(test_srs_power, use_pusch_power_adjustment_state) +{ + NR_UE_MAC_INST_t mac = {0}; + NR_UE_UL_BWP_t current_UL_BWP = {0}; + current_UL_BWP.scs = 1; + current_UL_BWP.BWPSize = 106; + mac.current_UL_BWP = ¤t_UL_BWP; + NR_SRS_Resource_t srs_resource = {0}; + NR_SRS_ResourceSet_t srs_resource_set = {0}; + bool is_configured_for_pusch_on_current_bwp = true; + int delta_srs = 0; + srs_resource_set.srs_PowerControlAdjustmentStates = NULL; + mac.nr_band = 78; + mac.f_b_f_c = 0; + mac.pusch_power_control_initialized = true; + long p0 = 0; + srs_resource_set.p0 = &p0; + + int tx_power = get_srs_tx_power_ue(&mac, &srs_resource, &srs_resource_set, delta_srs, is_configured_for_pusch_on_current_bwp); + + mac.f_b_f_c = 4; + + int increased_tx_power = + get_srs_tx_power_ue(&mac, &srs_resource, &srs_resource_set, delta_srs, is_configured_for_pusch_on_current_bwp); + EXPECT_EQ(tx_power + mac.f_b_f_c, increased_tx_power); +} + +TEST(test_srs_power, no_support_for_two_pusch_power_adjustment_states) +{ + NR_UE_MAC_INST_t mac = {0}; + NR_UE_UL_BWP_t current_UL_BWP = {0}; + current_UL_BWP.scs = 1; + current_UL_BWP.BWPSize = 106; + mac.current_UL_BWP = ¤t_UL_BWP; + NR_SRS_Resource_t srs_resource = {0}; + NR_SRS_ResourceSet_t srs_resource_set = {0}; + long p0 = 0; + srs_resource_set.p0 = &p0; + bool is_configured_for_pusch_on_current_bwp = true; + int delta_srs = 0; + long srs_PowerControlAdjustmentStates = NR_SRS_ResourceSet__srs_PowerControlAdjustmentStates_sameAsFci2; + srs_resource_set.srs_PowerControlAdjustmentStates = &srs_PowerControlAdjustmentStates; + mac.nr_band = 78; + mac.f_b_f_c = 0; + mac.pusch_power_control_initialized = true; + + EXPECT_DEATH(get_srs_tx_power_ue(&mac, &srs_resource, &srs_resource_set, delta_srs, is_configured_for_pusch_on_current_bwp), + "Two PUSCH power adjustment states not supported"); +} + +TEST(test_srs_power, no_tpc_accumulation) +{ + NR_UE_MAC_INST_t mac = {0}; + NR_UE_UL_BWP_t current_UL_BWP = {0}; + current_UL_BWP.scs = 1; + current_UL_BWP.BWPSize = 106; + mac.current_UL_BWP = ¤t_UL_BWP; + NR_SRS_Resource_t srs_resource = {0}; + NR_SRS_ResourceSet_t srs_resource_set = {0}; + long p0 = 0; + srs_resource_set.p0 = &p0; + bool is_configured_for_pusch_on_current_bwp = true; + int delta_srs = 0; + long srs_PowerControlAdjustmentStates = NR_SRS_ResourceSet__srs_PowerControlAdjustmentStates_separateClosedLoop; + srs_resource_set.srs_PowerControlAdjustmentStates = &srs_PowerControlAdjustmentStates; + mac.nr_band = 78; + mac.f_b_f_c = 0; + mac.pusch_power_control_initialized = true; + + NR_SRS_Config_t srs_Config = {0}; + long tpc_Accumulation = 0; + srs_Config.tpc_Accumulation = &tpc_Accumulation; + current_UL_BWP.srs_Config = &srs_Config; + + int tx_power = get_srs_tx_power_ue(&mac, &srs_resource, &srs_resource_set, delta_srs, is_configured_for_pusch_on_current_bwp); + + delta_srs = 4; + + int increased_tx_power = + get_srs_tx_power_ue(&mac, &srs_resource, &srs_resource_set, delta_srs, is_configured_for_pusch_on_current_bwp); + EXPECT_EQ(tx_power + delta_srs, increased_tx_power); +} + +TEST(test_srs_power, tpc_accumulation) +{ + NR_UE_MAC_INST_t mac = {0}; + NR_UE_UL_BWP_t current_UL_BWP = {0}; + current_UL_BWP.scs = 1; + current_UL_BWP.BWPSize = 106; + mac.current_UL_BWP = ¤t_UL_BWP; + NR_SRS_Resource_t srs_resource = {0}; + NR_SRS_ResourceSet_t srs_resource_set = {0}; + long p0 = 0; + srs_resource_set.p0 = &p0; + bool is_configured_for_pusch_on_current_bwp = true; + int delta_srs = 0; + long srs_PowerControlAdjustmentStates = NR_SRS_ResourceSet__srs_PowerControlAdjustmentStates_separateClosedLoop; + srs_resource_set.srs_PowerControlAdjustmentStates = &srs_PowerControlAdjustmentStates; + mac.nr_band = 78; + mac.f_b_f_c = 0; + mac.pusch_power_control_initialized = true; + current_UL_BWP.srs_power_control_initialized = true; + + NR_SRS_Config_t srs_Config = {0}; + current_UL_BWP.srs_Config = &srs_Config; + + int tx_power = get_srs_tx_power_ue(&mac, &srs_resource, &srs_resource_set, delta_srs, is_configured_for_pusch_on_current_bwp); + + delta_srs = 4; + + int increased_tx_power = + get_srs_tx_power_ue(&mac, &srs_resource, &srs_resource_set, delta_srs, is_configured_for_pusch_on_current_bwp); + EXPECT_EQ(tx_power + delta_srs, increased_tx_power); + + int more_tx_power = + get_srs_tx_power_ue(&mac, &srs_resource, &srs_resource_set, delta_srs, is_configured_for_pusch_on_current_bwp); + EXPECT_EQ(tx_power + delta_srs * 2, more_tx_power); +} + int main(int argc, char** argv) { logInit(); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 6d0dc011127d718c076e5bb93f5db39f80b5a31c..4cf6da74337dc82c54be472fd79aa53a8ebee6a7 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -3175,21 +3175,23 @@ void send_initial_ul_rrc_message(int rnti, const uint8_t *sdu, sdu_size_t sdu_le mac->mac_rrc.initial_ul_rrc_message_transfer(0, &ul_rrc_msg); } -void prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE) +bool prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE) { NR_SCHED_ENSURE_LOCKED(&mac->sched_lock); + + /* activate SRB0 */ + if (!nr_rlc_activate_srb0(UE->rnti, UE, send_initial_ul_rrc_message)) + return false; + /* create this UE's initial CellGroup */ int CC_id = 0; int srb_id = 1; const NR_ServingCellConfigCommon_t *scc = mac->common_channels[CC_id].ServingCellConfigCommon; const NR_ServingCellConfig_t *sccd = mac->common_channels[CC_id].pre_ServingCellConfig; NR_CellGroupConfig_t *cellGroupConfig = get_initial_cellGroupConfig(UE->uid, scc, sccd, &mac->radio_config); - + ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->CellGroup); UE->CellGroup = cellGroupConfig; - /* activate SRB0 */ - nr_rlc_activate_srb0(UE->rnti, UE, send_initial_ul_rrc_message); - /* the cellGroup sent to CU specifies there is SRB1, so create it */ DevAssert(cellGroupConfig->rlc_BearerToAddModList->list.count == 1); const NR_RLC_BearerConfig_t *bearer = cellGroupConfig->rlc_BearerToAddModList->list.array[0]; @@ -3199,6 +3201,7 @@ void prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE) int priority = bearer->mac_LogicalChannelConfig->ul_SpecificParameters->priority; nr_lc_config_t c = {.lcid = bearer->logicalChannelIdentity, .priority = priority}; nr_mac_add_lcid(&UE->UE_sched_ctrl, &c); + return true; } void nr_mac_trigger_release_timer(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpacing_t subcarrier_spacing) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 50dd276770be9a26c6c7956a8efb3e2c6b136e5e..cb233eae1bb8920fbec3c52efc3719560c7422f1 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -444,20 +444,23 @@ static int nr_process_mac_pdu(instance_t module_idP, mac_len = 6; } - LOG_D(MAC, "[RAPROC] Received SDU for CCCH length %d for UE %04x\n", mac_len, UE->rnti); - - prepare_initial_ul_rrc_message(RC.nrmac[module_idP], UE); - mac_rlc_data_ind(module_idP, - UE->rnti, - module_idP, - frameP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - 0, - (char *) (pduP + mac_subheader_len), - mac_len, - 1, - NULL); + LOG_I(MAC, "[RAPROC] Received SDU for CCCH length %d for UE %04x\n", mac_len, UE->rnti); + + if (prepare_initial_ul_rrc_message(RC.nrmac[module_idP], UE)) { + mac_rlc_data_ind(module_idP, + UE->rnti, + module_idP, + frameP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + 0, + (char *) (pduP + mac_subheader_len), + mac_len, + 1, + NULL); + } else { + LOG_E(NR_MAC, "prepare_initial_ul_rrc_message() returned false, cannot forward CCCH message\n"); + } break; case UL_SCH_LCID_DTCH ... (UL_SCH_LCID_DTCH + 28): @@ -498,7 +501,7 @@ static int nr_process_mac_pdu(instance_t module_idP, break; default: - LOG_E(NR_MAC, "Received unknown MAC header (LCID = 0x%02x)\n", rx_lcid); + LOG_E(NR_MAC, "RNTI %0x, received unknown MAC header (LCID = 0x%02x)\n", UE->rnti, rx_lcid); return -1; break; } diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index a869e172fdcb7aae3df94bdb052b152a2178bcc4..756ddbb39e26841efe52dd96acf0ede169aab462 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -449,7 +449,7 @@ size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset long get_lcid_from_drbid(int drb_id); long get_lcid_from_srbid(int srb_id); -void prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE); +bool prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE); void send_initial_ul_rrc_message(int rnti, const uint8_t *sdu, sdu_size_t sdu_len, void *data); void finish_nr_dl_harq(NR_UE_sched_ctrl_t *sched_ctrl, int harq_pid); diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 46e0da26cf7849e3e3dd38f81d9b8f3bc40c0ed1..b8fd1488763ee0aa7131c69fb46a3b435ae958ff 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -983,10 +983,17 @@ void deliver_sdu_srb0(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, s0->send_initial_ul_rrc_message(s0->ue_id, (unsigned char *)buf, size, s0->data); } -void nr_rlc_activate_srb0(int ue_id, +bool nr_rlc_activate_srb0(int ue_id, void *data, void (*send_initial_ul_rrc_message)(int ue_id, const uint8_t *sdu, sdu_size_t sdu_len, void *data)) { + nr_rlc_manager_lock(nr_rlc_ue_manager); + nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id); + if (ue->srb0 != NULL) { + LOG_W(RLC, "SRB0 already exists for UE %x, do nothing\n", ue_id); + nr_rlc_manager_unlock(nr_rlc_ue_manager); + return false; + } struct srb0_data *srb0_data = calloc(1, sizeof(struct srb0_data)); AssertFatal(srb0_data, "out of memory\n"); @@ -994,21 +1001,13 @@ void nr_rlc_activate_srb0(int ue_id, srb0_data->data = data; srb0_data->send_initial_ul_rrc_message = send_initial_ul_rrc_message; - nr_rlc_manager_lock(nr_rlc_ue_manager); - nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id); - if (ue->srb0 != NULL) { - LOG_W(RLC, "SRB0 already exists for UE %d, do nothing\n", ue_id); - free(srb0_data); - nr_rlc_manager_unlock(nr_rlc_ue_manager); - return; - } - nr_rlc_entity_t *nr_rlc_tm = new_nr_rlc_entity_tm(10000, - deliver_sdu_srb0, srb0_data); + deliver_sdu_srb0, srb0_data); nr_rlc_ue_add_srb_rlc_entity(ue, 0, nr_rlc_tm); LOG_I(RLC, "Activated srb0 for UE %d\n", ue_id); nr_rlc_manager_unlock(nr_rlc_ue_manager); + return true; } rlc_op_status_t rrc_rlc_config_req(const protocol_ctxt_t* const ctxt_pP, diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h index ea47b00f03ca837e649f374e90bf9b0868e10bd7..736c42a0b70f2950b37bac3239c48561fd4b09b6 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h @@ -62,7 +62,7 @@ void nr_rlc_activate_avg_time_to_tx(const int ue_id, const logical_chan_id_t cha void nr_rlc_srb_recv_sdu(const int ue_id, const logical_chan_id_t channel_id, unsigned char *buf, int size); -void nr_rlc_activate_srb0(int ue_id, +bool nr_rlc_activate_srb0(int ue_id, void *data, void (*send_initial_ul_rrc_message)(int rnti, const uint8_t *sdu, sdu_size_t sdu_len, void *data)); diff --git a/tools/formatting/README.md b/tools/formatting/README.md new file mode 100644 index 0000000000000000000000000000000000000000..fe01ed8002867d11ce21810f4d92390eaf98f4da --- /dev/null +++ b/tools/formatting/README.md @@ -0,0 +1,26 @@ +# Overview + +Dockerized tool to list clang-format errors introduced in a branch. + +# Usage + +Checkout the branch you want to compare. This is necessary because if there are files added by the branch +they need to be present for clang-format to analyze them. + +Then: + +``` +./tools/formatting/detect_clang_format_errors.sh +``` + +Or + +``` +docker compose up +``` + +Or (to avoid docker related lines in stdout) + +``` +docker compose run clang-formatter | tee output +``` diff --git a/tools/formatting/detect_clang_format_errors.sh b/tools/formatting/detect_clang_format_errors.sh new file mode 100755 index 0000000000000000000000000000000000000000..e8d0c89787682f3fd0ed695b0900900e7825b197 --- /dev/null +++ b/tools/formatting/detect_clang_format_errors.sh @@ -0,0 +1,5 @@ +#!/bin/bash +set -eo pipefail + +BASE_COMMIT=$(git merge-base HEAD origin/develop) +git diff -U0 --no-color $BASE_COMMIT...HEAD | clang-format-diff -p1 diff --git a/tools/formatting/docker-compose.yaml b/tools/formatting/docker-compose.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d2fa77de72739e712a00cbb2f434957b8bd7935e --- /dev/null +++ b/tools/formatting/docker-compose.yaml @@ -0,0 +1,13 @@ +services: + clang-formatter: + image: clang-formatter + build: + dockerfile_inline: | + FROM ubuntu:22.04 + RUN DEBIAN_FRONTEND=noninteractive apt update && apt install -y git clang-format + volumes: + - ../../:/code/ + command: + bash -c "git config --global --add safe.directory /code && cd /code/ && \ + git config --global clangFormat.style file && \ + ./tools/formatting/detect_clang_format_errors.sh"