Compare commits

...

324 Commits

Author SHA1 Message Date
Jérôme Härri
71056006a9 update missing sync status at SL MAC 2026-05-11 13:11:56 +02:00
Jérôme Härri
47cf9df46f fixing LC_ID for SL scheduler 2026-05-08 10:32:07 +02:00
Jérôme Härri
3339aa0fac Fix NR sidelink SDAP TUN data path 2026-05-08 09:21:26 +02:00
Jérôme Härri
acfba637cf rebase-sl-eurecom2-v2 with SL V2X mode2 scheduler 2026-05-06 13:27:17 +02:00
Rupanjali
9c9e34d206 Fixed compilation issues 2026-04-01 16:43:58 -04:00
Rupanjali
5559b17fe1 Rebase sl_eurecom2 2026-03-31 16:06:22 -04:00
Ejaz Ahmed
88dfcc8722 Added selected resource percentage support in pre-configurations 2025-06-17 13:51:03 -07:00
Deokseong "David" Kim
3cc086821f Fix bugs in the sensing of available resources and ssb count in Syncref UE. 2025-02-13 19:06:24 -08:00
Ejaz Ahmed
a8b4080383 Updated sampling rate 2025-01-09 14:00:57 -05:00
Ejaz Ahmed
a32aba4ec5 Merge branch 'episys/sl-eurecom2' into sl-eurecom2 2025-01-09 13:24:46 -05:00
Ejaz Ahmed
41552c0ea8 Removed warnings; temporarily fixed timestamp issue 2025-01-09 10:13:57 -08:00
Ejaz Ahmed
762e68c327 Reverted the payload length based num_pssch_tx stats update
We have reverted the payload length based num_pssch_tx stats update because
on the receiver, the payload length information is not available at PHY
layer so we could not update the rx_ok based on payload length
information. Thats why tx stats and rx stats were not matching.
2025-01-08 10:32:53 -08:00
Ejaz Ahmed
737155131b Merge branch 'episys/ea/fixed_decoding_error' into 'episys/sl-eurecom2'
Addressed ldpc decoding problems; fixed formatting issues

See merge request aburger/openairinterface5g!310
2025-01-03 20:50:57 +00:00
Ejaz Ahmed
75cf67dcf2 Modified the ldpc number max iterations loop condition 2025-01-03 12:49:31 -08:00
Laurent THOMAS
ad2c7372e0 remove-cblas-oai-5g 2025-01-03 12:31:05 -08:00
Ejaz Ahmed
65f3dd803f fixed warning; reverted fixed mcs assignment code 2025-01-03 12:08:19 -08:00
Ejaz Ahmed
f1ee81c22e Merge branch 'episys/sl-eurecom2' into episys/ea/fixed_decoding_error 2025-01-03 11:55:00 -08:00
Ejaz Ahmed
56898c81d3 Merge branch 'episys/mel/fixing-build' into 'episys/sl-eurecom2'
Episys/mel/fixing build

See merge request aburger/openairinterface5g!309
2025-01-03 19:53:17 +00:00
Ejaz Ahmed
9b37a05a71 Addressed ldpc decoding problems; fixed formatting issues
Following updates are added:
1) Returned 0, if decoded data is zero
2) Set numIter to 2, if CRC checks passes
3) Fixed formatting issues
2024-12-27 18:49:37 -08:00
Melissa Cusack
b960ede044 Making MCS based on CL and decreasing sampling rate 2024-12-23 17:22:36 -05:00
Melissa Cusack
a60aa4250a Updating usrp_lib.cpp to match develop 2024-12-23 13:27:32 -05:00
Melissa Cusack
6bdcac9e0b Fixing warnings and cleaning up ulsch decoding 2024-12-23 12:51:36 -05:00
Melissa Cusack
50892fa07f Return min_rescource_counter in reselection counter.
Also, this commit adds the phrase "in error" in the NACK log,
in the case of a failed reception. We do this becasue this is
the standard log the team is used to searching for in the logs.
2024-11-27 10:39:49 -08:00
Ejaz Ahmed
6cb94c69bd Merge branch 'episys/mel/debugging-resource-selection' into 'episys/sl-eurecom2'
Passed selected resource in PSSCH scheduling function

See merge request aburger/openairinterface5g!308
2024-11-27 17:13:37 +00:00
Melissa
f44aa9b86e Passed selected resource in PSSCH scheduling function 2024-11-27 17:13:36 +00:00
Melissa
336db01213 Merge branch 'episys/mel/cleanup-ea-branch' into 'episys/sl-eurecom2'
Dynamically configuring TX/RX slot selections

See merge request aburger/openairinterface5g!307
2024-11-21 22:31:35 +00:00
Melissa
a6a6fe043e Dynamically configuring TX/RX slot selections 2024-11-21 22:31:35 +00:00
Melissa
41fc98eda5 Merge branch 'episys/ea/resource_selection' into 'episys/sl-eurecom2'
Implemented Resource Sensing for 5G Sidelink

See merge request aburger/openairinterface5g!302
2024-11-13 16:33:33 +00:00
Ejaz Ahmed
230ebaea70 Added sl_threshold rsrp computation code; removed sensing window duplicated code 2024-11-12 17:34:40 -08:00
Ejaz Ahmed
87348885b4 Added explanation for conditions; provided references; cleaned code 2024-11-12 15:31:51 -08:00
Ejaz Ahmed
9b60e7f4ec Merge branch 'episys/fixing-preconfig-params' into 'episys/ea/resource_selection'
This commit fixes the hardcoded values for the sl_preconfig parameters.

See merge request aburger/openairinterface5g!303
2024-11-12 18:03:34 +00:00
Melissa
ea14ae4a15 This commit fixes the hardcoded values for the sl_preconfig parameters. 2024-11-12 18:03:34 +00:00
Ejaz Ahmed
8c8408ba8f Cleaned code 2024-11-11 12:24:06 -08:00
Ejaz Ahmed
c8ec792c3e Merge branch 'episys/sl-eurecom2' into episys/ea/resource_selection 2024-11-11 08:42:13 -08:00
Ejaz Ahmed
c9486cb4f8 Fixed the issues with candidate resource list 2024-11-10 16:51:56 -08:00
Ejaz Ahmed
30cb74b96c Added TRIV and FRIV 2024-11-09 18:03:19 -08:00
Ejaz Ahmed
c608abe8a1 Completed resource selection function 2024-11-06 21:08:05 -08:00
Ejaz Ahmed
5831ceada3 Implemented initial candidate resource selection code 2024-11-05 19:49:38 -08:00
Melissa
174e39b417 Merge branch 'episys/ea/resource_selection' into 'episys/sl-eurecom2'
Initial implementation of Resource Sensing

See merge request aburger/openairinterface5g!301
2024-11-01 18:52:06 +00:00
Ejaz Ahmed
6ee1ed99a0 Used rsrp as local variable; made consistent variable name 2024-11-01 11:30:33 -07:00
Ejaz Ahmed
e766185363 Removed unused code 2024-11-01 09:18:00 -07:00
Ejaz Ahmed
7dbe690dcf Removed commented code 2024-11-01 09:14:21 -07:00
Ejaz Ahmed
b7e443a2ed Cleaned code 2024-11-01 09:08:24 -07:00
Ejaz Ahmed
95c143657f Added sensing window related configuration params and some functions 2024-10-31 20:18:52 -07:00
Ejaz Ahmed
98ea7cf8a8 Merge branch 'episys/sl-eurecom2' into episys/ea/resource_selection 2024-10-31 15:49:51 -07:00
Ejaz Ahmed
817aeb6e1b Implemented initial structures for sensing window 2024-10-30 19:53:15 -07:00
Melissa Cusack
aaccfe4beb Reverting change that caused traffic to not work
Specifically, there were changes to the dmrs_lowpaprtype1 where we
check if the ref signal exits before freeing. The compiler complained
and said the check was unnecessary, however, without this change
traffic would not work on the PSSCH!
2024-10-28 16:55:16 -04:00
Ejaz Ahmed
3cdd8e2221 Merge branch 'episys/ea/fix_pdu_in_case_of_cno_csirs' into 'episys/sl-eurecom2'
Added NULL value for CSI-RS PHY params in case of no CSI

See merge request aburger/openairinterface5g!300
2024-10-28 18:50:01 +00:00
Ejaz Ahmed
2b6e7e105e Merge branch 'episys/sl-eurecom2' into episys/ea/fix_pdu_in_case_of_cno_csirs 2024-10-28 11:48:58 -07:00
Melissa
39fb255189 Merge branch 'episys/ea/sdap_ip_traffic' into 'episys/sl-eurecom2'
IP traffic sent through 5G sidelink stack

See merge request aburger/openairinterface5g!299
2024-10-28 18:33:39 +00:00
Ejaz Ahmed
e9dd1d9bf0 IP traffic sent through 5G sidelink stack 2024-10-28 18:33:39 +00:00
Ejaz Ahmed
3bf811e903 Properly updated PSSCH stats
Previously, PSSCH stats were computed for both PSSCH and PSFCH.
Now, we look at the payload length to determine if PSSCH is
being transmitted (This can happen with or without PSFCH).
2024-10-28 13:12:15 -04:00
Ejaz Ahmed
3782926ae5 Added NULL value in case of no csi-rs to make the code more robust 2024-10-25 10:28:30 -07:00
Ejaz Ahmed
6ced256931 RMeasured SRP Mand sent it to the AC layer 2024-10-24 14:25:47 -07:00
Melissa
e5f6ec76ec Merge branch 'episys/ea/support_fixed_slots_all_psfch_periods' into 'episys/sl-eurecom2'
Fixed slot mapping; tested on B210; MCS(0-11) PSFCH PERIOD (0,1,2,4)

See merge request aburger/openairinterface5g!298
2024-10-14 23:50:51 +00:00
Ejaz Ahmed
c3b314ab67 Fixed CSI receiver side reporting ldu and padding slength subtractions 2024-10-14 12:34:22 -07:00
Ejaz Ahmed
16bd6d4421 Merge branch 'episys/sl-eurecom2' into episys/ea/support_fixed_slots_all_psfch_periods 2024-10-11 18:03:51 -07:00
Ejaz Ahmed
6e00505f98 Removed Data traffic generating code 2024-10-11 18:01:20 -07:00
Melissa Cusack
bb792807ab episys/fixing-more-warnings 2024-10-11 20:36:41 -04:00
Ejaz Ahmed
852d0dc2b9 Fixed slot mapping; tested on B210; MCS(0-11) PSFCH PERIOD (0,1,2,4)
There are several updates on this commit:
    1) Introduced fixed slot mapping
    2) Enabled support for PSFCH period of 0, 1, 2, and 4 based on fixed
    slot mapping
    3) Fixed Log statements issues
    4) One big difference, which enabled us to run on B210 for MCS from 7 to
    11, was to increase the sleep time in following code. Previously, it was
    100000.

    +    // len = read(nas_sock_fd[0], &rx_buf, NL_MAX_PAYLOAD);
    +#if 1
    +    usleep(1000000);
    +    char msg1[] = "Hello Nearby  UE (from SyncRef UE)";
    +    char msg2[] = "Hello SyncRef UE (from Nearby UE)";
    +    int len1 = sizeof(msg1)/sizeof(msg1[0]);
    +    int len2 = sizeof(msg2)/sizeof(msg2[0]);

    Though we are not pushing this piece of code to our internal master
    branch, it is important to note if we test next time to regenerate
    the same results, we should apply the above change in sleep time.

    The syncref was on 5g-tx, nearby UE was on 5g-Rx

    Attenuation 30 dB

    SyncRef does not receive the correct messages in most of the cases
    Nearby UE receives the correct SLSCH; however, there are higher errors
    for MCS 9-11.

    sci_pdu->mcs = sched_pssch->mcs;
    should be replaced with user provided mcs assignment

    commands:

    sudo LD_LIBRARY_PATH=$PWD/ran_build/build:$LD_LIBRARY_PATH -E ./ran_build/build/nr-uesoftmodem -O ../targets/PROJECTS/NR-SIDELINK/CONF/sl_sync_ref.conf --sa --sl-mode 2 --sync-ref --ue-txgain 10 --ue-rxgain 100 --usrp-args "serial=3150361,type=b200" --thread-pool -1,-1 --mcs 0

    sudo LD_LIBRARY_PATH=$PWD/ran_build/build:$LD_LIBRARY_PATH ./ran_build/build/nr-uesoftmodem -O ../targets/PROJECTS/NR-SIDELINK/CONF/sl_ue1.conf --sa --sl-mode 2 --ue-txgain 10 --ue-rxgain 100 --usrp-args "serial=3150384,type=b200" --thread-pool -1,-1 --mcs 10
2024-10-11 17:27:31 -07:00
Ejaz Ahmed
1f47719f95 Fixed Log statements issues 2024-10-11 17:11:23 -07:00
Ejaz Ahmed
383a573665 Added more logs and updated AssertFatal conditions 2024-10-11 17:10:55 -07:00
Ejaz Ahmed
a376968ba4 Fixed slot mapping; tested on B210; MCS(0-11) PSFCH PERIOD (0,1,2,4)
There are several updates on this commit:
1) Introduced fixed slot mapping
2) Enabled support for PSFCH period of 0, 1, 2, and 4 based on fixed
slot mapping
3) One big difference, which enabled us to run on B210 for MCS from 7 to
11, was to increase the sleep time in following code. Previously, it was
100000.

+    // len = read(nas_sock_fd[0], &rx_buf, NL_MAX_PAYLOAD);
+#if 1
+    usleep(1000000);
+    char msg1[] = "Hello Nearby  UE (from SyncRef UE)";
+    char msg2[] = "Hello SyncRef UE (from Nearby UE)";
+    int len1 = sizeof(msg1)/sizeof(msg1[0]);
+    int len2 = sizeof(msg2)/sizeof(msg2[0]);
+    char *msg = (get_nrUE_params()->sync_ref) ? msg1 : msg2;
+    len = (get_nrUE_params()->sync_ref) ? len1 : len2;
+    memcpy(rx_buf, msg, len);
+    LOG_D(PDCP, "Sending %s\n", msg);
+#endif

Though we are not pushing this piece of code to our internal master
branch, it is important to note if we test next time to regenerate
the same results, we should apply the above change in sleep time.

The syncref was on 5g-tx, nearby UE was on 5g-Rx

Attenuation 30 dB

SyncRef does not receive the correct messages in most of the cases
Nearby UE receives the correct SLSCH; however, there are higher errors
for MCS 9-11.

sci_pdu->mcs = sched_pssch->mcs;
should be replaced with user provided mcs assignment

commands:

sudo LD_LIBRARY_PATH=$PWD/ran_build/build:$LD_LIBRARY_PATH -E ./ran_build/build/nr-uesoftmodem -O ../targets/PROJECTS/NR-SIDELINK/CONF/sl_sync_ref.conf --sa --sl-mode 2 --sync-ref --ue-txgain 10 --ue-rxgain 100 --usrp-args "serial=3150361,type=b200" --thread-pool -1,-1 --mcs 0

sudo LD_LIBRARY_PATH=$PWD/ran_build/build:$LD_LIBRARY_PATH ./ran_build/build/nr-uesoftmodem -O ../targets/PROJECTS/NR-SIDELINK/CONF/sl_ue1.conf --sa --sl-mode 2 --ue-txgain 10 --ue-rxgain 100 --usrp-args "serial=3150384,type=b200" --thread-pool -1,-1 --mcs 10
2024-10-10 12:02:33 -07:00
Ejaz Ahmed
7f7c343856 Added assertion for feedback slot; updated feedback slot in table for period of 4 2024-10-09 14:24:52 -07:00
Ejaz Ahmed
98ae1a296a Fixed bugs with static slot mapping 2024-10-08 18:41:52 -07:00
Ejaz Ahmed
9bab4005fe Added more code for static slot mapping; Added psfch period 1 feedback reception 2024-10-08 11:45:55 -07:00
Ejaz Ahmed
e2746c9e62 Added code for disabling PSFCH 2024-10-08 08:08:10 -07:00
Ejaz Ahmed
20ae13fa41 Merge branch 'episys/sl-eurecom2' into episys/ea/static_feedback_slot_mapping 2024-10-07 15:59:38 -07:00
Ejaz Ahmed
3b520e933b Merge branch 'episys/warning-fixes' into 'episys/sl-eurecom2'
Fixing warnings fournd on episys/sl-eurecom2

See merge request aburger/openairinterface5g!297
2024-10-07 17:30:37 +00:00
Melissa
e214756682 Fixing warnings fournd on episys/sl-eurecom2 2024-10-07 17:30:37 +00:00
Ejaz Ahmed
fb5e590d44 Fixed bit_len_harq; updated ack_nack and nack only conditions 2024-10-07 10:22:57 -07:00
Ejaz Ahmed
bde50f2e63 Added static feedback slot mapping 2024-10-07 09:28:01 -07:00
Ejaz Ahmed
55042e7b9f Updated UE_iterator for Sidelink to SL_UE_iterator and reverted the gNB UE_iterator 2024-10-06 11:49:26 -07:00
Ejaz Ahmed
2fd7150702 Restricted harq bit length to less than or equal to 1
Following changes are incorporated:
1) Restricted harq bit length to less than or equal to 1
2) Removed unused variables to fix warning
3) Fixed Typo
4) Removed unnecessary harq bit length condition
2024-10-05 17:38:09 -07:00
Melissa Cusack
74adc9eeb5 Fixing warnings fournd on episys/sl-eurecom2 2024-10-05 17:40:02 -04:00
Melissa
419eb6c81f Merge branch 'episys/ea/fixed_available_harq_list_updating_procedures' into 'episys/sl-eurecom2'
Fixed available harq list updating procedures issue

See merge request aburger/openairinterface5g!296
2024-10-05 21:00:59 +00:00
Ejaz Ahmed
6873c38471 Fixed available harq list updating procedures issue 2024-10-05 21:00:59 +00:00
Ejaz Ahmed
70d1e6e52c Merge branch 'episys/ea/bler_based_mcs_selection' into 'episys/sl-eurecom2'
Included BLER value in MCS selection criteria; Fixed CSI-RS REs issue if no CSI-RS scheduled

See merge request aburger/openairinterface5g!294
2024-09-25 23:34:21 +00:00
Ejaz Ahmed
8216cbf79a Merge branch 'episys/sl-eurecom2' into episys/ea/bler_based_mcs_selection 2024-09-25 19:30:36 -04:00
Ejaz Ahmed
bd210f9961 Removed unnecessary logs 2024-09-24 22:33:22 -04:00
Ejaz Ahmed
c23170f895 Reverted the unnecessary line spacing 2024-09-23 21:31:58 -04:00
Ejaz Ahmed
ecc78c1bea Reverted debug condition 2024-09-23 21:22:08 -04:00
Ejaz Ahmed
aa57104123 Removed unused header file 2024-09-23 21:06:14 -04:00
Ejaz Ahmed
d09522d616 Removed testing data generating code; mac log dump code; cleaned code 2024-09-23 20:31:58 -04:00
Ejaz Ahmed
a522b2dcb5 Reverted second declaration of csi-rs related variable 2024-09-23 19:45:56 -04:00
Ejaz Ahmed
c53d66f140 Fixed CSI-RS REs issue if there is no CSI-RS scheduled 2024-09-23 19:45:43 -04:00
Ejaz Ahmed
c8b84b8e50 Added logs for testing; Added data code for testing only 2024-09-23 19:44:58 -04:00
Ejaz Ahmed
47a94020cd Included BLER value in MCS selection criteria 2024-09-23 19:42:42 -04:00
Melissa
95b9990ef5 Merge branch 'episys/ea/update_configuration_files' into 'episys/sl-eurecom2'
Updated  configuration files to add CSI reporting parameters

See merge request aburger/openairinterface5g!293
2024-09-19 12:42:06 +00:00
Ejaz Ahmed
16f75be9fd Added updated configuration files 2024-09-13 19:07:39 -04:00
Ejaz Ahmed
aed1eb1841 Merge branch 'episys/ea/updated_sinr_estimation_sinr_cqi_mapping' into 'episys/sl-eurecom2'
Updated sinr estimation function; upgraded sinr to cq mapping function

See merge request aburger/openairinterface5g!292
2024-09-13 21:43:08 +00:00
Ejaz Ahmed
f5511fec98 Adjusteddenominator for noise per sample computation in rfsim; updated comment 2024-09-13 17:41:53 -04:00
Ejaz Ahmed
5db24ade57 Merge branch 'episys/sl-eurecom2' into episys/ea/updated_sinr_estimation_sinr_cqi_mapping 2024-09-13 17:27:14 -04:00
Ejaz Ahmed
171ba6f765 Merge branch 'episys/ea/fixed_higher_mod_order_issue' into 'episys/sl-eurecom2'
Fixed higher mod order llr computation;

See merge request aburger/openairinterface5g!291
2024-09-13 21:25:57 +00:00
Ejaz Ahmed
d6dc49bc4a Added paranethesis for readability 2024-09-13 17:25:25 -04:00
Ejaz Ahmed
302b64cc07 Merge branch 'episys/sl-eurecom2' into episys/ea/fixed_higher_mod_order_issue 2024-09-13 17:17:25 -04:00
Ejaz Ahmed
19d1eb25ba Merge branch 'episys/ea/added_csi_reporting_with_harq' into 'episys/sl-eurecom2'
Implemented HARQ retransmission; Added CSI functionality with HARQ

See merge request aburger/openairinterface5g!290
2024-09-13 21:16:21 +00:00
Ejaz Ahmed
0bcbc7401c Added logs; cleaned code; removed hacked code 2024-09-13 17:15:44 -04:00
Ejaz Ahmed
d56d68332e Changed datatype of mcs, ri nd cqi to uint8_t from int8_t 2024-09-13 16:16:37 -04:00
Ejaz Ahmed
4600b1bba6 Merge branch 'episys/sl-eurecom2' into episys/ea/added_csi_reporting_with_harq 2024-09-13 16:04:22 -04:00
Ejaz Ahmed
c282e8700a Merge branch 'episys/ea/mac_initial_updates' into episys/ea/added_csi_reporting_with_harq 2024-09-13 16:01:58 -04:00
Ejaz Ahmed
5314c750e8 Updated Log filtering condition 2024-09-13 15:59:21 -04:00
Ejaz Ahmed
6e708111d9 Merge branch 'episys/ea/mac_initial_updates' into 'episys/sl-eurecom2'
Updated CSI reporting related initialization

See merge request aburger/openairinterface5g!289
2024-09-13 19:58:40 +00:00
Ejaz Ahmed
fd2ac5a881 Removed slot condition in printing cqi log 2024-09-13 15:30:53 -04:00
Ejaz Ahmed
8fdc275c98 updated default mcs value to 9 2024-09-13 15:28:43 -04:00
Ejaz Ahmed
ae692d25ac Removed commented code 2024-09-13 11:48:37 -04:00
Ejaz Ahmed
1d3b40a602 Reverted spacing 2024-09-13 11:26:21 -04:00
Ejaz Ahmed
e4508b1d01 Updated sinr estimation function; upgraded sinr to cq mapping function
Following features are added:
1) Updated sinr estimation function
2) Upgraded sinr to cq mapping function
2024-09-12 23:36:21 -04:00
Ejaz Ahmed
a2184d2430 Fixed higher mod order llr computation;
Following changes are made:
1) Fixed Higher order llr computation issue
2) Removed remains of PSFCH and CSI-RS concurrent transmission
3) Added default MCS in cqi mcs mapping function
4) Introduced Latency bound for CSI report
5) Cleaned code
2024-09-12 22:59:32 -04:00
Ejaz Ahmed
3645c75ba8 Added CSI functions with HARQ; Fixed bugs came from HARQ implementation
Following functions have been implemented:
1) Integrated CSI reporting with HARQ
2) Fixed feedback frame and slot issue introduced during HARQ implementation
3) Fixed buflen_remain variable condition in case of csi report
4) Removed PSFCH and CSI-RS concurrent transmission as 5g SL does not support it
5) Fixed N_REprime calculation
6) Added default mcs in get_mcs_from_cqi function
7) Code cleanup
2024-09-12 21:07:13 -04:00
Ejaz Ahmed
88032eaa6f MAC initial configuration updates 2024-09-12 19:16:28 -04:00
Melissa
eb7214ed1e Merge branch 'episys/david/using_harq_pid_specified_in_MAC_scheduler' into 'episys/sl-eurecom2'
Update harq pid in PHY layer and added locking mechanism.

See merge request aburger/openairinterface5g!286
2024-08-27 15:09:44 +00:00
Deokseong "David" Kim
9ebfc7df80 Update harq pid in PHY layer and added locking mechanism. 2024-08-27 15:09:44 +00:00
Melissa
c5dd477299 Merge branch 'episys/david/psfch_harq_retransmission' into 'episys/sl-eurecom2'
pssch scheduler update to handle retransmission for HARQ

See merge request aburger/openairinterface5g!285
2024-08-22 19:26:11 +00:00
Deokseong "David" Kim
de8bde2eb1 pssch scheduler update to handle retransmission for HARQ 2024-08-22 19:26:11 +00:00
Ejaz Ahmed
041a74ad55 Merge branch 'episys/sl-eurecom2' into eurecom-sl-eurecom2
Following updates are included in this MR:

1) Updated PSFCH scheduling to make it more flexible to support various SL slot configurations
2) Added channel configuration files for RFSIM
3) Updated sl_sync_ref and sl_ue1 configuration files
4) Fixed TDD initialization issues
5) malloc16_clear() is used instead of malloc()
6) uint16_t *temp_llr is replaced with int16_t *temp_llr
7) SCI1 and SCI2 are separately processed only in case of (qam_mod_order > 2)
8) Fixed argument order issue in nr_cyclic_shift_hopping()
9) Set slot offset to zero in nr_ue_decode_pucch0()
10) Used appropriate format specifiers in psbch_pscch_pssch_processing
11) Formatted logs
2024-08-22 07:33:25 -07:00
Ejaz Ahmed
dd4c1851f3 Merge branch 'episys/ea/psfch_ack_nack_scheduling_rx' into 'episys/sl-eurecom2'
Fixed PSFCH rx related issues

See merge request aburger/openairinterface5g!284
2024-08-21 01:38:25 +00:00
Ejaz Ahmed
665143e3f6 Fixed warnings 2024-08-19 11:43:01 -07:00
Ejaz Ahmed
1a904623e1 Fixed PSFCH rx side issues; Addressed formatting issues 2024-08-19 10:16:11 -07:00
Ejaz Ahmed
c9e48b8ce9 Merge branch 'episys/sl-eurecom2' into pisys/ea/psfch_ack_nack_scheduling_rx 2024-08-19 09:54:08 -07:00
Ejaz Ahmed
2abf30ad6e Merge branch 'episys/ea/psfch_ack_nack_scheduling_tx' into 'episys/sl-eurecom2'
Implementation of psfch tx ack nack scheduling

See merge request aburger/openairinterface5g!283
2024-08-19 16:45:51 +00:00
Ejaz Ahmed
d37bf06d39 Fixed typo in function name; Fixed declaration error 2024-08-19 12:35:07 -04:00
Ejaz Ahmed
eca4d6a572 Provided mcs value from command line; Updated variables and functions names 2024-08-19 12:34:48 -04:00
Ejaz Ahmed
b4b73f2dea Support is provided for MCS 1-16, multiple SLSCH feedbacks and basic HARQ
Updates in this MR are as follows:

1) Enabled support for MCS 1-16; Fixed SNR estimation
2) Added multiple SLSCH feedback support in PSFCH
3) Implemented HARQ process for first transmission and reception
4) Implemented sync notification from nearby to syncref
5) Fixed PSFCH issue in sci_payload in case of psfch_period zero
6) Fixed order of SL UE phy params initializations
7) Moved gNB specific list functions to common file
8) Developed thread lock functions for NR_UE_SL_SCHED
9) Included header files for common moved functions in gNB code
10) Fixed l value in computing alpha for pucch0
11) Fixed warnings
12) cleaned code
2024-08-16 18:34:42 -07:00
Ejaz Ahmed
bc316b1cec Removed worked around code in condition 2024-08-13 19:02:36 -04:00
Ejaz Ahmed
0ff70cc496 Removed worked around code in condition 2024-08-13 18:37:27 -04:00
Ejaz Ahmed
816bfec661 Used Stats appropriate format specifier; working in B210 with tx gain (SyncRef 10, NB 5), rx gain 80 atten. 15 2024-08-13 13:59:56 -07:00
Ejaz Ahmed
e8afaa8cca Removed unnecessary codition 2024-08-13 11:37:32 -04:00
Ejaz Ahmed
f94fe2ac80 Separated tx side functionality changes 2024-08-13 11:22:44 -04:00
Ejaz Ahmed
b1d76e157c Removed trailing spaces 2024-08-12 21:37:23 -04:00
Ejaz Ahmed
eea92750b0 Reverted original spacing 2024-08-12 21:33:17 -04:00
Ejaz Ahmed
3743e20f87 Updated harq feedback function 2024-08-12 20:54:24 -04:00
Ejaz Ahmed
497858ef37 Updated acknack_scheduling function 2024-08-12 18:08:50 -04:00
Ejaz Ahmed
c56f246dd1 Working version with MCS 1 with CBLAS on USRP B210 2024-08-12 17:41:19 -04:00
Ejaz Ahmed
0fae27e94c Updated default mcs value 2024-08-12 17:21:42 +00:00
Ejaz Ahmed
e12bf1500d Cleaned code and logs 2024-08-12 10:12:04 -07:00
Ejaz Ahmed
ba90296301 Updated is_ssynced condition; updated logs 2024-08-12 07:31:25 -07:00
Ejaz Ahmed
9530eefa24 Fixed compute_llr execution in case of Mod order 2 2024-08-08 18:05:10 +00:00
Ejaz Ahmed
ea4ed2abd8 Shift value reverted from 11 to 31 2024-08-08 16:45:14 +00:00
Ejaz Ahmed
aab3fd92f2 Setting ACK/NACK debug environment 2024-08-08 00:58:25 +00:00
Ejaz Ahmed
31985289a2 Added debug logs 2024-08-07 19:03:17 +00:00
Ejaz Ahmed
2c686dd805 Added noise 2024-08-06 20:22:16 +00:00
Laurent THOMAS
368a599dc7 remove-cblas-oai-5g 2024-08-06 20:20:00 +00:00
Ejaz Ahmed
8ab77553ad Fixed check_vcd error 2024-08-05 20:17:00 -04:00
David Kim
0788a62aaf Merge branch 'episys/sl-eurecom2' into episys/david/ack_nack_scheduling_for_USRP_test_gpio_change 2024-08-05 10:06:46 -07:00
Ejaz Ahmed
865df9eea6 Fixed compute_llr crash issue in first symbol code 2024-08-02 18:36:52 -07:00
David Kim
4aa058efd8 Fixed memory free issue. 2024-08-01 17:36:54 -04:00
David Kim
0aa31e7af2 Enabled some log for debug. 2024-08-01 17:19:11 -04:00
David Kim
4c065efd22 GPIO changed. 2024-08-01 16:34:37 -04:00
David Kim
2e5c6f7d8d Disabled LOG_I for USRP test. 2024-08-01 17:35:53 +00:00
Ejaz Ahmed
bb3fb6cbd0 Fixed previous index value of -1 2024-08-01 17:21:46 +00:00
David Kim
b6f04e3ccf Disabled LOG_I. 2024-08-01 17:20:05 +00:00
David Kim
92340ebd77 Disabled LOG_I for USRP test. 2024-07-31 18:50:48 -07:00
Ejaz Ahmed
8c9588739f Working version of HARQ feedback for first tx/rx in rfsim 2024-08-01 01:16:37 +00:00
Ejaz Ahmed
42112e849d Fix in the for multiple PSFCH period 2024-07-30 23:36:08 +00:00
Melissa
c40d0d1cb1 Merge branch 'episys/ea/harq_implementation' into 'episys/sl-eurecom2'
Implementation of HARQ first transmission and reception

See merge request aburger/openairinterface5g!282
2024-07-30 22:32:29 +00:00
Ejaz Ahmed
a1ec6c9ba2 First working version of tx/rx HARQ 2024-07-30 20:49:51 +00:00
Ejaz Ahmed
bcc632dbdd Merge branch 'episys/ea/harq_implementation' of gitlab.int-episci.com:aburger/openairinterface5g into episys/ea/harq_implementation 2024-07-29 15:32:10 +00:00
Ejaz Ahmed
a7f3cd98ec Merge branch 'episys/sl-eurecom2' into episys/ea/harq_implementation 2024-07-29 15:30:48 +00:00
Ejaz Ahmed
16f63c749d TDD memory allocation fixed 2024-07-27 02:21:19 +00:00
David Kim
7e8d791010 harq feedback slot scheduling update. 2024-07-26 15:38:59 -07:00
Ejaz Ahmed
7ed097874a Finding available feedback slot 2024-07-26 19:56:31 +00:00
Ejaz Ahmed
06bccb4087 Merge branch 'episys/sl-eurecom2' into episys/ea/harq_implementation 2024-07-26 19:55:02 +00:00
Melissa
f41b149a58 Merge branch 'episys/ea/rx_multiple_slsch_feedbacks' into 'episys/sl-eurecom2'
Implemented PSFCH RX with support for receiving multiple SLSCH's feedbacks

See merge request aburger/openairinterface5g!281
2024-07-26 18:26:32 +00:00
Ejaz Ahmed
5f829ddb35 Implemented PSFCH RX with support for receiving multiple SLSCH's feedbacks 2024-07-26 18:26:31 +00:00
Ejaz Ahmed
59a69b5020 Added PSFCH feedback slot computation method 2024-07-26 02:49:23 +00:00
Ejaz Ahmed
0845154ef8 Merge branch 'episys/ea/tx_multiple_slsch_feedbacks' into 'episys/sl-eurecom2'
Added Multiple SLSCH feedback support on PSFCH tx side

See merge request aburger/openairinterface5g!280
2024-07-24 20:41:01 +00:00
Ejaz Ahmed
34d2c4d917 Started code for ack nack scheduling 2024-07-24 00:32:52 +00:00
Ejaz Ahmed
9c6c8366af Updated memory allocation 2024-07-23 21:18:12 +00:00
Ejaz Ahmed
d9ede841a1 Fixed warnings 2024-07-23 16:33:19 +00:00
Ejaz Ahmed
47dc503ca6 Aligned code 2024-07-23 14:08:50 +00:00
Ejaz Ahmed
2516b5b3f1 Implemented HARQ process for first transmission and reception; cleaned code 2024-07-23 01:31:02 +00:00
Ejaz Ahmed
e6e925f9ab Removed HARQ related preconfigurations 2024-07-22 17:54:33 +00:00
Ejaz Ahmed
105f2b57ef Fixed slot conflicts in sidelink scheduler; Addressed formatting issues 2024-07-22 17:25:55 +00:00
Ejaz Ahmed
848e380cd0 Implemented PSFCH RX with support for receiving multiple SLSCH's feedbacks 2024-07-22 17:21:57 +00:00
Ejaz Ahmed
1cacd66352 Reverted line spacing 2024-07-22 16:42:17 +00:00
Ejaz Ahmed
286ef21839 Removed redudant slot from sidelink scheduler 2024-07-22 16:31:48 +00:00
Ejaz Ahmed
e88f0f5539 Fixed l value in computing alpha for pucch0 2024-07-22 16:28:47 +00:00
Ejaz Ahmed
b1d830adc2 Added multiple SLSCH feedback support in PSFCH 2024-07-22 16:25:37 +00:00
Ejaz Ahmed
36a29714ff Merge branch 'episys/ea/harq_structures_and_initialization' into 'episys/sl-eurecom2'
Created initial data structures for HARQ

See merge request aburger/openairinterface5g!278
2024-07-19 22:55:34 +00:00
Ejaz Ahmed
9fd148dedd Reverted MAX_SL_UE_CONNECTIONS default value 2024-07-11 20:12:45 +00:00
Ejaz Ahmed
378e6f5643 Merge branch 'episys/sl-eurecom2' into episys/ea/harq_structures_and_initialization 2024-07-11 20:01:13 +00:00
Melissa
15f8f5aeea Merge branch 'episys/ea/nearby_ue_sync_ref_ue_indication' into 'episys/sl-eurecom2'
Added code to send sync information from nearby to syncref

See merge request aburger/openairinterface5g!277
2024-07-11 19:08:35 +00:00
Ejaz Ahmed
f776b88d7f Created initial data structures for HARQ
Following changes are made:
1) Added essential data structures for HARQ
2) Moved gNB specific list functions to common file
3) Implemented preconfigurations for HARQ
4) Developed thread lock functions for NR_UE_SL_SCHED
5) Included header files for common moved functions in gNB code
2024-07-10 22:49:03 +00:00
Ejaz Ahmed
ea9289b2de Fixed order of SL UE phy params initializations 2024-07-10 20:11:10 +00:00
Ejaz Ahmed
30ce40cf03 Fixed PSFCH issue in sci_payload in case of psfch_period zero 2024-07-10 19:51:30 +00:00
Ejaz Ahmed
23300df806 Fixed line spacing 2024-07-10 18:10:03 +00:00
Ejaz Ahmed
d9acb85bfa Added PSFCH in sci_payload 2024-07-10 17:58:43 +00:00
Ejaz Ahmed
ec7b44e6dd Added code to send synchronization information from nearby to syncref
Added code to send synchronization information from nearby to syncref
within reserved bit of sci1. Syncref starts sending SLSCH once syncref
receives synchronization information.
2024-07-08 19:58:36 +00:00
Melissa
076c83b6f2 Merge branch 'episys/ea/Fixed_SNR_and_MCS_1_16_issues' into 'episys/sl-eurecom2'
Enabled support for MCS 1-16; Fixed SNR estimation

See merge request aburger/openairinterface5g!276
2024-06-20 13:49:47 +00:00
Ejaz Ahmed
616f759661 Enabled support for MCS 1-16; Fixed SNR estimation 2024-06-20 13:49:47 +00:00
matilde.costa
61e62abb7f Added non-ip types to ip_traffic_type_t 2024-06-06 14:06:28 +00:00
Ejaz Ahmed
281dc32c26 Updated confurations; formatted logs 2024-06-06 14:03:33 +00:00
Ejaz Ahmed
bb35caebed Fixed interface's name conflicts; restricted tx and rx operations in specific slots to fix an issue in USRP. 2024-06-06 13:56:59 +00:00
Melissa
1ff86924ff Merge branch 'episys/ea/usrp_debugging_psfch_csi_rs' into 'episys/sl-eurecom2'
Fixed interface's name conflicts; restricted tx and rx  operations in specific slots to fix an issue in USRP.

See merge request aburger/openairinterface5g!274
2024-05-30 22:38:11 +00:00
Ejaz Ahmed
e13e26759e Fixed interface's name conflicts; restricted tx and rx operations in specific slots to fix an issue in USRP. 2024-05-30 22:38:11 +00:00
matilde.costa
9588e10de0 Added non-ip types to ip_traffic_type_t 2024-05-17 14:58:54 +02:00
Ejaz Ahmed
885d5cd426 Updated logs & fixed spacing issues 2024-05-03 16:48:43 -07:00
Matilde Costa
6536425c4b rlc/pdcp threads with -1 affinity 2024-05-03 16:30:53 -07:00
Ejaz Ahmed
c7e08dffbe Added separate conf files for sync_ref & nearby ue; reverted tx scheduling conditions 2024-05-03 16:23:03 -07:00
Ejaz Ahmed
d2475e0dd6 Added separate conf files for sync_ref & nearby ue; reverted tx scheduling conditions 2024-05-01 16:46:52 -07:00
Ejaz Ahmed
c584baf9e1 Merge branch 'episys/sl-eurecom2' into eurecom/sl-eurecom2
Following modifications are included in this merge:
1) Implemented CSI reporting
2) Developed a measurement function of SNR and computed CQI based on
that
3) Simplified functions
4) Improved logging
5) Cleaned code
6) Fixed pointers issues
2024-04-30 10:52:54 -07:00
Melissa
6fcda3dcc0 Merge branch 'episys/ea/5g_sidelink_csi' into 'episys/sl-eurecom2'
Implemented measurement of SNR and computed CQI; Updated tx and rx code of CSI reporting

See merge request aburger/openairinterface5g!273
2024-04-30 15:50:27 +00:00
Ejaz Ahmed
3e81184deb Implemented measurement of SNR and computed CQI; Updated tx and rx code of CSI reporting 2024-04-30 15:50:27 +00:00
matilde.costa
4e2b8ddb92 fix nas_config in rrc sl preconfiguration for tun interface name 2024-04-25 15:39:15 +02:00
Matilde Costa
e8ca12049a rlc/pdcp threads with -1 affinity 2024-04-25 11:08:02 +02:00
Raymond Knopp
e9ff59611d check of PSFCH pointer in ue_scheduler 2024-04-28 21:42:27 +02:00
Raymond Knopp
fb6baf3f76 check for PSFCH pointer definition 2024-04-28 21:26:19 +02:00
Raymond Knopp
18e9694f31 more debugging removal 2024-04-22 16:19:47 +02:00
Raymond Knopp
183e029c8c removed some logging 2024-04-22 16:16:37 +02:00
Raymond Knopp
da97a8f016 debugging info 2024-04-22 15:47:24 +02:00
Raymond Knopp
1a470d5af6 logging for debug 2024-04-26 16:52:15 +02:00
Ejaz Ahmed
c4250dcd2b Fixed MAC subpdu header; fixed multiple interface issue 2024-04-19 11:56:47 -07:00
Ejaz Ahmed
4c4a667fd6 Bug fixed and freed memorey in case of no psfch; set two interfaces 2024-04-19 11:31:44 -07:00
Melissa
da6f3251f3 Merge branch 'episys/ea/fix_mac_subheaders_length_issue' into 'episys/sl-eurecom2'
Fixed NR_SLSCH_MAC_SUBHEADER processing issue

See merge request aburger/openairinterface5g!272
2024-04-19 16:53:50 +00:00
Raymond Knopp
c534570eec added srcid to nas_config for SL 2024-04-19 16:27:32 +02:00
Raymond Knopp
9642a70e6d testing and bugfixing 2024-04-19 16:10:35 +02:00
Raymond Knopp
1c84699e00 handled freeing of PSFCH information in case PSFCH_Period = 0 2024-04-23 06:07:18 +02:00
Ejaz Ahmed
9d8db83ebd Fixed spacing 2024-04-18 16:11:54 -07:00
Ejaz Ahmed
9ceb3ddf93 Merge branch 'episys/sl-eurecom2' into episys/ea/fix_mac_subheaders_length_issue 2024-04-18 16:08:07 -07:00
Melissa
289991b0fe Merge branch 'episys/ea/fix_errors_with_disabled_psfch' into 'episys/sl-eurecom2'
Enabled No PSFCH Support

See merge request aburger/openairinterface5g!271
2024-04-18 22:21:44 +00:00
Ejaz Ahmed
38a43f3be6 Updated comment 2024-04-18 13:06:40 -07:00
Ejaz Ahmed
6fc72eae0f Reverted the debugging logs 2024-04-18 13:00:58 -07:00
Ejaz Ahmed
14420f24cb Additional conditions on rx csi-rs scheduling 2024-04-18 11:59:50 -07:00
Ejaz Ahmed
53aa746075 Fixing errors in case of 12 PSSCH symbols and 3 PSCCH channels 2024-04-17 19:50:15 -07:00
Ejaz Ahmed
4e10e4fa2c Fixed MAC subPDU header length issue 2024-04-17 11:59:34 -07:00
Ejaz Ahmed
9879c13cd4 Added option in conf file to activate/deactivate csi-rs 2024-04-17 10:36:00 -07:00
Ejaz Ahmed
63454cebf8 Added option in conf file to activate/deactivate csi-rs 2024-04-17 10:30:31 -07:00
Ejaz Ahmed
813b600305 Implemented CSI-RS transmission and reception. 2024-04-16 19:26:01 -07:00
Ejaz Ahmed
9f9dadf621 Replaced slots per frame variable to use appropriate one 2024-04-16 19:25:23 -07:00
Melissa
bb13bfa195 Merge branch 'episys/ea/5g_sidelink_csi_rs' into 'episys/sl-eurecom2'
Implemented CSI-RS transmission and reception.

See merge request aburger/openairinterface5g!270
2024-04-16 22:43:25 +00:00
Ejaz Ahmed
ee7244ca05 Implemented CSI-RS transmission and reception. 2024-04-16 22:43:25 +00:00
Ejaz Ahmed
05604174e0 Replaced slots per frame variable to use appropriate one 2024-03-19 12:22:35 -07:00
Ejaz Ahmed
cbcd09cbca Merge branch 'episys/ea/mac_headers_validation' into episys/sl-eurecom2 2024-02-23 08:35:42 -08:00
Ejaz Ahmed
4af8be50bd Added condition to check remaining buffer before creating MAC CE 2024-02-23 08:34:43 -08:00
Ejaz Ahmed
ef9f804da7 Adjusted loop execution to fix muliple SDUs placement before MAC CEs and padding 2024-02-22 14:30:41 -08:00
Ejaz Ahmed
a465e39bb9 Fixed issue with multiple SDUs placement before MAC CEs 2024-02-22 14:14:56 -08:00
Melissa
3370570ecd Merge branch 'episys/ea/mac_headers_validation' into 'episys/sl-eurecom2'
Added SLSCH MAC sub-header, updated MAC sub-headers based on spec. 38321

See merge request aburger/openairinterface5g!269
2024-02-22 00:22:39 +00:00
Ejaz Ahmed
29b74e7410 Added SLSCH MAC sub-header, updated MAC sub-headers based on spec. 38321 2024-02-22 00:22:39 +00:00
Ejaz Ahmed
3fa03965a1 reverted some changes; added sec label, modified variable name 2024-02-21 11:49:31 -08:00
Ejaz Ahmed
d7b1a78e71 Merge branch 'episys/sl-eurecom2' into episys/ea/mac_headers_validation
Following changes are made:
1) Added instructions in rfsim README.md for running
rfsimulator with updated sl_preconfiguration.conf location
2024-02-21 11:32:25 -08:00
Ejaz Ahmed
a2e75e10d3 Merge branch 'eurecom/sl-eurecom2' into episys/sl-eurecom2 2024-02-21 11:30:54 -08:00
Ejaz Ahmed
714629c26f Added SLSCH MAC subheader, updated MAC subheaders based on spec. 38321
Following changes are made:
1) Added SLSCH MAC subheader
2) Validated MAC SDU subheader
3) Added SL_BSR subheader
4) Modified & validated MAC subheaders processing on tx and rx
2024-02-21 11:17:13 -08:00
Ejaz Ahmed
9e686e448d 5G sidelink PSFCH Tx implementation
Updates covered in this commit:
1) Computed feedback slot based on PSFCH time gap, PSFCH period and HARQ
	    feedback
2) Generated PSFCH pdu
3) Implemented PSFCH scheduling
4) Allocated PRBs based on slot and subchannel
5) Updated data structures accordingly
6) Modified configuration computation for PSFCH PRB set
7) Changed computation for number of PSFCH symbols
8) Moved sl_preconfiguration.conf under NR-SIDELINK/CONF
2024-02-16 10:50:02 -08:00
Melissa
5a88bb670a Merge branch 'episys/ea/psfch_configurations' into 'episys/sl-eurecom2'
Removed send_psfch_with_pucch command line argument

See merge request aburger/openairinterface5g!267
2024-02-16 09:13:22 -08:00
Melissa
b4a314b64e Updated prconfiguration code & Moved configuration file 2024-02-16 09:13:01 -08:00
Deokseong "David" Kim
6be609a59f picked 907130d9 2024-02-16 09:00:36 -08:00
Ejaz Ahmed
69c357655e Fixed spacing issue 2024-02-15 10:20:55 -08:00
Melissa
45dd2a7fb0 Merge branch 'episys/ea/tx_psfch' into 'episys/sl-eurecom2'
PSFCH Tx implementation: PSFCH PDU generation, scheduling and PRBs allocation

See merge request aburger/openairinterface5g!268
2024-02-15 16:30:42 +00:00
Ejaz Ahmed
b5dd8de98f PSFCH Tx implementation: PSFCH PDU generation, scheduling and PRBs allocation 2024-02-15 16:30:42 +00:00
Melissa
a42a4d1a06 Merge branch 'episys/ea/psfch_configurations' into 'episys/sl-eurecom2'
Removed send_psfch_with_pucch command line argument

See merge request aburger/openairinterface5g!267
2024-01-30 16:50:45 +00:00
Ejaz Ahmed
3c485239ba Removed resetting of psfch based on pucch based psfch transmission 2024-01-30 16:46:22 +00:00
Ejaz Ahmed
14b972e878 Removed header file 2024-01-30 16:44:25 +00:00
Ejaz Ahmed
aff9391806 Merge branch 'episys/sl-eurecom2' into episys/ea/psfch_configurations 2024-01-30 16:43:41 +00:00
Ejaz Ahmed
c734cfab93 Removed help MACRO for command line psfch argument 2024-01-30 16:30:14 +00:00
Ejaz Ahmed
3dd8395c8f Removed flag for send_psfch_with_pucch 2024-01-30 16:24:03 +00:00
Ejaz Ahmed
99a750d672 Merge branch 'episys/ea/psfch_configurations' of gitlab.int-episci.com:aburger/openairinterface5g into episys/ea/psfch_configurations 2024-01-30 15:09:46 +00:00
Ejaz Ahmed
82dfb5c4ec Reverteunnecessary changes 2024-01-30 15:09:13 +00:00
Melissa
7fd180f30b Merge branch 'episys/ea/psfch_configurations' into 'episys/sl-eurecom2'
Added functionality to read PSFCH configurations from conf file

See merge request aburger/openairinterface5g!266
2024-01-30 15:09:11 +00:00
Ejaz Ahmed
f52f258eec Added functionality to read PSFCH configurations from conf file 2024-01-30 15:09:11 +00:00
Melissa Elkadi
fdad2f7d17 Fixing more white space 2024-01-30 13:59:32 +00:00
Melissa Elkadi
1245c05385 Reverting whitespace changes 2024-01-30 13:58:00 +00:00
Melissa Elkadi
e534761719 updating the name of psfch_pucch variable and clean up 2024-01-30 13:54:13 +00:00
Ejaz Ahmed
2976628409 Added PSFCH configurations; Ignored number of psfch symbols
a) Added PSFCH configurations in conf file for TX resource pool;
b) In case of pucch based psfch transmission, ignored number of psfch
symbols for number of pssch symbols calculation
2024-01-30 02:59:55 +00:00
Ejaz Ahmed
34aede6ee5 Moved conf file to conf directory; long bit replace with hex numbers 2024-01-27 17:32:28 +00:00
Ejaz Ahmed
d2bbbb16ad Temporarily Removed number of PSFCH symbols from number of PSSCH symbhols computation 2024-01-26 21:05:49 +00:00
Ejaz Ahmed
7e83f75d21 Added functionality to take PSFCH Preconfigurations from conf file 2024-01-26 20:36:53 +00:00
Ejaz Ahmed
c4706eda69 Added further logs 2024-01-25 19:56:47 +00:00
Ejaz Ahmed
28f2129d3e Added harq_feedback condition; Added more logs 2024-01-25 17:14:57 +00:00
Ejaz Ahmed
238a7837cf Added updated configuration file for psfch 2024-01-24 20:25:40 +00:00
Ejaz Ahmed
e474090459 Added sl_preconfiguration file 2024-01-24 18:44:10 +00:00
Ejaz Ahmed
6f5205ec1c Commented out Rx to Tx notification mechanism; added configurations 2024-01-24 18:38:38 +00:00
Ejaz Ahmed
f5250c1ec4 Added but commented out due to issue with slsch reception 2024-01-23 21:22:43 +00:00
Ejaz Ahmed
156b806abb Updated code for psfch tx side 2024-01-15 22:49:53 +00:00
Ejaz Ahmed
d4e030cc3b Added more parameters in psfch pdu 2024-01-09 02:04:07 +00:00
Ejaz Ahmed
cb17a2530c Added Pre-configurations, created psfch pdu, scheduled psfch for transmission 2024-01-06 01:37:14 +00:00
Deokseong "David" Kim
907130d999 Merge branch 'episys/ea/fixed_pscch_slot_conflict_psbch' into 'episys/sl-eurecom2'
Fixed issue with reception of PSBCH

See merge request aburger/openairinterface5g!265
2023-12-21 18:03:08 +00:00
Ejaz Ahmed
d201d89c94 Fixed issue with reception of PSBCH 2023-12-21 18:03:08 +00:00
Raymond Knopp
5cc6d9e5c3 Merge branch 'sl-eurecom2' of https://gitlab.eurecom.fr/oai/openairinterface5g into sl-eurecom2 2023-10-14 07:19:44 +02:00
Raymond Knopp
1a815f7e15 warnings 2023-10-14 07:19:29 +02:00
ue1
05cb48d29c GPIO changes 2023-10-13 16:00:35 -04:00
Raymond Knopp
911bd2be5d removed some assertions after bogus reception of PSCCH 2023-10-13 16:34:24 +02:00
ue1
5ea68eb132 Merge branch 'sl-eurecom2' of https://gitlab.eurecom.fr/oai/openairinterface5g into sl-eurecom2 2023-10-13 09:36:05 -04:00
ue1
94188666ce removed some assertions 2023-10-13 09:35:43 -04:00
Raymond Knopp
a6d86ea8c9 Merge branch 'sl-eurecom2' of https://gitlab.eurecom.fr/oai/openairinterface5g into sl-eurecom2 2023-10-13 09:12:33 -04:00
Raymond Knopp
d3702751ec removal of logs 2023-10-13 09:12:13 -04:00
ue1
63b3d8a92f testing 2023-10-13 08:25:31 -04:00
Raymond Knopp
597c897977 improving stat 2023-10-13 06:33:18 -04:00
Raymond Knopp
d1bbbb5dd3 analytics of PSCCH/PSSCH 2023-10-12 11:50:16 +02:00
Raymond Knopp
18853ab6cc supression of logs 2023-10-12 08:11:06 +02:00
Raymond Knopp
9cc948635c Merge branch 'sl-eurecom2' of https://gitlab.eurecom.fr/oai/openairinterface5g into sl-eurecom2 2023-10-12 07:41:57 +02:00
Raymond Knopp
93d4a07932 TX path MAC PDU fix 2023-10-12 07:41:35 +02:00
Raymond Knopp
6bfe76b086 MAC pdu fixes, testing RX patch of rlc/pdcp/sdap 2023-10-12 07:40:39 +02:00
Raymond Knopp
e568b2c85a fix for MAC subheader handling in SL 2023-10-12 00:35:49 +02:00
Raymond Knopp
435b636d89 minor changes 2023-10-11 22:20:12 +02:00
Raymond Knopp
84504a38a0 small fixes for LCID/SLRB ids 2023-10-11 06:28:31 -04:00
ue1
4bd3007565 removal of many debugging logs, added pscch/pssch statistics, TX/RX switching time increase (3->4 slots 2023-10-11 05:25:12 -04:00
Raymond Knopp
dad4240016 merged pdcp/rlc components to current L1/L2 2023-10-09 23:08:11 +02:00
Raymond Knopp
2cda03b016 compilation ok 2023-10-09 22:44:08 +02:00
Raymond Knopp
198c319788 intermediate commit 2023-10-05 21:20:58 +02:00
Raymond Knopp
18d720f377 fixed issue with demux of SCI1/SCI2/SLSCH in SLSCH receiver. Added skeleton for MAC parsing on RX for SL. 2023-10-02 02:58:40 +02:00
Raymond Knopp
ba6a8554a3 minor changes 2023-09-28 21:14:48 +02:00
Raymond Knopp
ffda9c758a removed logs and added a bit more temporary debugging for SCI2 2023-09-18 15:49:13 +02:00
Raymond Knopp
60a7eb326c adding color defs for printing 2023-09-18 10:07:37 +02:00
Raymond Knopp
6a5a9f18bf testing sci2/slsch 2023-09-18 09:34:51 +02:00
Raymond Knopp
4bf5166aed integration of PSSCH with PUSCH TX 2023-09-07 21:38:38 +02:00
Raymond Knopp
d4e30b972b PSCCH RX testing 2 2023-08-25 09:19:13 +02:00
Raymond Knopp
858a13119b sci1a RX testing 2023-08-24 21:56:32 +02:00
Raymond Knopp
5b16b58496 debugging memory leaks 2023-08-22 00:27:26 +02:00
Raymond Knopp
0588003034 testing SCI1A 2023-08-21 21:02:30 +02:00
Raymond Knopp
b8d9da2e81 sci/slsch mac step1 2023-08-19 08:58:44 +02:00
Raymond Knopp
8199a1e093 fixes after merge with NR_SL_PSBCH_2 2023-08-03 23:26:54 +02:00
Raymond Knopp
7efe5880a1 Merge branch 'NR_SL_PSBCH_2' into sl-eurecom2 2023-08-03 15:50:49 +02:00
Raymond Knopp
b9caf3ecc4 Merge branch 'NR_SL_PSBCH_2' of https://gitlab.eurecom.fr/oai/openairinterface5g into NR_SL_PSBCH_2 2023-08-03 15:50:02 +02:00
Raghavendra Dinavahi
4ca508228f Enable SCOPE for PSBCH
- PSBCH LLR, PSBCH IQ, PSBCH RSRP, CIR added in scope.
	- use --dqt or --d  option to enable scope on the RX UE
	- -d option does not show RSRP
2023-08-03 14:55:16 +02:00
Raymond Knopp
9ecd473a41 Merge branch 'sl_eurecom_integration' into sl-eurecom2
Conflicts:
	CMakeLists.txt
2023-08-03 10:21:42 +02:00
Raymond Knopp
f32c759ecf modifications to allow running SL without --phy-test flag 2023-08-03 10:19:07 +02:00
Raghavendra Dinavahi
88b6cdd209 Changes for Sidelink RFSIM testing
- UE1 is a SYNC REFERENCE UE - TX PSBCH
	   started using command -
		sudo RFSIMULATOR=server ./nr-uesoftmodem --rfsim --phy-test --sl-mode 2 --sync-ref
	- UE2 syncs onto UE1 - RX PSBCH and continues to receive PSBCH
	   started using command -
		sudo ./nr-uesoftmodem --rfsim --phy-test --sl-mode 2
	- In the default use case 2 Sidelink SSBs sent over 16 frames.
2023-08-02 02:30:21 +02:00
Raghavendra Dinavahi
8bb2f3991b Sidelink SLSS SEARCH Procedure 2023-08-02 02:28:25 +02:00
Raghavendra Dinavahi
4d369a6993 Sidelink config MAC->PHY, PSBCH scheduler and supporting functions
- Phy config update and Sidelink frame parameters initialisation
	- PSBCH scheduler to trigger TX PSBCH/RX PSBCH actions
	- Sidelink indication with rx ind to trigger send SL-MIB to MAC
2023-08-02 02:28:25 +02:00
Raghavendra Dinavahi
70f586cb3c Sidelink configuration passed from RRC->MAC, defined interface functions
- Phy configuration will be prepared by MAC
	- Sidelink preconfiguration parameters passed from RRC->MAC
	- Only 1 SSB TA allocation used
	- psbch payload prepared by MAC after receiving the tx slss req
2023-08-02 02:28:25 +02:00
Raghavendra Dinavahi
745cc733ea PSBCH RX TX changes
- RX/TX Phy processing accg to 38.211, 38.212 Rel16
	- Rate matching fix from Ralf to address 1782 bits
		- do not try to group the last bits, process them manually
	- PSBCH simulator used to validate TX/RX phy processing
2023-08-02 02:28:25 +02:00
Raymond Knopp
ee7aacf2ca sci development 2023-07-26 21:08:48 +02:00
Raymond Knopp
fef6303cc9 initial commit of SCI encoding 2023-07-22 23:07:11 +02:00
72 changed files with 9083 additions and 346 deletions

View File

@@ -980,6 +980,8 @@ set(PHY_SRC_UE
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_pbch.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_psbch_rx.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_psbch_tx.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_psfch_tx.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_pscch_tx.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
@@ -1253,7 +1255,10 @@ set (MAC_NR_SRC_UE
${NR_UE_MAC_DIR}/nr_ue_procedures_sl.c
${NR_UE_MAC_DIR}/nr_ue_scheduler.c
${NR_UE_MAC_DIR}/nr_ue_scheduler_sl.c
${NR_UE_MAC_DIR}/nr_ue_scheduler_sl_v2x.c
${NR_UE_MAC_DIR}/nr_ue_dci_configuration.c
${NR_UE_MAC_DIR}/nr_ue_sci_slsch.c
${NR_UE_MAC_DIR}/nr_slsch_scheduler.c
)
set (ENB_APP_SRC

8
common/utils/colors.h Normal file
View File

@@ -0,0 +1,8 @@
#define KNRM "\x1B[0m"
#define KRED "\x1B[31m"
#define KGRN "\x1B[32m"
#define KYEL "\x1B[33m"
#define KBLU "\x1B[34m"
#define KMAG "\x1B[35m"
#define KCYN "\x1B[36m"
#define KWHT "\x1B[37m"

View File

@@ -35,6 +35,7 @@
#include "common/utils/assertions.h"
#include "common/utils/LOG/log.h"
#include "nr_common.h"
#include <limits.h>
#include <math.h>
#include <simde/x86/gfni.h>

View File

@@ -970,8 +970,35 @@ void *UE_thread(void *arg)
curMsg.proc.frame_tx = ((absolute_slot + duration_rx_to_tx) / nb_slot_frame) % MAX_FRAME_NUMBER;
if (UE->received_config_request) {
if (UE->sl_mode) {
NR_UE_MAC_INST_t *mac = get_mac_inst(UE->Mod_id);
uint8_t pool_id = 0;
// Temporarily setting this to this initial NON_NR_SIDELINK_SLOT slot type.
// Later we should properly determine if the current slot is an NR_DOWNLINK_SLOT, NR_UPLINK_SLOT, or NR_MIXED_SLOT
curMsg.proc.rx_slot_type = sl_nr_ue_slot_select(sl_cfg, curMsg.proc.nr_slot_rx, TDD);
curMsg.proc.tx_slot_type = sl_nr_ue_slot_select(sl_cfg, curMsg.proc.nr_slot_tx, TDD);
SL_ResourcePool_params_t *sl_tx_rsrc_pool = mac->SL_MAC_PARAMS->sl_TxPool[pool_id];
uint16_t phy_map_sz_tx = ((sl_tx_rsrc_pool->phy_sl_bitmap.size << 3) - sl_tx_rsrc_pool->phy_sl_bitmap.bits_unused);
bool sl_tx_slot = is_sl_slot(mac, &sl_tx_rsrc_pool->phy_sl_bitmap, phy_map_sz_tx, absolute_slot + duration_rx_to_tx);
if (sl_tx_slot) {
frameslot_t frame_slot_tx;
frame_slot_tx.frame = curMsg.proc.frame_tx;
frame_slot_tx.slot = curMsg.proc.nr_slot_tx;
validate_selected_sl_slot(mac, true, false, mac->SL_MAC_PARAMS->sl_TDD_config, frame_slot_tx);
curMsg.proc.tx_slot_type = NR_SIDELINK_SLOT;
}
SL_ResourcePool_params_t *sl_rx_rsrc_pool = mac->SL_MAC_PARAMS->sl_RxPool[pool_id];
uint16_t phy_map_sz_rx = ((sl_rx_rsrc_pool->phy_sl_bitmap.size << 3) - sl_rx_rsrc_pool->phy_sl_bitmap.bits_unused);
bool sl_rx_slot = is_sl_slot(mac, &sl_rx_rsrc_pool->phy_sl_bitmap, phy_map_sz_rx, absolute_slot);
if (sl_rx_slot) {
frameslot_t frame_slot_rx;
frame_slot_rx.frame = curMsg.proc.frame_rx;
frame_slot_rx.slot = curMsg.proc.nr_slot_rx;
validate_selected_sl_slot(mac, false, true, mac->SL_MAC_PARAMS->sl_TDD_config, frame_slot_rx);
curMsg.proc.rx_slot_type = NR_SIDELINK_SLOT;
}
} else {
curMsg.proc.rx_slot_type = nr_ue_slot_select(cfg, curMsg.proc.nr_slot_rx);
curMsg.proc.tx_slot_type = nr_ue_slot_select(cfg, curMsg.proc.nr_slot_tx);
@@ -1095,11 +1122,11 @@ void *UE_thread(void *arg)
return NULL;
}
void init_NR_UE(int nb_inst, char *uecap_file, char *reconfig_file, char *rbconfig_file)
void init_NR_UE(int nb_inst, char *uecap_file, char *reconfig_file, char *rbconfig_file, ueinfo_t *ueinfo)
{
for (int instance_id = 0; instance_id < nb_inst; instance_id++) {
NR_UE_RRC_INST_t* rrc = nr_rrc_init_ue(uecap_file, instance_id, get_nrUE_params()->nb_antennas_tx);
NR_UE_MAC_INST_t *mac = nr_l2_init_ue(instance_id);
NR_UE_MAC_INST_t *mac = nr_l2_init_ue(instance_id, ueinfo);
nr_rrc_set_mac_queue(instance_id, &mac->input_nf);
mac->if_module = nr_ue_if_module_init(instance_id);
@@ -1109,7 +1136,7 @@ void init_NR_UE(int nb_inst, char *uecap_file, char *reconfig_file, char *rbconf
nr_rlc_activate_srb0(mac->crnti, NULL, send_srb0_rrc);
}
//TODO: Move this call to RRC
start_sidelink(instance_id);
start_sidelink(instance_id, ueinfo);
}
}

View File

@@ -88,6 +88,7 @@ unsigned short config_frames[4] = {2,9,11,13};
#include "nr_nas_msg.h"
#include <openair1/PHY/MODULATION/nr_modulation.h>
#include "openair2/GNB_APP/gnb_paramdef.h"
#include "openair2/RRC/NR_UE/sl_preconfig_paramvalues.h"
#include "actor.h"
THREAD_STRUCT thread_struct;
@@ -380,7 +381,16 @@ int main(int argc, char **argv)
nr_pdcp_layer_init();
nas_init_nrue(NB_UE_INST);
init_NR_UE(NB_UE_INST, get_nrUE_params()->uecap_file, get_nrUE_params()->reconfig_file, get_nrUE_params()->rbconfig_file);
ueinfo_t ueinfo;
char aprefix[MAX_OPTNAME_SIZE*2 + 8];
paramdef_t SL_UEINFO[] = SL_UEINFO_DESC(ueinfo);
paramlist_def_t SL_UEINFOList = {SL_CONFIG_STRING_UEINFO, NULL, 0};
sprintf(aprefix, "%s.[%d]", SL_CONFIG_STRING_SL_PRECONFIGURATION, 0);
config_getlist(config_get_if(), &SL_UEINFOList, NULL, 0, aprefix);
sprintf(aprefix, "%s.[%i].%s.[%i]", SL_CONFIG_STRING_SL_PRECONFIGURATION, 0, SL_CONFIG_STRING_UEINFO, 0);
config_get(config_get_if(), SL_UEINFO, sizeof(SL_UEINFO)/sizeof(paramdef_t), aprefix);
init_NR_UE(NB_UE_INST, get_nrUE_params()->uecap_file, get_nrUE_params()->reconfig_file, get_nrUE_params()->rbconfig_file, &ueinfo);
// start time manager with some reasonable default for the running mode
// (may be overwritten in configuration file or command line)
@@ -530,4 +540,3 @@ int main(int argc, char **argv)
free(pckg);
return 0;
}

View File

@@ -9,6 +9,12 @@
extern int NB_UE_INST;
extern uint16_t ue_id_g;
typedef struct ueinfo {
int srcid;
int thirdOctet;
int fourthOctet;
} ueinfo_t;
#define CONFIG_HLP_IF_FREQ "IF frequency for RF, if needed\n"
#define CONFIG_HLP_IF_FREQ_OFF "UL IF frequency offset for RF, if needed\n"
#define CONFIG_HLP_DLSCH_PARA "number of threads for dlsch processing 0 for no parallelization\n"
@@ -26,8 +32,11 @@ extern uint16_t ue_id_g;
#define CONFIG_HLP_NUM_UL_ACTORS "Number of UL actors to use. Set to 0 to disable UL actor framework and do processing inline\n"
#define CONFIG_HLP_NUM_DL_ACTORS "Number of DL actors to use. Set to 0 to disable DL actor framework and do processing inline\n"
#define CONFIG_HLP_EXTRA_PDU_ID "ID of an additional PDU session to configure alongside default PDU session\n"
#define CONFIG_HLP_SL_SYNCSOURCEUE "Sidelink UE acts as SYNC REF UE"
#define CONFIG_HLP_SL_MAX_MCS "Sidelink initial max mcs value"
#define CONFIG_HLP_SL_SNR "Sets sidelink SNR value"
/***************************************************************************************************************************************/
/*********************SL_UE_iterator******************************************************************************************************************/
/* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument
when calling config_get or config_getlist functions */
@@ -39,6 +48,8 @@ extern uint16_t ue_id_g;
#define CALIBPRACH_OPT "calib-prach-tx"
#define DUMPFRAME_OPT "ue-dump-frame"
#define SL_UE_iterator(BaSe, VaR) NR_SL_UE_info_t ** VaR##pptr=BaSe, *VaR; while ((VaR=*(VaR##pptr++)))
/*------------------------------------------------------------------------------------------------------------------------------------------*/
/* command line parameters defining UE running mode */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
@@ -84,6 +95,9 @@ extern uint16_t ue_id_g;
{"num-ul-actors", CONFIG_HLP_NUM_UL_ACTORS, 0, .iptr=&nrUE_params.num_ul_actors, .defintval=2, TYPE_INT, 0}, \
{"num-dl-actors", CONFIG_HLP_NUM_DL_ACTORS, 0, .iptr=&nrUE_params.num_dl_actors, .defintval=4, TYPE_INT, 0}, \
{"extra-pdu-id", CONFIG_HLP_EXTRA_PDU_ID, 0, .iptr=&nrUE_params.extra_pdu_id, .defintval=-1, TYPE_INT, 0}, \
{"sync-ref", CONFIG_HLP_SL_SYNCSOURCEUE, PARAMFLAG_BOOL, .uptr=&(nrUE_params.sync_ref), .defuintval=0, TYPE_UINT32, 0}, \
{"mcs", CONFIG_HLP_SL_MAX_MCS, 0, .u8ptr=&(nrUE_params.mcs), .defintval=9, TYPE_UINT8, 0}, \
{"snr", CONFIG_HLP_SL_SNR, 0, .dblptr=&(nrUE_params.snr), .defdblval=0.0, TYPE_DOUBLE, 0}, \
}
// clang-format on
@@ -126,6 +140,9 @@ typedef struct {
int num_ul_actors;
int num_dl_actors;
int extra_pdu_id;
uint32_t sync_ref;
uint8_t mcs;
double snr;
} nrUE_params_t;
extern uint64_t get_nrUE_optmask(void);
extern uint64_t set_nrUE_optmask(uint64_t bitmask);
@@ -135,7 +152,7 @@ extern nrUE_params_t *get_nrUE_params(void);
// In nr-ue.c
extern int setup_nr_ue_buffers(PHY_VARS_NR_UE **phy_vars_ue, openair0_config_t *openair0_cfg);
extern void fill_ue_band_info(void);
extern void init_NR_UE(int, char *, char *, char *);
extern void init_NR_UE(int, char *, char *, char *, ueinfo_t *);
extern void init_NR_UE_threads(PHY_VARS_NR_UE *ue);
void *UE_thread(void *arg);
void init_nr_ue_vars(PHY_VARS_NR_UE *ue, uint8_t UE_id);

View File

@@ -124,6 +124,8 @@ typedef struct {
typedef struct {
uint8_t harq_pid;
uint8_t ack_nack;
uint8_t *ack_nack_rcvd;
uint8_t num_acks_rcvd;
uint32_t pdu_length;
uint8_t* pdu;
} fapi_nr_pdsch_pdu_t;

View File

@@ -5,11 +5,30 @@
#define SL_NR_RX_CONFIG_LIST_NUM 1
#define SL_NR_TX_CONFIG_LIST_NUM 1
#define SL_NR_RX_IND_MAX_PDU 1
#define SL_NR_RX_IND_MAX_PDU 2
#define SL_NR_SCI_IND_MAX_PDU 2
#define SL_NR_MAX_PSCCH_SCI_LENGTH_IN_BYTES 8
#define SL_NR_MAX_PSSCH_SCI_LENGTH_IN_BYTES 8
#define SL_NR_MAX_SCI_LENGTH_IN_BYTES 8
typedef struct sl_nr_tti_csi_rs_pdu {
uint8_t subcarrier_spacing; // subcarrierSpacing [3GPP TS 38.211, sec 4.2], Value:0->4
uint8_t cyclic_prefix; // Cyclic prefix type [3GPP TS 38.211, sec 4.2], 0: Normal; 1: Extended
uint16_t start_rb; // PRB where this CSI resource starts related to common resource block #0 (CRB#0). Only multiples of 4 are allowed. [3GPP TS 38.331, sec 6.3.2 parameter CSIFrequencyOccupation], Value: 0 ->274
uint16_t nr_of_rbs; // Number of PRBs across which this CSI resource spans. Only multiples of 4 are allowed. [3GPP TS 38.331, sec 6.3.2 parameter CSI-FrequencyOccupation], Value: 24 -> 276
uint8_t csi_type; // CSI Type [3GPP TS 38.211, sec 7.4.1.5], Value: 0:TRS; 1:CSI-RS NZP; 2:CSI-RS ZP
uint8_t row; // Row entry into the CSI Resource location table. [3GPP TS 38.211, sec 7.4.1.5.3 and table 7.4.1.5.3-1], Value: 1-18
uint16_t freq_domain; // Bitmap defining the frequencyDomainAllocation [3GPP TS 38.211, sec 7.4.1.5.3] [3GPP TS 38.331 CSIResourceMapping], Value: Up to the 12 LSBs, actual size is determined by the Row parameter
uint8_t symb_l0; // The time domain location l0 and firstOFDMSymbolInTimeDomain [3GPP TS 38.211, sec 7.4.1.5.3], Value: 0->13
uint8_t symb_l1; // The time domain location l1 and firstOFDMSymbolInTimeDomain2 [3GPP TS 38.211, sec 7.4.1.5.3], Value: 2->12
uint8_t cdm_type; // The cdm-Type field [3GPP TS 38.211, sec 7.4.1.5.3 and table 7.4.1.5.3-1], Value: 0: noCDM; 1: fd-CDM2; 2: cdm4-FD2-TD2; 3: cdm8-FD2-TD4
uint8_t freq_density; // The density field, p and comb offset (for dot5). [3GPP TS 38.211, sec 7.4.1.5.3 and table 7.4.1.5.3-1], Value: 0: dot5 (even RB); 1: dot5 (odd RB); 2: one; 3: three
uint16_t scramb_id; // ScramblingID of the CSI-RS [3GPP TS 38.214, sec 5.2.2.3.1], Value: 0->1023
uint8_t power_control_offset; // Ratio of PDSCH EPRE to NZP CSI-RSEPRE [3GPP TS 38.214, sec 5.2.2.3.1], Value: 0->23 representing -8 to 15 dB in 1dB steps; 255: L1 is configured with ProfileSSS
uint8_t power_control_offset_ss; // Ratio of NZP CSI-RS EPRE to SSB/PBCH block EPRE [3GPP TS 38.214, sec 5.2.2.3.1], Values: 0: -3dB; 1: 0dB; 2: 3dB; 3: 6dB; 255: L1 is configured with ProfileSSS
uint8_t measurement_bitmap; // bit 0 RSRP, bit 1 RI, bit 2 LI, bit 3 PMI, bit 4 CQI, bit 5 i1
} sl_nr_tti_csi_rs_pdu_t;
typedef enum sl_sci_format_type_enum {
SL_SCI_INVALID_FORMAT,
SL_SCI_FORMAT_1A_ON_PSCCH,
@@ -20,7 +39,8 @@ typedef enum sl_sci_format_type_enum {
typedef enum sl_rx_pdu_type_enum {
SL_NR_RX_PDU_TYPE_NONE,
SL_NR_RX_PDU_TYPE_SSB,
SL_NR_RX_PDU_TYPE_SLSCH
SL_NR_RX_PDU_TYPE_SLSCH,
SL_NR_RX_PDU_TYPE_SLSCH_PSFCH
} sl_rx_pdu_type_enum_t;
//Type of SL-RX CONFIG requests from MAC to PHY
@@ -30,6 +50,7 @@ typedef enum sl_nr_rx_config_type_enum {
SL_NR_CONFIG_TYPE_RX_PSSCH_SCI,
SL_NR_CONFIG_TYPE_RX_PSSCH_SLSCH,
SL_NR_CONFIG_TYPE_RX_PSFCH,
SL_NR_CONFIG_TYPE_RX_PSSCH_SLSCH_CSI_RS,
SL_NR_CONFIG_TYPE_RX_MAXIMUM
} sl_nr_rx_config_type_enum_t;
@@ -38,6 +59,7 @@ typedef enum sl_nr_tx_config_type_enum {
SL_NR_CONFIG_TYPE_TX_PSBCH = SL_NR_CONFIG_TYPE_RX_MAXIMUM + 1,
SL_NR_CONFIG_TYPE_TX_PSCCH_PSSCH,
SL_NR_CONFIG_TYPE_TX_PSFCH,
SL_NR_CONFIG_TYPE_TX_PSCCH_PSSCH_CSI_RS,
SL_NR_CONFIG_TYPE_TX_MAXIMUM
} sl_nr_tx_config_type_enum_t;
@@ -69,7 +91,7 @@ typedef struct {
uint8_t sensing_result;
//in case pssch sensing is requested.
int16_t pssch_rsrp;
sl_nr_sci_indication_pdu_t sci_pdu;
sl_nr_sci_indication_pdu_t sci_pdu[SL_NR_SCI_IND_MAX_PDU];
} sl_nr_sci_indication_t;
// IF UE Rx PSBCH, PHY indicates MAC with received MIB and PSBCH RSRP
@@ -191,6 +213,22 @@ typedef struct sl_nr_rx_config_pssch_pdu {
uint8_t ndi;
} sl_nr_rx_config_pssch_pdu_t;
typedef struct sl_nr_tx_rx_config_psfch_pdu {
// These fields can be mapped directly to the same fields in nfapi_nr_ul_config_pucch_pdu
uint8_t freq_hop_flag;
uint8_t group_hop_flag;
uint8_t sequence_hop_flag;
uint16_t second_hop_prb;
uint8_t nr_of_symbols;
uint8_t start_symbol_index;
uint8_t hopping_id;
uint16_t prb;
uint16_t sl_bwp_start;
uint16_t initial_cyclic_shift;
uint8_t mcs;
uint8_t bit_len_harq;
} sl_nr_tx_rx_config_psfch_pdu_t;
typedef struct {
sl_nr_rx_config_type_enum_t pdu_type; // indicates the type of RX config request
union {
@@ -198,6 +236,9 @@ typedef struct {
sl_nr_rx_config_pssch_sci_pdu_t rx_sci2_config_pdu;
sl_nr_rx_config_pssch_pdu_t rx_pssch_config_pdu;
};
sl_nr_tti_csi_rs_pdu_t rx_csi_rs_config_pdu;
sl_nr_tx_rx_config_psfch_pdu_t *rx_psfch_pdu_list;
uint16_t num_psfch_pdus;
} sl_nr_rx_config_request_pdu_t;
// MAC commands PHY to perform an action on RX RESOURCE POOL or RX PSBCH using this RX CONFIG
@@ -244,6 +285,9 @@ typedef struct sl_nr_tx_config_pscch_pssch_pdu {
//Indicates the number of symbols for PSCCH+PSSCH txn
uint8_t pssch_numsym;
// start symbol of PSCCH/PSSCH (excluding AGC)
uint8_t pssch_startsym;
//.... Other Parameters for SCI-2 and PSSCH
// Used to determine number of SCI2 modulated symbols
@@ -266,14 +310,21 @@ typedef struct sl_nr_tx_config_pscch_pssch_pdu {
// Table from SPEC 38.211, Table 8.4.1.1.2-1
uint16_t dmrs_symbol_position;
// PSFCH related parameters
sl_nr_tx_rx_config_psfch_pdu_t *psfch_pdu_list;
uint16_t num_psfch_pdus;
//....TBD.. any additional parameters
// CSI-RS related parameters
sl_nr_tti_csi_rs_pdu_t nr_sl_csi_rs_pdu;
//TX Power for PSSCH in symbol without PSCCH.
// Power for PSCCH and power for PSSCH in symbol with PSCCH is calculated
// from this value according to 38.213 section 16
int16_t pssch_tx_power;
uint16_t slsch_payload_length;
uint8_t *slsch_payload;
} sl_nr_tx_config_pscch_pssch_pdu_t;
// MAC indicates PHY to send PSBCH.
@@ -383,7 +434,26 @@ typedef struct {
//only 1 SL-BWP can be configured in REL16, REL17
sl_nr_bwp_config_t sl_bwp_config;
uint32_t sl_DMRS_ScrambleId;
} sl_nr_phy_config_request_t;
/* Dependencies */
typedef enum NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR {
NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_NOTHING, /* No components present */
NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots4,
NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots5,
NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots8,
NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots10,
NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots16,
NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots20,
NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots32,
NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots40,
NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots64,
NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots80,
NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots160,
NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots320,
NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots640
} NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR;
#endif

View File

@@ -337,6 +337,10 @@ int check_crc(uint8_t* decoded_bytes, uint32_t n, uint8_t crc_type)
for (int i=0; i<crc_len; i++)
oldcrc |= (decoded_bytes[(n>>3)-crc_len+i])<<((crc_len-1-i)<<3);
if (oldcrc == 0) {
return 0;
}
switch (crc_type) {
case CRC24_A:

View File

@@ -274,6 +274,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
}
ue->init_averaging = 1;
init_symbol_rotation(fp);
init_timeshift_rotation(fp);

View File

@@ -97,6 +97,18 @@ static const int nr_ssb_table[][3] = {
{256, 15, nr_ssb_type_A}};
void set_Lmax(NR_DL_FRAME_PARMS *fp) {
if (get_softmodem_params()->sl_mode == 2) {
int sl_NumSSB_WithinPeriod = 1; //TODO: Needs to be updated from RRC parameters
int sl_TimeOffsetSSB = 1; //TODO: Needs to be updated from RRC parameters
int sl_TimeInterval = 1; //TODO: Needs to be updated from RRC parameters
if ((sl_NumSSB_WithinPeriod == 4) && ((sl_TimeOffsetSSB % fp->slots_per_frame) + 3 * sl_TimeInterval < NR_NUMBER_OF_SUBFRAMES_PER_FRAME * 2))
fp->Lmax = 4;
else if ((sl_NumSSB_WithinPeriod == 2) && ((sl_TimeOffsetSSB % fp->slots_per_frame) + sl_TimeInterval < NR_NUMBER_OF_SUBFRAMES_PER_FRAME))
fp->Lmax = 2;
else
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))
@@ -208,6 +220,9 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, int N_RB_DL)
fp->ofdm_symbol_size <<= 1;
fp->first_carrier_offset = fp->ofdm_symbol_size - (N_RB_DL * 12 / 2);
// TODO: Temporarily setting fp->first_carrier_offset = 0 for SL until MAC is developed
if (get_softmodem_params()->sl_mode == 2)
fp->first_carrier_offset = 0;
fp->nb_prefix_samples = fp->ofdm_symbol_size / 128 * 9;
fp->nb_prefix_samples0 = fp->ofdm_symbol_size / 128 * (9 + (1 << mu));
LOG_I(PHY,
@@ -370,6 +385,11 @@ 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 == 2) {
uint64_t sl_bw_khz = (12 * config->carrier_config.sl_grid_size[config->ssb_config.scs_common]) * (15 << config->ssb_config.scs_common);
fp->sl_CarrierFreq = ((sl_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 ;
@@ -393,7 +413,7 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp,
AssertFatal(fp->numerology_index == NR_MU_2,"Invalid cyclic prefix %d for numerology index %d\n", Ncp, fp->numerology_index);
fp->Ncp = Ncp;
int N_RB = fp->N_RB_DL;
int N_RB = (get_softmodem_params()->sl_mode == 2) ? fp->N_RB_SL : fp->N_RB_DL;
set_scs_parameters(fp, fp->numerology_index, N_RB);
fp->slots_per_frame = 10* fp->slots_per_subframe;
@@ -420,6 +440,10 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp,
}
fp->ssb_start_subcarrier = (12 * config->ssb_table.ssb_offset_point_a + sco);
// TODO: Temporarily setting fp->ssb_start_subcarrier = 0 for SL until MAC is developed
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;

View File

@@ -48,7 +48,6 @@ void normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,LTE_DL_FRA
{
PHY_ofdm_mod((int *)txdataF, // input
(int *)txdata, // output
frame_parms->ofdm_symbol_size,
@@ -75,6 +74,7 @@ void nr_normal_prefix_mod(c16_t *txdataF,
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT])
{
// This function works only slot wise. For more generic symbol generation refer nr_feptx0()
LOG_D(NR_PHY,"normal_prefix_mod: prefix0 %d, prefix %d, nsymb %d\n",frame_parms->nb_prefix_samples0,frame_parms->nb_prefix_samples,nsymb);
if (frame_parms->numerology_index != 0) { // case where numerology != 0
if (!(slot%(frame_parms->slots_per_subframe/2))) {
if (was_symbol_used[0]) {

View File

@@ -103,7 +103,7 @@ int slot_fep(PHY_VARS_UE *ue,
// (frame_parms->ofdm_symbol_size+nb_prefix_samples)*(l-1);
#ifdef DEBUG_FEP
// if (ue->frame <100)
LOG_I(PHY,"slot_fep: frame %d: slot %d, symbol %d, nb_prefix_samples %d, nb_prefix_samples0 %d, slot_offset %d, subframe_offset %d, sample_offset %d,rx_offset %d, frame_length_samples %d\n",
LOG_D(PHY,"slot_fep: frame %d: slot %d, symbol %d, nb_prefix_samples %d, nb_prefix_samples0 %d, slot_offset %d, subframe_offset %d, sample_offset %d,rx_offset %d, frame_length_samples %d\n",
ue->proc.proc_rxtx[(Ns>>1)&1].frame_rx,Ns, symbol,
nb_prefix_samples,nb_prefix_samples0,slot_offset,subframe_offset,sample_offset,rx_offset,frame_length_samples);
#endif
@@ -178,7 +178,7 @@ int slot_fep(PHY_VARS_UE *ue,
}
#ifdef DEBUG_FEP
printf("slot_fep: done\n");
printf("slot_fep: Ns %d l %d, done\n",Ns,l);
#endif
return(0);
}
@@ -261,7 +261,7 @@ int front_end_fft(PHY_VARS_UE *ue,
// (frame_parms->ofdm_symbol_size+nb_prefix_samples)*(l-1);
#ifdef DEBUG_FEP
// if (ue->frame <100)
LOG_I(PHY,
LOG_D(PHY,
"slot_fep: frame %d: slot %d, threadId %d, symbol %d, nb_prefix_samples %d, nb_prefix_samples0 %d, slot_offset %d, subframe_offset %d, sample_offset %d,rx_offset %d, frame_length_samples %d\n",
ue->proc.proc_rxtx[threadId].frame_rx,Ns, threadId,symbol,
nb_prefix_samples,nb_prefix_samples0,slot_offset,subframe_offset,sample_offset,rx_offset,frame_length_samples);

View File

@@ -58,6 +58,97 @@ void nr_symbol_fep(const NR_DL_FRAME_PARMS *frame_parms,
}
}
int sl_nr_slot_fep(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
unsigned char symbol,
unsigned char Ns,
uint32_t sample_offset,
c16_t rxdataF[][ue->SL_UE_PHY_PARAMS.sl_frame_params.samples_per_slot_wCP])
{
NR_DL_FRAME_PARMS *frame_params = &ue->SL_UE_PHY_PARAMS.sl_frame_params;
NR_UE_COMMON *common_vars = &ue->common_vars;
AssertFatal(symbol < frame_params->symbols_per_slot, "slot_fep: symbol must be between 0 and %d\n", frame_params->symbols_per_slot-1);
AssertFatal(Ns < frame_params->slots_per_frame, "slot_fep: Ns must be between 0 and %d\n", frame_params->slots_per_frame-1);
unsigned int nb_prefix_samples = frame_params->nb_prefix_samples;
unsigned int nb_prefix_samples0 = frame_params->nb_prefix_samples0;
dft_size_idx_t dftsize = get_dft(frame_params->ofdm_symbol_size);
// This is for misalignment issues
int32_t tmp_dft_in[8192] __attribute__ ((aligned (32)));
unsigned int rx_offset = frame_params->get_samples_slot_timestamp(Ns,frame_params,0);
unsigned int abs_symbol = Ns * frame_params->symbols_per_slot + symbol;
rx_offset += sample_offset;
rx_offset += ue->rx_offset;
for (int idx_symb = Ns*frame_params->symbols_per_slot; idx_symb <= abs_symbol; idx_symb++)
rx_offset += (idx_symb%(0x7<<frame_params->numerology_index)) ? nb_prefix_samples : nb_prefix_samples0;
rx_offset += frame_params->ofdm_symbol_size * symbol;
// use OFDM symbol from within 1/8th of the CP to avoid ISI
rx_offset -= (nb_prefix_samples / frame_params->ofdm_offset_divisor);
#ifdef SL_DEBUG_SLOT_FEP
// if (ue->frame <100)
LOG_I(PHY, "slot_fep: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, rx_offset %u\n",
Ns, symbol, nb_prefix_samples, nb_prefix_samples0, rx_offset);
#endif
for (unsigned char aa=0; aa<frame_params->nb_antennas_rx; aa++) {
memset(&rxdataF[aa][frame_params->ofdm_symbol_size*symbol],0,frame_params->ofdm_symbol_size*sizeof(int32_t));
int16_t *rxdata_ptr = (int16_t *)&common_vars->rxdata[aa][rx_offset];
// if input to dft is not 256-bit aligned
if ((rx_offset & 7) != 0) {
memcpy((void *)&tmp_dft_in[0],
(void *)&common_vars->rxdata[aa][rx_offset],
frame_params->ofdm_symbol_size * sizeof(int32_t));
rxdata_ptr = (int16_t *)tmp_dft_in;
}
dft(dftsize,
rxdata_ptr,
(int16_t *)&rxdataF[aa][frame_params->ofdm_symbol_size*symbol],
1);
int symb_offset = (Ns%frame_params->slots_per_subframe)*frame_params->symbols_per_slot;
int32_t rot2 = ((uint32_t*)frame_params->symbol_rotation[1])[symbol+symb_offset];
((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1];
#ifdef SL_DEBUG_SLOT_FEP
// if (ue->frame <100)
LOG_I(PHY, "slot_fep: slot %d, symbol %d rx_offset %u, rotation symbol %d %d.%d\n", Ns,symbol, rx_offset,
symbol+symb_offset,((int16_t*)&rot2)[0],((int16_t*)&rot2)[1]);
#endif
rotate_cpx_vector((c16_t *)&rxdataF[aa][frame_params->ofdm_symbol_size*symbol],
(c16_t *)&rot2,
(c16_t *)&rxdataF[aa][frame_params->ofdm_symbol_size*symbol],
frame_params->ofdm_symbol_size,
15);
c16_t *shift_rot = (c16_t *)frame_params->timeshift_symbol_rotation;
multadd_cpx_vector((c16_t *)&rxdataF[aa][frame_params->ofdm_symbol_size*symbol],
shift_rot,
(c16_t *)&rxdataF[aa][frame_params->ofdm_symbol_size*symbol],
frame_params->ofdm_symbol_size,
15);
}
LOG_D(PHY, "SIDELINK RX: Slot FEP: done for symbol:%d\n", symbol);
return 0;
}
int nr_slot_fep(PHY_VARS_NR_UE *ue,
const NR_DL_FRAME_PARMS *frame_parms,
unsigned int slot,

View File

@@ -65,6 +65,8 @@ uint32_t nr_get_G(uint16_t nb_rb,
uint32_t nr_get_E(uint32_t G, uint8_t C, uint8_t Qm, uint8_t Nl, uint8_t r);
uint32_t nr_get_G_SL(uint16_t nb_rb, uint16_t nb_symb_sch, uint8_t nb_re_dmrs, uint16_t length_dmrs, uint8_t sci1_dmrs_overlap, uint16_t sci1_re, uint16_t sci1_rb, uint16_t sci2_re, uint16_t csi_rs_re, uint8_t Qm, uint8_t Nl);
void compute_nr_prach_seq(uint8_t short_sequence, uint8_t num_sequences, uint8_t rootSequenceIndex, c16_t X_u[64][839]);
void nr_fill_du(uint16_t N_ZC, const uint16_t *prach_root_sequence_map, uint16_t nr_du[NR_PRACH_SEQ_LEN_L - 1]);

View File

@@ -123,35 +123,6 @@ int get_pucch0_cs_lut_index(PHY_VARS_gNB *gNB,nfapi_nr_pucch_pdu_t* pucch_pdu) {
return(gNB->pucch0_lut.nb_id-1);
}
static const int16_t idft12_re[12][12] = {
{23170,23170,23170,23170,23170,23170,23170,23170,23170,23170,23170,23170},
{23170,20066,11585,0,-11585,-20066,-23170,-20066,-11585,0,11585,20066},
{23170,11585,-11585,-23170,-11585,11585,23170,11585,-11585,-23170,-11585,11585},
{23170,0,-23170,0,23170,0,-23170,0,23170,0,-23170,0},
{23170,-11585,-11585,23170,-11585,-11585,23170,-11585,-11585,23170,-11585,-11585},
{23170,-20066,11585,0,-11585,20066,-23170,20066,-11585,0,11585,-20066},
{23170,-23170,23170,-23170,23170,-23170,23170,-23170,23170,-23170,23170,-23170},
{23170,-20066,11585,0,-11585,20066,-23170,20066,-11585,0,11585,-20066},
{23170,-11585,-11585,23170,-11585,-11585,23170,-11585,-11585,23170,-11585,-11585},
{23170,0,-23170,0,23170,0,-23170,0,23170,0,-23170,0},
{23170,11585,-11585,-23170,-11585,11585,23170,11585,-11585,-23170,-11585,11585},
{23170,20066,11585,0,-11585,-20066,-23170,-20066,-11585,0,11585,20066}
};
static const int16_t idft12_im[12][12] = {
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,11585,20066,23170,20066,11585,0,-11585,-20066,-23170,-20066,-11585},
{0,20066,20066,0,-20066,-20066,0,20066,20066,0,-20066,-20066},
{0,23170,0,-23170,0,23170,0,-23170,0,23170,0,-23170},
{0,20066,-20066,0,20066,-20066,0,20066,-20066,0,20066,-20066},
{0,11585,-20066,23170,-20066,11585,0,-11585,20066,-23170,20066,-11585},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,-11585,20066,-23170,20066,-11585,0,11585,-20066,23170,-20066,11585},
{0,-20066,20066,0,-20066,20066,0,-20066,20066,0,-20066,20066},
{0,-23170,0,23170,0,-23170,0,23170,0,-23170,0,23170},
{0,-20066,-20066,0,20066,20066,0,-20066,-20066,0,20066,20066},
{0,-11585,-20066,-23170,-20066,-11585,0,11585,20066,23170,20066,11585}
};
//************************************************************************//
void nr_decode_pucch0(PHY_VARS_gNB *gNB,
c16_t **rxdataF,

View File

@@ -319,6 +319,7 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue,
{
TracyCZone(ctx, true);
int symbol;
uint8_t Lmax=frame_parms->Lmax;
int M = NR_POLAR_PBCH_E;
int nushift = (Lmax == 4) ? i_ssb & 3 : i_ssb & 7;

View File

@@ -0,0 +1,75 @@
/*
* 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_UE_TRANSPORT/nr_pscch_tx.c
* \brief Top-level routines for generating and decoding the PSCCH physical channel
* \author R. Knopp
* \date 2023
* \version 0.1
* \company Eurecom
* \email:
* \note
* \warning
*/
//#include "PHY/defs.h"
#include "PHY/impl_defs_nr.h"
#include "PHY/defs_nr_common.h"
#include "PHY/defs_nr_UE.h"
//#include "PHY/extern.h"
#include "PHY/NR_UE_TRANSPORT/pucch_nr.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
#include <openair1/PHY/CODING/nrSmallBlock/nr_small_block_defs.h>
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "T.h"
uint32_t nr_generate_dci(void *gNB, PHY_VARS_NR_UE *ue,
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
int32_t *txdataF,
int16_t amp,
NR_DL_FRAME_PARMS *frame_parms,
int slot);
uint32_t nr_generate_sci1(const PHY_VARS_NR_UE *ue,
c16_t *txdataF,
const NR_DL_FRAME_PARMS *frame_parms,
const int16_t amp,
const int nr_slot_tx,
const sl_nr_tx_config_pscch_pssch_pdu_t *pscch_pssch_pdu)
{
nfapi_nr_dl_tti_pdcch_pdu_rel15_t pdcch_pdu_rel15={0};
// for SCI we put the startRB and number of RBs for PSCCH in the first 2 FAPI FreqDomainResource fields
pdcch_pdu_rel15.FreqDomainResource[0] = pscch_pssch_pdu->startrb;
pdcch_pdu_rel15.FreqDomainResource[1] = pscch_pssch_pdu->pscch_numrbs;
pdcch_pdu_rel15.StartSymbolIndex = 1;
pdcch_pdu_rel15.DurationSymbols = pscch_pssch_pdu->pscch_numsym;
pdcch_pdu_rel15.numDlDci = 1;
pdcch_pdu_rel15.dci_pdu[0].ScramblingId = pscch_pssch_pdu->pscch_dmrs_scrambling_id;
pdcch_pdu_rel15.dci_pdu[0].PayloadSizeBits = pscch_pssch_pdu->pscch_sci_payload_len;
// for SCI we put the number of PRBs in the FAPI AggregationLevel field
pdcch_pdu_rel15.dci_pdu[0].AggregationLevel = pscch_pssch_pdu->pscch_numrbs*pscch_pssch_pdu->pscch_numsym;
pdcch_pdu_rel15.dci_pdu[0].ScramblingRNTI = 1010;
*(uint64_t*)pdcch_pdu_rel15.dci_pdu[0].Payload = *(uint64_t *)pscch_pssch_pdu->pscch_sci_payload;
return(nr_generate_dci(NULL,(PHY_VARS_NR_UE *)ue,&pdcch_pdu_rel15,(int32_t *)txdataF,amp,(NR_DL_FRAME_PARMS*)frame_parms,nr_slot_tx));
}

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/NR_UE_TRANSPORT/pucch_nr.c
* \brief Top-level routines for generating and decoding the PSFCH physical channel
* \author R. Knopp
* \date 2023
* \version 0.1
* \company Eurecom
* \email:
* \note
* \warning
*/
//#include "PHY/defs.h"
#include "PHY/impl_defs_nr.h"
#include "PHY/defs_nr_common.h"
#include "PHY/defs_nr_UE.h"
//#include "PHY/extern.h"
#include "PHY/NR_UE_TRANSPORT/pucch_nr.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
#include <openair1/PHY/CODING/nrSmallBlock/nr_small_block_defs.h>
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "T.h"
void nr_generate_psfch0(const PHY_VARS_NR_UE *ue,
c16_t **txdataF,
const NR_DL_FRAME_PARMS *frame_parms,
const int16_t amp,
const int nr_slot_tx,
const sl_nr_tx_rx_config_psfch_pdu_t *psfch_pdu)
{
fapi_nr_ul_config_pucch_pdu pucch_pdu;
pucch_pdu.start_symbol_index = psfch_pdu->start_symbol_index;
pucch_pdu.hopping_id = psfch_pdu->hopping_id;
pucch_pdu.prb_start = psfch_pdu->prb;
pucch_pdu.initial_cyclic_shift = psfch_pdu->initial_cyclic_shift;
pucch_pdu.mcs = psfch_pdu->mcs;
pucch_pdu.nr_of_symbols = psfch_pdu->nr_of_symbols;
pucch_pdu.n_bit = psfch_pdu->bit_len_harq;
pucch_pdu.bwp_start = psfch_pdu->sl_bwp_start;
pucch_pdu.freq_hop_flag = psfch_pdu->freq_hop_flag;
pucch_pdu.group_hop_flag = psfch_pdu->group_hop_flag;
pucch_pdu.second_hop_prb = psfch_pdu->second_hop_prb;
pucch_pdu.sequence_hop_flag = psfch_pdu->sequence_hop_flag;
nr_generate_pucch0(ue, txdataF, frame_parms, amp, nr_slot_tx, &pucch_pdu);
}

View File

@@ -0,0 +1,337 @@
/*
* 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/pucch_rx.c
* \brief Top-level routines for decoding the PUCCH physical channel
* \author A. Mico Pereperez, Padarthi Naga Prasanth, Francesco Mani, Raymond Knopp
* \date 2020
* \version 0.2
* \company Eurecom
* \email:
* \note
* \warning
*/
#include<stdio.h>
#include <string.h>
#include <math.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include "PHY/impl_defs_nr.h"
#include "PHY/defs_nr_common.h"
#include "PHY/defs_gNB.h"
#include "PHY/sse_intrin.h"
#include "PHY/NR_UE_TRANSPORT/pucch_nr.h"
#include <openair1/PHY/CODING/nrSmallBlock/nr_small_block_defs.h>
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/NR_REFSIG/nr_refsig.h"
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "nfapi/oai_integration/vendor_ext.h"
#include "nfapi/oai_integration/vendor_ext.h"
#include "executables/nr-uesoftmodem.h"
#include "T.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
//#define DEBUG_NR_PUCCH_RX 1
int get_pucch0_cs_lut_index(PHY_VARS_NR_UE *ue, nfapi_nr_pucch_pdu_t* pucch_pdu) {
int i = 0;
#ifdef DEBUG_NR_PUCCH_RX
LOG_I(NR_PHY, "getting index for LUT with %d entries, Nid %d\n", ue->pucch0_lut.nb_id, pucch_pdu->hopping_id);
#endif
for (i=0; i<ue->pucch0_lut.nb_id; i++) {
if (ue->pucch0_lut.Nid[i] == pucch_pdu->hopping_id) break;
}
#ifdef DEBUG_NR_PUCCH_RX
LOG_I(NR_PHY, "found index %d\n", i);
#endif
if (i < ue->pucch0_lut.nb_id) return(i);
#ifdef DEBUG_NR_PUCCH_RX
LOG_I(NR_PHY, "Initializing PUCCH0 LUT index %i with Nid %d\n", i, pucch_pdu->hopping_id);
#endif
// initialize
ue->pucch0_lut.Nid[ue->pucch0_lut.nb_id] = pucch_pdu->hopping_id;
for (int slot=0; slot<10<<pucch_pdu->subcarrier_spacing; slot++)
for (int symbol=0; symbol<14; symbol++)
ue->pucch0_lut.lut[ue->pucch0_lut.nb_id][slot][symbol] = (int)floor(nr_cyclic_shift_hopping(pucch_pdu->hopping_id, 0, 0, 0, symbol, slot) / 0.5235987756);
ue->pucch0_lut.nb_id++;
return(ue->pucch0_lut.nb_id-1);
}
int8_t nr_ue_decode_psfch0(PHY_VARS_NR_UE *ue,
int frame,
int slot,
c16_t rxdataF[][ue->SL_UE_PHY_PARAMS.sl_frame_params.samples_per_slot_wCP],
const sl_nr_tx_rx_config_psfch_pdu_t *psfch_pdu) {
int8_t ack_nack_rcvd = -1;
nfapi_nr_pucch_pdu_t pucch_pdu;
pucch_pdu.freq_hop_flag = psfch_pdu->freq_hop_flag;
pucch_pdu.group_hop_flag = psfch_pdu->group_hop_flag;
pucch_pdu.sequence_hop_flag = psfch_pdu->sequence_hop_flag;
pucch_pdu.second_hop_prb = psfch_pdu->second_hop_prb;
pucch_pdu.nr_of_symbols = psfch_pdu->nr_of_symbols;
pucch_pdu.start_symbol_index = psfch_pdu->start_symbol_index;
pucch_pdu.hopping_id = psfch_pdu->hopping_id;
pucch_pdu.prb_start = psfch_pdu->prb;
pucch_pdu.prb_size = 1;
pucch_pdu.bwp_start = psfch_pdu->sl_bwp_start;
pucch_pdu.initial_cyclic_shift = psfch_pdu->initial_cyclic_shift;
pucch_pdu.bit_len_harq = psfch_pdu->bit_len_harq;
pucch_pdu.sr_flag = 0;
pucch_pdu.subcarrier_spacing = 1;
ack_nack_rcvd = nr_ue_decode_pucch0(ue,
frame,
slot,
rxdataF,
NULL,
&pucch_pdu);
return ack_nack_rcvd;
}
int8_t nr_ue_decode_pucch0(PHY_VARS_NR_UE *ue,
int frame,
int slot,
c16_t rxdataF[][ue->SL_UE_PHY_PARAMS.sl_frame_params.samples_per_slot_wCP],
nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu,
nfapi_nr_pucch_pdu_t *pucch_pdu)
{
NR_DL_FRAME_PARMS *frame_parms = get_softmodem_params()->sl_mode ? &ue->SL_UE_PHY_PARAMS.sl_frame_params : &ue->frame_parms;
int soffset = 0;
int nr_sequences;
const uint8_t *mcs;
AssertFatal(pucch_pdu->sr_flag == 0, "SR flag MUST be 0 in SL\n");
AssertFatal(pucch_pdu->bit_len_harq == 0 || pucch_pdu->bit_len_harq == 1, "Invalid value for bit_len_harq %d\n", pucch_pdu->bit_len_harq);
if(pucch_pdu->bit_len_harq == 0){
mcs = table1_mcs;
nr_sequences = 1;
}
else if(pucch_pdu->bit_len_harq == 1){
mcs = table1_mcs;
nr_sequences = 4 >> 1;
}
AssertFatal(nr_sequences == 1 || nr_sequences == 2, "nr_sequences must be either 1 or 2, nr_sequences %d\n", nr_sequences);
LOG_D(PHY, "%s pucch0: nr_symbols %d, start_symbol %d, prb_start %d, second_hop_prb %d, group_hop_flag %d, sequence_hop_flag %d, O_ACK %d, O_SR %d, mcs %d, initial_cyclic_shift %d, subcarrier_spacing %d\n",
__FUNCTION__,
pucch_pdu->nr_of_symbols,
pucch_pdu->start_symbol_index,
pucch_pdu->prb_start,
pucch_pdu->second_hop_prb,
pucch_pdu->group_hop_flag,
pucch_pdu->sequence_hop_flag,
pucch_pdu->bit_len_harq,
pucch_pdu->sr_flag,
mcs[0],
pucch_pdu->initial_cyclic_shift,
pucch_pdu->subcarrier_spacing);
int cs_ind = get_pucch0_cs_lut_index(ue, pucch_pdu);
/*
* Implement TS 38.211 Subclause 6.3.2.3.1 Sequence generation
*
*/
/*
* Defining cyclic shift hopping TS 38.211 Subclause 6.3.2.2.2
*/
/*
* in TS 38.213 Subclause 9.2.1 it is said that:
* for PUCCH format 0 or PUCCH format 1, the index of the cyclic shift
* is indicated by higher layer parameter PUCCH-F0-F1-initial-cyclic-shift
*/
/*
* Implementing TS 38.211 Subclause 6.3.2.3.1, the sequence x(n) shall be generated according to:
* x(l*12+n) = r_u_v_alpha_delta(n)
*/
// the value of u,v (delta always 0 for PUCCH) has to be calculated according to TS 38.211 Subclause 6.3.2.2.1
uint8_t u[2] = {0}, v[2] = {0};
// // x_n contains the sequence r_u_v_alpha_delta(n)
int n, i;
int prb_offset[2] = {pucch_pdu->bwp_start + pucch_pdu->prb_start, pucch_pdu->bwp_start + pucch_pdu->prb_start};
pucch_GroupHopping_t pucch_GroupHopping = pucch_pdu->group_hop_flag + (pucch_pdu->sequence_hop_flag << 1);
nr_group_sequence_hopping(pucch_GroupHopping,
pucch_pdu->hopping_id,
0,
slot,
&u[0],
&v[0]); // calculating u and v value first hop
LOG_D(PHY, "pucch0: u %d, v %d\n", u[0], v[0]);
if (pucch_pdu->freq_hop_flag == 1) {
nr_group_sequence_hopping(pucch_GroupHopping,
pucch_pdu->hopping_id,
1,
slot,
&u[1],
&v[1]); // calculating u and v value second hop
LOG_D(PHY, "pucch0 second hop: u %d, v %d\n", u[1], v[1]);
prb_offset[1] = pucch_pdu->bwp_start + pucch_pdu->second_hop_prb;
}
AssertFatal(pucch_pdu->nr_of_symbols < 3, "nr_of_symbols %d not allowed\n", pucch_pdu->nr_of_symbols);
uint32_t re_offset[2] = {0};
const int16_t *x_re[2], *x_im[2];
x_re[0] = table_5_2_2_2_2_Re[u[0]];
x_im[0] = table_5_2_2_2_2_Im[u[0]];
x_re[1] = table_5_2_2_2_2_Re[u[1]];
x_im[1] = table_5_2_2_2_2_Im[u[1]];
c64_t xr[frame_parms->nb_antennas_rx][pucch_pdu->nr_of_symbols][12] __attribute__((aligned(32)));
int64_t xrtmag = 0, xrtmag_next = 0;
uint8_t maxpos = 0;
uint8_t index = 0;
LOG_D(NR_PHY, "prb_size %d\n", pucch_pdu->prb_size);
int nb_re_pucch = 12*pucch_pdu->prb_size; // prb size is 1
int32_t rp[frame_parms->nb_antennas_rx][pucch_pdu->nr_of_symbols][nb_re_pucch];
memset(rp, 0, sizeof(rp));
int32_t *tmp_rp = NULL;
for (int l=0; l<pucch_pdu->nr_of_symbols; l++) {
uint8_t l2 = l + pucch_pdu->start_symbol_index;
re_offset[l] = (12 * prb_offset[l]) + frame_parms->first_carrier_offset;
if (re_offset[l] >= frame_parms->ofdm_symbol_size)
re_offset[l] -= frame_parms->ofdm_symbol_size;
for (int aa = 0; aa < frame_parms->nb_antennas_rx; aa++) {
LOG_D(NR_PHY, "soffset %i, soffset + l2*frame_parms->ofdm_symbol_size %i %i re_offset[%d] %i\n",
soffset, soffset + l2*frame_parms->ofdm_symbol_size,
(soffset + l2*frame_parms->ofdm_symbol_size + nb_re_pucch), l, re_offset[l]);
for (int z = soffset + l2*frame_parms->ofdm_symbol_size + re_offset[l]; z < (soffset + l2*frame_parms->ofdm_symbol_size + re_offset[l] + nb_re_pucch); z++)
LOG_D(NR_PHY, "%4d.%2d z %d rxdataF (%d,%d)\n", frame, slot, z, rxdataF[aa][z].r, rxdataF[aa][z].i);
tmp_rp = (int32_t *)&rxdataF[aa][soffset + l2 * frame_parms->ofdm_symbol_size];
if(re_offset[l] + nb_re_pucch > frame_parms->ofdm_symbol_size) {
int neg_length = frame_parms->ofdm_symbol_size - re_offset[l];
int pos_length = nb_re_pucch - neg_length;
memcpy1((void*)rp[aa][l], (void*)&tmp_rp[re_offset[l]], neg_length*sizeof(int32_t));
memcpy1((void*)&rp[aa][l][neg_length], (void*)tmp_rp, pos_length*sizeof(int32_t));
}
else
memcpy1((void*)rp[aa][l], (void*)&tmp_rp[re_offset[l]], nb_re_pucch*sizeof(int32_t));
c16_t *r = (c16_t*)&rp[aa][l];
for (n=0; n<nb_re_pucch; n++) {
xr[aa][l][n].r = (int32_t)x_re[l][n] * r[n].r + (int32_t)x_im[l][n] * r[n].i;
xr[aa][l][n].i = (int32_t)x_re[l][n] * r[n].i - (int32_t)x_im[l][n] * r[n].r;
#ifdef DEBUG_NR_PUCCH_RX
LOG_I(NR_PHY, "x (%d,%d), r%d.%d (%d,%d), xr (%lld,%lld)\n",
x_re[l][n], x_im[l][n], l2, re_offset[l], r[n].r, r[n].i, xr[aa][l][n].r, xr[aa][l][n].i);
#endif
}
}
}
int seq_index = 0;
int64_t temp;
for(i=0; i<nr_sequences; i++) {
c64_t corr[frame_parms->nb_antennas_rx][2];
for (int aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
for (int l=0; l<pucch_pdu->nr_of_symbols; l++) {
seq_index = (pucch_pdu->initial_cyclic_shift+
mcs[i]+
ue->pucch0_lut.lut[cs_ind][slot][l+pucch_pdu->start_symbol_index])%12;
#ifdef DEBUG_NR_PUCCH_RX
LOG_I(NR_PHY, "PUCCH symbol %d seq %d, seq_index %d, mcs %d , slot %d, cs_ind %d\n",
l, i, seq_index, mcs[i], slot, cs_ind);
#endif
corr[aa][l] = (c64_t){0};
for (n = 0; n < 12; n++) {
corr[aa][l].r += xr[aa][l][n].r * idft12_re[seq_index][n] + xr[aa][l][n].i * idft12_im[seq_index][n];
corr[aa][l].i += xr[aa][l][n].r * idft12_im[seq_index][n] - xr[aa][l][n].i * idft12_re[seq_index][n];
}
corr[aa][l].r >>= 31;
corr[aa][l].i >>= 31;
}
}
LOG_D(PHY,"PUCCH IDFT[%d/%d] = (%ld,%ld)=>%f\n",
mcs[i], seq_index, corr[0][0].r, corr[0][0].i,
10*log10((double)squaredMod(corr[0][0])));
if (pucch_pdu->nr_of_symbols == 2)
LOG_D(PHY,"PUCCH 2nd symbol IDFT[%d/%d] = (%ld,%ld)=>%f\n",
mcs[i], seq_index, corr[0][1].r, corr[0][1].i,
10*log10((double)squaredMod(corr[0][1])));
if (pucch_pdu->freq_hop_flag == 0) {
if (pucch_pdu->nr_of_symbols == 1) {// non-coherent correlation
temp = 0;
for (int aa=0; aa<frame_parms->nb_antennas_rx; aa++)
temp += squaredMod(corr[aa][0]);
} else {
temp = 0;
for (int aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
c64_t corr2;
csum(corr2, corr[aa][0], corr[aa][1]);
// coherent combining of 2 symbols and then complex modulus for single-frequency case
temp += corr2.r*corr2.r + corr2.i*corr2.i;
}
}
} else if (pucch_pdu->freq_hop_flag == 1) {
// full non-coherent combining of 2 symbols for frequency-hopping case
temp = 0;
for (int aa=0; aa<frame_parms->nb_antennas_rx; aa++)
temp += squaredMod(corr[aa][0]) + squaredMod(corr[aa][1]);
}
else AssertFatal(1==0,"shouldn't happen\n");
LOG_D(PHY, "Sequence %d temp %ld vs. xrtmag %ld xrtmag_next %ld, slot %d rx atnennas %u\n",
i, temp, xrtmag, xrtmag_next, slot, frame_parms->nb_antennas_rx);
if (temp > xrtmag) {
xrtmag_next = xrtmag;
xrtmag = temp;
LOG_D(PHY,"Sequence %d xrtmag %ld xrtmag_next %ld, slot %d\n", i, xrtmag, xrtmag_next, slot);
maxpos = i;
int64_t temp2 = 0,temp3 = 0;;
for (int aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
temp2 += squaredMod(corr[aa][0]);
if (pucch_pdu->nr_of_symbols == 2)
temp3 += squaredMod(corr[aa][1]);
}
}
else if (temp > xrtmag_next)
xrtmag_next = temp;
}
#ifdef DEBUG_NR_PUCCH_RX
LOG_D(NR_PHY, "PUCCH 0 : maxpos %d\n", maxpos);
#endif
index = maxpos;
uint8_t ack_nack = !(index&0x01);
LOG_D(PHY,
"[PSFCH RX] %d.%d HARQ %s\n",
frame,
slot,
ack_nack == 0 ? "ACK" : "NACK");
return ack_nack;
}

View File

@@ -47,7 +47,7 @@
#include <execinfo.h>
#include <getopt.h>
#include <sys/sysinfo.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

View File

@@ -93,6 +93,8 @@
#include "impl_defs_top.h"
#include "impl_defs_nr.h"
// This is for ULSCH RX structures used for Sidelink
#include "defs_gNB.h"
#include "time_meas.h"
#include "PHY/CODING/coding_defs.h"
#include "PHY/CODING/nrLDPC_coding/nrLDPC_coding_interface.h"
@@ -279,7 +281,7 @@ typedef struct {
#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)
#define NR_SLSCH_RX_MAX 2
/* NR Sidelink PSBCH payload fields
TODO: This will be removed in the future and
filled in by the upper layers once developed. */
@@ -406,6 +408,7 @@ typedef struct PHY_VARS_NR_UE_s {
uint8_t prs_active_gNBs;
NR_DL_UE_HARQ_t dl_harq_processes[2][NR_MAX_DLSCH_HARQ_PROCESSES];
NR_UL_UE_HARQ_t ul_harq_processes[NR_MAX_ULSCH_HARQ_PROCESSES];
NR_UL_UE_HARQ_t sl_harq_processes[NR_MAX_SLSCH_HARQ_PROCESSES];
//Paging parameters
uint32_t IMSImod1024;
uint32_t PF;
@@ -457,6 +460,7 @@ typedef struct PHY_VARS_NR_UE_s {
/// temporary offset during cell search prior to MIB decoding
int ssb_offset;
uint16_t symbol_offset; /// offset in terms of symbols for detected ssb in sync
int rx_offset; /// Timing offset
int64_t max_pos_iir; /// Timing offset IIR filter
int max_pos_acc; /// Timing offset accumuluated error for PI filter
@@ -521,6 +525,20 @@ typedef struct PHY_VARS_NR_UE_s {
// Sidelink parameters
sl_nr_sidelink_mode_t sl_mode;
sl_nr_ue_phy_params_t SL_UE_PHY_PARAMS;
struct PHY_MEASUREMENTS_gNB_s *sl_measurements;
int max_nb_slsch;
// we use the gNB ULSCH context for SLSCH reception
struct NR_gNB_ULSCH_t *slsch;
struct NR_gNB_PUSCH *pssch_vars;
bool phy_config_request_sent;
int pscch_dmrs_gold_init;
/// PDCCH DMRS for TX
uint32_t ***nr_gold_pscch_dmrs;
/// PSCCH DMRS for RX
uint32_t ***nr_gold_pscch;
/// PSSCH signal detection threshold
int pssch_thres;
Actor_t sync_actor;
Actor_t *dl_actors;
Actor_t *ul_actors;
@@ -581,6 +599,8 @@ typedef struct nr_phy_data_tx_s {
// Sidelink Rx action decided by MAC
sl_nr_tx_config_type_enum_t sl_tx_action;
sl_nr_tx_config_psbch_pdu_t psbch_vars;
sl_nr_tx_config_pscch_pssch_pdu_t nr_sl_pssch_pscch_pdu;
uint32_t pscch_Nid;
} nr_phy_data_tx_t;
typedef struct nr_phy_data_s {
@@ -589,6 +609,12 @@ typedef struct nr_phy_data_s {
// Sidelink Rx action decided by MAC
sl_nr_rx_config_type_enum_t sl_rx_action;
sl_nr_rx_config_pscch_pdu_t nr_sl_pscch_pdu;
sl_nr_rx_config_pssch_sci_pdu_t nr_sl_pssch_sci_pdu;
sl_nr_rx_config_pssch_pdu_t nr_sl_pssch_pdu;
sl_nr_tti_csi_rs_pdu_t nr_sl_csi_rs_pdu;
sl_nr_tx_rx_config_psfch_pdu_t *psfch_pdu_list;
uint8_t num_psfch_pdus;
NR_UE_CSI_RS csirs_vars;
NR_UE_CSI_IM csiim_vars;
} nr_phy_data_t;

View File

@@ -336,4 +336,34 @@ typedef struct {
#define KHz (1000UL)
#define MHz (1000*KHz)
static const int16_t idft12_re[12][12] = {
{23170,23170,23170,23170,23170,23170,23170,23170,23170,23170,23170,23170},
{23170,20066,11585,0,-11585,-20066,-23170,-20066,-11585,0,11585,20066},
{23170,11585,-11585,-23170,-11585,11585,23170,11585,-11585,-23170,-11585,11585},
{23170,0,-23170,0,23170,0,-23170,0,23170,0,-23170,0},
{23170,-11585,-11585,23170,-11585,-11585,23170,-11585,-11585,23170,-11585,-11585},
{23170,-20066,11585,0,-11585,20066,-23170,20066,-11585,0,11585,-20066},
{23170,-23170,23170,-23170,23170,-23170,23170,-23170,23170,-23170,23170,-23170},
{23170,-20066,11585,0,-11585,20066,-23170,20066,-11585,0,11585,-20066},
{23170,-11585,-11585,23170,-11585,-11585,23170,-11585,-11585,23170,-11585,-11585},
{23170,0,-23170,0,23170,0,-23170,0,23170,0,-23170,0},
{23170,11585,-11585,-23170,-11585,11585,23170,11585,-11585,-23170,-11585,11585},
{23170,20066,11585,0,-11585,-20066,-23170,-20066,-11585,0,11585,20066}
};
static const int16_t idft12_im[12][12] = {
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,11585,20066,23170,20066,11585,0,-11585,-20066,-23170,-20066,-11585},
{0,20066,20066,0,-20066,-20066,0,20066,20066,0,-20066,-20066},
{0,23170,0,-23170,0,23170,0,-23170,0,23170,0,-23170},
{0,20066,-20066,0,20066,-20066,0,20066,-20066,0,20066,-20066},
{0,11585,-20066,23170,-20066,11585,0,-11585,20066,-23170,20066,-11585},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,-11585,20066,-23170,20066,-11585,0,11585,-20066,23170,-20066,11585},
{0,-20066,20066,0,-20066,20066,0,-20066,20066,0,-20066,20066},
{0,-23170,0,23170,0,-23170,0,23170,0,-23170,0,23170},
{0,-20066,-20066,0,20066,20066,0,-20066,-20066,0,20066,20066},
{0,-11585,-20066,-23170,-20066,-11585,0,11585,20066,23170,20066,11585}
};
#endif

View File

@@ -113,6 +113,47 @@ typedef struct SL_NR_SYNC_PARAMS {
} SL_NR_SYNC_PARAMS_t;
typedef struct SL_NR_UE_PSSCH {
// AVG POWER OF PSSCH DMRS in dB/RE
int16_t rsrp_dB_per_RE;
// AVG POWER OF PSSCH DMRS in dBm/RE
int16_t rsrp_dBm_per_RE;
// STATS - CRC Errors observed during PSSCH reception (per HARQ round)
uint32_t rx_errors[8];
// STATS - CRC Errors observed during PSSCH SCI2 reception
uint32_t rx_sci2_errors;
// STATS - Receptions with CRC OK
uint32_t rx_ok;
// STATS - Receptions with CRC OK
uint32_t rx_sci2_ok;
// STATS - transmissions of PSSCH by the UE
uint32_t num_pssch_tx;
// STATS - transmissions of PSSCH by the UE
uint32_t num_pssch_sci2_tx;
} SL_NR_UE_PSSCH_t;
typedef struct SL_NR_UE_PSCCH {
// AVG POWER OF PSCCH DMRS in dB/RE
int16_t rsrp_dB_per_RE;
// AVG POWER OF PSCCH DMRS in dBm/RE
int16_t rsrp_dBm_per_RE;
// STATS - Receptions with CRC OK
uint32_t rx_ok;
// STATS - transmissions of PSBCH by the UE
uint32_t num_pscch_tx;
} SL_NR_UE_PSCCH_t;
typedef struct SL_NR_UE_PSBCH {
// AVG POWER OF PSBCH DMRS in dB/RE
int16_t rsrp_dB_per_RE;
@@ -130,6 +171,12 @@ typedef struct SL_NR_UE_PSBCH {
} SL_NR_UE_PSBCH_t;
typedef struct SL_NR_UE_PSFCH {
// STATS - transmissions of PSFCH by the UE
uint32_t num_psfch_tx;
uint32_t num_psfch_rx;
} SL_NR_UE_PSFCH_t;
typedef struct sl_nr_ue_phy_params {
SL_NR_UE_INIT_PARAMS_t init_params;
@@ -138,7 +185,16 @@ typedef struct sl_nr_ue_phy_params {
// Sidelink PHY PARAMETERS USED FOR PSBCH reception/Txn
SL_NR_UE_PSBCH_t psbch;
// Configuration parameters from MAC
// sidelink phy parameters used for pscch reception/txn
SL_NR_UE_PSCCH_t pscch;
// sidelink phy parameters used for pssch reception/txn
SL_NR_UE_PSSCH_t pssch;
// sidelink phy parameters used for psfch reception/txn
SL_NR_UE_PSFCH_t psfch;
//Configuration parameters from MAC
sl_nr_phy_config_request_t sl_config;
NR_DL_FRAME_PARMS sl_frame_params;
@@ -150,4 +206,4 @@ typedef struct sl_nr_ue_phy_params {
} sl_nr_ue_phy_params_t;
#endif
#endif

View File

@@ -277,6 +277,7 @@
#define NR_MAX_ULSCH_HARQ_PROCESSES (NR_MAX_HARQ_PROCESSES) /* cf 38.214 6.1 UE procedure for receiving the physical uplink shared channel */
#define NR_MAX_DLSCH_HARQ_PROCESSES (NR_MAX_HARQ_PROCESSES) /* cf 38.214 5.1 UE procedure for receiving the physical downlink shared channel */
#define NR_MAX_SLSCH_HARQ_PROCESSES (NR_MAX_HARQ_PROCESSES)
#endif
/// Data structure for transmission.

View File

@@ -183,5 +183,15 @@ void nr_fill_sl_rx_indication(sl_nr_rx_indication_t *rx_ind,
void *typeSpecific,
uint16_t rx_slss_id);
void nr_postDecode_slsch(PHY_VARS_NR_UE *UE, notifiedFIFO_elt_t *req,
UE_nr_rxtx_proc_t *proc,
nr_phy_data_t *phy_data,
int8_t *ack_nack_rcvd,
uint8_t num_acks);
typedef struct {
ldpcDecode_t *rdata;
bool rxok;
} slsch_status_t;
#endif
/** @}*/

View File

@@ -451,12 +451,17 @@ void nr_ue_sl_phy_config_request(nr_sl_phy_config_t *phy_config)
void sl_handle_scheduled_response(nr_scheduled_response_t *scheduled_response)
{
module_id_t module_id = scheduled_response->module_id;
const char *sl_rx_action[] = {"NONE", "RX_PSBCH", "RX_PSCCH", "RX_SCI2_ON_PSSCH", "RX_SLSCH_ON_PSSCH"};
const char *sl_tx_action[] = {"TX_PSBCH", "TX_PSCCH_PSSCH", "TX_PSFCH"};
const char *sl_rx_action[] = {"NONE", "RX_PSBCH", "RX_PSCCH", "RX_SCI2_ON_PSSCH", "RX_SLSCH_ON_PSSCH", "RX_PSFCH", "RX_SLSCH_ON_PSSCH_CSI_RS"};
const char *sl_tx_action[] = {"TX_PSBCH", "TX_PSCCH_PSSCH", "TX_PSCCH_PSSCH_PSFCH", "TX_PSCCH_PSSCH_CSI_RS"};
//NR_UE_CSI_RS *csirs_vars = PHY_vars_UE_g[module_id][cc_id]->csirs_vars[0];
if (scheduled_response->sl_rx_config != NULL) {
sl_nr_rx_config_request_t *sl_rx_config = scheduled_response->sl_rx_config;
nr_phy_data_t *phy_data = (nr_phy_data_t *)scheduled_response->phy_data;
sl_nr_tti_csi_rs_pdu_t *csirs_config_pdu;
AssertFatal(sl_rx_config->number_pdus == SL_NR_RX_CONFIG_LIST_NUM,
"sl_rx_config->number_pdus incorrect\n");
AssertFatal(sl_rx_config->number_pdus == SL_NR_RX_CONFIG_LIST_NUM, "sl_rx_config->number_pdus incorrect\n");
@@ -465,6 +470,34 @@ void sl_handle_scheduled_response(nr_scheduled_response_t *scheduled_response)
phy_data->sl_rx_action = SL_NR_CONFIG_TYPE_RX_PSBCH;
LOG_D(PHY, "Recvd CONFIG_TYPE_RX_PSBCH\n");
break;
case SL_NR_CONFIG_TYPE_RX_PSCCH:
phy_data->sl_rx_action = SL_NR_CONFIG_TYPE_RX_PSCCH;
phy_data->nr_sl_pscch_pdu = sl_rx_config->sl_rx_config_list[0].rx_pscch_config_pdu;
LOG_D(NR_PHY, "Recvd CONFIG_TYPE_RX_PSCCH\n");
break;
case SL_NR_CONFIG_TYPE_RX_PSSCH_SCI:
phy_data->sl_rx_action = SL_NR_CONFIG_TYPE_RX_PSSCH_SCI;
phy_data->nr_sl_pssch_sci_pdu = sl_rx_config->sl_rx_config_list[0].rx_sci2_config_pdu;
LOG_D(NR_PHY, "Recvd CONFIG_TYPE_RX_PSSCH_SCI\n");
break;
case SL_NR_CONFIG_TYPE_RX_PSSCH_SLSCH:
case SL_NR_CONFIG_TYPE_RX_PSFCH:
case SL_NR_CONFIG_TYPE_RX_PSSCH_SLSCH_CSI_RS:
phy_data->sl_rx_action = sl_rx_config->sl_rx_config_list[0].pdu_type;
phy_data->nr_sl_pssch_pdu = sl_rx_config->sl_rx_config_list[0].rx_pssch_config_pdu;
LOG_D(NR_PHY, "%4d.%2d Recvd %s\n", sl_rx_config->sfn, sl_rx_config->slot, sl_rx_action[phy_data->sl_rx_action]);
if (phy_data->sl_rx_action == SL_NR_CONFIG_TYPE_RX_PSSCH_SLSCH_CSI_RS) {
csirs_config_pdu = &sl_rx_config->sl_rx_config_list[0].rx_csi_rs_config_pdu;
memcpy((void*)&(phy_data->csirs_vars.csirs_config_pdu), (void*)csirs_config_pdu, sizeof(sl_nr_tti_csi_rs_pdu_t));
phy_data->csirs_vars.active = true;
}
if (phy_data->sl_rx_action == SL_NR_CONFIG_TYPE_RX_PSFCH) {
phy_data->psfch_pdu_list = calloc(sl_rx_config->sl_rx_config_list[0].num_psfch_pdus, sizeof(sl_nr_tx_rx_config_psfch_pdu_t));
memcpy((void*)phy_data->psfch_pdu_list, (void*)sl_rx_config->sl_rx_config_list[0].rx_psfch_pdu_list,
sl_rx_config->sl_rx_config_list[0].num_psfch_pdus * sizeof(sl_nr_tx_rx_config_psfch_pdu_t));
phy_data->num_psfch_pdus = sl_rx_config->sl_rx_config_list[0].num_psfch_pdus;
}
break;
default:
AssertFatal(0, "Incorrect sl_rx config req pdutype \n");
break;
@@ -492,6 +525,32 @@ void sl_handle_scheduled_response(nr_scheduled_response_t *scheduled_response)
phy_data_tx->psbch_vars.psbch_tx_power = sl_tx_config->tx_config_list[0].tx_psbch_config_pdu.psbch_tx_power;
phy_data_tx->psbch_vars.tx_slss_id = sl_tx_config->tx_config_list[0].tx_psbch_config_pdu.tx_slss_id;
break;
case SL_NR_CONFIG_TYPE_TX_PSCCH_PSSCH:
case SL_NR_CONFIG_TYPE_TX_PSCCH_PSSCH_CSI_RS:
case SL_NR_CONFIG_TYPE_TX_PSFCH: {
sl_nr_tx_config_pscch_pssch_pdu_t *tx_config_pdu = &sl_tx_config->tx_config_list[0].tx_pscch_pssch_config_pdu;
phy_data_tx->sl_tx_action = sl_tx_config->tx_config_list[0].pdu_type;
phy_data_tx->nr_sl_pssch_pscch_pdu = *tx_config_pdu;
LOG_D(PHY, "Recvd CONFIG_TYPE_%s in (%d.%d) PSCCH startRB %hhu, PSCCH numRB %hhu\n",
sl_tx_action[phy_data_tx->sl_tx_action - SL_NR_CONFIG_TYPE_TX_PSBCH],
sl_tx_config->sfn, sl_tx_config->slot,
phy_data_tx->nr_sl_pssch_pscch_pdu.startrb,
phy_data_tx->nr_sl_pssch_pscch_pdu.pscch_numrbs);
LOG_D(NR_PHY, "format 1A length %hu :%llx, format 2x length %hu : %llx, PSSCH mcs %hu, PSSCH tbslrm %u\n",
phy_data_tx->nr_sl_pssch_pscch_pdu.pscch_sci_payload_len,
(unsigned long long)*phy_data_tx->nr_sl_pssch_pscch_pdu.pscch_sci_payload,
phy_data_tx->nr_sl_pssch_pscch_pdu.sci2_payload_len,
(unsigned long long)*phy_data_tx->nr_sl_pssch_pscch_pdu.sci2_payload,
phy_data_tx->nr_sl_pssch_pscch_pdu.mcs,
phy_data_tx->nr_sl_pssch_pscch_pdu.tbslbrm);
if (phy_data_tx->sl_tx_action == SL_NR_CONFIG_TYPE_TX_PSCCH_PSSCH_CSI_RS) {
phy_data_tx->nr_sl_pssch_pscch_pdu.nr_sl_csi_rs_pdu = tx_config_pdu->nr_sl_csi_rs_pdu;
}
//uint8_t current_harq_pid = tx_config_pdu->harq_pid;
//NR_UL_UE_HARQ_t *harq_process = &PHY_vars_UE_g[module_id][cc_id]->sl_harq_processes[current_harq_pid];
phy_data_tx->ulsch.status = ACTIVE; //harq_process->status = ACTIVE;
}
break;
default:
AssertFatal(0, "Incorrect sl_tx config req pdutype \n");
break;

View File

@@ -23,7 +23,10 @@
#include "PHY/defs_nr_UE.h"
#include <openair1/PHY/TOOLS/phy_scope_interface.h>
#include "openair1/PHY/NR_TRANSPORT/nr_ulsch.h"
#include "openair1/PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "common/utils/LOG/log.h"
#include "common/utils/utils.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "UTIL/OPT/opt.h"
#include "intertask_interface.h"
@@ -31,6 +34,8 @@
#include "PHY/MODULATION/modulation_UE.h"
#include "PHY/NR_UE_ESTIMATION/nr_estimation.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
#include "executables/nr-uesoftmodem.h"
#include "common/utils/colors.h"
void nr_fill_sl_indication(nr_sidelink_indication_t *sl_ind,
sl_nr_rx_indication_t *rx_ind,
@@ -77,6 +82,18 @@ void nr_fill_sl_rx_indication(sl_nr_rx_indication_t *rx_ind,
switch (pdu_type) {
case SL_NR_RX_PDU_TYPE_SLSCH:
case SL_NR_RX_PDU_TYPE_SLSCH_PSFCH: {
sl_nr_slsch_pdu_t *rx_slsch_pdu = &rx_ind->rx_indication_body[n_pdus - 1].rx_slsch_pdu;
slsch_status_t *slsch_status = (slsch_status_t *)typeSpecific;
rx_slsch_pdu->pdu = slsch_status->rdata->ulsch_harq->b;
rx_slsch_pdu->pdu_length = slsch_status->rdata->ulsch_harq->TBS;
rx_slsch_pdu->harq_pid = slsch_status->rdata->harq_pid;
rx_slsch_pdu->ack_nack = (slsch_status->rxok==true) ? 1 : 0;
LOG_D(NR_MAC, "%4d.%2d Received %s SLSCH\n", rx_ind->sfn, rx_ind->slot, rx_slsch_pdu->ack_nack ? "Correct" : "Incorrect");
if (slsch_status->rxok==true) ue->SL_UE_PHY_PARAMS.pssch.rx_ok++;
else ue->SL_UE_PHY_PARAMS.pssch.rx_errors[0]++;
}
break;
case FAPI_NR_RX_PDU_TYPE_SSB: {
sl_nr_ssb_pdu_t *ssb_pdu = &rx_ind->rx_indication_body[n_pdus - 1].ssb_pdu;
@@ -102,6 +119,246 @@ void nr_fill_sl_rx_indication(sl_nr_rx_indication_t *rx_ind,
rx_ind->number_pdus = n_pdus;
}
extern int dmrs_pscch_mask[2];
#if 0
int nr_slsch_procedures(PHY_VARS_NR_UE *ue, int frame_rx, int slot_rx, int SLSCH_id, UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data, bool is_csi_rs_slot, int8_t *ack_nack_rcvd, int num_acks) {
sl_nr_ue_phy_params_t *sl_phy_params = &ue->SL_UE_PHY_PARAMS;
NR_DL_FRAME_PARMS *fp = &sl_phy_params->sl_frame_params;
sl_nr_rx_config_pssch_pdu_t *slsch_pdu = &phy_data->nr_sl_pssch_pdu; //ue->slsch[SLSCH_id].harq_process->slsch_pdu;
sl_nr_rx_config_pssch_sci_pdu_t *pssch_pdu = &phy_data->nr_sl_pssch_sci_pdu; //ue->slsch[SLSCH_id].harq_process->pssch_pdu;
uint8_t freq_density = 0;
uint8_t nr_of_rbs = 0;
if (is_csi_rs_slot) {
freq_density = phy_data->csirs_vars.csirs_config_pdu.freq_density; //ue->csirs_vars[0]->csirs_config_pdu.freq_density;
nr_of_rbs = phy_data->csirs_vars.csirs_config_pdu.nr_of_rbs; //ue->csirs_vars[0]->csirs_config_pdu.nr_of_rbs;
AssertFatal((freq_density == 1) || (nr_of_rbs > 0), "CSI-RS parameters are not properly configured\n");
}
int harq_pid = slsch_pdu->harq_pid;
uint16_t nb_re_dmrs;
uint16_t start_symbol = 1;
uint16_t number_symbols = pssch_pdu->pssch_numsym;
ue->slsch[SLSCH_id].harq_process->harq_to_be_cleared=true;
uint8_t number_dmrs_symbols = 0;
for (int l = start_symbol; l < start_symbol + number_symbols; l++)
number_dmrs_symbols += ((pssch_pdu->dmrs_symbol_position)>>l)&0x01;
nb_re_dmrs = 6;
uint32_t rb_size = pssch_pdu->num_subch*pssch_pdu->subchannel_size;
int sci1_dmrs_overlap = pssch_pdu->dmrs_symbol_position & dmrs_pscch_mask[pssch_pdu->pscch_numsym-2];
int sci2_re = get_NREsci2_2(pssch_pdu->sci2_alpha_times_100,
pssch_pdu->sci2_len,
pssch_pdu->sci2_beta_offset,
pssch_pdu->pssch_numsym,
pssch_pdu->pscch_numsym,
pssch_pdu->pscch_numrbs,
pssch_pdu->l_subch,
pssch_pdu->subchannel_size,
pssch_pdu->targetCodeRate,
0);
uint8_t nr_rbs_w_csi_rs = nr_of_rbs / freq_density;
uint8_t subcarriers_used = get_nrUE_params()->nb_antennas_tx > 2 ? 2 : get_nrUE_params()->nb_antennas_tx;
int num_CSI_REs = is_csi_rs_slot ? nr_rbs_w_csi_rs * subcarriers_used : 0;
uint16_t sci1_re = pssch_pdu->pscch_numsym * pssch_pdu->pscch_numrbs * NR_NB_SC_PER_RB;
uint32_t G = nr_get_G_SL(rb_size,
number_symbols,
nb_re_dmrs,
number_dmrs_symbols, // number of dmrs symbols irrespective of single or double symbol dmrs
sci1_dmrs_overlap,
sci1_re,
pssch_pdu->pscch_numrbs,
sci2_re,
num_CSI_REs,
pssch_pdu->mod_order,
pssch_pdu->num_layers);
AssertFatal(G>0,"G is 0 : rb_size %u, number_symbols %d, nb_re_dmrs %d, number_dmrs_symbols %d, qam_mod_order %u, nrOfLayer %u\n",
rb_size,
number_symbols,
nb_re_dmrs,
number_dmrs_symbols, // number of dmrs symbols irrespective of single or double symbol dmrs
pssch_pdu->mod_order,
pssch_pdu->num_layers);
LOG_D(NR_PHY,"slot %d rb_size %d, number_symbols %d, nb_re_dmrs %d, dmrs symbol positions %d, number_dmrs_symbols %d, qam_mod_order %d, nrOfLayer %d\n",
slot_rx,
rb_size,
number_symbols,
nb_re_dmrs,
pssch_pdu->dmrs_symbol_position,
number_dmrs_symbols, // number of dmrs symbols irrespective of single or double symbol dmrs
pssch_pdu->mod_order,
pssch_pdu->num_layers);
nr_ulsch_layer_demapping(ue->pssch_vars[SLSCH_id].llr,
pssch_pdu->num_layers,
pssch_pdu->mod_order,
G,
ue->pssch_vars[SLSCH_id].llr_layers);
//for (int g=0;g<G;g++) LOG_I(NR_PHY,"prescrambling_llr[%d] %d\n",g,ue->pssch_vars[SLSCH_id].llr[g]);
//----------------------------------------------------------
//------------------- ULSCH unscrambling -------------------
//----------------------------------------------------------
//LOG_I(NR_PHY,"SLSCH, unscrambling with Nid %x\n",pssch_pdu->Nid);
nr_ulsch_unscrambling(ue->pssch_vars[SLSCH_id].llr, G, pssch_pdu->Nid, 1010);
// for (int g=0;g<32;g++) LOG_I(NR_PHY,"unscrambling_llr[%d] %d\n",g,ue->pssch_vars[SLSCH_id].llr[g]);
//----------------------------------------------------------
//--------------------- ULSCH decoding ---------------------
//----------------------------------------------------------
nfapi_nr_pusch_pdu_t pusch_pdu;
pusch_pdu.rb_size = rb_size;
pusch_pdu.qam_mod_order = pssch_pdu->mod_order;
pusch_pdu.mcs_index = slsch_pdu->mcs;
pusch_pdu.nrOfLayers = pssch_pdu->num_layers;
pusch_pdu.pusch_data.tb_size=slsch_pdu->tb_size;
uint32_t A = slsch_pdu->tb_size<<3;
pusch_pdu.target_code_rate=slsch_pdu->target_coderate;
float Coderate = (float) (slsch_pdu->target_coderate) / 10240.0f;
pusch_pdu.pusch_data.rv_index=slsch_pdu->rv_index;
if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){
pusch_pdu.maintenance_parms_v3.ldpcBaseGraph=2;
}
else{
pusch_pdu.maintenance_parms_v3.ldpcBaseGraph=1;
}
pusch_pdu.maintenance_parms_v3.tbSizeLbrmBytes=slsch_pdu->tbslbrm>>3;
LOG_D(NR_PHY, "%4d.%2d Calling nr_ulsch_decoding\n", frame_rx, slot_rx);
int nbDecode =
nr_ulsch_decoding(NULL, ue, SLSCH_id, ue->pssch_vars[SLSCH_id].llr, fp, &pusch_pdu, frame_rx, slot_rx, harq_pid, G, proc, phy_data, ack_nack_rcvd, num_acks);
return nbDecode;
}
void nr_postDecode_slsch(PHY_VARS_NR_UE *UE, notifiedFIFO_elt_t *req,UE_nr_rxtx_proc_t *proc,nr_phy_data_t *phy_data, int8_t *ack_nack_rcvd, uint8_t num_acks)
{
ldpcDecode_t *rdata = (ldpcDecode_t*) NotifiedFifoData(req);
NR_UL_gNB_HARQ_t *slsch_harq = rdata->ulsch_harq;
NR_gNB_ULSCH_t *slsch = rdata->ulsch;
int r = rdata->segment_r;
sl_nr_rx_config_pssch_pdu_t *slsch_pdu = &phy_data->nr_sl_pssch_pdu;//UE->slsch[rdata->ulsch_id].harq_process->slsch_pdu;
bool decodeSuccess = (rdata->decodeIterations <= rdata->decoderParms.numMaxIter);
slsch_harq->processedSegments++;
LOG_D(NR_PHY,
"processing result of segment: %d, processed %d/%d\n",
rdata->segment_r,
slsch_harq->processedSegments,
rdata->nbSegments);
if (decodeSuccess) {
memcpy(slsch_harq->b + rdata->offset, slsch_harq->c[r], rdata->Kr_bytes - (slsch_harq->F >> 3) - ((slsch_harq->C > 1) ? 3 : 0));
} else {
LOG_D(NR_PHY, "ULSCH %d in error\n", rdata->ulsch_id);
}
//int dumpsig=0;
// if all segments are done
if (rdata->nbSegments == slsch_harq->processedSegments) {
sl_nr_rx_indication_t sl_rx_indication;
nr_sidelink_indication_t sl_indication;
slsch_status_t slsch_status;
if (!check_abort(&slsch_harq->abort_decode) && !UE->pssch_vars[rdata->ulsch_id].DTX) {
LOG_D(NR_PHY,
"[UE] SLSCH: Setting ACK for SFN/SF %d.%d (pid %d, ndi %d, status %d, round %d, TBS %d, Max interation "
"(all seg) %d)\n",
slsch->frame,
slsch->slot,
rdata->harq_pid,
slsch_pdu->ndi,
slsch->active,
slsch_harq->round,
slsch_harq->TBS,
rdata->decodeIterations);
slsch->active = false;
slsch_harq->round = 0;
LOG_D(NR_PHY, "%4d.%2d SLSCH received ok \n", proc->frame_rx, proc->nr_slot_rx);
slsch_status.rdata = rdata;
slsch_status.rxok = true;
//dumpsig=1;
} else {
LOG_E(NR_PHY,
"[UE] SLSCH %d in error: Setting NAK for SFN/SF %d/%d (pid %d, ndi %d, status %d, round %d, RV %d, prb_start %d, prb_size %d, "
"TBS %d) r %d\n",
rdata->ulsch_id,
slsch->frame,
slsch->slot,
rdata->harq_pid,
slsch_pdu->ndi,
slsch->active,
slsch_harq->round,
slsch_harq->ulsch_pdu.pusch_data.rv_index,
slsch_harq->ulsch_pdu.rb_start,
slsch_harq->ulsch_pdu.rb_size,
slsch_harq->TBS,
r);
slsch->handled = 1;
LOG_D(NR_PHY, "%4d.%2d SLSCH %d in error\n", proc->frame_rx, proc->nr_slot_rx, rdata->ulsch_id);
slsch_status.rdata = rdata;
slsch_status.rxok = false;
// dumpsig=1;
}
slsch->last_iteration_cnt = rdata->decodeIterations;
sl_rx_indication.sfn = proc->frame_rx;
sl_rx_indication.slot = proc->nr_slot_rx;
sl_rx_indication.rx_indication_body[0].rx_slsch_pdu.ack_nack_rcvd = calloc(num_acks, sizeof(uint8_t));
memcpy((void*)sl_rx_indication.rx_indication_body[0].rx_slsch_pdu.ack_nack_rcvd, (void*)ack_nack_rcvd,
num_acks * sizeof(uint8_t));
sl_rx_indication.rx_indication_body[0].rx_slsch_pdu.num_acks_rcvd = num_acks;
uint8_t pdu_type = phy_data->sl_rx_action == SL_NR_CONFIG_TYPE_RX_PSSCH_SLSCH_PSFCH ? SL_NR_RX_PDU_TYPE_SLSCH_PSFCH : SL_NR_RX_PDU_TYPE_SLSCH;
nr_fill_sl_rx_indication(&sl_rx_indication, pdu_type, UE, 1, proc, (void*)&slsch_status, 0);
nr_fill_sl_indication(&sl_indication,&sl_rx_indication,NULL,proc,UE,phy_data);
if (UE->if_inst && UE->if_inst->sl_indication)
UE->if_inst->sl_indication(&sl_indication);
/*
if (ulsch_harq->ulsch_pdu.mcs_index == 0 && dumpsig==1) {
int off = ((ulsch_harq->ulsch_pdu.rb_size&1) == 1)? 4:0;
LOG_M("rxsigF0.m","rxsF0",&gNB->common_vars.rxdataF[0][(ulsch_harq->slot&3)*gNB->frame_parms.ofdm_symbol_size*gNB->frame_parms.symbols_per_slot],gNB->frame_parms.ofdm_symbol_size*gNB->frame_parms.symbols_per_slot,1,1);
LOG_M("rxsigF0_ext.m","rxsF0_ext",
&gNB->pusch_vars[0].rxdataF_ext[0][ulsch_harq->ulsch_pdu.start_symbol_index*NR_NB_SC_PER_RB *
ulsch_harq->ulsch_pdu.rb_size],ulsch_harq->ulsch_pdu.nr_of_symbols*(off+(NR_NB_SC_PER_RB *
ulsch_harq->ulsch_pdu.rb_size)),1,1); LOG_M("chestF0.m","chF0",
&gNB->pusch_vars[0].ul_ch_estimates[0][ulsch_harq->ulsch_pdu.start_symbol_index*gNB->frame_parms.ofdm_symbol_size],gNB->frame_parms.ofdm_symbol_size,1,1);
LOG_M("chestF0_ext.m","chF0_ext",
&gNB->pusch_vars[0]->ul_ch_estimates_ext[0][(ulsch_harq->ulsch_pdu.start_symbol_index+1)*(off+(NR_NB_SC_PER_RB *
ulsch_harq->ulsch_pdu.rb_size))], (ulsch_harq->ulsch_pdu.nr_of_symbols-1)*(off+(NR_NB_SC_PER_RB *
ulsch_harq->ulsch_pdu.rb_size)),1,1); LOG_M("rxsigF0_comp.m","rxsF0_comp",
&gNB->pusch_vars[0].rxdataF_comp[0][ulsch_harq->ulsch_pdu.start_symbol_index*(off+(NR_NB_SC_PER_RB *
ulsch_harq->ulsch_pdu.rb_size))],ulsch_harq->ulsch_pdu.nr_of_symbols*(off+(NR_NB_SC_PER_RB *
ulsch_harq->ulsch_pdu.rb_size)),1,1); LOG_M("rxsigF0_llr.m","rxsF0_llr",
&gNB->pusch_vars[0].llr[0],(ulsch_harq->ulsch_pdu.nr_of_symbols-1)*NR_NB_SC_PER_RB * ulsch_harq->ulsch_pdu.rb_size *
ulsch_harq->ulsch_pdu.qam_mod_order,1,0); if (gNB->frame_parms.nb_antennas_rx > 1) {
LOG_M("rxsigF1_ext.m","rxsF0_ext",
&gNB->pusch_vars[0].rxdataF_ext[1][ulsch_harq->ulsch_pdu.start_symbol_index*NR_NB_SC_PER_RB *
ulsch_harq->ulsch_pdu.rb_size],ulsch_harq->ulsch_pdu.nr_of_symbols*(off+(NR_NB_SC_PER_RB *
ulsch_harq->ulsch_pdu.rb_size)),1,1); LOG_M("chestF1.m","chF1",
&gNB->pusch_vars[0].ul_ch_estimates[1][ulsch_harq->ulsch_pdu.start_symbol_index*gNB->frame_parms.ofdm_symbol_size],gNB->frame_parms.ofdm_symbol_size,1,1);
LOG_M("chestF1_ext.m","chF1_ext",
&gNB->pusch_vars[0].ul_ch_estimates_ext[1][(ulsch_harq->ulsch_pdu.start_symbol_index+1)*(off+(NR_NB_SC_PER_RB *
ulsch_harq->ulsch_pdu.rb_size))], (ulsch_harq->ulsch_pdu.nr_of_symbols-1)*(off+(NR_NB_SC_PER_RB *
ulsch_harq->ulsch_pdu.rb_size)),1,1); LOG_M("rxsigF1_comp.m","rxsF1_comp",
&gNB->pusch_vars[0].rxdataF_comp[1][ulsch_harq->ulsch_pdu.start_symbol_index*(off+(NR_NB_SC_PER_RB *
ulsch_harq->ulsch_pdu.rb_size))],ulsch_harq->ulsch_pdu.nr_of_symbols*(off+(NR_NB_SC_PER_RB *
ulsch_harq->ulsch_pdu.rb_size)),1,1);
}
exit(-1);
}
*/
slsch->last_iteration_cnt = rdata->decodeIterations;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING,0);
}
}
#endif
static int nr_ue_psbch_procedures(PHY_VARS_NR_UE *ue,
NR_DL_FRAME_PARMS *fp,
const UE_nr_rxtx_proc_t *proc,
@@ -174,6 +431,10 @@ int psbch_pscch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr
sl_nr_ue_phy_params_t *sl_phy_params = &ue->SL_UE_PHY_PARAMS;
NR_DL_FRAME_PARMS *fp = &sl_phy_params->sl_frame_params;
int sampleShift = INT_MAX;
#if 0
bool is_csi_rs_slot = false;
int8_t *ack_nack_rcvd = NULL;
#endif
// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX_SL, VCD_FUNCTION_IN);
start_meas(&sl_phy_params->phy_proc_sl_rx);
@@ -183,6 +444,41 @@ int psbch_pscch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr
const uint32_t rxdataF_sz = fp->samples_per_slot_wCP;
__attribute__((aligned(32))) c16_t rxdataF[fp->nb_antennas_rx][rxdataF_sz];
if ((frame_rx & 127) == 0)
{
LOG_I(NR_PHY,"============================================\n");
LOG_I(NR_PHY,"%s[UE%d] %d:%d PSBCH Stats: TX %u, RX ok %u, RX not ok %u\n",KGRN,
ue->Mod_id, frame_rx, nr_slot_rx,
sl_phy_params->psbch.num_psbch_tx,
sl_phy_params->psbch.rx_ok,
sl_phy_params->psbch.rx_errors);
LOG_I(NR_PHY,"%s[UE%d] %d:%d PSCCH Stats: TX %u, RX ok %u\n",KGRN,
ue->Mod_id, frame_rx, nr_slot_rx,
sl_phy_params->pscch.num_pscch_tx,
sl_phy_params->pscch.rx_ok);
LOG_I(NR_PHY,"%s[UE%d] %d:%d PSSCH/SCI2 Stats: TX %u, RX ok %u, RX not ok %u\n",KGRN,
ue->Mod_id, frame_rx, nr_slot_rx,
sl_phy_params->pssch.num_pssch_sci2_tx,
sl_phy_params->pssch.rx_sci2_ok,
sl_phy_params->pssch.rx_sci2_errors);
LOG_I(NR_PHY,"%s[UE%d] %d:%d PSSCH Stats: TX %u, RX ok %u, RX not ok (%u/%u/%u/%u)\n",KGRN,
ue->Mod_id, frame_rx, nr_slot_rx,
sl_phy_params->pssch.num_pssch_tx,
sl_phy_params->pssch.rx_ok,
sl_phy_params->pssch.rx_errors[0],
sl_phy_params->pssch.rx_errors[1],
sl_phy_params->pssch.rx_errors[2],
sl_phy_params->pssch.rx_errors[3]);
LOG_I(NR_PHY, "%s[UE%d] %d:%d PSFCH Stats: TX %u\n", KGRN,
ue->Mod_id, frame_rx, nr_slot_rx,
sl_phy_params->psfch.num_psfch_tx
);
LOG_I(NR_PHY,"============================================\n");
}
if (phy_data->sl_rx_action == SL_NR_CONFIG_TYPE_RX_PSBCH) {
const int estimateSz = fp->symbols_per_slot * fp->ofdm_symbol_size;
@@ -258,6 +554,200 @@ int psbch_pscch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr
LOG_I(NR_PHY, "============================================\n");
}
}
#if 0
else if (phy_data->sl_rx_action == SL_NR_CONFIG_TYPE_RX_PSCCH)
{
fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &phy_data->phy_pdcch_config.pdcch_config[0];
LOG_D(NR_PHY,"pscch_numsym = %d\n",phy_data->nr_sl_pscch_pdu.pscch_numsym);
LOG_D(NR_PHY,"pscch_startrb = %d\n",phy_data->nr_sl_pscch_pdu.pscch_startrb);
LOG_D(NR_PHY,"pscch_numrbs = %d\n",phy_data->nr_sl_pscch_pdu.pscch_numrbs);
LOG_D(NR_PHY,"pscch_dmrs_scrambling_id = %d\n",phy_data->nr_sl_pscch_pdu.pscch_dmrs_scrambling_id);
LOG_D(NR_PHY,"pscch_num_subch= %d\n",phy_data->nr_sl_pscch_pdu.num_subch);
LOG_D(NR_PHY,"pscch_subchannel_size = %d\n",phy_data->nr_sl_pscch_pdu.subchannel_size);
LOG_D(NR_PHY,"pscch_l_subch = %d\n",phy_data->nr_sl_pscch_pdu.l_subch);
LOG_D(NR_PHY,"pscch_pssch_numsym = %d\n",phy_data->nr_sl_pscch_pdu.pssch_numsym);
LOG_D(NR_PHY,"sense_pscch = %d\n",phy_data->nr_sl_pscch_pdu.sense_pscch);
rel15->rnti = 0;
rel15->BWPSize = phy_data->nr_sl_pscch_pdu.num_subch * phy_data->nr_sl_pscch_pdu.subchannel_size;
rel15->BWPStart = phy_data->nr_sl_pscch_pdu.pscch_startrb;
rel15->SubcarrierSpacing = fp->subcarrier_spacing;
rel15->coreset.frequency_domain_resource[0] = phy_data->nr_sl_pscch_pdu.pscch_startrb;
rel15->coreset.frequency_domain_resource[1] = phy_data->nr_sl_pscch_pdu.pscch_numrbs;
rel15->coreset.CoreSetType = NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG;
rel15->coreset.StartSymbolIndex = 1;
rel15->coreset.RegBundleSize = 0;
rel15->coreset.duration = phy_data->nr_sl_pscch_pdu.pscch_numsym;
rel15->coreset.pdcch_dmrs_scrambling_id = phy_data->nr_sl_pscch_pdu.pscch_dmrs_scrambling_id;
rel15->coreset.scrambling_rnti = 1010;
rel15->coreset.tci_present_in_dci = 0;
rel15->number_of_candidates = phy_data->nr_sl_pscch_pdu.l_subch;
rel15->num_dci_options = 1;
rel15->dci_length_options[0] = phy_data->nr_sl_pscch_pdu.sci_1a_length;
// L now provides the number of PRBs used by PSCCH instead of the number of CCEs
rel15->L[0] = phy_data->nr_sl_pscch_pdu.pscch_numrbs * phy_data->nr_sl_pscch_pdu.pscch_numsym;
// This provides the offset of the candidate of PSCCH in RBs instead of CCEs
rel15->CCE[0] = 0;
// Hold the channel estimates in frequency domain.
int32_t pscch_est_size = ((((fp->symbols_per_slot*(fp->ofdm_symbol_size+LTE_CE_FILTER_LENGTH))+15)/16)*16);
__attribute__ ((aligned(16))) int32_t pscch_dl_ch_estimates[4*fp->nb_antennas_rx][pscch_est_size];
//
int16_t rsrp_dBm = 0;
for (int sym=0; sym<rel15->coreset.duration;sym++) {
nr_slot_fep(ue,
fp,
proc->nr_slot_rx,
1+sym,
rxdataF,
link_type_sl,
0,
ue->common_vars.rxdata);
nr_pdcch_channel_estimation(ue,
proc,
1,
1+sym,
&rel15->coreset,
fp->first_carrier_offset,
rel15->BWPStart,
pscch_est_size,
pscch_dl_ch_estimates,
rxdataF,
&rsrp_dBm);
}
nr_ue_pdcch_procedures(ue, proc, 1, pscch_est_size, pscch_dl_ch_estimates, phy_data, 0, rxdataF, &rsrp_dBm);
LOG_D(NR_PHY,"returned from nr_ue_pdcch_procedures\n");
}
if (phy_data->sl_rx_action == SL_NR_CONFIG_TYPE_RX_PSSCH_SCI)
{
LOG_D(NR_PHY,"sci2_len = %d\n",phy_data->nr_sl_pssch_sci_pdu.sci2_len);
LOG_D(NR_PHY,"sci2_beta_offset = %d\n",phy_data->nr_sl_pssch_sci_pdu.sci2_beta_offset);
LOG_D(NR_PHY,"sci2_alpha_times_100= %d\n",phy_data->nr_sl_pssch_sci_pdu.sci2_alpha_times_100);
LOG_D(NR_PHY,"pssch_targetCodeRate = %d\n",phy_data->nr_sl_pssch_sci_pdu.targetCodeRate);
LOG_D(NR_PHY,"pssch_num_layers = %d\n",phy_data->nr_sl_pssch_sci_pdu.num_layers);
LOG_D(NR_PHY,"dmrs_symbol_position = %d\n",phy_data->nr_sl_pssch_sci_pdu.dmrs_symbol_position);
int num_dmrs = 0;
for (int s = 0; s < NR_NUMBER_OF_SYMBOLS_PER_SLOT; s++)
num_dmrs += (phy_data->nr_sl_pssch_sci_pdu.dmrs_symbol_position >> s) & 1;
LOG_D(NR_PHY,"num_dmrs = %d\n",num_dmrs);
LOG_D(NR_PHY,"Nid = %x\n",phy_data->nr_sl_pssch_sci_pdu.Nid);
LOG_D(NR_PHY,"startrb = %d\n",phy_data->nr_sl_pssch_sci_pdu.startrb);
LOG_D(NR_PHY,"pscch_numsym = %d\n",phy_data->nr_sl_pssch_sci_pdu.pscch_numsym);
LOG_D(NR_PHY,"pscch_numrbs = %d\n",phy_data->nr_sl_pssch_sci_pdu.pscch_numrbs);
LOG_D(NR_PHY,"num_subch= %d\n",phy_data->nr_sl_pssch_sci_pdu.num_subch);
LOG_D(NR_PHY,"subchannel_size = %d\n",phy_data->nr_sl_pssch_sci_pdu.subchannel_size);
LOG_D(NR_PHY,"l_subch = %d\n",phy_data->nr_sl_pssch_sci_pdu.l_subch);
LOG_D(NR_PHY,"pssch_numsym = %d\n",phy_data->nr_sl_pssch_sci_pdu.pssch_numsym);
LOG_D(NR_PHY,"sense_pssch = %d\n",phy_data->nr_sl_pssch_sci_pdu.sense_pssch);
ue->slsch->harq_process->pssch_pdu = &phy_data->nr_sl_pssch_sci_pdu;
// compute number of REs containing SCI2
int sci2_re = get_NREsci2_2(phy_data->nr_sl_pssch_sci_pdu.sci2_alpha_times_100,
phy_data->nr_sl_pssch_sci_pdu.sci2_len,
phy_data->nr_sl_pssch_sci_pdu.sci2_beta_offset,
phy_data->nr_sl_pssch_sci_pdu.pssch_numsym,
phy_data->nr_sl_pssch_sci_pdu.pscch_numsym,
phy_data->nr_sl_pssch_sci_pdu.pscch_numrbs,
phy_data->nr_sl_pssch_sci_pdu.l_subch,
phy_data->nr_sl_pssch_sci_pdu.subchannel_size,
phy_data->nr_sl_pssch_sci_pdu.targetCodeRate,
0);
LOG_D(NR_PHY,"Starting slot FEP for SLSCH (symbol %d to %d) pscch_numsym %d pssch_numsym %d REs with SCI2 %d\n",
1 + phy_data->nr_sl_pssch_sci_pdu.pscch_numsym, phy_data->nr_sl_pssch_sci_pdu.pssch_numsym,
phy_data->nr_sl_pssch_sci_pdu.pscch_numsym, phy_data->nr_sl_pssch_sci_pdu.pssch_numsym, sci2_re);
for (int sym=1+phy_data->nr_sl_pssch_sci_pdu.pscch_numsym; sym<=phy_data->nr_sl_pssch_sci_pdu.pssch_numsym;sym++) {
nr_slot_fep(ue,
fp,
proc,
sym,
rxdataF,
link_type_sl);
}
nr_rx_pusch(NULL,
ue,
proc,
phy_data,
rxdataF_sz,
rxdataF,
0,
frame_rx,
nr_slot_rx,
0,
&is_csi_rs_slot);
if (phy_data->sl_rx_action == SL_NR_CONFIG_TYPE_RX_PSSCH_SLSCH_PSFCH) {
ack_nack_rcvd = calloc(phy_data->num_psfch_pdus, sizeof(ack_nack_rcvd));
LOG_D(NR_PHY, "num_psfch_pdus: %d\n", phy_data->num_psfch_pdus);
for (int k = 0; k < phy_data->num_psfch_pdus; k++) {
sl_nr_tx_rx_config_psfch_pdu_t *psfch_pdu = &phy_data->psfch_pdu_list[k];
LOG_D(NR_PHY, "%s start_symbol_index %d, sl_bwp_start %d, sequence_hop_flag %d, \
second_hop_prb %d, prb %d, nr_of_symbols %d, initial_cyclic_shift %d, hopping_id %d, \
group_hop_flag %d, freq_hop_flag %d, bit_len_harq %d\n",
__FUNCTION__,
psfch_pdu->start_symbol_index, psfch_pdu->sl_bwp_start,
psfch_pdu->sequence_hop_flag, psfch_pdu->second_hop_prb, psfch_pdu->prb,
psfch_pdu->nr_of_symbols, psfch_pdu->initial_cyclic_shift, psfch_pdu->hopping_id,
psfch_pdu->group_hop_flag, psfch_pdu->freq_hop_flag, psfch_pdu->bit_len_harq);
nr_slot_fep(ue,
fp,
proc,
psfch_pdu->start_symbol_index,
rxdataF,
link_type_sl);
ack_nack_rcvd[k] = nr_ue_decode_psfch0(ue,
frame_rx,
nr_slot_rx,
rxdataF,
psfch_pdu);
}
free(phy_data->psfch_pdu_list);
phy_data->psfch_pdu_list = NULL;
}
NR_gNB_PUSCH *pssch_vars = &ue->pssch_vars[0];
pssch_vars->ulsch_power_tot = 0;
pssch_vars->ulsch_noise_power_tot = 0;
for (int aarx = 0; aarx < fp->nb_antennas_rx; aarx++) {
pssch_vars->ulsch_power[aarx] /= num_dmrs;
pssch_vars->ulsch_power_tot += pssch_vars->ulsch_power[aarx];
pssch_vars->ulsch_noise_power[aarx] /= num_dmrs;
pssch_vars->ulsch_noise_power_tot += pssch_vars->ulsch_noise_power[aarx];
}
if (dB_fixed_x10(pssch_vars->ulsch_power_tot) < dB_fixed_x10(pssch_vars->ulsch_noise_power_tot) + ue->pssch_thres) {
LOG_D(NR_PHY,
"PSSCH not detected in %d.%d (%d,%d,%d)\n",
frame_rx,
nr_slot_rx,
dB_fixed_x10(pssch_vars->ulsch_power_tot),
dB_fixed_x10(pssch_vars->ulsch_noise_power_tot),
ue->pssch_thres);
pssch_vars->ulsch_power_tot = pssch_vars->ulsch_noise_power_tot;
pssch_vars->DTX = 1;
//if (stats)
// stats->ulsch_stats.DTX++;
// nr_fill_indication(gNB, frame_rx, slot_rx, ULSCH_id, ulsch->harq_pid, 1, 1);
//pssch_DTX++;
// continue;
} else {
pssch_vars->DTX = 0;
int totalDecode = nr_slsch_procedures(ue, frame_rx, nr_slot_rx, 0, proc, phy_data, is_csi_rs_slot, ack_nack_rcvd, phy_data->num_psfch_pdus);
LOG_D(NR_PHY,
"Total %d decoded PSSCH detected in %d.%d (%d,%d,%d)\n",
totalDecode,
frame_rx,
nr_slot_rx,
dB_fixed_x10(pssch_vars->ulsch_power_tot),
dB_fixed_x10(pssch_vars->ulsch_noise_power_tot),
ue->pssch_thres);
}
}
#endif
UEscopeCopy(ue, commonRxdataF, rxdataF, sizeof(int32_t), fp->nb_antennas_rx, rxdataF_sz, 0);
@@ -270,6 +760,10 @@ void phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc
int frame_tx = proc->frame_tx;
int tx_action = 0;
const char *sl_tx_actions[] = {"PSBCH", "PSCCH_PSSCH", "PSCCH_PSSCH_PSFCH", "PSCCH_PSSCH_CSI_RS"};
if (phy_data->sl_tx_action == SL_NR_CONFIG_TYPE_TX_PSCCH_PSSCH_CSI_RS) {
LOG_D(NR_PHY, "Generating %s (%d.%d)\n", sl_tx_actions[phy_data->sl_tx_action - SL_NR_CONFIG_TYPE_TX_PSBCH], frame_tx, slot_tx);
}
sl_nr_ue_phy_params_t *sl_phy_params = &ue->SL_UE_PHY_PARAMS;
NR_DL_FRAME_PARMS *fp = &sl_phy_params->sl_frame_params;

View File

@@ -927,7 +927,7 @@ int main(int argc, char **argv)
init_nr_ue_transport(UE);
UE_mac = nr_l2_init_ue(0);
UE_mac = nr_l2_init_ue(0, NULL);
ue_init_config_request(UE_mac, get_slots_per_frame_from_scs(mu));
UE->if_inst = nr_ue_if_module_init(0);

View File

@@ -86,6 +86,27 @@ void deref_sched_response(int _)
exit(1);
}
int nr_postDecode_sim(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req, int *nb_ok)
{
ldpcDecode_t *rdata = (ldpcDecode_t*) NotifiedFifoData(req);
NR_UL_gNB_HARQ_t *ulsch_harq = rdata->ulsch_harq;
int r = rdata->segment_r;
bool decodeSuccess = (rdata->decodeIterations <= rdata->decoderParms.numMaxIter);
ulsch_harq->processedSegments++;
if (decodeSuccess) {
memcpy(ulsch_harq->b+rdata->offset,
ulsch_harq->c[r],
rdata->Kr_bytes - (ulsch_harq->F>>3) -((ulsch_harq->C>1)?3:0));
}
// if all segments are done
if (rdata->nbSegments == ulsch_harq->processedSegments)
return *nb_ok == rdata->nbSegments;
return 0;
}
nrUE_params_t nrUE_params;
nrUE_params_t *get_nrUE_params(void) {

View File

@@ -885,7 +885,7 @@ int main(int argc, char *argv[])
init_nr_ue_transport(UE);
//Configure UE
NR_UE_MAC_INST_t* UE_mac = nr_l2_init_ue(0);
NR_UE_MAC_INST_t* UE_mac = nr_l2_init_ue(0, NULL);
ue_init_config_request(UE_mac, get_slots_per_frame_from_scs(mu));

View File

@@ -103,6 +103,54 @@ uint32_t nr_compute_tbs(uint16_t Qm,
LOG_D(NR_MAC, "Ninfo %u nbp_re %d nb_re %d Qm %d, R %d, tbs %d bits\n", Ninfo, nbp_re, nb_re, Qm, R, nr_tbs);
return nr_tbs;
}
uint32_t nr_compute_tbs_sl(uint16_t Qm,
uint16_t R,
uint16_t nb_re,
uint8_t Nl)
{
LOG_D(NR_MAC, "In %s: nb_re %d, Nl %d\n", __FUNCTION__, nb_re,Nl);
// Intermediate number of information bits
// Rx1024 is tabulated as 10 times the actual code rate
const uint32_t R_5 = R/5; // R can be fractional so we can't divide by 10
// So we ned to right shift by 11 (10 for x1024 and 1 additional as above)
const uint32_t Ninfo = ((nb_re * R_5 * Qm * Nl)>>11);
uint32_t nr_tbs=0;
uint32_t Np_info, C, n;
if (Ninfo <=3824) {
n = max(3, floor(log2(Ninfo)) - 6);
Np_info = max(24, (Ninfo>>n)<<n);
for (int i=0; i<INDEX_MAX_TBS_TABLE; i++) {
if (Tbstable_nr[i] >= Np_info){
nr_tbs = Tbstable_nr[i];
break;
}
}
} else {
n = log2(Ninfo-24)-5;
Np_info = max(3840, (ROUNDIDIV((Ninfo-24),(1<<n)))<<n);
if (R <= 2560) {
C = CEILIDIV((Np_info+24),3816);
nr_tbs = (C<<3)*CEILIDIV((Np_info+24),(C<<3)) - 24;
} else {
if (Np_info > 8424){
C = CEILIDIV((Np_info+24),8424);
nr_tbs = (C<<3)*CEILIDIV((Np_info+24),(C<<3)) - 24;
} else {
nr_tbs = ((CEILIDIV((Np_info+24),8))<<3) - 24;
}
}
}
LOG_D(NR_MAC, "In %s: Ninfo %u nb_re %d Qm %d, R %d, tbs %d bits\n", __FUNCTION__, Ninfo, nb_re, Qm, R, nr_tbs);
return nr_tbs;
}
//tbslbrm calculation according to 5.4.2.1 of 38.212
uint32_t nr_compute_tbslbrm(uint16_t table, uint16_t nb_rb, uint8_t Nl)

View File

@@ -39,6 +39,8 @@
#include <stdbool.h>
#include "common/utils/nr/nr_common.h"
#include "common/utils/LOG/log.h"
#include "common/utils/collection/linear_alloc.h"
#include "NR_CellGroupConfig.h"
#define MAX_FRAME_NUMBER 0x400
@@ -109,6 +111,14 @@ typedef struct {
uint8_t R: 2; // octet 1 [7:6]
} __attribute__ ((__packed__)) NR_MAC_SUBHEADER_FIXED;
// 38321 section 6.1.6 Figure 6.1.6-1
typedef struct {
uint8_t V: 4; // octet 1 [7:4]
uint8_t R: 4; // octet 1 [3:0]
uint16_t SRC: 16; // octet 2, octet 3
uint8_t DST: 8; // octet 4
}__attribute__ ((__packed__)) NR_SLSCH_MAC_SUBHEADER_FIXED;
static inline int get_mac_len(uint8_t *pdu, uint32_t pdu_len, uint16_t *mac_ce_len, uint16_t *mac_subheader_len)
{
if (pdu_len < sizeof(NR_MAC_SUBHEADER_SHORT))
@@ -132,6 +142,17 @@ static inline int get_mac_len(uint8_t *pdu, uint32_t pdu_len, uint16_t *mac_ce_l
return true;
}
// SL BSR MAC CEs
// TS 38.321 ch. 6.1.3.33
// Short BSR for a specific logical channel group ID
typedef struct {
uint8_t destination_index: 5; // octet 1 MSB
uint8_t LcgID: 3; // octet 1 LSB
uint8_t Buffer_size: 8;
} __attribute__ ((__packed__)) NR_SL_BSR_SHORT;
typedef NR_SL_BSR_SHORT NR_SL_BSR_SHORT_TRUNCATED;
// BSR MAC CEs
// TS 38.321 ch. 6.1.3.1
// Short BSR for a specific logical channel group ID
@@ -432,6 +453,22 @@ typedef struct {
#define UL_SCH_LCID_PADDING 0x3F
#define NR_MAX_NUM_LCGID 8
#define SL_SCH_LCID_SCCH_PC5_NOT_PROT 0 // SCCH carrying PC5-S messages that are not protected
#define SL_SCH_LCID_SCCH_PC5_DSMC 1 // SCCH carrying PC5-S messages "Direct Security Mode Command" and "Direct Security Mode Complete"
#define SL_SCH_LCID_SCCH_PC5_PROT 2 // SCCH carrying other PC5-S messages that are protected
#define SL_SCH_LCID_SCCH_PC5_RRC 3 // SCCH carrying PC5-RRC messages
#define SL_SCH_LCID_4_19 4 // 419 Identity of the logical channel
#define SL_SCH_LCID_20_55 20 // 2055 Reserved
#define SL_SCH_LCID_SCCH_RRC_SL_RLC0 56 // SCCH carrying RRC messages delivered via SL-RLC0 as specified in TS 38.331 [5]
#define SL_SCH_LCID_SCCH_RRC_SL_RLC1 57 // SCCH carrying RRC message delivered via SL-RLC1 as specified in TS 38.331 [5]
#define SL_SCH_LCID_SCCH_SL_DISCOVERY 58 // SCCH for Sidelink Discovery Messages
#define SL_SCH_LCID_SL_INTER_UE_COORD_REQ 59 // Sidelink Inter-UE Coordination Request
#define SL_SCH_LCID_SL_INTER_UE_COORD_INFO 60 // Sidelink Inter-UE Coordination Information
#define SL_SCH_LCID_SL_DRX_CMD 61 // Sidelink DRX Command
#define SL_SCH_LCID_SL_CSI_REPORT 62 // Sidelink CSI Reporting
#define SL_SCH_LCID_SL_PADDING 63 // Padding
#define MAX_RLC_SDU_SUBHEADER_SIZE 3
//=========
@@ -522,6 +559,25 @@ typedef struct nr_csi_report {
int N2;
} nr_csi_report_t;
// 38321 sec. 6.1.3.35
typedef struct {
uint8_t RI: 1; // 7th bit
uint8_t CQI: 4; // 3-6 bits
uint8_t R: 3; // 0-2 bits
} __attribute__ ((__packed__)) nr_sl_csi_report_t;
// 38321 sec. 6.1.3.34
typedef struct {
uint8_t C1: 1; // 1st bit
uint8_t C2: 1; // 2nd bit
uint8_t C3: 1; // 3rd bit
uint8_t C4: 1; // 4th bit
uint8_t C5: 1; // 5th bit
uint8_t C6: 1; // 6th bit
uint8_t C7: 1; // 7th bit
uint8_t C8: 1; // 8th bit
} __attribute__ ((__packed__)) nr_sl_config_grant_t;
typedef enum {
NR_SRS_SRI_0 = 0,
NR_SRS_SRI_1,
@@ -641,5 +697,21 @@ typedef enum {
RA_2_STEP = 1,
} nr_ra_type_t;
typedef struct NR_bler_stats {
frame_t last_frame;
float bler;
uint8_t mcs;
uint64_t rounds[8];
} NR_bler_stats_t;
/*! \brief NR_list_t is a "list" (of users, HARQ processes, slices, ...).
* * Especially useful in the scheduler and to keep "classes" of users. */
typedef struct {
int head;
int *next;
int tail;
int len;
} NR_list_t;
#endif /*__LAYER2_MAC_H__ */

View File

@@ -39,6 +39,18 @@
#define reserved 0xffff
void reverse_n_bits(uint8_t *value, uint16_t bitlen) {
uint16_t j;
uint8_t i;
for(j = bitlen - 1,i = 0; j > i; j--, i++) {
if(((*value>>j)&1) != ((*value>>i)&1)) {
*value ^= (1<<j);
*value ^= (1<<i);
}
}
}
//38.321 Table 6.1.3.1-1
const uint32_t NR_SHORT_BSR_TABLE[NR_SHORT_BSR_TABLE_SIZE] = {
0, 10, 14, 20, 28, 38, 53, 74,
@@ -79,6 +91,62 @@ uint32_t get_long_bsr_value(int idx)
return NR_LONG_BSR_TABLE[idx];
}
// #define DEBUG_DCI
// CQI TABLES (10 times the value in 214 to adequately compare with R)
// Table 1 (38.214 5.2.2.1-2)
static const uint16_t cqi_table1[16][2] = {{0, 0},
{2, 780},
{2, 1200},
{2, 1930},
{2, 3080},
{2, 4490},
{2, 6020},
{4, 3780},
{4, 4900},
{4, 6160},
{6, 4660},
{6, 5670},
{6, 6660},
{6, 7720},
{6, 8730},
{6, 9480}};
// Table 2 (38.214 5.2.2.1-3)
static const uint16_t cqi_table2[16][2] = {{0, 0},
{2, 780},
{2, 1930},
{2, 4490},
{4, 3780},
{4, 4900},
{4, 6160},
{6, 4660},
{6, 5670},
{6, 6660},
{6, 7720},
{6, 8730},
{8, 7110},
{8, 7970},
{8, 8850},
{8, 9480}};
// Table 2 (38.214 5.2.2.1-4)
static const uint16_t cqi_table3[16][2] = {{0, 0},
{2, 300},
{2, 500},
{2, 780},
{2, 1200},
{2, 1930},
{2, 3080},
{2, 4490},
{2, 6020},
{4, 3780},
{4, 4900},
{4, 6160},
{6, 4660},
{6, 5670},
{6, 6660},
{6, 7720}};
// start symbols for SSB types A,B,C,D,E
static const uint16_t symbol_ssb_AC[8] = {2, 8, 16, 22, 30, 36, 44, 50};
static const uint16_t symbol_ssb_BD[64] = {4, 8, 16, 20, 32, 36, 44, 48, 60, 64, 72, 76, 88, 92, 100, 104,
@@ -90,6 +158,8 @@ static const uint16_t symbol_ssb_E[64] = {8, 12, 16, 20, 32, 36, 40, 44,
288, 292, 296, 300, 312, 316, 320, 324, 344, 348, 352, 356, 368, 372, 376, 380,
400, 404, 408, 412, 424, 428, 432, 436, 456, 460, 464, 468, 480, 484, 488, 492};
const uint8_t nr_slots_per_frame[5] = {10, 20, 40, 80, 160};
// Table 6.3.3.1-5 (38.211) NCS for preamble formats with delta_f_RA = 1.25 KHz
static const uint16_t NCS_unrestricted_delta_f_RA_125[16] = {0, 13, 15, 18, 22, 26, 32, 38, 46, 59, 76, 93, 119, 167, 279, 419};
static const uint16_t NCS_restricted_TypeA_delta_f_RA_125[15] =
@@ -3260,6 +3330,45 @@ int16_t fill_dmrs_mask(const NR_PDSCH_Config_t *pdsch_Config,
return l_prime;
}
#define BLER_UPDATE_FRAME 10
#define BLER_FILTER 0.9f
int get_mcs_from_bler(const NR_bler_options_t *bler_options,
const NR_mac_dir_stats_t *stats,
NR_bler_stats_t *bler_stats,
int max_mcs,
frame_t frame)
{
int diff = frame - bler_stats->last_frame;
if (diff < 0) // wrap around
diff += 1024;
max_mcs = min(max_mcs, bler_options->max_mcs);
const uint8_t old_mcs = min(bler_stats->mcs, max_mcs);
if (diff < BLER_UPDATE_FRAME)
return old_mcs; // no update
// last update is longer than x frames ago
const int num_dl_sched = (int)(stats->rounds[0] - bler_stats->rounds[0]);
const int num_dl_retx = (int)(stats->rounds[1] - bler_stats->rounds[1]);
const float bler_window = num_dl_sched > 0 ? (float) num_dl_retx / num_dl_sched : bler_stats->bler;
bler_stats->bler = BLER_FILTER * bler_stats->bler + (1 - BLER_FILTER) * bler_window;
int new_mcs = old_mcs;
if (bler_stats->bler < bler_options->lower && old_mcs < max_mcs && num_dl_sched > 3)
new_mcs += 1;
else if (bler_stats->bler > bler_options->upper || num_dl_sched <= 3) // above threshold or no activity
new_mcs -= 1;
// else we are within threshold boundaries
new_mcs = max(new_mcs, bler_options->min_mcs);
bler_stats->last_frame = frame;
bler_stats->mcs = new_mcs;
memcpy(bler_stats->rounds, stats->rounds, sizeof(stats->rounds));
LOG_D(MAC, "frame %4d MCS %d -> %d (num_dl_sched %d, num_dl_retx %d, BLER wnd %.3f avg %.6f)\n",
frame, old_mcs, new_mcs, num_dl_sched, num_dl_retx, bler_window, bler_stats->bler);
return new_mcs;
}
uint8_t get_pdsch_mcs_table(long *mcs_Table, int dci_format, int rnti_type, int ss_type)
{
@@ -4959,3 +5068,228 @@ int get_j_for_k2(int mu)
AssertFatal(mu >= 0 && mu < sizeofArray(j_table), "Invalid numerology %d\n", mu);
return j_table[mu];
}
/*
* Create a new NR_list
*/
void create_nr_list(NR_list_t *list, int len)
{
list->head = -1;
list->next = malloc(len * sizeof(*list->next));
AssertFatal(list->next, "cannot malloc() memory for NR_list_t->next\n");
for (int i = 0; i < len; ++i)
list->next[i] = -1;
list->tail = -1;
list->len = len;
}
/*
* Resize an NR_list
*/
void resize_nr_list(NR_list_t *list, int new_len)
{
if (new_len == list->len)
return;
if (new_len > list->len) {
/* list->head remains */
const int old_len = list->len;
int* n = realloc(list->next, new_len * sizeof(*list->next));
AssertFatal(n, "cannot realloc() memory for NR_list_t->next\n");
list->next = n;
for (int i = old_len; i < new_len; ++i)
list->next[i] = -1;
/* list->tail remains */
list->len = new_len;
} else { /* new_len < len */
AssertFatal(list->head < new_len, "shortened list head out of index %d (new len %d)\n", list->head, new_len);
AssertFatal(list->tail < new_len, "shortened list tail out of index %d (new len %d)\n", list->head, new_len);
for (int i = 0; i < list->len; ++i)
AssertFatal(list->next[i] < new_len, "shortened list entry out of index %d (new len %d)\n", list->next[i], new_len);
/* list->head remains */
int *n = realloc(list->next, new_len * sizeof(*list->next));
AssertFatal(n, "cannot realloc() memory for NR_list_t->next\n");
list->next = n;
/* list->tail remains */
list->len = new_len;
}
}
/*
* Destroy an NR_list
*/
void destroy_nr_list(NR_list_t *list)
{
free(list->next);
}
/*
* Add an ID to an NR_list at the end, traversing the whole list. Note:
* add_tail_nr_list() is a faster alternative, but this implementation ensures
* we do not add an existing ID.
*/
void add_nr_list(NR_list_t *listP, int id)
{
int *cur = &listP->head;
while (*cur >= 0) {
AssertFatal(*cur != id, "id %d already in NR_UE_list!\n", id);
cur = &listP->next[*cur];
}
*cur = id;
if (listP->next[id] < 0)
listP->tail = id;
}
/*
* Remove an ID from an NR_list
*/
void remove_nr_list(NR_list_t *listP, int id)
{
int *cur = &listP->head;
int *prev = &listP->head;
while (*cur != -1 && *cur != id) {
prev = cur;
cur = &listP->next[*cur];
}
AssertFatal(*cur != -1, "ID %d not found in UE_list\n", id);
int *next = &listP->next[*cur];
*cur = listP->next[*cur];
*next = -1;
listP->tail = *prev >= 0 && listP->next[*prev] >= 0 ? listP->tail : *prev;
}
/*
* Add an ID to the tail of the NR_list in O(1). Note that there is
* corresponding remove_tail_nr_list(), as we cannot set the tail backwards and
* therefore need to go through the whole list (use remove_nr_list())
*/
void add_tail_nr_list(NR_list_t *listP, int id)
{
int *last = listP->tail < 0 ? &listP->head : &listP->next[listP->tail];
*last = id;
listP->next[id] = -1;
listP->tail = id;
}
/*
* Add an ID to the front of the NR_list in O(1)
*/
void add_front_nr_list(NR_list_t *listP, int id)
{
const int ohead = listP->head;
listP->head = id;
listP->next[id] = ohead;
if (listP->tail < 0)
listP->tail = id;
}
/*
* Remove an ID from the front of the NR_list in O(1)
*/
void remove_front_nr_list(NR_list_t *listP)
{
AssertFatal(listP->head >= 0, "Nothing to remove\n");
const int ohead = listP->head;
listP->head = listP->next[ohead];
listP->next[ohead] = -1;
if (listP->head < 0)
listP->tail = -1;
}
#define MAX_EL_213_9_3_2 19
const float tab38_213_9_3_2[MAX_EL_213_9_3_2] = {1.125,1.250,1.375,1.625,1.750,2.000,2.250,2.500,2.875,3.125,3.500,4.000,5.000,6.250,8.000,10.000,12.625,15.875,20.000};
int get_NREsci2(const int sci2_alpha,
const int sci2_payload_len,
const int sci2_beta_offset,
const int pssch_numsym,
const int pscch_numsym,
const int pscch_numrbs,
const int l_subch,
const int subchannel_size,
const int mcs,
const int mcs_tb_ind) {
float Osci2 = (float)sci2_payload_len;
AssertFatal(sci2_beta_offset < MAX_EL_213_9_3_2, "illegal sci2_beta_offset %d\n",sci2_beta_offset);
float beta_offset_sci2 = tab38_213_9_3_2[sci2_beta_offset];
uint32_t R10240 = nr_get_code_rate_ul(mcs,mcs_tb_ind);
uint32_t tmp = (uint32_t)ceil((Osci2 + 24)*beta_offset_sci2/((float)R10240/5120));
float tmp2 = 12.0*pssch_numsym;
int N_REsci1 = 12*pscch_numrbs*pscch_numsym;
tmp2 *= l_subch*subchannel_size;
tmp2 -= N_REsci1;
tmp2 *= ((float)sci2_alpha/100.0);
int min_val = min(tmp,(int)ceil(tmp2));
uint8_t gamma = 12 - (min_val % 12);
return min_val + (gamma % 12);
}
int get_NREsci2_2(const int sci2_alpha,
const int sci2_payload_len,
const int sci2_beta_offset,
const int pssch_numsym,
const int pscch_numsym,
const int pscch_numrbs,
const int l_subch,
const int subchannel_size,
const int target_coderate,
const int mcs_table_index) {
float Osci2 = (float)sci2_payload_len;
AssertFatal(sci2_beta_offset < MAX_EL_213_9_3_2, "illegal sci2_beta_offset %d\n",sci2_beta_offset);
float beta_offset_sci2 = tab38_213_9_3_2[sci2_beta_offset];
uint32_t R10240 = get_softmodem_params()->sl_mode ? nr_get_code_rate_ul(1, mcs_table_index) : target_coderate;
uint32_t tmp = (uint32_t)ceil((Osci2 + 24)*beta_offset_sci2/((float)R10240/5120));
float tmp2 = 12.0*pssch_numsym;
int N_REsci1 = 12*pscch_numrbs*pscch_numsym;
tmp2 *= l_subch*subchannel_size;
tmp2 -= N_REsci1;
tmp2 *= ((float)sci2_alpha/100.0);
int min_val = min(tmp,(int)ceil(tmp2));
uint8_t gamma = 12 - (min_val % 12);
return min_val + (gamma % 12);
}
uint8_t get_mcs_from_cqi(int mcs_table, int cqi_table, int cqi_idx)
{
if (cqi_idx <= 0) {
LOG_E(NR_MAC, "invalid cqi_idx %d, default to MCS 9\n", cqi_idx);
return 9;
}
if (mcs_table != cqi_table) {
LOG_E(NR_MAC, "indices of CQI (%d) and MCS (%d) tables don't correspond yet\n", cqi_table, mcs_table);
return 9;
}
uint16_t target_coderate, target_qm;
switch (cqi_table) {
case 0:
target_qm = cqi_table1[cqi_idx][0];
target_coderate = cqi_table1[cqi_idx][1];
break;
case 1:
target_qm = cqi_table2[cqi_idx][0];
target_coderate = cqi_table2[cqi_idx][1];
break;
case 2:
target_qm = cqi_table3[cqi_idx][0];
target_coderate = cqi_table3[cqi_idx][1];
break;
default:
AssertFatal(1==0,"Invalid cqi table index %d\n",cqi_table);
}
const int max_mcs = mcs_table == 1 ? 27 : 28;
for (int i = 0; i <= max_mcs; i++) {
const int R = nr_get_code_rate_dl(i, mcs_table);
const int Qm = nr_get_Qm_dl(i, mcs_table);
if (Qm == target_qm && target_coderate <= R)
return i;
}
LOG_E(NR_MAC, "could not find maximum MCS from cqi_idx %d, default to 9\n", cqi_idx);
return 9;
}

View File

@@ -96,6 +96,36 @@ typedef enum {
pusch_len2 = 2
} pusch_maxLength_t;
typedef struct NR_mac_dir_stats {
uint64_t lc_bytes[64];
uint64_t rounds[8];
uint64_t errors;
uint64_t total_bytes;
uint32_t current_bytes;
uint64_t total_sdu_bytes;
uint32_t total_rbs;
uint32_t total_rbs_retx;
uint32_t num_mac_sdu;
uint32_t current_rbs;
} NR_mac_dir_stats_t;
typedef struct NR_UE_sl_mac_stats {
NR_mac_dir_stats_t sl;
uint32_t slsch_DTX;
uint64_t slsch_total_bytes_scheduled;
int cumul_rsrp;
uint8_t num_rsrp_meas;
uint32_t cumul_round[5];
} NR_UE_sl_mac_stats_t;
typedef struct NR_bler_options {
double upper;
double lower;
uint8_t min_mcs;
uint8_t max_mcs;
uint8_t harq_round_max;
} NR_bler_options_t;
typedef struct {
uint16_t bwpStart;
uint16_t bwpSize;
@@ -123,6 +153,7 @@ void config_frame_structure(int mu,
uint8_t tdd_period,
uint8_t frame_type,
frame_structure_t *fs);
int get_first_ul_slot(const frame_structure_t *fs, bool mixed);
NR_PDSCH_TimeDomainResourceAllocationList_t *get_dl_tdalist(const NR_UE_DL_BWP_t *DL_BWP,
int controlResourceSetId,
@@ -198,6 +229,14 @@ uint8_t compute_nr_root_seq(NR_RACH_ConfigCommon_t *rach_config,
uint8_t unpaired,
frequency_range_t);
uint8_t get_mcs_from_cqi(int mcs_table, int cqi_table, int cqi_idx);
int get_mcs_from_bler(const NR_bler_options_t *bler_options,
const NR_mac_dir_stats_t *stats,
NR_bler_stats_t *bler_stats,
int max_mcs,
frame_t frame);
int ul_ant_bits(NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig, long transformPrecoder);
uint8_t get_pdsch_mcs_table(long *mcs_Table, int dci_format, int rnti_type, int ss_type);
@@ -219,6 +258,11 @@ uint32_t nr_compute_tbs(uint16_t Qm,
uint8_t tb_scaling,
uint8_t Nl);
uint32_t nr_compute_tbs_sl(uint16_t Qm,
uint16_t R,
uint16_t nb_re,
uint8_t Nl);
/** \brief Computes Q based on I_MCS PDSCH and table_idx for downlink. Implements MCS Tables from 38.214. */
uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx);
uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx);
@@ -334,4 +378,37 @@ int get_delta_for_k2(int mu);
int get_j_for_k2(int mu);
/* Functions to manage an NR_list_t */
void create_nr_list(NR_list_t *listP, int len);
void resize_nr_list(NR_list_t *list, int new_len);
void destroy_nr_list(NR_list_t *list);
void add_nr_list(NR_list_t *listP, int id);
void remove_nr_list(NR_list_t *listP, int id);
void add_tail_nr_list(NR_list_t *listP, int id);
void add_front_nr_list(NR_list_t *listP, int id);
void remove_front_nr_list(NR_list_t *listP);
int get_NREsci2(const int sci2_alpha,
const int sci2_payload_len,
const int sci2_beta_offset,
const int pssch_numsym,
const int pscch_numsym,
const int pscch_numrbs,
const int l_subch,
const int subchannel_size,
const int mcs,
const int mcs_tb_ind);
int get_NREsci2_2(const int sci2_alpha,
const int sci2_payload_len,
const int sci2_beta_offset,
const int pssch_numsym,
const int pscch_numsym,
const int pscch_numrbs,
const int l_subch,
const int subchannel_size,
const int target_coderate,
const int mcs_table_index);
#endif

View File

@@ -259,3 +259,25 @@ bool is_mixed_slot(const slot_t slot, const frame_structure_t *fs)
const tdd_period_config_t *pc = &fs->period_cfg;
return pc->tdd_slot_bitmap[s].slot_type == TDD_NR_MIXED_SLOT;
}
/**
* @brief Get the first UL slot index in period
* @param fs frame structure
* @param mixed indicates whether to include in the count also mixed slot with UL symbols or only full UL slot
* @return slot index
*/
int get_first_ul_slot(const frame_structure_t *fs, bool mixed)
{
DevAssert(fs);
if (fs->frame_type == TDD) {
for (int i = 0; i < fs->numb_slots_period; i++) {
if ((mixed && is_ul_slot(i, fs)) || fs->period_cfg.tdd_slot_bitmap[i].slot_type == TDD_NR_UPLINK_SLOT) {
return i;
}
}
}
return 0; // FDD
}

View File

@@ -0,0 +1,118 @@
/*
* 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 nr_mac_extern.h
* \brief NR mac externs
* \author Navid Nikaein, Raymond Knopp, Guido Casati
* \date 2019
* \version 1.0
* \email navid.nikaein@eurecom.fr, guido.casati@iis.fraunhofer.de
* @ingroup _mac
*/
#ifndef __NR_MAC_EXTERN_H__
#define __NR_MAC_EXTERN_H__
#include "common/ran_context.h"
#include "nr_mac.h"
/*#include "PHY/defs_common.h"*/
extern const uint8_t nr_slots_per_frame[5];
extern dci_pdu_rel15_t *def_dci_pdu_rel15;
/* Scheduler */
extern RAN_CONTEXT_t RC;
extern uint8_t nfapi_mode;
extern const uint32_t NR_SHORT_BSR_TABLE[NR_SHORT_BSR_TABLE_SIZE];
extern const uint32_t NR_LONG_BSR_TABLE[NR_LONG_BSR_TABLE_SIZE];
// Type0-PDCCH search space
extern const int32_t table_38213_13_1_c1[16];
extern const int32_t table_38213_13_1_c2[16];
extern const int32_t table_38213_13_1_c3[16];
extern const int32_t table_38213_13_1_c4[16];
extern const int32_t table_38213_13_2_c1[16];
extern const int32_t table_38213_13_2_c2[16];
extern const int32_t table_38213_13_2_c3[16];
extern const int32_t table_38213_13_2_c4[16];
extern const int32_t table_38213_13_3_c1[16];
extern const int32_t table_38213_13_3_c2[16];
extern const int32_t table_38213_13_3_c3[16];
extern const int32_t table_38213_13_3_c4[16];
extern const int32_t table_38213_13_4_c1[16];
extern const int32_t table_38213_13_4_c2[16];
extern const int32_t table_38213_13_4_c3[16];
extern const int32_t table_38213_13_4_c4[16];
extern const int32_t table_38213_13_5_c1[16];
extern const int32_t table_38213_13_5_c2[16];
extern const int32_t table_38213_13_5_c3[16];
extern const int32_t table_38213_13_5_c4[16];
extern const int32_t table_38213_13_6_c1[16];
extern const int32_t table_38213_13_6_c2[16];
extern const int32_t table_38213_13_6_c3[16];
extern const int32_t table_38213_13_6_c4[16];
extern const int32_t table_38213_13_7_c1[16];
extern const int32_t table_38213_13_7_c2[16];
extern const int32_t table_38213_13_7_c3[16];
extern const int32_t table_38213_13_7_c4[16];
extern const int32_t table_38213_13_8_c1[16];
extern const int32_t table_38213_13_8_c2[16];
extern const int32_t table_38213_13_8_c3[16];
extern const int32_t table_38213_13_8_c4[16];
extern const int32_t table_38213_13_9_c1[16];
extern const int32_t table_38213_13_9_c2[16];
extern const int32_t table_38213_13_9_c3[16];
extern const int32_t table_38213_13_9_c4[16];
extern const int32_t table_38213_13_10_c1[16];
extern const int32_t table_38213_13_10_c2[16];
extern const int32_t table_38213_13_10_c3[16];
extern const int32_t table_38213_13_10_c4[16];
extern const float table_38213_13_11_c1[16];
extern const int32_t table_38213_13_11_c2[16];
extern const float table_38213_13_11_c3[16];
extern const int32_t table_38213_13_11_c4[16];
extern const float table_38213_13_12_c1[16];
extern const int32_t table_38213_13_12_c2[16];
extern const float table_38213_13_12_c3[16];
extern const int32_t table_38213_10_1_1_c2[5];
extern const char table_38211_6_3_1_5_1[6][2][1];
extern const char table_38211_6_3_1_5_2[28][4][1];
extern const char table_38211_6_3_1_5_3[28][4][1];
extern const char table_38211_6_3_1_5_4[3][2][2];
extern const char table_38211_6_3_1_5_5[22][4][2];
#endif //DEF_H

View File

@@ -1794,7 +1794,7 @@ void nr_rrc_mac_config_req_reset(module_id_t module_id, NR_UE_MAC_reset_cause_t
switch (cause) {
case GO_TO_IDLE:
reset_ra(mac, true);
nr_ue_init_mac(mac);
nr_ue_init_mac(mac, NULL);
release_mac_configuration(mac, cause);
nr_ue_mac_default_configs(mac);
// new sync but no target cell id -> -1
@@ -2800,3 +2800,4 @@ void nr_rrc_mac_config_req_cg(module_id_t module_id,
ret = pthread_mutex_unlock(&mac->if_mutex);
AssertFatal(!ret, "mutex failed %d\n", ret);
}

View File

@@ -20,8 +20,66 @@
*/
#include "openair2/LAYER2/NR_MAC_UE/mac_defs.h"
#include "openair2/LAYER2/NR_MAC_UE/nr_ue_sci.h"
#include "NR_SidelinkPreconfigNR-r16.h"
#include "mac_proto.h"
#include "common/config/config_paramdesc.h"
#include <executables/nr-uesoftmodem.h>
#define SL_CONFIG_STRING_SL_PRECONFIGURATION "SIDELINK_PRECONFIGURATION"
/* Sidelink CSI-RS configuration parameters for MAC*/
#define SL_CONFIG_STRING_SL_CSI_RS_LIST "sl_csi_rs"
#define SL_CONFIG_STRING_SL_CSI_RS_SYMB_L0 "symb_l0"
#define SL_CONFIG_STRING_SL_CSI_RS_CSI_TYPE "csi_Type"
#define SL_CONFIG_STRING_SL_CSI_RS_SLOT_OFFSET "slot_Offset"
#define SL_CONFIG_STRING_SL_CSI_RS_SLOT_PERIODICITY "slot_Periodicity"
#define SL_CONFIG_STRING_SL_CSI_RS_POWER_CONTROL_OFFSET "sl_powerControlOffset"
#define SL_CONFIG_STRING_SL_CSI_RS_POWER_CONTROL_OFFSET_SS "sl_powerControlOffsetSS"
#define SL_CONFIG_STRING_SL_CSI_RS_SL_CSI_ACQUISITION "sl_CSI_Acquisition"
#define SL_CONFIG_STRING_SL_CSI_RS_SL_LATENCYBOUNDCSI_REPORT "sl_LatencyBoundCSI_Report"
#define SL_CONFIG_STRING_SL_ALLOWED_RESOURCE_SELECTION_CONFIG "sl_AllowedResourceSelectionConfig"
#define SL_CSI_RS_DESC(sl_csi_info) { \
{SL_CONFIG_STRING_SL_CSI_RS_SYMB_L0,NULL,0,.u8ptr=&sl_csi_info->symb_l0,.defuintval=1,TYPE_UINT8,0}, \
{SL_CONFIG_STRING_SL_CSI_RS_CSI_TYPE,NULL,0,.u8ptr=&sl_csi_info->csi_type,.defuintval=1,TYPE_UINT8,0}, \
{SL_CONFIG_STRING_SL_CSI_RS_POWER_CONTROL_OFFSET,NULL,0,.u8ptr=&sl_csi_info->power_control_offset,.defuintval=1,TYPE_UINT8,0}, \
{SL_CONFIG_STRING_SL_CSI_RS_POWER_CONTROL_OFFSET_SS,NULL,0,.u8ptr=&sl_csi_info->power_control_offset_ss,.defuintval=1,TYPE_UINT8,0}, \
{SL_CONFIG_STRING_SL_CSI_RS_SLOT_OFFSET,NULL,0,.u8ptr=&sl_csi_info->slot_offset,.defuintval=1,TYPE_UINT8,0}, \
{SL_CONFIG_STRING_SL_CSI_RS_SLOT_PERIODICITY,NULL,0,.u8ptr=&sl_csi_info->slot_periodicity,.defuintval=1,TYPE_UINT8,0}, \
{SL_CONFIG_STRING_SL_CSI_RS_SL_CSI_ACQUISITION,NULL,0,.u8ptr=&sl_csi_info->sl_csi_acquisition,.defuintval=1,TYPE_UINT8,0}, \
{SL_CONFIG_STRING_SL_CSI_RS_SL_LATENCYBOUNDCSI_REPORT,NULL,0,.u8ptr=&sl_csi_info->sl_latencyboundcsi_report,.defuintval=8,TYPE_UINT8,0}}
/*Sidelink HARQ configuration parameters */
#define SL_CONFIG_STRING_SL_CONFIGUREDGRANT_LIST "sl_ConfiguredGrantConfig"
#define SL_CONFIG_STRING_SL_CONFIGUREDGRANT_NROFHARQ_PROCESSES "sl_NrOfHARQ_Processes"
#define SL_CONFIG_STRING_SL_CONFIGUREDGRANT_HARQ_PROCID_OFFSET "sl_HARQ_ProcID_offset"
#define SL_CONFIG_STRING_SL_CONFIGUREDGRANT_HARQ_PERIODIC_RRI "sl_periodic_rsc_rsr_interval"
#define SL_CONFIGUREDGRANT_DESC(sl_harq_info) { \
{SL_CONFIG_STRING_SL_CONFIGUREDGRANT_NROFHARQ_PROCESSES, NULL, 0, .u16ptr=&sl_harq_info->sl_Num_HARQ_Processes, .defuintval=0, TYPE_UINT16, 0}, \
{SL_CONFIG_STRING_SL_CONFIGUREDGRANT_HARQ_PROCID_OFFSET, NULL, 0, .u16ptr=&sl_harq_info->sl_HARQ_ProcID_offset, .defuintval=0, TYPE_UINT16, 0}, \
{SL_CONFIG_STRING_SL_CONFIGUREDGRANT_HARQ_PERIODIC_RRI, NULL, 0, .u16ptr=&sl_harq_info->sl_Periodic_RRI, .defuintval=0, TYPE_UINT16, 0}}
#define SL_CONFIG_RESOURCE_SELECTION(resource_selection_cfg) { \
{SL_CONFIG_STRING_SL_ALLOWED_RESOURCE_SELECTION_CONFIG, NULL, 0, .u16ptr=resource_selection_cfg, .defuintval=3, TYPE_UINT16, 0}}
typedef struct sl_csi_info {
uint8_t symb_l0;
uint8_t csi_type;
uint8_t slot_offset;
uint8_t slot_periodicity;
uint8_t power_control_offset;
uint8_t power_control_offset_ss;
uint8_t sl_csi_acquisition;
uint8_t sl_latencyboundcsi_report;
} sl_csi_info_t;
typedef struct sl_harq_info {
uint16_t sl_Num_HARQ_Processes;
uint16_t sl_HARQ_ProcID_offset;
uint16_t sl_Periodic_RRI;
} sl_harq_info_t;
void sl_ue_mac_free(NR_UE_MAC_INST_t *mac)
{
@@ -33,8 +91,10 @@ void sl_ue_mac_free(NR_UE_MAC_INST_t *mac)
//Allocated by MAC only in case of SYNC_REF_UE
//else it is freed as part of RRC pre-config structure
if (syncsource == SL_SYNC_SOURCE_SYNC_REF_UE) {
if (syncsource == SL_SYNC_SOURCE_SYNC_REF_UE &&
mac->SL_MAC_PARAMS->sl_TDD_config) {
ASN_STRUCT_FREE (asn_DEF_NR_TDD_UL_DL_Pattern, mac->SL_MAC_PARAMS->sl_TDD_config);
mac->SL_MAC_PARAMS->sl_TDD_config = NULL;
}
fapi_nr_max_tdd_periodicity_t *tdd_list =
@@ -132,6 +192,8 @@ static void sl_prepare_phy_config(int module_id,
//FREQSHIFT_7P5KHZ is DISABLED
phycfg->sl_carrier_config.sl_frequency_shift_7p5khz = 0;
phycfg->sl_carrier_config.sl_value_N = freqcfg->valueN_r16;
phycfg->sl_carrier_config.sl_num_tx_ant = 1;
phycfg->sl_carrier_config.sl_num_rx_ant = 1;
NR_SCS_SpecificCarrier_t *carriercfg =
freqcfg->sl_SCS_SpecificCarrierList_r16.list.array[0];
@@ -235,10 +297,12 @@ static void sl_prepare_phy_config(int module_id,
str[phycfg->sl_sync_source.sync_source],
phycfg->sl_sync_source.gnss_dfn_offset,
phycfg->sl_sync_source.rx_slss_id);
LOG_I(NR_MAC, "UE[%d] Carrier CFG Params: freq:%ld, bw:%d, gridsize:%d, valueN:%d\n",
LOG_I(NR_MAC, "UE[%d] Carrier CFG Params: freq:%ld, bw:%d, gridsize:%d, rxant:%d, txant:%d, valueN:%d\n",
module_id,phycfg->sl_carrier_config.sl_frequency,
phycfg->sl_carrier_config.sl_bandwidth,
phycfg->sl_carrier_config.sl_grid_size,
phycfg->sl_carrier_config.sl_num_rx_ant,
phycfg->sl_carrier_config.sl_num_tx_ant,
phycfg->sl_carrier_config.sl_value_N);
LOG_I(NR_MAC, "UE[%d] SL-BWP Params: start:%d, size:%d, scs:%d, Ncp:%d, startsym:%d, numsym:%d,ssb_offset:%d,dcloc:%d\n",
module_id,phycfg->sl_bwp_config.sl_bwp_start,
@@ -305,6 +369,7 @@ int nr_rrc_mac_config_req_sl_preconfig(module_id_t module_id,
if (freqcfg->sl_BWP_List_r16 &&
freqcfg->sl_BWP_List_r16->list.array[0])
bwp = freqcfg->sl_BWP_List_r16->list.array[0];
mac->sl_bwp = bwp;
AssertFatal(bwp!=NULL, "BWP config common cannot be NULL\n");
if (bwp->sl_BWP_PoolConfigCommon_r16) {
@@ -315,6 +380,7 @@ int nr_rrc_mac_config_req_sl_preconfig(module_id_t module_id,
if (rxpool) {
if (sl_mac->sl_RxPool[i] == NULL)
sl_mac->sl_RxPool[i] = malloc16_clear(sizeof(SL_ResourcePool_params_t));
mac->sl_rx_res_pool = rxpool;
sl_mac->sl_RxPool[i]->respool = rxpool;
uint16_t sci_1a_len = 0, num_subch = 0;
sci_1a_len = sl_determine_sci_1a_len(&num_subch,
@@ -339,10 +405,44 @@ int nr_rrc_mac_config_req_sl_preconfig(module_id_t module_id,
bwp->sl_BWP_PoolConfigCommon_r16->sl_TxPoolSelectedNormal_r16->list.array[0]->sl_ResourcePool_r16;
if (txpool) {
mac->sl_tx_res_pool = txpool;
if (sl_mac->sl_TxPool[i] == NULL)
sl_mac->sl_TxPool[i] = malloc16_clear(sizeof(SL_ResourcePool_params_t));
sl_mac->sl_TxPool[i]->respool = txpool;
uint8_t tproc1_valaues[] = {3, 5, 9, 17};
uint8_t mu = get_softmodem_params()->numerology;
struct NR_SL_UE_SelectedConfigRP_r16 *sl_ue_selected_config = sl_mac->sl_TxPool[i]->respool->sl_UE_SelectedConfigRP_r16;
uint16_t sensing_window_ms = (uint16_t)*sl_ue_selected_config->sl_SensingWindow_r16;
uint16_t selection_window = (uint16_t)sl_ue_selected_config->sl_SelectionWindowList_r16->list.array[0]->sl_SelectionWindow_r16;
sl_mac->sl_TxPool[i]->t2min = selection_window;
sl_mac->sl_TxPool[i]->t0 = time_to_slots(mu, sensing_window_ms);
sl_mac->sl_TxPool[i]->tproc0 = 1;
sl_mac->sl_TxPool[i]->tproc1 = tproc1_valaues[mu];
sl_mac->sl_TxPool[i]->t1 = 1;
sl_mac->sl_TxPool[i]->t2 = 60; // According to 38214 sec. 8.1.4: T2min <= t2 <= PDB, where T2min = {1,5,10,20}*2^μ, u = 1, PDB = 20ms = 40 slots
sl_mac->mac_tx_params.rri = sl_ue_selected_config->sl_ResourceReservePeriodList_r16->list.array[0]->choice.sl_ResourceReservePeriod1_r16;
sl_mac->mac_tx_params.resel_counter = get_random_reselection_counter(sl_mac->mac_tx_params.rri);
sl_mac->mac_tx_params.sl_thresh_rsrp = (-128 + (*sl_ue_selected_config->sl_Thres_RSRP_List_r16->list.array[0] - 1) * 2);
long sl_TxPercentage = txpool->sl_TxPercentageList_r16->list.array[0]->sl_TxPercentage_r16;
switch (sl_TxPercentage)
{
case NR_SL_TxPercentageConfig_r16__sl_TxPercentage_r16_p20:
sl_mac->mac_tx_params.sl_res_ratio = 20.0 / 100;
break;
case NR_SL_TxPercentageConfig_r16__sl_TxPercentage_r16_p35:
sl_mac->mac_tx_params.sl_res_ratio = 35.0 / 100;
break;
case NR_SL_TxPercentageConfig_r16__sl_TxPercentage_r16_p50:
sl_mac->mac_tx_params.sl_res_ratio = 50.0 / 100;
break;
default:
LOG_E(NR_MAC, "Incorrect sl_TxPercentage provided, !!!");
break;
}
LOG_D(NR_MAC, "sl_thresh_rsrp %d rri %i sl_ResourceReservePeriod1 %ld, i %d, sensing_window_ms %d, selection_window %d\n",
sl_mac->mac_tx_params.sl_thresh_rsrp, sl_mac->mac_tx_params.rri,
sl_ue_selected_config->sl_ResourceReservePeriodList_r16->list.array[0]->choice.sl_ResourceReservePeriod1_r16,
i, sensing_window_ms, selection_window);
uint16_t sci_1a_len = 0, num_subch = 0;
sci_1a_len = sl_determine_sci_1a_len(&num_subch,
sl_mac->sl_TxPool[i]->respool,
@@ -372,8 +472,19 @@ int nr_rrc_mac_config_req_sl_preconfig(module_id_t module_id,
sl_mac->sl_TDD_config = sl_preconfig->sl_PreconfigGeneral_r16->sl_TDD_Configuration_r16;
config_frame_structure(get_softmodem_params()->numerology,
sl_mac->sl_TDD_config,
get_tdd_period_idx(sl_mac->sl_TDD_config),
TDD,
&mac->frame_structure);
sl_set_tdd_config_nr_ue(&sl_mac->sl_phy_config.sl_config_req.tdd_table,
get_softmodem_params()->numerology,
&sl_mac->sl_TDD_config->pattern1);
// Sync source is identified, timing needs to be adjusted.
sl_mac->timing_acquired = true;
mac->is_synced = true;
}
//Do not copy TDD config yet as SYNC source is not yet found
@@ -382,6 +493,66 @@ int nr_rrc_mac_config_req_sl_preconfig(module_id_t module_id,
ASN_STRUCT_FREE(asn_DEF_NR_TDD_UL_DL_ConfigCommon, sl_mac->sl_TDD_config);
sl_mac->sl_TDD_config = NULL;
}
if (get_nrUE_params()->sync_ref) {
int scs = get_softmodem_params()->numerology;
const int nr_slots_frame = nr_slots_per_frame[scs];
NR_TDD_UL_DL_Pattern_t *tdd = &sl_mac->sl_TDD_config->pattern1;
const int n_ul_slots_period = tdd ? tdd->nrofUplinkSlots + (tdd->nrofUplinkSymbols > 0 ? 1 : 0) : nr_slots_frame;
uint16_t num_subch = sl_get_num_subch(mac->sl_tx_res_pool);
mac->sl_info.list[0]->UE_sched_ctrl.sched_psfch = calloc(n_ul_slots_period * num_subch, sizeof(SL_sched_feedback_t));
mac->sl_info.list[0]->UE_sched_ctrl.sched_psfch->feedback_frame = -1;
mac->sl_info.list[0]->UE_sched_ctrl.sched_psfch->feedback_slot = -1;
int nr_slots_period = nr_slots_frame;
int nr_ulstart_slot = 0;
if (tdd) {
nr_ulstart_slot = get_first_ul_slot(&mac->frame_structure, false);
nr_slots_period /= get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity);
}
memset(mac->ulsch_slot_bitmap, 0, sizeof(mac->ulsch_slot_bitmap));
for (int slot = 0; slot < nr_slots_frame; ++slot) {
mac->ulsch_slot_bitmap[slot / 64] |= (uint64_t)((slot % nr_slots_period) >= nr_ulstart_slot) << (slot % 64);
LOG_D(NR_MAC,
"slot %d UL %d\n",
slot,
(mac->ulsch_slot_bitmap[slot / 64] & ((uint64_t)1 << (slot % 64))) != 0);
}
BIT_STRING_t *sl_tx_time_rsrc = mac->sl_tx_res_pool->ext1->sl_TimeResource_r16;
int total_downlink_slots_in_bitmap = (((sl_tx_time_rsrc->size << 3) - sl_tx_time_rsrc->bits_unused) / n_ul_slots_period) * (nr_slots_period - n_ul_slots_period);
int total_uplink_slots_in_bitmap = (((sl_tx_time_rsrc->size << 3) - sl_tx_time_rsrc->bits_unused) / n_ul_slots_period) * (n_ul_slots_period);
AssertFatal(((sl_tx_time_rsrc->size << 3) - sl_tx_time_rsrc->bits_unused) == total_uplink_slots_in_bitmap, "The computation for total uplink slots is invalid. %ld != %d\n",
((sl_tx_time_rsrc->size << 3) - sl_tx_time_rsrc->bits_unused), total_uplink_slots_in_bitmap);
int phy_sl_size = ((sl_tx_time_rsrc->size << 3) - sl_tx_time_rsrc->bits_unused) + total_downlink_slots_in_bitmap;
AssertFatal(total_downlink_slots_in_bitmap + total_uplink_slots_in_bitmap == phy_sl_size, "The total number of uplink and downlink slots must equal the total bitmap size!");
LOG_D(NR_MAC, "size of phy_sl_map %d total_downlink_slots %d, sl_tx_time_rsrc.size %ld, n_ul_slots_period %d, (nr_slots_period - n_ul_slots_period) %d\n",
phy_sl_size, total_downlink_slots_in_bitmap, ((sl_tx_time_rsrc->size << 3) - sl_tx_time_rsrc->bits_unused), n_ul_slots_period, (nr_slots_period - n_ul_slots_period));
uint8_t pool_id = 0;
size_t byte_capacity = (phy_sl_size + 7) / 8;
SL_ResourcePool_params_t *sl_tx_rsrc_pool = sl_mac->sl_TxPool[pool_id];
BIT_STRING_t *phy_sl_tx_bitmap = &sl_tx_rsrc_pool->phy_sl_bitmap;
phy_sl_tx_bitmap->buf = (uint8_t*)malloc16_clear(byte_capacity);
phy_sl_tx_bitmap->size = byte_capacity;
phy_sl_tx_bitmap->bits_unused = ((phy_sl_tx_bitmap->size << 3) - phy_sl_size) % 8;
uint16_t tx_phy_map_sz = get_physical_sl_pool(mac, sl_tx_time_rsrc, phy_sl_tx_bitmap);
SL_ResourcePool_params_t *sl_rx_rsrc_pool = sl_mac->sl_RxPool[pool_id];
BIT_STRING_t *phy_sl_rx_bitmap = &sl_rx_rsrc_pool->phy_sl_bitmap;
phy_sl_rx_bitmap->buf = (uint8_t*)malloc16_clear(byte_capacity);
phy_sl_rx_bitmap->size = byte_capacity;
phy_sl_rx_bitmap->bits_unused = ((phy_sl_rx_bitmap->size << 3) - phy_sl_size) % 8;
BIT_STRING_t *sl_rx_time_rsrc = mac->sl_rx_res_pool->ext1->sl_TimeResource_r16;
uint16_t rx_phy_map_sz = get_physical_sl_pool(mac, sl_rx_time_rsrc, phy_sl_rx_bitmap);
AssertFatal(tx_phy_map_sz == rx_phy_map_sz, "Transmit %d and receive %d phy_map_sz is different.\n",
tx_phy_map_sz, rx_phy_map_sz);
}
// Configuring CSI-RS parameters locally at MAC.
nr_sl_params_read_conf(module_id);
nr_sl_phy_config_t *sl_phy_cfg = &sl_mac->sl_phy_config;
sl_phy_cfg->Mod_id = module_id;
@@ -390,6 +561,7 @@ int nr_rrc_mac_config_req_sl_preconfig(module_id_t module_id,
sl_prepare_phy_config(module_id, &sl_phy_cfg->sl_config_req,
freqcfg, sync_source, sl_OffsetDFN, sl_mac->sl_TDD_config);
sl_mac->mac_tx_params.packet_delay_budget_ms = 30;
return 0;
}
@@ -483,6 +655,7 @@ void nr_rrc_mac_config_req_sl_mib(module_id_t module_id,
sl_config->sl_sync_source.rx_slss_id = rx_slss_id;
sl_mac->timing_acquired = true;
mac->is_synced = true;
sl_mac->rx_sl_bch.status = 1;
sl_mac->rx_sl_bch.slss_id = rx_slss_id;
@@ -519,16 +692,152 @@ void nr_rrc_mac_config_req_sl_mib(module_id_t module_id,
NR_NUMBER_OF_SUBFRAMES_PER_FRAME*(1<<cfg->sl_bwp_config.sl_scs);
}
config_frame_structure(get_softmodem_params()->numerology,
sl_mac->sl_TDD_config,
get_tdd_period_idx(sl_mac->sl_TDD_config),
TDD,
&mac->frame_structure);
sl_set_tdd_config_nr_ue(&cfg->tdd_table,
cfg->sl_bwp_config.sl_scs,
&sl_mac->sl_TDD_config->pattern1);
AssertFatal(get_nrUE_params()->sync_ref == 0, "Expecting Nearby UE\n");
int scs = get_softmodem_params()->numerology;
const int nr_slots_frame = nr_slots_per_frame[scs];
NR_TDD_UL_DL_Pattern_t *tdd = &sl_mac->sl_TDD_config->pattern1;
const int n_ul_slots_period = tdd ? tdd->nrofUplinkSlots + (tdd->nrofUplinkSymbols > 0 ? 1 : 0) : nr_slots_frame;
uint16_t num_subch = sl_get_num_subch(mac->sl_tx_res_pool);
mac->sl_info.list[0]->UE_sched_ctrl.sched_psfch = calloc(n_ul_slots_period * num_subch, sizeof(SL_sched_feedback_t));
mac->sl_info.list[0]->UE_sched_ctrl.sched_psfch->feedback_frame = -1;
mac->sl_info.list[0]->UE_sched_ctrl.sched_psfch->feedback_slot = -1;
LOG_I(MAC, "SIDELINK CONFIGs: tdd config period:%ld, mu:%ld, DLslots:%ld,ULslots:%ld Mixedslotsym DL:UL %ld:%ld\n",
sl_mac->sl_TDD_config->pattern1.dl_UL_TransmissionPeriodicity,sl_mac->sl_TDD_config->referenceSubcarrierSpacing,
sl_mac->sl_TDD_config->pattern1.nrofDownlinkSlots, sl_mac->sl_TDD_config->pattern1.nrofUplinkSlots,
sl_mac->sl_TDD_config->pattern1.nrofDownlinkSymbols,sl_mac->sl_TDD_config->pattern1.nrofUplinkSymbols);
int nr_slots_period = nr_slots_frame;
int nr_ulstart_slot = 0;
if (tdd) {
nr_ulstart_slot = get_first_ul_slot(&mac->frame_structure, false);
nr_slots_period /= get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity);
}
memset(mac->ulsch_slot_bitmap, 0, sizeof(mac->ulsch_slot_bitmap));
for (int slot = 0; slot < nr_slots_frame; ++slot) {
mac->ulsch_slot_bitmap[slot / 64] |= (uint64_t)((slot % nr_slots_period) >= nr_ulstart_slot) << (slot % 64);
LOG_D(NR_MAC,
"slot %d UL %d\n",
slot,
(mac->ulsch_slot_bitmap[slot / 64] & ((uint64_t)1 << (slot % 64))) != 0);
}
BIT_STRING_t *sl_time_rsrc = mac->sl_tx_res_pool->ext1->sl_TimeResource_r16;
int total_downlink_slots = ((sl_time_rsrc->size << 3) - sl_time_rsrc->bits_unused) / n_ul_slots_period * (nr_slots_period - n_ul_slots_period);
int phy_sl_size = ((sl_time_rsrc->size << 3) - sl_time_rsrc->bits_unused) + total_downlink_slots;
LOG_D(NR_MAC, "size of phy_sl_map %d total_downlink_slots %d, sl_time_rsrc->size %ld, n_ul_slots_period %d, (nr_slots_period - n_ul_slots_period) %d\n", phy_sl_size, total_downlink_slots, ((sl_time_rsrc->size << 3) - sl_time_rsrc->bits_unused), n_ul_slots_period, (nr_slots_period - n_ul_slots_period));
size_t byte_capacity = (phy_sl_size + 7) / 8;
uint8_t pool_id = 0;
SL_ResourcePool_params_t *sl_tx_rsrc_pool = sl_mac->sl_TxPool[pool_id];
SL_ResourcePool_params_t *sl_rx_rsrc_pool = sl_mac->sl_RxPool[pool_id];
sl_tx_rsrc_pool->phy_sl_bitmap.buf = (uint8_t*)malloc16_clear(byte_capacity);
sl_rx_rsrc_pool->phy_sl_bitmap.buf = (uint8_t*)malloc16_clear(byte_capacity);
sl_tx_rsrc_pool->phy_sl_bitmap.size = (phy_sl_size + 7) >> 3;
sl_tx_rsrc_pool->phy_sl_bitmap.bits_unused = ((sl_tx_rsrc_pool->phy_sl_bitmap.size << 3) - phy_sl_size) % 8;
BIT_STRING_t *phy_sl_bitmap = &sl_tx_rsrc_pool->phy_sl_bitmap;
uint16_t tx_phy_map_sz = get_physical_sl_pool(mac, sl_time_rsrc, phy_sl_bitmap);
sl_time_rsrc = mac->sl_rx_res_pool->ext1->sl_TimeResource_r16;
phy_sl_bitmap = &sl_rx_rsrc_pool->phy_sl_bitmap;
sl_rx_rsrc_pool->phy_sl_bitmap.size = (phy_sl_size + 7) >> 3;
sl_rx_rsrc_pool->phy_sl_bitmap.bits_unused = ((sl_rx_rsrc_pool->phy_sl_bitmap.size << 3) - phy_sl_size) % 8;
uint16_t rx_phy_map_sz = get_physical_sl_pool(mac, sl_time_rsrc, phy_sl_bitmap);
AssertFatal(tx_phy_map_sz == rx_phy_map_sz, "Transmit and Receive physical sidelink bitmap does not have same length!!!");
DevAssert(mac->if_module != NULL && mac->if_module->sl_phy_config_request != NULL);
mac->if_module->sl_phy_config_request(&sl_mac->sl_phy_config);
}
}
void nr_sl_params_read_conf(module_id_t module_id) {
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
sl_nr_ue_mac_params_t *sl_mac = mac->SL_MAC_PARAMS;
char aprefix[MAX_OPTNAME_SIZE*2 + 8];
sl_csi_info_t *sl_csi_rs_info = (sl_csi_info_t *)malloc16_clear(sizeof(sl_csi_info_t));
paramdef_t SL_CRI_RS_INFO[] = SL_CSI_RS_DESC(sl_csi_rs_info);
paramlist_def_t SL_CRI_RS_List = {SL_CONFIG_STRING_SL_CSI_RS_LIST, NULL, 0};
sprintf(aprefix, "%s.[%d]", SL_CONFIG_STRING_SL_PRECONFIGURATION, 0);
config_getlist(config_get_if(), &SL_CRI_RS_List, NULL, 0, aprefix);
sprintf(aprefix, "%s.[%i].%s.[%i]", SL_CONFIG_STRING_SL_PRECONFIGURATION, 0, SL_CONFIG_STRING_SL_CSI_RS_LIST, 0);
config_get(config_get_if(), SL_CRI_RS_INFO, sizeof(SL_CRI_RS_INFO)/sizeof(paramdef_t), aprefix);
char aprefix1[MAX_OPTNAME_SIZE*2 + 8];
sl_harq_info_t *sl_harq_info = (sl_harq_info_t*)malloc16_clear(sizeof(sl_harq_info_t));
paramdef_t SL_HARQ_INFO[] = SL_CONFIGUREDGRANT_DESC(sl_harq_info);
sprintf(aprefix1, "%s.[%i].%s.[%i]", SL_CONFIG_STRING_SL_PRECONFIGURATION, 0, SL_CONFIG_STRING_SL_CONFIGUREDGRANT_LIST, 0);
config_get(config_get_if(), SL_HARQ_INFO, sizeof(SL_HARQ_INFO)/sizeof(paramdef_t), aprefix1);
sl_mac->sl_Num_HARQ_Processes = sl_harq_info->sl_Num_HARQ_Processes;
sl_mac->sl_HARQ_ProcID_offset = sl_harq_info->sl_HARQ_ProcID_offset;
sl_mac->sl_Periodic_RRI = sl_harq_info->sl_Periodic_RRI;
sl_mac->csi_type = sl_csi_rs_info->csi_type;
sl_mac->symb_l0 = sl_csi_rs_info->symb_l0;
sl_mac->power_control_offset = sl_csi_rs_info->power_control_offset;
sl_mac->power_control_offset_ss = sl_csi_rs_info->power_control_offset_ss;
sl_mac->measurement_bitmap = 0b00011011;
sl_mac->sl_CSI_Acquisition = sl_csi_rs_info->sl_csi_acquisition;
sl_mac->sl_LatencyBoundCSI_Report = sl_csi_rs_info->sl_latencyboundcsi_report;
// Based on 38211 Table 7.4.1.5.3-1, for density of 1 and ports 1 & 2 ENUMERATED {noCDM, fd-CDM2}
sl_mac->cdm_type = get_nrUE_params()->nb_antennas_tx == 1 ? 0 : 1;
sl_mac->row = get_nrUE_params()->nb_antennas_tx == 1 ? 2 : 3;
// Only 1 is supported (38211, 8.4.1.5.3) - means CSI-RS transmission in every resource block
sl_mac->freq_density = 1;
sl_mac->freq_domain = 0b000000000001; //bitmap size is dependent upon row size; for row 2 length is 12 bits else 6 bits;
int loc_bw = mac->sl_bwp->sl_BWP_Generic_r16->sl_BWP_r16->locationAndBandwidth;
uint16_t bwp_start = NRRIV2PRBOFFSET(loc_bw, MAX_BWP_SIZE);
// PRB where this CSI resource starts in relation to common resource block #0 (CRB#0) on the common resource block grid.
// Only multiples of 4 are allowed (0, 4, ...)
// INTEGER (0..maxNrofPhysicalResourceBlocks-1)
sl_mac->start_rb = (bwp_start % 4 == 0) ? bwp_start : ((bwp_start >> 2) << 2) + 4;
// Number of PRBs across which this CSI resource spans. The smallest configurable number is the minimum of 24 and the width of the associated BWP
// Only multiples of 4 are allowed.
// INTEGER (24..maxNrofPhysicalResourceBlocksPlus1)
uint16_t max_allowable_num_rbs = (NRRIV2BW(loc_bw, MAX_BWP_SIZE) >> 2) << 2;
sl_mac->nr_of_rbs = min(24, max_allowable_num_rbs);
LOG_D(NR_MAC, "loc_bw %i, start_rb %i, nr_of_rbs %i, max_allowable_num_rbs %i\n", loc_bw, sl_mac->start_rb, sl_mac->nr_of_rbs, max_allowable_num_rbs);
char aprefix_rsc[MAX_OPTNAME_SIZE*2 + 8];
sprintf(aprefix_rsc, "%s.[%d]", SL_CONFIG_STRING_SL_PRECONFIGURATION, 0);
uint16_t* resource_selection_cfg = (uint16_t *)malloc16_clear(sizeof(*resource_selection_cfg));
paramdef_t SL_CONFIG_RSR_INFO[] = SL_CONFIG_RESOURCE_SELECTION(resource_selection_cfg);
config_get(config_get_if(), SL_CONFIG_RSR_INFO, sizeof(SL_CONFIG_RSR_INFO) / sizeof(paramdef_t), aprefix_rsc);
switch(*resource_selection_cfg) {
case 0:
mac->rsc_selection_method = c1;
break;
case 3:
mac->rsc_selection_method = c4;
break;
case 4:
mac->rsc_selection_method = c5;
break;
case 6:
mac->rsc_selection_method = c7;
break;
default:
LOG_D(NR_MAC, "Provided resource selection mechanism is not supported!!!\n");
break;
}
}

View File

@@ -45,6 +45,7 @@
/* MAC */
#include "LAYER2/NR_MAC_COMMON/nr_mac.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
#include "NR_MAC_COMMON/nr_mac_extern.h"
#include "mac_defs_sl.h"
/* RRC */
@@ -61,6 +62,7 @@
#include "NR_ServingCellConfig.h"
#include "NR_MeasConfig.h"
#include "NR_ServingCellConfigCommonSIB.h"
#include "NR_SL-BWP-ConfigCommon-r16.h"
// ==========
@@ -459,6 +461,264 @@ typedef struct ssb_list_info {
int nb_ssb_per_index[MAX_NB_SSB];
} ssb_list_info_t;
typedef struct NR_sched_pssch {
int frame;
int slot;
int mu;
/// RB allocation within active uBWP
uint16_t rbSize;
uint16_t rbStart;
/// MCS
uint8_t mcs;
/// TBS-related info
uint16_t R;
uint8_t Qm;
uint32_t tb_size;
/// UL HARQ PID to use for this UE, or -1 for "any new"
int8_t sl_harq_pid;
uint8_t nrOfLayers;
//NR_pusch_dmrs_t dmrs_info;
} NR_sched_pssch_t;
typedef struct {
bool is_waiting;
bool is_active;
uint8_t ndi;
uint8_t round;
uint16_t feedback_slot;
uint16_t feedback_frame;
int8_t sl_harq_pid;
// Transport block to be sent using this HARQ process, its size is in sched_pssch
uint32_t transportBlock[38016]; // valid up to 4 layers
uint32_t tb_size;
/// sched_pusch keeps information on MCS etc used for the initial transmission
NR_sched_pssch_t sched_pssch;
} NR_UE_sl_harq_t;
typedef struct SL_CSI_Report {
uint8_t ri;
int8_t cqi;
uint8_t cqi_table;
uint32_t frame;
uint32_t slot;
bool active;
uint8_t slot_offset;
uint8_t slot_periodicity;
NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR slot_periodicity_offset;
} SL_CSI_Report_t;
//
typedef struct SL_sched_feedback {
int16_t feedback_slot;
int16_t feedback_frame;
int16_t harq_feedback;
uint8_t dai_c;
bool active;
uint8_t freq_hop_flag;
uint8_t group_hop_flag;
uint8_t sequence_hop_flag;
uint16_t second_hop_prb;
uint8_t nr_of_symbols;
uint8_t start_symbol_index;
uint8_t hopping_id;
uint16_t prb;
uint16_t sl_bwp_start;
uint16_t initial_cyclic_shift;
uint8_t mcs;
uint8_t bit_len_harq;
} SL_sched_feedback_t;
typedef struct {
// sidelink bytes that are currently scheduled
int sched_sl_bytes;
/// Sched PSSCH: scheduling decisions, copied into HARQ and cleared every TTI
NR_sched_pssch_t sched_pssch;
// Used on PSFCH transmitter
SL_sched_feedback_t *sched_psfch;
/// total amount of data awaiting for this UE
uint32_t num_total_bytes;
uint16_t sl_pdus_total;
/// per-LC status data
mac_rlc_status_resp_t rlc_status[NR_MAX_NUM_LCID];
//
NR_bler_stats_t sl_bler_stats;
/// information about every UL HARQ process
NR_UE_sl_harq_t sl_harq_processes[NR_MAX_HARQ_PROCESSES];
/// UL HARQ processes that are free
NR_list_t available_sl_harq;
/// UL HARQ processes that await feedback
NR_list_t feedback_sl_harq;
/// UL HARQ processes that await retransmission
NR_list_t retrans_sl_harq;
// NR_SLSCH
// Used on CSI report transmitter
SL_CSI_Report_t sched_csi_report;
// To hold the CSI report values received from different users
nr_sl_csi_report_t rx_csi_report;
bool print_csi_report;
/// UE-estimated maximum MCS (from CSI-RS)
uint8_t sl_max_mcs;
} NR_SL_UE_sched_ctrl_t;
#define MAX_SL_UE_CONNECTIONS 8
#define CUR_SL_UE_CONNECTIONS 1
#define MAX_SL_CSI_REPORTCONFIG MAX_SL_UE_CONNECTIONS
typedef struct {
uid_t uid; // unique ID of this UE
/// scheduling control info
nr_sl_csi_report_t csi_report_template[MAX_SL_CSI_REPORTCONFIG];
NR_SL_UE_sched_ctrl_t UE_sched_ctrl;
NR_UE_sl_mac_stats_t mac_sl_stats;
} NR_SL_UE_info_t;
typedef struct {
NR_SL_UE_info_t *list[MAX_SL_UE_CONNECTIONS+1];
uid_allocator_t ue_allocator;
pthread_mutex_t mutex;
} NR_SL_UEs_t;
typedef struct {
int16_t frame;
int16_t slot;
} frameslot_t;
typedef struct {
frameslot_t frame_slot;
uint16_t rsvp; // The resource reservation period in ms
uint8_t subch_len; // The total number of the sub-channel allocated
uint8_t subch_start; // The index of the starting sub-channel allocated
uint8_t prio; // The priority
int16_t sl_rsrp; // The measured RSRP value over the used resource blocks
uint8_t gap_re_tx1; // Gap for a first retransmission in absolute slots
uint8_t subch_startre_tx1; // The index of the starting sub-channel allocated
// to first retransmission
uint8_t gap_re_tx2; // Gap for a second retransmission in absolute slots
uint8_t subch_startre_tx2; // The index of the starting sub-channel allocated
// to second retransmission
} sensing_data_t;
typedef struct {
void* data;
size_t element_size;
size_t size;
size_t capacity;
} List_t;
typedef struct {
List_t* lists;
size_t size;
size_t capacity;
} vec_of_list_t;
typedef enum {
c1, c2, c3, c4, c5, c6, c7
} allowed_rsc_selection_t;
typedef struct {
uint16_t num_sl_pscch_rbs;
uint16_t sl_pscch_sym_start;
uint16_t sl_pscch_sym_len;
uint16_t sl_pssch_sym_start;
uint16_t sl_pssch_sym_len;
uint16_t sl_subchan_size;
uint16_t sl_max_num_per_reserve;
uint8_t sl_psfch_period;
uint8_t sl_min_time_gap_psfch;
uint8_t sl_min_time_gap_processing;
frameslot_t sfn;
uint8_t sl_subchan_start;
uint8_t sl_subchan_len;
bool slot_busy;
} sl_resource_info_t;
typedef enum {
NR_SL_V2X_LBT_DISABLED = 0,
NR_SL_V2X_LBT_TYPE2,
NR_SL_V2X_LBT_TYPE1,
} nr_sl_v2x_lbt_mode_t;
typedef struct {
bool enabled;
nr_sl_v2x_lbt_mode_t mode;
int16_t energy_detection_threshold_dbm;
uint8_t max_consecutive_failures;
uint8_t consecutive_failures;
uint32_t attempts;
uint32_t failures;
uint32_t successes;
frameslot_t last_failure;
} nr_sl_v2x_lbt_state_t;
typedef struct {
bool active;
uint16_t pool_id;
uint16_t c_resel;
uint16_t c_resel_initial;
uint16_t p_rsvp_slots;
int64_t next_abs_slot;
sl_resource_info_t resource;
sl_resource_info_t current_resource;
uint32_t reselections;
uint32_t kept;
uint32_t released;
} nr_sl_v2x_sps_state_t;
typedef struct {
bool enabled;
nr_sl_v2x_lbt_state_t lbt;
nr_sl_v2x_sps_state_t sps;
} nr_sl_v2x_scheduler_t;
/**
* \brief Structure to denote a future resource reserved by another UE
*
* This data structure represents resources excluded by step 6c) of the
* TS 38.214 Sec. 8.1.4 sensing algorithm.
*/
typedef struct {
frameslot_t sfn; // The SfnSf
uint16_t rsvp; // The resource reservation period in ms
uint8_t sb_ch_length; // The total number of the sub-channel allocated
uint8_t sb_ch_start; // The index of the starting sub-channel allocated
uint8_t prio; // The priority
double sl_rsrp; // The measured RSRP value over the used resource blocks
} reserved_resource_t;
typedef struct {
// PSCCH
uint16_t num_sl_pscch_rbs; // Indicates the number of PRBs for PSCCH in a resource pool where it is not
// greater than the number PRBs of the subchannel.
uint16_t sl_pscch_sym_start; // Indicates the starting symbol used for sidelink PSCCH in a slot
uint16_t sl_pscch_sym_len; // Indicates the total number of symbols available for sidelink PSCCH
// PSSCH
uint16_t sl_pssch_sym_start; // Indicates the starting symbol used for sidelink PSSCH in a slot
uint16_t sl_pssch_sym_len; // Indicates the total number of symbols available for sidelink PSSCH
bool sl_has_psfch; // Indicates whether PSFCH is present in the slot
// subchannel size in RBs
uint16_t sl_sub_chan_size; // Indicates the subchannel size in number of RBs
uint16_t sl_max_num_per_reserve; // The maximum number of reserved PSCCH/PSSCH resources
// that can be indicated by an SCI.
uint64_t abs_slot_index; // Indicates the the absolute slot index
uint32_t slot_offset; // Indicates the positive offset between two slots
} slot_info_t;
typedef struct nr_lcordered_info_s {
// logical channels ids ordered as per priority
NR_LogicalChannelIdentity_t lcid;
@@ -597,6 +857,12 @@ typedef struct NR_UE_MAC_INST_s {
NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon;
frame_structure_t frame_structure;
// sidelink
NR_SL_BWP_ConfigCommon_r16_t *sl_bwp;
int max_fb_time;
NR_SL_ResourcePool_r16_t *sl_rx_res_pool;
NR_SL_ResourcePool_r16_t *sl_tx_res_pool;
/* Random Access */
/// CRNTI
uint16_t crnti;
@@ -656,6 +922,35 @@ typedef struct NR_UE_MAC_INST_s {
//SIDELINK MAC PARAMETERS
sl_nr_ue_mac_params_t *SL_MAC_PARAMS;
// SIDELINK Scheduling fields
NR_SL_UEs_t sl_info;
// current SCI pdu build from SCI1 and SCI2
nr_sci_pdu_t sci_pdu_rx;
nr_sci_pdu_t sci1_pdu;
nr_sci_pdu_t sci2_pdu;
uint8_t slsch_payload[16384];
time_stats_t rlc_data_req;
int src_id;
pthread_mutex_t sl_sched_lock;
bool is_synced;
allowed_rsc_selection_t rsc_selection_method; // Flag to enable NR Sidelink resource selection based on
// sensing; otherwise, use random selection
double m_slProbResourceKeep; // Sidelink probability of keeping a resource after resource
// re-selection counter reaches zero
List_t sl_sensing_data; // List to store sensing data
uint8_t sl_resel_counter; // The resource selection counter
uint16_t sl_c_resel; // The C_resel counter
List_t sl_transmit_history; // History of slots used for transmission
nr_sl_v2x_scheduler_t sl_v2x_scheduler;
/// bitmap of ULSCH slots, can hold up to 160 slots
uint64_t ulsch_slot_bitmap[3];
List_t *sl_candidate_resources;
uint16_t reselection_timer;
// PUCCH closed loop power control state
int G_b_f_c;
bool pucch_power_control_initialized;

View File

@@ -27,7 +27,11 @@
#include "NR_TDD-UL-DL-ConfigCommon.h"
#include "NR_MAC_COMMON/nr_mac.h"
#include "NR_UE_PHY_INTERFACE/NR_IF_Module.h"
#include "nr_ue_sci.h"
#include <pthread.h>
#include "mac_defs.h"
#define HARQ_ROUND_MAX 4
#define SL_NR_MAC_NUM_RX_RESOURCE_POOLS 1
#define SL_NR_MAC_NUM_TX_RESOURCE_POOLS 1
#define SL_NUM_BYTES_TIMERESOURCEBITMAP 20
@@ -44,6 +48,24 @@
#define sci_field_t dci_field_t
#define NR_UE_SL_SCHED_LOCK(lock) \
do { \
int rc = pthread_mutex_lock(lock); \
AssertFatal(rc == 0, "error while locking scheduler mutex\n"); \
} while (0)
#define NR_UE_SL_SCHED_UNLOCK(lock) \
do { \
int rc = pthread_mutex_unlock(lock); \
AssertFatal(rc == 0, "error while locking scheduler mutex\n"); \
} while (0)
#define NR_UE_SL_SCHED_ENSURE_LOCKED(lock)\
do {\
int rc = pthread_mutex_trylock(lock); \
AssertFatal(rc == EBUSY, "this function should be called with the scheduler mutex locked\n");\
} while (0)
typedef struct sidelink_sci_format_1a_fields {
// Priority of this transmission
@@ -96,6 +118,7 @@ typedef struct SL_ResourcePool_params {
//This holds the structure from RRC
NR_SL_ResourcePool_r16_t *respool;
BIT_STRING_t phy_sl_bitmap;
//NUM Subchannels in this resource pool
uint16_t num_subch;
@@ -105,6 +128,13 @@ typedef struct SL_ResourcePool_params {
//SCI-1A configuration according to RESPOOL configured.
sidelink_sci_format_1a_fields_t sci_1a;
uint8_t tproc0; // T_proc0 in slots
uint8_t tproc1; // T_proc1 in slots
uint16_t t0; // T0 - Sensing window
uint8_t t1; // T1 - The offset in number of slots between the slot in which the resource
// selection is triggered and the start of the selection window
uint16_t t2; // T2 - The configured value of T2 (end of selection window)
uint8_t t2min; // t2min
} SL_ResourcePool_params_t;
typedef struct sl_ssb_timealloc {
@@ -131,6 +161,23 @@ typedef struct sl_bch_params {
} sl_bch_params_t;
/**
* \brief Structure to pass parameters to trigger the selection of candidate
* resources as per TR 38.214 Section 8.1.4
*/
typedef struct {
uint8_t priority; // L1 priority prio_TX
uint16_t packet_delay_budget_ms; // remaining packet delay budget
uint16_t l_subch; // L_subCH; number of subchannels to be used
uint16_t rri; // resource reservation interval
uint16_t resel_counter; // C_resel counter
int sl_thresh_rsrp; // A threshold in dBm used for sensing based UE autonomous resource selection
float sl_res_ratio; /* The percentage threshold to indicate the
minimum number of candidate single-slot
resources to be selected using sensing procedure.
*/
} nr_sl_transmission_params_t;
typedef struct sl_stored_tti_req {
uint32_t sl_action;
int frame;
@@ -148,6 +195,29 @@ typedef struct sl_nr_ue_mac_params {
//Holds either the TDD config from RRC
//or TDD config decoded from SL-MIB
NR_TDD_UL_DL_ConfigCommon_t *sl_TDD_config;
nr_sl_transmission_params_t mac_tx_params;
// CSI params configured locally
uint8_t symb_l0;
uint8_t csi_type;
uint8_t power_control_offset;
uint8_t power_control_offset_ss;
uint8_t freq_density;
uint8_t subcarrier_spacing;
uint8_t cyclic_prefix;
uint16_t start_rb;
uint16_t nr_of_rbs;
uint8_t row;
uint16_t freq_domain;
uint8_t cdm_type;
uint16_t scramb_id;
uint8_t measurement_bitmap;
uint8_t sl_LatencyBoundCSI_Report;
// configured grant harq parameters
uint8_t sl_Num_HARQ_Processes;
uint8_t sl_HARQ_ProcID_offset;
uint16_t sl_Periodic_RRI;
//Configured from RRC
uint32_t sl_MaxNumConsecutiveDTX;
@@ -177,6 +247,7 @@ typedef struct sl_nr_ue_mac_params {
uint16_t decoded_DFN;
uint16_t decoded_slot;
NR_bler_options_t sl_bler;
uint32_t N_SL_SLOTS;
uint16_t N_SSB_16frames;

View File

@@ -37,13 +37,34 @@
#include "oai_asn1.h"
#include "RRC/NR_UE/rrc_defs.h"
#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h"
#include "executables/nr-uesoftmodem.h"
#define NR_DL_MAX_DAI (4) /* TS 38.213 table 9.1.3-1 Value of counter DAI for DCI format 1_0 and 1_1 */
#define NR_DL_MAX_NB_CW (2) /* number of downlink code word */
// 38.213 Table 16.3-1 set of cyclic shift pairs
static const int16_t table_16_3_1[4][6] = {
{0},
{0, 3},
{0, 2, 4},
{0, 1, 2, 3, 4, 5}
};
typedef struct prbs_set {
uint16_t **start_prb;
uint16_t **end_prb;
} prbs_set_t;
typedef struct psfch_params {
uint16_t m0;
prbs_set_t *prbs_sets;
} psfch_params_t;
/**\brief initialize the field in nr_mac instance
\param mac MAC pointer */
void nr_ue_init_mac(NR_UE_MAC_INST_t *mac);
void nr_ue_init_mac(NR_UE_MAC_INST_t *mac, ueinfo_t *ueinfo);
void nr_ue_init_mac_sl(NR_UE_MAC_INST_t *mac, ueinfo_t *ueinfo);
NR_UE_DL_BWP_t *get_dl_bwp_structure(NR_UE_MAC_INST_t *mac, int bwp_id, bool setup);
NR_UE_UL_BWP_t *get_ul_bwp_structure(NR_UE_MAC_INST_t *mac, int bwp_id, bool setup);
@@ -95,7 +116,7 @@ void nr_rrc_mac_resume_rb(module_id_t module_id, bool is_srb, int rb_id);
void nr_rrc_mac_config_req_reset(module_id_t module_id, NR_UE_MAC_reset_cause_t cause);
/**\brief initialization NR UE MAC instance(s)*/
NR_UE_MAC_INST_t * nr_l2_init_ue(int nb_inst);
NR_UE_MAC_INST_t * nr_l2_init_ue(int nb_inst, ueinfo_t* ueinfo);
/**\brief fetch MAC instance by module_id
\param module_id index of MAC instance(s)*/
@@ -150,6 +171,21 @@ typedef struct {
enum { b_none, b_long, b_short, b_short_trunc, b_long_trunc } type_bsr;
} type_bsr_t;
typedef struct {
uint8_t phr_len;
uint sdu_length_total;
NR_SINGLE_ENTRY_PHR_MAC_CE phr;
type_bsr_t bsr;
uint8_t *pdu_end;
uint8_t *end_for_tailer;
uint8_t *cur_ptr;
uint num_sdus;
// int highest_priority = 16;
// variable used to store the lcid data status during lcp
bool lcids_data_status[NR_MAX_NUM_LCID];
uint32_t lcp_allocation_counter;
} NR_UE_MAC_CE_INFO;
int nr_write_ce_ulsch_pdu(uint8_t *mac_ce,
NR_UE_MAC_INST_t *mac,
NR_SINGLE_ENTRY_PHR_MAC_CE *power_headroom,
@@ -329,6 +365,8 @@ int nr_rrc_mac_config_req_sl_preconfig(module_id_t module_id,
NR_SL_PreconfigurationNR_r16_t *sl_preconfiguration,
uint8_t sync_source);
uint8_t count_on_bits(uint8_t* buf, size_t size);
void nr_rrc_mac_transmit_slss_req(module_id_t module_id,
uint8_t *sl_mib_payload,
uint16_t tx_slss_id,
@@ -338,6 +376,8 @@ void nr_rrc_mac_config_req_sl_mib(module_id_t module_id,
uint16_t rx_slss_id,
uint8_t *sl_mib);
void nr_sl_params_read_conf(module_id_t module_id);
void sl_prepare_psbch_payload(NR_TDD_UL_DL_ConfigCommon_t *TDD_UL_DL_Config,
uint8_t *bits_0_to_7, uint8_t *bits_8_to_11,
uint8_t mu, uint8_t L, uint8_t Y);
@@ -357,8 +397,332 @@ uint8_t sl_determine_sci_1a_len(uint16_t *num_subchannels,
@returns int : 0 or Sidelink slot type */
int sl_nr_ue_slot_select(const sl_nr_phy_config_request_t *cfg, int nr_slot, uint8_t frame_duplex_type);
void nr_ue_process_mac_sl_pdu(int module_idP,
sl_nr_rx_indication_t *rx_ind,
int pdu_id);
NR_SL_UE_info_t* find_UE(NR_UE_MAC_INST_t *mac,
uint16_t ue_id);
int get_csi_reporting_frame_slot(NR_UE_MAC_INST_t *mac,
NR_TDD_UL_DL_Pattern_t *tdd,
uint8_t csi_offset,
const int nr_slots_frame,
uint32_t frame,
uint32_t slot,
uint32_t *csi_report_frame,
uint32_t *csi_report_slot);
uint16_t sl_get_subchannel_size(NR_SL_ResourcePool_r16_t *rpool);
int nr_ue_process_sci1_indication_pdu(NR_UE_MAC_INST_t *mac,module_id_t mod_id,int cc_id,frame_t frame, int slot, sl_nr_sci_indication_pdu_t *sci,void *phy_data);
void nr_ue_sidelink_scheduler(nr_sidelink_indication_t *sl_ind, NR_UE_MAC_INST_t *mac);
void nr_ue_sl_v2x_init_scheduler(NR_UE_MAC_INST_t *mac);
sl_resource_info_t *nr_ue_sl_v2x_select_resource(NR_UE_MAC_INST_t *mac,
const frameslot_t *frame_slot,
sl_sidelink_slot_type_t slot_type);
bool nr_ue_sl_v2x_lbt_allows_tx(NR_UE_MAC_INST_t *mac,
const sl_resource_info_t *resource,
const frameslot_t *frame_slot);
void nr_ue_sl_v2x_notify_tx_result(NR_UE_MAC_INST_t *mac,
const sl_resource_info_t *resource,
const frameslot_t *frame_slot,
bool transmitted);
NR_SearchSpace_t *get_common_search_space(const NR_UE_MAC_INST_t *mac, const NR_SearchSpaceId_t ss_id);
void nr_schedule_slsch(NR_UE_MAC_INST_t *mac, int frameP, int slotP, nr_sci_pdu_t *sci_pdu,
nr_sci_pdu_t *sci2_pdu,
nr_sci_format_t format2,
NR_SL_UE_info_t *UE,
uint16_t *slsch_pdu_length,
NR_UE_sl_harq_t *cur_harq,
mac_rlc_status_resp_t *rlc_status,
sl_resource_info_t *resource);
SL_CSI_Report_t* set_nr_ue_sl_csi_meas_periodicity(const NR_TDD_UL_DL_Pattern_t *tdd,
NR_SL_UE_sched_ctrl_t *sched_ctrl,
NR_UE_MAC_INST_t *mac,
int uid,
bool is_rsrp);
void nr_ue_sl_csi_period_offset(SL_CSI_Report_t *sl_csi_report,
int *period,
int *offset);
uint8_t nr_ue_sl_psbch_scheduler(nr_sidelink_indication_t *sl_ind,
sl_nr_ue_mac_params_t *sl_mac_params,
sl_nr_rx_config_request_t *rx_config,
sl_nr_tx_config_request_t *tx_config,
uint8_t *config_type);
bool nr_ue_sl_pssch_scheduler(NR_UE_MAC_INST_t *mac,
nr_sidelink_indication_t *sl_ind,
const NR_SL_BWP_ConfigCommon_r16_t *sl_bwp,
const NR_SL_ResourcePool_r16_t *sl_res_pool,
sl_nr_tx_config_request_t *tx_config,
sl_resource_info_t *resource,
uint8_t *config_type);
void nr_ue_sl_pscch_rx_scheduler(nr_sidelink_indication_t *sl_ind,
const NR_SL_BWP_ConfigCommon_r16_t *sl_bwp,
const NR_SL_ResourcePool_r16_t *sl_res_pool,
sl_nr_rx_config_request_t *rx_config,
uint8_t *config_type,
bool sl_has_psfch);
void nr_ue_sl_csi_rs_scheduler(NR_UE_MAC_INST_t *mac,
uint8_t scs,
const NR_SL_BWP_ConfigCommon_r16_t *sl_bwp,
sl_nr_tx_config_request_t *tx_config,
sl_nr_rx_config_request_t *rx_config,
uint8_t *config_type);
void nr_ue_sl_csi_report_scheduling(int Mod_idP,
NR_SL_UE_sched_ctrl_t *sched_ctrl,
frame_t frame,
sub_frame_t slot);
void fill_csi_rs_pdu(sl_nr_ue_mac_params_t *sl_mac,
sl_nr_tti_csi_rs_pdu_t *csi_rs_pdu,
const NR_SL_BWP_ConfigCommon_r16_t *sl_bwp,
uint8_t scs);
void nr_ue_sl_psfch_scheduler(NR_UE_MAC_INST_t *mac,
frame_t frame,
uint16_t slot,
long psfch_period,
nr_sidelink_indication_t *sl_ind,
const NR_SL_BWP_ConfigCommon_r16_t *sl_bwp,
sl_nr_tx_config_request_t *tx_config,
uint8_t *config_type);
void config_pscch_pdu_rx(sl_nr_rx_config_pscch_pdu_t *nr_sl_pscch_pdu,
const NR_SL_BWP_ConfigCommon_r16_t *sl_bwp,
const NR_SL_ResourcePool_r16_t *sl_res_pool,
bool sl_has_psfch);
int config_pssch_sci_pdu_rx(sl_nr_rx_config_pssch_sci_pdu_t *nr_sl_pssch_sci_pdu,
nr_sci_format_t sci2_format,
nr_sci_pdu_t *sci_pdu,
uint32_t pscch_Nid,
int pscch_subchannel_index,
const NR_SL_BWP_ConfigCommon_r16_t *sl_bwp,
const NR_SL_ResourcePool_r16_t *sl_res_pool,
bool sl_has_psfch);
sl_resource_info_t* get_resource_element(List_t* resource_list, frameslot_t sfn);
int nr_ue_process_sci2_indication_pdu(NR_UE_MAC_INST_t *mac,
module_id_t mod_id,
int cc_id,
frame_t frame,
int slot,
sl_nr_sci_indication_pdu_t *sci,
void *phy_data);
void extract_pssch_sci_pdu(uint64_t *sci2_payload,
int len,
const NR_SL_BWP_ConfigCommon_r16_t *sl_bwp,
const NR_SL_ResourcePool_r16_t *sl_res_pool,
nr_sci_pdu_t *sci_pdu);
void fill_pssch_pscch_pdu(sl_nr_ue_mac_params_t *sl_mac_params,
sl_nr_tx_config_pscch_pssch_pdu_t *nr_sl_pssch_pscch_pdu,
const NR_SL_BWP_ConfigCommon_r16_t *sl_bwp,
const NR_SL_ResourcePool_r16_t *sl_res_pool,
nr_sci_pdu_t *sci_pdu,
nr_sci_pdu_t *sci2_pdu,
uint16_t slsch_pdu_length,
const nr_sci_format_t format1,
const nr_sci_format_t format2,
uint16_t slot,
sl_resource_info_t *selected_resource);
void fill_psfch_pdu(SL_sched_feedback_t *mac_psfch_pdu,
sl_nr_tx_rx_config_psfch_pdu_t *tx_psfch_pdu,
int num_psfch_symbols);
void update_harq_lists(NR_UE_MAC_INST_t *mac, frame_t frame, sub_frame_t slot, NR_SL_UE_info_t* UE);
int find_current_slot_harqs(frame_t frame, sub_frame_t slot, NR_SL_UE_sched_ctrl_t * sched_ctrl, NR_UE_sl_harq_t **matched_harqs);
uint8_t sl_num_slsch_feedbacks(NR_UE_MAC_INST_t *mac);
bool is_feedback_scheduled(NR_UE_MAC_INST_t *mac, int frameP,int slotP);
uint16_t sl_get_num_subch(NR_SL_ResourcePool_r16_t *rpool);
void fill_psfch_params_tx(NR_UE_MAC_INST_t *mac, sl_nr_rx_indication_t *rx_ind, long psfch_period, uint16_t sched_frame, uint16_t sched_slot, uint8_t ack_nack, psfch_params_t *psfch_params, const int nr_slots_frame, int psfch_index);
void fill_psfch_params_rx(sl_nr_rx_config_request_t *rx_config, sl_nr_tx_rx_config_psfch_pdu_t *psfch_pdu, psfch_params_t *psfch_params, NR_UE_sl_harq_t *cur_harq, NR_UE_MAC_INST_t *mac, long psfch_period, const uint16_t slot);
void configure_psfch_params_rx(int module_idP, NR_UE_MAC_INST_t *mac, sl_nr_rx_config_request_t *rx_config);
void reset_sched_psfch(NR_UE_MAC_INST_t *mac, int frameP,int slotP);
size_t dump_mac_stats_sl(NR_UE_MAC_INST_t *mac, char *output, size_t strlen, bool reset_rsrp);
void handle_nr_ue_sl_harq(module_id_t mod_id, frame_t frame, sub_frame_t slot, sl_nr_slsch_pdu_t *rx_slsch_pdu, uint16_t src_id);
void abort_nr_ue_sl_harq(NR_UE_MAC_INST_t *mac, int8_t harq_pid, NR_SL_UE_info_t *UE_info);
int nr_ue_sl_acknack_scheduling(NR_UE_MAC_INST_t *mac, sl_nr_rx_indication_t *rx_ind,
long psfch_period, uint16_t frame, uint16_t slot, const int nr_slots_frame);
int get_feedback_frame_slot(NR_UE_MAC_INST_t *mac, NR_TDD_UL_DL_Pattern_t *tdd,
uint8_t feedback_offset, uint8_t psfch_min_time_gap,
const int nr_slots_frame, uint16_t frame, uint16_t slot,
long psfch_period, int *psfch_frame, int *psfch_slot);
int16_t get_feedback_slot(long psfch_period, uint16_t slot);
int get_pssch_to_harq_feedback(uint8_t *pssch_to_harq_feedback,
uint8_t psfch_min_time_gap,
NR_TDD_UL_DL_Pattern_t *tdd,
const int nr_slots_frame);
int get_psfch_index(const frame_structure_t *fs, int frame, int slot, int n_slots_frame, const NR_TDD_UL_DL_Pattern_t *tdd, int sched_psfch_max_size);
void init_list(List_t* list, size_t element_size, size_t initial_capacity);
void push_back(List_t* list, void* element);
void update_sensing_data(List_t* sensing_data, frameslot_t *frame_slot, sl_nr_ue_mac_params_t *sl_mac, uint16_t pool_id);
void update_transmit_history(List_t* transmit_history, frameslot_t *frame_slot, sl_nr_ue_mac_params_t *sl_mac, uint16_t pool_id);
void pop_back(List_t* sensing_data);
void free_list_mem(List_t* list);
int64_t normalize(frameslot_t *frame_slot, uint8_t mu);
void de_normalize(int64_t abs_slot_idx, uint8_t mu, frameslot_t *frame_slot);
frameslot_t add_to_sfn(frameslot_t* sfn, uint16_t slot_n, uint8_t mu);
uint16_t get_T2_min(uint16_t pool_id, sl_nr_ue_mac_params_t *sl_mac, uint8_t mu);
uint16_t get_t2(uint16_t pool_id,
uint8_t mu,
nr_sl_transmission_params_t* sl_tx_params,
sl_nr_ue_mac_params_t *sl_mac);
uint16_t time_to_slots(uint8_t mu, uint16_t time);
uint8_t get_tproc0(sl_nr_ue_mac_params_t *sl_mac, uint16_t pool_id);
void remove_old_sensing_data(frameslot_t *frame_slot,
uint16_t sensing_window,
List_t* sensing_data,
sl_nr_ue_mac_params_t *sl_mac);
void remove_old_transmit_history(frameslot_t *frame_slot,
uint16_t sensing_window,
List_t* transmit_history,
sl_nr_ue_mac_params_t *sl_mac);
List_t* get_candidate_resources(frameslot_t *frame_slot,
NR_UE_MAC_INST_t *mac,
List_t *sensing_data,
List_t *transmission_history);
List_t get_nr_sl_comm_opportunities(NR_UE_MAC_INST_t *mac,
uint64_t abs_idx_cur_slot,
uint8_t bwp_id,
uint16_t mu,
uint16_t pool_id,
uint8_t t1,
uint16_t t2,
uint8_t psfch_period);
bool is_sl_slot(NR_UE_MAC_INST_t *mac, BIT_STRING_t *phy_sl_bitmap, uint16_t phy_map_sz, uint64_t abs_slot);
void validate_selected_sl_slot(NR_UE_MAC_INST_t *mac, bool tx, bool rx, NR_TDD_UL_DL_ConfigCommon_t *conf, frameslot_t frame_slot);
bool check_t1_within_tproc1(uint8_t mu, uint16_t t1_slots);
NR_SL_ResourcePool_r16_t* get_resource_pool(NR_UE_MAC_INST_t *mac, uint16_t pool_id);
bool slot_has_psfch(NR_UE_MAC_INST_t *mac, BIT_STRING_t *phy_sl_bitmap, uint64_t abs_index_cur_slot, uint8_t psfch_period, size_t phy_sl_map_size, NR_TDD_UL_DL_ConfigCommon_t *conf);
void append_bit(uint8_t *buf, size_t bit_pos, int bit_value);
int get_bit_from_map(const uint8_t *buf, size_t bit_pos);
void init_vector(vec_of_list_t* vec, size_t initial_capacity);
void add_list(vec_of_list_t* vec, size_t element_size, size_t initial_list_capacity);
List_t* get_list(vec_of_list_t *vec, size_t index);
void* get_front(const List_t* list);
void* get_back(const List_t* list);
void delete_at(List_t* list, size_t index);
void free_vector(vec_of_list_t* vec);
int get_physical_sl_pool(NR_UE_MAC_INST_t *mac, BIT_STRING_t *sl_time_rsrc, BIT_STRING_t *phy_sl_bitmap);
void push_back_list(vec_of_list_t* vec, List_t* new_list);
List_t* get_candidate_resources_from_slots(frameslot_t *sfn,
uint8_t psfch_period,
uint8_t min_time_gap_psfch,
uint16_t l_subch,
uint16_t total_subch,
List_t* slot_info,
uint8_t mu);
List_t exclude_reserved_resources(sensing_data_t *sensed_data,
float slot_period_ms,
uint16_t resv_period_slots,
uint16_t t1,
uint16_t t2,
uint8_t mu);
void exclude_resources_based_on_history(frameslot_t frame_slot,
List_t* transmit_history,
List_t* candidate_resources,
List_t* sl_rsrc_rsrv_period_list,
uint8_t mu);
bool overlapped_resource(uint8_t first_start,
uint8_t first_length,
uint8_t second_start,
uint8_t second_length);
uint8_t get_random_reselection_counter(uint16_t rri);
uint32_t compute_TRIV(uint8_t N, uint8_t t1, uint8_t t2);
uint32_t compute_FRIV(uint8_t sl_max_num_per_reserve,
uint8_t L_sub_chan,
uint8_t n_start_subch1,
uint8_t n_start_subch2,
uint8_t N_sl_subch);
void nr_update_bsr(NR_UE_MAC_INST_t *mac, uint32_t *LCG_bytes);
void nr_ue_get_sdu_mac_ce_pre(NR_UE_MAC_INST_t *mac,
int CC_id,
frame_t frame,
slot_t slot,
uint8_t gNB_index,
uint8_t *ulsch_buffer,
uint32_t buflen,
uint32_t *LCG_bytes,
NR_UE_MAC_CE_INFO *mac_ce_p,
int tx_power,
int P_CMAX);
#endif
/** @}*/

View File

@@ -51,7 +51,43 @@ void send_srb0_rrc(int ue_id, const uint8_t *sdu, sdu_size_t sdu_len, void *data
itti_send_msg_to_task(TASK_RRC_NRUE, ue_id, message_p);
}
void nr_ue_init_mac(NR_UE_MAC_INST_t *mac)
void nr_ue_init_mac_sl(NR_UE_MAC_INST_t *mac, ueinfo_t* ueinfo)
{
int k = 0;
mac->SL_MAC_PARAMS = CALLOC(1, sizeof(sl_nr_ue_mac_params_t));
mac->SL_MAC_PARAMS->sl_bler.harq_round_max = HARQ_ROUND_MAX;
init_list(&mac->sl_sensing_data, sizeof(sensing_data_t), 1);
init_list(&mac->sl_transmit_history, sizeof(frameslot_t), 1);
mac->sl_candidate_resources = (List_t*)malloc16_clear(sizeof(List_t*));
init_list(mac->sl_candidate_resources, sizeof(sl_resource_info_t), 1);
nr_ue_sl_v2x_init_scheduler(mac);
if (ueinfo != NULL) {
mac->src_id = ueinfo->srcid;
LOG_D(NR_MAC, "srcid %d\n", ueinfo->srcid);
}
for (int i = 0; i < CUR_SL_UE_CONNECTIONS + 1; i++) {
if (mac->src_id == i)
continue;
mac->sl_info.list[k] = calloc(1, sizeof(NR_SL_UE_info_t));
mac->sl_info.list[k]->uid = i;
NR_SL_UE_sched_ctrl_t *UE_sched_ctrl = &mac->sl_info.list[k]->UE_sched_ctrl;
UE_sched_ctrl->rx_csi_report.RI = 0;
UE_sched_ctrl->rx_csi_report.CQI = 0;
UE_sched_ctrl->sl_max_mcs = get_nrUE_params()->mcs;
create_nr_list(&UE_sched_ctrl->available_sl_harq, 16);
for (int harq = 0; harq < 16; harq++)
add_tail_nr_list(&UE_sched_ctrl->available_sl_harq, harq);
create_nr_list(&UE_sched_ctrl->feedback_sl_harq, 16);
create_nr_list(&UE_sched_ctrl->retrans_sl_harq, 16);
k++;
}
}
void nr_ue_init_mac(NR_UE_MAC_INST_t *mac, ueinfo_t* ueinfo)
{
LOG_I(NR_MAC, "[UE%d] Initializing MAC\n", mac->ue_id);
nr_ue_reset_sync_state(mac);
@@ -72,6 +108,7 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac)
mac->ntn_ta.ntn_params_changed = false;
initNotifiedFIFO(&mac->input_nf);
reset_mac_inst(mac);
nr_ue_init_mac_sl(mac, ueinfo);
// need to inizialize because might not been setup (optional timer)
nr_timer_stop(&mac->scheduling_info.sr_DelayTimer);
@@ -130,7 +167,7 @@ NR_UE_L2_STATE_t nr_ue_get_sync_state(module_id_t mod_id)
return mac->state;
}
NR_UE_MAC_INST_t *nr_l2_init_ue(int instance_id)
NR_UE_MAC_INST_t *nr_l2_init_ue(int instance_id, ueinfo_t *ueinfo)
{
AssertFatal(instance_id < MAX_NUM_NR_UE_INST, "instance_id %d is out of range\n", instance_id);
AssertFatal(nr_ue_mac_inst[instance_id] == NULL, "MAC instance %d already initialized\n", instance_id);
@@ -138,7 +175,7 @@ NR_UE_MAC_INST_t *nr_l2_init_ue(int instance_id)
NR_UE_MAC_INST_t *mac = nr_ue_mac_inst[instance_id];
mac->ue_id = instance_id;
nr_ue_init_mac(mac);
nr_ue_init_mac(mac, ueinfo);
int ret = pthread_mutex_init(&mac->if_mutex, NULL);
AssertFatal(ret == 0, "Mutex init failed\n");
nr_ue_mac_default_configs(mac);

View File

@@ -0,0 +1,468 @@
/*
* 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 nr_slsch_scheduler.c
* \brief Routines for UE SLSCH scheduling
* \author R. Knopp
* \date Aug. 2023
* \version 0.1
* \company EURECOM
* \email raymond.knopp@eurecom.fr
*/
#include <stdio.h>
#include <math.h>
#include <stdbool.h>
#include <common/utils/nr/nr_common.h>
#include "NR_MAC_COMMON/nr_mac.h"
#include "NR_MAC_COMMON/nr_mac_common.h"
#include "NR_MAC_UE/mac_proto.h"
#include "NR_MAC_UE/nr_ue_sci.h"
#include <executables/nr-uesoftmodem.h>
#include "NR_MAC_UE/mac_defs_sl.h"
#include "NR_MAC_gNB/nr_mac_gNB.h"
#define LOWER_BLER 0.2344
#define UPPER_BLER 5.547
#define MAX_MCS 28
const uint8_t nr_rv_round_map[4] = {0, 2, 3, 1};
void reset_sl_harq_list(NR_SL_UE_sched_ctrl_t *sched_ctrl) {
int harq;
while ((harq = sched_ctrl->feedback_sl_harq.head) >= 0) {
remove_front_nr_list(&sched_ctrl->feedback_sl_harq);
add_tail_nr_list(&sched_ctrl->available_sl_harq, harq);
}
while ((harq = sched_ctrl->retrans_sl_harq.head) >= 0) {
remove_front_nr_list(&sched_ctrl->retrans_sl_harq);
add_tail_nr_list(&sched_ctrl->available_sl_harq, harq);
}
for (int i = 0; i < NR_MAX_HARQ_PROCESSES; i++) {
sched_ctrl->sl_harq_processes[i].feedback_slot = -1;
sched_ctrl->sl_harq_processes[i].round = 0;
sched_ctrl->sl_harq_processes[i].is_waiting = false;
}
}
void abort_nr_ue_sl_harq(NR_UE_MAC_INST_t *mac, int8_t harq_pid, NR_SL_UE_info_t *UE_info)
{
NR_SL_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl;
NR_UE_sl_harq_t *harq = &sched_ctrl->sl_harq_processes[harq_pid];
harq->round = 0;
UE_info->mac_sl_stats.sl.errors++;
add_tail_nr_list(&sched_ctrl->available_sl_harq, harq_pid);
/* the transmission failed: the UE won't send the data we expected initially,
* so retrieve to correctly schedule after next BSR */
sched_ctrl->sched_sl_bytes -= harq->sched_pssch.tb_size;
if (sched_ctrl->sched_sl_bytes < 0)
sched_ctrl->sched_sl_bytes = 0;
}
void handle_nr_ue_sl_harq(module_id_t mod_id,
frame_t frame,
sub_frame_t slot,
sl_nr_slsch_pdu_t *rx_slsch_pdu,
uint16_t src_id)
{
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
NR_UE_SL_SCHED_LOCK(&mac->sl_sched_lock);
NR_SL_UE_info_t **UE_SL_temp = (NR_SL_UE_info_t **)&mac->sl_info.list, *UE;
// TODO: update for multiple UEs
UE=*(UE_SL_temp);
uint8_t num_ack_rcvd = rx_slsch_pdu->num_acks_rcvd;
NR_SL_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
NR_UE_sl_harq_t **matched_harqs = (NR_UE_sl_harq_t **) calloc(sched_ctrl->feedback_sl_harq.len, sizeof(NR_UE_sl_harq_t *));
int k = find_current_slot_harqs(frame, slot, sched_ctrl, matched_harqs);
LOG_D(NR_MAC, "Found %d matching HARQ processes vs. num. of received acks %d\n", k, num_ack_rcvd);
for (int i = 0; i < num_ack_rcvd; i++) {
uint8_t ack_nack = rx_slsch_pdu->ack_nack_rcvd[i];
uint8_t rx_harq_id = matched_harqs[i]->sl_harq_pid;
NR_SL_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
int8_t harq_pid = sched_ctrl->feedback_sl_harq.head;
LOG_D(NR_MAC, "Comparing %4u.%2u rx_harq_id vs feedback harq_pid = %d %d\n", frame, slot, rx_harq_id, harq_pid);
while (rx_harq_id != harq_pid || harq_pid < 0) {
LOG_W(NR_MAC,
"Unexpected SLSCH HARQ PID %d (have %d) for src id %4d\n",
rx_harq_id,
harq_pid,
src_id);
if (harq_pid < 0) {
NR_UE_SL_SCHED_UNLOCK(&mac->sl_sched_lock);
return;
}
remove_front_nr_list(&sched_ctrl->feedback_sl_harq);
sched_ctrl->sl_harq_processes[harq_pid].is_waiting = false;
if(sched_ctrl->sl_harq_processes[harq_pid].round >= (HARQ_ROUND_MAX - 1)) {
abort_nr_ue_sl_harq(mac, harq_pid, UE);
} else {
sched_ctrl->sl_harq_processes[harq_pid].round++;
add_tail_nr_list(&sched_ctrl->retrans_sl_harq, harq_pid);
}
harq_pid = sched_ctrl->feedback_sl_harq.head;
}
remove_front_nr_list(&sched_ctrl->feedback_sl_harq);
NR_UE_sl_harq_t *harq = &sched_ctrl->sl_harq_processes[harq_pid];
DevAssert(harq->is_waiting);
harq->feedback_slot = -1;
harq->is_waiting = false;
if (!ack_nack) {
UE->mac_sl_stats.cumul_round[harq->round]++;
harq->round = 0;
LOG_D(NR_MAC,
"%4u.%2u Slharq id %d crc passed for src id %4d\n",
frame,
slot,
harq_pid,
src_id);
add_tail_nr_list(&sched_ctrl->available_sl_harq, harq_pid);
} else if (harq->round >= (HARQ_ROUND_MAX - 1)) {
UE->mac_sl_stats.cumul_round[HARQ_ROUND_MAX]++;
LOG_D(NR_MAC,
"src id %4d, Slharq id %d crc failed in all rounds\n",
src_id,
harq_pid);
abort_nr_ue_sl_harq(mac, harq_pid, UE);
} else {
harq->round++;
LOG_D(NR_MAC,
"%4u.%2u Slharq id %d crc failed for src id %4d\n",
frame,
slot,
harq_pid,
src_id);
add_tail_nr_list(&sched_ctrl->retrans_sl_harq, harq_pid);
}
}
free(matched_harqs);
matched_harqs = NULL;
NR_UE_SL_SCHED_UNLOCK(&mac->sl_sched_lock);
}
uint32_t compute_TRIV(uint8_t N, uint8_t t1, uint8_t t2) {
int32_t triv = 0;
if (N == 1) {
triv = 0;
} else if (N == 2) {
triv = t1;
} else {
if ((t2 - t1 - 1) <= 15) {
triv = 30 * (t2 - t1 - 1) + t1 + 31;
} else {
triv = 30 * (31 - t2 + t1) + 62 - t1;
}
}
return triv;
}
uint32_t compute_FRIV(uint8_t sl_max_num_per_reserve,
uint8_t L_sub_chan,
uint8_t n_start_subch1,
uint8_t n_start_subch2,
uint8_t N_sl_subch) {
uint32_t friv = 0;
int sum = 0;
if (sl_max_num_per_reserve == NR_SL_UE_SelectedConfigRP_r16__sl_MaxNumPerReserve_r16_n2) {
for (int i = 1; i < L_sub_chan; i++) {
sum += N_sl_subch + 1 - i;
}
friv = n_start_subch1 + sum;
} else if (sl_max_num_per_reserve == NR_SL_UE_SelectedConfigRP_r16__sl_MaxNumPerReserve_r16_n3) {
for (int i = 1; i < L_sub_chan; i++) {
sum += (N_sl_subch + 1 - i) * (N_sl_subch + 1 - i);
}
friv = n_start_subch1 + n_start_subch2 * (N_sl_subch + 1 - L_sub_chan) + sum;
} else {
AssertFatal(1 == 0, "sl_MaxNumPerReserve is configured with incorrect value");
}
return friv;
}
void nr_schedule_slsch(NR_UE_MAC_INST_t *mac, int frameP, int slotP, nr_sci_pdu_t *sci_pdu,
nr_sci_pdu_t *sci2_pdu, nr_sci_format_t format2,
NR_SL_UE_info_t *UE,
uint16_t *slsch_pdu_length_max, NR_UE_sl_harq_t *cur_harq,
mac_rlc_status_resp_t *rlc_status,
sl_resource_info_t *resource) {
uid_t dest_id = UE->uid;
NR_SL_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
const NR_mac_dir_stats_t *stats = &UE->mac_sl_stats.sl;
NR_sched_pssch_t *sched_pssch = &sched_ctrl->sched_pssch;
sl_nr_ue_mac_params_t *sl_mac = mac->SL_MAC_PARAMS;
uint8_t mu = sl_mac->sl_phy_config.sl_config_req.sl_bwp_config.sl_scs;
uint8_t slots_per_frame = nr_slots_per_frame[mu];
uint8_t psfch_period = 0;
const uint8_t psfch_periods[] = {0,1,2,4};
psfch_period = (mac->sl_tx_res_pool->sl_PSFCH_Config_r16 &&
mac->sl_tx_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_PSFCH_Period_r16)
? psfch_periods[*mac->sl_tx_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_PSFCH_Period_r16] : 0;
*slsch_pdu_length_max = 0;
NR_TDD_UL_DL_Pattern_t *tdd = &sl_mac->sl_TDD_config->pattern1;
int period = 0, offset = 0;
bool csi_acq = !mac->SL_MAC_PARAMS->sl_CSI_Acquisition;
SL_CSI_Report_t *sl_csi_report = set_nr_ue_sl_csi_meas_periodicity(tdd, sched_ctrl, mac, dest_id, false);
nr_ue_sl_csi_period_offset(sl_csi_report,
&period,
&offset);
// Determine current slot is csi-rs schedule slot
bool csi_req_slot = !((slots_per_frame * frameP + slotP - offset) % period);
uint8_t ri = 0;
uint8_t cqi_Table = 0;
uint8_t cqi = sched_ctrl->rx_csi_report.CQI;
sched_pssch->mcs = sched_ctrl->sl_max_mcs;
int mcs_tb_ind = 0;
// we are using as a flag to indicate if csi report was received
if (cqi) {
if (sci_pdu->additional_mcs.nbits > 0)
mcs_tb_ind = sci_pdu->additional_mcs.val;
if (mcs_tb_ind == 0)
cqi_Table = NR_CSI_ReportConfig__cqi_Table_table1;
else if (mcs_tb_ind == 1)
cqi_Table = NR_CSI_ReportConfig__cqi_Table_table2;
else if (mcs_tb_ind == 2)
cqi_Table = NR_CSI_ReportConfig__cqi_Table_table3;
sched_pssch->mcs = get_mcs_from_cqi(mcs_tb_ind, cqi_Table, cqi);
sched_ctrl->sl_max_mcs = sched_pssch->mcs;
ri = sched_ctrl->rx_csi_report.RI;
}
/* Calculate coeff */
NR_bler_options_t *sl_bo = &sl_mac->sl_bler;
sl_bo->lower = LOWER_BLER;
sl_bo->upper = UPPER_BLER;
sl_bo->max_mcs = MAX_MCS;
const int max_mcs_table = mcs_tb_ind == 1 ? 27 : 28;
int max_mcs = min(sched_ctrl->sl_max_mcs, max_mcs_table);
if (sl_bo->harq_round_max == 1)
sched_pssch->mcs = max_mcs;
else {
sched_pssch->mcs = get_mcs_from_bler(sl_bo, stats, &sched_ctrl->sl_bler_stats, max_mcs, frameP);
}
uint16_t sl_max_num_reserve = *mac->sl_tx_res_pool->sl_UE_SelectedConfigRP_r16->sl_MaxNumPerReserve_r16;
/*
Following values are based on spec. 38214 section 8.1.5, N = 1 or 2 actual resources when sl-
MaxNumPerReserve is 2, and N = 1 or 2 or 3 actual resources when sl-MaxNumPerReserve is 3.
For N = 2, 1 <= t1 <= 31; and for N = 3, 1 <= t1 <= 30, t1 < t2 <= 31, We are taking N = 1; it represents only 1 reserved resource.
*/
int N = 1;
uint8_t t1 = 0, t2 = 0;
long sl_num_subch = *mac->sl_tx_res_pool->sl_NumSubchannel_r16;
uint8_t l_subch = resource ? resource->sl_subchan_len : 1;
uint8_t n_start_subch1 = resource ? resource->sl_subchan_start : 0;
uint8_t n_start_subch2 = 0;
// Fill SCI1A
sci_pdu->priority = 0;
sci_pdu->frequency_resource_assignment.val = compute_FRIV(sl_max_num_reserve, l_subch, n_start_subch1, n_start_subch2, sl_num_subch);
sci_pdu->time_resource_assignment.val = compute_TRIV(N, t1, t2);
sci_pdu->resource_reservation_period.val = mac->SL_MAC_PARAMS->mac_tx_params.rri;
sci_pdu->dmrs_pattern.val = 0;
sci_pdu->second_stage_sci_format = 0;
sci_pdu->number_of_dmrs_port = ri;
// we are using as a flag to indicate if csi report was received
sci_pdu->mcs = sched_pssch->mcs;
sci_pdu->additional_mcs.val = 0;
if (frameP % 5 == 0)
LOG_D(NR_MAC, "cqi ---> %d Tx %4d.%2d dest: %d mcs %i\n",
cqi, frameP, slotP, dest_id, sci_pdu->mcs);
/*Following code will check whether SLSCH was received before and
its feedback has scheduled for current slot
*/
int scs = sl_mac->sl_phy_config.sl_config_req.sl_bwp_config.sl_scs;
const int nr_slots_frame = nr_slots_per_frame[scs];
const int n_ul_slots_period = tdd ? tdd->nrofUplinkSlots + (tdd->nrofUplinkSymbols > 0 ? 1 : 0) : nr_slots_frame;
uint16_t num_subch = sl_get_num_subch(mac->sl_tx_res_pool);
bool is_feedback_slot = false;
for (int i = 0; i < (n_ul_slots_period * num_subch); i++) {
SL_sched_feedback_t *sched_psfch = &mac->sl_info.list[0]->UE_sched_ctrl.sched_psfch[i];
if (slotP == sched_psfch->feedback_slot) {
LOG_D(NR_MAC, "%4d.%2d i = %d sched_psfch %p feedback slot %d\n", frameP, slotP, i, sched_psfch, sched_psfch->feedback_slot);
is_feedback_slot = true;
frameslot_t frame_slot;
frame_slot.frame = frameP;
frame_slot.slot = slotP;
validate_selected_sl_slot(mac, true, false, mac->SL_MAC_PARAMS->sl_TDD_config, frame_slot);
break;
}
}
frameslot_t fs;
fs.frame = frameP;
fs.slot = slotP;
uint8_t pool_id = 0;
uint64_t tx_abs_slot = normalize(&fs, mu);
SL_ResourcePool_params_t *sl_tx_rsrc_pool = sl_mac->sl_TxPool[pool_id];
size_t phy_map_sz = ((sl_tx_rsrc_pool->phy_sl_bitmap.size << 3) - sl_tx_rsrc_pool->phy_sl_bitmap.bits_unused);
bool sl_has_psfch = slot_has_psfch(mac, &sl_tx_rsrc_pool->phy_sl_bitmap, tx_abs_slot, psfch_period, phy_map_sz, mac->SL_MAC_PARAMS->sl_TDD_config);
if ((psfch_period == 2 || psfch_period == 4) && (sl_has_psfch)) {
if (is_feedback_slot) {
sci_pdu->psfch_overhead.val = 1;
LOG_D(NR_MAC, "%4d.%2d Setting psfch_overhead 1\n", frameP, slotP);
} else {
sci_pdu->psfch_overhead.val = 0;
LOG_D(NR_MAC, "%4d.%2d Setting psfch_overhead 0\n", frameP, slotP);
}
} else if ((psfch_period == 2 || psfch_period == 4) && (!sl_has_psfch)) {
sci_pdu->psfch_overhead.val = 0;
}
sci_pdu->reserved.val = mac->is_synced ? 1 : 0;
sci_pdu->conflict_information_receiver.val = 0;
sci_pdu->beta_offset_indicator = 0;
sci2_pdu->harq_pid = cur_harq->sl_harq_pid;
sci2_pdu->ndi = cur_harq->ndi;
sci2_pdu->rv_index = nr_rv_round_map[cur_harq->round % 4];
sci2_pdu->source_id = mac->src_id;
sci2_pdu->dest_id = dest_id;
sci2_pdu->harq_feedback = cur_harq->is_waiting;
LOG_D(NR_MAC, "%4d.%2d Comparing Setting harq_feedback %d bytes_in_buffer %d sl_harq_pid %d\n", frameP, slotP, sci2_pdu->harq_feedback, rlc_status->bytes_in_buffer, cur_harq ? cur_harq->sl_harq_pid : 0);
sci2_pdu->cast_type = 1;
if (format2 == NR_SL_SCI_FORMAT_2C || format2 == NR_SL_SCI_FORMAT_2A) {
sci2_pdu->csi_req = (csi_acq && csi_req_slot) ? 1 : 0;
sci2_pdu->csi_req = (cur_harq->round > 0 || is_feedback_slot) ? 0 : sci2_pdu->csi_req;
LOG_D(NR_MAC, "%4d.%2d Setting sci2_pdu->csi_req %d\n", frameP, slotP, sci2_pdu->csi_req);
}
if (format2 == NR_SL_SCI_FORMAT_2B)
sci2_pdu->zone_id = 0;
// Fill in for R17: communication_range
sci2_pdu->communication_range.val = 0;
if (format2 == NR_SL_SCI_FORMAT_2C) {
sci2_pdu->providing_req_ind = 0;
// Fill in for R17 : resource combinations
sci2_pdu->resource_combinations.val = 0;
sci2_pdu->first_resource_location = 0;
// Fill in for R17 : reference_slot_location
sci2_pdu->reference_slot_location.val = 0;
sci2_pdu->resource_set_type = 0;
// Fill in for R17 : lowest_subchannel_indices
sci2_pdu->lowest_subchannel_indices.val = 0;
}
// Set SLSCH
*slsch_pdu_length_max = rlc_status->bytes_in_buffer;
}
SL_CSI_Report_t* set_nr_ue_sl_csi_meas_periodicity(const NR_TDD_UL_DL_Pattern_t *tdd,
NR_SL_UE_sched_ctrl_t *sched_ctrl,
NR_UE_MAC_INST_t *mac,
int uid,
bool is_rsrp) {
sl_nr_ue_mac_params_t *sl_mac = mac->SL_MAC_PARAMS;
sl_nr_phy_config_request_t *sl_cfg = &sl_mac->sl_phy_config.sl_config_req;
uint8_t mu = sl_cfg->sl_bwp_config.sl_scs;
uint8_t n_slots_frame = nr_slots_per_frame[mu];
const int n_ul_slots_period = tdd ? tdd->nrofUplinkSlots + (tdd->nrofUplinkSymbols > 0 ? 1 : 0) : n_slots_frame;
const int nr_slots_period = tdd ? n_slots_frame / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity) : n_slots_frame;
const int ideal_period = (CUR_SL_UE_CONNECTIONS * nr_slots_period) / n_ul_slots_period;
const int first_ul_slot_period = tdd ? get_first_ul_slot(&mac->frame_structure, false) : 0;
const int idx = (uid << 1) + is_rsrp;
SL_CSI_Report_t *csi_report = &sched_ctrl->sched_csi_report;
const int offset = first_ul_slot_period + idx % n_ul_slots_period + (idx / n_ul_slots_period) * nr_slots_period;
AssertFatal(offset < 320, "Not enough UL slots to accomodate all possible UEs. Need to rework the implementation\n");
csi_report->slot_offset = offset;
if (ideal_period < 5) {
csi_report->slot_periodicity_offset = NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots4;
} else if (ideal_period < 6) {
csi_report->slot_periodicity_offset = NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots5;
} else if (ideal_period < 9) {
csi_report->slot_periodicity_offset = NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots8;
} else if (ideal_period < 11) {
csi_report->slot_periodicity_offset = NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots10;
} else if (ideal_period < 17) {
csi_report->slot_periodicity_offset = NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots16;
} else if (ideal_period < 21) {
csi_report->slot_periodicity_offset = NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots20;
} else if (ideal_period < 41) {
csi_report->slot_periodicity_offset = NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots40;
} else if (ideal_period < 81) {
csi_report->slot_periodicity_offset = NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots80;
} else if (ideal_period < 161) {
csi_report->slot_periodicity_offset = NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots160;
} else {
csi_report->slot_periodicity_offset = NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots320;
}
return csi_report;
}
void nr_ue_sl_csi_period_offset(SL_CSI_Report_t *sl_csi_report,
int *period,
int *offset) {
*offset = sl_csi_report->slot_offset;
switch(sl_csi_report->slot_periodicity_offset) {
case NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots4:
*period = 4;
break;
case NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots5:
*period = 5;
break;
case NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots8:
*period = 8;
break;
case NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots10:
*period = 10;
break;
case NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots16:
*period = 16;
break;
case NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots20:
*period = 20;
break;
case NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots32:
*period = 32;
break;
case NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots40:
*period = 40;
break;
case NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots64:
*period = 64;
break;
case NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots80:
*period = 80;
break;
case NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots160:
*period = 160;
break;
case NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots320:
*period = 320;
break;
case NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots640:
*period = 640;
break;
default:
AssertFatal(1 == 0, "No periodicity and offset found in CSI resource");
}
}

View File

@@ -21,9 +21,25 @@
#include "mac_defs.h"
#include "mac_proto.h"
#include "openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h"
#include "executables/softmodem-common.h"
#include "executables/nr-uesoftmodem.h"
#include "LAYER2/nr_rlc/nr_rlc_oai_api.h"
#define SL_DEBUG
static const int sequence_cyclic_shift_harq_ack_or_ack_or_only_nack[2]
/* Sequence cyclic shift */ = { 0, 6 };
void print_prb_set_allocation(psfch_params_t *psfch_params, uint8_t psfch_period, uint8_t num_subchannels) {
LOG_D(NR_PHY, "PSSCH Slot mod PSFCH period | Subchannel | Start PRB | End PRB\n");
for (int i = 0; i < psfch_period; i++) {
for (int j = 0; j < num_subchannels; j++) {
LOG_D(NR_PHY, "\t\t %d \t\t|\t%d\t|\t%d\t| \t %d\n", i, j, psfch_params->prbs_sets->start_prb[i][j], psfch_params->prbs_sets->end_prb[i][j]);
}
}
}
uint8_t sl_process_TDD_UL_DL_config_patterns(NR_TDD_UL_DL_ConfigCommon_t *TDD_UL_DL_Config,
uint8_t mu,
double *slot_period_P,
@@ -308,6 +324,12 @@ uint8_t sl_decode_sl_TDD_Config(NR_TDD_UL_DL_ConfigCommon_t *TDD_UL_DL_Config,
//a5,a6..a11 bits from the 7th to 1st LSB of num SL slots
num_SL_slots = ((bits_0_to_7 & 0x07) << 4 ) | ((bits_8_to_11 & 0xF0) >> 4);
const int nr_slots_period = nr_slots_per_frame[mu] / get_nb_periods_per_frame(TDD_UL_DL_Config->pattern1.dl_UL_TransmissionPeriodicity);
AssertFatal(num_SL_slots <= nr_slots_period,
"Decoded sidelink slots %d exceed TDD period slots %d\n",
num_SL_slots,
nr_slots_period);
TDD_UL_DL_Config->pattern1.nrofDownlinkSlots = nr_slots_period - num_SL_slots;
TDD_UL_DL_Config->pattern1.nrofUplinkSlots = num_SL_slots;
TDD_UL_DL_Config->pattern1.nrofUplinkSymbols = mixed_slot_numsym;
@@ -528,3 +550,904 @@ uint8_t sl_determine_sci_1a_len(uint16_t *num_subchannels,
return sci_1a_len;
}
uint8_t count_on_bits(uint8_t* buf, size_t size) {
uint8_t count = 0;
uint8_t byte;
for (size_t i = 0; i < size; i++) {
byte = buf[i];
while(byte) {
count += byte & 1;
byte >>= 1;
}
}
return count;
}
static void compute_params(int module_idP, psfch_params_t* psfch_params) {
NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
if (!mac->sl_tx_res_pool->sl_PSFCH_Config_r16 &&
mac->sl_tx_res_pool->sl_PSFCH_Config_r16->present != NR_SetupRelease_SL_PSFCH_Config_r16_PR_setup)
return;
psfch_params->prbs_sets = calloc(1, sizeof(prbs_set_t));
NR_SL_PSFCH_Config_r16_t *sl_psfch_config = mac->sl_tx_res_pool->sl_PSFCH_Config_r16->choice.setup;
const int sl_num_muxcs_pair[4] = {1, 2, 3, 6};
uint8_t sci2_src_id = mac->sci_pdu_rx.source_id;
uint8_t *rb_buf = sl_psfch_config->sl_PSFCH_RB_Set_r16->buf;
size_t size = sl_psfch_config->sl_PSFCH_RB_Set_r16->size / sizeof(rb_buf[0]);
uint8_t m_psfch_prb_set = count_on_bits(rb_buf, size);
long sl_numsubchannel = *mac->sl_tx_res_pool->sl_NumSubchannel_r16;
const uint8_t psfch_periods[] = {0,1,2,4};
long n_psfch_pssch = (sl_psfch_config->sl_PSFCH_Period_r16)
? psfch_periods[*sl_psfch_config->sl_PSFCH_Period_r16] : 0;
long n_psfch_cs = *sl_psfch_config->sl_NumMuxCS_Pair_r16;
double m_psfch_subch_slot = m_psfch_prb_set / (sl_numsubchannel * n_psfch_pssch);
// FIXME: Add second condition from spec. 38213 16.3, current implementation assuming single subchannel
long n_psfch_type = *sl_psfch_config->sl_PSFCH_CandidateResourceType_r16 ? sl_numsubchannel : 1;
uint16_t r_psfch_prb_cs = n_psfch_type * m_psfch_subch_slot * sl_num_muxcs_pair[n_psfch_cs];
uint8_t psfch_rsc_idx = (sci2_src_id + mac->src_id) / r_psfch_prb_cs;
LOG_D(NR_MAC, "sci2_src_id %d, UE id %d\n", sci2_src_id, mac->src_id);
LOG_D(NR_MAC, "size %lu, m_psfch_prb_set %d, sl_numsubchannel %ld, n_psfch_pssch %ld, n_psfch_cs %d\n", size, m_psfch_prb_set, sl_numsubchannel, n_psfch_pssch, sl_num_muxcs_pair[n_psfch_cs]);
LOG_D(NR_MAC, "m_psfch_subch_slot %f, n_psfch_type %ld, r_psfch_prb_cs %d, psfch_rsc_idx %d\n", m_psfch_subch_slot, n_psfch_type, r_psfch_prb_cs, psfch_rsc_idx);
psfch_params->m0 = table_16_3_1[n_psfch_cs][psfch_rsc_idx];
// 38213 16.3 Compute PRB allocation
psfch_params->prbs_sets->start_prb = (uint16_t**)calloc(n_psfch_pssch, sizeof(uint16_t*));
psfch_params->prbs_sets->end_prb = (uint16_t**)calloc(n_psfch_pssch, sizeof(uint16_t*));
for (int k=0; k<n_psfch_pssch; k++) {
psfch_params->prbs_sets->start_prb[k] = (uint16_t*)calloc(sl_numsubchannel, sizeof(uint16_t));
psfch_params->prbs_sets->end_prb[k] = (uint16_t*)calloc(sl_numsubchannel, sizeof(uint16_t));
}
for (int i = 0; i < n_psfch_pssch; i++) {
for (int j = 0; j < sl_numsubchannel; j++) {
psfch_params->prbs_sets->start_prb[i][j] = (i + j * n_psfch_pssch) * m_psfch_subch_slot;
psfch_params->prbs_sets->end_prb[i][j] = (i + 1 + j * n_psfch_pssch) * m_psfch_subch_slot - 1;
}
}
}
void configure_psfch_params_tx(int module_idP,
NR_UE_MAC_INST_t *mac,
sl_nr_rx_indication_t *rx_ind,
int pdu_id)
{
// TODO: May need to update in case of multiple UEs
const uint8_t psfch_periods[] = {0,1,2,4};
NR_SL_PSFCH_Config_r16_t *sl_psfch_config = mac->sl_tx_res_pool->sl_PSFCH_Config_r16->choice.setup;
long psfch_period = (sl_psfch_config->sl_PSFCH_Period_r16)
? psfch_periods[*sl_psfch_config->sl_PSFCH_Period_r16] : 0;
int scs = get_softmodem_params()->numerology;
uint16_t tx_slot = (rx_ind->slot + GET_DURATION_RX_TO_TX(&mac->ntn_ta, scs)) % nr_slots_per_frame[scs];
uint16_t tx_frame = (rx_ind->sfn + (rx_ind->slot + GET_DURATION_RX_TO_TX(&mac->ntn_ta, scs)) / nr_slots_per_frame[scs]) % 1024;
uint8_t ack_nack = (rx_ind->rx_indication_body + pdu_id)->rx_slsch_pdu.ack_nack;
LOG_D(NR_MAC, "tx_frame %4u.%2u, ack_nack %d rx: %4u.%2u\n", tx_frame, tx_slot, ack_nack, rx_ind->sfn, rx_ind->slot);
psfch_params_t *psfch_params = calloc(1, sizeof(psfch_params_t));
compute_params(module_idP, psfch_params);
const int nr_slots_frame = nr_slots_per_frame[scs];
int psfch_index = nr_ue_sl_acknack_scheduling(mac, rx_ind, psfch_period, tx_frame, tx_slot, nr_slots_frame);
if (psfch_index != -1)
fill_psfch_params_tx(mac, rx_ind, psfch_period, tx_frame, tx_slot, ack_nack, psfch_params, nr_slots_frame, psfch_index);
free(psfch_params);
psfch_params = NULL;
}
int get_psfch_index(const frame_structure_t *fs, int frame, int slot, int n_slots_frame, const NR_TDD_UL_DL_Pattern_t *tdd, int sched_psfch_max_size)
{
// PUCCH structures are indexed by slot in the PUCCH period determined by sched_psfch_max_size number of UL slots
// this functions return the index to the structure for slot passed to the function
const int first_ul_slot_period = tdd ? get_first_ul_slot(fs, false) : 0;
const int n_ul_slots_period = tdd ? tdd->nrofUplinkSlots + (tdd->nrofUplinkSymbols > 0 ? 1 : 0) : n_slots_frame;
const int nr_slots_period = tdd ? n_slots_frame / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity) : n_slots_frame;
const int n_ul_slots_frame = n_slots_frame / nr_slots_period * n_ul_slots_period;
// (frame * n_ul_slots_frame) adds up the number of UL slots in the previous frames
const int frame_start = frame * n_ul_slots_frame;
// ((slot / nr_slots_period) * n_ul_slots_period) adds up the number of UL slots in the previous TDD periods of this frame
const int ul_period_start = (slot / nr_slots_period) * n_ul_slots_period;
// ((slot % nr_slots_period) - first_ul_slot_period) gives the progressive number of the slot in this TDD period
const int ul_period_slot = (slot % nr_slots_period) - first_ul_slot_period;
// the sum gives the index of current UL slot in the frame which is normalized wrt sched_psfch_max_size
return (frame_start + ul_period_start + ul_period_slot) % sched_psfch_max_size;
}
int get_pssch_to_harq_feedback(uint8_t *pssch_to_harq_feedback, uint8_t psfch_min_time_gap, NR_TDD_UL_DL_Pattern_t *tdd, const int nr_slots_frame) {
int n_ul_slots_period = tdd ? tdd->nrofUplinkSlots + (tdd->nrofUplinkSymbols > 0 ? 1 : 0) : nr_slots_frame;
for (int i = 0; i < n_ul_slots_period; i++) {
pssch_to_harq_feedback[i] = psfch_min_time_gap + i + 1;
}
return n_ul_slots_period;
}
void get_csirs_to_csi_report(uint8_t *csirs_to_csi_report, uint8_t sl_latencyboundcsi_report, const int nr_slots_frame) {
for (int i = 0; i < sl_latencyboundcsi_report; i++)
csirs_to_csi_report[i] = i + 1;
}
int get_feedback_frame_slot(NR_UE_MAC_INST_t *mac, NR_TDD_UL_DL_Pattern_t *tdd,
uint8_t feedback_offset, uint8_t psfch_min_time_gap,
const int nr_slots_frame, uint16_t frame, uint16_t slot,
long psfch_period, int *psfch_frame, int *psfch_slot) {
AssertFatal(tdd != NULL, "Expecting valid tdd configurations");
const int first_ul_slot_period = tdd ? get_first_ul_slot(&mac->frame_structure, false) : 0;
const int nr_slots_period = tdd ? nr_slots_frame / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity) : nr_slots_frame;
// can't schedule ACKNACK before minimum feedback time
if(feedback_offset < psfch_min_time_gap)
return -1;
*psfch_slot = (slot + feedback_offset) % nr_slots_frame;
// check if the slot is UL
if(*psfch_slot % nr_slots_period < first_ul_slot_period)
return -1;
if (*psfch_slot % psfch_period > 0)
return -1;
*psfch_frame = (frame + ((slot + feedback_offset) / nr_slots_frame)) & 1023;
return 0;
}
int16_t get_feedback_slot(long psfch_period, uint16_t slot) {
int16_t feedback_slot = -1;
if (psfch_period == 1) {
switch(slot) {
case 0:
feedback_slot = 6;
break;
case 1:
feedback_slot = 7;
break;
case 2:
feedback_slot = 8;
break;
case 3:
feedback_slot = 9;
break;
case 10:
feedback_slot = 16;
break;
case 11:
feedback_slot = 17;
break;
case 12:
feedback_slot = 18;
break;
case 13:
feedback_slot = 19;
break;
default:
AssertFatal(1 == 0, "Invalid slot %d\n", slot);
}
} else if (psfch_period == 2) {
switch(slot) {
case 0:
case 1:
feedback_slot = 7;
break;
case 2:
case 3:
feedback_slot = 9;
break;
case 10:
case 11:
feedback_slot = 17;
break;
case 12:
case 13:
feedback_slot = 19;
break;
default:
AssertFatal(1 == 0, "Invalid slot %d\n", slot);
}
} else if (psfch_period == 4) {
switch(slot) {
case 0:
case 1:
case 2:
case 3:
feedback_slot = 9;
break;
case 10:
case 11:
case 12:
case 13:
feedback_slot = 19;
break;
default:
AssertFatal(1 == 0, "Invalid slot %d\n", slot);
}
}
return feedback_slot;
}
int nr_ue_sl_acknack_scheduling(NR_UE_MAC_INST_t *mac, sl_nr_rx_indication_t *rx_ind,
long psfch_period, uint16_t frame, uint16_t slot, const int nr_slots_frame) {
// TODO: needs to be updated for multi-subchannels
int psfch_frame, psfch_slot;
sl_nr_ue_mac_params_t *sl_mac = mac->SL_MAC_PARAMS;
NR_TDD_UL_DL_Pattern_t *tdd = &sl_mac->sl_TDD_config->pattern1;
const int n_ul_slots_period = tdd ? tdd->nrofUplinkSlots + (tdd->nrofUplinkSymbols > 0 ? 1 : 0) : nr_slots_frame;
uint16_t num_subch = sl_get_num_subch(mac->sl_tx_res_pool);
int n_ul_buf_max_size = n_ul_slots_period * num_subch;
psfch_slot = get_feedback_slot(psfch_period, slot);
const int psfch_index = get_psfch_index(&mac->frame_structure, rx_ind->sfn, rx_ind->slot, nr_slots_frame, tdd, n_ul_buf_max_size);
NR_SL_UE_sched_ctrl_t *sched_ctrl = &mac->sl_info.list[0]->UE_sched_ctrl;
SL_sched_feedback_t *curr_psfch = &sched_ctrl->sched_psfch[psfch_index];
psfch_frame = frame;
frameslot_t fs;
fs.frame = psfch_frame;
fs.slot = psfch_slot;
uint8_t pool_id = 0;
uint64_t tx_abs_slot = normalize(&fs, get_softmodem_params()->numerology);
SL_ResourcePool_params_t *sl_tx_rsrc_pool = sl_mac->sl_TxPool[pool_id];
size_t phy_map_sz = (sl_tx_rsrc_pool->phy_sl_bitmap.size << 3) - sl_tx_rsrc_pool->phy_sl_bitmap.bits_unused;
bool sl_has_psfch = slot_has_psfch(mac, &sl_tx_rsrc_pool->phy_sl_bitmap, tx_abs_slot, psfch_period, phy_map_sz, mac->SL_MAC_PARAMS->sl_TDD_config);
LOG_D(NR_MAC, "%s %4d.%2d sl_has_psfch %d\n", __FUNCTION__, psfch_frame, psfch_slot, sl_has_psfch);
curr_psfch->feedback_frame = psfch_frame;
curr_psfch->feedback_slot = psfch_slot;
curr_psfch->dai_c = psfch_index;
LOG_D(NR_MAC, "Rx SLSCH %4d.%2d, SL_ACK %4d.%2d in current PSFCH: psfch_index %d, n_ul_slots_period %d dai_c %u curr_psfch %p\n",
rx_ind->sfn,
rx_ind->slot,
psfch_frame,
psfch_slot,
psfch_index,
n_ul_slots_period,
curr_psfch->dai_c,
curr_psfch);
LOG_D(NR_MAC, "SL %4d.%2d, Couldn't find scheduling occasion for this HARQ process\n", rx_ind->sfn, rx_ind->slot);
return psfch_index;
}
void fill_psfch_params_tx(NR_UE_MAC_INST_t *mac, sl_nr_rx_indication_t *rx_ind,
long psfch_period, uint16_t frame, uint16_t slot,
uint8_t ack_nack, psfch_params_t *psfch_params,
const int nr_slots_frame, int psfch_index) {
NR_SL_BWP_Generic_r16_t *sl_bwp = mac->sl_bwp->sl_BWP_Generic_r16;
SL_sched_feedback_t *sched_psfch = &mac->sl_info.list[0]->UE_sched_ctrl.sched_psfch[psfch_index];
LOG_D(NR_MAC, "psfch_period %ld, feedback frame:slot %d:%d, frame:slot %d:%d, harq feedback %d psfch_index %d\n",
psfch_period,
sched_psfch->feedback_frame,
sched_psfch->feedback_slot,
rx_ind->sfn,
rx_ind->slot,
mac->sci_pdu_rx.harq_feedback,
psfch_index);
sched_psfch->initial_cyclic_shift = psfch_params->m0;
if ((mac->sci1_pdu.second_stage_sci_format == 0 && (mac->sci_pdu_rx.cast_type == 1 ||
mac->sci_pdu_rx.cast_type == 2)) || mac->sci1_pdu.second_stage_sci_format == 2) {
sched_psfch->mcs = sequence_cyclic_shift_harq_ack_or_ack_or_only_nack[ack_nack];
sched_psfch->bit_len_harq = 1;
LOG_D(NR_MAC, "mcs %i, ack_nack: %i, sched_psfch->initial_cyclic_shift %i\n",
sched_psfch->mcs, ack_nack, sched_psfch->initial_cyclic_shift);
} else if (mac->sci1_pdu.second_stage_sci_format == 1 ||
(mac->sci1_pdu.second_stage_sci_format == 0 && mac->sci_pdu_rx.cast_type == 3)) {
sched_psfch->mcs = sequence_cyclic_shift_harq_ack_or_ack_or_only_nack[0];
sched_psfch->bit_len_harq = 0;
}
const uint8_t values[] = {7, 8, 9, 10, 11, 12, 13, 14};
uint8_t sl_num_symbols = *sl_bwp->sl_LengthSymbols_r16 ? values[*sl_bwp->sl_LengthSymbols_r16] : 0;
// start_symbol_index has been used as lprime check 38.213 16.3
sched_psfch->start_symbol_index = *sl_bwp->sl_StartSymbol_r16 + sl_num_symbols - 2;
LOG_D(NR_PHY, "sl_StartSymbol_r16 %ld, sl_num_symbols: %d, start sym index %d, mcs %d\n",
*sl_bwp->sl_StartSymbol_r16, sl_num_symbols, sched_psfch->start_symbol_index, sched_psfch->mcs);
sched_psfch->hopping_id = *mac->sl_bwp->sl_BWP_PoolConfigCommon_r16->sl_TxPoolSelectedNormal_r16->list.array[0]->sl_ResourcePool_r16->sl_PSFCH_Config_r16->choice.setup->sl_PSFCH_HopID_r16;
sched_psfch->prb = psfch_params->prbs_sets->start_prb[rx_ind->slot % psfch_period][0]; // FIXME [0] is based on assumption of number of subchannels = 1; 0 is channel id
print_prb_set_allocation(psfch_params, psfch_period, 1);
LOG_D(NR_PHY, "slot %d, slot mode psfch_period %ld, sched_psfch->prb %d, start_prb %d\n",
rx_ind->slot, rx_ind->slot%psfch_period, sched_psfch->prb,
psfch_params->prbs_sets->start_prb[rx_ind->slot%psfch_period][0]);
int locbw = sl_bwp->sl_BWP_r16->locationAndBandwidth;
sched_psfch->sl_bwp_start = NRRIV2PRBOFFSET(locbw, MAX_BWP_SIZE);
sched_psfch->freq_hop_flag = 0;
sched_psfch->group_hop_flag = 0;
sched_psfch->second_hop_prb = 0;
sched_psfch->sequence_hop_flag = 0;
sched_psfch->harq_feedback = mac->sci_pdu_rx.harq_feedback;
LOG_D(NR_MAC, "Filled psfch pdu\n");
}
int find_current_slot_harqs(frame_t frame, sub_frame_t slot, NR_SL_UE_sched_ctrl_t * sched_ctrl, NR_UE_sl_harq_t **matched_harqs)
{
int cur = sched_ctrl->feedback_sl_harq.head;
int k = 0;
while (cur != -1) {
NR_UE_sl_harq_t *harq = &sched_ctrl->sl_harq_processes[cur];
LOG_D(NR_MAC, "%s %4d.%2d feedback %4d.%2d\n", __FUNCTION__, frame, slot, harq->feedback_frame, harq->feedback_slot);
if (harq->feedback_frame == frame && harq->feedback_slot == slot) {
if (matched_harqs) {
matched_harqs[k] = harq;
LOG_D(NR_MAC, "%s matched_harqs[%d] %4d.%2d %d slot %d\n",
__FUNCTION__,
k,
matched_harqs[k]->feedback_frame,
matched_harqs[k]->feedback_slot,
matched_harqs[k]->sl_harq_pid,
matched_harqs[k]->sched_pssch.slot);
}
k++;
}
cur = sched_ctrl->feedback_sl_harq.next[cur];
}
return k;
}
/*
Following function is used to remove the harq_pids from the feedback list;
Adds back to available list or retransmission list based on round value.
*/
void update_harq_lists(NR_UE_MAC_INST_t *mac, frame_t frame, sub_frame_t slot, NR_SL_UE_info_t* UE)
{
NR_SL_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
int cur = sched_ctrl->feedback_sl_harq.head;
while (cur != -1) {
NR_UE_sl_harq_t *harq = &sched_ctrl->sl_harq_processes[cur];
if ((harq->feedback_frame < frame
|| (harq->feedback_frame == frame && harq->feedback_slot < slot))) {
remove_nr_list(&sched_ctrl->feedback_sl_harq, cur);
harq->feedback_slot = -1;
harq->is_waiting = false;
if (harq->round >= HARQ_ROUND_MAX - 1) {
abort_nr_ue_sl_harq(mac, cur, UE);
} else {
add_tail_nr_list(&sched_ctrl->retrans_sl_harq, cur);
harq->round++;
}
}
cur = sched_ctrl->feedback_sl_harq.next[cur];
}
}
void configure_psfch_params_rx(int module_idP,
NR_UE_MAC_INST_t *mac,
sl_nr_rx_config_request_t *rx_config)
{
const uint16_t slot = rx_config->slot;
frame_t frame = rx_config->sfn;
const uint8_t psfch_periods[] = {0,1,2,4};
NR_SL_PSFCH_Config_r16_t *sl_psfch_config = mac->sl_rx_res_pool->sl_PSFCH_Config_r16->choice.setup;
long psfch_period = (sl_psfch_config->sl_PSFCH_Period_r16)
? psfch_periods[*sl_psfch_config->sl_PSFCH_Period_r16] : 0;
uint16_t num_subch = sl_get_num_subch(mac->sl_rx_res_pool);
rx_config->sl_rx_config_list[0].rx_psfch_pdu_list = calloc(psfch_period*num_subch, sizeof(sl_nr_tx_rx_config_psfch_pdu_t));
NR_SL_UEs_t *UE_info = &mac->sl_info;
if (*(UE_info->list) == NULL) {
LOG_D(NR_MAC, "UE list is empty\n");
return;
}
psfch_params_t *psfch_params = calloc(1, sizeof(psfch_params_t));
compute_params(module_idP, psfch_params);
SL_UE_iterator(UE_info->list, UE) {
NR_SL_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
NR_UE_sl_harq_t **matched_harqs = (NR_UE_sl_harq_t **) calloc(sched_ctrl->feedback_sl_harq.len, sizeof(NR_UE_sl_harq_t *));
int matched_sz = find_current_slot_harqs(frame, slot, sched_ctrl, matched_harqs);
LOG_D(NR_MAC, "%s matched_sz %d\n", __FUNCTION__, matched_sz);
rx_config->sl_rx_config_list[0].num_psfch_pdus = 0;
for (int i = 0; i < matched_sz; i++) {
AssertFatal(i < UE->UE_sched_ctrl.feedback_sl_harq.len, "k MUST be smaller than feedback_sl_harq length\n");
AssertFatal(i < (psfch_period * num_subch), "k MUST be smaller than %ld\n", (psfch_period * num_subch));
NR_UE_sl_harq_t *cur_harq = matched_harqs[i];
sl_nr_tx_rx_config_psfch_pdu_t *psfch_pdu = &rx_config->sl_rx_config_list[0].rx_psfch_pdu_list[i];
fill_psfch_params_rx(rx_config, psfch_pdu, psfch_params, cur_harq, mac, psfch_period, slot);
}
free(matched_harqs);
matched_harqs = NULL;
}
}
void fill_psfch_params_rx(sl_nr_rx_config_request_t *rx_config, sl_nr_tx_rx_config_psfch_pdu_t *psfch_pdu, psfch_params_t *psfch_params, NR_UE_sl_harq_t *cur_harq, NR_UE_MAC_INST_t *mac, long psfch_period, const uint16_t slot) {
rx_config->sl_rx_config_list[0].num_psfch_pdus++;
psfch_pdu->initial_cyclic_shift = psfch_params->m0;
LOG_D(NR_MAC, "psfch_pdu->initial_cyclic_shift %i\n", psfch_pdu->initial_cyclic_shift);
const uint8_t values[] = {7, 8, 9, 10, 11, 12, 13, 14};
NR_SL_BWP_Generic_r16_t *sl_bwp = mac->sl_bwp->sl_BWP_Generic_r16;
uint8_t sl_num_symbols = *sl_bwp->sl_LengthSymbols_r16 ? values[*sl_bwp->sl_LengthSymbols_r16] : 0;
// start_symbol_index has been used as lprime check 38.213 16.3
psfch_pdu->start_symbol_index = *sl_bwp->sl_StartSymbol_r16 + sl_num_symbols - 2;
LOG_D(NR_PHY, "Rx sl_StartSymbol_r16 %ld, sl_num_symbols: %d, start sym index %d, mcs %d\n", *sl_bwp->sl_StartSymbol_r16, sl_num_symbols, psfch_pdu->start_symbol_index, psfch_pdu->mcs);
psfch_pdu->hopping_id = *mac->sl_bwp->sl_BWP_PoolConfigCommon_r16->sl_TxPoolSelectedNormal_r16->list.array[0]->sl_ResourcePool_r16->sl_PSFCH_Config_r16->choice.setup->sl_PSFCH_HopID_r16;
uint8_t index = cur_harq->sched_pssch.slot%psfch_period;
psfch_pdu->prb = psfch_params->prbs_sets->start_prb[index][0]; // FIXME [0] is based on assumption of number of subchannels = 1; 0 is channel id
print_prb_set_allocation(psfch_params, psfch_period, 1);
LOG_D(NR_PHY, "Rx slot %d, slsch tx slot %d, tx slot mode psfch_period %d, start_prb %d\n", slot, cur_harq->sched_pssch.slot, index, psfch_params->prbs_sets->start_prb[index][0]);
int locbw = sl_bwp->sl_BWP_r16->locationAndBandwidth;
psfch_pdu->sl_bwp_start = NRRIV2PRBOFFSET(locbw, MAX_BWP_SIZE);
psfch_pdu->freq_hop_flag = 0;
psfch_pdu->group_hop_flag = 0;
psfch_pdu->second_hop_prb = 0;
psfch_pdu->sequence_hop_flag = 0;
psfch_pdu->bit_len_harq = 1;
int num_psfch_symbols = 0;
if (psfch_period == 1) num_psfch_symbols = 3;
else if (psfch_period == 2 || psfch_period == 4) {
num_psfch_symbols = mac->SL_MAC_PARAMS->sl_RxPool[0]->sci_1a.psfch_overhead_indication.nbits ? 3 : 0;
}
psfch_pdu->nr_of_symbols = num_psfch_symbols ? num_psfch_symbols - 2 : 0; // (num_psfch_symbols - 2) excludes PSFCH AGC and Guard
rx_config->sl_rx_config_list[0].pdu_type = SL_NR_CONFIG_TYPE_RX_PSFCH;
LOG_D(NR_PHY, "%s start_symbol_index %d, sl_bwp_start %d, sequence_hop_flag %d, \
second_hop_prb %d, prb %d, nr_of_symbols %d, initial_cyclic_shift %d, hopping_id %d, \
group_hop_flag %d, freq_hop_flag %d, bit_len_harq %d----> Setting pdu type SL_NR_CONFIG_TYPE_RX_PSFCH \n",
__FUNCTION__,
psfch_pdu->start_symbol_index, psfch_pdu->sl_bwp_start,
psfch_pdu->sequence_hop_flag, psfch_pdu->second_hop_prb, psfch_pdu->prb,
psfch_pdu->nr_of_symbols, psfch_pdu->initial_cyclic_shift, psfch_pdu->hopping_id,
psfch_pdu->group_hop_flag, psfch_pdu->freq_hop_flag, psfch_pdu->bit_len_harq);
}
void set_csi_report_params(NR_UE_MAC_INST_t* mac, NR_SL_UE_sched_ctrl_t *sched_ctrl) {
SL_CSI_Report_t *csi_report = &sched_ctrl->sched_csi_report;
csi_report->cqi = mac->csirs_measurements.cqi;
csi_report->ri = mac->csirs_measurements.ri;
}
uint8_t sl_num_slsch_feedbacks(NR_UE_MAC_INST_t *mac) {
sl_nr_ue_mac_params_t *sl_mac = mac->SL_MAC_PARAMS;
NR_TDD_UL_DL_Pattern_t *tdd = &sl_mac->sl_TDD_config->pattern1;
uint8_t scs = sl_mac->sl_phy_config.sl_config_req.sl_bwp_config.sl_scs;
const int nr_slots_frame = nr_slots_per_frame[scs];
const int n_ul_slots_period = tdd ? tdd->nrofUplinkSlots + (tdd->nrofUplinkSymbols > 0 ? 1 : 0) : nr_slots_frame;
uint16_t num_subch = sl_get_num_subch(mac->sl_tx_res_pool);
return n_ul_slots_period * num_subch;
}
bool is_feedback_scheduled(NR_UE_MAC_INST_t *mac, int frameP,int slotP) {
for (int i = 0; i < sl_num_slsch_feedbacks(mac); i++) {
SL_sched_feedback_t *sched_psfch = &mac->sl_info.list[0]->UE_sched_ctrl.sched_psfch[i];
LOG_D(NR_MAC, "frame.slot %4d.%2d, harq_feedback %d\n", frameP, slotP, sched_psfch->harq_feedback);
if (frameP == sched_psfch->feedback_frame && slotP == sched_psfch->feedback_slot && sched_psfch->harq_feedback) {
return true;
}
}
return false;
}
void reset_sched_psfch(NR_UE_MAC_INST_t *mac, int frameP,int slotP) {
for (int i = 0; i < sl_num_slsch_feedbacks(mac); i++) {
SL_sched_feedback_t *sched_psfch = &mac->sl_info.list[0]->UE_sched_ctrl.sched_psfch[i];
if (frameP == sched_psfch->feedback_frame && slotP == sched_psfch->feedback_slot) {
sched_psfch->feedback_frame = -1;
sched_psfch->feedback_slot = -1;
sched_psfch->harq_feedback = 0;
}
}
}
void nr_ue_process_mac_sl_pdu(int module_idP,
sl_nr_rx_indication_t *rx_ind,
int pdu_id)
{
int8_t pdu_type = (rx_ind->rx_indication_body + pdu_id)->pdu_type;
sl_nr_slsch_pdu_t *rx_slsch_pdu = &(rx_ind->rx_indication_body + pdu_id)->rx_slsch_pdu;
uint8_t *pduP = rx_slsch_pdu->pdu;
int32_t pdu_len = (int32_t)rx_slsch_pdu->pdu_length;
uint8_t done = 0;
NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
int frame = rx_ind->sfn;
int slot = rx_ind->slot;
if (!pduP){
return;
}
NR_SLSCH_MAC_SUBHEADER_FIXED *sl_sch_subheader = (NR_SLSCH_MAC_SUBHEADER_FIXED *) pduP;
uint8_t psfch_period = 0;
if (mac->sl_tx_res_pool->sl_PSFCH_Config_r16 &&
mac->sl_tx_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_PSFCH_Period_r16)
psfch_period = *mac->sl_tx_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_PSFCH_Period_r16;
if (psfch_period && mac->sci_pdu_rx.harq_feedback) {
configure_psfch_params_tx(module_idP, mac, rx_ind, pdu_id);
}
NR_SL_UE_info_t *UE = find_UE(mac, sl_sch_subheader->SRC);
if (UE == NULL)
return;
if (pdu_type == SL_NR_RX_PDU_TYPE_SLSCH_PSFCH) {
handle_nr_ue_sl_harq(module_idP, frame, slot, rx_slsch_pdu, sl_sch_subheader->SRC);
int r0 = UE->mac_sl_stats.cumul_round[0];
int r1 = UE->mac_sl_stats.cumul_round[1];
int r2 = UE->mac_sl_stats.cumul_round[2];
int r3 = UE->mac_sl_stats.cumul_round[3];
int r4 = UE->mac_sl_stats.cumul_round[4];
int round_sum = r1 + 2 * r2 + 3 * r3 + 4 * r4;
int total_tx = r0 + round_sum;
if (total_tx % 20 == 0 || (total_tx > 299 && total_tx < 305)) {
LOG_I(NR_PHY, "[UE] %d:%d PSFCH Stats: RX round (%u %u %u %u %u), SumRetx %u TotalTx %u\n",
frame, slot,
UE->mac_sl_stats.cumul_round[0],
UE->mac_sl_stats.cumul_round[1],
UE->mac_sl_stats.cumul_round[2],
UE->mac_sl_stats.cumul_round[3],
UE->mac_sl_stats.cumul_round[4],
round_sum, total_tx
);
}
}
LOG_D(NR_MAC, "%4d.%2d ack_nack %d pdu_type %d mac->sci_pdu_rx.csi_req %d\n",
frame, slot, rx_slsch_pdu->ack_nack, pdu_type, mac->sci_pdu_rx.csi_req);
if (rx_slsch_pdu->ack_nack == 0)
return;
NR_SL_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
if (mac->sci_pdu_rx.csi_req) {
LOG_D(NR_MAC, "%4d.%2d Configuring sl_csi_report parameters\n", frame, slot);
int scs = get_softmodem_params()->numerology;
uint16_t tx_slot = (rx_ind->slot + GET_DURATION_RX_TO_TX(&mac->ntn_ta, scs)) % nr_slots_per_frame[scs];
uint16_t tx_frame = (rx_ind->sfn + (rx_ind->slot + GET_DURATION_RX_TO_TX(&mac->ntn_ta, scs)) / nr_slots_per_frame[scs]) % 1024;
set_csi_report_params(mac, sched_ctrl);
nr_ue_sl_csi_report_scheduling(module_idP,
sched_ctrl,
tx_frame,
tx_slot);
}
LOG_D(NR_MAC, "In %s : processing PDU %d (with length %d) of %d total number of PDUs...\n", __FUNCTION__, pdu_id, pdu_len, rx_ind->number_pdus);
LOG_D(NR_PHY, "%4d.%2d Rx V %d R %d SRC %d DST %d\n", frame, slot, sl_sch_subheader->V, sl_sch_subheader->R, sl_sch_subheader->SRC, sl_sch_subheader->DST);
pduP += sizeof(*sl_sch_subheader);
pdu_len -= sizeof(*sl_sch_subheader);
if (frame % 20 == 0)
LOG_D(NR_PHY, "%4d.%2d Rx V %d R %d SRC %d DST %d\n", frame, slot, sl_sch_subheader->V, sl_sch_subheader->R, sl_sch_subheader->SRC, sl_sch_subheader->DST);
while (!done && pdu_len > 0) {
uint16_t mac_len = 0x0000;
uint16_t mac_subheader_len = 0x0001; // default to fixed-length subheader = 1-oct
uint8_t rx_lcid = ((NR_MAC_SUBHEADER_FIXED *)(pduP))->LCID;
LOG_D(NR_MAC, "[UE %x] LCID %d, remaining pdu length %d byte(s)\n", mac->src_id, rx_lcid, pdu_len);
switch (rx_lcid) {
// MAC CE
case SL_SCH_LCID_4_19:
if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
return;
LOG_D(NR_MAC, "%4d.%2d : SLSCH -> LCID %d %d bytes with subheader %d\n", frame, slot, rx_lcid, mac_len, mac_subheader_len);
#if 0
mac_rlc_data_ind(module_idP,
mac->src_id,
0,
frame,
ENB_FLAG_NO,
MBMS_FLAG_NO,
rx_lcid,
(char *)(pduP + mac_subheader_len),
mac_len,
1,
NULL);
#endif
nr_mac_rlc_data_ind(mac->ue_id, mac->src_id, false, rx_lcid, (char *)(pduP + mac_subheader_len), mac_len);
break;
case SL_SCH_LCID_SL_CSI_REPORT:
{
NR_MAC_SUBHEADER_FIXED* sub_pdu_header = (NR_MAC_SUBHEADER_FIXED*) pduP;
if (frame % 20 == 0)
LOG_D(NR_MAC, "\tLCID: %i, R: %i\n", sub_pdu_header->LCID, sub_pdu_header->R);
mac_subheader_len = sizeof(*sub_pdu_header);
nr_sl_csi_report_t* nr_sl_csi_report = (nr_sl_csi_report_t *) (pduP + mac_len);
mac_len = sizeof(*nr_sl_csi_report);
if (frame % 20 == 0)
LOG_D(NR_MAC, "\tCQI: %i RI: %i\n", nr_sl_csi_report->CQI, nr_sl_csi_report->RI);
sched_ctrl->rx_csi_report.CQI = nr_sl_csi_report->CQI;
sched_ctrl->rx_csi_report.RI = nr_sl_csi_report->RI;
LOG_D(NR_MAC, "Setting to CQI %i\n", sched_ctrl->rx_csi_report.CQI);
break;
}
case SL_SCH_LCID_SL_PADDING:
{
NR_MAC_SUBHEADER_FIXED* sub_pdu_header = (NR_MAC_SUBHEADER_FIXED*) pduP;
mac_subheader_len = sizeof(*sub_pdu_header);
mac_len = pdu_len - mac_subheader_len;
LOG_D(NR_MAC, "%4d.%2d Received padding %d\n", frame, slot, pdu_len);
done = 1;
break;
}
case SL_SCH_LCID_SCCH_PC5_NOT_PROT:
case SL_SCH_LCID_SCCH_PC5_DSMC:
case SL_SCH_LCID_SCCH_PC5_PROT:
case SL_SCH_LCID_SCCH_PC5_RRC:
case SL_SCH_LCID_20_55:
case SL_SCH_LCID_SCCH_RRC_SL_RLC0:
case SL_SCH_LCID_SCCH_RRC_SL_RLC1:
case SL_SCH_LCID_SCCH_SL_DISCOVERY:
case SL_SCH_LCID_SL_INTER_UE_COORD_REQ:
case SL_SCH_LCID_SL_INTER_UE_COORD_INFO:
case SL_SCH_LCID_SL_DRX_CMD:
LOG_W(NR_MAC,"Received unsupported SL LCID %d\n",rx_lcid);
return;
break;
}
pduP += ( mac_subheader_len + mac_len );
pdu_len -= ( mac_subheader_len + mac_len );
LOG_D(NR_MAC, "mac_subhead_len + mac_len = %d\n", mac_subheader_len + mac_len);
LOG_D(NR_MAC, "%4d.%2d : SLSCH -> LCID %d remaining pdu length %d byte(s)\n", frame, slot, rx_lcid, pdu_len);
if (pdu_len < 0)
LOG_E(NR_MAC, "[UE %d][%d.%d] nr_ue_process_mac_pdu_sl, residual mac pdu length %d < 0!\n", module_idP, frame, slot, pdu_len);
}
}
void nr_ue_sl_csi_report_scheduling(int mod_id,
NR_SL_UE_sched_ctrl_t *sched_ctrl,
uint32_t frame,
uint32_t slot) {
uint32_t sched_slot, sched_frame;
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
sl_nr_ue_mac_params_t *sl_mac = mac->SL_MAC_PARAMS;
NR_TDD_UL_DL_Pattern_t *tdd = &sl_mac->sl_TDD_config->pattern1;
if (sched_ctrl->sched_csi_report.active == false) {
uint8_t scs = sl_mac->sl_phy_config.sl_config_req.sl_bwp_config.sl_scs;
const int nr_slots_frame = nr_slots_per_frame[scs];
uint8_t csirs_to_csi_report[sl_mac->sl_LatencyBoundCSI_Report];
get_csirs_to_csi_report(csirs_to_csi_report, sl_mac->sl_LatencyBoundCSI_Report, nr_slots_frame);
int continue_flag = 0;
for (int f = 0; f < sl_mac->sl_LatencyBoundCSI_Report; f++) {
continue_flag = get_csi_reporting_frame_slot(mac,
tdd,
csirs_to_csi_report[f],
nr_slots_frame,
frame,
slot,
&sched_frame,
&sched_slot);
if (continue_flag == -1)
continue;
else
break;
}
LOG_D(NR_MAC, "%4d.%2d Scheduling csi_report\n", sched_frame, sched_slot);
SL_CSI_Report_t *csi_report = &sched_ctrl->sched_csi_report;
csi_report->frame = sched_frame;
csi_report->slot = sched_slot;
csi_report->active = true;
}
}
NR_SL_UE_info_t* find_UE(NR_UE_MAC_INST_t *mac,
uint16_t nearby_ue_id) {
NR_SL_UEs_t *UE_info = &mac->sl_info;
if (*(UE_info->list) == NULL) {
LOG_D(NR_MAC, "UE list is empty\n");
return NULL;
}
SL_UE_iterator(UE_info->list, UE) {
LOG_D(NR_MAC, "%s: dest_id %d nearby id %d\n", __FUNCTION__, UE->uid, nearby_ue_id);
if((UE->uid == nearby_ue_id)) {
return UE;
}
}
return NULL;
}
int get_csi_reporting_frame_slot(NR_UE_MAC_INST_t *mac,
NR_TDD_UL_DL_Pattern_t *tdd,
uint8_t csi_offset,
const int nr_slots_frame,
uint32_t frame,
uint32_t slot,
uint32_t *csi_report_frame,
uint32_t *csi_report_slot) {
AssertFatal(tdd != NULL, "Expecting valid tdd configurations");
const int first_ul_slot_period = tdd ? get_first_ul_slot(&mac->frame_structure, false) : 0;
const int nr_slots_period = tdd ? nr_slots_frame / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity) : nr_slots_frame;
*csi_report_slot = (slot + csi_offset) % nr_slots_frame;
// check if the slot is UL
if(*csi_report_slot % nr_slots_period < first_ul_slot_period)
return -1;
*csi_report_frame = (frame + ((slot + csi_offset) / nr_slots_frame)) & 1023;
return 0;
}
void init_list(List_t* list, size_t element_size, size_t initial_capacity) {
list->data = calloc(1, element_size * initial_capacity);
list->element_size = element_size;
list->size = 0;
list->capacity = initial_capacity;
}
void push_back(List_t* list, void *element) {
if (list->size == list->capacity) {
list->capacity *= 2;
list->data = realloc(list->data, list->element_size * list->capacity);
}
void *target = (char*)list->data + (list->size * list->element_size);
memcpy(target, element, list->element_size);
list->size++;
}
void* get_front(const List_t* list) {
if (list->size == 0) {
return NULL;
}
return list->data; // pointer to first element
}
void* get_back(const List_t* list) {
if (list->size == 0) {
return NULL;
}
return (char*)list->data + (list->size - 1) * list->element_size; // pointer to last element
}
void delete_at(List_t* list, size_t index) {
if (index >= list->size) {
LOG_E(NR_MAC, "Index of bound\n");
return;
}
char* element_ptr = (char*)list->data + index * list->element_size;
memmove(element_ptr, element_ptr + list->element_size, (list->size - index - 1) * list->element_size);
list->size--;
}
int64_t normalize(frameslot_t *frame_slot, uint8_t mu) {
int64_t num_slots = 0;
uint8_t slots_per_frame = nr_slots_per_frame[mu];
num_slots = frame_slot->slot;
num_slots += frame_slot->frame * slots_per_frame;
return num_slots;
}
void de_normalize(int64_t abs_slot_idx, uint8_t mu, frameslot_t *frame_slot) {
uint8_t slots_per_frame = nr_slots_per_frame[mu];
frame_slot->frame = (abs_slot_idx / slots_per_frame) & 1023;
frame_slot->slot = (abs_slot_idx % slots_per_frame);
}
frameslot_t add_to_sfn(frameslot_t* sfn, uint16_t slot_n, uint8_t mu) {
frameslot_t temp_sfn;
temp_sfn.frame = (sfn->frame + ((sfn->slot + slot_n) / nr_slots_per_frame[mu])) % 1024;
temp_sfn.slot = (sfn->slot + slot_n) % nr_slots_per_frame[mu];
return temp_sfn;
}
void update_sensing_data(List_t* sensing_data, frameslot_t *frame_slot, sl_nr_ue_mac_params_t *sl_mac, uint16_t pool_id) {
uint8_t mu = sl_mac->sl_phy_config.sl_config_req.sl_bwp_config.sl_scs;
int64_t num_max_slots = nr_slots_per_frame[mu] * 1024;
while(sensing_data->size > 0) {
sensing_data_t* last_elem = (sensing_data_t*)((char*)sensing_data->data + (sensing_data->size - 1) * sensing_data->element_size);
int64_t diff = (normalize(frame_slot, mu) - normalize(&last_elem->frame_slot, mu) + num_max_slots) % num_max_slots;
if (diff <= get_tproc0(sl_mac, pool_id)) {
pop_back(sensing_data);
} else {
break;
}
}
}
void update_transmit_history(List_t* transmit_history, frameslot_t *frame_slot, sl_nr_ue_mac_params_t *sl_mac, uint16_t pool_id) {
uint8_t mu = sl_mac->sl_phy_config.sl_config_req.sl_bwp_config.sl_scs;
int64_t num_max_slots = nr_slots_per_frame[mu] * 1024;
while(transmit_history->size > 0) {
frameslot_t* last_frame_slot = (frameslot_t*)((uint8_t*)transmit_history->data + (transmit_history->size - 1) * transmit_history->element_size);
int64_t diff = (normalize(frame_slot, mu) - normalize(last_frame_slot, mu) + num_max_slots) % num_max_slots;
if (diff <= get_tproc0(sl_mac, pool_id)) {
pop_back(transmit_history);
} else {
break;
}
}
}
void pop_back(List_t* sensing_data) {
if(sensing_data->size > 0) {
sensing_data->size--;
}
}
void free_list_mem(List_t* list) {
free(list->data);
list->data = NULL;
list->size = 0;
list->capacity = 0;
}
uint16_t get_T2_min(uint16_t pool_id, sl_nr_ue_mac_params_t *sl_mac, uint8_t mu) {
uint16_t t2min = sl_mac->sl_TxPool[pool_id]->t2min * pow(2, mu);
return t2min;
}
uint16_t get_t2(uint16_t pool_id, uint8_t mu, nr_sl_transmission_params_t* sl_tx_params, sl_nr_ue_mac_params_t *sl_mac) {
uint16_t t2;
if (!(sl_tx_params->packet_delay_budget_ms == 0)) {
// Packet delay budget is known, so use it
uint16_t pdb_slots = time_to_slots(mu, sl_tx_params->packet_delay_budget_ms);
t2 = min(pdb_slots, sl_mac->sl_TxPool[pool_id]->t2);
} else {
// Packet delay budget is not known, so use max(NrSlUeMac::T2, T2min)
uint16_t t2min = get_T2_min(pool_id, sl_mac, mu);
t2 = max(t2min, sl_mac->sl_TxPool[pool_id]->t2);
}
return t2;
}
uint16_t time_to_slots(uint8_t mu, uint16_t time) {
uint8_t slots_per_ms = (uint8_t)pow(2, mu); // subframe is of 1 ms
uint16_t time_in_slots = time * slots_per_ms;
return time_in_slots;
}
uint8_t get_tproc0(sl_nr_ue_mac_params_t *sl_mac, uint16_t pool_id) {
return sl_mac->sl_TxPool[pool_id]->tproc0;
}
void init_vector(vec_of_list_t* vec, size_t initial_capacity) {
vec->size = 0;
vec->capacity = initial_capacity;
vec->lists = (List_t*)malloc16_clear(initial_capacity * sizeof(List_t));
if (!vec->lists) {
LOG_E(NR_MAC, "Memory allocation failed\n");
exit(EXIT_FAILURE);
}
}
void add_list(vec_of_list_t* vec, size_t element_size, size_t initial_list_capacity) {
if (vec->size == vec->capacity) {
vec->capacity *= 2;
vec->lists = realloc(vec->lists, vec->capacity * sizeof(List_t));
if (!vec->lists) {
LOG_E(NR_MAC, "Memory allocation failed\n");
exit(EXIT_FAILURE);
}
}
init_list(&vec->lists[vec->size], element_size, initial_list_capacity);
vec->size++;
}
void push_back_list(vec_of_list_t* vec, List_t* new_list) {
if (vec->size == vec->capacity) {
vec->capacity *= 2;
vec->lists = realloc(vec->lists, vec->capacity * sizeof(List_t));
if (!vec->lists) {
LOG_E(NR_MAC, "Memory allocation failed\n");
exit(EXIT_FAILURE);
}
}
vec->lists[vec->size] = *new_list;
vec->size++;
}
List_t* get_list(vec_of_list_t *vec, size_t index) {
if (index >= vec->size) {
LOG_E(NR_MAC, "Index out of bounds\n");
return NULL;
}
return &vec->lists[index];
}
void free_vector(vec_of_list_t* vec) {
for (size_t i = 0; i < vec->size; i++) {
free_list_mem(&vec->lists[i]);
}
free(vec->lists);
vec->lists = NULL;
vec->size = 0;
vec->capacity = 0;
}

View File

@@ -163,6 +163,51 @@ static void trigger_regular_bsr(NR_UE_MAC_INST_t *mac, NR_LogicalChannelIdentity
nr_timer_stop(&mac->scheduling_info.sr_DelayTimer);
}
/*TS 38.321
A BSR shall be triggered if any of the following events occur:
- UL data, for a logical channel which belongs to an LCG, becomes available to the MAC entity; and either
=> here we don't implement exactly the same, there is no direct relation with new data came in the UE since last BSR
- this UL data belongs to a logical channel with higher priority than the priority of any logical channel
containing available UL data which belong to any LCG; or
=> same, we don't know the last BSR content
- none of the logical channels which belong to an LCG contains any available UL data.
in which case the BSR is referred below to as 'Regular BSR';
- UL resources are allocated and number of padding bits is equal to or larger than the size of the Buffer Status
Report MAC CE plus its subheader, in which case the BSR is referred below to as 'Padding BSR';
- retxBSR-Timer expires, and at least one of the logical channels which belong to an LCG contains UL data, in
which case the BSR is referred below to as 'Regular BSR';
- periodicBSR-Timer expires, in which case the BSR is referred below to as 'Periodic BSR'.
*/
void nr_update_bsr(NR_UE_MAC_INST_t *mac, uint32_t *LCG_bytes)
{
bool bsr_regular_triggered = mac->scheduling_info.BSR_reporting_active & NR_BSR_TRIGGER_REGULAR;
for (int i = 0; i < mac->lc_ordered_list.count; i++) {
nr_lcordered_info_t *lc_info = mac->lc_ordered_list.array[i];
if (lc_info->rb_suspended)
continue;
int lcid = lc_info->lcid;
NR_LC_SCHEDULING_INFO *lc_sched_info = get_scheduling_info_from_lcid(mac, lcid);
int lcgid = lc_sched_info->LCGID;
// check if UL data for a logical channel which belongs to a LCG becomes available for transmission
if (lcgid != NR_INVALID_LCGID) {
// Update waiting bytes for this LCG
LCG_bytes[lcgid] += lc_sched_info->LCID_buffer_remain;
if (!bsr_regular_triggered) {
bsr_regular_triggered = true;
trigger_regular_bsr(mac, lcid, lc_info->sr_DelayTimerApplied);
LOG_D(NR_MAC, "[UE %d] MAC BSR Triggered\n", mac->ue_id);
}
}
}
}
void handle_time_alignment_timer_expired(NR_UE_MAC_INST_t *mac)
{
// flush all HARQ buffers for all Serving Cells
@@ -1303,51 +1348,6 @@ static void nr_update_rlc_buffers_status(NR_UE_MAC_INST_t *mac, frame_t frameP,
}
}
/*TS 38.321
A BSR shall be triggered if any of the following events occur:
- UL data, for a logical channel which belongs to an LCG, becomes available to the MAC entity; and either
=> here we don't implement exactly the same, there is no direct relation with new data came in the UE since last BSR
- this UL data belongs to a logical channel with higher priority than the priority of any logical channel
containing available UL data which belong to any LCG; or
=> same, we don't know the last BSR content
- none of the logical channels which belong to an LCG contains any available UL data.
in which case the BSR is referred below to as 'Regular BSR';
- UL resources are allocated and number of padding bits is equal to or larger than the size of the Buffer Status
Report MAC CE plus its subheader, in which case the BSR is referred below to as 'Padding BSR';
- retxBSR-Timer expires, and at least one of the logical channels which belong to an LCG contains UL data, in
which case the BSR is referred below to as 'Regular BSR';
- periodicBSR-Timer expires, in which case the BSR is referred below to as 'Periodic BSR'.
*/
static void nr_update_bsr(NR_UE_MAC_INST_t *mac, uint32_t *LCG_bytes)
{
bool bsr_regular_triggered = mac->scheduling_info.BSR_reporting_active & NR_BSR_TRIGGER_REGULAR;
for (int i = 0; i < mac->lc_ordered_list.count; i++) {
nr_lcordered_info_t *lc_info = mac->lc_ordered_list.array[i];
if (lc_info->rb_suspended)
continue;
int lcid = lc_info->lcid;
NR_LC_SCHEDULING_INFO *lc_sched_info = get_scheduling_info_from_lcid(mac, lcid);
int lcgid = lc_sched_info->LCGID;
// check if UL data for a logical channel which belongs to a LCG becomes available for transmission
if (lcgid != NR_INVALID_LCGID) {
// Update waiting bytes for this LCG
LCG_bytes[lcgid] += lc_sched_info->LCID_buffer_remain;
if (!bsr_regular_triggered) {
bsr_regular_triggered = true;
trigger_regular_bsr(mac, lcid, lc_info->sr_DelayTimerApplied);
LOG_D(NR_MAC, "[UE %d] MAC BSR Triggered\n", mac->ue_id);
}
}
}
}
void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info)
{
int cc_id = ul_info->cc_id;
@@ -2258,22 +2258,7 @@ static void nr_ue_prach_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t
} // if is_nr_UL_slot
}
typedef struct {
uint8_t phr_len;
uint sdu_length_total;
NR_SINGLE_ENTRY_PHR_MAC_CE phr;
type_bsr_t bsr;
uint8_t *pdu_end;
uint8_t *end_for_tailer;
uint8_t *cur_ptr;
uint num_sdus;
// int highest_priority = 16;
// variable used to store the lcid data status during lcp
bool lcids_data_status[NR_MAX_NUM_LCID];
uint32_t lcp_allocation_counter;
} NR_UE_MAC_CE_INFO;
static void nr_ue_get_sdu_mac_ce_pre(NR_UE_MAC_INST_t *mac,
void nr_ue_get_sdu_mac_ce_pre(NR_UE_MAC_INST_t *mac,
int CC_id,
frame_t frame,
slot_t slot,
@@ -2303,7 +2288,7 @@ static void nr_ue_get_sdu_mac_ce_pre(NR_UE_MAC_INST_t *mac,
// A Regular or Periodic BSR can only be sent if TBS is sufficient
// as transmitting only a BSR is not allowed if UE has data to transmit
int size_for_long = num_lcg_id_with_data + sizeof(NR_BSR_LONG) + sizeof(NR_MAC_SUBHEADER_SHORT);
int size_for_short = sizeof(NR_BSR_SHORT) + sizeof(NR_MAC_SUBHEADER_FIXED);
int size_for_short = (get_softmodem_params()->sl_mode ? sizeof(NR_SL_BSR_SHORT) : sizeof(NR_BSR_SHORT)) + sizeof(NR_MAC_SUBHEADER_FIXED);
if (num_lcg_id_with_data > 1 && buflen >= size_for_long)
bsr_len = size_for_long;
else if ((num_lcg_id_with_data > 0 && buflen >= size_for_short)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,349 @@
/*
* 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 nr_ue_scheduler_sl_v2x.c
* \brief Rel-16 NR sidelink V2X semi-persistent resource selection and LBT gate
*/
#include <stdlib.h>
#include <string.h>
#include "NR_MAC_UE/mac_proto.h"
#include "common/utils/LOG/log.h"
#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h"
#define NR_SL_V2X_DEFAULT_PROB_RESOURCE_KEEP 0.8
#define NR_SL_V2X_DEFAULT_LBT_ED_THRESHOLD_DBM -72
#define NR_SL_V2X_DEFAULT_MAX_LBT_FAILURES 4
#define NR_SL_V2X_SLSCH_LCID 4
static bool nr_sl_v2x_is_configured(const NR_UE_MAC_INST_t *mac)
{
return mac != NULL && mac->SL_MAC_PARAMS != NULL && mac->sl_tx_res_pool != NULL && mac->SL_MAC_PARAMS->sl_TxPool[0] != NULL;
}
static double nr_sl_v2x_random_unit(void)
{
return (double)(lrand48() & 0x7fffffff) / (double)0x7fffffff;
}
static void nr_sl_v2x_reset_selected_list(NR_UE_MAC_INST_t *mac, const sl_resource_info_t *resource)
{
if (mac->sl_candidate_resources == NULL) {
mac->sl_candidate_resources = calloc(1, sizeof(*mac->sl_candidate_resources));
init_list(mac->sl_candidate_resources, sizeof(*resource), 1);
} else if (mac->sl_candidate_resources->data == NULL || mac->sl_candidate_resources->element_size != sizeof(*resource)) {
init_list(mac->sl_candidate_resources, sizeof(*resource), 1);
} else {
mac->sl_candidate_resources->size = 0;
}
if (resource != NULL)
push_back(mac->sl_candidate_resources, (void *)resource);
}
static uint16_t nr_sl_v2x_next_reselection_counter(NR_UE_MAC_INST_t *mac)
{
sl_nr_ue_mac_params_t *sl_mac = mac->SL_MAC_PARAMS;
uint16_t rri = sl_mac->mac_tx_params.rri;
uint16_t counter = get_random_reselection_counter(rri);
if (counter == 0)
counter = 1;
sl_mac->mac_tx_params.resel_counter = counter;
mac->sl_resel_counter = counter;
mac->sl_c_resel = counter;
return counter;
}
static void nr_sl_v2x_release_sps_resource(NR_UE_MAC_INST_t *mac)
{
nr_sl_v2x_sps_state_t *sps = &mac->sl_v2x_scheduler.sps;
sps->active = false;
sps->next_abs_slot = -1;
sps->released++;
nr_sl_v2x_reset_selected_list(mac, NULL);
}
static bool nr_sl_v2x_pick_candidate(const List_t *candidates, sl_resource_info_t *selected)
{
if (candidates == NULL || candidates->size == 0)
return false;
size_t idle_count = 0;
for (size_t i = 0; i < candidates->size; i++) {
const sl_resource_info_t *candidate = (const sl_resource_info_t *)((const char *)candidates->data + i * candidates->element_size);
if (!candidate->slot_busy)
idle_count++;
}
size_t target = 0;
if (idle_count > 0) {
target = lrand48() % idle_count;
for (size_t i = 0; i < candidates->size; i++) {
const sl_resource_info_t *candidate = (const sl_resource_info_t *)((const char *)candidates->data + i * candidates->element_size);
if (!candidate->slot_busy && target-- == 0) {
*selected = *candidate;
return true;
}
}
}
*selected = *(const sl_resource_info_t *)((const char *)candidates->data + (lrand48() % candidates->size) * candidates->element_size);
return true;
}
static bool nr_sl_v2x_activate_sps_resource(NR_UE_MAC_INST_t *mac, const frameslot_t *frame_slot)
{
sl_nr_ue_mac_params_t *sl_mac = mac->SL_MAC_PARAMS;
uint8_t mu = sl_mac->sl_phy_config.sl_config_req.sl_bwp_config.sl_scs;
List_t *candidates = get_candidate_resources((frameslot_t *)frame_slot, mac, &mac->sl_sensing_data, &mac->sl_transmit_history);
sl_resource_info_t selected = {0};
bool selected_ok = nr_sl_v2x_pick_candidate(candidates, &selected);
if (candidates != NULL) {
free_list_mem(candidates);
free(candidates);
}
if (!selected_ok)
return false;
nr_sl_v2x_sps_state_t *sps = &mac->sl_v2x_scheduler.sps;
sps->active = true;
sps->pool_id = 0;
sps->p_rsvp_slots = time_to_slots(mu, sl_mac->mac_tx_params.rri);
if (sps->p_rsvp_slots == 0)
sps->p_rsvp_slots = 1;
sps->c_resel = nr_sl_v2x_next_reselection_counter(mac);
sps->c_resel_initial = sps->c_resel;
sps->resource = selected;
sps->current_resource = selected;
sps->next_abs_slot = normalize(&selected.sfn, mu);
sps->reselections++;
nr_sl_v2x_reset_selected_list(mac, &selected);
LOG_D(NR_MAC,
"SL-V2X SPS selected %4d.%2d subch %d len %d C_resel %d RRI-slots %d\n",
selected.sfn.frame,
selected.sfn.slot,
selected.sl_subchan_start,
selected.sl_subchan_len,
sps->c_resel,
sps->p_rsvp_slots);
return true;
}
static void nr_sl_v2x_refresh_config(NR_UE_MAC_INST_t *mac)
{
nr_sl_v2x_scheduler_t *scheduler = &mac->sl_v2x_scheduler;
scheduler->enabled = true;
if (mac->m_slProbResourceKeep <= 0.0 || mac->m_slProbResourceKeep > 1.0)
mac->m_slProbResourceKeep = NR_SL_V2X_DEFAULT_PROB_RESOURCE_KEEP;
scheduler->lbt.enabled = true;
if (scheduler->lbt.mode == NR_SL_V2X_LBT_DISABLED)
scheduler->lbt.mode = NR_SL_V2X_LBT_TYPE2;
if (scheduler->lbt.energy_detection_threshold_dbm == 0)
scheduler->lbt.energy_detection_threshold_dbm = NR_SL_V2X_DEFAULT_LBT_ED_THRESHOLD_DBM;
if (mac->SL_MAC_PARAMS->mac_tx_params.sl_thresh_rsrp != 0)
scheduler->lbt.energy_detection_threshold_dbm = mac->SL_MAC_PARAMS->mac_tx_params.sl_thresh_rsrp;
if (scheduler->lbt.max_consecutive_failures == 0)
scheduler->lbt.max_consecutive_failures = NR_SL_V2X_DEFAULT_MAX_LBT_FAILURES;
}
void nr_ue_sl_v2x_init_scheduler(NR_UE_MAC_INST_t *mac)
{
AssertFatal(mac != NULL, "mac cannot be NULL\n");
nr_sl_v2x_scheduler_t *scheduler = &mac->sl_v2x_scheduler;
memset(scheduler, 0, sizeof(*scheduler));
scheduler->enabled = true;
scheduler->lbt.enabled = true;
scheduler->lbt.mode = NR_SL_V2X_LBT_TYPE2;
scheduler->lbt.energy_detection_threshold_dbm = NR_SL_V2X_DEFAULT_LBT_ED_THRESHOLD_DBM;
scheduler->lbt.max_consecutive_failures = NR_SL_V2X_DEFAULT_MAX_LBT_FAILURES;
scheduler->lbt.last_failure.frame = -1;
scheduler->lbt.last_failure.slot = -1;
scheduler->sps.next_abs_slot = -1;
mac->m_slProbResourceKeep = NR_SL_V2X_DEFAULT_PROB_RESOURCE_KEEP;
}
sl_resource_info_t *nr_ue_sl_v2x_select_resource(NR_UE_MAC_INST_t *mac,
const frameslot_t *frame_slot,
sl_sidelink_slot_type_t slot_type)
{
if (!nr_sl_v2x_is_configured(mac) || slot_type != SIDELINK_SLOT_TYPE_TX)
return NULL;
nr_sl_v2x_refresh_config(mac);
if (!mac->sl_v2x_scheduler.enabled)
return mac->sl_candidate_resources ? get_resource_element(mac->sl_candidate_resources, *frame_slot) : NULL;
sl_nr_ue_mac_params_t *sl_mac = mac->SL_MAC_PARAMS;
uint8_t mu = sl_mac->sl_phy_config.sl_config_req.sl_bwp_config.sl_scs;
nr_sl_v2x_sps_state_t *sps = &mac->sl_v2x_scheduler.sps;
int64_t current_abs_slot = normalize((frameslot_t *)frame_slot, mu);
if (!sps->active && !nr_sl_v2x_activate_sps_resource(mac, frame_slot))
return NULL;
if (current_abs_slot > sps->next_abs_slot) {
int64_t missed = ((current_abs_slot - sps->next_abs_slot) / sps->p_rsvp_slots) + 1;
sps->next_abs_slot += missed * sps->p_rsvp_slots;
}
if (current_abs_slot != sps->next_abs_slot)
return NULL;
sps->current_resource = sps->resource;
sps->current_resource.sfn = *frame_slot;
return &sps->current_resource;
}
static bool nr_sl_v2x_has_pending_tx(NR_UE_MAC_INST_t *mac, const frameslot_t *frame_slot)
{
if (mac->sl_tx_res_pool != NULL && mac->sl_tx_res_pool->sl_PSFCH_Config_r16 && is_feedback_scheduled(mac, frame_slot->frame, frame_slot->slot))
return true;
for (int i = 0; i < MAX_SL_UE_CONNECTIONS && mac->sl_info.list[i] != NULL; i++) {
NR_SL_UE_sched_ctrl_t *sched_ctrl = &mac->sl_info.list[i]->UE_sched_ctrl;
if (sched_ctrl->retrans_sl_harq.head >= 0)
return true;
if (sched_ctrl->sched_csi_report.active &&
sched_ctrl->sched_csi_report.frame == frame_slot->frame &&
sched_ctrl->sched_csi_report.slot == frame_slot->slot)
return true;
}
mac_rlc_status_resp_t rlc_status = nr_mac_rlc_status_ind(mac->ue_id, frame_slot->frame, NR_SL_V2X_SLSCH_LCID);
return rlc_status.bytes_in_buffer > 0;
}
static bool nr_sl_v2x_sensed_resource_busy(NR_UE_MAC_INST_t *mac, const sl_resource_info_t *resource, const frameslot_t *frame_slot)
{
sl_nr_ue_mac_params_t *sl_mac = mac->SL_MAC_PARAMS;
uint8_t mu = sl_mac->sl_phy_config.sl_config_req.sl_bwp_config.sl_scs;
int64_t cycle_slots = nr_slots_per_frame[mu] * 1024;
int64_t target_abs = normalize((frameslot_t *)frame_slot, mu);
int16_t threshold = mac->sl_v2x_scheduler.lbt.energy_detection_threshold_dbm;
for (size_t i = 0; i < mac->sl_sensing_data.size; i++) {
const sensing_data_t *sensed = (const sensing_data_t *)((const char *)mac->sl_sensing_data.data + i * mac->sl_sensing_data.element_size);
if (sensed->sl_rsrp <= threshold)
continue;
if (!overlapped_resource(sensed->subch_start, sensed->subch_len, resource->sl_subchan_start, resource->sl_subchan_len))
continue;
int64_t sensed_abs = normalize((frameslot_t *)&sensed->frame_slot, mu);
int64_t diff = (target_abs - sensed_abs + cycle_slots) % cycle_slots;
if (diff == 0)
return true;
uint16_t p_rsvp_slots = sensed->rsvp ? time_to_slots(mu, sensed->rsvp) : 0;
if (p_rsvp_slots > 0 && diff > 0 && (diff % p_rsvp_slots) == 0)
return true;
}
return false;
}
bool nr_ue_sl_v2x_lbt_allows_tx(NR_UE_MAC_INST_t *mac,
const sl_resource_info_t *resource,
const frameslot_t *frame_slot)
{
if (!nr_sl_v2x_is_configured(mac) || resource == NULL || !mac->sl_v2x_scheduler.lbt.enabled)
return true;
if (!nr_sl_v2x_has_pending_tx(mac, frame_slot))
return true;
nr_sl_v2x_lbt_state_t *lbt = &mac->sl_v2x_scheduler.lbt;
lbt->attempts++;
if (!nr_sl_v2x_sensed_resource_busy(mac, resource, frame_slot))
return true;
lbt->failures++;
lbt->consecutive_failures++;
lbt->last_failure = *frame_slot;
LOG_D(NR_MAC,
"SL-V2X LBT busy at %4d.%2d subch %d len %d RSRP threshold %d failures %d/%d\n",
frame_slot->frame,
frame_slot->slot,
resource->sl_subchan_start,
resource->sl_subchan_len,
lbt->energy_detection_threshold_dbm,
lbt->consecutive_failures,
lbt->max_consecutive_failures);
if (lbt->consecutive_failures >= lbt->max_consecutive_failures) {
LOG_D(NR_MAC, "SL-V2X LBT releasing SPS resource after consecutive failures\n");
nr_sl_v2x_release_sps_resource(mac);
lbt->consecutive_failures = 0;
}
return false;
}
void nr_ue_sl_v2x_notify_tx_result(NR_UE_MAC_INST_t *mac,
const sl_resource_info_t *resource,
const frameslot_t *frame_slot,
bool transmitted)
{
if (!nr_sl_v2x_is_configured(mac) || resource == NULL || !mac->sl_v2x_scheduler.sps.active || !transmitted)
return;
nr_sl_v2x_scheduler_t *scheduler = &mac->sl_v2x_scheduler;
nr_sl_v2x_sps_state_t *sps = &scheduler->sps;
scheduler->lbt.successes++;
scheduler->lbt.consecutive_failures = 0;
if (sps->c_resel > 0)
sps->c_resel--;
mac->sl_c_resel = sps->c_resel;
mac->sl_resel_counter = sps->c_resel;
mac->SL_MAC_PARAMS->mac_tx_params.resel_counter = sps->c_resel;
if (sps->c_resel == 0) {
if (nr_sl_v2x_random_unit() <= mac->m_slProbResourceKeep) {
sps->c_resel = nr_sl_v2x_next_reselection_counter(mac);
sps->c_resel_initial = sps->c_resel;
sps->kept++;
LOG_D(NR_MAC,
"SL-V2X SPS keeping resource %4d.%2d subch %d for C_resel %d\n",
sps->resource.sfn.frame,
sps->resource.sfn.slot,
sps->resource.sl_subchan_start,
sps->c_resel);
} else {
LOG_D(NR_MAC,
"SL-V2X SPS releasing resource %4d.%2d subch %d after C_resel expiry\n",
frame_slot->frame,
frame_slot->slot,
resource->sl_subchan_start);
nr_sl_v2x_release_sps_resource(mac);
return;
}
}
sps->next_abs_slot += sps->p_rsvp_slots;
}

View File

@@ -0,0 +1,77 @@
/*
* 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 nr_ue_sci.h
* \brief Definitions and Structures for sci/slsch procedures for Sidelink UE
* \author R. Knopp
* \date 2023
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr
* \note
* \warning
*/
#ifndef __LAYER2_NR_UE_SCI_H__
#define __LAYER2_NR_UE_SCI_H__
#include "NR_MAC_COMMON/nr_mac.h"
typedef enum {
NR_SL_SCI_FORMAT_1A = 0,
NR_SL_SCI_FORMAT_2A = 1,
NR_SL_SCI_FORMAT_2B = 2,
NR_SL_SCI_FORMAT_2C = 3
} nr_sci_format_t;
typedef struct {
// 1st stage fields
uint8_t priority; // 3 bits
dci_field_t frequency_resource_assignment; // depending on sl-MaxNumPerReserve and N_subChannel^SL
dci_field_t time_resource_assignment; // depending on sl_MaxNumPerReserve
dci_field_t resource_reservation_period; // sl-ResourceReservePeriodList and sl-MultiReserveResource
dci_field_t dmrs_pattern; // depending on N_pattern and sl-PSSCH-DMRS-TimePatternList
uint8_t second_stage_sci_format; // 2 bits - Table 8.3.1.1-1
uint8_t beta_offset_indicator; // 2 bits - depending sl-BetaOffsets2ndSCI and Table 8.3.1.1-2
uint8_t number_of_dmrs_port; // 1 bit - Table 8.3.1.1-3
uint8_t mcs; // 5 bits
dci_field_t additional_mcs; // depending on sl-Additional-MCS-Table
dci_field_t psfch_overhead; // depending on sl-PSFCH-Period
dci_field_t reserved; // depending on N_reserved (sl-NumReservedBits) and sl-IndicationUE-B
dci_field_t conflict_information_receiver; // depending on sl-IndicationUE-B
// 2nd stage fields
uint8_t harq_pid; // 4 bits
uint8_t ndi; // 1 bit
uint8_t rv_index; // 2 bits
uint8_t source_id; // 8 bits
uint16_t dest_id; // 16 bits
uint8_t harq_feedback; //1 bit
uint8_t cast_type; // 2 bits formac 2A
uint8_t csi_req; // 1 bit format 2A, format 2C
uint16_t zone_id; // 12 bits format 2B
dci_field_t communication_range; // 4 bits depending on sl-ZoneConfigMCR-Index, format 2B
uint8_t providing_req_ind; // 1 bit, format 2C
dci_field_t resource_combinations; // depending on n_subChannel^SL (sl-NumSubchennel), N_rsv_period (sl-ResourceReservePeriodList) and sl-MultiReservedResource, format 2C
uint8_t first_resource_location; // 8 bits, format 2C
dci_field_t reference_slot_location; // depending on mu, format 2C
uint8_t resource_set_type; // 1 bit, format 2C
dci_field_t lowest_subchannel_indices; // depending on n_subChannel^SL, format 2C
} nr_sci_pdu_t;
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -268,27 +268,6 @@ nfapi_nr_pm_list_t init_DL_MIMO_codebook(gNB_MAC_INST *gNB, nr_pdsch_AntennaPort
return mat;
}
/**
* @brief Get the first UL slot index in period
* @param fs frame structure
* @param mixed indicates whether to include in the count also mixed slot with UL symbols or only full UL slot
* @return slot index
*/
int get_first_ul_slot(const frame_structure_t *fs, bool mixed)
{
DevAssert(fs);
if (fs->frame_type == TDD) {
for (int i = 0; i < fs->numb_slots_period; i++) {
if ((mixed && is_ul_slot(i, fs)) || fs->period_cfg.tdd_slot_bitmap[i].slot_type == TDD_NR_UPLINK_SLOT) {
return i;
}
}
}
return 0; // FDD
}
/**
* @brief Get number of DL slots per period (full DL slots + mixed slots with DL symbols)
*/

View File

@@ -66,62 +66,6 @@
#define NR_RRC_RECONFIGURATION_DELAY_MS 10
#define NR_RRC_BWP_SWITCHING_DELAY_MS 6
// #define DEBUG_DCI
// CQI TABLES (10 times the value in 214 to adequately compare with R)
// Table 1 (38.214 5.2.2.1-2)
static const uint16_t cqi_table1[16][2] = {{0, 0},
{2, 780},
{2, 1200},
{2, 1930},
{2, 3080},
{2, 4490},
{2, 6020},
{4, 3780},
{4, 4900},
{4, 6160},
{6, 4660},
{6, 5670},
{6, 6660},
{6, 7720},
{6, 8730},
{6, 9480}};
// Table 2 (38.214 5.2.2.1-3)
static const uint16_t cqi_table2[16][2] = {{0, 0},
{2, 780},
{2, 1930},
{2, 4490},
{4, 3780},
{4, 4900},
{4, 6160},
{6, 4660},
{6, 5670},
{6, 6660},
{6, 7720},
{6, 8730},
{8, 7110},
{8, 7970},
{8, 8850},
{8, 9480}};
// Table 2 (38.214 5.2.2.1-4)
static const uint16_t cqi_table3[16][2] = {{0, 0},
{2, 300},
{2, 500},
{2, 780},
{2, 1200},
{2, 1930},
{2, 3080},
{2, 4490},
{2, 6020},
{4, 3780},
{4, 4900},
{4, 6160},
{6, 4660},
{6, 5670},
{6, 6660},
{6, 7720}};
static void determine_aggregation_level_search_order(int agg_level_search_order[NUM_PDCCH_AGG_LEVELS],
float pdcch_cl_adjust);
@@ -282,47 +226,6 @@ int get_mcs_from_SINRx10(int mcs_table, int SINRx10, int Nl)
return 0;
}
uint8_t get_mcs_from_cqi(int mcs_table, int cqi_table, int cqi_idx)
{
if (cqi_idx <= 0) {
LOG_E(NR_MAC, "invalid cqi_idx %d, default to MCS 9\n", cqi_idx);
return 9;
}
if (mcs_table != cqi_table) {
LOG_E(NR_MAC, "indices of CQI (%d) and MCS (%d) tables don't correspond yet\n", cqi_table, mcs_table);
return 9;
}
uint16_t target_coderate, target_qm;
switch (cqi_table) {
case 0:
target_qm = cqi_table1[cqi_idx][0];
target_coderate = cqi_table1[cqi_idx][1];
break;
case 1:
target_qm = cqi_table2[cqi_idx][0];
target_coderate = cqi_table2[cqi_idx][1];
break;
case 2:
target_qm = cqi_table3[cqi_idx][0];
target_coderate = cqi_table3[cqi_idx][1];
break;
default:
AssertFatal(1==0,"Invalid cqi table index %d\n",cqi_table);
}
const int max_mcs = mcs_table == 1 ? 27 : 28;
for (int i = 0; i <= max_mcs; i++) {
const int R = nr_get_code_rate_dl(i, mcs_table);
const int Qm = nr_get_Qm_dl(i, mcs_table);
if (Qm == target_qm && target_coderate <= R)
return i;
}
LOG_E(NR_MAC, "could not find maximum MCS from cqi_idx %d, default to 9\n", cqi_idx);
return 9;
}
NR_pdsch_dmrs_t get_dl_dmrs_params(const NR_ServingCellConfigCommon_t *scc,
const NR_UE_DL_BWP_t *dl_bwp,
const NR_tda_info_t *tda_info,
@@ -782,45 +685,6 @@ NR_pusch_dmrs_t get_ul_dmrs_params(const NR_ServingCellConfigCommon_t *scc,
return dmrs;
}
#define BLER_UPDATE_FRAME 10
#define BLER_FILTER 0.9f
int get_mcs_from_bler(const NR_bler_options_t *bler_options,
const NR_mac_dir_stats_t *stats,
NR_bler_stats_t *bler_stats,
int max_mcs,
frame_t frame)
{
int diff = frame - bler_stats->last_frame;
if (diff < 0) // wrap around
diff += 1024;
max_mcs = min(max_mcs, bler_options->max_mcs);
const uint8_t old_mcs = min(bler_stats->mcs, max_mcs);
if (diff < BLER_UPDATE_FRAME)
return old_mcs; // no update
// last update is longer than x frames ago
const int num_dl_sched = (int)(stats->rounds[0] - bler_stats->rounds[0]);
const int num_dl_retx = (int)(stats->rounds[1] - bler_stats->rounds[1]);
const float bler_window = num_dl_sched > 0 ? (float) num_dl_retx / num_dl_sched : bler_stats->bler;
bler_stats->bler = BLER_FILTER * bler_stats->bler + (1 - BLER_FILTER) * bler_window;
int new_mcs = old_mcs;
if (bler_stats->bler < bler_options->lower && old_mcs < max_mcs && num_dl_sched > 3)
new_mcs += 1;
else if (bler_stats->bler > bler_options->upper || num_dl_sched <= 3) // above threshold or no activity
new_mcs -= 1;
// else we are within threshold boundaries
new_mcs = max(new_mcs, bler_options->min_mcs);
bler_stats->last_frame = frame;
bler_stats->mcs = new_mcs;
memcpy(bler_stats->rounds, stats->rounds, sizeof(stats->rounds));
LOG_D(MAC, "frame %4d MCS %d -> %d (num_dl_sched %d, num_dl_retx %d, BLER wnd %.3f avg %.6f)\n",
frame, old_mcs, new_mcs, num_dl_sched, num_dl_retx, bler_window, bler_stats->bler);
return new_mcs;
}
nfapi_nr_dl_dci_pdu_t *prepare_dci_pdu(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
const NR_ServingCellConfigCommon_t *scc,
const NR_SearchSpace_t *ss,
@@ -2338,6 +2202,7 @@ void dump_nr_list(NR_UE_info_t **list)
}
}
#if 0
/*
* Create a new NR_list
*/
@@ -2463,6 +2328,7 @@ void remove_front_nr_list(NR_list_t *listP)
if (listP->head < 0)
listP->tail = -1;
}
#endif
NR_UE_info_t *find_nr_UE(NR_UEs_t *UEs, rnti_t rntiP)
{

View File

@@ -40,7 +40,6 @@ void set_cset_offset(uint16_t);
void get_K1_K2(int N1, int N2, int *K1, int *K2, int layers);
int get_NTN_Koffset(const NR_ServingCellConfigCommon_t *scc);
int get_first_ul_slot(const frame_structure_t *fs, bool mixed);
int get_ul_slots_per_period(const frame_structure_t *fs);
int get_ul_slots_per_frame(const frame_structure_t *fs);
int get_dl_slots_per_period(const frame_structure_t *fs);
@@ -396,7 +395,6 @@ uint16_t get_pm_index(const gNB_MAC_INST *nrmac,
int xp_pdsch_antenna_ports);
int get_mcs_from_SINRx10(int mcs_table, int SINRx10, int Nl);
uint8_t get_mcs_from_cqi(int mcs_table, int cqi_table, int cqi_idx);
uint8_t get_dl_nrOfLayers(const NR_UE_sched_ctrl_t *sched_ctrl, const nr_dci_format_t dci_format);
int get_ul_nrOfLayers(const NR_UE_sched_ctrl_t *sched_ctrl, const nr_dci_format_t dci_format);
@@ -438,12 +436,6 @@ bool nr_find_nb_rb(uint16_t Qm,
uint32_t *tbs,
uint16_t *nb_rb);
int get_mcs_from_bler(const NR_bler_options_t *bler_options,
const NR_mac_dir_stats_t *stats,
NR_bler_stats_t *bler_stats,
int max_mcs,
frame_t frame);
int ul_buffer_index(int frame, int slot, int slots_per_frame, int size);
void UL_tti_req_ahead_initialization(gNB_MAC_INST *gNB, int n, int CCid, frame_t frameP, int slotP);
void fapi_beam_index_allocation(NR_ServingCellConfigCommon_t *scc, const nr_mac_config_t *config, gNB_MAC_INST *mac);

View File

@@ -102,15 +102,6 @@
uint8_t nr_get_rv(int rel_round);
/*! \brief NR_list_t is a "list" (of users, HARQ processes, slices, ...).
* Especially useful in the scheduler and to keep "classes" of users. */
typedef struct {
int head;
int *next;
int tail;
int len;
} NR_list_t;
typedef enum {
nrRA_gNB_IDLE,
nrRA_Msg2,
@@ -520,13 +511,6 @@ typedef struct NR_UE_harq {
//! fixme : need to enhace for the multiple TB CQI report
typedef struct NR_bler_stats {
frame_t last_frame;
float bler;
uint8_t mcs;
uint64_t rounds[8];
} NR_bler_stats_t;
//
/*! As per spec 38.214 section 5.2.1.4.2
* - if the UE is configured with the higher layer parameter groupBasedBeamReporting set to 'disabled', the UE shall report in
@@ -708,19 +692,6 @@ typedef struct {
float pdcch_cl_adjust;
} NR_UE_sched_ctrl_t;
typedef struct NR_mac_dir_stats {
uint64_t lc_bytes[64];
uint64_t rounds[8];
uint64_t errors;
uint64_t total_bytes;
uint32_t current_bytes;
uint64_t total_sdu_bytes;
uint32_t total_rbs;
uint32_t total_rbs_retx;
uint32_t num_mac_sdu;
uint32_t current_rbs;
} NR_mac_dir_stats_t;
typedef struct NR_mac_stats {
NR_mac_dir_stats_t dl;
NR_mac_dir_stats_t ul;
@@ -737,14 +708,6 @@ typedef struct NR_mac_stats {
int NPRB;
} NR_mac_stats_t;
typedef struct NR_bler_options {
double upper;
double lower;
uint8_t min_mcs;
uint8_t max_mcs;
uint8_t harq_round_max;
} NR_bler_options_t;
typedef struct nr_mac_rrc_ul_if_s {
f1_reset_du_initiated_func_t f1_reset;
f1_reset_acknowledge_cu_initiated_func_t f1_reset_acknowledge;

View File

@@ -46,3 +46,4 @@ ENCODE_DECODE(t_reordering, T_REORDERING)
ENCODE_DECODE(sn_size_ul, SN_SIZE)
ENCODE_DECODE(sn_size_dl, SN_SIZE)
ENCODE_DECODE(discard_timer, DISCARD_TIMER)
ENCODE_DECODE(discard_timer_sl, DISCARD_TIMER_SL)

View File

@@ -26,10 +26,12 @@ int decode_t_reordering(int v);
int decode_sn_size_ul(int v);
int decode_sn_size_dl(int v);
int decode_discard_timer(int v);
int decode_discard_timer_sl(int v);
int encode_t_reordering(int v);
int encode_sn_size_ul(int v);
int encode_sn_size_dl(int v);
int encode_discard_timer(int v);
#endif /* _OPENAIR2_LAYER2_NR_PDCP_ASN1_UTILS_H_ */

View File

@@ -58,12 +58,21 @@
#define SIZEOF_NR_PDCP_DISCARD_TIMER INT_LIST_SIZE(VALUES_NR_PDCP_DISCARD_TIMER)
#define VALUES_NR_PDCP_DISCARD_TIMER_SL \
3, 10, 20, 25, 30, 40, 50, 60, 75, 100, 150, 200, 250, 300, 500, 750, 1500, -1 /* -1 means infinity */
#define VALUES_NR_PDCP_DISCARD_TIMER_SL_STR \
"ms3", "ms10", "ms20", "ms25", "ms30", "ms40", "ms50", "ms60", "ms75", "ms100", "ms150", "ms200", "ms250", "ms300", "ms500", "ms750", "ms1500", "infinity"
#define SIZEOF_NR_PDCP_DISCARD_TIMER_SL INT_LIST_SIZE(VALUES_NR_PDCP_DISCARD_TIMER_SL)
/* configuration of NR PDCP, coming from configuration file */
typedef struct {
struct {
int sn_size;
int t_reordering;
int discard_timer;
int discard_timer_sl;
} drb;
} nr_pdcp_configuration_t;

View File

@@ -640,6 +640,69 @@ void nr_pdcp_add_drb(int is_gnb,
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
}
void add_drb_sl(ue_id_t srcid, NR_SL_RadioBearerConfig_r16_t *s, const nr_pdcp_entity_security_keys_and_algos_t *security_parameters)
{
nr_pdcp_entity_t *pdcp_drb;
AssertFatal(s->sl_PDCP_Config_r16 != NULL, "SL PDCP config is not there!\n");
int slrb_id = s->slrb_Uu_ConfigIndex_r16;
int sn_size = decode_sn_size_ul(*s->sl_PDCP_Config_r16->sl_PDCP_SN_Size_r16);
int discard_timer = decode_discard_timer_sl(*s->sl_PDCP_Config_r16->sl_DiscardTimer_r16);
int t_reordering = 20;
// get SDAP config
sdap_config_t sdap = {0};
sdap.pdusession_id = 0;
sdap.drb_id = slrb_id;
int role = 0;
if (s->sl_SDAP_Config_r16 && s->sl_SDAP_Config_r16->sl_SDAP_Header_r16 == NR_SL_SDAP_Config_r16__sl_SDAP_Header_r16_present)
{
role |= SDAP_UL_TX | SDAP_DL_RX;
}
sdap.role = role;
sdap.defaultDRB = s->sl_SDAP_Config_r16 && s->sl_SDAP_Config_r16->sl_DefaultRB_r16 == true ? true : false;
if (s->sl_SDAP_Config_r16->sl_MappedQoS_Flows_r16) {
sdap.mappedQFIs2AddCount = s->sl_SDAP_Config_r16->sl_MappedQoS_Flows_r16->choice.sl_MappedQoS_FlowsList_r16->list.count;
DevAssert(sdap.mappedQFIs2AddCount <= SDAP_MAX_QFI);
LOG_D(SDAP, "SL DRB %d: mapped QFIs = %d \n", slrb_id, sdap.mappedQFIs2AddCount);
long standardized_PQI = 0;
for (int i = 0; i < sdap.mappedQFIs2AddCount; i++){
DevAssert(i < SDAP_MAX_QFI);
standardized_PQI = s->sl_SDAP_Config_r16->sl_MappedQoS_Flows_r16->choice.sl_MappedQoS_FlowsList_r16->list.array[i]->sl_PQI_r16->choice.sl_StandardizedPQI_r16;
if (standardized_PQI < SDAP_MAX_QFI)
sdap.mappedQFIs2Add[i] = standardized_PQI;
LOG_D(SDAP, "SL DRB %d: Captured mappedQoS_FlowsToAdd[%d] from RRC: %ld\n", slrb_id, i, sdap.mappedQFIs2Add[i]);
}
}
// add SDAP entity
nr_sdap_addmod_entity(GNB_FLAG_NO, srcid, &sdap);
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
nr_pdcp_ue_t *ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, srcid);
if (ue->drb[slrb_id-1] != NULL) {
LOG_W(PDCP, "%s:%d:%s: warning DRB %d already exist for UE ID/RNTI %ld, do nothing\n", __FILE__, __LINE__, __FUNCTION__, slrb_id, srcid);
} else {
pdcp_drb = new_nr_pdcp_entity(NR_PDCP_DRB_AM, 0, slrb_id, 0,
(sdap.role & (SDAP_UL_RX | SDAP_DL_RX)) != 0,
(sdap.role & (SDAP_UL_TX | SDAP_DL_TX)) != 0,
deliver_sdu_drb, ue, deliver_pdu_drb_ue, ue,
sn_size, t_reordering, discard_timer,
security_parameters);
nr_pdcp_ue_add_drb_pdcp_entity(ue, slrb_id, pdcp_drb);
LOG_I(PDCP, "%s:%d:%s: added slrb %d to UE ID %ld\n", __FILE__, __LINE__, __FUNCTION__, slrb_id, srcid);
//new_nr_sdap_entity(0, has_sdap, has_sdap, srcid, 0, is_sdap_DefaultRB, slrb_id, mappedQFIs2Add, mappedQFIs2AddCount);
}
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
}
void nr_pdcp_add_srbs(eNB_flag_t enb_flag,
ue_id_t UEid,
NR_SRB_ToAddModList_t *const srb2add_list,

View File

@@ -131,4 +131,6 @@ void nr_pdcp_count_update(ue_id_t ue_id,
void nr_pdcp_get_drb_count_values(ue_id_t ue_id, rb_id_t rb_id, nr_pdcp_count_t *ul_count, nr_pdcp_count_t *dl_count);
void add_drb_sl(ue_id_t srcid, NR_SL_RadioBearerConfig_r16_t *sl_rb_config, const nr_pdcp_entity_security_keys_and_algos_t *security_parameters);
#endif /* NR_PDCP_OAI_API_H */

View File

@@ -43,6 +43,13 @@
#include "openair3/ocp-gtpu/gtp_itf.h"
#include <stdint.h>
static logical_chan_id_t get_sl_lcid_from_drb(int drb_id)
{
logical_chan_id_t lcid = 4 + drb_id - 1;
AssertFatal(lcid >= 4 && lcid <= 19, "Invalid SL DRB ID %d for LCID %d\n", drb_id, lcid);
return lcid;
}
#include <executables/softmodem-common.h>
static nr_rlc_ue_manager_t *nr_rlc_ue_manager;
@@ -802,6 +809,71 @@ static void add_drb_am(int ue_id, int drb_id, const NR_RLC_BearerConfig_t *rlc_B
nr_rlc_manager_unlock(nr_rlc_ue_manager);
}
static void add_drb_am_sl(int src_id, int drb_id, const NR_SL_RLC_BearerConfig_r16_t *rlc_BearerConfig)
{
nr_rlc_entity_t *nr_rlc_am;
nr_rlc_ue_t *ue;
struct NR_SL_RLC_Config_r16 *r = rlc_BearerConfig->sl_RLC_Config_r16;
struct NR_SL_LogicalChannelConfig_r16 *l = rlc_BearerConfig->sl_MAC_LogicalChannelConfig_r16;
int logical_channel_group;
int t_status_prohibit;
int t_poll_retransmit;
int poll_pdu;
int poll_byte;
int max_retx_threshold;
int t_reassembly;
int sn_field_length;
if (!(drb_id >= 1 && drb_id <= MAX_DRBS_PER_UE)) {
LOG_E(RLC, "%s:%d:%s: fatal, bad srb id %d\n",
__FILE__, __LINE__, __FUNCTION__, drb_id);
exit(1);
}
logical_channel_group = *l->sl_LogicalChannelGroup_r16;
/* TODO: accept other values? */
if (logical_channel_group != 1) {
LOG_E(RLC, "%s:%d:%s: fatal error\n", __FILE__, __LINE__, __FUNCTION__);
//exit(1);
}
struct NR_SL_RLC_Config_r16__sl_AM_RLC_r16 *am;
am = r->choice.sl_AM_RLC_r16;
t_reassembly = 35;
t_status_prohibit = 35;
t_poll_retransmit = decode_t_poll_retransmit(am->sl_T_PollRetransmit_r16);
poll_pdu = decode_poll_pdu(am->sl_PollPDU_r16);
poll_byte = decode_poll_byte(am->sl_PollByte_r16);
max_retx_threshold = decode_max_retx_threshold(am->sl_MaxRetxThreshold_r16);
sn_field_length = decode_sn_field_length_am(*am->sl_SN_FieldLengthAM_r16);
nr_rlc_manager_lock(nr_rlc_ue_manager);
ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, src_id);
logical_chan_id_t lcid = get_sl_lcid_from_drb(drb_id);
ue->lcid2rb[lcid - 1].type = NR_LCID_DRB;
ue->lcid2rb[lcid - 1].choice.drb_id = drb_id;
if (ue->drb[drb_id-1] != NULL) {
LOG_W(RLC, "%s:%d:%s: DRB %d already exists for SL UE with src_id %04x, do nothing\n", __FILE__, __LINE__, __FUNCTION__, drb_id, src_id);
} else {
nr_rlc_am = new_nr_rlc_entity_am(RLC_RX_MAXSIZE,
RLC_TX_MAXSIZE,
deliver_sdu, ue,
successful_delivery, ue,
max_retx_reached, ue,
t_poll_retransmit,
t_reassembly, t_status_prohibit,
poll_pdu, poll_byte, max_retx_threshold,
sn_field_length);
nr_rlc_ue_add_drb_rlc_entity(ue, drb_id, nr_rlc_am);
LOG_I(RLC, "%s:%d:%s: added drb %d to UE with SRCID 0x%x\n", __FILE__, __LINE__, __FUNCTION__, drb_id, src_id);
}
nr_rlc_manager_unlock(nr_rlc_ue_manager);
}
static void add_drb_um(int ue_id, int drb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig)
{
struct NR_RLC_Config *r = rlc_BearerConfig->rlc_Config;
@@ -853,6 +925,57 @@ static void add_drb_um(int ue_id, int drb_id, const NR_RLC_BearerConfig_t *rlc_B
nr_rlc_manager_unlock(nr_rlc_ue_manager);
}
static void add_drb_um_sl(int src_id, int drb_id, const NR_SL_RLC_BearerConfig_r16_t *rlc_BearerConfig)
{
nr_rlc_entity_t *nr_rlc_um;
nr_rlc_ue_t *ue;
struct NR_SL_RLC_Config_r16 *r = rlc_BearerConfig->sl_RLC_Config_r16;
struct NR_SL_LogicalChannelConfig_r16 *l = rlc_BearerConfig->sl_MAC_LogicalChannelConfig_r16;
int logical_channel_group;
int sn_field_length;
int t_reassembly;
if (!(drb_id >= 1 && drb_id <= MAX_DRBS_PER_UE)) {
LOG_E(RLC, "%s:%d:%s: fatal, bad srb id %d\n",
__FILE__, __LINE__, __FUNCTION__, drb_id);
exit(1);
}
logical_channel_group = *l->sl_LogicalChannelGroup_r16;
/* TODO: accept other values? */
if (logical_channel_group != 1) {
LOG_E(RLC, "%s:%d:%s: fatal error\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
struct NR_SL_RLC_Config_r16__sl_UM_RLC_r16 *um;
um = r->choice.sl_UM_RLC_r16;
t_reassembly = 35; // up to UE implementation, choose 35ms
sn_field_length = decode_sn_field_length_um(*um->sl_SN_FieldLengthUM_r16);
nr_rlc_manager_lock(nr_rlc_ue_manager);
ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, src_id);
logical_chan_id_t lcid = get_sl_lcid_from_drb(drb_id);
ue->lcid2rb[lcid - 1].type = NR_LCID_DRB;
ue->lcid2rb[lcid - 1].choice.drb_id = drb_id;
if (ue->drb[drb_id-1] != NULL) {
LOG_W(RLC, "DEBUG add_drb_um %s:%d:%s: warning DRB %d already exist for SL ue %d, do nothing\n", __FILE__, __LINE__, __FUNCTION__, drb_id, src_id);
} else {
nr_rlc_um = new_nr_rlc_entity_um(RLC_RX_MAXSIZE,
RLC_TX_MAXSIZE,
deliver_sdu, ue,
t_reassembly,
sn_field_length);
nr_rlc_ue_add_drb_rlc_entity(ue, drb_id, nr_rlc_um);
LOG_D(RLC, "%s:%d:%s: added drb %d to UE with SRCID 0x%x\n", __FILE__, __LINE__, __FUNCTION__, drb_id, src_id);
}
nr_rlc_manager_unlock(nr_rlc_ue_manager);
}
void nr_rlc_add_drb(int ue_id, int drb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig)
{
switch (rlc_BearerConfig->rlc_Config->present) {
@@ -869,6 +992,23 @@ void nr_rlc_add_drb(int ue_id, int drb_id, const NR_RLC_BearerConfig_t *rlc_Bear
LOG_I(RLC, "Added DRB to UE %d\n", ue_id);
}
void nr_rlc_add_drb_sl(int srcid, int drb_id, const NR_SL_RLC_BearerConfig_r16_t *rlc_BearerConfig)
{
switch (rlc_BearerConfig->sl_RLC_Config_r16->present) {
case NR_SL_RLC_Config_r16_PR_sl_AM_RLC_r16:
add_drb_am_sl(srcid, drb_id, rlc_BearerConfig);
break;
case NR_SL_RLC_Config_r16_PR_sl_UM_RLC_r16:
add_drb_um_sl(srcid, drb_id, rlc_BearerConfig);
break;
default:
LOG_E(RLC, "%s:%d:%s: fatal: unhandled DRB type\n",
__FILE__, __LINE__, __FUNCTION__);
exit(1);
}
LOG_I(RLC, "%s:%s:%d: added SL_DRB %d to UE with SRCID 0x%x\n", __FILE__, __FUNCTION__, __LINE__, drb_id,srcid);
}
struct srb0_data {
int ue_id;
void *data;

View File

@@ -63,6 +63,7 @@ mac_rlc_status_resp_t nr_mac_rlc_status_ind(const uint16_t ue_id, const frame_t
void nr_rlc_add_srb(int ue_id, int srb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig);
void nr_rlc_add_drb(int ue_id, int drb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig);
void nr_rlc_add_drb_sl(int srcid, int drb_id, const NR_SL_RLC_BearerConfig_r16_t *rlc_BearerConfig);
void nr_rlc_set_rlf_handler(int ue_id, rlf_handler_t rlf_h);

View File

@@ -385,6 +385,86 @@ nr_ue_if_module_t *nr_ue_if_module_init(uint32_t module_id)
return nr_ue_if_module_inst[module_id];
}
/*
int nr_ue_scireq(nr_scireq_t *scireq) {
sl_nr_rx_config_request_t *sl_config = &scireq->sl_config_req;
NR_UE_MAC_INST_t *UE_mac = get_mac_inst(0);
sl_config->sfn = scireq->frame;
sl_config->slot = scireq->slot;
LOG_T(PHY, "Entering UE SCI configuration frame %d slot %d \n", scireq->frame, scireq->slot);
// ue_sci_configuration(UE_mac, sl_config, scireq->frame, scireq->slot);
return 0;
}
*/
/*
int nr_ue_sl_indication_rk(nr_sidelink_indication_t *sl_info)
{
pthread_mutex_lock(&mac_IF_mutex);
uint32_t ret_mask = 0x0;
module_id_t module_id = sl_info->module_id;
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
if ((!sl_info->sci_ind && !sl_info->rx_ind)) {
// indication to schedule SCI reception
if (mac->phy_config_request_sent)
nr_ue_sl_scheduler(sl_info);
} else {
// SL indication after reception of SCI or SL PDU
if (sl_info && sl_info->sci_ind && sl_info->sci_ind->number_of_SCIs) {
LOG_T(MAC,"[L2][IF MODULE][SL INDICATION][SCI_IND]\n");
for (int i = 0; i < sl_info->sci_ind->number_of_SCIs; i++) {
LOG_T(MAC,">>>NR_IF_Module i=%d, sl_info->sci_ind->number_of_scis=%d\n",i,sl_info->sci_ind->number_of_SCIs);
nr_scheduled_response_t scheduled_response;
int8_t ret = handle_sci(sl_info->module_id,
sl_info->frame_rx,
sl_info->slot_rx,
sl_info->sci_ind->sci_pdu+i);
if (ret < 0)
continue;
sl_nr_sci_indication_pdu_t *sci_index = sl_info->sci_ind->sci_pdu+i;
AssertFatal( nr_ue_if_module_inst[module_id] != NULL, "IF module is NULL!\n" );
AssertFatal( nr_ue_if_module_inst[module_id]->scheduled_response != NULL, "scheduled_response is NULL!\n" );
sl_nr_rx_config_request_t *sl_config = get_sl_config_request(mac, sl_info->slot_rx);
fill_sl_scheduled_response(&scheduled_response, sl_config, NULL, NULL, sl_info->module_id, sl_info->frame_rx, sl_info->slot_rx, sl_info->phy_data);
nr_ue_if_module_inst[module_id]->scheduled_response(&scheduled_response);
}
sl_info->sci_ind = NULL;
}
if (sl_info->rx_ind != NULL) {
for (int i = 0; i < sl_info->rx_ind->number_pdus; ++i) {
sl_nr_rx_indication_body_t rx_indication_body = sl_info->rx_ind->rx_indication_body[i];
LOG_D(NR_MAC, "Sending DL indication to MAC. 1 PDU type %d of %d total number of PDUs \n",
rx_indication_body.pdu_type,
sl_info->rx_ind->number_pdus);
switch(rx_indication_body.pdu_type){
case SL_NR_RX_PDU_TYPE_SSB:
break;
case SL_NR_RX_PDU_TYPE_SLSCH:
break;
default:
AssertFatal(1==0,"Unknown RX indication type\n");
break;
}
}
sl_info->rx_ind = NULL;
}
}
pthread_mutex_unlock(&mac_IF_mutex);
return ret_mask;
}
*/
static void handle_sl_bch(int ue_id,
sl_nr_ue_mac_params_t *sl_mac,
uint8_t *const sl_mib,
@@ -425,6 +505,28 @@ static void handle_sl_bch(int ue_id,
return;
}
int8_t handle_slsch(int module_idP,sl_nr_rx_indication_t *rx_ind,int pdu_id)
{
nr_ue_process_mac_sl_pdu(module_idP,rx_ind,pdu_id);
return 0;
}
void handle_sl_sci1a(module_id_t module_id, int cc_id, uint32_t frame, uint32_t slot, sl_nr_sci_indication_pdu_t *const sci, void *phy_data) {
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
nr_ue_process_sci1_indication_pdu(mac,module_id,cc_id,frame,slot,sci,phy_data);
}
void handle_sl_sci2(module_id_t module_id, int cc_id, uint32_t frame, uint32_t slot, sl_nr_sci_indication_pdu_t *const sci, void *phy_data) {
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
nr_ue_process_sci2_indication_pdu(mac, module_id, cc_id, frame, slot, sci, phy_data);
}
/*
if PSBCH rx - handle_psbch()
- Extract FN, Slot
@@ -466,11 +568,46 @@ void sl_nr_process_rx_ind(int ue_id,
break;
case SL_NR_RX_PDU_TYPE_SLSCH:
case SL_NR_RX_PDU_TYPE_SLSCH_PSFCH:
LOG_D(NR_MAC, "[UE%d]SL-MAC Received SLSCH: rx_slsch_pdu:%p, rx_slsch_len %d, ack_nack %d, harq_pid %d\n",
ue_id,
rx_ind->rx_indication_body[num_pdus - 1].rx_slsch_pdu.pdu,
rx_ind->rx_indication_body[num_pdus - 1].rx_slsch_pdu.pdu_length,
rx_ind->rx_indication_body[num_pdus - 1].rx_slsch_pdu.ack_nack,
rx_ind->rx_indication_body[num_pdus - 1].rx_slsch_pdu.harq_pid);
handle_slsch(ue_id, rx_ind, 0);
break;
default:
AssertFatal(1 == 0, "Incorrect type received. %s\n", __FUNCTION__);
break;
}
}
/* Process SCI indication from PHY */
void sl_nr_process_sci_ind(uint16_t module_id, int cc_id, uint32_t frame, uint32_t slot, sl_nr_ue_mac_params_t *sl_mac, sl_nr_sci_indication_t *sci_ind, void *phy_data) {
uint8_t num_SCIs = sci_ind->number_of_SCIs;
for (int idx=0;idx<num_SCIs;idx++) {
switch (sci_ind->sci_pdu[idx].sci_format_type) {
case SL_SCI_FORMAT_1A_ON_PSCCH:
LOG_D(NR_MAC,"%d.%d Received PSCCH PDU %d/%d PSCCH RSRP %d, length %d, sub-channel index %d, Nid %x, payload %llx\n", sci_ind->sfn,sci_ind->slot,1+idx,num_SCIs,sci_ind->sci_pdu[idx].pscch_rsrp,sci_ind->sci_pdu[idx].sci_payloadlen,sci_ind->sci_pdu[idx].subch_index,sci_ind->sci_pdu[idx].Nid,*(unsigned long long*)sci_ind->sci_pdu[idx].sci_payloadBits);
handle_sl_sci1a(module_id, cc_id, frame, slot, &sci_ind->sci_pdu[idx], phy_data);
break;
case SL_SCI_FORMAT_2_ON_PSSCH:
LOG_D(NR_MAC,"%d.%d Received PSSCH PDU %d/%d PSSCH RSRP %d, length %d, payload %llx\n", sci_ind->sfn,sci_ind->slot,1+idx,num_SCIs,sci_ind->sci_pdu[idx].pscch_rsrp,sci_ind->sci_pdu[idx].sci_payloadlen,*(unsigned long long*)sci_ind->sci_pdu[idx].sci_payloadBits);
handle_sl_sci2(module_id, cc_id, frame, slot, &sci_ind->sci_pdu[idx], phy_data);
break;
default:
AssertFatal(1==0,"Unhandled or unknown sci format %d\n",sci_ind->sci_pdu[idx].sci_format_type);
break;
}
}
}
@@ -484,6 +621,7 @@ void nr_ue_sl_indication(nr_sidelink_indication_t *sl_indication)
{
// NR_UE_L2_STATE_t ret;
int ue_id = sl_indication->module_id;
int cc_id = sl_indication->cc_id;
NR_UE_MAC_INST_t *mac = get_mac_inst(ue_id);
uint16_t slot = sl_indication->slot_rx;
@@ -493,6 +631,8 @@ void nr_ue_sl_indication(nr_sidelink_indication_t *sl_indication)
if (sl_indication->rx_ind) {
sl_nr_process_rx_ind(ue_id, frame, slot, sl_mac, sl_indication->rx_ind);
} else if (sl_indication->sci_ind) {
sl_nr_process_sci_ind(ue_id, cc_id, frame, slot, sl_mac, sl_indication->sci_ind, sl_indication->phy_data);
} else {
nr_ue_sidelink_scheduler(sl_indication, mac);
}

View File

@@ -123,6 +123,7 @@ void nr_mac_rrc_data_ind_ue(const module_id_t module_id,
NR_RRC_MAC_SBCCH_DATA_IND (message_p).frame = frame; //frameP
NR_RRC_MAC_SBCCH_DATA_IND (message_p).slot = slot;
NR_RRC_MAC_SBCCH_DATA_IND (message_p).sdu_size = sdu_size;
NR_RRC_MAC_SBCCH_DATA_IND (message_p).gnb_index = gNB_index;
NR_RRC_MAC_SBCCH_DATA_IND(message_p).rx_slss_id = cellid; // cellid is rx slss id
itti_send_msg_to_task(TASK_RRC_NRUE, GNB_MODULE_ID_TO_INSTANCE(module_id), message_p);
}

View File

@@ -43,6 +43,7 @@ void nr_mac_rrc_meas_ind_ue(module_id_t module_id,
bool csi_meas,
bool is_neighboring_cell,
int rsrp_dBm);
void nr_mac_rrc_inactivity_timer_ind(const module_id_t mod_id);
void nr_mac_rrc_msg3_ind(const module_id_t mod_id, const int rnti, bool prepare_payload);
void nr_ue_rrc_timer_trigger(int instance, int frame, int gnb_id);

View File

@@ -2681,6 +2681,8 @@ void *rrc_nrue(void *notUsed)
nr_rrc_ue_decode_NR_SBCCH_SL_BCH_Message(rrc, sbcch->gnb_index,sbcch->frame, sbcch->slot, sbcch->sdu,
sbcch->sdu_size, sbcch->rx_slss_id);
break;
case NR_RRC_MAC_MEAS_DATA_IND:
LOG_D(NR_RRC, "[%s][Nid_cell %i] Received %s measurements: RSRP = %i (dBm)\n",
@@ -3057,15 +3059,25 @@ void handle_t430_expiry(NR_UE_RRC_INST_t *rrc)
}
//This calls the sidelink preconf message after RRC, MAC instances are created.
void start_sidelink(int instance)
void start_sidelink(int instance, ueinfo_t *ueinfo)
{
NR_UE_RRC_INST_t *rrc = get_NR_UE_rrc_inst(instance);
nr_pdcp_entity_security_keys_and_algos_t security_up_parameters = get_security_rrc_parameters(rrc, false);
// these 3 are configured differently in Sidelink
int has_integrity = 0;
int has_ciphering = 0;
// int has_rohc = 0;
security_up_parameters.ciphering_algorithm = has_ciphering ? rrc->cipheringAlgorithm : 0;
security_up_parameters.integrity_algorithm = has_integrity ? rrc->integrityProtAlgorithm : 0;
if (get_softmodem_params()->sl_mode == 2) {
AssertFatal(ueinfo != NULL, "Sidelink UE info not configured\n");
//Process the Sidelink Preconfiguration
rrc_ue_process_sidelink_Preconfiguration(rrc, get_softmodem_params()->sync_ref);
rrc_ue_process_sidelink_Preconfiguration(rrc, get_softmodem_params()->sync_ref, ueinfo, &security_up_parameters);
}
}

View File

@@ -40,6 +40,8 @@
#include "NR_CellGroupConfig.h"
#include "NR_RadioBearerConfig.h"
#include "common/utils/ocp_itti/intertask_interface.h"
#include "executables/nr-uesoftmodem.h"
#include "LAYER2/nr_pdcp/nr_pdcp_oai_api.h"
NR_UE_RRC_INST_t *nr_rrc_init_ue(char* uecap_file, int nb_inst, int num_ant_tx);
NR_UE_RRC_INST_t* get_NR_UE_rrc_inst(int instance);
@@ -87,11 +89,12 @@ void nr_rrc_handle_SetupRelease_RLF_TimersAndConstants(NR_UE_RRC_INST_t *rrc,
struct NR_SetupRelease_RLF_TimersAndConstants *rlf_TimersAndConstants);
int configure_NR_SL_Preconfig(NR_UE_RRC_INST_t *rrc,int sync_source);
//void nr_UE_configure_Sidelink(uint8_t id, uint8_t is_sync_source, ueinfo_t *ueinfo);
void init_sidelink(NR_UE_RRC_INST_t *rrc);
void start_sidelink(int instance);
void start_sidelink(int instance, ueinfo_t *ueinfo);
void rrc_ue_process_sidelink_Preconfiguration(NR_UE_RRC_INST_t *rrc_inst, int sync_ref);
void rrc_ue_process_sidelink_Preconfiguration(NR_UE_RRC_INST_t *rrc_inst, int sync_ref, ueinfo_t *ueinfo, nr_pdcp_entity_security_keys_and_algos_t *security_up_parameters);
void nr_rrc_ue_decode_NR_SBCCH_SL_BCH_Message(NR_UE_RRC_INST_t *rrc,
const uint8_t gNB_index,
@@ -105,4 +108,3 @@ void nr_rrc_set_mac_queue(instance_t instance, notifiedFIFO_t *mac_input_nf);
/** @}*/
#endif

View File

@@ -30,6 +30,19 @@
#include "rrc_defs.h"
#include "LAYER2/NR_MAC_UE/mac_proto.h"
#include "nr-uesoftmodem.h"
#include "tun_if.h"
#include "LAYER2/nr_rlc/nr_rlc_oai_api.h"
#include "LAYER2/nr_pdcp/nr_pdcp_oai_api.h"
#include "openair2/SDAP/nr_sdap/nr_sdap.h"
#include "openair2/SDAP/nr_sdap/nr_sdap_entity.h"
#define GNSS_SUPPORT 0
#define SL_SYNC_SOURCE_NONE 0 //No sync source selected
#define SL_SYNC_SOURCE_GNBENB 1 // GNB/ENB as sync source
#define SL_SYNC_SOURCE_GNSS 2 // GPS as sync source
#define SL_SYNC_SOURCE_SYNC_REF_UE 3 // another SYNC REF UE as sync source
#define SL_SYNC_SOURCE_LOCAL_TIMING 4 //UE acts as sync source
void free_sl_rrc(NR_UE_RRC_INST_t *rrc)
{
@@ -109,6 +122,15 @@ static void prepare_NR_SL_ResourcePool(NR_SL_ResourcePool_r16_t *sl_res_pool,
sl_res_pool->sl_PSSCH_Config_r16 = calloc(1, sizeof(NR_SetupRelease_SL_PSSCH_Config_r16_t));
sl_res_pool->sl_PSSCH_Config_r16->present = NR_SetupRelease_SL_PSSCH_Config_r16_PR_setup;
sl_res_pool->sl_PSSCH_Config_r16->choice.setup = calloc(1, sizeof(NR_SL_PSSCH_Config_r16_t));
sl_res_pool->sl_PSSCH_Config_r16->choice.setup->sl_BetaOffsets2ndSCI_r16 =
calloc(1, sizeof(*sl_res_pool->sl_PSSCH_Config_r16->choice.setup->sl_BetaOffsets2ndSCI_r16));
for(int i=0; i<4; i++) {
long *p = calloc(1, sizeof(long));
*p = i<<2; // valid values: 0...15, for the moment choose 0,4,8,12
ASN_SEQUENCE_ADD(&sl_res_pool->sl_PSSCH_Config_r16->choice.setup->sl_BetaOffsets2ndSCI_r16->list, p);
}
sl_res_pool->sl_PSSCH_Config_r16->choice.setup->sl_PSSCH_DMRS_TimePatternList_r16 =
calloc(1, sizeof(*sl_res_pool->sl_PSSCH_Config_r16->choice.setup->sl_PSSCH_DMRS_TimePatternList_r16));
for(int i=0; i<3; i++) {
@@ -117,8 +139,35 @@ static void prepare_NR_SL_ResourcePool(NR_SL_ResourcePool_r16_t *sl_res_pool,
ASN_SEQUENCE_ADD(&sl_res_pool->sl_PSSCH_Config_r16->choice.setup->sl_PSSCH_DMRS_TimePatternList_r16->list, p);
}
//PSFCH configuration
sl_res_pool->sl_PSFCH_Config_r16 = NULL;
// This should be added to configuration file
sl_res_pool->sl_PSSCH_Config_r16->choice.setup->sl_Scaling_r16 = calloc(1,sizeof(*sl_res_pool->sl_PSSCH_Config_r16->choice.setup->sl_Scaling_r16));
*sl_res_pool->sl_PSSCH_Config_r16->choice.setup->sl_Scaling_r16 = NR_SL_PSSCH_Config_r16__sl_Scaling_r16_f0p5;
// PSFCH configuration
sl_res_pool->sl_PSFCH_Config_r16 = calloc(1, sizeof(*sl_res_pool->sl_PSFCH_Config_r16));
sl_res_pool->sl_PSFCH_Config_r16->present = NR_SetupRelease_SL_PSFCH_Config_r16_PR_setup;
sl_res_pool->sl_PSFCH_Config_r16->choice.setup = calloc(1, sizeof(NR_SL_PSFCH_Config_r16_t));
// Period of PSFCH resource in the unit of slots within this resource pool. If set to sl0, no resource for PSFCH,
//and HARQ feedback for all transmissions in the resource pool is disabled.
// {sl0, sl1, sl2, sl4}
sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_PSFCH_Period_r16 = calloc(1, sizeof(long));
// Set of PRBs that are actually used for PSFCH transmission and reception (bitmap)
// 0xFFFFFFFFFFFF (PRBs bitmap) Multiple of sl_NumSubchannel * sl_PSFCH_Period
sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_PSFCH_RB_Set_r16 = calloc(1, sizeof(*sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_PSFCH_RB_Set_r16));
// Number of cyclic shift pairs used for a PSFCH transmission that can be multiplexed in a PRB
sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_NumMuxCS_Pair_r16 = calloc(1, sizeof(long));
// The minimum time gap between PSFCH and the associated PSSCH in the unit of slots {sl2, sl3}
sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_MinTimeGapPSFCH_r16 = calloc(1, sizeof(long));
// Scrambling ID {0..1023} for sequence hopping of the PSFCH used in the resource pool
sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_PSFCH_HopID_r16 = calloc(1, sizeof(long));
// Indicates the number of PSFCH resources available {startSubCH, allocSubCH} for multiplexing HARQ-ACK information in a PSFCH transmission
sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_PSFCH_CandidateResourceType_r16 = calloc(1, sizeof(long));
// indicates allowed sync sources which are allowed to use this resource pool
sl_res_pool->sl_SyncAllowed_r16 = calloc(1, sizeof(NR_SL_SyncAllowed_r16_t));
@@ -153,7 +202,9 @@ static void prepare_NR_SL_ResourcePool(NR_SL_ResourcePool_r16_t *sl_res_pool,
sl_res_pool->sl_TimeWindowSizeCBR_r16 = NULL;
sl_res_pool->sl_TimeWindowSizeCR_r16 = NULL;
sl_res_pool->sl_PTRS_Config_r16 = NULL;
sl_res_pool->sl_UE_SelectedConfigRP_r16 = NULL;
sl_res_pool->sl_UE_SelectedConfigRP_r16 = calloc(1,sizeof(*sl_res_pool->sl_UE_SelectedConfigRP_r16));
sl_res_pool->sl_UE_SelectedConfigRP_r16->sl_MaxNumPerReserve_r16 = calloc(1,sizeof(*sl_res_pool->sl_UE_SelectedConfigRP_r16->sl_MaxNumPerReserve_r16));
sl_res_pool->sl_RxParametersNcell_r16 = NULL;
sl_res_pool->sl_ZoneConfigMCR_List_r16 = NULL;
sl_res_pool->sl_FilterCoefficient_r16 = NULL;
@@ -165,8 +216,13 @@ static void prepare_NR_SL_ResourcePool(NR_SL_ResourcePool_r16_t *sl_res_pool,
sl_res_pool->sl_PriorityThreshold_UL_URLLC_r16 = NULL;
sl_res_pool->sl_PriorityThreshold_r16 = NULL;
sl_res_pool->sl_X_Overhead_r16 = NULL;
sl_res_pool->sl_PowerControl_r16 = NULL;
sl_res_pool->sl_TxPercentageList_r16 = NULL;
sl_res_pool->sl_PowerControl_r16 = calloc(1,sizeof(*sl_res_pool->sl_PowerControl_r16));
sl_res_pool->sl_PowerControl_r16->sl_Alpha_PSSCH_PSCCH_r16 = calloc(1,sizeof(*sl_res_pool->sl_PowerControl_r16->sl_Alpha_PSSCH_PSCCH_r16));
*sl_res_pool->sl_PowerControl_r16->sl_Alpha_PSSCH_PSCCH_r16 = 0;
sl_res_pool->sl_TxPercentageList_r16 = calloc(1, sizeof(*sl_res_pool->sl_TxPercentageList_r16));
sl_res_pool->sl_TxPercentageList_r16->list.array = (NR_SL_TxPercentageConfig_r16_t **)malloc16_clear(sizeof(NR_SL_TxPercentageConfig_r16_t*));
sl_res_pool->sl_TxPercentageList_r16->list.array[0] = (NR_SL_TxPercentageConfig_r16_t *)malloc16_clear(sizeof(NR_SL_TxPercentageConfig_r16_t));
sl_res_pool->sl_MinMaxMCS_List_r16 = NULL;
sl_res_pool->ext1 = calloc(1, sizeof(*sl_res_pool->ext1));
@@ -193,9 +249,72 @@ static void prepare_NR_SL_ResourcePool(NR_SL_ResourcePool_r16_t *sl_res_pool,
if (is_txpool)
sprintf(aprefix, "%s.[%i].%s.[%i]", SL_CONFIG_STRING_SL_PRECONFIGURATION, 0,SL_CONFIG_STRING_SL_TX_RPOOL_LIST, 0);
else
{
sprintf(aprefix, "%s.[%i].%s.[%i]", SL_CONFIG_STRING_SL_PRECONFIGURATION, 0,SL_CONFIG_STRING_SL_RX_RPOOL_LIST, 0);
}
config_get(config_get_if(), SL_POOLPARAMS, sizeofArray(SL_POOLPARAMS), aprefix);
config_get(config_get_if(), SL_POOLPARAMS, sizeofArray(SL_POOLPARAMS), aprefix);
sl_res_pool->sl_UE_SelectedConfigRP_r16->sl_SelectionWindowList_r16 = calloc(1, sizeof(*sl_res_pool->sl_UE_SelectedConfigRP_r16->sl_SelectionWindowList_r16));
struct NR_SL_UE_SelectedConfigRP_r16 *nr_sl_ue_Selected_config = sl_res_pool->sl_UE_SelectedConfigRP_r16;
nr_sl_ue_Selected_config->sl_SelectionWindowList_r16->list.array = (NR_SL_SelectionWindowConfig_r16_t**)malloc16_clear(sizeof(NR_SL_SelectionWindowConfig_r16_t*));
nr_sl_ue_Selected_config->sl_SelectionWindowList_r16->list.array[0] = (NR_SL_SelectionWindowConfig_r16_t*)malloc16_clear(sizeof(NR_SL_SelectionWindowConfig_r16_t));
nr_sl_ue_Selected_config->sl_SensingWindow_r16 = calloc(1, sizeof(*nr_sl_ue_Selected_config->sl_SensingWindow_r16));
nr_sl_ue_Selected_config->sl_Thres_RSRP_List_r16 = calloc(1, sizeof(*nr_sl_ue_Selected_config->sl_Thres_RSRP_List_r16));
nr_sl_ue_Selected_config->sl_Thres_RSRP_List_r16->list.array = (NR_SL_Thres_RSRP_r16_t**)malloc16_clear(sizeof(NR_SL_Thres_RSRP_r16_t*));
nr_sl_ue_Selected_config->sl_Thres_RSRP_List_r16->list.array[0] = (NR_SL_Thres_RSRP_r16_t*)malloc16_clear(sizeof(NR_SL_Thres_RSRP_r16_t));
nr_sl_ue_Selected_config->sl_MaxNumPerReserve_r16 = calloc(1, sizeof(*nr_sl_ue_Selected_config->sl_MaxNumPerReserve_r16));
nr_sl_ue_Selected_config->sl_ResourceReservePeriodList_r16 = calloc(1, sizeof(*nr_sl_ue_Selected_config->sl_ResourceReservePeriodList_r16));
nr_sl_ue_Selected_config->sl_ResourceReservePeriodList_r16->list.array = (NR_SL_ResourceReservePeriod_r16_t**)malloc16_clear(sizeof(NR_SL_ResourceReservePeriod_r16_t*));
nr_sl_ue_Selected_config->sl_ResourceReservePeriodList_r16->list.array[0] = (NR_SL_ResourceReservePeriod_r16_t*)malloc16_clear(sizeof(NR_SL_ResourceReservePeriod_r16_t));
char aprefix_rsc_sel[MAX_OPTNAME_SIZE*2 + 8];
paramdef_t SL_RSCSELECTIONPARAMS[] = SL_RSRCSELPARAMS_DESC(sl_res_pool);
sprintf(aprefix_rsc_sel, "%s.[%i].%s.[%i]", SL_CONFIG_STRING_SL_PRECONFIGURATION, 0,SL_CONFIG_STRING_RSRC_SEL_PARAMS_LIST, 0);
config_get(config_get_if(), SL_RSCSELECTIONPARAMS, sizeofArray(SL_RSCSELECTIONPARAMS), aprefix_rsc_sel);
LOG_D(NR_RRC, "sl_MaxNumPerReserve %ld, sl_SensingWindow %ld, sl_Priority %ld, sl_SelectionWindow %ld, sl_ResourceReservePeriod1 %ld\n",
*sl_res_pool->sl_UE_SelectedConfigRP_r16->sl_MaxNumPerReserve_r16,
*sl_res_pool->sl_UE_SelectedConfigRP_r16->sl_SensingWindow_r16,
sl_res_pool->sl_UE_SelectedConfigRP_r16->sl_SelectionWindowList_r16->list.array[0]->sl_Priority_r16,
sl_res_pool->sl_UE_SelectedConfigRP_r16->sl_SelectionWindowList_r16->list.array[0]->sl_SelectionWindow_r16,
sl_res_pool->sl_UE_SelectedConfigRP_r16->sl_ResourceReservePeriodList_r16->list.array[0]->choice.sl_ResourceReservePeriod1_r16);
struct NR_SL_PSFCH_Config_r16 *nr_sl_psfch_config = sl_res_pool->sl_PSFCH_Config_r16->choice.setup;
if (*nr_sl_psfch_config->sl_PSFCH_Period_r16 > 0) {
const uint8_t psfch_periods[] = {0,1,2,4};
AssertFatal(*nr_sl_psfch_config->sl_PSFCH_Period_r16 < 4, "sl_PSFCH_Period_r16 index must be less than 4\n");
LOG_D(NR_PHY, "Configuring PSFCH Period %d\n", psfch_periods[*nr_sl_psfch_config->sl_PSFCH_Period_r16]);
uint8_t psfch_period = psfch_periods[*nr_sl_psfch_config->sl_PSFCH_Period_r16];
uint16_t prod_numCh_period = *sl_res_pool->sl_NumSubchannel_r16*psfch_period;
uint16_t num_prbs = (*sl_res_pool->sl_RB_Number_r16 / prod_numCh_period) * prod_numCh_period;
uint16_t num_bytes = (num_prbs % 8) ? (num_prbs / 8) + 1 : (num_prbs / 8);
sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_PSFCH_RB_Set_r16->size = num_bytes;
sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_PSFCH_RB_Set_r16->bits_unused = (num_prbs % 8) ? 8 - (num_prbs % 8) : 0;
sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_PSFCH_RB_Set_r16->buf = calloc(sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_PSFCH_RB_Set_r16->size, sizeof(uint8_t));
memset(sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_PSFCH_RB_Set_r16->buf, 0xFF, num_prbs / 8);
uint8_t remaining_prbs = 0;
for (int i = 8 - (num_prbs % 8); i < 8; i++)
remaining_prbs |= 1 << i;
if ( num_prbs % 8 != 0 )
sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_PSFCH_RB_Set_r16->buf[num_prbs/8] = remaining_prbs;
LOG_D(RRC, "M: %d, PRBs %d, size in bytes %d, unused bits %d, full size bytes %d, remaining prbs %d\n", prod_numCh_period, num_prbs, num_bytes, (num_prbs % 8) ? 8 - (num_prbs % 8) : 0, num_prbs / 8, remaining_prbs);
} else {
LOG_I(NR_RRC,"Freeing sl_PSFCH_Config_r16\n");
free(sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_PSFCH_CandidateResourceType_r16);
free(sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_PSFCH_HopID_r16);
free(sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_MinTimeGapPSFCH_r16);
free(sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_NumMuxCS_Pair_r16);
free(sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_PSFCH_RB_Set_r16);
free(sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_PSFCH_Period_r16);
free(sl_res_pool->sl_PSFCH_Config_r16->choice.setup);
free(sl_res_pool->sl_PSFCH_Config_r16);
sl_res_pool->sl_PSFCH_Config_r16 = NULL;
}
}
static void prepare_NR_SL_BWPConfigCommon(NR_SL_BWP_ConfigCommon_r16_t *sl_bwp,
@@ -352,11 +471,64 @@ NR_SL_PreconfigurationNR_r16_t *prepare_NR_SL_PRECONFIGURATION(uint16_t num_tx_p
sl_preconfig->sl_PreconfigEUTRA_AnchorCarrierFreqList_r16 = NULL;
// NR sidelink radio bearer(s) configuration(s)
sl_preconfig->sl_RadioBearerPreConfigList_r16 = NULL; // fill later
sl_preconfig->sl_RadioBearerPreConfigList_r16 = calloc(1,sizeof(*sl_preconfig->sl_RadioBearerPreConfigList_r16)); // fill later
struct NR_SL_RadioBearerConfig_r16 *sl_RadioBearerConfig_r16 = calloc(1,sizeof(*sl_RadioBearerConfig_r16));
sl_RadioBearerConfig_r16->slrb_Uu_ConfigIndex_r16 = 1;
sl_RadioBearerConfig_r16->sl_SDAP_Config_r16 = calloc(1, sizeof(*sl_RadioBearerConfig_r16->sl_SDAP_Config_r16));
struct NR_SL_SDAP_Config_r16* sl_SDAP_Config = sl_RadioBearerConfig_r16->sl_SDAP_Config_r16;
sl_SDAP_Config->sl_SDAP_Header_r16 = NR_SL_SDAP_Config_r16__sl_SDAP_Header_r16_present;
sl_SDAP_Config->sl_DefaultRB_r16 = true;
sl_SDAP_Config->sl_CastType_r16 = calloc(1, sizeof(*sl_SDAP_Config->sl_CastType_r16));
*sl_SDAP_Config->sl_CastType_r16 = NR_SL_SDAP_Config_r16__sl_CastType_r16_unicast;
sl_SDAP_Config->sl_MappedQoS_Flows_r16 = calloc(1, sizeof(*sl_SDAP_Config->sl_MappedQoS_Flows_r16));
sl_SDAP_Config->sl_MappedQoS_Flows_r16->choice.sl_MappedQoS_FlowsList_r16 = calloc(1, sizeof(*sl_SDAP_Config->sl_MappedQoS_Flows_r16->choice.sl_MappedQoS_FlowsList_r16));
struct NR_SL_SDAP_Config_r16__sl_MappedQoS_Flows_r16__sl_MappedQoS_FlowsList_r16* sl_MappedQoS_FlowList = sl_SDAP_Config->sl_MappedQoS_Flows_r16->choice.sl_MappedQoS_FlowsList_r16;
NR_SL_QoS_Profile_r16_t *sl_QoS_Profile_r16_f1 = calloc(1, sizeof(*sl_QoS_Profile_r16_f1));
sl_QoS_Profile_r16_f1->sl_PQI_r16 = calloc(1, sizeof(*sl_QoS_Profile_r16_f1->sl_PQI_r16));
struct NR_SL_PQI_r16 *sl_PQI = sl_QoS_Profile_r16_f1->sl_PQI_r16;
sl_PQI->choice.sl_StandardizedPQI_r16 = 55;
ASN_SEQUENCE_ADD(&sl_MappedQoS_FlowList->list, sl_QoS_Profile_r16_f1);
sl_RadioBearerConfig_r16->sl_TransRange_r16 = NULL;
sl_RadioBearerConfig_r16->sl_PDCP_Config_r16 = calloc(1,sizeof(*sl_RadioBearerConfig_r16));
sl_RadioBearerConfig_r16->sl_PDCP_Config_r16->sl_DiscardTimer_r16 = calloc(1,sizeof(*sl_RadioBearerConfig_r16->sl_PDCP_Config_r16->sl_DiscardTimer_r16));
*sl_RadioBearerConfig_r16->sl_PDCP_Config_r16->sl_DiscardTimer_r16 = NR_SL_PDCP_Config_r16__sl_DiscardTimer_r16_infinity;
sl_RadioBearerConfig_r16->sl_PDCP_Config_r16->sl_PDCP_SN_Size_r16 = calloc(1,sizeof(*sl_RadioBearerConfig_r16->sl_PDCP_Config_r16->sl_PDCP_SN_Size_r16));
*sl_RadioBearerConfig_r16->sl_PDCP_Config_r16->sl_PDCP_SN_Size_r16 = NR_SL_PDCP_Config_r16__sl_PDCP_SN_Size_r16_len12bits;
sl_RadioBearerConfig_r16->sl_PDCP_Config_r16->sl_OutOfOrderDelivery = NULL;
ASN_SEQUENCE_ADD(&sl_preconfig->sl_RadioBearerPreConfigList_r16->list,sl_RadioBearerConfig_r16);
// NR sidelink RLC bearer(s) configuration(s)
sl_preconfig->sl_RLC_BearerPreConfigList_r16 = NULL; // fill later
sl_preconfig->sl_RLC_BearerPreConfigList_r16 = calloc(1,sizeof(*sl_preconfig->sl_RLC_BearerPreConfigList_r16));
struct NR_SL_RLC_BearerConfig_r16 *sl_RLC_BearerConfig_r16 = calloc(1,sizeof(*sl_RLC_BearerConfig_r16));
// initialize with UM for now
sl_RLC_BearerConfig_r16->sl_RLC_BearerConfigIndex_r16 = 0;
sl_RLC_BearerConfig_r16->sl_ServedRadioBearer_r16 = calloc(1,sizeof(*sl_RLC_BearerConfig_r16->sl_ServedRadioBearer_r16));
*sl_RLC_BearerConfig_r16->sl_ServedRadioBearer_r16 = 1;
sl_RLC_BearerConfig_r16->sl_RLC_Config_r16 = calloc(1,sizeof(*sl_RLC_BearerConfig_r16->sl_RLC_Config_r16));
sl_RLC_BearerConfig_r16->sl_RLC_Config_r16->present = NR_SL_RLC_Config_r16_PR_sl_UM_RLC_r16;
sl_RLC_BearerConfig_r16->sl_RLC_Config_r16->choice.sl_UM_RLC_r16 = calloc(1,sizeof(*sl_RLC_BearerConfig_r16->sl_RLC_Config_r16->choice.sl_UM_RLC_r16));
sl_RLC_BearerConfig_r16->sl_RLC_Config_r16->choice.sl_UM_RLC_r16->sl_SN_FieldLengthUM_r16=calloc(1,sizeof(*sl_RLC_BearerConfig_r16->sl_MAC_LogicalChannelConfig_r16));
*sl_RLC_BearerConfig_r16->sl_RLC_Config_r16->choice.sl_UM_RLC_r16->sl_SN_FieldLengthUM_r16=NR_SN_FieldLengthUM_size6;
// Logical Channel Config for default link
sl_RLC_BearerConfig_r16->sl_MAC_LogicalChannelConfig_r16 = calloc(1,sizeof(*sl_RLC_BearerConfig_r16->sl_MAC_LogicalChannelConfig_r16));
sl_RLC_BearerConfig_r16->sl_MAC_LogicalChannelConfig_r16->sl_Priority_r16 = 1;
sl_RLC_BearerConfig_r16->sl_MAC_LogicalChannelConfig_r16->sl_PrioritisedBitRate_r16 = NR_SL_LogicalChannelConfig_r16__sl_PrioritisedBitRate_r16_infinity;
sl_RLC_BearerConfig_r16->sl_MAC_LogicalChannelConfig_r16->sl_BucketSizeDuration_r16 = NR_SL_LogicalChannelConfig_r16__sl_BucketSizeDuration_r16_ms5;
sl_RLC_BearerConfig_r16->sl_MAC_LogicalChannelConfig_r16->sl_ConfiguredGrantType1Allowed_r16 = NULL;
sl_RLC_BearerConfig_r16->sl_MAC_LogicalChannelConfig_r16->sl_HARQ_FeedbackEnabled_r16 = calloc(1,sizeof(*sl_RLC_BearerConfig_r16->sl_MAC_LogicalChannelConfig_r16->sl_HARQ_FeedbackEnabled_r16));
*sl_RLC_BearerConfig_r16->sl_MAC_LogicalChannelConfig_r16->sl_HARQ_FeedbackEnabled_r16 = NR_SL_LogicalChannelConfig_r16__sl_HARQ_FeedbackEnabled_r16_enabled;
sl_RLC_BearerConfig_r16->sl_MAC_LogicalChannelConfig_r16->sl_AllowedCG_List_r16 = NULL;
sl_RLC_BearerConfig_r16->sl_MAC_LogicalChannelConfig_r16->sl_AllowedSCS_List_r16 = NULL;
sl_RLC_BearerConfig_r16->sl_MAC_LogicalChannelConfig_r16->sl_LogicalChannelGroup_r16 = calloc(1,sizeof(*sl_RLC_BearerConfig_r16->sl_MAC_LogicalChannelConfig_r16->sl_LogicalChannelGroup_r16));
*sl_RLC_BearerConfig_r16->sl_MAC_LogicalChannelConfig_r16->sl_LogicalChannelGroup_r16 = 1;
sl_RLC_BearerConfig_r16->sl_MAC_LogicalChannelConfig_r16->sl_SchedulingRequestId_r16 = NULL;
sl_RLC_BearerConfig_r16->sl_MAC_LogicalChannelConfig_r16->sl_LogicalChannelSR_DelayTimerApplied_r16 = NULL;
ASN_SEQUENCE_ADD(&sl_preconfig->sl_RLC_BearerPreConfigList_r16->list,sl_RLC_BearerConfig_r16);
//Measurement and reporting configuration
sl_preconfig->sl_MeasPreConfig_r16 = NULL;
@@ -398,7 +570,7 @@ NR_SL_PreconfigurationNR_r16_t *prepare_NR_SL_PRECONFIGURATION(uint16_t num_tx_p
sl_preconfig->sl_UE_SelectedPreConfig_r16 = NULL;
// indicates if CSI reporting supported in SL unicast.
sl_preconfig->sl_CSI_Acquisition_r16 = NULL;
sl_preconfig->sl_CSI_Acquisition_r16 = calloc(1, sizeof(*sl_preconfig->sl_CSI_Acquisition_r16));
// ROHC profiles for NR SL
sl_preconfig->sl_RoHC_Profiles_r16 = NULL;
@@ -508,19 +680,70 @@ void nr_rrc_ue_decode_NR_SBCCH_SL_BCH_Message(NR_UE_RRC_INST_t *rrc,
return;
}
static uint8_t get_sl_tun_qfi(NR_SL_PreconfigurationNR_r16_t *sl_preconfig)
{
NR_SL_RadioBearerConfig_r16_t *slrb =
sl_preconfig->sidelinkPreconfigNR_r16.sl_RadioBearerPreConfigList_r16->list.array[0];
DevAssert(slrb != NULL);
struct NR_SL_SDAP_Config_r16 *sdap = slrb->sl_SDAP_Config_r16;
DevAssert(sdap != NULL && sdap->sl_MappedQoS_Flows_r16 != NULL);
struct NR_SL_SDAP_Config_r16__sl_MappedQoS_Flows_r16__sl_MappedQoS_FlowsList_r16 *flows =
sdap->sl_MappedQoS_Flows_r16->choice.sl_MappedQoS_FlowsList_r16;
DevAssert(flows != NULL && flows->list.count > 0);
NR_SL_QoS_Profile_r16_t *profile = flows->list.array[0];
DevAssert(profile != NULL && profile->sl_PQI_r16 != NULL);
const long standardized_PQI = profile->sl_PQI_r16->choice.sl_StandardizedPQI_r16;
DevAssert(standardized_PQI >= 0 && standardized_PQI < SDAP_MAX_QFI);
return standardized_PQI;
}
void rrc_ue_process_sidelink_Preconfiguration(NR_UE_RRC_INST_t *rrc_inst,
sl_sync_source_enum_t sync_source)
sl_sync_source_enum_t sync_source,
ueinfo_t *ueinfo,
nr_pdcp_entity_security_keys_and_algos_t *security_up_parameters)
{
AssertFatal(rrc_inst, "RRC instance not created.\n");
NR_SL_PreconfigurationNR_r16_t *sl_preconfig = rrc_inst->sl_preconfig;
AssertFatal(rrc_inst->sl_preconfig, "Check if SL-preconfig was created");
AssertFatal(sync_source != SL_SYNC_SOURCE_GNBENB, "Sync source GNB not supported\n");
LOG_D(NR_RRC, "SL L2 SRCid %x, SL ipv4 addr X.X.%d.%d\n", ueinfo->srcid, ueinfo->thirdOctet, ueinfo->fourthOctet);
#if 0
nas_config(1 + ueinfo->srcid, ueinfo->thirdOctet, ueinfo->fourthOctet, "oai_sl_tun");
#else
char ip[20];
snprintf(ip,
sizeof(ip),
"10.0.%d.%d",
ueinfo->thirdOctet, ueinfo->fourthOctet);
char ifname[IFNAMSIZ];
tun_generate_ifname(ifname, "oai_sl_tun", ueinfo->srcid);
int sl_tun_sock = tun_alloc(ifname);
if (sl_tun_sock >= 0 && tun_config(ifname, ip, NULL))
{
setup_ue_ipv4_route(ifname, ueinfo->srcid, ip);
}
#endif
nr_rrc_mac_config_req_sl_preconfig(rrc_inst->ue_id, sl_preconfig, sync_source);
// SL RadioBearers
for (int i=0; i<sl_preconfig->sidelinkPreconfigNR_r16.sl_RadioBearerPreConfigList_r16->list.count; i++) {
add_drb_sl(ueinfo->srcid, (NR_SL_RadioBearerConfig_r16_t *)sl_preconfig->sidelinkPreconfigNR_r16.sl_RadioBearerPreConfigList_r16->list.array[i], security_up_parameters);
}
if (sl_tun_sock >= 0) {
set_qfi(get_sl_tun_qfi(sl_preconfig), 0, ueinfo->srcid);
start_sdap_tun_ue(ueinfo->srcid, 0, sl_tun_sock);
}
// configure RLC
for (int i=0; i<sl_preconfig->sidelinkPreconfigNR_r16.sl_RLC_BearerPreConfigList_r16->list.count; i++) {
nr_rlc_add_drb_sl(ueinfo->srcid, 1, (NR_SL_RLC_BearerConfig_r16_t *)sl_preconfig->sidelinkPreconfigNR_r16.sl_RLC_BearerPreConfigList_r16->list.array[i]);
}
//TBD.. These should be chosen by RRC according to 3GPP 38.331 RRC specification.
//Currently hardcoding the values to these
uint16_t slss_id = 671, ssb_ta_index = 1;

View File

@@ -74,9 +74,27 @@
#define SL_CONFIG_STRING_RESPOOL_SUBCH_START_RB "sl_StartRB_Subchannel"
#define SL_CONFIG_STRING_RESPOOL_NUM_RBS "sl_RB_Number"
#define SL_CONFIG_STRING_RESPOOL_NUM_SUBCHS "sl_NumSubchannel"
#define SL_CONFIG_STRING_RESPOOL_PSFCH_PERIOD "sl_PSFCH_Period"
#define SL_CONFIG_STRING_RESPOOL_PSFCH_RB_SET "sl_PSFCH_RB_Set"
#define SL_CONFIG_STRING_RESPOOL_PSFCH_NUMMUXCS_PAIR "sl_NumMuxCS_Pair"
#define SL_CONFIG_STRING_RESPOOL_PSFCH_MINTIMEGAP "sl_MinTimeGapPSFCH"
#define SL_CONFIG_STRING_RESPOOL_PSFCH_HOPID "sl_PSFCH_HopID"
#define SL_CONFIG_STRING_RESPOOL_PSFCH_CANDIDATERESOURCETYPE "sl_PSFCH_CandidateResourceType"
#define SL_CONFIG_STRING_RSRC_SEL_PRIORITY "sl_Priority"
#define SL_CONFIG_STRING_RSRC_SEL_PARAMS_LIST "rsrc_selection_params"
#define SL_CONFIG_STRING_RSRC_SEL_SELECTION_WINDOW "sl_SelectionWindow"
#define SL_CONFIG_STRING_RSRC_SEL_SENSING_WINDOW "sl_SensingWindow"
#define SL_CONFIG_STRING_RSRC_SEL_TRESHOLD_RSRP "sl_Thres_RSRP"
#define SL_CONFIG_STRING_RSRC_SEL_MAXNUM_PER_RESERVE "sl_MaxNumPerReserve"
#define SL_CONFIG_STRING_RSRC_SEL_RESOURCE_RESERVED_PERIOD "sl_ResourceReservePeriod"
#define SL_CONFIG_STRING_RSRC_SEL_RS_FOR_SENSING "sl_RS_ForSensing"
#define SL_CONFIG_STRING_RSRC_SEL_TX_PERCENTAGE "sl_TxPercentage"
#define SL_CONFIG_STRING_UEINFO "sl_UEINFO"
#define SL_CONFIG_STRING_UEINFO_SRCID "srcid"
#define SL_CONFIG_STRING_UEINFO_IPV4ADDR_THIRD_OCTET "thirdOctet"
#define SL_CONFIG_STRING_UEINFO_IPV4ADDR_FOURTH_OCTET "fourthOctet"
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* Sidelink Frequency common Cell Config parameters */
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
@@ -148,11 +166,37 @@
*/
#define SL_RESPOOLPARAMS_DESC(sl_res_pool) { \
{SL_CONFIG_STRING_RESPOOL_PSCCH_NUMSYM,NULL,0,.i64ptr=sl_res_pool->sl_PSCCH_Config_r16->choice.setup->sl_TimeResourcePSCCH_r16,.defint64val=1,TYPE_INT64,0}, \
{SL_CONFIG_STRING_RESPOOL_PSCCH_NUMRBS,NULL,0,.i64ptr=sl_res_pool->sl_PSCCH_Config_r16->choice.setup->sl_FreqResourcePSCCH_r16,.defint64val=4,TYPE_INT64,0}, \
{SL_CONFIG_STRING_RESPOOL_PSCCH_NUMRBS,NULL,0,.i64ptr=sl_res_pool->sl_PSCCH_Config_r16->choice.setup->sl_FreqResourcePSCCH_r16,.defint64val=1,TYPE_INT64,0}, \
{SL_CONFIG_STRING_RESPOOL_SUBCH_SIZE_IN_RBS,NULL,0,.i64ptr=sl_res_pool->sl_SubchannelSize_r16,.defint64val=0,TYPE_INT64,0},\
{SL_CONFIG_STRING_RESPOOL_SUBCH_START_RB,NULL,0,.i64ptr=sl_res_pool->sl_StartRB_Subchannel_r16,.defint64val=0,TYPE_INT64,0},\
{SL_CONFIG_STRING_RESPOOL_NUM_RBS,NULL,0,.i64ptr=sl_res_pool->sl_RB_Number_r16,.defint64val=106,TYPE_INT64,0},\
{SL_CONFIG_STRING_RESPOOL_NUM_SUBCHS,NULL,0,.i64ptr=sl_res_pool->sl_NumSubchannel_r16,.defint64val=10,TYPE_INT64,0}}
{SL_CONFIG_STRING_RESPOOL_NUM_SUBCHS,NULL,0,.i64ptr=sl_res_pool->sl_NumSubchannel_r16,.defint64val=10,TYPE_INT64,0},\
{SL_CONFIG_STRING_RESPOOL_PSFCH_PERIOD,NULL,0,.i64ptr=sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_PSFCH_Period_r16,.defint64val=3,TYPE_INT64,0}, \
{SL_CONFIG_STRING_RESPOOL_PSFCH_NUMMUXCS_PAIR,NULL,0,.i64ptr=sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_NumMuxCS_Pair_r16,.defint64val=1,TYPE_INT64,0}, \
{SL_CONFIG_STRING_RESPOOL_PSFCH_MINTIMEGAP,NULL,0,.i64ptr=sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_MinTimeGapPSFCH_r16,.defint64val=1,TYPE_INT64,0}, \
{SL_CONFIG_STRING_RESPOOL_PSFCH_HOPID,NULL,0,.i64ptr=sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_PSFCH_HopID_r16,.defint64val=1,TYPE_INT64,0}, \
{SL_CONFIG_STRING_RESPOOL_PSFCH_CANDIDATERESOURCETYPE,NULL,0,.i64ptr=sl_res_pool->sl_PSFCH_Config_r16->choice.setup->sl_PSFCH_CandidateResourceType_r16,.defint64val=0,TYPE_INT64,0}}
#define SL_RSRCSELPARAMS_DESC(sl_rsrc_sel_pool) { \
{SL_CONFIG_STRING_RSRC_SEL_PRIORITY,NULL,0,.i64ptr=&sl_res_pool->sl_UE_SelectedConfigRP_r16->sl_SelectionWindowList_r16->list.array[0]->sl_Priority_r16,.defint64val=7,TYPE_INT64,0}, \
{SL_CONFIG_STRING_RSRC_SEL_SELECTION_WINDOW,NULL,0,.i64ptr=&sl_res_pool->sl_UE_SelectedConfigRP_r16->sl_SelectionWindowList_r16->list.array[0]->sl_SelectionWindow_r16,.defint64val=5,TYPE_INT64,0}, \
{SL_CONFIG_STRING_RSRC_SEL_SENSING_WINDOW,NULL,0,.i64ptr=sl_res_pool->sl_UE_SelectedConfigRP_r16->sl_SensingWindow_r16,.defint64val=6,TYPE_INT64,0}, \
{SL_CONFIG_STRING_RSRC_SEL_TRESHOLD_RSRP,NULL,0,.i64ptr=sl_res_pool->sl_UE_SelectedConfigRP_r16->sl_Thres_RSRP_List_r16->list.array[0],.defint64val=-128,TYPE_INT64,0}, \
{SL_CONFIG_STRING_RSRC_SEL_MAXNUM_PER_RESERVE,NULL,0,.i64ptr=sl_res_pool->sl_UE_SelectedConfigRP_r16->sl_MaxNumPerReserve_r16,.defint64val=1,TYPE_INT64,0}, \
{SL_CONFIG_STRING_RSRC_SEL_RESOURCE_RESERVED_PERIOD,NULL,0,.i64ptr=&sl_res_pool->sl_UE_SelectedConfigRP_r16->sl_ResourceReservePeriodList_r16->list.array[0]->choice.sl_ResourceReservePeriod1_r16,.defint64val=100,TYPE_INT64,0}, \
{SL_CONFIG_STRING_RSRC_SEL_RS_FOR_SENSING,NULL,0,.i64ptr=&sl_res_pool->sl_UE_SelectedConfigRP_r16->sl_RS_ForSensing_r16,.defint64val=1,TYPE_INT64,0}, \
{SL_CONFIG_STRING_RSRC_SEL_TX_PERCENTAGE,NULL,0,.i64ptr=&sl_res_pool->sl_TxPercentageList_r16->list.array[0]->sl_TxPercentage_r16,.defint64val=0,TYPE_INT64,0}, \
}
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* Sidelink Top-Level UE Info */
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/*
sl_srcid - 16-bit source ID used for LCID information and indexing in L2 stack
sl_ipv4addr - string containing ipv4 address for default SLRB
*/
#define SL_UEINFO_DESC(sl_ueinfo) { \
{SL_CONFIG_STRING_UEINFO_SRCID,NULL,0,.iptr=&ueinfo.srcid,.defintval=1,TYPE_INT,0}, \
{SL_CONFIG_STRING_UEINFO_IPV4ADDR_THIRD_OCTET,NULL,0,.iptr=&ueinfo.thirdOctet,.defintval=0,TYPE_INT,0}, \
{SL_CONFIG_STRING_UEINFO_IPV4ADDR_FOURTH_OCTET,NULL,0,.iptr=&ueinfo.fourthOctet,.defintval=1,TYPE_INT,0}}
#endif

View File

@@ -0,0 +1,28 @@
#/* configuration for channel modelisation */
#/* To be included in main config file when */
#/* channel modelisation is used (rfsimulator with chanmod options enabled) */
channelmod = {
max_chan=10;
modellist="modellist_rfsimu_1";
modellist_rfsimu_1 = (
{
model_name = "rfsimu_channel_ue0"
type = "AWGN";
ploss_dB = 10;
noise_power_dB = -10;
forgetfact = 0;
offset = 0;
ds_tdl = 0;
},
{
model_name = "rfsimu_channel_enB0"
type = "AWGN";
ploss_dB = 10;
noise_power_dB = -10;
forgetfact = 0;
offset = 0;
ds_tdl = 0;
}
);
};

View File

@@ -0,0 +1,28 @@
#/* configuration for channel modelisation */
#/* To be included in main config file when */
#/* channel modelisation is used (rfsimulator with chanmod options enabled) */
channelmod = {
max_chan=10;
modellist="modellist_rfsimu_1";
modellist_rfsimu_1 = (
{
model_name = "rfsimu_channel_ue0"
type = "AWGN";
ploss_dB = 10;
noise_power_dB = -10;
forgetfact = 0;
offset = 0;
ds_tdl = 0;
},
{
model_name = "rfsimu_channel_enB0"
type = "AWGN";
ploss_dB = 10;
noise_power_dB = -10;
forgetfact = 0;
offset = 0;
ds_tdl = 0;
}
);
};

View File

@@ -0,0 +1,155 @@
SIDELINK_PRECONFIGURATION = (
{
# TDD ULDL CONFIG used for sidelink
sl_dl_UL_TransmissionPeriodicity = 6;
sl_nrofDownlinkSlots = 6;
sl_nrofDownlinkSymbols = 0;
sl_nrofUplinkSlots = 4;
sl_nrofUplinkSymbols = 0;
sl_csi_rs = (
{
symb_l0 = 5;
# csi_type 2 is not supported 38211, 8.4.1.5.3
csi_Type = 1;
sl_powerControlOffset = 1;
sl_powerControlOffsetSS = 1;
slot_Offset = 0;
slot_Periodicity = 5;
# Indicates if CSI Reporting is enabled in UNICAST. is 0-ENABLED, 1-DISABLED
sl_CSI_Acquisition = 1;
sl_LatencyBoundCSI_Report = 8;
}
);
sl_AllowedResourceSelectionConfig = 3; // Supported only {0, 3, 4, 6}
sl_FrequencyCommonConfig = (
{
sl_offstToCarrier = 0;
sl_subcarrierSpacing = 1;//0-15Khz, 1-30Khz
sl_carrierBandwidth = 106;//numPRBs
#NR bands for Sidelink n47, n38. N47 - 5855Mhz - 5925Mhz
#SL SSB chosen to be located from RB10 to RB21. points to the middle of the SSB block.
#SSB location should be within Sidelink BWP
# this is 2584.95 MHz => 301 REs from PointA 25 PRBs + 1 RE
sl_absoluteFrequencySSB = 516990;
# this is 2575.92 MHz (center frequency is 2585.1 MHz
sl_absoluteFrequencyPointA = 515184;
}
);
sl_BWP = (
{
#RB start 0, RB size = 106. occupies complete Bw.
sl_locationAndBandwidth = 28875;
# Num Symbols used for Sidelink in an uplink slot
# Herein, sl_LengthSymbols represents an index; not the number of symbols.
# This index value can be from 0 to 7 representing the (7 to 14 symbols)
sl_LengthSymbols = 7;
#Sidelink Starting symbol in a slot
#Value can be between symbols 0 to 7
sl_StartSymbol = 0;
}
);
sl_syncCfg = (
{
#NUM SL-SSB within 16 frames
sl_NumSSB_WithinPeriod_0 = 4;
#Slot Offset for the first txn in the 16 frame period
sl_TimeOffsetSSB_0 = 8;
#interval in slots for repetition of SL-SSB
sl_TimeInterval_0 = 120;
}
);
sl_ConfiguredGrantConfig = (
{
sl_NrOfHARQ_Processes = 16;
sl_HARQ_ProcID_offset = 0;
sl_periodic_rsc_rsr_interval = 100;
}
);
sl_RxResPools = (
{
#Number of symbols which carry PSCCH.
#Possible values 0 means 2 symbols, 1 - means 3 symbols.
sl_TimeResourcePSCCH = 0;
#Number of RBS which carry PSCCH
#Possible values {n10,n12,n15,n20,n25}
sl_FreqResourcePSCCH = 1; //12RBs
#Size of subchannel in RBs
#Possible values - {n10,n12,n15,n20,n25,n50,n75,n100}
sl_SubchannelSize = 5;//10RBs
#start in RB of the lowest subchannel in a rpool
sl_StartRB_Subchannel = 0;
#number of PRBs in a rpool
sl_RB_Number = 50;
sl_NumSubchannel = 1;
# period of PSFCH resource in units of slots within this resource pool
# Possible values sl0 means no PSFCH resource, {sl0, sl1, sl2, sl4}
sl_PSFCH_Period = 2;
# Number of cyclic shift pairs used for a PSFCH transmission that can be multiplexed in a PRB
# Possible values {n1, n2, n3, n4}
sl_NumMuxCS_Pair = 1;
# Minimum time gap between PSFCH and the associated PSSCH in the unit of slots {sl2, sl3}
sl_MinTimeGapPSFCH = 1; //sl3
# Scrambling ID {0..1023} for sequence hopping of the PSFCH used in the resource pool
sl_PSFCH_HopID = 1;
# Number of PSFCH resources available {startSubCH, allocSubCH} for multiplexing HARQ-ACK information in a PSFCH transmission
sl_PSFCH_CandidateResourceType = 0; // startSubCH
}
);
sl_TxResPools = (
{
#Number of symbols which carry PSCCH.
#Possible values 0 means 2 symbols, 1 - means 3 symbols.
sl_TimeResourcePSCCH = 0;
#Number of RBS which carry PSCCH
#Possible values {n10,n12,n15,n20,n25}
sl_FreqResourcePSCCH = 1; //12RBs
#Size of subchannel in RBs
#Possible values - {n10,n12,n15,n20,n25,n50,n75,n100}
sl_SubchannelSize = 5;//50RBs
#start in RB of the lowest subchannel in a rpool
sl_StartRB_Subchannel = 0;
#number of PRBs in a rpool
sl_RB_Number = 50;
sl_NumSubchannel = 1;
# period of PSFCH resource in units of slots within this resource pool
# Possible values sl0 means no PSFCH resource, {sl0, sl1, sl2, sl4}
sl_PSFCH_Period = 2;
# Number of cyclic shift pairs used for a PSFCH transmission that can be multiplexed in a PRB
# Possible values {n1, n2, n3, n4}
sl_NumMuxCS_Pair = 1;
# Minimum time gap between PSFCH and the associated PSSCH in the unit of slots {sl2, sl3}
sl_MinTimeGapPSFCH = 1; //sl3
# Scrambling ID {0..1023} for sequence hopping of the PSFCH used in the resource pool
sl_PSFCH_HopID = 1;
# Number of PSFCH resources available {startSubCH, allocSubCH} for multiplexing HARQ-ACK information in a PSFCH transmission
sl_PSFCH_CandidateResourceType = 0; // startSubCH
}
);
rsrc_selection_params = (
{
# Resource selection parameters
sl_SelectionWindow = 5; // n1, n5, n10, n20}
sl_Thres_RSRP = 0; // (-128 + (n-1)*2) dBm n is 0..66
sl_MaxNumPerReserve = 0; // n2, n3
sl_SensingWindow = 100; // {ms100, ms1100}
sl_ResourceReservePeriod = 100; //{ms0, ms100, ms200, ms300, ms400, ms500, ms600, ms700, ms800, ms900, ms1000}
sl_RS_ForSensing = 0; // 0 pscch, 1 pssch
sl_TxPercentage = 0; // index of {20, 35, 50}
}
);
sl_UEINFO = (
{
srcid = 0;
thirdOctet = 0;
fourthOctet = 1;
}
);
}
);

View File

@@ -0,0 +1,156 @@
SIDELINK_PRECONFIGURATION = (
{
# TDD ULDL CONFIG used for sidelink
sl_dl_UL_TransmissionPeriodicity = 6;
sl_nrofDownlinkSlots = 6;
sl_nrofDownlinkSymbols = 0;
sl_nrofUplinkSlots = 4;
sl_nrofUplinkSymbols = 0;
sl_csi_rs = (
{
symb_l0 = 5;
# csi_type 2 is not supported 38211, 8.4.1.5.3
csi_Type = 1;
sl_powerControlOffset = 1;
sl_powerControlOffsetSS = 1;
slot_Offset = 0;
slot_Periodicity = 5;
# Indicates if CSI Reporting is enabled in UNICAST. is 0-ENABLED, 1-DISABLED
sl_CSI_Acquisition = 1;
sl_LatencyBoundCSI_Report = 8;
}
);
sl_AllowedResourceSelectionConfig = 3; // Supported only {0, 3, 4, 6}
sl_FrequencyCommonConfig = (
{
sl_offstToCarrier = 0;
sl_subcarrierSpacing = 1;//0-15Khz, 1-30Khz
sl_carrierBandwidth = 106;//numPRBs
#NR bands for Sidelink n47, n38. N47 - 5855Mhz - 5925Mhz
#SL SSB chosen to be located from RB10 to RB21. points to the middle of the SSB block.
#SSB location should be within Sidelink BWP
# this is 2584.95 MHz => 301 REs from PointA 25 PRBs + 1 RE
sl_absoluteFrequencySSB = 516990;
# this is 2575.92 MHz (center frequency is 2585.1 MHz
sl_absoluteFrequencyPointA = 515184;
}
);
sl_BWP = (
{
#RB start 0, RB size = 106. occupies complete Bw.
sl_locationAndBandwidth = 28875;
# Num Symbols used for Sidelink in an uplink slot
# Herein, sl_LengthSymbols represents an index; not the number of symbols.
# This index value can be from 0 to 7 representing the (7 to 14 symbols)
sl_LengthSymbols = 7;
#Sidelink Starting symbol in a slot
#Value can be between symbols 0 to 7
sl_StartSymbol = 0;
}
);
sl_syncCfg = (
{
#NUM SL-SSB within 16 frames
sl_NumSSB_WithinPeriod_0 = 4;
#Slot Offset for the first txn in the 16 frame period
sl_TimeOffsetSSB_0 = 8;
#interval in slots for repetition of SL-SSB
sl_TimeInterval_0 = 120;
}
);
sl_ConfiguredGrantConfig = (
{
sl_NrOfHARQ_Processes = 16;
sl_HARQ_ProcID_offset = 0;
sl_periodic_rsc_rsr_interval = 100;
}
);
sl_RxResPools = (
{
#Number of symbols which carry PSCCH.
#Possible values 0 means 2 symbols, 1 - means 3 symbols.
sl_TimeResourcePSCCH = 0;
#Number of RBS which carry PSCCH
#Possible values {n10,n12,n15,n20,n25}
sl_FreqResourcePSCCH = 1; //12RBs
#Size of subchannel in RBs
#Possible values - {n10,n12,n15,n20,n25,n50,n75,n100}
sl_SubchannelSize = 5;//10RBs
#start in RB of the lowest subchannel in a rpool
sl_StartRB_Subchannel = 0;
#number of PRBs in a rpool
sl_RB_Number = 50;
sl_NumSubchannel = 1;
# period of PSFCH resource in units of slots within this resource pool
# Possible values sl0 means no PSFCH resource, {sl0, sl1, sl2, sl4}
sl_PSFCH_Period = 2;
# Number of cyclic shift pairs used for a PSFCH transmission that can be multiplexed in a PRB
# Possible values {n1, n2, n3, n4}
sl_NumMuxCS_Pair = 1;
# Minimum time gap between PSFCH and the associated PSSCH in the unit of slots {sl2, sl3}
sl_MinTimeGapPSFCH = 1; //sl3
# Scrambling ID {0..1023} for sequence hopping of the PSFCH used in the resource pool
sl_PSFCH_HopID = 1;
# Number of PSFCH resources available {startSubCH, allocSubCH} for multiplexing HARQ-ACK information in a PSFCH transmission
sl_PSFCH_CandidateResourceType = 0; // startSubCH
}
);
sl_TxResPools = (
{
#Number of symbols which carry PSCCH.
#Possible values 0 means 2 symbols, 1 - means 3 symbols.
sl_TimeResourcePSCCH = 0;
#Number of RBS which carry PSCCH
#Possible values {n10,n12,n15,n20,n25}
sl_FreqResourcePSCCH = 1; //12RBs
#Size of subchannel in RBs
#Possible values - {n10,n12,n15,n20,n25,n50,n75,n100}
sl_SubchannelSize = 5;//50RBs
#start in RB of the lowest subchannel in a rpool
sl_StartRB_Subchannel = 0;
#number of PRBs in a rpool
sl_RB_Number = 50;
sl_NumSubchannel = 1;
# period of PSFCH resource in units of slots within this resource pool
# Possible values sl0 means no PSFCH resource, {sl0, sl1, sl2, sl4}
sl_PSFCH_Period = 2;
# Number of cyclic shift pairs used for a PSFCH transmission that can be multiplexed in a PRB
# Possible values {n1, n2, n3, n4}
sl_NumMuxCS_Pair = 1;
# Minimum time gap between PSFCH and the associated PSSCH in the unit of slots {sl2, sl3}
sl_MinTimeGapPSFCH = 1; //sl3
# Scrambling ID {0..1023} for sequence hopping of the PSFCH used in the resource pool
sl_PSFCH_HopID = 1;
# Number of PSFCH resources available {startSubCH, allocSubCH} for multiplexing HARQ-ACK information in a PSFCH transmission
sl_PSFCH_CandidateResourceType = 0; // startSubCH
}
);
rsrc_selection_params = (
{
# Resource selection parameters
# sl_Priority = 1;
sl_SelectionWindow = 5; // n1, n5, n10, n20} {1,5,10,20}*2^μ
sl_Thres_RSRP = 0; // (-128 + (n-1)*2) dBm n is 0..66
sl_MaxNumPerReserve = 0; // n2, n3
sl_SensingWindow = 100; // {ms100, ms1100}
sl_ResourceReservePeriod = 100; //{ms0, ms100, ms200, ms300, ms400, ms500, ms600, ms700, ms800, ms900, ms1000}
sl_RS_ForSensing = 0; // 0 pscch, 1 pssch
sl_TxPercentage = 0; // index of {20, 35, 50}
}
);
sl_UEINFO = (
{
srcid = 1;
thirdOctet = 0;
fourthOctet = 2;
}
);
}
);