Commit fe210667 authored by laurent's avatar laurent Committed by Sakthivel Velumani

fix race in startup procedure (config before starting threads that use the config)

parent 3197baab
......@@ -289,9 +289,59 @@ void exit_function(const char *file, const char *function, const int line, const
int create_gNB_tasks(uint32_t gnb_nb) {
int create_gNB_tasks(void) {
uint32_t gnb_nb = RC.nb_nr_inst;
uint32_t gnb_id_start = 0;
uint32_t gnb_id_end = gnb_id_start + gnb_nb;
LOG_D(GNB_APP, "%s(gnb_nb:%d)\n", __FUNCTION__, gnb_nb);
itti_wait_ready(1);
LOG_I(PHY, "%s() Task ready initialize structures\n", __FUNCTION__);
RCconfig_NR_L1();
if (RC.nb_nr_macrlc_inst>0) RCconfig_nr_macrlc();
LOG_I(PHY, "%s() RC.nb_nr_L1_inst:%d\n", __FUNCTION__, RC.nb_nr_L1_inst);
if (RC.nb_nr_L1_inst>0) AssertFatal(l1_north_init_gNB()==0,"could not initialize L1 north interface\n");
AssertFatal (gnb_nb <= RC.nb_nr_inst,
"Number of gNB is greater than gNB defined in configuration file (%d/%d)!",
gnb_nb, RC.nb_nr_inst);
LOG_I(GNB_APP,"Allocating gNB_RRC_INST for %d instances\n",RC.nb_nr_inst);
RC.nrrrc = (gNB_RRC_INST **)malloc(RC.nb_nr_inst*sizeof(gNB_RRC_INST *));
LOG_I(PHY, "%s() RC.nb_nr_inst:%d RC.nrrrc:%p\n", __FUNCTION__, RC.nb_nr_inst, RC.nrrrc);
for (int gnb_id = gnb_id_start; (gnb_id < gnb_id_end) ; gnb_id++) {
RC.nrrrc[gnb_id] = (gNB_RRC_INST*)calloc(1,sizeof(gNB_RRC_INST));
LOG_I(PHY, "%s() Creating RRC instance RC.nrrrc[%d]:%p (%d of %d)\n", __FUNCTION__, gnb_id, RC.nrrrc[gnb_id], gnb_id+1, gnb_id_end);
RC.nrrrc[gnb_id]->node_type=set_node_type();
configure_nr_rrc(gnb_id);
}
if (RC.nb_nr_inst > 0 &&
!get_softmodem_params()->nsa &&
!(RC.nrrrc[0]->node_type == ngran_gNB_DU)) {
// we start pdcp in both cuup (for drb) and cucp (for srb)
init_pdcp();
}
if (is_x2ap_enabled() ) { //&& !NODE_IS_DU(RC.rrc[0]->node_type)
LOG_I(X2AP, "X2AP enabled \n");
__attribute__((unused)) uint32_t x2_register_gnb_pending = gNB_app_register_x2 (gnb_id_start, gnb_id_end);
}
/* For the CU case the gNB registration with the AMF might have to take place after the F1 setup, as the PLMN info
* can originate from the DU. Add check on whether x2ap is enabled to account for ENDC NSA scenario.*/
if ((get_softmodem_params()->sa || is_x2ap_enabled()) &&
!NODE_IS_DU(RC.nrrrc[0]->node_type) &&
RC.nrrrc[gnb_id_start]->node_type != ngran_gNB_CUUP) {
/* Try to register each gNB */
//registered_gnb = 0;
__attribute__((unused)) uint32_t register_gnb_pending = gNB_app_register (gnb_id_start, gnb_id_end);
}
if (gnb_nb > 0) {
/* Last task to create, others task must be ready before its start */
......@@ -313,7 +363,9 @@ int create_gNB_tasks(uint32_t gnb_nb) {
}
}
if (AMF_MODE_ENABLED) {
if (get_softmodem_params()->sa &&
!NODE_IS_DU(RC.nrrrc[0]->node_type) &&
RC.nrrrc[gnb_id_start]->node_type != ngran_gNB_CUUP ) {
char* gnb_ipv4_address_for_NGU = NULL;
uint32_t gnb_port_for_NGU = 0;
......@@ -326,23 +378,18 @@ int create_gNB_tasks(uint32_t gnb_nb) {
for(int i = GNB_INTERFACE_NAME_FOR_NG_AMF_IDX; i <= GNB_IPV4_ADDRESS_FOR_NG_AMF_IDX; i++) {
if( NETParams[i].strptr == NULL) {
LOG_E(NGAP, "No configuration in the file.\n");
NGAP_CONF_MODE = 0;
LOG_E(NGAP, "No AMF configuration in the file.\n");
exit(1);
} else {
LOG_D(NGAP, "Configuration in the file: %s.\n",*NETParams[i].strptr);
}
}
if (gnb_nb > 0) {
if(NGAP_CONF_MODE) {
if (itti_create_task (TASK_NGAP, ngap_gNB_task, NULL) < 0) {
LOG_E(NGAP, "Create task for NGAP failed\n");
return -1;
}
} else {
LOG_I(NGAP, "Ngap task not created\n");
}
}
}
......@@ -359,8 +406,8 @@ int create_gNB_tasks(uint32_t gnb_nb) {
return -1;
}
//Use check on x2ap to consider the NSA scenario and check on AMF_MODE_ENABLED for the SA scenario
if(is_x2ap_enabled() || AMF_MODE_ENABLED) {
//Use check on x2ap to consider the NSA scenario
if((is_x2ap_enabled() || get_softmodem_params()->sa) && (RC.nrrrc[0]->node_type != ngran_gNB_CUCP) ) {
if (itti_create_task (TASK_GTPV1_U, &gtpv1uTask, NULL) < 0) {
LOG_E(GTPU, "Create task for GTPV1U failed\n");
return -1;
......@@ -630,8 +677,6 @@ int main( int argc, char **argv ) {
}
openair0_cfg[0].threequarter_fs = threequarter_fs;
AMF_MODE_ENABLED = get_softmodem_params()->sa;
NGAP_CONF_MODE = get_softmodem_params()->sa;
if (get_softmodem_params()->do_ra)
AssertFatal(get_softmodem_params()->phy_test == 0,"RA and phy_test are mutually exclusive\n");
......@@ -669,7 +714,7 @@ int main( int argc, char **argv ) {
RCconfig_NR_L1();
// don't create if node doesn't connect to RRC/S1/GTP
int ret=create_gNB_tasks(1);
int ret=create_gNB_tasks();
AssertFatal(ret==0,"cannot create ITTI tasks\n");
/* Start the agent. If it is turned off in the configuration, it won't start */
......
......@@ -89,7 +89,7 @@ uint32_t gNB_app_register(uint32_t gnb_id_start, uint32_t gnb_id_end)//, const E
for (gnb_id = gnb_id_start; (gnb_id < gnb_id_end) ; gnb_id++) {
{
if(NGAP_CONF_MODE){
if(get_softmodem_params()->sa){
ngap_register_gnb_req_t *ngap_register_gNB; //Type Temporarily reuse
// note: there is an implicit relationship between the data structure and the message name
......@@ -139,9 +139,6 @@ uint32_t gNB_app_register_x2(uint32_t gnb_id_start, uint32_t gnb_id_end) {
void *gNB_app_task(void *args_p)
{
uint32_t gnb_nb = RC.nb_nr_inst;
uint32_t gnb_id_start = 0;
uint32_t gnb_id_end = gnb_id_start + gnb_nb;
MessageDef *msg_p = NULL;
const char *msg_name = NULL;
instance_t instance;
......@@ -152,51 +149,6 @@ void *gNB_app_task(void *args_p)
int cell_to_activate = 0;
itti_mark_task_ready (TASK_GNB_APP);
LOG_I(PHY, "%s() Task ready initialize structures\n", __FUNCTION__);
RCconfig_NR_L1();
if (RC.nb_nr_macrlc_inst>0) RCconfig_nr_macrlc();
LOG_I(PHY, "%s() RC.nb_nr_L1_inst:%d\n", __FUNCTION__, RC.nb_nr_L1_inst);
if (RC.nb_nr_L1_inst>0) AssertFatal(l1_north_init_gNB()==0,"could not initialize L1 north interface\n");
AssertFatal (gnb_nb <= RC.nb_nr_inst,
"Number of gNB is greater than gNB defined in configuration file (%d/%d)!",
gnb_nb, RC.nb_nr_inst);
LOG_I(GNB_APP,"Allocating gNB_RRC_INST for %d instances\n",RC.nb_nr_inst);
RC.nrrrc = (gNB_RRC_INST **)malloc(RC.nb_nr_inst*sizeof(gNB_RRC_INST *));
LOG_I(PHY, "%s() RC.nb_nr_inst:%d RC.nrrrc:%p\n", __FUNCTION__, RC.nb_nr_inst, RC.nrrrc);
for (int gnb_id = gnb_id_start; (gnb_id < gnb_id_end) ; gnb_id++) {
RC.nrrrc[gnb_id] = (gNB_RRC_INST*)calloc(1,sizeof(gNB_RRC_INST));
LOG_I(PHY, "%s() Creating RRC instance RC.nrrrc[%d]:%p (%d of %d)\n", __FUNCTION__, gnb_id, RC.nrrrc[gnb_id], gnb_id+1, gnb_id_end);
RC.nrrrc[gnb_id]->node_type=set_node_type();
configure_nr_rrc(gnb_id);
}
if (RC.nb_nr_inst > 0 &&
!get_softmodem_params()->nsa &&
!(RC.nrrrc[0]->node_type == ngran_gNB_DU)) {
// we start pdcp in both cuup (for drb) and cucp (for srb)
init_pdcp();
}
if (is_x2ap_enabled() ) { //&& !NODE_IS_DU(RC.rrc[0]->node_type)
LOG_I(X2AP, "X2AP enabled \n");
__attribute__((unused)) uint32_t x2_register_gnb_pending = gNB_app_register_x2 (gnb_id_start, gnb_id_end);
}
/* For the CU case the gNB registration with the AMF might have to take place after the F1 setup, as the PLMN info
* can originate from the DU. Add check on whether x2ap is enabled to account for ENDC NSA scenario.*/
if ((AMF_MODE_ENABLED || is_x2ap_enabled()) && !NODE_IS_DU(RC.nrrrc[0]->node_type) ) { //&& !NODE_IS_CU(RC.nrrrc[0]->node_type)) {
/* Try to register each gNB */
//registered_gnb = 0;
__attribute__((unused)) uint32_t register_gnb_pending = gNB_app_register (gnb_id_start, gnb_id_end);
}
if (RC.nb_nr_inst > 0) {
if (RC.nrrrc[0]->node_type == ngran_gNB_CUCP ||
RC.nrrrc[0]->node_type == ngran_gNB_CU ||
......
......@@ -34,6 +34,7 @@
#include "common/utils/nr/nr_common.h"
#include "common/utils/LOG/log_extern.h"
#include "assertions.h"
#include "executables/softmodem-common.h"
#include "gnb_config.h"
#include "gnb_paramdef.h"
#include "enb_paramdef.h"
......@@ -639,7 +640,7 @@ void RCconfig_nr_flexran()
/* gNB ID from configuration, as read in by RCconfig_RRC() */
if (!GNBParamList.paramarray[i][GNB_GNB_ID_IDX].uptr) {
// Calculate a default gNB ID
if (AMF_MODE_ENABLED)
if (get_softmodem_params()->sa)
gnb_id = i + (ngap_generate_gNB_id () & 0xFFFFFF8);
else
gnb_id = i;
......@@ -1064,24 +1065,6 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
num_gnbs = GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt;
AssertFatal (i<num_gnbs,"Failed to parse config file no %ith element in %s \n",i, GNB_CONFIG_STRING_ACTIVE_GNBS);
/*
if (AMF_MODE_ENABLED) {
if (strcasecmp( *(GNBSParams[GNB_ASN1_VERBOSITY_IDX].strptr), GNB_CONFIG_STRING_ASN1_VERBOSITY_NONE) == 0) {
asn_debug = 0;
asn1_xer_print = 0;
} else if (strcasecmp( *(GNBSParams[GNB_ASN1_VERBOSITY_IDX].strptr), GNB_CONFIG_STRING_ASN1_VERBOSITY_INFO) == 0) {
asn_debug = 1;
asn1_xer_print = 1;
} else if (strcasecmp(*(GNBSParams[GNB_ASN1_VERBOSITY_IDX].strptr) , GNB_CONFIG_STRING_ASN1_VERBOSITY_ANNOYING) == 0) {
asn_debug = 1;
asn1_xer_print = 2;
} else {
asn_debug = 0;
asn1_xer_print = 0;
}
}
*/
if (num_gnbs>0) {
// Output a list of all gNBs. ////////// Identification parameters
......@@ -1089,7 +1072,7 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
if (GNBParamList.paramarray[i][GNB_GNB_ID_IDX].uptr == NULL) {
// Calculate a default gNB ID
if (AMF_MODE_ENABLED) {
if (get_softmodem_params()->sa) {
uint32_t hash;
hash = ngap_generate_gNB_id ();
gnb_id = i + (hash & 0xFFFFFF8);
......@@ -1342,24 +1325,6 @@ int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i) {
/* get global parameters, defined outside any section in the config file */
config_get( GNBSParams,sizeof(GNBSParams)/sizeof(paramdef_t),NULL);
/*
if (AMF_MODE_ENABLED) {
if (strcasecmp( *(GNBSParams[GNB_ASN1_VERBOSITY_IDX].strptr), GNB_CONFIG_STRING_ASN1_VERBOSITY_NONE) == 0) {
asn_debug = 0;
asn1_xer_print = 0;
} else if (strcasecmp( *(GNBSParams[GNB_ASN1_VERBOSITY_IDX].strptr), GNB_CONFIG_STRING_ASN1_VERBOSITY_INFO) == 0) {
asn_debug = 1;
asn1_xer_print = 1;
} else if (strcasecmp(*(GNBSParams[GNB_ASN1_VERBOSITY_IDX].strptr) , GNB_CONFIG_STRING_ASN1_VERBOSITY_ANNOYING) == 0) {
asn_debug = 1;
asn1_xer_print = 2;
} else {
asn_debug = 0;
asn1_xer_print = 0;
}
}
*/
AssertFatal (i<GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt,
"Failed to parse config file %s, %uth attribute %s \n",
RC.config_file_name, i, GNB_CONFIG_STRING_ACTIVE_GNBS);
......@@ -1372,7 +1337,7 @@ int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i) {
for (k = 0; k < GNBParamList.numelt; k++) {
if (GNBParamList.paramarray[k][GNB_GNB_ID_IDX].uptr == NULL) {
// Calculate a default gNB ID
if (AMF_MODE_ENABLED) {
if (get_softmodem_params()->sa) {
uint32_t hash;
hash = ngap_generate_gNB_id ();
......@@ -1528,7 +1493,7 @@ int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i) {
// SCTP SETTING
NGAP_REGISTER_GNB_REQ (msg_p).sctp_out_streams = SCTP_OUT_STREAMS;
NGAP_REGISTER_GNB_REQ (msg_p).sctp_in_streams = SCTP_IN_STREAMS;
if (AMF_MODE_ENABLED) {
if (get_softmodem_params()->sa) {
sprintf(aprefix,"%s.[%i].%s",GNB_CONFIG_STRING_GNB_LIST,k,GNB_CONFIG_STRING_SCTP_CONFIG);
config_get( SCTPParams,sizeof(SCTPParams)/sizeof(paramdef_t),aprefix);
NGAP_REGISTER_GNB_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[GNB_SCTP_INSTREAMS_IDX].uptr);
......@@ -1652,7 +1617,7 @@ int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i) {
for (k = 0; k < GNBParamList.numelt; k++) {
if (GNBParamList.paramarray[k][GNB_GNB_ID_IDX].uptr == NULL) {
// Calculate a default eNB ID
if (AMF_MODE_ENABLED) {
if (get_softmodem_params()->sa) {
uint32_t hash;
hash = ngap_generate_gNB_id ();
gnb_id = k + (hash & 0xFFFFFF8);
......@@ -1795,7 +1760,7 @@ int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i) {
X2AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = SCTP_OUT_STREAMS;
X2AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = SCTP_IN_STREAMS;
if (AMF_MODE_ENABLED) {
if (get_softmodem_params()->sa) {
sprintf(aprefix,"%s.[%i].%s",GNB_CONFIG_STRING_GNB_LIST,k,GNB_CONFIG_STRING_SCTP_CONFIG);
config_get( SCTPParams,sizeof(SCTPParams)/sizeof(paramdef_t),aprefix);
X2AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[GNB_SCTP_INSTREAMS_IDX].uptr);
......
......@@ -510,7 +510,7 @@ rrc_gNB_process_RRCSetupComplete(
ue_context_pP->ue_context.Srb1.Srb_info.Srb_id = 1;
ue_context_pP->ue_context.StatusRrc = NR_RRC_CONNECTED;
if (AMF_MODE_ENABLED) {
if (get_softmodem_params()->sa) {
rrc_gNB_send_NGAP_NAS_FIRST_REQ(ctxt_pP, ue_context_pP, rrcSetupComplete);
} else {
rrc_gNB_generate_SecurityModeCommand(ctxt_pP, ue_context_pP);
......@@ -1606,7 +1606,7 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete(
ue_context_pP->ue_context.Srb1.Active = 1;
//ue_context_pP->ue_context.Srb2.Srb_info.Srb_id = 2;
if (AMF_MODE_ENABLED) {
if (get_softmodem_params()->sa) {
hashtable_rc_t h_rc;
int j;
rrc_ue_ngap_ids_t *rrc_ue_ngap_ids_p = NULL;
......@@ -1683,13 +1683,13 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete(
ue_context_pP->ue_context.ul_failure_timer = 0;
return;
}
} /* AMF_MODE_ENABLED */
}
/* Update RNTI in ue_context */
ue_context_pP->ue_id_rnti = ctxt_pP->rnti; // here ue_id_rnti is just a key, may be something else
ue_context_pP->ue_context.rnti = ctxt_pP->rnti;
if (AMF_MODE_ENABLED) {
if (get_softmodem_params()->sa) {
uint8_t send_security_mode_command = false;
nr_rrc_pdcp_config_security(
ctxt_pP,
......@@ -2311,7 +2311,7 @@ rrc_gNB_decode_dcch(
ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->rrc_TransactionIdentifier);
}
if (AMF_MODE_ENABLED) {
if (get_softmodem_params()->sa) {
if(ue_context_p->ue_context.pdu_session_release_command_flag == 1) {
xid = ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->rrc_TransactionIdentifier;
ue_context_p->ue_context.pdu_session_release_command_flag = 0;
......@@ -2444,7 +2444,7 @@ rrc_gNB_decode_dcch(
LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP,
"[MSG] RRC UL Information Transfer \n");
if (AMF_MODE_ENABLED == 1) {
if (get_softmodem_params()->sa) {
rrc_gNB_send_NGAP_UPLINK_NAS(ctxt_pP,
ue_context_p,
ul_dcch_msg);
......@@ -2592,7 +2592,7 @@ rrc_gNB_decode_dcch(
if(eutra_index == -1)
break;
}
if (AMF_MODE_ENABLED == 1) {
if (get_softmodem_params()->sa) {
rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(ctxt_pP,
ue_context_p,
ul_dcch_msg);
......
......@@ -152,7 +152,7 @@ static int nr_rrc_set_state (module_id_t ue_mod_idP, Rrc_State_NR_t state) {
}
static int nr_rrc_set_sub_state( module_id_t ue_mod_idP, Rrc_Sub_State_NR_t subState ) {
if (AMF_MODE_ENABLED) {
if (get_softmodem_params()->sa) {
switch (NR_UE_rrc_inst[ue_mod_idP].nrRrcState) {
case RRC_STATE_INACTIVE_NR:
AssertFatal ((RRC_SUB_STATE_INACTIVE_FIRST_NR <= subState) && (subState <= RRC_SUB_STATE_INACTIVE_LAST_NR),
......@@ -835,7 +835,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) {
if (get_softmodem_params()->sa) {
nr_rrc_ue_generate_RRCSetupRequest( ctxt_pP->module_id, gNB_index );
}
......@@ -1341,20 +1341,16 @@ static void rrc_ue_generate_RRCSetupComplete(
const char *nas_msg;
int nas_msg_length;
if (AMF_MODE_ENABLED) {
if (get_softmodem_params()->sa) {
as_nas_info_t initialNasMsg;
generateRegistrationRequest(&initialNasMsg, ctxt_pP->module_id);
nas_msg = (char*)initialNasMsg.data;
nas_msg_length = initialNasMsg.length;
} else {
nas_msg = (char *) NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.data;
nas_msg_length = NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.length;
}
} else {
nas_msg = nr_nas_attach_req_imsi;
nas_msg_length = sizeof(nr_nas_attach_req_imsi);
}
size = do_RRCSetupComplete(ctxt_pP->module_id, buffer, sizeof(buffer),
Transaction_id, sel_plmn_id, nas_msg_length, nas_msg);
LOG_I(NR_RRC,"[UE %d][RAPROC] Frame %d : Logical Channel UL-DCCH (SRB1), Generating RRCSetupComplete (bytes%d, gNB %d)\n",
......@@ -1708,9 +1704,6 @@ int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB
void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index) {
uint8_t i=0,rv[6];
if(get_softmodem_params()->sa) {
AMF_MODE_ENABLED = 1;
}
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
......@@ -1802,7 +1795,7 @@ nr_rrc_ue_establish_srb2(
LOG_I(NR_RRC,"[UE %d] Frame %d: processing RRCReconfiguration: reconfiguring DRB %ld\n",
ue_mod_idP, frameP, DRB_config->drb_Identity);
if(!AMF_MODE_ENABLED) {
if(!get_softmodem_params()->sa) {
ip_addr_offset3 = 0;
ip_addr_offset4 = 1;
LOG_I(OIP, "[UE %d] trying to bring up the OAI interface %d, IP X.Y.%d.%d\n", ue_mod_idP, ip_addr_offset3+ue_mod_idP,
......
......@@ -64,8 +64,6 @@
#include "oaisim_amf_test_s1c.h"
#endif
ngap_gNB_config_t ngap_config;
static int ngap_gNB_generate_ng_setup_request(
ngap_gNB_instance_t *instance_p, ngap_gNB_amf_data_t *ngap_amf_data_p);
......
......@@ -39,18 +39,6 @@
#ifndef NGAP_GNB_H_
#define NGAP_GNB_H_
typedef struct ngap_gNB_config_s {
// MME related params
unsigned char amf_enabled; ///< AMF enabled ?
unsigned char ngap_enabled; ///< NGAP enabled ?
} ngap_gNB_config_t;
extern ngap_gNB_config_t ngap_config;
#define AMF_MODE_ENABLED ngap_config.amf_enabled
#define NGAP_CONF_MODE ngap_config.ngap_enabled
void *ngap_gNB_process_itti_msg(void*);
void ngap_gNB_init(void);
void *ngap_gNB_task(void *arg);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment