Merge remote-tracking branch 'develop' into NR_DL_MIMO

This commit is contained in:
Thomas Schlichter
2021-03-16 13:37:07 +01:00
232 changed files with 16089 additions and 3546 deletions
+13
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
@@ -393,6 +398,11 @@ typedef struct s1ap_register_enb_req_s {
/* Number of SCTP streams used for a mme association */
uint16_t sctp_in_streams;
uint16_t sctp_out_streams;
uint16_t s1_setuprsp_wait_timer;
uint16_t s1_setupreq_wait_timer;
uint16_t s1_setupreq_count;
uint16_t sctp_req_timer;
uint16_t sctp_req_count;
} s1ap_register_enb_req_t;
//-------------------------------------------------------------------------------------------//
@@ -538,6 +548,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];
+59
View File
@@ -2429,6 +2429,65 @@ int RCconfig_S1(
"to\n"
" tracking_area_code = 1; // no string!!\n"
" plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } )\n");
if(*ENBParamList.paramarray[k][ENB_S1SETUP_RSP_TIMER_IDX].uptr <= 0xffff)
{
S1AP_REGISTER_ENB_REQ(msg_p).s1_setuprsp_wait_timer = *ENBParamList.paramarray[k][ENB_S1SETUP_RSP_TIMER_IDX].uptr;
}
else
{
LOG_E(S1AP,
"s1setup_rsp_timer value in conf file is invalid (%d). Default value is set.\n",
*ENBParamList.paramarray[k][ENB_S1SETUP_RSP_TIMER_IDX].uptr);
S1AP_REGISTER_ENB_REQ(msg_p).s1_setuprsp_wait_timer = 5;
}
if(*ENBParamList.paramarray[k][ENB_S1SETUP_REQ_TIMER_IDX].uptr <= 0xffff)
{
S1AP_REGISTER_ENB_REQ(msg_p).s1_setupreq_wait_timer = *ENBParamList.paramarray[k][ENB_S1SETUP_REQ_TIMER_IDX].uptr;
}
else
{
LOG_E(S1AP,
"s1setup_req_timer value in conf file is invalid (%d). Default value is set.\n",
*ENBParamList.paramarray[k][ENB_S1SETUP_REQ_TIMER_IDX].uptr);
S1AP_REGISTER_ENB_REQ(msg_p).s1_setupreq_wait_timer = 5;
}
if(*ENBParamList.paramarray[k][ENB_S1SETUP_REQ_COUNT_IDX].uptr <= 0xffff)
{
S1AP_REGISTER_ENB_REQ(msg_p).s1_setupreq_count = *ENBParamList.paramarray[k][ENB_S1SETUP_REQ_COUNT_IDX].uptr;
}
else
{
LOG_E(S1AP,
"s1setup_req_count value in conf file is invalid (%d). Default value is set.\n",
*ENBParamList.paramarray[k][ENB_S1SETUP_REQ_COUNT_IDX].uptr);
S1AP_REGISTER_ENB_REQ(msg_p).s1_setupreq_count = 0xffff;
}
if(*ENBParamList.paramarray[k][ENB_SCTP_REQ_TIMER_IDX].uptr <= 0xffff)
{
S1AP_REGISTER_ENB_REQ(msg_p).sctp_req_timer = *ENBParamList.paramarray[k][ENB_SCTP_REQ_TIMER_IDX].uptr;
}
else
{
LOG_E(S1AP,
"sctp_req_timer value in conf file is invalid (%d). Default value is set.\n",
*ENBParamList.paramarray[k][ENB_SCTP_REQ_TIMER_IDX].uptr);
S1AP_REGISTER_ENB_REQ(msg_p).sctp_req_timer = 180;
}
if(*ENBParamList.paramarray[k][ENB_SCTP_REQ_COUNT_IDX].uptr <= 0xffff)
{
S1AP_REGISTER_ENB_REQ(msg_p).sctp_req_count = *ENBParamList.paramarray[k][ENB_SCTP_REQ_COUNT_IDX].uptr;
}
else
{
LOG_E(S1AP,
"sctp_req_count value in conf file is invalid (%d). Default value is set.\n",
*ENBParamList.paramarray[k][ENB_SCTP_REQ_COUNT_IDX].uptr);
S1AP_REGISTER_ENB_REQ(msg_p).sctp_req_count = 0xffff;
}
config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams)/sizeof(paramdef_t), aprefix);
if (PLMNParamList.numelt < 1 || PLMNParamList.numelt > 6) {
+15
View File
@@ -214,6 +214,11 @@ typedef enum {
#define ENB_CONFIG_STRING_X2 "enable_x2"
#define ENB_CONFIG_STRING_ENB_M2 "enable_enb_m2"
#define ENB_CONFIG_STRING_MCE_M2 "enable_mce_m2"
#define ENB_CONFIG_STRING_S1SETUP_RSP_TIMER "s1setup_rsp_timer"
#define ENB_CONFIG_STRING_S1SETUP_REQ_TIMER "s1setup_req_timer"
#define ENB_CONFIG_STRING_S1SETUP_REQ_COUNT "s1setup_req_count"
#define ENB_CONFIG_STRING_SCTP_REQ_TIMER "sctp_req_timer"
#define ENB_CONFIG_STRING_SCTP_REQ_COUNT "sctp_req_count"
/*-----------------------------------------------------------------------------------------------------------------------------------------*/
/* cell configuration parameters */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
@@ -239,6 +244,11 @@ typedef enum {
{ENB_CONFIG_STRING_X2, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
{ENB_CONFIG_STRING_ENB_M2, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0}, \
{ENB_CONFIG_STRING_MCE_M2, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0}, \
{ENB_CONFIG_STRING_S1SETUP_RSP_TIMER, NULL, 0, uptr:NULL, defuintval:5, TYPE_UINT, 0}, \
{ENB_CONFIG_STRING_S1SETUP_REQ_TIMER, NULL, 0, uptr:NULL, defuintval:5, TYPE_UINT, 0}, \
{ENB_CONFIG_STRING_S1SETUP_REQ_COUNT, NULL, 0, uptr:NULL, defuintval:65535, TYPE_UINT, 0}, \
{ENB_CONFIG_STRING_SCTP_REQ_TIMER, NULL, 0, uptr:NULL, defuintval:180, TYPE_UINT, 0}, \
{ENB_CONFIG_STRING_SCTP_REQ_COUNT, NULL, 0, uptr:NULL, defuintval:65535, TYPE_UINT, 0}, \
}
#define ENB_ENB_ID_IDX 0
@@ -261,6 +271,11 @@ typedef enum {
#define ENB_ENABLE_X2 17
#define ENB_ENABLE_ENB_M2 18
#define ENB_ENABLE_MCE_M2 19
#define ENB_S1SETUP_RSP_TIMER_IDX 20
#define ENB_S1SETUP_REQ_TIMER_IDX 21
#define ENB_S1SETUP_REQ_COUNT_IDX 22
#define ENB_SCTP_REQ_TIMER_IDX 23
#define ENB_SCTP_REQ_COUNT_IDX 24
#define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD}
#define ENBPARAMS_CHECK { \
+101 -4
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));
@@ -430,7 +432,7 @@ void RCconfig_NR_L1(void) {
mac_top_init_gNB();
configure_nfapi_pnf(RC.gNB[j]->eth_params_n.remote_addr, RC.gNB[j]->eth_params_n.remote_portc, RC.gNB[j]->eth_params_n.my_addr, RC.gNB[j]->eth_params_n.my_portd, RC.gNB[j]->eth_params_n .remote_portd);
configure_nr_nfapi_pnf(RC.gNB[j]->eth_params_n.remote_addr, RC.gNB[j]->eth_params_n.remote_portc, RC.gNB[j]->eth_params_n.my_addr, RC.gNB[j]->eth_params_n.my_portd, RC.gNB[j]->eth_params_n .remote_portd);
}else { // other midhaul
}
}// for (j = 0; j < RC.nb_nr_L1_inst; j++)
@@ -500,8 +502,8 @@ void RCconfig_nr_macrlc() {
//sf_ahead = 2; // Cannot cope with 4 subframes between RX and TX - set it to 2
printf("**************** vnf_port:%d\n", RC.mac[j]->eth_params_s.my_portc);
configure_nfapi_vnf(RC.nrmac[j]->eth_params_s.my_addr, RC.nrmac[j]->eth_params_s.my_portc);
printf("**************** vnf_port:%d\n", RC.nrmac[j]->eth_params_s.my_portc);
configure_nr_nfapi_vnf(RC.nrmac[j]->eth_params_s.my_addr, RC.nrmac[j]->eth_params_s.my_portc);
printf("**************** RETURNED FROM configure_nfapi_vnf() vnf_port:%d\n", RC.nrmac[j]->eth_params_s.my_portc);
}else { // other midhaul
AssertFatal(1==0,"MACRLC %d: %s unknown southbound midhaul\n",j,*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr));
@@ -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;
@@ -681,7 +778,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
@@ -455,4 +455,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
@@ -490,7 +490,7 @@ typedef struct {
/*! \brief Uplink SCH PDU Structure */
typedef struct {
int8_t payload[SCH_PAYLOAD_SIZE_MAX]; /*!< \brief SACH payload */
uint8_t payload[SCH_PAYLOAD_SIZE_MAX]; /*!< \brief SACH payload */
uint16_t Pdu_size;
} __attribute__ ((__packed__)) ULSCH_PDU;
+37 -99
View File
@@ -31,6 +31,7 @@
*/
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "common/utils/nr/nr_common.h"
#include <limits.h>
#define reserved 0xffff
@@ -1220,6 +1221,11 @@ int get_nr_prach_occasion_info_from_index(uint8_t index,
else { // FDD
x = table_6_3_3_2_2_prachConfig_Index[index][2];
s_map = table_6_3_3_2_2_prachConfig_Index[index][4];
for(int i = 0; i < 64 ; i++) {
if ( (s_map >> i) & 0x01) {
(*N_RA_sfn)++;
}
}
*N_RA_slot = table_6_3_3_2_2_prachConfig_Index[index][6];
if (start_symbol != NULL && N_t_slot != NULL && N_dur != NULL && format != NULL){
*start_symbol = table_6_3_3_2_2_prachConfig_Index[index][5];
@@ -1429,6 +1435,11 @@ int get_nr_prach_info_from_index(uint8_t index,
if ( (table_6_3_3_2_2_prachConfig_Index[index][6] <= 1) && (slot%2 == 0) )
return 0; // no prach in even slots @ 30kHz for 1 prach per subframe
}
for(int i = 0; i <= subframe ; i++) {
if ( (s_map >> i) & 0x01) {
(*RA_sfn_index)++;
}
}
if (start_symbol != NULL && N_t_slot != NULL && N_dur != NULL && format != NULL){
*start_symbol = table_6_3_3_2_2_prachConfig_Index[index][5];
*N_t_slot = table_6_3_3_2_2_prachConfig_Index[index][7];
@@ -1567,79 +1578,6 @@ uint8_t compute_nr_root_seq(NR_RACH_ConfigCommon_t *rach_config,
}
}
// Table 5.2-1 NR operating bands in FR1 & FR2 (3GPP TS 38.101)
// Table 5.4.2.3-1 Applicable NR-ARFCN per operating band in FR1 & FR2 (3GPP TS 38.101)
// Notes:
// - N_OFFs for bands from 80 to 89 and band 95 is referred to UL
// - Frequencies are expressed in KHz
// - col: NR_band ul_min ul_max dl_min dl_max step N_OFFs_DL deltaf_raster
nr_bandentry_t nr_bandtable[] = {
{1, 1920000, 1980000, 2110000, 2170000, 20, 422000, 100},
{2, 1850000, 1910000, 1930000, 1990000, 20, 386000, 100},
{3, 1710000, 1785000, 1805000, 1880000, 20, 361000, 100},
{5, 824000, 849000, 869000, 894000, 20, 173800, 100},
{7, 2500000, 2570000, 2620000, 2690000, 20, 524000, 100},
{8, 880000, 915000, 925000, 960000, 20, 185000, 100},
{12, 698000, 716000, 729000, 746000, 20, 145800, 100},
{14, 788000, 798000, 758000, 768000, 20, 151600, 100},
{18, 815000, 830000, 860000, 875000, 20, 172000, 100},
{20, 832000, 862000, 791000, 821000, 20, 158200, 100},
{25, 1850000, 1915000, 1930000, 1995000, 20, 386000, 100},
{26, 814000, 849000, 859000, 894000, 20, 171800, 100},
{28, 703000, 758000, 758000, 813000, 20, 151600, 100},
{29, 000, 000, 717000, 728000, 20, 143400, 100},
{30, 2305000, 2315000, 2350000, 2360000, 20, 470000, 100},
{34, 2010000, 2025000, 2010000, 2025000, 20, 402000, 100},
{38, 2570000, 2620000, 2570000, 2630000, 20, 514000, 100},
{39, 1880000, 1920000, 1880000, 1920000, 20, 376000, 100},
{40, 2300000, 2400000, 2300000, 2400000, 20, 460000, 100},
{41, 2496000, 2690000, 2496000, 2690000, 3, 499200, 15},
{41, 2496000, 2690000, 2496000, 2690000, 6, 499200, 30},
{47, 5855000, 5925000, 5855000, 5925000, 1, 790334, 15},
//{48, 3550000, 3700000, 3550000, 3700000, 1, 636667, 15},
//{48, 3550000, 3700000, 3550000, 3700000, 2, 636668, 30},
{50, 1432000, 1517000, 1432000, 1517000, 20, 286400, 100},
{51, 1427000, 1432000, 1427000, 1432000, 20, 285400, 100},
{53, 2483500, 2495000, 2483500, 2495000, 20, 496700, 100},
{65, 1920000, 2010000, 2110000, 2200000, 20, 422000, 100},
{66, 1710000, 1780000, 2110000, 2200000, 20, 422000, 100},
{70, 1695000, 1710000, 1995000, 2020000, 20, 399000, 100},
{71, 663000, 698000, 617000, 652000, 20, 123400, 100},
{74, 1427000, 1470000, 1475000, 1518000, 20, 295000, 100},
{75, 000, 000, 1432000, 1517000, 20, 286400, 100},
{76, 000, 000, 1427000, 1432000, 20, 285400, 100},
{77, 3300000, 4200000, 3300000, 4200000, 1, 620000, 15},
{77, 3300000, 4200000, 3300000, 4200000, 2, 620000, 30},
{78, 3300000, 3800000, 3300000, 3800000, 1, 620000, 15},
{78, 3300000, 3800000, 3300000, 3800000, 2, 620000, 30},
{79, 4400010, 5000000, 4400010, 5000000, 1, 693334, 15},
{79, 4400010, 5000000, 4400010, 5000000, 2, 693334, 30},
{80, 1710000, 1785000, 000, 000, 20, 342000, 100},
{81, 880000, 915000, 000, 000, 20, 176000, 100},
{82, 832000, 862000, 000, 000, 20, 166400, 100},
{83, 703000, 748000, 000, 000, 20, 140600, 100},
{84, 1920000, 1980000, 000, 000, 20, 384000, 100},
{86, 1710000, 1785000, 000, 000, 20, 342000, 100},
{89, 824000, 849000, 000, 000, 20, 342000, 100},
{90, 2496000, 2690000, 2496000, 2690000, 3, 499200, 15},
{90, 2496000, 2690000, 2496000, 2690000, 6, 499200, 30},
{90, 2496000, 2690000, 2496000, 2690000, 20, 499200, 100},
{91, 832000, 862000, 1427000, 1432000, 20, 285400, 100},
{92, 832000, 862000, 1432000, 1517000, 20, 286400, 100},
{93, 880000, 915000, 1427000, 1432000, 20, 285400, 100},
{94, 880000, 915000, 1432000, 1517000, 20, 286400, 100},
{95, 2010000, 2025000, 000, 000, 20, 402000, 100},
{257,26500020,29500000,26500020,29500000, 1,2054166, 60},
{257,26500080,29500000,26500080,29500000, 2,2054167, 120},
{258,24250080,27500000,24250080,27500000, 1,2016667, 60},
{258,24250080,27500000,24250080,27500000, 2,2016667, 120},
{260,37000020,40000000,37000020,40000000, 1,2229166, 60},
{260,37000080,40000000,37000080,40000000, 2,2229167, 120},
{261,27500040,28350000,27500040,28350000, 1,2070833, 60},
{261,27500040,28350000,27500040,28350000, 2,2070833, 120}
};
// TS 38.211 Table 6.4.1.1.3-3: PUSCH DMRS positions l' within a slot for single-symbol DMRS and intra-slot frequency hopping disabled.
// The first 4 colomns are PUSCH mapping type A and the last 4 colomns are PUSCH mapping type B.
// When l' = l0, it is represented by 1
@@ -1680,11 +1618,9 @@ int32_t table_6_4_1_1_3_4_pusch_dmrs_positions_l [12][8] = {
{1, 1025, -1, -1, 1, 513, -1, -1}, //14 // (DMRS l' position)
};
#define NR_BANDTABLE_SIZE (sizeof(nr_bandtable)/sizeof(nr_bandentry_t))
// Returns the corresponding row index of the NR table
int get_nr_table_idx(int nr_bandP, uint8_t scs_index){
int get_nr_table_idx(int nr_bandP, uint8_t scs_index)
{
int i, j;
int scs_khz = 15 << scs_index;
int supplementary_bands[] = {29,75,76,80,81,82,83,84,86,89,95};
@@ -1695,8 +1631,8 @@ int get_nr_table_idx(int nr_bandP, uint8_t scs_index){
AssertFatal(0 == 1, "Band %d is a supplementary band (%d). This is not supported yet.\n", nr_bandP, supplementary_bands[j]);
}
AssertFatal(nr_bandP <= nr_bandtable[NR_BANDTABLE_SIZE-1].band, "NR band %d exceeds NR bands table maximum limit %d\n", nr_bandP, nr_bandtable[NR_BANDTABLE_SIZE-1].band);
for (i = 0; i < NR_BANDTABLE_SIZE && nr_bandtable[i].band != nr_bandP; i++);
AssertFatal(nr_bandP <= nr_bandtable[nr_bandtable_size-1].band, "NR band %d exceeds NR bands table maximum limit %d\n", nr_bandP, nr_bandtable[nr_bandtable_size-1].band);
for (i = 0; i < nr_bandtable_size && nr_bandtable[i].band != nr_bandP; i++);
// selection of correct Deltaf raster according to SCS
if ((nr_bandtable[i].deltaf_raster != 100) && (nr_bandtable[i].deltaf_raster != scs_khz))
@@ -1705,35 +1641,33 @@ int get_nr_table_idx(int nr_bandP, uint8_t scs_index){
LOG_D(PHY, "NR band table index %d (Band %d, dl_min %lu, ul_min %lu)\n", i, nr_bandtable[i].band, nr_bandtable[i].dl_min,nr_bandtable[i].ul_min);
return i;
}
// Computes the duplex spacing (either positive or negative) in KHz
void get_delta_duplex(int nr_bandP, uint8_t scs_index, int32_t *delta_duplex){
int32_t get_delta_duplex(int nr_bandP, uint8_t scs_index)
{
int nr_table_idx = get_nr_table_idx(nr_bandP, scs_index);
*delta_duplex = (nr_bandtable[nr_table_idx].ul_min - nr_bandtable[nr_table_idx].dl_min);
int32_t delta_duplex = (nr_bandtable[nr_table_idx].ul_min - nr_bandtable[nr_table_idx].dl_min);
LOG_D(PHY, "NR band duplex spacing is %d KHz (nr_bandtable[%d].band = %d)\n", *delta_duplex, nr_table_idx, nr_bandtable[nr_table_idx].band);
LOG_I(PHY, "NR band duplex spacing is %d KHz (nr_bandtable[%d].band = %d)\n", delta_duplex, nr_table_idx, nr_bandtable[nr_table_idx].band);
return delta_duplex;
}
void get_frame_type(uint16_t current_band,
uint8_t scs_index,
lte_frame_type_t *current_type){
lte_frame_type_t get_frame_type(uint16_t current_band, uint8_t scs_index)
{
lte_frame_type_t current_type;
int32_t delta_duplex = get_delta_duplex(current_band, scs_index);
int32_t current_offset;
get_delta_duplex(current_band, scs_index, &current_offset);
current_offset *= 1000;
if (current_offset == 0)
*current_type = TDD;
if (delta_duplex == 0)
current_type = TDD;
else
*current_type = FDD;
current_type = FDD;
LOG_I(MAC, "NR band %d, duplex mode %s, duplex spacing = %d KHz\n", current_band, duplex_mode[*current_type], current_offset);
LOG_I(MAC, "NR band %d, duplex mode %s, duplex spacing = %d KHz\n", current_band, duplex_mode[current_type], delta_duplex);
return current_type;
}
uint16_t config_bandwidth(int mu, int nb_rb, int nr_band)
@@ -1911,7 +1845,6 @@ uint64_t from_nrarfcn(int nr_bandP,
int deltaFglobal = 5;
uint32_t N_REF_Offs = 0;
uint64_t F_REF_Offs_khz = 0;
int32_t delta_duplex;
uint64_t N_OFFs, frequency, freq_min;
int i = get_nr_table_idx(nr_bandP, scs_index);
@@ -1926,7 +1859,7 @@ uint64_t from_nrarfcn(int nr_bandP,
F_REF_Offs_khz = 24250080;
}
get_delta_duplex(nr_bandP, scs_index, &delta_duplex);
int32_t delta_duplex = get_delta_duplex(nr_bandP, scs_index);
if (delta_duplex <= 0){ // DL band >= UL band
if (nrarfcn >= nr_bandtable[i].N_OFFs_DL){ // is TDD of FDD DL
@@ -2836,11 +2769,15 @@ int is_nr_DL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slot) {
else return(slot_in_period <= slots1+scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSlots ? 1 : 0);
}
int is_nr_UL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slot) {
int is_nr_UL_slot(NR_ServingCellConfigCommon_t *scc, slot_t slot, lte_frame_type_t frame_type) {
int period,period1,period2=0;
if (scc->tdd_UL_DL_ConfigurationCommon==NULL) return(1);
// Note: condition on frame_type
// goal: the UL scheduler assumes mode is TDD therefore this hack is needed to make FDD work
if (scc->tdd_UL_DL_ConfigurationCommon == NULL || frame_type == FDD) {
return(1);
}
if (scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1 &&
scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530)
@@ -3067,6 +3004,7 @@ bool set_dl_ptrs_values(NR_PTRS_DownlinkConfig_t *ptrs_config,
//printf("[MAC] PTRS is set K= %u L= %u\n", *K_ptrs,1<<*L_ptrs);
return valid;
}
uint32_t get_ssb_slot(uint32_t ssb_index){
// this function now only support f <= 3GHz
return ssb_index & 0x3 ;
@@ -39,9 +39,9 @@
uint16_t config_bandwidth(int mu, int nb_rb, int nr_band);
void get_frame_type(uint16_t nr_bandP, uint8_t scs_index, lte_frame_type_t *current_type);
lte_frame_type_t get_frame_type(uint16_t nr_bandP, uint8_t scs_index);
void get_delta_duplex(int nr_bandP, uint8_t scs_index, int32_t *delta_duplex);
int32_t get_delta_duplex(int nr_bandP, uint8_t scs_index);
uint64_t from_nrarfcn(int nr_bandP, uint8_t scs_index, uint32_t dl_nrarfcn);
@@ -51,7 +51,7 @@ int16_t fill_dmrs_mask(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,i
int is_nr_DL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slotP);
int is_nr_UL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slotP);
int is_nr_UL_slot(NR_ServingCellConfigCommon_t *scc, slot_t slotP, lte_frame_type_t frame_type);
uint16_t nr_dci_size(const NR_ServingCellConfigCommon_t *scc,
const NR_CellGroupConfig_t *secondaryCellGroup,
+3 -4
View File
@@ -203,13 +203,12 @@ void config_common_ue(NR_UE_MAC_INST_t *mac,
uint32_t band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
frequency_range_t frequency_range = band<100?FR1:FR2;
lte_frame_type_t frame_type;
get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing, &frame_type);
mac->frame_type = get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
// cell config
cfg->cell_config.phy_cell_id = *scc->physCellId;
cfg->cell_config.frame_duplex_type = frame_type;
cfg->cell_config.frame_duplex_type = mac->frame_type;
// SSB config
cfg->ssb_config.ss_pbch_power = scc->ss_PBCH_BlockPower;
@@ -313,7 +312,7 @@ void config_common_ue(NR_UE_MAC_INST_t *mac,
cfg->prach_config.num_prach_fd_occasions_list[i].k1 = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart;
cfg->prach_config.num_prach_fd_occasions_list[i].prach_zero_corr_conf = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig;
cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences = compute_nr_root_seq(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup, nb_preambles, frame_type,frequency_range);
cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences = compute_nr_root_seq(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup, nb_preambles, mac->frame_type, frequency_range);
//cfg->prach_config.num_prach_fd_occasions_list[i].num_unused_root_sequences = ???
}
+2
View File
@@ -325,6 +325,8 @@ typedef struct {
NR_ControlResourceSet_t *coreset[MAX_NUM_BWP][FAPI_NR_MAX_CORESET_PER_BWP];
NR_SearchSpace_t *SSpace[MAX_NUM_BWP][FAPI_NR_MAX_CORESET_PER_BWP][FAPI_NR_MAX_SS_PER_CORESET];
lte_frame_type_t frame_type;
/*BWP*/
// dedicated active DL BWP
NR_BWP_Id_t DL_BWP_Id;
+2 -2
View File
@@ -56,14 +56,14 @@ int8_t nr_ue_decode_mib(
void *pduP,
uint16_t cell_id );
/**\brief decode sib1 pdu in NR_UE, from if_module dl_ind
/**\brief decode SIB1 and other SIs pdus in NR_UE, from if_module dl_ind
\param module_id module id
\param cc_id component carrier id
\param gNB_index gNB index
\param sibs_mask sibs mask
\param pduP pointer to pdu
\param pdu_length length of pdu */
int8_t nr_ue_decode_sib1(module_id_t module_id,
int8_t nr_ue_decode_BCCH_DL_SCH(module_id_t module_id,
int cc_id,
unsigned int gNB_index,
uint32_t sibs_mask,
+1 -1
View File
@@ -32,7 +32,7 @@
#include <stdint.h>
const char *rnti_types[]={"RNTI_new", "RNTI_C", "RNTI_RA", "NR_RNTI_P", "NR_RNTI_CS", "NR_RNTI_TC"};
const char *rnti_types[]={"RNTI_new", "RNTI_C", "RNTI_RA", "NR_RNTI_P", "NR_RNTI_CS", "NR_RNTI_TC", "NR_RNTI_SP_CSI", "NR_RNTI_SI"};
const char *dci_formats[]={"1_0", "1_1", "2_0", "2_1", "2_2", "2_3", "0_0", "0_1"};
// table_7_3_1_1_2_2_3_4_5 contains values for number of layers and precoding information for tables 7.3.1.1.2-2/3/4/5 from TS 38.212 subclause 7.3.1.1.2
+37 -29
View File
@@ -35,6 +35,7 @@
/* RRC */
#include "NR_RACH-ConfigCommon.h"
#include "RRC/NR_UE/rrc_proto.h"
/* PHY */
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
@@ -514,7 +515,8 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
uint8_t sdu_lcids[NB_RB_MAX] = {0};
uint16_t sdu_lengths[NB_RB_MAX] = {0};
int TBS_bytes = 848, header_length_total=0, num_sdus, offset, mac_ce_len;
int num_sdus = 0;
int offset = 0;
// Delay init RA procedure to allow the convergence of the IIR filter on PRACH noise measurements at gNB side
if (!prach_resources->init_msg1) {
@@ -532,36 +534,27 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
LOG_D(MAC, "RA not active. Checking for data to transmit from upper layers...\n");
payload = (uint8_t*) &mac->CCCH_pdu.payload;
mac_ce_len = 0;
uint8_t TBS_max = 8 + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT);
payload = (uint8_t*) mac->CCCH_pdu.payload;
num_sdus = 1;
post_padding = 1;
sdu_lcids[0] = lcid;
if (0){
// initialisation by RRC
// CCCH PDU
// size_sdu = (uint16_t) mac_rrc_data_req_ue(mod_id,
// CC_id,
// frame,
// CCCH,
// 1,
// mac_sdus,
// gNB_id,
// 0);
LOG_D(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n", mod_id, frame, size_sdu);
} else {
// fill ulsch_buffer with random data
for (int i = 0; i < TBS_bytes; i++){
mac_sdus[i] = (unsigned char) (lrand48()&0xff);
}
//Sending SDUs with size 1
//Initialize elements of sdu_lcids and sdu_lengths
sdu_lcids[0] = lcid;
sdu_lengths[0] = TBS_bytes - 3 - post_padding - mac_ce_len;
header_length_total += 2 + (sdu_lengths[0] >= 128);
size_sdu += sdu_lengths[0];
// initialisation by RRC
// TODO: To be removed after RA procedures fully implemented
if(get_softmodem_params()->do_ra) {
nr_rrc_ue_generate_RRCSetupRequest(mod_id,gNB_id);
}
// CCCH PDU
size_sdu = (uint16_t) nr_mac_rrc_data_req_ue(mod_id, CC_id, gNB_id, frame, CCCH, mac_sdus);
sdu_lengths[0] = size_sdu;
LOG_D(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n", mod_id, frame, size_sdu);
if (size_sdu > 0) {
LOG_D(MAC, "[UE %d][%d.%d]: starting initialisation Random Access Procedure...\n", mod_id, frame, nr_slot_tx);
@@ -589,12 +582,27 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
post_padding,
0);
AssertFatal(TBS_max > offset, "Frequency resources are not enough for Msg3!\n");
// Padding: fill remainder with 0
if (post_padding > 0){
for (int j = 0; j < (TBS_bytes - offset); j++)
payload[offset + j] = 0; // mac_pdu[offset + j] = 0;
for (int j = 0; j < (TBS_max - offset); j++)
payload[offset + j] = 0;
}
}
}
LOG_D(MAC,"size_sdu = %i\n", size_sdu);
LOG_D(MAC,"offset = %i\n", offset);
for(int k = 0; k < TBS_max; k++) {
LOG_D(MAC,"(%i): %i\n", k, prach_resources->Msg3[k]);
}
// Msg3 was initialized with TBS_max bytes because the RA_Msg3_size will only be known after
// receiving Msg2 (which contains the Msg3 resource reserve).
// Msg3 will be transmitted with RA_Msg3_size bytes, removing unnecessary 0s.
mac->ulsch_pdu.Pdu_size = TBS_max;
memcpy(mac->ulsch_pdu.payload, prach_resources->Msg3, TBS_max);
} else if (ra->RA_window_cnt != -1) { // RACH is active
LOG_D(MAC, "In %s [%d.%d] RA is active: RA window count %d, RA backoff count %d\n", __FUNCTION__, frame, nr_slot_tx, ra->RA_window_cnt, ra->RA_backoff_cnt);
+18 -8
View File
@@ -154,13 +154,13 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
return 0;
}
int8_t nr_ue_decode_sib1(module_id_t module_id,
int cc_id,
unsigned int gNB_index,
uint32_t sibs_mask,
uint8_t *pduP,
uint32_t pdu_len) {
LOG_D(MAC, "Decode sib1\n");
int8_t nr_ue_decode_BCCH_DL_SCH(module_id_t module_id,
int cc_id,
unsigned int gNB_index,
uint32_t sibs_mask,
uint8_t *pduP,
uint32_t pdu_len) {
LOG_D(NR_MAC, "Decoding NR-BCCH-DL-SCH-Message (SIB1 or SI)\n");
nr_mac_rrc_data_ind_ue(module_id, cc_id, gNB_index, NR_BCCH_DL_SCH, (uint8_t *) pduP, pdu_len);
return 0;
}
@@ -814,7 +814,17 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DLSCH;
dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.rnti = rnti;
// FIXME: fix number of additional dmrs
if(pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition == NULL)
pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition=calloc(1,sizeof(*pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition));
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu_1_1 = &dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.dlsch_config_rel15;
dlsch_config_pdu_1_1->BWPSize = NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
dlsch_config_pdu_1_1->BWPStart = NRRIV2PRBOFFSET(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
dlsch_config_pdu_1_1->SubcarrierSpacing = mac->DLbwp[0]->bwp_Common->genericParameters.subcarrierSpacing;
/* IDENTIFIER_DCI_FORMATS */
/* CARRIER_IND */
/* BANDWIDTH_PART_IND */
@@ -2230,7 +2240,7 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t
// TA command
ul_time_alignment->apply_ta = 1;
ul_time_alignment->ta_command = rar->TA2 + (rar->TA1 << 5);
ul_time_alignment->ta_command = 31 + rar->TA2 + (rar->TA1 << 5);
#ifdef DEBUG_RAR
// CSI
+42 -38
View File
@@ -118,13 +118,14 @@ long get_k2(NR_UE_MAC_INST_t *mac, uint8_t time_domain_ind) {
* This function returns the UL config corresponding to a given UL slot
* from MAC instance .
*/
fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int slot) {
fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int slot)
{
//Check if request to access ul_config is for a UL slot
if (is_nr_UL_slot(mac->scc, slot) == 0) {
if (is_nr_UL_slot(mac->scc, slot, mac->frame_type) == 0) {
LOG_W(MAC, "Slot %d is not a UL slot. %s called for wrong slot!!!\n", slot, __FUNCTION__);
return NULL;
}
// Calculate the index of the UL slot in mac->ul_config_request list. This is
// based on the TDD pattern (slot configuration period) and number of UL+mixed
// slots in the period. TS 38.213 Sec 11.1
@@ -889,34 +890,40 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
uint16_t TBS_bytes = ulcfg_pdu->pusch_config_pdu.pusch_data.tb_size;
// Push data from MAC to PHY only when NDI toggles
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
data_existing = nr_ue_get_sdu(mod_id,
cc_id,
frame_tx,
slot_tx,
0,
ulsch_input_buffer,
TBS_bytes,
&access_mode);
}
if (ra->ra_state == WAIT_RAR){
memcpy(ulsch_input_buffer, mac->ulsch_pdu.payload, TBS_bytes);
LOG_D(NR_MAC,"[RAPROC] Msg3 to be transmitted:\n");
for (int k = 0; k < TBS_bytes; k++) {
LOG_D(NR_MAC,"(%i): 0x%x\n",k,mac->ulsch_pdu.payload[k]);
}
} 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
data_existing = nr_ue_get_sdu(mod_id,
cc_id,
frame_tx,
slot_tx,
0,
ulsch_input_buffer,
TBS_bytes,
&access_mode);
}
mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] = ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator;
//Random traffic to be transmitted if there is no IP traffic available for this Tx opportunity
if (!IS_SOFTMODEM_NOS1 || !data_existing) {
//Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid
//and block this traffic from being forwarded to the upper layers at the gNB
LOG_D(PHY, "In %s: Random data to be transmitted: TBS_bytes %d \n", __FUNCTION__, TBS_bytes);
mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] = ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator;
//Random traffic to be transmitted if there is no IP traffic available for this Tx opportunity
if (!IS_SOFTMODEM_NOS1 || !data_existing) {
//Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid
//and block this traffic from being forwarded to the upper layers at the gNB
LOG_D(PHY, "In %s: Random data to be transmitted: TBS_bytes %d \n", __FUNCTION__, TBS_bytes);
//Give the first byte a dummy value (a value not corresponding to any valid LCID based on 38.321, Table 6.2.1-2)
//in order to distinguish the PHY random packets at the MAC layer of the gNB receiver from the normal packets that should
//have a valid LCID (nr_process_mac_pdu function)
ulsch_input_buffer[0] = 0x31;
//Give the first byte a dummy value (a value not corresponding to any valid LCID based on 38.321, Table 6.2.1-2)
//in order to distinguish the PHY random packets at the MAC layer of the gNB receiver from the normal packets that should
//have a valid LCID (nr_process_mac_pdu function)
ulsch_input_buffer[0] = 0x31;
for (int i = 1; i < TBS_bytes; i++) {
ulsch_input_buffer[i] = (unsigned char) rand();
//printf(" input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]);
for (int i = 1; i < TBS_bytes; i++) {
ulsch_input_buffer[i] = (unsigned char) rand();
}
}
}
@@ -1662,7 +1669,7 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
ra->RA_offset = 2; // to compensate the rx frame offset at the gNB
ra->generate_nr_prach = 0; // Reset flag for PRACH generation
if (is_nr_UL_slot(scc, slotP)) {
if (is_nr_UL_slot(scc, slotP, mac->frame_type)) {
// WIP Need to get the proper selected ssb_idx
// Initial beam selection functionality is not available yet
@@ -1683,13 +1690,11 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
format0 = format & 0xff; // single PRACH format
format1 = (format >> 8) & 0xff; // dual PRACH format
ul_config->sfn = frameP;
ul_config->slot = slotP;
ul_config->ul_config_list[ul_config->number_pdus].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PRACH;
prach_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].prach_config_pdu;
memset(prach_config_pdu, 0, sizeof(fapi_nr_ul_config_prach_pdu));
ul_config->number_pdus += 1;
fill_ul_config(ul_config, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PRACH);
LOG_D(PHY, "In %s: (%p) %d UL PDUs:\n", __FUNCTION__, ul_config, ul_config->number_pdus);
ncs = get_NCS(rach_ConfigGeneric->zeroCorrelationZoneConfig, format0, setup->restrictedSetConfig);
@@ -1767,11 +1772,10 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
AssertFatal(1 == 0, "Invalid PRACH format");
}
} // if format1
fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP, thread_id);
if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
mac->if_module->scheduled_response(&scheduled_response);
} // is_nr_prach_slot
fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP, thread_id);
if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
mac->if_module->scheduled_response(&scheduled_response);
} // if is_nr_UL_slot
}
+31 -15
View File
@@ -45,7 +45,7 @@
#include "NR_MIB.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
#include "../../../../nfapi/oai_integration/vendor_ext.h"
/* Softmodem params */
#include "executables/softmodem-common.h"
@@ -127,8 +127,7 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, int pusch_AntennaPorts,
uint32_t band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
frequency_range_t frequency_range = band<100?FR1:FR2;
lte_frame_type_t frame_type;
get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing, &frame_type);
lte_frame_type_t frame_type = get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
RC.nrmac[Mod_idP]->common_channels[0].frame_type = frame_type;
// Cell configuration
@@ -264,6 +263,7 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, int pusch_AntennaPorts,
}
cfg->ssb_table.ssb_mask_list[0].ssb_mask.tl.tag = NFAPI_NR_CONFIG_SSB_MASK_TAG;
cfg->ssb_table.ssb_mask_list[1].ssb_mask.tl.tag = NFAPI_NR_CONFIG_SSB_MASK_TAG;
cfg->num_tlv++;
cfg->carrier_config.num_tx_ant.value = pdsch_AntennaPorts;
@@ -306,7 +306,7 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, int pusch_AntennaPorts,
if (return_tdd != 0)
LOG_E(MAC,"TDD configuration can not be done\n");
else
LOG_I(MAC,"TDD has been properly configurated\n");
LOG_I(MAC,"TDD has been properly configurated\n");
}
}
@@ -369,11 +369,11 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
LOG_E(MAC, "%s() %s:%d RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req:%p\n", __FUNCTION__, __FILE__, __LINE__, RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req);
// if in nFAPI mode
if ( (nfapi_mode == 1 || nfapi_mode == 2) && (RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req == NULL) ){
if ( (NFAPI_MODE == NFAPI_MODE_PNF || NFAPI_MODE == NFAPI_MODE_VNF) && (RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req == NULL) ){
while(RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req == NULL) {
// DJP AssertFatal(RC.nrmac[Mod_idP]->if_inst->PHY_config_req != NULL,"if_inst->phy_config_request is null\n");
usleep(100 * 1000);
printf("Waiting for PHY_config_req\n");
// DJP AssertFatal(RC.nrmac[Mod_idP]->if_inst->PHY_config_req != NULL,"if_inst->phy_config_request is null\n");
usleep(100 * 1000);
printf("Waiting for PHY_config_req\n");
}
}
@@ -403,21 +403,37 @@ 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;
}
}
}
}
}
LOG_I(PHY,"Added new RA process for UE RNTI %04x with initial secondaryCellGroup\n", rnti);
+11 -2
View File
@@ -52,6 +52,7 @@
#include "intertask_interface.h"
#include "executables/softmodem-common.h"
#include "nfapi/oai_integration/vendor_ext.h"
uint16_t nr_pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 };
@@ -104,7 +105,7 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
gNB->pdu_index[CC_idP] = 0;
if (nfapi_mode==0 || nfapi_mode == 1) { // monolithic or PNF
if (NFAPI_MODE == NFAPI_MONOLITHIC || NFAPI_MODE == NFAPI_MODE_PNF) { // monolithic or PNF
DL_req[CC_idP].SFN = frameP;
DL_req[CC_idP].Slot = slotP;
@@ -363,14 +364,22 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
/* send tick to RLC and RRC every ms */
if ((slot & ((1 << *scc->ssbSubcarrierSpacing) - 1)) == 0) {
void nr_rlc_tick(int frame, int subframe);
void nr_pdcp_tick(int frame, int subframe);
nr_rlc_tick(frame, slot >> *scc->ssbSubcarrierSpacing);
nr_pdcp_tick(frame, slot >> *scc->ssbSubcarrierSpacing);
nr_rrc_trigger(&ctxt, 0 /*CC_id*/, frame, slot >> *scc->ssbSubcarrierSpacing);
}
#define BIT(x) (1 << (x))
const uint64_t dlsch_in_slot_bitmap = BIT( 1) | BIT( 2) | BIT( 3) | BIT( 4) | BIT( 5) | BIT( 6)
| BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(15) | BIT(16);
const uint64_t ulsch_in_slot_bitmap = BIT( 8) | BIT(18);
uint8_t prach_config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex;
uint64_t ulsch_in_slot_bitmap;
if (prach_config_index==4) //this is the PRACH config used in the Benetel RRU. TODO: make this generic for any PRACH config.
ulsch_in_slot_bitmap = BIT( 8) | BIT( 9);
else
ulsch_in_slot_bitmap = BIT( 8) | BIT(18);
memset(RC.nrmac[module_idP]->cce_list[bwp_id][0],0,MAX_NUM_CCE*sizeof(int)); // coreset0
memset(RC.nrmac[module_idP]->cce_list[bwp_id][1],0,MAX_NUM_CCE*sizeof(int)); // coresetid 1
+244 -176
View File
@@ -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)
@@ -210,7 +245,8 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP
nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[module_idP]->UL_tti_req_ahead[0][slotP];
nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[module_idP]->config[0];
if (is_nr_UL_slot(scc,slotP)) {
if (is_nr_UL_slot(scc, slotP, cc->frame_type)) {
uint8_t config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex;
uint8_t mu,N_dur,N_t_slot,start_symbol = 0,N_RA_slot;
uint16_t RA_sfn_index = -1;
@@ -439,139 +475,167 @@ 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 = 64;
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 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( scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles != NULL)
total_RApreambles = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles;
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);
int loop = 0;
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);
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_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);
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
}
}
int loop = 0;
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);
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_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;
}
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){
//uint8_t i = 0;
int CC_id = 0;
void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
{
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:
//generate_Msg4(module_idP, CC_id, frameP, slotP);
break;
case WAIT_Msg4_ACK:
//check_Msg4_retransmission(module_idP, CC_id, frameP, slotP);
break;
default:
break;
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(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:
// generate_Msg4(module_idP, CC_id, frameP, slotP);
break;
case WAIT_Msg4_ACK:
// check_Msg4_retransmission(module_idP, CC_id, frameP, slotP);
break;
default:
break;
}
}
}
// }
// }
stop_meas(&mac->schedule_ra);
}
@@ -584,7 +648,8 @@ void nr_get_Msg3alloc(module_id_t module_id,
NR_RA_t *ra) {
// msg3 is schedulend in mixed slot in the following TDD period
// for now we consider a TBS of 18 bytes
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;
@@ -614,30 +679,30 @@ void nr_get_Msg3alloc(module_id_t module_id,
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 18 free RBs */
/* search msg3_nb_rb free RBs */
int rbSize = 0;
int rbStart = 0;
while (rbSize < 18) {
while (rbSize < msg3_nb_rb) {
rbStart += rbSize; /* last iteration rbSize was not enough, skip it */
rbSize = 0;
while (rbStart < bwpSize && vrb_map_UL[rbStart])
rbStart++;
AssertFatal(rbStart < bwpSize - 18, "no space to allocate Msg 3 for RA!\n");
AssertFatal(rbStart < bwpSize - msg3_nb_rb, "no space to allocate Msg 3 for RA!\n");
while (rbStart + rbSize < bwpSize
&& !vrb_map_UL[rbStart + rbSize]
&& rbSize < 18)
&& rbSize < msg3_nb_rb)
rbSize++;
}
ra->msg3_nb_rb = 18;
ra->msg3_nb_rb = msg3_nb_rb;
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);
@@ -752,27 +817,25 @@ 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)
{
int mcsIndex;
int startSymbolAndLength = 0, StartSymbolIndex = -1, NrOfSymbols = 14, StartSymbolIndex_tmp, NrOfSymbols_tmp, x_Overhead, time_domain_assignment = 0;
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[CC_id];
NR_SearchSpace_t *ss = ra->ra_ss;
// 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->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
"downlinkBWP_ToAddModList has %d BWP!\n",
ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
uint16_t RA_rnti = ra->RA_rnti;
long locationAndBandwidth;
@@ -780,7 +843,7 @@ void nr_generate_Msg2(module_id_t module_idP,
// get the BW of the PDCCH for PDCCH size and RAR PDSCH size
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
int dci10_bw;
int dci10_bw = 0;
if (ra->coreset0_configured == 1) {
AssertFatal(1==0,"This is a standalone condition\n");
@@ -792,8 +855,24 @@ void nr_generate_Msg2(module_id_t module_idP,
if ((ra->Msg2_frame == frameP) && (ra->Msg2_slot == slotP)) {
uint16_t *vrb_map = cc[CC_id].vrb_map;
int rbStart = 0, rbSize = 6;
for (int i = 0; (i < rbSize) && (rbStart <= (dci10_bw - rbSize)); i++) {
if (vrb_map[rbStart + i]) {
rbStart += i;
i = 0;
}
}
if (rbStart > (dci10_bw - rbSize)) {
LOG_E(MAC, "%s(): cannot find free vrb_map for RA RNTI %04x!\n", __func__, ra->RA_rnti);
return;
}
nfapi_nr_dl_tti_request_body_t *dl_req = &nr_mac->DL_req[CC_id].dl_tti_request_body;
// Checking if the DCI allocation is feasible in current subframe
// Checking if the DCI allocation is feasible in current subframe: we might
// need to need up to two (PDCCH + PDSCH) messages, so check that we can
// always allocate both (this might be an overestimation, since the PDCCH
// message might already exist)
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_rnti);
return;
@@ -816,8 +895,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 */
@@ -844,14 +921,6 @@ void nr_generate_Msg2(module_id_t module_idP,
LOG_I(MAC,"[gNB %d] [RAPROC] CC_id %d Frame %d, slotP %d: Generating RAR 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->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);
NR_BWP_Uplink_t *ubwp=ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id-1];
LOG_I(MAC, "[RAPROC] Scheduling common search space DCI type 1 dlBWP BW %d\n", dci10_bw);
@@ -898,8 +967,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; // non interleaved
for (int i=0; i<bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count; i++) {
@@ -974,17 +1043,8 @@ void nr_generate_Msg2(module_id_t module_idP,
dci10_bw,
ra->bwp_id);
// Program UL processing for Msg3
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;
@@ -992,16 +1052,24 @@ 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_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, (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_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_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;
for (int rb = 0; rb < rbSize; rb++)
vrb_map[rb + rbStart] = 1;
}
}
@@ -235,6 +235,7 @@ void schedule_control_sib1(module_id_t module_id,
int time_domain_allocation,
uint8_t mcsTableIdx,
uint8_t mcs,
uint8_t candidate_idx,
int num_total_bytes) {
gNB_MAC_INST *gNB_mac = RC.nrmac[module_id];
@@ -266,13 +267,10 @@ void schedule_control_sib1(module_id_t module_id,
gNB_mac->sched_ctrlCommon->coreset,
gNB_mac->sched_ctrlCommon->aggregation_level,
0,
0,
candidate_idx,
nr_of_candidates);
if (gNB_mac->sched_ctrlCommon->cce_index < 0) {
LOG_E(MAC, "%s(): could not find CCE for coreset0\n", __func__);
return;
}
AssertFatal(gNB_mac->sched_ctrlCommon->cce_index >= 0, "Could not find CCE for coreset0\n");
const uint16_t bwpSize = gNB_mac->type0_PDCCH_CSS_config.num_rbs;
int rbStart = gNB_mac->type0_PDCCH_CSS_config.cset_start_rb;
@@ -301,9 +299,7 @@ void schedule_control_sib1(module_id_t module_id,
TBS = nr_compute_tbs(nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx),
nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx),
rbSize, nrOfSymbols, N_PRB_DMRS * dmrs_length,0, 0,1) >> 3;
// FIXME: Something is not working in nr_modulation() for TBS = 84, so we need to skip it
} while ( (rbStart + rbSize < bwpSize && !vrb_map[rbStart + rbSize] && TBS < gNB_mac->sched_ctrlCommon->num_total_bytes) || (TBS==84) );
} while (rbStart + rbSize < bwpSize && !vrb_map[rbStart + rbSize] && TBS < gNB_mac->sched_ctrlCommon->num_total_bytes);
gNB_mac->sched_ctrlCommon->rbSize = rbSize;
gNB_mac->sched_ctrlCommon->rbStart = 0;
@@ -467,6 +463,7 @@ void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
int time_domain_allocation = 0;
uint8_t mcsTableIdx = 0;
uint8_t mcs = 6;
uint8_t candidate_idx = 0;
gNB_MAC_INST *gNB_mac = RC.nrmac[module_idP];
@@ -482,7 +479,7 @@ void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
for (int i=0;i<sib1_sdu_length;i++) LOG_D(MAC,"byte %d : %x\n",i,((uint8_t*)sib1_payload)[i]);
// Configure sched_ctrlCommon for SIB1
schedule_control_sib1(module_idP, CC_id, time_domain_allocation, mcsTableIdx, mcs, sib1_sdu_length);
schedule_control_sib1(module_idP, CC_id, time_domain_allocation, mcsTableIdx, mcs, candidate_idx, sib1_sdu_length);
// Calculate number of symbols
int startSymbolIndex, nrOfSymbols;
@@ -1045,7 +1045,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
size += 3;
}
}
else if (get_softmodem_params()->phy_test || get_softmodem_params()->do_ra) {
else if (get_softmodem_params()->phy_test || get_softmodem_params()->do_ra || get_softmodem_params()->sa) {
/* we will need the large header, phy-test typically allocates all
* resources and fills to the last byte below */
NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *) buf;
@@ -103,7 +103,7 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
dl_tti_pdcch_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE;
dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs+1];
dl_tti_pdsch_pdu = &nr_mac->DL_req[CC_id].dl_tti_request_body.dl_tti_pdu_list[nr_mac->DL_req[CC_id].dl_tti_request_body.nPDUs+1];
memset((void *)dl_tti_pdsch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
dl_tti_pdsch_pdu->PDUType = NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE;
dl_tti_pdsch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdsch_pdu));
@@ -238,14 +238,16 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
pdsch_pdu_rel15->mcsIndex[0]);
*/
dl_req->nPDUs+=2;
nr_mac->DL_req[CC_id].dl_tti_request_body.nPDUs+=2;
TX_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs];
TX_req->PDU_length = 6;
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;
@@ -31,6 +31,7 @@
#include "NR_MAC_COMMON/nr_mac_extern.h"
#include "NR_MAC_gNB/mac_proto.h"
#include "common/ran_context.h"
#include "nfapi/oai_integration/vendor_ext.h"
extern RAN_CONTEXT_t RC;
@@ -395,7 +395,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
T_BUFFER(sduP, sdu_lenP));
UE_info->mac_stats[UE_id].ulsch_total_bytes_rx += sdu_lenP;
LOG_D(MAC, "[gNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu from PHY (rnti %x, UE_id %d) ul_cqi %d\n",
LOG_D(NR_MAC, "[gNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu from PHY (rnti %x, UE_id %d) ul_cqi %d sduP %p\n",
gnb_mod_idP,
harq_pid,
CC_idP,
@@ -403,7 +403,8 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
slotP,
current_rnti,
UE_id,
ul_cqi);
ul_cqi,
sduP);
// if not missed detection (10dB threshold for now)
if (UE_scheduling_control->ul_rssi < (100+rssi)) {
@@ -411,7 +412,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
if (timing_advance != 0xffff)
UE_scheduling_control->ta_update = timing_advance;
UE_scheduling_control->ul_rssi = rssi;
LOG_D(MAC, "[UE %d] PUSCH TPC %d and TA %d\n",UE_id,UE_scheduling_control->tpc0,UE_scheduling_control->ta_update);
LOG_D(NR_MAC, "[UE %d] PUSCH TPC %d and TA %d\n",UE_id,UE_scheduling_control->tpc0,UE_scheduling_control->ta_update);
}
else{
UE_scheduling_control->tpc0 = 1;
@@ -430,9 +431,10 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
#endif
if (sduP != NULL){
LOG_D(MAC, "Received PDU at MAC gNB \n");
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 +444,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;
}
@@ -465,7 +468,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
// random access pusch with TC-RNTI
if (ra->rnti != current_rnti) {
LOG_W(MAC,
LOG_W(NR_MAC,
"expected TC-RNTI %04x to match current RNTI %04x\n",
ra->rnti,
current_rnti);
@@ -473,19 +476,25 @@ 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(MAC,
LOG_I(NR_MAC,
"[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_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]);
}
// re-initialize ta update variables afrer RA procedure completion
UE_info->UE_sched_ctrl[UE_id].ta_frame = frameP;
free(ra->preambles.preamble_list);
ra->state = RA_IDLE;
LOG_I(MAC,
LOG_I(NR_MAC,
"reset RA state information for RA-RNTI %04x/index %d\n",
ra->rnti,
i);
@@ -862,7 +871,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;
@@ -916,6 +925,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",
@@ -929,7 +939,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",
@@ -1130,4 +1139,4 @@ void nr_schedule_ulsch(module_id_t module_id,
memset(sched_pusch, 0, sizeof(*sched_pusch));
}
}
}
+2 -5
View File
@@ -75,6 +75,7 @@ void schedule_control_sib1(module_id_t module_id,
int time_domain_allocation,
uint8_t mcsTableIdx,
uint8_t mcs,
uint8_t candidate_idx,
int num_total_bytes);
void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP);
@@ -348,11 +349,7 @@ void config_nr_mib(int Mod_idP,
int cellBarred,
int intraFreqReselection);
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_process_mac_pdu(
module_id_t module_idP,
+1 -1
View File
@@ -96,7 +96,7 @@ void mac_top_init_gNB(void)
// These should be out of here later
pdcp_layer_init();
if(IS_SOFTMODEM_NOS1 && !get_softmodem_params()->do_ra)
if(IS_SOFTMODEM_NOS1 && !(get_softmodem_params()->do_ra || get_softmodem_params()->sa) )
nr_DRB_preconfiguration(0x1234);
rrc_init_nr_global_param();
+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;
+1 -2
View File
@@ -2098,8 +2098,7 @@ pdcp_config_set_security(
}
//-----------------------------------------------------------------------------
void
rrc_pdcp_config_req (
void rrc_pdcp_config_req (
const protocol_ctxt_t *const ctxt_pP,
const srb_flag_t srb_flagP,
const uint32_t actionP,
+252 -25
View File
@@ -21,24 +21,223 @@
#include "nr_pdcp_entity.h"
#include "nr_pdcp_entity_drb_am.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "nr_pdcp_security_nea2.h"
#include "nr_pdcp_sdu.h"
#include "LOG/log.h"
nr_pdcp_entity_t *new_nr_pdcp_entity_srb(
int rb_id,
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
char *buf, int size),
void *deliver_sdu_data,
void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity,
char *buf, int size, int sdu_id),
void *deliver_pdu_data)
static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
char *_buffer, int size)
{
abort();
unsigned char *buffer = (unsigned char *)_buffer;
nr_pdcp_sdu_t *sdu;
int rcvd_sn;
uint32_t rcvd_hfn;
uint32_t rcvd_count;
int header_size;
int integrity_size;
int rx_deliv_sn;
uint32_t rx_deliv_hfn;
if (size < 1) {
LOG_E(PDCP, "bad PDU received (size = %d)\n", size);
return;
}
if (!(buffer[0] & 0x80)) {
LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
if (entity->sn_size == 12) {
rcvd_sn = (((unsigned char)buffer[0] & 0xf) << 8) |
(unsigned char)buffer[1];
header_size = 2;
} else {
rcvd_sn = (((unsigned char)buffer[0] & 0x3) << 16) |
((unsigned char)buffer[1] << 8) |
(unsigned char)buffer[2];
header_size = 3;
}
integrity_size = 0;
if (size < header_size + integrity_size + 1) {
LOG_E(PDCP, "bad PDU received (size = %d)\n", size);
return;
}
rx_deliv_sn = entity->rx_deliv & entity->sn_max;
rx_deliv_hfn = (entity->rx_deliv >> entity->sn_size) & ~entity->sn_max;
if (rcvd_sn < rx_deliv_sn - entity->window_size) {
rcvd_hfn = rx_deliv_hfn + 1;
} else if (rcvd_sn >= rx_deliv_sn + entity->window_size) {
rcvd_hfn = rx_deliv_hfn - 1;
} else {
rcvd_hfn = rx_deliv_hfn;
}
rcvd_count = (rcvd_hfn << entity->sn_size) | rcvd_sn;
if (entity->has_ciphering)
entity->cipher(entity->security_context,
(unsigned char *)buffer+header_size, size-header_size,
entity->rb_id, rcvd_count, entity->is_gnb ? 0 : 1);
if (rcvd_count < entity->rx_deliv
|| nr_pdcp_sdu_in_list(entity->rx_list, rcvd_count)) {
LOG_D(PDCP, "discard NR PDU rcvd_count=%d\n", rcvd_count);
return;
}
sdu = nr_pdcp_new_sdu(rcvd_count,
(char *)buffer + header_size,
size - header_size - integrity_size);
entity->rx_list = nr_pdcp_sdu_list_add(entity->rx_list, sdu);
entity->rx_size += size-header_size;
if (rcvd_count >= entity->rx_next) {
entity->rx_next = rcvd_count + 1;
}
/* TODO(?): out of order delivery */
if (rcvd_count == entity->rx_deliv) {
/* deliver all SDUs starting from rx_deliv up to discontinuity or end of list */
uint32_t count = entity->rx_deliv;
while (entity->rx_list != NULL && count == entity->rx_list->count) {
nr_pdcp_sdu_t *cur = entity->rx_list;
entity->deliver_sdu(entity->deliver_sdu_data, entity,
cur->buffer, cur->size);
entity->rx_list = cur->next;
entity->rx_size -= cur->size;
nr_pdcp_free_sdu(cur);
count++;
}
entity->rx_deliv = count;
}
if (entity->t_reordering_start != 0 && entity->rx_deliv > entity->rx_reord) {
/* stop and reset t-Reordering */
entity->t_reordering_start = 0;
}
if (entity->t_reordering_start == 0 && entity->rx_deliv < entity->rx_next) {
entity->rx_reord = entity->rx_next;
entity->t_reordering_start = entity->t_current;
}
}
nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am(
int rb_id,
static void nr_pdcp_entity_recv_sdu(nr_pdcp_entity_t *entity,
char *buffer, int size, int sdu_id)
{
uint32_t count;
int sn;
int header_size;
char buf[size+3+4];
count = entity->tx_next;
sn = entity->tx_next & entity->sn_max;
if (entity->sn_size == 12) {
buf[0] = 0x80 | ((sn >> 8) & 0xf);
buf[1] = sn & 0xff;
header_size = 2;
} else {
buf[0] = 0x80 | ((sn >> 16) & 0x3);
buf[1] = (sn >> 8) & 0xff;
buf[2] = sn & 0xff;
header_size = 3;
}
memcpy(buf+header_size, buffer, size);
if (entity->has_ciphering)
entity->cipher(entity->security_context,
(unsigned char *)buf+header_size, size,
entity->rb_id, count, entity->is_gnb ? 1 : 0);
entity->tx_next++;
entity->deliver_pdu(entity->deliver_pdu_data, entity, buf,
size+header_size, sdu_id);
}
static void nr_pdcp_entity_set_integrity_key(nr_pdcp_entity_t *entity,
char *key)
{
memcpy(entity->integrity_key, key, 16);
}
static void check_t_reordering(nr_pdcp_entity_t *entity)
{
uint32_t count;
if (entity->t_reordering_start == 0
|| entity->t_current <= entity->t_reordering_start + entity->t_reordering)
return;
/* stop timer */
entity->t_reordering_start = 0;
/* deliver all SDUs with count < rx_reord */
while (entity->rx_list != NULL && entity->rx_list->count < entity->rx_reord) {
nr_pdcp_sdu_t *cur = entity->rx_list;
entity->deliver_sdu(entity->deliver_sdu_data, entity,
cur->buffer, cur->size);
entity->rx_list = cur->next;
entity->rx_size -= cur->size;
nr_pdcp_free_sdu(cur);
}
/* deliver all SDUs starting from rx_reord up to discontinuity or end of list */
count = entity->rx_reord;
while (entity->rx_list != NULL && count == entity->rx_list->count) {
nr_pdcp_sdu_t *cur = entity->rx_list;
entity->deliver_sdu(entity->deliver_sdu_data, entity,
cur->buffer, cur->size);
entity->rx_list = cur->next;
entity->rx_size -= cur->size;
nr_pdcp_free_sdu(cur);
count++;
}
entity->rx_deliv = count;
if (entity->rx_deliv < entity->rx_next) {
entity->rx_reord = entity->rx_next;
entity->t_reordering_start = entity->t_current;
}
}
void nr_pdcp_entity_set_time(struct nr_pdcp_entity_t *entity, uint64_t now)
{
entity->t_current = now;
check_t_reordering(entity);
}
void nr_pdcp_entity_delete(nr_pdcp_entity_t *entity)
{
nr_pdcp_sdu_t *cur = entity->rx_list;
while (cur != NULL) {
nr_pdcp_sdu_t *next = cur->next;
nr_pdcp_free_sdu(cur);
cur = next;
}
if (entity->free_security != NULL)
entity->free_security(entity->security_context);
free(entity);
}
nr_pdcp_entity_t *new_nr_pdcp_entity(
nr_pdcp_entity_type_t type,
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,34 +246,62 @@ 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;
nr_pdcp_entity_t *ret;
ret = calloc(1, sizeof(nr_pdcp_entity_drb_am_t));
ret = calloc(1, sizeof(nr_pdcp_entity_t));
if (ret == NULL) {
LOG_E(PDCP, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
ret->common.recv_pdu = nr_pdcp_entity_drb_am_recv_pdu;
ret->common.recv_sdu = nr_pdcp_entity_drb_am_recv_sdu;
ret->common.set_integrity_key = nr_pdcp_entity_drb_am_set_integrity_key;
ret->type = type;
ret->common.delete = nr_pdcp_entity_drb_am_delete;
ret->recv_pdu = nr_pdcp_entity_recv_pdu;
ret->recv_sdu = nr_pdcp_entity_recv_sdu;
ret->set_integrity_key = nr_pdcp_entity_set_integrity_key;
ret->set_time = nr_pdcp_entity_set_time;
ret->common.deliver_sdu = deliver_sdu;
ret->common.deliver_sdu_data = deliver_sdu_data;
ret->delete = nr_pdcp_entity_delete;
ret->common.deliver_pdu = deliver_pdu;
ret->common.deliver_pdu_data = deliver_pdu_data;
ret->deliver_sdu = deliver_sdu;
ret->deliver_sdu_data = deliver_sdu_data;
ret->deliver_pdu = deliver_pdu;
ret->deliver_pdu_data = deliver_pdu_data;
ret->rb_id = rb_id;
ret->sn_size = sn_size;
ret->t_reordering = t_reordering;
ret->discard_timer = discard_timer;
ret->common.maximum_nr_pdcp_sn = (1 << sn_size) - 1;
ret->sn_max = (1 << sn_size) - 1;
ret->window_size = 1 << (sn_size - 1);
return (nr_pdcp_entity_t *)ret;
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->has_ciphering = 1;
ret->ciphering_algorithm = ciphering_algorithm;
memcpy(ret->ciphering_key, ciphering_key, 16);
ret->security_context = nr_pdcp_security_nea2_init(ciphering_key);
ret->cipher = nr_pdcp_security_nea2_cipher;
ret->free_security = nr_pdcp_security_nea2_free_security;
}
ret->is_gnb = is_gnb;
if (integrity_key != NULL) {
printf("%s:%d:%s: TODO\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
return ret;
}
+66 -17
View File
@@ -19,18 +19,29 @@
* contact@openairinterface.org
*/
#include <stdint.h>
#ifndef _NR_PDCP_ENTITY_H_
#define _NR_PDCP_ENTITY_H_
#include <stdint.h>
#include "nr_pdcp_sdu.h"
typedef enum {
NR_PDCP_DRB_AM,
NR_PDCP_DRB_UM,
NR_PDCP_SRB
} nr_pdcp_entity_type_t;
typedef struct nr_pdcp_entity_t {
nr_pdcp_entity_type_t type;
/* functions provided by the PDCP module */
void (*recv_pdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size);
void (*recv_sdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size,
int sdu_id);
void (*delete)(struct nr_pdcp_entity_t *entity);
void (*set_integrity_key)(struct nr_pdcp_entity_t *entity, char *key);
void (*set_time)(struct nr_pdcp_entity_t *entity, uint64_t now);
/* callbacks provided to the PDCP module */
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
@@ -39,22 +50,56 @@ typedef struct nr_pdcp_entity_t {
void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity,
char *buf, int size, int sdu_id);
void *deliver_pdu_data;
int tx_hfn;
int next_nr_pdcp_tx_sn;
int maximum_nr_pdcp_sn;
/* configuration variables */
int rb_id;
int sn_size; /* SN size, in bits */
int t_reordering; /* unit: ms */
int discard_timer; /* unit: ms */
int sn_max; /* (2^SN_size) - 1 */
int window_size; /* 2^(SN_size - 1) */
/* state variables */
uint32_t tx_next;
uint32_t rx_next;
uint32_t rx_deliv;
uint32_t rx_reord;
/* set to the latest know time by the user of the module. Unit: ms */
uint64_t t_current;
/* timers (stores the ms of activation, 0 means not active) */
int t_reordering_start;
/* 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;
/* rx management */
nr_pdcp_sdu_t *rx_list;
int rx_size;
int rx_maxsize;
} nr_pdcp_entity_t;
nr_pdcp_entity_t *new_nr_pdcp_entity_srb(
int rb_id,
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
char *buf, int size),
void *deliver_sdu_data,
void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity,
char *buf, int size, int sdu_id),
void *deliver_pdu_data);
nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am(
int rb_id,
nr_pdcp_entity_t *new_nr_pdcp_entity(
nr_pdcp_entity_type_t type,
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 +108,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);
@@ -1,75 +0,0 @@
/*
* 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_entity_drb_am.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "common/utils/LOG/log.h"
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;
if (size < 3) abort();
if (!(buffer[0] & 0x80))
LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
entity->common.deliver_sdu(entity->common.deliver_sdu_data,
(nr_pdcp_entity_t *)entity, buffer+3, size-3);
}
void nr_pdcp_entity_drb_am_recv_sdu(nr_pdcp_entity_t *_entity, char *buffer, int size,
int sdu_id)
{
nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity;
int sn;
char buf[size+3];
sn = entity->common.next_nr_pdcp_tx_sn;
entity->common.next_nr_pdcp_tx_sn++;
if (entity->common.next_nr_pdcp_tx_sn > entity->common.maximum_nr_pdcp_sn) {
entity->common.next_nr_pdcp_tx_sn = 0;
entity->common.tx_hfn++;
}
buf[0] = 0x80 | ((sn >> 16) & 0x3);
buf[1] = (sn >> 8) & 0xff;
buf[2] = sn & 0xff;
memcpy(buf+3, buffer, size);
entity->common.deliver_pdu(entity->common.deliver_pdu_data,
(nr_pdcp_entity_t *)entity, buf, size+3, sdu_id);
}
void nr_pdcp_entity_drb_am_set_integrity_key(nr_pdcp_entity_t *_entity, char *key)
{
/* nothing to do */
}
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;
free(entity);
}
+48 -9
View File
@@ -24,6 +24,7 @@
#endif
#include "asn1_utils.h"
#include "nr_pdcp_ue_manager.h"
#include "nr_pdcp_timer_thread.h"
#include "NR_RadioBearerConfig.h"
#include "NR_RLC-BearerConfig.h"
#include "NR_RLC-Config.h"
@@ -41,6 +42,11 @@
static nr_pdcp_ue_manager_t *nr_pdcp_ue_manager;
/* TODO: handle time a bit more properly */
static uint64_t nr_pdcp_current_time;
static int nr_pdcp_current_time_last_frame;
static int nr_pdcp_current_time_last_subframe;
/* necessary globals for OAI, not used internally */
hash_table_t *pdcp_coll_p;
static uint64_t pdcp_optmask;
@@ -339,6 +345,8 @@ void pdcp_layer_init(void)
nr_pdcp_ue_manager = new_nr_pdcp_ue_manager(1);
init_nr_rlc_data_req_queue();
nr_pdcp_init_timer_thread(nr_pdcp_ue_manager);
}
#include "nfapi/oai_integration/vendor_ext.h"
@@ -591,7 +599,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 +633,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(NR_PDCP_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 +645,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 +679,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 +699,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 +716,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 +731,7 @@ boolean_t nr_rrc_pdcp_config_asn1_req(
free(kRRCenc);
free(kRRCint);
free(kUPenc);
free(kUPint);
return 0;
}
@@ -805,6 +832,7 @@ void nr_DRB_preconfiguration(uint16_t crnti)
NULL,
NULL,
NULL,
NULL,
Rlc_Bearer_ToAdd_list);
nr_rrc_rlc_config_asn1_req (&ctxt,
@@ -956,3 +984,14 @@ void
pdcp_mbms_run ( const protocol_ctxt_t *const ctxt_pP){
/* nothing to do */
}
void nr_pdcp_tick(int frame, int subframe)
{
if (frame != nr_pdcp_current_time_last_frame ||
subframe != nr_pdcp_current_time_last_subframe) {
nr_pdcp_current_time_last_frame = frame;
nr_pdcp_current_time_last_subframe = subframe;
nr_pdcp_current_time++;
nr_pdcp_wakeup_timer_thread(nr_pdcp_current_time);
}
}
+78
View File
@@ -0,0 +1,78 @@
/*
* 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_sdu.h"
#include <stdlib.h>
#include <string.h>
nr_pdcp_sdu_t *nr_pdcp_new_sdu(uint32_t count, char *buffer, int size)
{
nr_pdcp_sdu_t *ret = calloc(1, sizeof(nr_pdcp_sdu_t));
if (ret == NULL)
exit(1);
ret->count = count;
ret->buffer = malloc(size);
if (ret->buffer == NULL)
exit(1);
memcpy(ret->buffer, buffer, size);
ret->size = size;
return ret;
}
nr_pdcp_sdu_t *nr_pdcp_sdu_list_add(nr_pdcp_sdu_t *l, nr_pdcp_sdu_t *sdu)
{
nr_pdcp_sdu_t head;
nr_pdcp_sdu_t *cur;
nr_pdcp_sdu_t *prev;
head.next = l;
cur = l;
prev = &head;
/* order is by 'count' */
while (cur != NULL) {
/* check if 'sdu' is before 'cur' in the list */
if (sdu->count < cur->count)
break;
prev = cur;
cur = cur->next;
}
prev->next = sdu;
sdu->next = cur;
return head.next;
}
int nr_pdcp_sdu_in_list(nr_pdcp_sdu_t *l, uint32_t count)
{
while (l != NULL) {
if (l->count == count)
return 1;
l = l->next;
}
return 0;
}
void nr_pdcp_free_sdu(nr_pdcp_sdu_t *sdu)
{
free(sdu->buffer);
free(sdu);
}
@@ -19,23 +19,21 @@
* contact@openairinterface.org
*/
#ifndef _NR_PDCP_ENTITY_DRB_AM_H_
#define _NR_PDCP_ENTITY_DRB_AM_H_
#ifndef _NR_PDCP_SDU_H_
#define _NR_PDCP_SDU_H_
#include "nr_pdcp_entity.h"
#include <stdint.h>
typedef struct {
nr_pdcp_entity_t common;
int rb_id;
int sn_size; /* unit: bits */
int t_reordering; /* unit: ms */
int discard_timer; /* unit: ms, -1 means infinity */
} nr_pdcp_entity_drb_am_t;
typedef struct nr_pdcp_sdu_t {
uint32_t count;
char *buffer;
int size;
struct nr_pdcp_sdu_t *next;
} nr_pdcp_sdu_t;
void nr_pdcp_entity_drb_am_recv_pdu(nr_pdcp_entity_t *entity, char *buffer, int size);
void nr_pdcp_entity_drb_am_recv_sdu(nr_pdcp_entity_t *entity, char *buffer, int size,
int sdu_id);
void nr_pdcp_entity_drb_am_set_integrity_key(nr_pdcp_entity_t *entity, char *key);
void nr_pdcp_entity_drb_am_delete(nr_pdcp_entity_t *entity);
nr_pdcp_sdu_t *nr_pdcp_new_sdu(uint32_t count, char *buffer, int size);
nr_pdcp_sdu_t *nr_pdcp_sdu_list_add(nr_pdcp_sdu_t *l, nr_pdcp_sdu_t *sdu);
int nr_pdcp_sdu_in_list(nr_pdcp_sdu_t *l, uint32_t count);
void nr_pdcp_free_sdu(nr_pdcp_sdu_t *sdu);
#endif /* _NR_PDCP_ENTITY_DRB_AM_H_ */
#endif /* _NR_PDCP_SDU_H_ */
@@ -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_ */
@@ -0,0 +1,87 @@
/*
* 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_timer_thread.h"
#include <stdlib.h>
#include <pthread.h>
#include <stdint.h>
#include "LOG/log.h"
static pthread_mutex_t timer_thread_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t timer_thread_cond = PTHREAD_COND_INITIALIZER;
static volatile uint64_t timer_thread_curtime = 0;
static void *nr_pdcp_timer_thread(void *_nr_pdcp_ue_manager)
{
nr_pdcp_ue_manager_t *nr_pdcp_ue_manager = (nr_pdcp_ue_manager_t *)_nr_pdcp_ue_manager;
nr_pdcp_ue_t **ue_list;
int ue_count;
int i;
int j;
uint64_t curtime = 0;
while (1) {
if (pthread_mutex_lock(&timer_thread_mutex) != 0) abort();
while (curtime == timer_thread_curtime)
if (pthread_cond_wait(&timer_thread_cond, &timer_thread_mutex) != 0) abort();
curtime = timer_thread_curtime;
if (pthread_mutex_unlock(&timer_thread_mutex) != 0) abort();
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
ue_list = nr_pdcp_manager_get_ue_list(nr_pdcp_ue_manager);
ue_count = nr_pdcp_manager_get_ue_count(nr_pdcp_ue_manager);
for (i = 0; i < ue_count; i++) {
for (j = 0; j < 2; j++) {
if (ue_list[i]->srb[j] != NULL)
ue_list[i]->srb[j]->set_time(ue_list[i]->srb[j], curtime);
}
for (j = 0; j < 5; j++) {
if (ue_list[i]->drb[j] != NULL)
ue_list[i]->drb[j]->set_time(ue_list[i]->drb[j], curtime);
}
}
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
}
return NULL;
}
void nr_pdcp_init_timer_thread(nr_pdcp_ue_manager_t *nr_pdcp_ue_manager)
{
pthread_t t;
if (pthread_create(&t, NULL, nr_pdcp_timer_thread, nr_pdcp_ue_manager) != 0) {
LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
}
void nr_pdcp_wakeup_timer_thread(uint64_t time)
{
if (pthread_mutex_lock(&timer_thread_mutex)) abort();
timer_thread_curtime = time;
if (pthread_cond_broadcast(&timer_thread_cond)) abort();
if (pthread_mutex_unlock(&timer_thread_mutex)) abort();
}
@@ -0,0 +1,32 @@
/*
* 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_TIMER_THREAD_H_
#define _NR_PDCP_TIMER_THREAD_H_
#include "nr_pdcp_ue_manager.h"
#include <stdint.h>
void nr_pdcp_init_timer_thread(nr_pdcp_ue_manager_t *nr_pdcp_ue_manager);
void nr_pdcp_wakeup_timer_thread(uint64_t time);
#endif /* _NR_PDCP_TIMER_THREAD_H_ */
@@ -189,6 +189,20 @@ void nr_pdcp_ue_add_drb_pdcp_entity(nr_pdcp_ue_t *ue, int drb_id, nr_pdcp_entity
ue->drb[drb_id] = entity;
}
/* must be called with lock acquired */
nr_pdcp_ue_t **nr_pdcp_manager_get_ue_list(nr_pdcp_ue_manager_t *_m)
{
nr_pdcp_ue_manager_internal_t *m = _m;
return m->ue_list;
}
/* must be called with lock acquired */
int nr_pdcp_manager_get_ue_count(nr_pdcp_ue_manager_t *_m)
{
nr_pdcp_ue_manager_internal_t *m = _m;
return m->ue_count;
}
int nr_pdcp_get_first_rnti(nr_pdcp_ue_manager_t *_m)
{
nr_pdcp_ue_manager_internal_t *m = _m;
@@ -46,6 +46,9 @@ void nr_pdcp_manager_unlock(nr_pdcp_ue_manager_t *m);
nr_pdcp_ue_t *nr_pdcp_manager_get_ue(nr_pdcp_ue_manager_t *m, int rnti);
void nr_pdcp_manager_remove_ue(nr_pdcp_ue_manager_t *m, int rnti);
nr_pdcp_ue_t **nr_pdcp_manager_get_ue_list(nr_pdcp_ue_manager_t *_m);
int nr_pdcp_manager_get_ue_count(nr_pdcp_ue_manager_t *_m);
/***********************************************************************/
/* ue functions */
/***********************************************************************/
+1
View File
@@ -302,6 +302,7 @@ void ue_ip_change_rx_flags(struct net_device *dev_pP, int flagsP) {
}
//---------------------------------------------------------------------------
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0)
void ue_ip_tx_timeout(struct net_device *dev_pP, unsigned int txqueue)
#else
+4 -2
View File
@@ -36,6 +36,7 @@
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "common/ran_context.h"
#include "executables/softmodem-common.h"
#include "nfapi/oai_integration/vendor_ext.h"
#define MAX_IF_MODULES 100
//#define UL_HARQ_PRINT
@@ -104,6 +105,7 @@ void handle_nr_uci(NR_UL_IND_t *UL_info)
}
UL_info->uci_ind.num_ucis = 0;
// mark corresponding PUCCH resources as free
// NOTE: we just assume it is BWP ID 1, to be revised for multiple BWPs
RC.nrmac[mod_id]->pucch_index_used[1][slot] = 0;
@@ -184,7 +186,7 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
module_id,CC_id, UL_info->rach_ind.number_of_pdus,
UL_info->rx_ind.number_of_pdus, UL_info->crc_ind.number_crcs);
if (nfapi_mode != 1) {
if (NFAPI_MODE != NFAPI_MODE_PNF) {
if (ifi->CC_mask==0) {
ifi->current_frame = UL_info->frame;
ifi->current_slot = UL_info->slot;
@@ -203,7 +205,7 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
mac->UL_dci_req[CC_id].numPdus = 0;
handle_nr_ulsch(UL_info);
if (nfapi_mode != 1) {
if (NFAPI_MODE != NFAPI_MODE_PNF) {
if (ifi->CC_mask == ((1<<MAX_NUM_CCs)-1)) {
/*
eNB_dlsch_ulsch_scheduler(module_id,
+2 -2
View File
@@ -62,7 +62,7 @@ int handle_bcch_bch(module_id_t module_id, int cc_id, unsigned int gNB_index, ui
// L2 Abstraction Layer
int handle_bcch_dlsch(module_id_t module_id, int cc_id, unsigned int gNB_index, uint32_t sibs_mask, uint8_t *pduP, uint32_t pdu_len){
return nr_ue_decode_sib1(module_id, cc_id, gNB_index, sibs_mask, pduP, pdu_len);
return nr_ue_decode_BCCH_DL_SCH(module_id, cc_id, gNB_index, sibs_mask, pduP, pdu_len);
}
// L2 Abstraction Layer
@@ -90,7 +90,7 @@ int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){
ret = nr_ue_scheduler(NULL, ul_info);
if (is_nr_UL_slot(mac->scc, ul_info->slot_tx) && get_softmodem_params()->do_ra)
if (is_nr_UL_slot(mac->scc, ul_info->slot_tx, mac->frame_type) && get_softmodem_params()->do_ra)
nr_ue_prach_scheduler(module_id, ul_info->frame_tx, ul_info->slot_tx, ul_info->thread_id);
switch(ret){
+4
View File
@@ -30,6 +30,10 @@
#include "targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h"
#include "common/config/config_load_configmodule.h"
#include "common/config/config_userapi.h"
#include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h"
#include "openair1/PHY/defs_gNB.h"
#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h"
#include "openair1/PHY/LTE_TRANSPORT/transport_common.h"
extern int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind);
void configure_nfapi_pnf(char *vnf_ip_addr,
+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;
+33 -8
View File
@@ -782,21 +782,37 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ(
S1AP_NAS_FIRST_REQ (message_p).ue_identity.presenceMask |= UE_IDENTITIES_gummei;
if (r_mme->plmn_Identity != NULL) {
if ((r_mme->plmn_Identity->mcc != NULL) && (r_mme->plmn_Identity->mcc->list.count > 0)) {
/* Use first indicated PLMN MCC if it is defined */
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc = *r_mme->plmn_Identity->mcc->list.array[selected_plmn_identity];
if ((r_mme->plmn_Identity->mcc != NULL) && (r_mme->plmn_Identity->mcc->list.count == 3))
{
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc = (*r_mme->plmn_Identity->mcc->list.array[0] & 0xf) * 100 +
(*r_mme->plmn_Identity->mcc->list.array[1] & 0xf) * 10 +
(*r_mme->plmn_Identity->mcc->list.array[2] & 0xf);
LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MCC %u ue %x\n",
ctxt_pP->module_id,
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc,
ue_context_pP->ue_context.rnti);
}
if (r_mme->plmn_Identity->mnc.list.count > 0) {
/* Use first indicated PLMN MNC if it is defined */
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc = *r_mme->plmn_Identity->mnc.list.array[selected_plmn_identity];
LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MNC %u ue %x\n",
if(r_mme->plmn_Identity->mnc.list.count == 3)
{
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc = (*r_mme->plmn_Identity->mnc.list.array[0] & 0xf) * 100 +
(*r_mme->plmn_Identity->mnc.list.array[1] & 0xf) * 10 +
(*r_mme->plmn_Identity->mnc.list.array[2] & 0xf);
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc_len = 3;
LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MNC %u %udigit ue %x\n",
ctxt_pP->module_id,
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc,
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc_len,
ue_context_pP->ue_context.rnti);
}
else if(r_mme->plmn_Identity->mnc.list.count == 2)
{
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc = (*r_mme->plmn_Identity->mnc.list.array[0] & 0xf) * 10 +
(*r_mme->plmn_Identity->mnc.list.array[1] & 0xf);
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc_len = 2;
LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MNC %u %udigit ue %x\n",
ctxt_pP->module_id,
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc,
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc_len,
ue_context_pP->ue_context.rnti);
}
} else { // end if plmn_Identity != NULL
@@ -1045,6 +1061,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);
+1 -1
View File
@@ -303,4 +303,4 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP,
return(0);
}
}
+11
View File
@@ -448,6 +448,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 {
@@ -480,6 +489,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,
+3 -3
View File
@@ -32,11 +32,11 @@
#define RRC_TYPES_NR_H_
typedef enum Rrc_State_NR_e {
RRC_STATE_INACTIVE_NR=0,
RRC_STATE_IDLE_NR,
RRC_STATE_IDLE_NR=0,
RRC_STATE_INACTIVE_NR,
RRC_STATE_CONNECTED_NR,
RRC_STATE_FIRST_NR = RRC_STATE_INACTIVE_NR,
RRC_STATE_FIRST_NR = RRC_STATE_IDLE_NR,
RRC_STATE_LAST_NR = RRC_STATE_CONNECTED_NR,
} Rrc_State_NR_t;
+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
@@ -890,6 +891,7 @@ rrc_gNB_process_RRCReconfigurationComplete(
kUPenc,
NULL,
NULL,
NULL,
NULL);
/* Refresh SRBs/DRBs */
nr_rrc_rlc_config_asn1_req(ctxt_pP,
@@ -1705,6 +1707,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)) {
+97 -24
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,
@@ -255,7 +327,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
1024);
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer_size = (enc_rval.encoded+7)>>3;
itti_send_msg_to_task(TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(0), msg); //Check right id instead of hardcoding
} else if (get_softmodem_params()->do_ra) {
} else if (get_softmodem_params()->do_ra || get_softmodem_params()->sa) {
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, ue_context_p->ue_id_rnti, 0, 0,rrc->module_id);
}
@@ -286,10 +358,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);
+11 -8
View File
@@ -135,7 +135,7 @@ void fill_default_searchSpaceZero(NR_SearchSpace_t *ss0) {
// FIXME: update values from TS38.213 Section 10.1 Table 10.1-1: CCE aggregation levels and maximum number of PDCCH candidates per CCE aggregation level for CSS sets configured by searchSpaceSIB1
ss0->nrofCandidates->aggregationLevel1 = NR_SearchSpace__nrofCandidates__aggregationLevel1_n0;
ss0->nrofCandidates->aggregationLevel2 = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0;
ss0->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n1;
ss0->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n2;
ss0->nrofCandidates->aggregationLevel8 = NR_SearchSpace__nrofCandidates__aggregationLevel8_n0;
ss0->nrofCandidates->aggregationLevel16 = NR_SearchSpace__nrofCandidates__aggregationLevel16_n0;
@@ -172,7 +172,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
secondaryCellGroup->cellGroupId = scg_id;
NR_RLC_BearerConfig_t *RLC_BearerConfig = calloc(1,sizeof(*RLC_BearerConfig));
nr_rlc_bearer_init(RLC_BearerConfig);
if (get_softmodem_params()->do_ra)
if (get_softmodem_params()->do_ra || get_softmodem_params()->sa)
nr_drb_config(RLC_BearerConfig->rlc_Config, NR_RLC_Config_PR_um_Bi_Directional);
else
nr_drb_config(RLC_BearerConfig->rlc_Config, NR_RLC_Config_PR_am);
@@ -1329,7 +1329,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;
@@ -1337,8 +1340,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));
@@ -1367,12 +1370,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)
+28 -4
View File
@@ -33,6 +33,7 @@
#include "rrc_defs.h"
#include "rrc_proto.h"
#include "assertions.h"
#include "rrc_vars.h"
typedef uint32_t channel_t;
@@ -50,7 +51,7 @@ nr_mac_rrc_data_ind_ue(
AssertFatal( nr_rrc_ue_decode_NR_BCCH_BCH_Message(module_id, gNB_index, (uint8_t*)pduP, pdu_len) == 0, "UE decode BCCH-BCH error!\n");
break;
case NR_BCCH_DL_SCH:
AssertFatal( nr_rrc_ue_decode_NR_SIB1_Message(module_id, gNB_index, (uint8_t*)pduP, pdu_len) == 0, "UE decode BCCH-DLSCH error!\n");
AssertFatal( nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(module_id, gNB_index, (uint8_t*)pduP, pdu_len, 0, 0) == 0, "UE decode BCCH-DL-SCH error!\n");
break;
default:
break;
@@ -59,13 +60,36 @@ nr_mac_rrc_data_ind_ue(
return(0);
}
int8_t mac_rrc_nr_data_req_ue(const module_id_t Mod_idP,
int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP,
const int CC_id,
const uint8_t gNB_id,
const frame_t frameP,
const rb_id_t Srb_id,
uint8_t *const buffer_pP ){
uint8_t *buffer_pP){
// todo
switch(Srb_id){
case CCCH:
// TODO: Enable timer T300
//NR_UE_rrc_inst[Mod_idP].Info[gNB_id].T300_active = 1;
//NR_UE_rrc_inst[Mod_idP].Info[gNB_id].T300_cnt = 0;
LOG_D(NR_RRC, "nr_mac_rrc_data_req_ue: Payload size = %i\n", NR_UE_rrc_inst[Mod_idP].Srb0[gNB_id].Tx_buffer.payload_size);
memcpy(buffer_pP, (uint8_t*)NR_UE_rrc_inst[Mod_idP].Srb0[gNB_id].Tx_buffer.Payload, NR_UE_rrc_inst[Mod_idP].Srb0[gNB_id].Tx_buffer.payload_size);
for(int i = 0; i<NR_UE_rrc_inst[Mod_idP].Srb0[gNB_id].Tx_buffer.payload_size; i++) {
LOG_D(NR_RRC,"(%i): %i\n", i, buffer_pP[i]);
}
return NR_UE_rrc_inst[Mod_idP].Srb0[gNB_id].Tx_buffer.payload_size;
case DCCH:
AssertFatal(1==0, "SRB1 not implemented yet!\n");
case DCCH1:
AssertFatal(1==0, "SRB2 not implemented yet!\n");
default:
AssertFatal(1==0, "Invalid SRB id!\n");
}
return 0;
}
+166 -249
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
@@ -413,6 +414,18 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* rrc_config_path){
for(nr_ue=0;nr_ue<NB_NR_UE_INST;nr_ue++){
// fill UE-NR-Capability @ UE-CapabilityRAT-Container here.
NR_UE_rrc_inst[nr_ue].selected_plmn_identity = 1;
// TODO: Put the appropriate list of SIBs
NR_UE_rrc_inst[nr_ue].requested_SI_List.buf = CALLOC(1,4);
NR_UE_rrc_inst[nr_ue].requested_SI_List.buf[0] = SIB2 | SIB3 | SIB5; // SIB2 - SIB9
NR_UE_rrc_inst[nr_ue].requested_SI_List.buf[1] = 0; // SIB10 - SIB17
NR_UE_rrc_inst[nr_ue].requested_SI_List.buf[2] = 0; // SIB18 - SIB25
NR_UE_rrc_inst[nr_ue].requested_SI_List.buf[3] = 0; // SIB26 - SIB32
NR_UE_rrc_inst[nr_ue].requested_SI_List.size= 4;
NR_UE_rrc_inst[nr_ue].requested_SI_List.bits_unused= 0;
NR_UE_rrc_inst[nr_ue].ra_trigger = RA_NOT_RUNNING;
// init RRC lists
RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].RLC_Bearer_Config_list, NR_maxLC_ID);
RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].SchedulingRequest_list, NR_maxNrofSR_ConfigPerCellGroup);
@@ -834,7 +847,7 @@ int nr_decode_SI( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index
// After SI is received, prepare RRCConnectionRequest
if (NR_UE_rrc_inst[ctxt_pP->module_id].MBMS_flag < 3) // see -Q option
if (AMF_MODE_ENABLED) {
rrc_ue_generate_RRCSetupRequest( ctxt_pP, gNB_index );
nr_rrc_ue_generate_RRCSetupRequest( ctxt_pP->module_id, gNB_index );
}
if (NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].State == NR_RRC_IDLE) {
@@ -1028,205 +1041,120 @@ int nr_decode_SI( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index
return 0;
}
int nr_decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index, const uint8_t rsrq, const uint8_t rsrp ) {
NR_SIB1_t *sib1 = NR_UE_rrc_inst[ctxt_pP->module_id].sib1[gNB_index];
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SIB1, VCD_FUNCTION_IN );
LOG_I( RRC, "[UE %d] : Dumping SIB 1\n", ctxt_pP->module_id );
const int n = sib1->cellAccessRelatedInfo.plmn_IdentityList.list.count;
for (int i = 0; i < n; ++i) {
NR_PLMN_Identity_t *PLMN_identity = sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[i]->plmn_IdentityList.list.array[0];
int mccdigits = PLMN_identity->mcc->list.count;
int mncdigits = PLMN_identity->mnc.list.count;
int8_t check_requested_SI_List(module_id_t module_id, BIT_STRING_t requested_SI_List, NR_SIB1_t sib1) {
int mcc;
if (mccdigits == 2) {
mcc = *PLMN_identity->mcc->list.array[0]*10 + *PLMN_identity->mcc->list.array[1];
} else {
mcc = *PLMN_identity->mcc->list.array[0]*100 + *PLMN_identity->mcc->list.array[1]*10 + *PLMN_identity->mcc->list.array[2];
if(sib1.si_SchedulingInfo) {
bool SIB_to_request[32] = {};
LOG_D(RRC, "SIBs broadcasting: ");
for(int i = 0; i < sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.count; i++) {
printf("SIB%li ", sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.array[i]->type + 2);
}
printf("\n");
int mnc;
if (mncdigits == 2) {
mnc = *PLMN_identity->mnc.list.array[0]*10 + *PLMN_identity->mnc.list.array[1];
} else {
mnc = *PLMN_identity->mnc.list.array[0]*100 + *PLMN_identity->mnc.list.array[1]*10 + *PLMN_identity->mnc.list.array[2];
}
LOG_D(RRC, "SIBs needed by UE: ");
for(int j = 0; j < 8*requested_SI_List.size; j++) {
if( ((requested_SI_List.buf[j/8]>>(j%8))&1) == 1) {
LOG_I( RRC, "PLMN %d MCC %0*d, MNC %0*d\n", i + 1, mccdigits, mcc, mncdigits, mnc);
// search internal table for provider name
int plmn_ind = 0;
printf("SIB%i ", j + 2);
while (plmn_data[plmn_ind].mcc > 0) {
if ((plmn_data[plmn_ind].mcc == mcc) && (plmn_data[plmn_ind].mnc == mnc)) {
LOG_I( RRC, "Found %s (name from internal table)\n", plmn_data[plmn_ind].oper_short );
break;
}
plmn_ind++;
}
}
LOG_I( RRC, "TAC 0x%04x\n",
((sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->trackingAreaCode->size == 2)?((sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->trackingAreaCode->buf[0]<<8) + sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->trackingAreaCode->buf[1]):0));
LOG_I( RRC, "cellReservedForOperatorUse : raw:%ld decoded:%s\n", sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellReservedForOperatorUse,
nr_SIBreserved(sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellReservedForOperatorUse) );
LOG_I( RRC, "cellAccessRelatedInfo.cellIdentity : raw:%"PRIu32" decoded:%02x.%02x.%02x.%02x\n",
BIT_STRING_to_uint32( &sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellIdentity ),
sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellIdentity.buf[0],
sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellIdentity.buf[1],
sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellIdentity.buf[2],
sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellIdentity.buf[3] >> sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellIdentity.bits_unused);
//LOG_I( RRC, "cellAccessRelatedInfo.cellBarred : raw:%ld decoded:%s\n", sib1->cellAccessRelatedInfo.cellBarred, SIBbarred(sib1->cellAccessRelatedInfo.cellBarred) );
//LOG_I( RRC, "cellAccessRelatedInfo.intraFreqReselection : raw:%ld decoded:%s\n", sib1->cellAccessRelatedInfo.intraFreqReselection, SIBallowed(sib1->cellAccessRelatedInfo.intraFreqReselection) );
//LOG_I( RRC, "cellAccessRelatedInfo.csg_Indication : %d\n", sib1->cellAccessRelatedInfo.csg_Indication );
//if (sib1->cellAccessRelatedInfo.csg_Identity)
// LOG_I( RRC, "cellAccessRelatedInfo.csg_Identity : %"PRIu32"\n", BIT_STRING_to_uint32(sib1->cellAccessRelatedInfo.csg_Identity) );
//else
// LOG_I( RRC, "cellAccessRelatedInfo.csg_Identity : not defined\n" );
LOG_I( RRC, "cellSelectionInfo.q_RxLevMin : %ld\n", sib1->cellSelectionInfo->q_RxLevMin );
if (sib1->cellSelectionInfo->q_RxLevMinOffset)
LOG_I( RRC, "cellSelectionInfo.q_RxLevMinOffset : %ld\n", *sib1->cellSelectionInfo->q_RxLevMinOffset );
else
LOG_I( RRC, "cellSelectionInfo.q_RxLevMinOffset : not defined\n" );
//if (sib1->p_Max)
// LOG_I( RRC, "p_Max : %ld\n", *sib1->p_Max );
//else
// LOG_I( RRC, "p_Max : not defined\n" );
//LOG_I( RRC, "freqBandIndicator : %ld\n", sib1->freqBandIndicator );
if (sib1->si_SchedulingInfo->schedulingInfoList.list.count > 0) {
for (int i=0; i<sib1->si_SchedulingInfo->schedulingInfoList.list.count; i++) {
LOG_I( RRC, "si_Periodicity[%d] : %s\n", i, SIBPeriod[min(sib1->si_SchedulingInfo->schedulingInfoList.list.array[i]->si_Periodicity,7)]);
if (sib1->si_SchedulingInfo->schedulingInfoList.list.array[i]->sib_MappingInfo.list.count > 0) {
char temp[32 * sizeof(SIBType[0])] = {0}; // maxSIB==32
for (int j=0; j<sib1->si_SchedulingInfo->schedulingInfoList.list.array[i]->sib_MappingInfo.list.count; j++) {
sprintf( temp + j*sizeof(SIBType[0]), "%*s ", (int)sizeof(SIBType[0])-1, SIBType[min(sib1->si_SchedulingInfo->schedulingInfoList.list.array[i]->sib_MappingInfo.list.array[0]->type,11)] );
SIB_to_request[j] = true;
for(int i = 0; i < sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.count; i++) {
if(sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.array[i]->type == j) {
SIB_to_request[j] = false;
break;
}
}
LOG_I( RRC, "siSchedulingInfoSIBType[%d] : %s\n", i, temp );
}
}
printf("\n");
LOG_D(RRC, "SIBs to request by UE: ");
bool do_ra = false;
for(int j = 0; j < 8*requested_SI_List.size; j++) {
if(SIB_to_request[j]) {
printf("SIB%i ", j + 2);
do_ra = true;
}
}
printf("\n");
if(do_ra) {
NR_UE_rrc_inst[module_id].ra_trigger = REQUEST_FOR_OTHER_SI;
get_softmodem_params()->do_ra = 1;
if(sib1.si_SchedulingInfo->si_RequestConfig) {
LOG_D(RRC, "Trigger contention-free RA procedure (ra_trigger = %i)\n", NR_UE_rrc_inst[module_id].ra_trigger);
} else {
LOG_I( RRC, "mapping list %d is null\n", i );
LOG_D(RRC, "Trigger contention-based RA procedure (ra_trigger = %i)\n", NR_UE_rrc_inst[module_id].ra_trigger);
}
}
} else {
LOG_E( RRC, "siSchedulingInfoPeriod[0] : PROBLEM!!!\n" );
return -1;
}
if (sib1->servingCellConfigCommon->tdd_UL_DL_ConfigurationCommon) {
//TODO
}
LOG_I( RRC, "siWindowLength : %s\n", siWindowLength[min(sib1->si_SchedulingInfo->si_WindowLength,8)] );
//LOG_I( RRC, "systemInfoValueTag : %ld\n", sib1->systemInfoValueTag );
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIperiod = siPeriod_int[sib1->si_SchedulingInfo->schedulingInfoList.list.array[0]->si_Periodicity];
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIwindowsize = siWindowLength_int[sib1->si_SchedulingInfo->si_WindowLength];
LOG_I( RRC, "[FRAME unknown][RRC_UE][MOD %02"PRIu8"][][--- MAC_CONFIG_REQ (SIB1 params gNB %"PRIu8") --->][MAC_UE][MOD %02"PRIu8"][]\n",
ctxt_pP->module_id, gNB_index, ctxt_pP->module_id );
//rrc_mac_config_req_ue
LOG_I(RRC,"Setting SIStatus bit 0 to 1\n");
NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus = 1;
//NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIB1systemInfoValueTag = sib1->systemInfoValueTag;
if (AMF_MODE_ENABLED) {
int cell_valid = 0;
//if (sib1->cellAccessRelatedInfo.cellBarred == LTE_SystemInformationBlockType1__cellAccessRelatedInfo__cellBarred_notBarred) {
/* Cell is not barred */
int plmn;
int plmn_number;
plmn_number = sib1->cellAccessRelatedInfo.plmn_IdentityList.list.count;
/* Compare requested PLMN and PLMNs from SIB1*/
for (plmn = 0; plmn < plmn_number; plmn++) {
NR_PLMN_Identity_t *plmn_Identity;
plmn_Identity = sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[plmn]->plmn_IdentityList.list.array[0];
if (
(
(plmn_Identity->mcc == NULL)
||
(
(NR_UE_rrc_inst[ctxt_pP->module_id].plmnID.MCCdigit1 == *(plmn_Identity->mcc->list.array[0])) &&
(NR_UE_rrc_inst[ctxt_pP->module_id].plmnID.MCCdigit2 == *(plmn_Identity->mcc->list.array[1])) &&
(NR_UE_rrc_inst[ctxt_pP->module_id].plmnID.MCCdigit3 == *(plmn_Identity->mcc->list.array[2]))
)
)
&&
(NR_UE_rrc_inst[ctxt_pP->module_id].plmnID.MNCdigit1 == *(plmn_Identity->mnc.list.array[0]))
&&
(NR_UE_rrc_inst[ctxt_pP->module_id].plmnID.MNCdigit2 == *(plmn_Identity->mnc.list.array[1]))
&&
(
((NR_UE_rrc_inst[ctxt_pP->module_id].plmnID.MNCdigit3 == 0xf) && (plmn_Identity->mnc.list.count == 2))
||
(NR_UE_rrc_inst[ctxt_pP->module_id].plmnID.MNCdigit3 == *(plmn_Identity->mnc.list.array[2]))
)
) {
/* PLMN match, send a confirmation to NAS */
MessageDef *msg_p;
msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_CELL_SELECTION_CNF);
NAS_CELL_SELECTION_CNF (msg_p).errCode = AS_SUCCESS;
NAS_CELL_SELECTION_CNF (msg_p).cellID = BIT_STRING_to_uint32(&sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellIdentity);
NAS_CELL_SELECTION_CNF (msg_p).tac = BIT_STRING_to_uint16(sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->trackingAreaCode);
NAS_CELL_SELECTION_CNF (msg_p).rat = 0xFF;
NAS_CELL_SELECTION_CNF (msg_p).rsrq = rsrq;
NAS_CELL_SELECTION_CNF (msg_p).rsrp = rsrp;
itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p);
cell_valid = 1;
NR_UE_rrc_inst[ctxt_pP->module_id].selected_plmn_identity = plmn + 1;
break;
}
}
//}
if (cell_valid == 0) {
/* Cell can not be used, ask PHY to try the next one */
MessageDef *msg_p;
msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, PHY_FIND_NEXT_CELL_REQ);
itti_send_msg_to_task(TASK_PHY_UE, ctxt_pP->instance, msg_p);
LOG_E(RRC,
"Synched with a cell, but PLMN doesn't match our SIM "
"(selected_plmn_identity %ld), the message PHY_FIND_NEXT_CELL_REQ "
"is sent but lost in current UE implementation!\n",
NR_UE_rrc_inst[ctxt_pP->module_id].selected_plmn_identity);
}
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SIB1, VCD_FUNCTION_OUT );
return 0;
}
int nr_decode_BCCH_DLSCH_Message(
const protocol_ctxt_t *const ctxt_pP,
const uint8_t gNB_index,
uint8_t *const Sdu,
const uint8_t Sdu_len,
const uint8_t rsrq,
const uint8_t rsrp ) {
int8_t nr_rrc_ue_generate_ra_msg(module_id_t module_id, uint8_t gNB_index) {
switch(NR_UE_rrc_inst[module_id].ra_trigger){
case INITIAL_ACCESS_FROM_RRC_IDLE:
// After SIB1 is received, prepare RRCConnectionRequest
nr_rrc_ue_generate_RRCSetupRequest(module_id,gNB_index);
break;
case RRC_CONNECTION_REESTABLISHMENT:
AssertFatal(1==0, "ra_trigger not implemented yet!\n");
break;
case DURING_HANDOVER:
AssertFatal(1==0, "ra_trigger not implemented yet!\n");
break;
case NON_SYNCHRONISED:
AssertFatal(1==0, "ra_trigger not implemented yet!\n");
break;
case TRANSITION_FROM_RRC_INACTIVE:
AssertFatal(1==0, "ra_trigger not implemented yet!\n");
break;
case TO_ESTABLISH_TA:
AssertFatal(1==0, "ra_trigger not implemented yet!\n");
break;
case REQUEST_FOR_OTHER_SI:
AssertFatal(1==0, "ra_trigger not implemented yet!\n");
break;
case BEAM_FAILURE_RECOVERY:
AssertFatal(1==0, "ra_trigger not implemented yet!\n");
break;
default:
AssertFatal(1==0, "Invalid ra_trigger value!\n");
break;
}
return 0;
}
int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(
module_id_t module_id,
const uint8_t gNB_index,
uint8_t *const Sdu,
const uint8_t Sdu_len,
const uint8_t rsrq,
const uint8_t rsrp) {
NR_BCCH_DL_SCH_Message_t *bcch_message = NULL;
NR_SIB1_t *sib1 = NR_UE_rrc_inst[ctxt_pP->module_id].sib1[gNB_index];
NR_SIB1_t *sib1 = NR_UE_rrc_inst[module_id].sib1[gNB_index];
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_IN );
if (((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&1) == 1) && // SIB1 received
(NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIcnt == sib1->si_SchedulingInfo->schedulingInfoList.list.count)) {
if (((NR_UE_rrc_inst[module_id].Info[gNB_index].SIStatus&1) == 1) && // SIB1 received
(NR_UE_rrc_inst[module_id].Info[gNB_index].SIcnt == sib1->si_SchedulingInfo->schedulingInfoList.list.count)) {
// to prevent memory bloating
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT );
return 0;
}
nr_rrc_set_sub_state( ctxt_pP->module_id, RRC_SUB_STATE_IDLE_RECEIVING_SIB_NR );
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
xer_fprint(stdout, &asn_DEF_NR_BCCH_DL_SCH_Message,(void *)bcch_message );
}
nr_rrc_set_sub_state( module_id, RRC_SUB_STATE_IDLE_RECEIVING_SIB_NR );
asn_dec_rval_t dec_rval = uper_decode_complete( NULL,
&asn_DEF_NR_BCCH_DL_SCH_Message,
@@ -1234,11 +1162,15 @@ int nr_decode_BCCH_DLSCH_Message(
(const void *)Sdu,
Sdu_len );
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
xer_fprint(stdout, &asn_DEF_NR_BCCH_DL_SCH_Message,(void *)bcch_message );
}
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
LOG_E( RRC, "[UE %"PRIu8"] Failed to decode BCCH_DLSCH_MESSAGE (%zu bits)\n",
ctxt_pP->module_id,
LOG_E( NR_RRC, "[UE %"PRIu8"] Failed to decode BCCH_DLSCH_MESSAGE (%zu bits)\n",
module_id,
dec_rval.consumed );
log_dump(RRC, Sdu, Sdu_len, LOG_DUMP_CHAR," Received bytes:\n" );
log_dump(NR_RRC, Sdu, Sdu_len, LOG_DUMP_CHAR," Received bytes:\n" );
// free the memory
SEQUENCE_free( &asn_DEF_LTE_BCCH_DL_SCH_Message, (void *)bcch_message, 1 );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT );
@@ -1248,35 +1180,53 @@ int nr_decode_BCCH_DLSCH_Message(
if (bcch_message->message.present == NR_BCCH_DL_SCH_MessageType_PR_c1) {
switch (bcch_message->message.choice.c1->present) {
case NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1:
if ((ctxt_pP->frame % 2) == 0) {
// even frame
if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&1) == 0) {
NR_SIB1_t *sib1 = NR_UE_rrc_inst[ctxt_pP->module_id].sib1[gNB_index];
memcpy( (void *)sib1,
(void *)bcch_message->message.choice.c1->choice.systemInformationBlockType1,
sizeof(NR_SIB1_t) );
LOG_D( RRC, "[UE %"PRIu8"] Decoding First SIB1\n", ctxt_pP->module_id );
nr_decode_SIB1( ctxt_pP, gNB_index, rsrq, rsrp );
if ((NR_UE_rrc_inst[module_id].Info[gNB_index].SIStatus&1) == 0) {
NR_SIB1_t *sib1 = NR_UE_rrc_inst[module_id].sib1[gNB_index];
if(sib1 != NULL){
SEQUENCE_free(&asn_DEF_NR_SIB1, (void *)sib1, 1 );
}
sib1 = bcch_message->message.choice.c1->choice.systemInformationBlockType1;
if (*(int64_t*)sib1 != 1) {
NR_UE_rrc_inst[module_id].sib1[gNB_index] = sib1;
if( g_log->log_component[NR_RRC].level >= OAILOG_DEBUG ) {
xer_fprint(stdout, &asn_DEF_NR_SIB1, (const void *) NR_UE_rrc_inst[module_id].sib1[gNB_index]);
}
LOG_I(NR_RRC, "SIB1 decoded\n");
// FIXME: improve condition for the RA trigger
// Check for on-demand not broadcasted SI
check_requested_SI_List(module_id, NR_UE_rrc_inst[module_id].requested_SI_List, *sib1);
if( nr_rrc_get_state(module_id) == RRC_STATE_IDLE_NR ) {
NR_UE_rrc_inst[module_id].ra_trigger = INITIAL_ACCESS_FROM_RRC_IDLE;
// TODO: remove flag after full RA procedures implemented
get_softmodem_params()->do_ra = 1;
}
nr_rrc_ue_generate_ra_msg(module_id,gNB_index);
} else {
LOG_E(NR_RRC, "SIB1 not decoded\n");
}
}
break;
case NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformation:
if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&1) == 1) {
if ((NR_UE_rrc_inst[module_id].Info[gNB_index].SIStatus&1) == 1) {
LOG_W(NR_RRC, "Decoding SI not implemented yet\n");
// TODO: Decode SI
/*
// SIB1 with schedulingInfoList is available
NR_SystemInformation_t *si = NR_UE_rrc_inst[ctxt_pP->module_id].si[gNB_index];
NR_SystemInformation_t *si = NR_UE_rrc_inst[module_id].si[gNB_index];
memcpy( si,
bcch_message->message.choice.c1->choice.systemInformation,
sizeof(NR_SystemInformation_t) );
LOG_I( RRC, "[UE %"PRIu8"] Decoding SI for frameP %"PRIu32"\n",
ctxt_pP->module_id,
ctxt_pP->frame );
LOG_I(NR_RRC, "[UE %"PRIu8"] Decoding SI\n", module_id);
nr_decode_SI( ctxt_pP, gNB_index );
//if (nfapi_mode == 3)
//UE_mac_inst[ctxt_pP->module_id].SI_Decoded = 1;
}
if (nfapi_mode == 3)
UE_mac_inst[ctxt_pP->module_id].SI_Decoded = 1;
*/
}
break;
case NR_BCCH_DL_SCH_MessageType__c1_PR_NOTHING:
@@ -1285,10 +1235,10 @@ int nr_decode_BCCH_DLSCH_Message(
}
}
if (nr_rrc_get_sub_state(ctxt_pP->module_id) == RRC_SUB_STATE_IDLE_SIB_COMPLETE_NR) {
if (nr_rrc_get_sub_state(module_id) == RRC_SUB_STATE_IDLE_SIB_COMPLETE_NR) {
//if ( (NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.data != NULL) || (!AMF_MODE_ENABLED)) {
rrc_ue_generate_RRCSetupRequest(ctxt_pP, 0);
nr_rrc_set_sub_state( ctxt_pP->module_id, RRC_SUB_STATE_IDLE_CONNECTING );
nr_rrc_ue_generate_RRCSetupRequest(module_id, 0);
nr_rrc_set_sub_state( module_id, RRC_SUB_STATE_IDLE_CONNECTING );
//}
}
@@ -1488,41 +1438,6 @@ int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB
return rval;
}
/*brief decode SIB1 message*/
int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len) {
NR_BCCH_DL_SCH_Message_t *bcch_message = NULL;
asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
&asn_DEF_NR_BCCH_DL_SCH_Message,
(void **)&bcch_message,
(const void *)bufferP,
buffer_len);
if ((dec_rval.code != RC_OK) || (dec_rval.consumed == 0)) {
LOG_D(RRC,"NR_BCCH_DL_SCH decode error\n");
SEQUENCE_free( &asn_DEF_NR_BCCH_DL_SCH_Message, (void *)bcch_message, 1 );
return -1;
}
else {
NR_SIB1_t *sib1 = NR_UE_rrc_inst[module_id].sib1[gNB_index];
if(sib1 != NULL){
SEQUENCE_free(&asn_DEF_NR_BCCH_BCH_Message, (void *)sib1, 1 );
}
sib1 = bcch_message->message.choice.c1->choice.systemInformationBlockType1;
if (*(int64_t*)sib1 != 1) {
LOG_I(RRC, "SIB1 decoded\n");
if( g_log->log_component[RRC].level >= OAILOG_DEBUG )
xer_fprint(stdout, &asn_DEF_NR_SIB1, (const void*)sib1);
}
else
LOG_E(PHY, "sib1 is starting by 8 times 0\n");
}
return 0;
}
// from NR SRB3
int8_t nr_rrc_ue_decode_NR_DL_DCCH_Message(
const module_id_t module_id,
@@ -1783,10 +1698,10 @@ nr_rrc_ue_process_securityModeCommand(
}
//-----------------------------------------------------------------------------
void rrc_ue_generate_RRCSetupRequest( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index ) {
void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index) {
uint8_t i=0,rv[6];
if(NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size ==0) {
if(NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size ==0) {
// Get RRCConnectionRequest, fill random for now
// Generate random byte stream for contention resolution
for (i=0; i<6; i++) {
@@ -1800,16 +1715,16 @@ void rrc_ue_generate_RRCSetupRequest( const protocol_ctxt_t *const ctxt_pP, cons
}
LOG_T(NR_RRC,"\n");
NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size =
do_RRCSetupRequest(
ctxt_pP->module_id,
(uint8_t *)NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.Payload,
rv);
LOG_I(NR_RRC,"[UE %d] : Frame %d, Logical Channel UL-CCCH (SRB0), Generating RRCSetupRequest (bytes %d, eNB %d)\n",
ctxt_pP->module_id, ctxt_pP->frame, NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size, gNB_index);
NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size =
do_RRCSetupRequest(
module_id,
(uint8_t *)NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.Payload,
rv);
LOG_I(NR_RRC,"[UE %d] : Logical Channel UL-CCCH (SRB0), Generating RRCSetupRequest (bytes %d, gNB %d)\n",
module_id, NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size, gNB_index);
for (i=0; i<NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size; i++) {
LOG_T(NR_RRC,"%x.",NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.Payload[i]);
for (i=0; i<NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size; i++) {
LOG_T(NR_RRC,"%x.",NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.Payload[i]);
}
LOG_T(NR_RRC,"\n");
@@ -2085,6 +2000,7 @@ nr_sa_rrc_ue_process_radioBearerConfig(
// NULL,
// NULL,
// NULL,
// NULL,
// NULL);
// Refresh SRBs
// nr_rrc_rlc_config_asn1_req(ctxt_pP,
@@ -2176,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
@@ -2557,7 +2474,7 @@ void *rrc_nrue_task( void *args_p ) {
NR_RRC_MAC_BCCH_DATA_IND (msg_p).frame, NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index);
// PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_NO, NOT_A_RNTI, RRC_MAC_BCCH_DATA_IND (msg_p).frame, 0);
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NOT_A_RNTI, NR_RRC_MAC_BCCH_DATA_IND (msg_p).frame, 0,NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index);
nr_decode_BCCH_DLSCH_Message (&ctxt,
nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message (ctxt.module_id,
NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index,
NR_RRC_MAC_BCCH_DATA_IND (msg_p).sdu,
NR_RRC_MAC_BCCH_DATA_IND (msg_p).sdu_size,
+29 -2
View File
@@ -77,6 +77,30 @@ typedef struct OAI_NR_UECapability_s {
NR_UE_NR_Capability_t *UE_NR_Capability;
} OAI_NR_UECapability_t;
typedef enum requested_SI_List_e {
SIB2 = 1,
SIB3 = 2,
SIB4 = 4,
SIB5 = 8,
SIB6 = 16,
SIB7 = 32,
SIB8 = 64,
SIB9 = 128
} requested_SI_List_t;
// 3GPP TS 38.300 Section 9.2.6
typedef enum RA_trigger_e {
RA_NOT_RUNNING,
INITIAL_ACCESS_FROM_RRC_IDLE,
RRC_CONNECTION_REESTABLISHMENT,
DURING_HANDOVER,
NON_SYNCHRONISED,
TRANSITION_FROM_RRC_INACTIVE,
TO_ESTABLISH_TA,
REQUEST_FOR_OTHER_SI,
BEAM_FAILURE_RECOVERY,
} RA_trigger_t;
typedef struct NR_UE_RRC_INST_s {
NR_MeasConfig_t *meas_config;
@@ -99,10 +123,13 @@ typedef struct NR_UE_RRC_INST_s {
NR_SRB_INFO_TABLE_ENTRY Srb2[NB_CNX_UE];
uint8_t MBMS_flag;
OAI_NR_UECapability_t *UECap;
uint8_t *UECapability;
OAI_NR_UECapability_t *UECap;
uint8_t *UECapability;
uint8_t UECapability_size;
RA_trigger_t ra_trigger;
BIT_STRING_t requested_SI_List;
NR_SystemInformation_t *si[NB_CNX_UE];
NR_SIB1_t *sib1[NB_CNX_UE];
NR_SIB2_t *sib2[NB_CNX_UE];
+12 -9
View File
@@ -86,12 +86,14 @@ int8_t nr_rrc_ue_process_radio_bearer_config(NR_RadioBearerConfig_t *radio_beare
\param sdu_len length of buffer*/
int8_t nr_rrc_ue_decode_NR_BCCH_BCH_Message(const module_id_t module_id, const uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len);
/**\brief decode NR SIB1 message
/**\brief decode NR BCCH-DLSCH (SI) messages
\param module_idP module id
\param gNB_index gNB index
\param sduP pointer to buffer of ASN message
\param sdu_len length of buffer*/
int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len);
\param sduP pointer to buffer of ASN message BCCH-DLSCH
\param sdu_len length of buffer
\param rsrq RSRQ
\param rsrp RSRP*/
int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(const module_id_t module_id, const uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len, const uint8_t rsrq, const uint8_t rsrp);
/**\brief Decode NR DCCH from gNB, sent from lower layer through SRB3
\param module_id module id
@@ -112,24 +114,25 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, cons
/**\brief
\param module_id module id
\param CC_id component carrier id
\param gNB_index gNB index
\param frame_t frameP
\param rb_id_t SRB id
\param buffer_pP pointer to buffer*/
int8_t mac_rrc_nr_data_req_ue(const module_id_t Mod_idP,
int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP,
const int CC_id,
const uint8_t gNB_id,
const frame_t frameP,
const rb_id_t Srb_id,
uint8_t *const buffer_pP);
uint8_t *buffer_pP);
/**\brief RRC UE task.
\param void *args_p Pointer on arguments to start the task. */
void *rrc_nrue_task(void *args_p);
/**\brief RRC UE generate RRCSetupRequest message.
\param ctxt_pP protocol context
\param module_id module id
\param gNB_index gNB index */
void rrc_ue_generate_RRCSetupRequest( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index );
void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index);
/** @}*/
#endif
+1 -1
View File
@@ -624,7 +624,7 @@ int main( int argc, char **argv )
0);
NR_UE_rrc_inst[ctxt.module_id].Info[0].State = RRC_SI_RECEIVED;
rrc_ue_generate_RRCSetupRequest(&ctxt, 0);
nr_rrc_ue_generate_RRCSetupRequest(ctxt.module_id, 0);
printf("Entering ITTI signals handler\n");
itti_wait_tasks_end();
+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;
}
+34 -1
View File
@@ -536,6 +536,14 @@ int x2ap_eNB_handle_x2_setup_response(instance_t instance,
return -1;
}
if((x2ap_eNB_data->state == X2AP_ENB_STATE_CONNECTED) ||
(x2ap_eNB_data->state == X2AP_ENB_STATE_READY))
{
X2AP_ERROR("Received Unexpexted X2 Setup Response Message\n");
return -1;
}
X2AP_DEBUG("Received a new X2 setup response\n");
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_X2SetupResponse_IEs_t, ie, x2SetupResponse,
@@ -662,6 +670,14 @@ int x2ap_eNB_handle_x2_setup_failure(instance_t instance,
return -1;
}
if((x2ap_eNB_data->state == X2AP_ENB_STATE_CONNECTED) ||
(x2ap_eNB_data->state == X2AP_ENB_STATE_READY))
{
X2AP_ERROR("Received Unexpexted X2 Setup Failure Message\n");
return -1;
}
X2AP_DEBUG("Received a new X2 setup failure\n");
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_X2SetupFailure_IEs_t, ie, x2SetupFailure,
@@ -730,6 +746,7 @@ int x2ap_eNB_handle_handover_preparation (instance_t instance,
X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID, true);
if (ie == NULL ) {
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
return -1;
}
@@ -750,7 +767,11 @@ int x2ap_eNB_handle_handover_preparation (instance_t instance,
//measResultListEUTRA.list.array[ncell_index]->physCellId;
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequest_IEs_t, ie, x2HandoverRequest,
X2AP_ProtocolIE_ID_id_GUMMEI_ID, true);
if (ie == NULL ) {
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
return -1;
}
TBCD_TO_MCC_MNC(&ie->value.choice.ECGI.pLMN_Identity, X2AP_HANDOVER_REQ(msg).ue_gummei.mcc,
X2AP_HANDOVER_REQ(msg).ue_gummei.mnc, X2AP_HANDOVER_REQ(msg).ue_gummei.mnc_len);
OCTET_STRING_TO_INT8(&ie->value.choice.GUMMEI.mME_Code, X2AP_HANDOVER_REQ(msg).ue_gummei.mme_code);
@@ -761,6 +782,7 @@ int x2ap_eNB_handle_handover_preparation (instance_t instance,
if (ie == NULL ) {
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
return -1;
}
@@ -872,6 +894,7 @@ int x2ap_eNB_handle_handover_response (instance_t instance,
if (ie == NULL ) {
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
return -1;
}
@@ -882,6 +905,7 @@ int x2ap_eNB_handle_handover_response (instance_t instance,
if (ie == NULL ) {
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
return -1;
}
@@ -912,6 +936,7 @@ int x2ap_eNB_handle_handover_response (instance_t instance,
if (ie == NULL ) {
X2AP_ERROR("%s %d: ie is a NULL pointer \n", __FILE__, __LINE__);
itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
return -1;
}else{
if (ie->value.choice.E_RABs_Admitted_List.list.count > 0) {
@@ -959,6 +984,12 @@ int x2ap_eNB_handle_handover_response (instance_t instance,
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequestAcknowledge_IEs_t, ie, x2HandoverRequestAck,
X2AP_ProtocolIE_ID_id_TargeteNBtoSource_eNBTransparentContainer, true);
if (ie == NULL ) {
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
return -1;
}
X2AP_TargeteNBtoSource_eNBTransparentContainer_t *c = &ie->value.choice.TargeteNBtoSource_eNBTransparentContainer;
if (c->size > 1024 /* TODO: this is the size of rrc_buffer in struct x2ap_handover_req_ack_s */)
@@ -1012,6 +1043,7 @@ int x2ap_eNB_handle_ue_context_release (instance_t instance,
if (ie == NULL ) {
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
return -1;
}
@@ -1022,6 +1054,7 @@ int x2ap_eNB_handle_ue_context_release (instance_t instance,
if (ie == NULL ) {
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
return -1;
}