Merge branch 'develop-SA-CBRA' of https://gitlab.eurecom.fr/oai/openairinterface5g into develop-SA-CBRA

This commit is contained in:
Laurent Thomas
2021-02-28 11:06:02 +01:00
50 changed files with 2088 additions and 456 deletions
+1
View File
@@ -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
)
+10 -5
View File
@@ -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)</desc>
(Test11: SC-FDMA, 216 PRBs),
(Test12: SC-FDMA, 273 PRBs),
(Test13: SC-FDMA, 3 DMRS)</desc>
<pre_compile_prog></pre_compile_prog>
<compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
<compile_prog_args> --phy_simulators -c </compile_prog_args>
@@ -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</main_exec_args>
<tags>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</tags>
-n100 -s2 -Z
-n100 -s2 -Z -r75
-n100 -s2 -Z -r216 -R217
-n100 -s2 -Z -r270 -R273
-n100 -s2 -Z -U 2 0 2</main_exec_args>
<tags>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</tags>
<search_expr_true>PUSCH test OK</search_expr_true>
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
<nruns>3</nruns>
@@ -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
+97 -8
View File
@@ -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];
}
}
+1 -1
View File
@@ -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;
}
@@ -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<Msc_PUSCH; i++, ip+=4) {
((int32_t*)idft_in0)[ip+0] = z[i];
}
switch (Msc_PUSCH) {
case 12:
dft(DFT_12,(int16_t *)idft_in0, (int16_t *)idft_out0,0);
@@ -194,25 +193,102 @@ void nr_idft(int32_t *z, uint32_t Msc_PUSCH)
dft(DFT_1200,idft_in0, idft_out0, 1);
break;
case 1296:
dft(DFT_1296,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 1440:
dft(DFT_1440,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 1500:
dft(DFT_1500,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 1536:
//dft(DFT_1536,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
idft(IDFT_1536,(int16_t*)z, (int16_t*)z, 1);
break;
case 1620:
dft(DFT_1620,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 1728:
dft(DFT_1728,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 1800:
dft(DFT_1800,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 1920:
dft(DFT_1920,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 1944:
dft(DFT_1944,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 2160:
dft(DFT_2160,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 2304:
dft(DFT_2304,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 2400:
dft(DFT_2400,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 2592:
dft(DFT_2592,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 2700:
dft(DFT_2700,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 2880:
dft(DFT_2880,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 2916:
dft(DFT_2916,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 3000:
dft(DFT_3000,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 3072:
//dft(DFT_3072,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
idft(IDFT_3072,(int16_t*)z, (int16_t*)z, 1);
break;
case 3240:
dft(DFT_3240,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
default:
// should not be reached
LOG_E( PHY, "Unsupported Msc_PUSCH value of %"PRIu16"\n", Msc_PUSCH );
return;
}
if ((Msc_PUSCH % 1536) > 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,
+937 -8
View File
@@ -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;
}
+31 -10
View File
@@ -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
+1 -1
View File
@@ -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
+6
View File
@@ -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
+6
View File
@@ -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;
+6
View File
@@ -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];
+8
View File
@@ -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 {
+1 -1
View File
@@ -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];
+98 -1
View File
@@ -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 <num_gnbs ; k++)
}//End if (num_gnbs>0)
config_security(rrc);
}//End RCconfig_NRRRC function
int RCconfig_nr_gtpu(void ) {
+23
View File
@@ -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
+1 -1
View File
@@ -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);
}
@@ -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
+26 -10
View File
@@ -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; i<cc->num_active_ssb; i++) {
for(int j=0; j<num_preamble; j++) {
if (cc->ssb_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);
+7 -1
View File
@@ -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);
+283 -240
View File
@@ -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;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_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; i<ubwp->bwp_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; i<ubwp->bwp_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; i<bwp->bwp_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;
@@ -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;
@@ -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);
@@ -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);
@@ -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",
+3 -12
View File
@@ -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,
+2 -2
View File
@@ -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;
+28 -3
View File
@@ -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;
}
+25 -3
View File
@@ -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);
@@ -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);
}
+29 -9
View File
@@ -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,
@@ -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 <stdlib.h>
#include <string.h>
#include <nettle/nettle-meta.h>
#include <nettle/aes.h>
#include <nettle/ctr.h>
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);
}
@@ -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_ */
+1 -1
View File
@@ -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--;
+10
View File
@@ -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];
+9 -67
View File
@@ -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;
+9
View File
@@ -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);
+11
View File
@@ -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
+5 -1
View File
@@ -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,
+4 -1
View File
@@ -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)) {
+96 -23
View File
@@ -39,6 +39,7 @@
#include "openair2/RRC/LTE/rrc_eNB_GTPV1U.h"
#include "executables/softmodem-common.h"
#include <openair2/RRC/NR/rrc_gNB_UE_context.h>
#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);
+9 -6
View File
@@ -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)
+4 -1
View File
@@ -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
+2
View File
@@ -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,
+24
View File
@@ -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;
}
+16 -2
View File
@@ -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;
}
@@ -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;
@@ -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;
@@ -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";
@@ -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;