diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index bd2d8e3b1e..e11c850b8e 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -1968,6 +1968,7 @@ set(NR_PDCP_SRC
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_entity.c
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c
+ ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c
${OPENAIR2_DIR}/LAYER2/nr_pdcp/asn1_utils.c
)
diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml
index 6d3424b420..089d0503fd 100644
--- a/cmake_targets/autotests/test_case_list.xml
+++ b/cmake_targets/autotests/test_case_list.xml
@@ -1292,7 +1292,9 @@
(Test8: DMRS Type B, 3 DMRS, 2 PTRS, 3 Interpolated Symbols),
(Test9: SC-FDMA, 50 PRBs),
(Test10: SC-FDMA, 75 PRBs),
- (Test11: SC-FDMA, 3 DMRS)
+ (Test11: SC-FDMA, 216 PRBs),
+ (Test12: SC-FDMA, 273 PRBs),
+ (Test13: SC-FDMA, 3 DMRS)
$OPENAIR_DIR/cmake_targets/build_oai
--phy_simulators -c
@@ -1307,10 +1309,13 @@
-n100 -s5 -T 2 1 2 -U 2 0 2
-n100 -s5 -T 2 2 2 -U 2 1 2
-n100 -s5 -a4 -b8 -T 2 1 2 -U 2 1 3
- -n100 -s20 -Z
- -n100 -s20 -Z -r75
- -n100 -s20 -Z -U 2 0 2
- nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 nr_ulsim.test6 nr_ulsim.test7 nr_ulsim.test8 nr_ulsim.test9 nr_ulsim.test10 nr_ulsim.test11
+ -n100 -s2 -Z
+ -n100 -s2 -Z -r75
+ -n100 -s2 -Z -r216 -R217
+ -n100 -s2 -Z -r270 -R273
+ -n100 -s2 -Z -U 2 0 2
+
+ nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 nr_ulsim.test6 nr_ulsim.test7 nr_ulsim.test8 nr_ulsim.test9 nr_ulsim.test10 nr_ulsim.test11 nr_ulsim.test12 nr_ulsim.test13
PUSCH test OK
segmentation fault|assertion|exiting|fatal
3
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
index ebe5c26bf6..bc5e7af45f 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
@@ -715,8 +715,10 @@ typedef struct {
uint16_t prgSize;
/// Number of STD ant ports (parallel streams) feeding into the digBF Value: 0->255
uint8_t digBFInterfaces;
+ // Depends on numPRGs
uint16_t PMIdx[275];
- uint16_t *beamIdx[275];
+ // Depends on digBFInterfaces
+ uint16_t beamIdx[256];
} nfapi_nr_tx_precoding_and_beamforming_t;
//table 3-37
diff --git a/openair1/PHY/MODULATION/nr_modulation.c b/openair1/PHY/MODULATION/nr_modulation.c
index 0a7088ba39..ed9a859fb6 100644
--- a/openair1/PHY/MODULATION/nr_modulation.c
+++ b/openair1/PHY/MODULATION/nr_modulation.c
@@ -325,10 +325,10 @@ void nr_ue_layer_mapping(NR_UE_ULSCH_t **ulsch_ue,
void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH)
{
-#if defined(__x86_64__) || defined(__i386__)
- __m128i dft_in128[1][1200], dft_out128[1][1200];
+#if defined(__x86_64__) || +defined(__i386__)
+ __m128i dft_in128[1][3240], dft_out128[1][3240];
#elif defined(__arm__)
- int16x8_t dft_in128[1][1200], dft_out128[1][1200];
+ int16x8_t dft_in128[1][3240], dft_out128[1][3240];
#endif
uint32_t *dft_in0 = (uint32_t*)dft_in128[0], *dft_out0 = (uint32_t*)dft_out128[0];
@@ -340,8 +340,10 @@ void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH)
int16x8_t norm128;
#endif
- for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) {
- dft_in0[ip] = d[i];
+ if ((Msc_PUSCH % 1536) > 0) {
+ for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) {
+ dft_in0[ip] = d[i];
+ }
}
switch (Msc_PUSCH) {
@@ -480,7 +482,7 @@ void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH)
break;
case 972:
- dft(DFT_960,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ dft(DFT_972,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 1080:
@@ -494,11 +496,98 @@ void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH)
case 1200:
dft(DFT_1200,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
+
+ case 1296:
+ dft(DFT_1296,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ break;
+
+ case 1440:
+ dft(DFT_1440,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ break;
+
+ case 1500:
+ dft(DFT_1500,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ break;
+
+ case 1536:
+ //dft(DFT_1536,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ dft(DFT_1536,(int16_t*)d, (int16_t*)z, 1);
+ break;
+
+ case 1620:
+ dft(DFT_1620,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ break;
+
+ case 1728:
+ dft(DFT_1728,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ break;
+
+ case 1800:
+ dft(DFT_1800,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ break;
+
+ case 1920:
+ dft(DFT_1920,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ break;
+
+ case 1944:
+ dft(DFT_1944,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ break;
+
+ case 2160:
+ dft(DFT_2160,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ break;
+
+ case 2304:
+ dft(DFT_2304,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ break;
+
+ case 2400:
+ dft(DFT_2400,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ break;
+
+ case 2592:
+ dft(DFT_2592,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ break;
+
+ case 2700:
+ dft(DFT_2700,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ break;
+
+ case 2880:
+ dft(DFT_2880,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ break;
+
+ case 2916:
+ dft(DFT_2916,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ break;
+
+ case 3000:
+ dft(DFT_3000,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ break;
+
+ case 3072:
+ //dft(DFT_3072,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ dft(DFT_3072,(int16_t*)d, (int16_t*)z, 1);
+ break;
+
+ case 3240:
+ dft(DFT_3240,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ break;
+
+ default:
+ // should not be reached
+ LOG_E( PHY, "Unsupported Msc_PUSCH value of %"PRIu16"\n", Msc_PUSCH );
+ return;
+
}
- for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) {
- z[i] = dft_out0[ip];
+
+ if ((Msc_PUSCH % 1536) > 0) {
+ for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4)
+ z[i] = dft_out0[ip];
}
+
}
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c
index 61238ae647..c4673e9d18 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dci.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c
@@ -88,7 +88,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
cset_start_sc = frame_parms.first_carrier_offset + rb_offset*NR_NB_SC_PER_RB;
if (pdcch_pdu_rel15->CoreSetType == NFAPI_NR_CSET_CONFIG_MIB_SIB1) {
cset_start_sc = cset_start_sc + RC.nrmac[gNB->Mod_id]->type0_PDCCH_CSS_config.cset_start_rb*NR_NB_SC_PER_RB;
- } else if (pdcch_pdu_rel15->CoreSetType == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG_CSET_0) {
+ } else {
cset_start_sc = cset_start_sc + pdcch_pdu_rel15->BWPStart*NR_NB_SC_PER_RB;
}
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
index 7e6becb4a8..42d6cfad7a 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
@@ -16,10 +16,10 @@ void nr_idft(int32_t *z, uint32_t Msc_PUSCH)
{
#if defined(__x86_64__) || defined(__i386__)
- __m128i idft_in128[1][1200], idft_out128[1][1200];
+ __m128i idft_in128[1][3240], idft_out128[1][3240];
__m128i norm128;
#elif defined(__arm__)
- int16x8_t idft_in128[1][1200], idft_out128[1][1200];
+ int16x8_t idft_in128[1][3240], idft_out128[1][3240];
int16x8_t norm128;
#endif
int16_t *idft_in0 = (int16_t*)idft_in128[0], *idft_out0 = (int16_t*)idft_out128[0];
@@ -28,20 +28,19 @@ void nr_idft(int32_t *z, uint32_t Msc_PUSCH)
LOG_T(PHY,"Doing lte_idft for Msc_PUSCH %d\n",Msc_PUSCH);
- // conjugate input
- for (i = 0; i < (Msc_PUSCH>>2); i++) {
+ if ((Msc_PUSCH % 1536) > 0) {
+ // conjugate input
+ for (i = 0; i < (Msc_PUSCH>>2); i++) {
#if defined(__x86_64__)||defined(__i386__)
- *&(((__m128i*)z)[i]) = _mm_sign_epi16(*&(((__m128i*)z)[i]), *(__m128i*)&conjugate2[0]);
+ *&(((__m128i*)z)[i]) = _mm_sign_epi16(*&(((__m128i*)z)[i]), *(__m128i*)&conjugate2[0]);
#elif defined(__arm__)
- *&(((int16x8_t*)z)[i]) = vmulq_s16(*&(((int16x8_t*)z)[i]), *(int16x8_t*)&conjugate2[0]);
+ *&(((int16x8_t*)z)[i]) = vmulq_s16(*&(((int16x8_t*)z)[i]), *(int16x8_t*)&conjugate2[0]);
#endif
+ }
+ for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4)
+ ((uint32_t*)idft_in0)[ip+0] = z[i];
}
- for (i=0,ip=0; i 0) {
+ for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4)
+ z[i] = ((uint32_t*)idft_out0)[ip];
-
- for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) {
- z[i] = ((int32_t*)idft_out0)[ip];
- }
-
- // conjugate output
- for (i = 0; i < (Msc_PUSCH>>2); i++) {
+ // conjugate output
+ for (i = 0; i < (Msc_PUSCH>>2); i++) {
#if defined(__x86_64__) || defined(__i386__)
- ((__m128i*)z)[i] = _mm_sign_epi16(((__m128i*)z)[i], *(__m128i*)&conjugate2[0]);
+ ((__m128i*)z)[i] = _mm_sign_epi16(((__m128i*)z)[i], *(__m128i*)&conjugate2[0]);
#elif defined(__arm__)
- *&(((int16x8_t*)z)[i]) = vmulq_s16(*&(((int16x8_t*)z)[i]), *(int16x8_t*)&conjugate2[0]);
+ *&(((int16x8_t*)z)[i]) = vmulq_s16(*&(((int16x8_t*)z)[i]), *(int16x8_t*)&conjugate2[0]);
#endif
+ }
}
#if defined(__x86_64__) || defined(__i386__)
@@ -222,6 +298,7 @@ void nr_idft(int32_t *z, uint32_t Msc_PUSCH)
}
+
void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
NR_gNB_PUSCH *pusch_vars,
unsigned char symbol,
diff --git a/openair1/PHY/TOOLS/oai_dfts.c b/openair1/PHY/TOOLS/oai_dfts.c
index e4e85f7ba9..6569f7eab5 100644
--- a/openair1/PHY/TOOLS/oai_dfts.c
+++ b/openair1/PHY/TOOLS/oai_dfts.c
@@ -5952,8 +5952,6 @@ void idft32768(int16_t *x,int16_t *y,unsigned char scale)
#endif
-
-
int16_t twa1536[1024],twb1536[1024];
// 512 x 3
@@ -9471,6 +9469,919 @@ void dft1200(int16_t *x,int16_t *y,unsigned char scale_flag)
}
+
+static int16_t twa1296[431*2*4];
+static int16_t twb1296[431*2*4];
+
+void dft1296(int16_t *x,int16_t *y,unsigned char scale_flag) //432 * 3
+{
+
+ int i,j;
+ simd_q15_t *x128=(simd_q15_t *)x;
+ simd_q15_t *y128=(simd_q15_t *)y;
+ simd_q15_t *twa128=(simd_q15_t *)&twa1296[0];
+ simd_q15_t *twb128=(simd_q15_t *)&twb1296[0];
+ simd_q15_t x2128[1296];// = (simd_q15_t *)&x2128array[0];
+ simd_q15_t ytmp128[1296];//=&ytmp128array3[0];
+
+
+
+ for (i=0,j=0; i<432; i++,j+=3) {
+ x2128[i] = x128[j];
+ x2128[i+432] = x128[j+1];
+ x2128[i+864] = x128[j+2];
+ }
+
+ dft432((int16_t *)x2128,(int16_t *)ytmp128,1);
+ dft432((int16_t *)(x2128+432),(int16_t *)(ytmp128+432),1);
+ dft432((int16_t *)(x2128+864),(int16_t *)(ytmp128+864),1);
+
+ bfly3_tw1(ytmp128,ytmp128+432,ytmp128+864,y128,y128+432,y128+864);
+
+ for (i=1,j=0; i<432; i++,j++) {
+ bfly3(ytmp128+i,
+ ytmp128+432+i,
+ ytmp128+864+i,
+ y128+i,
+ y128+432+i,
+ y128+864+i,
+ twa128+j,
+ twb128+j);
+ }
+
+ if (scale_flag==1) {
+ norm128 = set1_int16(dft_norm_table[14]);
+
+ for (i=0; i<1296; i++) {
+ y128[i] = mulhi_int16(y128[i],norm128);
+ }
+ }
+
+ _mm_empty();
+ _m_empty();
+
+};
+
+
+static int16_t twa1440[479*2*4];
+static int16_t twb1440[479*2*4];
+
+void dft1440(int16_t *x,int16_t *y,unsigned char scale_flag) // 480 x 3
+{
+ int i,j;
+ simd_q15_t *x128=(simd_q15_t *)x;
+ simd_q15_t *y128=(simd_q15_t *)y;
+ simd_q15_t *twa128=(simd_q15_t *)&twa1440[0];
+ simd_q15_t *twb128=(simd_q15_t *)&twb1440[0];
+ simd_q15_t x2128[1440];// = (simd_q15_t *)&x2128array[0];
+ simd_q15_t ytmp128[1440];//=&ytmp128array3[0];
+
+
+
+ for (i=0,j=0; i<480; i++,j+=3) {
+ x2128[i] = x128[j];
+ x2128[i+480] = x128[j+1];
+ x2128[i+960] = x128[j+2];
+ }
+
+ dft480((int16_t *)x2128,(int16_t *)ytmp128,1);
+ dft480((int16_t *)(x2128+480),(int16_t *)(ytmp128+480),1);
+ dft480((int16_t *)(x2128+960),(int16_t *)(ytmp128+960),1);
+
+ bfly3_tw1(ytmp128,ytmp128+480,ytmp128+960,y128,y128+480,y128+960);
+
+ for (i=1,j=0; i<480; i++,j++) {
+ bfly3(ytmp128+i,
+ ytmp128+480+i,
+ ytmp128+960+i,
+ y128+i,
+ y128+480+i,
+ y128+960+i,
+ twa128+j,
+ twb128+j);
+ }
+
+ if (scale_flag==1) {
+ norm128 = set1_int16(dft_norm_table[14]);
+
+ for (i=0; i<1440; i++) {
+ y128[i] = mulhi_int16(y128[i],norm128);
+ }
+ }
+
+ _mm_empty();
+ _m_empty();
+
+};
+
+static int16_t twa1500[2392]__attribute__((aligned(32)));
+static int16_t twb1500[2392]__attribute__((aligned(32)));
+static int16_t twc1500[2392]__attribute__((aligned(32)));
+static int16_t twd1500[2392]__attribute__((aligned(32)));
+
+void dft1500(int16_t *x,int16_t *y,unsigned char scale_flag)
+{
+
+ int i,j;
+ simd_q15_t *x128=(simd_q15_t *)x;
+ simd_q15_t *y128=(simd_q15_t *)y;
+ simd_q15_t *twa128=(simd_q15_t *)&twa1500[0];
+ simd_q15_t *twb128=(simd_q15_t *)&twb1500[0];
+ simd_q15_t *twc128=(simd_q15_t *)&twc1500[0];
+ simd_q15_t *twd128=(simd_q15_t *)&twd1500[0];
+ simd_q15_t x2128[1500];// = (simd_q15_t *)&x2128array[0];
+ simd_q15_t ytmp128[1500];//=&ytmp128array2[0];
+
+
+
+ for (i=0,j=0; i<300; i++,j+=5) {
+ x2128[i] = x128[j];
+ x2128[i+300] = x128[j+1];
+ x2128[i+600] = x128[j+2];
+ x2128[i+900] = x128[j+3];
+ x2128[i+1200] = x128[j+4];
+ }
+
+ dft300((int16_t *)x2128,(int16_t *)ytmp128,1);
+ dft300((int16_t *)(x2128+300),(int16_t *)(ytmp128+300),1);
+ dft300((int16_t *)(x2128+600),(int16_t *)(ytmp128+600),1);
+ dft300((int16_t *)(x2128+900),(int16_t *)(ytmp128+900),1);
+ dft300((int16_t *)(x2128+1200),(int16_t *)(ytmp128+1200),1);
+
+ bfly5_tw1(ytmp128,ytmp128+300,ytmp128+600,ytmp128+900,ytmp128+1200,y128,y128+300,y128+600,y128+900,y128+1200);
+
+ for (i=1,j=0; i<300; i++,j++) {
+ bfly5(ytmp128+i,
+ ytmp128+300+i,
+ ytmp128+600+i,
+ ytmp128+900+i,
+ ytmp128+1200+i,
+ y128+i,
+ y128+300+i,
+ y128+600+i,
+ y128+900+i,
+ y128+1200+i,
+ twa128+j,
+ twb128+j,
+ twc128+j,
+ twd128+j);
+ }
+
+ if (scale_flag==1) {
+ norm128 = set1_int16(dft_norm_table[15]);
+
+ for (i=0; i<1500; i++) {
+ y128[i] = mulhi_int16(y128[i],norm128);
+ }
+ }
+
+ _mm_empty();
+ _m_empty();
+
+}
+
+static int16_t twa1620[539*2*4];
+static int16_t twb1620[539*2*4];
+
+void dft1620(int16_t *x,int16_t *y,unsigned char scale_flag) // 540 x 3
+{
+ int i,j;
+ simd_q15_t *x128=(simd_q15_t *)x;
+ simd_q15_t *y128=(simd_q15_t *)y;
+ simd_q15_t *twa128=(simd_q15_t *)&twa1620[0];
+ simd_q15_t *twb128=(simd_q15_t *)&twb1620[0];
+ simd_q15_t x2128[1620];// = (simd_q15_t *)&x2128array[0];
+ simd_q15_t ytmp128[1620];//=&ytmp128array3[0];
+
+
+
+ for (i=0,j=0; i<540; i++,j+=3) {
+ x2128[i] = x128[j];
+ x2128[i+540] = x128[j+1];
+ x2128[i+1080] = x128[j+2];
+ }
+
+ dft540((int16_t *)x2128,(int16_t *)ytmp128,1);
+ dft540((int16_t *)(x2128+540),(int16_t *)(ytmp128+540),1);
+ dft540((int16_t *)(x2128+1080),(int16_t *)(ytmp128+1080),1);
+
+ bfly3_tw1(ytmp128,ytmp128+540,ytmp128+1080,y128,y128+540,y128+1080);
+
+ for (i=1,j=0; i<540; i++,j++) {
+ bfly3(ytmp128+i,
+ ytmp128+540+i,
+ ytmp128+1080+i,
+ y128+i,
+ y128+540+i,
+ y128+1080+i,
+ twa128+j,
+ twb128+j);
+ }
+
+ if (scale_flag==1) {
+ norm128 = set1_int16(dft_norm_table[14]);
+
+ for (i=0; i<1620; i++) {
+ y128[i] = mulhi_int16(y128[i],norm128);
+ }
+ }
+
+ _mm_empty();
+ _m_empty();
+
+};
+
+static int16_t twa1728[575*2*4];
+static int16_t twb1728[575*2*4];
+
+void dft1728(int16_t *x,int16_t *y,unsigned char scale_flag) // 576 x 3
+{
+ int i,j;
+ simd_q15_t *x128=(simd_q15_t *)x;
+ simd_q15_t *y128=(simd_q15_t *)y;
+ simd_q15_t *twa128=(simd_q15_t *)&twa1728[0];
+ simd_q15_t *twb128=(simd_q15_t *)&twb1728[0];
+ simd_q15_t x2128[1728];// = (simd_q15_t *)&x2128array[0];
+ simd_q15_t ytmp128[1728];//=&ytmp128array3[0];
+
+
+
+ for (i=0,j=0; i<576; i++,j+=3) {
+ x2128[i] = x128[j];
+ x2128[i+576] = x128[j+1];
+ x2128[i+1152] = x128[j+2];
+ }
+
+ dft576((int16_t *)x2128,(int16_t *)ytmp128,1);
+ dft576((int16_t *)(x2128+576),(int16_t *)(ytmp128+576),1);
+ dft576((int16_t *)(x2128+1152),(int16_t *)(ytmp128+1152),1);
+
+ bfly3_tw1(ytmp128,ytmp128+576,ytmp128+1152,y128,y128+576,y128+1152);
+
+ for (i=1,j=0; i<576; i++,j++) {
+ bfly3(ytmp128+i,
+ ytmp128+576+i,
+ ytmp128+1152+i,
+ y128+i,
+ y128+576+i,
+ y128+1152+i,
+ twa128+j,
+ twb128+j);
+ }
+
+ if (scale_flag==1) {
+ norm128 = set1_int16(dft_norm_table[14]);
+
+ for (i=0; i<1728; i++) {
+ y128[i] = mulhi_int16(y128[i],norm128);
+ }
+ }
+
+ _mm_empty();
+ _m_empty();
+
+};
+
+static int16_t twa1800[599*2*4];
+static int16_t twb1800[599*2*4];
+
+void dft1800(int16_t *x,int16_t *y,unsigned char scale_flag) // 600 x 3
+{
+ int i,j;
+ simd_q15_t *x128=(simd_q15_t *)x;
+ simd_q15_t *y128=(simd_q15_t *)y;
+ simd_q15_t *twa128=(simd_q15_t *)&twa1800[0];
+ simd_q15_t *twb128=(simd_q15_t *)&twb1800[0];
+ simd_q15_t x2128[1800];// = (simd_q15_t *)&x2128array[0];
+ simd_q15_t ytmp128[1800];//=&ytmp128array3[0];
+
+
+
+ for (i=0,j=0; i<600; i++,j+=3) {
+ x2128[i] = x128[j];
+ x2128[i+600] = x128[j+1];
+ x2128[i+1200] = x128[j+2];
+ }
+
+ dft600((int16_t *)x2128,(int16_t *)ytmp128,1);
+ dft600((int16_t *)(x2128+600),(int16_t *)(ytmp128+600),1);
+ dft600((int16_t *)(x2128+1200),(int16_t *)(ytmp128+1200),1);
+
+ bfly3_tw1(ytmp128,ytmp128+600,ytmp128+1200,y128,y128+600,y128+1200);
+
+ for (i=1,j=0; i<600; i++,j++) {
+ bfly3(ytmp128+i,
+ ytmp128+600+i,
+ ytmp128+1200+i,
+ y128+i,
+ y128+600+i,
+ y128+1200+i,
+ twa128+j,
+ twb128+j);
+ }
+
+ if (scale_flag==1) {
+ norm128 = set1_int16(dft_norm_table[14]);
+
+ for (i=0; i<1800; i++) {
+ y128[i] = mulhi_int16(y128[i],norm128);
+ }
+ }
+
+ _mm_empty();
+ _m_empty();
+
+};
+
+static int16_t twa1920[479*2*4];
+static int16_t twb1920[479*2*4];
+static int16_t twc1920[479*2*4];
+
+void dft1920(int16_t *x,int16_t *y,unsigned char scale_flag) // 480 x 4
+{
+ int i,j;
+ simd_q15_t *x128=(simd_q15_t *)x;
+ simd_q15_t *y128=(simd_q15_t *)y;
+ simd_q15_t *twa128=(simd_q15_t *)&twa1920[0];
+ simd_q15_t *twb128=(simd_q15_t *)&twb1920[0];
+ simd_q15_t *twc128=(simd_q15_t *)&twc1920[0];
+ simd_q15_t x2128[1920];// = (simd_q15_t *)&x2128array[0];
+ simd_q15_t ytmp128[1920];//=&ytmp128array2[0];
+
+
+
+ for (i=0,j=0; i<480; i++,j+=4) {
+ x2128[i] = x128[j];
+ x2128[i+480] = x128[j+1];
+ x2128[i+960] = x128[j+2];
+ x2128[i+1440] = x128[j+3];
+ }
+
+ dft480((int16_t *)x2128,(int16_t *)ytmp128,1);
+ dft480((int16_t *)(x2128+480),(int16_t *)(ytmp128+480),1);
+ dft480((int16_t *)(x2128+960),(int16_t *)(ytmp128+960),1);
+ dft480((int16_t *)(x2128+1440),(int16_t *)(ytmp128+1440),1);
+
+ bfly4_tw1(ytmp128,ytmp128+480,ytmp128+960,ytmp128+1440,y128,y128+480,y128+960,y128+1440);
+
+ for (i=1,j=0; i<480; i++,j++) {
+ bfly4(ytmp128+i,
+ ytmp128+480+i,
+ ytmp128+960+i,
+ ytmp128+1440+i,
+ y128+i,
+ y128+480+i,
+ y128+960+i,
+ y128+1440+i,
+ twa128+j,
+ twb128+j,
+ twc128+j);
+ }
+
+ if (scale_flag==1) {
+ norm128 = set1_int16(dft_norm_table[13]);
+ for (i=0; i<1920; i++) {
+ y128[i] = mulhi_int16(y128[i],norm128);
+ }
+ }
+
+ _mm_empty();
+ _m_empty();
+
+};
+
+static int16_t twa1944[647*2*4];
+static int16_t twb1944[647*2*4];
+
+void dft1944(int16_t *x,int16_t *y,unsigned char scale_flag) // 648 x 3
+{
+ int i,j;
+ simd_q15_t *x128=(simd_q15_t *)x;
+ simd_q15_t *y128=(simd_q15_t *)y;
+ simd_q15_t *twa128=(simd_q15_t *)&twa1944[0];
+ simd_q15_t *twb128=(simd_q15_t *)&twb1944[0];
+ simd_q15_t x2128[1944];// = (simd_q15_t *)&x2128array[0];
+ simd_q15_t ytmp128[1944];//=&ytmp128array3[0];
+
+
+
+ for (i=0,j=0; i<648; i++,j+=3) {
+ x2128[i] = x128[j];
+ x2128[i+648] = x128[j+1];
+ x2128[i+1296] = x128[j+2];
+ }
+
+ dft648((int16_t *)x2128,(int16_t *)ytmp128,1);
+ dft648((int16_t *)(x2128+648),(int16_t *)(ytmp128+648),1);
+ dft648((int16_t *)(x2128+1296),(int16_t *)(ytmp128+1296),1);
+
+ bfly3_tw1(ytmp128,ytmp128+648,ytmp128+1296,y128,y128+648,y128+1296);
+
+ for (i=1,j=0; i<648; i++,j++) {
+ bfly3(ytmp128+i,
+ ytmp128+648+i,
+ ytmp128+1296+i,
+ y128+i,
+ y128+648+i,
+ y128+1296+i,
+ twa128+j,
+ twb128+j);
+ }
+
+ if (scale_flag==1) {
+ norm128 = set1_int16(dft_norm_table[14]);
+
+ for (i=0; i<1944; i++) {
+ y128[i] = mulhi_int16(y128[i],norm128);
+ }
+ }
+
+ _mm_empty();
+ _m_empty();
+
+};
+
+static int16_t twa2160[719*2*4];
+static int16_t twb2160[719*2*4];
+
+void dft2160(int16_t *x,int16_t *y,unsigned char scale_flag) // 720 x 3
+{
+ int i,j;
+ simd_q15_t *x128=(simd_q15_t *)x;
+ simd_q15_t *y128=(simd_q15_t *)y;
+ simd_q15_t *twa128=(simd_q15_t *)&twa2160[0];
+ simd_q15_t *twb128=(simd_q15_t *)&twb2160[0];
+ simd_q15_t x2128[2160];// = (simd_q15_t *)&x2128array[0];
+ simd_q15_t ytmp128[2160];//=&ytmp128array3[0];
+
+
+
+ for (i=0,j=0; i<720; i++,j+=3) {
+ x2128[i] = x128[j];
+ x2128[i+720] = x128[j+1];
+ x2128[i+1440] = x128[j+2];
+ }
+
+ dft720((int16_t *)x2128,(int16_t *)ytmp128,1);
+ dft720((int16_t *)(x2128+720),(int16_t *)(ytmp128+720),1);
+ dft720((int16_t *)(x2128+1440),(int16_t *)(ytmp128+1440),1);
+
+ bfly3_tw1(ytmp128,ytmp128+720,ytmp128+1440,y128,y128+720,y128+1440);
+
+ for (i=1,j=0; i<720; i++,j++) {
+ bfly3(ytmp128+i,
+ ytmp128+720+i,
+ ytmp128+1440+i,
+ y128+i,
+ y128+720+i,
+ y128+1440+i,
+ twa128+j,
+ twb128+j);
+ }
+
+ if (scale_flag==1) {
+ norm128 = set1_int16(dft_norm_table[14]);
+
+ for (i=0; i<2160; i++) {
+ y128[i] = mulhi_int16(y128[i],norm128);
+ }
+ }
+
+ _mm_empty();
+ _m_empty();
+
+};
+
+static int16_t twa2304[767*2*4];
+static int16_t twb2304[767*2*4];
+
+void dft2304(int16_t *x,int16_t *y,unsigned char scale_flag) // 768 x 3
+{
+ int i,j;
+ simd_q15_t *x128=(simd_q15_t *)x;
+ simd_q15_t *y128=(simd_q15_t *)y;
+ simd_q15_t *twa128=(simd_q15_t *)&twa2304[0];
+ simd_q15_t *twb128=(simd_q15_t *)&twb2304[0];
+ simd_q15_t x2128[2304];// = (simd_q15_t *)&x2128array[0];
+ simd_q15_t ytmp128[2304];//=&ytmp128array3[0];
+
+
+
+ for (i=0,j=0; i<768; i++,j+=3) {
+ x2128[i] = x128[j];
+ x2128[i+768] = x128[j+1];
+ x2128[i+1536] = x128[j+2];
+ }
+
+ dft768((int16_t *)x2128,(int16_t *)ytmp128,1);
+ dft768((int16_t *)(x2128+768),(int16_t *)(ytmp128+768),1);
+ dft768((int16_t *)(x2128+1536),(int16_t *)(ytmp128+1536),1);
+
+ bfly3_tw1(ytmp128,ytmp128+768,ytmp128+1536,y128,y128+768,y128+1536);
+
+ for (i=1,j=0; i<768; i++,j++) {
+ bfly3(ytmp128+i,
+ ytmp128+768+i,
+ ytmp128+1536+i,
+ y128+i,
+ y128+768+i,
+ y128+1536+i,
+ twa128+j,
+ twb128+j);
+ }
+
+ if (scale_flag==1) {
+ norm128 = set1_int16(dft_norm_table[14]);
+
+ for (i=0; i<2304; i++) {
+ y128[i] = mulhi_int16(y128[i],norm128);
+ }
+ }
+
+ _mm_empty();
+ _m_empty();
+
+};
+
+static int16_t twa2400[599*2*4];
+static int16_t twb2400[599*2*4];
+static int16_t twc2400[599*2*4];
+
+void dft2400(int16_t *x,int16_t *y,unsigned char scale_flag) // 600 x 4
+{
+
+ int i,j;
+ simd_q15_t *x128=(simd_q15_t *)x;
+ simd_q15_t *y128=(simd_q15_t *)y;
+ simd_q15_t *twa128=(simd_q15_t *)&twa2400[0];
+ simd_q15_t *twb128=(simd_q15_t *)&twb2400[0];
+ simd_q15_t *twc128=(simd_q15_t *)&twc2400[0];
+ simd_q15_t x2128[2400];// = (simd_q15_t *)&x2128array[0];
+ simd_q15_t ytmp128[2400];//=&ytmp128array2[0];
+
+
+
+ for (i=0,j=0; i<600; i++,j+=4) {
+ x2128[i] = x128[j];
+ x2128[i+600] = x128[j+1];
+ x2128[i+1200] = x128[j+2];
+ x2128[i+1800] = x128[j+3];
+ }
+
+ dft600((int16_t *)x2128,(int16_t *)ytmp128,1);
+ dft600((int16_t *)(x2128+600),(int16_t *)(ytmp128+600),1);
+ dft600((int16_t *)(x2128+1200),(int16_t *)(ytmp128+1200),1);
+ dft600((int16_t *)(x2128+1800),(int16_t *)(ytmp128+1800),1);
+
+ bfly4_tw1(ytmp128,ytmp128+600,ytmp128+1200,ytmp128+1800,y128,y128+600,y128+1200,y128+1800);
+
+ for (i=1,j=0; i<600; i++,j++) {
+ bfly4(ytmp128+i,
+ ytmp128+600+i,
+ ytmp128+1200+i,
+ ytmp128+1800+i,
+ y128+i,
+ y128+600+i,
+ y128+1200+i,
+ y128+1800+i,
+ twa128+j,
+ twb128+j,
+ twc128+j);
+ }
+
+ if (scale_flag==1) {
+ norm128 = set1_int16(dft_norm_table[13]);
+ for (i=0; i<2400; i++) {
+ y128[i] = mulhi_int16(y128[i],norm128);
+ }
+ }
+
+ _mm_empty();
+ _m_empty();
+
+};
+
+static int16_t twa2592[863*2*4];
+static int16_t twb2592[863*2*4];
+
+void dft2592(int16_t *x,int16_t *y,unsigned char scale_flag) // 864 x 3
+{
+ int i,j;
+ simd_q15_t *x128=(simd_q15_t *)x;
+ simd_q15_t *y128=(simd_q15_t *)y;
+ simd_q15_t *twa128=(simd_q15_t *)&twa2592[0];
+ simd_q15_t *twb128=(simd_q15_t *)&twb2592[0];
+ simd_q15_t x2128[2592];// = (simd_q15_t *)&x2128array[0];
+ simd_q15_t ytmp128[2592];//=&ytmp128array3[0];
+
+
+
+ for (i=0,j=0; i<864; i++,j+=3) {
+ x2128[i] = x128[j];
+ x2128[i+864] = x128[j+1];
+ x2128[i+1728] = x128[j+2];
+ }
+
+ dft864((int16_t *)x2128,(int16_t *)ytmp128,1);
+ dft864((int16_t *)(x2128+864),(int16_t *)(ytmp128+864),1);
+ dft864((int16_t *)(x2128+1728),(int16_t *)(ytmp128+1728),1);
+
+ bfly3_tw1(ytmp128,ytmp128+864,ytmp128+1728,y128,y128+864,y128+1728);
+
+ for (i=1,j=0; i<864; i++,j++) {
+ bfly3(ytmp128+i,
+ ytmp128+864+i,
+ ytmp128+1728+i,
+ y128+i,
+ y128+864+i,
+ y128+1728+i,
+ twa128+j,
+ twb128+j);
+ }
+
+ if (scale_flag==1) {
+ norm128 = set1_int16(dft_norm_table[14]);
+
+ for (i=0; i<2592; i++) {
+ y128[i] = mulhi_int16(y128[i],norm128);
+ }
+ }
+
+ _mm_empty();
+ _m_empty();
+
+};
+
+static int16_t twa2700[899*2*4];
+static int16_t twb2700[899*2*4];
+
+void dft2700(int16_t *x,int16_t *y,unsigned char scale_flag) // 900 x 3
+{
+ int i,j;
+ simd_q15_t *x128=(simd_q15_t *)x;
+ simd_q15_t *y128=(simd_q15_t *)y;
+ simd_q15_t *twa128=(simd_q15_t *)&twa2700[0];
+ simd_q15_t *twb128=(simd_q15_t *)&twb2700[0];
+ simd_q15_t x2128[2700];// = (simd_q15_t *)&x2128array[0];
+ simd_q15_t ytmp128[2700];//=&ytmp128array3[0];
+
+
+
+ for (i=0,j=0; i<900; i++,j+=3) {
+ x2128[i] = x128[j];
+ x2128[i+900] = x128[j+1];
+ x2128[i+1800] = x128[j+2];
+ }
+
+ dft900((int16_t *)x2128,(int16_t *)ytmp128,1);
+ dft900((int16_t *)(x2128+900),(int16_t *)(ytmp128+900),1);
+ dft900((int16_t *)(x2128+1800),(int16_t *)(ytmp128+1800),1);
+
+ bfly3_tw1(ytmp128,ytmp128+900,ytmp128+1800,y128,y128+900,y128+1800);
+
+ for (i=1,j=0; i<900; i++,j++) {
+ bfly3(ytmp128+i,
+ ytmp128+900+i,
+ ytmp128+1800+i,
+ y128+i,
+ y128+900+i,
+ y128+1800+i,
+ twa128+j,
+ twb128+j);
+ }
+
+ if (scale_flag==1) {
+ norm128 = set1_int16(dft_norm_table[14]);
+
+ for (i=0; i<2700; i++) {
+ y128[i] = mulhi_int16(y128[i],norm128);
+ }
+ }
+
+ _mm_empty();
+ _m_empty();
+
+};
+
+static int16_t twa2880[959*2*4];
+static int16_t twb2880[959*2*4];
+
+void dft2880(int16_t *x,int16_t *y,unsigned char scale_flag) // 960 x 3
+{
+ int i,j;
+ simd_q15_t *x128=(simd_q15_t *)x;
+ simd_q15_t *y128=(simd_q15_t *)y;
+ simd_q15_t *twa128=(simd_q15_t *)&twa2880[0];
+ simd_q15_t *twb128=(simd_q15_t *)&twb2880[0];
+ simd_q15_t x2128[2880];// = (simd_q15_t *)&x2128array[0];
+ simd_q15_t ytmp128[2880];//=&ytmp128array3[0];
+
+
+
+ for (i=0,j=0; i<960; i++,j+=3) {
+ x2128[i] = x128[j];
+ x2128[i+960] = x128[j+1];
+ x2128[i+1920] = x128[j+2];
+ }
+
+ dft960((int16_t *)x2128,(int16_t *)ytmp128,1);
+ dft960((int16_t *)(x2128+960),(int16_t *)(ytmp128+960),1);
+ dft960((int16_t *)(x2128+1920),(int16_t *)(ytmp128+1920),1);
+
+ bfly3_tw1(ytmp128,ytmp128+960,ytmp128+1920,y128,y128+960,y128+1920);
+
+ for (i=1,j=0; i<960; i++,j++) {
+ bfly3(ytmp128+i,
+ ytmp128+960+i,
+ ytmp128+1920+i,
+ y128+i,
+ y128+960+i,
+ y128+1920+i,
+ twa128+j,
+ twb128+j);
+ }
+
+ if (scale_flag==1) {
+ norm128 = set1_int16(dft_norm_table[14]);
+
+ for (i=0; i<2880; i++) {
+ y128[i] = mulhi_int16(y128[i],norm128);
+ }
+ }
+
+ _mm_empty();
+ _m_empty();
+
+};
+
+static int16_t twa2916[971*2*4];
+static int16_t twb2916[971*2*4];
+
+void dft2916(int16_t *x,int16_t *y,unsigned char scale_flag) // 972 x 3
+{
+ int i,j;
+ simd_q15_t *x128=(simd_q15_t *)x;
+ simd_q15_t *y128=(simd_q15_t *)y;
+ simd_q15_t *twa128=(simd_q15_t *)&twa2916[0];
+ simd_q15_t *twb128=(simd_q15_t *)&twb2916[0];
+ simd_q15_t x2128[2916];// = (simd_q15_t *)&x2128array[0];
+ simd_q15_t ytmp128[2916];//=&ytmp128array3[0];
+
+
+
+ for (i=0,j=0; i<972; i++,j+=3) {
+ x2128[i] = x128[j];
+ x2128[i+972] = x128[j+1];
+ x2128[i+1944] = x128[j+2];
+ }
+
+ dft972((int16_t *)x2128,(int16_t *)ytmp128,1);
+ dft972((int16_t *)(x2128+972),(int16_t *)(ytmp128+972),1);
+ dft972((int16_t *)(x2128+1944),(int16_t *)(ytmp128+1944),1);
+
+ bfly3_tw1(ytmp128,ytmp128+972,ytmp128+1944,y128,y128+972,y128+1944);
+
+ for (i=1,j=0; i<972; i++,j++) {
+ bfly3(ytmp128+i,
+ ytmp128+972+i,
+ ytmp128+1944+i,
+ y128+i,
+ y128+972+i,
+ y128+1944+i,
+ twa128+j,
+ twb128+j);
+ }
+
+ if (scale_flag==1) {
+ norm128 = set1_int16(dft_norm_table[14]);
+
+ for (i=0; i<2916; i++) {
+ y128[i] = mulhi_int16(y128[i],norm128);
+ }
+ }
+
+ _mm_empty();
+ _m_empty();
+
+};
+
+static int16_t twa3000[599*8]__attribute__((aligned(32)));
+static int16_t twb3000[599*8]__attribute__((aligned(32)));
+static int16_t twc3000[599*8]__attribute__((aligned(32)));
+static int16_t twd3000[599*8]__attribute__((aligned(32)));
+
+void dft3000(int16_t *x,int16_t *y,unsigned char scale_flag) // 600 * 5
+{
+
+ int i,j;
+ simd_q15_t *x128=(simd_q15_t *)x;
+ simd_q15_t *y128=(simd_q15_t *)y;
+ simd_q15_t *twa128=(simd_q15_t *)&twa3000[0];
+ simd_q15_t *twb128=(simd_q15_t *)&twb3000[0];
+ simd_q15_t *twc128=(simd_q15_t *)&twc3000[0];
+ simd_q15_t *twd128=(simd_q15_t *)&twd3000[0];
+ simd_q15_t x2128[3000];// = (simd_q15_t *)&x2128array[0];
+ simd_q15_t ytmp128[3000];//=&ytmp128array2[0];
+
+
+
+ for (i=0,j=0; i<600; i++,j+=5) {
+ x2128[i] = x128[j];
+ x2128[i+600] = x128[j+1];
+ x2128[i+1200] = x128[j+2];
+ x2128[i+1800] = x128[j+3];
+ x2128[i+2400] = x128[j+4];
+ }
+
+ dft600((int16_t *)x2128,(int16_t *)ytmp128,1);
+ dft600((int16_t *)(x2128+600),(int16_t *)(ytmp128+600),1);
+ dft600((int16_t *)(x2128+1200),(int16_t *)(ytmp128+1200),1);
+ dft600((int16_t *)(x2128+1800),(int16_t *)(ytmp128+1800),1);
+ dft600((int16_t *)(x2128+2400),(int16_t *)(ytmp128+2400),1);
+
+ bfly5_tw1(ytmp128,ytmp128+600,ytmp128+1200,ytmp128+1800,ytmp128+2400,y128,y128+600,y128+1200,y128+1800,y128+2400);
+
+ for (i=1,j=0; i<600; i++,j++) {
+ bfly5(ytmp128+i,
+ ytmp128+600+i,
+ ytmp128+1200+i,
+ ytmp128+1800+i,
+ ytmp128+2400+i,
+ y128+i,
+ y128+600+i,
+ y128+1200+i,
+ y128+1800+i,
+ y128+2400+i,
+ twa128+j,
+ twb128+j,
+ twc128+j,
+ twd128+j);
+ }
+
+ if (scale_flag==1) {
+ norm128 = set1_int16(dft_norm_table[15]);
+
+ for (i=0; i<3000; i++) {
+ y128[i] = mulhi_int16(y128[i],norm128);
+ }
+ }
+
+ _mm_empty();
+ _m_empty();
+
+}
+
+static int16_t twa3240[1079*2*4];
+static int16_t twb3240[1079*2*4];
+
+void dft3240(int16_t *x,int16_t *y,unsigned char scale_flag) // 1080 x 3
+{
+ int i,j;
+ simd_q15_t *x128=(simd_q15_t *)x;
+ simd_q15_t *y128=(simd_q15_t *)y;
+ simd_q15_t *twa128=(simd_q15_t *)&twa3240[0];
+ simd_q15_t *twb128=(simd_q15_t *)&twb3240[0];
+ simd_q15_t x2128[3240];// = (simd_q15_t *)&x2128array[0];
+ simd_q15_t ytmp128[3240];//=&ytmp128array3[0];
+
+
+
+ for (i=0,j=0; i<1080; i++,j+=3) {
+ x2128[i] = x128[j];
+ x2128[i+1080] = x128[j+1];
+ x2128[i+2160] = x128[j+2];
+ }
+
+ dft1080((int16_t *)x2128,(int16_t *)ytmp128,1);
+ dft1080((int16_t *)(x2128+1080),(int16_t *)(ytmp128+1080),1);
+ dft1080((int16_t *)(x2128+2160),(int16_t *)(ytmp128+2160),1);
+
+ bfly3_tw1(ytmp128,ytmp128+1080,ytmp128+2160,y128,y128+1080,y128+2160);
+
+ for (i=1,j=0; i<1080; i++,j++) {
+ bfly3(ytmp128+i,
+ ytmp128+1080+i,
+ ytmp128+2160+i,
+ y128+i,
+ y128+1080+i,
+ y128+2160+i,
+ twa128+j,
+ twb128+j);
+ }
+
+ if (scale_flag==1) {
+ norm128 = set1_int16(dft_norm_table[14]);
+
+ for (i=0; i<3240; i++) {
+ y128[i] = mulhi_int16(y128[i],norm128);
+ }
+ }
+
+ _mm_empty();
+ _m_empty();
+
+};
+
void init_rad4(int N,int16_t *tw) {
int16_t *twa = tw;
@@ -9492,7 +10403,7 @@ void init_rad4_rep(int N,int16_t *twa,int16_t *twb,int16_t *twc) {
int i,j;
for (i=1;i<(N/4);i++) {
- twa[0] = (int16_t)round(32767.0*cos(2*M_PI*i/N));
+ twa[0] = (int16_t)round(32767.0*cos(2*M_PI*i/N));
twa[1] = -(int16_t)round(32767.0*sin(2*M_PI*i/N));
twb[0] = (int16_t)round(32767.0*cos(2*M_PI*2*i/N));
twb[1] = -(int16_t)round(32767.0*sin(2*M_PI*2*i/N));
@@ -9525,7 +10436,7 @@ void init_rad2_rep(int N,int16_t *twa) {
int i,j;
for (i=1;i<(N/2);i++) {
- twa[0] = (int16_t)round(32767.0*cos(2*M_PI*i/N));
+ twa[0] = (int16_t)round(32767.0*cos(2*M_PI*i/N));
twa[1] = -(int16_t)round(32767.0*sin(2*M_PI*i/N));
for (j=1;j<4;j++) {
((int32_t*)twa)[j]=((int32_t*)twa)[0];
@@ -9551,7 +10462,7 @@ void init_rad3_rep(int N,int16_t *twa,int16_t *twb) {
int i,j;
for (i=1;i<(N/3);i++) {
- twa[0] = (int16_t)round(32767.0*cos(2*M_PI*i/N));
+ twa[0] = (int16_t)round(32767.0*cos(2*M_PI*i/N));
twa[1] = -(int16_t)round(32767.0*sin(2*M_PI*i/N));
twb[0] = (int16_t)round(32767.0*cos(2*M_PI*2*i/N));
twb[1] = -(int16_t)round(32767.0*sin(2*M_PI*2*i/N));
@@ -9569,7 +10480,7 @@ void init_rad5_rep(int N,int16_t *twa,int16_t *twb,int16_t *twc,int16_t *twd) {
int i,j;
for (i=1;i<(N/5);i++) {
- twa[0] = (int16_t)round(32767.0*cos(2*M_PI*i/N));
+ twa[0] = (int16_t)round(32767.0*cos(2*M_PI*i/N));
twa[1] = -(int16_t)round(32767.0*sin(2*M_PI*i/N));
twb[0] = (int16_t)round(32767.0*cos(2*M_PI*2*i/N));
twb[1] = -(int16_t)round(32767.0*sin(2*M_PI*2*i/N));
@@ -9586,7 +10497,7 @@ void init_rad5_rep(int N,int16_t *twa,int16_t *twb,int16_t *twc,int16_t *twd) {
twa+=8;
twb+=8;
twc+=8;
- twd+=8;
+ twd+=8;
}
}
/*----------------------------------------------------------------*/
@@ -9600,7 +10511,7 @@ int dfts_autoinit(void)
init_rad2(8192,tw8192);
init_rad4(16384,tw16384);
init_rad2(32768,tw32768);
-
+
init_rad3(1536,twa1536,twb1536);
init_rad3(3072,twa3072,twb3072);
init_rad3(6144,twa6144,twb6144);
@@ -9645,6 +10556,24 @@ int dfts_autoinit(void)
init_rad3_rep(1080,twa1080,twb1080);
init_rad4_rep(1152,twa1152,twb1152,twc1152);
init_rad4_rep(1200,twa1200,twb1200,twc1200);
+ init_rad3_rep(1296,twa1296,twb1296);
+ init_rad3_rep(1440,twa1440,twb1440);
+ init_rad5_rep(1500,twa1500,twb1500,twc1500,twd1500);
+ init_rad3_rep(1620,twa1620,twb1620);
+ init_rad3_rep(1728,twa1728,twb1728);
+ init_rad3_rep(1800,twa1800,twb1800);
+ init_rad4_rep(1920,twa1920,twb1920, twc1920);
+ init_rad3_rep(1944,twa1944,twb1944);
+ init_rad3_rep(2160,twa2160,twb2160);
+ init_rad3_rep(2304,twa2304,twb2304);
+ init_rad4_rep(2400,twa2400,twb2400,twc2400);
+ init_rad3_rep(2592,twa2592,twb2592);
+ init_rad3_rep(2700,twa2700,twb2700);
+ init_rad3_rep(2880,twa2880,twb2880);
+ init_rad3_rep(2916,twa2916,twb2916);
+ init_rad5_rep(3000,twa3000,twb3000,twc3000,twd3000);
+ init_rad3_rep(3240,twa3240,twb3240);
+
return 0;
}
diff --git a/openair1/PHY/TOOLS/tools_defs.h b/openair1/PHY/TOOLS/tools_defs.h
index 12467e1fdc..db7ac3d813 100644
--- a/openair1/PHY/TOOLS/tools_defs.h
+++ b/openair1/PHY/TOOLS/tools_defs.h
@@ -226,9 +226,26 @@ void dft1024(int16_t *x,int16_t *y,uint8_t scale_flag);
void dft1080(int16_t *x,int16_t *y,uint8_t scale_flag);
void dft1152(int16_t *x,int16_t *y,uint8_t scale_flag);
void dft1200(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft1296(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft1440(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft1500(int16_t *x,int16_t *y,uint8_t scale_flag);
void dft1536(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
+void dft1620(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft1728(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft1800(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft1920(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft1944(int16_t *x,int16_t *y,uint8_t scale_flag);
void dft2048(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft2160(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft2304(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft2400(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft2592(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft2700(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft2880(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft2916(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft3000(int16_t *x,int16_t *y,uint8_t scale_flag);
void dft3072(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
+void dft3240(int16_t *x,int16_t *y,uint8_t scale_flag);
void dft4096(int16_t *x,int16_t *y,uint8_t scale_flag);
void dft6144(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
void dft8192(int16_t *x,int16_t *y,uint8_t scale_flag);
@@ -283,21 +300,25 @@ typedef enum DFT_size_idx {
DFT_108, DFT_120, DFT_128, DFT_144, DFT_180, DFT_192, DFT_216, DFT_240,
DFT_256, DFT_288, DFT_300, DFT_324, DFT_360, DFT_384, DFT_432, DFT_480,
DFT_512, DFT_540, DFT_576, DFT_600, DFT_648, DFT_720, DFT_768, DFT_864,
- DFT_900, DFT_960, DFT_972, DFT_1024, DFT_1080, DFT_1152, DFT_1200, DFT_1536,
- DFT_2048, DFT_3072, DFT_4096, DFT_6144, DFT_8192, DFT_9216, DFT_12288, DFT_18432,
- DFT_24576, DFT_36864, DFT_49152, DFT_73728, DFT_98304,
+ DFT_900, DFT_960, DFT_972, DFT_1024, DFT_1080, DFT_1152, DFT_1200, DFT_1296,
+ DFT_1440, DFT_1500, DFT_1536, DFT_1620, DFT_1728, DFT_1800, DFT_1920, DFT_1944,
+ DFT_2048, DFT_2160, DFT_2304, DFT_2400, DFT_2592, DFT_2700, DFT_2880, DFT_2916,
+ DFT_3000, DFT_3072, DFT_3240, DFT_4096, DFT_6144, DFT_8192, DFT_9216, DFT_12288,
+ DFT_18432, DFT_24576, DFT_36864, DFT_49152, DFT_73728, DFT_98304,
DFT_SIZE_IDXTABLESIZE
} dft_size_idx_t;
#ifdef OAIDFTS_MAIN
adftfunc_t dft_ftab[]={
dft12, dft24, dft36, dft48, dft60, dft72, dft96,
- dft108, dft120, dft128, dft144, dft180, dft192, dft216, dft240,
+ dft108, dft120, dft128, dft144, dft180, dft192, dft216, dft240,
dft256, dft288, dft300, dft324, dft360, dft384, dft432, dft480,
dft512, dft540, dft576, dft600, dft648, dft720, dft768, dft864,
- dft900, dft960, dft972, dft1024, dft1080, dft1152, dft1200, dft1536,
- dft2048, dft3072, dft4096, dft6144, dft8192, dft9216, dft12288, dft18432,
- dft24576, dft36864, dft49152, dft73728, dft98304
+ dft900, dft960, dft972, dft1024, dft1080, dft1152, dft1200, dft1296,
+ dft1440, dft1500, dft1536, dft1620, dft1728, dft1800, dft1920, dft1944,
+ dft2048, dft2160, dft2304, dft2400, dft2592, dft2700, dft2880, dft2916,
+ dft3000, dft3072, dft3240, dft4096, dft6144, dft8192, dft9216, dft12288,
+ dft18432, dft24576, dft36864, dft49152, dft73728, dft98304
};
#endif
@@ -309,9 +330,9 @@ typedef enum idft_size_idx {
} idft_size_idx_t;
#ifdef OAIDFTS_MAIN
aidftfunc_t idft_ftab[]={
- idft128, idft256, idft512, idft1024, idft1536, idft2048, idft3072, idft4096,
- idft6144, idft8192, idft9216, idft12288, idft18432, idft24576, idft36864, idft49152,
- idft73728, idft98304
+ idft128, idft256, idft512, idft1024, idft1536, idft2048, idft3072, idft4096,
+ idft6144, idft8192, idft9216, idft12288, idft18432, idft24576, idft36864, idft49152,
+ idft73728, idft98304
};
#endif
diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h
index 9d828ae1c7..52abe9fddc 100644
--- a/openair1/PHY/defs_gNB.h
+++ b/openair1/PHY/defs_gNB.h
@@ -655,7 +655,7 @@ typedef struct {
int prach_I0;
} PHY_MEASUREMENTS_gNB;
-#define TOTAL_NUM_NR_PRACH_PREAMBLES 64
+#define MAX_NUM_NR_PRACH_PREAMBLES 64
#define MAX_NUM_NR_RX_RACH_PDUS 4
#define MAX_NUM_NR_RX_PRACH_PREAMBLES 4
#define MAX_UL_PDUS_PER_SLOT 8
diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c
index 9b056bf4a1..6856ecfb04 100644
--- a/openair1/SIMULATION/NR_PHY/dlsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlsim.c
@@ -166,6 +166,12 @@ nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
return 0;
}
+int nr_derive_key(int alg_type, uint8_t alg_id,
+ const uint8_t key[32], uint8_t **out)
+{
+ return 0;
+}
+
void config_common(int Mod_idP,
int pdsch_AntennaPorts,
NR_ServingCellConfigCommon_t *scc
diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c
index cc5b72af6c..3c15707402 100644
--- a/openair1/SIMULATION/NR_PHY/prachsim.c
+++ b/openair1/SIMULATION/NR_PHY/prachsim.c
@@ -153,6 +153,12 @@ int is_x2ap_enabled(void)
return 0;
}
+int nr_derive_key(int alg_type, uint8_t alg_id,
+ const uint8_t key[32], uint8_t **out)
+{
+ return 0;
+}
+
int main(int argc, char **argv){
char c;
diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c
index 207a8285de..3b9d8045d0 100644
--- a/openair1/SIMULATION/NR_PHY/ulsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulsim.c
@@ -177,6 +177,12 @@ int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req){ return(0);
int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req){ return(0); }
int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req){ return(0); }
+int nr_derive_key(int alg_type, uint8_t alg_id,
+ const uint8_t key[32], uint8_t **out)
+{
+ return 0;
+}
+
// needed for some functions
uint16_t n_rnti = 0x1234;
openair0_config_t openair0_cfg[MAX_CARDS];
diff --git a/openair2/COMMON/s1ap_messages_types.h b/openair2/COMMON/s1ap_messages_types.h
index f6b4f3c4e2..bd0788d2d0 100644
--- a/openair2/COMMON/s1ap_messages_types.h
+++ b/openair2/COMMON/s1ap_messages_types.h
@@ -155,6 +155,11 @@ typedef struct security_capabilities_s {
uint16_t integrity_algorithms;
} security_capabilities_t;
+typedef struct nr_security_capabilities_s {
+ uint16_t encryption_algorithms;
+ uint16_t integrity_algorithms;
+} nr_security_capabilities_t;
+
/* Provides the establishment cause for the RRC connection request as provided
* by the upper layers. W.r.t. the cause value names: highPriorityAccess
* concerns AC11..AC15, ‘mt’ stands for ‘Mobile Terminating’ and ‘mo’ for
@@ -538,6 +543,9 @@ typedef struct s1ap_initial_context_setup_req_s {
uint8_t nb_of_e_rabs;
/* list of e_rab to be setup by RRC layers */
e_rab_t e_rab_param[S1AP_MAX_E_RAB];
+
+ /* NR Security algorithms (if any, set to 0 if not present) */
+ nr_security_capabilities_t nr_security_capabilities;
} s1ap_initial_context_setup_req_t;
typedef struct tai_plmn_identity_s {
diff --git a/openair2/COMMON/x2ap_messages_types.h b/openair2/COMMON/x2ap_messages_types.h
index 0c55764d6e..f4911c47dc 100644
--- a/openair2/COMMON/x2ap_messages_types.h
+++ b/openair2/COMMON/x2ap_messages_types.h
@@ -338,7 +338,7 @@ typedef struct x2ap_ENDC_sgnb_addition_req_s {
/* used for RRC->X2AP in source eNB */
int rnti;
- security_capabilities_t security_capabilities;
+ nr_security_capabilities_t security_capabilities;
/* SgNB Security Key */
uint8_t kgnb[32];
diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c
index 4ee676a49e..957485a992 100644
--- a/openair2/GNB_APP/gnb_config.c
+++ b/openair2/GNB_APP/gnb_config.c
@@ -163,6 +163,8 @@ void prepare_scc(NR_ServingCellConfigCommon_t *scc) {
// scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rsrp_ThresholdSSB_SUL = CALLOC(1,sizeof(NR_RSRP_Range_t));
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing = CALLOC(1,sizeof(NR_SubcarrierSpacing_t));
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder = CALLOC(1,sizeof(long));
+ // 0 - ENABLE, 1 - DISABLE, hence explicitly setting to DISABLED.
+ *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder = NR_PUSCH_Config__transformPrecoder_disabled;
scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon = CALLOC(1,sizeof(NR_SetupRelease_PUSCH_ConfigCommon_t));
scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->present = NR_SetupRelease_PUSCH_ConfigCommon_PR_setup;
scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup = CALLOC(1,sizeof(struct NR_PUSCH_ConfigCommon));
@@ -513,6 +515,101 @@ void RCconfig_nr_macrlc() {
}
+void config_security(gNB_RRC_INST *rrc)
+{
+ paramdef_t logparams_defaults[] = SECURITY_GLOBALPARAMS_DESC;
+ int ret = config_get(logparams_defaults,
+ sizeof(logparams_defaults) / sizeof(paramdef_t),
+ CONFIG_STRING_SECURITY);
+ int i;
+
+ if (ret < 0) {
+ LOG_W(RRC, "configuration file does not contain a \"security\" section, applying default parameters (no security)\n");
+ rrc->security.ciphering_algorithms[0] = 0; /* nea0 = no ciphering */
+ rrc->security.ciphering_algorithms_count = 1;
+ rrc->security.integrity_algorithms[0] = 0; /* nia0 = no integrity */
+ rrc->security.integrity_algorithms_count = 1;
+ return;
+ }
+
+ if (logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].numelt > 4) {
+ LOG_E(RRC, "too much ciphering algorithms in section \"security\" of the configuration file, maximum is 4\n");
+ exit(1);
+ }
+ if (logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].numelt > 4) {
+ LOG_E(RRC, "too much integrity algorithms in section \"security\" of the configuration file, maximum is 4\n");
+ exit(1);
+ }
+
+ /* get ciphering algorithms */
+ rrc->security.ciphering_algorithms_count = 0;
+ for (i = 0; i < logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].numelt; i++) {
+ if (!strcmp(logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].strlistptr[i], "nea0")) {
+ rrc->security.ciphering_algorithms[rrc->security.ciphering_algorithms_count] = 0;
+ rrc->security.ciphering_algorithms_count++;
+ continue;
+ }
+ if (!strcmp(logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].strlistptr[i], "nea1")) {
+ rrc->security.ciphering_algorithms[rrc->security.ciphering_algorithms_count] = 1;
+ rrc->security.ciphering_algorithms_count++;
+ continue;
+ }
+ if (!strcmp(logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].strlistptr[i], "nea2")) {
+ rrc->security.ciphering_algorithms[rrc->security.ciphering_algorithms_count] = 2;
+ rrc->security.ciphering_algorithms_count++;
+ continue;
+ }
+ if (!strcmp(logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].strlistptr[i], "nea3")) {
+ rrc->security.ciphering_algorithms[rrc->security.ciphering_algorithms_count] = 3;
+ rrc->security.ciphering_algorithms_count++;
+ continue;
+ }
+ LOG_E(RRC, "unknown ciphering algorithm \"%s\" in section \"security\" of the configuration file\n",
+ logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].strlistptr[i]);
+ exit(1);
+ }
+
+ /* get integrity algorithms */
+ rrc->security.integrity_algorithms_count = 0;
+ for (i = 0; i < logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].numelt; i++) {
+ if (!strcmp(logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].strlistptr[i], "nia0")) {
+ rrc->security.integrity_algorithms[rrc->security.integrity_algorithms_count] = 0;
+ rrc->security.integrity_algorithms_count++;
+ continue;
+ }
+ if (!strcmp(logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].strlistptr[i], "nia1")) {
+ rrc->security.integrity_algorithms[rrc->security.integrity_algorithms_count] = 1;
+ rrc->security.integrity_algorithms_count++;
+ continue;
+ }
+ if (!strcmp(logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].strlistptr[i], "nia2")) {
+ rrc->security.integrity_algorithms[rrc->security.integrity_algorithms_count] = 2;
+ rrc->security.integrity_algorithms_count++;
+ continue;
+ }
+ if (!strcmp(logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].strlistptr[i], "nia3")) {
+ rrc->security.integrity_algorithms[rrc->security.integrity_algorithms_count] = 3;
+ rrc->security.integrity_algorithms_count++;
+ continue;
+ }
+ LOG_E(RRC, "unknown integrity algorithm \"%s\" in section \"security\" of the configuration file\n",
+ logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].strlistptr[i]);
+ exit(1);
+ }
+
+ if (rrc->security.ciphering_algorithms_count == 0) {
+ LOG_W(RRC, "no preferred ciphering algorithm set in configuration file, applying default parameters (no security)\n");
+ rrc->security.ciphering_algorithms[0] = 0; /* nea0 = no ciphering */
+ rrc->security.ciphering_algorithms_count = 1;
+ }
+
+ if (rrc->security.integrity_algorithms_count == 0) {
+ LOG_W(RRC, "no preferred integrity algorithm set in configuration file, applying default parameters (no security)\n");
+ rrc->security.integrity_algorithms[0] = 0; /* nia0 = no integrity */
+ rrc->security.integrity_algorithms_count = 1;
+ }
+}
+
void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
int num_gnbs = 0;
@@ -679,7 +776,7 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
}//End for (k=0; k 0)
-
+ config_security(rrc);
}//End RCconfig_NRRRC function
int RCconfig_nr_gtpu(void ) {
diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h
index f1fe0c97c9..403602c109 100644
--- a/openair2/GNB_APP/gnb_paramdef.h
+++ b/openair2/GNB_APP/gnb_paramdef.h
@@ -452,4 +452,27 @@ typedef enum {
#define CONFIG_HLP_WORKER "coding and FEP worker thread WORKER_DISABLE or WORKER_ENABLE\n"
#define CONFIG_HLP_PARALLEL "PARALLEL_SINGLE_THREAD, PARALLEL_RU_L1_SPLIT, or PARALLEL_RU_L1_TRX_SPLIT(RU_L1_TRX_SPLIT by defult)\n"
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+/* security configuration */
+/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+#define CONFIG_STRING_SECURITY "security"
+
+#define SECURITY_CONFIG_CIPHERING "ciphering_algorithms"
+#define SECURITY_CONFIG_INTEGRITY "integrity_algorithms"
+
+/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+/* security configuration */
+/* optname help paramflags XXXptr defXXXval type numelt */
+/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+#define SECURITY_GLOBALPARAMS_DESC { \
+ {SECURITY_CONFIG_CIPHERING, "preferred ciphering algorithms\n", 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST, 0}, \
+ {SECURITY_CONFIG_INTEGRITY, "preferred integrity algorithms\n", 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST, 0}, \
+}
+
+#define SECURITY_CONFIG_CIPHERING_IDX 0
+#define SECURITY_CONFIG_INTEGRITY_IDX 1
+/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+
#endif
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
index d228c7fc96..f26062d4c7 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
@@ -783,7 +783,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
// FIXME: Remove this
if (ra->ra_state == WAIT_CONTENTION_RESOLUTION && rnti == ra->t_crnti){
- LOG_I(NR_MAC,"RA-Msg4 was received\n");
+ LOG_I(NR_MAC,"RA-Msg4 received\n");
nr_ra_succeeded(module_id, frame, slot);
}
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
index 9fcf9baaaf..d60fc55090 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
@@ -895,6 +895,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
for (int k = 0; k < TBS_bytes; k++) {
LOG_D(NR_MAC,"(%i): 0x%x\n",k,mac->ulsch_pdu.payload[k]);
}
+ LOG_I(NR_MAC,"[RAPROC] RA-Msg3 transmitted\n");
} else {
if (IS_SOFTMODEM_NOS1 && (mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] != ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator)){
// Getting IP traffic to be transmitted
diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c
index 847b095ab8..41317f8bbc 100644
--- a/openair2/LAYER2/NR_MAC_gNB/config.c
+++ b/openair2/LAYER2/NR_MAC_gNB/config.c
@@ -401,28 +401,44 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
const int UE_id = add_new_nr_ue(Mod_idP, rnti, secondaryCellGroup);
LOG_I(PHY,"Added new UE_id %d/%x with initial secondaryCellGroup\n",UE_id,rnti);
} else if (add_ue == 1 && !get_softmodem_params()->phy_test) {
- /* TODO: should check for free RA process */
const int CC_id = 0;
- NR_RA_t *ra = &RC.nrmac[Mod_idP]->common_channels[CC_id].ra[0];
- ra->state = RA_IDLE;
+ NR_COMMON_channels_t *cc = &RC.nrmac[Mod_idP]->common_channels[CC_id];
+ uint8_t ra_index = 0;
+ /* checking for free RA process */
+ for(; ra_index < NR_NB_RA_PROC_MAX; ra_index++) {
+ if((cc->ra[ra_index].state == RA_IDLE) && (!cc->ra[ra_index].cfra)) break;
+ }
+ if (ra_index == NR_NB_RA_PROC_MAX) {
+ LOG_E(MAC, "%s() %s:%d RA processes are not available for CFRA RNTI :%x\n", __FUNCTION__, __FILE__, __LINE__, rnti);
+ return -1;
+ }
+ NR_RA_t *ra = &cc->ra[ra_index];
ra->secondaryCellGroup = secondaryCellGroup;
if (secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated!=NULL) {
if (secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra != NULL) {
ra->cfra = true;
ra->rnti = rnti;
- struct NR_CFRA cfra = *secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra;
- uint8_t num_preamble = cfra.resources.choice.ssb->ssb_ResourceList.list.count;
+ struct NR_CFRA *cfra = secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra;
+ uint8_t num_preamble = cfra->resources.choice.ssb->ssb_ResourceList.list.count;
ra->preambles.num_preambles = num_preamble;
ra->preambles.preamble_list = (uint8_t *) malloc(num_preamble*sizeof(uint8_t));
- for (int i = 0; i < num_preamble; i++)
- ra->preambles.preamble_list[i] = cfra.resources.choice.ssb->ssb_ResourceList.list.array[i]->ra_PreambleIndex;
+ for(int i=0; inum_active_ssb; i++) {
+ for(int j=0; jssb_index[i] == cfra->resources.choice.ssb->ssb_ResourceList.list.array[j]->ssb) {
+ // one dedicated preamble for each beam
+ ra->preambles.preamble_list[i] =
+ cfra->resources.choice.ssb->ssb_ResourceList.list.array[j]->ra_PreambleIndex;
+ break;
+ }
+ }
+ }
}
} else {
ra->cfra = false;
ra->rnti = rnti;
- ra->preambles.num_preambles = TOTAL_NUM_NR_PRACH_PREAMBLES;
- ra->preambles.preamble_list = (uint8_t *) malloc(TOTAL_NUM_NR_PRACH_PREAMBLES*sizeof(uint8_t));
- for (int i = 0; i < TOTAL_NUM_NR_PRACH_PREAMBLES; i++)
+ ra->preambles.num_preambles = MAX_NUM_NR_PRACH_PREAMBLES;
+ ra->preambles.preamble_list = (uint8_t *) malloc(MAX_NUM_NR_PRACH_PREAMBLES*sizeof(uint8_t));
+ for (int i = 0; i < MAX_NUM_NR_PRACH_PREAMBLES; i++)
ra->preambles.preamble_list[i] = i;
}
LOG_I(PHY,"Added new RA process for UE RNTI %04x with initial secondaryCellGroup\n", rnti);
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
index 7201b29596..6164f64e21 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
@@ -438,7 +438,13 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
}
// This schedules the DCI for Downlink and PDSCH
- if (is_xlsch_in_slot(dlsch_in_slot_bitmap, slot))
+ bool tx_ra_msg4 = false;
+ for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
+ if(cc->ra[i].state == Msg4 && cc->ra[i].Msg4_frame==frame && cc->ra[i].Msg4_slot==slot) {
+ tx_ra_msg4 = true;
+ }
+ }
+ if ( is_xlsch_in_slot(dlsch_in_slot_bitmap, slot) && tx_ra_msg4 == false )
nr_schedule_ue_spec(module_idP, frame, slot);
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
index 00827a13ee..1eb25c0366 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
@@ -65,7 +65,7 @@ int16_t ssb_index_from_prach(module_id_t module_idP,
uint8_t config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex;
uint8_t fdm = cfg->prach_config.num_prach_fd_occasions.value;
- uint8_t total_RApreambles = 64;
+ uint8_t total_RApreambles = MAX_NUM_NR_PRACH_PREAMBLES;
if( scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles != NULL)
total_RApreambles = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles;
@@ -151,6 +151,38 @@ void find_SSB_and_RO_available(module_id_t module_idP) {
uint8_t num_active_ssb = 0;
uint8_t max_association_period = 1;
+ struct NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB *ssb_perRACH_OccasionAndCB_PreamblesPerSSB = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB;
+
+ switch (ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present){
+ case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneEighth:
+ cc->cb_preambles_per_ssb = 4 * (ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneEighth + 1);
+ break;
+ case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneFourth:
+ cc->cb_preambles_per_ssb = 4 * (ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneFourth + 1);
+ break;
+ case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneHalf:
+ cc->cb_preambles_per_ssb = 4 * (ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneHalf + 1);
+ break;
+ case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_one:
+ cc->cb_preambles_per_ssb = 4 * (ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.one + 1);
+ break;
+ case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_two:
+ cc->cb_preambles_per_ssb = 4 * (ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.two + 1);
+ break;
+ case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_four:
+ cc->cb_preambles_per_ssb = ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.four;
+ break;
+ case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_eight:
+ cc->cb_preambles_per_ssb = ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.eight;
+ break;
+ case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_sixteen:
+ cc->cb_preambles_per_ssb = ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.sixteen;
+ break;
+ default:
+ AssertFatal(1 == 0, "Unsupported ssb_perRACH_config %d\n", ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present);
+ break;
+ }
+
if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing)
mu = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing;
else
@@ -181,25 +213,28 @@ void find_SSB_and_RO_available(module_id_t module_idP) {
}
}
- for(int i = 1; (1 << (i-1)) <= max_association_period;i++) {
+ cc->total_prach_occasions_per_config_period = total_RA_occasions;
+ for(int i=1; (1 << (i-1)) < max_association_period; i++) {
+ cc->max_association_period = (1 <<(i-1));
+ total_RA_occasions = total_RA_occasions * cc->max_association_period;
if(total_RA_occasions >= (int) (num_active_ssb/num_ssb_per_RO)) {
repetition = (uint16_t)((total_RA_occasions * num_ssb_per_RO )/num_active_ssb);
break;
}
- else {
- total_RA_occasions = total_RA_occasions * i;
- cc->max_association_period = i;
- }
}
- if(cc->max_association_period == 0)
- cc->max_association_period = 1;
unused_RA_occasion = total_RA_occasions - (int)((num_active_ssb * repetition)/num_ssb_per_RO);
cc->total_prach_occasions = total_RA_occasions - unused_RA_occasion;
cc->num_active_ssb = num_active_ssb;
- LOG_I(MAC, "Total available RO %d, num of active SSB %d: unused RO = %d max_association_period %u N_RA_sfn %u \n",
- cc->total_prach_occasions, cc->num_active_ssb, unused_RA_occasion, max_association_period, N_RA_sfn);
+ LOG_I(MAC,
+ "Total available RO %d, num of active SSB %d: unused RO = %d association_period %u N_RA_sfn %u total_prach_occasions_per_config_period %u\n",
+ cc->total_prach_occasions,
+ cc->num_active_ssb,
+ unused_RA_occasion,
+ cc->max_association_period,
+ N_RA_sfn,
+ cc->total_prach_occasions_per_config_period);
}
void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
@@ -439,190 +474,217 @@ void nr_initiate_ra_proc(module_id_t module_idP,
gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
- NR_RA_t *ra = &cc->ra[0];
- uint16_t ra_rnti;
+ uint8_t total_RApreambles = MAX_NUM_NR_PRACH_PREAMBLES;
+ uint8_t num_ssb_per_RO = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present;
+ int pr_found;
- // ra_rnti from 5.1.3 in 38.321
- // FK: in case of long PRACH the phone seems to expect the subframe number instead of the slot number here.
- if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present==NR_RACH_ConfigCommon__prach_RootSequenceIndex_PR_l839)
- ra_rnti=1+symbol+(9/*slotP*/*14)+(freq_index*14*80)+(ul_carrier_id*14*80*8);
- else
- ra_rnti=1+symbol+(slotP*14)+(freq_index*14*80)+(ul_carrier_id*14*80*8);
+ if( scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles != NULL)
+ total_RApreambles = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles;
-
- // if the preamble received correspond to one of the listed
- // the UE sent a RACH either for starting RA procedure or RA procedure failed and UE retries
- int pr_found=0;
- for (int i = 0; i < ra->preambles.num_preambles; i++) {
- if (preamble_index == ra->preambles.preamble_list[i]) {
- pr_found=1;
- break;
- }
+ if(num_ssb_per_RO > 3) { /*num of ssb per RO >= 1*/
+ num_ssb_per_RO -= 3;
+ total_RApreambles = total_RApreambles/num_ssb_per_RO ;
}
- if (!pr_found) {
- LOG_E(MAC, "[gNB %d][RAPROC] FAILURE: preamble %d does not correspond to any of the ones in rach_ConfigDedicated\n",
- module_idP, preamble_index);
-
- return; // if the PRACH preamble does not correspond to any of the ones sent through RRC abort RA proc
- }
- // This should be handled differently when we use the initialBWP for RA
- ra->bwp_id=1;
- NR_BWP_Downlink_t *bwp=ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id-1];
-
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 1);
-
- LOG_I(MAC, "[gNB %d][RAPROC] CC_id %d Frame %d, Slot %d Initiating RA procedure for preamble index %d\n", module_idP, CC_id, frameP, slotP, preamble_index);
-
- if (ra->state == RA_IDLE) {
-
- uint8_t beam_index = ssb_index_from_prach(module_idP,
- frameP,
- slotP,
- preamble_index,
- freq_index,
- symbol);
-
- LOG_D(MAC, "Frame %d, Slot %d: Activating RA process \n", frameP, slotP);
- ra->state = Msg2;
- ra->timing_offset = timing_offset;
- ra->preamble_slot = slotP;
-
- struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList;
- AssertFatal(commonSearchSpaceList->list.count>0,
- "common SearchSpace list has 0 elements\n");
- // Common searchspace list
- for (int i=0;ilist.count;i++) {
- ss=commonSearchSpaceList->list.array[i];
- if(ss->searchSpaceId == *bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace)
- ra->ra_ss=ss;
- }
-
- // retrieving ra pdcch monitoring period and offset
- find_monitoring_periodicity_offset_common(ra->ra_ss,
- &monitoring_slot_period,
- &monitoring_offset);
-
- nr_schedule_msg2(frameP, slotP, &msg2_frame, &msg2_slot, scc, monitoring_slot_period, monitoring_offset,beam_index,cc->num_active_ssb);
-
- ra->Msg2_frame = msg2_frame;
- ra->Msg2_slot = msg2_slot;
-
- LOG_I(MAC, "%s() Msg2[%04d%d] SFN/SF:%04d%d\n", __FUNCTION__, ra->Msg2_frame, ra->Msg2_slot, frameP, slotP);
-
- // TODO: Configure RRC with the new RNTI of the following commented lines
- /*
- int loop = 0;
- if (!ra->cfra) {
- do {
- ra->rnti = (taus() % 65518) + 1;
- loop++;
+ for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
+ NR_RA_t *ra = &cc->ra[i];
+ pr_found = 0;
+ if (ra->state == RA_IDLE) {
+ for(int j = 0; j < ra->preambles.num_preambles; j++) {
+ //check if the preamble received correspond to one of the listed or configured preambles
+ if (preamble_index == ra->preambles.preamble_list[j]) {
+ pr_found=1;
+ break;
+ }
}
- while (loop != 100 && !((find_nr_UE_id(module_idP, ra->rnti) == -1) && (find_nr_RA_id(module_idP, CC_id, ra->rnti) == -1) && ra->rnti >= 1 && ra->rnti <= 65519));
- if (loop == 100) {
- LOG_E(MAC,"%s:%d:%s: [RAPROC] initialisation random access aborted\n", __FILE__, __LINE__, __FUNCTION__);
- abort();
+
+ if (pr_found == 0) {
+ continue;
}
+
+ uint16_t ra_rnti;
+
+ // ra_rnti from 5.1.3 in 38.321
+ // FK: in case of long PRACH the phone seems to expect the subframe number instead of the slot number here.
+ if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present
+ == NR_RACH_ConfigCommon__prach_RootSequenceIndex_PR_l839)
+ ra_rnti = 1 + symbol + (9 /*slotP*/ * 14) + (freq_index * 14 * 80) + (ul_carrier_id * 14 * 80 * 8);
+ else
+ ra_rnti = 1 + symbol + (slotP * 14) + (freq_index * 14 * 80) + (ul_carrier_id * 14 * 80 * 8);
+
+ // This should be handled differently when we use the initialBWP for RA
+ ra->bwp_id = 1;
+ NR_BWP_Downlink_t *bwp = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList
+ ->list.array[ra->bwp_id - 1];
+
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 1);
+
+ LOG_D(MAC,
+ "[gNB %d][RAPROC] CC_id %d Frame %d, Slot %d Initiating RA procedure for preamble index %d\n",
+ module_idP,
+ CC_id,
+ frameP,
+ slotP,
+ preamble_index);
+
+ uint8_t beam_index = ssb_index_from_prach(module_idP, frameP, slotP, preamble_index, freq_index, symbol);
+
+ // the UE sent a RACH either for starting RA procedure or RA procedure failed and UE retries
+ if (ra->cfra) {
+ // if the preamble received correspond to one of the listed
+ if (!(preamble_index == ra->preambles.preamble_list[beam_index])) {
+ LOG_E(
+ MAC,
+ "[gNB %d][RAPROC] FAILURE: preamble %d does not correspond to any of the ones in rach_ConfigDedicated\n",
+ module_idP,
+ preamble_index);
+ continue; // if the PRACH preamble does not correspond to any of the ones sent through RRC abort RA proc
+ }
+ }
+ LOG_D(MAC, "Frame %d, Slot %d: Activating RA process \n", frameP, slotP);
+ ra->state = Msg2;
+ ra->timing_offset = timing_offset;
+ ra->preamble_slot = slotP;
+
+ struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList =
+ bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList;
+ AssertFatal(commonSearchSpaceList->list.count > 0, "common SearchSpace list has 0 elements\n");
+ // Common searchspace list
+ for (int i = 0; i < commonSearchSpaceList->list.count; i++) {
+ ss = commonSearchSpaceList->list.array[i];
+ if (ss->searchSpaceId == *bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace)
+ ra->ra_ss = ss;
+ }
+
+ // retrieving ra pdcch monitoring period and offset
+ find_monitoring_periodicity_offset_common(ra->ra_ss, &monitoring_slot_period, &monitoring_offset);
+
+ nr_schedule_msg2(frameP,
+ slotP,
+ &msg2_frame,
+ &msg2_slot,
+ scc,
+ monitoring_slot_period,
+ monitoring_offset,
+ beam_index,
+ cc->num_active_ssb);
+
+ ra->Msg2_frame = msg2_frame;
+ ra->Msg2_slot = msg2_slot;
+
+ LOG_D(MAC, "%s() Msg2[%04d%d] SFN/SF:%04d%d\n", __FUNCTION__, ra->Msg2_frame, ra->Msg2_slot, frameP, slotP);
+
+ // TODO: Configure RRC with the new RNTI of the following commented lines
+ /*
+ int loop = 0;
+ if (!ra->cfra) {
+ do {
+ ra->rnti = (taus() % 65518) + 1;
+ loop++;
+ } while (loop != 100
+ && !((find_nr_UE_id(module_idP, ra->rnti) == -1) && (find_nr_RA_id(module_idP, CC_id, ra->rnti) == -1)
+ && ra->rnti >= 1 && ra->rnti <= 65519));
+ if (loop == 100) {
+ LOG_E(MAC, "%s:%d:%s: [RAPROC] initialisation random access aborted\n", __FILE__, __LINE__, __FUNCTION__);
+ abort();
+ }
+ }
+ */
+
+ ra->RA_rnti = ra_rnti;
+ ra->preamble_index = preamble_index;
+ ra->beam_id = beam_index;
+
+ LOG_D(MAC,
+ "[gNB %d][RAPROC] CC_id %d Frame %d Activating Msg2 generation in frame %d, slot %d using RA rnti %x SSB "
+ "index %u\n",
+ module_idP,
+ CC_id,
+ frameP,
+ ra->Msg2_frame,
+ ra->Msg2_slot,
+ ra->RA_rnti,
+ cc->ssb_index[beam_index]);
+
+ return;
}
- */
-
- ra->RA_rnti = ra_rnti;
- ra->preamble_index = preamble_index;
- ra->beam_id = beam_index;
-
- LOG_I(MAC,"[gNB %d][RAPROC] CC_id %d Frame %d Activating Msg2 generation in frame %d, slot %d using RA rnti %x SSB index %u\n",
- module_idP,
- CC_id,
- frameP,
- ra->Msg2_frame,
- ra->Msg2_slot,
- ra->RA_rnti,
- cc->ssb_index[beam_index]);
-
- return;
}
LOG_E(MAC, "[gNB %d][RAPROC] FAILURE: CC_id %d Frame %d initiating RA procedure for preamble index %d\n", module_idP, CC_id, frameP, preamble_index);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0);
}
-void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){
+ void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
+ {
+ gNB_MAC_INST *mac = RC.nrmac[module_idP];
- //uint8_t i = 0;
- int CC_id = 0;
- gNB_MAC_INST *mac = RC.nrmac[module_idP];
- NR_COMMON_channels_t *cc = &mac->common_channels[CC_id];
-
- start_meas(&mac->schedule_ra);
-
-// for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
-// for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
-
-// NR_RA_t *ra = &cc->ra[i];
- NR_RA_t *ra = &cc->ra[0];
-
- LOG_D(MAC,"RA[state:%d]\n",ra->state);
- switch (ra->state){
- case Msg2:
- nr_generate_Msg2(module_idP, CC_id, frameP, slotP);
- break;
- case Msg4:
- nr_generate_Msg4(module_idP, CC_id, frameP, slotP);
- break;
- case WAIT_Msg4_ACK:
- nr_check_Msg4_Ack(module_idP, CC_id, frameP, slotP);
- break;
- default:
- break;
- }
-// }
-// }
- stop_meas(&mac->schedule_ra);
-}
-
-void nr_get_Msg3alloc(module_id_t module_id,
- int CC_id,
- NR_ServingCellConfigCommon_t *scc,
- NR_BWP_Uplink_t *ubwp,
- sub_frame_t current_slot,
- frame_t current_frame,
- NR_RA_t *ra) {
-
- // msg3 is schedulend in mixed slot in the following TDD period
-
- uint16_t msg3_nb_rb = 8 + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT); // sdu has 6 or 8 bytes
-
- int mu = ubwp->bwp_Common->genericParameters.subcarrierSpacing;
- int StartSymbolIndex, NrOfSymbols, startSymbolAndLength, temp_slot;
- ra->Msg3_tda_id = 16; // initialization to a value above limit
-
- for (int i=0; ibwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.count; i++) {
- startSymbolAndLength = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[i]->startSymbolAndLength;
- SLIV2SL(startSymbolAndLength, &StartSymbolIndex, &NrOfSymbols);
- // we want to transmit in the uplink symbols of mixed slot
- if (NrOfSymbols == scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols) {
- ra->Msg3_tda_id = i;
- break;
+ start_meas(&mac->schedule_ra);
+ for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
+ NR_COMMON_channels_t *cc = &mac->common_channels[CC_id];
+ for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
+ NR_RA_t *ra = &cc->ra[i];
+ LOG_D(NR_MAC, "RA[state:%d]\n", ra->state);
+ switch (ra->state) {
+ case Msg2:
+ nr_generate_Msg2(module_idP, CC_id, frameP, slotP, ra);
+ break;
+ case Msg4:
+ nr_generate_Msg4(module_idP, CC_id, frameP, slotP, ra);
+ break;
+ case WAIT_Msg4_ACK:
+ nr_check_Msg4_Ack(module_idP, CC_id, frameP, slotP, ra);
+ break;
+ default:
+ break;
+ }
+ }
}
+ stop_meas(&mac->schedule_ra);
}
- AssertFatal(ra->Msg3_tda_id<16,"Unable to find Msg3 time domain allocation in list\n");
- uint8_t k2 = *ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->k2;
+ void nr_get_Msg3alloc(module_id_t module_id,
+ int CC_id,
+ NR_ServingCellConfigCommon_t *scc,
+ NR_BWP_Uplink_t *ubwp,
+ sub_frame_t current_slot,
+ frame_t current_frame,
+ NR_RA_t *ra) {
- temp_slot = current_slot + k2 + DELTA[mu]; // msg3 slot according to 8.3 in 38.213
- ra->Msg3_slot = temp_slot%nr_slots_per_frame[mu];
- if (nr_slots_per_frame[mu]>temp_slot)
- ra->Msg3_frame = current_frame;
- else
- ra->Msg3_frame = current_frame + (temp_slot/nr_slots_per_frame[mu]);
+ // msg3 is schedulend in mixed slot in the following TDD period
- LOG_I(MAC, "[RAPROC] Msg3 slot %d: current slot %u Msg3 frame %u k2 %u Msg3_tda_id %u start symbol index %u\n", ra->Msg3_slot, current_slot, ra->Msg3_frame, k2,ra->Msg3_tda_id, StartSymbolIndex);
- uint16_t *vrb_map_UL =
- &RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[ra->Msg3_slot * MAX_BWP_SIZE];
- const uint16_t bwpSize = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+ uint16_t msg3_nb_rb = 8 + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT); // sdu has 6 or 8 bytes
- /* search msg3_nb_rb free RBs */
+ int mu = ubwp->bwp_Common->genericParameters.subcarrierSpacing;
+ int StartSymbolIndex, NrOfSymbols, startSymbolAndLength, temp_slot;
+ ra->Msg3_tda_id = 16; // initialization to a value above limit
+
+ for (int i=0; ibwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.count; i++) {
+ startSymbolAndLength = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[i]->startSymbolAndLength;
+ SLIV2SL(startSymbolAndLength, &StartSymbolIndex, &NrOfSymbols);
+ // we want to transmit in the uplink symbols of mixed slot
+ if (NrOfSymbols == scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols) {
+ ra->Msg3_tda_id = i;
+ break;
+ }
+ }
+ AssertFatal(ra->Msg3_tda_id<16,"Unable to find Msg3 time domain allocation in list\n");
+
+ uint8_t k2 = *ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->k2;
+
+ temp_slot = current_slot + k2 + DELTA[mu]; // msg3 slot according to 8.3 in 38.213
+ ra->Msg3_slot = temp_slot%nr_slots_per_frame[mu];
+ if (nr_slots_per_frame[mu]>temp_slot)
+ ra->Msg3_frame = current_frame;
+ else
+ ra->Msg3_frame = current_frame + (temp_slot/nr_slots_per_frame[mu]);
+
+ LOG_D(MAC, "[RAPROC] Msg3 slot %d: current slot %u Msg3 frame %u k2 %u Msg3_tda_id %u start symbol index %u\n", ra->Msg3_slot, current_slot, ra->Msg3_frame, k2,ra->Msg3_tda_id, StartSymbolIndex);
+ uint16_t *vrb_map_UL =
+ &RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[ra->Msg3_slot * MAX_BWP_SIZE];
+ const uint16_t bwpSize = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+
+ /* search msg3_nb_rb free RBs */
int rbSize = 0;
int rbStart = 0;
while (rbSize < msg3_nb_rb) {
@@ -640,12 +702,11 @@ void nr_get_Msg3alloc(module_id_t module_id,
ra->msg3_first_rb = rbStart;
}
-void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP){
-
+void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra, uint8_t *RAR_pdu)
+{
gNB_MAC_INST *mac = RC.nrmac[module_idP];
NR_COMMON_channels_t *cc = &mac->common_channels[CC_id];
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
- NR_RA_t *ra = &cc->ra[0];
if (ra->state == RA_IDLE) {
LOG_W(MAC,"RA is not active for RA %X. skipping msg3 scheduling\n", ra->rnti);
@@ -760,23 +821,14 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
pusch_pdu->nrOfLayers = 1)>>3;
// calling function to fill rar message
- nr_fill_rar(module_idP, ra, cc->RAR_pdu.payload, pusch_pdu);
-
+ nr_fill_rar(module_idP, ra, RAR_pdu, pusch_pdu);
}
-// WIP
-// todo:
-// - fix me
-// - get msg3 alloc (see nr_process_rar)
-void nr_generate_Msg2(module_id_t module_idP,
- int CC_id,
- frame_t frameP,
- sub_frame_t slotP)
+void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra)
{
gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
- NR_RA_t *ra = &cc->ra[0];
if ((ra->Msg2_frame == frameP) && (ra->Msg2_slot == slotP)) {
@@ -790,14 +842,31 @@ void nr_generate_Msg2(module_id_t module_idP,
int time_domain_assignment = 0;
uint8_t nr_of_candidates = 0;
uint8_t aggregation_level = 0;
+ int rbStart = 0;
+ int rbSize = 6;
+ uint16_t *vrb_map = cc[CC_id].vrb_map;
NR_SearchSpace_t *ss = nr_mac->sched_ctrlCommon->search_space;
NR_BWP_Downlink_t *bwp = nr_mac->sched_ctrlCommon->active_bwp;
NR_ControlResourceSet_t *coreset = nr_mac->sched_ctrlCommon->coreset;
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
+ long BWPSize = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+ long BWPStart = NRRIV2PRBOFFSET(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+
nfapi_nr_dl_tti_request_body_t *dl_req = &nr_mac->DL_req[CC_id].dl_tti_request_body;
+ for (int i = 0; (i < rbSize) && (rbStart <= (BWPSize - rbSize)); i++) {
+ if (vrb_map[rbStart + i]) {
+ rbStart += i;
+ i = 0;
+ }
+ }
+ if (rbStart > (BWPSize - rbSize)) {
+ LOG_E(MAC, "%s(): cannot find free vrb_map for RA RNTI %04x!\n", __func__, ra->RA_rnti);
+ return;
+ }
+
// Checking if the DCI allocation is feasible in current subframe
if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) {
LOG_I(MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, ra->RA_rnti);
@@ -818,8 +887,6 @@ void nr_generate_Msg2(module_id_t module_idP,
return;
}
- nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs];
-
// look up the PDCCH PDU for this CC, BWP, and CORESET. If it does not exist, create it. This is especially
// important if we have multiple RAs, and the DLSCH has to reuse them, so we need to mark them
const int bwpid = bwp->bwp_Id;
@@ -846,14 +913,9 @@ void nr_generate_Msg2(module_id_t module_idP,
dl_req->nPDUs+=1;
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15;
- LOG_I(NR_MAC,"[gNB %d] [RAPROC] CC_id %d Frame %d, slotP %d: Generating RA-Msg2 DCI, state %d\n", module_idP, CC_id, frameP, slotP, ra->state);
+ LOG_I(NR_MAC,"[gNB %d][RAPROC] CC_id %d Frame %d, slotP %d: Generating RA-Msg2 DCI, rnti 0x%x, state %d\n", module_idP, CC_id, frameP, slotP, ra->RA_rnti, ra->state);
- // This code from this point on will not work on initialBWP or CORESET0
- AssertFatal(ra->bwp_id>0,"cannot work on initialBWP for now\n");
-
- AssertFatal(ra->secondaryCellGroup,
- "no secondaryCellGroup for RNTI %04x\n",
- ra->crnti);
+ AssertFatal(ra->secondaryCellGroup, "no secondaryCellGroup for RNTI %04x\n", ra->crnti);
AssertFatal(ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
"downlinkBWP_ToAddModList has %d BWP!\n", ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
@@ -864,15 +926,14 @@ void nr_generate_Msg2(module_id_t module_idP,
// information to data and is reset every slot.
const int pduindex = nr_mac->pdu_index[CC_id]++;
pdsch_pdu_rel15->pduIndex = pduindex;
- pdsch_pdu_rel15->BWPSize = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
- pdsch_pdu_rel15->BWPStart = NRRIV2PRBOFFSET(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+ pdsch_pdu_rel15->BWPSize = BWPSize;
+ pdsch_pdu_rel15->BWPStart = BWPStart;
pdsch_pdu_rel15->SubcarrierSpacing = bwp->bwp_Common->genericParameters.subcarrierSpacing;
pdsch_pdu_rel15->CyclicPrefix = 0;
pdsch_pdu_rel15->NrOfCodewords = 1;
pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(mcsIndex,0);
pdsch_pdu_rel15->qamModOrder[0] = 2;
pdsch_pdu_rel15->mcsIndex[0] = mcsIndex;
-
if (bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table == NULL)
pdsch_pdu_rel15->mcsTable[0] = 0;
else{
@@ -881,7 +942,6 @@ void nr_generate_Msg2(module_id_t module_idP,
else
pdsch_pdu_rel15->mcsTable[0] = 2;
}
-
pdsch_pdu_rel15->rvIndex[0] = 0;
pdsch_pdu_rel15->dataScramblingId = *scc->physCellId;
pdsch_pdu_rel15->nrOfLayers = 1;
@@ -893,8 +953,8 @@ void nr_generate_Msg2(module_id_t module_idP,
pdsch_pdu_rel15->numDmrsCdmGrpsNoData = 2;
pdsch_pdu_rel15->dmrsPorts = 1;
pdsch_pdu_rel15->resourceAlloc = 1;
- pdsch_pdu_rel15->rbStart = 0;
- pdsch_pdu_rel15->rbSize = 6;
+ pdsch_pdu_rel15->rbStart = rbStart;
+ pdsch_pdu_rel15->rbSize = rbSize;
pdsch_pdu_rel15->VRBtoPRBMapping = 0;
for (int i=0; ibwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count; i++) {
@@ -963,18 +1023,8 @@ void nr_generate_Msg2(module_id_t module_idP,
pdsch_pdu_rel15->BWPSize,
nr_mac->sched_ctrlCommon->active_bwp->bwp_Id);
- // Program UL processing for Msg3
- NR_BWP_Uplink_t *ubwp=ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id-1];
- nr_get_Msg3alloc(module_idP, CC_id, scc, ubwp, slotP, frameP, ra);
- LOG_I(MAC, "Frame %d, Subframe %d: Setting Msg3 reception for Frame %d Subframe %d\n", frameP, slotP, ra->Msg3_frame, ra->Msg3_slot);
- nr_add_msg3(module_idP, CC_id, frameP, slotP);
- ra->state = WAIT_Msg3;
- LOG_I(MAC,"[gNB %d][RAPROC] Frame %d, Subframe %d: RA state %d\n", module_idP, frameP, slotP, ra->state);
-
- x_Overhead = 0;
- nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, x_Overhead, pdsch_pdu_rel15->numDmrsCdmGrpsNoData, dci_payload.tb_scaling);
-
// DL TX request
+ nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs];
tx_req->PDU_length = pdsch_pdu_rel15->TBSize[0];
tx_req->PDU_index = pduindex;
tx_req->num_TLV = 1;
@@ -982,28 +1032,33 @@ void nr_generate_Msg2(module_id_t module_idP,
nr_mac->TX_req[CC_id].SFN = frameP;
nr_mac->TX_req[CC_id].Number_of_PDUs++;
nr_mac->TX_req[CC_id].Slot = slotP;
- memcpy((void*)&tx_req->TLVs[0].value.direct[0], (void*)&cc[CC_id].RAR_pdu.payload[0], tx_req->TLVs[0].length);
+
+ // Program UL processing for Msg3
+ NR_BWP_Uplink_t *ubwp=ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id-1];
+ nr_get_Msg3alloc(module_idP, CC_id, scc, ubwp, slotP, frameP, ra);
+ LOG_I(MAC, "Frame %d, Subframe %d: Setting RA-Msg3 reception for Frame %d Subframe %d\n", frameP, slotP, ra->Msg3_frame, ra->Msg3_slot);
+ nr_add_msg3(module_idP, CC_id, frameP, slotP, ra, (uint8_t *) &tx_req->TLVs[0].value.direct[0]);
+ ra->state = WAIT_Msg3;
+ LOG_I(MAC,"[gNB %d][RAPROC] Frame %d, Subframe %d: RA state %d\n", module_idP, frameP, slotP, ra->state);
+
+ x_Overhead = 0;
+ nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, x_Overhead, pdsch_pdu_rel15->numDmrsCdmGrpsNoData, dci_payload.tb_scaling);
T(T_GNB_MAC_DL_RAR_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id),
- T_INT(ra->RA_rnti), T_INT(frameP), T_INT(slotP), T_INT(0) /* harq pid, meaningful? */,
- T_BUFFER(&cc[CC_id].RAR_pdu.payload[0], tx_req->TLVs[0].length));
+ T_INT(ra->RA_rnti), T_INT(frameP), T_INT(slotP), T_INT(0),
+ T_BUFFER(&tx_req->TLVs[0].value.direct[0], tx_req->TLVs[0].length));
- // mark the corresponding RBs as used
- uint16_t *vrb_map = cc[CC_id].vrb_map;
- for (int rb = 0; rb < pdsch_pdu_rel15->rbSize; rb++) {
- vrb_map[rb + pdsch_pdu_rel15->rbStart] = 1;
+ // Mark the corresponding RBs as used
+ for (int rb = 0; rb < rbSize; rb++) {
+ vrb_map[rb + rbStart] = 1;
}
}
}
-void nr_generate_Msg4(module_id_t module_idP,
- int CC_id,
- frame_t frameP,
- sub_frame_t slotP) {
+void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra) {
gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
- NR_RA_t *ra = &cc->ra[0];
if (ra->Msg4_frame == frameP && ra->Msg4_slot == slotP ) {
@@ -1075,10 +1130,7 @@ void nr_generate_Msg4(module_id_t module_idP,
LOG_I(NR_MAC,"[gNB %d] [RAPROC] CC_id %d Frame %d, slotP %d: Generating RA-Msg4 DCI, state %d\n", module_idP, CC_id, frameP, slotP, ra->state);
- // This code from this point on will not work on initialBWP or CORESET0
- AssertFatal(ra->bwp_id>0,"cannot work on initialBWP for now\n");
AssertFatal(ra->secondaryCellGroup, "no secondaryCellGroup for RNTI %04x\n", ra->rnti);
-
AssertFatal(ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
"downlinkBWP_ToAddModList has %d BWP!\n",
ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
@@ -1205,7 +1257,7 @@ void nr_generate_Msg4(module_id_t module_idP,
nr_mac->TX_req[CC_id].Slot = slotP;
memcpy(tx_req->TLVs[0].value.direct, payload, tx_req->TLVs[0].length);
- // mark the corresponding RBs as used
+ // Mark the corresponding RBs as used
uint16_t *vrb_map = cc[CC_id].vrb_map;
for (int rb = 0; rb < pdsch_pdu_rel15->rbSize; rb++) {
vrb_map[rb + pdsch_pdu_rel15->rbStart] = 1;
@@ -1229,17 +1281,8 @@ void nr_generate_Msg4(module_id_t module_idP,
}
}
-void nr_check_Msg4_Ack(module_id_t module_id,
- int CC_id,
- frame_t frame,
- sub_frame_t slot) {
-
+void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_frame_t slot, NR_RA_t *ra) {
LOG_W(NR_MAC,"nr_check_Msg4_Ack() is not implemented yet!\n");
-
- gNB_MAC_INST *nr_mac = RC.nrmac[module_id];
- NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
- NR_RA_t *ra = &cc->ra[0];
-
ra->state = RA_IDLE;
}
@@ -1247,7 +1290,7 @@ void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP){
NR_RA_t *ra = &RC.nrmac[module_idP]->common_channels[CC_id].ra[0];
LOG_D(MAC,"[gNB %d][RAPROC] CC_id %d Frame %d Clear Random access information rnti %x\n", module_idP, CC_id, frameP, ra->rnti);
- ra->state = IDLE;
+ ra->state = RA_IDLE;
ra->timing_offset = 0;
ra->RRC_timer = 20;
ra->rnti = 0;
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
index 9587e3b0bb..6487f391b9 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
@@ -245,7 +245,9 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
TX_req->PDU_index = nr_mac->pdu_index[CC_id]++;
TX_req->num_TLV = 1;
TX_req->TLVs[0].length = 8;
- memcpy((void*)&TX_req->TLVs[0].value.direct[0],(void*)&cc[CC_id].RAR_pdu.payload[0],TX_req->TLVs[0].length);
+ // why do we copy from RAR_pdu here? Shouldn't we fill some more or less
+ // meaningful data, e.g., padding + random data?
+ //memcpy((void *)&TX_req->TLVs[0].value.direct[0], (void *)&cc[CC_id].RAR_pdu[0].payload[0], TX_req->TLVs[0].length);
nr_mac->TX_req[CC_id].Number_of_PDUs++;
nr_mac->TX_req[CC_id].SFN=frameP;
nr_mac->TX_req[CC_id].Slot=slotP;
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
index f2c75acd22..d9948b64b8 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
@@ -1698,7 +1698,7 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *secon
add_tail_nr_list(&sched_ctrl->available_ul_harq, harq);
create_nr_list(&sched_ctrl->feedback_ul_harq, 16);
create_nr_list(&sched_ctrl->retrans_ul_harq, 16);
- LOG_I(MAC, "gNB %d] Add NR UE_id %d : rnti %x\n",
+ LOG_I(MAC, "[gNB %d] Add NR UE_id %d : rnti %x\n",
mod_idP,
UE_id,
rntiP);
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
index 629b4dc7b0..4c7e063a0f 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
@@ -164,7 +164,7 @@ void compute_csi_bitlen (NR_CellGroupConfig_t *secondaryCellGroup, NR_UE_info_t
UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].diff_rsrp_bitlen =0;
}
- LOG_I (MAC, "UCI: CSI_bit len : ssbri %d, rsrp: %d, diff_rsrp: %d\n",
+ LOG_D (MAC, "UCI: CSI_bit len : ssbri %d, rsrp: %d, diff_rsrp: %d\n",
UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].cri_ssbri_bitlen,
UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].rsrp_bitlen,
UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].diff_rsrp_bitlen);
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
index 0ac10c90d5..b0b6ebbd5a 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
@@ -432,7 +432,8 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
if (sduP != NULL){
LOG_D(NR_MAC, "Received PDU at MAC gNB \n");
- UE_scheduling_control->sched_ul_bytes -= UE_info->mac_stats[UE_id].ulsch_current_bytes;
+ const uint32_t tb_size = UE_scheduling_control->ul_harq_processes[harq_pid].sched_pusch.tb_size;
+ UE_scheduling_control->sched_ul_bytes -= tb_size;
if (UE_scheduling_control->sched_ul_bytes < 0)
UE_scheduling_control->sched_ul_bytes = 0;
@@ -442,7 +443,8 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
NR_UE_ul_harq_t *cur_harq = &UE_scheduling_control->ul_harq_processes[harq_pid];
/* reduce sched_ul_bytes when cur_harq->round == 3 */
if (cur_harq->round == 3){
- UE_scheduling_control->sched_ul_bytes -= UE_info->mac_stats[UE_id].ulsch_current_bytes;
+ const uint32_t tb_size = UE_scheduling_control->ul_harq_processes[harq_pid].sched_pusch.tb_size;
+ UE_scheduling_control->sched_ul_bytes -= tb_size;
if (UE_scheduling_control->sched_ul_bytes < 0)
UE_scheduling_control->sched_ul_bytes = 0;
}
@@ -474,13 +476,14 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
const int UE_id = add_new_nr_ue(gnb_mod_idP, ra->rnti, ra->secondaryCellGroup);
UE_info->UE_beam_index[UE_id] = ra->beam_id;
LOG_I(NR_MAC,
- "[gNB %d][RAPROC] PUSCH with TC_RNTI %x received correctly, "
+ "[gNB %d][RAPROC] PUSCH with TC-RNTI %x received correctly, "
"adding UE MAC Context UE_id %d/RNTI %04x\n",
gnb_mod_idP,
current_rnti,
UE_id,
ra->rnti);
+ LOG_I(NR_MAC,"[RAPROC] RA-Msg3 received\n");
LOG_D(NR_MAC,"[RAPROC] Received Msg3:\n");
for (int k = 0; k < sdu_lenP; k++) {
LOG_D(NR_MAC,"(%i): 0x%x\n",k,sduP[k]);
@@ -494,7 +497,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
ra->state = Msg4;
ra->Msg4_frame = ( frameP +2 ) % 1024;
ra->Msg4_slot = 1;
- LOG_I(MAC, "set RA state to Msg4 for RA-RNTI %04x, msg4 frame %d %d\n", ra->rnti, ra->Msg4_frame, ra->Msg4_slot);
+ LOG_I(MAC, "Scheduling RA-Msg4 for TC-RNTI %04x (state %d, frame %d, slot %d)\n", ra->rnti, ra->state, ra->Msg4_frame, ra->Msg4_slot);
return;
}
}
@@ -867,7 +870,7 @@ void nr_schedule_ulsch(module_id_t module_id,
/* a PDCCH PDU groups DCIs per BWP and CORESET. Save a pointer to each
* allocated PDCCH so we can easily allocate UE's DCIs independent of any
* CORESET order */
- nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_bwp_coreset[MAX_NUM_BWP][MAX_NUM_CORESET] = {0};
+ nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_bwp_coreset[MAX_NUM_BWP][MAX_NUM_CORESET] = {{0}};
NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon;
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
@@ -921,6 +924,7 @@ void nr_schedule_ulsch(module_id_t module_id,
/* Save information on MCS, TBS etc for the current initial transmission
* so we have access to it when retransmitting */
cur_harq->sched_pusch = *sched_pusch;
+ sched_ctrl->sched_ul_bytes += sched_pusch->tb_size;
} else {
LOG_D(MAC,
"%d.%2d UL retransmission RNTI %04x sched %d.%2d HARQ PID %d round %d NDI %d\n",
@@ -934,7 +938,6 @@ void nr_schedule_ulsch(module_id_t module_id,
cur_harq->ndi);
}
UE_info->mac_stats[UE_id].ulsch_current_bytes = sched_pusch->tb_size;
- sched_ctrl->sched_ul_bytes += sched_pusch->tb_size;
LOG_D(MAC,
"%4d.%2d RNTI %04x UL sched %4d.%2d start %d RBS %d MCS %d TBS %d HARQ PID %d round %d NDI %d\n",
diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
index d0131e5cb2..823e374ceb 100644
--- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
@@ -353,20 +353,11 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP,
unsigned char drx_cmd,
unsigned char *ue_cont_res_id);
-void nr_generate_Msg2(module_id_t module_idP,
- int CC_id,
- frame_t frameP,
- sub_frame_t slotP);
+void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra);
-void nr_generate_Msg4(module_id_t module_idP,
- int CC_id,
- frame_t frameP,
- sub_frame_t slotP);
+void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra);
-void nr_check_Msg4_Ack(module_id_t module_id,
- int CC_id,
- frame_t frame,
- sub_frame_t slot);
+void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_frame_t slot, NR_RA_t *ra);
void nr_process_mac_pdu(
module_id_t module_idP,
diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
index bca974a00f..63587d58a4 100644
--- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
+++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
@@ -194,8 +194,6 @@ typedef struct {
uint32_t PCCH_alloc_pdu;
/// Outgoing PCCH pdu for PHY
PCCH_PDU PCCH_pdu;
- /// Outgoing RAR pdu for PHY
- RAR_PDU RAR_pdu;
/// Template for RA computations
NR_RA_t ra[NR_NB_RA_PROC_MAX];
/// VRB map for common channels
@@ -215,6 +213,8 @@ typedef struct {
uint8_t max_association_period;
//SSB index
uint8_t ssb_index[MAX_NUM_OF_SSB];
+ //CB preambles for each SSB
+ uint8_t cb_preambles_per_ssb;
} NR_COMMON_channels_t;
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c
index f3d4b16130..ffc669a461 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c
@@ -22,11 +22,12 @@
#include "nr_pdcp_entity.h"
#include "nr_pdcp_entity_drb_am.h"
+#include "nr_pdcp_security_nea2.h"
#include "LOG/log.h"
nr_pdcp_entity_t *new_nr_pdcp_entity_srb(
- int rb_id,
+ int is_gnb, int rb_id,
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
char *buf, int size),
void *deliver_sdu_data,
@@ -38,7 +39,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_srb(
}
nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am(
- int rb_id,
+ int is_gnb, int rb_id,
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
char *buf, int size),
void *deliver_sdu_data,
@@ -47,7 +48,11 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am(
void *deliver_pdu_data,
int sn_size,
int t_reordering,
- int discard_timer)
+ int discard_timer,
+ int ciphering_algorithm,
+ int integrity_algorithm,
+ unsigned char *ciphering_key,
+ unsigned char *integrity_key)
{
nr_pdcp_entity_drb_am_t *ret;
@@ -76,5 +81,25 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am(
ret->common.maximum_nr_pdcp_sn = (1 << sn_size) - 1;
+ if (ciphering_key != NULL && ciphering_algorithm != 0) {
+ if (ciphering_algorithm != 2) {
+ LOG_E(PDCP, "FATAL: only nea2 supported for the moment\n");
+ exit(1);
+ }
+ ret->common.has_ciphering = 1;
+ ret->common.ciphering_algorithm = ciphering_algorithm;
+ memcpy(ret->common.ciphering_key, ciphering_key, 16);
+
+ ret->common.security_context = nr_pdcp_security_nea2_init(ciphering_key);
+ ret->common.cipher = nr_pdcp_security_nea2_cipher;
+ ret->common.free_security = nr_pdcp_security_nea2_free_security;
+ }
+ ret->common.is_gnb = is_gnb;
+
+ if (integrity_key != NULL) {
+ printf("%s:%d:%s: TODO\n", __FILE__, __LINE__, __FUNCTION__);
+ exit(1);
+ }
+
return (nr_pdcp_entity_t *)ret;
}
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h
index ce5dd300e9..58d79835ec 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h
@@ -42,10 +42,28 @@ typedef struct nr_pdcp_entity_t {
int tx_hfn;
int next_nr_pdcp_tx_sn;
int maximum_nr_pdcp_sn;
+
+ /* security */
+ int has_ciphering;
+ int has_integrity;
+ int ciphering_algorithm;
+ int integrity_algorithm;
+ unsigned char ciphering_key[16];
+ unsigned char integrity_key[16];
+ void *security_context;
+ void (*cipher)(void *security_context,
+ unsigned char *buffer, int length,
+ int bearer, int count, int direction);
+ void (*free_security)(void *security_context);
+ /* security algorithms need to know uplink/downlink information
+ * which is reverse for gnb and ue, so we need to know if this
+ * pdcp entity is for a gnb or an ue
+ */
+ int is_gnb;
} nr_pdcp_entity_t;
nr_pdcp_entity_t *new_nr_pdcp_entity_srb(
- int rb_id,
+ int is_gnb, int rb_id,
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
char *buf, int size),
void *deliver_sdu_data,
@@ -54,7 +72,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_srb(
void *deliver_pdu_data);
nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am(
- int rb_id,
+ int is_gnb, int rb_id,
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
char *buf, int size),
void *deliver_sdu_data,
@@ -63,7 +81,11 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am(
void *deliver_pdu_data,
int sn_size,
int t_reordering,
- int discard_timer);
+ int discard_timer,
+ int ciphering_algorithm,
+ int integrity_algorithm,
+ unsigned char *ciphering_key,
+ unsigned char *integrity_key);
void nr_DRB_preconfiguration(uint16_t crnti);
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c
index f2f849b9e3..62881c184e 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c
@@ -29,12 +29,21 @@
void nr_pdcp_entity_drb_am_recv_pdu(nr_pdcp_entity_t *_entity, char *buffer, int size)
{
nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity;
+ int sn;
if (size < 3) abort();
if (!(buffer[0] & 0x80))
LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
+ sn = (((unsigned char)buffer[0] & 0x3) << 16) |
+ ((unsigned char)buffer[1] << 8) |
+ (unsigned char)buffer[2];
+
+ if (entity->common.has_ciphering)
+ entity->common.cipher(entity->common.security_context, (unsigned char *)buffer+3, size-3,
+ entity->rb_id, sn, entity->common.is_gnb ? 0 : 1);
+
entity->common.deliver_sdu(entity->common.deliver_sdu_data,
(nr_pdcp_entity_t *)entity, buffer+3, size-3);
}
@@ -59,6 +68,10 @@ void nr_pdcp_entity_drb_am_recv_sdu(nr_pdcp_entity_t *_entity, char *buffer, int
buf[2] = sn & 0xff;
memcpy(buf+3, buffer, size);
+ if (entity->common.has_ciphering)
+ entity->common.cipher(entity->common.security_context, (unsigned char *)buf+3, size,
+ entity->rb_id, sn, entity->common.is_gnb ? 1 : 0);
+
entity->common.deliver_pdu(entity->common.deliver_pdu_data,
(nr_pdcp_entity_t *)entity, buf, size+3, sdu_id);
}
@@ -71,5 +84,7 @@ void nr_pdcp_entity_drb_am_set_integrity_key(nr_pdcp_entity_t *_entity, char *ke
void nr_pdcp_entity_drb_am_delete(nr_pdcp_entity_t *_entity)
{
nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity;
+ if (entity->common.free_security != NULL)
+ entity->common.free_security(entity->common.security_context);
free(entity);
}
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
index 6195a91ea2..f14d25b145 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
@@ -591,7 +591,11 @@ static void add_srb(int rnti, struct NR_SRB_ToAddMod *s)
TODO;
}
-static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s)
+static void add_drb_am(int is_gnb, int rnti, struct NR_DRB_ToAddMod *s,
+ int ciphering_algorithm,
+ int integrity_algorithm,
+ unsigned char *ciphering_key,
+ unsigned char *integrity_key)
{
nr_pdcp_entity_t *pdcp_drb;
nr_pdcp_ue_t *ue;
@@ -621,8 +625,11 @@ static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s)
LOG_D(PDCP, "%s:%d:%s: warning DRB %d already exist for ue %d, do nothing\n",
__FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
} else {
- pdcp_drb = new_nr_pdcp_entity_drb_am(drb_id, deliver_sdu_drb, ue, deliver_pdu_drb, ue,
- sn_size_dl, t_reordering, discard_timer);
+ pdcp_drb = new_nr_pdcp_entity_drb_am(is_gnb, drb_id,
+ deliver_sdu_drb, ue, deliver_pdu_drb, ue,
+ sn_size_dl, t_reordering, discard_timer,
+ ciphering_algorithm, integrity_algorithm,
+ ciphering_key, integrity_key);
nr_pdcp_ue_add_drb_pdcp_entity(ue, drb_id, pdcp_drb);
LOG_D(PDCP, "%s:%d:%s: added drb %d to ue rnti %x\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
@@ -630,16 +637,23 @@ static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s)
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
}
-static void add_drb(int rnti, struct NR_DRB_ToAddMod *s, NR_RLC_Config_t *rlc_Config)
+static void add_drb(int is_gnb, int rnti, struct NR_DRB_ToAddMod *s,
+ NR_RLC_Config_t *rlc_Config,
+ int ciphering_algorithm,
+ int integrity_algorithm,
+ unsigned char *ciphering_key,
+ unsigned char *integrity_key)
{
switch (rlc_Config->present) {
case NR_RLC_Config_PR_am:
- add_drb_am(rnti, s);
+ add_drb_am(is_gnb, rnti, s, ciphering_algorithm, integrity_algorithm,
+ ciphering_key, integrity_key);
break;
case NR_RLC_Config_PR_um_Bi_Directional:
//add_drb_um(rnti, s);
/* hack */
- add_drb_am(rnti, s);
+ add_drb_am(is_gnb, rnti, s, ciphering_algorithm, integrity_algorithm,
+ ciphering_key, integrity_key);
break;
default:
LOG_E(PDCP, "%s:%d:%s: fatal: unhandled DRB type\n",
@@ -657,7 +671,8 @@ boolean_t nr_rrc_pdcp_config_asn1_req(
const uint8_t security_modeP,
uint8_t *const kRRCenc,
uint8_t *const kRRCint,
- uint8_t *const kUPenc
+ uint8_t *const kUPenc,
+ uint8_t *const kUPint
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9
#endif
@@ -676,7 +691,7 @@ boolean_t nr_rrc_pdcp_config_asn1_req(
//srb2add_list == NULL ||
//drb2add_list != NULL ||
drb2release_list != NULL ||
- security_modeP != 255 ||
+ //security_modeP != 255 ||
//kRRCenc != NULL ||
//kRRCint != NULL ||
//kUPenc != NULL ||
@@ -693,7 +708,10 @@ boolean_t nr_rrc_pdcp_config_asn1_req(
if (drb2add_list != NULL) {
for (i = 0; i < drb2add_list->list.count; i++) {
- add_drb(rnti, drb2add_list->list.array[i], rlc_bearer2add_list->list.array[i]->rlc_Config);
+ add_drb(ctxt_pP->enb_flag, rnti, drb2add_list->list.array[i],
+ rlc_bearer2add_list->list.array[i]->rlc_Config,
+ security_modeP & 0x0f, (security_modeP >> 4) & 0x0f,
+ kUPenc, kUPint);
}
}
@@ -705,6 +723,7 @@ boolean_t nr_rrc_pdcp_config_asn1_req(
free(kRRCenc);
free(kRRCint);
free(kUPenc);
+ free(kUPint);
return 0;
}
@@ -805,6 +824,7 @@ void nr_DRB_preconfiguration(uint16_t crnti)
NULL,
NULL,
NULL,
+ NULL,
Rlc_Bearer_ToAdd_list);
nr_rrc_rlc_config_asn1_req (&ctxt,
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c
new file mode 100644
index 0000000000..fc07f661dd
--- /dev/null
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ * contact@openairinterface.org
+ */
+
+#include "nr_pdcp_security_nea2.h"
+
+#include
+#include
+#include
+#include
+#include
+
+void *nr_pdcp_security_nea2_init(unsigned char *ciphering_key)
+{
+ void *ctx = calloc(1, nettle_aes128.context_size);
+ if (ctx == NULL) exit(1);
+
+#if NETTLE_VERSION_MAJOR < 3
+ nettle_aes128.set_encrypt_key(ctx, 16, ciphering_key);
+#else
+ nettle_aes128.set_encrypt_key(ctx, ciphering_key);
+#endif
+
+ return ctx;
+}
+
+void nr_pdcp_security_nea2_cipher(void *security_context,
+ unsigned char *buffer, int length,
+ int bearer, int count, int direction)
+{
+ unsigned char t[16];
+
+ t[0] = (count >> 24) & 255;
+ t[1] = (count >> 16) & 255;
+ t[2] = (count >> 8) & 255;
+ t[3] = (count ) & 255;
+ t[4] = ((bearer-1) << 3) | (direction << 2);
+ memset(&t[5], 0, 16-5);
+
+ nettle_ctr_crypt(security_context, nettle_aes128.encrypt,
+ nettle_aes128.block_size, t,
+ length, buffer, buffer);
+}
+
+void nr_pdcp_security_nea2_free_security(void *security_context)
+{
+ free(security_context);
+}
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.h
new file mode 100644
index 0000000000..c3667c93d4
--- /dev/null
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.h
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ * contact@openairinterface.org
+ */
+
+#ifndef _NR_PDCP_SECURITY_NEA2_H_
+#define _NR_PDCP_SECURITY_NEA2_H_
+
+void *nr_pdcp_security_nea2_init(unsigned char *ciphering_key);
+
+void nr_pdcp_security_nea2_cipher(void *security_context,
+ unsigned char *buffer, int length,
+ int bearer, int count, int direction);
+
+void nr_pdcp_security_nea2_free_security(void *security_context);
+
+#endif /* _NR_PDCP_SECURITY_NEA2_H_ */
diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c
index b183b32aab..63cc0cf0de 100644
--- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c
+++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c
@@ -56,7 +56,7 @@ extern uint16_t sl_ahead;
void handle_nr_rach(NR_UL_IND_t *UL_info) {
if (UL_info->rach_ind.number_of_pdus>0) {
- LOG_I(MAC,"UL_info[Frame %d, Slot %d] Calling initiate_ra_proc RACH:SFN/SLOT:%d/%d\n",UL_info->frame,UL_info->slot, UL_info->rach_ind.sfn,UL_info->rach_ind.slot);
+ LOG_D(MAC,"UL_info[Frame %d, Slot %d] Calling initiate_ra_proc RACH:SFN/SLOT:%d/%d\n",UL_info->frame,UL_info->slot, UL_info->rach_ind.sfn,UL_info->rach_ind.slot);
int npdus = UL_info->rach_ind.number_of_pdus;
for(int i = 0; i < npdus; i++) {
UL_info->rach_ind.number_of_pdus--;
diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h
index 7602e9ca64..4f55f94121 100644
--- a/openair2/RRC/LTE/rrc_defs.h
+++ b/openair2/RRC/LTE/rrc_defs.h
@@ -546,6 +546,13 @@ typedef struct rrc_gummei_s {
uint16_t mme_group_id;
} rrc_gummei_t;
+typedef struct {
+ uint16_t ciphering_algorithms;
+ uint16_t integrity_algorithms;
+ uint16_t sk_counter;
+ uint8_t kgNB[32];
+} lte_rrc_nr_security_t;
+
typedef struct eNB_RRC_UE_s {
uint8_t primaryCC_id;
LTE_SCellToAddMod_r10_t sCell_config[2];
@@ -615,6 +622,9 @@ typedef struct eNB_RRC_UE_s {
security_capabilities_t security_capabilities;
+ /* security capabilities and settings for an UE in ENDC mode */
+ lte_rrc_nr_security_t nr_security;
+
int next_hop_chain_count;
uint8_t next_security_key[SECURITY_KEY_LENGTH];
diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c
index 6d39fb2221..526ce129b1 100644
--- a/openair2/RRC/LTE/rrc_eNB.c
+++ b/openair2/RRC/LTE/rrc_eNB.c
@@ -4426,69 +4426,11 @@ static int encode_CG_ConfigInfo(
struct NR_RadioBearerConfig *rb_config = NULL;
asn_enc_rval_t enc_rval;
int RRC_OK = 1;
- int index = 0;
char temp_buff[ASN_MAX_ENCODE_SIZE];
NR_UE_CapabilityRAT_ContainerList_t *ue_cap_rat_container_list = NULL;
NR_UE_CapabilityRAT_Container_t *ue_cap_rat_container_MRDC = NULL;
NR_UE_CapabilityRAT_Container_t *ue_cap_rat_container_nr = NULL;
int RAT_Container_count = 0;
- rb_config = calloc(1,sizeof(struct NR_RadioBearerConfig));
- AssertFatal(rb_config != NULL,"failed to allocate memory for rb_config");
-
- if(ue_context_pP->ue_context.DRB_configList->list.count != 0) {
- rb_config->drb_ToAddModList = calloc(1,sizeof(struct NR_DRB_ToAddModList ));
- AssertFatal(rb_config->drb_ToAddModList != NULL,"failed to allocated memory for drbtoaddmodlist");
- rb_config->drb_ToAddModList->list.count = NUMBEROF_DRBS_TOBE_ADDED;
- rb_config->drb_ToAddModList->list.array
- = calloc(NUMBEROF_DRBS_TOBE_ADDED, sizeof(struct NR_DRB_ToAddMod *));
- AssertFatal( rb_config->drb_ToAddModList->list.array != NULL,
- "falied to allocate memory for list.array");
-
- for(index = 0; index < NUMBEROF_DRBS_TOBE_ADDED; index++) {
- rb_config->drb_ToAddModList->list.array[index]
- = calloc(1,sizeof(struct NR_DRB_ToAddMod));
- AssertFatal(rb_config->drb_ToAddModList->list.array[index] != NULL,
- "failed to allocate memory for drb_toaddmod");
- rb_config->drb_ToAddModList->list.array[index]->drb_Identity
- = ue_context_pP->ue_context.DRB_configList->list.array[index]->drb_Identity;
-
- if(ue_context_pP->ue_context.DRB_configList->list.array[index]->eps_BearerIdentity) {
- rb_config->drb_ToAddModList->list.array[index]->cnAssociation
- = calloc(1,sizeof(struct NR_DRB_ToAddMod__cnAssociation));
- AssertFatal(rb_config->drb_ToAddModList->list.array[index]->cnAssociation != NULL,
- "failed to allocate memory cnAssociation");
- rb_config->drb_ToAddModList->list.array[index]->cnAssociation->present
- = NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity;
- rb_config->drb_ToAddModList->list.array[index]->cnAssociation->choice.eps_BearerIdentity
- = *(ue_context_pP->ue_context.DRB_configList->list.array[index]->eps_BearerIdentity);
- }
-
- rb_config->drb_ToAddModList->list.array[index]->pdcp_Config = calloc(1,sizeof(struct NR_PDCP_Config));
- rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb = calloc(1,sizeof(struct NR_PDCP_Config__drb));
- rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->discardTimer = calloc(1,sizeof(long));
- *rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->discardTimer
- = *(ue_context_pP->ue_context.DRB_configList->list.array[index]->pdcp_Config->discardTimer);
- rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->pdcp_SN_SizeUL = calloc(1,sizeof(long));
- *rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->pdcp_SN_SizeUL
- = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits;
- rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->pdcp_SN_SizeDL = calloc(1,sizeof(long));
- *rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->pdcp_SN_SizeDL
- = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits;
- rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->headerCompression.present
- = NR_PDCP_Config__drb__headerCompression_PR_notUsed;
- rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->headerCompression.choice.notUsed = 0;
- rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->t_Reordering = calloc(1,sizeof(long));
- *rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->t_Reordering
- = NR_PDCP_Config__t_Reordering_ms0;
- }
-
- rb_config->securityConfig = calloc(1,sizeof(struct NR_SecurityConfig ));
- rb_config->securityConfig->securityAlgorithmConfig = calloc(1,sizeof(struct NR_SecurityAlgorithmConfig));
- rb_config->securityConfig->securityAlgorithmConfig->cipheringAlgorithm = NR_CipheringAlgorithm_nea0;
- rb_config->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm = NULL;
- rb_config->securityConfig->keyToUse = calloc(1,sizeof(long));
- *rb_config->securityConfig->keyToUse = NR_SecurityConfig__keyToUse_master;
- }
cg_configinfo = calloc(1,sizeof(struct NR_CG_ConfigInfo));
AssertFatal(cg_configinfo != NULL,"failed to allocate memory for cg_configinfo");
@@ -4548,15 +4490,6 @@ static int encode_CG_ConfigInfo(
(const char *)temp_buff, (enc_rval.encoded+7)>>3);
}
- cg_configinfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo->mcg_RB_Config
- = calloc(1,sizeof(OCTET_STRING_t));
- AssertFatal(cg_configinfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo->
- mcg_RB_Config != NULL, "failed to allocate memory for mcg_rb_config");
- enc_rval = uper_encode_to_buffer(&asn_DEF_NR_RadioBearerConfig,NULL,(void *)rb_config,temp_buff,ASN_MAX_ENCODE_SIZE);
- AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n",
- enc_rval.failed_type->name, enc_rval.encoded);
- OCTET_STRING_fromBuf(cg_configinfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo->mcg_RB_Config,
- (const char *)temp_buff, (enc_rval.encoded+7)>>3);
// this xer_fprint can be enabled for additional debugging messages
// xer_fprint(stdout,&asn_DEF_NR_CG_ConfigInfo,(void *)cg_configinfo);
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CG_ConfigInfo,NULL,(void *)cg_configinfo,
@@ -4665,11 +4598,20 @@ rrc_eNB_process_MeasurementReport(
msg = itti_alloc_new_message(TASK_RRC_ENB, 0, X2AP_ENDC_SGNB_ADDITION_REQ);
memset(&(X2AP_ENDC_SGNB_ADDITION_REQ(msg)), 0, sizeof(x2ap_ENDC_sgnb_addition_req_t));
+
X2AP_ENDC_SGNB_ADDITION_REQ(msg).rnti = ctxt_pP->rnti;
+
+ X2AP_ENDC_SGNB_ADDITION_REQ(msg).security_capabilities.encryption_algorithms = ue_context_pP->ue_context.nr_security.ciphering_algorithms;
+ X2AP_ENDC_SGNB_ADDITION_REQ(msg).security_capabilities.integrity_algorithms = ue_context_pP->ue_context.nr_security.integrity_algorithms;
+
+ memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).kgnb, ue_context_pP->ue_context.nr_security.kgNB, 32);
+
memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer,enc_buf,enc_size);
X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer_size = enc_size;
+
X2AP_ENDC_SGNB_ADDITION_REQ(msg).target_physCellId
= measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[0]->physCellId;
+
//For the moment we have a single E-RAB which will be the one to be added to the gNB
//Not sure how to select bearers to be added if there are multiple.
X2AP_ENDC_SGNB_ADDITION_REQ(msg).nb_e_rabs_tobeadded = 1;
diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c
index 320004a361..d34b4164a2 100644
--- a/openair2/RRC/LTE/rrc_eNB_S1AP.c
+++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c
@@ -1045,6 +1045,15 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char
}
}
+ ue_context_p->ue_context.nr_security.ciphering_algorithms = S1AP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nr_security_capabilities.encryption_algorithms;
+ ue_context_p->ue_context.nr_security.integrity_algorithms = S1AP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nr_security_capabilities.integrity_algorithms;
+ /* let's initialize sk_counter to 0 */
+ ue_context_p->ue_context.nr_security.sk_counter = 0;
+ /* let's compute kgNB */
+ derive_skgNB(ue_context_p->ue_context.kenb,
+ ue_context_p->ue_context.nr_security.sk_counter,
+ ue_context_p->ue_context.nr_security.kgNB);
+
// in case, send the S1SP initial context response if it is not sent with the attach complete message
if (ue_context_p->ue_context.Status == RRC_RECONFIGURED) {
LOG_I(RRC, "Sending rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP, cause %ld\n", ue_context_p->ue_context.reestablishment_cause);
diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h
index c53d44983c..36d9bdee60 100644
--- a/openair2/RRC/NR/nr_rrc_defs.h
+++ b/openair2/RRC/NR/nr_rrc_defs.h
@@ -447,6 +447,15 @@ typedef struct {
//---------------------------------------------------
+typedef struct {
+ /* nea0 = 0, nea1 = 1, ... */
+ int ciphering_algorithms[4];
+ int ciphering_algorithms_count;
+
+ /* nia0 = 0, nia1 = 1, ... */
+ int integrity_algorithms[4];
+ int integrity_algorithms_count;
+} nr_security_configuration_t;
//---NR---(completely change)---------------------
typedef struct gNB_RRC_INST_s {
@@ -479,6 +488,8 @@ typedef struct gNB_RRC_INST_s {
int srb1_timer_status_prohibit;
int srs_enable[MAX_NUM_CCs];
+ // security configuration (preferred algorithms)
+ nr_security_configuration_t security;
} gNB_RRC_INST;
#include "nr_rrc_proto.h" //should be put here otherwise compilation error
diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h
index 9b7d734e2c..6d876a0eef 100644
--- a/openair2/RRC/NR/nr_rrc_proto.h
+++ b/openair2/RRC/NR/nr_rrc_proto.h
@@ -39,6 +39,7 @@
#include "LTE_UE-CapabilityRAT-ContainerList.h"
#include "NR_CG-Config.h"
#include "NR_CG-ConfigInfo.h"
+#include "NR_SecurityConfig.h"
int rrc_init_nr_global_param(void);
@@ -90,7 +91,10 @@ void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon
int n_physical_antenna_ports,
int initial_csi_index);
-void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig);
+void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig,
+ int eps_bearer_id, int rb_id,
+ e_NR_CipheringAlgorithm ciphering_algorithm,
+ e_NR_SecurityConfig__keyToUse key_to_use);
int generate_CG_Config(gNB_RRC_INST *rrc,
NR_CG_Config_t *cg_Config,
diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c
index abf85a805b..6d430d7223 100755
--- a/openair2/RRC/NR/rrc_gNB.c
+++ b/openair2/RRC/NR/rrc_gNB.c
@@ -103,7 +103,8 @@ extern boolean_t nr_rrc_pdcp_config_asn1_req(
const uint8_t security_modeP,
uint8_t *const kRRCenc,
uint8_t *const kRRCint,
- uint8_t *const kUPenc
+ uint8_t *const kUPenc,
+ uint8_t *const kUPint
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9
#endif
@@ -887,6 +888,7 @@ rrc_gNB_process_RRCReconfigurationComplete(
kUPenc,
NULL,
NULL,
+ NULL,
NULL);
/* Refresh SRBs/DRBs */
nr_rrc_rlc_config_asn1_req(ctxt_pP,
@@ -1702,6 +1704,7 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP,
// NULL,
// NULL,
// NULL,
+ // NULL,
// NULL);
// if (!NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)) {
diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c
index 39dc5ca2d8..4e09f46c36 100644
--- a/openair2/RRC/NR/rrc_gNB_nsa.c
+++ b/openair2/RRC/NR/rrc_gNB_nsa.c
@@ -39,6 +39,7 @@
#include "openair2/RRC/LTE/rrc_eNB_GTPV1U.h"
#include "executables/softmodem-common.h"
#include
+#include "UTIL/OSA/osa_defs.h"
extern boolean_t nr_rrc_pdcp_config_asn1_req(
const protocol_ctxt_t *const ctxt_pP,
@@ -48,7 +49,8 @@ extern boolean_t nr_rrc_pdcp_config_asn1_req(
const uint8_t security_modeP,
uint8_t *const kRRCenc,
uint8_t *const kRRCint,
- uint8_t *const kUPenc
+ uint8_t *const kUPenc,
+ uint8_t *const kUPint
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9
#endif
@@ -115,28 +117,14 @@ void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc, NR_UE_CapabilityRAT_ContainerL
// dump ue_capabilities
- if ( LOG_DEBUGFLAG(DEBUG_ASN1 && ueCapabilityRAT_Container_nr != NULL) ) {
+ if ( LOG_DEBUGFLAG(DEBUG_ASN1) && ueCapabilityRAT_Container_nr != NULL ) {
xer_fprint(stdout, &asn_DEF_NR_UE_NR_Capability, ue_context_p->ue_context.UE_Capability_nr);
}
- if ( LOG_DEBUGFLAG(DEBUG_ASN1 && ueCapabilityRAT_Container_MRDC != NULL) ) {
+ if ( LOG_DEBUGFLAG(DEBUG_ASN1) && ueCapabilityRAT_Container_MRDC != NULL ) {
xer_fprint(stdout, &asn_DEF_NR_UE_MRDC_Capability, ue_context_p->ue_context.UE_Capability_MRDC);
}
- if(cg_config_info && cg_config_info->mcg_RB_Config) {
- asn_dec_rval_t dec_rval = uper_decode(NULL,
- &asn_DEF_NR_RadioBearerConfig,
- (void **)&ue_context_p->ue_context.rb_config,
- cg_config_info->mcg_RB_Config->buf,
- cg_config_info->mcg_RB_Config->size, 0, 0);
-
- if((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
- AssertFatal(1==0,"[InterNode] Failed to decode mcg_rb_config (%zu bits), size of OCTET_STRING %lu\n",
- dec_rval.consumed, cg_config_info->mcg_RB_Config->size);
- }
- }
-
- xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void *)ue_context_p->ue_context.rb_config);
rrc_add_nsa_user(rrc,ue_context_p, m);
}
@@ -152,6 +140,8 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
gtpv1u_enb_create_tunnel_req_t create_tunnel_req;
gtpv1u_enb_create_tunnel_resp_t create_tunnel_resp;
protocol_ctxt_t ctxt={0};
+ unsigned char *kUPenc = NULL;
+ int i;
// NR RRCReconfiguration
AssertFatal(rrc->Nb_ue < MAX_NR_RRC_UE_CONTEXTS,"cannot add another UE\n");
ue_context_p->ue_context.reconfig = calloc(1,sizeof(NR_RRCReconfiguration_t));
@@ -162,9 +152,91 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
NR_RRCReconfiguration_IEs_t *reconfig_ies=calloc(1,sizeof(NR_RRCReconfiguration_IEs_t));
ue_context_p->ue_context.reconfig->criticalExtensions.choice.rrcReconfiguration = reconfig_ies;
carrier->initial_csi_index[rrc->Nb_ue] = 0;
+ ue_context_p->ue_context.rb_config = calloc(1,sizeof(NR_RRCReconfiguration_t));
if (get_softmodem_params()->phy_test == 1 || get_softmodem_params()->do_ra == 1 || get_softmodem_params()->sa == 1){
- ue_context_p->ue_context.rb_config = calloc(1,sizeof(NR_RRCReconfiguration_t));
- fill_default_rbconfig(ue_context_p->ue_context.rb_config);
+ fill_default_rbconfig(ue_context_p->ue_context.rb_config,
+ 5 /* EPS bearer ID */,
+ 1 /* drb ID */,
+ NR_CipheringAlgorithm_nea0,
+ NR_SecurityConfig__keyToUse_master);
+ } else {
+ /* TODO: handle more than one bearer */
+ if (m == NULL) {
+ LOG_E(RRC, "fatal: m==NULL\n");
+ exit(1);
+ }
+ if (m->nb_e_rabs_tobeadded != 1) {
+ LOG_E(RRC, "fatal: m->nb_e_rabs_tobeadded = %d, should be 1\n", m->nb_e_rabs_tobeadded);
+ exit(1);
+ }
+
+ /* store security key and security capabilities */
+ memcpy(ue_context_p->ue_context.kgnb, m->kgnb, 32);
+ ue_context_p->ue_context.security_capabilities.nRencryption_algorithms = m->security_capabilities.encryption_algorithms;
+ ue_context_p->ue_context.security_capabilities.nRintegrity_algorithms = m->security_capabilities.integrity_algorithms;
+
+ /* Select ciphering algorithm based on gNB configuration file and
+ * UE's supported algorithms.
+ * We take the first from the list that is supported by the UE.
+ * The ordering of the list comes from the configuration file.
+ */
+ /* preset nea0 as fallback */
+ ue_context_p->ue_context.ciphering_algorithm = 0;
+ for (i = 0; i < rrc->security.ciphering_algorithms_count; i++) {
+ int nea_mask[4] = {
+ 0,
+ 0x8000, /* nea1 */
+ 0x4000, /* nea2 */
+ 0x2000 /* nea3 */
+ };
+ if (rrc->security.ciphering_algorithms[i] == 0) {
+ /* nea0 already preselected */
+ break;
+ }
+ if (ue_context_p->ue_context.security_capabilities.nRencryption_algorithms & nea_mask[rrc->security.ciphering_algorithms[i]]) {
+ ue_context_p->ue_context.ciphering_algorithm = rrc->security.ciphering_algorithms[i];
+ break;
+ }
+ }
+
+ LOG_I(RRC, "selecting ciphering algorithm %d\n", (int)ue_context_p->ue_context.ciphering_algorithm);
+
+ /* integrity: no integrity protection for DRB in ENDC mode
+ * as written in 38.331: "If UE is connected to E-UTRA/EPC, this field
+ * indicates the integrity protection algorithm to be used for SRBs
+ * configured with NR PDCP, as specified in TS 33.501"
+ * So nothing for DRB. Plus a test with a COTS UE revealed that it
+ * did not apply integrity on the DRB.
+ */
+ ue_context_p->ue_context.integrity_algorithm = 0;
+
+ LOG_I(RRC, "selecting integrity algorithm %d\n", ue_context_p->ue_context.integrity_algorithm);
+
+ /* derive UP security key */
+ unsigned char *kUPenc_kdf;
+ nr_derive_key_up_enc(ue_context_p->ue_context.ciphering_algorithm,
+ ue_context_p->ue_context.kgnb,
+ &kUPenc_kdf);
+ /* kUPenc: last 128 bits of key derivation function which returns 256 bits */
+ kUPenc = malloc(16);
+ if (kUPenc == NULL) exit(1);
+ memcpy(kUPenc, kUPenc_kdf+16, 16);
+ free(kUPenc_kdf);
+
+ e_NR_CipheringAlgorithm cipher_algo;
+ switch (ue_context_p->ue_context.ciphering_algorithm) {
+ case 0: cipher_algo = NR_CipheringAlgorithm_nea0; break;
+ case 1: cipher_algo = NR_CipheringAlgorithm_nea1; break;
+ case 2: cipher_algo = NR_CipheringAlgorithm_nea2; break;
+ case 3: cipher_algo = NR_CipheringAlgorithm_nea3; break;
+ default: LOG_E(RRC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); exit(1);
+ }
+
+ fill_default_rbconfig(ue_context_p->ue_context.rb_config,
+ m->e_rabs_tobeadded[0].e_rab_id,
+ m->e_rabs_tobeadded[0].drb_ID,
+ cipher_algo,
+ NR_SecurityConfig__keyToUse_secondary);
}
fill_default_reconfig(carrier->servingcellconfigcommon,
reconfig_ies,
@@ -285,10 +357,11 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
(NR_SRB_ToAddModList_t *) NULL,
ue_context_p->ue_context.rb_config->drb_ToAddModList ,
ue_context_p->ue_context.rb_config->drb_ToReleaseList,
- 0xff,
- NULL,
- NULL,
- NULL,
+ (ue_context_p->ue_context.integrity_algorithm << 4) | ue_context_p->ue_context.ciphering_algorithm,
+ NULL, /* kRRCenc - unused */
+ NULL, /* kRRCint - unused */
+ kUPenc, /* kUPenc */
+ NULL, /* kUPint - unused */
NULL,
NULL,
ue_context_p->ue_context.secondaryCellGroup->rlc_BearerToAddModList);
diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c
index 95dcfcc3e8..051352590a 100644
--- a/openair2/RRC/NR/rrc_gNB_reconfig.c
+++ b/openair2/RRC/NR/rrc_gNB_reconfig.c
@@ -1334,7 +1334,10 @@ void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon
reconfig->nonCriticalExtension = NULL;
}
-void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig) {
+void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig,
+ int eps_bearer_id, int rb_id,
+ e_NR_CipheringAlgorithm ciphering_algorithm,
+ e_NR_SecurityConfig__keyToUse key_to_use) {
rbconfig->srb_ToAddModList = NULL;
rbconfig->srb3_ToRelease = NULL;
@@ -1342,8 +1345,8 @@ void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig) {
NR_DRB_ToAddMod_t *drb_ToAddMod = calloc(1,sizeof(*drb_ToAddMod));
drb_ToAddMod->cnAssociation = calloc(1,sizeof(*drb_ToAddMod->cnAssociation));
drb_ToAddMod->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity;
- drb_ToAddMod->cnAssociation->choice.eps_BearerIdentity= 5;
- drb_ToAddMod->drb_Identity = 1;
+ drb_ToAddMod->cnAssociation->choice.eps_BearerIdentity= eps_bearer_id;
+ drb_ToAddMod->drb_Identity = rb_id;
drb_ToAddMod->reestablishPDCP = NULL;
drb_ToAddMod->recoverPDCP = NULL;
drb_ToAddMod->pdcp_Config = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config));
@@ -1372,12 +1375,12 @@ void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig) {
rbconfig->securityConfig = calloc(1,sizeof(*rbconfig->securityConfig));
rbconfig->securityConfig->securityAlgorithmConfig = calloc(1,sizeof(*rbconfig->securityConfig->securityAlgorithmConfig));
- rbconfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm = NR_CipheringAlgorithm_nea0;
+ rbconfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm = ciphering_algorithm;
rbconfig->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm=NULL;
rbconfig->securityConfig->keyToUse = calloc(1,sizeof(*rbconfig->securityConfig->keyToUse));
- *rbconfig->securityConfig->keyToUse = NR_SecurityConfig__keyToUse_master;
+ *rbconfig->securityConfig->keyToUse = key_to_use;
- xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void*)rbconfig);
+// xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void*)rbconfig);
}
/* Function to set or overwrite PTRS DL RRC parameters */
void rrc_config_dl_ptrs_params(NR_BWP_Downlink_t *bwp, int *ptrsNrb, int *ptrsMcs, int *epre_Ratio, int * reOffset)
diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c
index b398ca7ce8..f373d74230 100644
--- a/openair2/RRC/NR_UE/rrc_UE.c
+++ b/openair2/RRC/NR_UE/rrc_UE.c
@@ -186,7 +186,8 @@ extern boolean_t nr_rrc_pdcp_config_asn1_req(
const uint8_t security_modeP,
uint8_t *const kRRCenc,
uint8_t *const kRRCint,
- uint8_t *const kUPenc
+ uint8_t *const kUPenc,
+ uint8_t *const kUPint
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9
#endif
@@ -1999,6 +2000,7 @@ nr_sa_rrc_ue_process_radioBearerConfig(
// NULL,
// NULL,
// NULL,
+ // NULL,
// NULL);
// Refresh SRBs
// nr_rrc_rlc_config_asn1_req(ctxt_pP,
@@ -2090,6 +2092,7 @@ nr_sa_rrc_ue_process_radioBearerConfig(
// NULL,
// kUPenc,
// NULL,
+ // NULL,
// NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB,
// NULL);
// Refresh DRBs
diff --git a/openair2/UTIL/OSA/osa_defs.h b/openair2/UTIL/OSA/osa_defs.h
index 304dd07042..6334658683 100644
--- a/openair2/UTIL/OSA/osa_defs.h
+++ b/openair2/UTIL/OSA/osa_defs.h
@@ -53,6 +53,8 @@ typedef enum {
//int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t **keNB);
+int derive_skgNB(const uint8_t *keNB, const uint16_t sk_counter, uint8_t *skgNB);
+
int derive_key(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id,
const uint8_t key[32], uint8_t **out);
int nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id,
diff --git a/openair2/UTIL/OSA/osa_key_deriver.c b/openair2/UTIL/OSA/osa_key_deriver.c
index 71c7793fa0..159ee7f159 100644
--- a/openair2/UTIL/OSA/osa_key_deriver.c
+++ b/openair2/UTIL/OSA/osa_key_deriver.c
@@ -159,3 +159,27 @@ int derive_keNB(const uint8_t key[32], const uint32_t nas_count, uint8_t **keNB)
return 0;
}
*/
+
+int derive_skgNB(const uint8_t *keNB, const uint16_t sk_counter, uint8_t *skgNB)
+{
+ uint8_t *out;
+ uint8_t s[5];
+
+ /* FC is 0x1c (see 3gpp 33.401 annex A.15) */
+ s[0] = 0x1c;
+
+ /* put sk_counter */
+ s[1] = (sk_counter >> 8) & 0xff;
+ s[2] = sk_counter & 0xff;
+
+ /* put length of sk_counter (2) */
+ s[3] = 0x00;
+ s[4] = 0x02;
+
+ kdf(s, 5, keNB, 32, &out, 32);
+
+ memcpy(skgNB, out, 32);
+ free(out);
+
+ return 0;
+}
diff --git a/openair3/S1AP/s1ap_eNB_handlers.c b/openair3/S1AP/s1ap_eNB_handlers.c
index 7c233d9e14..370d34868b 100644
--- a/openair3/S1AP/s1ap_eNB_handlers.c
+++ b/openair3/S1AP/s1ap_eNB_handlers.c
@@ -864,22 +864,36 @@ int s1ap_eNB_handle_initial_context_request(uint32_t assoc_id,
BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.encryptionAlgorithms);
S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_capabilities.integrity_algorithms =
BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.integrityProtectionAlgorithms);
- /* id-SecurityKey : Copy the security key */
} else {/* ie != NULL */
return -1;
}
+ /* id-SecurityKey : Copy the security key */
S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_InitialContextSetupRequestIEs_t, ie, container,
S1AP_ProtocolIE_ID_id_SecurityKey, true);
if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */
memcpy(&S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_key,
ie->value.choice.SecurityKey.buf, ie->value.choice.SecurityKey.size);
- itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p);
} else {/* ie != NULL */
return -1;
}
+ /* id-NRUESecurityCapabilities */
+ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_InitialContextSetupRequestIEs_t, ie, container,
+ S1AP_ProtocolIE_ID_id_NRUESecurityCapabilities, false);
+ if (ie != NULL) {
+ S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nr_security_capabilities.encryption_algorithms =
+ BIT_STRING_to_uint16(&ie->value.choice.NRUESecurityCapabilities.nRencryptionAlgorithms);
+ S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nr_security_capabilities.integrity_algorithms =
+ BIT_STRING_to_uint16(&ie->value.choice.NRUESecurityCapabilities.nRintegrityProtectionAlgorithms);
+ } else {
+ S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nr_security_capabilities.encryption_algorithms = 0;
+ S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nr_security_capabilities.integrity_algorithms = 0;
+ }
+
+ itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p);
+
return 0;
}
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf
index 0659641607..40361aaf4e 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf
@@ -33,7 +33,7 @@ gNBs =
# downlinkConfigCommon
#frequencyInfoDL
# this is 3600 MHz + 84 PRBs@30kHz SCS (same as initial BWP)
- absoluteFrequencySSB = 642364;
+ absoluteFrequencySSB = 642016;#642364;
dl_frequencyBand = 78;
# this is 3600 MHz
dl_absoluteFrequencyPointA = 640000;
@@ -130,16 +130,21 @@ gNBs =
# 0=unrestricted, 1=restricted type A, 2=restricted type B
restrictedSetConfig = 0,
# pusch-ConfigCommon (up to 16 elements)
- initialULBWPk2_0 = 2;
+ initialULBWPk2_0 = 6; #2;
initialULBWPmappingType_0 = 1
# this is SS=0 L=11
initialULBWPstartSymbolAndLength_0 = 55;
- initialULBWPk2_1 = 2;
+ initialULBWPk2_1 = 6; #2;
initialULBWPmappingType_1 = 1;
# this is SS=0 L=12
initialULBWPstartSymbolAndLength_1 = 69;
+ initialULBWPk2_2 = 7;
+ initialULBWPmappingType_2 = 1;
+ # this is SS=10 L=4
+ initialULBWPstartSymbolAndLength_2 = 52;
+
msg3_DeltaPreamble = 1;
p0_NominalWithGrant =-90;
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf
index 0a6268f8a8..a899845cb8 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf
@@ -130,16 +130,21 @@ gNBs =
# 0=unrestricted, 1=restricted type A, 2=restricted type B
restrictedSetConfig = 0,
# pusch-ConfigCommon (up to 16 elements)
- initialULBWPk2_0 = 2;
+ initialULBWPk2_0 = 6;#2;
initialULBWPmappingType_0 = 1
# this is SS=0 L=11
initialULBWPstartSymbolAndLength_0 = 55;
- initialULBWPk2_1 = 2;
+ initialULBWPk2_1 = 6;#2;
initialULBWPmappingType_1 = 1;
# this is SS=0 L=12
initialULBWPstartSymbolAndLength_1 = 69;
+ initialULBWPk2_2 = 7;
+ initialULBWPmappingType_2 = 1;
+ # this is SS=10 L=4
+ initialULBWPstartSymbolAndLength_2 = 52;
+
msg3_DeltaPreamble = 1;
p0_NominalWithGrant =-90;
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf
index 555af5835d..c46ea98ec2 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf
@@ -278,6 +278,18 @@ THREAD_STRUCT = (
}
);
+security = {
+ # preferred ciphering algorithms
+ # the first one of the list that an UE supports in chosen
+ # valid values: nea0, nea1, nea2, nea3
+ ciphering_algorithms = ( "nea0", "nea2" );
+
+ # preferred integrity algorithms
+ # the first one of the list that an UE supports in chosen
+ # valid values: nia0, nia1, nia2, nia3
+ integrity_algorithms = ( "nia0" );
+};
+
log_config :
{
global_log_level ="info";
diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf
index d28427dbf3..892aa73398 100644
--- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf
+++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf
@@ -50,8 +50,8 @@ gNBs =
dl_carrierBandwidth = 106;
#initialDownlinkBWP
#genericParameters
- # this is RBstart=41,L=24 (275*(L-1))+RBstart
- initialDLBWPlocationAndBandwidth = 6366; # 6366 12925 12956 28875
+ # this is RBstart=27,L=48 (275*(L-1))+RBstart
+ initialDLBWPlocationAndBandwidth = 12952; # 6366 12925 12956 28875 12952
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialDLBWPsubcarrierSpacing = 1;
@@ -94,7 +94,7 @@ gNBs =
pMax = 20;
#initialUplinkBWP
#genericParameters
- initialULBWPlocationAndBandwidth = 6366;
+ initialULBWPlocationAndBandwidth = 12952;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialULBWPsubcarrierSpacing = 1;