Commit f0fce7c1 authored by Robert Schmidt's avatar Robert Schmidt

Merge branch 'integration_2025_w08' into 'develop'

Integration: `2025.w08`

Closes #772

See merge request oai/openairinterface5g!3273

* !3263 Free ITTI message after receiving it at MAC from RRC
* !3268 Upgrade SIMDe commit
* !3269 chore(ci): change image rentention from 4weeks to 3weeks
* !3227 fix(nrLDPC_coding): timers in DL encoding, fix(ldpctest): Confusion in sizes
* !3270 Update of gNB-N300-Timing-Phytest threshold
* !3272 Fix: write NSSAI info of F1AP Cell Info struct
* !3259 UE DCI no candidates
* !3264 Fix "Received Nack" log for Msg4/MsgB and minor improvement in RA logs
* !3228 Add option to use global noise power for all RX channels in RFSimulator
* !2725 Use 5G-S-TMSI as UE identity in RRCSetupRequest
parents 6d9c2c35 e03c15e8
...@@ -315,9 +315,9 @@ class Cluster: ...@@ -315,9 +315,9 @@ class Cluster:
# delete old images by Sagar Arora <sagar.arora@openairinterface.org>: # delete old images by Sagar Arora <sagar.arora@openairinterface.org>:
# 1. retrieve all images and their timestamp # 1. retrieve all images and their timestamp
# 2. awk retrieves those whose timestamp is older than 4 weeks # 2. awk retrieves those whose timestamp is older than 3 weeks
# 3. issue delete command on corresponding istags (the images are dangling and will be cleaned by the registry) # 3. issue delete command on corresponding istags (the images are dangling and will be cleaned by the registry)
delete_cmd = "oc get istag -o go-template --template '{{range .items}}{{.metadata.name}} {{.metadata.creationTimestamp}}{{\"\\n\"}}{{end}}' | awk '$2 <= \"'$(date -d '-4weeks' -Ins --utc | sed 's/+0000/Z/')'\" { print $1 }' | xargs --no-run-if-empty oc delete istag" delete_cmd = "oc get istag -o go-template --template '{{range .items}}{{.metadata.name}} {{.metadata.creationTimestamp}}{{\"\\n\"}}{{end}}' | awk '$2 <= \"'$(date -d '-3weeks' -Ins --utc | sed 's/+0000/Z/')'\" { print $1 }' | xargs --no-run-if-empty oc delete istag"
response = self.cmd.run(delete_cmd) response = self.cmd.run(delete_cmd)
logging.debug(f"deleted images:\n{response.stdout}") logging.debug(f"deleted images:\n{response.stdout}")
......
...@@ -9,14 +9,14 @@ ColNames : ...@@ -9,14 +9,14 @@ ColNames :
Ref : Ref :
feprx : 150.0 feprx : 150.0
feptx_prec : 0.0 feptx_prec : 0.0
feptx_ofdm : 65.0 feptx_ofdm : 60.0
feptx_total : 177.0 feptx_total : 150.0
L1 Tx processing : 700.0 L1 Tx processing : 530.0
DLSCH encoding : 226.0 DLSCH encoding : 220.0
L1 Rx processing : 640.0 L1 Rx processing : 530.0
PUSCH inner-receiver : 400.0 PUSCH inner-receiver : 360.0
Schedule Response : 3.0 Schedule Response : 3.0
DL & UL scheduling timing : 15.0 DL & UL scheduling timing : 17.0
UL Indication : 3.0 UL Indication : 3.0
Slot Indication : 17.0 Slot Indication : 17.0
DeviationThreshold : DeviationThreshold :
......
...@@ -7,16 +7,16 @@ ColNames : ...@@ -7,16 +7,16 @@ ColNames :
- Average; Max; Count - Average; Max; Count
- Average vs Reference Deviation (Reference Value; Acceptability Deviation Threshold) - Average vs Reference Deviation (Reference Value; Acceptability Deviation Threshold)
Ref : Ref :
feprx : 46.0 feprx : 40.0
feptx_prec : 15.0 feptx_prec : 15.0
feptx_ofdm : 35.0 feptx_ofdm : 30.0
feptx_total : 50.0 feptx_total : 45.0
L1 Tx processing : 260.0 L1 Tx processing : 205.0
DLSCH encoding : 160.0 DLSCH encoding : 140.0
L1 Rx processing : 420.0 L1 Rx processing : 345.0
PUSCH inner-receiver : 170.0 PUSCH inner-receiver : 150.0
Schedule Response : 3.0 Schedule Response : 3.0
DL & UL scheduling timing : 8.0 DL & UL scheduling timing : 7.0
UL Indication : 3.0 UL Indication : 3.0
Slot Indication : 8.0 Slot Indication : 8.0
DeviationThreshold : DeviationThreshold :
......
...@@ -7,18 +7,18 @@ ColNames : ...@@ -7,18 +7,18 @@ ColNames :
- Average; Max; Count - Average; Max; Count
- Average vs Reference Deviation (Reference Value; Acceptability Deviation Threshold) - Average vs Reference Deviation (Reference Value; Acceptability Deviation Threshold)
Ref : Ref :
feprx : 84.0 feprx : 75.0
feptx_prec : 14.0 feptx_prec : 14.0
feptx_ofdm : 35.0 feptx_ofdm : 30.0
feptx_total : 100.0 feptx_total : 80.0
L1 Tx processing : 400.0 L1 Tx processing : 315.0
DLSCH encoding : 177.0 DLSCH encoding : 155.0
L1 Rx processing : 345.0 L1 Rx processing : 345.0
PUSCH inner-receiver : 200.0 PUSCH inner-receiver : 155.0
Schedule Response : 3.0 Schedule Response : 3.0
DL & UL scheduling timing : 13.0 DL & UL scheduling timing : 13.0
UL Indication : 3.0 UL Indication : 3.0
Slot Indication : 15.0 Slot Indication : 12.0
DeviationThreshold : DeviationThreshold :
feprx : 0.25 feprx : 0.25
feptx_prec : 0.25 feptx_prec : 0.25
......
...@@ -7,17 +7,17 @@ ColNames : ...@@ -7,17 +7,17 @@ ColNames :
- Average; Max; Count - Average; Max; Count
- Average vs Reference Deviation (Reference Value; Acceptability Deviation Threshold) - Average vs Reference Deviation (Reference Value; Acceptability Deviation Threshold)
Ref : Ref :
feprx : 43.0 feprx : 40.0
feptx_prec : 13.0 feptx_prec : 13.0
feptx_ofdm : 33.0 feptx_ofdm : 30.0
feptx_total : 50.0 feptx_total : 45.0
L1 Tx processing : 200.0 L1 Tx processing : 160.0
DLSCH encoding : 100.0 DLSCH encoding : 100.0
L1 Rx processing : 330.0 L1 Rx processing : 290.0
PUSCH inner-receiver : 120.0 PUSCH inner-receiver : 115.0
Schedule Response : 3.0 Schedule Response : 3.0
DL & UL scheduling timing : 6.0 DL & UL scheduling timing : 6.0
UL Indication : 3.0 UL Indication : 2.0
Slot Indication : 7.0 Slot Indication : 7.0
DeviationThreshold : DeviationThreshold :
feprx : 0.25 feprx : 0.25
......
...@@ -25,7 +25,10 @@ ...@@ -25,7 +25,10 @@
<htmlTabRef>test-ldpc-gpu</htmlTabRef> <htmlTabRef>test-ldpc-gpu</htmlTabRef>
<htmlTabName>Test-ldpc-GPU</htmlTabName> <htmlTabName>Test-ldpc-GPU</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon> <htmlTabIcon>tasks</htmlTabIcon>
<TestCaseRequestedList>000002 000003 000004 000005 000006 000007 000008 000009 000010 000011 000012 000013 000014 000015 000016 000017 000018 000019 000020 000021</TestCaseRequestedList> <TestCaseRequestedList>
000002 000003 000004 000005 000006 000007 000008 000009 000010 000011 000012 000013 000014 000015 000016 000017 000018 000019 000020 000021
000022 000023 000024 000025 000026 000027 000028 000029 000030 000031 000032 000033 000034 000035 000036 000037 000038 000039 000040 000041
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList> <TestCaseExclusionList></TestCaseExclusionList>
<testCase id="000002"> <testCase id="000002">
...@@ -188,6 +191,166 @@ ...@@ -188,6 +191,166 @@
<physim_run_args>-l 8448 -s10 -n100 -G 1</physim_run_args> <physim_run_args>-l 8448 -s10 -n100 -G 1</physim_run_args>
</testCase> </testCase>
<testCase id="000022">
<class>Run_Physim</class>
<desc>Run LDPC Test with CPU</desc>
<always_exec>true</always_exec>
<physim_test>ldpctest</physim_test>
<physim_run_args>-l 1 -s10 -n100</physim_run_args>
</testCase>
<testCase id="000023">
<class>Run_Physim</class>
<desc>Run LDPC Test with GPU</desc>
<always_exec>true</always_exec>
<physim_test>ldpctest</physim_test>
<physim_run_args>-l 1 -s10 -n100 -G 1</physim_run_args>
</testCase>
<testCase id="000024">
<class>Run_Physim</class>
<desc>Run LDPC Test with CPU</desc>
<always_exec>true</always_exec>
<physim_test>ldpctest</physim_test>
<physim_run_args>-l 100 -s10 -n100</physim_run_args>
</testCase>
<testCase id="000025">
<class>Run_Physim</class>
<desc>Run LDPC Test with GPU</desc>
<always_exec>true</always_exec>
<physim_test>ldpctest</physim_test>
<physim_run_args>-l 100 -s10 -n100 -G 1</physim_run_args>
</testCase>
<testCase id="000026">
<class>Run_Physim</class>
<desc>Run LDPC Test with CPU</desc>
<always_exec>true</always_exec>
<physim_test>ldpctest</physim_test>
<physim_run_args>-l 193 -s10 -n100</physim_run_args>
</testCase>
<testCase id="000027">
<class>Run_Physim</class>
<desc>Run LDPC Test with GPU</desc>
<always_exec>true</always_exec>
<physim_test>ldpctest</physim_test>
<physim_run_args>-l 193 -s10 -n100 -G 1</physim_run_args>
</testCase>
<testCase id="000028">
<class>Run_Physim</class>
<desc>Run LDPC Test with CPU</desc>
<always_exec>true</always_exec>
<physim_test>ldpctest</physim_test>
<physim_run_args>-l 500 -s10 -n100</physim_run_args>
</testCase>
<testCase id="000029">
<class>Run_Physim</class>
<desc>Run LDPC Test with GPU</desc>
<always_exec>true</always_exec>
<physim_test>ldpctest</physim_test>
<physim_run_args>-l 500 -s10 -n100 -G 1</physim_run_args>
</testCase>
<testCase id="000030">
<class>Run_Physim</class>
<desc>Run LDPC Test with CPU</desc>
<always_exec>true</always_exec>
<physim_test>ldpctest</physim_test>
<physim_run_args>-l 561 -s10 -n100</physim_run_args>
</testCase>
<testCase id="000031">
<class>Run_Physim</class>
<desc>Run LDPC Test with GPU</desc>
<always_exec>true</always_exec>
<physim_test>ldpctest</physim_test>
<physim_run_args>-l 561 -s10 -n100 -G 1</physim_run_args>
</testCase>
<testCase id="000032">
<class>Run_Physim</class>
<desc>Run LDPC Test with CPU</desc>
<always_exec>true</always_exec>
<physim_test>ldpctest</physim_test>
<physim_run_args>-l 600 -s10 -n100</physim_run_args>
</testCase>
<testCase id="000033">
<class>Run_Physim</class>
<desc>Run LDPC Test with GPU</desc>
<always_exec>true</always_exec>
<physim_test>ldpctest</physim_test>
<physim_run_args>-l 600 -s10 -n100 -G 1</physim_run_args>
</testCase>
<testCase id="000034">
<class>Run_Physim</class>
<desc>Run LDPC Test with CPU</desc>
<always_exec>true</always_exec>
<physim_test>ldpctest</physim_test>
<physim_run_args>-l 641 -s10 -n100</physim_run_args>
</testCase>
<testCase id="000035">
<class>Run_Physim</class>
<desc>Run LDPC Test with GPU</desc>
<always_exec>true</always_exec>
<physim_test>ldpctest</physim_test>
<physim_run_args>-l 641 -s10 -n100 -G 1</physim_run_args>
</testCase>
<testCase id="000036">
<class>Run_Physim</class>
<desc>Run LDPC Test with CPU</desc>
<always_exec>true</always_exec>
<physim_test>ldpctest</physim_test>
<physim_run_args>-l 2000 -s10 -n100</physim_run_args>
</testCase>
<testCase id="000037">
<class>Run_Physim</class>
<desc>Run LDPC Test with GPU</desc>
<always_exec>true</always_exec>
<physim_test>ldpctest</physim_test>
<physim_run_args>-l 2000 -s10 -n100 -G 1</physim_run_args>
</testCase>
<testCase id="000038">
<class>Run_Physim</class>
<desc>Run LDPC Test with CPU</desc>
<always_exec>true</always_exec>
<physim_test>ldpctest</physim_test>
<physim_run_args>-l 3000 -s10 -n100</physim_run_args>
</testCase>
<testCase id="000039">
<class>Run_Physim</class>
<desc>Run LDPC Test with GPU</desc>
<always_exec>true</always_exec>
<physim_test>ldpctest</physim_test>
<physim_run_args>-l 3000 -s10 -n100 -G 1</physim_run_args>
</testCase>
<testCase id="000040">
<class>Run_Physim</class>
<desc>Run LDPC Test with CPU</desc>
<always_exec>true</always_exec>
<physim_test>ldpctest</physim_test>
<physim_run_args>-l 3840 -s10 -n100</physim_run_args>
</testCase>
<testCase id="000041">
<class>Run_Physim</class>
<desc>Run LDPC Test with GPU</desc>
<always_exec>true</always_exec>
<physim_test>ldpctest</physim_test>
<physim_run_args>-l 3840 -s10 -n100 -G 1</physim_run_args>
</testCase>
</testCaseList> </testCaseList>
...@@ -66,16 +66,26 @@ ...@@ -66,16 +66,26 @@
</testCase> </testCase>
<testCase id="ldpctest"> <testCase id="ldpctest">
<desc>ldpc Test cases. (Test1: block length = 3872), <desc>ldpc Test cases. (Test1: block length = 3872, BG1),
(Test2: block length = 4224), (Test2: block length = 4224, BG1),
(Test3: block length = 4576), (Test3: block length = 4576, BG1),
(Test4: block length = 4928), (Test4: block length = 4928, BG1),
(Test5: block length = 5280), (Test5: block length = 5280, BG1),
(Test6: block length = 5632), (Test6: block length = 5632, BG1),
(Test7: block length = 6336), (Test7: block length = 6336, BG1),
(Test8: block length = 7040), (Test8: block length = 7040, BG1),
(Test9: block length = 7744), (Test9: block length = 7744, BG1),
(Test10: block length = 8448)</desc> (Test10: block length = 8448, BG1),
(Test11: block length = 1, BG2),
(Test12: block length = 100, BG2),
(Test13: block length = 193, BG2),
(Test14: block length = 500, BG2),
(Test15: block length = 561, BG2),
(Test16: block length = 600, BG2),
(Test17: block length = 641, BG2),
(Test18: block length = 2000, BG2),
(Test19: block length = 3000, BG2),
(Test20: block length = 3840, BG2)</desc>
<main_exec>ldpctest</main_exec> <main_exec>ldpctest</main_exec>
<main_exec_args>-l3872 -s10 -n100 <main_exec_args>-l3872 -s10 -n100
-l4224 -s10 -n100 -l4224 -s10 -n100
...@@ -87,9 +97,17 @@ ...@@ -87,9 +97,17 @@
-l7040 -s10 -n100 -l7040 -s10 -n100
-l7744 -s10 -n100 -l7744 -s10 -n100
-l8448 -s10 -n100 -l8448 -s10 -n100
-l561 -s10 -n1 -l1 -s10 -n100
-l500 -s10 -n1</main_exec_args> -l100 -s10 -n100
<tags>test1 test2 test3 test4 test5 test6 test7 test8 test9 test10</tags> -l193 -s10 -n100
-l500 -s10 -n100
-l561 -s10 -n100
-l600 -s10 -n100
-l641 -s10 -n100
-l2000 -s10 -n100
-l3000 -s10 -n100
-l3840 -s10 -n100</main_exec_args>
<tags>test1 test2 test3 test4 test5 test6 test7 test8 test9 test10 test11 test12 test13 test14 test15 test16 test17 test18 test19 test20</tags>
<search_expr_true>BLER 0.000000</search_expr_true> <search_expr_true>BLER 0.000000</search_expr_true>
<search_expr_false>segmentation fault|assertion|exiting|fatal|differ</search_expr_false> <search_expr_false>segmentation fault|assertion|exiting|fatal|differ</search_expr_false>
<nruns>3</nruns> <nruns>3</nruns>
......
...@@ -674,8 +674,8 @@ install_simde_from_source(){ ...@@ -674,8 +674,8 @@ install_simde_from_source(){
if [[ -v SIMDE_VERSION ]]; then if [[ -v SIMDE_VERSION ]]; then
git checkout -f $SIMDE_VERSION git checkout -f $SIMDE_VERSION
else else
# At time of writing, last working commit for OAI: 1a09d3bc # At time of writing, last working commit for OAI: c7f26b7
git checkout 1a09d3bc9de47c4d9a5daa23eb753d5322748201 git checkout c7f26b73ba8e874b95c2cec2b497826ad2188f68
fi fi
# Showing which version is used # Showing which version is used
git log -n1 git log -n1
......
This diff is collapsed.
...@@ -49,7 +49,7 @@ typedef struct ldpc8blocks_args_s { ...@@ -49,7 +49,7 @@ typedef struct ldpc8blocks_args_s {
encoder_implemparams_t impp; encoder_implemparams_t impp;
} ldpc8blocks_args_t; } ldpc8blocks_args_t;
static void ldpc8blocks_coding_segment(void *p) static void ldpc8blocks(void *p)
{ {
ldpc8blocks_args_t *args = (ldpc8blocks_args_t *)p; ldpc8blocks_args_t *args = (ldpc8blocks_args_t *)p;
nrLDPC_TB_encoding_parameters_t *nrLDPC_TB_encoding_parameters = args->nrLDPC_TB_encoding_parameters; nrLDPC_TB_encoding_parameters_t *nrLDPC_TB_encoding_parameters = args->nrLDPC_TB_encoding_parameters;
...@@ -192,7 +192,7 @@ static int nrLDPC_prepare_TB_encoding(nrLDPC_slot_encoding_parameters_t *nrLDPC_ ...@@ -192,7 +192,7 @@ static int nrLDPC_prepare_TB_encoding(nrLDPC_slot_encoding_parameters_t *nrLDPC_
perJobImpp->impp = impp; perJobImpp->impp = impp;
perJobImpp->nrLDPC_TB_encoding_parameters = nrLDPC_TB_encoding_parameters; perJobImpp->nrLDPC_TB_encoding_parameters = nrLDPC_TB_encoding_parameters;
task_t t = {.func = ldpc8blocks_coding_segment, .args = perJobImpp}; task_t t = {.func = ldpc8blocks, .args = perJobImpp};
pushTpool(nrLDPC_slot_encoding_parameters->threadPool, t); pushTpool(nrLDPC_slot_encoding_parameters->threadPool, t);
} }
return n_seg; return n_seg;
......
...@@ -20,8 +20,8 @@ ...@@ -20,8 +20,8 @@
*/ */
/*! \file PHY/NR_TRANSPORT/nr_dlsch_coding_slot.c /*! \file PHY/NR_TRANSPORT/nr_dlsch_coding_slot.c
* \brief Top-level routines for implementing LDPC-coded (DLSCH) transport channels from 38-212, 15.2 * \brief Top-level routines for implementing LDPC-coded (DLSCH) transport channels from 38-212, 15.2
*/ */
#include "PHY/defs_gNB.h" #include "PHY/defs_gNB.h"
#include "PHY/CODING/coding_extern.h" #include "PHY/CODING/coding_extern.h"
...@@ -39,17 +39,17 @@ ...@@ -39,17 +39,17 @@
#include <syscall.h> #include <syscall.h>
#include <openair2/UTIL/OPT/opt.h> #include <openair2/UTIL/OPT/opt.h>
//#define DEBUG_DLSCH_CODING // #define DEBUG_DLSCH_CODING
//#define DEBUG_DLSCH_FREE 1 // #define DEBUG_DLSCH_FREE 1
void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch, uint16_t N_RB, const NR_DL_FRAME_PARMS *frame_parms) void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch, uint16_t N_RB, const NR_DL_FRAME_PARMS *frame_parms)
{ {
int max_layers = (frame_parms->nb_antennas_tx<NR_MAX_NB_LAYERS) ? frame_parms->nb_antennas_tx : NR_MAX_NB_LAYERS; int max_layers = (frame_parms->nb_antennas_tx < NR_MAX_NB_LAYERS) ? frame_parms->nb_antennas_tx : NR_MAX_NB_LAYERS;
uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*max_layers; uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER * max_layers;
if (N_RB != 273) { if (N_RB != 273) {
a_segments = a_segments*N_RB; a_segments = a_segments * N_RB;
a_segments = a_segments/273 +1; a_segments = a_segments / 273 + 1;
} }
NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process; NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process;
...@@ -70,16 +70,16 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch, uint16_t N_RB, const NR_DL_FRAME_PARM ...@@ -70,16 +70,16 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch, uint16_t N_RB, const NR_DL_FRAME_PARM
NR_gNB_DLSCH_t new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, uint16_t N_RB) NR_gNB_DLSCH_t new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, uint16_t N_RB)
{ {
int max_layers = (frame_parms->nb_antennas_tx<NR_MAX_NB_LAYERS) ? frame_parms->nb_antennas_tx : NR_MAX_NB_LAYERS; int max_layers = (frame_parms->nb_antennas_tx < NR_MAX_NB_LAYERS) ? frame_parms->nb_antennas_tx : NR_MAX_NB_LAYERS;
uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*max_layers; //number of segments to be allocated uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER * max_layers; // number of segments to be allocated
if (N_RB != 273) { if (N_RB != 273) {
a_segments = a_segments*N_RB; a_segments = a_segments * N_RB;
a_segments = a_segments/273 +1; a_segments = a_segments / 273 + 1;
} }
LOG_D(PHY,"Allocating %d segments (MAX %d, N_PRB %d)\n",a_segments,MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER,N_RB); LOG_D(PHY, "Allocating %d segments (MAX %d, N_PRB %d)\n", a_segments, MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER, N_RB);
uint32_t dlsch_bytes = a_segments*1056; // allocated bytes per segment uint32_t dlsch_bytes = a_segments * 1056; // allocated bytes per segment
NR_gNB_DLSCH_t dlsch; NR_gNB_DLSCH_t dlsch;
NR_DL_gNB_HARQ_t *harq = &dlsch.harq_process; NR_DL_gNB_HARQ_t *harq = &dlsch.harq_process;
...@@ -88,7 +88,7 @@ NR_gNB_DLSCH_t new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, uint16_t N_RB) ...@@ -88,7 +88,7 @@ NR_gNB_DLSCH_t new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, uint16_t N_RB)
AssertFatal(harq->b, "cannot allocate memory for harq->b\n"); AssertFatal(harq->b, "cannot allocate memory for harq->b\n");
bzero(harq->b, dlsch_bytes); bzero(harq->b, dlsch_bytes);
harq->c = (uint8_t **)malloc16(a_segments*sizeof(uint8_t *)); harq->c = (uint8_t **)malloc16(a_segments * sizeof(uint8_t *));
for (int r = 0; r < a_segments; r++) { for (int r = 0; r < a_segments; r++) {
// account for filler in first segment and CRCs for multiple segment case // account for filler in first segment and CRCs for multiple segment case
// [hna] 8448 is the maximum CB size in NR // [hna] 8448 is the maximum CB size in NR
...@@ -103,7 +103,7 @@ NR_gNB_DLSCH_t new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, uint16_t N_RB) ...@@ -103,7 +103,7 @@ NR_gNB_DLSCH_t new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, uint16_t N_RB)
AssertFatal(harq->f, "cannot allocate harq->f\n"); AssertFatal(harq->f, "cannot allocate harq->f\n");
bzero(harq->f, N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS); bzero(harq->f, N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
return(dlsch); return (dlsch);
} }
int nr_dlsch_encoding(PHY_VARS_gNB *gNB, int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
...@@ -120,34 +120,30 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, ...@@ -120,34 +120,30 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
time_stats_t *dlsch_interleaving_stats, time_stats_t *dlsch_interleaving_stats,
time_stats_t *dlsch_segmentation_stats) time_stats_t *dlsch_segmentation_stats)
{ {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ENCODING, VCD_FUNCTION_IN); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ENCODING, VCD_FUNCTION_IN);
nrLDPC_TB_encoding_parameters_t TBs[msgTx->num_pdsch_slot]; nrLDPC_TB_encoding_parameters_t TBs[msgTx->num_pdsch_slot];
memset(TBs, 0, sizeof(TBs)); memset(TBs, 0, sizeof(TBs));
nrLDPC_slot_encoding_parameters_t slot_parameters = { nrLDPC_slot_encoding_parameters_t slot_parameters = {.frame = frame,
.frame = frame, .slot = slot,
.slot = slot, .nb_TBs = msgTx->num_pdsch_slot,
.nb_TBs = msgTx->num_pdsch_slot, .threadPool = &gNB->threadPool,
.threadPool = &gNB->threadPool, .tinput = tinput,
.tinput = tinput, .tprep = tprep,
.tprep = tprep, .tparity = tparity,
.tparity = tparity, .toutput = toutput,
.toutput = toutput, .TBs = TBs};
.TBs = TBs
};
int num_segments = 0; int num_segments = 0;
for (int dlsch_id=0; dlsch_id<msgTx->num_pdsch_slot; dlsch_id++) { for (int dlsch_id = 0; dlsch_id < msgTx->num_pdsch_slot; dlsch_id++) {
NR_gNB_DLSCH_t *dlsch = msgTx->dlsch[dlsch_id]; NR_gNB_DLSCH_t *dlsch = msgTx->dlsch[dlsch_id];
NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process; NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process;
unsigned int crc=1; unsigned int crc = 1;
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &harq->pdsch_pdu.pdsch_pdu_rel15; nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &harq->pdsch_pdu.pdsch_pdu_rel15;
uint32_t A = rel15->TBSize[0]<<3; uint32_t A = rel15->TBSize[0] << 3;
unsigned char *a=harq->pdu; unsigned char *a = harq->pdu;
if (rel15->rnti != SI_RNTI) { if (rel15->rnti != SI_RNTI) {
ws_trace_t tmp = {.nr = true, ws_trace_t tmp = {.nr = true,
.direction = DIRECTION_DOWNLINK, .direction = DIRECTION_DOWNLINK,
...@@ -175,38 +171,30 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, ...@@ -175,38 +171,30 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
phy_stats->dlsch_stats.current_Qm = rel15->qamModOrder[0]; phy_stats->dlsch_stats.current_Qm = rel15->qamModOrder[0];
} }
int max_bytes = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*rel15->nrOfLayers*1056; int max_bytes = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER * rel15->nrOfLayers * 1056;
int B; int B;
if (A > NR_MAX_PDSCH_TBS) { if (A > NR_MAX_PDSCH_TBS) {
// Add 24-bit crc (polynomial A) to payload // Add 24-bit crc (polynomial A) to payload
crc = crc24a(a,A)>>8; crc = crc24a(a, A) >> 8;
a[A>>3] = ((uint8_t *)&crc)[2]; a[A >> 3] = ((uint8_t *)&crc)[2];
a[1+(A>>3)] = ((uint8_t *)&crc)[1]; a[1 + (A >> 3)] = ((uint8_t *)&crc)[1];
a[2+(A>>3)] = ((uint8_t *)&crc)[0]; a[2 + (A >> 3)] = ((uint8_t *)&crc)[0];
//printf("CRC %x (A %d)\n",crc,A); // printf("CRC %x (A %d)\n",crc,A);
//printf("a0 %d a1 %d a2 %d\n", a[A>>3], a[1+(A>>3)], a[2+(A>>3)]); // printf("a0 %d a1 %d a2 %d\n", a[A>>3], a[1+(A>>3)], a[2+(A>>3)]);
B = A + 24; B = A + 24;
// harq->b = a; // harq->b = a;
AssertFatal((A / 8) + 4 <= max_bytes, AssertFatal((A / 8) + 4 <= max_bytes, "A %d is too big (A/8+4 = %d > %d)\n", A, (A / 8) + 4, max_bytes);
"A %d is too big (A/8+4 = %d > %d)\n",
A,
(A / 8) + 4,
max_bytes);
memcpy(harq->b, a, (A / 8) + 4); // why is this +4 if the CRC is only 3 bytes? memcpy(harq->b, a, (A / 8) + 4); // why is this +4 if the CRC is only 3 bytes?
} else { } else {
// Add 16-bit crc (polynomial A) to payload // Add 16-bit crc (polynomial A) to payload
crc = crc16(a,A)>>16; crc = crc16(a, A) >> 16;
a[A>>3] = ((uint8_t *)&crc)[1]; a[A >> 3] = ((uint8_t *)&crc)[1];
a[1+(A>>3)] = ((uint8_t *)&crc)[0]; a[1 + (A >> 3)] = ((uint8_t *)&crc)[0];
//printf("CRC %x (A %d)\n",crc,A); // printf("CRC %x (A %d)\n",crc,A);
//printf("a0 %d a1 %d \n", a[A>>3], a[1+(A>>3)]); // printf("a0 %d a1 %d \n", a[A>>3], a[1+(A>>3)]);
B = A + 16; B = A + 16;
// harq->b = a; // harq->b = a;
AssertFatal((A / 8) + 3 <= max_bytes, AssertFatal((A / 8) + 3 <= max_bytes, "A %d is too big (A/8+3 = %d > %d)\n", A, (A / 8) + 3, max_bytes);
"A %d is too big (A/8+3 = %d > %d)\n",
A,
(A / 8) + 3,
max_bytes);
memcpy(harq->b, a, (A / 8) + 3); // using 3 bytes to mimic the case of 24 bit crc memcpy(harq->b, a, (A / 8) + 3); // using 3 bytes to mimic the case of 24 bit crc
} }
...@@ -228,12 +216,11 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, ...@@ -228,12 +216,11 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
TB_parameters->BG); TB_parameters->BG);
stop_meas(dlsch_segmentation_stats); stop_meas(dlsch_segmentation_stats);
if (TB_parameters->C>MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*rel15->nrOfLayers) { if (TB_parameters->C > MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER * rel15->nrOfLayers) {
LOG_E(PHY, "nr_segmentation.c: too many segments %d, B %d\n", TB_parameters->C, B); LOG_E(PHY, "nr_segmentation.c: too many segments %d, B %d\n", TB_parameters->C, B);
return(-1); return (-1);
} }
num_segments += TB_parameters->C; num_segments += TB_parameters->C;
} }
nrLDPC_segment_encoding_parameters_t segments[num_segments]; nrLDPC_segment_encoding_parameters_t segments[num_segments];
...@@ -284,18 +271,13 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, ...@@ -284,18 +271,13 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
for (int r = 0; r < TB_parameters->C; r++) { for (int r = 0; r < TB_parameters->C; r++) {
nrLDPC_segment_encoding_parameters_t *segment_parameters = &TB_parameters->segments[r]; nrLDPC_segment_encoding_parameters_t *segment_parameters = &TB_parameters->segments[r];
segment_parameters->c = harq->c[r]; segment_parameters->c = harq->c[r];
segment_parameters->E = nr_get_E(TB_parameters->G, segment_parameters->E = nr_get_E(TB_parameters->G, TB_parameters->C, TB_parameters->Qm, rel15->nrOfLayers, r);
TB_parameters->C,
TB_parameters->Qm,
rel15->nrOfLayers,
r);
segment_parameters->output = &output[dlsch_offset + r_offset]; segment_parameters->output = &output[dlsch_offset + r_offset];
r_offset += segment_parameters->E; r_offset += segment_parameters->E;
reset_meas(&segment_parameters->ts_interleave); reset_meas(&segment_parameters->ts_interleave);
reset_meas(&segment_parameters->ts_rate_match); reset_meas(&segment_parameters->ts_rate_match);
reset_meas(&segment_parameters->ts_ldpc_encode); reset_meas(&segment_parameters->ts_ldpc_encode);
} }
segments_offset += TB_parameters->C; segments_offset += TB_parameters->C;
...@@ -309,6 +291,16 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, ...@@ -309,6 +291,16 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
gNB->nrLDPC_coding_interface.nrLDPC_coding_encoder(&slot_parameters); gNB->nrLDPC_coding_interface.nrLDPC_coding_encoder(&slot_parameters);
for (int dlsch_id = 0; dlsch_id < msgTx->num_pdsch_slot; dlsch_id++) {
nrLDPC_TB_encoding_parameters_t *TB_parameters = &TBs[dlsch_id];
for (int r = 0; r < TB_parameters->C; r++) {
nrLDPC_segment_encoding_parameters_t *segment_parameters = &TB_parameters->segments[r];
merge_meas(dlsch_interleaving_stats, &segment_parameters->ts_interleave);
merge_meas(dlsch_rate_matching_stats, &segment_parameters->ts_rate_match);
// merge_meas(, &segment_parameters->ts_ldpc_encode);
}
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ENCODING, VCD_FUNCTION_OUT); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
return 0; return 0;
} }
...@@ -20,9 +20,8 @@ ...@@ -20,9 +20,8 @@
*/ */
/*! \file PHY/NR_TRANSPORT/nr_ulsch_decoding_slot.c /*! \file PHY/NR_TRANSPORT/nr_ulsch_decoding_slot.c
* \brief Top-level routines for decoding LDPC (ULSCH) transport channels from 38.212, V15.4.0 2018-12 * \brief Top-level routines for decoding LDPC (ULSCH) transport channels from 38.212, V15.4.0 2018-12
*/ */
// [from gNB coding] // [from gNB coding]
#include "PHY/defs_gNB.h" #include "PHY/defs_gNB.h"
...@@ -41,27 +40,26 @@ ...@@ -41,27 +40,26 @@
#include "common/utils/LOG/vcd_signal_dumper.h" #include "common/utils/LOG/vcd_signal_dumper.h"
#include "common/utils/LOG/log.h" #include "common/utils/LOG/log.h"
#include <syscall.h> #include <syscall.h>
//#define DEBUG_ULSCH_DECODING // #define DEBUG_ULSCH_DECODING
//#define gNB_DEBUG_TRACE // #define gNB_DEBUG_TRACE
#define OAI_UL_LDPC_MAX_NUM_LLR 27000//26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX = 68*384 #define OAI_UL_LDPC_MAX_NUM_LLR 27000 // 26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX = 68*384
//#define DEBUG_CRC // #define DEBUG_CRC
#ifdef DEBUG_CRC #ifdef DEBUG_CRC
#define PRINT_CRC_CHECK(a) a #define PRINT_CRC_CHECK(a) a
#else #else
#define PRINT_CRC_CHECK(a) #define PRINT_CRC_CHECK(a)
#endif #endif
//extern double cpuf; // extern double cpuf;
void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch, uint16_t N_RB_UL) void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch, uint16_t N_RB_UL)
{ {
uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER * NR_MAX_NB_LAYERS; // number of segments to be allocated
uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER*NR_MAX_NB_LAYERS; //number of segments to be allocated
if (N_RB_UL != 273) { if (N_RB_UL != 273) {
a_segments = a_segments*N_RB_UL; a_segments = a_segments * N_RB_UL;
a_segments = a_segments/273 +1; a_segments = a_segments / 273 + 1;
} }
if (ulsch->harq_process) { if (ulsch->harq_process) {
...@@ -83,12 +81,11 @@ void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch, uint16_t N_RB_UL) ...@@ -83,12 +81,11 @@ void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch, uint16_t N_RB_UL)
NR_gNB_ULSCH_t new_gNB_ulsch(uint8_t max_ldpc_iterations, uint16_t N_RB_UL) NR_gNB_ULSCH_t new_gNB_ulsch(uint8_t max_ldpc_iterations, uint16_t N_RB_UL)
{ {
uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER * NR_MAX_NB_LAYERS; // number of segments to be allocated
uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER*NR_MAX_NB_LAYERS; //number of segments to be allocated
if (N_RB_UL != 273) { if (N_RB_UL != 273) {
a_segments = a_segments*N_RB_UL; a_segments = a_segments * N_RB_UL;
a_segments = a_segments/273 +1; a_segments = a_segments / 273 + 1;
} }
uint32_t ulsch_bytes = a_segments * 1056; // allocated bytes per segment uint32_t ulsch_bytes = a_segments * 1056; // allocated bytes per segment
...@@ -110,7 +107,7 @@ NR_gNB_ULSCH_t new_gNB_ulsch(uint8_t max_ldpc_iterations, uint16_t N_RB_UL) ...@@ -110,7 +107,7 @@ NR_gNB_ULSCH_t new_gNB_ulsch(uint8_t max_ldpc_iterations, uint16_t N_RB_UL)
} }
harq->d_to_be_cleared = calloc(a_segments, sizeof(bool)); harq->d_to_be_cleared = calloc(a_segments, sizeof(bool));
AssertFatal(harq->d_to_be_cleared != NULL, "out of memory\n"); AssertFatal(harq->d_to_be_cleared != NULL, "out of memory\n");
return(ulsch); return (ulsch);
} }
int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
...@@ -121,18 +118,15 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, ...@@ -121,18 +118,15 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
uint8_t *ULSCH_ids, uint8_t *ULSCH_ids,
int nb_pusch) int nb_pusch)
{ {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING, 1); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING, 1);
nrLDPC_TB_decoding_parameters_t TBs[nb_pusch]; nrLDPC_TB_decoding_parameters_t TBs[nb_pusch];
memset(TBs, 0, sizeof(TBs)); memset(TBs, 0, sizeof(TBs));
nrLDPC_slot_decoding_parameters_t slot_parameters = { nrLDPC_slot_decoding_parameters_t slot_parameters = {.frame = frame,
.frame = frame, .slot = nr_tti_rx,
.slot = nr_tti_rx, .nb_TBs = nb_pusch,
.nb_TBs = nb_pusch, .threadPool = &phy_vars_gNB->threadPool,
.threadPool = &phy_vars_gNB->threadPool, .TBs = TBs};
.TBs = TBs
};
int max_num_segments = 0; int max_num_segments = 0;
...@@ -154,17 +148,17 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, ...@@ -154,17 +148,17 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
// The harq_pid is not unique among the active HARQ processes in the instance so we use ULSCH_id instead // The harq_pid is not unique among the active HARQ processes in the instance so we use ULSCH_id instead
TB_parameters->harq_unique_pid = ULSCH_id; TB_parameters->harq_unique_pid = ULSCH_id;
// ------------------------------------------------------------------ // ------------------------------------------------------------------
TB_parameters->nb_rb = pusch_pdu->rb_size; TB_parameters->nb_rb = pusch_pdu->rb_size;
TB_parameters->Qm = pusch_pdu->qam_mod_order; TB_parameters->Qm = pusch_pdu->qam_mod_order;
TB_parameters->mcs = pusch_pdu->mcs_index; TB_parameters->mcs = pusch_pdu->mcs_index;
TB_parameters->nb_layers = pusch_pdu->nrOfLayers; TB_parameters->nb_layers = pusch_pdu->nrOfLayers;
// ------------------------------------------------------------------ // ------------------------------------------------------------------
TB_parameters->processedSegments = &harq_process->processedSegments; TB_parameters->processedSegments = &harq_process->processedSegments;
harq_process->TBS = pusch_pdu->pusch_data.tb_size; harq_process->TBS = pusch_pdu->pusch_data.tb_size;
TB_parameters->BG = pusch_pdu->maintenance_parms_v3.ldpcBaseGraph; TB_parameters->BG = pusch_pdu->maintenance_parms_v3.ldpcBaseGraph;
TB_parameters->A = (harq_process->TBS) << 3; TB_parameters->A = (harq_process->TBS) << 3;
NR_gNB_PHY_STATS_t *stats = get_phy_stats(phy_vars_gNB, ulsch->rnti); NR_gNB_PHY_STATS_t *stats = get_phy_stats(phy_vars_gNB, ulsch->rnti);
...@@ -181,7 +175,7 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, ...@@ -181,7 +175,7 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
stats->ulsch_stats.total_bytes_tx += harq_process->TBS; stats->ulsch_stats.total_bytes_tx += harq_process->TBS;
} }
} }
uint8_t harq_pid = ulsch->harq_pid; uint8_t harq_pid = ulsch->harq_pid;
LOG_D(PHY, LOG_D(PHY,
"ULSCH Decoding, harq_pid %d rnti %x TBS %d G %d mcs %d Nl %d nb_rb %d, Qm %d, Coderate %f RV %d round %d new RX %d\n", "ULSCH Decoding, harq_pid %d rnti %x TBS %d G %d mcs %d Nl %d nb_rb %d, Qm %d, Coderate %f RV %d round %d new RX %d\n",
...@@ -197,7 +191,7 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, ...@@ -197,7 +191,7 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
pusch_pdu->pusch_data.rv_index, pusch_pdu->pusch_data.rv_index,
harq_process->round, harq_process->round,
harq_process->harq_to_be_cleared); harq_process->harq_to_be_cleared);
// [hna] Perform nr_segmenation with input and output set to NULL to calculate only (C, K, Z, F) // [hna] Perform nr_segmenation with input and output set to NULL to calculate only (C, K, Z, F)
nr_segmentation(NULL, nr_segmentation(NULL,
NULL, NULL,
...@@ -211,40 +205,34 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, ...@@ -211,40 +205,34 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
harq_process->K = TB_parameters->K; harq_process->K = TB_parameters->K;
harq_process->Z = TB_parameters->Z; harq_process->Z = TB_parameters->Z;
harq_process->F = TB_parameters->F; harq_process->F = TB_parameters->F;
uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER * TB_parameters->nb_layers; // number of segments to be allocated uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER * TB_parameters->nb_layers; // number of segments to be allocated
if (TB_parameters->C > a_segments) { if (TB_parameters->C > a_segments) {
LOG_E(PHY, "nr_segmentation.c: too many segments %d, A %d\n", harq_process->C, TB_parameters->A); LOG_E(PHY, "nr_segmentation.c: too many segments %d, A %d\n", harq_process->C, TB_parameters->A);
return(-1); return (-1);
} }
if (TB_parameters->nb_rb != 273) { if (TB_parameters->nb_rb != 273) {
a_segments = a_segments*TB_parameters->nb_rb; a_segments = a_segments * TB_parameters->nb_rb;
a_segments = a_segments/273 +1; a_segments = a_segments / 273 + 1;
} }
if (TB_parameters->C > a_segments) { if (TB_parameters->C > a_segments) {
LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,a_segments); LOG_E(PHY, "Illegal harq_process->C %d > %d\n", harq_process->C, a_segments);
return -1; return -1;
} }
max_num_segments = max(max_num_segments, TB_parameters->C); max_num_segments = max(max_num_segments, TB_parameters->C);
#ifdef DEBUG_ULSCH_DECODING #ifdef DEBUG_ULSCH_DECODING
printf("ulsch decoding nr segmentation Z %d\n", TB_parameters->Z); printf("ulsch decoding nr segmentation Z %d\n", TB_parameters->Z);
if (!frame % 100) if (!frame % 100)
printf("K %d C %d Z %d \n", printf("K %d C %d Z %d \n", TB_parameters->K, TB_parameters->C, TB_parameters->Z);
TB_parameters->K, printf("Segmentation: C %d, K %d\n", TB_parameters->C, TB_parameters->K);
TB_parameters->C,
TB_parameters->Z);
printf("Segmentation: C %d, K %d\n",
TB_parameters->C,
TB_parameters->K);
#endif #endif
TB_parameters->max_ldpc_iterations = ulsch->max_ldpc_iterations; TB_parameters->max_ldpc_iterations = ulsch->max_ldpc_iterations;
TB_parameters->rv_index = pusch_pdu->pusch_data.rv_index; TB_parameters->rv_index = pusch_pdu->pusch_data.rv_index;
TB_parameters->tbslbrm = pusch_pdu->maintenance_parms_v3.tbSizeLbrmBytes; TB_parameters->tbslbrm = pusch_pdu->maintenance_parms_v3.tbSizeLbrmBytes;
TB_parameters->abort_decode = &harq_process->abort_decode; TB_parameters->abort_decode = &harq_process->abort_decode;
set_abort(&harq_process->abort_decode, false); set_abort(&harq_process->abort_decode, false);
} }
nrLDPC_segment_decoding_parameters_t segments[nb_pusch][max_num_segments]; nrLDPC_segment_decoding_parameters_t segments[nb_pusch][max_num_segments];
...@@ -267,11 +255,7 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, ...@@ -267,11 +255,7 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
uint32_t r_offset = 0; uint32_t r_offset = 0;
for (int r = 0; r < TB_parameters->C; r++) { for (int r = 0; r < TB_parameters->C; r++) {
nrLDPC_segment_decoding_parameters_t *segment_parameters = &TB_parameters->segments[r]; nrLDPC_segment_decoding_parameters_t *segment_parameters = &TB_parameters->segments[r];
segment_parameters->E = nr_get_E(TB_parameters->G, segment_parameters->E = nr_get_E(TB_parameters->G, TB_parameters->C, TB_parameters->Qm, TB_parameters->nb_layers, r);
TB_parameters->C,
TB_parameters->Qm,
TB_parameters->nb_layers,
r);
segment_parameters->R = nr_get_R_ldpc_decoder(TB_parameters->rv_index, segment_parameters->R = nr_get_R_ldpc_decoder(TB_parameters->rv_index,
segment_parameters->E, segment_parameters->E,
TB_parameters->BG, TB_parameters->BG,
...@@ -296,7 +280,6 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, ...@@ -296,7 +280,6 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
} }
harq_process->harq_to_be_cleared = false; harq_process->harq_to_be_cleared = false;
} }
} }
int ret_decoder = phy_vars_gNB->nrLDPC_coding_interface.nrLDPC_coding_decoder(&slot_parameters); int ret_decoder = phy_vars_gNB->nrLDPC_coding_interface.nrLDPC_coding_decoder(&slot_parameters);
...@@ -314,7 +297,9 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, ...@@ -314,7 +297,9 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
nrLDPC_segment_decoding_parameters_t nrLDPC_segment_decoding_parameters = TB_parameters.segments[r]; nrLDPC_segment_decoding_parameters_t nrLDPC_segment_decoding_parameters = TB_parameters.segments[r];
// Copy c to b in case of decoding success // Copy c to b in case of decoding success
if (nrLDPC_segment_decoding_parameters.decodeSuccess) { if (nrLDPC_segment_decoding_parameters.decodeSuccess) {
memcpy(harq_process->b + offset, harq_process->c[r], (harq_process->K >> 3) - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0)); memcpy(harq_process->b + offset,
harq_process->c[r],
(harq_process->K >> 3) - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0));
} else { } else {
LOG_D(PHY, "uplink segment error %d/%d\n", r, harq_process->C); LOG_D(PHY, "uplink segment error %d/%d\n", r, harq_process->C);
LOG_D(PHY, "ULSCH %d in error\n", ULSCH_id); LOG_D(PHY, "ULSCH %d in error\n", ULSCH_id);
......
...@@ -142,6 +142,7 @@ Channel simulation parameters can also be specified on the command line by using ...@@ -142,6 +142,7 @@ Channel simulation parameters can also be specified on the command line by using
|:--- |:---- |:---- |:----| |:--- |:---- |:---- |:----|
|`modellist` |char string |`DefaultChannelList`|select and load the `modellist` from the config file.| |`modellist` |char string |`DefaultChannelList`|select and load the `modellist` from the config file.|
|`max_chan` |integer |10 |set the maximum number of channel models that can be defined in the system. Must be greater than the number of model definitions in the model list loaded at init time.| |`max_chan` |integer |10 |set the maximum number of channel models that can be defined in the system. Must be greater than the number of model definitions in the model list loaded at init time.|
|`noise_power_dBFS` |integer |0 |Noise power in dBFS. If set, noise per channel is not applied. To achieve positive SNR use values below the default gNB/nrUE amp backoff value (-36dBFS)|
Example usage: Example usage:
```bash ```bash
......
...@@ -73,6 +73,7 @@ static telnetshell_vardef_t channelmod_vardef[] = {{"", 0, 0, NULL}}; ...@@ -73,6 +73,7 @@ static telnetshell_vardef_t channelmod_vardef[] = {{"", 0, 0, NULL}};
static unsigned int max_chan; static unsigned int max_chan;
static channel_desc_t **defined_channels; static channel_desc_t **defined_channels;
static char *modellist_name; static char *modellist_name;
static int noise_power_dBFS = INVALID_DBFS_VALUE;
void fill_channel_desc(channel_desc_t *chan_desc, void fill_channel_desc(channel_desc_t *chan_desc,
uint8_t nb_tx, uint8_t nb_tx,
...@@ -2365,6 +2366,10 @@ int load_channellist(uint8_t nb_tx, uint8_t nb_rx, double sampling_rate, uint64_ ...@@ -2365,6 +2366,10 @@ int load_channellist(uint8_t nb_tx, uint8_t nb_rx, double sampling_rate, uint64_
return channel_list.numelt; return channel_list.numelt;
} /* load_channelist */ } /* load_channelist */
int get_noise_power_dBFS(void) {
return noise_power_dBFS;
}
#ifdef RANDOM_CHANNEL_MAIN #ifdef RANDOM_CHANNEL_MAIN
#define sampling_rate 5.0 #define sampling_rate 5.0
#define Td 2.0 #define Td 2.0
......
...@@ -278,10 +278,15 @@ typedef enum { ...@@ -278,10 +278,15 @@ typedef enum {
#define CHANNELMOD_MODELLIST_PARANAME "modellist" #define CHANNELMOD_MODELLIST_PARANAME "modellist"
#define CHANNELMOD_HELP_MODELLIST "<list name> channel list name in config file describing the model type and its parameters\n" #define CHANNELMOD_HELP_MODELLIST "<list name> channel list name in config file describing the model type and its parameters\n"
#define CHANNELMOD_HELP_NOISE_POWER \
"Noise power in dBFS. If set, noise per channel is not applied. To achieve positive SNR use values below -36dBFS\n"
#define INVALID_DBFS_VALUE 100
// clang-format off // clang-format off
#define CHANNELMOD_PARAMS_DESC { \ #define CHANNELMOD_PARAMS_DESC { \
{"max_chan", "Max number of runtime models", 0, .uptr=&max_chan, .defintval=10, TYPE_UINT, 0}, \ {"max_chan", "Max number of runtime models", 0, .uptr=&max_chan, .defintval=10, TYPE_UINT, 0}, \
{CHANNELMOD_MODELLIST_PARANAME, CHANNELMOD_HELP_MODELLIST, 0, .strptr=&modellist_name, .defstrval="DefaultChannelList", TYPE_STRING, 0}, \ {CHANNELMOD_MODELLIST_PARANAME, CHANNELMOD_HELP_MODELLIST, 0, .strptr=&modellist_name, .defstrval="DefaultChannelList", TYPE_STRING, 0}, \
{"noise_power_dBFS", CHANNELMOD_HELP_NOISE_POWER, 0, .iptr=&noise_power_dBFS, .defintval=INVALID_DBFS_VALUE, TYPE_INT, 0 },\
} }
// clang-format on // clang-format on
...@@ -585,5 +590,6 @@ void do_DL_sig(sim_t *sim, ...@@ -585,5 +590,6 @@ void do_DL_sig(sim_t *sim,
int CC_id); int CC_id);
void do_UL_sig(sim_t *sim, uint16_t subframe, uint8_t abstraction_flag, LTE_DL_FRAME_PARMS *frame_parms, uint32_t frame, int ru_id, uint8_t CC_id, int NB_UEs); void do_UL_sig(sim_t *sim, uint16_t subframe, uint8_t abstraction_flag, LTE_DL_FRAME_PARMS *frame_parms, uint32_t frame, int ru_id, uint8_t CC_id, int NB_UEs);
int get_noise_power_dBFS(void);
#endif #endif
...@@ -404,6 +404,13 @@ typedef struct nas_detach_req_s { ...@@ -404,6 +404,13 @@ typedef struct nas_detach_req_s {
bool wait_release; bool wait_release;
} nas_detach_req_t; } nas_detach_req_t;
/**
* @brief 5GS mobility management information
* @ref clause 9.11.3 of 3GPP TS 24.501
*/
typedef struct nas_5gmm_ind_s {
uint64_t fiveG_STMSI;
} nas_5gmm_ind_t;
/* /*
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* NAS information transfer * NAS information transfer
...@@ -578,6 +585,7 @@ typedef struct as_message_s { ...@@ -578,6 +585,7 @@ typedef struct as_message_s {
rab_establish_cnf_t rab_establish_cnf; rab_establish_cnf_t rab_establish_cnf;
rab_release_req_t rab_release_req; rab_release_req_t rab_release_req;
rab_release_ind_t rab_release_ind; rab_release_ind_t rab_release_ind;
nas_5gmm_ind_t Nas5GMMInd;
} __attribute__((__packed__)) msg; } __attribute__((__packed__)) msg;
} as_message_t; } as_message_t;
......
...@@ -63,6 +63,7 @@ MESSAGE_DEF(NAS_CONN_ESTABLI_REQ, MESSAGE_PRIORITY_MED, nas_establish_req_t, nas ...@@ -63,6 +63,7 @@ MESSAGE_DEF(NAS_CONN_ESTABLI_REQ, MESSAGE_PRIORITY_MED, nas_establish_req_t, nas
MESSAGE_DEF(NAS_UPLINK_DATA_REQ, MESSAGE_PRIORITY_MED, ul_info_transfer_req_t, nas_ul_data_req) MESSAGE_DEF(NAS_UPLINK_DATA_REQ, MESSAGE_PRIORITY_MED, ul_info_transfer_req_t, nas_ul_data_req)
MESSAGE_DEF(NAS_DETACH_REQ, MESSAGE_PRIORITY_MED, nas_detach_req_t, nas_detach_req) MESSAGE_DEF(NAS_DETACH_REQ, MESSAGE_PRIORITY_MED, nas_detach_req_t, nas_detach_req)
MESSAGE_DEF(NAS_DEREGISTRATION_REQ, MESSAGE_PRIORITY_MED, nas_deregistration_req_t, nas_deregistration_req) MESSAGE_DEF(NAS_DEREGISTRATION_REQ, MESSAGE_PRIORITY_MED, nas_deregistration_req_t, nas_deregistration_req)
MESSAGE_DEF(NAS_5GMM_IND, MESSAGE_PRIORITY_MED, nas_5gmm_ind_t, nas_5gmm_ind)
MESSAGE_DEF(NAS_RAB_ESTABLI_RSP, MESSAGE_PRIORITY_MED, rab_establish_rsp_t, nas_rab_est_rsp) MESSAGE_DEF(NAS_RAB_ESTABLI_RSP, MESSAGE_PRIORITY_MED, rab_establish_rsp_t, nas_rab_est_rsp)
...@@ -74,6 +75,7 @@ MESSAGE_DEF(NAS_CELL_SELECTION_IND, MESSAGE_PRIORITY_MED, cell_info_ind_t, nas_c ...@@ -74,6 +75,7 @@ MESSAGE_DEF(NAS_CELL_SELECTION_IND, MESSAGE_PRIORITY_MED, cell_info_ind_t, nas_c
MESSAGE_DEF(NAS_PAGING_IND, MESSAGE_PRIORITY_MED, paging_ind_t, nas_paging_ind) MESSAGE_DEF(NAS_PAGING_IND, MESSAGE_PRIORITY_MED, paging_ind_t, nas_paging_ind)
MESSAGE_DEF(NAS_CONN_ESTABLI_CNF, MESSAGE_PRIORITY_MED, nas_establish_cnf_t, nas_conn_establi_cnf) MESSAGE_DEF(NAS_CONN_ESTABLI_CNF, MESSAGE_PRIORITY_MED, nas_establish_cnf_t, nas_conn_establi_cnf)
MESSAGE_DEF(NAS_CONN_RELEASE_IND, MESSAGE_PRIORITY_MED, nas_release_ind_t, nas_conn_release_ind) MESSAGE_DEF(NAS_CONN_RELEASE_IND, MESSAGE_PRIORITY_MED, nas_release_ind_t, nas_conn_release_ind)
MESSAGE_DEF(NR_NAS_CONN_ESTABLISH_IND, MESSAGE_PRIORITY_MED, nas_establish_ind_t, nr_nas_conn_establish_ind)
MESSAGE_DEF(NR_NAS_CONN_RELEASE_IND, MESSAGE_PRIORITY_MED, NRNasConnReleaseInd, nr_nas_conn_release_ind) MESSAGE_DEF(NR_NAS_CONN_RELEASE_IND, MESSAGE_PRIORITY_MED, NRNasConnReleaseInd, nr_nas_conn_release_ind)
MESSAGE_DEF(NAS_UPLINK_DATA_CNF, MESSAGE_PRIORITY_MED, ul_info_transfer_cnf_t, nas_ul_data_cnf) MESSAGE_DEF(NAS_UPLINK_DATA_CNF, MESSAGE_PRIORITY_MED, ul_info_transfer_cnf_t, nas_ul_data_cnf)
MESSAGE_DEF(NAS_DOWNLINK_DATA_IND, MESSAGE_PRIORITY_MED, dl_info_transfer_ind_t, nas_dl_data_ind) MESSAGE_DEF(NAS_DOWNLINK_DATA_IND, MESSAGE_PRIORITY_MED, dl_info_transfer_ind_t, nas_dl_data_ind)
......
...@@ -76,6 +76,7 @@ ...@@ -76,6 +76,7 @@
#define NAS_UPLINK_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_ul_data_req #define NAS_UPLINK_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_ul_data_req
#define NAS_DETACH_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_detach_req #define NAS_DETACH_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_detach_req
#define NAS_DEREGISTRATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_deregistration_req #define NAS_DEREGISTRATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_deregistration_req
#define NAS_5GMM_IND(mSGpTR) (mSGpTR)->ittiMsg.nas_5gmm_ind
#define NAS_RAB_ESTABLI_RSP(mSGpTR) (mSGpTR)->ittiMsg.nas_rab_est_rsp #define NAS_RAB_ESTABLI_RSP(mSGpTR) (mSGpTR)->ittiMsg.nas_rab_est_rsp
...@@ -84,6 +85,7 @@ ...@@ -84,6 +85,7 @@
#define NAS_PAGING_IND(mSGpTR) (mSGpTR)->ittiMsg.nas_paging_ind #define NAS_PAGING_IND(mSGpTR) (mSGpTR)->ittiMsg.nas_paging_ind
#define NAS_CONN_ESTABLI_CNF(mSGpTR) (mSGpTR)->ittiMsg.nas_conn_establi_cnf #define NAS_CONN_ESTABLI_CNF(mSGpTR) (mSGpTR)->ittiMsg.nas_conn_establi_cnf
#define NAS_CONN_RELEASE_IND(mSGpTR) (mSGpTR)->ittiMsg.nas_conn_release_ind #define NAS_CONN_RELEASE_IND(mSGpTR) (mSGpTR)->ittiMsg.nas_conn_release_ind
#define NR_NAS_CONN_ESTABLISH_IND(mSGpTR) (mSGpTR)->ittiMsg.nr_nas_conn_establish_ind
#define NR_NAS_CONN_RELEASE_IND(mSGpTR) (mSGpTR)->ittiMsg.nr_nas_conn_release_ind #define NR_NAS_CONN_RELEASE_IND(mSGpTR) (mSGpTR)->ittiMsg.nr_nas_conn_release_ind
#define NAS_UPLINK_DATA_CNF(mSGpTR) (mSGpTR)->ittiMsg.nas_ul_data_cnf #define NAS_UPLINK_DATA_CNF(mSGpTR) (mSGpTR)->ittiMsg.nas_ul_data_cnf
#define NAS_DOWNLINK_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.nas_dl_data_ind #define NAS_DOWNLINK_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.nas_dl_data_ind
......
...@@ -404,6 +404,31 @@ static int read_slice_info(const F1AP_ServedPLMNs_Item_t *plmn, nssai_t *nssai, ...@@ -404,6 +404,31 @@ static int read_slice_info(const F1AP_ServedPLMNs_Item_t *plmn, nssai_t *nssai,
return ssl->list.count; return ssl->list.count;
} }
static F1AP_ProtocolExtensionContainer_10696P34_t *write_slice_info(int num_ssi, const nssai_t *nssai)
{
if (num_ssi == 0)
return NULL;
F1AP_ProtocolExtensionContainer_10696P34_t *p = calloc_or_fail(1, sizeof(*p));
asn1cSequenceAdd(p->list, F1AP_ServedPLMNs_ItemExtIEs_t, served_plmns_itemExtIEs);
served_plmns_itemExtIEs->criticality = F1AP_Criticality_ignore;
served_plmns_itemExtIEs->id = F1AP_ProtocolIE_ID_id_TAISliceSupportList;
served_plmns_itemExtIEs->extensionValue.present = F1AP_ServedPLMNs_ItemExtIEs__extensionValue_PR_SliceSupportList;
F1AP_SliceSupportList_t *slice_support_list = &served_plmns_itemExtIEs->extensionValue.choice.SliceSupportList;
for (int s = 0; s < num_ssi; s++) {
asn1cSequenceAdd(slice_support_list->list, F1AP_SliceSupportItem_t, slice);
const nssai_t *n = &nssai[s];
INT8_TO_OCTET_STRING(n->sst, &slice->sNSSAI.sST);
if (n->sd != 0xffffff) {
asn1cCalloc(slice->sNSSAI.sD, tmp);
INT24_TO_OCTET_STRING(n->sd, tmp);
}
}
return p;
}
/** /**
* @brief F1AP Setup Request memory management * @brief F1AP Setup Request memory management
*/ */
...@@ -468,6 +493,8 @@ static F1AP_Served_Cell_Information_t encode_served_cell_info(const f1ap_served_ ...@@ -468,6 +493,8 @@ static F1AP_Served_Cell_Information_t encode_served_cell_info(const f1ap_served_
asn1cSequenceAdd(scell_info.servedPLMNs.list, F1AP_ServedPLMNs_Item_t, servedPLMN_item); asn1cSequenceAdd(scell_info.servedPLMNs.list, F1AP_ServedPLMNs_Item_t, servedPLMN_item);
// PLMN Identity (M) // PLMN Identity (M)
MCC_MNC_TO_PLMNID(c->plmn.mcc, c->plmn.mnc, c->plmn.mnc_digit_length, &servedPLMN_item->pLMN_Identity); MCC_MNC_TO_PLMNID(c->plmn.mcc, c->plmn.mnc, c->plmn.mnc_digit_length, &servedPLMN_item->pLMN_Identity);
// NSSAIs (O)
servedPLMN_item->iE_Extensions = (struct F1AP_ProtocolExtensionContainer *)write_slice_info(c->num_ssi, c->nssai);
// NR-Mode-Info (M) // NR-Mode-Info (M)
F1AP_NR_Mode_Info_t *nR_Mode_Info = &scell_info.nR_Mode_Info; F1AP_NR_Mode_Info_t *nR_Mode_Info = &scell_info.nR_Mode_Info;
if (c->mode == F1AP_MODE_FDD) { // FDD Info if (c->mode == F1AP_MODE_FDD) { // FDD Info
......
...@@ -57,6 +57,11 @@ bool eq_f1ap_cell_info(const f1ap_served_cell_info_t *a, const f1ap_served_cell_ ...@@ -57,6 +57,11 @@ bool eq_f1ap_cell_info(const f1ap_served_cell_info_t *a, const f1ap_served_cell_
return false; return false;
if (a->tac) if (a->tac)
_F1_EQ_CHECK_INT(*a->tac, *b->tac); _F1_EQ_CHECK_INT(*a->tac, *b->tac);
_F1_EQ_CHECK_INT(a->num_ssi, b->num_ssi);
for (int i = 0; i < a->num_ssi; ++i) {
_F1_EQ_CHECK_INT(a->nssai[i].sst, b->nssai[i].sst);
_F1_EQ_CHECK_INT(a->nssai[i].sd, b->nssai[i].sd);
}
_F1_EQ_CHECK_INT(a->mode, b->mode); _F1_EQ_CHECK_INT(a->mode, b->mode);
if (a->mode == F1AP_MODE_TDD) { if (a->mode == F1AP_MODE_TDD) {
/* TDD */ /* TDD */
......
...@@ -39,9 +39,7 @@ ...@@ -39,9 +39,7 @@
#include "executables/softmodem-common.h" #include "executables/softmodem-common.h"
#include <stdio.h> #include <stdio.h>
void fill_dci_search_candidates(const NR_SearchSpace_t *ss, void fill_dci_search_candidates(const NR_SearchSpace_t *ss, fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15, const uint32_t Y)
fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15,
const uint32_t Y)
{ {
LOG_T(NR_MAC_DCI, "Filling search candidates for DCI\n"); LOG_T(NR_MAC_DCI, "Filling search candidates for DCI\n");
...@@ -320,6 +318,11 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, ...@@ -320,6 +318,11 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac,
if (ss->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific) if (ss->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific)
Y = get_Y(ss, slot, rel15->rnti); Y = get_Y(ss, slot, rel15->rnti);
fill_dci_search_candidates(ss, rel15, Y); fill_dci_search_candidates(ss, rel15, Y);
// not scheduling DCI reception if there are no candidates
if (rel15->number_of_candidates == 0) {
LOG_E(NR_MAC, "No candidates in this DCI, not scheduling it");
return;
}
#ifdef DEBUG_DCI #ifdef DEBUG_DCI
for (int i = 0; i < rel15->num_dci_options; i++) { for (int i = 0; i < rel15->num_dci_options; i++) {
......
...@@ -2248,7 +2248,13 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP, ...@@ -2248,7 +2248,13 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP,
nr_clear_ra_proc(ra); nr_clear_ra_proc(ra);
} else { } else {
ra->ra_state = nrRA_WAIT_Msg4_MsgB_ACK; ra->ra_state = nrRA_WAIT_Msg4_MsgB_ACK;
LOG_I(NR_MAC,"UE %04x Generate msg4: feedback at %4d.%2d, payload %d bytes, next state WAIT_Msg4_ACK\n", ra->rnti, pucch->frame, pucch->ul_slot, harq->tb_size); LOG_I(NR_MAC,
"UE %04x Generate %s: feedback at %4d.%2d, payload %d bytes, next state nrRA_WAIT_Msg4_MsgB_ACK\n",
ra->rnti,
ra_type_str,
pucch->frame,
pucch->ul_slot,
harq->tb_size);
} }
} }
} }
...@@ -2294,7 +2300,7 @@ static void nr_check_Msg4_MsgB_Ack(module_id_t module_id, int CC_id, frame_t fra ...@@ -2294,7 +2300,7 @@ static void nr_check_Msg4_MsgB_Ack(module_id_t module_id, int CC_id, frame_t fra
remove_nr_list(&sched_ctrl->retrans_dl_harq, current_harq_pid); remove_nr_list(&sched_ctrl->retrans_dl_harq, current_harq_pid);
} }
} else { } else {
LOG_I(NR_MAC, "(UE %04x) Received Nack in %s, preparing retransmission!\n", ra->rnti, nrra_text[ra->ra_state]); LOG_I(NR_MAC, "(UE %04x) Received Nack in %s, preparing retransmission!\n", ra->rnti, ra_type_str);
ra->ra_state = ra->ra_type == RA_4_STEP ? nrRA_Msg4 : nrRA_MsgB; ra->ra_state = ra->ra_type == RA_4_STEP ? nrRA_Msg4 : nrRA_MsgB;
} }
} }
......
...@@ -126,7 +126,7 @@ typedef enum { ...@@ -126,7 +126,7 @@ typedef enum {
} RA_gNB_state_t; } RA_gNB_state_t;
static const char *const nrra_text[] = static const char *const nrra_text[] =
{"IDLE", "Msg2", "WAIT_MsgA_PUSCH", "WAIT_Msg3", "Msg3_retransmission", "Msg3_dcch_dtch", "Msg4", "MsgB", "WAIT_Msg4_ACK"}; {"IDLE", "Msg2", "WAIT_MsgA_PUSCH", "WAIT_Msg3", "Msg3_retransmission", "Msg4", "MsgB", "WAIT_Msg4_MsgB_ACK"};
typedef struct { typedef struct {
int idx; int idx;
......
...@@ -765,7 +765,7 @@ int do_RRCReconfiguration(const gNB_RRC_UE_t *UE, ...@@ -765,7 +765,7 @@ int do_RRCReconfiguration(const gNB_RRC_UE_t *UE,
return((enc_rval.encoded+7)/8); return((enc_rval.encoded+7)/8);
} }
int do_RRCSetupRequest(uint8_t *buffer, size_t buffer_size, uint8_t *rv) int do_RRCSetupRequest(uint8_t *buffer, size_t buffer_size, uint8_t *rv, uint64_t fiveG_S_TMSI)
{ {
NR_UL_CCCH_Message_t ul_ccch_msg = {0}; NR_UL_CCCH_Message_t ul_ccch_msg = {0};
ul_ccch_msg.message.present = NR_UL_CCCH_MessageType_PR_c1; ul_ccch_msg.message.present = NR_UL_CCCH_MessageType_PR_c1;
...@@ -773,24 +773,34 @@ int do_RRCSetupRequest(uint8_t *buffer, size_t buffer_size, uint8_t *rv) ...@@ -773,24 +773,34 @@ int do_RRCSetupRequest(uint8_t *buffer, size_t buffer_size, uint8_t *rv)
c1->present = NR_UL_CCCH_MessageType__c1_PR_rrcSetupRequest; c1->present = NR_UL_CCCH_MessageType__c1_PR_rrcSetupRequest;
asn1cCalloc(c1->choice.rrcSetupRequest, rrcSetupRequest); asn1cCalloc(c1->choice.rrcSetupRequest, rrcSetupRequest);
if (1) { if (fiveG_S_TMSI == UINT64_MAX) {
/* set the ue-Identity to a random value */
rrcSetupRequest->rrcSetupRequest.ue_Identity.present = NR_InitialUE_Identity_PR_randomValue; rrcSetupRequest->rrcSetupRequest.ue_Identity.present = NR_InitialUE_Identity_PR_randomValue;
BIT_STRING_t *str = &rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.randomValue; BIT_STRING_t *str = &rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.randomValue;
str->size = 5; str->size = 5;
str->bits_unused = 1; str->bits_unused = 1;
str->buf = CALLOC(1, str->size); str->buf = calloc_or_fail(str->size, sizeof(str->buf[0]));
str->buf[0] = rv[0]; str->buf[0] = rv[0];
str->buf[1] = rv[1]; str->buf[1] = rv[1];
str->buf[2] = rv[2]; str->buf[2] = rv[2];
str->buf[3] = rv[3]; str->buf[3] = rv[3];
str->buf[4] = rv[4] & 0xfe; str->buf[4] = rv[4] & 0xfe;
} else { } else {
uint64_t fiveG_S_TMSI_part1 = fiveG_S_TMSI & ((1ULL << 39) - 1);
/** set the ue-Identity to ng-5G-S-TMSI-Part1
* ng-5G-S-TMSI-Part1: the rightmost 39 bits of 5G-S-TMSI
* BIT STRING (SIZE (39)) - 3GPP TS 38.331 */
LOG_D(NR_RRC, "5G-S-TMSI: %lu, set the ue-Identity to ng-5G-S-TMSI-Part1 %lu\n", fiveG_S_TMSI, fiveG_S_TMSI_part1);
rrcSetupRequest->rrcSetupRequest.ue_Identity.present = NR_InitialUE_Identity_PR_ng_5G_S_TMSI_Part1; rrcSetupRequest->rrcSetupRequest.ue_Identity.present = NR_InitialUE_Identity_PR_ng_5G_S_TMSI_Part1;
BIT_STRING_t *str = &rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.ng_5G_S_TMSI_Part1; BIT_STRING_t *str = &rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.ng_5G_S_TMSI_Part1;
str->size = 1; str->size = 5;
str->bits_unused = 0; str->bits_unused = 1;
str->buf = CALLOC(1, str->size); str->buf = calloc_or_fail(str->size, sizeof(str->buf[0]));
str->buf[0] = 0x12; str->buf[0] = (fiveG_S_TMSI_part1 >> 31) & 0xff;
str->buf[1] = (fiveG_S_TMSI_part1 >> 23) & 0xff;
str->buf[2] = (fiveG_S_TMSI_part1 >> 15) & 0xff;
str->buf[3] = (fiveG_S_TMSI_part1 >> 7) & 0xff;
str->buf[4] = (fiveG_S_TMSI_part1 << 1) & 0xff;
} }
rrcSetupRequest->rrcSetupRequest.establishmentCause = NR_EstablishmentCause_mo_Signalling; //EstablishmentCause_mo_Data; rrcSetupRequest->rrcSetupRequest.establishmentCause = NR_EstablishmentCause_mo_Signalling; //EstablishmentCause_mo_Data;
...@@ -872,6 +882,8 @@ int do_RRCSetupComplete(uint8_t *buffer, ...@@ -872,6 +882,8 @@ int do_RRCSetupComplete(uint8_t *buffer,
size_t buffer_size, size_t buffer_size,
const uint8_t Transaction_id, const uint8_t Transaction_id,
uint8_t sel_plmn_id, uint8_t sel_plmn_id,
bool is_rrc_connection_setup,
uint64_t fiveG_s_tmsi,
const int dedicatedInfoNASLength, const int dedicatedInfoNASLength,
const char *dedicatedInfoNAS) const char *dedicatedInfoNAS)
{ {
...@@ -887,7 +899,31 @@ int do_RRCSetupComplete(uint8_t *buffer, ...@@ -887,7 +899,31 @@ int do_RRCSetupComplete(uint8_t *buffer,
NR_RRCSetupComplete_IEs_t *ies = RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete; NR_RRCSetupComplete_IEs_t *ies = RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete;
ies->selectedPLMN_Identity = sel_plmn_id; ies->selectedPLMN_Identity = sel_plmn_id;
ies->registeredAMF = NULL; ies->registeredAMF = NULL;
ies->ng_5G_S_TMSI_Value = NULL; /* RRCSetup is received in response to an RRCSetupRequest
* set the ng-5G-S-TMSI-Value to ng-5G-S-TMSI-Part2
* i.e. the leftmost 9 bits of 5G-S-TMSI (5.3.3.4 of 3GPP TS 38.331) */
if (fiveG_s_tmsi != UINT64_MAX) {
if (is_rrc_connection_setup) {
ies->ng_5G_S_TMSI_Value = calloc_or_fail(1, sizeof(*ies->ng_5G_S_TMSI_Value));
ies->ng_5G_S_TMSI_Value->present = NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value_PR_ng_5G_S_TMSI_Part2;
BIT_STRING_t *str = &ies->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI_Part2;
str->size = 2;
str->bits_unused = 7;
str->buf = calloc_or_fail(str->size, sizeof(str->buf[0]));
uint16_t fiveG_s_tmsi_part2 = (fiveG_s_tmsi >> 39) & ((1ULL << 9) - 1);
str->buf[0] = (fiveG_s_tmsi_part2 >> (8 - str->bits_unused)) & 0xFF;
str->buf[1] = (fiveG_s_tmsi_part2 << str->bits_unused) & 0xFF;
LOG_D(NR_RRC, "5G-S-TMSI part 2 %d in RRCSetupComplete (5G-S-TMSI %ld)\n", fiveG_s_tmsi_part2, fiveG_s_tmsi);
} else {
ies->ng_5G_S_TMSI_Value = CALLOC(1, sizeof(struct NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value));
ies->ng_5G_S_TMSI_Value->present = NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value_PR_ng_5G_S_TMSI;
FIVEG_S_TMSI_TO_BIT_STRING(fiveG_s_tmsi, &ies->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI);
LOG_D(NR_RRC, "5G-S-TMSI %lu in RRCSetupComplete\n", fiveG_s_tmsi);
}
} else {
LOG_D(NR_RRC, "5G-S-TMSI is not available!\n");
ies->ng_5G_S_TMSI_Value = NULL;
}
memset(&ies->dedicatedNAS_Message,0,sizeof(OCTET_STRING_t)); memset(&ies->dedicatedNAS_Message,0,sizeof(OCTET_STRING_t));
OCTET_STRING_fromBuf(&ies->dedicatedNAS_Message, dedicatedInfoNAS, dedicatedInfoNASLength); OCTET_STRING_fromBuf(&ies->dedicatedNAS_Message, dedicatedInfoNAS, dedicatedInfoNASLength);
......
...@@ -119,12 +119,14 @@ int do_RRCSetupComplete(uint8_t *buffer, ...@@ -119,12 +119,14 @@ int do_RRCSetupComplete(uint8_t *buffer,
size_t buffer_size, size_t buffer_size,
const uint8_t Transaction_id, const uint8_t Transaction_id,
uint8_t sel_plmn_id, uint8_t sel_plmn_id,
bool is_rrc_connection_setup,
uint64_t fiveG_S_TMSI,
const int dedicatedInfoNASLength, const int dedicatedInfoNASLength,
const char *dedicatedInfoNAS); const char *dedicatedInfoNAS);
int do_NR_HandoverPreparationInformation(const uint8_t *uecap_buf, int uecap_buf_size, uint8_t *buf, int buf_size); int do_NR_HandoverPreparationInformation(const uint8_t *uecap_buf, int uecap_buf_size, uint8_t *buf, int buf_size);
int do_RRCSetupRequest(uint8_t *buffer, size_t buffer_size, uint8_t *rv); int do_RRCSetupRequest(uint8_t *buffer, size_t buffer_size, uint8_t *rv, uint64_t fiveG_S_TMSI_part1);
int do_NR_RRCReconfigurationComplete_for_nsa(uint8_t *buffer, size_t buffer_size, NR_RRC_TransactionIdentifier_t Transaction_id); int do_NR_RRCReconfigurationComplete_for_nsa(uint8_t *buffer, size_t buffer_size, NR_RRC_TransactionIdentifier_t Transaction_id);
......
...@@ -149,6 +149,7 @@ void process_msg_rcc_to_mac(MessageDef *msg) ...@@ -149,6 +149,7 @@ void process_msg_rcc_to_mac(MessageDef *msg)
default: default:
LOG_E(NR_MAC, "Unexpected msg from RRC: %d\n", ITTI_MSG_ID(msg)); LOG_E(NR_MAC, "Unexpected msg from RRC: %d\n", ITTI_MSG_ID(msg));
} }
itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
} }
void nr_mac_rrc_inactivity_timer_ind(const module_id_t mod_id) void nr_mac_rrc_inactivity_timer_ind(const module_id_t mod_id)
......
...@@ -276,7 +276,7 @@ static void nr_rrc_ue_prepare_RRCSetupRequest(NR_UE_RRC_INST_t *rrc) ...@@ -276,7 +276,7 @@ static void nr_rrc_ue_prepare_RRCSetupRequest(NR_UE_RRC_INST_t *rrc)
} }
uint8_t buf[1024]; uint8_t buf[1024];
int len = do_RRCSetupRequest(buf, sizeof(buf), rv); int len = do_RRCSetupRequest(buf, sizeof(buf), rv, rrc->fiveG_S_TMSI);
nr_rlc_srb_recv_sdu(rrc->ue_id, 0, buf, len); nr_rlc_srb_recv_sdu(rrc->ue_id, 0, buf, len);
} }
...@@ -601,6 +601,8 @@ NR_UE_RRC_INST_t* nr_rrc_init_ue(char* uecap_file, int nb_inst, int num_ant_tx) ...@@ -601,6 +601,8 @@ NR_UE_RRC_INST_t* nr_rrc_init_ue(char* uecap_file, int nb_inst, int num_ant_tx)
rrc->as_security_activated = false; rrc->as_security_activated = false;
rrc->detach_after_release = false; rrc->detach_after_release = false;
rrc->reconfig_after_reestab = false; rrc->reconfig_after_reestab = false;
/* 5G-S-TMSI */
rrc->fiveG_S_TMSI = UINT64_MAX;
FILE *f = NULL; FILE *f = NULL;
if (uecap_file) if (uecap_file)
...@@ -1123,26 +1125,38 @@ static void nr_rrc_ue_process_masterCellGroup(NR_UE_RRC_INST_t *rrc, ...@@ -1123,26 +1125,38 @@ static void nr_rrc_ue_process_masterCellGroup(NR_UE_RRC_INST_t *rrc,
static void rrc_ue_generate_RRCSetupComplete(const NR_UE_RRC_INST_t *rrc, const uint8_t Transaction_id) static void rrc_ue_generate_RRCSetupComplete(const NR_UE_RRC_INST_t *rrc, const uint8_t Transaction_id)
{ {
uint8_t buffer[100]; uint8_t buffer[100];
const char *nas_msg; as_nas_info_t initialNasMsg;
int nas_msg_length;
if (IS_SA_MODE(get_softmodem_params())) { if (IS_SA_MODE(get_softmodem_params())) {
as_nas_info_t initialNasMsg;
nr_ue_nas_t *nas = get_ue_nas_info(rrc->ue_id); nr_ue_nas_t *nas = get_ue_nas_info(rrc->ue_id);
// Send Initial NAS message (Registration Request) before Security Mode control procedure // Send Initial NAS message (Registration Request) before Security Mode control procedure
generateRegistrationRequest(&initialNasMsg, nas, false); generateRegistrationRequest(&initialNasMsg, nas, false);
nas_msg = (char *)initialNasMsg.nas_data; if (!initialNasMsg.nas_data) {
nas_msg_length = initialNasMsg.length; LOG_E(NR_RRC, "Failed to complete RRCSetup. NAS InitialUEMessage message not found.\n");
return;
}
} else { } else {
nas_msg = nr_nas_attach_req_imsi_dummy_NSA_case; initialNasMsg.length = sizeof(nr_nas_attach_req_imsi_dummy_NSA_case);
nas_msg_length = sizeof(nr_nas_attach_req_imsi_dummy_NSA_case); initialNasMsg.nas_data = malloc_or_fail(initialNasMsg.length);
memcpy(initialNasMsg.nas_data, nr_nas_attach_req_imsi_dummy_NSA_case, initialNasMsg.length);
} }
int size = do_RRCSetupComplete(buffer, sizeof(buffer), Transaction_id, rrc->selected_plmn_identity, nas_msg_length, nas_msg); // Encode RRCSetupComplete
int size = do_RRCSetupComplete(buffer,
sizeof(buffer),
Transaction_id,
rrc->selected_plmn_identity,
rrc->ra_trigger == RRC_CONNECTION_SETUP,
rrc->fiveG_S_TMSI,
(const uint32_t)initialNasMsg.length,
(const char*)initialNasMsg.nas_data);
// Free dynamically allocated data (heap allocated in both SA and NSA)
free(initialNasMsg.nas_data);
LOG_I(NR_RRC, "[UE %ld][RAPROC] Logical Channel UL-DCCH (SRB1), Generating RRCSetupComplete (bytes%d)\n", rrc->ue_id, size); LOG_I(NR_RRC, "[UE %ld][RAPROC] Logical Channel UL-DCCH (SRB1), Generating RRCSetupComplete (bytes%d)\n", rrc->ue_id, size);
int srb_id = 1; // RRC setup complete on SRB1 int srb_id = 1; // RRC setup complete on SRB1
LOG_D(NR_RRC, "[RRC_UE %ld] PDCP_DATA_REQ/%d Bytes RRCSetupComplete ---> %d\n", rrc->ue_id, size, srb_id); LOG_D(NR_RRC, "[RRC_UE %ld] PDCP_DATA_REQ/%d Bytes RRCSetupComplete ---> %d\n", rrc->ue_id, size, srb_id);
nr_pdcp_data_req_srb(rrc->ue_id, srb_id, 0, size, buffer, deliver_pdu_srb_rlc, NULL); nr_pdcp_data_req_srb(rrc->ue_id, srb_id, 0, size, buffer, deliver_pdu_srb_rlc, NULL);
} }
...@@ -1182,6 +1196,10 @@ static void nr_rrc_process_rrcsetup(NR_UE_RRC_INST_t *rrc, ...@@ -1182,6 +1196,10 @@ static void nr_rrc_process_rrcsetup(NR_UE_RRC_INST_t *rrc,
// enter RRC_CONNECTED // enter RRC_CONNECTED
rrc->nrRrcState = RRC_STATE_CONNECTED_NR; rrc->nrRrcState = RRC_STATE_CONNECTED_NR;
// Indicate to NAS that the RRC connection has been established (5.3.1.3 of 3GPP TS 24.501)
MessageDef *msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_NAS_CONN_ESTABLISH_IND);
itti_send_msg_to_task(TASK_NAS_NRUE, rrc->ue_id, msg_p);
// set the content of RRCSetupComplete message // set the content of RRCSetupComplete message
// TODO procedues described in 5.3.3.4 seems more complex than what we actualy do // TODO procedues described in 5.3.3.4 seems more complex than what we actualy do
rrc_ue_generate_RRCSetupComplete(rrc, rrcSetup->rrc_TransactionIdentifier); rrc_ue_generate_RRCSetupComplete(rrc, rrcSetup->rrc_TransactionIdentifier);
...@@ -2094,6 +2112,12 @@ void *rrc_nrue(void *notUsed) ...@@ -2094,6 +2112,12 @@ void *rrc_nrue(void *notUsed)
break; break;
} }
case NAS_5GMM_IND: {
nas_5gmm_ind_t *req = &NAS_5GMM_IND(msg_p);
rrc->fiveG_S_TMSI = req->fiveG_STMSI;
break;
}
default: default:
LOG_E(NR_RRC, "[UE %ld] Received unexpected message %s\n", rrc->ue_id, ITTI_MSG_NAME(msg_p)); LOG_E(NR_RRC, "[UE %ld] Received unexpected message %s\n", rrc->ue_id, ITTI_MSG_NAME(msg_p));
break; break;
...@@ -2538,6 +2562,8 @@ void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc, ...@@ -2538,6 +2562,8 @@ void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc,
// discard the keys (only kgnb is stored) // discard the keys (only kgnb is stored)
memset(rrc->kgnb, 0, sizeof(rrc->kgnb)); memset(rrc->kgnb, 0, sizeof(rrc->kgnb));
rrc->integrityProtAlgorithm = 0;
rrc->cipheringAlgorithm = 0;
// release all radio resources, including release of the RLC entity, // release all radio resources, including release of the RLC entity,
// the MAC configuration and the associated PDCP entity // the MAC configuration and the associated PDCP entity
......
...@@ -239,6 +239,9 @@ typedef struct NR_UE_RRC_INST_s { ...@@ -239,6 +239,9 @@ typedef struct NR_UE_RRC_INST_s {
Rrc_State_NR_t nrRrcState; Rrc_State_NR_t nrRrcState;
// flag to identify 1st reconfiguration after reestablishment // flag to identify 1st reconfiguration after reestablishment
bool reconfig_after_reestab; bool reconfig_after_reestab;
// 5G-S-TMSI
uint64_t fiveG_S_TMSI;
//Sidelink params //Sidelink params
NR_SL_PreconfigurationNR_r16_t *sl_preconfig; NR_SL_PreconfigurationNR_r16_t *sl_preconfig;
// NTN params // NTN params
......
...@@ -77,6 +77,8 @@ static nr_ue_nas_t nr_ue_nas[MAX_NAS_UE] = {0}; ...@@ -77,6 +77,8 @@ static nr_ue_nas_t nr_ue_nas[MAX_NAS_UE] = {0};
TYPE_DEF(NAS_SECURITY_INTEGRITY_PASSED, 4) \ TYPE_DEF(NAS_SECURITY_INTEGRITY_PASSED, 4) \
TYPE_DEF(NAS_SECURITY_BAD_INPUT, 5) TYPE_DEF(NAS_SECURITY_BAD_INPUT, 5)
const char *nr_release_cause_desc[] = {"RRC_CONNECTION_FAILURE", "RRC_RESUME_FAILURE", "OTHER"};
typedef enum { FOREACH_STATE(TO_ENUM) } security_state_t; typedef enum { FOREACH_STATE(TO_ENUM) } security_state_t;
static const text_info_t security_state_info[] = {FOREACH_STATE(TO_TEXT)}; static const text_info_t security_state_info[] = {FOREACH_STATE(TO_TEXT)};
...@@ -661,6 +663,12 @@ void generateRegistrationRequest(as_nas_info_t *initialNasMsg, nr_ue_nas_t *nas, ...@@ -661,6 +663,12 @@ void generateRegistrationRequest(as_nas_info_t *initialNasMsg, nr_ue_nas_t *nas,
nasmessagecontainercontents->length = mm_msg_encode(&full_mm, nasmessagecontainercontents->value, size_nct); nasmessagecontainercontents->length = mm_msg_encode(&full_mm, nasmessagecontainercontents->value, size_nct);
size += (nasmessagecontainercontents->length + 2); size += (nasmessagecontainercontents->length + 2);
rr->presencemask |= REGISTRATION_REQUEST_NAS_MESSAGE_CONTAINER_PRESENT; rr->presencemask |= REGISTRATION_REQUEST_NAS_MESSAGE_CONTAINER_PRESENT;
// Workaround to pass integrity in RRC_IDLE
uint8_t *kamf = nas->security.kamf;
uint8_t *kgnb = nas->security.kgnb;
derive_kgnb(kamf, nas->security.nas_count_ul, kgnb);
int nas_itti_kgnb_refresh_req(instance_t instance, const uint8_t kgnb[32]);
nas_itti_kgnb_refresh_req(nas->UE_id, nas->security.kgnb);
} }
// Allocate buffer (including NAS message container size) // Allocate buffer (including NAS message container size)
initialNasMsg->nas_data = malloc_or_fail(size * sizeof(*initialNasMsg->nas_data)); initialNasMsg->nas_data = malloc_or_fail(size * sizeof(*initialNasMsg->nas_data));
...@@ -1365,6 +1373,15 @@ static void send_nas_detach_req(nr_ue_nas_t *nas, bool wait_release) ...@@ -1365,6 +1373,15 @@ static void send_nas_detach_req(nr_ue_nas_t *nas, bool wait_release)
itti_send_msg_to_task(TASK_RRC_NRUE, nas->UE_id, msg); itti_send_msg_to_task(TASK_RRC_NRUE, nas->UE_id, msg);
} }
static void send_nas_5gmm_ind(instance_t instance, const Guti5GSMobileIdentity_t *guti)
{
MessageDef *msg = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_5GMM_IND);
nas_5gmm_ind_t *ind = &NAS_5GMM_IND(msg);
LOG_I(NR_RRC, "5G-GUTI: AMF pointer %u, AMF Set ID %u, 5G-TMSI %u \n", guti->amfpointer, guti->amfsetid, guti->tmsi);
ind->fiveG_STMSI = ((uint64_t)guti->amfsetid << 38) | ((uint64_t)guti->amfpointer << 32) | guti->tmsi;
itti_send_msg_to_task(TASK_RRC_NRUE, instance, msg);
}
static void request_default_pdusession(nr_ue_nas_t *nas) static void request_default_pdusession(nr_ue_nas_t *nas)
{ {
MessageDef *message_p = itti_alloc_new_message(TASK_NAS_NRUE, nas->UE_id, NAS_PDU_SESSION_REQ); MessageDef *message_p = itti_alloc_new_message(TASK_NAS_NRUE, nas->UE_id, NAS_PDU_SESSION_REQ);
...@@ -1439,6 +1456,9 @@ static void handle_registration_accept(nr_ue_nas_t *nas, const uint8_t *pdu_buff ...@@ -1439,6 +1456,9 @@ static void handle_registration_accept(nr_ue_nas_t *nas, const uint8_t *pdu_buff
LOG_W(NAS, "no GUTI in registration accept\n"); LOG_W(NAS, "no GUTI in registration accept\n");
} }
if(nas->guti)
send_nas_5gmm_ind(nas->UE_id, nas->guti);
as_nas_info_t initialNasMsg = {0}; as_nas_info_t initialNasMsg = {0};
generateRegistrationComplete(nas, &initialNasMsg, NULL); generateRegistrationComplete(nas, &initialNasMsg, NULL);
if (initialNasMsg.length > 0) { if (initialNasMsg.length > 0) {
...@@ -1481,11 +1501,6 @@ void *nas_nrue(void *args_p) ...@@ -1481,11 +1501,6 @@ void *nas_nrue(void *args_p)
NAS_CELL_SELECTION_CNF(msg_p).errCode, NAS_CELL_SELECTION_CNF(msg_p).errCode,
NAS_CELL_SELECTION_CNF(msg_p).cellID, NAS_CELL_SELECTION_CNF(msg_p).cellID,
NAS_CELL_SELECTION_CNF(msg_p).tac); NAS_CELL_SELECTION_CNF(msg_p).tac);
// as_stmsi_t s_tmsi={0, 0};
// as_nas_info_t nas_info;
// plmn_t plmnID={0, 0, 0, 0};
// generateRegistrationRequest(&nas_info);
// nr_nas_itti_nas_establish_req(0, AS_TYPE_ORIGINATING_SIGNAL, s_tmsi, plmnID, nas_info.data, nas_info.length, 0);
break; break;
case NAS_CELL_SELECTION_IND: case NAS_CELL_SELECTION_IND:
...@@ -1516,6 +1531,16 @@ void *nas_nrue(void *args_p) ...@@ -1516,6 +1531,16 @@ void *nas_nrue(void *args_p)
break; break;
} }
case NR_NAS_CONN_ESTABLISH_IND: {
nas->fiveGMM_mode = FGS_CONNECTED;
LOG_I(NAS,
"[UE %ld] Received %s: asCause %u\n",
nas->UE_id,
ITTI_MSG_NAME(msg_p),
NR_NAS_CONN_ESTABLISH_IND(msg_p).asCause);
break;
}
case NAS_CONN_ESTABLI_CNF: { case NAS_CONN_ESTABLI_CNF: {
LOG_I(NAS, LOG_I(NAS,
"[UE %ld] Received %s: errCode %u, length %u\n", "[UE %ld] Received %s: errCode %u, length %u\n",
...@@ -1546,8 +1571,12 @@ void *nas_nrue(void *args_p) ...@@ -1546,8 +1571,12 @@ void *nas_nrue(void *args_p)
break; break;
} }
case NR_NAS_CONN_RELEASE_IND: case NR_NAS_CONN_RELEASE_IND: {
LOG_I(NAS, "[UE %ld] Received %s: cause %u\n", nas->UE_id, ITTI_MSG_NAME(msg_p), NR_NAS_CONN_RELEASE_IND(msg_p).cause); LOG_I(NAS, "[UE %ld] Received %s: cause %s\n",
nas->UE_id, ITTI_MSG_NAME (msg_p), nr_release_cause_desc[NR_NAS_CONN_RELEASE_IND (msg_p).cause]);
/* In N1 mode, upon indication from lower layers that the access stratum connection has been released,
the UE shall enter 5GMM-IDLE mode and consider the N1 NAS signalling connection released (3GPP TS 24.501) */
nas->fiveGMM_mode = FGS_IDLE;
// TODO handle connection release // TODO handle connection release
if (nas->termination_procedure) { if (nas->termination_procedure) {
/* the following is not clean, but probably necessary: we need to give /* the following is not clean, but probably necessary: we need to give
...@@ -1558,7 +1587,7 @@ void *nas_nrue(void *args_p) ...@@ -1558,7 +1587,7 @@ void *nas_nrue(void *args_p)
itti_wait_tasks_unblock(); /* will unblock ITTI to stop nr-uesoftmodem */ itti_wait_tasks_unblock(); /* will unblock ITTI to stop nr-uesoftmodem */
} }
break; break;
}
case NAS_UPLINK_DATA_CNF: case NAS_UPLINK_DATA_CNF:
LOG_I(NAS, LOG_I(NAS,
"[UE %ld] Received %s: UEid %u, errCode %u\n", "[UE %ld] Received %s: UEid %u, errCode %u\n",
......
...@@ -42,12 +42,13 @@ ...@@ -42,12 +42,13 @@
legacy: we regenerate each sub frame in UL, and each frame only in DL legacy: we regenerate each sub frame in UL, and each frame only in DL
*/ */
void rxAddInput(const c16_t *input_sig, void rxAddInput(const c16_t *input_sig,
c16_t *after_channel_sig, cf_t *after_channel_sig,
int rxAnt, int rxAnt,
channel_desc_t *channelDesc, channel_desc_t *channelDesc,
int nbSamples, int nbSamples,
uint64_t TS, uint64_t TS,
uint32_t CirSize) uint32_t CirSize,
bool add_noise)
{ {
if ((channelDesc->sat_height > 0) && (channelDesc->enable_dynamic_delay || channelDesc->enable_dynamic_Doppler)) { // model for transparent satellite on circular orbit if ((channelDesc->sat_height > 0) && (channelDesc->enable_dynamic_delay || channelDesc->enable_dynamic_Doppler)) { // model for transparent satellite on circular orbit
/* assumptions: /* assumptions:
...@@ -127,12 +128,12 @@ void rxAddInput(const c16_t *input_sig, ...@@ -127,12 +128,12 @@ void rxAddInput(const c16_t *input_sig,
const double pathLossLinear = pow(10,channelDesc->path_loss_dB/20.0); const double pathLossLinear = pow(10,channelDesc->path_loss_dB/20.0);
// Energy in one sample to calibrate input noise // Energy in one sample to calibrate input noise
// the normalized OAI value seems to be 256 as average amplitude (numerical amplification = 1) // the normalized OAI value seems to be 256 as average amplitude (numerical amplification = 1)
const double noise_per_sample = pow(10,channelDesc->noise_power_dB/10.0) * 256; const double noise_per_sample = add_noise ? pow(10,channelDesc->noise_power_dB/10.0) * 256 : 0;
const uint64_t dd = channelDesc->channel_offset; const uint64_t dd = channelDesc->channel_offset;
const int nbTx=channelDesc->nb_tx; const int nbTx=channelDesc->nb_tx;
for (int i=0; i<nbSamples; i++) { for (int i=0; i<nbSamples; i++) {
struct complex16 *out_ptr=after_channel_sig+i; cf_t *out_ptr = after_channel_sig + i;
struct complexd rx_tmp= {0}; struct complexd rx_tmp= {0};
for (int txAnt=0; txAnt < nbTx; txAnt++) { for (int txAnt=0; txAnt < nbTx; txAnt++) {
...@@ -166,8 +167,8 @@ void rxAddInput(const c16_t *input_sig, ...@@ -166,8 +167,8 @@ void rxAddInput(const c16_t *input_sig,
channelDesc->Doppler_phase_cur[rxAnt] += channelDesc->Doppler_phase_inc; channelDesc->Doppler_phase_cur[rxAnt] += channelDesc->Doppler_phase_inc;
} }
out_ptr->r = lround(rx_tmp.r*pathLossLinear + noise_per_sample*gaussZiggurat(0.0,1.0)); out_ptr->r += rx_tmp.r * pathLossLinear + noise_per_sample * gaussZiggurat(0.0, 1.0);
out_ptr->i = lround(rx_tmp.i*pathLossLinear + noise_per_sample*gaussZiggurat(0.0,1.0)); out_ptr->i += rx_tmp.i * pathLossLinear + noise_per_sample * gaussZiggurat(0.0, 1.0);
out_ptr++; out_ptr++;
} }
......
...@@ -23,13 +23,15 @@ ...@@ -23,13 +23,15 @@
#ifndef __RFSIMULATOR_H #ifndef __RFSIMULATOR_H
#define __RFSIMULATOR_H #define __RFSIMULATOR_H
#include <stdbool.h>
void rxAddInput( const c16_t *input_sig, void rxAddInput( const c16_t *input_sig,
c16_t *after_channel_sig, cf_t *after_channel_sig,
int rxAnt, int rxAnt,
channel_desc_t *channelDesc, channel_desc_t *channelDesc,
int nbSamples, int nbSamples,
uint64_t TS, uint64_t TS,
uint32_t CirSize uint32_t CirSize,
bool apply_noise
); );
#endif #endif
...@@ -177,7 +177,6 @@ typedef struct { ...@@ -177,7 +177,6 @@ typedef struct {
double chan_pathloss; double chan_pathloss;
double chan_forgetfact; double chan_forgetfact;
uint64_t chan_offset; uint64_t chan_offset;
float noise_power_dB;
void *telnetcmd_qid; void *telnetcmd_qid;
poll_telnetcmdq_func_t poll_telnetcmdq; poll_telnetcmdq_func_t poll_telnetcmdq;
int wait_timeout; int wait_timeout;
...@@ -456,7 +455,7 @@ static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt, ...@@ -456,7 +455,7 @@ static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt,
t->chan_forgetfact, // forgetting_factor t->chan_forgetfact, // forgetting_factor
t->chan_offset, // propagation delay in samples t->chan_offset, // propagation delay in samples
t->chan_pathloss, t->chan_pathloss,
t->noise_power_dB); // path_loss in dB 0); // noise_power
set_channeldesc_owner(newmodel, RFSIMU_MODULEID); set_channeldesc_owner(newmodel, RFSIMU_MODULEID);
set_channeldesc_name(newmodel,modelname); set_channeldesc_name(newmodel,modelname);
random_channel(newmodel,false); random_channel(newmodel,false);
...@@ -1004,10 +1003,17 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest ...@@ -1004,10 +1003,17 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest
} while (have_to_wait); } while (have_to_wait);
} }
struct timespec start_time;
int ret = clock_gettime(CLOCK_REALTIME, &start_time);
AssertFatal(ret == 0, "clock_gettime() failed: errno %d, %s\n", errno, strerror(errno));
// Clear the output buffer // Clear the output buffer
for (int a=0; a<nbAnt; a++) for (int a=0; a<nbAnt; a++)
memset(samplesVoid[a],0,sampleToByte(nsamps,1)); memset(samplesVoid[a],0,sampleToByte(nsamps,1));
cf_t temp_array[nbAnt][nsamps];
bool apply_noise_per_channel = get_noise_power_dBFS() == INVALID_DBFS_VALUE;
int num_chanmod_channels = 0;
// Add all input nodes signal in the output buffer // Add all input nodes signal in the output buffer
for (int sock = 0; sock < MAX_FD_RFSIMU; sock++) { for (int sock = 0; sock < MAX_FD_RFSIMU; sock++) {
buffer_t *ptr=&t->buf[sock]; buffer_t *ptr=&t->buf[sock];
...@@ -1025,12 +1031,18 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest ...@@ -1025,12 +1031,18 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest
for (int a=0; a<nbAnt; a++) {//loop over number of Rx antennas for (int a=0; a<nbAnt; a++) {//loop over number of Rx antennas
if ( ptr->channel_model != NULL ) { // apply a channel model if ( ptr->channel_model != NULL ) { // apply a channel model
rxAddInput(ptr->circularBuf, (c16_t *) samplesVoid[a], if (num_chanmod_channels == 0) {
memset(temp_array, 0, sizeof(temp_array));
}
num_chanmod_channels++;
rxAddInput(ptr->circularBuf,
temp_array[a],
a, a,
ptr->channel_model, ptr->channel_model,
nsamps, nsamps,
t->nextRxTstamp, t->nextRxTstamp,
CirSize); CirSize,
apply_noise_per_channel);
} }
else { // no channel modeling else { // no channel modeling
int nbAnt_tx = ptr->th.nbAnt; // number of Tx antennas int nbAnt_tx = ptr->th.nbAnt; // number of Tx antennas
...@@ -1064,6 +1076,37 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest ...@@ -1064,6 +1076,37 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest
} // end for a (number of rx antennas) } // end for a (number of rx antennas)
} }
} }
if (apply_noise_per_channel && num_chanmod_channels > 0) {
// Noise is already applied through the channel model
for (int a = 0; a < nbAnt; a++) {
sample_t *out = (sample_t *)samplesVoid[a];
for (int i = 0; i < nsamps; i++) {
out[i].r += lroundf(temp_array[a][i].r);
out[i].i += lroundf(temp_array[a][i].i);
}
}
} else if (num_chanmod_channels > 0) {
// Apply noise from global setting
int16_t noise_power = (int16_t)(32767.0 / powf(10.0, .05 * -get_noise_power_dBFS()));
for (int a = 0; a < nbAnt; a++) {
sample_t *out = (sample_t *)samplesVoid[a];
for (int i = 0; i < nsamps; i++) {
out[i].r += lroundf(temp_array[a][i].r + noise_power * gaussZiggurat(0.0, 1.0));
out[i].i += lroundf(temp_array[a][i].i + noise_power * gaussZiggurat(0.0, 1.0));
}
}
}
struct timespec end_time;
ret = clock_gettime(CLOCK_REALTIME, &end_time);
AssertFatal(ret == 0, "clock_gettime() failed: errno %d, %s\n", errno, strerror(errno));
double diff_ns = (end_time.tv_sec - start_time.tv_sec) * 1000000000 + (end_time.tv_nsec - start_time.tv_nsec);
static double average = 0.0;
average = (average * 0.98) + ( nsamps / (diff_ns / 1e9) * 0.02);
static int calls = 0;
if (calls++ % 10000 == 0) {
LOG_D(HW, "Rfsimulator: velocity %.2f Msps, realtime requirements %.2f Msps\n", average / 1e6, t->sample_rate / 1e6);
}
*ptimestamp = t->nextRxTstamp; // return the time of the first sample *ptimestamp = t->nextRxTstamp; // return the time of the first sample
t->nextRxTstamp+=nsamps; t->nextRxTstamp+=nsamps;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment