Compare commits

...

531 Commits

Author SHA1 Message Date
Raymond Knopp
149034887c log reduction 2023-07-27 16:34:46 +02:00
Raymond Knopp
5917f0f2b8 initial synch : SSS threshold condition removed 2023-07-27 12:36:36 +02:00
Raymond Knopp
6832959b0b bugfix in command-line parameters 2023-07-26 21:09:54 +02:00
ue1
e7b42f419b Merge branch 'sl-eurecom' of https://gitlab.eurecom.fr/oai/openairinterface5g into sl-eurecom 2023-07-26 13:46:14 -04:00
ue1
d629498b98 testing sync-ref 2023-07-26 13:44:31 -04:00
Raymond Knopp
1c01343d49 Merge branch 'sl-eurecom' of https://gitlab.eurecom.fr/oai/openairinterface5g into sl-eurecom 2023-07-26 19:38:28 +02:00
Raymond Knopp
f633fc8d96 testing 2023-07-26 19:35:38 +02:00
Raymond Knopp
5e28985954 Merge branch 'sl-eurecom' of https://gitlab.eurecom.fr/oai/openairinterface5g into sl-eurecom 2023-07-26 13:28:00 -04:00
Raymond Knopp
af662183f4 debugging OTA 2023-07-26 13:25:14 -04:00
Raymond Knopp
efccb416cc command line parameter --sync-ref added again 2023-07-25 23:11:17 +02:00
Raymond Knopp
4232baec52 "synchronized" PSBCH simulation working now 2023-06-08 16:10:00 +02:00
Raymond Knopp
2f19c2de4d Modifications for SL-SSB. 2023-06-08 14:43:28 +02:00
Melissa Elkadi
b17e862742 Fixing build errors 2023-05-10 08:05:50 -07:00
Melissa
d680bb83b2 Merge branch 'develop' into 'episys-merge-develop-sl'
# Conflicts:
#   openair2/LAYER2/NR_MAC_UE/main_ue_nr.c
2023-05-08 14:26:24 +00:00
Melissa Elkadi
50923c7f80 Merge branch 'eurecom-develop' into episys-merge-develop-sl 2023-05-05 10:51:22 -07:00
Melissa Elkadi
90e5db3728 Removing unnecessary changes to unit tests 2023-04-24 16:22:09 -07:00
Melissa Elkadi
c9bc86312f Merging in Adding new sidelink (SL) variables 2023-04-24 10:23:49 -07:00
Melissa Elkadi
7221a5f736 Some minor clean up 2023-04-24 10:07:43 -07:00
Melissa Elkadi
629b2c9fe3 Merge branch 'eurecom-develop' into episys-merge-develop-sl 2023-04-24 09:59:13 -07:00
Melissa Elkadi
9f91dbd9bb Merge branch 'episys-merge-develop-sl' of https://gitlab.eurecom.fr/oai/openairinterface5g into episys-merge-develop-sl 2023-04-24 09:48:47 -07:00
Melissa Elkadi
a354ce01cf Updating SL TX side for PSS and SSS. Also propberly setting d_sss 2023-04-24 09:48:31 -07:00
Melissa Elkadi
93d32eca45 Updating SL TX side for PSS and SSS. Also propberly setting d_sss 2023-04-24 09:31:38 -07:00
Melissa Elkadi
053d8d938f Fixing PSBCHSIM for sidelink finally! 2023-04-21 17:09:44 -07:00
Melissa Elkadi
cf4a22b58a Fixing build failure 2023-04-21 16:40:28 -07:00
Melissa Elkadi
75e9db0633 More conversions 2023-04-21 16:38:43 -07:00
Melissa Elkadi
24bf0d8046 More conversions for int16_t to c16_t 2023-04-21 16:21:30 -07:00
Melissa Elkadi
d8627c91f3 Some more clean up to make review easier 2023-04-21 07:30:24 -07:00
Melissa Elkadi
ad8da84671 Fixing implicit declaration 2023-04-21 06:45:41 -07:00
Melissa Elkadi
f0f1121e9c Merge branch 'episys-merge-SL-variables' into episys-merge-develop-sl 2023-04-21 06:10:47 -07:00
Melissa Elkadi
9b8eae2256 Merge branch 'eurecom-develop' into episys-merge-SL-variables 2023-04-20 14:05:14 -07:00
Melissa Elkadi
e9e347043e Fixing typo and aligning input buffer 2023-04-18 11:09:15 -07:00
Melissa Elkadi
28741ed967 Reverting unnecessary CICD test change 2023-04-18 10:09:16 -07:00
Melissa Elkadi
608aa3ebc4 Adding 32 bit alignment to PSS variables 2023-04-18 09:59:51 -07:00
Melissa Elkadi
a6e18fe06a Merge branch 'eurecom-develop' into episys-merge-SL-variables 2023-04-18 09:29:56 -07:00
Melissa Elkadi
aa6468f95e Merge branch 'eurecom-develop' into episys-merge-SL-variables 2023-04-10 13:45:19 -07:00
Melissa Elkadi
f09fffdb2b Whitespace and updating pss_search_time_nr() footprint 2023-04-06 10:05:48 -07:00
Melissa Elkadi
376a9beb80 Adding __attribute__((aligned(32))) back in 2023-04-04 15:02:56 -07:00
Melissa Elkadi
0b892acef3 Updating simulator and adding memsets 2023-04-04 07:25:38 -07:00
Melissa Elkadi
73907e5ee2 Re-adding clean-up and refactoing now that pbch works! 2023-04-03 19:34:59 -07:00
Melissa Elkadi
703047eca9 Fixing build errors 2023-04-03 17:28:40 -07:00
Melissa Elkadi
5cbad19d19 Temporarily removing refactoring in PSS until I can understand the sync problems 2023-04-03 10:41:40 -07:00
Melissa Elkadi
d1e1f56199 Merge branch 'eurecom-develop' into episys-merge-SL-variables 2023-04-03 05:35:06 -07:00
Melissa Elkadi
61435e9066 More clean up and use of c16_t's - but PBCH sync is failing 2023-03-31 08:40:35 -07:00
Melissa Elkadi
ee8af9dcfb Fixing seg fault and removing unused variables for PHY testing 2023-03-30 11:39:18 -07:00
Melissa Elkadi
b7f47aa70a Refactoring and more clean up 2023-03-29 12:34:52 -07:00
Melissa Elkadi
066de7c3c5 Removing primary_synchro_nr2_sl and others 2023-03-28 16:36:03 -07:00
Melissa Elkadi
fec2a15bdf Merge branch 'eurecom-develop' into episys-merge-SL-variables 2023-03-27 14:24:12 -07:00
Melissa Elkadi
8cbe4bb1d1 Adding softmodem_params() to prach and pucchsim
The get_softmodem_params() function needs to be added
to set the mode for sl_mode (or not). Several places
in the code will check this mode and it should be added
to ensure the proper code path is followed.
2023-03-24 14:34:14 -07:00
Melissa Elkadi
a54ca2c6e3 Slowly implementing sidelink changes.
Specifically, in this commit, we will begin to
implement the #define variables required for
synchronization. These variables include offset
and payload size values that vary from the Uu
interface, in relation to the PSS, SSS and PBCH
elements. We also introduce the new sl_mode
command line flag, which is used to switch between
the Uu interface and SL interface. This will allow
us to modify exisitng PSS and SSS functions, without
copying complete 5G functions and only changing
a few lines to support sidelink mode.

Fixing formatting for softmodem-common.h

Fixing formatting for softmodem-common.h
2023-03-24 10:55:09 -07:00
Melissa Elkadi
e79756d7ab Merge branch 'eurecom-develop' into episys-merge-develop-sl 2023-03-20 12:27:28 -07:00
Melissa Elkadi
39b73391d4 This commit fixing the rfsimualtor
There were three main issues with the simulator.
1. PSS_SSS_SUB_CARRIER_START was not properly used in Uu mode
2. phy_procedures_nrUE_TX(UE, proc, &phy_data) missing last arg
3. Premature free was added in the MAC layer by us for some reason.
2023-03-20 12:24:04 -07:00
Melissa Elkadi
784be9d241 Removing unnecessary changes 2023-03-16 17:48:21 -07:00
Melissa Elkadi
5d378b6416 Passing in local rxdataF to nr_slot_fep_init_sync then memcpy into global 2023-03-15 17:44:27 -07:00
Melissa Elkadi
b6e5b3594c Merge branch 'eurecom-develop' into episys-merge-develop-sl 2023-03-15 12:49:34 -07:00
Melissa Elkadi
f79ab7e087 Merge branch 'eurecom-develop' into episys-merge-develop-sl 2023-03-15 06:37:38 -07:00
Melissa Elkadi
c6c004b8aa Getting rid of remaining warnings 2023-03-14 20:11:27 -07:00
Melissa Elkadi
2b193cded0 Reverting unnecessary changes 2023-03-14 19:02:17 -07:00
Melissa Elkadi
a07d4376d6 Merge branch 'eurecom-develop' into episys-merge-develop-sl 2023-03-13 11:29:55 -07:00
Melissa Elkadi
2f23bf1ea4 Fixing botched build_oai merge 2023-03-10 09:16:38 -08:00
Melissa Elkadi
d8e92e93b3 Merge branch 'eurecom-develop' into episys-merge-develop-sl 2023-03-09 11:09:17 -08:00
Melissa Elkadi
6db9c37e47 Fixing white space, and using c16_t in psbchsim 2023-03-09 05:43:19 -08:00
Melissa Elkadi
f596c6907a Reverting change to node_number initialization 2023-03-08 13:00:32 -08:00
Melissa Elkadi
d22d11d003 Fixing prachsim - get_softmodem_params was NULL 2023-03-08 12:25:02 -08:00
Melissa Elkadi
8bf5a0acf6 Using rxdataF in UE rather than local 2023-03-08 11:41:28 -08:00
Deokseong "David" Kim
95fc447472 Merge branch 'episys/ea/sidelink_frequency_update' into 'episys/master-sl'
Exploiting Sidelink carrier frequency for SL

See merge request aburger/openairinterface5g!185
2023-03-08 10:37:14 -08:00
Melissa Elkadi
5a61145948 Resolving all warning associated with c16_t conversion 2023-03-08 09:46:27 -08:00
Melissa Elkadi
751f06b15e Only preconfiguring SL for SL mode 2023-03-07 21:17:07 -08:00
David
98d5c1691c Adding NRUE_thread_SL back to nr_ue.c
Also, fixed all warning associated with switching
all global buffers on the NRUE side from int32_t to
c16_t
2023-03-06 17:01:41 -08:00
David
678e3f9a01 Merge branch 'develop' into episys-merge-develop-sl 2023-03-06 07:35:37 -08:00
Ejaz
ec1d5ead6a Only preconfigurating for SL in SL mode 2023-03-03 05:32:49 -08:00
David
7cbfbd6c92 Updating arg types in pss_sl_ch_est_nr 2023-03-02 14:23:46 -08:00
Melissa Elkadi
9338925b93 This commit is a large refactoring of UE_thread_sl
We chose to initially create our own (SL) version
of the UE_thread() function in the nr_ue.c. The original
function was then refactored and merged to the develop
branch. Now that it has been refactored, we have added
the UE SL support into the original function and removed
the UE_thread_sl function. This still needs to be validated
on the USRPs prior to merge. (It has been tested with RFSIM).

Also, a few more lingering warnings related to the int32_t -> c16_t
conversion
2023-03-01 14:14:28 -08:00
Melissa Elkadi
64b65cb5d9 Converting int16_t to c16_t struct 2023-03-01 09:18:22 -08:00
Melissa Elkadi
7b2d0dbf39 Merge branch 'eurecom-develop' into episys-merge-develop-sl 2023-02-28 14:21:21 -08:00
Melissa Elkadi
ac4c4defd3 Merge branch 'eurecom-develop' into episys-merge-develop-sl 2023-02-23 08:51:34 -08:00
Melissa Elkadi
816532d86c Removing PHY_SIDE_LINK definition 2023-02-23 08:31:14 -08:00
Melissa Elkadi
a96d727409 Merge branch 'episys-merge-develop-sl' of https://gitlab.eurecom.fr/oai/openairinterface5g into episys-merge-develop-sl 2023-02-23 08:29:06 -08:00
Melissa Elkadi
624fc5353e Forgot to update PSS_SEQ_OFFSET_SL - now it works 2023-02-23 08:19:53 -08:00
Melissa Elkadi
d609f3f5ae Removing PHY_SIDE_LINK variable and dependents 2023-02-23 06:57:53 -08:00
Melissa
bb525dc0ee Merge branch 'episys/sl_script_update_for_rfsim' into 'episys/master-sl'
Updated sidelink test script to include rfsim test.

See merge request aburger/openairinterface5g!188
2023-02-17 05:35:24 -08:00
Melissa Elkadi
1f432be612 Merge branch 'eurecom-develop' into episys-merge-develop-sl 2023-02-15 05:44:45 -08:00
Melissa Elkadi
b47cb76977 Removing unused PSS and SSS tests as well as bw variable 2023-02-15 05:42:27 -08:00
Melissa Elkadi
528e1d99d2 Adding test cases for nr_psbchsim 2023-02-14 14:52:10 -08:00
Melissa Elkadi
aba645dc93 Removing unused/not working PSS and SSS tests 2023-02-14 06:33:27 -08:00
Melissa Elkadi
468e7330de Adding back in DPHY_SIDE_LINK 2023-02-13 12:44:40 -08:00
Melissa Elkadi
e7d04ec14f Adding definition for MIBSLCH 2023-02-13 10:15:47 -08:00
Melissa Elkadi
600399aa63 Fixing white space and removing unrelated changes 2023-02-13 08:56:04 -08:00
Melissa Elkadi
56b87424db Removing LTE HO changes 2023-02-13 08:42:34 -08:00
Melissa Elkadi
7a1928dfd0 Removing nFAPI LTE HO changes from this MR 2023-02-13 08:20:46 -08:00
Melissa Elkadi
6c8112581b Reverting LTE code (removing LTE HO changes from this MR) 2023-02-13 08:16:58 -08:00
Melissa Elkadi
7e473ca971 Reverting docker-compose to original 2023-02-13 08:06:48 -08:00
Melissa Elkadi
7f40b90ceb Merge branch 'eurecom-develop' into episys-merge-develop-sl 2023-02-13 07:59:48 -08:00
Melissa Elkadi
7feb6ed41f Merge branch 'episys/master-sl' into episys-merge-develop-sl 2023-02-09 07:37:18 -08:00
Melissa Elkadi
6fbb4df0a3 CMDLINE_PARAMS_CHECK_DESC must be correct
When merging in the new --nfapi str CL option from
develop, the santizer was catching a null pointer in
config_checkstr_assign_integer(). To fix this, I logged
params and i in config_execcheck(). This showed that
only 36 CMDLINE_PARAMS_CHECKs were happening when we
have 41 CL options in executables/softmodem-common.h.

To fix this, I added 7 more { .s5 = { NULL } }, for the
remaining CL parameters defined. Furthermore, the .s3a
CL parameter must be associated with the new --nfapi
string, so if it does not properly line up with the CL
definitions order, it will fail. The logs added in
config_execcheck() will show this.
2023-02-09 06:50:43 -08:00
Melissa
89f11abe68 Merge branch 'episys/gNB_tdd_config' into 'episys/master-sl'
Episys/gNB_tdd_config

See merge request aburger/openairinterface5g!183
2023-02-07 23:39:43 +00:00
Moein Sadeghi
3362fa991f Episys/gNB_tdd_config 2023-02-07 23:39:43 +00:00
Melissa Elkadi
3614c221c4 Merge branch 'eurecom-develop' into episys-merge-develop-sl 2023-02-07 13:54:29 -08:00
Melissa Elkadi
298d822bd1 Merge branch 'episys/master-sl' into episys-merge-develop-sl 2023-02-07 13:14:57 -08:00
Melissa
6775b577fd Merge branch 'episys/david/counting_tx_sssb_in_tx_log' into 'episys/master-sl'
Adding Tx SSB count and measured RSRP value in the script.

See merge request aburger/openairinterface5g!180
2023-02-06 23:37:25 +00:00
David Kim
1283065946 Fixed delay time computation. 2023-02-06 15:02:16 -08:00
David Kim
50f4890faa Merge remote-tracking branch 'origin/episys/master-sl' into episys/david/counting_tx_sssb_in_tx_log 2023-02-06 10:16:29 -08:00
Melissa
03b75ed679 Merge branch 'episys/ea/sss_rsrp' into 'episys/master-sl'
Episys/ea/sss rsrp

See merge request aburger/openairinterface5g!182
2023-02-06 18:12:43 +00:00
Melissa
a91839e69c Episys/ea/sss rsrp 2023-02-06 18:12:43 +00:00
Melissa
2e34ab0190 Merge branch 'revert-a93da4a8' into 'episys/master-sl'
Revert "Merge branch 'episys/ea/sss_rsrp' into 'episys/master-sl'"

See merge request aburger/openairinterface5g!181
2023-02-06 18:09:11 +00:00
Melissa
e6abb12fb1 Revert "Merge branch 'episys/ea/sss_rsrp' into 'episys/master-sl'" 2023-02-06 18:09:11 +00:00
Melissa
a93da4a886 Merge branch 'episys/ea/sss_rsrp' into 'episys/master-sl'
Added RSRP calculation for SSB

See merge request aburger/openairinterface5g!179
2023-02-06 18:07:38 +00:00
Ejaz Ahmed
27e14a06c2 Added RSRP calculation for SSB 2023-02-06 18:07:38 +00:00
David Kim
028f92a3e2 Code cleanup. 2023-02-06 10:05:43 -08:00
David
bf6b8442f1 Added no-run option for log analysis only. 2023-02-03 12:55:21 -08:00
David
0f90a7c24c Added Sidelink SSB RSRP metric value in the script result. 2023-02-03 12:05:40 -08:00
David
0e84775e29 Merge branch 'episys/ea/sss_rsrp' into episys/david/counting_tx_sssb_in_tx_log 2023-02-02 16:17:42 -08:00
David
0e0fc7eab4 Counting the number tx Sidelink SSB for sync.
1. Parsed tx log file in case that SyncRef UE was found.
2. Counted the number of tx Sidelink SSB until sync.
3. Added average statistics for multiple iternations.
2023-02-02 15:17:31 -08:00
Ejaz
323f52aeb1 Code cleanup in log and format adjustment. 2023-02-02 12:12:11 -08:00
Ejaz
334fbb8879 Fixed symbol_offset and ssb_offset in rsrp measurement method 2023-02-02 11:48:40 -08:00
Melissa Elkadi
39d54215bd Removing whitespace 2023-02-01 16:59:10 -08:00
David
bb580fae58 Adding the time option to logs and removing color
By modifying the reported logs on the rx side, we
can then use the test script to analyze these logs
and figure out the time it took to achieve sync.
2023-02-01 16:38:35 -08:00
Melissa
783e3d0da6 Merge branch 'episys/add-test-metrics' into 'episys/master-sl'
Fixing spacing for test script

See merge request aburger/openairinterface5g!177
2023-02-01 23:20:17 +00:00
Melissa Elkadi
3fc1825e44 Fixing spacing for test script 2023-02-01 15:19:29 -08:00
Ejaz
c0bf78efa0 Separated SyncRef and UE in logs 2023-02-01 14:58:26 -08:00
Ejaz
c4f4a5d793 Merge branch 'episys/master-sl' into episys/ea/sss_rsrp 2023-02-01 14:49:54 -08:00
Ejaz
b6247b075b Fixed ssb index issue 2023-02-01 14:47:30 -08:00
Melissa
cfdfe6aaa7 Merge branch 'episys/david/updating_sl_launch_script' into 'episys/master-sl'
Updated sidelink launching script.

See merge request aburger/openairinterface5g!175
2023-02-01 22:40:45 +00:00
Deokseong "David" Kim
709efd5da5 Updated sidelink launching script. 2023-02-01 22:40:45 +00:00
Ejaz
d9e487359d Merge branch 'episys/master-sl' into episys/ea/for_merging_changes_4m_sss_rsrp 2023-02-01 12:06:05 -08:00
Ejaz
500069fcf0 Added Second SSS in rsrp calculation 2023-02-01 12:05:40 -08:00
Ejaz
99fb046474 Replaced ue->is_synchronized with ue->is_synchronized_sl 2023-02-01 12:05:10 -08:00
Ejaz
c8ace3b540 Added nr_ue_sl_ssb_rsrp_measurements function 2023-02-01 12:04:32 -08:00
Melissa
6fc62b0184 Merge branch 'episys/david/adding_sl_launch_scripts' into 'episys/master-sl'
Added sidelink launch scripts for both SyncRef UE and Nearby UE.

See merge request aburger/openairinterface5g!174
2023-02-01 14:54:29 +00:00
Melissa
085e84dc38 Merge branch 'episys/ea/fixed_nid_sl_calculation' into 'episys/master-sl'
Fixed nid_sl calculation formula

See merge request aburger/openairinterface5g!173
2023-02-01 14:29:49 +00:00
Ejaz Ahmed
b1407040b6 Fixed nid_sl calculation formula 2023-02-01 14:29:49 +00:00
David
88accf144e Fixed typo error in the log. 2023-01-31 18:48:12 -08:00
David
a7c5a0bb29 Indentation was changed to spaces. 2023-01-31 18:20:18 -08:00
David
2949d00083 Added sidelink launch scripts for both SyncRef UE and Nearby UE.
1. run_sl_usrp.py for launching both SyncRef UE and Nearby UE.
2. sl_rx_agent.py will be trigged by run_sl_usrp.py for Nearby UE
3. sl_usrp_cmds.txt for sidelink usrp commands.
2023-01-31 17:58:49 -08:00
Melissa
8378127c2c Merge branch 'episys/fixed_sync_ref_inconsistentency_issue' into 'episys/master-sl'
Replaced synch with sync

See merge request aburger/openairinterface5g!172
2023-01-31 23:51:23 +00:00
Ejaz Ahmed
e1d9d15b2c Replaced synch with sync 2023-01-31 23:51:23 +00:00
Melissa
53eb37e674 Merge branch 'episys/ssb_time_slot' into 'episys/master-sl'
ssb time slot allocation

See merge request aburger/openairinterface5g!171
2023-01-31 23:14:09 +00:00
Melissa Elkadi
682b1be022 Merge branch 'episys/master-sl' into episys/ssb_time_slot 2023-01-31 15:12:56 -08:00
Melissa Elkadi
f4047b7aa4 Removing commented code 2023-01-31 15:11:48 -08:00
Melissa
34d80d4754 Merge branch 'episys/ea/nid_1_nid_2_flags' into 'episys/master-sl'
Added nid1 and nid2 flags

See merge request aburger/openairinterface5g!170
2023-01-31 19:38:20 +00:00
Ejaz Ahmed
5dc3663f16 Added nid1 and nid2 flags 2023-01-31 19:38:20 +00:00
Melissa
de54ec5b8b Merge branch 'episys/fixing-cl-dl-freq' into 'episys/master-sl'
Calling nr_init_frame_parms_ue_sa we can dynamically set the tx/rx freq

See merge request aburger/openairinterface5g!169
2023-01-31 19:34:05 +00:00
Melissa
ce07b567d0 Calling nr_init_frame_parms_ue_sa we can dynamically set the tx/rx freq 2023-01-31 19:34:05 +00:00
Moein Sadeghi
4ee9a6d8c6 last commit was not correct commit. this time it is resolved ! 2023-01-31 10:36:15 -08:00
Moein Sadeghi
39726e3274 resolved merge conflict 2023-01-31 10:30:03 -08:00
Ejaz
0d5dcbbccb Merge branch 'episys-merge-develop-sl' of gitlab.int-episci.com:aburger/openairinterface5g into episys-merge-develop-sl 2023-01-31 07:38:48 -08:00
Ejaz
684f762fd9 Merge branch 'episys/fixing-cl-dl-freq' into episys-merge-develop-sl 2023-01-31 07:35:47 -08:00
David
b95722b670 Merge branch 'episys/fixing-cl-dl-freq' into episys-merge-develop-sl 2023-01-31 07:35:39 -08:00
David
b431e042fc Calling nr_init_frame_parms_ue_sa we can dynamically set the tx/rx freq
Additionally, there were a few variables defined as PARAMBOOLs
rather than ints in the softmodem-common.h so they were not properly
updated from the CL. Lastly, setting a default value for dl_freq.
2023-01-31 06:51:34 -08:00
Moein Sadeghi
43e8dcd7b6 appropriate formatting 2023-01-30 15:46:34 -08:00
Moein Sadeghi
5ea2e6d029 feature is working in rfsim 2023-01-30 15:01:21 -08:00
Moein Sadeghi
7cdf6847f1 modification regardgin SSB slot allocation 2023-01-27 12:00:22 -08:00
Melissa Elkadi
1483d53e28 Using rxdataF instead of local passed around 2023-01-23 14:44:13 -08:00
Melissa Elkadi
8727d12d18 Properly allocating common_vars->rxdataF 2023-01-23 09:12:03 -08:00
Melissa Elkadi
6f6a314ab6 Merge branch 'eurecom-develop' into episys-merge-develop-sl 2023-01-23 08:39:32 -08:00
Melissa
77f069c1af Merge branch 'episys/timestamp_sl_debug' into 'episys/master-sl'
Synchronization is working on USRPs OTA!

See merge request aburger/openairinterface5g!168
2023-01-20 22:39:13 +00:00
Melissa Elkadi
6a2f5664b8 Fixing whitespace 2023-01-20 14:38:42 -08:00
Ejaz
6d51179357 Adding/fixing whitespace 2023-01-16 13:03:32 -08:00
Ejaz
720b2669fd Properly updating the SSB start location 2023-01-16 12:55:26 -08:00
Ejaz
9ffe2b7851 Reverting write timestamps since these changes did not effect sync 2023-01-16 11:46:20 -08:00
Ejaz
6befa6b3b0 Reverting check for nr_slot_tx == 20 becasue not possible 2023-01-16 11:28:57 -08:00
Ejaz
d497806c6c Properly setting SSB offset.
Previously, we hackily changed the rx_offset right before
taking the DFT. It is better for us to properly calculate
the SSB offset. This is done by subtracting off the prefix
symbols of every symbol that exists before the correalted
PSS.
2023-01-16 11:14:29 -08:00
Ejaz
475f99195e Reverting hack 2023-01-16 10:25:37 -08:00
Ejaz
e1c152fbcf This rx_offset change is how we are able to get sync 2023-01-16 10:12:24 -08:00
Ejaz
0db28d4f5a Removing unnecessary changes 2023-01-16 09:55:50 -08:00
Ejaz
e344d531f9 Fixing merge conflicts. 2023-01-16 09:53:10 -08:00
Ejaz
433f3d1507 Reverting white space changes and unnecessary check for overflow 2023-01-16 09:50:20 -08:00
Ejaz
7e7b00e58b Merge branch 'episys/timestamp_sl' into episys/timestamp_sl_debug 2023-01-16 09:44:46 -08:00
David
9b03282972 Reverting whitespace change 2023-01-16 09:38:58 -08:00
David
b5a2dab4e9 Reverting more unnecessary changes 2023-01-16 09:38:09 -08:00
David
0f22e2a2d8 Fixing more white space 2023-01-16 09:34:16 -08:00
David
9fe8a273f2 Reverting whitespace change 2023-01-16 09:32:12 -08:00
David
e95d6e28fc Reverting init changes that have no effect on sync 2023-01-16 09:31:40 -08:00
David
71f52d180f Reverting whitespace changes 2023-01-16 09:27:24 -08:00
David
0c048b28bd Merge branch 'episys/master-sl' into episys/timestamp_sl 2023-01-16 09:24:21 -08:00
David
0a38dbb7be Clean up for MR 2023-01-16 09:15:16 -08:00
Ejaz
40a2ee85aa Sync is workinggit add -u! 2023-01-16 08:47:42 -08:00
David
c61ab7fb7e Sync is workinggit add -u! 2023-01-16 08:47:28 -08:00
Melissa Elkadi
9591a5bef5 Adding hex dumps 2023-01-13 13:58:46 -08:00
Melissa
f95c3f92ed Merge branch 'episys/cleanup-ue-thread-sl' into 'episys/master-sl'
UE_thread_sl() clean-up, code simplification, and small bug fix

See merge request aburger/openairinterface5g!166
2023-01-13 18:18:36 +00:00
Melissa
0a6e7eb898 UE_thread_sl() clean-up, code simplification, and small bug fix 2023-01-13 18:18:36 +00:00
Melissa Elkadi
26a52906df Removing 5G code that was incorrectly added, it still exists in nr_initial_sync 2023-01-13 10:15:57 -08:00
Melissa Elkadi
0f8bb964a4 White space clean up 2023-01-13 10:11:35 -08:00
Melissa Elkadi
937c7119ae The nb_prefix_samples0 is dependent on sync status.
By changing the global value of the nb_prefix_samples0
at the top of the thread, we are never able to properly
set the value after sync. To fix this, a local variable
was added in every place we use nb_prefix_samples0 in
the UE_thread_SL. However this commit has quite a few
changes becasue some places where the nb_prefix_samples0
global was used did not have the UE global available, so
we had to update the function footprint to pass in a
sync bool for proeprly setting the local nb_prefix_samples0
variable.
2023-01-13 06:48:07 -08:00
Melissa Elkadi
3e028a43b5 Not writing in the future if this data is not ready yet. 2023-01-12 15:51:11 -08:00
Ejaz
c501e448ca Updated the write_time_stamp value.
Previously this value was based on the slot_tx,
however the slot_tx is in the future and has not
be fully populated at this time (execution of writing
to USRP). So, we should write to USRP in current
slot, but we will fill the buffer in the generation
code in the future.
2023-01-11 14:57:10 -08:00
David
8313896093 Lowering init size of txdata and txdataF to not be ridiculous 2023-01-11 14:39:38 -08:00
Ejaz
87436a1884 Lowering init size of txdata and txdataF buffers to not be ridiculous 2023-01-11 14:38:46 -08:00
David
34d508ae23 Updating write timestamp
The generated SSB frame is in the future,
but what we are transmitting should be the current spot not the future
one.
2023-01-11 13:17:39 -08:00
Melissa Elkadi
ffb6ca5934 Merge branch 'episys/master-sl' into episys/cleanup-ue-thread-sl 2023-01-11 11:57:47 -08:00
Melissa Elkadi
682721cf57 Disabling MAC layer code after sync is achieved. 2023-01-11 11:05:50 -08:00
David
1a627782dd Reverting back to old SL configuration 2023-01-11 07:44:30 -08:00
Ejaz
28688065e2 Reverting back to old SL configuration 2023-01-11 07:43:56 -08:00
Ejaz
21b766912b Updating log messages for sync and adding an exit 2023-01-11 06:06:35 -08:00
Ejaz
774b8ef6e9 Merge remote-tracking branch 'episci/episys/timestamp_sl' into episys/timestamp_sl_debug 2023-01-10 09:56:10 -08:00
David
aefe918f9f Adding logs to show PSS location on TX side 2023-01-09 16:16:03 -08:00
Ejaz
1dbe99316a Changed IP address in conf and Added log in usrp_lib.cpp 2023-01-09 13:46:51 -08:00
David
b0ca489e60 Currently gets rid of LLLLs somewhat thorugh process 2023-01-09 12:07:37 -08:00
David
5d270d63ac Only seeing LLLLs on a few items! 2023-01-09 11:10:32 -08:00
David
22063a35ec Trying to get sync_ref to match gNB 2023-01-09 10:54:54 -08:00
David
d39997d8b0 Added logs to check tx sl timestamp using USRP 2023-01-06 17:19:00 -08:00
Melissa Elkadi
74998221e8 This commit does a lot of clean up.
It includes clean up of the entire UE_thread_sl().
It should also be simplifying a lot of the code and
it now uses UE->rx_offset_sl properly instead of
UE->rx_offset.
2023-01-05 13:18:27 -08:00
Melissa Elkadi
c468bd519b This commit does three things:
1. The dummyWrite is only necessary for the client (!sync_ref)
   UE, since it should write dummy data for timing to the server.
2. There is a typo in one of the logs (pbch -> psbch)
3. The MAC layer is currently disabled. We should not fill the
   RX_IND since it is not even allocated. Later we can re-enable
   this code.
2023-01-05 11:23:22 -08:00
Melissa
385243f521 Merge branch 'episys/validated-tx-on-rfsim' into 'episys/master-sl'
Updating hexdumps for debugging

See merge request aburger/openairinterface5g!165
2023-01-03 19:54:32 +00:00
Melissa
0453ef25dd Updating hexdumps for debugging 2023-01-03 19:54:32 +00:00
Melissa
a909589185 Merge branch 'episys/validated-tx-on-rfsim' into 'episys/master-sl'
TX Data Validation for RFSIM

See merge request aburger/openairinterface5g!164
2023-01-03 19:27:16 +00:00
Melissa
064b05aee8 TX Data Validation for RFSIM 2023-01-03 19:27:16 +00:00
Melissa
4f34b5f97a Merge branch 'episys/mel/preventing-overflow-during-decode' into 'episys/master-sl'
The calculation of -1/1 in decoding was buggy.

See merge request aburger/openairinterface5g!162
2022-12-20 23:58:56 +00:00
Melissa
9c2c8067ef The calculation of -1/1 in decoding was buggy. 2022-12-20 23:58:56 +00:00
Melissa
ca86a8a5ac Merge branch 'episys/mel-modifying-idft-input-output-pointer-locations' into 'episys/master-sl'
Changing the address in which the output of the IDFT starts

See merge request aburger/openairinterface5g!160
2022-12-19 19:27:59 +00:00
Melissa
4708a7d81c Changing the address in which the output of the IDFT starts 2022-12-19 19:27:59 +00:00
Melissa
1d730cd8e2 Merge branch 'episys/rotate-in-freq-domain' into 'episys/master-sl'
Rotating the txdata buffer in the freq domain

See merge request aburger/openairinterface5g!158
2022-12-14 23:33:06 +00:00
Melissa Elkadi
e20bd2edaa Rotating the txdata buffer in the freq domain 2022-12-14 15:22:08 -08:00
Melissa
fc236e4bd3 Merge branch 'episys/mel-debugging-dmrs-correl' into 'episys/master-sl'
Validate the pilot bits and suspect PSBCH channel estimation is problematic.

See merge request aburger/openairinterface5g!155
2022-12-13 23:56:03 +00:00
Melissa Elkadi
2ebef66785 Removing unnecessary change 2022-12-13 15:53:18 -08:00
Melissa Elkadi
4cd71874c0 Adding gold psbch back in to RX side 2022-12-13 15:50:27 -08:00
Melissa Elkadi
c19ffff075 Removing redundant return 2022-12-13 15:44:49 -08:00
Melissa Elkadi
1c50671296 Improved performance by resetting k every symbol 2022-12-13 15:00:41 -08:00
Melissa Elkadi
611c98f6f1 Resetting the k value seems to help channel estimation on DMRS 2022-12-13 13:46:25 -08:00
Melissa Elkadi
a66d7fcafc More whitespcae clean up 2022-12-13 13:23:27 -08:00
Melissa Elkadi
c6a972f65e More code clean up 2022-12-13 13:19:55 -08:00
Melissa Elkadi
28290c792d Clean up for MR 2022-12-13 13:13:20 -08:00
Melissa Elkadi
aa2e0319d0 Adding uncommented code and update to match Ejaz 2022-12-13 11:32:11 -08:00
Melissa Elkadi
0cce63fae9 Code clean up and running DMRS correlation on all PSBCH symbols 2022-12-13 11:21:44 -08:00
Melissa Elkadi
f4bd344b9b This commit has several changes (some hacks) that result in correct first 3 PSBCH decoding
The changes include:
1. The last argument in nr_slot_fep_init_sync() is the
   ssb_offset. This offset was shifting the rxdata buffer
   by PSS location (2368) - # prefix samples (144) = 2224.
   This offset was causing the first PSBCH to be missed and
   the other symbols to be shifted. Now, by setting this
   offset argument to 0, the shift is 144, 144+2048, 144+2048*2, etc.

2. The estimateSz fed to the nr_psbch_channel_estimation should
   be the number of symbols per slot * ofdm sym size * sizeof(int).

3. The nb_prefix_samples was not matching between the TX and RX side.
   The first cp_size is nb_prefix_samples if sync is 0.

Lastly, we can only correlate with the first 3 PSBCH symbols.
Meaning, the 0th, 5th, and 6th symbol index in the SSB.. Not sure why.
2022-12-09 13:45:31 -08:00
Melissa Elkadi
565f6e13b0 Merge branch 'episys/nr_initial_sync_ota_test' into episys/mel-debugging-dmrs-correl 2022-12-09 11:33:05 -08:00
Melissa Elkadi
30e6cc01c6 Hacked the psbch reception in nr_sl_initial_sync without DMRS correlation... and it works! 2022-12-09 11:27:44 -08:00
Melissa Elkadi
f9f8e21b55 Applying rotation to time domain of txdata instead of freq domain 2022-12-09 11:20:55 -08:00
Melissa Elkadi
bb1699e4d6 In this commit, we validated the first set of pilot bits.
The nr_psbch_dmrs_rx() is able to properly generate the
pilot bits used in the PSBCH correaltion. It seems that the
RXdataF is not properly aligned and we cannot correlate
with the pilot bits
2022-12-09 10:29:35 -08:00
Melissa Elkadi
853f2737a4 Reverting incorrect change 2022-12-09 08:24:57 -08:00
Melissa Elkadi
7f3242a2b4 Merge branch 'episys/nr_initial_sync_ota_test' into episys/mel-debugging-dmrs-correl 2022-12-09 08:08:38 -08:00
Melissa Elkadi
f2e678375b Clean up of nr_psbch_detection 2022-12-09 08:03:34 -08:00
David Kim
6444ee9aee Changed dmrs signal index in psbch. 2022-12-08 20:07:43 -08:00
Melissa
5fc0e53cc8 Merge branch 'nr_sl_phy_2' into 'episys/master-sl'
SSS synch working

See merge request aburger/openairinterface5g!154
2022-12-09 00:35:30 +00:00
Melissa Elkadi
147b5af7fe Fixing small whitespace changes and re-assignment of rxdataF 2022-12-08 16:33:43 -08:00
Melissa Elkadi
fa5fb4e49b Cleaning up rx_sss_sl_nr() 2022-12-08 16:29:22 -08:00
Melissa Elkadi
d98f09825f Cleaning up pss_sl_ch_est_nr() 2022-12-08 16:14:15 -08:00
Melissa Elkadi
74c075a751 Cleaning up pss_sss_sl_extract_nr() 2022-12-08 16:07:21 -08:00
Melissa Elkadi
f6815c381a Cleaning up nr_sl_initial_sync() 2022-12-08 15:56:43 -08:00
Prashanth Saidu
7268877512 formatting nr_sl_initial_sync 2022-12-08 15:35:23 -08:00
Prashanth Saidu
9114cd36cd Reverting Correlation threshold to 30K from 60K as results are better at 30K 2022-12-08 14:02:21 -08:00
Prashanth Saidu
530a5a3f01 Cleanup pss_sl_ch_est_nr 2022-12-08 13:46:11 -08:00
Prashanth Saidu
1a9148ae2f Cleaning upnr_sl_initial_sync 2022-12-08 13:23:25 -08:00
Prashanth Saidu
e74d9c8aea Cleaning up pss_sss_sl_extract_nr 1 2022-12-08 11:15:21 -08:00
Prashanth Saidu
662d453bf5 Cleaning up pss_sss_sl_extract_nr 2022-12-08 11:12:49 -08:00
Prashanth Saidu
00885ccfd6 Calling nr_psbch_detection() instead of nr_pbch_detection 2022-12-08 10:55:41 -08:00
Prashanth Saidu
2e17b65004 Removing ref to Nid_cell and adjusting correlation threshold for SL 2022-12-08 08:56:15 -08:00
Prashanth Saidu
df3a7bab95 Fixing spaces in pbchsim.c 2022-12-07 15:06:02 -08:00
Ejaz AHmed
c96851dc0d Updated rx_sync in the psbchsim to handle all psbch symbols 2022-12-07 13:27:04 -08:00
Prashanth Saidu
8c528798ad Merge branch 'episys/master-sl' into nr_sl_phy_2 2022-12-07 12:49:22 -08:00
Ejaz AHmed
c065dc89bb Merge branch 'episys/master-sl' into episys/nr_initial_sync_wplan 2022-12-07 10:45:51 -08:00
Prashanth Saidu
f339b8b1e7 Fixed SSS correlation 2022-12-07 10:16:18 -08:00
Melissa
24cec4d5ba Merge branch 'episys/changed_phy_parameters' into 'episys/master-sl'
Changed PHY parameters in psbchsim

See merge request aburger/openairinterface5g!153
2022-12-06 23:32:19 +00:00
Ejaz AHmed
0d769760fd Changed PHY parameters in psbchsim 2022-12-06 12:18:50 -08:00
Prashanth Saidu
8fb5f5a350 Updated SSS unit test 2022-11-18 11:40:10 -08:00
Ejaz Ahmed
9ffc7359b4 Merge branch 'episys/pss_sync' into 'episys/master-sl'
Some of the rx side functions updated to enable pss initial synchronization

See merge request aburger/openairinterface5g!151
2022-11-18 17:45:40 +00:00
Ejaz Ahmed
e6d200befe Some of the rx side functions updated to enable pss initial synchronization 2022-11-18 17:45:39 +00:00
Prashanth Saidu
e079c43485 Merge branch 'episys/master-sl' into nr_sl_phy_2 2022-11-18 08:49:36 -08:00
Prashanth Saidu
5f200844a4 updated log vectors for SSS and PSS 2022-11-18 08:48:26 -08:00
Melissa
6a4aa58c2e Merge branch 'episys/mel-new-pss-tests' into 'episys/master-sl'
Adding Sidelink PSS and SSS Tests into the PSBCH Simulator.

See merge request aburger/openairinterface5g!150
2022-11-18 16:46:12 +00:00
Melissa Elkadi
679bcc4365 Updating white space 2022-11-18 08:45:45 -08:00
Melissa Elkadi
9f056450d6 Freeing allocated memory regardless of PSS/SSS mode or PSBCH sim mode.
Also, reverting UE->common_vars.eNb_id == pss_sequence_number
comparison for *now* until we merge in updated PSS and SSS
code. In which case, it will be:
UE->common_vars.N2_id == pss_sequence_number
2022-11-18 05:58:22 -08:00
Prashanth Saidu
27994e444d Removing a debug while(1) 2022-11-17 16:10:19 -08:00
Melissa Elkadi
9d11486431 Updating the code to support PSS SL changes 2022-11-17 14:06:32 -08:00
Prashanth Saidu
e6ed641079 SSS metric is lower than floor, needs to be fixed 2022-11-17 13:00:51 -08:00
Melissa Elkadi
99bdc94279 Updating pss_test boolean to be named properly 2022-11-17 09:59:02 -08:00
Melissa Elkadi
a86559bdce Adding sss sl test into the simulator.
The new nr_sss_sl_test.c/h files are used
for the SSS test. These files are simplified
versions of the pss_tests that already exist.

Now that these tests are able to be compiled
and ran, they should explicitly call the SL
specific SSS functions
2022-11-17 09:54:05 -08:00
Melissa Elkadi
971bb3bfc0 Code clean up 2022-11-16 13:56:45 -08:00
Melissa Elkadi
c387aa0f0d Adding pss sl test into the simulator.
The new nr_pss_sl_test.c/h files are used
for the PSS test. These files are simplified
versions of the pss_tests that already exist.

Now that these tests are able to be compiled
and ran, they should explicitly call the SL
specific PSS functions.
2022-11-16 13:44:19 -08:00
Prashanth Saidu
10ec942d67 Enabing nr_sl_initial_sync 2022-11-16 11:31:42 -08:00
Prashanth Saidu
91338a7439 Updated NID SL macro to use Nid_SL 2022-11-16 10:50:49 -08:00
Prashanth Saidu
a5ff057b69 Updated GET_NID macros 2022-11-16 10:38:50 -08:00
Melissa Elkadi
d04291d66d Revert "Merge branch 'episys/master-sl' of gitlab.int-episci.com:aburger/openairinterface5g into episys/master-sl"
This reverts commit 4b9bc61748, reversing
changes made to 12f240c7e5.
2022-11-16 09:49:23 -08:00
Melissa Elkadi
4b9bc61748 Merge branch 'episys/master-sl' of gitlab.int-episci.com:aburger/openairinterface5g into episys/master-sl 2022-11-16 09:30:33 -08:00
Prashanth Saidu
a0a0e32f68 Fixed GET_NID1_SL computation 2022-11-16 08:47:31 -08:00
Prashanth Saidu
8167d64bcb Updated computation of Nid1, Nid2 2022-11-15 12:24:18 -08:00
Prashanth Saidu
e6b101d7da Update SSS with 2nd SSS symnbol computations 2022-11-14 20:02:28 -08:00
Prashanth Saidu
3689def55f Added PSS and SSS sync for Side Link 2022-11-14 09:55:31 -08:00
Prashanth Saidu
a8c79ebf3b Merge branch 'episys/master-sl' into nr_sl_phy_2 2022-11-11 12:31:13 -08:00
Melissa
12f240c7e5 Merge branch 'episys/david/sl_param_and_channel_update' into 'episys/master-sl'
Sidelink Parameter and Channel index update.

See merge request aburger/openairinterface5g!149
2022-11-11 18:19:52 +00:00
Deokseong "David" Kim
e1fc0a4d6b Sidelink Parameter and Channel index update. 2022-11-11 18:19:52 +00:00
Prashanth Saidu
1c602f0e92 Merge branch 'episys/master-sl' into nr_sl_phy_2 2022-11-07 05:46:16 -08:00
Melissa Elkadi
f5ad65cd2e Using the working polar_decoder instead of polar_decode_int16 2022-11-04 17:46:50 -07:00
Deokseong "David" Kim
4fe865a30f Merge branch 'episys/debug_psbchsim' into 'episys/master-sl'
Changed the number of dmrs RE per symbol in psbch.

See merge request aburger/openairinterface5g!147
2022-11-04 23:40:15 +00:00
Ejaz AHmed
4ba390adfc Changed the number of dmrs RE per symbol in psbch. 2022-11-04 16:20:50 -07:00
Prashanth Saidu
ebfa50dce4 Merge branch 'episys/master-sl' into nr_sl_phy_2 2022-11-04 11:20:05 -07:00
Deokseong "David" Kim
3d1631a673 Merge branch 'episys/develop-sl' into 'episys/master-sl'
PSBCH simulator parameter update.

See merge request aburger/openairinterface5g!146
2022-11-04 18:13:24 +00:00
David Kim
7ea1501058 PSBCH simulator parameter update. 2022-11-04 11:02:47 -07:00
Deokseong "David" Kim
6fe163f4c4 Merge branch 'nr_sl_phy_2' into 'episys/master-sl'
Updates to PSBCH DMRS Tx

See merge request aburger/openairinterface5g!145
2022-11-04 16:40:33 +00:00
Prashanth
38cccc73f0 Updates to PSBCH DMRS Tx 2022-11-04 16:40:32 +00:00
Prashanth Saidu
75d0b6116e Removing DMRS mod_count check to let complete DMRS generation 2022-11-03 21:31:56 -07:00
Melissa
acb3a50768 Merge branch 'mel-debugging-psbchsim' into 'episys/master-sl'
Fixing for loop indices for PSBCH

See merge request aburger/openairinterface5g!144
2022-11-04 00:02:40 +00:00
Melissa Elkadi
e51ce1d232 Removing DEBUG_PSBCH definition 2022-11-03 17:02:26 -07:00
Melissa Elkadi
e23e81425c Fixing for loop indices for PSBCH 2022-11-03 17:00:01 -07:00
Melissa
14234e9eca Merge branch 'episys/david/updating_psbch_rx_side' into 'episys/master-sl'
Updating psbch rx side

See merge request aburger/openairinterface5g!143
2022-11-03 23:20:33 +00:00
Deokseong "David" Kim
5dd561743e Updating psbch rx side 2022-11-03 23:20:33 +00:00
Prashanth Saidu
264ab2ddd2 Merge branch 'episys/master-sl' into nr_sl_phy_2 2022-11-03 16:18:58 -07:00
Melissa
1e3932fbe1 Merge branch 'debugging-polar-encoding' into 'episys/master-sl'
HACKY change for NR_POLAR_PSBCH_E.

See merge request aburger/openairinterface5g!142
2022-11-03 22:43:41 +00:00
Melissa Elkadi
51b8271ee9 HACKY change for NR_POLAR_PSBCH_E.
This is going to be a long explaination. The spec says
for polar encoding that N = 512 (input size) - 2^9,
K = 56, and E (encoded size) = 1782. However, the interleaver
will break 512 into 16, 32 bit sections. These 16 sections
are moved around to form the interleaved input. Then
the code does something else and basically, every 16th
bit is modified (or important) and triggers the mingroupsize
to be 16. The mingroupsize is calculated in a for loop and
starts from 0->16 and then resets again at 0. However, the
E size if 1782, which is not divisible by 16, will make
minigroupsize end at 6 (it is incremented until the special
character is found at index 16). The hack is to just
make 1782 large enough so the last bit is found, so we change
it to size 1792.
2022-11-03 15:36:03 -07:00
Prashanth Saidu
c6d13e8d73 Merge branch 'episys/master-sl' into nr_sl_phy_2 2022-11-03 14:35:52 -07:00
Melissa
8a8c5275b0 Merge branch 'episys/convert_payload_to_nrue' into 'episys/master-sl'
Created psbch_nr_sl; Added nr_generated_sl_psbch() function

See merge request aburger/openairinterface5g!141
2022-11-03 20:11:24 +00:00
Ejaz Ahmed
a884e37625 Created psbch_nr_sl; Added nr_generated_sl_psbch() function 2022-11-03 20:11:23 +00:00
Prashanth Saidu
dc84deafea merge to master-sl 2022-11-03 11:38:36 -07:00
Melissa
23adfc132a Merge branch 'update-psbchsim-mode2' into 'episys/master-sl'
Moving nr_sl_common_signal_procedures to nr_psbch.c temporarily

See merge request aburger/openairinterface5g!140
2022-11-03 17:47:15 +00:00
Melissa Elkadi
be8bed3602 Fixing white space and adding new dmrs gen file to UE 2022-11-03 10:45:47 -07:00
Melissa Elkadi
a8cb993e56 This commit moves the DMRS symbol generation to the UE side
In this commit, the code properly builds and is able to
(somehow) generate non-zero values into the txdata buffer.
2022-11-03 10:40:51 -07:00
Melissa Elkadi
43da8296cf Moving nr_sl_common_signal_procedures to nr_psbch.c temporarily
Currently, the psbchsim will build and run correctly without
linking errors. Several solutions have been tried unsuccessfully.
Now that we have a working version, we will save these changes
and try a few more logical places to put this
2022-11-03 10:17:48 -07:00
Melissa
3462053a08 Merge branch 'update-psbchsim-mode2' into 'episys/master-sl'
Moving psbchsim to be only UE dependent

See merge request aburger/openairinterface5g!139
2022-11-03 01:07:53 +00:00
Melissa Elkadi
5e21c904ae This commit adds assert fatals and code clean up 2022-11-02 18:01:50 -07:00
Melissa Elkadi
26395fa2c2 Merge branch 'episys/master-sl' into update-psbchsim-mode2 2022-11-02 16:52:59 -07:00
Melissa
f62ea2b3e0 Merge branch 'adding_sl_common_signal_procedures' into 'episys/master-sl'
Adding sl common signal procedures

See merge request aburger/openairinterface5g!138
2022-11-02 23:52:13 +00:00
Deokseong "David" Kim
f70097d9c9 Adding sl common signal procedures 2022-11-02 23:52:13 +00:00
Melissa Elkadi
47c400da03 Adding hex dumps for debugging tx payloads 2022-11-02 15:59:24 -07:00
Melissa Elkadi
a01a5f06ed Moving psbchsim to be only UE dependent
Also, this commit includes removing the NR_txUE_PSBCH
struct members into the NR_UE_PSBCH struct. At this point,
I cannot see a reason for a seprate struct. Especially
since the NR_txUE_PSBCH is not declared within the PHY_VARS_UE
scope so it is not accessible by the UE PHY layer global
anyways.

Additionally, the changes in psbchsim will allow the
UE to be used instead of the gNB. It configures the
frame parameters and should allocate memory for the
tx and rx buffers used in SL.
2022-11-02 15:50:43 -07:00
Melissa
d8a53795fe Merge branch 'nr_sl_phy_2' into 'episys/master-sl'
NR SL PHY updates 1

See merge request aburger/openairinterface5g!137
2022-11-02 21:08:41 +00:00
Prashanth
42991ff0ca NR SL PHY updates 1 2022-11-02 21:08:40 +00:00
Melissa
087318f333 Merge branch 'new-sl-file-creation' into 'episys/master-sl'
UE frame parameter configuration

See merge request aburger/openairinterface5g!136
2022-11-02 21:06:59 +00:00
Ejaz Ahmed
c2c574f153 UE frame parameter configuration 2022-11-02 21:06:59 +00:00
Prashanth Saidu
96b7930292 Update log for ssb_start_symbol 2022-11-02 13:55:46 -07:00
Prashanth Saidu
789b639bbe removing gNB arguments in SL PSBCH DMRS 2022-11-02 13:49:00 -07:00
Prashanth Saidu
7b5eb7e1b7 SSS PSS deleting gNB arguments 2022-11-02 13:39:45 -07:00
Prashanth Saidu
04d35e8d7e Updating Nid ops from 335 to 336 2022-11-02 13:26:03 -07:00
Prashanth Saidu
bef8362087 Updated Nid for LS SSS 2022-11-02 13:12:27 -07:00
Prashanth Saidu
d80ba9b649 increasing pilot size to accommodate for new size 2022-11-02 12:59:15 -07:00
Prashanth Saidu
fdd75c4a36 moved sl sss generation to separate file 2022-11-02 10:30:52 -07:00
Prashanth Saidu
31beafbd04 Merge branch 'episys/master-sl' into nr_sl_phy_2 2022-11-02 09:56:59 -07:00
Melissa
b203c79d87 Merge branch 'new-sl-file-creation' into 'episys/master-sl'
Adding sidelink functions and files

See merge request aburger/openairinterface5g!135
2022-11-02 01:26:02 +00:00
Melissa Elkadi
18188b6f39 Updating white space 2022-11-01 18:25:08 -07:00
Melissa Elkadi
3e8ad6e26c Updating white space 2022-11-01 18:23:12 -07:00
Melissa Elkadi
6ef808cae1 Updating cmake cache to be correct 2022-11-01 18:20:13 -07:00
Melissa Elkadi
bc2fe3db05 Fixing build and white space errors
A few gNB items were added back into psbchsim to ensure it successfully builds
2022-11-01 18:17:43 -07:00
Prashanth Saidu
400447825a Using psbch sources 2022-11-01 17:59:17 -07:00
Prashanth Saidu
75f52cef4a Added SL_PSBCH to use UE instead of gNb 2022-11-01 17:38:39 -07:00
Melissa Elkadi
4bec2f496d Merge branch 'episys/master-sl' into new-sl-file-creation 2022-11-01 17:27:22 -07:00
Melissa Elkadi
39c6b07820 Defined nr_sl_generate_pss in UE PHY procedures 2022-11-01 17:22:01 -07:00
Melissa
f2cf9f0bd1 Merge branch 'episys/david/porting_nr_sl_generate_pss' into 'episys/master-sl'
Porting nr sl generate pss

See merge request aburger/openairinterface5g!134
2022-11-02 00:17:52 +00:00
Deokseong "David" Kim
38b1b41682 Porting nr sl generate pss 2022-11-02 00:17:51 +00:00
Melissa
68638ae67c Merge branch 'episys/david/adding_phy_procedures_nrUE_SL_TX' into 'episys/master-sl'
Adding phy procedures nr ue sl tx

See merge request aburger/openairinterface5g!133
2022-11-01 23:54:18 +00:00
Deokseong "David" Kim
9000f91f7e Adding phy procedures nr ue sl tx 2022-11-01 23:54:17 +00:00
Prashanth Saidu
46b1cf6dc9 Updated SL functions for Rx 2022-11-01 16:01:11 -07:00
Prashanth Saidu
a74d7fa54f Changed to support PSS for Side Link. 2022-11-01 12:03:02 -07:00
Melissa Elkadi
cdec2dd204 Temporarily using Lmax == 4 for SL 2022-11-01 10:51:59 -07:00
Melissa Elkadi
f98be66eda Updating generat dmrs for psbch 2022-11-01 10:31:27 -07:00
Melissa Elkadi
af5c062638 Updating assert fatals 2022-11-01 10:08:19 -07:00
Melissa Elkadi
6ca28a9931 Removing warnings and calling nr_sl_initial_sync in nr_psbchsim 2022-11-01 08:32:10 -07:00
Melissa Elkadi
ce10596a13 Merge branch 'episys/master-sl' into new-sl-file-creation 2022-11-01 08:19:59 -07:00
Melissa Elkadi
d9a8108a15 Adding sidelink files and structs.
The purpose of this commit is to:
1. Stop using NR functions for SL functions
2. Removing SL functions from NR functions
3. Creating new #define SL values rather than just changing NR #defines
4. Creating new psbchsim.c (which fails)
5. Adding AssertFatals and code clean up

The next steps include:
- Implementing initial_sync for SL
- Validating that the SL values are correct
- Getting psbchsim.c to pass
2022-11-01 08:18:55 -07:00
Melissa Elkadi
1b5005277c Conducting more code clean up and fixing warnings
Also, I have started to add the psbchsim.c.
The next fix should be to update all pbch members
to be psbch.
2022-11-01 06:47:02 -07:00
Melissa Elkadi
ee9b35bec7 Fixing white space 2022-10-31 18:31:25 -07:00
Prashanth Saidu
d82ab58c24 Merge branch 'nr_sl_phy' of gitlab.int-episci.com:aburger/openairinterface5g into nr_sl_phy 2022-10-31 18:29:57 -07:00
Prashanth Saidu
dbcc558f04 Support for SL id on SSS 2022-10-31 18:26:52 -07:00
Prashanth Saidu
54f8add2de Support for SL PSS, SSS on Rx 2022-10-31 18:04:37 -07:00
Melissa Elkadi
6e11362b75 Code clean up and adding more assertions 2022-10-31 17:02:13 -07:00
Prashanth Saidu
59310feb4b updated psbch_e size for scrambling 2022-10-31 13:41:05 -07:00
Melissa Elkadi
8017cb16f3 More code clean up and error checking 2022-10-29 13:35:59 -07:00
Melissa Elkadi
be32f71b1a Updating AssertFatal logs and adding a few more 2022-10-29 13:24:09 -07:00
Melissa Elkadi
193720a376 Adding assert fatals and more code clean up 2022-10-29 13:19:24 -07:00
Melissa Elkadi
865dd7984d Code clean up
This commit consists of simple white space changes,
function alignment and moving local variable declarations
near the first usage.
2022-10-29 13:02:06 -07:00
Prashanth Saidu
d31d050dd5 added psbch ch estimate 2022-10-28 12:36:38 -07:00
Melissa
3ae4e95775 Merge branch 'episys/david/sidelink_thread_update' into 'episys/master-sl'
Episys/david/sidelink thread update

See merge request aburger/openairinterface5g!132
2022-10-28 18:23:20 +00:00
Deokseong "David" Kim
1450ffd015 Episys/david/sidelink thread update 2022-10-28 18:23:20 +00:00
Melissa
0ff5045410 Merge branch 'episys/sidelink_preconfig' into 'episys/master-sl'
Implemented required sidelink preconfigurations, SLSS and MIB-SL for NR

See merge request aburger/openairinterface5g!131
2022-10-28 18:13:30 +00:00
Ejaz Ahmed
e6a68d8cf2 Implemented required sidelink preconfigurations, SLSS and MIB-SL for NR 2022-10-28 18:13:29 +00:00
Prashanth Saidu
a093745aa1 updated psbch ch level and compensation 2022-10-27 15:36:00 -07:00
Prashanth Saidu
0af95f24fc updated PSBCH sizes 2022-10-27 13:39:13 -07:00
Prashanth Saidu
6d1462712c added psbch_dmrs_rx 2022-10-27 11:32:53 -07:00
Prashanth Saidu
048782bbec updated nr_psbch_extract 2022-10-27 08:47:01 -07:00
Prashanth Saidu
7397fca459 added nr_rx_psbch 2022-10-26 12:55:59 -07:00
Prashanth Saidu
3dfb02e876 added ssb frame plus rx functions 2022-10-26 12:06:37 -07:00
Melissa
7e31ec9994 Merge branch 'episys/david/adding_sync_ref_flag' into 'episys/master-sl'
Added sync_ref flag in command line argument to specify SyncRef UE.

See merge request aburger/openairinterface5g!130
2022-10-21 00:25:28 +00:00
Deokseong "David" Kim
594811b9e6 Added sync_ref flag in command line argument to specify SyncRef UE. 2022-10-21 00:25:27 +00:00
Deokseong "David" Kim
c18da15703 Merge branch 'episys/master-sl-cleanup' into 'episys/master-sl'
Fixing camel case vs. underscores to be consistent

See merge request aburger/openairinterface5g!129
2022-10-20 16:48:26 +00:00
Melissa Elkadi
c7c30d26b5 Cleaning up white space 2022-10-20 06:30:07 -07:00
Melissa Elkadi
b2cf3f5270 Fixing camel case vs. underscores to be consistent 2022-10-19 16:55:06 -07:00
Melissa
1ebc4643e9 Merge branch 'episys/david/sidelink_thread_creation' into 'episys/master-sl'
Added sidelink sync flags to check sync status.

See merge request aburger/openairinterface5g!127
2022-10-19 23:09:51 +00:00
David Kim
e77818daf8 Added sidelink sync flags to check sync status. 2022-10-19 13:50:07 -07:00
Melissa
eb6068cc1f Merge branch 'episys/david/adding_SL_thread_placeholder' into 'episys/master-sl'
Added Sidelink thread placeholder.

See merge request aburger/openairinterface5g!126
2022-10-18 19:39:34 +00:00
Deokseong "David" Kim
fbec6c1261 Added Sidelink thread placeholder. 2022-10-18 19:39:34 +00:00
Melissa
2b05e90a57 Merge branch 'nr_sl_phy' into 'episys/master-sl'
Support for Side Link PSBCH Tx and Rx.

See merge request aburger/openairinterface5g!125
2022-10-12 00:23:05 +00:00
Prashanth Saidu
028166428d Fixed MR comments 2022-10-11 17:21:48 -07:00
Prashanth Saidu
fccae8a158 Fixed MR comments 2022-10-11 17:17:29 -07:00
Prashanth Saidu
9e8f3f8c67 Fixing MR comments 2022-10-11 17:11:59 -07:00
Prashanth Saidu
5886bb2b6a Merge branch 'nr_sl_phy' of gitlab.int-episci.com:aburger/openairinterface5g into nr_sl_phy 2022-10-11 17:03:03 -07:00
Prashanth Saidu
a999ce41ce Merge branch 'nr_sl_phy' of gitlab.int-episci.com:aburger/openairinterface5g into nr_sl_phy 2022-10-11 17:02:35 -07:00
Prashanth Saidu
d911c83c56 Merge branch 'nr_sl_phy' of gitlab.int-episci.com:aburger/openairinterface5g into nr_sl_phy 2022-10-11 16:59:59 -07:00
Prashanth Saidu
471df37f73 Merge branch 'nr_sl_phy' of gitlab.int-episci.com:aburger/openairinterface5g into nr_sl_phy 2022-10-11 16:59:43 -07:00
Prashanth Saidu
fab708d74e Merge branch 'nr_sl_phy' of gitlab.int-episci.com:aburger/openairinterface5g into nr_sl_phy 2022-10-11 14:02:42 -07:00
Prashanth Saidu
96583ee109 Merge branch 'nr_sl_phy' of gitlab.int-episci.com:aburger/openairinterface5g into nr_sl_phy 2022-10-11 14:02:24 -07:00
Prashanth Saidu
d3dd8af4cc Merge branch 'nr_sl_phy' of gitlab.int-episci.com:aburger/openairinterface5g into nr_sl_phy 2022-10-11 13:16:25 -07:00
Prashanth Saidu
f9642228af Merge branch 'nr_sl_phy' of gitlab.int-episci.com:aburger/openairinterface5g into nr_sl_phy 2022-10-11 13:16:04 -07:00
Prashanth Saidu
7a30b607e5 Merge branch 'nr_sl_phy' of gitlab.int-episci.com:aburger/openairinterface5g into nr_sl_phy 2022-10-11 13:13:16 -07:00
Prashanth Saidu
042b9e3c85 Merge branch 'nr_sl_phy' of gitlab.int-episci.com:aburger/openairinterface5g into nr_sl_phy 2022-10-11 13:12:48 -07:00
Prashanth Saidu
e57d62184e Merge branch 'nr_sl_phy' of gitlab.int-episci.com:aburger/openairinterface5g into nr_sl_phy 2022-10-11 12:23:26 -07:00
Prashanth Saidu
0139c38786 Merge branch 'episys/master-sl' into nr_sl_phy 2022-10-11 12:22:22 -07:00
Prashanth Saidu
81c5c06414 Merge branch 'episys/master-sl' into nr_sl_phy 2022-10-11 11:56:54 -07:00
Prashanth Saidu
8e702ad0d0 Merge branch 'develop' into episys/master-sl 2022-10-11 11:55:06 -07:00
Prashanth Saidu
8a06717f95 Merge branch 'episys/master-sl' into nr_sl_phy 2022-10-11 11:43:34 -07:00
Prashanth Saidu
123bf7e339 PSBCH Sidelink PHY Tx and Rx working, SSSB frame creation pending 2022-10-07 14:53:58 -07:00
Melissa
0bfaeac94b Merge branch 'adding-new-sl-cl-opt' into 'episys/master-sl'
Adding two new sidelink command line options

See merge request aburger/openairinterface5g!124
2022-10-05 22:29:28 +00:00
Melissa
81a2d3854b Adding two new sidelink command line options 2022-10-05 22:29:27 +00:00
Prashanth Saidu
e6bcd4e559 Added PSBCH payload with bitwise formatting 2022-10-03 16:22:52 -07:00
Prashanth Saidu
0d78000ca3 Added PSBCH payload 2022-09-27 17:05:18 -07:00
Prashanth Saidu
175579f8e2 PBCH side link phy initial version 2022-09-19 15:34:58 -07:00
Melissa Elkadi
05d2c538ea Merge branch 'episys-lte-handover' into develop 2022-09-19 11:33:21 -07:00
David Kim
28a78f02a8 Removed duplicated flag __func__ in the logging line. 2022-09-16 18:06:21 -07:00
David Kim
9de72b2e7e Merge remote-tracking branch 'eurocom/develop' into episys-lte-handover 2022-09-16 15:01:08 -07:00
David Kim
c6a892c15d Added explanations for AWGN results files. 2022-09-16 14:51:58 -07:00
David Kim
618ea544c2 Setting pdcp security mode active in LTE handover. 2022-09-16 14:02:19 -07:00
David Kim
4ed69e515e Removed return in gtp_itf.cpp to make ping work in lte mode. 2022-09-14 13:27:16 -07:00
David Kim
124715d93e Restored entity->is_gnb flag in sdap_data_ind for NR PDCP. 2022-09-12 21:44:59 -07:00
David Kim
26553dfdad Merge remote-tracking branch 'eurocom/develop' into episys-lte-handover 2022-09-12 16:26:16 -07:00
David Kim
844d683915 Updated docker-compose file to fix node-number value. 2022-09-09 17:53:48 -07:00
David Kim
47c429e8c3 Merge branch 'episys-lte-handover' of https://gitlab.eurecom.fr/oai/openairinterface5g into episys-lte-handover 2022-09-08 16:08:12 -07:00
Melissa Elkadi
33d9f68cda Merge branch 'episys-lte-handover-debugging' of gitlab.int-episci.com:aburger/openairinterface5g into episys-lte-handover-debugging 2022-09-07 17:45:39 -07:00
Melissa Elkadi
8618b6ad60 The new changes for exiting nr-softmodem properly broke NSA mode.
In this commit we are sure not to exucute PHY parameters
in emulated mode.
2022-09-07 17:44:41 -07:00
David Kim
893ca2a4cb Removed merge lines in config file. 2022-09-07 17:00:20 -07:00
David Kim
ef09160447 Update NRUE interface config in MACRLC layer.
1. Configuration file update corresponding to NRUE.
2. Compile error fix.
3. Reverting node id to new one.
2022-09-07 14:17:09 -07:00
David Kim
1ab09a6fa8 Handling of exceptional pdu size case for ULSCH Trncated BSR. 2022-09-07 11:59:00 -07:00
Melissa Elkadi
0134d8c914 First attempt to stop using configurations from L1
We need to now configure the NR UE based on MACRLC
similar to how the gNB does. This is started but not
tested in this commit. We only need to update for the
NRUE.
2022-09-07 11:52:46 -07:00
David Kim
ac0ec7b314 Merge remote-tracking branch 'eurocom/develop' into episys-lte-handover 2022-09-07 10:22:42 -07:00
Melissa Elkadi
9350e05ad6 Reverting node_number changes to show SA mode working.
However, currently 6c31639522 and
some other related changes have broken the path for getting the
MIB in emulated SA mode. The full source of these changes has not
been established. This may or may not be a big problem. It seems
that all other connections and the RA procedure are completing
properly. Therefore, we may decide not to worry about this and
simply make the assumption that the MIB configuration information
is hard coded for emulated mode and move on.
2022-09-06 18:10:27 -07:00
Melissa Elkadi
76797a5e86 Merge branch 'eurecom-develop' into episys-lte-handover 2022-09-06 12:29:02 -07:00
Melissa Elkadi
6163143cfe Merge branch 'eurecom-develop' into episys-lte-handover 2022-09-01 16:11:47 -07:00
Melissa Elkadi
60bcbb230f Reverting these changes as MR 1573 should cover them 2022-09-01 16:10:45 -07:00
Melissa Elkadi
57824f4f02 Merge branch 'eurecom-develop' into episys-lte-handover 2022-08-25 15:26:19 -07:00
David Kim
9642337729 Code cleanup. 2022-08-17 10:44:30 -07:00
Melissa Elkadi
c265a6ec6a Removing unused variables to resolve added warnings. 2022-08-17 08:27:00 -07:00
Melissa Elkadi
0558d55259 Reverting incorrect change 2022-08-17 07:44:44 -07:00
Melissa Elkadi
c2328793a3 A few more whitespace changes 2022-08-17 07:34:26 -07:00
Melissa Elkadi
e1300914da Fixing whitespace changes for MR-1642 2022-08-17 07:20:36 -07:00
Melissa Elkadi
713f6632f9 Fixing CI/CD build errors 2022-08-15 06:43:07 -07:00
Melissa Elkadi
9e8bd87501 Merge branch 'eurecom-develop' into episys-lte-handover 2022-08-12 15:59:25 -07:00
David Kim
b508ea71f8 Removed heap-use-after-free issue. 2022-08-12 10:34:09 -07:00
David Kim
be5a93b29a Removed INHIBIT_REALTIME_SCHEDULER flag. 2022-08-12 10:00:36 -07:00
David Kim
972256cd6e Code cleanup, log level reset, code location adjustment.
1. Code cleanup and format update.
2. Log level reset
3. Channel model related codes moved into NR_Packet_Drop.c or .h file.
2022-08-12 09:57:31 -07:00
David Kim
b5c2634151 Merge branch 'eurocom/develop' into episys-lte-handover 2022-08-03 14:11:26 -07:00
David Kim
992aa392a9 Adding shift in build_oai item. 2022-07-29 17:35:39 -07:00
Melissa Elkadi
6b751b2874 Merge branch 'eurecom-develop' into release-3.0 2022-07-28 16:51:55 -07:00
Deokseong "David" Kim
034b64c895 Merge branch 'episys/david/lte_handover' into 'release-3.0'
Cleaning  LTE Handover code

See merge request aburger/openairinterface5g!122
2022-07-28 23:04:12 +00:00
Deokseong "David" Kim
61a93c2374 Cleaning LTE Handover code 2022-07-28 23:04:10 +00:00
Melissa Elkadi
73c8012b52 Merge branch 'eurecom-develop' into release-3.0 2022-07-26 11:39:36 -07:00
David Kim
eca4415287 Inhibit rt scheduler in Ubuntu 20.04. 2022-06-28 17:16:00 -07:00
David Kim
a5c67fac57 Adding mimo config file 2022-06-27 19:09:28 -07:00
Melissa Elkadi
b0d1b9d44f Increasing buffer size for NSA throughput 2022-06-27 19:06:24 -07:00
Melissa Elkadi
4d7958414e This commit fixes UE to UE IP traffic
The bug fixes include, proeprly allocating
for multiple dl_config PDUs for the num_dci_options.
It also includes getting rid of a double free.
It also does not index pdu (from rx_ind) since there
is only one PDU.
It also puts frees back in the check_and_process_dci().
2022-06-24 15:48:45 -07:00
Melissa Elkadi
4d122d5d7c Costmetic change to packing/unpacking 2022-06-24 13:55:25 -07:00
Melissa Elkadi
5228c18981 Removing commented code causing incorrect pack/unpack 2022-06-24 13:05:46 -07:00
Melissa Elkadi
7b39aa61a9 Merge branch 'episys/david/channel_abstraction_on_top_of_MIMO_CSI_Reporting' of gitlab.int-episci.com:aburger/openairinterface5g into episys/david/channel_abstraction_on_top_of_MIMO_CSI_Reporting 2022-06-24 09:51:00 -07:00
David Kim
d785a95a5f Code fix to remove compile warning. 2022-06-23 16:42:33 -07:00
Melissa Elkadi
ff43319fdb TBS + 2 bug fix (not standard compliant for nFAPI header)
Also, added a return 0; for invalid PDU length in the gNB.
This is a bug. We need to understand why the PDU length is
overrun. For now, this avoids indexing past the end of pduP
pointer.
2022-06-23 13:57:19 -07:00
David Kim
4167066f04 Merge remote-tracking branch 'origin/episys/master-sa' into episys/david/channel_abstraction_on_top_of_MIMO_CSI_Reporting 2022-06-21 18:17:15 -07:00
Melissa Elkadi
61232c4557 Merge branch 'eurecom-develop' into episys/master-sa 2022-06-21 17:01:15 -07:00
Melissa Elkadi
5f8b20761b TBS + 2 bug fix (not standard compliant for nFAPI header)
Also, added a return 0; for invalid PDU length in the gNB.
This is a bug. We need to understand why the PDU length is
overrun. For now, this avoids indexing past the end of pduP
pointer.
2022-06-21 16:49:27 -07:00
David Kim
4ad9d66a3c Changed log level. 2022-06-20 18:24:08 -07:00
David Kim
5d4ad105b7 Merge remote-tracking branch 'origin/episys/master-sa' into episys/david/channel_abstraction_on_top_of_MIMO_CSI_Reporting 2022-06-20 11:56:33 -07:00
David Kim
fa8bc0b57c Updated to resolve crash when handling MAC pdus. 2022-06-20 11:26:24 -07:00
David Kim
1341cc35b9 Updated for NR traffic test. 2022-06-16 16:11:34 -07:00
Melissa Elkadi
173b4722fc Merge branch 'eurecom-develop' into episys/master-sa 2022-06-14 06:33:18 -07:00
David Kim
515093ca29 Updated SDAP setting to handle with NSA mode. 2022-06-09 10:10:17 -07:00
Melissa Elkadi
013e70d22d Bug fix in the NSA tunnel interface command
When the develop branch from OAI was merged,
the NSA tunnel interface command was was causing
a Heap-Buffer-Overflow. The filling of the buffer
was of size 500, but the memcpy in the RRC layer
was not matching the buffer size. Now, all buffer
sizes have been updated to be sufficient for the
content and are consistent.
2022-06-08 09:25:21 -07:00
David Kim
640ce7beed Updated to execute multiple UEs.
1. Introduced NR_NUM_SINR instead of NUM_SINR for NR case.
2. Extended Max number of UL PDU, Max number of RA Proc, and Max number of mobiles per gNB.
3. Changed log level to anlaysis for nsa and nr.
4. Fixed compiler warning regarding to data type in the logging of rsrp comparison.
2022-06-06 11:03:09 -07:00
Melissa Elkadi
d704dbec15 Symbol rotation not working properly.
This is a PHY function that we do not
use in our emulate-l1 mode. The previous
develop branch has broken the symbol_rotation
function, which causes the gNB to crash in
NSA mode. For now, we shunt out the functionality,
but an issue will be created in git for the
OAI team to investigate.
2022-06-03 18:07:27 -07:00
Melissa Elkadi
33989c3551 Merge branch 'eurecom-develop' into episys/master-sa 2022-06-03 18:07:13 -07:00
David Kim
6470165730 Fixed compile error when handling usim_data. 2022-06-02 21:56:34 -07:00
David Kim
fc33a75f22 Added AWGN_MIMO2x2 CDLC Bler table.
- Added env variable to refer to this bler table.
- Bler table will be chosen dynamically.
- Area code was used to select proper bler table.
2022-05-30 19:21:19 -07:00
David Kim
0645690f3d Handling edge case of channel info. 2022-05-26 18:26:44 -07:00
David Kim
e9a541a096 Updated csi structure members instead of encoding csi values. 2022-05-26 16:41:11 -07:00
David Kim
ec253251bc Merge branch 'episys/david/handover_step2_handover_execution' into episys/david/updating_MIMO_CSI_report_values 2022-05-26 13:43:30 -07:00
David Kim
ae72632b85 Merge remote-tracking branch 'origin/episys/master-sa' into episys/david/updating_MIMO_CSI_report_values 2022-05-26 13:15:42 -07:00
David Kim
b69a4aaa9b Updated rrc status and SINR value after Handover. 2022-05-25 17:43:41 -07:00
David Kim
fc56972a35 Code cleanup. 2022-05-20 16:35:28 -07:00
David Kim
f898a1724c Merge remote-tracking branch 'origin/episys/master-sa' into episys/david/handover_step2_handover_execution 2022-05-20 12:45:20 -07:00
David Kim
ef37bcf170 Updated pdcp functions to check uplink traffic.
In this commit, we confirm that uplink and downlink IP traffic is working for LTE handover.
The uplink traffic works only up to 3 Mbps, anything more it belongs to  show a lot of loss.
The downlink traffic and pings works well.
The following is additional update in this commit.

1. Used PDCP_COLL_KEY_VALUE to find key using rab_id after handover.
2. Disabled channel modeling in case of handover.
3. Updated rsrq by using rsrp.
2022-05-20 12:07:14 -07:00
David Kim
31437e3185 Updated rlc functions to check downlink traffic.
1. Downlink traffic is working.
2. Set default rlc mode to be AM even in drb case.
3. Code cleanup.
2022-05-18 19:07:07 -07:00
Melissa Elkadi
fb98755a48 Adding LOG_As back to OAI code for EpiSci tests 2022-05-18 09:12:23 -07:00
Melissa Elkadi
b2c07b620d Merge branch 'eurecom-develop' into episys/master-sa 2022-05-18 07:25:32 -07:00
David Kim
d3cda4816d Checking Msg3 size and code cleanup. 2022-05-16 11:20:05 -07:00
David Kim
8aaa384193 Updated sinr to csi to check rsrp. 2022-05-12 08:56:55 -07:00
David Kim
2eed6f18e4 Updated to use RSRP value to trigger handover. 2022-05-06 18:18:43 -07:00
David Kim
c79b681480 Added and updated config file for LTE HO.
1. Two eNB config file updated.
2. Removed lte specific node_number variable to get softmodem params.
3. Checking sfn_sf values for all eNBs.
4. Added phy_id member in phy_channel_params to identify source eNB.
2022-05-02 18:31:45 -07:00
David Kim
15b6259dcc Updated handover RACH Procedure together with code cleanup.
1. Added default case for handling actions in rrc_rlc_config_req.
2. Added a log for analysis purpose for Msg3 in rrc_eNB.
3. Handled RACH procedure to send Msg3 properly from UE.
4. Code cleanup.
2022-04-26 17:10:14 -07:00
David Kim
d3e96c6769 Updated pdcp and rlc layer config to reset for Handover.
1. Config reset in pdcp and rlc layer.
2. Adding new rb for target eNB.
3. eNB RRC layer received RRCConnectionReconfigurationComplete.
4. Need to setup further for NAS.
2022-04-22 10:07:36 -07:00
Melissa Elkadi
eef2fb907b Merge branch 'eurecom-develop' into episys/master-sa 2022-04-19 07:18:57 -07:00
Melissa Elkadi
29a68836fa Merge branch 'episys/master-sa' of gitlab.int-episci.com:aburger/openairinterface5g into episys/master-sa 2022-04-19 06:52:53 -07:00
David Kim
4b5cf91125 Added Msg4 with empty payload and received harq ack. 2022-04-18 15:58:05 -07:00
David Kim
e66640f5ab Updated ulsch_buffer for Handover Msg3.
1. Changed ulsch_buffer as static variable.
2. Swapped crnti bytes in eNB.
3. Changed status after sending Msg3 in UE.
2022-04-15 11:45:12 -07:00
David Kim
01921cf9f0 We receive the RAR and send Msg3. Fixes include:
- Properly providing crnti value to mac_rlc_status_ind() for HO (this
allowed us to be able to get the Msg3 from the RRC -> PDCP ->
RLC -> MAC). We were able to remove the hack we added in
the previous commit for BSR_Bytes.
- The unpacked rnti value from the
mobility info was saved incorrectly (bug fix)
- RX_IND and CRC_IND for msg3 crnti
had to be updated to the correct expected value.
- Currently, the ULSCH header is clearly incorrect.
- We can possibly try to call ue_get_sdu() instead.
2022-04-14 14:33:38 -07:00
David Kim
d30b232aeb Receiving RAR but sending incorrect Msg3.
- We started utilizing the HO case in the ue_get_rach
- We hacked the code to have BSR_Bytes > 0
- The BSR_Bytes is not properly set by RLC
- We then saw RAR received after shunting out RLC handling
- We are building msg3 before RAR
- We are sending "msg 3" = RX_IND after RAR
- The eNB does not like the Msg3 (It is CCCH - should be DCCH)
- The next steps are to look at why the RX is CCCH and not DCCH
- We can look at the RX we build in the UE to make sure its correct
2022-04-13 13:34:55 -07:00
David Kim
f9d93403d0 Updated preamble index for handover. 2022-04-12 17:51:27 -07:00
David Kim
2c84fdbea3 nFAPI queue reset for handover. 2022-04-07 19:05:34 -07:00
David Kim
61ebbc3403 Detach from source eNB. 2022-04-07 13:56:15 -07:00
Melissa
4d8615c4fa Merge branch 'episys/rt_sched_or_sanitizer' into 'episys/master-sa'
pthread_create and the RT scheduler together are incompatible in Ubuntu 18.04+

See merge request aburger/openairinterface5g!119
2022-04-06 22:06:41 +00:00
Melissa
55eb112ab0 pthread_create and the RT scheduler together are incompatible in Ubuntu 18.04+ 2022-04-06 22:06:40 +00:00
David Kim
9fa16cd5b9 Inactivating X2U interface. 2022-04-06 11:53:44 -07:00
Melissa Elkadi
6101792f4a Merge branch 'episys/master-sa' into episys/rt_sched_or_sanitizer 2022-04-05 14:23:16 -07:00
David Kim
b931c1b008 Updated the 4th byte value of cellIdentitys(28 bits length). 2022-04-04 16:49:34 -07:00
Melissa Elkadi
6aa1ad83a6 pthread_create and the RT scheduler together are incompatible.
When we run with the RT scheduler and the address santizer in
Ubuntu 18.04, pthread_create will hang and never create threads.
2022-04-04 14:55:50 -07:00
David Kim
634f7dc1e6 Updated to fix asn encoding error. 2022-04-04 10:44:09 -07:00
David Kim
80420d7cba Enabled ASAN log and print. 2022-04-01 15:46:23 -07:00
David Kim
b62d2fcf08 Adjusted to one udp interface. 2022-03-31 20:06:03 -07:00
David Kim
e5f851b01e Updated config file for handover. 2022-03-30 10:33:46 -07:00
David Kim
12cecf668a Enabled mreasurement report. 2022-03-25 09:47:58 -07:00
David Kim
f92a972aa5 Adjusted the delta of port numbering between eNBs. 2022-03-25 09:45:48 -07:00
David Kim
756ff02fb7 Updated eNB config for X2C in lte handover. 2022-03-23 17:42:35 -07:00
David Kim
1acb2fe894 Added additional UDP connection for handover. 2022-03-23 15:46:50 -07:00
Melissa Elkadi
4694664470 Merge branch 'eurecom-develop' into episys/master-sa 2022-03-22 16:59:25 -07:00
David Kim
10c992bb27 Added AssertFatal for operation of eNB node_number. 2022-03-22 16:03:59 -07:00
David Kim
5c443ee7a5 code cleanup when using node_number. 2022-03-22 15:56:11 -07:00
David Kim
2785c83a90 Added vnf p7 port arguement when calling configure_nfapi_vnf. 2022-03-22 15:48:56 -07:00
David Kim
a7f35bba02 code cleanup. 2022-03-22 15:43:10 -07:00
David Kim
cb5f8919e4 Fixed argument format in function. 2022-03-22 15:29:33 -07:00
David Kim
16371a8f5d Updated PDCP config for multiple eNB by using node_number.
Updated target eNB's config for nFAPI connection.
2022-03-22 13:15:58 -07:00
David Kim
98ac49f1bb Adding update from episci/master-sa. 2022-03-15 16:33:45 -07:00
David Kim
5006fd48d8 Adding one more eNB config file for LTE handover. 2022-03-15 16:23:34 -07:00
David Kim
a389eb8fd6 Function reallocation for downlink cqi value. 2022-03-09 12:21:27 -08:00
David Kim
c68640f6f7 Code cleanup by removing some added logs. 2022-03-09 12:02:56 -08:00
David Kim
2695df5f31 Updated cqi value setting. 2022-03-09 11:51:49 -08:00
David Kim
fd4dbbfb35 Updated for MIMO CSI Reporting. 2022-03-09 10:55:10 -08:00
David Kim
5902aaf138 Updated pdsch_AntennaPorts = 2. 2022-03-08 17:53:39 -08:00
David Kim
fc2ba4f4bd Removed duplicated semicolon at the end of line. 2022-03-08 17:51:23 -08:00
David Kim
d50dae5005 Cleaned code by removing logs. 2022-03-08 17:50:46 -08:00
David Kim
e883528dd1 Added zero pad in reporting PMI in nrUE. 2022-03-08 17:49:38 -08:00
David Kim
b1f721503e Added CSI report signaling with default values. 2022-03-08 17:43:09 -08:00
David Kim
c0e71341a5 Merge remote-tracking branch 'eurocom/tdd25period_for_MR' into episys/david/merge_develop 2022-03-08 11:22:18 -08:00
Melissa Elkadi
f2b9d369bd Reveting hack that was added to master-sa 2022-03-08 10:56:23 -08:00
Melissa
b1a1d1d0dd Merge branch 'error-checking-ul-tti-req' into 'episys/master-sa'
Clean up to nFAPI and error checking UL_TTI_REQ n_pdus

See merge request aburger/openairinterface5g!115
2022-03-08 16:48:53 +00:00
Melissa Elkadi
51e56f74d8 Merge remote-tracking branch 'eurecom/episys-throughput-updates-and-downlink-siso-cm' into episys/master-sa 2022-03-07 12:16:37 -08:00
Melissa Elkadi
a34ce559a4 Removing untracked/unnecessary conf files 2022-03-07 11:31:17 -08:00
Melissa Elkadi
8bf7e77b0e Merge branch 'episys-throughput-updates-and-downlink-siso-cm' into episys/master-sa
This commit includes resolutions for MR comments from OAI
2022-03-07 11:28:55 -08:00
Melissa Elkadi
7b633b141f Merge branch 'eurecom-develop' into episys/master-sa 2022-03-07 09:09:18 -08:00
Melissa Elkadi
95dbe3089e Adding min_rxtxtime to internal proxy conf file 2022-03-01 08:27:59 -08:00
Melissa Elkadi
ee2f7c8a5c Merge branch 'eurecom-develop' into episys/master-sa 2022-03-01 07:45:48 -08:00
79 changed files with 5109 additions and 839 deletions

View File

@@ -1203,10 +1203,15 @@ set(PHY_SRC_UE
${OPENAIR1_DIR}/PHY/MODULATION/slot_fep_nr.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/pss_nr.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/sss_nr.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/pss_nr_sl.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/sss_nr_sl.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_generate_psbch_dmrs_sl.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/psbch_nr_sl.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/cic_filter_nr.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_pbch.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_psbch.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
@@ -2436,7 +2441,19 @@ target_link_libraries(nr_pbchsim PRIVATE
target_link_libraries(nr_pbchsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
#PUCCH ---> Prashanth
add_executable(nr_psbchsim
${OPENAIR1_DIR}/SIMULATION/NR_PHY/psbchsim.c
${OPENAIR_DIR}/common/utils/nr/nr_common.c
${T_SOURCE}
${SHLIB_LOADER_SOURCES}
)
target_link_libraries(nr_psbchsim PRIVATE
-Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
m pthread ${ATLAS_LIBRARIES} ${T_LIB} ITTI dl
)
target_link_libraries(nr_psbchsim PRIVATE asn1_nr_rrc asn1_lte_rrc)
add_executable(nr_pucchsim
${OPENAIR1_DIR}/SIMULATION/NR_PHY/pucchsim.c
${OPENAIR1_DIR}/SIMULATION/NR_PHY/nr_dummy_functions.c
@@ -2567,7 +2584,7 @@ if (${T_TRACER})
lte-softmodem lte-uesoftmodem nr-softmodem
nr-uesoftmodem dlsim dlsim_tm4 dlsim_tm7
ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim
syncsim nr_ulsim nr_dlsim nr_dlschsim nr_pbchsim nr_pucchsim
syncsim nr_ulsim nr_dlsim nr_dlschsim nr_pbchsim nr_psbchsim nr_pucchsim
nr_ulschsim ldpctest polartest smallblocktest cu_test du_test
#all "add_library" definitions
ITTI lte_rrc nr_rrc s1ap x2ap m2ap m3ap f1ap

341
ci-scripts/run_sl_test.py Executable file
View File

@@ -0,0 +1,341 @@
#!/usr/bin/env python3
#
# Automated tests for running 5G NR Sidelink SyncRef UE and/or Nearby UE.
# The following is an example to run remote machine (nearby) three times.
# The syncref UE is launched on the current machine, and a single
# nearby UE is launched on the machine specified by the --host and
# --user flags. The -r will enable this simulation to be repeated
# three times.
#
# python3 run_sl_test.py --user account --host 10.1.1.68 -r 3
#
# The following is an example to run just a Sidelink Nearby UE.
# By specifying -l nearby, only the nearby UE will be launched
# on the machine specified by the --host and --user flags.
# The -r will enable this simulation to be repeated two times.
#
# python3 run_sl_test.py -l nearby --user account --host 10.1.1.68 -r 2
#
# See `--help` for more information.
#
import os
import sys
import argparse
import logging
import time
import re
import glob
import subprocess
from subprocess import Popen
import threading
from typing import Dict
from queue import *
from sl_check_log import LogChecker
HOME_DIR = os.path.expanduser( '~' )
# ----------------------------------------------------------------------------
# Command line argument parsing
parser = argparse.ArgumentParser(description="""
Automated tests for 5G NR Sidelink simulations
""")
parser.add_argument('--launch', '-l', default='both', choices='syncref nearby both'.split(), help="""
Sidelink UE type to launch test scenario (default: %(default)s)
""")
parser.add_argument('--host', default='10.1.1.80', type=str, help="""
Nearby Host IP (default: %(default)s)
""")
parser.add_argument('--user', '-u', default='zaid', type=str, help="""
User id in Nearby Host (default: %(default)s)
""")
parser.add_argument('--repeat', '-r', default=1, type=int, help="""
The number of repeated test iterations (default: %(default)s)
""")
parser.add_argument('--basic', '-b', action='store_true', help="""
Basic test with basic shell commands
""")
parser.add_argument('--commands', default='sl_cmds.txt', help="""
The USRP Commands .txt file (default: %(default)s)
""")
parser.add_argument('--duration', '-d', metavar='SECONDS', type=int, default=30, help="""
How long to run the test before stopping to examine the logs
""")
parser.add_argument('--nid1', type=int, default=10, help="""
Nid1 value
""")
parser.add_argument('--nid2', type=int, default=1, help="""
Nid2 value
""")
parser.add_argument('--log-dir', default=HOME_DIR, help="""
Where to store log files
""")
parser.add_argument('--compress', action='store_true', help="""
Compress the log files in the --log-dir
""")
parser.add_argument('--no-run', '-n', action='store_true', help="""
Don't run the test, only examine the logs in the --log-dir
directory from a previous run of the test
""")
parser.add_argument('--debug', action='store_true', help="""
Enable debug logging (for this script only)
""")
parser.add_argument('--test', '-t', default='usrp', choices='psbchsim rfsim usrp'.split(), help="""
The kind of test scenario to run. The options include psbchsim, rfsim, or usrp. (default: %(default)s)
""")
OPTS = parser.parse_args()
del parser
logging.basicConfig(level=logging.DEBUG if OPTS.debug else logging.INFO,
format='>>> %(name)s: %(levelname)s: %(message)s')
LOGGER = logging.getLogger(os.path.basename(sys.argv[0]))
# ----------------------------------------------------------------------------
def redirect_output(cmd: str, filename: str) -> str:
cmd += ' >{} 2>&1'.format(filename)
return cmd
def thread_delay(thread_name: str, delay: int) -> None:
count = 0
while count < 1:
time.sleep(delay)
count += 1
class Command:
"""
Parsing USRP commands file
"""
def __init__(self, filename) -> None:
self.check_user()
self.filename = self.check_file(filename)
self.parse_commands()
def check_user(self) -> None:
if OPTS.test != 'usrp': return
if OPTS.launch != 'syncref' and OPTS.user == '':
LOGGER.error("--user followed by [user id] is mandatory to connect to remote machine")
sys.exit(1)
def check_file(self, filename) -> str:
data_file = glob.glob(filename)
if data_file:
return filename
else:
LOGGER.error(f'The file {filename} does not exist!')
sys.exit(1)
def parse_commands(self) -> None:
"""
Scan the provided commands file.
"""
self.launch_cmds: Dict[str, str] = {}
if OPTS.test == 'usrp':
launch_cmds_re = re.compile(r'^\s*(\S*)usrp\S*\s*=\s*((\S+\s*)*)')
elif OPTS.test == 'rfsim':
launch_cmds_re = re.compile(r'^\s*(\S*)rfsim\S*\s*=\s*((\S+\s*)*)')
elif OPTS.test == 'psbchsim':
launch_cmds_re = re.compile(r'^\s*(\S*)psbchsim\S*\s*=\s*((\S+\s*)*)')
else:
LOGGER.error("Provided test option not valid! %s", OPTS.test)
exit(1)
with open(self.filename, 'rt') as fh:
nearby_cmd_continued = False
syncref_cmd_continued = False
for line in fh:
if line == '\n': continue
match = launch_cmds_re.match(line)
if match:
host_role = match.group(1)
launch_cmds = match.group(2)
if host_role.lower().startswith('nearby'):
nearby_cmd_continued = True
continue
if host_role.lower().startswith('syncref'):
syncref_cmd_continued = True
continue
elif nearby_cmd_continued:
launch_cmds += line
if not line.strip().endswith('\\'):
self.launch_cmds['nearby'] = launch_cmds
LOGGER.debug('Nearby cmd is %s', launch_cmds)
nearby_cmd_continued = False
continue
elif syncref_cmd_continued:
launch_cmds += line
if not line.strip().endswith('\\'):
self.launch_cmds['syncref'] = launch_cmds
LOGGER.debug('Syncref cmd is %s', launch_cmds)
syncref_cmd_continued = False
continue
else:
LOGGER.debug('Unmatched line %r', line)
continue
if self.launch_cmds == {}:
LOGGER.error(f'usrp commands are not found in file: {self.filename} ')
exit()
class TestThread(threading.Thread):
"""
Represents TestThread
"""
def __init__(self, queue, commands, passed, log_agent):
threading.Thread.__init__(self)
self.queue = queue
self.commands = commands
self.passed = passed
self.delay = 0
self.log_file = log_agent.txlog_file_path
self.log_agent = log_agent
def run(self):
if self.queue.empty() == True:
LOGGER.error("Queue is empty!")
sys.exit(1)
try:
while not self.queue.empty():
job = self.queue.get()
if "nearby" == job:
thread_delay(job, delay = 0)
self.launch_nearby(job)
if "syncref" == job and not OPTS.no_run:
thread_delay(job, delay = self.delay)
self.launch_syncref(job)
self.queue.task_done()
except Exception as inst:
LOGGER.info(f"Failed to operate on job with type {type(inst)} and args {inst.args}")
def launch_syncref(self, job) -> Popen:
LOGGER.info('Launching SyncRef UE')
if OPTS.basic: cmd = redirect_output('uname -a', self.log_file)
else: cmd = self.commands.launch_cmds[job]
proc = Popen(cmd, shell=True)
LOGGER.info(f"syncref_proc = {proc}")
if not OPTS.basic and not OPTS.no_run:
LOGGER.info(f"Process running... {job}")
time.sleep(OPTS.duration)
self.kill_process("syncref", proc)
def launch_nearby(self, job, host=OPTS.host, user=OPTS.user) -> Popen:
LOGGER.info('#' * 42)
LOGGER.info('Launching Nearby UE')
if OPTS.basic: cmd = redirect_output('uname -a', self.log_file)
else: cmd = self.commands.launch_cmds[job]
if OPTS.test == 'usrp':
cmd = cmd[:-1] + f' -d {OPTS.duration} --nid1 {OPTS.nid1} --nid2 {OPTS.nid2}'
proc = Popen(["ssh", f"{user}@{host}", cmd],
shell=False,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
LOGGER.info(f"nearby_proc = {proc}")
remote_output = proc.stdout.readlines()
if remote_output == []:
nearby_result = proc.stderr.readlines()
else:
nearby_result = remote_output
self.kill_process("nearby", proc)
if nearby_result:
self.find_nearby_result_metric(nearby_result)
else:
proc = Popen(cmd, shell=True)
LOGGER.info(f"nearby_proc = {proc}")
if not OPTS.basic and not OPTS.no_run:
LOGGER.info(f"Process running... {job}")
time.sleep(OPTS.duration)
self.kill_process("nearby", proc)
nearby_result = self.log_agent.analyze_nearby_logs(OPTS.nid1, OPTS.nid2)
if nearby_result:
self.find_nearby_result_metric(nearby_result)
def find_nearby_result_metric(self, remote_log):
result_metric = None
for line in remote_log:
if type(line) is not str:
line = line.decode()
if OPTS.test == 'usrp':
LOGGER.info(line.strip())
# 'SyncRef UE found. RSRP: -100 dBm/RE. It took {delta_time_s} seconds'
if 'SyncRef UE found' in line:
fields = line.split(maxsplit=12)
if len(fields) > 6:
ssb_rsrp = float(fields[-6])
sync_duration = float(fields[-2])
counting_duration = sync_duration - self.delay
result_metric = (ssb_rsrp, sync_duration, counting_duration)
self.passed += [result_metric]
return
def kill_process(self, job: str, proc: Popen) -> None:
# Wait for the processes to end
LOGGER.info(f'kill main simulation processes... {job}')
cmd = ['sudo', 'killall']
cmd.append('-KILL')
if proc:
cmd.append('nr-uesoftmodem')
if "syncref" == job:
subprocess.run(cmd)
LOGGER.info(f'Waiting for PID proc.pid for {job}')
proc.kill()
proc.wait()
LOGGER.info(f'kill main simulation processes...done for {job}')
# ----------------------------------------------------------------------------
def main() -> int:
commands = Command(OPTS.commands)
log_agent = LogChecker(OPTS, LOGGER)
LOGGER.debug(f'Number of iterations {OPTS.repeat}')
if commands.launch_cmds is not None:
for role, cmd in commands.launch_cmds.items():
LOGGER.debug(f'{role} UE: {cmd}')
jobs = ['nearby', 'syncref'] if OPTS.launch == 'both' else [OPTS.launch]
passed_metric = []
num_tx_ssb = []
num_passed = 0
for i in range(OPTS.repeat):
threads = []
queue = Queue()
for job in jobs:
queue.put(job)
th = TestThread(queue, commands, passed_metric, log_agent)
th.setDaemon(True)
th.start()
threads.append(th)
for th in threads:
th.join()
if num_passed != len(passed_metric):
# Examine the logs to determine if the test passed
(ssb_rsrp, sync_duration, counting_duration) = passed_metric[-1]
num_ssb = log_agent.analyze_syncref_logs(counting_duration)
num_tx_ssb += [num_ssb]
LOGGER.info(f"Trial {i+1}/{OPTS.repeat} PASSED. {num_ssb} SSB(s) were generated. Measured {ssb_rsrp} RSRP (dbm/RE)")
else:
LOGGER.info(f"Failure detected during {i+1}/{OPTS.repeat} trial(s).")
num_passed = len(passed_metric)
LOGGER.info('#' * 42)
LOGGER.info(f"Number of passed = {len(passed_metric)}/{OPTS.repeat}")
if len(num_tx_ssb) > 0:
LOGGER.info(f"Avg number of SSB = {sum(num_tx_ssb) / len(num_tx_ssb)} ({num_tx_ssb})")
if len(passed_metric) > 0:
LOGGER.info(f"Avg SSB RSRP = {sum([result[0] for result in passed_metric]) / len(passed_metric)}")
LOGGER.info(f"Avg Sync duration (seconds) = {sum([result[1] for result in passed_metric]) / len(passed_metric)}")
return 0
sys.exit(main())

112
ci-scripts/sl_check_log.py Executable file
View File

@@ -0,0 +1,112 @@
#!/usr/bin/env python3
import os
import bz2
import logging
from typing import Optional, List, Generator
class LogChecker():
def __init__(self, OPTS, LOGGER):
self.OPTS = OPTS
self.LOGGER = LOGGER
self.rxlog_file_path = os.path.join(OPTS.log_dir, 'rx.log')
self.txlog_file_path = os.path.join(OPTS.log_dir, 'tx.log')
def get_lines(self, filename: str) -> Generator[str, None, None]:
"""
Yield each line of the given log file (.bz2 compressed log file if -c flag is used.)
"""
fh = bz2.open(filename, 'rb') if self.OPTS.compress else open(filename, 'rb')
for line_bytes in fh:
line = line_bytes.decode('utf-8', 'backslashreplace')
line = line.rstrip('\r\n')
yield line
def get_analysis_messages_nearby(self, filename: str) -> Generator[str, None, None]:
"""
Finding all logs in the log file with X fields for log parsing optimization
"""
self.LOGGER.info('Scanning %s', filename)
for line in self.get_lines(filename):
#796821.854505 [NR_PHY] SyncRef UE found with Nid1 10 and Nid2 1 SS-RSRP 100 dBm/RE
#796811.532881 [NR_PHY] nrUE configured
fields = line.split(maxsplit=10)
if len(fields) == 11 or len(fields) == 4:
yield line
def analyze_nearby_logs(self, exp_nid1: int, exp_nid2: int) -> bool:
found = set()
est_nid1, est_nid2, time_start_s, time_end_s = -1, -1, -1, -1
ssb_rsrp = 0
log_file = self.rxlog_file_path
result = None
if self.OPTS.compress:
log_file = f'{log_file}.bz2'
for line in self.get_analysis_messages_nearby(log_file):
#796821.854505 [NR_PHY] SyncRef UE found with Nid1 10 and Nid2 1 SS-RSRP -100 dBm/RE
#796811.532881 [NR_PHY] nrUE configured
if 'SyncRef UE found' in line and 'Nid1' in line and 'Nid2' in line:
num_split = 13 if 'RSRP' in line else 10
fields = line.split(maxsplit=num_split)
est_nid1 = int(fields[7])
est_nid2 = int(fields[10])
if 'RSRP' in line:
ssb_rsrp = int(fields[12])
found.add('found')
time_end_s = float(fields[0])
break
if time_start_s == -1 and 'nrUE configured' in line:
fields = line.split(maxsplit=3)
time_start_s = float(fields[0])
self.LOGGER.debug('found: %r', found)
if len(found) != 1:
self.LOGGER.error(f'Failed -- No SyncRef UE found.')
return
elif exp_nid1 != est_nid1 or exp_nid2 != est_nid2:
self.LOGGER.error(f'Failed -- found SyncRef UE Nid1 {est_nid1}, Ni2 {est_nid2}, expecting Nid1 {exp_nid1}, Nid2 {exp_nid2}')
return
if time_start_s == -1:
self.LOGGER.error(f'Failed -- No start time found! Fix log and re-run!')
return
delta_time_s = time_end_s - time_start_s
result = f'SyncRef UE found. RSRP: {ssb_rsrp} dBm/RE. It took {delta_time_s} seconds'
self.LOGGER.info(result)
return [result]
def get_analysis_messages_syncref(self, filename: str) -> Generator[str, None, None]:
"""
Finding all logs in the log file with X fields for log parsing optimization
"""
self.LOGGER.info('Scanning %s', filename)
for line in self.get_lines(filename):
#796811.532881 [NR_PHY] nrUE configured
#796821.854505 [NR_PHY] PSBCH SL generation started
fields = line.split(maxsplit=5)
if len(fields) == 4 or len(fields) == 6 :
yield line
def analyze_syncref_logs(self, counting_delta: float) -> int:
time_start_s, time_end_s = -1, -1
log_file = self.txlog_file_path
sum_ssb = 0
if self.OPTS.compress:
tx_log_file = f'{log_file}.bz2'
for line in self.get_analysis_messages_syncref(log_file):
#796811.532881 [NR_PHY] nrUE configured
#796821.854505 [NR_PHY] PSBCH SL generation started
if time_start_s == -1 and 'nrUE configured' in line:
fields = line.split(maxsplit=2)
time_start_s = float(fields[0])
time_end_s = time_start_s + counting_delta
if 'PSBCH SL generation started' in line:
fields = line.split(maxsplit=2)
time_st = float(''.join([ch for ch in fields[0] if ch.isnumeric() or ch =='.']))
if time_st < time_end_s:
sum_ssb += 1
return sum_ssb

45
ci-scripts/sl_cmds.txt Normal file
View File

@@ -0,0 +1,45 @@
# The lines containing 'usrp' and starts with 'syncref' or 'nearby' will be valid until it does not contain backspace.
####################
#### USRP ####
####################
### RX Nearby UE ###
nearby_usrp_cmd = cd $HOME/openairinterface5g/ci-scripts; \
python3 sl_rx_agent.py --cmd \
'sudo -E LD_LIBRARY_PATH=$HOME/openairinterface5g/cmake_targets/ran_build/build:$LD_LIBRARY_PATH \
$HOME/openairinterface5g/cmake_targets/ran_build/build/nr-uesoftmodem \
--sl-mode 2 -r 106 --numerology 1 --band 38 --SLC 2600000000 --ue-rxgain 90 \
--usrp-args "type=n3xx,addr=192.168.20.2,subdev=A:0,master_clock_rate=122.88e6" \
--log_config.global_log_options time,nocolor \
> ~/rx.log 2>&1'
### TX SyncRef UE ###
syncref_usrp_cmd = \
sudo -E LD_LIBRARY_PATH=$HOME/openairinterface5g/cmake_targets/ran_build/build:$LD_LIBRARY_PATH \
$HOME/openairinterface5g/cmake_targets/ran_build/build/nr-uesoftmodem \
--sl-mode 2 --sync-ref -r 106 --numerology 1 --band 38 --SLC 2600000000 --ue-txgain 8 \
--usrp-args "type=n3xx,addr=192.168.10.2,subdev=A:0,master_clock_rate=122.88e6" \
--log_config.global_log_options time,nocolor\
> ~/tx.log 2>&1
####################
#### RFSIM ####
####################
### RX Nearby UE ###
nearby_rfsim_cmd = \
sudo -E RFSIMULATOR=127.0.0.1 \
$HOME/openairinterface5g/cmake_targets/ran_build/build/nr-uesoftmodem \
--rfsim --sl-mode 2 --rfsimulator.serverport 4048 \
--log_config.global_log_options time,nocolor \
> ~/rx.log 2>&1
### TX SyncRef UE ###
syncref_rfsim_cmd = \
sudo -E RFSIMULATOR=server \
$HOME/openairinterface5g/cmake_targets/ran_build/build/nr-uesoftmodem \
--sync-ref --rfsim --sl-mode 2 --rfsimulator.serverport 4048 \
--log_config.global_log_options time,nocolor \
> ~/tx.log 2>&1

218
ci-scripts/sl_rx_agent.py Executable file
View File

@@ -0,0 +1,218 @@
#!/usr/bin/env python3
#
# Automated tests for running 5G NR Sidelink Nearby UE.
# The following is an example to run this script.
#
# python3 sl_rx_agent.py \
# --cmd 'sudo -E LD_LIBRARY_PATH=$HOME/openairinterface5g/cmake_targets/ran_build/build:$LD_LIBRARY_PATH \
# $HOME/openairinterface5g/cmake_targets/ran_build/build/nr-uesoftmodem \
# --sl-mode 2 -r 106 --numerology 1 --band 38 -C 2600000000 --ue-rxgain 90 \
# --usrp-args "type=n3xx,addr=192.168.20.2,subdev=A:0,master_clock_rate=122.88e6" \
# > ~/rx.log 2>&1' \
# --nid1 10 --nid2 1
#
# See `--help` for more information.
#
import os
import sys
import argparse
import logging
import time
import glob
import bz2
import subprocess
from subprocess import Popen
from typing import Optional, List
from sl_check_log import LogChecker
HOME_DIR = os.path.expanduser( '~' )
# ----------------------------------------------------------------------------
# Command line argument parsing
parser = argparse.ArgumentParser(description="""
Automated tests for 5G NR Sidelink Rx simulations
""")
parser.add_argument('--duration', '-d', metavar='SECONDS', type=int, default=30, help="""
How long to run the test before stopping to examine the logs
""")
parser.add_argument('--cmd', type=str, default='', help="""
Commands
""")
parser.add_argument('--nid1', type=int, default=10, help="""
Nid1 value
""")
parser.add_argument('--nid2', type=int, default=1, help="""
Nid2 value
""")
parser.add_argument('--log-dir', default=HOME_DIR, help="""
Where to store log files
""")
parser.add_argument('--compress', '-c', action='store_true', help="""
Compress the log files in the --log-dir
""")
parser.add_argument('--no-run', '-n', action='store_true', help="""
Don't run the test, only examine the logs in the --log-dir
directory from a previous run of the test
""")
parser.add_argument('--debug', action='store_true', help="""
Enable debug logging (for this script only)
""")
OPTS = parser.parse_args()
del parser
logging.basicConfig(level=logging.DEBUG if OPTS.debug else logging.INFO,
format='>>> %(name)s: %(levelname)s: %(message)s')
LOGGER = logging.getLogger(os.path.basename(sys.argv[0]))
log_file_path = os.path.join(OPTS.log_dir, 'rx.log')
# ----------------------------------------------------------------------------
def compress(from_name: str, to_name: Optional[str]=None, remove_original: bool=False) -> None:
"""
Compress the file `from_name` and store it as `to_name`.
`to_name` defaults to `from_name` with `.bz2` appended.
If `remove_original` is True, removes `from_name` when the compress finishes.
"""
if to_name is None:
to_name = from_name
if not to_name.endswith('.bz2'):
to_name += '.bz2'
LOGGER.info('Compress %s to %s', from_name, to_name)
with bz2.open(to_name, 'w') as outh, \
open(from_name, 'rb') as inh:
while True:
data = inh.read(10240)
if not data:
break
outh.write(data)
if remove_original:
LOGGER.debug('Remove %s', from_name)
os.remove(from_name)
class CompressJobs:
"""
Allow multiple invocations of `compress` to run in parallel
"""
def __init__(self) -> None:
self.kids: List[int] = []
def compress(self, from_name: str, to_name: Optional[str]=None, remove_original: bool=False) -> None:
if not os.path.exists(from_name):
# It's not necessarily an error if the log file does not exist.
# For example, if nfapi_trace never gets invoked (e.g., because
# NFAPI_TRACE_LEVEL is set to none), then the log file nfapi.log
# will not get created.
LOGGER.warning('No file: %s', from_name)
return
kid = os.fork()
if kid != 0:
self.kids.append(kid)
else:
LOGGER.debug('in pid %d compress %s...', os.getpid(), from_name)
compress(from_name, to_name, remove_original)
LOGGER.debug('in pid %d compress %s...done', os.getpid(), from_name)
sys.exit()
def wait(self) -> None:
LOGGER.debug('wait %s...', self.kids)
failed = []
for kid in self.kids:
LOGGER.debug('waitpid %d', kid)
_pid, status = os.waitpid(kid, 0)
if status != 0:
failed.append(kid)
if failed:
raise Exception('compression failed: %s', failed)
LOGGER.debug('wait...done')
class TestNearby():
"""
Represents TestNearby
"""
def __init__(self):
self.cmd = None
self.delay = 0 # seconds
def run(self, cmd: str) -> bool:
self.cmd = cmd
job = "nearby"
time.sleep(self.delay)
proc = self.launch_nearby(job)
LOGGER.info(f"nearby_proc = {proc}")
LOGGER.info(f"Process running... {job}")
time.sleep(OPTS.duration)
passed = self.kill_process("nearby", proc)
if OPTS.compress:
self.compress_log_file(proc)
return passed
def launch_nearby(self, job) -> Popen:
LOGGER.info('Launching Nearby UE: %s', log_file_path)
cmd = self.cmd
proc = Popen(cmd, shell=True)
time.sleep(1)
return proc
def kill_process(self, job: str, proc: Popen) -> bool:
passed = True
if proc:
status = proc.poll()
if status is None:
LOGGER.info('process is still running, which is good')
else:
#passed = False
LOGGER.info('process ended early: %r', status)
LOGGER.info(f'kill main simulation processes... {job}')
cmd = ['sudo', 'killall']
cmd.append('-KILL')
if proc:
cmd.append('nr-uesoftmodem')
if "nearby" == job:
subprocess.run(cmd)
LOGGER.info(f'Waiting for PID proc.pid for {job}')
proc.kill()
proc.wait()
LOGGER.info(f'kill main simulation processes...done for {job}')
return passed
def compress_log_file(self, proc: Popen):
jobs = CompressJobs()
jobs.compress(log_file_path)
jobs.wait()
# ----------------------------------------------------------------------------
def main(argv) -> int:
test_agent = TestNearby()
log_agent = LogChecker(OPTS, LOGGER)
passed = True
if not OPTS.no_run:
passed = test_agent.run(OPTS.cmd)
# Examine the logs to determine if the test passed
if not log_agent.analyze_nearby_logs(exp_nid1=OPTS.nid1, exp_nid2=OPTS.nid2):
passed = False
if not passed:
LOGGER.critical('FAILED')
return 1
LOGGER.info('PASSED')
return 0
sys.exit(main(sys.argv))

View File

@@ -147,6 +147,18 @@
<nruns>3</nruns>
</testCase>
<testCase id="nr_psbchsim.106rb">
<desc>nr_psbchsim Test cases. (Test1: PSBCH and synchronization, 106PBR),
(Test2: PSBCH and synchronization, 106PBR, SSB SC OFFSET 6)</desc>
<main_exec>nr_psbchsim</main_exec>
<main_exec_args>-s-11 -S2 -n1 -I -R106
-s-11 -S2 -n1 -I -R106 -O6</main_exec_args>
<tags>test1 test2 test3</tags>
<search_expr_true>PSBCH test OK</search_expr_true>
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
<nruns>3</nruns>
</testCase>
<testCase id="nr_dlsim.basic">
<desc>nr_dlsim Test cases. (Test1: 106 PRB),
(Test2: 217 PRB),

View File

@@ -508,7 +508,7 @@ function main() {
[[ "$UE" == 1 ]] && execlist="$execlist lte-uesoftmodem"
[[ "$nrUE" == 1 ]] && execlist="$execlist nr-uesoftmodem"
# TODO: fix: dlsim_tm4 pucchsim prachsim pdcchsim pbchsim mbmssim
[[ "$SIMUS_PHY" == "1" ]] && execlist="$execlist dlsim ulsim ldpctest polartest smallblocktest nr_pbchsim nr_dlschsim nr_ulschsim nr_dlsim nr_ulsim nr_pucchsim nr_prachsim"
[[ "$SIMUS_PHY" == "1" ]] && execlist="$execlist dlsim ulsim ldpctest polartest smallblocktest nr_pbchsim nr_psbchsim nr_dlschsim nr_ulschsim nr_dlsim nr_ulsim nr_pucchsim nr_prachsim"
[[ "$BUILD_OPTLIB" != "" ]] && execlist="$execlist $BUILD_OPTLIB"
[[ "$execlist" != "" ]] && execlist="$execlist params_libconfig coding rfsimulator"

View File

@@ -30,7 +30,7 @@ The main oai binaries, which are tested by the Continuous Integration process ar
- The 5G gNodeB: `nr-softmodem`
- The 5G CU-UP: `nr-cuup`
- The LTE PHY simulators: `dlsim` and `ulsim`
- The 5G PHY simulators: `nr_dlschsim`, `nr_dlsim`, `nr_pbchsim`, `nr_pucchsim`, `nr_ulschsim`, `nr_ulsim`, `polartest`, `smallblocktest`, `nr _ulsim`, `ldpctest`
- The 5G PHY simulators: `nr_dlschsim`, `nr_dlsim`, `nr_pbchsim`, `nr_psbchsim`, `nr_pucchsim`, `nr_ulschsim`, `nr_ulsim`, `polartest`, `smallblocktest`, `nr _ulsim`, `ldpctest`
Running the [build_oai](../cmake_targets/build_oai) script also generates some utilities required to build and/or run the oai softmodem binaries:

View File

@@ -195,7 +195,8 @@ void rx_func(void *param)
gNB->common_vars.rxdataF[aa],
slot_rx,
0,
gNB->frame_parms.Ncp==EXTENDED?12:14);
gNB->frame_parms.Ncp==EXTENDED?12:14,
NR_LINK_TYPE_UL);
}
phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx);
}

View File

@@ -33,6 +33,13 @@
#include "executables/softmodem-common.h"
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
#include "radio/COMMON/common_lib.h"
#include "LAYER2/nr_pdcp/nr_pdcp_entity.h"
#include "SCHED_NR_UE/pucch_uci_ue_nr.h"
#include "openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h"
#include "openair1/PHY/NR_REFSIG/sss_nr.h"
#include "common/utils/nr/nr_common.h"
//#define DEBUG_PHY_SL_PROC
#include "pdcp.h"
#include "LAYER2/nr_pdcp/nr_pdcp_oai_api.h"
/*
@@ -99,7 +106,8 @@
typedef enum {
pss = 0,
pbch = 1,
si = 2
si = 2,
psbch = 3,
} sync_mode_t;
static void *NRUE_phy_stub_standalone_pnf_task(void *arg);
@@ -160,12 +168,13 @@ void init_nr_ue_vars(PHY_VARS_NR_UE *ue,
// initialize all signal buffers
init_nr_ue_signal(ue, nb_connected_gNB);
if (get_softmodem_params()->sl_mode != 2) {
// intialize transport
init_nr_ue_transport(ue);
// intialize transport
init_nr_ue_transport(ue);
// init N_TA offset
init_N_TA_offset(ue);
// init N_TA offset
init_N_TA_offset(ue);
}
}
void init_nrUE_standalone_thread(int ue_idx)
@@ -376,7 +385,12 @@ static void UE_synch(void *arg) {
sync_mode_t sync_mode = pbch;
//int CC_id = UE->CC_id;
static int freq_offset=0;
UE->is_synchronized = 0;
if (get_softmodem_params()->sl_mode == 2) {
UE->is_synchronized_sl = 0;
sync_mode = psbch;
} else {
UE->is_synchronized = 0;
}
if (UE->UE_scan == 0) {
@@ -392,7 +406,6 @@ static void UE_synch(void *arg) {
}
sync_mode = pbch;
} else {
LOG_E(PHY,"Fixme!\n");
/*
@@ -492,9 +505,44 @@ static void UE_synch(void *arg) {
break;
case si:
case psbch: {
int initial_synch_sl = nr_sl_initial_sync(&syncD->proc, UE, 2);
if (initial_synch_sl >= 0) { // gNB will work as SyncRef UE in simulation.
// rerun with new cell parameters and frequency-offset
freq_offset = UE->common_vars.freq_offset; // frequency offset computed with pss in initial sync
nr_sl_rf_card_config_freq(UE, &openair0_cfg[UE->rf_map.card], freq_offset);
UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0]);
if (UE->UE_scan_carrier == 1) {
UE->UE_scan_carrier = 0;
} else {
if (initial_synch_sl == 0) {
UE->is_synchronized_sl = 1;
LOG_I(NR_PHY, "SyncRef UE found with Nid1 %d and Nid2 %d SSS-RSRP %d dBm/RE\n",
GET_NID1_SL(UE->frame_parms.Nid_SL), GET_NID2_SL(UE->frame_parms.Nid_SL),
UE->measurements.ssb_rsrp_dBm[0]);
exit(1);
}
}
} else {
LOG_I(NR_PHY, "No SyncRef UE found\n");
if (UE->UE_scan_carrier == 1) {
LOG_I(PHY, "Initial sync failed: trying carrier off %d Hz\n", freq_offset);
if (freq_offset >= 0)
freq_offset += 100;
freq_offset *= -1;
nr_sl_rf_card_config_freq(UE, &openair0_cfg[UE->rf_map.card], freq_offset);
UE->rfdevice.trx_set_freq_func(&UE->rfdevice, &openair0_cfg[0]);
}
}
break;
}
default:
break;
}
}
@@ -561,6 +609,8 @@ void processSlotTX(void *arg) {
nr_phy_data_tx_t phy_data = {0};
LOG_D(PHY,"%d.%d => slot type %d\n", proc->frame_tx, proc->nr_slot_tx, proc->tx_slot_type);
if (UE->sync_ref && get_softmodem_params()->sl_mode != 0)
proc->tx_slot_type = NR_UPLINK_SLOT;
if (proc->tx_slot_type == NR_UPLINK_SLOT || proc->tx_slot_type == NR_MIXED_SLOT){
// wait for rx slots to send indication (if any) that DLSCH decoding is finished
@@ -571,7 +621,7 @@ void processSlotTX(void *arg) {
// trigger L2 to run ue_scheduler thru IF module
// [TODO] mapping right after NR initial sync
if(UE->if_inst != NULL && UE->if_inst->ul_indication != NULL) {
if (get_softmodem_params()->sl_mode != 2 && UE->if_inst != NULL && UE->if_inst->ul_indication != NULL) {
start_meas(&UE->ue_ul_indication_stats);
nr_uplink_indication_t ul_indication;
memset((void*)&ul_indication, 0, sizeof(ul_indication));
@@ -589,10 +639,20 @@ void processSlotTX(void *arg) {
stop_meas(&UE->ue_ul_indication_stats);
}
phy_procedures_nrUE_TX(UE, proc, &phy_data);
if (get_softmodem_params()->sl_mode == 0) {
phy_procedures_nrUE_TX(UE, proc, &phy_data);
} else {
phy_procedures_nrUE_SL_TX(UE, proc, 0);
}
}
if (get_softmodem_params()->sl_mode == 0) {
RU_write(rxtxD);
}
}
RU_write(rxtxD);
void processSlotRX_SL(void *arg) {
nr_rxtx_thread_data_t *rxtxD = (nr_rxtx_thread_data_t *) arg;
processSlotTX(rxtxD);
}
nr_phy_data_t UE_dl_preprocessing(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
@@ -703,11 +763,11 @@ void readFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp, bool toTrash)
void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) {
LOG_I(PHY,"Resynchronizing RX by %d samples\n",UE->rx_offset);
int rx_offset = (get_softmodem_params()->sl_mode != 0) ? UE->rx_offset_sl : UE->rx_offset;
if (IS_SOFTMODEM_IQPLAYER || IS_SOFTMODEM_IQRECORDER) {
// Resynchonize by slot (will work with numerology 1 only)
for ( int size=UE->rx_offset ; size > 0 ; size -= UE->frame_parms.samples_per_subframe/2 ) {
for (int size = rx_offset; size > 0; size -= UE->frame_parms.samples_per_subframe / 2) {
int unitTransfer=size>UE->frame_parms.samples_per_subframe/2 ? UE->frame_parms.samples_per_subframe/2 : size ;
AssertFatal(unitTransfer ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
@@ -718,11 +778,11 @@ void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) {
}
} else {
*timestamp += UE->frame_parms.get_samples_per_slot(1,&UE->frame_parms);
for ( int size=UE->rx_offset ; size > 0 ; size -= UE->frame_parms.samples_per_subframe ) {
for (int size = rx_offset; size > 0; size -= UE->frame_parms.samples_per_subframe) {
int unitTransfer=size>UE->frame_parms.samples_per_subframe ? UE->frame_parms.samples_per_subframe : size ;
// we write before read because gNB waits for UE to write and both executions halt
// this happens here as the read size is samples_per_subframe which is very much larger than samp_per_slot
if (IS_SOFTMODEM_RFSIM) dummyWrite(UE,*timestamp, unitTransfer);
if (IS_SOFTMODEM_RFSIM) dummyWrite(UE,*timestamp, unitTransfer);
AssertFatal(unitTransfer ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
timestamp,
@@ -738,28 +798,305 @@ int computeSamplesShift(PHY_VARS_NR_UE *UE) {
int samples_shift = -(UE->rx_offset>>1);
if (samples_shift != 0) {
LOG_I(NR_PHY,"Adjusting frame in time by %i samples\n", samples_shift);
UE->rx_offset = 0; // reset so that it is not applied falsely in case of SSB being only in every second frame
if (get_softmodem_params()->sl_mode == 0) {
UE->rx_offset = 0; // reset so that it is not applied falsely in case of SSB being only in every second frame
} else {
UE->rx_offset_sl = 0; // reset so that it is not applied falsely in case of SSB being only in every second frame
}
UE->max_pos_fil += samples_shift << 15; // reset IIR filter when sample shift is applied
}
return samples_shift;
}
static inline int get_firstSymSamp(uint16_t slot, NR_DL_FRAME_PARMS *fp) {
static inline int get_firstSymSamp(uint16_t slot, NR_DL_FRAME_PARMS *fp, bool sync) {
uint16_t nb_prefix_samples0 = fp->nb_prefix_samples0;
if (get_softmodem_params()->sl_mode != 0) {
nb_prefix_samples0 = sync ? fp->nb_prefix_samples0 : fp->nb_prefix_samples;
}
if (fp->numerology_index == 0)
return fp->nb_prefix_samples0 + fp->ofdm_symbol_size;
int num_samples = (slot%(fp->slots_per_subframe/2)) ? fp->nb_prefix_samples : fp->nb_prefix_samples0;
int num_samples = (slot % (fp->slots_per_subframe / 2)) ? fp->nb_prefix_samples : nb_prefix_samples0;
num_samples += fp->ofdm_symbol_size;
return num_samples;
}
static inline int get_readBlockSize(uint16_t slot, NR_DL_FRAME_PARMS *fp) {
int rem_samples = fp->get_samples_per_slot(slot, fp) - get_firstSymSamp(slot, fp);
static inline int get_readBlockSize(uint16_t slot, NR_DL_FRAME_PARMS *fp, bool sync) {
int rem_samples = fp->get_samples_per_slot(slot, fp) - get_firstSymSamp(slot, fp, sync);
int next_slot_first_symbol = 0;
if (slot < (fp->slots_per_frame-1))
next_slot_first_symbol = get_firstSymSamp(slot+1, fp);
next_slot_first_symbol = get_firstSymSamp(slot+1, fp, sync);
return rem_samples + next_slot_first_symbol;
}
int slot_to_flag_sl(uint8_t tdd_period, int slot, uint16_t slot_config, uint16_t num_slot_frame) {
int flag, isUL, isULnext, isULbefore;
int num_period_slot = get_nb_periods_per_frame(tdd_period);
slot = slot % (num_slot_frame / num_period_slot);
isUL = (slot_config >> slot) & 0x1;// indicator to show if the slot is UL or DL
if (slot > 0) {
//checking if previous slot is UL
isULbefore = (slot_config >> (slot - 1)) & 0x1;
} else {
isULbefore = 0;
}
if (slot < (num_slot_frame / num_period_slot) - 1) {
// checking if next slot is UL
isULnext = (slot_config >> (slot+1)) & 0x1;
} else {
isULnext = 0;
}
if (isUL) {
if (slot == 0 || !isULbefore) {
flag = 2; // first slot should start transmission
} else if (slot == (num_slot_frame / num_period_slot) - 1 || !isULnext) {
flag = 3; // last slot that should stop transmission
} else {
flag = 1; // it is niether first nor last slot.
}
} else {
flag = 0; // don't transmit at all
}
LOG_D(NR_PHY, "### slot(%d), UL(%d), flag(%d)\n", slot, isUL, flag);
return flag;
}
void *UE_thread_SL(void *arg) {
PHY_VARS_NR_UE *UE = (PHY_VARS_NR_UE *) arg;
openair0_timestamp timestamp, writeTimestamp;
void *rxp[NB_ANTENNAS_RX], *txp[NB_ANTENNAS_TX];
AssertFatal(0 == openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]), "");
UE->rfdevice.host_type = RAU_HOST;
AssertFatal(UE->rfdevice.trx_start_func(&UE->rfdevice) == 0, "Could not start the device\n");
notifiedFIFO_t nf;
initNotifiedFIFO(&nf);
notifiedFIFO_t freeBlocks;
initNotifiedFIFO_nothreadSafe(&freeBlocks);
int nbSlotProcessing = 0;
NR_UE_MAC_INST_t *mac = get_mac_inst(0);
int timing_advance = UE->timing_advance;
UE->lost_sync_sl = 0;
UE->is_synchronized_sl = 0;
UE->sync_ref = get_softmodem_params()->sync_ref;
bool sync_running_sl = false;
const int nb_slot_frame = UE->frame_parms.slots_per_frame;
int absolute_slot = 0, decoded_frame_rx = INT_MAX, trashed_frames = 0, start_rx_stream = 0;
for (int i = 0; i < NR_RX_NB_TH + 1; i++) {// NR_RX_NB_TH working + 1 we are making to be pushed
notifiedFIFO_elt_t *newElt = newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), RX_JOB_ID, &nf, processSlotRX_SL);
nr_rxtx_thread_data_t *curMsg=(nr_rxtx_thread_data_t *)NotifiedFifoData(newElt);
initNotifiedFIFO(&curMsg->txFifo);
pushNotifiedFIFO_nothreadSafe(&freeBlocks, newElt);
}
while (!oai_exit) {
if (UE->lost_sync_sl && UE->sync_ref == 0) {
LOG_I(NR_PHY, "Sync UE: lost_sync status\n");
int nb = abortTpoolJob(&(get_nrUE_params()->Tpool),RX_JOB_ID);
nb += abortNotifiedFIFOJob(&nf, RX_JOB_ID);
LOG_I(PHY,"Number of aborted slots %d\n",nb);
for (int i=0; i<nb; i++)
pushNotifiedFIFO_nothreadSafe(&freeBlocks, newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), RX_JOB_ID, &nf, processSlotRX_SL));
nbSlotProcessing = 0;
UE->is_synchronized_sl = 0;
UE->lost_sync_sl = 0;
}
if (sync_running_sl && UE->sync_ref == 0) {
LOG_I(NR_PHY, "Nearby UE: sync_running status.\n");
notifiedFIFO_elt_t *res=tryPullTpool(&nf,&(get_nrUE_params()->Tpool));
if (res) {
sync_running_sl = false;
LOG_I(NR_PHY, "Nearby UE: sync_running was set to false due to valid res.\n");
syncData_t *tmp=(syncData_t *)NotifiedFifoData(res);
LOG_I(NR_PHY, "Nearby UE: UE->is_synchronized_sl = %d\n", UE->is_synchronized_sl);
if (UE->is_synchronized_sl && get_softmodem_params()->sl_mode < 2) {
decoded_frame_rx=(((mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | tmp->proc.decoded_frame_rx);
// shift the frame index with all the frames we trashed meanwhile we perform the synch search
decoded_frame_rx=(decoded_frame_rx + UE->init_sync_frame + trashed_frames) % MAX_FRAME_NUMBER;
}
delNotifiedFIFO_elt(res);
start_rx_stream = 0;
} else {
LOG_I(PHY, "Nearby UE: sync_running_sl still in readFrame due to INVALID res.\n");
readFrame(UE, &timestamp, true);
trashed_frames += 2;
continue;
}
}
AssertFatal(!sync_running_sl, "At this point synchronization can't be running\n");
if (UE->is_synchronized_sl == 0 && UE->sync_ref == 0) {
LOG_I(NR_PHY, "Sync UE: UE->is_synchronized_sl == 0 && UE->sync_ref == 0)\n");
readFrame(UE, &timestamp, false);
notifiedFIFO_elt_t *Msg=newNotifiedFIFO_elt(sizeof(syncData_t), 0, &nf, UE_synch);
syncData_t *syncMsg = (syncData_t *)NotifiedFifoData(Msg);
syncMsg->UE = UE;
memset(&syncMsg->proc, 0, sizeof(syncMsg->proc));
pushTpool(&(get_nrUE_params()->Tpool), Msg);
trashed_frames=0;
sync_running_sl =true;
continue;
}
if (start_rx_stream == 0 && UE->sync_ref == 0) {
start_rx_stream = 1;
syncInFrame(UE, &timestamp);
LOG_I(NR_PHY, "Sync UE: rx_stream = 1 and timestamp %ld\n", timestamp);
UE->rx_offset_sl = 0;
UE->time_sync_cell = 0;
uint16_t nb_prefix_samples0 = UE->is_synchronized_sl ? UE->frame_parms.nb_prefix_samples0 :
UE->frame_parms.nb_prefix_samples;
AssertFatal (UE->frame_parms.ofdm_symbol_size + nb_prefix_samples0 ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
&timestamp,
(void **)UE->common_vars.rxdata,
UE->frame_parms.ofdm_symbol_size + nb_prefix_samples0,
UE->frame_parms.nb_antennas_rx), "Could not read in first symbol");
// we have the decoded frame index in the return of the synch process
// and we shifted above to the first slot of next frame
decoded_frame_rx++;
// we do ++ first in the regular processing, so it will be begin of frame;
absolute_slot = decoded_frame_rx * nb_slot_frame - 1;
continue;
}
absolute_slot++;
// Fix me: will be wrong when slot 1 is slow, as slot 2 finishes
// Slot 3 will overlap if NR_RX_NB_TH is 2
// this is general failure in UE !!
int slot_nr = absolute_slot % nb_slot_frame;
notifiedFIFO_elt_t *msgToPush;
AssertFatal((msgToPush=pullNotifiedFIFO_nothreadSafe(&freeBlocks)) != NULL,"chained list failure");
nr_rxtx_thread_data_t *curMsg=(nr_rxtx_thread_data_t *)NotifiedFifoData(msgToPush);
curMsg->UE = UE;
// update thread index for received subframe
curMsg->proc.CC_id = UE->CC_id;
curMsg->proc.nr_slot_rx = slot_nr;
curMsg->proc.nr_slot_tx = (absolute_slot + DURATION_RX_TO_TX) % nb_slot_frame;
curMsg->proc.frame_rx = (absolute_slot/nb_slot_frame) % MAX_FRAME_NUMBER;
curMsg->proc.frame_tx = ((absolute_slot+DURATION_RX_TO_TX)/nb_slot_frame) % MAX_FRAME_NUMBER;
curMsg->proc.decoded_frame_rx=-1;
LOG_D(NR_PHY, "Process slot %d total gain %d\n", slot_nr, UE->rx_total_gain_dB);
int firstSymSamp = get_firstSymSamp(slot_nr, &UE->frame_parms, UE->is_synchronized_sl);
uint64_t write_time_stamp = UE->frame_parms.get_samples_slot_timestamp(slot_nr, &UE->frame_parms, 0);
uint64_t read_time_stamp = UE->frame_parms.get_samples_slot_timestamp(slot_nr, &UE->frame_parms, 0);
for (int i = 0; i<UE->frame_parms.nb_antennas_rx; i++)
rxp[i] = (void *)&UE->common_vars.rxdata[i][read_time_stamp];
for (int i = 0; i < UE->frame_parms.nb_antennas_tx; i++)
txp[i] = (void *)&UE->common_vars.txdata[i][write_time_stamp];
int readBlockSize, writeBlockSize;
if (slot_nr < (nb_slot_frame - 1)) {
readBlockSize = get_readBlockSize(slot_nr, &UE->frame_parms, UE->is_synchronized_sl);
writeBlockSize = UE->frame_parms.get_samples_per_slot(slot_nr, &UE->frame_parms);
} else {
UE->rx_offset_diff = computeSamplesShift(UE);
readBlockSize = get_readBlockSize(slot_nr, &UE->frame_parms, UE->is_synchronized_sl) - UE->rx_offset_diff;
writeBlockSize = UE->frame_parms.get_samples_per_slot(slot_nr, &UE->frame_parms) - UE->rx_offset_diff;
}
AssertFatal(readBlockSize ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
&timestamp,
rxp,
readBlockSize,
UE->frame_parms.nb_antennas_rx), "");
if (slot_nr == (nb_slot_frame - 1)) {
// read in first symbol of next frame and adjust for timing drift
uint16_t nb_prefix_samples0 = UE->is_synchronized_sl ? UE->frame_parms.nb_prefix_samples0 :
UE->frame_parms.nb_prefix_samples;
int first_symbols = UE->frame_parms.ofdm_symbol_size + nb_prefix_samples0;
if (first_symbols > 0) {
openair0_timestamp ignore_timestamp;
AssertFatal(first_symbols ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
&ignore_timestamp,
(void **)UE->common_vars.rxdata,
first_symbols,
UE->frame_parms.nb_antennas_rx),"");
} else {
LOG_E(NR_PHY, "Can't compensate: diff =%d\n", first_symbols);
}
}
curMsg->proc.timestamp_tx = timestamp +
UE->frame_parms.get_samples_slot_timestamp(slot_nr, &UE->frame_parms, DURATION_RX_TO_TX) -
firstSymSamp;
while (nbSlotProcessing >= NR_RX_NB_TH) {
notifiedFIFO_elt_t *res = pullTpool(&nf, &(get_nrUE_params()->Tpool));
if (res == NULL)
break; // Tpool has been stopped
nbSlotProcessing--;
nr_rxtx_thread_data_t *tmp = (nr_rxtx_thread_data_t *)res->msgData;
if (tmp->proc.decoded_frame_rx != -1)
decoded_frame_rx=(((mac->mib->systemFrameNumber.buf[0] >>
mac->mib->systemFrameNumber.bits_unused) << 4) |
tmp->proc.decoded_frame_rx);
else
decoded_frame_rx=-1;
pushNotifiedFIFO_nothreadSafe(&freeBlocks,res);
}
if (UE->sync_ref == 0 && decoded_frame_rx > 0 && decoded_frame_rx != curMsg->proc.frame_rx)
LOG_E(NR_PHY, "Sync UE: Decoded frame index (%d) is not compatible with current context (%d), "
"UE should go back to synch mode\n", decoded_frame_rx, curMsg->proc.frame_rx);
// use previous timing_advance value to compute writeTimestamp
writeTimestamp = timestamp +
UE->frame_parms.get_samples_slot_timestamp(slot_nr, &UE->frame_parms, DURATION_RX_TO_TX - NR_RX_NB_TH) -
firstSymSamp - openair0_cfg[0].tx_sample_advance - UE->N_TA_offset - timing_advance;
// but use current UE->timing_advance value to compute writeBlockSize
if (UE->timing_advance != timing_advance) {
writeBlockSize -= UE->timing_advance - timing_advance;
timing_advance = UE->timing_advance;
}
int flags = 1;
NR_DL_FRAME_PARMS *fp = &UE->frame_parms;
flags = slot_to_flag_sl(fp->tdd_period, slot_nr, fp->tdd_slot_config, fp->slots_per_frame);
if (flags || IS_SOFTMODEM_RFSIM) {
LOG_D(NR_PHY, "current slot goring to write USRP: %d\n", slot_nr);
AssertFatal(writeBlockSize ==
UE->rfdevice.trx_write_func(&UE->rfdevice,
writeTimestamp,
txp,
writeBlockSize,
UE->frame_parms.nb_antennas_tx,
flags), "");
}
#ifdef DEBUG_PHY_SL_PROC
char buffer[UE->frame_parms.ofdm_symbol_size];
for (int i = 0; i < 13; i++) {
bzero(buffer, sizeof(buffer));
LOG_I(NR_PHY, "Transmitted SSB %d = %s\n",
i, hexdump(&txp[0][UE->frame_parms.ofdm_symbol_size*i],
UE->frame_parms.ofdm_symbol_size, buffer, sizeof(buffer)));
}
#endif
for (int i = 0; i < UE->frame_parms.nb_antennas_tx; i++) {
memset(txp[i], 0, writeBlockSize);
}
nbSlotProcessing++;
LOG_D(NR_PHY, "Number of slots being processed at the moment: %d\n", nbSlotProcessing);
pushTpool(&(get_nrUE_params()->Tpool), msgToPush);
} // while !oai_exit
return NULL;
}
void *UE_thread(void *arg) {
//this thread should be over the processing thread to keep in real time
PHY_VARS_NR_UE *UE = (PHY_VARS_NR_UE *) arg;
@@ -897,7 +1234,7 @@ void *UE_thread(void *arg) {
}*/
#endif
int firstSymSamp = get_firstSymSamp(slot_nr, &UE->frame_parms);
int firstSymSamp = get_firstSymSamp(slot_nr, &UE->frame_parms, UE->is_synchronized);
for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
rxp[i] = (void *)&UE->common_vars.rxdata[i][firstSymSamp+
UE->frame_parms.get_samples_slot_timestamp(slot_nr,&UE->frame_parms,0)];
@@ -905,11 +1242,11 @@ void *UE_thread(void *arg) {
int readBlockSize, writeBlockSize;
if (slot_nr<(nb_slot_frame - 1)) {
readBlockSize=get_readBlockSize(slot_nr, &UE->frame_parms);
readBlockSize=get_readBlockSize(slot_nr, &UE->frame_parms, UE->is_synchronized);
writeBlockSize=UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX) % nb_slot_frame, &UE->frame_parms);
} else {
UE->rx_offset_diff = computeSamplesShift(UE);
readBlockSize=get_readBlockSize(slot_nr, &UE->frame_parms) -
readBlockSize=get_readBlockSize(slot_nr, &UE->frame_parms, UE->is_synchronized) -
UE->rx_offset_diff;
writeBlockSize=UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX) % nb_slot_frame, &UE->frame_parms)- UE->rx_offset_diff;
}
@@ -1004,18 +1341,27 @@ void init_NR_UE(int nb_inst,
}
void init_NR_UE_threads(int nb_inst) {
int inst;
pthread_t threads[nb_inst];
pthread_t threadsSL[nb_inst];
for (inst=0; inst < nb_inst; inst++) {
for (int inst = 0; inst < nb_inst; inst++) {
PHY_VARS_NR_UE *UE = PHY_vars_UE_g[inst][0];
LOG_I(PHY,"Intializing UE Threads for instance %d (%p,%p)...\n",inst,PHY_vars_UE_g[inst],PHY_vars_UE_g[inst][0]);
threadCreate(&threads[inst], UE_thread, (void *)UE, "UEthread", -1, OAI_PRIORITY_RT_MAX);
if (!IS_SOFTMODEM_NOSTATS_BIT) {
pthread_t stat_pthread;
threadCreate(&stat_pthread, nrL1_UE_stats_thread, UE, "L1_UE_stats", -1, OAI_PRIORITY_RT_LOW);
if (get_softmodem_params()->sl_mode == 0) {
LOG_I(NR_PHY, "Intializing UE Threads for instance %d (%p,%p)...\n", inst, PHY_vars_UE_g[inst], PHY_vars_UE_g[inst][0]);
threadCreate(&threads[inst], UE_thread, (void *)UE, "UEthread", -1, OAI_PRIORITY_RT_MAX);
if (!IS_SOFTMODEM_NOSTATS_BIT) {
pthread_t stat_pthread;
threadCreate(&stat_pthread, nrL1_UE_stats_thread, UE, "L1_UE_stats", -1, OAI_PRIORITY_RT_LOW);
}
}
else if (get_softmodem_params()->sl_mode == 2) {
LOG_I(NR_PHY, "Intializing Sidelink UE Threads for instance %d (%p,%p)...\n", inst, PHY_vars_UE_g[inst], PHY_vars_UE_g[inst][0]);
threadCreate(&threadsSL[inst], UE_thread_SL, (void *)UE, "UEthreadSL", -1, OAI_PRIORITY_RT_MAX);
}
else {
LOG_I(NR_PHY,"Need implementation...\n");
abort();
}
}
}

View File

@@ -86,6 +86,7 @@ unsigned short config_frames[4] = {2,9,11,13};
#include "nr_nas_msg_sim.h"
#include <openair1/PHY/MODULATION/nr_modulation.h>
#include "openair2/GNB_APP/gnb_paramdef.h"
#include <openair1/PHY/NR_REFSIG/sss_nr.h>
extern const char *duplex_mode[];
THREAD_STRUCT thread_struct;
@@ -128,6 +129,7 @@ int dumpframe = 0;
uint64_t downlink_frequency[MAX_NUM_CCs][4];
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
uint64_t sidelink_frequency[MAX_NUM_CCs][4];
int rx_input_level_dBm;
#if MAX_NUM_CCs == 1
@@ -143,7 +145,6 @@ double rx_gain[MAX_NUM_CCs][4] = {{110,0,0,0},{20,0,0,0}};
// UE and OAI config variables
openair0_config_t openair0_cfg[MAX_CARDS];
int16_t node_synch_ref[MAX_NUM_CCs];
int otg_enabled;
double cpuf;
@@ -163,6 +164,7 @@ uint32_t N_RB_DL = 106;
uint8_t abstraction_flag=0;
nr_bler_struct nr_bler_data[NR_NUM_MCS];
nr_bler_struct nr_mimo_bler_data[NR_NUM_MCS];
static void init_bler_table(char*);
@@ -259,6 +261,81 @@ nrUE_params_t *get_nrUE_params(void) {
return &nrUE_params;
}
static void nr_phy_config_request_sl(PHY_VARS_NR_UE *ue,
int N_RB_DL,
int N_RB_UL,
int CC_id)
{
uint64_t rev_burst = 0;
uint64_t SSB_positions = 0x01;
int mu = 1;
uint8_t n_tx = 1;
uint8_t n_rx = 1;
uint16_t Nid_cell = 0;
int ssb_subcarrier_offset = 0;
for (int i = 0; i < 64; i++)
rev_burst |= (((SSB_positions >> (63-i))&0x01) << i);
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
fapi_nr_config_request_t *nrUE_config = &ue->nrUE_config;
nrUE_config->cell_config.phy_cell_id = get_softmodem_params()->nid1 + get_softmodem_params()->nid2 * NUMBER_SSS_SEQUENCE;
nrUE_config->ssb_config.scs_common = mu;
nrUE_config->ssb_table.ssb_subcarrier_offset = 0;
nrUE_config->ssb_table.ssb_offset_point_a = 0;
nrUE_config->ssb_table.ssb_mask_list[1].ssb_mask = (rev_burst)&(0xFFFFFFFF);
nrUE_config->ssb_table.ssb_mask_list[0].ssb_mask = (rev_burst>>32)&(0xFFFFFFFF);
nrUE_config->cell_config.frame_duplex_type = TDD;
nrUE_config->ssb_table.ssb_period = 1; //10ms
nrUE_config->carrier_config.dl_grid_size[mu] = N_RB_DL;
nrUE_config->carrier_config.ul_grid_size[mu] = N_RB_UL;
nrUE_config->carrier_config.num_tx_ant = fp->nb_antennas_tx;
nrUE_config->carrier_config.num_rx_ant = fp->nb_antennas_rx;
nrUE_config->tdd_table.tdd_period = 0;
nrUE_config->carrier_config.dl_frequency = downlink_frequency[CC_id][0] / 1000;
nrUE_config->carrier_config.uplink_frequency = downlink_frequency[CC_id][0] / 1000;
nrUE_config->carrier_config.sl_frequency = sidelink_frequency[CC_id][0] / 1000;
LOG_D(NR_PHY, "SL Frequency %u\n", nrUE_config->carrier_config.sl_frequency);
fp->tdd_period = 6; // 6 indicates 5ms (see get_nb_periods_per_frame())
fp->tdd_slot_config = 0b0000111111; // 1 -> UL, 0-> DL for each slot , LSB is the slot 0
fp->dl_CarrierFreq = 2600000000;
fp->ul_CarrierFreq = 2600000000;
fp->nb_antennas_tx = n_tx;
fp->nb_antennas_rx = n_rx;
fp->nb_antenna_ports_gNB = n_tx;
fp->N_RB_DL = N_RB_DL;
fp->Nid_cell = Nid_cell;
fp->Nid_SL = get_softmodem_params()->nid1 + get_softmodem_params()->nid2 * NUMBER_SSS_SEQUENCE;;
fp->nushift = 0; //No nushift in SL
fp->ssb_type = nr_ssb_type_C; //Note: case c for NR SL???
fp->freq_range = mu < 2 ? nr_FR1 : nr_FR2;
fp->nr_band = get_softmodem_params()->band; //Note: NR SL uses for n38 and n47
fp->threequarter_fs = 0;
fp->ofdm_offset_divisor = UINT_MAX;
fp->first_carrier_offset = 0;
fp->ssb_start_subcarrier = 12 * ue->nrUE_config.ssb_table.ssb_offset_point_a + ssb_subcarrier_offset;
int bw_index = get_supported_band_index(mu, fp->nr_band, N_RB_DL);
nrUE_config->carrier_config.dl_bandwidth = get_supported_bw_mhz(fp->nr_band > 256 ? FR2 : FR1, bw_index);
ue->slss = calloc(1, sizeof(*ue->slss));
int len = sizeof(ue->slss->sl_mib) / sizeof(ue->slss->sl_mib[0]);
for (int i = 0; i < len; i++) {
ue->slss->sl_mib[i] = 0;
}
ue->slss->sl_mib_length = 32;
ue->slss->sl_numssb_withinperiod_r16 = 16;
ue->slss->sl_timeinterval_r16 = 20;
ue->slss->sl_timeoffsetssb_r16 = 0;
ue->slss->sl_numssb_withinperiod_r16_copy = 16;
ue->slss->sl_timeinterval_r16_copy = 20;
ue->slss->sl_timeoffsetssb_r16_copy = 0;
ue->slss->slss_id = get_softmodem_params()->nid1 + get_softmodem_params()->nid2 * NUMBER_SSS_SEQUENCE;;
ue->is_synchronized_sl = 0;
ue->UE_fo_compensation = 0;
ue->sync_ref = get_softmodem_params()->sync_ref;
LOG_I(NR_PHY, "nrUE configured\n");
}
static void get_options(void) {
paramdef_t cmdline_params[] =CMDLINE_NRUEPARAMS_DESC ;
@@ -321,7 +398,7 @@ void init_openair0(void) {
NR_DL_FRAME_PARMS *frame_parms = &PHY_vars_UE_g[0][0]->frame_parms;
for (card=0; card<MAX_CARDS; card++) {
uint64_t dl_carrier, ul_carrier;
uint64_t dl_carrier, ul_carrier, sl_carrier;
openair0_cfg[card].configFilename = NULL;
openair0_cfg[card].threequarter_fs = frame_parms->threequarter_fs;
openair0_cfg[card].sample_rate = frame_parms->samples_per_subframe * 1e3;
@@ -348,8 +425,15 @@ void init_openair0(void) {
duplex_mode[openair0_cfg[card].duplex_mode]);
nr_get_carrier_frequencies(PHY_vars_UE_g[0][0], &dl_carrier, &ul_carrier);
LOG_I(NR_PHY,"Configuring SL carrier for %llu Hz \n",sl_carrier);
nr_rf_card_config_freq(&openair0_cfg[card], ul_carrier, dl_carrier, freq_off);
if (get_softmodem_params()->sl_mode != 0) {
nr_get_carrier_frequencies_sl(PHY_vars_UE_g[0][0], &sl_carrier);
LOG_I(NR_PHY,"Configuring SL carrier for %llu Hz \n",sl_carrier);
nr_rf_card_config_freq(&openair0_cfg[card], sl_carrier, sl_carrier, freq_off);
}
nr_rf_card_config_gain(&openair0_cfg[card], rx_gain_off);
openair0_cfg[card].configFilename = get_softmodem_params()->rf_config_file;
@@ -508,8 +592,14 @@ int main( int argc, char **argv ) {
set_options(CC_id, UE[CC_id]);
NR_UE_MAC_INST_t *mac = get_mac_inst(0);
if (get_softmodem_params()->sa) { // set frame config to initial values from command line and assume that the SSB is centered on the grid
if (get_softmodem_params()->sl_mode != 0) {
uint16_t nr_band = get_band(sidelink_frequency[CC_id][0],0);
mac->if_module = NULL;
LOG_I(HW, "Setting mac->if_module = NULL b/c we config PHY in nr_phy_config_request_sl (for now - TODO)\n");
nr_phy_config_request_sl(UE[CC_id], N_RB_DL, N_RB_DL, CC_id);
nr_init_frame_parms_ue_sl(&UE[CC_id]->frame_parms,sidelink_frequency[CC_id][0],nr_band);
}
if (get_softmodem_params()->sa) {
uint16_t nr_band = get_band(downlink_frequency[CC_id][0],uplink_frequency_offset[CC_id][0]);
mac->nr_band = nr_band;
nr_init_frame_parms_ue_sa(&UE[CC_id]->frame_parms,
@@ -517,15 +607,15 @@ int main( int argc, char **argv ) {
uplink_frequency_offset[CC_id][0],
get_softmodem_params()->numerology,
nr_band);
}
else{
DevAssert(mac->if_module != NULL && mac->if_module->phy_config_request != NULL);
mac->if_module->phy_config_request(&mac->phy_config);
mac->phy_config_request_sent = true;
fapi_nr_config_request_t *nrUE_config = &UE[CC_id]->nrUE_config;
nr_init_frame_parms_ue(&UE[CC_id]->frame_parms, nrUE_config,
*mac->scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]);
} else {
if (mac->if_module != NULL && mac->if_module->phy_config_request != NULL) {
mac->if_module->phy_config_request(&mac->phy_config);
mac->phy_config_request_sent = true;
}
nr_init_frame_parms_ue(&UE[CC_id]->frame_parms, &UE[CC_id]->nrUE_config,
((get_softmodem_params()->sl_mode == 0) ?
*mac->scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0] :
UE[CC_id]->frame_parms.nr_band));
}
init_nr_ue_vars(UE[CC_id], 0, abstraction_flag);
@@ -636,3 +726,56 @@ static void init_bler_table(char *env_string) {
fclose(pFile);
}
}
// Read in each MCS file and build BLER-SINR-TB table
static void init_mimo_bler_table(void) {
memset(nr_mimo_bler_data, 0, sizeof(nr_mimo_bler_data));
const char *awgn_results_dir = getenv("NR_MIMO2x2_AWGN_RESULTS_DIR");
if (!awgn_results_dir) {
LOG_W(NR_MAC, "No $NR_MIMO2x2_AWGN_RESULTS_DIR\n");
return;
}
for (unsigned int i = 0; i < NR_NUM_MCS; i++) {
char fName[1024];
snprintf(fName, sizeof(fName), "%s/mcs%d_cdlc_mimo2x2_dl.csv", awgn_results_dir, i);
FILE *pFile = fopen(fName, "r");
if (!pFile) {
LOG_E(NR_MAC, "open %s: %s\n", fName, strerror(errno));
continue;
}
size_t bufSize = 1024;
char * line = NULL;
char * token;
char * temp = NULL;
int nlines = 0;
while (getline(&line, &bufSize, pFile) > 0) {
if (!strncmp(line, "SNR", 3)) {
continue;
}
if (nlines > NR_NUM_SINR) {
LOG_E(NR_MAC, "BLER FILE ERROR - num lines greater than expected - file: %s\n", fName);
abort();
}
token = strtok_r(line, ";", &temp);
int ncols = 0;
while (token != NULL) {
if (ncols > NUM_BLER_COL) {
LOG_E(NR_MAC, "BLER FILE ERROR - num of cols greater than expected\n");
abort();
}
nr_mimo_bler_data[i].bler_table[nlines][ncols] = strtof(token, NULL);
ncols++;
token = strtok_r(NULL, ";", &temp);
}
nlines++;
}
nr_mimo_bler_data[i].length = nlines;
fclose(pFile);
}
}

View File

@@ -42,6 +42,7 @@
{"uecap_file", CONFIG_HLP_UECAP_FILE, 0, .strptr=&uecap_file, .defstrval="./uecap_ports1.xml", TYPE_STRING, 0}, \
{"rrc_config_path", CONFIG_HLP_RRC_CFG_PATH, 0, .strptr=&rrc_config_path, .defstrval="./", TYPE_STRING, 0}, \
{"ue-idx-standalone", NULL, 0, .u16ptr=&ue_idx_standalone, .defuintval=0xFFFF, TYPE_UINT16, 0}, \
{"SLC", CONFIG_HLP_SLF, 0, .u64ptr=&(sidelink_frequency[0][0]), .defuintval=2600000000, TYPE_UINT64, 0}, \
{"ue-rxgain", CONFIG_HLP_UERXG, 0, .dblptr=&(rx_gain[0][0]), .defdblval=110, TYPE_DOUBLE, 0}, \
{"ue-rxgain-off", CONFIG_HLP_UERXGOFF, 0, .dblptr=&rx_gain_off, .defdblval=0, TYPE_DOUBLE, 0}, \
{"ue-txgain", CONFIG_HLP_UETXG, 0, .dblptr=&(tx_gain[0][0]), .defdblval=0, TYPE_DOUBLE, 0}, \

View File

@@ -55,8 +55,10 @@ extern "C"
#define CONFIG_HLP_DUMPFRAME "dump UE received frame to rxsig_frame0.dat and exit\n"
#define CONFIG_HLP_PHYTST "test UE phy layer, mac disabled\n"
#define CONFIG_HLP_SL_PHYTST "test SL UE phy layer, mac disabled\n"
#define CONFIG_HLP_DORA "test gNB and UE with RA procedures\n"
#define CONFIG_HLP_SA "run gNB in standalone mode\n"
#define CONFIG_HLP_SL_MODE "sets the NR sidelink mode (0: not in sidelink mode, 1: in-coverage/gNB, 2: out-of-coverage/no gNB)"
#define CONFIG_HLP_EXTS "tells hardware to use an external timing reference\n"
#define CONFIG_HLP_DMRSSYNC "tells RU to insert DMRS in subframe 1 slot 0"
#define CONFIG_HLP_CLK "tells hardware to use a clock reference (0:internal, 1:external, 2:gpsdo)\n"
@@ -66,6 +68,7 @@ extern "C"
#define CONFIG_HLP_NOSNGLT "Disables single-thread mode in lte-softmodem\n"
#define CONFIG_HLP_DLF "Set the downlink frequency for all component carriers\n"
#define CONFIG_HLP_ULF "Set the uplink frequency offset for all component carriers\n"
#define CONFIG_HLP_SLF "Set the sidelink frequency for all component carriers\n"
#define CONFIG_HLP_CHOFF "Channel id offset\n"
#define CONFIG_HLP_SOFTS "Enable soft scope and L1 and L2 stats (Xforms)\n"
#define CONFIG_HLP_SOFTS_QT "Enable soft scope and L1 and L2 stats (QT)\n"
@@ -103,6 +106,9 @@ extern "C"
#define CONFIG_L1_EMULATOR "Run in L1 emulated mode (disable PHY layer)\n"
#define CONFIG_HLP_CONTINUOUS_TX "perform continuous transmission, even in TDD mode (to work around USRP issues)\n"
#define CONFIG_HLP_STATS_DISABLE "disable globally the stats generation and persistence"
#define CONFIG_HLP_SYNC_REF "Sync Reference in Sidelink\n"
#define CONFIG_HLP_NID1 "Set NID1 value in Sidelink\n"
#define CONFIG_HLP_NID2 "Set NID2 value in Sidelink\n"
/*-----------------------------------------------------------------------------------------------------------------------------------------------------*/
/* command line parameters common to eNodeB and UE */
@@ -111,8 +117,10 @@ extern "C"
#define RF_CONFIG_FILE softmodem_params.rf_config_file
#define TP_CONFIG softmodem_params.threadPoolConfig
#define PHY_TEST softmodem_params.phy_test
#define SL_PHY_TEST softmodem_params.sl_phy_test
#define DO_RA softmodem_params.do_ra
#define SA softmodem_params.sa
#define SL_MODE softmodem_params.sl_mode
#define WAIT_FOR_SYNC softmodem_params.wait_for_sync
#define SINGLE_THREAD_FLAG softmodem_params.single_thread_flag
#define CHAIN_OFFSET softmodem_params.chain_offset
@@ -132,6 +140,9 @@ extern "C"
#define NON_STOP softmodem_params.non_stop
#define EMULATE_L1 softmodem_params.emulate_l1
#define CONTINUOUS_TX softmodem_params.continuous_tx
#define SYNC_REF softmodem_params.sync_ref
#define NID1 softmodem_params.nid1
#define NID2 softmodem_params.nid2
#define DEFAULT_RFCONFIG_FILE "/usr/local/etc/syriq/ue.band7.tm1.PRB100.NR40.dat";
@@ -143,6 +154,8 @@ extern int usrp_tx_thread;
{"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, .iptr=&PHY_TEST, .defintval=0, TYPE_INT, 0}, \
{"do-ra", CONFIG_HLP_DORA, PARAMFLAG_BOOL, .iptr=&DO_RA, .defintval=0, TYPE_INT, 0}, \
{"sa", CONFIG_HLP_SA, PARAMFLAG_BOOL, .iptr=&SA, .defintval=0, TYPE_INT, 0}, \
{"sl-mode", CONFIG_HLP_SL_MODE, 0, .u8ptr=&SL_MODE, .defintval=0, TYPE_UINT8, 0}, \
{"sync-ref", CONFIG_HLP_SYNC_REF, PARAMFLAG_BOOL, .iptr=&SYNC_REF, .defintval=0, TYPE_INT, 0}, \
{"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, .u8ptr=&USIM_TEST, .defintval=0, TYPE_UINT8, 0}, \
{"clock-source", CONFIG_HLP_CLK, 0, .uptr=&CLOCK_SOURCE, .defintval=0, TYPE_UINT, 0}, \
{"time-source", CONFIG_HLP_TME, 0, .uptr=&TIMING_SOURCE, .defintval=0, TYPE_UINT, 0}, \
@@ -174,6 +187,8 @@ extern int usrp_tx_thread;
{"emulate-l1", CONFIG_L1_EMULATOR, PARAMFLAG_BOOL, .iptr=&EMULATE_L1, .defintval=0, TYPE_INT, 0}, \
{"continuous-tx", CONFIG_HLP_CONTINUOUS_TX, PARAMFLAG_BOOL, .iptr=&CONTINUOUS_TX, .defintval=0, TYPE_INT, 0}, \
{"disable-stats", CONFIG_HLP_STATS_DISABLE, PARAMFLAG_BOOL, .iptr=&stats_disabled, .defintval=0, TYPE_INT, 0}, \
{"nid1", CONFIG_HLP_NID1, 0, .iptr=&NID1, .defintval=10, TYPE_INT, 0}, \
{"nid2", CONFIG_HLP_NID2, 0, .iptr=&NID2, .defintval=1, TYPE_INT, 0}, \
}
// clang-format on
@@ -210,6 +225,8 @@ extern int usrp_tx_thread;
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s3a = { config_checkstr_assign_integer, \
{"MONOLITHIC", "PNF", "VNF","UE_STUB_PNF","UE_STUB_OFFNET","STANDALONE_PNF"}, \
{NFAPI_MONOLITHIC, NFAPI_MODE_PNF, NFAPI_MODE_VNF,NFAPI_UE_STUB_PNF,NFAPI_UE_STUB_OFFNET,NFAPI_MODE_STANDALONE_PNF}, \
@@ -218,6 +235,8 @@ extern int usrp_tx_thread;
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
}
// clang-format on
@@ -301,8 +320,10 @@ typedef struct {
char *rf_config_file;
char *threadPoolConfig;
int phy_test;
int sl_phy_test;
int do_ra;
int sa;
uint8_t sl_mode;
uint8_t usim_test;
int emulate_rf;
int wait_for_sync; //eNodeB only
@@ -324,6 +345,9 @@ typedef struct {
int non_stop;
int emulate_l1;
int continuous_tx;
int sync_ref;
int nid1;
int nid2;
} softmodem_params_t;
extern uint64_t get_softmodem_optmask(void);

View File

@@ -559,7 +559,9 @@ typedef struct {
typedef struct
{
uint16_t dl_bandwidth;//Carrier bandwidth for DL in MHz [38.104, sec 5.3.2] Values: 5, 10, 15, 20, 25, 30, 40,50, 60, 70, 80,90,100,200,400
uint16_t sl_bandwidth; //Carrier bandwidth for SL in MHz [38.101, sec 5.3.5] Values: 10, 20, 30, and 40
uint32_t dl_frequency; //Absolute frequency of DL point A in KHz [38.104, sec5.2 and 38.211 sec 4.4.4.2] Value: 450000 -> 52600000
uint32_t sl_frequency; //Absolute frequency of SL point A in KHz [38.331, sec6.3.5 and 38.211 sec 8.2.7]
uint16_t dl_k0[5];//𝑘_{0}^{𝜇} for each of the numerologies [38.211, sec 5.3.1] Value: 0 ->23699
uint16_t dl_grid_size[5];//Grid size 𝑁_{𝑔𝑟𝑖𝑑}^{𝑠𝑖𝑧𝑒,𝜇} for each of the numerologies [38.211, sec 4.4.2] Value: 0->275 0 = this numerology not used
uint16_t num_tx_ant;//Number of Tx antennas

View File

@@ -351,9 +351,17 @@ void applyGtoright(const t_nrPolar_params *pp,decoder_node_t *node) {
((__m64 *)alpha_r)[0] = _mm_subs_pi16(((__m64 *)alpha_v)[1],_mm_sign_pi16(((__m64 *)alpha_v)[0],((__m64 *)betal)[0]));
}
else
{// equivalent scalar code to above, activated only on non x86/ARM architectures or Nv=1,2
for (int i=0;i<node->Nv/2;i++) {
alpha_r[i] = alpha_v[i+(node->Nv/2)] - (betal[i]*alpha_v[i]);
{
int temp_alpha_r;
for (int i = 0; i < node->Nv / 2; i++) {
temp_alpha_r = alpha_v[i + (node->Nv / 2)] - (betal[i] * alpha_v[i]);
if (temp_alpha_r > SHRT_MAX) {
alpha_r[i] = SHRT_MAX;
} else if (temp_alpha_r < -SHRT_MAX) {
alpha_r[i] = -SHRT_MAX;
} else {
alpha_r[i] = temp_alpha_r;
}
}
}
if (node->Nv == 2) { // apply hard decision on right node

View File

@@ -42,6 +42,7 @@
#include "PHY/CODING/nrPolar_tools/nr_polar_dci_defs.h"
#include "PHY/CODING/nrPolar_tools/nr_polar_uci_defs.h"
#include "PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h"
#include "PHY/CODING/nrPolar_tools/nr_polar_psbch_defs.h"
#include "PHY/CODING/coding_defs.h"
//#include "SIMULATION/TOOLS/sim.h"

View File

@@ -35,6 +35,7 @@
#define NR_POLAR_PBCH_AGGREGATION_LEVEL 0 //uint8_t
#define NR_POLAR_PBCH_MESSAGE_TYPE 0 //int8_t
#define NR_POLAR_PSBCH_MESSAGE_TYPE 3 //int8_t
#define NR_POLAR_PBCH_PAYLOAD_BITS 32 //uint16_t
#define NR_POLAR_PBCH_CRC_PARITY_BITS 24
#define NR_POLAR_PBCH_CRC_ERROR_CORRECTION_BITS 3
@@ -52,6 +53,8 @@
#define NR_POLAR_PBCH_I_BIL 0 //uint8_t
#define NR_POLAR_PBCH_E 864 //uint16_t
#define NR_POLAR_PBCH_E_DWORD 27 // NR_POLAR_PBCH_E/32
#define NR_POLAR_PSBCH_E 1792 //uint16_t
#define NR_POLAR_PSBCH_E_DWORD 56 // NR_POLAR_PSBCH_E/32
/*
* TEST CODE

View File

@@ -0,0 +1,70 @@
/*
* 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
*/
/*!\file PHY/CODING/nrPolar_tools/nr_polar_psbch_defs.h
* \brief Defines the constant variables for polar coding of the PSBCH from 38-212, V15.1.1 2018-04.
* \author Turker Yilmaz
* \date 2018
* \version 0.1
* \company EURECOM
* \email turker.yilmaz@eurecom.fr
* \note
* \warning
*/
#ifndef __NR_POLAR_PSBCH_DEFS__H__
#define __NR_POLAR_PSBCH_DEFS__H__
#define NR_POLAR_PSBCH_AGGREGATION_LEVEL 0 //uint8_t
#define NR_POLAR_PSBCH_MESSAGE_TYPE 3 //int8_t
#define NR_POLAR_PSBCH_PAYLOAD_BITS 32 //uint16_t
#define NR_POLAR_PSBCH_CRC_PARITY_BITS 24
#define NR_POLAR_PSBCH_CRC_ERROR_CORRECTION_BITS 3
//Assumed 3 by 3GPP when NR_POLAR_PSBCH_L>8 to meet false alarm rate requirements.
//Sec. 7.1.4: Channel Coding
#define NR_POLAR_PSBCH_N_MAX 9 //uint8_t
#define NR_POLAR_PSBCH_I_IL 1 //uint8_t
#define NR_POLAR_PSBCH_I_SEG 0 //uint8_t
#define NR_POLAR_PSBCH_N_PC 0 //uint8_t
#define NR_POLAR_PSBCH_N_PC_WM 0 //uint8_t
//#define NR_POLAR_PSBCH_N 512 //uint16_t
//Sec. 7.1.5: Rate Matching
#define NR_POLAR_PSBCH_I_BIL 0 //uint8_t
#define NR_POLAR_PSBCH_E 1792 //uint16_t
#define NR_POLAR_PSBCH_E_DWORD 56 // NR_POLAR_PSBCH_E/32
/*
* TEST CODE
*/
//#define DEBUG_POLAR
// Usage in code:
//#ifdef DEBUG_POLAR
//...
//#endif
//unsigned int testPayload0=0x00000000, testPayload1=0xffffffff; //payload1=~payload0;
//unsigned int testPayload2=0xa5a5a5a5; //testPayload3=0xb3f02c82;
//double testReceivedPayload3[NR_POLAR_PSBCH_E] = {-1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1};
#endif

View File

@@ -193,7 +193,18 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui
newPolarInitNode->payloadBits = messageLength;
newPolarInitNode->crcCorrectionBits = NR_POLAR_PUCCH_CRC_ERROR_CORRECTION_BITS;
//LOG_D(PHY,"New polar node, encoderLength %d, aggregation_level %d\n",newPolarInitNode->encoderLength,aggregation_level);
} else if (messageType == 3) { // PSBCH
newPolarInitNode->n_max = NR_POLAR_PSBCH_N_MAX;
newPolarInitNode->i_il = NR_POLAR_PSBCH_I_IL;
newPolarInitNode->i_seg = NR_POLAR_PSBCH_I_SEG;
newPolarInitNode->n_pc = NR_POLAR_PSBCH_N_PC;
newPolarInitNode->n_pc_wm = NR_POLAR_PSBCH_N_PC_WM;
newPolarInitNode->i_bil = NR_POLAR_PSBCH_I_BIL;
newPolarInitNode->crcParityBits = NR_POLAR_PSBCH_CRC_PARITY_BITS;
newPolarInitNode->payloadBits = NR_POLAR_PSBCH_PAYLOAD_BITS;
newPolarInitNode->encoderLength = NR_POLAR_PSBCH_E;
newPolarInitNode->crcCorrectionBits = NR_POLAR_PSBCH_CRC_ERROR_CORRECTION_BITS;
newPolarInitNode->crc_generator_matrix = crc24c_generator_matrix(newPolarInitNode->payloadBits);//G_P
} else {
AssertFatal(1 == 0, "[nr_polar_init] Incorrect Message Type(%d)", messageType);
}

View File

@@ -26,6 +26,7 @@
#include "PHY/NR_REFSIG/nr_refsig.h"
#include "PHY/INIT/nr_phy_init.h"
#include "PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h"
#include "PHY/CODING/nrPolar_tools/nr_polar_psbch_defs.h"
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
#include "openair1/PHY/MODULATION/nr_modulation.h"
@@ -38,7 +39,7 @@
#include "PHY/NR_REFSIG/nr_refsig.h"
#include "SCHED_NR/fapi_nr_l1.h"
#include "nfapi_nr_interface.h"
#include "executables/softmodem-common.h"
#include "PHY/NR_REFSIG/ul_ref_seq_nr.h"

View File

@@ -35,6 +35,9 @@
#include "PHY/MODULATION/nr_modulation.h"
#include "openair2/COMMON/prs_nr_paramdef.h"
#include "SCHED_NR_UE/harq_nr.h"
#include <nr-uesoftmodem.h>
void RCconfig_nrUE_prs(void *cfg)
{
@@ -199,6 +202,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
// create shortcuts
NR_DL_FRAME_PARMS *const fp = &ue->frame_parms;
NR_UE_COMMON *const common_vars = &ue->common_vars;
NR_UE_PSBCH **const psbch_vars = ue->psbch_vars;
NR_UE_PRACH **const prach_vars = ue->prach_vars;
NR_UE_CSI_IM **const csiim_vars = ue->csiim_vars;
NR_UE_CSI_RS **const csirs_vars = ue->csirs_vars;
@@ -350,6 +354,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
// DLSCH
for (gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) {
prach_vars[gNB_id] = (NR_UE_PRACH *)malloc16_clear(sizeof(NR_UE_PRACH));
psbch_vars[gNB_id] = (NR_UE_PSBCH *)malloc16_clear(sizeof(NR_UE_PSBCH));
csiim_vars[gNB_id] = (NR_UE_CSI_IM *)malloc16_clear(sizeof(NR_UE_CSI_IM));
csirs_vars[gNB_id] = (NR_UE_CSI_RS *)malloc16_clear(sizeof(NR_UE_CSI_RS));
srs_vars[gNB_id] = (NR_UE_SRS *)malloc16_clear(sizeof(NR_UE_SRS));
@@ -468,6 +473,7 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
free_and_zero(ue->csirs_vars[gNB_id]);
free_and_zero(ue->srs_vars[gNB_id]);
free_and_zero(ue->psbch_vars[gNB_id]);
free_and_zero(ue->prach_vars[gNB_id]);
}
@@ -697,7 +703,12 @@ void phy_init_nr_top(PHY_VARS_NR_UE *ue) {
crcTableInit();
init_scrambling_luts();
load_dftslib();
frame_parms->Nid_SL = 0;
init_context_synchro_nr(frame_parms);
if (get_softmodem_params()->sl_mode>0) {
frame_parms->Nid_SL = 336;
init_context_synchro_nr(frame_parms);
}
generate_ul_reference_signal_sequences(SHRT_MAX);
}

View File

@@ -22,6 +22,7 @@
#include "nr_phy_init.h"
#include "common/utils/nr/nr_common.h"
#include "common/utils/LOG/log.h"
#include "executables/softmodem-common.h"
/// Subcarrier spacings in Hz indexed by numerology index
static const uint32_t nr_subcarrier_spacing[MAX_NUM_SUBCARRIER_SPACING] = {15e3, 30e3, 60e3, 120e3, 240e3};
@@ -41,6 +42,11 @@ static const int nr_ssb_table[48][3] = {
{93, 15, nr_ssb_type_A}, {94, 15, nr_ssb_type_A}, {96, 30, nr_ssb_type_C}};
void set_Lmax(NR_DL_FRAME_PARMS *fp) {
if (get_softmodem_params()->sl_mode == 2) {
fp->Lmax = 1;
return;
}
// definition of Lmax according to ts 38.213 section 4.1
if (fp->dl_CarrierFreq < 6e9) {
if(fp->frame_type && (fp->ssb_type==2))
@@ -150,7 +156,10 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, int N_RB_DL)
while(fp->ofdm_symbol_size < N_RB_DL * 12)
fp->ofdm_symbol_size <<= 1;
fp->first_carrier_offset = fp->ofdm_symbol_size - (N_RB_DL * 12 / 2);
if (get_softmodem_params()->sl_mode == 2)
fp->first_carrier_offset = 0;
else
fp->first_carrier_offset = fp->ofdm_symbol_size - (N_RB_DL * 12 / 2);
fp->nb_prefix_samples = fp->ofdm_symbol_size / 128 * 9;
fp->nb_prefix_samples0 = fp->ofdm_symbol_size / 128 * (9 + (1 << mu));
LOG_W(PHY,"Init: N_RB_DL %d, first_carrier_offset %d, nb_prefix_samples %d,nb_prefix_samples0 %d, ofdm_symbol_size %d\n",
@@ -283,6 +292,10 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp,
LOG_D(PHY,"dl_bw_kHz %lu\n",dl_bw_khz);
LOG_D(PHY,"dl_CarrierFreq %lu\n",fp->dl_CarrierFreq);
if (get_softmodem_params()->sl_mode != 0) {
fp->sl_CarrierFreq = ((dl_bw_khz >> 1) + config->carrier_config.sl_frequency) * 1000;
}
uint64_t ul_bw_khz = (12*config->carrier_config.ul_grid_size[config->ssb_config.scs_common])*(15<<config->ssb_config.scs_common);
fp->ul_CarrierFreq = ((ul_bw_khz>>1) + config->carrier_config.uplink_frequency)*1000 ;
@@ -332,6 +345,9 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp,
}
fp->ssb_start_subcarrier = (12 * config->ssb_table.ssb_offset_point_a + sco);
if (get_softmodem_params()->sl_mode == 2) {
fp->ssb_start_subcarrier = 0;
}
set_Lmax(fp);
fp->L_ssb = (((uint64_t) config->ssb_table.ssb_mask_list[0].ssb_mask)<<32) | config->ssb_table.ssb_mask_list[1].ssb_mask;
@@ -381,6 +397,11 @@ void nr_init_frame_parms_ue_sa(NR_DL_FRAME_PARMS *frame_parms, uint64_t downlink
}
void nr_init_frame_parms_ue_sl(NR_DL_FRAME_PARMS *frame_parms, uint64_t sidelink_frequency, uint16_t nr_band) {
LOG_D(NR_PHY, "SL init parameters. SL freq %lu\n", sidelink_frequency);
frame_parms->sl_CarrierFreq = sidelink_frequency;
frame_parms->nr_band = nr_band;
}
void nr_dump_frame_parms(NR_DL_FRAME_PARMS *fp)
{

View File

@@ -29,6 +29,7 @@ int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp,uint8_t i_ssb);
int nr_init_frame_parms(nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms);
int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms, fapi_nr_config_request_t *config, uint16_t nr_band);
void nr_init_frame_parms_ue_sa(NR_DL_FRAME_PARMS *frame_parms, uint64_t downlink_frequency, int32_t uplink_frequency_offset, uint8_t mu, uint16_t nr_band);
void nr_init_frame_parms_ue_sl(NR_DL_FRAME_PARMS *frame_parms, uint64_t sidelink_frequency, uint16_t nr_band);
int init_nr_ue_signal(PHY_VARS_NR_UE *ue,int nb_connected_eNB);
void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB);
void init_nr_ue_transport(PHY_VARS_NR_UE *ue);
@@ -55,5 +56,5 @@ void free_nr_ue_ul_harq(NR_UL_UE_HARQ_t harq_list[NR_MAX_ULSCH_HARQ_PROCESSES],
void phy_init_nr_top(PHY_VARS_NR_UE *ue);
void phy_term_nr_top(void);
void init_dfts(void);
#endif

View File

@@ -51,7 +51,7 @@ void PHY_ofdm_mod(int *input,
void normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,LTE_DL_FRAME_PARMS *frame_parms);
void nr_normal_prefix_mod(c16_t *txdataF, c16_t *txdata, uint8_t nsymb, NR_DL_FRAME_PARMS *frame_parms, uint32_t slot);
void do_OFDM_mod(int32_t **txdataF, int32_t **txdata, uint32_t frame,uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms);
void do_OFDM_mod(c16_t **txdataF, c16_t **txdata, uint32_t frame,uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms);
/** @}*/

View File

@@ -599,7 +599,8 @@ void init_symbol_rotation(NR_DL_FRAME_PARMS *fp) {
uint64_t dl_CarrierFreq = fp->dl_CarrierFreq;
uint64_t ul_CarrierFreq = fp->ul_CarrierFreq;
double f[2] = {(double)dl_CarrierFreq, (double)ul_CarrierFreq};
uint64_t sl_CarrierFreq = fp->sl_CarrierFreq;
double f[3] = {(double)dl_CarrierFreq, (double)ul_CarrierFreq, (double)sl_CarrierFreq};
const int nsymb = fp->symbols_per_slot * fp->slots_per_frame/10;
const double Tc=(1/480e3/4096);
@@ -607,10 +608,10 @@ void init_symbol_rotation(NR_DL_FRAME_PARMS *fp) {
const double Ncp0=16*64 + (144*64*(1/(float)(1<<fp->numerology_index)));
const double Ncp1=(144*64*(1/(float)(1<<fp->numerology_index)));
for (uint8_t ll = 0; ll < 2; ll++){
for (uint8_t ll = 0; ll < sizeof(f)/sizeof(f[0]); ll++){
double f0 = f[ll];
LOG_D(PHY, "Doing symbol rotation calculation for gNB TX/RX, f0 %f Hz, Nsymb %d\n", f0, nsymb);
LOG_I(PHY, "Doing symbol rotation calculation for gNB TX/RX, f0 %f Hz, Nsymb %d\n", f0, nsymb);
c16_t *symbol_rotation = fp->symbol_rotation[ll];
double tl = 0.0;

View File

@@ -112,7 +112,8 @@ void apply_nr_rotation(NR_DL_FRAME_PARMS *fp,
c16_t* txdata,
int slot,
int first_symbol,
int nsymb);
int nsymb,
int link_type);
void init_symbol_rotation(NR_DL_FRAME_PARMS *fp);
@@ -122,7 +123,8 @@ void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms,
c16_t *rxdataF,
int slot,
int first_symbol,
int nsymb);
int nsymb,
int link_type);
/*! \brief Perform NR precoding. TS 38.211 V15.4.0 subclause 6.3.1.5
@param[in] datatx_F_precoding, Pointer to n_layers*re data array

View File

@@ -37,6 +37,7 @@ This section deals with basic functions for OFDM Modulation.
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "modulation_common.h"
#include "PHY/LTE_TRANSPORT/transport_common_proto.h"
#include "../executables/softmodem-common.h"
//#define DEBUG_OFDM_MOD
@@ -45,15 +46,15 @@ void normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,LTE_DL_FRA
PHY_ofdm_mod(txdataF, // input
txdata, // output
PHY_ofdm_mod((int *)txdataF, // input
(int *)txdata, // output
frame_parms->ofdm_symbol_size,
1, // number of symbols
frame_parms->nb_prefix_samples0, // number of prefix samples
CYCLIC_PREFIX);
PHY_ofdm_mod(txdataF+frame_parms->ofdm_symbol_size, // input
txdata+OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES0, // output
PHY_ofdm_mod((int *)txdataF+frame_parms->ofdm_symbol_size, // input
(int *)txdata+OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES0, // output
frame_parms->ofdm_symbol_size,
nsymb-1,
frame_parms->nb_prefix_samples, // number of prefix samples
@@ -280,7 +281,7 @@ void PHY_ofdm_mod(int *input, /// pointer to complex input
}
void do_OFDM_mod(int32_t **txdataF, int32_t **txdata, uint32_t frame,uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms)
void do_OFDM_mod(c16_t **txdataF, c16_t **txdata, uint32_t frame,uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms)
{
int aa, slot_offset, slot_offset_F;
@@ -292,39 +293,39 @@ void do_OFDM_mod(int32_t **txdataF, int32_t **txdata, uint32_t frame,uint16_t ne
if (is_pmch_subframe(frame,next_slot>>1,frame_parms)) {
if ((next_slot%2)==0) {
LOG_D(PHY,"Frame %d, subframe %d: Doing MBSFN modulation (slot_offset %d)\n",frame,next_slot>>1,slot_offset);
PHY_ofdm_mod(&txdataF[aa][slot_offset_F], // input
&txdata[aa][slot_offset], // output
PHY_ofdm_mod((int *)&txdataF[aa][slot_offset_F], // input
(int *)&txdata[aa][slot_offset], // output
frame_parms->ofdm_symbol_size,
12, // number of symbols
frame_parms->ofdm_symbol_size>>2, // number of prefix samples
CYCLIC_PREFIX);
if (frame_parms->Ncp == EXTENDED)
PHY_ofdm_mod(&txdataF[aa][slot_offset_F], // input
&txdata[aa][slot_offset], // output
PHY_ofdm_mod((int *)&txdataF[aa][slot_offset_F], // input
(int *)&txdata[aa][slot_offset], // output
frame_parms->ofdm_symbol_size,
2, // number of symbols
frame_parms->nb_prefix_samples, // number of prefix samples
CYCLIC_PREFIX);
else {
LOG_D(PHY,"Frame %d, subframe %d: Doing PDCCH modulation\n",frame,next_slot>>1);
normal_prefix_mod(&txdataF[aa][slot_offset_F],
&txdata[aa][slot_offset],
normal_prefix_mod((int32_t *)&txdataF[aa][slot_offset_F],
(int32_t *)&txdata[aa][slot_offset],
2,
frame_parms);
}
}
} else {
if (frame_parms->Ncp == EXTENDED)
PHY_ofdm_mod(&txdataF[aa][slot_offset_F], // input
&txdata[aa][slot_offset], // output
PHY_ofdm_mod((int *)&txdataF[aa][slot_offset_F], // input
(int *)&txdata[aa][slot_offset], // output
frame_parms->ofdm_symbol_size,
6, // number of symbols
frame_parms->nb_prefix_samples, // number of prefix samples
CYCLIC_PREFIX);
else {
normal_prefix_mod(&txdataF[aa][slot_offset_F],
&txdata[aa][slot_offset],
normal_prefix_mod((int32_t *)&txdataF[aa][slot_offset_F],
(int32_t *)&txdata[aa][slot_offset],
7,
frame_parms);
}
@@ -337,17 +338,18 @@ void apply_nr_rotation(NR_DL_FRAME_PARMS *fp,
c16_t *txdataF,
int slot,
int first_symbol,
int nsymb)
int nsymb,
int link_type)
{
int symb_offset = (slot%fp->slots_per_subframe)*fp->symbols_per_slot;
c16_t *symbol_rotation = fp->symbol_rotation[0] + symb_offset;
c16_t *symbol_rotation = fp->symbol_rotation[link_type] + symb_offset;
for (int sidx = first_symbol; sidx < first_symbol + nsymb; sidx++) {
c16_t *this_rotation = symbol_rotation + sidx;
c16_t *this_symbol = (txdataF) + sidx * fp->ofdm_symbol_size;
LOG_D(PHY,"Rotating symbol %d, slot %d, symbol_subframe_index %d (%d,%d)\n",
LOG_I(PHY,"Rotating symbol %d, slot %d, symbol_subframe_index %d (%d,%d)\n",
sidx,
slot,
sidx + symb_offset,
@@ -371,4 +373,4 @@ void apply_nr_rotation(NR_DL_FRAME_PARMS *fp,
}
}
}

View File

@@ -26,6 +26,7 @@
#include "PHY/LTE_ESTIMATION/lte_estimation.h"
#include "PHY/NR_UE_ESTIMATION/nr_estimation.h"
#include <common/utils/LOG/log.h>
#include "executables/softmodem-common.h"
//#define DEBUG_FEP
@@ -48,7 +49,11 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
unsigned int nb_prefix_samples;
unsigned int nb_prefix_samples0;
if (ue->is_synchronized) {
bool is_synced = ue->is_synchronized;
if(get_softmodem_params()->sl_mode == 2) {
is_synced = ue->is_synchronized_sl;
}
if (is_synced) {
nb_prefix_samples = frame_parms->nb_prefix_samples;
nb_prefix_samples0 = frame_parms->nb_prefix_samples0;
} else {
@@ -161,13 +166,19 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
unsigned int nb_prefix_samples;
unsigned int nb_prefix_samples0;
if (get_softmodem_params()->sl_mode == 2) {
if (ue->is_synchronized_sl) {
nb_prefix_samples = frame_parms->nb_prefix_samples;
nb_prefix_samples0 = frame_parms->nb_prefix_samples0;
}
}
if (pbch_decoded) {
nb_prefix_samples = frame_parms->nb_prefix_samples;
nb_prefix_samples0 = frame_parms->nb_prefix_samples0;
}
else {
nb_prefix_samples = frame_parms->nb_prefix_samples;
nb_prefix_samples0 = frame_parms->nb_prefix_samples;
nb_prefix_samples0 = frame_parms->nb_prefix_samples0;
}
unsigned int frame_length_samples = frame_parms->samples_per_frame;
@@ -178,8 +189,8 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
unsigned int slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
unsigned int rx_offset = sample_offset + slot_offset;
unsigned int abs_symbol = Ns * frame_parms->symbols_per_slot + symbol;
for (int idx_symb = Ns*frame_parms->symbols_per_slot; idx_symb <= abs_symbol; idx_symb++)
rx_offset += (abs_symbol%(0x7<<frame_parms->numerology_index)) ? nb_prefix_samples : nb_prefix_samples0;
for (int idx_symb = Ns*frame_parms->symbols_per_slot; idx_symb <= abs_symbol; idx_symb++)
rx_offset += (idx_symb%(0x7<<frame_parms->numerology_index)) ? nb_prefix_samples : nb_prefix_samples0;
rx_offset += frame_parms->ofdm_symbol_size * symbol;
#ifdef DEBUG_FEP
@@ -230,7 +241,7 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
stop_meas(&ue->rx_dft_stats);
int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot;
c16_t rot2 = frame_parms->symbol_rotation[0][symbol + symb_offset];
c16_t rot2 = frame_parms->symbol_rotation[get_softmodem_params()->sl_mode == 2 ? NR_LINK_TYPE_SL : 0][symbol + symb_offset];
rot2.i=-rot2.i;
#ifdef DEBUG_FEP
@@ -240,7 +251,7 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
#endif
c16_t *this_symbol = &rxdataF[aa][frame_parms->ofdm_symbol_size*symbol];
rotate_cpx_vector(this_symbol, &rot2, this_symbol, frame_parms->ofdm_symbol_size, 15);
//rotate_cpx_vector(this_symbol, &rot2, this_symbol, frame_parms->ofdm_symbol_size, 15);
}
#ifdef DEBUG_FEP
@@ -314,14 +325,15 @@ void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms,
c16_t *rxdataF,
int slot,
int first_symbol,
int nsymb)
int nsymb,
int link_type)
{
int symb_offset = (slot%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot;
int soffset = (slot&3)*frame_parms->symbols_per_slot*frame_parms->ofdm_symbol_size;
for (int symbol=first_symbol;symbol<nsymb;symbol++) {
c16_t rot2 = frame_parms->symbol_rotation[1][symbol + symb_offset];
c16_t rot2 = frame_parms->symbol_rotation[link_type][symbol + symb_offset];
rot2.i=-rot2.i;
LOG_D(PHY,"slot %d, symb_offset %d rotating by %d.%d\n",slot,symb_offset,rot2.r,rot2.i);

View File

@@ -72,6 +72,10 @@ void nr_chest_time_domain_avg(NR_DL_FRAME_PARMS *frame_parms,
uint16_t dmrs_bitmap,
uint16_t num_rbs);
int nr_psbch_dmrs_rx(int symbol,
unsigned int *nr_gold_psbch,
int32_t *output);
static inline uint8_t is_dmrs_symbol(uint8_t l, uint16_t dmrsSymbMask)
{
DevAssert(l < 32);

View File

@@ -232,6 +232,38 @@ int nr_pbch_dmrs_rx(int symbol,
return(0);
}
int nr_psbch_dmrs_rx(int symbol,
unsigned int *nr_gold_psbch,
int32_t *output)
{
AssertFatal(symbol >= 0 && symbol < 14, "Illegal symbol %d\n", symbol);
int offset = (symbol == 0) ? 0 : 4;
int m0 = (symbol - offset) * 33;
int m1 = ((symbol - offset) + 1) * 33;
/// QPSK modulation
for (int m = m0; m < m1; m++) {
AssertFatal(((m << 1) >> 5) < NR_PSBCH_DMRS_LENGTH_DWORD, "Index in output is invalid %d >= %d\n",
((m << 1) >> 5), NR_PSBCH_DMRS_LENGTH_DWORD);
AssertFatal((((m << 1) + 1) >> 5) < NR_PSBCH_DMRS_LENGTH_DWORD, "Index in output is invalid %d >= %d\n",
(((m << 1) + 1) >> 5), NR_PSBCH_DMRS_LENGTH_DWORD);
uint8_t idx = ((((nr_gold_psbch[(m << 1) >> 5]) >> ((m << 1) & 0x1f)) & 1) << 1) ^ (((nr_gold_psbch[((m << 1) + 1) >> 5]) >> (((m << 1) + 1) & 0x1f)) & 1);
AssertFatal(((m - m0) << 1) + 1 < 200, "Index in output is invalid %d >= %d\n",
((m - m0) << 1) + 1, 200);
AssertFatal(((NR_MOD_TABLE_QPSK_OFFSET + idx) << 1) + 1 < 14, "Index in output is invalid %d >= 14\n",
((NR_MOD_TABLE_QPSK_OFFSET + idx) << 1) + 1);
((int16_t*)output)[(m - m0) << 1] = nr_rx_mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx) << 1];
((int16_t*)output)[((m - m0) << 1) + 1] = nr_rx_mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx) << 1) + 1];
#ifdef DEBUG_PSBCH
printf("%d %d\n", (m - m0) << 1, nr_rx_mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx) << 1]);
if (m < 16) {
printf("nr_gold_psbch[(m << 1) >> 5] %x\n", nr_gold_psbch[(m << 1) >> 5]);
printf("m %d output %d %d addr %p\n", m, ((int16_t*)output)[m << 1], ((int16_t*)output)[(m << 1) + 1], &output[0]);
}
#endif
}
return(0);
}
/*!
\brief This function generate gold ptrs sequence for each OFDM symbol
\param *in gold sequence for ptrs per OFDM symbol

View File

@@ -51,6 +51,20 @@ void nr_gold_pbch(PHY_VARS_NR_UE* ue)
}
void nr_gold_psbch(PHY_VARS_NR_UE* ue)
{
uint8_t reset = 1;
unsigned int x1;
unsigned int x2 = ue->frame_parms.Nid_SL;
for (int n = 0; n < NR_PSBCH_DMRS_LENGTH_DWORD; n++) {
AssertFatal(n < sizeof(ue->nr_gold_psbch) / sizeof(ue->nr_gold_psbch[0]),
"Invalid nr_gold_psbch index %d > %d\n", n, NR_PSBCH_DMRS_LENGTH_DWORD);
ue->nr_gold_psbch[n] = lte_gold_generic(&x1, &x2, reset);
reset = 0;
}
}
void nr_gold_pdcch(PHY_VARS_NR_UE* ue,
unsigned short nid)
{

View File

@@ -66,7 +66,7 @@
#define SYNCHRO_FFT_SIZE_MAX (8192) /* maximum size of fft for synchronisation */
#define NO_RATE_CHANGE (1)
#define INITIAL_PSS_NR (7)
#ifdef PSS_DECIMATOR
#define RATE_CHANGE (SYNCHRO_FFT_SIZE_MAX/SYNCHRO_FFT_SIZE_PSS)
#define SYNCHRO_FFT_SIZE_PSS (256)
@@ -86,33 +86,26 @@
/************** VARIABLES *****************************************/
//#define STATIC_SYNC_BUFFER
#ifdef STATIC_SYNC_BUFFER
/* buffer defined in file lte_sync_time */
EXTERN int16_t synchro_tmp[SYNC_TMP_SIZE] __attribute__((aligned(32)));
EXTERN int16_t synchroF_tmp[SYNCF_TMP_SIZE] __attribute__((aligned(32)));
#else
EXTERN int16_t *synchro_tmp;
EXTERN int16_t *synchroF_tmp;
#endif
EXTERN int16_t *primary_synchro_nr[NUMBER_PSS_SEQUENCE]
EXTERN c16_t *primary_synchro_nr[NUMBER_PSS_SEQUENCE] __attribute__((aligned(32)));
#ifdef INIT_VARIABLES_PSS_NR_H
= { NULL, NULL, NULL}
#endif
;
EXTERN int16_t *primary_synchro_nr2[NUMBER_PSS_SEQUENCE]
EXTERN c16_t *primary_synchro_nr2[NUMBER_PSS_SEQUENCE] __attribute__((aligned(32)));
#ifdef INIT_VARIABLES_PSS_NR_H
= { NULL, NULL, NULL}
#endif
;
EXTERN int16_t *primary_synchro_time_nr[NUMBER_PSS_SEQUENCE]
EXTERN c16_t *primary_synchro_time_nr[NUMBER_PSS_SEQUENCE] __attribute__((aligned(32)));
#ifdef INIT_VARIABLES_PSS_NR_H
= { NULL, NULL, NULL}
#endif
;
EXTERN int16_t *primary_synchro_time_nr_sl[NUMBER_PSS_SEQUENCE_SL]
#ifdef INIT_VARIABLES_PSS_NR_H
= { NULL, NULL}
#endif
;
/* profiling structure */
EXTERN time_stats_t generic_time[TIME_LAST];
@@ -123,7 +116,6 @@ EXTERN time_stats_t generic_time[TIME_LAST];
void init_context_synchro_nr(NR_DL_FRAME_PARMS *frame_parms_ue);
void free_context_synchro_nr(void);
void init_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue);
void free_context_pss_nr(void);
int set_pss_nr(int ofdm_symbol_size);
int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int is, int rate_change);
int pss_search_time_nr(c16_t **rxdata, PHY_VARS_NR_UE *ue, int fo_flag, int is);

View File

@@ -56,6 +56,8 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue,
void nr_gold_pbch(PHY_VARS_NR_UE* ue);
void nr_gold_psbch(PHY_VARS_NR_UE* ue);
void nr_gold_pdcch(PHY_VARS_NR_UE* ue,
unsigned short n_idDMRS);

View File

@@ -41,7 +41,13 @@
/* PSS parameters */
#define NUMBER_PSS_SEQUENCE (3)
#define NUMBER_PSS_SEQUENCE_SL (2)
#define PSS_SEQ_OFFSET (0)
#define PSS_SEQ_OFFSET_SL (22)
#define PSS_SSS_SUB_CARRIER_START (56)
#define PSS_SSS_SUB_CARRIER_START_SL (2)
#define INVALID_PSS_SEQUENCE (NUMBER_PSS_SEQUENCE)
#define INVALID_PSS_SEQUENCE_SL (NUMBER_PSS_SEQUENCE_SL)
#define LENGTH_PSS_NR (127)
#define N_SC_RB (12) /* Resource block size in frequency domain expressed as a number if subcarriers */
#define SCALING_PSS_NR (3)
@@ -62,6 +68,12 @@
#define SSS_SYMBOL_NB ((2) + OFFSET_SS_PBCH)
#define PBCH_LAST_SYMBOL_NB ((3) + OFFSET_SS_PBCH)
#define OFFSET_SS_PSBCH 0//-1
#define PSS0_SL_SYMBOL_NB ((1) + OFFSET_SS_PSBCH)
#define PSS1_SL_SYMBOL_NB ((2) + OFFSET_SS_PSBCH)
#define SSS0_SL_SYMBOL_NB ((3) + OFFSET_SS_PSBCH)
#define SSS1_SL_SYMBOL_NB ((4) + OFFSET_SS_PSBCH)
/* SS/PBCH parameters */
#define N_RB_SS_PBCH_BLOCK (20)
#define NB_SYMBOLS_PBCH (3)

View File

@@ -51,15 +51,26 @@
#define NUMBER_SSS_SEQUENCE (336)
#define INVALID_SSS_SEQUENCE (NUMBER_SSS_SEQUENCE)
#define LENGTH_SSS_NR (127)
#define SCALING_METRIC_SSS_NR (15)//(19)
#define SCALING_METRIC_SSS_NR (19)//(15)
#define N_ID_2_NUMBER (NUMBER_PSS_SEQUENCE)
#define N_ID_2_NUMBER_SL (NUMBER_PSS_SEQUENCE_SL)
#define N_ID_1_NUMBER (NUMBER_SSS_SEQUENCE)
#define GET_NID2(Nid_cell) (Nid_cell%3)
#define GET_NID1(Nid_cell) (Nid_cell/3)
#define GET_NID2_SL(Nid_SL) (Nid_SL/NUMBER_SSS_SEQUENCE)
#define GET_NID1_SL(Nid_SL) (Nid_SL%NUMBER_SSS_SEQUENCE)
#define PSS_SC_START_NR (52) /* see from TS 38.211 table 7.4.3.1-1: Resources within an SS/PBCH block for PSS... */
#define SSS_START_IDX (3) /* [0:PSBCH 1:PSS0 2:PSS1 3:SSS0 4:SSS1] */
#define NUM_SSS_SYMBOLS (2)
#define SSS_START_IDX (3) /* [0:PSBCH 1:PSS0 2:PSS1 3:SSS0 4:SSS1] */
#define NUM_SSS_SYMBOLS (2)
#define SSS_METRIC_FLOOR_NR (30000)
/************** VARIABLES *****************************************/
@@ -89,15 +100,17 @@ EXTERN int16_t d_sss[N_ID_2_NUMBER][N_ID_1_NUMBER][LENGTH_SSS_NR];
void init_context_sss_nr(int amp);
void free_context_sss_nr(void);
void insert_sss_nr(int16_t *sss_time,
void insert_sss_nr(c16_t *sss_time,
NR_DL_FRAME_PARMS *frame_parms);
int pss_ch_est_nr(PHY_VARS_NR_UE *ue,
int32_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR],
int32_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR]);
c16_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR],
c16_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR]);
int rx_sss_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int32_t *tot_metric, uint8_t *phase_max, int *freq_offset_sss, c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
int rx_sss_sl_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int32_t *tot_metric, uint8_t *phase_max, int *freq_offset_sss);
#undef INIT_VARIABLES_SSS_NR_H
#undef EXTERN

View File

@@ -54,7 +54,8 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
short ncoef = 32767 - coef;
LOG_D(PHY,"AbsSubframe %d: rx_offset (before) = %d\n",subframe,ue->rx_offset);
LOG_D(NR_PHY, "AbsSubframe %d: rx_offset (before) = %d\n", subframe,
get_softmodem_params()->sl_mode != 2 ? ue->rx_offset : ue->rx_offset_sl);
// search for maximum position within the cyclic prefix
for (int i = -frame_parms->nb_prefix_samples/2; i < frame_parms->nb_prefix_samples/2; i++) {
@@ -89,10 +90,17 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
else
sync_offset = 0;
if ( abs(diff) < (SYNCH_HYST+sync_offset) )
ue->rx_offset = 0;
else
ue->rx_offset = diff;
if ( abs(diff) < (SYNCH_HYST+sync_offset) ) {
if (get_softmodem_params()->sl_mode == 0)
ue->rx_offset = 0;
else
ue->rx_offset_sl = 0;
} else {
if (get_softmodem_params()->sl_mode == 0)
ue->rx_offset = diff;
else
ue->rx_offset_sl = diff;
}
if(abs(diff)<5)
count_max_pos_ok ++;

View File

@@ -723,6 +723,94 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
return(0);
}
int nr_psbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
uint8_t gNB_id,
unsigned char Ns,
unsigned char symbol,
int dmrss,
NR_UE_SSB *current_ssb)
{
ue->frame_parms.nushift = 0;
unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier;
if (ssb_offset>= ue->frame_parms.ofdm_symbol_size)
ssb_offset-=ue->frame_parms.ofdm_symbol_size;
#ifdef DEBUG_CH
printf("PSBCH DMRS Correlation : ThreadId %d, gNB_id %d , OFDM size %d, Ncp=%d, Ns=%d, symbol %d, ssb_offset %d\n",
proc->thread_id, gNB_id, ue->frame_parms.ofdm_symbol_size, ue->frame_parms.Ncp, Ns, symbol, ssb_offset);
#endif
AssertFatal(dmrss >= 0 && dmrss <= 12, "symbol %d is illegal for PSBCH DM-RS \n", dmrss);
int pilot[300] __attribute__((aligned(16)));
nr_psbch_dmrs_rx(dmrss, &ue->nr_gold_psbch[current_ssb->i_ssb], &pilot[0]);
if (0 < dmrss && dmrss < 5)
return 0;
int16_t ch[2], *pil, *rxF;
c16_t **rxdataF = ue->common_vars.rxdataF;
int symbol_offset = ue->frame_parms.ofdm_symbol_size * symbol;
unsigned short k = 0;
for (int aarx = 0; aarx < ue->frame_parms.nb_antennas_rx; aarx++) {
int re_offset = ssb_offset;
pil = (int16_t *)&pilot[0];
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
current_ssb->c_re += ch[0];
current_ssb->c_im += ch[1];
pil += 2;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
current_ssb->c_re += ch[0];
current_ssb->c_im += ch[1];
pil += 2;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
current_ssb->c_re += ch[0];
current_ssb->c_im += ch[1];
pil += 2;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
for (int pilot_cnt = 3; pilot_cnt < (3 * 11); pilot_cnt += 3) {
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
current_ssb->c_re += ch[0];
current_ssb->c_im += ch[1];
pil += 2;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
current_ssb->c_re += ch[0];
current_ssb->c_im += ch[1];
pil += 2;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
current_ssb->c_re += ch[0];
current_ssb->c_im += ch[1];
pil += 2;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
}
}
return(0);
}
int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
int estimateSz,
struct complex16 dl_ch_estimates[][estimateSz],
@@ -989,6 +1077,223 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
return(0);
}
int nr_psbch_channel_estimation(PHY_VARS_NR_UE *ue,
int estimateSz,
struct complex16 dl_ch_estimates [][estimateSz],
struct complex16 dl_ch_estimates_time [][ue->frame_parms.ofdm_symbol_size],
UE_nr_rxtx_proc_t *proc,
uint8_t gNB_id,
unsigned char Ns,
unsigned char symbol,
int dmrss,
uint8_t ssb_index,
uint8_t n_hf)
{
int pilot[200] __attribute__((aligned(16)));
unsigned short k;
unsigned int pilot_cnt;
int16_t *pil,*rxF,*dl_ch,*fl,*fm,*fr;
int ch_offset,symbol_offset;
uint8_t nushift;
c16_t **rxdataF=ue->common_vars.rxdataF;
nushift = 0;// ue->frame_parms.Nid_cell%4;
ue->frame_parms.nushift = nushift;
unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier;
if (ssb_offset>= ue->frame_parms.ofdm_symbol_size) ssb_offset-=ue->frame_parms.ofdm_symbol_size;
ch_offset = ue->frame_parms.ofdm_symbol_size*symbol;
AssertFatal(dmrss >= 0 && dmrss <= 13,
"symbol %d is illegal for PSBCH DM-RS \n",
dmrss);
symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol;
k = nushift;
#ifdef DEBUG_CH
printf("PSBCH Channel Estimation : ThreadId %d, gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, gNB_id,ch_offset,ue->frame_parms.ofdm_symbol_size,
ue->frame_parms.Ncp,Ns,k, symbol);
#endif
fl = filt16a_l0;
fm = filt16a_m0;
fr = filt16a_r0;
idft_size_idx_t idftsizeidx;
switch (ue->frame_parms.ofdm_symbol_size) {
case 128:
idftsizeidx = IDFT_128;
break;
case 256:
idftsizeidx = IDFT_256;
break;
case 512:
idftsizeidx = IDFT_512;
break;
case 1024:
idftsizeidx = IDFT_1024;
break;
case 1536:
idftsizeidx = IDFT_1536;
break;
case 2048:
idftsizeidx = IDFT_2048;
break;
case 3072:
idftsizeidx = IDFT_3072;
break;
case 4096:
idftsizeidx = IDFT_4096;
break;
default:
printf("unsupported ofdm symbol size \n");
assert(0);
}
// generate pilot
nr_psbch_dmrs_rx(dmrss, &ue->nr_gold_psbch[ssb_index], &pilot[0]);
for (int aarx = 0; aarx < ue->frame_parms.nb_antennas_rx; aarx++) {
int re_offset = ssb_offset;
pil = (int16_t *)&pilot[0];
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset];
memset(dl_ch,0,sizeof(struct complex16)*(ue->frame_parms.ofdm_symbol_size));
#ifdef DEBUG_CH
printf("psbch ch est pilot addr %p RB_DL %d\n",&pilot[0], ue->frame_parms.N_RB_DL);
printf("k %d, first_carrier %d\n",k,ue->frame_parms.first_carrier_offset);
printf("rxF addr %p\n", rxF);
printf("dl_ch addr %p\n",dl_ch);
#endif
// Treat first 2 pilots specially (left edge)
int16_t ch[2];
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1]));
printf("pilot 0 : rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
#endif
multadd_real_vector_complex_scalar(fl, ch, dl_ch, 16);
pil += 2;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
//for (int i= 0; i<8; i++)
//printf("dl_ch addr %p %d\n", dl_ch+i, *(dl_ch+i));
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
multadd_real_vector_complex_scalar(fm, ch, dl_ch, 16);
pil += 2;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot 2 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
multadd_real_vector_complex_scalar(fr,
ch,
dl_ch,
16);
pil += 2;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
dl_ch += 24;
for (pilot_cnt = 3; pilot_cnt < (3 * 11); pilot_cnt += 3) {
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
multadd_real_vector_complex_scalar(fl,
ch,
dl_ch,
16);
//for (int i= 0; i<8; i++)
// printf("pilot_cnt %d dl_ch %d %d\n", pilot_cnt, dl_ch+i, *(dl_ch+i));
pil += 2;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
multadd_real_vector_complex_scalar(fm,
ch,
dl_ch,
16);
pil += 2;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
multadd_real_vector_complex_scalar(fr,
ch,
dl_ch,
16);
pil += 2;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
dl_ch += 24;
}
if( dmrss == 12) // update time statistics for last PSBCH symbol
{
// do ifft of channel estimate
LOG_D(PHY,"Channel Impulse Computation Slot %d Symbol %d ch_offset %d\n", Ns, symbol, ch_offset);
idft(idftsizeidx,
(int16_t*) &dl_ch_estimates[aarx][ch_offset],
(int16_t*) dl_ch_estimates_time[aarx],
1);
}
}
if (dmrss == 12)
UEscopeCopy(ue, psbchDlChEstimateTime, (void*)dl_ch_estimates_time, sizeof(struct complex16), ue->frame_parms.nb_antennas_rx, idftsizeidx);
return(0);
}
void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
unsigned char symbol,

View File

@@ -67,6 +67,14 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
NR_UE_SSB *current_ssb,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
int nr_psbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
uint8_t gNB_id,
unsigned char Ns,
unsigned char symbol,
int dmrss,
NR_UE_SSB *current_ssb);
int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
int estimateSz,
struct complex16 dl_ch_estimates[][estimateSz],
@@ -78,6 +86,18 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
uint8_t n_hf,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
int nr_psbch_channel_estimation(PHY_VARS_NR_UE *ue,
int estimateSz,
struct complex16 dl_ch_estimates [][estimateSz],
struct complex16 dl_ch_estimates_time [][estimateSz],
UE_nr_rxtx_proc_t *proc,
uint8_t gNB_id,
unsigned char Ns,
unsigned char symbol,
int dmrss,
uint8_t ssb_index,
uint8_t n_hf);
int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
bool is_SI,
@@ -115,6 +135,10 @@ void nr_ue_ssb_rsrp_measurements(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
void nr_ue_sl_ssb_rsrp_measurements(PHY_VARS_NR_UE *ue,
int ssb_index,
UE_nr_rxtx_proc_t *proc);
void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);

View File

@@ -37,6 +37,8 @@
#include "PHY/phy_extern_nr_ue.h"
#include "common/utils/LOG/log.h"
#include "PHY/sse_intrin.h"
#include "openair1/PHY/NR_REFSIG/sss_nr.h"
#include "openair1/PHY/NR_REFSIG/ss_pbch_nr.h"
//#define k1 1000
#define k1 ((long long int) 1000)
@@ -236,6 +238,40 @@ void nr_ue_ssb_rsrp_measurements(PHY_VARS_NR_UE *ue,
rsrp);
}
// This function implements:
// - Sidelink SS reference signal received power (SSS-RSRP)
// Measurement units:
// - RSRP: W (dBW)
// - RX Gain dB
void nr_ue_sl_ssb_rsrp_measurements(PHY_VARS_NR_UE *ue,
int ssb_index,
UE_nr_rxtx_proc_t *proc) {
uint32_t rsrp = 0;
int nb_re = 0;
for (int aarx = 0; aarx < ue->frame_parms.nb_antennas_rx; aarx++) {
for (int i = 0; i < NUM_SSS_SYMBOLS; i++) {
uint8_t l_sss = (SSS_START_IDX + i) % ue->frame_parms.symbols_per_slot;
int16_t *rxF_sss = (int16_t *)&ue->common_vars.rxdataF[aarx][(l_sss * ue->frame_parms.ofdm_symbol_size)];
for (int k = PSS_SSS_SUB_CARRIER_START_SL; k < (PSS_SSS_SUB_CARRIER_START_SL + LENGTH_SSS_NR); k++) {
#ifdef DEBUG_MEAS_UE
LOG_I(NR_PHY, "In %s rxF_sss %d %d\n", __FUNCTION__, rxF_sss[k * 2], rxF_sss[k * 2 + 1]);
#endif
rsrp += (((int32_t)rxF_sss[k * 2] * rxF_sss[k * 2]) + ((int32_t)rxF_sss[k * 2 + 1] * rxF_sss[k * 2 + 1]));
nb_re++;
}
}
}
rsrp /= nb_re;
ue->measurements.ssb_rsrp_dBm[ssb_index] = 10 * log10(rsrp) +
30 - 10 * log10(pow(2, 30)) -
((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) -
dB_fixed(ue->frame_parms.ofdm_symbol_size);
LOG_I(NR_PHY, "In %s: [UE %d] ssb %d SS-RSRP: %d dBm/RE (%d)\n",
__FUNCTION__, ue->Mod_id, ssb_index, ue->measurements.ssb_rsrp_dBm[ssb_index], rsrp);
}
// This function computes the received noise power
// Measurement units:
// - psd_awgn (AWGN power spectral density): dBm/Hz

View File

@@ -0,0 +1,119 @@
/*
* 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 <stdio.h>
#include <assert.h>
#include <errno.h>
#include <math.h>
#include <nr-uesoftmodem.h>
#include "PHY/defs_nr_UE.h"
#include "PHY/phy_extern.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
#include "executables/softmodem-common.h"
//#define DEBUG_PSBCH
//#define DEBUG_PSBCH_ENCODING
//#define DEBUG_PSBCH_DMRS
int nr_sl_generate_psbch_dmrs(uint32_t *gold_psbch_dmrs,
c16_t *txdataF,
int16_t amp,
uint8_t ssb_start_symbol,
NR_DL_FRAME_PARMS *frame_parms) {
int dmrs_modulations_per_symbol = 33;
int16_t mod_dmrs[NR_PSBCH_DMRS_LENGTH << 1];
LOG_D(NR_PHY, "PSBCH DMRS mapping started at symbol %d\n", ssb_start_symbol);
/// QPSK modulation
for (int m = 0; m < NR_PSBCH_DMRS_LENGTH; m++) {
AssertFatal(((m << 1) >> 5) < NR_PSBCH_DMRS_LENGTH_DWORD, "Invalid index size %d\n", (m << 1) >> 5);
int idx = (((gold_psbch_dmrs[(m << 1) >> 5]) >> ((m << 1) & 0x1f)) & 3);
AssertFatal(((idx << 1) + 1) < (sizeof(nr_qpsk_mod_table) / sizeof(nr_qpsk_mod_table[0])), "Invalid index size %d\n", (idx << 1) + 1);
AssertFatal((m << 1) + 1 < (sizeof(mod_dmrs) / sizeof(mod_dmrs[0])), "Invalid index size %d\n", (idx << 1) + 1);
mod_dmrs[m << 1] = nr_qpsk_mod_table[idx << 1];
mod_dmrs[(m << 1) + 1] = nr_qpsk_mod_table[(idx << 1) + 1];
#ifdef DEBUG_PSBCH_DMRS
printf("m %d idx %d gold seq %d b0-b1 %d-%d mod_dmrs %d %d\n", m, idx, gold_psbch_dmrs[(m << 1) >> 5], (((gold_psbch_dmrs[(m << 1) >> 5]) >> ((m << 1) & 0x1f)) & 1),
(((gold_psbch_dmrs[((m << 1) + 1) >> 5]) >> (((m << 1)+1) & 0x1f)) & 1), mod_dmrs[(m << 1)], mod_dmrs[(m << 1)+1]);
#endif
}
/// Resource mapping
// PSBCH DMRS are mapped within the SSB block on every fourth subcarrier starting from nushift of symbols 1, 2, 3
///symbol 0 [0+nushift:4:236+nushift] -- 33 mod symbols
int k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier;
int l = ssb_start_symbol;
int m = 0;
for (; m < dmrs_modulations_per_symbol; m++) {
#ifdef DEBUG_PSBCH_DMRS
printf("m %d at k %d of l %d\n", m, k, l);
#endif
AssertFatal(((m << 1) + 1) < (sizeof(mod_dmrs) / sizeof(mod_dmrs[0])), "Invalid index into mod_dmrs. Index %d > %lu\n",
(m << 1) + 1, (sizeof(mod_dmrs) / sizeof(mod_dmrs[0])));
txdataF[(l * frame_parms->ofdm_symbol_size + k)].r = (amp * mod_dmrs[m << 1]) >> 15;
txdataF[(l * frame_parms->ofdm_symbol_size + k)].i = (amp * mod_dmrs[(m << 1) + 1]) >> 15;
#ifdef DEBUG_PSBCH_DMRS
printf("(%d,%d)\n",
((int16_t *)txdataF)[(l * frame_parms->ofdm_symbol_size + k)].r,
((int16_t *)txdataF)[(l * frame_parms->ofdm_symbol_size + k)].i);
#endif
k+=4;
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
}
int N_SSSB_Symb = 13;
l = ssb_start_symbol + 5;
while (l < N_SSSB_Symb)
{
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier;
int mod_count = 0;
while (m < NR_PSBCH_DMRS_LENGTH) {
#ifdef DEBUG_PSBCH_DMRS
printf("m %d at k %d of l %d\n", m, k, l);
#endif
AssertFatal(((m << 1) + 1) < (sizeof(mod_dmrs) / sizeof(mod_dmrs[0])), "Invalid index into mod_dmrs. Index %d > %lu\n",
(m << 1) + 1, (sizeof(mod_dmrs) / sizeof(mod_dmrs[0])));
txdataF[(l * frame_parms->ofdm_symbol_size + k)].r = (amp * mod_dmrs[m << 1]) >> 15;
txdataF[(l * frame_parms->ofdm_symbol_size + k)].i = (amp * mod_dmrs[(m << 1) + 1]) >> 15;
#ifdef DEBUG_PSBCH_DMRS
printf("%d (%d,%d)\n", m,
((int16_t *)txdataF)[(l * frame_parms->ofdm_symbol_size + k)].r,
((int16_t *)txdataF)[(l * frame_parms->ofdm_symbol_size + k)].i);
#endif
k+=4;
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
mod_count++;
m++;
if (mod_count == dmrs_modulations_per_symbol)
break;
}
l++;
}
#ifdef DEBUG_PSBCH_DMRS
write_output("txdataF_psbch_dmrs.m", "txdataF_psbch_dmrs", txdataF[0], frame_parms->samples_per_frame_wCP>>1, 1, 1);
#endif
return 0;
}

View File

@@ -44,13 +44,14 @@
#include "PHY/NR_REFSIG/pss_nr.h"
#include "PHY/NR_REFSIG/sss_nr.h"
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
#include "executables/softmodem-common.h"
extern openair0_config_t openair0_cfg[];
//static nfapi_nr_config_request_t config_t;
//static nfapi_nr_config_request_t* config =&config_t;
int cnt=0;
#define DEBUG_INITIAL_SYNCH
#define DEBUG_INITIAL_SYNCH 1
#define DUMP_PBCH_CH_ESTIMATES 0
// create a new node of SSB structure
@@ -197,9 +198,169 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini
}
int nr_psbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int psbch_initial_symbol, NR_UE_PDCCH_CONFIG *phy_pdcch_config)
{
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
int ret = -1;
NR_UE_SSB *best_ssb = NULL;
NR_UE_SSB *current_ssb;
uint8_t N_L = 2;
uint8_t N_hf = 0;
for (int l = 0; l < N_L; l++) {
current_ssb = create_ssb_node(l, N_hf);
start_meas(&ue->dlsch_channel_estimation_stats);
// computing correlation between received DMRS symbols and transmitted sequence for current i_ssb and n_hf
for (int i = psbch_initial_symbol; i < 13; i++) {
if (i >= 1 && i <= 4)
continue;
nr_psbch_dmrs_correlation(ue, proc, 0, 0, i, i - psbch_initial_symbol, current_ssb);
}
stop_meas(&ue->dlsch_channel_estimation_stats);
current_ssb->metric = current_ssb->c_re*current_ssb->c_re + current_ssb->c_im*current_ssb->c_im;
// generate a list of SSB structures
if (best_ssb == NULL)
best_ssb = current_ssb;
else
best_ssb = insert_into_list(best_ssb, current_ssb);
}
NR_UE_SSB *temp_ptr = best_ssb;
while (ret != 0 && temp_ptr != NULL) {
start_meas(&ue->dlsch_channel_estimation_stats);
const int estimateSz = frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size;
__attribute__ ((aligned(32))) struct complex16 dl_ch_estimates[frame_parms->nb_antennas_rx][estimateSz];
__attribute__ ((aligned(32))) struct complex16 dl_ch_estimates_time[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size];
for (int i = psbch_initial_symbol; i < 13; i++) {
if (i >= 1 && i <= 4)
continue;
nr_psbch_channel_estimation(ue, estimateSz, dl_ch_estimates, dl_ch_estimates_time,
proc, 0, 0, i, i - psbch_initial_symbol, temp_ptr->i_ssb, temp_ptr->n_hf);
}
stop_meas(&ue->dlsch_channel_estimation_stats);
nr_ue_sl_ssb_rsrp_measurements(ue, temp_ptr->i_ssb, proc);
fapiPsbch_t result;
ret = nr_rx_psbch(ue, proc, estimateSz, dl_ch_estimates, ue->psbch_vars[0], frame_parms,
0, temp_ptr->i_ssb, SISO, phy_pdcch_config, &result);
temp_ptr = temp_ptr->next_ssb;
}
free_list(best_ssb);
return ret;
}
char duplex_string[2][4] = {"FDD","TDD"};
char prefix_string[2][9] = {"NORMAL","EXTENDED"};
int nr_sl_initial_sync(UE_nr_rxtx_proc_t *proc,
PHY_VARS_NR_UE *ue,
int n_frames)
{
/* Initial synchronisation
*
* 1 radio frame = 10 ms
* <--------------------------------------------------------------------------->
* -----------------------------------------------------------------------------
* | Received UE data buffer |
* ----------------------------------------------------------------------------
* -------------------------------------------------
* <-------------->| psbch | spss | spss | ssss | ssss | psbch |....
* -------------------------------------------------
* sync_pos SL S-SSB/PSBCH block
*/
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INITIAL_UE_SYNC, VCD_FUNCTION_IN);
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
LOG_I(NR_PHY, "nr_initial SL sync ue RB_DL %d prefix 0 %d\n", fp->N_RB_DL, fp->nb_prefix_samples0);
int ret = -1;
int32_t sync_pos = 0;
for (int is = 0; is < n_frames; is++) {
sync_pos = pss_synchro_nr(ue, is, NO_RATE_CHANGE);
if (sync_pos >= fp->nb_prefix_samples) {
// In 5G SL, the first SSB symbol is the PSBCH, so we need adjust the SSB
// offset accordingly (psbch_plus_prefix_size). Additionally, there are 2
// PSS symbols. So in the case where we correlate on the second PSS,
// we need to adjust the SSB offset accordingly (subtracting first PSS prefix).
// However, if we correlated on the second PSS, we do not need to include
// the size of the first PSS0, becasue the correlation occurs on each individual PSS.
// The sync position (sync_pos) is the start of the found PSS + nb_prefix_samples.
// PSBCH PREFIX | PSBCH 0 | PSS 0 PREFIX | PSS 0 | PSS 1 PREFIX | PSS 1 |
// 176 | 2048 | 144 | 2048 | 144 | 2048 |
// ----------------------------------------------------------------------
// 176 | 2048 | 144 | - | 144 | X | SSB Offset = X - (144 + 144 + 2048 + 144)
// 176 | 2048 | 144 | X | 144 | 2048 | SSB Offset = X - (144 + 2048 + 144)
uint32_t psbch_plus_prefix_size = fp->ofdm_symbol_size + fp->nb_prefix_samples0;
uint32_t num_pss_prefix_samples_size = fp->nb_prefix_samples;/*(ue->common_vars.N2_id + 1) * fp->nb_prefix_samples;*/
LOG_I(NR_PHY, "This is num_pss_prefix_samples_size %d, psbch_plus_prefix_size %d, sync_pos %d, N2_id %d\n",
num_pss_prefix_samples_size, psbch_plus_prefix_size, sync_pos, ue->common_vars.N2_id);
ue->ssb_offset = sync_pos - num_pss_prefix_samples_size - psbch_plus_prefix_size;
} else {
ue->ssb_offset = sync_pos + (fp->samples_per_subframe * 10) - fp->nb_prefix_samples;
}
LOG_I(NR_PHY, "[UE%d] Initial SL sync : n_frames %d Estimated PSS position %d, Nid2 %d ssb_offset %d prefix0 %d\n",
ue->Mod_id, n_frames, sync_pos, ue->common_vars.N2_id, ue->ssb_offset,ue->frame_parms.nb_prefix_samples0);
if (sync_pos < (NR_NUMBER_OF_SUBFRAMES_PER_FRAME * fp->samples_per_subframe - (NB_SYMBOLS_PBCH * fp->ofdm_symbol_size))) {
uint8_t phase_tdd_ncp;
int32_t metric_tdd_ncp = 0;
const uint32_t rxdataF_sz = ue->frame_parms.samples_per_slot_wCP;
__attribute__ ((aligned(32))) c16_t rxdataF[ue->frame_parms.nb_antennas_rx][rxdataF_sz];
for (int i = 0; i < 13; i++)
nr_slot_fep_init_sync(ue, proc, i, is * fp->samples_per_frame + ue->ssb_offset,
false, rxdataF);
memcpy(ue->common_vars.rxdataF[0], rxdataF[0], rxdataF_sz * sizeof(int32_t));
LOG_I(NR_PHY, "Calling sss detection (normal CP) prefix0 %d\n",ue->frame_parms.nb_prefix_samples0);
int freq_offset_sss = 0;
ret = rx_sss_sl_nr(ue, proc, &metric_tdd_ncp, &phase_tdd_ncp, &freq_offset_sss);
if (ue->UE_fo_compensation) {
double sampling_time = 1 / (1.0e3 * fp->samples_per_subframe);
double off_angle = -2 * M_PI * sampling_time * freq_offset_sss;
int start = is * fp->samples_per_frame + ue->ssb_offset;
int end = start + NR_N_SYMBOLS_SSB * (fp->ofdm_symbol_size + fp->nb_prefix_samples);
for (int n = start; n < end; n++) {
for (int ar = 0; ar < fp->nb_antennas_rx; ar++) {
double re = ((double)(((short *)ue->common_vars.rxdata[ar]))[2 * n]);
double im = ((double)(((short *)ue->common_vars.rxdata[ar]))[2 * n + 1]);
((short *)ue->common_vars.rxdata[ar])[2 * n] = (short)(round(re * cos(n * off_angle) - im * sin(n * off_angle)));
((short *)ue->common_vars.rxdata[ar])[2 * n + 1] = (short)(round(re * sin(n * off_angle) + im *cos(n * off_angle)));
}
}
ue->common_vars.freq_offset += freq_offset_sss;
}
if (ret == 0) {
nr_gold_psbch(ue);
NR_UE_PDCCH_CONFIG phy_pdcch_config = {0};
ret = nr_psbch_detection(proc, ue, 0, &phy_pdcch_config);
}
LOG_I(NR_PHY, "TDD Normal prefix: CellId %d metric %d, phase %d, psbch %d\n",
fp->Nid_cell, metric_tdd_ncp, phase_tdd_ncp, ret);
} else {
LOG_I(NR_PHY, "TDD Normal prefix: SSS error condition: sync_pos %d\n", sync_pos);
}
if (ret == 0) break;
if (ret < 0) exit(-1);
}
if (ret == 0) {
LOG_I(NR_PHY, "[UE %d] rx_offset %d Measured Carrier Frequency %.0f Hz (offset %d Hz) prefix0 %d\n",
ue->Mod_id, ue->rx_offset_sl, openair0_cfg[0].rx_freq[0] + ue->common_vars.freq_offset, ue->common_vars.freq_offset,ue->frame_parms.nb_prefix_samples0);
if (ue->UE_scan_carrier == 0) {
ue->psbch_vars[0]->pdu_errors_conseq = 0;
}
} else {
LOG_I(NR_PHY, "[UE%d] Initial sync : PSBCH not ok. Estimated PSS position %d, Nid1 %d, Nid2 %d, Frame_type %d\n",
ue->Mod_id, sync_pos, GET_NID1_SL(fp->Nid_SL), GET_NID2_SL(fp->Nid_SL), fp->frame_type);
ue->psbch_vars[0]->pdu_errors_last = ue->psbch_vars[0]->pdu_errors;
ue->psbch_vars[0]->pdu_errors++;
ue->psbch_vars[0]->pdu_errors_conseq++;
int rx_power = 0;
ue->measurements.rx_power_avg[0] = rx_power / fp->nb_antennas_rx;
ue->measurements.rx_power_avg_dB[0] = dB_fixed(ue->measurements.rx_power_avg[0]);
LOG_I(NR_PHY, "[UE%d] Gain Control - Initial sync : Estimated power: %d dB\n", ue->Mod_id, ue->measurements.rx_power_avg_dB[0]);
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INITIAL_UE_SYNC, VCD_FUNCTION_OUT);
return ret;
}
int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
PHY_VARS_NR_UE *ue,
int n_frames, int sa)

View File

@@ -0,0 +1,450 @@
/*
* 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.0 (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
*/
/*! \file PHY/LTE_TRANSPORT/psbch.c
* \brief Top-level routines for generating and decoding the PSBCH/BCH physical/transport channel V8.6 2009-03
* \author R. Knopp, F. Kaltenberger
* \date 2011
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr,florian.kaltenberger.fr
* \note
* \warning
*/
#include "PHY/defs_nr_UE.h"
#include "PHY/CODING/coding_extern.h"
#include "PHY/phy_extern_nr_ue.h"
#include "PHY/sse_intrin.h"
#include "PHY/LTE_REFSIG/lte_refsig.h"
#include "openair1/SCHED_NR_UE/defs.h"
#include <openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h>
#include <openair1/PHY/TOOLS/phy_scope_interface.h>
#include "openair1/PHY/NR_REFSIG/refsig_defs_ue.h"
// #define DEBUG_PSBCH
//#define DEBUG_PSBCH_ENCODING
//#include "PHY_INTERFACE/defs.h"
static void nr_psbch_quantize(int16_t *psbch_llr8,
int16_t *psbch_llr,
uint16_t len) {
for (int i = 0; i < len; i++) {
if (psbch_llr[i] > 31)
psbch_llr8[i] = 32;
else if (psbch_llr[i] < -31)
psbch_llr8[i] = -32;
else
psbch_llr8[i] = psbch_llr[i];
}
}
static uint16_t nr_psbch_extract(c16_t **rxdataF,
const int estimateSz,
struct complex16 dl_ch_estimates[][estimateSz],
struct complex16 rxdataF_ext[][PSBCH_MAX_RE_PER_SYMBOL],
struct complex16 dl_ch_estimates_ext[][PSBCH_MAX_RE_PER_SYMBOL],
uint32_t symbol,
uint32_t s_offset,
NR_DL_FRAME_PARMS *frame_parms) {
uint16_t rb;
uint8_t i,j,aarx;
int nushiftmod4 = 0;//frame_parms->nushift;
AssertFatal(symbol == 0 || symbol < 14,
"symbol %d illegal for PSBCH extraction\n",
symbol);
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
unsigned int rx_offset = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier;
rx_offset = (rx_offset)%(frame_parms->ofdm_symbol_size);
struct complex16 *rxF = (struct complex16 *)&rxdataF[aarx][(symbol+s_offset)*frame_parms->ofdm_symbol_size];
struct complex16 *rxF_ext = rxdataF_ext[aarx];
#ifdef DEBUG_PSBCH
LOG_I(NR_PHY,"extract_rbs (nushift %d): rx_offset=%d, symbol %u\n",frame_parms->nushift,
(rx_offset + ((symbol+s_offset)*(frame_parms->ofdm_symbol_size))),symbol);
int16_t *p = (int16_t *)rxF;
for (int i =0; i<8; i++) {
LOG_I(NR_PHY,"rxF [%d]= %d\n",i,rxF[i]);
LOG_I(NR_PHY,"psbch extract rxF %d %d addr %p\n", p[2*i], p[2*i+1], &p[2*i]);
}
#endif
for (rb=0; rb<11; rb++) {
j=0;
if (symbol == 0 || ((symbol > 4) && (symbol <= 13))) {
for (i=0; i<12; i++) {
if ((i!=nushiftmod4) &&
(i!=(nushiftmod4+4)) &&
(i!=(nushiftmod4+8))) {
rxF_ext[j]=rxF[rx_offset];
#ifdef DEBUG_PSBCH
LOG_I(NR_PHY,"rxF ext[%d] = (%d,%d) rxF [%u]= (%d,%d)\n", (9*rb) + j,
rxF_ext[j].r, rxF_ext[j].i,
rx_offset,
rxF[rx_offset].r,rxF[rx_offset].i);
#endif
j++;
}
rx_offset=(rx_offset+1)%(frame_parms->ofdm_symbol_size);
//rx_offset = (rx_offset >= frame_parms->ofdm_symbol_size) ? (rx_offset - frame_parms->ofdm_symbol_size + 1) : (rx_offset+1);
}
rxF_ext+=9;
}
}
struct complex16 *dl_ch0 = &dl_ch_estimates[aarx][((symbol+s_offset)*(frame_parms->ofdm_symbol_size))];
//printf("dl_ch0 addr %p\n",dl_ch0);
struct complex16 *dl_ch0_ext = dl_ch_estimates_ext[aarx];
for (rb=0; rb<11; rb++) {
j=0;
if (symbol == 0 || ((symbol > 4) && (symbol <= 13))) {
for (i=0; i<12; i++) {
if ((i!=nushiftmod4) &&
(i!=(nushiftmod4+4)) &&
(i!=(nushiftmod4+8))) {
dl_ch0_ext[j]=dl_ch0[i];
#ifdef DEBUG_PSBCH
if ((rb==0) && (i<2))
printf("dl ch0 ext[%d] = (%d,%d) dl_ch0 [%d]= (%d,%d)\n",j,
dl_ch0_ext[j].r, dl_ch0_ext[j].i,
i,
dl_ch0[j].r, dl_ch0[j].i);
#endif
j++;
}
}
dl_ch0+=12;
dl_ch0_ext+=9;
}
}
}
return(0);
}
//__m128i avg128;
//compute average channel_level on each (TX,RX) antenna pair
int nr_psbch_channel_level(struct complex16 dl_ch_estimates_ext[][PSBCH_MAX_RE_PER_SYMBOL],
NR_DL_FRAME_PARMS *frame_parms,
int nb_re) {
int16_t nb_rb=nb_re/12;
#if defined(__x86_64__) || defined(__i386__)
__m128i avg128;
__m128i *dl_ch128;
#elif defined(__arm__)
int32x4_t avg128;
int16x8_t *dl_ch128;
#endif
int avg1=0,avg2=0;
for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
//clear average level
#if defined(__x86_64__) || defined(__i386__)
avg128 = _mm_setzero_si128();
dl_ch128=(__m128i *)dl_ch_estimates_ext[aarx];
#elif defined(__arm__)
avg128 = vdupq_n_s32(0);
dl_ch128=(int16x8_t *)dl_ch_estimates_ext[aarx];
#endif
for (int rb=0; rb<nb_rb; rb++) {
#if defined(__x86_64__) || defined(__i386__)
avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[0],dl_ch128[0]));
avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[1],dl_ch128[1]));
avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[2],dl_ch128[2]));
#elif defined(__arm__)
abort();
// to be filled in
#endif
dl_ch128+=3;
/*
if (rb==0) {
print_shorts("dl_ch128",&dl_ch128[0]);
print_shorts("dl_ch128",&dl_ch128[1]);
print_shorts("dl_ch128",&dl_ch128[2]);
}*/
}
avg1 = (((int *)&avg128)[0] +
((int *)&avg128)[1] +
((int *)&avg128)[2] +
((int *)&avg128)[3])/(nb_rb*12);
if (avg1>avg2)
avg2 = avg1;
//LOG_I(PHY,"Channel level : %d, %d\n",avg1, avg2);
}
return(avg2);
}
static void nr_psbch_channel_compensation(struct complex16 rxdataF_ext[][PSBCH_MAX_RE_PER_SYMBOL],
struct complex16 dl_ch_estimates_ext[][PSBCH_MAX_RE_PER_SYMBOL],
int nb_re,
struct complex16 rxdataF_comp[][PSBCH_MAX_RE_PER_SYMBOL],
NR_DL_FRAME_PARMS *frame_parms,
uint8_t output_shift) {
for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
vect128 *dl_ch128 = (vect128 *)dl_ch_estimates_ext[aarx];
vect128 *rxdataF128 = (vect128 *)rxdataF_ext[aarx];
vect128 *rxdataF_comp128 = (vect128 *)rxdataF_comp[aarx];
for (int re=0; re<nb_re; re+=12) {
*rxdataF_comp128++ = mulByConjugate128(rxdataF128++, dl_ch128++, output_shift);
*rxdataF_comp128++ = mulByConjugate128(rxdataF128++, dl_ch128++, output_shift);
*rxdataF_comp128++ = mulByConjugate128(rxdataF128++, dl_ch128++, output_shift);
}
}
}
static void nr_psbch_unscrambling(NR_UE_PSBCH *psbch,
int16_t *demod_psbch_e,
uint16_t Nid,
uint8_t nushift,
uint16_t M,
uint16_t length,
uint8_t bitwise,
uint32_t unscrambling_mask,
uint32_t psbch_a_prime,
uint32_t *psbch_a_interleaved) {
uint8_t reset, offset;
uint32_t x1, x2, s=0;
uint8_t k=0;
reset = 1;
// x1 is set in first call to lte_gold_generic
x2 = Nid; //this is c_init
// The Gold sequence is shifted by nushift* M, so we skip (nushift*M /32) double words
for (int i=0; i<(uint16_t)ceil(((float)M)/32); i++) {
s = lte_gold_generic(&x1, &x2, reset);
reset = 0;
}
// Scrambling is now done with offset (nushift*M)%32
offset = 0; //(nushift*M)&0x1f;
for (int i=0; i<length; i++) {
/*if (((i+offset)&0x1f)==0) {
s = lte_gold_generic(&x1, &x2, reset);
reset = 0;
}*/
if (bitwise) {
if (((k+offset)&0x1f)==0 && (!((unscrambling_mask>>i)&1))) {
s = lte_gold_generic(&x1, &x2, reset);
reset = 0;
}
*psbch_a_interleaved ^= ((unscrambling_mask>>i)&1)? ((psbch_a_prime>>i)&1)<<i : (((psbch_a_prime>>i)&1) ^ ((s>>((k+offset)&0x1f))&1))<<i;
k += (!((unscrambling_mask>>i)&1));
#ifdef DEBUG_PSBCH_ENCODING
printf("i %d k %d offset %d (unscrambling_mask>>i)&1) %d s: %08x\t psbch_a_interleaved 0x%08x (!((unscrambling_mask>>i)&1)) %d\n", i, k, offset, (unscrambling_mask>>i)&1, s, *psbch_a_interleaved,
(!((unscrambling_mask>>i)&1)));
#endif
} else {
if (((i+offset)&0x1f)==0) {
s = lte_gold_generic(&x1, &x2, reset);
reset = 0;
}
if (((s>>((i+offset)&0x1f))&1)==1)
demod_psbch_e[i] = -demod_psbch_e[i];
#ifdef DEBUG_PSBCH_ENCODING
if (i<8)
printf("s %d demod_psbch_e[i] %d\n", ((s>>((i+offset)&0x1f))&1), demod_psbch_e[i]);
#endif
}
}
}
void nr_sl_common_signal_procedures(PHY_VARS_NR_UE *ue, int frame, int slot)
{
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
c16_t **txdataF = ue->common_vars.txdataF;
uint8_t ssb_index = 0; //TODO: Need update to get 0 or 1 from parameter in case of mu = 1.
int txdataF_offset = slot * fp->samples_per_slot_wCP;
uint16_t ssb_start_symbol = 0;
LOG_D(NR_PHY, "common_signal_procedures: frame %d, slot %d ssb index %d, ssb_start_symbol %d, txdataF_offset %d\n",
frame, slot, ssb_index, ssb_start_symbol, txdataF_offset);
const int prb_offset = 0; //TODO: Need to properly get these values.
const int sc_offset = 0; //TODO: Need to properly get these values.
fp->ssb_start_subcarrier = prb_offset * 12 + sc_offset;
LOG_D(NR_PHY, "SSB first subcarrier %d (%d,%d)\n", fp->ssb_start_subcarrier, prb_offset, sc_offset);
nr_gold_psbch(ue);
nr_sl_generate_pss(&txdataF[0][txdataF_offset], AMP, ssb_start_symbol, fp);
nr_sl_generate_sss(&txdataF[0][txdataF_offset], AMP, ssb_start_symbol, fp);
nr_sl_generate_psbch_dmrs(&ue->nr_gold_psbch[ssb_index & 7], &txdataF[0][txdataF_offset], AMP, ssb_start_symbol, fp);
uint8_t n_hf = 0;
nr_generate_sl_psbch(ue, &txdataF[0][txdataF_offset], AMP, ssb_start_symbol, n_hf, frame, fp);
}
int nr_rx_psbch( PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
int estimateSz, struct complex16 dl_ch_estimates [][estimateSz],
NR_UE_PSBCH *nr_ue_psbch_vars,
NR_DL_FRAME_PARMS *frame_parms,
uint8_t gNB_id,
uint8_t i_ssb,
MIMO_mode_t mimo_mode,
NR_UE_PDCCH_CONFIG *phy_pdcch_config,
fapiPsbch_t *result) {
NR_UE_COMMON *nr_ue_common_vars = &ue->common_vars;
uint8_t ssb_index = 0; //TODO: Need update to get 0 or 1 from parameter in case of mu = 1.
int symbol_offset = ue->is_synchronized > 0 ? (ue->slss->sl_timeoffsetssb_r16 + ue->slss->sl_timeinterval_r16 * ssb_index) * frame_parms->symbols_per_slot : 0;
int psbch_e_rx_idx = 0;
int16_t psbch_unClipped[NR_POLAR_PSBCH_E] = {0};
int16_t psbch_e_rx[NR_POLAR_PSBCH_E] = {0};
// symbol refers to symbol within SSB. symbol_offset is the offset of the SSB wrt start of slot
for (int symbol = 0; symbol < 13; symbol++) {
const uint16_t nb_re = 99;
__attribute__ ((aligned(32))) struct complex16 rxdataF_ext[frame_parms->nb_antennas_rx][PSBCH_MAX_RE_PER_SYMBOL];
__attribute__ ((aligned(32))) struct complex16 dl_ch_estimates_ext[frame_parms->nb_antennas_rx][PSBCH_MAX_RE_PER_SYMBOL];
memset(dl_ch_estimates_ext,0, sizeof dl_ch_estimates_ext);
nr_psbch_extract(nr_ue_common_vars->rxdataF,
estimateSz,
dl_ch_estimates,
rxdataF_ext,
dl_ch_estimates_ext,
symbol,
symbol_offset,
frame_parms);
int log2_maxh = 0;
if (symbol == 0) {
int max_h = nr_psbch_channel_level(dl_ch_estimates_ext,
frame_parms,
nb_re);
log2_maxh = 3 + (log2_approx(max_h) / 2);
#ifdef DEBUG_PSBCH
LOG_I(NR_PHY, "PSBCH Symbol %d ofdm size %d\n", symbol, frame_parms->ofdm_symbol_size );
LOG_I(NR_PHY,"PSBCH log2_maxh = %d (%d)\n", log2_maxh, max_h);
#endif
}
__attribute__ ((aligned(32))) struct complex16 rxdataF_comp[frame_parms->nb_antennas_rx][PSBCH_MAX_RE_PER_SYMBOL];
nr_psbch_channel_compensation(rxdataF_ext,
dl_ch_estimates_ext,
nb_re,
rxdataF_comp,
frame_parms,
log2_maxh); // log2_maxh+I0_shift
int nb = 198; // QPSK 2 bits 99*2 (m from TX side)
nr_psbch_quantize(psbch_e_rx + psbch_e_rx_idx, (short *)rxdataF_comp[0], nb);
memcpy(psbch_unClipped + psbch_e_rx_idx, rxdataF_comp[0], nb*sizeof(int16_t));
psbch_e_rx_idx += nb;
if (symbol == 0)
symbol += 4; // skip to accommodate PSS and SSS
}
// legacy code use int16, but it is complex16
UEscopeCopy(ue, psbchRxdataF_comp, psbch_unClipped, sizeof(struct complex16), frame_parms->nb_antennas_rx, psbch_e_rx_idx/2);
UEscopeCopy(ue, psbchLlr, psbch_e_rx, sizeof(int16_t), frame_parms->nb_antennas_rx, psbch_e_rx_idx);
#ifdef DEBUG_PSBCH
for (int cnt = 0; cnt < NR_POLAR_PSBCH_E; cnt++)
printf("psbch rx llr %d\n",*(psbch_e_rx + cnt));
#endif
//un-scrambling
uint16_t M = NR_POLAR_PSBCH_E;
uint8_t nushift = 0; //(Lmax==4)? i_ssb&3 : i_ssb&7;
uint32_t psbch_a_interleaved = 0;
uint32_t psbch_a_prime = 0;
nr_psbch_unscrambling(nr_ue_psbch_vars, psbch_e_rx, frame_parms->Nid_SL, nushift, M, NR_POLAR_PSBCH_E,
0, 0, psbch_a_prime, &psbch_a_interleaved);
//polar decoding de-rate matching
uint64_t tmp = 0;
uint32_t decoderState = polar_decoder_int16(psbch_e_rx, (uint64_t *)&tmp, 0,
NR_POLAR_PSBCH_MESSAGE_TYPE,
NR_POLAR_PSBCH_PAYLOAD_BITS,
NR_POLAR_PSBCH_AGGREGATION_LEVEL);
psbch_a_prime = tmp;
if(decoderState)
return(decoderState);
uint32_t payload = 0;
for (int i = 0; i < NR_POLAR_PSBCH_PAYLOAD_BITS; i++)
payload |= (((uint64_t)psbch_a_prime >> i) & 1) << (31 - i);
LOG_I(NR_PHY, "PSBCH payload received 0x%x \n", payload);
for (int i = 0; i < 4; i++)
result->decoded_output[i] = (uint8_t)((payload >> ((3 - i) << 3)) & 0xff);
frame_parms->half_frame_bit = (result->xtra_byte >> 4) & 0x01; // computing the half frame index from the extra byte
frame_parms->ssb_index = i_ssb; // ssb index corresponds to i_ssb for Lmax = 4,8
if (frame_parms->Lmax == 64) { // for Lmax = 64 ssb index 4th,5th and 6th bits are in extra byte
for (int i = 0; i < 3; i++)
frame_parms->ssb_index += (((result->xtra_byte >> (7 - i)) & 0x01) << (3 + i));
}
ue->symbol_offset = 0;
if (frame_parms->half_frame_bit)
ue->symbol_offset += (frame_parms->slots_per_frame>>1)*frame_parms->symbols_per_slot;
uint8_t frame_number_4lsb = 0;
for (int i = 0; i < 4; i++)
frame_number_4lsb |= ((result->xtra_byte >> i) & 1) << (3 - i);
proc->decoded_frame_rx = frame_number_4lsb;
#ifdef DEBUG_PSBCH
printf("xtra_byte %x payload %x\n", result->xtra_byte, payload);
for (int i=0; i<(NR_POLAR_PSBCH_PAYLOAD_BITS>>3); i++) {
// printf("unscrambling psbch_a[%d] = %x \n", i,psbch_a[i]);
printf("[PSBCH] decoder payload[%d] = %x\n",i,result->decoded_output[i]);
}
// TODO: Handle MAC Layer on RX
nr_downlink_indication_t dl_indication;
fapi_nr_rx_indication_t *rx_ind = calloc(1, sizeof(*rx_ind));
uint16_t number_pdus = 1;
nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id, phy_pdcch_config);
nr_fill_rx_indication(rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, gNB_id, ue, NULL, NULL, number_pdus, proc,(void *)result);
if (ue->if_inst && ue->if_inst->dl_indication)
ue->if_inst->dl_indication(&dl_indication, NULL);
else
free(rx_ind); // dl_indication would free(), so free() here if not called
#endif
return 0;
}

View File

@@ -41,6 +41,7 @@
#define NR_PUSCH_x 2 // UCI placeholder bit TS 38.212 V15.4.0 subclause 5.3.3.1
#define NR_PUSCH_y 3 // UCI placeholder bit
extern short nr_qpsk_mod_table[8];
// Functions below implement 36-211 and 36-212
/** @addtogroup _PHY_TRANSPORT_
@@ -280,6 +281,54 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
*/
int rx_sss(PHY_VARS_NR_UE *phy_vars_ue,int32_t *tot_metric,uint8_t *flip_max,uint8_t *phase_max);
/*!
\fn int nr_sl_generate_psbch_dmrs
\brief Generation of the DMRS for the PSBCH
@param
@returns 0 on success
*/
int nr_sl_generate_psbch_dmrs(uint32_t *gold_pbch_dmrs,
c16_t *txdataF,
int16_t amp,
uint8_t ssb_start_symbol,
NR_DL_FRAME_PARMS *frame_parms);
/*!
\fn int nr_generate_pss
\brief Generation of the NR PSS
@param
@returns 0 on success
*/
int nr_sl_generate_pss(c16_t *txdataF,
int16_t amp,
uint8_t ssb_start_symbol,
NR_DL_FRAME_PARMS *frame_parms);
/*!
\fn int nr_generate_sss
\brief Generation of the NR SSS
@param
@returns 0 on success
*/
int nr_sl_generate_sss(c16_t *txdataF,
int16_t amp,
uint8_t ssb_start_symbol,
NR_DL_FRAME_PARMS *frame_parms);
/*!
\fn int nr_generate_sl_pbch
\brief Generation of the PBCH
@param
@returns 0 on success
*/
int nr_generate_sl_psbch(PHY_VARS_NR_UE *ue,
c16_t *txdataF,
int16_t amp,
uint8_t ssb_start_symbol,
uint8_t n_hf,
int sfn,
NR_DL_FRAME_PARMS *frame_parms);
/*! \brief receiver for the PBCH
\returns number of tx antennas or -1 if error
*/
@@ -294,12 +343,34 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue,
fapiPbch_t* result,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
/*! \brief receiver for the PBCH
\returns number of tx antennas or -1 if error
*/
void nr_sl_common_signal_procedures(PHY_VARS_NR_UE *ue, int frame, int slot);
int nr_rx_psbch(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
const int estimateSz,
struct complex16 dl_ch_estimates[][estimateSz],
NR_UE_PSBCH *nr_ue_psbch_vars,
NR_DL_FRAME_PARMS *frame_parms,
uint8_t eNB_id,
uint8_t i_ssb,
MIMO_mode_t mimo_mode,
NR_UE_PDCCH_CONFIG *phy_pdcch_config,
fapiPsbch_t* result);
int nr_pbch_detection(UE_nr_rxtx_proc_t *proc,
PHY_VARS_NR_UE *ue,
int pbch_initial_symbol,
nr_phy_data_t *phy_data,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
int nr_psbch_detection(UE_nr_rxtx_proc_t *proc,
PHY_VARS_NR_UE *ue,
int psbch_initial_symbol,
NR_UE_PDCCH_CONFIG *phy_pdcch_config);
#ifndef modOrder
#define modOrder(I_MCS,I_TBS) ((I_MCS-I_TBS)*2+2) // Find modulation order from I_TBS and I_MCS
@@ -307,6 +378,10 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t *proc,
int dump_ue_stats(PHY_VARS_NR_UE *phy_vars_ue, UE_nr_rxtx_proc_t *proc, char* buffer, int length, runmode_t mode, int input_level_dBm);
int nr_sl_initial_sync(UE_nr_rxtx_proc_t *proc,
PHY_VARS_NR_UE *phy_vars_ue,
int n_frames);
/*!
\brief This function performs the initial cell search procedure - PSS detection, SSS detection and PBCH detection. At the
end, the basic frame parameters are known (Frame configuration - TDD/FDD and cyclic prefix length,
@@ -330,6 +405,13 @@ void nr_get_carrier_frequencies(PHY_VARS_NR_UE *ue,
uint64_t *dl_Carrier,
uint64_t *ul_Carrier);
/*!
\brief This function gets the carrier frequencies either from FP or command-line-set global variables, depending on the availability of the latter
@param fp Pointer to frame params
@param sl_Carrier Pointer to SL carrier to be set
*/
void nr_get_carrier_frequencies_sl(PHY_VARS_NR_UE *ue,
uint64_t *sl_Carrier);
/*!
\brief This function sets the OAI RF card rx/tx params
@param openair0_cfg Pointer OAI config for a specific card
@@ -347,6 +429,10 @@ void nr_rf_card_config_freq(openair0_config_t *openair0_cfg,
uint64_t dl_Carrier,
int freq_offset);
void nr_sl_rf_card_config_freq(PHY_VARS_NR_UE *ue,
openair0_config_t *openair0_cfg,
int freq_offset);
void nr_pdcch_unscrambling(int16_t *z,
uint16_t scrambling_RNTI,
uint32_t length,

View File

@@ -166,6 +166,17 @@ typedef struct {
uint8_t ptrs_symbol_index;
} NR_UE_DLSCH_t;
typedef struct {
long sl_numssb_withinperiod_r16;
long sl_timeoffsetssb_r16;
long sl_timeinterval_r16;
long sl_numssb_withinperiod_r16_copy;
long sl_timeinterval_r16_copy;
long sl_timeoffsetssb_r16_copy;
uint16_t slss_id;
uint8_t sl_mib_length;
uint8_t sl_mib[5];
} NR_SLSS_t;
/**@}*/
#endif

View File

@@ -46,6 +46,15 @@ void nr_get_carrier_frequencies(PHY_VARS_NR_UE *ue, uint64_t *dl_carrier, uint64
}
}
void nr_get_carrier_frequencies_sl(PHY_VARS_NR_UE *ue, uint64_t *sl_carrier) {
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
if (ue->if_freq!=0) {
*sl_carrier = ue->if_freq;
} else {
*sl_carrier = fp->sl_CarrierFreq;
}
}
void nr_rf_card_config_gain(openair0_config_t *openair0_cfg,
double rx_gain_off){
@@ -113,3 +122,17 @@ void nr_rf_card_config_freq(openair0_config_t *openair0_cfg,
}
}
void nr_sl_rf_card_config_freq(PHY_VARS_NR_UE *ue, openair0_config_t *openair0_cfg, int freq_offset) {
for (int i = 0; i < openair0_cfg->rx_num_channels; i++) {
openair0_cfg->rx_gain[ue->rf_map.chain + i] = ue->rx_total_gain_dB;
if (ue->UE_scan_carrier == 1) {
if (freq_offset >= 0)
openair0_cfg->rx_freq[ue->rf_map.chain + i] += abs(freq_offset);
else
openair0_cfg->rx_freq[ue->rf_map.chain + i] -= abs(freq_offset);
freq_offset=0;
}
}
}

View File

@@ -0,0 +1,254 @@
/*
* 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
*/
/*! \file PHY/NR_TRANSPORT/nr_psbch.c
* \brief Top-level routines for generating the PSBCH/BCH physical/transport channel V15.1 03/2018
* \author Guy De Souza
* \thanks Special Thanks to Son Dang for helpful contributions and testing
* \date 2018
* \version 0.1
* \company Eurecom
* \email: desouza@eurecom.fr
* \note
* \warning
*/
#include "PHY/defs_gNB.h"
#include "PHY/defs_nr_UE.h"
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/LTE_REFSIG/lte_refsig.h"
#include "PHY/sse_intrin.h"
#include "executables/softmodem-common.h"
//#define DEBUG_PSBCH
//#define DEBUG_PSBCH_ENCODING
//#define DEBUG_PSBCH_DMRS
extern short nr_qpsk_mod_table[8];
static void nr_psbch_scrambling(NR_UE_PSBCH *psbch,
uint32_t Nid,
uint8_t nushift,
uint16_t M,
uint16_t length,
uint8_t encoded,
uint32_t unscrambling_mask) {
uint32_t *psbch_e = psbch->psbch_e;
uint8_t reset = 1;
uint32_t x1, s = 0;
uint32_t x2 = Nid;
// The Gold sequence is shifted by nushift* M, so we skip (nushift*M /32) double words
for (int i = 0; i < (uint16_t)ceil(((float)M) / 32); i++) {
s = lte_gold_generic(&x1, &x2, reset);
reset = 0;
}
// Scrambling is now done with offset (nushift*M)%32
uint8_t offset = 0; //(nushift*M)&0x1f;
#ifdef DEBUG_PSBCH_ENCODING
printf("Scrambling params: nushift %d M %d length %d encoded %d offset %d\n", nushift, M, length, encoded, offset);
#endif
#ifdef DEBUG_PSBCH_ENCODING
printf("s: %04x\t", s);
#endif
int k = 0;
if (!encoded) {
/// 1st Scrambling
for (int i = 0; i < length; ++i) {
if ((unscrambling_mask>>i)&1)
psbch->psbch_a_prime ^= ((psbch->psbch_a_interleaved >> i) & 1) << i;
else {
if (((k + offset) & 0x1f) == 0) {
s = lte_gold_generic(&x1, &x2, reset);
reset = 0;
}
psbch->psbch_a_prime ^= (((psbch->psbch_a_interleaved >> i) & 1) ^ ((s >> ((k + offset) & 0x1f)) & 1)) << i;
k++; /// k increase only when payload bit is not special bit
}
}
} else {
/// 2nd Scrambling
for (int i = 0; i < length; ++i) {
if (((i + offset) & 0x1f) == 0) {
s = lte_gold_generic(&x1, &x2, reset);
reset = 0;
}
AssertFatal((i >> 5) < NR_POLAR_PSBCH_E_DWORD, "Invalid index into psbch->psbch_e. Index %d > %d\n",
(i >> 5), NR_POLAR_PSBCH_E_DWORD);
psbch_e[i >> 5] ^= (((s >> ((i + offset) & 0x1f)) & 1) << (i & 0x1f));
}
}
}
int nr_generate_sl_psbch(PHY_VARS_NR_UE *ue,
c16_t *txdataF,
int16_t amp,
uint8_t ssb_start_symbol,
uint8_t n_hf,
int sfn,
NR_DL_FRAME_PARMS *frame_parms) {
LOG_I(NR_PHY, "PSBCH SL generation started\n");
/* payload is 56 bits */
PSBCH_payload psbch_payload; // NR Side Link Payload for Rel 16
psbch_payload.coverageIndicator = 0; // 1 bit
psbch_payload.tddConfig = 0xFFF; // 12 bits for TDD configuration
psbch_payload.DFN = 0x3FF; // 10 bits for DFN
psbch_payload.slotIndex = 0x2A; // 7 bits for Slot Index //frame_parms->p_TDD_UL_DL_ConfigDedicated->slotIndex;
psbch_payload.reserved = 0; // 2 bits reserved
NR_UE_PSBCH m_psbch;
ue->psbch_vars[0] = &m_psbch;
NR_UE_PSBCH *psbch = ue->psbch_vars[0];
memset((void *)psbch, 0, sizeof(NR_UE_PSBCH));
psbch->psbch_a = *((uint32_t *)&psbch_payload);
psbch->psbch_a_interleaved = psbch->psbch_a; // skip interlevaing for Sidelink
psbch->psbch_a_prime = 0;
#ifdef DEBUG_PSBCH_ENCODING
printf("PSBCH payload = 0x%08x\n",psbch->psbch_a);
#endif
// Encoder reversal
uint64_t a_reversed = 0;
for (int i = 0; i < NR_POLAR_PSBCH_PAYLOAD_BITS; i++)
a_reversed |= (((uint64_t)psbch->psbch_a_interleaved >> i) & 1) << (31 - i);
/// CRC, coding and rate matching
polar_encoder_fast(&a_reversed, (void*)psbch->psbch_e, 0, 0,
NR_POLAR_PSBCH_MESSAGE_TYPE, NR_POLAR_PSBCH_PAYLOAD_BITS, NR_POLAR_PSBCH_AGGREGATION_LEVEL);
#ifdef DEBUG_PSBCH_ENCODING
printf("PSBCH SL generation started\n");
printf("Channel coding:\n");
for (int i=0; i<NR_POLAR_PSBCH_E_DWORD; i++)
printf("sl_psbch_e[%d]: 0x%08x\n", i, psbch->psbch_e[i]);
printf("\n");
#endif
/// Scrambling
uint16_t M = NR_POLAR_PSBCH_E;
uint8_t nushift = 0;
nr_psbch_scrambling(psbch, (uint32_t)frame_parms->Nid_SL, nushift, M, NR_POLAR_PSBCH_E, 1, 0);
#ifdef DEBUG_PSBCH_ENCODING
printf("Scrambling:\n");
for (int i=0; i<NR_POLAR_PSBCH_E_DWORD; i++) {
printf("sl_psbch_e[%d]: 0x%08x\n", i, psbch->psbch_e[i]);
}
printf("\n");
#endif
/// QPSK modulation
int16_t mod_psbch_e[NR_POLAR_PSBCH_E];
for (int i = 0; i < NR_POLAR_PSBCH_E >> 1; i++) {
AssertFatal(((i << 1) >> 5) < NR_POLAR_PSBCH_E_DWORD, "Invalid index into psbch->psbch_e. Index %d > %d\n",
((i << 1) >> 5), NR_POLAR_PSBCH_E_DWORD);
uint8_t idx = ((psbch->psbch_e[(i << 1) >> 5] >> ((i << 1) & 0x1f)) & 3);
AssertFatal(((idx << 1) + 1) < 8, "Invalid index into nr_qpsk_mod_table. Index %d > 8\n",
(idx << 1) + 1);
AssertFatal(((i << 1) + 1) < (sizeof(mod_psbch_e) / sizeof(mod_psbch_e[0])), "Invalid index into mod_psbch_e. Index %d > %lu\n",
(i << 1) + 1, sizeof(mod_psbch_e) / sizeof(mod_psbch_e[0]));
mod_psbch_e[i << 1] = nr_qpsk_mod_table[idx << 1];
mod_psbch_e[(i << 1) + 1] = nr_qpsk_mod_table[(idx << 1) + 1];
#ifdef DEBUG_PSBCH
printf("i %d idx %d mod_psbch %d %d\n", i, idx, mod_psbch_e[2*i], mod_psbch_e[2*i+1]);
#endif
}
/// Resource mapping
nushift = 0; //config->cell_config.phy_cell_id.value &3;
// PSBCH modulated symbols are mapped within the SSB block on symbols 1, 2, 3 excluding the subcarriers used for the PSBCH DMRS
///symbol 1 [0:132] -- 99 mod symbols
int k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier;
int l = ssb_start_symbol;
int m = 0;
for (int ssb_sc_idx = 0; ssb_sc_idx < NR_PSBCH_MAX_NB_CARRIERS; ssb_sc_idx++) {
if ((ssb_sc_idx & 3) == nushift) { //skip DMRS
k++;
continue;
} else {
#ifdef DEBUG_PSBCH
printf("m %d ssb_sc_idx %d at k %d of l %d\n", m, ssb_sc_idx, k, l);
#endif
AssertFatal(((m << 1) + 1) < (sizeof(mod_psbch_e) / sizeof(mod_psbch_e[0])), "Invalid index into mod_psbch_e. Index %d > %lu\n",
(m << 1) + 1, sizeof(mod_psbch_e) / sizeof(mod_psbch_e[0]));
int idx = (l * frame_parms->ofdm_symbol_size + k);
AssertFatal((idx + 1) < frame_parms->samples_per_frame_wCP, "txdataF index %d invalid!\n", idx + 1);
txdataF[idx].r = (amp * mod_psbch_e[m << 1]) >> 15;
txdataF[idx].i = (amp * mod_psbch_e[(m << 1) + 1]) >> 15;
k++;
m++;
}
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
}
int N_SSSB_Symb = 14;
///symbol 5 to N_SSSB_Symb [0:132] -- 99 mod symbols
l = ssb_start_symbol + 5;
AssertFatal(m == 99, "m does not equal 99");
m = 99;
while (l < N_SSSB_Symb - 1)
{
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier;
for (int ssb_sc_idx = 0; ssb_sc_idx < NR_PSBCH_MAX_NB_CARRIERS; ssb_sc_idx++) {
if ((ssb_sc_idx & 3) == nushift) { //skip DMRS
k++;
continue;
} else {
#ifdef DEBUG_PSBCH
printf("m %d ssb_sc_idx %d at k %d of l %d\n", m, ssb_sc_idx, k, l);
#endif
AssertFatal((m << 1) + 1 < (sizeof(mod_psbch_e) / sizeof(mod_psbch_e[0])),
"Indexing outside of mod_psbch_e bounds. %d > %lu",
(m << 1) + 1 , (sizeof(mod_psbch_e) / sizeof(mod_psbch_e[0])));
txdataF[(l * frame_parms->ofdm_symbol_size + k)].r = (amp * mod_psbch_e[m << 1]) >> 15;
txdataF[(l * frame_parms->ofdm_symbol_size + k)].i = (amp * mod_psbch_e[(m << 1) + 1]) >> 15;
k++;
m++;
}
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
}
l++;
}
#ifdef DEBUG_PSBCH
char buffer[frame_parms->ofdm_symbol_size];
for (int i = 0; i < 13; i++) {
if (i >= 1 && i <= 4)
continue;
bzero(buffer, sizeof(buffer));
LOG_I(NR_PHY, "PSBCH %d = %s\n", i, hexdump(&txdataF[frame_parms->ofdm_symbol_size*i],
frame_parms->ofdm_symbol_size, buffer, sizeof(buffer)));
}
#endif
return 0;
}

View File

@@ -64,69 +64,33 @@
*
*********************************************************************/
void generate_pss_nr(NR_DL_FRAME_PARMS *fp,int N_ID_2)
void generate_pss_nr(NR_DL_FRAME_PARMS *fp, int N_ID_2, int pss_seq_offset)
{
AssertFatal(fp->ofdm_symbol_size > 127,"Illegal ofdm_symbol_size %d\n",fp->ofdm_symbol_size);
AssertFatal(N_ID_2>=0 && N_ID_2 <=2,"Illegal N_ID_2 %d\n",N_ID_2);
int16_t d_pss[LENGTH_PSS_NR];
const int x_initial[INITIAL_PSS_NR] = {0, 1, 1, 0, 1, 1, 1};
int16_t x[LENGTH_PSS_NR];
int16_t *primary_synchro_time = primary_synchro_time_nr[N_ID_2];
unsigned int length = fp->ofdm_symbol_size;
unsigned int size = length * IQ_SIZE; /* i & q */
int16_t *primary_synchro = primary_synchro_nr[N_ID_2]; /* pss in complex with alternatively i then q */
int16_t *primary_synchro2 = primary_synchro_nr2[N_ID_2]; /* pss in complex with alternatively i then q */
#define INITIAL_PSS_NR (7)
const int x_initial[INITIAL_PSS_NR] = {0, 1, 1 , 0, 1, 1, 1};
assert(N_ID_2 < NUMBER_PSS_SEQUENCE);
assert(size <= SYNCF_TMP_SIZE);
assert(size <= SYNC_TMP_SIZE);
bzero(synchroF_tmp, size);
bzero(synchro_tmp, size);
for (int i=0; i < INITIAL_PSS_NR; i++) {
for (int i = 0; i < INITIAL_PSS_NR; i++)
x[i] = x_initial[i];
for (int i = 0; i < (LENGTH_PSS_NR - INITIAL_PSS_NR); i++)
x[i + INITIAL_PSS_NR] = (x[i + 4] + x[i]) % (2);
int16_t d_pss[LENGTH_PSS_NR];
for (int n = 0; n < LENGTH_PSS_NR; n++) {
int m = (n + 43 * N_ID_2) % (LENGTH_PSS_NR);
d_pss[n] = 1 - 2 * x[m];
}
for (int i=0; i < (LENGTH_PSS_NR - INITIAL_PSS_NR); i++) {
x[i+INITIAL_PSS_NR] = (x[i + 4] + x[i])%(2);
c16_t *primary_synchro = primary_synchro_nr[N_ID_2];
c16_t *primary_synchro2 = primary_synchro_nr2[N_ID_2];
for (int i = 0; i < LENGTH_PSS_NR; i++) {
primary_synchro[i].r = (d_pss[i] * SHRT_MAX) >> SCALING_PSS_NR;
primary_synchro[i].i = 0;
primary_synchro2[i].r = d_pss[i];
primary_synchro2[i].i = d_pss[i];
}
for (int n=0; n < LENGTH_PSS_NR; n++) {
int m = (n + 43*N_ID_2)%(LENGTH_PSS_NR);
d_pss[n] = 1 - 2*x[m];
}
/* PSS is directly mapped to subcarrier without modulation 38.211 */
for (int i=0; i < LENGTH_PSS_NR; i++) {
#if 1
primary_synchro[2*i] = (d_pss[i] * SHRT_MAX)>>SCALING_PSS_NR; /* Maximum value for type short int ie int16_t */
primary_synchro[2*i+1] = 0;
primary_synchro2[i] = d_pss[i];
#else
primary_synchro[2*i] = d_pss[i] * AMP;
primary_synchro[2*i+1] = 0;
primary_synchro2[i] = d_pss[i];
#endif
}
#ifdef DBG_PSS_NR
if (N_ID_2 == 0) {
char output_file[255];
char sequence_name[255];
sprintf(output_file, "pss_seq_%d_%u.m", N_ID_2, length);
sprintf(sequence_name, "pss_seq_%d_%u", N_ID_2, length);
printf("file %s sequence %s\n", output_file, sequence_name);
LOG_M(output_file, sequence_name, primary_synchro, LENGTH_PSS_NR, 1, 1);
}
#endif
/* call of IDFT should be done with ordered input as below
*
* n input samples
@@ -149,99 +113,27 @@ void generate_pss_nr(NR_DL_FRAME_PARMS *fp,int N_ID_2)
* sample 0 is for continuous frequency which is used here
*/
unsigned int k = fp->first_carrier_offset + fp->ssb_start_subcarrier + 56; //and
unsigned int subcarrier_start = get_softmodem_params()->sl_mode == 0 ? PSS_SSS_SUB_CARRIER_START : PSS_SSS_SUB_CARRIER_START_SL;
unsigned int k = fp->first_carrier_offset + fp->ssb_start_subcarrier + subcarrier_start;
if (k>= fp->ofdm_symbol_size) k-=fp->ofdm_symbol_size;
for (int i=0; i < LENGTH_PSS_NR; i++) {
synchroF_tmp[2*k] = primary_synchro[2*i];
synchroF_tmp[2*k+1] = primary_synchro[2*i+1];
LOG_I(NR_PHY,"generate_pss_nr: subcarrier_start %d, k %d\n",subcarrier_start,k);
c16_t in[sizeof(int16_t) * fp->ofdm_symbol_size] __attribute__((aligned(32)));
memset(in, 0, sizeof(in));
for (int i = 0; i < LENGTH_PSS_NR; i++) {
in[k]= primary_synchro[i];
k++;
if (k == length) k=0;
if (k == fp->ofdm_symbol_size) k = 0;
}
/* IFFT will give temporal signal of Pss */
idft((int16_t)get_idft(length),
synchroF_tmp, /* complex input */
synchro_tmp, /* complex output */
1); /* scaling factor */
/* then get final pss in time */
for (unsigned int i=0; i<length; i++) {
((int32_t *)primary_synchro_time)[i] = ((int32_t *)synchro_tmp)[i];
c16_t out[sizeof(int16_t) * fp->ofdm_symbol_size] __attribute__((aligned(32)));
memset(out, 0, sizeof(out));
memset(primary_synchro_time_nr[N_ID_2], 0, sizeof(int16_t) * fp->ofdm_symbol_size);
idft((int16_t)get_idft(fp->ofdm_symbol_size), (int16_t *)in, (int16_t *)out, 1);
for (unsigned int i = 0; i < fp->ofdm_symbol_size; i++) {
primary_synchro_time_nr[N_ID_2][i] = out[i];
}
#ifdef DBG_PSS_NR
if (N_ID_2 == 0) {
char output_file[255];
char sequence_name[255];
sprintf(output_file, "%s%d_%u%s","pss_seq_t_", N_ID_2, length, ".m");
sprintf(sequence_name, "%s%d_%u","pss_seq_t_", N_ID_2, length);
printf("file %s sequence %s\n", output_file, sequence_name);
LOG_M(output_file, sequence_name, primary_synchro_time, length, 1, 1);
sprintf(output_file, "%s%d_%u%s","pss_seq_f_", N_ID_2, length, ".m");
sprintf(sequence_name, "%s%d_%u","pss_seq_f_", N_ID_2, length);
LOG_M(output_file, sequence_name, synchroF_tmp, length, 1, 1);
}
#endif
#if 0
/* it allows checking that process of idft on a signal and then dft gives same signal with limited errors */
if ((N_ID_2 == 0) && (length == 256)) {
LOG_M("pss_f00.m","pss_f00",synchro_tmp,length,1,1);
bzero(synchroF_tmp, size);
/* get pss in the time domain by applying an inverse FFT */
dft((int16_t)get_dft(length),
synchro_tmp, /* complex input */
synchroF_tmp, /* complex output */
1); /* scaling factor */
if ((N_ID_2 == 0) && (length == 256)) {
LOG_M("pss_f_0.m","pss_f_0",synchroF_tmp,length,1,1);
}
/* check Pss */
k = length - (LENGTH_PSS_NR/2);
#define LIMIT_ERROR_FFT (10)
for (int i=0; i < LENGTH_PSS_NR; i++) {
if (abs(synchroF_tmp[2*k] - primary_synchro[2*i]) > LIMIT_ERROR_FFT) {
printf("Pss Error[%d] Compute %d Reference %d \n", k, synchroF_tmp[2*k], primary_synchro[2*i]);
}
if (abs(synchroF_tmp[2*k+1] - primary_synchro[2*i+1]) > LIMIT_ERROR_FFT) {
printf("Pss Error[%d] Compute %d Reference %d\n", (2*k+1), synchroF_tmp[2*k+1], primary_synchro[2*i+1]);
}
k++;
if (k >= length) {
k-=length;
}
}
}
#endif
}
/*******************************************************************
@@ -259,60 +151,47 @@ void generate_pss_nr(NR_DL_FRAME_PARMS *fp,int N_ID_2)
void init_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue)
{
int ofdm_symbol_size = frame_parms_ue->ofdm_symbol_size;
int sizePss = LENGTH_PSS_NR * IQ_SIZE; /* complex value i & q signed 16 bits */
int size = ofdm_symbol_size * IQ_SIZE; /* i and q samples signed 16 bits */
int16_t *p = NULL;
AssertFatal(ofdm_symbol_size > 127, "illegal ofdm_symbol_size %d\n",ofdm_symbol_size);
for (int i = 0; i < NUMBER_PSS_SEQUENCE; i++) {
p = malloc16(sizePss); /* pss in complex with alternatively i then q */
LOG_I(NR_PHY,"Calling init_context_pss_nr\n");
AssertFatal(frame_parms_ue->ofdm_symbol_size > 127, "illegal frame_parms_ue->ofdm_symbol_size %d\n",
frame_parms_ue->ofdm_symbol_size);
c16_t *p = NULL;
int pss_sequence = get_softmodem_params()->sl_mode == 0 ? NUMBER_PSS_SEQUENCE : NUMBER_PSS_SEQUENCE_SL;
c16_t txdataF[3*4096];
for (int i = 0; i < pss_sequence; i++) {
LOG_I(NR_PHY,"Initializing PSS %d\n",i);
p = malloc(LENGTH_PSS_NR * sizeof(c16_t));
if (p != NULL) {
primary_synchro_nr[i] = p;
bzero( primary_synchro_nr[i], sizePss);
}
else {
bzero(primary_synchro_nr[i], LENGTH_PSS_NR * sizeof(c16_t));
} else {
LOG_E(PHY,"Fatal memory allocation problem \n");
assert(0);
}
p = malloc(LENGTH_PSS_NR*2);
p = malloc(LENGTH_PSS_NR * sizeof(c16_t));
if (p != NULL) {
primary_synchro_nr2[i] = p;
bzero( primary_synchro_nr2[i],LENGTH_PSS_NR*2);
bzero(primary_synchro_nr2[i], LENGTH_PSS_NR * sizeof(c16_t));
} else {
LOG_E(PHY,"Fatal memory allocation problem \n");
assert(0);
}
p = malloc16(size);
p = malloc(sizeof(c16_t) * frame_parms_ue->ofdm_symbol_size);
if (p != NULL) {
primary_synchro_time_nr[i] = p;
bzero( primary_synchro_time_nr[i], size);
}
else {
bzero(primary_synchro_time_nr[i], sizeof(c16_t) * frame_parms_ue->ofdm_symbol_size);
} else {
LOG_E(PHY,"Fatal memory allocation problem \n");
assert(0);
}
generate_pss_nr(frame_parms_ue,i);
}
}
/*******************************************************************
*
* NAME : free_context_pss_nr
*
* PARAMETERS : none
*
* RETURN : none
*
* DESCRIPTION : free context related to pss
*
*********************************************************************/
void free_context_pss_nr(void)
{
for (int i = 0; i < NUMBER_PSS_SEQUENCE; i++) {
free_and_zero(primary_synchro_nr[i]);
free_and_zero(primary_synchro_nr2[i]);
free_and_zero(primary_synchro_time_nr[i]);
if (get_softmodem_params()->sl_mode==0 || get_softmodem_params()->sync_ref) generate_pss_nr(frame_parms_ue, i, pss_sequence);
else {
int tmp=frame_parms_ue->Nid_SL;
frame_parms_ue->Nid_SL = 336*i;
nr_sl_generate_pss(txdataF,AMP,0,frame_parms_ue);
frame_parms_ue->Nid_SL = tmp;
}
}
}
@@ -330,25 +209,7 @@ void free_context_pss_nr(void)
void init_context_synchro_nr(NR_DL_FRAME_PARMS *frame_parms_ue)
{
#ifndef STATIC_SYNC_BUFFER
/* initialise global buffers for synchronisation */
synchroF_tmp = malloc16(SYNCF_TMP_SIZE);
if (synchroF_tmp == NULL) {
LOG_E(PHY,"Fatal memory allocation problem \n");
assert(0);
}
synchro_tmp = malloc16(SYNC_TMP_SIZE);
if (synchro_tmp == NULL) {
LOG_E(PHY,"Fatal memory allocation problem \n");
assert(0);
}
#endif
init_context_pss_nr(frame_parms_ue);
init_context_sss_nr(AMP);
}
@@ -366,29 +227,11 @@ void init_context_synchro_nr(NR_DL_FRAME_PARMS *frame_parms_ue)
void free_context_synchro_nr(void)
{
#ifndef STATIC_SYNC_BUFFER
if (synchroF_tmp != NULL) {
free(synchroF_tmp);
synchroF_tmp = NULL;
for (int i = 0; i < NUMBER_PSS_SEQUENCE; i++) {
free_and_zero(primary_synchro_nr[i]);
free_and_zero(primary_synchro_nr2[i]);
free_and_zero(primary_synchro_time_nr[i]);
}
else {
LOG_E(PHY,"Fatal memory deallocation problem \n");
assert(0);
}
if (synchro_tmp != NULL) {
free(synchro_tmp);
synchro_tmp = NULL;
}
else {
LOG_E(PHY,"Fatal memory deallocation problem \n");
assert(0);
}
#endif
free_context_pss_nr();
}
/*******************************************************************
@@ -408,42 +251,10 @@ void set_frame_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue, int rate_change
/* set new value according to rate_change */
frame_parms_ue->ofdm_symbol_size = (frame_parms_ue->ofdm_symbol_size / rate_change);
frame_parms_ue->samples_per_subframe = (frame_parms_ue->samples_per_subframe / rate_change);
free_context_pss_nr();
/* pss reference have to be rebuild with new parameters ie ofdm symbol size */
init_context_synchro_nr(frame_parms_ue);
#ifdef SYNCHRO_DECIMAT
set_pss_nr(frame_parms_ue->ofdm_symbol_size);
#endif
init_context_pss_nr(frame_parms_ue);
init_context_sss_nr(AMP);
}
/*******************************************************************
*
* NAME : restore_frame_context_pss_nr
*
* PARAMETERS : configuration for UE and eNB with new FFT size
*
* RETURN : 0 if OK else error
*
* DESCRIPTION : initialisation of UE and eNode contexts
*
*********************************************************************/
void restore_frame_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue, int rate_change)
{
frame_parms_ue->ofdm_symbol_size = frame_parms_ue->ofdm_symbol_size * rate_change;
frame_parms_ue->samples_per_subframe = frame_parms_ue->samples_per_subframe * rate_change;
free_context_pss_nr();
/* pss reference have to be rebuild with new parameters ie ofdm symbol size */
init_context_synchro_nr(frame_parms_ue);
#ifdef SYNCHRO_DECIMAT
set_pss_nr(frame_parms_ue->ofdm_symbol_size);
#endif
}
/********************************************************************
*
@@ -555,9 +366,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int is, int rate_change)
#endif
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PSS_SEARCH_TIME_NR, VCD_FUNCTION_IN);
synchro_position = pss_search_time_nr(rxdata, PHY_vars_UE, fo_flag, is);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PSS_SEARCH_TIME_NR, VCD_FUNCTION_OUT);
#if TEST_SYNCHRO_TIMING_PSS
@@ -650,133 +459,109 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int is, int rate_change)
int pss_search_time_nr(c16_t **rxdata, PHY_VARS_NR_UE *ue, int fo_flag, int is)
{
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
int *eNB_id = (int *)&ue->common_vars.eNb_id;
int *f_off = (int *)&ue->common_vars.freq_offset;
unsigned int n, ar, peak_position, pss_source;
int64_t peak_value;
int64_t avg[NUMBER_PSS_SEQUENCE] = {0};
double ffo_est = 0;
unsigned int length = is == 0 ? frame_parms->samples_per_frame + (2 * frame_parms->ofdm_symbol_size) :
frame_parms->samples_per_frame;
AssertFatal(length > 0, "illegal length %d\n", length);
// performing the correlation on a frame length plus one symbol for the first of the two frame
// to take into account the possibility of PSS in between the two frames
unsigned int length;
if (is==0)
length = frame_parms->samples_per_frame + (2*frame_parms->ofdm_symbol_size);
else
length = frame_parms->samples_per_frame;
AssertFatal(length>0,"illegal length %d\n",length);
peak_value = 0;
peak_position = 0;
pss_source = 0;
int maxval=0;
for (int i=0;i<2*(frame_parms->ofdm_symbol_size);i++) {
maxval = max(maxval,primary_synchro_time_nr[0][i]);
maxval = max(maxval,-primary_synchro_time_nr[0][i]);
maxval = max(maxval,primary_synchro_time_nr[1][i]);
maxval = max(maxval,-primary_synchro_time_nr[1][i]);
maxval = max(maxval,primary_synchro_time_nr[2][i]);
maxval = max(maxval,-primary_synchro_time_nr[2][i]);
int maxval = 0;
for (int i = 0; i < frame_parms->ofdm_symbol_size; i++) {
maxval = max(maxval, primary_synchro_time_nr[0][i].r);
maxval = max(maxval, primary_synchro_time_nr[0][i].i);
maxval = max(maxval, -primary_synchro_time_nr[0][i].r);
maxval = max(maxval, -primary_synchro_time_nr[0][i].i);
maxval = max(maxval, primary_synchro_time_nr[1][i].r);
maxval = max(maxval, primary_synchro_time_nr[1][i].i);
maxval = max(maxval, -primary_synchro_time_nr[1][i].r);
maxval = max(maxval, -primary_synchro_time_nr[1][i].i);
if (get_softmodem_params()->sl_mode == 0) {
maxval = max(maxval, primary_synchro_time_nr[2][i].r);
maxval = max(maxval, primary_synchro_time_nr[2][i].i);
maxval = max(maxval, -primary_synchro_time_nr[2][i].r);
maxval = max(maxval, -primary_synchro_time_nr[2][i].i);
}
}
int shift = log2_approx(maxval);//*(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)*2);
int avg_size = get_softmodem_params()->sl_mode == 0 ? NUMBER_PSS_SEQUENCE : NUMBER_PSS_SEQUENCE_SL;
int64_t avg[avg_size];
bzero(avg, avg_size);
int shift = log2_approx(maxval);
int64_t peak_value = 0;
unsigned int peak_position = 0;
unsigned int pss_source = 0;
/* Search pss in the received buffer each 4 samples which ensures a memory alignment on 128 bits (32 bits x 4 ) */
/* This is required by SIMD (single instruction Multiple Data) Extensions of Intel processors. */
/* Correlation computation is based on a a dot product which is realized thank to SIMS extensions */
uint16_t pss_index_start = 0;
uint16_t pss_index_end = NUMBER_PSS_SEQUENCE;
uint16_t pss_index_end = get_softmodem_params()->sl_mode == 0 ? NUMBER_PSS_SEQUENCE : NUMBER_PSS_SEQUENCE_SL;
if (ue->target_Nid_cell != -1) {
pss_index_start = GET_NID2(ue->target_Nid_cell);
pss_index_end = pss_index_start + 1;
}
unsigned int step = get_softmodem_params()->sl_mode == 0 ? 8 : 4;
for (int pss_index = pss_index_start; pss_index < pss_index_end; pss_index++) {
for (n = 0; n < length; n += 8) { //
int64_t pss_corr_ue=0;
/* calculate dot product of primary_synchro_time_nr and rxdata[ar][n]
* (ar=0..nb_ant_rx) and store the sum in temp[n]; */
for (ar=0; ar<frame_parms->nb_antennas_rx; ar++) {
for (unsigned int n = 0; n < length; n += step) {
int64_t pss_corr_ue = 0;
for (unsigned int ar = 0; ar < frame_parms->nb_antennas_rx; ar++) {
/* perform correlation of rx data and pss sequence ie it is a dot product */
const c32_t result = dot_product((c16_t *)primary_synchro_time_nr[pss_index], &(rxdata[ar][n + is * frame_parms->samples_per_frame]), frame_parms->ofdm_symbol_size, shift);
const c32_t result = dot_product(primary_synchro_time_nr[pss_index],
&(rxdata[ar][n + is * frame_parms->samples_per_frame]),
frame_parms->ofdm_symbol_size,
shift);
const c64_t r64 = {.r = result.r, .i = result.i};
pss_corr_ue += squaredMod(r64);
//((short*)pss_corr_ue[pss_index])[2*n] += ((short*) &result)[0]; /* real part */
//((short*)pss_corr_ue[pss_index])[2*n+1] += ((short*) &result)[1]; /* imaginary part */
//((short*)&synchro_out)[0] += ((int*) &result)[0]; /* real part */
//((short*)&synchro_out)[1] += ((int*) &result)[1]; /* imaginary part */
if (get_softmodem_params()->sl_mode > 0) {
//non-coherentely combine repeition of PSS
const c32_t result = dot_product(primary_synchro_time_nr[pss_index],
&(rxdata[ar][n + is * frame_parms->samples_per_frame + frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples]),
frame_parms->ofdm_symbol_size,
shift);
const c64_t r64 = {.r = result.r, .i = result.i};
pss_corr_ue += squaredMod(r64);
}
}
/* calculate the absolute value of sync_corr[n] */
avg[pss_index]+=pss_corr_ue;
if (pss_corr_ue > peak_value) {
peak_value = pss_corr_ue;
peak_position = n;
pss_source = pss_index;
#ifdef DEBUG_PSS_NR
printf("pss_index %d: n %6u peak_value %15llu\n", pss_index, n, (unsigned long long)pss_corr_ue[n]);
#endif
}
}
}
if (fo_flag){
double ffo_est = 0;
if (fo_flag) {
// fractional frequency offset computation according to Cross-correlation Synchronization Algorithm Using PSS
// Shoujun Huang, Yongtao Su, Ying He and Shan Tang, "Joint time and frequency offset estimation in LTE downlink," 7th International Conference on Communications and Networking in China, 2012.
// Computing cross-correlation at peak on half the symbol size for first half of data
c32_t r1 = dot_product((c16_t *)primary_synchro_time_nr[pss_source], &(rxdata[0][peak_position + is * frame_parms->samples_per_frame]), frame_parms->ofdm_symbol_size >> 1, shift);
c32_t r1 = dot_product(primary_synchro_time_nr[pss_source],
&(rxdata[0][peak_position + is * frame_parms->samples_per_frame]),
frame_parms->ofdm_symbol_size >> 1,
shift);
// Computing cross-correlation at peak on half the symbol size for data shifted by half symbol size
// as it is real and complex it is necessary to shift by a value equal to symbol size to obtain such shift
c32_t r2 = dot_product((c16_t *)primary_synchro_time_nr[pss_source] + (frame_parms->ofdm_symbol_size >> 1),
c32_t r2 = dot_product(primary_synchro_time_nr[pss_source] + (frame_parms->ofdm_symbol_size >> 1),
&(rxdata[0][peak_position + is * frame_parms->samples_per_frame]) + (frame_parms->ofdm_symbol_size >> 1),
frame_parms->ofdm_symbol_size >> 1,
shift);
cd_t r1d = {r1.r, r1.i}, r2d = {r2.r, r2.i};
// estimation of fractional frequency offset: angle[(result1)'*(result2)]/pi
ffo_est = atan2(r1d.r * r2d.i - r2d.r * r1d.i, r1d.r * r2d.r + r1d.i * r2d.i) / M_PI;
#ifdef DBG_PSS_NR
printf("ffo %lf\n",ffo_est);
#endif
}
// computing absolute value of frequency offset
*f_off = ffo_est*frame_parms->subcarrier_spacing;
ue->common_vars.freq_offset = ffo_est * frame_parms->subcarrier_spacing;
int *id = get_softmodem_params()->sl_mode == 0 ? (int *)&ue->common_vars.eNb_id : (int *)&ue->common_vars.N2_id;
*id = pss_source;
for (int pss_index = pss_index_start; pss_index < pss_index_end; pss_index++)
avg[pss_index] /= (length / 4);
*eNB_id = pss_source;
LOG_I(NR_PHY, "[UE] nr_synchro_time: Sync source = %d, Peak found at pos %d, val = %llu (%d dB) avg %d dB, ffo %lf\n",
pss_source, peak_position, (unsigned long long)peak_value, dB_fixed64(peak_value), dB_fixed64(avg[pss_source]), ffo_est);
LOG_I(PHY,"[UE] nr_synchro_time: Sync source = %d, Peak found at pos %d, val = %llu (%d dB) avg %d dB, ffo %lf\n", pss_source, peak_position, (unsigned long long)peak_value, dB_fixed64(peak_value),dB_fixed64(avg[pss_source]),ffo_est);
if (peak_value < 5*avg[pss_source])
if (peak_value < 5 * avg[pss_source])
return(-1);
#ifdef DBG_PSS_NR
static int debug_cnt = 0;
if (debug_cnt == 0) {
if (is)
LOG_M("rxdata1.m","rxd0",rxdata[frame_parms->samples_per_frame],length,1,1);
else
LOG_M("rxdata0.m","rxd0",rxdata[0],length,1,1);
} else {
debug_cnt++;
}
#endif
return peak_position;
return(peak_position);
}

View File

@@ -0,0 +1,127 @@
/*
* 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 <stdio.h>
#include <assert.h>
#include <errno.h>
#include <math.h>
#include <nr-uesoftmodem.h>
#include "PHY/defs_nr_UE.h"
#include "PHY/phy_extern.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
#include "PHY/NR_REFSIG/ss_pbch_nr.h"
#include "openair1/PHY/NR_REFSIG/pss_nr.h"
int nr_sl_generate_pss(c16_t *txdataF,
int16_t amp,
uint8_t ssb_start_symbol,
NR_DL_FRAME_PARMS *frame_parms)
{
const int x_initial[INITIAL_PSS_NR] = {0, 1, 1, 0, 1, 1, 1};
int16_t x[LENGTH_PSS_NR];
for (int i = 0; i < INITIAL_PSS_NR; i++)
x[i] = x_initial[i];
for (int i = 0; i < (LENGTH_PSS_NR - INITIAL_PSS_NR); i++)
x[i + INITIAL_PSS_NR] = (x[i + 4] + x[i]) % (2);
#ifdef NR_PSS_DEBUG
write_output("d_pss.m", "d_pss", (void*)d_pss, NR_PSS_LENGTH, 1, 0);
printf("PSS: ofdm_symbol_size %d, first_carrier_offset %d\n",frame_parms->ofdm_symbol_size,frame_parms->first_carrier_offset);
#endif
/// Resource mapping
uint8_t Nid2 = frame_parms->Nid_SL / 336;
int16_t d_pss[LENGTH_PSS_NR];
c16_t *primary_synchro = primary_synchro_nr[Nid2];
c16_t *primary_synchro2 = primary_synchro_nr2[Nid2];
// PSS occupies a predefined position (subcarriers 2-128, symbol 0) within the SSB block starting from
int k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + PSS_SSS_SUB_CARRIER_START_SL;
if (k >= frame_parms->ofdm_symbol_size) k -= frame_parms->ofdm_symbol_size;
int l = ssb_start_symbol + 1;
for (int i = 0; i < NR_PSS_LENGTH; i++) {
int m = (i + 22 + 43 * Nid2) % (NR_PSS_LENGTH);
d_pss[i] = (1 - 2 * x[m]) * 23170;
txdataF[(l * frame_parms->ofdm_symbol_size + k)].r = (((int16_t)amp) * d_pss[i]) >> 15;
txdataF[(l * frame_parms->ofdm_symbol_size + k)].i = 0;
primary_synchro[i].r = (d_pss[i] * SHRT_MAX) >> SCALING_PSS_NR;
primary_synchro[i].i = 0;
primary_synchro2[i].r = d_pss[i];
primary_synchro2[i].i = d_pss[i];
k++;
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
}
// PSS occupies a predefined position (subcarriers 2-128, symbol 0) within the SSB block starting from
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + PSS_SSS_SUB_CARRIER_START_SL;
if (k >= frame_parms->ofdm_symbol_size) k-=frame_parms->ofdm_symbol_size;
l = ssb_start_symbol + 2;
for (int i = 0; i < NR_PSS_LENGTH; i++) {
int m = (i + 22 + 43 * Nid2) % (NR_PSS_LENGTH);
d_pss[i] = (1 - 2 * x[m]) * 23170;
// printf("pss: writing position k %d / %d\n",k,frame_parms->ofdm_symbol_size);
txdataF[(l * frame_parms->ofdm_symbol_size + k)].r = (((int16_t)amp) * d_pss[i]) >> 15;
txdataF[(l * frame_parms->ofdm_symbol_size + k)].i = 0;
k++;
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
}
#ifdef NR_PSS_DEBUG
LOG_M("pss_0.m", "pss_0",
(void*)&txdataF[0][ssb_start_symbol*frame_parms->ofdm_symbol_size],
frame_parms->ofdm_symbol_size, 1, 1);
char buffer[frame_parms->ofdm_symbol_size];
for (int i = 1; i < 3; i++) {
bzero(buffer, sizeof(buffer));
LOG_I(NR_PHY, "PSS %d = %s\n", i, hexdump(&txdataF[frame_parms->ofdm_symbol_size*i],
frame_parms->ofdm_symbol_size, buffer, sizeof(buffer)));
}
#endif
LOG_I(NR_PHY,"nr_sl_generate_pss : ssb_start_subcarrier %d, k %d\n",frame_parms->ssb_start_subcarrier,k);
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + PSS_SSS_SUB_CARRIER_START_SL;
if (k >= frame_parms->ofdm_symbol_size) k-=frame_parms->ofdm_symbol_size;
c16_t in[sizeof(int16_t) * frame_parms->ofdm_symbol_size] __attribute__((aligned(32)));
memset(in, 0, sizeof(in));
for (int i = 0; i < LENGTH_PSS_NR; i++) {
in[k]= primary_synchro[i];
k++;
if (k == frame_parms->ofdm_symbol_size) k = 0;
}
c16_t out[sizeof(int16_t) * frame_parms->ofdm_symbol_size] __attribute__((aligned(32)));
memset(out, 0, sizeof(out));
memset(primary_synchro_time_nr[Nid2], 0, sizeof(int16_t) * frame_parms->ofdm_symbol_size);
idft((int16_t)get_idft(frame_parms->ofdm_symbol_size), (int16_t *)in, (int16_t *)out, 1);
for (unsigned int i = 0; i < frame_parms->ofdm_symbol_size; i++) {
primary_synchro_time_nr[Nid2][i] = out[i];
}
return 0;
}

View File

@@ -36,7 +36,7 @@
#include "PHY/defs_nr_UE.h"
#include "PHY/MODULATION/modulation_UE.h"
#include "executables/softmodem-common.h"
#include "PHY/NR_REFSIG/ss_pbch_nr.h"
#define DEFINE_VARIABLES_SSS_NR_H
@@ -67,50 +67,32 @@ void init_context_sss_nr(int amp)
{
int16_t x0[LENGTH_SSS_NR];
int16_t x1[LENGTH_SSS_NR];
int16_t dss_current;
int m0, m1;
const int x0_initial[INITIAL_SSS_NR] = { 1, 0, 0, 0, 0, 0, 0 };
const int x1_initial[INITIAL_SSS_NR] = { 1, 0, 0, 0, 0, 0, 0 };
for (int i=0; i < INITIAL_SSS_NR; i++) {
for (int i = 0; i < INITIAL_SSS_NR; i++) {
x0[i] = x0_initial[i];
x1[i] = x1_initial[i];
}
for (int i=0; i < (LENGTH_SSS_NR - INITIAL_SSS_NR); i++) {
x0[i+7] = (x0[i + 4] + x0[i])%(2);
x1[i+7] = (x1[i + 1] + x1[i])%(2);
for (int i = 0; i < (LENGTH_SSS_NR - INITIAL_SSS_NR); i++) {
x0[i + 7] = (x0[i + 4] + x0[i]) % (2);
x1[i + 7] = (x1[i + 1] + x1[i]) % (2);
}
for (int N_ID_2 = 0; N_ID_2 < N_ID_2_NUMBER; N_ID_2++) {
int nid_2_num = get_softmodem_params()->sl_mode == 0 ? N_ID_2_NUMBER : N_ID_2_NUMBER_SL;
int dss_current;
int m0, m1;
for (int N_ID_2 = 0; N_ID_2 < nid_2_num; N_ID_2++) {
for (int N_ID_1 = 0; N_ID_1 < N_ID_1_NUMBER; N_ID_1++) {
m0 = 15*(N_ID_1/112) + (5*N_ID_2);
m1 = N_ID_1%112;
m0 = 15 * (N_ID_1 / 112) + (5 * N_ID_2);
m1 = N_ID_1 % 112;
for (int n = 0; n < LENGTH_SSS_NR; n++) {
dss_current = (1 - 2*x0[(n + m0)%(LENGTH_SSS_NR)])*(1 - 2*x1[(n + m1)%(LENGTH_SSS_NR)]);
dss_current = (1 - 2 * x0 [(n + m0) % (LENGTH_SSS_NR)]) * (1 - 2 * x1[(n + m1) % (LENGTH_SSS_NR)]);
/* Modulation of SSS is a BPSK TS 36.211 chapter 5.1.2 BPSK */
#if 1
d_sss[N_ID_2][N_ID_1][n] = dss_current;// * amp;
(void) amp;
#else
(void) amp;
d_sss[N_ID_2][N_ID_1][n] = (dss_current * SHRT_MAX)>>SCALING_PSS_NR;
#endif
d_sss[N_ID_2][N_ID_1][n] = dss_current;
}
}
}
#if 0
for (int i = 0; i < LENGTH_SSS_NR; i++) {
printf("sss ref[%i] : %d %d \n", i, d_sss[0][0][i], d_sss[0][0][i]);
}
#endif
}
/*******************************************************************
@@ -129,18 +111,10 @@ void init_context_sss_nr(int amp)
//#define DEBUG_SSS_NR
//#define DEBUG_PLOT_SSS
void insert_sss_nr(int16_t *sss_time,
void insert_sss_nr(c16_t *sss_time,
NR_DL_FRAME_PARMS *frame_parms)
{
unsigned int ofdm_symbol_size = frame_parms->ofdm_symbol_size;
unsigned int size = ofdm_symbol_size * IQ_SIZE; /* i & q */
assert(size <= SYNCF_TMP_SIZE);
assert(size <= SYNC_TMP_SIZE);
bzero(synchroF_tmp, size);
bzero(synchro_tmp, size);
int Nid2 = GET_NID2(frame_parms->Nid_cell);
int Nid1 = GET_NID1(frame_parms->Nid_cell);
@@ -169,12 +143,12 @@ void insert_sss_nr(int16_t *sss_time,
unsigned int k = ofdm_symbol_size - ((LENGTH_SSS_NR/2)+1);
/* SSS is directly mapped to subcarrier */
for (int i=0; i<LENGTH_SSS_NR; i++) {
synchroF_tmp[2*k] = d_sss[Nid2][Nid1][i];
synchroF_tmp[2*k+1] = 0;
c16_t in[sizeof(int16_t) * ofdm_symbol_size] __attribute__((aligned(32)));
memset(in, 0, sizeof(in));
for (int i = 0; i < LENGTH_SSS_NR; i++) {
in[i].r = d_sss[Nid2][Nid1][i];
in[i].i = 0;
k++;
if (k >= ofdm_symbol_size) {
k++;
k-=ofdm_symbol_size;
@@ -182,13 +156,12 @@ void insert_sss_nr(int16_t *sss_time,
}
/* get sss in the frequency domain by applying an inverse FFT */
idft(IDFT_2048,synchroF_tmp, /* complex input */
synchro_tmp, /* complex output */
1); /* scaling factor */
/* then get final sss in time */
for (unsigned int i=0; i<ofdm_symbol_size; i++) {
((int32_t *)sss_time)[i] = ((int32_t *)synchro_tmp)[i];
c16_t out[sizeof(int16_t) * ofdm_symbol_size] __attribute__((aligned(32)));
memset(out, 0, sizeof(out));
memset(sss_time, 0, sizeof(int16_t) * ofdm_symbol_size);
idft(IDFT_2048, (int16_t *)&in, (int16_t *)&out, 1);
for (unsigned int i = 0; i < ofdm_symbol_size; i++) {
sss_time[i] = out[i];
}
}
@@ -205,99 +178,35 @@ void insert_sss_nr(int16_t *sss_time,
*********************************************************************/
int pss_ch_est_nr(PHY_VARS_NR_UE *ue,
int32_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR],
int32_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR])
c16_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR],
c16_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR])
{
int16_t *pss;
int16_t *pss_ext2,*sss_ext2,*sss_ext3,tmp_re,tmp_im,tmp_re2,tmp_im2;
uint8_t aarx,i;
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
pss = primary_synchro_nr2[ue->common_vars.eNb_id];
sss_ext3 = (int16_t*)&sss_ext[0][0];
#if 0
int16_t chest[2*LENGTH_PSS_NR];
#endif
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
sss_ext2 = (int16_t*)&sss_ext[aarx][0];
pss_ext2 = (int16_t*)&pss_ext[aarx][0];
#if 0
int16_t *p = pss;
for (int i = 0; i < LENGTH_PSS_NR; i++) {
printf(" pss ref [%d] %d %d at address %p\n", i, p[2*i], p[2*i+1], &p[2*i]);
printf(" pss ext [%d] %d %d at address %p\n", i, pss_ext2[2*i], pss_ext2[2*i+1], &pss_ext2[2*i]);
}
#endif
#if 0
for (int i = 0; i < LENGTH_PSS_NR; i++) {
printf(" sss ext 2 [%d] %d %d at address %p\n", i, sss_ext2[2*i], sss_ext2[2*i+1], &sss_ext2[2*i]);
printf(" sss ref [%d] %d %d at address %p\n", i, d_sss[0][0][i], d_sss[0][0][i], &d_sss[0][0][i]);
}
#endif
int32_t amp;
int shift;
for (i = 0; i < LENGTH_PSS_NR; i++) {
// This is H*(PSS) = R* \cdot PSS
tmp_re = pss_ext2[i*2] * pss[i];
tmp_im = -pss_ext2[i*2+1] * pss[i];
amp = (((int32_t)tmp_re)*tmp_re) + ((int32_t)tmp_im)*tmp_im;
shift = log2_approx(amp)/2;
#if 0
printf("H*(%d,%d) : (%d,%d)\n",aarx,i,tmp_re,tmp_im);
printf("pss(%d,%d) : (%d,%d)\n",aarx,i,pss[2*i],pss[2*i+1]);
printf("pss_ext(%d,%d) : (%d,%d)\n",aarx,i,pss_ext2[2*i],pss_ext2[2*i+1]);
if (aarx==0) {
chest[i<<1]=tmp_re;
chest[1+(i<<1)]=tmp_im;
}
#endif
// This is R(SSS) \cdot H*(PSS)
tmp_re2 = (int16_t)(((tmp_re * (int32_t)sss_ext2[i*2])>>shift) - ((tmp_im * (int32_t)sss_ext2[i*2+1]>>shift)));
tmp_im2 = (int16_t)(((tmp_re * (int32_t)sss_ext2[i*2+1])>>shift) + ((tmp_im * (int32_t)sss_ext2[i*2]>>shift)));
// printf("SSSi(%d,%d) : (%d,%d)\n",aarx,i,sss_ext2[i<<1],sss_ext2[1+(i<<1)]);
// printf("SSSo(%d,%d) : (%d,%d)\n",aarx,i,tmp_re2,tmp_im2);
// MRC on RX antennas
if (aarx==0) {
sss_ext3[i<<1] = tmp_re2;
sss_ext3[1+(i<<1)] = tmp_im2;
int id = get_softmodem_params()->sl_mode == 0 ? ue->common_vars.eNb_id : ue->common_vars.N2_id;
c16_t *pss = primary_synchro_nr2[id];
c16_t tmp, tmp2;
c16_t *sss_ext3 = &sss_ext[0][0];
for (uint8_t aarx = 0; aarx < ue->frame_parms.nb_antennas_rx; aarx++) {
c16_t *sss_ext2 = &sss_ext[aarx][0];
c16_t *pss_ext2 = &pss_ext[aarx][0];
int32_t amp;
int shift;
for (uint8_t i = 0; i < LENGTH_PSS_NR; i++) {
tmp.r = pss_ext2[i].r * pss[i].r;
tmp.i = -pss_ext2[i].i * pss[i].i;
amp = (((int32_t)tmp.r) * tmp.r) + ((int32_t)tmp.i) * tmp.i;
shift = log2_approx(amp) / 2;
tmp2.r = (int16_t)(((tmp.r * (int32_t)sss_ext2[i].r) >> shift) - ((tmp.i * (int32_t)sss_ext2[i].i >> shift)));
tmp2.i = (int16_t)(((tmp.r * (int32_t)sss_ext2[i].i) >> shift) + ((tmp.i * (int32_t)sss_ext2[i].r >> shift)));
if (aarx == 0) {
sss_ext3[i].r = tmp2.r;
sss_ext3[i].i = tmp2.i;
} else {
sss_ext3[i<<1] += tmp_re2;
sss_ext3[1+(i<<1)] += tmp_im2;
sss_ext3[i].r += tmp2.r;
sss_ext3[i].i += tmp2.i;
}
}
}
#if 0
LOG_M("pssrx.m","pssrx",pss,LENGTH_PSS_NR,1,1);
LOG_M("pss_ext.m","pssext",pss_ext2,LENGTH_PSS_NR,1,1);
LOG_M("psschest.m","pssch",chest,LENGTH_PSS_NR,1,1);
#endif
#if 0
for (int i = 0; i < LENGTH_PSS_NR; i++) {
printf(" sss ext 2 [%d] %d %d at address %p\n", i, sss_ext2[2*i], sss_ext2[2*i+1]);
printf(" sss ref [%d] %d %d at address %p\n", i, d_sss[0][0][i], d_sss[0][0][i]);
printf(" sss ext 3 [%d] %d %d at address %p\n", i, sss_ext3[2*i], sss_ext3[2*i+1]);
}
#endif
// sss_ext now contains the compensated SSS
return(0);
}
@@ -315,97 +224,49 @@ int pss_ch_est_nr(PHY_VARS_NR_UE *ue,
int do_pss_sss_extract_nr(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
int32_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR],
int32_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR],
c16_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR],
c16_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR],
uint8_t doPss, uint8_t doSss,
uint8_t subframe,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) // add flag to indicate extracting only PSS, only SSS, or both
{
uint8_t aarx;
int32_t *pss_rxF,*pss_rxF_ext;
int32_t *sss_rxF,*sss_rxF_ext;
uint8_t pss_symbol, sss_symbol;
c16_t *pss_rxF,*pss_rxF_ext;
c16_t *sss_rxF,*sss_rxF_ext;
uint8_t pss_symbol = 0;
uint8_t sss_symbol = get_softmodem_params()->sl_mode == 0 ?
(SSS_SYMBOL_NB - PSS_SYMBOL_NB) :
(SSS0_SL_SYMBOL_NB - PSS0_SL_SYMBOL_NB) ;
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
pss_symbol = 0;
sss_symbol = SSS_SYMBOL_NB-PSS_SYMBOL_NB;
unsigned int ofdm_symbol_size = frame_parms->ofdm_symbol_size;
pss_rxF = (int32_t *)&rxdataF[aarx][pss_symbol*ofdm_symbol_size];
sss_rxF = (int32_t *)&rxdataF[aarx][sss_symbol*ofdm_symbol_size];
pss_rxF = &rxdataF[aarx][pss_symbol * frame_parms->ofdm_symbol_size];
sss_rxF = &rxdataF[aarx][sss_symbol * frame_parms->ofdm_symbol_size];
pss_rxF_ext = &pss_ext[aarx][0];
sss_rxF_ext = &sss_ext[aarx][0];
unsigned int k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + 56;
unsigned int k = frame_parms->first_carrier_offset +
frame_parms->ssb_start_subcarrier +
((get_softmodem_params()->sl_mode == 0) ?
PSS_SSS_SUB_CARRIER_START :
PSS_SSS_SUB_CARRIER_START_SL);
if (k>= frame_parms->ofdm_symbol_size) k-=frame_parms->ofdm_symbol_size;
for (int i=0; i < LENGTH_PSS_NR; i++) {
if (doPss) {
if (doPss) {
pss_rxF_ext[i] = pss_rxF[k];
}
if (doSss) {
sss_rxF_ext[i] = sss_rxF[k];
}
k++;
if (k == ofdm_symbol_size) k=0;
if (k == frame_parms->ofdm_symbol_size) k = 0;
}
}
#if 0
int16_t *p = (int16_t *)sss_rxF_ext;
for (int i = 0; i < LENGTH_PSS_NR; i++) {
printf(" sss ext 2 [%d] %d %d at address %p\n", i, p[2*i], p[2*i+1], &p[2*i]);
printf(" sss ref [%d] %d %d at address %p\n", i, d_sss[0][0][i], d_sss[0][0][i], &d_sss[0][0][i]);
}
#endif
#if 0
int16_t *p2 = (int16_t *)pss_rxF_ext;
for (int i = 0; i < LENGTH_PSS_NR; i++) {
printf(" pss_rxF_ext [%d] %d %d at address %p\n", i, p2[2*i], p2[2*i+1], &p2[2*i]);
}
#endif
return(0);
}
/*******************************************************************
*
* NAME : pss_sss_extract_nr
*
* PARAMETERS : none
*
* RETURN : none
*
* DESCRIPTION :
*
*********************************************************************/
int pss_sss_extract_nr(PHY_VARS_NR_UE *phy_vars_ue,
UE_nr_rxtx_proc_t *proc,
int32_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR],
int32_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR],
uint8_t subframe,
c16_t rxdataF[][phy_vars_ue->frame_parms.samples_per_slot_wCP])
{
return do_pss_sss_extract_nr(phy_vars_ue, proc, pss_ext, sss_ext, 1 /* doPss */, 1 /* doSss */, subframe, rxdataF);
}
/*******************************************************************
*
* NAME : rx_sss_nr
@@ -419,170 +280,63 @@ int pss_sss_extract_nr(PHY_VARS_NR_UE *phy_vars_ue,
*
*********************************************************************/
int rx_sss_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int32_t *tot_metric, uint8_t *phase_max, int *freq_offset_sss, c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
int rx_sss_nr(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
int32_t *tot_metric,
uint8_t *phase_max,
int *freq_offset_sss,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
{
uint8_t i;
int32_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR];
int32_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR];
uint8_t Nid2 = GET_NID2(ue->common_vars.eNb_id);
uint16_t Nid1;
uint8_t phase;
int16_t *sss;
NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
int32_t metric, metric_re;
int16_t *d;
c16_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR];
c16_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR];
do_pss_sss_extract_nr(ue, proc, pss_ext, sss_ext, 1 /* doPss */, 1 /* doSss */, 0 /* subframe */, rxdataF);
pss_ch_est_nr(ue, pss_ext, sss_ext);
// pss sss extraction
pss_sss_extract_nr(ue,
proc,
pss_ext,
sss_ext,
0,
rxdataF); /* subframe */
#ifdef DEBUG_PLOT_SSS
write_output("rxsig0.m","rxs0",&ue->common_vars.rxdata[0][0],ue->frame_parms.samples_per_subframe,1,1);
write_output("rxdataF0_pss.m","rxF0_pss",&ue->common_vars.rxdataF[0][0],frame_parms->ofdm_symbol_size,1,1);
write_output("rxdataF0_sss.m","rxF0_sss",&ue->common_vars.rxdataF[0][(SSS_SYMBOL_NB-PSS_SYMBOL_NB)*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1);
write_output("pss_ext.m","pss_ext",pss_ext,LENGTH_PSS_NR,1,1);
#endif
#if 0
int16_t *p = (int16_t *)sss_ext[0];
int16_t *p2 = (int16_t *)pss_ext[0];
for (int i = 0; i < LENGTH_SSS_NR; i++) {
printf("sss ref [%i] : %d %d \n", i, d_sss[0][0][i], d_sss[0][0][i]);
printf("sss ext [%i] : %d %d \n", i, p[2*i], p[2*i+1]);
printf("pss ref [%i] : %d %d \n", i, primary_synchro_nr2[0][2*i], primary_synchro_nr2[0][2*i+1]);
printf("pss ext [%i] : %d %d \n", i, p2[2*i], p2[2*i+1]);
}
#endif
// get conjugated channel estimate from PSS, H* = R* \cdot PSS
// and do channel estimation and compensation based on PSS
pss_ch_est_nr(ue,
pss_ext,
sss_ext);
// now do the SSS detection based on the precomputed sequences in PHY/LTE_TRANSPORT/sss.h
*tot_metric = INT_MIN;
sss = (int16_t*)&sss_ext[0][0];
#ifdef DEBUG_PLOT_SSS
write_output("sss_ext.m","sss_ext",sss_ext[0],LENGTH_SSS_NR,1,1);
write_output("sss_ref.m","sss_ref", d_sss,LENGTH_SSS_NR,1,1);
#endif
#if 0
/* simulate of a phase shift on the signal */
int phase_shift_index = 0;
phase_shift_samples(sss, LENGTH_SSS_NR, phase_re_nr[phase_shift_index], phase_im_nr[phase_shift_index]);
#endif
#if 0
int16_t *ps = (int16_t *)pss_ext;
for (int i = 0; i < LENGTH_SSS_NR; i++) {
printf("sss ref [%i] : %d \n", i, d_sss[0][0][i]);
printf("sss ext [%i] : %d %d \n", i, sss[2*i], sss[2*i+1]);
printf("pss ref [%i] : %d %d \n", i, primary_synchro_nr2[0][2*i], primary_synchro_nr2[0][2*i+1]);
printf("pss ext [%i] : %d %d \n", i, ps[2*i], ps[2*i+1]);
}
#endif
/* for phase evaluation, one uses an array of possible phase shifts */
/* then a correlation is done between received signal with a shift pĥase and the reference signal */
/* Computation of signal with shift phase is based on below formula */
/* cosinus cos(x + y) = cos(x)cos(y) - sin(x)sin(y) */
/* sinus sin(x + y) = sin(x)cos(y) + cos(x)sin(y) */
uint16_t Nid1_start = 0;
uint16_t Nid1_end = N_ID_1_NUMBER;
if (ue->target_Nid_cell != -1) {
Nid1_start = GET_NID1(ue->target_Nid_cell);
Nid1_end = Nid1_start + 1;
}
for (Nid1 = Nid1_start; Nid1 < Nid1_end; Nid1++) { // all possible Nid1 values
for (phase = 0; phase < PHASE_HYPOTHESIS_NUMBER; phase++) { // phase offset between PSS and SSS
metric = 0;
metric_re = 0;
c16_t *sss = &sss_ext[0][0];
uint16_t Nid1;
uint8_t Nid2 = get_softmodem_params()->sl_mode == 0 ? ue->common_vars.eNb_id : ue->common_vars.N2_id;
int16_t *d;
for (Nid1 = 0; Nid1 < N_ID_1_NUMBER; Nid1++) {
for (uint8_t phase = 0; phase < PHASE_HYPOTHESIS_NUMBER; phase++) {
int32_t metric = 0;
int32_t metric_re = 0;
d = (int16_t *)&d_sss[Nid2][Nid1];
// This is the inner product using one particular value of each unknown parameter
for (i=0; i < LENGTH_SSS_NR; i++) {
metric_re += d[i]*(((phase_re_nr[phase]*sss[2*i])>>SCALING_METRIC_SSS_NR) - ((phase_im_nr[phase]*sss[2*i+1])>>SCALING_METRIC_SSS_NR));
#if 0
printf("i %d, phase %d/%d: metric %d, phase (%d,%d) sss (%d,%d) d %d\n",i,phase,PHASE_HYPOTHESIS_NUMBER,metric_re,phase_re_nr[phase],phase_im_nr[phase],sss[2*i],sss[1+(2*i)],d[i]);
#endif
for (uint8_t i = 0; i < LENGTH_SSS_NR; i++) {
metric_re += d[i] * (((phase_re_nr[phase] * sss[i].r) >> SCALING_METRIC_SSS_NR) - ((phase_im_nr[phase] * sss[i].i) >> SCALING_METRIC_SSS_NR));
}
metric = metric_re;
// if the current metric is better than the last save it
if (metric > *tot_metric) {
*tot_metric = metric;
ue->frame_parms.Nid_cell = Nid2+(3*Nid1);
*phase_max = phase;
#ifdef DEBUG_SSS_NR
LOG_D(PHY,"(phase,Nid1) (%d,%d), metric_phase %d tot_metric %d, phase_max %d \n",phase, Nid1, metric, *tot_metric, *phase_max);
#endif
}
}
}
//#ifdef DEBUG_SSS_NR
#define SSS_METRIC_FLOOR_NR (30000)
if (*tot_metric > SSS_METRIC_FLOOR_NR) {
Nid2 = GET_NID2(frame_parms->Nid_cell);
Nid1 = GET_NID1(frame_parms->Nid_cell);
LOG_D(PHY,"Nid2 %d Nid1 %d tot_metric %d, phase_max %d \n", Nid2, Nid1, *tot_metric, *phase_max);
if (*tot_metric > SSS_METRIC_FLOOR_NR) {
Nid2 = GET_NID2(ue->frame_parms.Nid_cell);
Nid1 = GET_NID1(ue->frame_parms.Nid_cell);
LOG_I(NR_PHY,"Nid2 %d Nid1 %d tot_metric %d, phase_max %d \n", Nid2, Nid1, *tot_metric, *phase_max);
}
//#endif
if (Nid1==N_ID_1_NUMBER)
if (Nid1 == N_ID_1_NUMBER) {
LOG_I(NR_PHY,"Failed to detect SSS after PSS\n");
return -1;
}
int re = 0;
int im = 0;
if (Nid1 == N_ID_1_NUMBER) {
LOG_I(PHY,"Failed to detect SSS after PSS\n");
return -1;
for(int i = 0; i < LENGTH_SSS_NR; i++) {
re += d[i] * sss[i].r;
im += d[i] * sss[i].i;
}
d = (int16_t *)&d_sss[Nid2][Nid1];
for(i = 0; i<LENGTH_SSS_NR; i++) {
re += d[i]*sss[2*i];
im += d[i]*sss[2*i+1];
}
double ffo_sss = atan2(im,re)/M_PI/4.3;
*freq_offset_sss = (int)(ffo_sss*frame_parms->subcarrier_spacing);
double ffo_pss = ((double)ue->common_vars.freq_offset)/frame_parms->subcarrier_spacing;
double ffo_sss = atan2(im,re)/M_PI/4.3;
*freq_offset_sss = (int)(ffo_sss * ue->frame_parms.subcarrier_spacing);
double ffo_pss = ((double)ue->common_vars.freq_offset)/ue->frame_parms.subcarrier_spacing;
LOG_I(NR_PHY, "ffo_pss %f (%i Hz), ffo_sss %f (%i Hz), ffo_pss+ffo_sss %f (%i Hz)\n",
ffo_pss, (int)(ffo_pss*frame_parms->subcarrier_spacing), ffo_sss, *freq_offset_sss, ffo_pss+ffo_sss, (int)((ffo_pss+ffo_sss)*frame_parms->subcarrier_spacing));
ffo_pss, (int)(ffo_pss*ue->frame_parms.subcarrier_spacing), ffo_sss, *freq_offset_sss, ffo_pss+ffo_sss, (int)((ffo_pss+ffo_sss)*ue->frame_parms.subcarrier_spacing));
return(0);
}

View File

@@ -0,0 +1,357 @@
/*
* 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 <stdio.h>
#include <assert.h>
#include <errno.h>
#include <math.h>
#include <nr-uesoftmodem.h>
#include "PHY/defs_nr_UE.h"
#include "PHY/phy_extern.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
#include "PHY/NR_REFSIG/ss_pbch_nr.h"
#include "PHY/NR_REFSIG/sss_nr.h"
//#define DEBUG_PLOT_SSS 1
int nr_sl_generate_sss(c16_t *txdataF,
int16_t amp,
uint8_t ssb_start_symbol,
NR_DL_FRAME_PARMS *frame_parms)
{
int16_t x0[NR_SSS_LENGTH];
int16_t x1[NR_SSS_LENGTH];
const int x0_initial[7] = { 1, 0, 0, 0, 0, 0, 0 };
const int x1_initial[7] = { 1, 0, 0, 0, 0, 0, 0 };
/// Sequence generation
int Nid = frame_parms->Nid_SL;
int Nid1 = GET_NID1_SL(Nid);
int Nid2 = GET_NID2_SL(Nid);
for (int i=0; i < 7; i++) {
x0[i] = x0_initial[i];
x1[i] = x1_initial[i];
}
for (int i=0; i < NR_SSS_LENGTH - 7; i++) {
x0[i+7] = (x0[i + 4] + x0[i]) % 2;
x1[i+7] = (x1[i + 1] + x1[i]) % 2;
}
int m0 = 15 * (Nid1 / 112) + (5 * Nid2);
int m1 = Nid1 % 112;
#ifdef NR_SSS_DEBUG
write_output("d_sss.m", "d_sss", (void*)d_sss, NR_SSS_LENGTH, 1, 1);
#endif
/// Resource mapping
// SSS occupies a predefined position (subcarriers 2-129, symbol 3) within the SSB block starting from
int k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + PSS_SSS_SUB_CARRIER_START_SL;
int l = ssb_start_symbol + 3;
for (int i = 0; i < NR_SSS_LENGTH; i++) {
int16_t dss_current = (1 - 2 * x0[(i + m0) % NR_SSS_LENGTH] ) * (1 - 2 * x1[(i + m1) % NR_SSS_LENGTH] ) * 23170;
d_sss[Nid2][Nid1][i] = dss_current;
txdataF[(l * frame_parms->ofdm_symbol_size + k)].r = (((int16_t)amp) * dss_current) >> 15;
txdataF[(l * frame_parms->ofdm_symbol_size + k)].i = 0;
k++;
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
}
// SSS occupies a predefined position (subcarriers 2 to 129, symbol 4) within the SSB block starting from
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + PSS_SSS_SUB_CARRIER_START_SL;
l = ssb_start_symbol + 4;
for (int i = 0; i < NR_SSS_LENGTH; i++) {
int16_t dss_current = (1 - 2 * x0[(i + m0) % NR_SSS_LENGTH]) * (1 - 2 * x1[(i + m1) % NR_SSS_LENGTH] ) * 23170;
d_sss[Nid2][Nid1][i] = dss_current;
txdataF[(l*frame_parms->ofdm_symbol_size + k)].r = (((int16_t)amp) * dss_current) >> 15;
txdataF[(l*frame_parms->ofdm_symbol_size + k)].i = 0;
k++;
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
}
#ifdef NR_SSS_DEBUG
// write_output("sss_0.m", "sss_0", (void*)txdataF[0][l*frame_parms->ofdm_symbol_size], frame_parms->ofdm_symbol_size, 1, 1);
char buffer[frame_parms->ofdm_symbol_size];
for (int i = 3; i < 5; i++) {
bzero(buffer, sizeof(buffer));
LOG_I(NR_PHY, "SSS %d = %s\n", i, hexdump(&txdataF[frame_parms->ofdm_symbol_size*i],
frame_parms->ofdm_symbol_size, buffer, sizeof(buffer)));
}
#endif
return 0;
}
/*******************************************************************
*
* NAME : pss_sss_sl_extract_nr
*
* PARAMETERS : none
*
* RETURN : none
*
* DESCRIPTION :
*
*********************************************************************/
static int pss_sss_sl_extract_nr(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
c16_t pss0_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR],
c16_t sss0_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR],
c16_t pss1_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR],
c16_t sss1_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR])
{
c16_t **rxdataF = ue->common_vars.rxdataF;
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
unsigned int ofdm_symbol_size = frame_parms->ofdm_symbol_size;
c16_t *pss0_rxF, *pss0_rxF_ext;
c16_t *sss0_rxF, *sss0_rxF_ext;
for (uint8_t aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
pss0_rxF = &rxdataF[aarx][PSS0_SL_SYMBOL_NB * ofdm_symbol_size];
sss0_rxF = &rxdataF[aarx][SSS0_SL_SYMBOL_NB * ofdm_symbol_size];
pss0_rxF_ext = &pss0_ext[aarx][0];
sss0_rxF_ext = &sss0_ext[aarx][0];
unsigned int k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + PSS_SSS_SUB_CARRIER_START_SL;
if (k >= ofdm_symbol_size)
k-=ofdm_symbol_size;
for (int i = 0; i < LENGTH_PSS_NR; i++) {
pss0_rxF_ext[i] = pss0_rxF[k];
sss0_rxF_ext[i] = sss0_rxF[k];
k++;
if (k == ofdm_symbol_size) k = 0;
}
}
c16_t *pss1_rxF, *pss1_rxF_ext;
c16_t *sss1_rxF, *sss1_rxF_ext;
for (uint8_t aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
pss1_rxF = &rxdataF[aarx][PSS1_SL_SYMBOL_NB * ofdm_symbol_size];
sss1_rxF = &rxdataF[aarx][SSS1_SL_SYMBOL_NB * ofdm_symbol_size];
pss1_rxF_ext = &pss1_ext[aarx][0];
sss1_rxF_ext = &sss1_ext[aarx][0];
unsigned int k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + PSS_SSS_SUB_CARRIER_START_SL;
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
for (int i=0; i < LENGTH_PSS_NR; i++) {
pss1_rxF_ext[i] = pss1_rxF[k];
sss1_rxF_ext[i] = sss1_rxF[k];
k++;
if (k == ofdm_symbol_size) k = 0;
}
}
return(0);
}
/*******************************************************************
*
* NAME : pss_ch_est
*
* PARAMETERS : none
*
* RETURN : none
*
* DESCRIPTION : pss channel estimation
*
*********************************************************************/
int pss_sl_ch_est_nr(PHY_VARS_NR_UE *ue,
c16_t pss0_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR],
c16_t sss0_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR],
c16_t pss1_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR],
c16_t sss1_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR])
{
int id = get_softmodem_params()->sl_mode == 0 ? ue->common_vars.eNb_id : ue->common_vars.N2_id;
c16_t *pss = primary_synchro_nr[id];
c16_t tmp, tmp2;
c16_t *sss0_ext3 = &sss0_ext[0][0];
for (uint8_t aarx = 0; aarx < ue->frame_parms.nb_antennas_rx; aarx++) {
c16_t *sss0_ext2 = &sss0_ext[aarx][0];
c16_t *pss0_ext2 = &pss0_ext[aarx][0];
for (uint8_t i = 0; i < LENGTH_PSS_NR; i++) {
// This is H*(PSS) = R* \cdot PSS
tmp.r = (int16_t)((((int32_t)pss0_ext2[i].r) * pss[i].r)>>15);
tmp.i = -(int16_t)((((int32_t)pss0_ext2[i].i) * pss[i].r)>>15);
int32_t amp = (((int32_t)tmp.r) * tmp.r) + ((int32_t)tmp.i) * tmp.i;
int shift = log2_approx(amp) / 2;
// This is R(SSS) \cdot H*(PSS)
tmp2.r = (int16_t)(((tmp.r * (int32_t)sss0_ext2[i].r) >> shift) - ((tmp.i * (int32_t)sss0_ext2[i].i >> shift)));
tmp2.i = (int16_t)(((tmp.r * (int32_t)sss0_ext2[i].i) >> shift) + ((tmp.i * (int32_t)sss0_ext2[i].r >> shift)));
// MRC on RX antennas
if (aarx==0) {
sss0_ext3[i].r = tmp2.r;
sss0_ext3[i].i = tmp2.i;
} else {
sss0_ext3[i].r += tmp2.r;
sss0_ext3[i].i += tmp2.i;
}
}
}
c16_t *sss1_ext3 = &sss1_ext[0][0];
for (uint8_t aarx = 0; aarx < ue->frame_parms.nb_antennas_rx; aarx++) {
c16_t *sss1_ext2 = &sss1_ext[aarx][0];
c16_t *pss1_ext2 = &pss1_ext[aarx][0];
for (uint8_t i = 0; i < LENGTH_PSS_NR; i++) {
// This is H*(PSS) = R* \cdot PSS
tmp.r = (int16_t)((((int32_t)pss1_ext2[i].r) * pss[i].r)>>15);
tmp.i = -(int16_t)((((int32_t)pss1_ext2[i].i) * pss[i].r)>>15);
int32_t amp = (((int32_t)tmp.r) * tmp.r) + ((int32_t)tmp.i) * tmp.i;
int shift = log2_approx(amp) / 2;
// This is R(SSS) \cdot H*(PSS)
tmp2.r = (int16_t)(((tmp.r * (int32_t)sss1_ext2[i].r) >> shift) - ((tmp.i * (int32_t)sss1_ext2[i].i >> shift)));
tmp2.i = (int16_t)(((tmp.r * (int32_t)sss1_ext2[i].i) >> shift) + ((tmp.i * (int32_t)sss1_ext2[i].r >> shift)));
// MRC on RX antennas
if (aarx == 0) {
sss1_ext3[i].r = tmp2.r;
sss1_ext3[i].i = tmp2.i;
} else {
sss1_ext3[i].r += tmp2.r;
sss1_ext3[i].i += tmp2.i;
}
}
}
return(0);
}
/*******************************************************************
*
* NAME : rx_sss_sl_nr
*
* PARAMETERS : none
*
* RETURN : Set Nid_cell in ue context
*
* DESCRIPTION : Determine element Nid1 of cell identity
* so Nid_cell in ue context is set according to Nid1 & Nid2
*
*********************************************************************/
int rx_sss_sl_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int32_t *tot_metric, uint8_t *phase_max, int *freq_offset_sss)
{
c16_t pss0_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR];
c16_t sss0_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR];
c16_t pss1_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR];
c16_t sss1_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR];
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
pss_sss_sl_extract_nr(ue, proc, pss0_ext, sss0_ext, pss1_ext, sss1_ext);
#ifdef DEBUG_PLOT_SSS
write_output("rxsig0.m","rxs0",&ue->common_vars.rxdata[0][0],ue->frame_parms.samples_per_frame,1,1);
write_output("rxdataF0_pss.m","rxF0_pss",&ue->common_vars.rxdataF[0][0],frame_parms->ofdm_symbol_size,1,1);
write_output("rxdataF0_sss.m","rxF0_sss",&ue->common_vars.rxdataF[0][(SSS_SYMBOL_NB-PSS_SYMBOL_NB)*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1);
write_output("pss0_ext.m","pss0_ext",pss0_ext,LENGTH_PSS_NR,1,1);
write_output("pss1_ext.m","pss1_ext",pss1_ext,LENGTH_PSS_NR,1,1);
write_output("sss0_ext.m","sss0_ext",sss0_ext,LENGTH_PSS_NR,1,1);
write_output("sss1_ext.m","sss1_ext",sss1_ext,LENGTH_PSS_NR,1,1);
write_output("pss0_time.m","pss0_time",primary_synchro_time_nr[0],frame_parms->ofdm_symbol_size,1,1);
write_output("pss1_time.m","pss1_time",primary_synchro_time_nr[1],frame_parms->ofdm_symbol_size,1,1);
#endif
// get conjugated channel estimate from PSS, H* = R* \cdot PSS
// and do channel estimation and compensation based on PSS
pss_sl_ch_est_nr(ue, pss0_ext, sss0_ext, pss1_ext, sss1_ext);
write_output("sss0_comp.m","sss0_comp",sss0_ext,LENGTH_PSS_NR,1,1);
write_output("sss1_comp.m","sss1_comp",sss1_ext,LENGTH_PSS_NR,1,1);
/* now do the SSS detection based on the precomputed sequences in PHY/LTE_TRANSPORT/sss.
for phase evaluation, one uses an array of possible phase shifts
then a correlation is done between received signal with a shift pĥase and the reference signal
Computation of signal with shift phase is based on below formula
cosinus cos(x + y) = cos(x)cos(y) - sin(x)sin(y)
sinus sin(x + y) = sin(x)cos(y) + cos(x)sin(y) */
uint16_t Nid1;
uint8_t Nid2 = ue->common_vars.N2_id;
*tot_metric = INT_MIN;
c16_t *sss0 = &sss0_ext[0][0];
c16_t *sss1 = &sss1_ext[0][0];
int16_t *d;
for (Nid1 = 0; Nid1 < N_ID_1_NUMBER; Nid1++) { // all possible Nid1 values
for (uint8_t phase = 0; phase < PHASE_HYPOTHESIS_NUMBER; phase++) { // phase offset between PSS and SSS
int32_t metric = 0;
int32_t metric_re = 0;
d = (int16_t *)&d_sss[Nid2][Nid1];
// This is the inner product using one particular value of each unknown parameter
for (int i = 0; i < LENGTH_SSS_NR; i++) {
metric_re += d[i] * (((phase_re_nr[phase] * sss0[i].r) >> SCALING_METRIC_SSS_NR) - ((phase_im_nr[phase] * sss0[i].i) >> SCALING_METRIC_SSS_NR)) +
d[i] * (((phase_re_nr[phase] * sss1[i].r) >> SCALING_METRIC_SSS_NR) - ((phase_im_nr[phase] * sss1[i].i) >> SCALING_METRIC_SSS_NR));
}
metric = metric_re;
if (metric > *tot_metric) {
*tot_metric = metric;
ue->frame_parms.Nid_SL = Nid1 + NUMBER_SSS_SEQUENCE * Nid2;
*phase_max = phase;
#ifdef DEBUG_SSS_NR
LOG_I(NR_PHY,"(phase, Nid1) (%d,%d), metric_phase = %d, tot_metric = %d, phase_max = %d \n", phase, Nid1, metric, *tot_metric, *phase_max);
#endif
}
}
}
Nid2 = GET_NID2_SL(frame_parms->Nid_SL);
Nid1 = GET_NID1_SL(frame_parms->Nid_SL);
#if 1
LOG_I(NR_PHY, "Nid2 %d Nid1 %d tot_metric %d, phase_max %d \n", Nid2, Nid1, *tot_metric, *phase_max);
#endif
if (Nid1 == N_ID_1_NUMBER) {
LOG_I(PHY,"Failled to detect SL SSS after PSS\n");
return -1;
}
int re = 0;
int im = 0;
d = (int16_t *)&d_sss[Nid2][Nid1];
for(int i = 0; i < LENGTH_SSS_NR; i++) {
re += d[i] * sss0[i].r;
im += d[i] * sss0[i].i;
re += d[i] * sss1[i].r;
im += d[i] * sss1[i].i;
}
double ffo_sss = atan2(im, re) / M_PI / 4.3;
*freq_offset_sss = (int)(ffo_sss * frame_parms->subcarrier_spacing);
double ffo_pss = ((double)ue->common_vars.freq_offset) / frame_parms->subcarrier_spacing;
LOG_I(NR_PHY, "ffo_pss %f (%i Hz), ffo_sss %f (%i Hz), ffo_pss+ffo_sss %f (%i Hz)\n",
ffo_pss, (int)(ffo_pss * frame_parms->subcarrier_spacing), ffo_sss, *freq_offset_sss, ffo_pss + ffo_sss,
(int)((ffo_pss + ffo_sss) * frame_parms->subcarrier_spacing));
return(0);
}

View File

@@ -61,10 +61,13 @@ enum UEdataType {
pbchRxdataF_comp,
pdcchLlr,
pdcchRxdataF_comp,
UEdataTypeNumberOfItems,
psbchDlChEstimateTime,
psbchLlr,
psbchRxdataF_comp,
pdschLlr,
pdschRxdataF_comp,
commonRxdataF,
UEdataTypeNumberOfItems
};
typedef struct scopeData_s {

View File

@@ -39,6 +39,7 @@
#include "defs_nr_common.h"
#include "CODING/nrPolar_tools/nr_polar_pbch_defs.h"
#include "CODING/nrPolar_tools/nr_polar_psbch_defs.h"
#include <stdio.h>
#include <stdlib.h>
@@ -233,17 +234,18 @@ typedef struct {
/// - first index: rx antenna [0..nb_antennas_rx[
/// - second index: sample [0..2*FRAME_LENGTH_COMPLEX_SAMPLES+2048[
c16_t **rxdata;
/// \brief Holds the received data in time domain.
/// Should point to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER.
/// - first index: rx antenna [0..nb_antennas_rx[
/// - second index: sample [0..2*FRAME_LENGTH_COMPLEX_SAMPLES+2048[
/// \brief Holds the received data in the frequency domain.
/// For IFFT_FPGA this points to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER.
/// - first index: tx antenna [0..nb_antennas_tx[
/// - second index: sample [0..FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX[
c16_t **rxdataF;
/// holds output of the sync correlator
int32_t *sync_corr;
/// estimated frequency offset (in radians) for all subcarriers
int32_t freq_offset;
// N2_id - assigned based on in coverage status received in pss
int32_t N2_id;
/// eNb_id user is synched to
int32_t eNb_id;
} NR_UE_COMMON;
@@ -318,7 +320,24 @@ typedef struct {
fapi_nr_dl_config_dci_dl_pdu_rel15_t pdcch_config[FAPI_NR_MAX_SS];
} NR_UE_PDCCH_CONFIG;
#define PBCH_A 24
#define PSBCH_A 32
#define PSBCH_MAX_RE_PER_SYMBOL (11*12)
#define PSBCH_MAX_RE (PSBCH_MAX_RE_PER_SYMBOL*14)
typedef struct {
/// \brief Total number of PDU errors.
uint32_t pdu_errors;
/// \brief Total number of PDU errors 128 frames ago.
uint32_t pdu_errors_last;
/// \brief Total number of consecutive PDU errors.
uint32_t pdu_errors_conseq;
/// \brief FER (in percent) .
//uint32_t pdu_fer;
uint32_t psbch_a;
uint32_t psbch_a_interleaved;
uint32_t psbch_a_prime;
uint32_t psbch_e[NR_POLAR_PSBCH_E_DWORD];
} NR_UE_PSBCH;
typedef struct {
int16_t amp;
@@ -378,8 +397,14 @@ typedef struct {
int if_freq_off;
/// \brief Indicator that UE is synchronized to a gNB
int is_synchronized;
/// \brief Indicator that UE is synchronized to a SyncRef UE on Sidelink
int is_synchronized_sl;
/// \brief Indicator that UE lost frame synchronization on Sidelink
int lost_sync_sl;
/// \brief Target gNB Nid_cell when UE is resynchronizing
int target_Nid_cell;
/// \brief Indicator that UE is an SynchRef UE
int sync_ref;
/// Data structure for UE process scheduling
UE_nr_proc_t proc;
/// Flag to indicate the UE shouldn't do timing correction at all
@@ -420,10 +445,13 @@ typedef struct {
fapi_nr_config_request_t nrUE_config;
nr_synch_request_t synch_request;
NR_UE_PSBCH *psbch_vars[NUMBER_OF_CONNECTED_gNB_MAX];
NR_UE_PRACH *prach_vars[NUMBER_OF_CONNECTED_gNB_MAX];
NR_UE_CSI_IM *csiim_vars[NUMBER_OF_CONNECTED_gNB_MAX];
NR_UE_CSI_RS *csirs_vars[NUMBER_OF_CONNECTED_gNB_MAX];
NR_UE_SRS *srs_vars[NUMBER_OF_CONNECTED_gNB_MAX];
NR_SLSS_t *slss;
NR_UE_PRS *prs_vars[NR_MAX_PRS_COMB_SIZE];
uint8_t prs_active_gNBs;
NR_DL_UE_HARQ_t dl_harq_processes[2][NR_MAX_DLSCH_HARQ_PROCESSES];
@@ -445,7 +473,10 @@ typedef struct {
/// PBCH DMRS sequence
uint32_t nr_gold_pbch[2][64][NR_PBCH_DMRS_LENGTH_DWORD];
/// PDSCH DMRS
/// PSBCH DMRS sequence
uint32_t nr_gold_psbch[NR_PSBCH_DMRS_LENGTH_DWORD];
/// PDSCH DMRS
uint32_t ****nr_gold_pdsch[NUMBER_OF_CONNECTED_eNB_MAX];
// Scrambling IDs used in PDSCH DMRS
@@ -514,6 +545,7 @@ typedef struct {
int ssb_offset;
uint16_t symbol_offset; /// offset in terms of symbols for detected ssb in sync
int rx_offset; /// Timing offset
int rx_offset_sl; /// Timing offset for Sidelink
int rx_offset_diff; /// Timing adjustment for ofdm symbol0 on HW USRP
int max_pos_fil; /// Timing offset IIR filter
int time_sync_cell;
@@ -659,6 +691,7 @@ typedef struct nr_rxtx_thread_data_s {
UE_nr_rxtx_proc_t proc;
PHY_VARS_NR_UE *UE;
int writeBlockSize;
notifiedFIFO_t txFifo;
nr_phy_data_t phy_data;
int tx_wait_for_dlsch;
} nr_rxtx_thread_data_t;

View File

@@ -69,6 +69,10 @@
#define NR_PBCH_DMRS_LENGTH 144 // in mod symbols
#define NR_PBCH_DMRS_LENGTH_DWORD 10 // ceil(2(QPSK)*NR_PBCH_DMRS_LENGTH/32)
#define NR_PSBCH_MAX_NB_CARRIERS 132
#define NR_PSBCH_MAX_NB_MOD_SYMBOLS 99
#define NR_PSBCH_DMRS_LENGTH 297 // in mod symbols
#define NR_PSBCH_DMRS_LENGTH_DWORD 20 // ceil(2(QPSK)*NR_PBCH_DMRS_LENGTH/32)
/*used for the resource mapping*/
#define NR_MAX_PDCCH_DMRS_LENGTH 576 // 16(L)*2(QPSK)*3(3 DMRS symbs per REG)*6(REG per CCE)
@@ -95,6 +99,8 @@
#define NR_NB_NSCID 2
#define NR_RX_NB_TH 1
#define MAX_UL_DELAY_COMP 20
typedef enum {
@@ -157,6 +163,8 @@ struct NR_DL_FRAME_PARMS {
uint64_t dl_CarrierFreq;
/// UL carrier frequency
uint64_t ul_CarrierFreq;
/// SL carrier frequency
uint64_t sl_CarrierFreq;
/// TX attenuation
uint32_t att_tx;
/// RX attenuation
@@ -164,7 +172,12 @@ struct NR_DL_FRAME_PARMS {
/// total Number of Resource Block Groups: this is ceil(N_PRB/P)
/// Frame type (0 FDD, 1 TDD)
frame_type_t frame_type;
uint16_t tdd_slot_config;
uint8_t tdd_period;
uint8_t tdd_config;
/// Sidelink Cell ID
uint16_t Nid_SL;
/// Cell ID
uint16_t Nid_cell;
/// subcarrier spacing (15,30,60,120)
@@ -216,8 +229,8 @@ struct NR_DL_FRAME_PARMS {
/// Cyclic Prefix for DL (0=Normal CP, 1=Extended CP)
lte_prefix_type_t Ncp;
/// sequence which is computed based on carrier frequency and numerology to rotate/derotate each OFDM symbol according to Section 5.3 in 38.211
/// First dimension is for the direction of the link (0 DL, 1 UL)
c16_t symbol_rotation[2][224];
/// First dimension is for the direction of the link (0 DL, 1 UL, 2 SL)
c16_t symbol_rotation[3][224];
/// sequence used to compensate the phase rotation due to timeshifted OFDM symbols
/// First dimenstion is for different CP lengths
c16_t timeshift_symbol_rotation[4096*2] __attribute__ ((aligned (16)));
@@ -258,6 +271,17 @@ struct NR_DL_FRAME_PARMS {
uint32_t ofdm_offset_divisor;
};
/* NR Sidelink PSBCH payload fields
TODO: This will be removed in the future and
filled in by the upper layers once developed. */
typedef struct {
uint32_t coverageIndicator : 1;
uint32_t tddConfig : 12;
uint32_t DFN : 10;
uint32_t slotIndex : 7;
uint32_t reserved : 2;
} PSBCH_payload;
// PRS config structures
typedef struct {
uint16_t PRSResourceSetPeriod[2]; // [slot period, slot offset] of a PRS resource set

View File

@@ -99,6 +99,10 @@ SystemInformationBlockType1_nr_t;
#define NR_UPLINK_SLOT (0x02)
#define NR_MIXED_SLOT (0x03)
#define NR_LINK_TYPE_DL (0x00)
#define NR_LINK_TYPE_UL (0x01)
#define NR_LINK_TYPE_SL (0x02)
#define FRAME_DURATION_MICRO_SEC (10000) /* frame duration in microsecond */
typedef enum {

View File

@@ -23,6 +23,10 @@
#define __PHY_EXTERN_NR_UE__H__
#include "PHY/defs_nr_UE.h"
extern uint64_t downlink_frequency[MAX_NUM_CCs][4];
extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
extern uint64_t sidelink_frequency[MAX_NUM_CCs][4];
extern PHY_VARS_NR_UE ***PHY_vars_UE_g;
#endif /*__PHY_EXTERN_H__ */

View File

@@ -166,7 +166,7 @@ void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx) {
LOG_D(PHY,"feptx_ofdm (TXPATH): frame %d, slot %d: txp (time %p) %d dB, txp (freq) %d dB\n",
frame_tx,slot,txdata,dB_fixed(signal_energy((int32_t*)txdata,fp->get_samples_per_slot(
slot,fp))),dB_fixed(signal_energy_nodc(ru->common.txdataF_BF[aa],2*slot_sizeF)));
slot,fp))),dB_fixed(signal_energy_nodc(ru->common.txdataF_BF[aa],2*slot_sizeF)));
}

View File

@@ -198,7 +198,7 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
//apply the OFDM symbol rotation here
for (aa=0; aa<cfg->carrier_config.num_tx_ant.value; aa++) {
apply_nr_rotation(fp, &gNB->common_vars.txdataF[aa][txdataF_offset], slot, 0, fp->Ncp == EXTENDED ? 12 : 14);
apply_nr_rotation(fp, &gNB->common_vars.txdataF[aa][txdataF_offset], slot, 0, fp->Ncp == EXTENDED ? 12 : 14, NR_LINK_TYPE_DL);
T(T_GNB_PHY_DL_OUTPUT_SIGNAL, T_INT(0),
T_INT(frame), T_INT(slot),

View File

@@ -87,6 +87,11 @@ typedef struct {
uint8_t xtra_byte;
} fapiPbch_t;
typedef struct {
uint8_t decoded_output[NR_POLAR_PSBCH_PAYLOAD_BITS];
uint8_t xtra_byte;
} fapiPsbch_t;
/** @addtogroup _PHY_PROCEDURES_
* @{
*/
@@ -98,6 +103,28 @@ typedef struct {
*/
void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data);
/*! \brief Scheduling for UE SL TX procedures in normal slots.
@param ue Pointer to UE variables on which to act
@param proc Pointer to RXn-TXnp4 proc information
@param gNB_id Local id of gNB on which to act, 0 in case of sidelink
*/
void phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id);
/*! \brief check weather if current slot in current frame is suitable for SL SSB time slot allocation.
@param ue Pointer to UE variables on which to act
@param frame frame number
@param slot slot number
*/
bool phy_ssb_slot_allocation_sl(PHY_VARS_NR_UE *ue, int frame, int slot);
/*! \brief Scheduling for UE RX procedures in normal subframes.
@param ue Pointer to UE variables on which to act
@param proc Pointer to proc information
@param dlsch_parallel use multithreaded dlsch processing
@param phy_pdcch_config PDCCH Config for this slot
@param txFifo Result fifo if PDSCH is run in parallel
*/
void send_slot_ind(notifiedFIFO_t *nf, int slot);
void pbch_pdcch_processing(PHY_VARS_NR_UE *ue,

View File

@@ -50,6 +50,8 @@
#endif
#include "executables/softmodem-common.h"
#include "executables/nr-uesoftmodem.h"
#include "LAYER2/NR_MAC_UE/mac_proto.h"
#include "openair1/PHY/MODULATION/nr_modulation.h"
#include "SCHED_NR_UE/pucch_uci_ue_nr.h"
#include <openair1/PHY/TOOLS/phy_scope_interface.h>
@@ -256,6 +258,99 @@ void ue_ta_procedures(PHY_VARS_NR_UE *ue, int slot_tx, int frame_tx)
}
}
bool phy_ssb_slot_allocation_sl(PHY_VARS_NR_UE *ue, int frame, int slot)
{
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
if ((frame * fp->slots_per_frame + slot) % (16 * fp->slots_per_frame) == 0) {
ue->slss->sl_numssb_withinperiod_r16 = ue->slss->sl_numssb_withinperiod_r16_copy;
ue->slss->sl_timeoffsetssb_r16 = frame * fp->slots_per_frame + ue->slss->sl_timeoffsetssb_r16_copy;
}
if (ue->slss->sl_numssb_withinperiod_r16 > 0) {
if (frame * fp->slots_per_frame + slot == ue->slss->sl_timeoffsetssb_r16) {
ue->slss->sl_timeoffsetssb_r16 = ue->slss->sl_timeoffsetssb_r16 + ue->slss->sl_timeinterval_r16;
ue->slss->sl_numssb_withinperiod_r16 = ue->slss->sl_numssb_withinperiod_r16 - 1;
LOG_I(PHY,"*** SL-SSB slot allocation %d.%d ***\n", frame, slot);
} else {
return false;
}
} else {
return false;
}
return true;
}
void phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
uint8_t gNB_id)
{
int slot_tx = proc->nr_slot_tx;
int frame_tx = proc->frame_tx;
AssertFatal(frame_tx >= 0 && frame_tx < 1024, "frame_tx %d is not in 0...1023\n",frame_tx);
AssertFatal(slot_tx >= 0 && slot_tx < 20, "slot_tx %d is not in 0...19\n", slot_tx);
LOG_D(PHY,"****** start Sidelink TX-Chain for AbsSlot %d.%d ******\n", frame_tx, slot_tx);
if (get_softmodem_params()->sl_mode == 2) {
ue->tx_power_dBm[slot_tx] = -127;
int num_samples_per_slot = ue->frame_parms.slots_per_frame * ue->frame_parms.samples_per_slot_wCP;
for(int i = 0; i < ue->frame_parms.nb_antennas_tx; ++i) {
AssertFatal(i < sizeof(ue->common_vars.txdataF), "Array index %d is over the Array size %lu\n", i, sizeof(ue->common_vars.txdataF));
memset(ue->common_vars.txdataF[i], 0, sizeof(int32_t) * num_samples_per_slot);
}
}
if (ue->sync_ref && phy_ssb_slot_allocation_sl(ue, frame_tx, slot_tx)) {
nr_sl_common_signal_procedures(ue, frame_tx, slot_tx);
const int txdataF_offset = slot_tx * ue->frame_parms.samples_per_slot_wCP;
LOG_D(NR_PHY, "%s() %d. slot %d txdataF_offset %d\n", __FUNCTION__, __LINE__, slot_tx, txdataF_offset);
//ue->frame_parms.nb_prefix_samples0 = ue->is_synchronized_sl ? ue->frame_parms.nb_prefix_samples0 : ue->frame_parms.nb_prefix_samples;
int slot_timestamp = ue->frame_parms.get_samples_slot_timestamp(slot_tx, &ue->frame_parms, 0);
LOG_D(NR_PHY,"slot_timestamp %d\n",slot_timestamp);
for (int aa = 0; aa < ue->frame_parms.nb_antennas_tx; aa++) {
/* apply_nr_rotation(&ue->frame_parms,
&ue->common_vars.txdataF[aa][txdataF_offset],
slot_tx, 0, 1, NR_LINK_TYPE_SL); // Conducts rotation on 0th symbol*/
PHY_ofdm_mod((int*)&ue->common_vars.txdataF[aa][txdataF_offset],
(int*)&ue->common_vars.txdata[aa][slot_timestamp],
ue->frame_parms.ofdm_symbol_size,
1, // Takes IDFT of 1st symbol (first PSBCH)ue->frame_parms.nb_prefix_samples
ue->frame_parms.nb_prefix_samples0,
CYCLIC_PREFIX);
/* apply_nr_rotation(&ue->frame_parms,
&ue->common_vars.txdataF[aa][txdataF_offset],
slot_tx, 1, 13, NR_LINK_TYPE_SL); // Conducts rotation on symbols located 1 (PSS) to 13 (guard)*/
PHY_ofdm_mod((int*)&ue->common_vars.txdataF[aa][ue->frame_parms.ofdm_symbol_size + txdataF_offset], // Starting at PSS (in freq)
(int*)&ue->common_vars.txdata[aa][ue->frame_parms.ofdm_symbol_size +
ue->frame_parms.nb_prefix_samples0 + /*
ue->frame_parms.nb_prefix_samples +*/
slot_timestamp], // Starting output offset at CP0 + PSBCH0 + CP1
ue->frame_parms.ofdm_symbol_size,
13, // Takes IDFT of remaining 13 symbols (PSS to guard)... Notice the offset of the input and output above
ue->frame_parms.nb_prefix_samples,
CYCLIC_PREFIX);
}
#ifdef DEBUG_PHY_PROC
char buffer1[ue->frame_parms.ofdm_symbol_size];
for (int i = 0; i < 13; i++) {
bzero(buffer1, sizeof(buffer1));
LOG_I(NR_PHY, "%s(): %d After rotation txdataF[%d] = %s\n",
__FUNCTION__, __LINE__, txdataF_offset + (ue->frame_parms.ofdm_symbol_size * i),
hexdump((void *)&ue->common_vars.txdataF[0][txdataF_offset + (ue->frame_parms.ofdm_symbol_size * i)], ue->frame_parms.ofdm_symbol_size, buffer1, sizeof(buffer1)));
}
char buffer0[ue->frame_parms.ofdm_symbol_size];
for (int i = 0; i < 13; i++) {
bzero(buffer0, sizeof(buffer0));
LOG_I(NR_PHY, "%s(): %d Time domain txdata[%d] = %s\n",
__FUNCTION__, __LINE__, slot_timestamp + ue->frame_parms.ofdm_symbol_size * i,
hexdump((void *)&ue->common_vars.txdata[0][slot_timestamp + ue->frame_parms.ofdm_symbol_size * i], ue->frame_parms.ofdm_symbol_size, buffer0, sizeof(buffer0)));
}
#endif
}
LOG_D(PHY,"****** end Sidelink TX-Chain for AbsSlot %d.%d ******\n", frame_tx, slot_tx);
}
void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
nr_phy_data_tx_t *phy_data) {

View File

@@ -29,7 +29,8 @@
* \note
* \warning
*/
#include "NR_ServingCellConfigCommon.h"
#include "NR_ServingCellConfig.h"
#ifndef __NR_UNITARY_DEFS__H__
#define __NR_UNITARY_DEFS__H__

View File

@@ -191,7 +191,7 @@ int main(int argc, char **argv)
double sigma2, sigma2_dB=10,SNR,snr0=-2.0,snr1=2.0;
double cfo=0;
uint8_t snr1set=0;
int **txdata;
c16_t **txdata;
double **s_re,**s_im,**r_re,**r_im;
//double iqim = 0.0;
double ip =0.0;
@@ -586,7 +586,7 @@ int main(int argc, char **argv)
s_im = malloc(2*sizeof(double*));
r_re = malloc(2*sizeof(double*));
r_im = malloc(2*sizeof(double*));
txdata = calloc(2,sizeof(int*));
txdata = calloc(2, sizeof(c16_t*));
for (i=0; i<2; i++) {
@@ -596,7 +596,7 @@ int main(int argc, char **argv)
r_re[i] = malloc16_clear(frame_length_complex_samples*sizeof(double));
r_im[i] = malloc16_clear(frame_length_complex_samples*sizeof(double));
printf("Allocating %d samples for txdata\n",frame_length_complex_samples);
txdata[i] = malloc16_clear(frame_length_complex_samples*sizeof(int));
txdata[i] = malloc16_clear(frame_length_complex_samples * sizeof(c16_t));
}
if (pbch_file_fd!=NULL) {
@@ -652,10 +652,11 @@ int main(int argc, char **argv)
gNB->common_vars.txdataF[aa],
slot,
0,
12);
12,
NR_LINK_TYPE_DL);
PHY_ofdm_mod((int *)gNB->common_vars.txdataF[aa],
&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
(int *)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot, frame_parms, 0)],
frame_parms->ofdm_symbol_size,
12,
frame_parms->nb_prefix_samples,
@@ -665,7 +666,8 @@ int main(int argc, char **argv)
gNB->common_vars.txdataF[aa],
slot,
0,
14);
14,
NR_LINK_TYPE_DL);
/*nr_normal_prefix_mod(gNB->common_vars.txdataF[aa],
&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
@@ -726,8 +728,8 @@ int main(int argc, char **argv)
for (i=0; i<frame_length_complex_samples; i++) {
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
r_re[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)]);
r_im[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)+1]);
r_re[aa][i] = (double)txdata[aa][i].r;
r_im[aa][i] = (double)txdata[aa][i].i;
}
}
@@ -761,8 +763,8 @@ int main(int argc, char **argv)
for (i=0; i<frame_length_complex_samples; i++) {
for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
((short*) UE->common_vars.rxdata[aa])[2*i] = (short) ((r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
((short*) UE->common_vars.rxdata[aa])[2*i+1] = (short) ((r_im[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
UE->common_vars.rxdata[aa][i].r = (short)(r_re[aa][i] + sqrt(sigma2 / 2) * gaussdouble(0.0, 1.0));
UE->common_vars.rxdata[aa][i].i = (short)(r_im[aa][i] + sqrt(sigma2 / 2) * gaussdouble(0.0, 1.0));
}
}

View File

@@ -80,7 +80,10 @@ void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) { }
/* temporary dummy implem of get_softmodem_optmask, till basic simulators implemented as device */
uint64_t get_softmodem_optmask(void) {return 0;}
softmodem_params_t *get_softmodem_params(void) {return 0;}
static softmodem_params_t softmodem_params;
softmodem_params_t *get_softmodem_params(void) {
return &softmodem_params;
}
//Fixme: Uniq dirty DU instance, by global var, datamodel need better management
instance_t DUuniqInstance=0;
instance_t CUuniqInstance=0;
@@ -138,13 +141,12 @@ void processSlotTX(void *arg) {}
int NB_UE_INST = 1;
int main(int argc, char **argv){
get_softmodem_params()->sl_mode = 0;
char c;
double sigma2, sigma2_dB = 0, SNR, snr0 = -2.0, snr1 = 0.0, ue_speed0 = 0.0, ue_speed1 = 0.0;
double **s_re, **s_im, **r_re, **r_im, iqim = 0.0, delay_avg = 0, ue_speed = 0, fs=-1, bw;
int i, l, aa, aarx, trial, n_frames = 1, prach_start, rx_prach_start; //, ntrials=1;
c16_t **txdata;
int N_RB_UL = 106, delay = 0, NCS_config = 13, rootSequenceIndex = 1, threequarter_fs = 0, mu = 1, fd_occasion = 0, loglvl = OAILOG_INFO, numRA = 0, prachStartSymbol = 0;
uint8_t snr1set = 0, ue_speed1set = 0, transmission_mode = 1, n_tx = 1, n_rx = 1, awgn_flag = 0, msg1_frequencystart = 0, num_prach_fd_occasions = 1, prach_format=0;
uint8_t config_index = 98, prach_sequence_length = 1, restrictedSetConfig = 0, N_dur, N_t_slot, start_symbol;
@@ -596,7 +598,7 @@ int main(int argc, char **argv){
ue_prach_pdu = &UE->prach_vars[0]->prach_pdu;
ue_prach_config = &UE->nrUE_config.prach_config;
txdata = UE->common_vars.txdata;
c16_t **txdata = UE->common_vars.txdata;
UE->prach_vars[0]->amp = AMP;
ue_prach_pdu->root_seq_id = rootSequenceIndex;

View File

@@ -0,0 +1,645 @@
/*
* 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 <string.h>
#include <math.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include "common/config/config_userapi.h"
#include "common/utils/LOG/log.h"
#include "common/utils/load_module_shlib.h"
#include "common/utils/nr/nr_common.h"
#include "PHY/types.h"
#include "PHY/defs_nr_common.h"
#include "PHY/defs_nr_UE.h"
#include "openair1/PHY/NR_REFSIG/refsig_defs_ue.h"
#include "PHY/MODULATION/modulation_eNB.h"
#include "PHY/MODULATION/modulation_UE.h"
#include "PHY/MODULATION/nr_modulation.h"
#include "PHY/INIT/nr_phy_init.h"
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
#include "PHY/NR_UE_ESTIMATION/nr_estimation.h"
#include "PHY/phy_vars.h"
#include "SCHED_NR/sched_nr.h"
#include "openair1/SIMULATION/TOOLS/sim.h"
#include "openair1/SIMULATION/RF/rf.h"
#include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h"
#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c"
#include "openair1/PHY/MODULATION/nr_modulation.h"
#include "openair1/PHY/NR_REFSIG/pss_nr.h"
#include <executables/softmodem-common.h>
#include <executables/nr-uesoftmodem.h>
#include "openair1/SCHED_NR_UE/defs.h"
//#define DEBUG_NR_PSBCHSIM
double cpuf;
uint16_t NB_UE_INST = 1;
openair0_config_t openair0_cfg[MAX_CARDS];
uint8_t const nr_rv_round_map[4] = {0, 2, 3, 1};
uint64_t get_softmodem_optmask(void) {return 0;}
static softmodem_params_t softmodem_params;
softmodem_params_t *get_softmodem_params(void) {
return &softmodem_params;
}
nrUE_params_t nrUE_params={0};
nrUE_params_t *get_nrUE_params(void) {
return &nrUE_params;
}
void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) {}
bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
NR_UE_DLSCH_t dlsch[2],
int16_t* llr[2]) {
return false;
}
int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
NR_UE_DLSCH_t dlsch[2],
int16_t *llr[2],
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) {
return 0;
}
int nr_ue_pdcch_procedures(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
int32_t pdcch_est_size,
int32_t pdcch_dl_ch_estimates[][pdcch_est_size],
nr_phy_data_t *phy_data,
int n_ss,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) {
return 0;
}
void nr_fill_dl_indication(nr_downlink_indication_t *dl_ind,
fapi_nr_dci_indication_t *dci_ind,
fapi_nr_rx_indication_t *rx_ind,
UE_nr_rxtx_proc_t *proc,
PHY_VARS_NR_UE *ue,
void *phy_data) {}
void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
uint8_t pdu_type,
PHY_VARS_NR_UE *ue,
NR_UE_DLSCH_t *dlsch0,
NR_UE_DLSCH_t *dlsch1,
uint16_t n_pdus,
UE_nr_rxtx_proc_t *proc,
void *typeSpecific,
uint8_t *b) {}
double cfo = 0;
double snr0 =- 2.0;
double snr1 = 2.0;
uint8_t snr1set = 0;
int n_trials = 1;
uint8_t n_tx = 1;
uint8_t n_rx = 1;
uint16_t Nid_cell = 0;
uint16_t Nid_SL = 336 + 10;
uint64_t SSB_positions = 0x01;
int ssb_subcarrier_offset = 0;
FILE *input_fd = NULL;
SCM_t channel_model = AWGN;
int N_RB_DL = 273;
int mu = 1;
unsigned char psbch_phase = 0;
int run_initial_sync = 0;
int loglvl = OAILOG_WARNING;
float target_error_rate = 0.01;
int seed = 0;
void free_psbchsim_members(PHY_VARS_NR_UE *UE,
double **s_re,
double **s_im,
double **r_re,
double **r_im,
c16_t **txdata,
FILE *input_fd)
{
term_nr_ue_signal(UE, 1);
if (UE->slss) free(UE->slss);
if (UE) free(UE);
for (int i = 0; i < 2; i++) {
if (s_re[i]) free(s_re[i]);
if (s_im[i]) free(s_im[i]);
if (r_re[i]) free(r_re[i]);
if (r_im[i]) free(r_im[i]);
if (txdata[i]) free(txdata[i]);
}
if (s_re) free(s_re);
if (s_im) free(s_im);
if (r_re) free(r_re);
if (r_im) free(r_im);
if (txdata) free(txdata);
if (input_fd)
fclose(input_fd);
loader_reset();
logTerm();
}
void nr_phy_config_request_sim_psbchsim(PHY_VARS_NR_UE *ue,
int N_RB_DL,
int N_RB_UL,
int mu,
int Nid_SL,
uint64_t position_in_burst)
{
uint64_t rev_burst = 0;
for (int i = 0; i < 64; i++)
rev_burst |= (((SSB_positions >> (63-i))&0x01) << i);
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
fapi_nr_config_request_t *nrUE_config = &ue->nrUE_config;
nrUE_config->cell_config.phy_cell_id = Nid_SL; // TODO
nrUE_config->ssb_config.scs_common = mu;
nrUE_config->ssb_table.ssb_subcarrier_offset = 0;
nrUE_config->ssb_table.ssb_offset_point_a = 0;
nrUE_config->ssb_table.ssb_mask_list[1].ssb_mask = (rev_burst)&(0xFFFFFFFF);
nrUE_config->ssb_table.ssb_mask_list[0].ssb_mask = (rev_burst>>32)&(0xFFFFFFFF);
nrUE_config->cell_config.frame_duplex_type = TDD;
nrUE_config->ssb_table.ssb_period = 1; //10ms
nrUE_config->carrier_config.dl_grid_size[mu] = N_RB_DL;
nrUE_config->carrier_config.ul_grid_size[mu] = N_RB_UL;
nrUE_config->carrier_config.num_tx_ant = fp->nb_antennas_tx;
nrUE_config->carrier_config.num_rx_ant = fp->nb_antennas_rx;
nrUE_config->tdd_table.tdd_period = 0;
nrUE_config->carrier_config.dl_frequency = 450000;
nrUE_config->carrier_config.uplink_frequency = 450000;
nrUE_config->carrier_config.sl_frequency = 450000;
fp->dl_CarrierFreq = 2600000000;
fp->ul_CarrierFreq = 2600000000;
fp->nb_antennas_tx = n_tx;
fp->nb_antennas_rx = n_rx;
fp->nb_antenna_ports_gNB = n_tx;
fp->N_RB_DL = N_RB_DL;
fp->Nid_cell = Nid_cell;
fp->Nid_SL = Nid_SL;
fp->nushift = 0; //No nushift in SL
fp->ssb_type = nr_ssb_type_C; //Note: case c for NR SL???
fp->freq_range = mu < 2 ? nr_FR1 : nr_FR2;
fp->nr_band = 38; //Note: NR SL uses for n38 and n47
fp->threequarter_fs = 0;
fp->ofdm_offset_divisor = UINT_MAX;
fp->first_carrier_offset = 0;
fp->ssb_start_subcarrier = 12 * ue->nrUE_config.ssb_table.ssb_offset_point_a + ssb_subcarrier_offset;
int bw_index = get_supported_band_index(mu, fp->nr_band, N_RB_DL);
nrUE_config->carrier_config.dl_bandwidth = get_supported_bw_mhz(fp->nr_band > 256 ? FR2 : FR1, bw_index);
nr_init_frame_parms_ue(fp, nrUE_config, fp->nr_band);
init_timeshift_rotation(fp);
init_symbol_rotation(fp);
LOG_I(NR_PHY, "nrUE configured\n");
}
static void get_sim_cl_opts(int argc, char **argv)
{
char c;
while ((c = getopt(argc, argv, "F:g:hIL:m:M:n:N:o:O:p:P:r:R:s:S:x:y:z:")) != -1) {
switch (c) {
case 'F':
input_fd = fopen(optarg, "r");
if (input_fd == NULL) {
printf("Problem with filename %s. Exiting.\n", optarg);
exit(-1);
}
break;
case 'g':
switch((char)*optarg) {
case 'A':
channel_model=SCM_A;
break;
case 'B':
channel_model=SCM_B;
break;
case 'C':
channel_model=SCM_C;
break;
case 'D':
channel_model=SCM_D;
break;
case 'E':
channel_model=EPA;
break;
case 'F':
channel_model=EVA;
break;
case 'G':
channel_model=ETU;
break;
default:
printf("Unsupported channel model! Exiting.\n");
exit(-1);
}
break;
case 'I':
run_initial_sync = 1;
target_error_rate = 0.1;
break;
case 'L':
loglvl = atoi(optarg);
break;
case 'm':
mu = atoi(optarg);
break;
case 'M':
SSB_positions = atoi(optarg);
break;
case 'n':
n_trials = atoi(optarg);
break;
case 'N':
Nid_cell = atoi(optarg);
break;
case 'O':
ssb_subcarrier_offset = atoi(optarg);
break;
case 'o':
cfo = atof(optarg);
break;
case 'P':
psbch_phase = atoi(optarg);
if (psbch_phase > 3)
printf("Illegal PSBCH phase (0-3) got %d\n", psbch_phase);
break;
case 'r':
seed = atoi(optarg);
break;
case 'R':
N_RB_DL = atoi(optarg);
break;
case 's':
snr0 = atof(optarg);
break;
case 'S':
snr1 = atof(optarg);
snr1set = 1;
break;
case 'y':
n_tx = atoi(optarg);
if ((n_tx == 0) || (n_tx > 2)) {
printf("Unsupported number of TX antennas %d. Exiting.\n", n_tx);
exit(-1);
}
break;
case 'z':
n_rx = atoi(optarg);
if ((n_rx == 0) || (n_rx > 2)) {
printf("Unsupported number of RX antennas %d. Exiting.\n", n_rx);
exit(-1);
}
break;
default:
case 'h':
printf("%s -F input_filename -g channel_mod -h(elp) -I(nitial sync) -L log_lvl -n n_frames -M SSBs -n frames -N cell_id -o FO -P phase -r seed -R RBs -s snr0 -S snr1 -y TXant -z RXant\n",
argv[0]);
printf("-F Input filename (.txt format) for RX conformance testing\n");
printf("-g [A,B,C,D,E,F,G] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models (ignores delay spread and Ricean factor)\n");
printf("-h This message\n");
printf("-I run initial sync with target error rate 0.1\n");
printf("-L set the log level (-1 disable, 0 error, 1 warning, 2 info, 3 debug, 4 trace)\n");
printf("-m Numerology index\n");
printf("-M Multiple SSB positions in burst\n");
printf("-n Number of frames to simulate\n");
printf("-N Nid_cell\n");
printf("-o Carrier frequency offset in Hz\n");
printf("-O SSB subcarrier offset\n");
printf("-p Conducting PSS and SSS testing\n");
printf("-P PSBCH phase, allowed values 0-3\n");
printf("-r set the random number generator seed (default: 0 = current time)\n");
printf("-R N_RB_DL\n");
printf("-s Starting SNR, runs from SNR0 to SNR0 + 10 dB if not -S given. If -n 1, then just SNR is simulated\n");
printf("-S Ending SNR, runs from SNR0 to SNR1\n");
printf("-x Transmission mode (1,2,6 for the moment)\n");
printf("-y Number of TX antennas used in eNB\n");
printf("-z Number of RX antennas used in UE\n");
exit (-1);
break;
}
}
}
int main(int argc, char **argv)
{
get_softmodem_params()->sa = 1;
get_softmodem_params()->sl_mode = 2;
if (load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY) == 0) {
exit_fun("[NR_PSBCHSIM] Error, configuration module init failed\n");
}
get_sim_cl_opts(argc, argv);
randominit(seed);
logInit();
set_glog(loglvl);
PHY_VARS_NR_UE *UE = malloc16_clear(sizeof(*UE));
printf("Initializing UE for mu %d, N_RB_DL %d\n", mu, N_RB_DL);
snr1 = snr1set == 0 ? snr0 + 10 : snr1;
nr_phy_config_request_sim_psbchsim(UE, N_RB_DL, N_RB_DL, mu, Nid_SL, SSB_positions);
double fs = 0;
double scs = 30000;
switch (mu) {
case 1:
scs = 30000;
UE->frame_parms.Lmax = 1;
if (N_RB_DL == 217) {
fs = 122.88e6;
}
else if (N_RB_DL == 245) {
fs = 122.88e6;
}
else if (N_RB_DL == 273) {
fs = 122.88e6;
}
else if (N_RB_DL == 106) {
fs = 61.44e6;
}
else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL);
break;
case 3:
UE->frame_parms.Lmax = 64;
scs = 120000;
if (N_RB_DL == 66) {
fs = 122.88e6;
}
else AssertFatal(1 == 0,"Unsupported numerology for mu %d, N_RB %d\n", mu, N_RB_DL);
break;
}
int frame_length_complex_samples = UE->frame_parms.samples_per_subframe * NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
double **s_re = malloc(2 * sizeof(double*));
double **s_im = malloc(2 * sizeof(double*));
double **r_re = malloc(2 * sizeof(double*));
double **r_im = malloc(2 * sizeof(double*));
c16_t **txdata = calloc(2, sizeof(c16_t*));
for (int i = 0; i < 2; i++) {
s_re[i] = malloc16_clear(frame_length_complex_samples * sizeof(double));
s_im[i] = malloc16_clear(frame_length_complex_samples * sizeof(double));
r_re[i] = malloc16_clear(frame_length_complex_samples * sizeof(double));
r_im[i] = malloc16_clear(frame_length_complex_samples * sizeof(double));
printf("Allocating %d samples for txdata\n", frame_length_complex_samples);
txdata[i] = malloc16_clear(2 * frame_length_complex_samples * sizeof(c16_t));
}
UE->slss = calloc(1, sizeof(*UE->slss));
int len = sizeof(UE->slss->sl_mib) / sizeof(UE->slss->sl_mib[0]);
for (int i = 0; i < len; i++) {
UE->slss->sl_mib[i] = 0;
}
UE->slss->sl_mib_length = 32;
UE->slss->sl_numssb_withinperiod_r16 = 1;
UE->slss->sl_timeinterval_r16 = 0;
UE->slss->sl_timeoffsetssb_r16 = 0;
UE->slss->slss_id = Nid_SL;
UE->target_Nid_cell = -1;
UE->is_synchronized_sl = run_initial_sync ? 0 : 1;
UE->UE_fo_compensation = (cfo / scs) != 0.0 ? 1 : 0; // if a frequency offset is set then perform fo estimation and compensation
if (init_nr_ue_signal(UE, 1) != 0) {
printf("Error at UE NR initialisation\n");
exit(-1);
}
nr_gold_psbch(UE);
processingData_L1tx_t msgDataTx;
AssertFatal(UE->frame_parms.Lmax < sizeof(msgDataTx.ssb) / sizeof(msgDataTx.ssb[0]), "Invalid index %d\n",
UE->frame_parms.Lmax);
AssertFatal(UE->frame_parms.nb_antennas_tx < 2, "Invalid index %d\n", UE->frame_parms.nb_antennas_tx);
for (int i = 0; i < UE->frame_parms.Lmax; i++) {
if((SSB_positions >> i) & 0x01) {
for (int aa = 0; aa < UE->frame_parms.nb_antennas_tx; aa++)
memset(UE->common_vars.txdataF[aa], 0, sizeof(*UE->common_vars.txdataF[aa]));
int frame = 0;
int ssb_start_symbol_abs = (UE->slss->sl_timeoffsetssb_r16 + UE->slss->sl_timeinterval_r16 * i) * UE->frame_parms.symbols_per_slot;
int slot = ssb_start_symbol_abs / 14;
nr_sl_common_signal_procedures(UE, frame, slot);
const int sc_offset = UE->frame_parms.freq_range == nr_FR1 ? ssb_subcarrier_offset << mu : ssb_subcarrier_offset;
const int prb_offset = UE->frame_parms.freq_range == nr_FR1 ? UE->nrUE_config.ssb_table.ssb_offset_point_a<<mu : UE->nrUE_config.ssb_table.ssb_offset_point_a << (mu - 2);
msgDataTx.ssb[i].ssb_pdu.ssb_pdu_rel15.bchPayload = UE->psbch_vars[0]->psbch_a;
msgDataTx.ssb[i].ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = i;
msgDataTx.ssb[i].ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset = sc_offset;
msgDataTx.ssb[i].ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA = prb_offset;
int slot_timestamp = UE->frame_parms.get_samples_slot_timestamp(slot, &UE->frame_parms, 0);
// UE->frame_parms.nb_prefix_samples0 = UE->is_synchronized_sl ? UE->frame_parms.nb_prefix_samples0 : UE->frame_parms.nb_prefix_samples;
int max_symbol_size = slot_timestamp + UE->frame_parms.nb_prefix_samples0 + UE->frame_parms.ofdm_symbol_size;
AssertFatal(max_symbol_size < frame_length_complex_samples, "Invalid index %d\n", max_symbol_size);
for (int aa = 0; aa < UE->frame_parms.nb_antennas_tx; aa++) {
apply_nr_rotation(&UE->frame_parms,
UE->common_vars.txdataF[aa],
slot, 0, 1, NR_LINK_TYPE_SL); // Conducts rotation on 0th symbol
LOG_I(NR_PHY,"slot %d, symbol 0, nb_prefix_samples0 %d\n",slot,UE->frame_parms.nb_prefix_samples0);
PHY_ofdm_mod((int*)UE->common_vars.txdataF[aa],
(int*)&txdata[aa][slot_timestamp],
UE->frame_parms.ofdm_symbol_size,
1, // Takes IDFT of 1st symbol (first PSBCH)
UE->frame_parms.nb_prefix_samples0,
CYCLIC_PREFIX);
apply_nr_rotation(&UE->frame_parms,
UE->common_vars.txdataF[aa],
slot, 1, 13, NR_LINK_TYPE_SL); // Conducts rotation on symbols located 1 (PSS) to 13 (guard)
LOG_I(NR_PHY,"slot %d, symbols 1...13, nb_prefix_samples %d\n",slot,UE->frame_parms.nb_prefix_samples);
PHY_ofdm_mod((int*)&UE->common_vars.txdataF[aa][UE->frame_parms.ofdm_symbol_size], // Starting at PSS (in freq)
(int*)&txdata[aa][UE->frame_parms.ofdm_symbol_size +
UE->frame_parms.nb_prefix_samples0 /*+
UE->frame_parms.nb_prefix_samples*/], // Starting output offset at CP0 + PSBCH0 + CP1
UE->frame_parms.ofdm_symbol_size,
13, // Takes IDFT of remaining 13 symbols (PSS to guard)... Notice the offset of the input and output above
UE->frame_parms.nb_prefix_samples,
CYCLIC_PREFIX);
}
}
}
char buffer[1024];
printf("txdataF[0] = %s\n", hexdump(UE->common_vars.txdataF[0], sizeof(UE->common_vars.txdataF[0]), buffer, sizeof(buffer)));
if (UE->frame_parms.nb_antennas_tx > 1)
printf("txdataF[1] = %s\n", hexdump(UE->common_vars.txdataF[1], sizeof(UE->common_vars.txdataF[1]), buffer, sizeof(buffer)));
printf("txdata[0] = %s\n", hexdump(txdata[0], sizeof(txdata[0]), buffer, sizeof(buffer)));
if (UE->frame_parms.nb_antennas_tx > 1)
printf("txdata[0] = %s\n", hexdump(txdata[1], sizeof(txdata[1]), buffer, sizeof(buffer)));
AssertFatal((((frame_length_complex_samples - 1) << 1) + 1) < 2 * frame_length_complex_samples,
"Invalid index %d >= %d\n", (((frame_length_complex_samples - 1)<< 1) + 1), 2 * frame_length_complex_samples);
int n_errors = 0;
int exitsim =0;
for (double SNR = snr0; SNR < snr1; SNR += 0.2) {
n_errors = 0;
int n_errors_payload = 0;
for (int trial = 0; trial < n_trials; trial++) {
for (int i = 0; i < frame_length_complex_samples; i++) {
for (int aa = 0; aa < UE->frame_parms.nb_antennas_tx; aa++) {
r_re[aa][i] = ((double)txdata[aa][i].r);
r_im[aa][i] = ((double)txdata[aa][i].i);
}
}
//AWGN
double ip = 0.0;
if ((cfo / scs) != 0.0) {
rf_rx(r_re, // real part of txdata
r_im, // imag part of txdata
NULL, // interference real part
NULL, // interference imag part
0, // interference power
UE->frame_parms.nb_antennas_rx, // number of rx antennas
frame_length_complex_samples, // number of samples in frame
1.0e9/fs, //sampling time (ns)
cfo, // frequency offset in Hz
0.0, // drift (not implemented)
0.0, // noise figure (not implemented)
0.0, // rx gain in dB ?
200, // 3rd order non-linearity in dB ?
&ip, // initial phase
30.0e3, // phase noise cutoff in kHz
-500.0, // phase noise amplitude in dBc
0.0, // IQ imbalance (dB),
0.0); // IQ phase imbalance (rad)
}
for (int i = 0; i < frame_length_complex_samples; i++) {
double sigma2_dB = 20 * log10((double)AMP / 4) - SNR;
double sigma2 = pow(10, sigma2_dB / 10);
for (int aa = 0; aa < UE->frame_parms.nb_antennas_rx; aa++) {
UE->common_vars.rxdata[aa][i].r = (short) (r_re[aa][i] + sqrt(sigma2 / 2) * gaussdouble(0.0,1.0));
UE->common_vars.rxdata[aa][i].i = (short) (r_im[aa][i] + sqrt(sigma2 / 2) * gaussdouble(0.0,1.0));
}
}
int ret = 0;
int n_frames = 1;
if (UE->is_synchronized_sl == 0) {
UE_nr_rxtx_proc_t proc = {0};
LOG_I(NR_PHY,"Running initial synch\n");
ret = nr_sl_initial_sync(&proc, UE, n_frames);
if (ret != 0) {
n_errors++;
}
} else {
LOG_I(NR_PHY,"Already synched, running PSBCH receiver directly\n");
UE_nr_rxtx_proc_t proc = {0};
UE->rx_offset_sl = 0;
uint8_t ssb_index = 0;
const int estimateSz = 7 * 2 * sizeof(int) * UE->frame_parms.ofdm_symbol_size;
__attribute__ ((aligned(32))) struct complex16 dl_ch_estimates[UE->frame_parms.nb_antennas_rx][estimateSz];
__attribute__ ((aligned(32))) struct complex16 dl_ch_estimates_time[UE->frame_parms.nb_antennas_rx][estimateSz];
while (!((SSB_positions >> ssb_index) & 0x01)) {
ssb_index++; // to select the first transmitted ssb
}
UE->symbol_offset = (UE->slss->sl_timeoffsetssb_r16 + UE->slss->sl_timeinterval_r16 * ssb_index) * UE->frame_parms.symbols_per_slot;
uint8_t n_hf = 0;
int ssb_slot = (UE->symbol_offset / 14) + (n_hf * (UE->frame_parms.slots_per_frame >> 1));
const uint32_t rxdataF_sz = UE->frame_parms.samples_per_slot_wCP;
__attribute__ ((aligned(32))) c16_t rxdataF[UE->frame_parms.nb_antennas_rx][rxdataF_sz];
for (int i = UE->symbol_offset; i < UE->symbol_offset + 13; i++) {
nr_slot_fep(UE, &proc, i % UE->frame_parms.symbols_per_slot, rxdataF);
for (int aa=0;aa<UE->frame_parms.nb_antennas_rx;aa++)
memcpy(UE->common_vars.rxdataF[aa],rxdataF,4*rxdataF_sz);
nr_psbch_channel_estimation(UE, estimateSz, dl_ch_estimates, dl_ch_estimates_time, &proc,
0, ssb_slot, i % UE->frame_parms.symbols_per_slot,
i - (UE->symbol_offset), ssb_index % 8, n_hf);
if (i==0) i=4;
}
fapiPsbch_t result;
NR_UE_PDCCH_CONFIG phy_pdcch_config = {0};
/* Side link rx PSBCH */
ret = 0;
ret = nr_rx_psbch(UE,
&proc,
estimateSz,
dl_ch_estimates,
UE->psbch_vars[0],
&UE->frame_parms,
0,
ssb_index % 8,
SISO,
&phy_pdcch_config,
&result);
if (ret == 0) {
int payload_ret = 0;
for (int i = 0; i < NR_POLAR_PSBCH_PAYLOAD_BITS >> 3; i++) {
LOG_I(NR_PHY,"result.decoded_output[i] %d, msgDataTx.ssb[ssb_index].ssb_pdu.ssb_pdu_rel15.bchPayload %d,\n",
result.decoded_output[i], ((msgDataTx.ssb[ssb_index].ssb_pdu.ssb_pdu_rel15.bchPayload >> (8 * (3-i))) & 0xff));
payload_ret += (result.decoded_output[i] == ((msgDataTx.ssb[ssb_index].ssb_pdu.ssb_pdu_rel15.bchPayload >> (8 * (3-i))) & 0xff));
}
if (payload_ret != (NR_POLAR_PSBCH_PAYLOAD_BITS >> 3))
n_errors_payload++;
}
if (ret != 0) {
n_errors++;
}
}
} //noise trials
printf("SNR %f: trials %d, n_errors_crc = %d, n_errors_payload %d\n", SNR, n_trials, n_errors, n_errors_payload);
if (((float)n_errors / (float)n_trials <= target_error_rate) && (n_errors_payload == 0)) {
printf("PSBCH test OK\n");
exitsim=1;
break;
}
if (exitsim == 1) break;
} // NSR
free_psbchsim_members(UE, s_re, s_im, r_re, r_im, txdata, input_fd);
return 0;
}

View File

@@ -48,6 +48,7 @@
#include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h"
#include "executables/nr-uesoftmodem.h"
#include "nfapi/oai_integration/vendor_ext.h"
#include "executables/softmodem-common.h"
THREAD_STRUCT thread_struct;
PHY_VARS_gNB *gNB;
@@ -67,7 +68,10 @@ const short conjugate2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1};
PHY_VARS_NR_UE * PHY_vars_UE_g[1][1]={{NULL}};
uint64_t get_softmodem_optmask(void) {return 0;}
softmodem_params_t *get_softmodem_params(void) {return 0;}
static softmodem_params_t softmodem_params;
softmodem_params_t *get_softmodem_params(void) {
return &softmodem_params;
}
void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) {}
NR_IF_Module_t *NR_IF_Module_init(int Mod_id) { return (NULL); }

View File

@@ -1278,7 +1278,8 @@ int main(int argc, char **argv)
gNB->common_vars.rxdataF[aa],
slot,
0,
gNB->frame_parms.Ncp == EXTENDED ? 12 : 14);
gNB->frame_parms.Ncp == EXTENDED ? 12 : 14,
NR_LINK_TYPE_UL);
}
ul_proc_error = phy_procedures_gNB_uespec_RX(gNB, frame, slot);

View File

@@ -220,15 +220,16 @@ void __attribute__ ((no_sanitize_address)) multipath_channel(channel_desc_t *des
rx_tmp.r += (tx.r * chan[l].r) - (tx.i * chan[l].i);
rx_tmp.i += (tx.i * chan[l].r) + (tx.r * chan[l].i);
}
#if 0
#if 0 // Failing compilation on Ubuntu 16.04
if (i==0 && log_channel == 1) {
printf("channel[%d][%d][%d] = %f dB \t(%e, %e)\n",
ii, j, l, 10 * log10(pow(chan[l].r, 2.0) + pow(chan[l].i, 2.0)), chan[l].r, chan[l].i);
}
#endif
#endif
} //l
} // j
#if 0
#if 0 // Failing compilation on Ubuntu 16.04
if (desc->max_Doppler != 0.0)
rx_tmp = cdMul(rx_tmp, cexp_doppler[i]);
#endif

View File

@@ -451,6 +451,7 @@ typedef struct {
/*!\brief LCID of Carrier component activation/deactivation */
#define CC_ACT_DEACT 27
//TTN (for D2D)
#define MIBSLCH 8
#define SL_DISCOVERY 8 //LCID (fake)
#define MAX_NUM_DEST 10

View File

@@ -823,3 +823,88 @@ void nr_rrc_mac_config_req_scg(module_id_t module_id,
// Setup the SSB to Rach Occasions mapping according to the config
build_ssb_to_ro_map(mac);
}
void print_sl_preconf_params_mac(const NR_SL_PreconfigurationNR_r16_t* sl_preconfigurations,
const NR_SL_FreqConfigCommon_r16_t* freq_conf_cmn)
{
LOG_D(NR_MAC, "sl_OffsetDFN: %lu\n", *(sl_preconfigurations->sidelinkPreconfigNR_r16.sl_OffsetDFN_r16)); // Integer (1 ..1000)
LOG_D(NR_MAC, "sl_NumSSB_WithinPeriod: %lu\n", *(freq_conf_cmn->sl_SyncConfigList_r16->list.array[0]->sl_SSB_TimeAllocation1_r16->sl_NumSSB_WithinPeriod_r16));
LOG_D(NR_MAC, "sl_TimeOffsetSSB: %lu\n", *(freq_conf_cmn->sl_SyncConfigList_r16->list.array[0]->sl_SSB_TimeAllocation1_r16->sl_TimeOffsetSSB_r16));
LOG_D(NR_MAC, "sl_TimeInterval: %lu\n", *(freq_conf_cmn->sl_SyncConfigList_r16->list.array[0]->sl_SSB_TimeAllocation1_r16->sl_TimeInterval_r16));
LOG_D(NR_MAC, "sl_NumSSB_WithinPeriod: %lu\n", *(freq_conf_cmn->sl_SyncConfigList_r16->list.array[0]->sl_SSB_TimeAllocation2_r16->sl_NumSSB_WithinPeriod_r16));
LOG_D(NR_MAC, "sl_TimeOffsetSSB: %lu\n", *(freq_conf_cmn->sl_SyncConfigList_r16->list.array[0]->sl_SSB_TimeAllocation2_r16->sl_TimeOffsetSSB_r16));
LOG_D(NR_MAC, "sl_TimeInterval: %lu\n", *(freq_conf_cmn->sl_SyncConfigList_r16->list.array[0]->sl_SSB_TimeAllocation2_r16->sl_TimeInterval_r16));
LOG_D(NR_MAC, "sl_NumSSB_WithinPeriod: %lu\n", *(freq_conf_cmn->sl_SyncConfigList_r16->list.array[0]->sl_SSB_TimeAllocation3_r16->sl_NumSSB_WithinPeriod_r16));
LOG_D(NR_MAC, "sl_TimeOffsetSSB: %lu\n", *(freq_conf_cmn->sl_SyncConfigList_r16->list.array[0]->sl_SSB_TimeAllocation3_r16->sl_TimeOffsetSSB_r16));
LOG_D(NR_MAC, "sl_TimeInterval: %lu\n", *(freq_conf_cmn->sl_SyncConfigList_r16->list.array[0]->sl_SSB_TimeAllocation3_r16->sl_TimeInterval_r16));
LOG_D(NR_MAC, "sl_SSID: %lu\n", *(freq_conf_cmn->sl_SyncConfigList_r16->list.array[0]->sl_SSID_r16));
LOG_D(NR_MAC, "syncTxThreshIC: %lu\n", *(freq_conf_cmn->sl_SyncConfigList_r16->list.array[0]->txParameters_r16.syncTxThreshIC_r16));
LOG_D(NR_MAC, "syncTxThreshOoC_r16: %lu\n", *(freq_conf_cmn->sl_SyncConfigList_r16->list.array[0]->txParameters_r16.syncTxThreshOoC_r16));
LOG_D(NR_MAC, "buf: %p\n", freq_conf_cmn->sl_SyncConfigList_r16->list.array[0]->txParameters_r16.syncInfoReserved_r16->buf);
LOG_D(NR_MAC, "size: %lu\n", freq_conf_cmn->sl_SyncConfigList_r16->list.array[0]->txParameters_r16.syncInfoReserved_r16->size);
LOG_D(NR_MAC, "bits_unused: %d\n", freq_conf_cmn->sl_SyncConfigList_r16->list.array[0]->txParameters_r16.syncInfoReserved_r16->bits_unused);
LOG_D(NR_MAC, "referenceSubcarrierSpacing: %lu\n", sl_preconfigurations->sidelinkPreconfigNR_r16.sl_PreconfigGeneral_r16
->sl_TDD_Configuration_r16->referenceSubcarrierSpacing);
LOG_D(NR_MAC, "dl_UL_TransmissionPeriodicity: %lu\n", sl_preconfigurations->sidelinkPreconfigNR_r16.sl_PreconfigGeneral_r16
->sl_TDD_Configuration_r16->pattern1.dl_UL_TransmissionPeriodicity);
LOG_D(NR_MAC, "sl_LengthSymbols: %lu\n", *(sl_preconfigurations->sidelinkPreconfigNR_r16.sl_PreconfigFreqInfoList_r16->list.array[0]
->sl_BWP_List_r16->list.array[0]->sl_BWP_Generic_r16->sl_LengthSymbols_r16));
LOG_D(NR_MAC, "sl_StartSymbol: %lu\n", *(sl_preconfigurations->sidelinkPreconfigNR_r16.sl_PreconfigFreqInfoList_r16->list.array[0]
->sl_BWP_List_r16->list.array[0]->sl_BWP_Generic_r16->sl_StartSymbol_r16));
LOG_D(NR_MAC, "sl_SubchannelSize: %lu\n", *(sl_preconfigurations->sidelinkPreconfigNR_r16.sl_PreconfigFreqInfoList_r16->list.array[0]
->sl_BWP_List_r16->list.array[0]->sl_BWP_PoolConfigCommon_r16->sl_RxPool_r16->list.array[0]->sl_SubchannelSize_r16));
LOG_D(NR_MAC, "sl_StartRB_Subchannel_r16: %lu\n", *(sl_preconfigurations->sidelinkPreconfigNR_r16.sl_PreconfigFreqInfoList_r16->list.array[0]
->sl_BWP_List_r16->list.array[0]->sl_BWP_PoolConfigCommon_r16->sl_RxPool_r16->list.array[0]->sl_StartRB_Subchannel_r16));
LOG_D(NR_MAC, "sl_NumSubchannel: %lu\n", *(sl_preconfigurations->sidelinkPreconfigNR_r16.sl_PreconfigFreqInfoList_r16->list.array[0]
->sl_BWP_List_r16->list.array[0]->sl_BWP_PoolConfigCommon_r16->sl_RxPool_r16->list.array[0]->sl_NumSubchannel_r16));
}
int nr_rrc_mac_config_req_ue_sl(module_id_t module_id,
int cc_idP,
const uint32_t * const sourceL2Id,
const uint32_t * const destinationL2Id,
const uint32_t * const groupL2Id,
NR_SL_PreconfigurationNR_r16_t *SL_Preconfiguration_r16,
uint32_t directFrameNumber_r16,
long slotIndex_r16)
{
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
if (SL_Preconfiguration_r16) {
LOG_I(NR_MAC,"Getting SL parameters\n");
mac->SL_Preconfiguration = SL_Preconfiguration_r16;
struct NR_SidelinkPreconfigNR_r16__sl_PreconfigFreqInfoList_r16 *freq_info =
SL_Preconfiguration_r16->sidelinkPreconfigNR_r16.sl_PreconfigFreqInfoList_r16;
//Assumption: Both NR-SL-FreqInfoList and NR-SL-SyncConfigList should have only one element (Spec. 38331 Release 16)
AssertFatal(freq_info->list.count == 1, "Number of elements in NR-SL-FreqInfoList should be 1");
for (int i = 0; i < freq_info->list.count; i++) {
NR_SL_SyncConfigList_r16_t *sync_conf = freq_info->list.array[i]->sl_SyncConfigList_r16;
AssertFatal(sync_conf->list.count == 1, "Number of elements in NR-SL-SyncConfigList should be 1");
for (int j = 0; j < sync_conf->list.count; j++) {
mac->slss.sl_numssb_withinperiod_r16 =
*(sync_conf->list.array[j]->sl_SSB_TimeAllocation1_r16->sl_NumSSB_WithinPeriod_r16);
mac->slss.sl_timeoffsetssb_r16 =
*(sync_conf->list.array[j]->sl_SSB_TimeAllocation1_r16->sl_TimeOffsetSSB_r16);
mac->slss.sl_timeinterval_r16 =
*(sync_conf->list.array[j]->sl_SSB_TimeAllocation1_r16->sl_TimeInterval_r16);
mac->slss.slss_id =
*(sync_conf->list.array[j]->sl_SSID_r16);
}
}
NR_SL_FreqConfigCommon_r16_t *freq_conf_cmn = malloc16_clear(sizeof(NR_SL_FreqConfigCommon_r16_t));
freq_conf_cmn->sl_SyncConfigList_r16 =
mac->SL_Preconfiguration->sidelinkPreconfigNR_r16.sl_PreconfigFreqInfoList_r16->list.array[0]->sl_SyncConfigList_r16;
print_sl_preconf_params_mac(mac->SL_Preconfiguration, freq_conf_cmn);
// TO-DO:: Add discovery mode
}
if (directFrameNumber_r16 < 1025) mac->directFrameNumber_r16 = directFrameNumber_r16;
return 0;
}

View File

@@ -47,6 +47,7 @@
#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
#include "LAYER2/MAC/mac.h"
#include "NR_MAC_COMMON/nr_mac_extern.h"
#include "NR_SL-PreconfigurationNR-r16.h"
/* RRC */
#include "NR_DRX-Config.h"
@@ -63,6 +64,9 @@
#include "NR_MeasConfig.h"
#include "NR_ServingCellConfigCommonSIB.h"
/* PHY */
#include "openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h"
// ==========
// NR UE defs
@@ -487,6 +491,14 @@ typedef struct {
pthread_mutex_t mutex_dl_info;
NR_SL_PreconfigurationNR_r16_t *SL_Preconfiguration;
uint32_t sourceL2Id;
uint32_t groupL2Id;
uint32_t destinationL2Id;
uint32_t directFrameNumber_r16;
int slotIndex_r16;
NR_SLSS_t slss;
} NR_UE_MAC_INST_t;

View File

@@ -112,6 +112,17 @@ void nr_rrc_mac_config_req_sib1(module_id_t module_id,
int cc_idP,
NR_ServingCellConfigCommonSIB_t *scc);
int nr_rrc_mac_config_req_ue_sl(module_id_t module_id,
int cc_idP,
const uint32_t * const sourceL2Id,
const uint32_t * const destinationL2Id,
const uint32_t * const groupL2Id,
NR_SL_PreconfigurationNR_r16_t *SL_Preconfiguration_r16,
uint32_t directFrameNumber_r16,
long slotIndex_r16);
NR_SLSS_t *nr_ue_get_slss(module_id_t Mod_id, int CC_id, frame_t frame_tx, int slot_tx);
/**\brief initialization NR UE MAC instance(s), total number of MAC instance based on NB_NR_UE_MAC_INST*/
NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst);

View File

@@ -89,9 +89,22 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst) {
}
else {
LOG_I(MAC,"Running without CellGroupConfig\n");
if(get_softmodem_params()->sa == 1) {
if (get_softmodem_params()->sa == 1) {
AssertFatal(rlc_module_init(0) == 0, "%s: Could not initialize RLC layer\n", __FUNCTION__);
}
if (get_softmodem_params()->sl_mode == 2) {
module_id_t module_id = 0;
int cc_idP = 0;
uint32_t sourceL2Id, groupL2Id, destinationL2Id;
sourceL2Id = get_softmodem_params()->node_number;
destinationL2Id = 2; //UPDATE it after implementing the ProSeApp connection
groupL2Id = 3; //UPDATE it after implementing the ProSeApp connection
uint32_t directFrameNumber_r16 = 1025; // Set greater than the valid directFrameNumber range (0-1023)
long slotIndex_r16 = 21; // Set greater than the valid slotIndex_r16 range
nr_rrc_mac_config_req_ue_sl(module_id, cc_idP, &sourceL2Id, &destinationL2Id, &groupL2Id,
rrc_inst->SL_Preconfiguration[0],
directFrameNumber_r16, slotIndex_r16);
}
}
return (nr_ue_mac_inst);

View File

@@ -240,6 +240,28 @@ int get_rnti_type(NR_UE_MAC_INST_t *mac, uint16_t rnti)
return rnti_type;
}
void nr_ue_decode_si(module_id_t module_idP, int CC_id, frame_t frameP,
uint8_t gNB_index, void *pdu, uint16_t len,
NR_SLSS_t *slss, int *frame, int *slot)
{
NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
if (slss == NULL) { // this is not MIB-SL
LOG_D(NR_MAC, "[UE %d] Frame %d Sending SI to RRC (LCID Id %d, len %d)\n",
module_idP, frameP, NR_BCCH_BCH, len);
nr_mac_rrc_data_ind_ue(module_idP, CC_id, gNB_index, frameP, 0,
SI_RNTI, NR_BCCH_BCH, (uint8_t *) pdu, len);
} else {
LOG_D(NR_MAC, "[UE %d] Frame %d Sending MIBSL to RRC (LCID Id %d, len %zu) : %x.%x.%x.%x.%x\n",
module_idP, frameP, MIBSLCH, sizeof(slss->sl_mib), slss->sl_mib[0], slss->sl_mib[1], slss->sl_mib[2], slss->sl_mib[3], slss->sl_mib[4]);
nr_mac_rrc_data_ind_ue(module_idP, CC_id, gNB_index, frameP, 0,
SI_RNTI, MIBSLCH, (uint8_t *) slss->sl_mib, sizeof(slss->sl_mib));
LOG_D(NR_MAC, "SL: Resetting SFN.SLOT to %d.%d\n", mac->directFrameNumber_r16, mac->slotIndex_r16);
}
}
int8_t nr_ue_decode_mib(module_id_t module_id,
int cc_id,
@@ -4189,3 +4211,22 @@ int16_t compute_nr_SSB_PL(NR_UE_MAC_INST_t *mac, short ssb_rsrp_dBm)
return pathloss;
}
NR_SLSS_t *nr_ue_get_slss(module_id_t Mod_id, int CC_id, frame_t frame_tx, int slot_tx)
{
NR_UE_MAC_INST_t *mac = get_mac_inst(Mod_id);
NR_SLSS_t *slss = &(mac->slss);
int slots = ((20 * frame_tx) + slot_tx);
if ((slots % 40) != slss->sl_timeoffsetssb_r16) {
slss->sl_mib_length = 0;
} else slss->sl_mib_length = nr_mac_rrc_data_req_ue(Mod_id, CC_id, 0,
slots, MIBCH, slss->sl_mib); // call RRC get check for SL-MIB
if (slss->sl_mib_length > 0) {
LOG_D(NR_MAC, "frame_tx %d, slot %d, slss->sl_TimeOffsetSSB %lu, mib length %d, sl_mib %p\n",
frame_tx, slot_tx, slss->sl_timeoffsetssb_r16, slss->sl_mib_length, slss->sl_mib);
LOG_D(NR_MAC, "MIB-SL : %x.%x.%x.%x.%x\n", slss->sl_mib[0], slss->sl_mib[1], slss->sl_mib[2], slss->sl_mib[3], slss->sl_mib[4]);
}
return(slss);
}

View File

@@ -48,6 +48,7 @@
#include "../nr_rrc_proto.h"
#include "UTIL/OSA/osa_defs.h"
#include "RRC/NR/nr_rrc_extern.h"
#include "RRC/NR_UE/rrc_vars.h"
#include "NR_DL-CCCH-Message.h"
#include "NR_UL-CCCH-Message.h"
#include "NR_DL-DCCH-Message.h"
@@ -192,6 +193,59 @@ int xer_nr_sprint (char *string, size_t string_size, asn_TYPE_descriptor_t *td,
return er.encoded;
}
//------------------------------------------------------------------------------
//TTN for D2D
// NR : 3GPP 38.331 (Section 5.8.5.3)
uint8_t do_MIB_SL_NR(const protocol_ctxt_t* const ctxt_pP, int abs_slot, NR_UE_RRC_INST_t* UE)
{
asn_enc_rval_t enc_rval;
uint16_t frame = abs_slot / 20;
uint8_t slot = abs_slot % 20;
NR_SBCCH_SL_BCH_MessageType_t *sl_mib = &UE->SL_mib_tx;
sl_mib->present = NR_SBCCH_SL_BCH_MessageType_PR_c1;
sl_mib->choice.c1 = CALLOC(1, sizeof(struct NR_SBCCH_SL_BCH_MessageType__c1));
sl_mib->choice.c1->present = NR_SBCCH_SL_BCH_MessageType__c1_PR_masterInformationBlockSidelink;
sl_mib->choice.c1->choice.masterInformationBlockSidelink = CALLOC(1, sizeof(NR_MasterInformationBlockSidelink_t));
NR_MasterInformationBlockSidelink_t *nr_sl_mib = sl_mib->choice.c1->choice.masterInformationBlockSidelink;
if (get_softmodem_params()->sl_mode != 2) {
nr_sl_mib->inCoverage_r16 = 1;
AssertFatal(1 == 0, "Needs development for in %s %d.\n", __FUNCTION__, __LINE__);
} else {
nr_sl_mib->inCoverage_r16 = 0;
nr_sl_mib->sl_TDD_Config_r16.size = 2;
nr_sl_mib->sl_TDD_Config_r16.buf = CALLOC(1, nr_sl_mib->sl_TDD_Config_r16.size);
nr_sl_mib->sl_TDD_Config_r16.bits_unused = 4;
nr_sl_mib->reservedBits_r16.size = 1;
nr_sl_mib->reservedBits_r16.buf = CALLOC(1, nr_sl_mib->reservedBits_r16.size);
nr_sl_mib->reservedBits_r16.bits_unused = 6;
}
nr_sl_mib->directFrameNumber_r16.size = 2;
nr_sl_mib->directFrameNumber_r16.buf = CALLOC(1, nr_sl_mib->directFrameNumber_r16.size);
nr_sl_mib->directFrameNumber_r16.buf[0] = frame & 255;
nr_sl_mib->directFrameNumber_r16.buf[1] = (frame >> 8) & 3;
nr_sl_mib->directFrameNumber_r16.bits_unused = 6;
nr_sl_mib->slotIndex_r16.size = 1;
nr_sl_mib->slotIndex_r16.buf = CALLOC(1, nr_sl_mib->slotIndex_r16.size);
nr_sl_mib->slotIndex_r16.buf[0] = slot;
nr_sl_mib->slotIndex_r16.bits_unused = 1;
if ((frame & 255) == 0)
LOG_D(NR_RRC, "[MIB-SL] sfn %x, slot %x\n", frame, slot);
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_SBCCH_SL_BCH_Message,
NULL,
(void*)&UE->SL_mib_tx,
UE->SL_MIB,
sizeof(UE->SL_MIB));
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
enc_rval.failed_type->name, enc_rval.encoded);
return ((enc_rval.encoded + 7) / 8);
}
//------------------------------------------------------------------------------
uint8_t do_SIB23_NR(rrc_gNB_carrier_data_t *carrier,

View File

@@ -43,6 +43,7 @@
#include "RRC/NR/nr_rrc_defs.h"
#include "RRC/NR/nr_rrc_config.h"
#include "RRC/NR_UE/rrc_defs.h"
/*
@@ -55,6 +56,8 @@
*/
int xer_sprint_NR(char *string, size_t string_size, struct asn_TYPE_descriptor_s *td, void *sptr);
uint8_t do_MIB_SL_NR(const protocol_ctxt_t* const ctxt_pP, int abs_slot, NR_UE_RRC_INST_t* UE);
uint8_t do_SIB23_NR(rrc_gNB_carrier_data_t *carrier,
gNB_RrcConfigurationReq *configuration);

View File

@@ -35,6 +35,8 @@
#include "assertions.h"
#include "rrc_vars.h"
#include "MAC/mac.h"
#include "NR_MAC_UE/mac_defs.h"
#include "../NR/MESSAGES/asn1_msg.h"
typedef uint32_t channel_t;
@@ -50,6 +52,8 @@ nr_mac_rrc_data_ind_ue(
const uint8_t* pduP,
const sdu_size_t pdu_len){
sdu_size_t sdu_size = 0;
protocol_ctxt_t ctxt;
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_id, 0, rnti, frame, sub_frame, gNB_index); // sub_frame is slot for SL
switch(channel){
case NR_BCCH_BCH:
@@ -108,6 +112,14 @@ nr_mac_rrc_data_ind_ue(
}
break;
case MIBSLCH:
LOG_D(NR_RRC, "[UE %d] Received SDU for MIBSL\n", module_id);
if (decode_MIB_SL_NR(&ctxt, (uint8_t* const) pduP, 5) >= 0)
LOG_D(NR_RRC, "Received MIB_SL: %x.%x.%x.%x.%x\n", pduP[0], pduP[1], pduP[2], pduP[3], pduP[4]);
else
LOG_E(NR_RRC, "Received bogus MIB_SL\n");
break;
default:
break;
}
@@ -121,6 +133,9 @@ int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP,
const frame_t frameP,
const rb_id_t Srb_id,
uint8_t *buffer_pP){
protocol_ctxt_t ctxt;
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, Mod_idP, GNB_FLAG_NO, NOT_A_RNTI, frameP / 20, frameP % 20, gNB_id);
int ret_size = 0;
switch(Srb_id){
@@ -138,6 +153,13 @@ int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP,
return NR_UE_rrc_inst[Mod_idP].Srb0[gNB_id].Tx_buffer.payload_size;
case MIBCH:
ret_size = do_MIB_SL_NR(&ctxt, frameP, &NR_UE_rrc_inst[Mod_idP]);
memcpy((void*)buffer_pP, (void*)NR_UE_rrc_inst[Mod_idP].SL_MIB, ret_size);
LOG_D(NR_RRC, "MIB-SL for %d.%d: %x.%x.%x.%x.%x\n",
frameP / 10, frameP % 10, buffer_pP[0], buffer_pP[1], buffer_pP[2], buffer_pP[3], buffer_pP[4]);
return (ret_size);
case DCCH:
AssertFatal(1==0, "SRB1 not implemented yet!\n");
case DCCH1:

View File

@@ -74,6 +74,10 @@
#include "nr_nas_msg_sim.h"
#include <openair2/RRC/NR/nr_rrc_proto.h>
#include "NR_SL-SyncConfig-r16.h"
#include "NR_SL-ResourcePool-r16.h"
#include "NR_SL-BWP-Config-r16.h"
#include "NR_SL-SSB-TimeAllocation-r16.h"
NR_UE_RRC_INST_t *NR_UE_rrc_inst;
/* NAS Attach request with IMSI */
@@ -432,6 +436,157 @@ void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type,
}
void print_sl_preconf_params(NR_SL_PreconfigurationNR_r16_t* sl_preconfigurations,
NR_SL_SyncConfig_r16_t* sl_sync_config,
NR_SL_BWP_ConfigCommon_r16_t* sl_bwp_conf_cmn,
struct NR_SL_ResourcePool_r16* nr_sl_rxpool)
{
LOG_D(NR_RRC, "sl_OffsetDFN: %lu\n", *(sl_preconfigurations->sidelinkPreconfigNR_r16.sl_OffsetDFN_r16));
LOG_D(NR_RRC, "sl_NumSSB_WithinPeriod: %lu\n", *(sl_sync_config->sl_SSB_TimeAllocation1_r16->sl_NumSSB_WithinPeriod_r16));
LOG_D(NR_RRC, "sl_TimeOffsetSSB: %lu\n", *(sl_sync_config->sl_SSB_TimeAllocation1_r16->sl_TimeOffsetSSB_r16));
LOG_D(NR_RRC, "sl_TimeInterval: %lu\n", *(sl_sync_config->sl_SSB_TimeAllocation1_r16->sl_TimeInterval_r16));
LOG_D(NR_RRC, "sl_NumSSB_WithinPeriod: %lu\n", *(sl_sync_config->sl_SSB_TimeAllocation2_r16->sl_NumSSB_WithinPeriod_r16));
LOG_D(NR_RRC, "sl_TimeOffsetSSB: %lu\n", *(sl_sync_config->sl_SSB_TimeAllocation2_r16->sl_TimeOffsetSSB_r16));
LOG_D(NR_RRC, "sl_TimeInterval: %lu\n", *(sl_sync_config->sl_SSB_TimeAllocation2_r16->sl_TimeInterval_r16));
LOG_D(NR_RRC, "sl_NumSSB_WithinPeriod: %lu\n", *(sl_sync_config->sl_SSB_TimeAllocation3_r16->sl_NumSSB_WithinPeriod_r16));
LOG_D(NR_RRC, "sl_TimeOffsetSSB: %lu\n", *(sl_sync_config->sl_SSB_TimeAllocation3_r16->sl_TimeOffsetSSB_r16));
LOG_D(NR_RRC, "sl_TimeInterval: %lu\n", *(sl_sync_config->sl_SSB_TimeAllocation3_r16->sl_TimeInterval_r16));
LOG_D(NR_RRC, "sl_SSID: %lu\n", *(sl_sync_config->sl_SSID_r16));
LOG_D(NR_RRC, "syncTxThreshIC: %lu\n", *(sl_sync_config->txParameters_r16.syncTxThreshIC_r16));
LOG_D(NR_RRC, "syncTxThreshOoC_r16: %lu\n", *(sl_sync_config->txParameters_r16.syncTxThreshOoC_r16));
LOG_D(NR_RRC, "buf: %p\n", sl_sync_config->txParameters_r16.syncInfoReserved_r16->buf);
LOG_D(NR_RRC, "size: %lu\n", sl_sync_config->txParameters_r16.syncInfoReserved_r16->size);
LOG_D(NR_RRC, "bits_unused: %d\n", sl_sync_config->txParameters_r16.syncInfoReserved_r16->bits_unused);
LOG_D(NR_RRC, "referenceSubcarrierSpacing: %lu\n", sl_preconfigurations->sidelinkPreconfigNR_r16.sl_PreconfigGeneral_r16
->sl_TDD_Configuration_r16->referenceSubcarrierSpacing);
LOG_D(NR_RRC, "dl_UL_TransmissionPeriodicity: %lu\n", sl_preconfigurations->sidelinkPreconfigNR_r16.sl_PreconfigGeneral_r16
->sl_TDD_Configuration_r16->pattern1.dl_UL_TransmissionPeriodicity);
LOG_D(NR_RRC, "sl_LengthSymbols: %lu\n", *(sl_bwp_conf_cmn->sl_BWP_Generic_r16->sl_LengthSymbols_r16));
LOG_D(NR_RRC, "sl_StartSymbol: %lu\n", *(sl_bwp_conf_cmn->sl_BWP_Generic_r16->sl_StartSymbol_r16));
LOG_D(NR_RRC, "sl_SubchannelSize: %lu\n", *(nr_sl_rxpool->sl_SubchannelSize_r16));
LOG_D(NR_RRC, "sl_StartRB_Subchannel_r16: %lu\n", *(nr_sl_rxpool->sl_StartRB_Subchannel_r16));
LOG_D(NR_RRC, "sl_NumSubchannel: %lu\n", *(nr_sl_rxpool->sl_NumSubchannel_r16));
}
void init_SL_preconfig_NR(NR_UE_RRC_INST_t *UE, const uint8_t gNB_index)
{
LOG_I(NR_RRC, "Initializing Sidelink Sync configuration for UE\n");
UE->SL_Preconfiguration[gNB_index] = malloc16_clear(sizeof(NR_SL_PreconfigurationNR_r16_t));
UE->SL_Preconfiguration[gNB_index]->sidelinkPreconfigNR_r16.sl_PreconfigFreqInfoList_r16 =
malloc16_clear(sizeof(struct NR_SidelinkPreconfigNR_r16__sl_PreconfigFreqInfoList_r16));
struct NR_SidelinkPreconfigNR_r16__sl_PreconfigFreqInfoList_r16 *freq_info =
UE->SL_Preconfiguration[gNB_index]->sidelinkPreconfigNR_r16.sl_PreconfigFreqInfoList_r16;
NR_SL_FreqConfigCommon_r16_t *freq_conf_cmn = malloc16_clear(sizeof(NR_SL_FreqConfigCommon_r16_t));
freq_conf_cmn->sl_SyncConfigList_r16 = malloc16_clear(sizeof(struct NR_SL_SyncConfigList_r16));
UE->SL_Preconfiguration[gNB_index]->sidelinkPreconfigNR_r16.sl_OffsetDFN_r16 = malloc16_clear(sizeof(long));
*(UE->SL_Preconfiguration[gNB_index]->sidelinkPreconfigNR_r16.sl_OffsetDFN_r16) = 1; // Integer (1 ..1000)
/*IE SL-SyncConfig */
NR_SL_SyncConfig_r16_t *sl_sync_config = malloc16_clear(sizeof(NR_SL_SyncConfig_r16_t));
sl_sync_config->sl_SSB_TimeAllocation1_r16 = malloc16_clear(sizeof(NR_SL_SSB_TimeAllocation_r16_t));
sl_sync_config->sl_SSB_TimeAllocation1_r16->sl_NumSSB_WithinPeriod_r16 = malloc16_clear(sizeof(long));
sl_sync_config->sl_SSB_TimeAllocation1_r16->sl_TimeOffsetSSB_r16 = malloc16_clear(sizeof(long));
sl_sync_config->sl_SSB_TimeAllocation1_r16->sl_TimeInterval_r16 = malloc16_clear(sizeof(long));
*(sl_sync_config->sl_SSB_TimeAllocation1_r16->sl_NumSSB_WithinPeriod_r16) = 1;
*(sl_sync_config->sl_SSB_TimeAllocation1_r16->sl_TimeOffsetSSB_r16) = 1;
*(sl_sync_config->sl_SSB_TimeAllocation1_r16->sl_TimeInterval_r16) = 2;
sl_sync_config->sl_SSB_TimeAllocation2_r16 = malloc16_clear(sizeof(NR_SL_SSB_TimeAllocation_r16_t));
sl_sync_config->sl_SSB_TimeAllocation2_r16->sl_NumSSB_WithinPeriod_r16 = malloc16_clear(sizeof(long));
sl_sync_config->sl_SSB_TimeAllocation2_r16->sl_TimeOffsetSSB_r16 = malloc16_clear(sizeof(long));
sl_sync_config->sl_SSB_TimeAllocation2_r16->sl_TimeInterval_r16 = malloc16_clear(sizeof(long));
*(sl_sync_config->sl_SSB_TimeAllocation2_r16->sl_NumSSB_WithinPeriod_r16) = 1;
*(sl_sync_config->sl_SSB_TimeAllocation2_r16->sl_TimeOffsetSSB_r16) = 1;
*(sl_sync_config->sl_SSB_TimeAllocation2_r16->sl_TimeInterval_r16) = 2;
sl_sync_config->sl_SSB_TimeAllocation3_r16 = malloc16_clear(sizeof(NR_SL_SSB_TimeAllocation_r16_t));
sl_sync_config->sl_SSB_TimeAllocation3_r16->sl_NumSSB_WithinPeriod_r16 = malloc16_clear(sizeof(long));
sl_sync_config->sl_SSB_TimeAllocation3_r16->sl_TimeOffsetSSB_r16 = malloc16_clear(sizeof(long));
sl_sync_config->sl_SSB_TimeAllocation3_r16->sl_TimeInterval_r16 = malloc16_clear(sizeof(long));
*(sl_sync_config->sl_SSB_TimeAllocation3_r16->sl_NumSSB_WithinPeriod_r16) = 1;
*(sl_sync_config->sl_SSB_TimeAllocation3_r16->sl_TimeOffsetSSB_r16) = 1;
*(sl_sync_config->sl_SSB_TimeAllocation3_r16->sl_TimeInterval_r16) = 2;
sl_sync_config->sl_SSID_r16 = malloc16_clear(sizeof(long));
*(sl_sync_config->sl_SSID_r16) = 338 + get_softmodem_params()->node_number;
sl_sync_config->txParameters_r16.syncTxThreshIC_r16 = malloc16_clear(sizeof(long));
*(sl_sync_config->txParameters_r16.syncTxThreshIC_r16) = 0; // INTEGER (0..13)
sl_sync_config->txParameters_r16.syncTxThreshOoC_r16 = malloc16_clear(sizeof(long));
*(sl_sync_config->txParameters_r16.syncTxThreshOoC_r16) = 0; // INTEGER (0..13)
sl_sync_config->txParameters_r16.syncInfoReserved_r16 = malloc16_clear(sizeof(BIT_STRING_t));
sl_sync_config->txParameters_r16.syncInfoReserved_r16->buf = malloc16_clear(sizeof(uint8_t));
sl_sync_config->txParameters_r16.syncInfoReserved_r16->buf = NULL;
sl_sync_config->txParameters_r16.syncInfoReserved_r16->size = 0;
sl_sync_config->txParameters_r16.syncInfoReserved_r16->bits_unused = 1;
ASN_SEQUENCE_ADD(&freq_conf_cmn->sl_SyncConfigList_r16->list, sl_sync_config);
ASN_SEQUENCE_ADD(&freq_info->list, freq_conf_cmn);
freq_info->list.array[0]->sl_BWP_List_r16 =
malloc16_clear(sizeof(struct NR_SL_FreqConfigCommon_r16__sl_BWP_List_r16));
struct NR_SL_FreqConfigCommon_r16__sl_BWP_List_r16 *sl_bwp_list =
freq_info->list.array[0]->sl_BWP_List_r16;
/* TODO SL-PreconfigurationNR, Not all IEs needed for demo*/
UE->SL_Preconfiguration[gNB_index]->sidelinkPreconfigNR_r16.sl_PreconfigGeneral_r16 =
malloc16_clear(sizeof(struct NR_SL_PreconfigGeneral_r16));
UE->SL_Preconfiguration[gNB_index]->sidelinkPreconfigNR_r16.sl_PreconfigGeneral_r16->sl_TDD_Configuration_r16 =
malloc16_clear(sizeof(struct NR_TDD_UL_DL_ConfigCommon));
UE->SL_Preconfiguration[gNB_index]->sidelinkPreconfigNR_r16.sl_PreconfigGeneral_r16
->sl_TDD_Configuration_r16->referenceSubcarrierSpacing = 30;
UE->SL_Preconfiguration[gNB_index]->sidelinkPreconfigNR_r16.sl_PreconfigGeneral_r16
->sl_TDD_Configuration_r16->pattern1.dl_UL_TransmissionPeriodicity = 2;
NR_SL_BWP_ConfigCommon_r16_t *sl_bwp_conf_cmn =
malloc16_clear(sizeof(NR_SL_BWP_ConfigCommon_r16_t));
sl_bwp_conf_cmn->sl_BWP_Generic_r16 =
malloc16_clear(sizeof(struct NR_SL_BWP_Generic_r16));
sl_bwp_conf_cmn->sl_BWP_Generic_r16->sl_LengthSymbols_r16 =
malloc16_clear(sizeof(long));
*(sl_bwp_conf_cmn->sl_BWP_Generic_r16->sl_LengthSymbols_r16) = 0; //sym7=0
sl_bwp_conf_cmn->sl_BWP_Generic_r16->sl_StartSymbol_r16 =
malloc16_clear(sizeof(long));
*(sl_bwp_conf_cmn->sl_BWP_Generic_r16->sl_StartSymbol_r16) = 0;
sl_bwp_conf_cmn->sl_BWP_PoolConfigCommon_r16 =
malloc16_clear(sizeof(struct NR_SL_BWP_PoolConfigCommon_r16));
sl_bwp_conf_cmn->sl_BWP_PoolConfigCommon_r16->sl_RxPool_r16 =
malloc16_clear(sizeof(struct NR_SL_BWP_PoolConfigCommon_r16__sl_RxPool_r16));
struct NR_SL_BWP_PoolConfigCommon_r16__sl_RxPool_r16 *sl_rxpool_list =
sl_bwp_conf_cmn->sl_BWP_PoolConfigCommon_r16->sl_RxPool_r16;
struct NR_SL_ResourcePool_r16 *nr_sl_rxpool =
malloc16_clear(sizeof(struct NR_SL_ResourcePool_r16));
nr_sl_rxpool->sl_SubchannelSize_r16 =
malloc16_clear(sizeof(long));
nr_sl_rxpool->sl_StartRB_Subchannel_r16 =
malloc16_clear(sizeof(long));
nr_sl_rxpool->sl_NumSubchannel_r16 =
malloc16_clear(sizeof(long));
*(nr_sl_rxpool->sl_SubchannelSize_r16) = 10;
*(nr_sl_rxpool->sl_StartRB_Subchannel_r16) = 2;
*(nr_sl_rxpool->sl_NumSubchannel_r16) = 1;
ASN_SEQUENCE_ADD(&sl_rxpool_list->list, nr_sl_rxpool);
ASN_SEQUENCE_ADD(&sl_bwp_list->list, sl_bwp_conf_cmn);
LOG_I(NR_RRC, "Initialization of Sidelink Sync Pre-configuration for UE ... Done\n");
print_sl_preconf_params(UE->SL_Preconfiguration[gNB_index],
sl_sync_config,
sl_bwp_conf_cmn,
nr_sl_rxpool);
}
NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* rrc_config_path){
int nr_ue;
if(NB_NR_UE_INST > 0){
@@ -504,6 +659,8 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* rrc_config_
RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].CSI_SSB_ResourceSet_list, NR_maxNrofCSI_SSB_ResourceSets);
RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].CSI_ResourceConfig_list, NR_maxNrofCSI_ResourceConfigurations);
RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].CSI_ReportConfig_list, NR_maxNrofCSI_ReportConfigurations);
if (get_softmodem_params()->sl_mode != 0)
init_SL_preconfig_NR(&NR_UE_rrc_inst[nr_ue], 0);
}
NR_UE_rrc_inst->uecap_file = uecap_file;
@@ -2833,6 +2990,35 @@ void process_lte_nsa_msg(nsa_msg_t *msg, int msg_len)
}
}
int decode_MIB_SL_NR(const protocol_ctxt_t* const ctxt_pP,
uint8_t* const sdu,
const uint8_t sdu_len)
{
memcpy((void*)&NR_UE_rrc_inst[ctxt_pP->module_id].SL_MIB, (void*)sdu, sdu_len);
asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
&asn_DEF_NR_SBCCH_SL_BCH_Message,
(void **)&NR_UE_rrc_inst[ctxt_pP->module_id].mib_sl[0],
(const void *)sdu,
sdu_len);
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
LOG_E(NR_RRC, "[UE %d] Frame %d : Failed to decode SBCCH_SL_BCH_Message (%zu bytes)\n", ctxt_pP->module_id, ctxt_pP->frame, dec_rval.consumed);
return -1;
}
LOG_D(NR_RRC, "Decoded MIBSL SFN.SLOT %d.%d, InCoverage %d\n",
*(NR_UE_rrc_inst[ctxt_pP->module_id].mib_sl[0]->choice.c1->choice.masterInformationBlockSidelink->directFrameNumber_r16.buf),
*(NR_UE_rrc_inst[ctxt_pP->module_id].mib_sl[0]->choice.c1->choice.masterInformationBlockSidelink->slotIndex_r16.buf),
(int)NR_UE_rrc_inst[ctxt_pP->module_id].mib_sl[0]->choice.c1->choice.masterInformationBlockSidelink->inCoverage_r16);
nr_rrc_mac_config_req_ue_sl(ctxt_pP->module_id, 0, 0, 0, 0,
NULL,
*(NR_UE_rrc_inst[ctxt_pP->module_id].mib_sl[0]->choice.c1->choice.masterInformationBlockSidelink->directFrameNumber_r16.buf),
*(NR_UE_rrc_inst[ctxt_pP->module_id].mib_sl[0]->choice.c1->choice.masterInformationBlockSidelink->slotIndex_r16.buf));
return(0);
}
void *nr_rrc_timers_update() {
while (1) {

View File

@@ -55,6 +55,10 @@
#include "NR_DL-DCCH-Message.h"
#include "../NR/nr_rrc_defs.h"
#include "NR_SBCCH-SL-BCH-Message.h"
#include "NR_SBCCH-SL-BCH-MessageType.h"
#include "NR_SL-PreconfigurationNR-r16.h"
#define NB_NR_UE_INST 1
#define NB_CNX_UE 2//MAX_MANAGED_RG_PER_MOBILE
#define NB_SIG_CNX_UE 2 //MAX_MANAGED_RG_PER_MOBILE
@@ -155,6 +159,20 @@ typedef struct NR_UE_RRC_INST_s {
NR_MIB_t *mib;
NR_SBCCH_SL_BCH_MessageType_t SL_mib_tx;
NR_SBCCH_SL_BCH_MessageType_t *mib_sl[NB_CNX_UE];
uint8_t SL_MIB[5];
NR_SL_PreconfigurationNR_r16_t *SL_Preconfiguration[NB_CNX_UE];
uint32_t sourceL2Id;
uint32_t groupL2Id;
uint32_t destinationL2Id;
//sl_discovery..
NR_SRB_INFO SL_Discovery[NB_CNX_UE];
/* KeNB as computed from parameters within USIM card */
uint8_t kgnb[32];
/* Used integrity/ciphering algorithms */

View File

@@ -173,6 +173,9 @@ void process_lte_nsa_msg(nsa_msg_t *msg, int msg_len);
int get_from_lte_ue_fd();
int decode_MIB_SL_NR(const protocol_ctxt_t* const ctxt_pP,
uint8_t* const sdu,
const uint8_t sdu_len);
/** @}*/
#endif

View File

@@ -188,11 +188,11 @@ void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data,
network_record_t record = networks.items[user_plmns->operators.items[i]].record;
usim_data->pnn[i].fullname.type = USIM_PNN_FULLNAME_TAG;
usim_data->pnn[i].fullname.length = strlen(record.fullname);
strncpy((char*) usim_data->pnn[i].fullname.value, record.fullname,
memcpy((char*) usim_data->pnn[i].fullname.value, record.fullname,
usim_data->pnn[i].fullname.length);
usim_data->pnn[i].shortname.type = USIM_PNN_SHORTNAME_TAG;
usim_data->pnn[i].shortname.length = strlen(record.shortname);
strncpy((char*) usim_data->pnn[i].shortname.value, record.shortname,
memcpy((char*) usim_data->pnn[i].shortname.value, record.shortname,
usim_data->pnn[i].shortname.length);
usim_data->opl[i].plmn = record.plmn;
usim_data->opl[i].start = record.tac_start;