Modify NGAP Messages
This commit is contained in:
@@ -312,6 +312,7 @@ void * rrc_enb_process_msg(void*);
|
||||
TASK_DEF(TASK_RRC_GNB, TASK_PRIORITY_MED, 200, NULL,NULL)\
|
||||
TASK_DEF(TASK_RAL_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \
|
||||
TASK_DEF(TASK_S1AP, TASK_PRIORITY_MED, 200, NULL, NULL) \
|
||||
TASK_DEF(TASK_NGAP, TASK_PRIORITY_MED, 200, NULL, NULL) \
|
||||
TASK_DEF(TASK_X2AP, TASK_PRIORITY_MED, 200, NULL, NULL) \
|
||||
TASK_DEF(TASK_M2AP_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \
|
||||
TASK_DEF(TASK_M2AP_MCE, TASK_PRIORITY_MED, 200, NULL, NULL) \
|
||||
|
||||
+15
-14
@@ -387,30 +387,31 @@ int create_gNB_tasks(uint32_t gnb_nb) {
|
||||
return -1;
|
||||
}*/
|
||||
if(itti_create_task(TASK_SCTP, sctp_eNB_task, NULL) < 0){
|
||||
LOG_E(SCTP, "Create task for SCTP failed\n");
|
||||
return -1;
|
||||
LOG_E(SCTP, "Create task for SCTP failed\n");
|
||||
return -1;
|
||||
}
|
||||
if (is_x2ap_enabled()) {
|
||||
if(itti_create_task(TASK_X2AP, x2ap_task, NULL) < 0){
|
||||
LOG_E(X2AP, "Create task for X2AP failed\n");
|
||||
}
|
||||
if(itti_create_task(TASK_X2AP, x2ap_task, NULL) < 0){
|
||||
LOG_E(X2AP, "Create task for X2AP failed\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG_I(X2AP, "X2AP is disabled.\n");
|
||||
LOG_I(X2AP, "X2AP is disabled.\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (EPC_MODE_ENABLED && (get_softmodem_params()->phy_test==0 && get_softmodem_params()->do_ra==0)) {
|
||||
if (gnb_nb > 0) {
|
||||
/*if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) {
|
||||
/*
|
||||
if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) {
|
||||
LOG_E(SCTP, "Create task for SCTP failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (itti_create_task (TASK_S1AP, s1ap_eNB_task, NULL) < 0) {
|
||||
LOG_E(S1AP, "Create task for S1AP failed\n");
|
||||
*/
|
||||
if (itti_create_task (TASK_NGAP, ngap_gNB_task, NULL) < 0) {
|
||||
LOG_E(S1AP, "Create task for NGAP failed\n");
|
||||
return -1;
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
if(!emulate_rf){
|
||||
@@ -430,9 +431,9 @@ int create_gNB_tasks(uint32_t gnb_nb) {
|
||||
|
||||
if (gnb_nb > 0) {
|
||||
if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) {
|
||||
LOG_E(GNB_APP, "Create task for gNB APP failed\n");
|
||||
return -1;
|
||||
}
|
||||
LOG_E(GNB_APP, "Create task for gNB APP failed\n");
|
||||
return -1;
|
||||
}
|
||||
LOG_I(NR_RRC,"Creating NR RRC gNB Task\n");
|
||||
|
||||
if (itti_create_task (TASK_RRC_GNB, rrc_gnb_task, NULL) < 0) {
|
||||
|
||||
@@ -31,23 +31,23 @@ MESSAGE_DEF(NGAP_UE_CONTEXT_RELEASE_REQ_LOG, MESSAGE_PRIORITY_MED, IttiMsgText
|
||||
MESSAGE_DEF(NGAP_UE_CONTEXT_RELEASE_COMMAND_LOG, MESSAGE_PRIORITY_MED, IttiMsgText , ngap_ue_context_release_command_log)
|
||||
MESSAGE_DEF(NGAP_UE_CONTEXT_RELEASE_COMPLETE_LOG, MESSAGE_PRIORITY_MED, IttiMsgText , ngap_ue_context_release_complete_log)
|
||||
MESSAGE_DEF(NGAP_UE_CONTEXT_RELEASE_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_ue_context_release_log)
|
||||
MESSAGE_DEF(NGAP_E_RAB_SETUP_REQUEST_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_e_rab_setup_request_log)
|
||||
MESSAGE_DEF(NGAP_E_RAB_SETUP_RESPONSE_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_e_rab_setup_response_log)
|
||||
MESSAGE_DEF(NGAP_E_RAB_MODIFY_REQUEST_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_e_rab_modify_request_log)
|
||||
MESSAGE_DEF(NGAP_E_RAB_MODIFY_RESPONSE_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_e_rab_modify_response_log)
|
||||
MESSAGE_DEF(NGAP_PDUSESSION_SETUP_REQUEST_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_pdusession_setup_request_log)
|
||||
MESSAGE_DEF(NGAP_PDUSESSION_SETUP_RESPONSE_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_pdusession_setup_response_log)
|
||||
MESSAGE_DEF(NGAP_PDUSESSION_MODIFY_REQUEST_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_pdusession_modify_request_log)
|
||||
MESSAGE_DEF(NGAP_PDUSESSION_MODIFY_RESPONSE_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_pdusession_modify_response_log)
|
||||
MESSAGE_DEF(NGAP_PAGING_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_paging_log)
|
||||
MESSAGE_DEF(NGAP_E_RAB_RELEASE_REQUEST_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_e_rab_release_request_log)
|
||||
MESSAGE_DEF(NGAP_E_RAB_RELEASE_RESPONSE_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_e_rab_release_response_log)
|
||||
MESSAGE_DEF(NGAP_PDUSESSION_RELEASE_REQUEST_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_pdusession_release_request_log)
|
||||
MESSAGE_DEF(NGAP_PDUSESSION_RELEASE_RESPONSE_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_pdusession_release_response_log)
|
||||
MESSAGE_DEF(NGAP_ERROR_INDICATION_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_error_indication_log)
|
||||
MESSAGE_DEF(NGAP_PATH_SWITCH_REQ_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_path_switch_req_log)
|
||||
MESSAGE_DEF(NGAP_PATH_SWITCH_REQ_ACK_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_path_switch_req_ack_log)
|
||||
|
||||
/* gNB application layer -> NGAP messages */
|
||||
MESSAGE_DEF(NGAP_REGISTER_GNB_REQ , MESSAGE_PRIORITY_MED, ngap_register_enb_req_t , ngap_register_enb_req)
|
||||
MESSAGE_DEF(NGAP_REGISTER_GNB_REQ , MESSAGE_PRIORITY_MED, ngap_register_gnb_req_t , ngap_register_gnb_req)
|
||||
|
||||
/* NGAP -> gNB application layer messages */
|
||||
MESSAGE_DEF(NGAP_REGISTER_GNB_CNF , MESSAGE_PRIORITY_MED, ngap_register_enb_cnf_t , ngap_register_enb_cnf)
|
||||
MESSAGE_DEF(NGAP_DEREGISTERED_GNB_IND , MESSAGE_PRIORITY_MED, ngap_deregistered_enb_ind_t , ngap_deregistered_enb_ind)
|
||||
MESSAGE_DEF(NGAP_REGISTER_GNB_CNF , MESSAGE_PRIORITY_MED, ngap_register_gnb_cnf_t , ngap_register_gnb_cnf)
|
||||
MESSAGE_DEF(NGAP_DEREGISTERED_GNB_IND , MESSAGE_PRIORITY_MED, ngap_deregistered_gnb_ind_t , ngap_deregistered_gnb_ind)
|
||||
|
||||
/* RRC -> NGAP messages */
|
||||
MESSAGE_DEF(NGAP_NAS_FIRST_REQ , MESSAGE_PRIORITY_MED, ngap_nas_first_req_t , ngap_nas_first_req)
|
||||
@@ -60,22 +60,22 @@ MESSAGE_DEF(NGAP_UE_CONTEXT_RELEASE_RESP , MESSAGE_PRIORITY_MED, ngap_ue_relea
|
||||
MESSAGE_DEF(NGAP_UE_CONTEXT_RELEASE_COMPLETE, MESSAGE_PRIORITY_MED, ngap_ue_release_complete_t , ngap_ue_release_complete)
|
||||
MESSAGE_DEF(NGAP_UE_CTXT_MODIFICATION_RESP , MESSAGE_PRIORITY_MED, ngap_ue_ctxt_modification_resp_t , ngap_ue_ctxt_modification_resp)
|
||||
MESSAGE_DEF(NGAP_UE_CTXT_MODIFICATION_FAIL , MESSAGE_PRIORITY_MED, ngap_ue_ctxt_modification_fail_t , ngap_ue_ctxt_modification_fail)
|
||||
MESSAGE_DEF(NGAP_E_RAB_SETUP_RESP , MESSAGE_PRIORITY_MED, ngap_e_rab_setup_resp_t , ngap_e_rab_setup_resp)
|
||||
MESSAGE_DEF(NGAP_E_RAB_SETUP_REQUEST_FAIL , MESSAGE_PRIORITY_MED, ngap_e_rab_setup_req_fail_t , ngap_e_rab_setup_request_fail)
|
||||
MESSAGE_DEF(NGAP_E_RAB_MODIFY_RESP , MESSAGE_PRIORITY_MED, ngap_e_rab_modify_resp_t , ngap_e_rab_modify_resp)
|
||||
MESSAGE_DEF(NGAP_E_RAB_RELEASE_RESPONSE , MESSAGE_PRIORITY_MED, ngap_e_rab_release_resp_t , ngap_e_rab_release_resp)
|
||||
MESSAGE_DEF(NGAP_PDUSESSION_SETUP_RESP , MESSAGE_PRIORITY_MED, ngap_pdusession_setup_resp_t , ngap_pdusession_setup_resp)
|
||||
MESSAGE_DEF(NGAP_PDUSESSION_SETUP_REQUEST_FAIL , MESSAGE_PRIORITY_MED, ngap_pdusession_setup_req_fail_t , ngap_pdusession_setup_request_fail)
|
||||
MESSAGE_DEF(NGAP_PDUSESSION_MODIFY_RESP , MESSAGE_PRIORITY_MED, ngap_pdusession_modify_resp_t , ngap_pdusession_modify_resp)
|
||||
MESSAGE_DEF(NGAP_PDUSESSION_RELEASE_RESPONSE , MESSAGE_PRIORITY_MED, ngap_pdusession_release_resp_t , ngap_pdusession_release_resp)
|
||||
MESSAGE_DEF(NGAP_PATH_SWITCH_REQ , MESSAGE_PRIORITY_MED, ngap_path_switch_req_t , ngap_path_switch_req)
|
||||
MESSAGE_DEF(NGAP_PATH_SWITCH_REQ_ACK , MESSAGE_PRIORITY_MED, ngap_path_switch_req_ack_t , ngap_path_switch_req_ack)
|
||||
MESSAGE_DEF(NGAP_E_RAB_MODIFICATION_IND , MESSAGE_PRIORITY_MED, ngap_e_rab_modification_ind_t , ngap_e_rab_modification_ind)
|
||||
MESSAGE_DEF(NGAP_PDUSESSION_MODIFICATION_IND , MESSAGE_PRIORITY_MED, ngap_pdusession_modification_ind_t , ngap_pdusession_modification_ind)
|
||||
|
||||
/* NGAP -> RRC messages */
|
||||
MESSAGE_DEF(NGAP_DOWNLINK_NAS , MESSAGE_PRIORITY_MED, ngap_downlink_nas_t , ngap_downlink_nas )
|
||||
MESSAGE_DEF(NGAP_INITIAL_CONTEXT_SETUP_REQ , MESSAGE_PRIORITY_MED, ngap_initial_context_setup_req_t , ngap_initial_context_setup_req )
|
||||
MESSAGE_DEF(NGAP_UE_CTXT_MODIFICATION_REQ , MESSAGE_PRIORITY_MED, ngap_ue_ctxt_modification_req_t , ngap_ue_ctxt_modification_req)
|
||||
MESSAGE_DEF(NGAP_PAGING_IND , MESSAGE_PRIORITY_MED, ngap_paging_ind_t , ngap_paging_ind )
|
||||
MESSAGE_DEF(NGAP_E_RAB_SETUP_REQ , MESSAGE_PRIORITY_MED, ngap_e_rab_setup_req_t , ngap_e_rab_setup_req )
|
||||
MESSAGE_DEF(NGAP_E_RAB_MODIFY_REQ , MESSAGE_PRIORITY_MED, ngap_e_rab_modify_req_t , ngap_e_rab_modify_req )
|
||||
MESSAGE_DEF(NGAP_E_RAB_RELEASE_COMMAND , MESSAGE_PRIORITY_MED, ngap_e_rab_release_command_t , ngap_e_rab_release_command)
|
||||
MESSAGE_DEF(NGAP_PDUSESSION_SETUP_REQ , MESSAGE_PRIORITY_MED, ngap_pdusession_setup_req_t , ngap_pdusession_setup_req )
|
||||
MESSAGE_DEF(NGAP_PDUSESSION_MODIFY_REQ , MESSAGE_PRIORITY_MED, ngap_pdusession_modify_req_t , ngap_pdusession_modify_req )
|
||||
MESSAGE_DEF(NGAP_PDUSESSION_RELEASE_COMMAND , MESSAGE_PRIORITY_MED, ngap_pdusession_release_command_t , ngap_pdusession_release_command)
|
||||
MESSAGE_DEF(NGAP_UE_CONTEXT_RELEASE_COMMAND, MESSAGE_PRIORITY_MED, ngap_ue_release_command_t , ngap_ue_release_command)
|
||||
|
||||
/* NGAP <-> RRC messages (can be initiated either by MME or gNB) */
|
||||
|
||||
@@ -26,10 +26,10 @@
|
||||
//-------------------------------------------------------------------------------------------//
|
||||
// Defines to access message fields.
|
||||
|
||||
#define NGAP_REGISTER_GNB_REQ(mSGpTR) (mSGpTR)->ittiMsg.ngap_register_enb_req
|
||||
#define NGAP_REGISTER_GNB_REQ(mSGpTR) (mSGpTR)->ittiMsg.ngap_register_gnb_req
|
||||
|
||||
#define NGAP_REGISTER_GNB_CNF(mSGpTR) (mSGpTR)->ittiMsg.ngap_register_enb_cnf
|
||||
#define NGAP_DEREGISTERED_GNB_IND(mSGpTR) (mSGpTR)->ittiMsg.ngap_deregistered_enb_ind
|
||||
#define NGAP_REGISTER_GNB_CNF(mSGpTR) (mSGpTR)->ittiMsg.ngap_register_gnb_cnf
|
||||
#define NGAP_DEREGISTERED_GNB_IND(mSGpTR) (mSGpTR)->ittiMsg.ngap_deregistered_gnb_ind
|
||||
|
||||
#define NGAP_NAS_FIRST_REQ(mSGpTR) (mSGpTR)->ittiMsg.ngap_nas_first_req
|
||||
#define NGAP_UPLINK_NAS(mSGpTR) (mSGpTR)->ittiMsg.ngap_uplink_nas
|
||||
@@ -40,48 +40,50 @@
|
||||
#define NGAP_NAS_NON_DELIVERY_IND(mSGpTR) (mSGpTR)->ittiMsg.ngap_nas_non_delivery_ind
|
||||
#define NGAP_UE_CTXT_MODIFICATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.ngap_ue_ctxt_modification_resp
|
||||
#define NGAP_UE_CTXT_MODIFICATION_FAIL(mSGpTR) (mSGpTR)->ittiMsg.ngap_ue_ctxt_modification_fail
|
||||
#define NGAP_E_RAB_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.ngap_e_rab_setup_resp
|
||||
#define NGAP_E_RAB_SETUP_FAIL(mSGpTR) (mSGpTR)->ittiMsg.ngap_e_rab_setup_req_fail
|
||||
#define NGAP_E_RAB_MODIFY_RESP(mSGpTR) (mSGpTR)->ittiMsg.ngap_e_rab_modify_resp
|
||||
#define NGAP_PDUSESSION_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.ngap_pdusession_setup_resp
|
||||
#define NGAP_PDUSESSION_SETUP_FAIL(mSGpTR) (mSGpTR)->ittiMsg.ngap_pdusession_setup_req_fail
|
||||
#define NGAP_PDUSESSION_MODIFY_RESP(mSGpTR) (mSGpTR)->ittiMsg.ngap_pdusession_modify_resp
|
||||
#define NGAP_PATH_SWITCH_REQ(mSGpTR) (mSGpTR)->ittiMsg.ngap_path_switch_req
|
||||
#define NGAP_PATH_SWITCH_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.ngap_path_switch_req_ack
|
||||
#define NGAP_E_RAB_MODIFICATION_IND(mSGpTR) (mSGpTR)->ittiMsg.ngap_e_rab_modification_ind
|
||||
#define NGAP_PDUSESSION_MODIFICATION_IND(mSGpTR) (mSGpTR)->ittiMsg.ngap_pdusession_modification_ind
|
||||
|
||||
#define NGAP_DOWNLINK_NAS(mSGpTR) (mSGpTR)->ittiMsg.ngap_downlink_nas
|
||||
#define NGAP_INITIAL_CONTEXT_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.ngap_initial_context_setup_req
|
||||
#define NGAP_UE_CTXT_MODIFICATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.ngap_ue_ctxt_modification_req
|
||||
#define NGAP_UE_CONTEXT_RELEASE_COMMAND(mSGpTR) (mSGpTR)->ittiMsg.ngap_ue_release_command
|
||||
#define NGAP_UE_CONTEXT_RELEASE_COMPLETE(mSGpTR) (mSGpTR)->ittiMsg.ngap_ue_release_complete
|
||||
#define NGAP_E_RAB_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.ngap_e_rab_setup_req
|
||||
#define NGAP_E_RAB_MODIFY_REQ(mSGpTR) (mSGpTR)->ittiMsg.ngap_e_rab_modify_req
|
||||
#define NGAP_PDUSESSION_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.ngap_pdusession_setup_req
|
||||
#define NGAP_PDUSESSION_MODIFY_REQ(mSGpTR) (mSGpTR)->ittiMsg.ngap_pdusession_modify_req
|
||||
#define NGAP_PAGING_IND(mSGpTR) (mSGpTR)->ittiMsg.ngap_paging_ind
|
||||
|
||||
#define NGAP_UE_CONTEXT_RELEASE_REQ(mSGpTR) (mSGpTR)->ittiMsg.ngap_ue_release_req
|
||||
#define NGAP_E_RAB_RELEASE_COMMAND(mSGpTR) (mSGpTR)->ittiMsg.ngap_e_rab_release_command
|
||||
#define NGAP_E_RAB_RELEASE_RESPONSE(mSGpTR) (mSGpTR)->ittiMsg.ngap_e_rab_release_resp
|
||||
#define NGAP_PDUSESSION_RELEASE_COMMAND(mSGpTR) (mSGpTR)->ittiMsg.ngap_pdusession_release_command
|
||||
#define NGAP_PDUSESSION_RELEASE_RESPONSE(mSGpTR) (mSGpTR)->ittiMsg.ngap_pdusession_release_resp
|
||||
|
||||
//-------------------------------------------------------------------------------------------//
|
||||
/* Maximum number of e-rabs to be setup/deleted in a single message.
|
||||
* Even if only one bearer will be modified by message.
|
||||
*/
|
||||
#define NGAP_MAX_E_RAB (LTE_maxDRB + 3)
|
||||
#define NGAP_MAX_PDUSESSION (LTE_maxDRB + 3)
|
||||
|
||||
/* Length of the transport layer address string
|
||||
* 160 bits / 8 bits by char.
|
||||
*/
|
||||
#define NGAP_TRANSPORT_LAYER_ADDRESS_SIZE (160 / 8)
|
||||
|
||||
#define NGAP_MAX_NB_MME_IP_ADDRESS 10
|
||||
#define NGAP_MAX_NB_AMF_IP_ADDRESS 10
|
||||
#define NGAP_IMSI_LENGTH 16
|
||||
|
||||
#define QOSFLOW_MAX_VALUE 64;
|
||||
|
||||
/* Security key length used within gNB
|
||||
* Even if only 16 bytes will be effectively used,
|
||||
* the key length is 32 bytes (256 bits)
|
||||
*/
|
||||
#define SECURITY_KEY_LENGTH 32
|
||||
typedef enum cell_type_e {
|
||||
CELL_MACRO_GNB,
|
||||
CELL_HOME_GNB,
|
||||
CELL_MACRO_ENB,
|
||||
CELL_HOME_ENB,
|
||||
CELL_MACRO_GNB
|
||||
} cell_type_t;
|
||||
|
||||
@@ -150,14 +152,16 @@ typedef struct allocation_retention_priority_s {
|
||||
pre_emp_vulnerability_t pre_emp_vulnerability;
|
||||
} allocation_retention_priority_t;
|
||||
|
||||
typedef struct security_capabilities_s {
|
||||
uint16_t encryption_algorithms;
|
||||
uint16_t integrity_algorithms;
|
||||
} security_capabilities_t;
|
||||
typedef struct nr_security_capabilities_s {
|
||||
uint16_t nRencryption_algorithms;
|
||||
uint16_t nRintegrity_algorithms;
|
||||
uint16_t eUTRAencryption_algorithms;
|
||||
uint16_t eUTRAintegrity_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
|
||||
* concerns AC11..AC15, ‘mt Estands for ‘Mobile Terminating Eand ‘mo Efor
|
||||
* 'Mobile Originating'. Defined in TS 36.331.
|
||||
*/
|
||||
typedef enum rrc_establishment_cause_e {
|
||||
@@ -172,13 +176,21 @@ typedef enum rrc_establishment_cause_e {
|
||||
RRC_CAUSE_LAST
|
||||
} rrc_establishment_cause_t;
|
||||
|
||||
typedef struct ngap_gummei_s {
|
||||
typedef struct ngap_guami_s {
|
||||
uint16_t mcc;
|
||||
uint16_t mnc;
|
||||
uint8_t mnc_len;
|
||||
uint8_t mme_code;
|
||||
uint16_t mme_group_id;
|
||||
} ngap_gummei_t;
|
||||
uint8_t amf_region_id;
|
||||
uint16_t amf_set_id;
|
||||
uint8_t amf_pointer;
|
||||
} ngap_guami_t;
|
||||
|
||||
typedef struct ngap_allowed_NSSAI_s{
|
||||
uint8_t sST;
|
||||
uint8_t sD_flag;
|
||||
uint8_t sD[3];
|
||||
}ngap_allowed_NSSAI_t;
|
||||
|
||||
|
||||
typedef struct ngap_imsi_s {
|
||||
uint8_t buffer[NGAP_IMSI_LENGTH];
|
||||
@@ -186,7 +198,7 @@ typedef struct ngap_imsi_s {
|
||||
} ngap_imsi_t;
|
||||
|
||||
typedef struct s_tmsi_s {
|
||||
uint8_t mme_code;
|
||||
uint8_t amf_code;
|
||||
uint32_t m_tmsi;
|
||||
} s_tmsi_t;
|
||||
|
||||
@@ -207,14 +219,14 @@ typedef struct ue_paging_identity_s {
|
||||
typedef enum ue_identities_presenceMask_e {
|
||||
UE_IDENTITIES_NONE = 0,
|
||||
UE_IDENTITIES_s_tmsi = 1 << 1,
|
||||
UE_IDENTITIES_gummei = 1 << 2,
|
||||
UE_IDENTITIES_guami = 1 << 2,
|
||||
} ue_identities_presenceMask_t;
|
||||
|
||||
typedef struct ue_identity_s {
|
||||
typedef struct nrue_identity_s {
|
||||
ue_identities_presenceMask_t presenceMask;
|
||||
s_tmsi_t s_tmsi;
|
||||
ngap_gummei_t gummei;
|
||||
} ue_identity_t;
|
||||
ngap_guami_t guami;
|
||||
} nrue_identity_t;
|
||||
|
||||
typedef struct nas_pdu_s {
|
||||
/* Octet string data */
|
||||
@@ -223,12 +235,21 @@ typedef struct nas_pdu_s {
|
||||
uint32_t length;
|
||||
} nas_pdu_t, ue_radio_cap_t;
|
||||
|
||||
typedef enum pdu_session_type_e {
|
||||
PDUSessionType_ipv4 = 0,
|
||||
PDUSessionType_ipv6 = 1,
|
||||
PDUSessionType_ipv4v6 = 2,
|
||||
PDUSessionType_ethernet = 3,
|
||||
PDUSessionType_unstructured = 4
|
||||
}pdu_session_type_t;
|
||||
|
||||
typedef struct transport_layer_addr_s {
|
||||
/* Length of the transport layer address buffer in bits. NGAP layer received a
|
||||
* bit string<1..160> containing one of the following addresses: ipv4,
|
||||
* ipv6, or ipv4 and ipv6. The layer doesn't interpret the buffer but
|
||||
* silently forward it to S1-U.
|
||||
* silently forward it to NG-U.
|
||||
*/
|
||||
uint8_t pdu_session_type;
|
||||
uint8_t length;
|
||||
uint8_t buffer[20]; // in network byte order
|
||||
} transport_layer_addr_t;
|
||||
@@ -240,53 +261,55 @@ typedef struct transport_layer_addr_s {
|
||||
dEST.length = sOURCE.length; \
|
||||
} while (0)
|
||||
|
||||
typedef struct e_rab_level_qos_parameter_s {
|
||||
typedef struct pdusession_level_qos_parameter_s {
|
||||
uint8_t qci;
|
||||
|
||||
allocation_retention_priority_t allocation_retention_priority;
|
||||
} e_rab_level_qos_parameter_t;
|
||||
} pdusession_level_qos_parameter_t;
|
||||
|
||||
typedef struct e_rab_s {
|
||||
/* Unique e_rab_id for the UE. */
|
||||
uint8_t e_rab_id;
|
||||
/* Quality of service for this e_rab */
|
||||
e_rab_level_qos_parameter_t qos;
|
||||
typedef struct pdusession_s {
|
||||
/* Unique pdusession_id for the UE. */
|
||||
uint8_t pdusession_id;
|
||||
|
||||
uint8_t nb_qos;
|
||||
/* Quality of service for this pdusession */
|
||||
pdusession_level_qos_parameter_t qos[QOSFLOW_MAX_VALUE];
|
||||
/* The NAS PDU should be forwarded by the RRC layer to the NAS layer */
|
||||
nas_pdu_t nas_pdu;
|
||||
/* The transport layer address for the IP packets */
|
||||
transport_layer_addr_t sgw_addr;
|
||||
transport_layer_addr_t upf_addr;
|
||||
/* S-GW Tunnel endpoint identifier */
|
||||
uint32_t gtp_teid;
|
||||
} e_rab_t;
|
||||
} pdusession_t;
|
||||
|
||||
typedef struct e_rab_setup_s {
|
||||
/* Unique e_rab_id for the UE. */
|
||||
uint8_t e_rab_id;
|
||||
typedef struct pdusession_setup_s {
|
||||
/* Unique pdusession_id for the UE. */
|
||||
uint8_t pdusession_id;
|
||||
|
||||
/* The transport layer address for the IP packets */
|
||||
transport_layer_addr_t gNB_addr;
|
||||
|
||||
/* S-GW Tunnel endpoint identifier */
|
||||
uint32_t gtp_teid;
|
||||
} e_rab_setup_t;
|
||||
} pdusession_setup_t;
|
||||
|
||||
typedef struct e_rab_tobe_added_s {
|
||||
/* Unique e_rab_id for the UE. */
|
||||
uint8_t e_rab_id;
|
||||
typedef struct pdusession_tobe_added_s {
|
||||
/* Unique pdusession_id for the UE. */
|
||||
uint8_t pdusession_id;
|
||||
|
||||
/* Unique drb_ID for the UE. */
|
||||
uint8_t drb_ID;
|
||||
|
||||
/* The transport layer address for the IP packets */
|
||||
transport_layer_addr_t sgw_addr;
|
||||
transport_layer_addr_t upf_addr;
|
||||
|
||||
/* S-GW Tunnel endpoint identifier */
|
||||
uint32_t gtp_teid;
|
||||
} e_rab_tobe_added_t;
|
||||
} pdusession_tobe_added_t;
|
||||
|
||||
typedef struct e_rab_admitted_tobe_added_s {
|
||||
/* Unique e_rab_id for the UE. */
|
||||
uint8_t e_rab_id;
|
||||
typedef struct pdusession_admitted_tobe_added_s {
|
||||
/* Unique pdusession_id for the UE. */
|
||||
uint8_t pdusession_id;
|
||||
|
||||
/* Unique drb_ID for the UE. */
|
||||
uint8_t drb_ID;
|
||||
@@ -296,25 +319,25 @@ typedef struct e_rab_admitted_tobe_added_s {
|
||||
|
||||
/* S-GW Tunnel endpoint identifier */
|
||||
uint32_t gtp_teid;
|
||||
} e_rab_admitted_tobe_added_t;
|
||||
} pdusession_admitted_tobe_added_t;
|
||||
|
||||
|
||||
|
||||
typedef struct e_rab_tobeswitched_s {
|
||||
/* Unique e_rab_id for the UE. */
|
||||
uint8_t e_rab_id;
|
||||
typedef struct pdusession_tobeswitched_s {
|
||||
/* Unique pdusession_id for the UE. */
|
||||
uint8_t pdusession_id;
|
||||
|
||||
/* The transport layer address for the IP packets */
|
||||
transport_layer_addr_t sgw_addr;
|
||||
transport_layer_addr_t upf_addr;
|
||||
|
||||
/* S-GW Tunnel endpoint identifier */
|
||||
uint32_t gtp_teid;
|
||||
} e_rab_tobeswitched_t;
|
||||
} pdusession_tobeswitched_t;
|
||||
|
||||
typedef struct e_rab_modify_s {
|
||||
/* Unique e_rab_id for the UE. */
|
||||
uint8_t e_rab_id;
|
||||
} e_rab_modify_t;
|
||||
typedef struct pdusession_modify_s {
|
||||
/* Unique pdusession_id for the UE. */
|
||||
uint8_t pdusession_id;
|
||||
} pdusession_modify_t;
|
||||
|
||||
typedef enum S1ap_Cause_e {
|
||||
NGAP_CAUSE_NOTHING, /* No components present */
|
||||
@@ -327,14 +350,14 @@ typedef enum S1ap_Cause_e {
|
||||
|
||||
} ngap_Cause_t;
|
||||
|
||||
typedef struct e_rab_failed_s {
|
||||
/* Unique e_rab_id for the UE. */
|
||||
uint8_t e_rab_id;
|
||||
typedef struct pdusession_failed_s {
|
||||
/* Unique pdusession_id for the UE. */
|
||||
uint8_t pdusession_id;
|
||||
/* Cause of the failure */
|
||||
// cause_t cause;
|
||||
ngap_Cause_t cause;
|
||||
uint8_t cause_value;
|
||||
} e_rab_failed_t;
|
||||
} pdusession_failed_t;
|
||||
|
||||
typedef enum ngap_ue_ctxt_modification_present_s {
|
||||
NGAP_UE_CONTEXT_MODIFICATION_SECURITY_KEY = (1 << 0),
|
||||
@@ -349,7 +372,7 @@ typedef enum ngap_paging_ind_present_s {
|
||||
|
||||
//-------------------------------------------------------------------------------------------//
|
||||
// gNB application layer -> NGAP messages
|
||||
typedef struct ngap_register_enb_req_s {
|
||||
typedef struct ngap_register_gnb_req_s {
|
||||
/* Unique gNB_id to identify the gNB within EPC.
|
||||
* For macro gNB ids this field should be 20 bits long.
|
||||
* For home gNB ids this field should be 28 bits long.
|
||||
@@ -380,38 +403,38 @@ typedef struct ngap_register_enb_req_s {
|
||||
paging_drx_t default_drx;
|
||||
|
||||
/* The gNB IP address to bind */
|
||||
net_ip_address_t enb_ip_address;
|
||||
net_ip_address_t gnb_ip_address;
|
||||
|
||||
/* Nb of MME to connect to */
|
||||
uint8_t nb_mme;
|
||||
/* List of MME to connect to */
|
||||
net_ip_address_t mme_ip_address[NGAP_MAX_NB_MME_IP_ADDRESS];
|
||||
uint8_t broadcast_plmn_num[NGAP_MAX_NB_MME_IP_ADDRESS];
|
||||
uint8_t broadcast_plmn_index[NGAP_MAX_NB_MME_IP_ADDRESS][PLMN_LIST_MAX_SIZE];
|
||||
/* Nb of AMF to connect to */
|
||||
uint8_t nb_amf;
|
||||
/* List of AMF to connect to */
|
||||
net_ip_address_t amf_ip_address[NGAP_MAX_NB_AMF_IP_ADDRESS];
|
||||
uint8_t broadcast_plmn_num[NGAP_MAX_NB_AMF_IP_ADDRESS];
|
||||
uint8_t broadcast_plmn_index[NGAP_MAX_NB_AMF_IP_ADDRESS][PLMN_LIST_MAX_SIZE];
|
||||
|
||||
/* Number of SCTP streams used for a mme association */
|
||||
/* Number of SCTP streams used for a amf association */
|
||||
uint16_t sctp_in_streams;
|
||||
uint16_t sctp_out_streams;
|
||||
} ngap_register_enb_req_t;
|
||||
} ngap_register_gnb_req_t;
|
||||
|
||||
//-------------------------------------------------------------------------------------------//
|
||||
// NGAP -> gNB application layer messages
|
||||
typedef struct ngap_register_enb_cnf_s {
|
||||
/* Nb of MME connected */
|
||||
uint8_t nb_mme;
|
||||
} ngap_register_enb_cnf_t;
|
||||
typedef struct ngap_register_gnb_cnf_s {
|
||||
/* Nb of AMF connected */
|
||||
uint8_t nb_amf;
|
||||
} ngap_register_gnb_cnf_t;
|
||||
|
||||
typedef struct ngap_deregistered_enb_ind_s {
|
||||
/* Nb of MME connected */
|
||||
uint8_t nb_mme;
|
||||
} ngap_deregistered_enb_ind_t;
|
||||
typedef struct ngap_deregistered_gnb_ind_s {
|
||||
/* Nb of AMF connected */
|
||||
uint8_t nb_amf;
|
||||
} ngap_deregistered_gnb_ind_t;
|
||||
|
||||
//-------------------------------------------------------------------------------------------//
|
||||
// RRC -> NGAP messages
|
||||
|
||||
/* The NAS First Req is the first message exchanged between RRC and NGAP
|
||||
* for an UE.
|
||||
* The rnti uniquely identifies an UE within a cell. Later the enb_ue_ngap_id
|
||||
* The rnti uniquely identifies an UE within a cell. Later the gnb_ue_ngap_id
|
||||
* will be the unique identifier used between RRC and NGAP.
|
||||
*/
|
||||
typedef struct ngap_nas_first_req_s {
|
||||
@@ -428,53 +451,53 @@ typedef struct ngap_nas_first_req_s {
|
||||
/* NAS PDU */
|
||||
nas_pdu_t nas_pdu;
|
||||
|
||||
/* If this flag is set NGAP layer is expecting the GUMMEI. If = 0,
|
||||
/* If this flag is set NGAP layer is expecting the GUAMI. If = 0,
|
||||
* the temporary s-tmsi is used.
|
||||
*/
|
||||
ue_identity_t ue_identity;
|
||||
nrue_identity_t ue_identity;
|
||||
} ngap_nas_first_req_t;
|
||||
|
||||
typedef struct ngap_uplink_nas_s {
|
||||
/* Unique UE identifier within an gNB */
|
||||
unsigned gNB_ue_ngap_id:24;
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
|
||||
/* NAS pdu */
|
||||
nas_pdu_t nas_pdu;
|
||||
} ngap_uplink_nas_t;
|
||||
|
||||
typedef struct ngap_ue_cap_info_ind_s {
|
||||
unsigned gNB_ue_ngap_id:24;
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
ue_radio_cap_t ue_radio_cap;
|
||||
} ngap_ue_cap_info_ind_t;
|
||||
|
||||
typedef struct ngap_initial_context_setup_resp_s {
|
||||
unsigned gNB_ue_ngap_id:24;
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
|
||||
/* Number of e_rab setup-ed in the list */
|
||||
uint8_t nb_of_e_rabs;
|
||||
/* list of e_rab setup-ed by RRC layers */
|
||||
e_rab_setup_t e_rabs[NGAP_MAX_E_RAB];
|
||||
/* Number of pdusession setup-ed in the list */
|
||||
uint8_t nb_of_pdusessions;
|
||||
/* list of pdusession setup-ed by RRC layers */
|
||||
pdusession_setup_t pdusessions[NGAP_MAX_PDUSESSION];
|
||||
|
||||
/* Number of e_rab failed to be setup in list */
|
||||
uint8_t nb_of_e_rabs_failed;
|
||||
/* list of e_rabs that failed to be setup */
|
||||
e_rab_failed_t e_rabs_failed[NGAP_MAX_E_RAB];
|
||||
/* Number of pdusession failed to be setup in list */
|
||||
uint8_t nb_of_pdusessions_failed;
|
||||
/* list of pdusessions that failed to be setup */
|
||||
pdusession_failed_t pdusessions_failed[NGAP_MAX_PDUSESSION];
|
||||
} ngap_initial_context_setup_resp_t;
|
||||
|
||||
typedef struct ngap_initial_context_setup_fail_s {
|
||||
unsigned gNB_ue_ngap_id:24;
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
|
||||
/* TODO add cause */
|
||||
} ngap_initial_context_setup_fail_t, ngap_ue_ctxt_modification_fail_t, ngap_e_rab_setup_req_fail_t;
|
||||
} ngap_initial_context_setup_fail_t, ngap_ue_ctxt_modification_fail_t, ngap_pdusession_setup_req_fail_t;
|
||||
|
||||
typedef struct ngap_nas_non_delivery_ind_s {
|
||||
unsigned gNB_ue_ngap_id:24;
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
nas_pdu_t nas_pdu;
|
||||
/* TODO: add cause */
|
||||
} ngap_nas_non_delivery_ind_t;
|
||||
|
||||
typedef struct ngap_ue_ctxt_modification_req_s {
|
||||
unsigned gNB_ue_ngap_id:24;
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
|
||||
/* Bit-mask of possible present parameters */
|
||||
ngap_ue_ctxt_modification_present_t present;
|
||||
@@ -487,17 +510,17 @@ typedef struct ngap_ue_ctxt_modification_req_s {
|
||||
/* UE aggregate maximum bitrate */
|
||||
ambr_t ue_ambr;
|
||||
|
||||
/* Security capabilities */
|
||||
security_capabilities_t security_capabilities;
|
||||
/* NR Security capabilities */
|
||||
nr_security_capabilities_t security_capabilities;
|
||||
} ngap_ue_ctxt_modification_req_t;
|
||||
|
||||
typedef struct ngap_ue_ctxt_modification_resp_s {
|
||||
unsigned gNB_ue_ngap_id:24;
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
} ngap_ue_ctxt_modification_resp_t;
|
||||
|
||||
typedef struct ngap_ue_release_complete_s {
|
||||
|
||||
unsigned gNB_ue_ngap_id:24;
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
|
||||
} ngap_ue_release_complete_t;
|
||||
|
||||
@@ -508,7 +531,7 @@ typedef struct ngap_downlink_nas_s {
|
||||
uint16_t ue_initial_id;
|
||||
|
||||
/* Unique UE identifier within an gNB */
|
||||
unsigned gNB_ue_ngap_id:24;
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
|
||||
/* NAS pdu */
|
||||
nas_pdu_t nas_pdu;
|
||||
@@ -520,23 +543,30 @@ typedef struct ngap_initial_context_setup_req_s {
|
||||
uint16_t ue_initial_id;
|
||||
|
||||
/* gNB ue ngap id as initialized by NGAP layer */
|
||||
unsigned gNB_ue_ngap_id:24;
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
|
||||
uint32_t mme_ue_ngap_id;
|
||||
unsigned long long amf_ue_ngap_id:40;
|
||||
|
||||
/* UE aggregate maximum bitrate */
|
||||
ambr_t ue_ambr;
|
||||
|
||||
/* guami */
|
||||
ngap_guami_t guami;
|
||||
|
||||
/* allowed nssai */
|
||||
uint8_t nb_allowed_nssais;
|
||||
ngap_allowed_NSSAI_t allowed_nssai[8];
|
||||
|
||||
/* Security algorithms */
|
||||
security_capabilities_t security_capabilities;
|
||||
nr_security_capabilities_t security_capabilities;
|
||||
|
||||
/* Security key */
|
||||
uint8_t security_key[SECURITY_KEY_LENGTH];
|
||||
|
||||
/* Number of e_rab to be setup in the list */
|
||||
uint8_t nb_of_e_rabs;
|
||||
/* list of e_rab to be setup by RRC layers */
|
||||
e_rab_t e_rab_param[NGAP_MAX_E_RAB];
|
||||
/* Number of pdusession to be setup in the list */
|
||||
uint8_t nb_of_pdusessions;
|
||||
/* list of pdusession to be setup by RRC layers */
|
||||
pdusession_t pdusession_param[NGAP_MAX_PDUSESSION];
|
||||
} ngap_initial_context_setup_req_t;
|
||||
|
||||
typedef struct tai_plmn_identity_s {
|
||||
@@ -572,57 +602,57 @@ typedef struct ngap_paging_ind_s {
|
||||
paging_priority_t paging_priority;
|
||||
} ngap_paging_ind_t;
|
||||
|
||||
typedef struct ngap_e_rab_setup_req_s {
|
||||
typedef struct ngap_pdusession_setup_req_s {
|
||||
/* UE id for initial connection to NGAP */
|
||||
uint16_t ue_initial_id;
|
||||
|
||||
/* MME UE id */
|
||||
uint32_t mme_ue_ngap_id;
|
||||
/* AMF UE id */
|
||||
unsigned long long amf_ue_ngap_id:40;
|
||||
|
||||
/* gNB ue ngap id as initialized by NGAP layer */
|
||||
unsigned gNB_ue_ngap_id:24;
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
|
||||
/* Number of e_rab to be setup in the list */
|
||||
uint8_t nb_e_rabs_tosetup;
|
||||
/* Number of pdusession to be setup in the list */
|
||||
uint8_t nb_pdusessions_tosetup;
|
||||
|
||||
/* E RAB setup request */
|
||||
e_rab_t e_rab_setup_params[NGAP_MAX_E_RAB];
|
||||
pdusession_t pdusession_setup_params[NGAP_MAX_PDUSESSION];
|
||||
|
||||
} ngap_e_rab_setup_req_t;
|
||||
} ngap_pdusession_setup_req_t;
|
||||
|
||||
typedef struct ngap_e_rab_setup_resp_s {
|
||||
typedef struct ngap_pdusession_setup_resp_s {
|
||||
unsigned gNB_ue_ngap_id:24;
|
||||
|
||||
/* Number of e_rab setup-ed in the list */
|
||||
uint8_t nb_of_e_rabs;
|
||||
/* list of e_rab setup-ed by RRC layers */
|
||||
e_rab_setup_t e_rabs[NGAP_MAX_E_RAB];
|
||||
/* Number of pdusession setup-ed in the list */
|
||||
uint8_t nb_of_pdusessions;
|
||||
/* list of pdusession setup-ed by RRC layers */
|
||||
pdusession_setup_t pdusessions[NGAP_MAX_PDUSESSION];
|
||||
|
||||
/* Number of e_rab failed to be setup in list */
|
||||
uint8_t nb_of_e_rabs_failed;
|
||||
/* list of e_rabs that failed to be setup */
|
||||
e_rab_failed_t e_rabs_failed[NGAP_MAX_E_RAB];
|
||||
} ngap_e_rab_setup_resp_t;
|
||||
/* Number of pdusession failed to be setup in list */
|
||||
uint8_t nb_of_pdusessions_failed;
|
||||
/* list of pdusessions that failed to be setup */
|
||||
pdusession_failed_t pdusessions_failed[NGAP_MAX_PDUSESSION];
|
||||
} ngap_pdusession_setup_resp_t;
|
||||
|
||||
typedef struct ngap_path_switch_req_s {
|
||||
|
||||
unsigned gNB_ue_ngap_id:24;
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
|
||||
/* Number of e_rab setup-ed in the list */
|
||||
uint8_t nb_of_e_rabs;
|
||||
/* Number of pdusession setup-ed in the list */
|
||||
uint8_t nb_of_pdusessions;
|
||||
|
||||
/* list of e_rab setup-ed by RRC layers */
|
||||
e_rab_setup_t e_rabs_tobeswitched[NGAP_MAX_E_RAB];
|
||||
/* list of pdusession setup-ed by RRC layers */
|
||||
pdusession_setup_t pdusessions_tobeswitched[NGAP_MAX_PDUSESSION];
|
||||
|
||||
/* MME UE id */
|
||||
uint32_t mme_ue_ngap_id;
|
||||
/* AMF UE id */
|
||||
unsigned long long amf_ue_ngap_id:40;
|
||||
|
||||
ngap_gummei_t ue_gummei;
|
||||
ngap_guami_t ue_guami;
|
||||
|
||||
uint16_t ue_initial_id;
|
||||
|
||||
/* Security algorithms */
|
||||
security_capabilities_t security_capabilities;
|
||||
nr_security_capabilities_t security_capabilities;
|
||||
|
||||
} ngap_path_switch_req_t;
|
||||
|
||||
@@ -631,25 +661,25 @@ typedef struct ngap_path_switch_req_ack_s {
|
||||
/* UE id for initial connection to NGAP */
|
||||
uint16_t ue_initial_id;
|
||||
|
||||
unsigned gNB_ue_ngap_id:24;
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
|
||||
/* MME UE id */
|
||||
uint32_t mme_ue_ngap_id;
|
||||
/* AMF UE id */
|
||||
unsigned long long amf_ue_ngap_id:40;
|
||||
|
||||
/* UE aggregate maximum bitrate */
|
||||
ambr_t ue_ambr;
|
||||
|
||||
/* Number of e_rab setup-ed in the list */
|
||||
uint8_t nb_e_rabs_tobeswitched;
|
||||
/* Number of pdusession setup-ed in the list */
|
||||
uint8_t nb_pdusessions_tobeswitched;
|
||||
|
||||
/* list of e_rab to be switched by RRC layers */
|
||||
e_rab_tobeswitched_t e_rabs_tobeswitched[NGAP_MAX_E_RAB];
|
||||
/* list of pdusession to be switched by RRC layers */
|
||||
pdusession_tobeswitched_t pdusessions_tobeswitched[NGAP_MAX_PDUSESSION];
|
||||
|
||||
/* Number of e_rabs to be released by RRC */
|
||||
uint8_t nb_e_rabs_tobereleased;
|
||||
/* Number of pdusessions to be released by RRC */
|
||||
uint8_t nb_pdusessions_tobereleased;
|
||||
|
||||
/* list of e_rabs to be released */
|
||||
e_rab_failed_t e_rabs_tobereleased[NGAP_MAX_E_RAB];
|
||||
/* list of pdusessions to be released */
|
||||
pdusession_failed_t pdusessions_tobereleased[NGAP_MAX_PDUSESSION];
|
||||
|
||||
/* Security key */
|
||||
int next_hop_chain_count;
|
||||
@@ -657,31 +687,31 @@ typedef struct ngap_path_switch_req_ack_s {
|
||||
|
||||
} ngap_path_switch_req_ack_t;
|
||||
|
||||
typedef struct ngap_e_rab_modification_ind_s {
|
||||
typedef struct ngap_pdusession_modification_ind_s {
|
||||
|
||||
unsigned gNB_ue_ngap_id:24;
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
|
||||
/* MME UE id */
|
||||
uint32_t mme_ue_ngap_id;
|
||||
/* AMF UE id */
|
||||
unsigned long long amf_ue_ngap_id:40;
|
||||
|
||||
/* Number of e_rab setup-ed in the list */
|
||||
uint8_t nb_of_e_rabs_tobemodified;
|
||||
/* Number of pdusession setup-ed in the list */
|
||||
uint8_t nb_of_pdusessions_tobemodified;
|
||||
|
||||
uint8_t nb_of_e_rabs_nottobemodified;
|
||||
uint8_t nb_of_pdusessions_nottobemodified;
|
||||
|
||||
/* list of e_rab setup-ed by RRC layers */
|
||||
e_rab_setup_t e_rabs_tobemodified[NGAP_MAX_E_RAB];
|
||||
/* list of pdusession setup-ed by RRC layers */
|
||||
pdusession_setup_t pdusessions_tobemodified[NGAP_MAX_PDUSESSION];
|
||||
|
||||
e_rab_setup_t e_rabs_nottobemodified[NGAP_MAX_E_RAB];
|
||||
pdusession_setup_t pdusessions_nottobemodified[NGAP_MAX_PDUSESSION];
|
||||
|
||||
uint16_t ue_initial_id;
|
||||
|
||||
} ngap_e_rab_modification_ind_t;
|
||||
} ngap_pdusession_modification_ind_t;
|
||||
|
||||
// NGAP --> RRC messages
|
||||
typedef struct ngap_ue_release_command_s {
|
||||
|
||||
unsigned gNB_ue_ngap_id:24;
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
|
||||
} ngap_ue_release_command_t;
|
||||
|
||||
@@ -689,83 +719,83 @@ typedef struct ngap_ue_release_command_s {
|
||||
//-------------------------------------------------------------------------------------------//
|
||||
// NGAP <-- RRC messages
|
||||
typedef struct ngap_ue_release_req_s {
|
||||
unsigned gNB_ue_ngap_id:24;
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
ngap_Cause_t cause;
|
||||
long cause_value;
|
||||
} ngap_ue_release_req_t, ngap_ue_release_resp_t;
|
||||
|
||||
typedef struct ngap_e_rab_modify_req_s {
|
||||
typedef struct ngap_pdusession_modify_req_s {
|
||||
/* UE id for initial connection to NGAP */
|
||||
uint16_t ue_initial_id;
|
||||
|
||||
/* MME UE id */
|
||||
uint32_t mme_ue_ngap_id;
|
||||
/* AMF UE id */
|
||||
unsigned long long amf_ue_ngap_id:40;
|
||||
|
||||
/* gNB ue ngap id as initialized by NGAP layer */
|
||||
unsigned gNB_ue_ngap_id:24;
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
|
||||
/* Number of e_rab to be modify in the list */
|
||||
uint8_t nb_e_rabs_tomodify;
|
||||
/* Number of pdusession to be modify in the list */
|
||||
uint8_t nb_pdusessions_tomodify;
|
||||
|
||||
/* E RAB modify request */
|
||||
e_rab_t e_rab_modify_params[NGAP_MAX_E_RAB];
|
||||
} ngap_e_rab_modify_req_t;
|
||||
pdusession_t pdusession_modify_params[NGAP_MAX_PDUSESSION];
|
||||
} ngap_pdusession_modify_req_t;
|
||||
|
||||
typedef struct ngap_e_rab_modify_resp_s {
|
||||
unsigned gNB_ue_ngap_id:24;
|
||||
typedef struct ngap_pdusession_modify_resp_s {
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
|
||||
/* Number of e_rab modify-ed in the list */
|
||||
uint8_t nb_of_e_rabs;
|
||||
/* list of e_rab modify-ed by RRC layers */
|
||||
e_rab_modify_t e_rabs[NGAP_MAX_E_RAB];
|
||||
/* Number of pdusession modify-ed in the list */
|
||||
uint8_t nb_of_pdusessions;
|
||||
/* list of pdusession modify-ed by RRC layers */
|
||||
pdusession_modify_t pdusessions[NGAP_MAX_PDUSESSION];
|
||||
|
||||
/* Number of e_rab failed to be modify in list */
|
||||
uint8_t nb_of_e_rabs_failed;
|
||||
/* list of e_rabs that failed to be modify */
|
||||
e_rab_failed_t e_rabs_failed[NGAP_MAX_E_RAB];
|
||||
} ngap_e_rab_modify_resp_t;
|
||||
/* Number of pdusession failed to be modify in list */
|
||||
uint8_t nb_of_pdusessions_failed;
|
||||
/* list of pdusessions that failed to be modify */
|
||||
pdusession_failed_t pdusessions_failed[NGAP_MAX_PDUSESSION];
|
||||
} ngap_pdusession_modify_resp_t;
|
||||
|
||||
typedef struct e_rab_release_s {
|
||||
/* Unique e_rab_id for the UE. */
|
||||
uint8_t e_rab_id;
|
||||
} e_rab_release_t;
|
||||
typedef struct pdusession_release_s {
|
||||
/* Unique pdusession_id for the UE. */
|
||||
uint8_t pdusession_id;
|
||||
} pdusession_release_t;
|
||||
|
||||
typedef struct ngap_e_rab_release_command_s {
|
||||
/* MME UE id */
|
||||
uint32_t mme_ue_ngap_id;
|
||||
typedef struct ngap_pdusession_release_command_s {
|
||||
/* AMF UE id */
|
||||
unsigned long long amf_ue_ngap_id:40;
|
||||
|
||||
/* gNB ue ngap id as initialized by NGAP layer */
|
||||
unsigned gNB_ue_ngap_id:24;
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
|
||||
/* The NAS PDU should be forwarded by the RRC layer to the NAS layer */
|
||||
nas_pdu_t nas_pdu;
|
||||
|
||||
/* Number of e_rab to be released in the list */
|
||||
uint8_t nb_e_rabs_torelease;
|
||||
/* Number of pdusession to be released in the list */
|
||||
uint8_t nb_pdusessions_torelease;
|
||||
|
||||
/* E RAB release command */
|
||||
e_rab_release_t e_rab_release_params[NGAP_MAX_E_RAB];
|
||||
pdusession_release_t pdusession_release_params[NGAP_MAX_PDUSESSION];
|
||||
|
||||
} ngap_e_rab_release_command_t;
|
||||
} ngap_pdusession_release_command_t;
|
||||
|
||||
typedef struct ngap_e_rab_release_resp_s {
|
||||
/* MME UE id */
|
||||
uint32_t mme_ue_ngap_id;
|
||||
typedef struct ngap_pdusession_release_resp_s {
|
||||
/* AMF UE id */
|
||||
unsigned long long amf_ue_ngap_id:40;
|
||||
|
||||
/* gNB ue ngap id as initialized by NGAP layer */
|
||||
unsigned gNB_ue_ngap_id:24;
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
|
||||
/* Number of e_rab released in the list */
|
||||
uint8_t nb_of_e_rabs_released;
|
||||
/* Number of pdusession released in the list */
|
||||
uint8_t nb_of_pdusessions_released;
|
||||
|
||||
/* list of e_rabs released */
|
||||
e_rab_release_t e_rab_release[NGAP_MAX_E_RAB];
|
||||
/* list of pdusessions released */
|
||||
pdusession_release_t pdusession_release[NGAP_MAX_PDUSESSION];
|
||||
|
||||
/* Number of e_rab failed to be released in list */
|
||||
uint8_t nb_of_e_rabs_failed;
|
||||
/* list of e_rabs that failed to be released */
|
||||
e_rab_failed_t e_rabs_failed[NGAP_MAX_E_RAB];
|
||||
/* Number of pdusession failed to be released in list */
|
||||
uint8_t nb_of_pdusessions_failed;
|
||||
/* list of pdusessions that failed to be released */
|
||||
pdusession_failed_t pdusessions_failed[NGAP_MAX_PDUSESSION];
|
||||
|
||||
} ngap_e_rab_release_resp_t;
|
||||
} ngap_pdusession_release_resp_t;
|
||||
|
||||
#endif /* NGAP_MESSAGES_TYPES_H_ */
|
||||
|
||||
+19
-19
@@ -75,26 +75,26 @@ static void configure_nr_rrc(uint32_t gnb_id)
|
||||
static uint32_t gNB_app_register(uint32_t gnb_id_start, uint32_t gnb_id_end)//, const Enb_properties_array_t *enb_properties)
|
||||
{
|
||||
uint32_t gnb_id;
|
||||
//MessageDef *msg_p;
|
||||
MessageDef *msg_p;
|
||||
uint32_t register_gnb_pending = 0;
|
||||
|
||||
for (gnb_id = gnb_id_start; (gnb_id < gnb_id_end) ; gnb_id++) {
|
||||
{
|
||||
//s1ap_register_enb_req_t *s1ap_register_gNB; //Type Temporarily reuse
|
||||
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
|
||||
/*msg_p = itti_alloc_new_message (TASK_GNB_APP, S1AP_REGISTER_ENB_REQ); //Message Temporarily reuse
|
||||
*msg_p = itti_alloc_new_message (TASK_GNB_APP, NGAP_REGISTER_GNB_REQ); //Message Temporarily reuse
|
||||
|
||||
RCconfig_NR_S1(msg_p, gnb_id);*/
|
||||
RCconfig_NR_NG(msg_p, gnb_id);
|
||||
|
||||
if (gnb_id == 0) RCconfig_nr_gtpu();
|
||||
|
||||
/*s1ap_register_gNB = &S1AP_REGISTER_ENB_REQ(msg_p); //Message Temporarily reuse
|
||||
LOG_I(GNB_APP,"default drx %d\n",s1ap_register_gNB->default_drx);*/
|
||||
ngap_register_gNB = &NGAP_REGISTER_GNB_REQ(msg_p); //Message Temporarily reuse
|
||||
LOG_I(GNB_APP,"default drx %d\n",ngap_register_gNB->default_drx);*/
|
||||
|
||||
LOG_I(GNB_APP,"[gNB %d] gNB_app_register for instance %d\n", gnb_id, GNB_MODULE_ID_TO_INSTANCE(gnb_id));
|
||||
|
||||
//itti_send_msg_to_task (TASK_S1AP, GNB_MODULE_ID_TO_INSTANCE(gnb_id), msg_p);
|
||||
itti_send_msg_to_task (TASK_NGAP, GNB_MODULE_ID_TO_INSTANCE(gnb_id), msg_p);
|
||||
|
||||
register_gnb_pending++;
|
||||
}
|
||||
@@ -201,16 +201,16 @@ void *gNB_app_task(void *args_p)
|
||||
break;
|
||||
|
||||
|
||||
/*
|
||||
case S1AP_REGISTER_ENB_CNF:
|
||||
LOG_I(GNB_APP, "[gNB %d] Received %s: associated MME %d\n", instance, msg_name,
|
||||
S1AP_REGISTER_ENB_CNF(msg_p).nb_mme);
|
||||
|
||||
case NGAP_REGISTER_GNB_CNF:
|
||||
LOG_I(GNB_APP, "[gNB %d] Received %s: associated AMF %d\n", instance, msg_name,
|
||||
NGAP_REGISTER_GNB_CNF(msg_p).nb_amf);
|
||||
/*
|
||||
DevAssert(register_gnb_pending > 0);
|
||||
register_gnb_pending--;
|
||||
|
||||
// Check if at least gNB is registered with one MME
|
||||
if (S1AP_REGISTER_ENB_CNF(msg_p).nb_mme > 0) {
|
||||
// Check if at least gNB is registered with one AMF
|
||||
if (NGAP_REGISTER_GNB_CNF(msg_p).nb_amf > 0) {
|
||||
registered_gnb++;
|
||||
}
|
||||
|
||||
@@ -226,7 +226,7 @@ void *gNB_app_task(void *args_p)
|
||||
} else {
|
||||
uint32_t not_associated = gnb_nb - registered_gnb;
|
||||
|
||||
LOG_W(GNB_APP, " %d gNB %s not associated with a MME, retrying registration in %d seconds ...\n",
|
||||
LOG_W(GNB_APP, " %d gNB %s not associated with a AMF, retrying registration in %d seconds ...\n",
|
||||
not_associated, not_associated > 1 ? "are" : "is", GNB_REGISTER_RETRY_DELAY);
|
||||
|
||||
// Restart the gNB registration process in GNB_REGISTER_RETRY_DELAY seconds
|
||||
@@ -241,12 +241,12 @@ void *gNB_app_task(void *args_p)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
*/
|
||||
case S1AP_DEREGISTERED_ENB_IND:
|
||||
LOG_W(GNB_APP, "[gNB %d] Received %s: associated MME %d\n", instance, msg_name,
|
||||
S1AP_DEREGISTERED_ENB_IND(msg_p).nb_mme);
|
||||
break;
|
||||
|
||||
case NGAP_DEREGISTERED_GNB_IND:
|
||||
LOG_W(GNB_APP, "[gNB %d] Received %s: associated AMF %d\n", instance, msg_name,
|
||||
NGAP_DEREGISTERED_GNB_IND(msg_p).nb_amf);
|
||||
|
||||
/* TODO handle recovering of registration */
|
||||
break;
|
||||
|
||||
+124
-127
@@ -37,7 +37,7 @@
|
||||
#include "UTIL/OTG/otg.h"
|
||||
#include "UTIL/OTG/otg_externs.h"
|
||||
#include "intertask_interface.h"
|
||||
#include "s1ap_eNB.h"
|
||||
#include "ngap_gNB.h"
|
||||
#include "sctp_eNB_task.h"
|
||||
#include "sctp_default_values.h"
|
||||
// #include "SystemInformationBlockType2.h"
|
||||
@@ -342,7 +342,7 @@ void RCconfig_nr_flexran()
|
||||
if (!GNBParamList.paramarray[i][GNB_GNB_ID_IDX].uptr) {
|
||||
// Calculate a default gNB ID
|
||||
if (EPC_MODE_ENABLED)
|
||||
gnb_id = i + (s1ap_generate_eNB_id () & 0xFFFF8);
|
||||
gnb_id = i + (ngap_generate_gNB_id () & 0xFFFF8);
|
||||
else
|
||||
gnb_id = i;
|
||||
} else {
|
||||
@@ -569,7 +569,7 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
|
||||
// Calculate a default gNB ID
|
||||
if (EPC_MODE_ENABLED) {
|
||||
uint32_t hash;
|
||||
hash = s1ap_generate_eNB_id ();
|
||||
hash = ngap_generate_gNB_id ();
|
||||
gnb_id = i + (hash & 0xFFFF8);
|
||||
} else {
|
||||
gnb_id = i;
|
||||
@@ -683,9 +683,9 @@ int RCconfig_nr_gtpu(void ) {
|
||||
|
||||
|
||||
|
||||
char* gnb_interface_name_for_S1U = NULL;
|
||||
char* gnb_ipv4_address_for_S1U = NULL;
|
||||
uint32_t gnb_port_for_S1U = 0;
|
||||
char* gnb_interface_name_for_NGU = NULL;
|
||||
char* gnb_ipv4_address_for_NGU = NULL;
|
||||
uint32_t gnb_port_for_NGU = 0;
|
||||
char *address = NULL;
|
||||
char *cidr = NULL;
|
||||
char gtpupath[MAX_OPTNAME_SIZE*2 + 8];
|
||||
@@ -708,28 +708,28 @@ int RCconfig_nr_gtpu(void ) {
|
||||
|
||||
|
||||
|
||||
cidr = gnb_ipv4_address_for_S1U;
|
||||
cidr = gnb_ipv4_address_for_NGU;
|
||||
address = strtok(cidr, "/");
|
||||
|
||||
if (address) {
|
||||
MessageDef *message;
|
||||
AssertFatal((message = itti_alloc_new_message(TASK_GNB_APP, GTPV1U_ENB_S1_REQ))!=NULL,"");
|
||||
// IPV4_STR_ADDR_TO_INT_NWBO ( address, RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" );
|
||||
// IPV4_STR_ADDR_TO_INT_NWBO ( address, RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB NG_U !\n" );
|
||||
// LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up);
|
||||
|
||||
|
||||
IPV4_STR_ADDR_TO_INT_NWBO ( address, GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" );
|
||||
IPV4_STR_ADDR_TO_INT_NWBO ( address, GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB NG_U !\n" );
|
||||
LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up);
|
||||
GTPV1U_ENB_S1_REQ(message).enb_port_for_S1u_S12_S4_up = gnb_port_for_S1U;
|
||||
GTPV1U_ENB_S1_REQ(message).enb_port_for_S1u_S12_S4_up = gnb_port_for_NGU;
|
||||
itti_send_msg_to_task (TASK_GTPV1_U, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id)
|
||||
} else
|
||||
LOG_E(GTPU,"invalid address for S1U\n");
|
||||
LOG_E(GTPU,"invalid address for NGU\n");
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RCconfig_NR_S1(MessageDef *msg_p, uint32_t i) {
|
||||
int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i) {
|
||||
|
||||
int j,k = 0;
|
||||
int gnb_id;
|
||||
@@ -779,29 +779,26 @@ int RCconfig_NR_S1(MessageDef *msg_p, uint32_t i) {
|
||||
config_getlist( &GNBParamList,GNBParams,sizeof(GNBParams)/sizeof(paramdef_t),NULL);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (GNBParamList.numelt > 0) {
|
||||
for (k = 0; k < GNBParamList.numelt; k++) {
|
||||
if (GNBParamList.paramarray[k][GNB_GNB_ID_IDX].uptr == NULL) {
|
||||
// Calculate a default gNB ID
|
||||
if (EPC_MODE_ENABLED) {
|
||||
uint32_t hash;
|
||||
|
||||
hash = s1ap_generate_eNB_id ();
|
||||
gnb_id = k + (hash & 0xFFFF8);
|
||||
} else {
|
||||
gnb_id = k;
|
||||
}
|
||||
} else {
|
||||
if (GNBParamList.paramarray[k][GNB_GNB_ID_IDX].uptr == NULL) {
|
||||
// Calculate a default gNB ID
|
||||
if (EPC_MODE_ENABLED) {
|
||||
uint32_t hash;
|
||||
|
||||
hash = ngap_generate_gNB_id ();
|
||||
gnb_id = k + (hash & 0xFFFF8);
|
||||
} else {
|
||||
gnb_id = k;
|
||||
}
|
||||
} else {
|
||||
gnb_id = *(GNBParamList.paramarray[k][GNB_GNB_ID_IDX].uptr);
|
||||
}
|
||||
|
||||
|
||||
// search if in active list
|
||||
for (j=0; j < GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt; j++) {
|
||||
if (strcmp(GNBSParams[GNB_ACTIVE_GNBS_IDX].strlistptr[j], *(GNBParamList.paramarray[k][GNB_GNB_NAME_IDX].strptr)) == 0) {
|
||||
// search if in active list
|
||||
for (j=0; j < GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt; j++) {
|
||||
if (strcmp(GNBSParams[GNB_ACTIVE_GNBS_IDX].strlistptr[j], *(GNBParamList.paramarray[k][GNB_GNB_NAME_IDX].strptr)) == 0) {
|
||||
paramdef_t PLMNParams[] = GNBPLMNPARAMS_DESC;
|
||||
paramlist_def_t PLMNParamList = {GNB_CONFIG_STRING_PLMN_LIST, NULL, 0};
|
||||
/* map parameter checking array instances to parameter definition array instances */
|
||||
@@ -810,27 +807,27 @@ int RCconfig_NR_S1(MessageDef *msg_p, uint32_t i) {
|
||||
for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I)
|
||||
PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]);
|
||||
|
||||
paramdef_t S1Params[] = GNBS1PARAMS_DESC;
|
||||
paramlist_def_t S1ParamList = {GNB_CONFIG_STRING_MME_IP_ADDRESS,NULL,0};
|
||||
|
||||
paramdef_t SCTPParams[] = GNBSCTPPARAMS_DESC;
|
||||
paramdef_t NETParams[] = GNBNETPARAMS_DESC;
|
||||
char aprefix[MAX_OPTNAME_SIZE*2 + 8];
|
||||
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).eNB_id = gnb_id;
|
||||
|
||||
if (strcmp(*(GNBParamList.paramarray[k][GNB_CELL_TYPE_IDX].strptr), "CELL_MACRO_GNB") == 0) {
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_MACRO_ENB;
|
||||
} else if (strcmp(*(GNBParamList.paramarray[k][GNB_CELL_TYPE_IDX].strptr), "CELL_HOME_GNB") == 0) {
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_HOME_ENB;
|
||||
} else {
|
||||
AssertFatal (0,
|
||||
"Failed to parse gNB configuration file %s, gnb %d unknown value \"%s\" for cell_type choice: CELL_MACRO_GNB or CELL_HOME_GNB !\n",
|
||||
RC.config_file_name, i, *(GNBParamList.paramarray[k][GNB_CELL_TYPE_IDX].strptr));
|
||||
}
|
||||
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).eNB_name = strdup(*(GNBParamList.paramarray[k][GNB_GNB_NAME_IDX].strptr));
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).tac = *GNBParamList.paramarray[k][GNB_TRACKING_AREA_CODE_IDX].uptr;
|
||||
paramdef_t NGParams[] = GNBNGPARAMS_DESC;
|
||||
paramlist_def_t NGParamList = {GNB_CONFIG_STRING_AMF_IP_ADDRESS,NULL,0};
|
||||
|
||||
paramdef_t SCTPParams[] = GNBSCTPPARAMS_DESC;
|
||||
paramdef_t NETParams[] = GNBNETPARAMS_DESC;
|
||||
char aprefix[MAX_OPTNAME_SIZE*2 + 8];
|
||||
|
||||
NGAP_REGISTER_GNB_REQ (msg_p).gNB_id = gnb_id;
|
||||
|
||||
if (strcmp(*(GNBParamList.paramarray[k][GNB_CELL_TYPE_IDX].strptr), "CELL_MACRO_GNB") == 0) {
|
||||
NGAP_REGISTER_GNB_REQ (msg_p).cell_type = CELL_MACRO_GNB;
|
||||
} else if (strcmp(*(GNBParamList.paramarray[k][GNB_CELL_TYPE_IDX].strptr), "CELL_HOME_GNB") == 0) {
|
||||
NGAP_REGISTER_GNB_REQ (msg_p).cell_type = CELL_HOME_ENB;
|
||||
} else {
|
||||
AssertFatal (0,
|
||||
"Failed to parse gNB configuration file %s, gnb %d unknown value \"%s\" for cell_type choice: CELL_MACRO_GNB or CELL_HOME_GNB !\n",
|
||||
RC.config_file_name, i, *(GNBParamList.paramarray[k][GNB_CELL_TYPE_IDX].strptr));
|
||||
}
|
||||
|
||||
NGAP_REGISTER_GNB_REQ (msg_p).gNB_name = strdup(*(GNBParamList.paramarray[k][GNB_GNB_NAME_IDX].strptr));
|
||||
NGAP_REGISTER_GNB_REQ (msg_p).tac = *GNBParamList.paramarray[k][GNB_TRACKING_AREA_CODE_IDX].uptr;
|
||||
AssertFatal(!GNBParamList.paramarray[k][GNB_MOBILE_COUNTRY_CODE_IDX_OLD].strptr
|
||||
&& !GNBParamList.paramarray[k][GNB_MOBILE_NETWORK_CODE_IDX_OLD].strptr,
|
||||
"It seems that you use an old configuration file. Please change the existing\n"
|
||||
@@ -846,100 +843,100 @@ int RCconfig_NR_S1(MessageDef *msg_p, uint32_t i) {
|
||||
AssertFatal(0, "The number of PLMN IDs must be in [1,6], but is %d\n",
|
||||
PLMNParamList.numelt);
|
||||
|
||||
S1AP_REGISTER_ENB_REQ(msg_p).num_plmn = PLMNParamList.numelt;
|
||||
NGAP_REGISTER_GNB_REQ(msg_p).num_plmn = PLMNParamList.numelt;
|
||||
|
||||
for (int l = 0; l < PLMNParamList.numelt; ++l) {
|
||||
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).mcc[l] = *PLMNParamList.paramarray[l][GNB_MOBILE_COUNTRY_CODE_IDX].uptr;
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).mnc[l] = *PLMNParamList.paramarray[l][GNB_MOBILE_NETWORK_CODE_IDX].uptr;
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length[l] = *PLMNParamList.paramarray[l][GNB_MNC_DIGIT_LENGTH].u8ptr;
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).default_drx = 0;
|
||||
AssertFatal((S1AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length[l] == 2) ||
|
||||
(S1AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length[l] == 3),
|
||||
"BAD MNC DIGIT LENGTH %d",
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length[l]);
|
||||
}
|
||||
sprintf(aprefix,"%s.[%i]",GNB_CONFIG_STRING_GNB_LIST,k);
|
||||
config_getlist( &S1ParamList,S1Params,sizeof(S1Params)/sizeof(paramdef_t),aprefix);
|
||||
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).nb_mme = 0;
|
||||
|
||||
for (int l = 0; l < S1ParamList.numelt; l++) {
|
||||
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).nb_mme += 1;
|
||||
|
||||
strcpy(S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv4_address,*(S1ParamList.paramarray[l][GNB_MME_IPV4_ADDRESS_IDX].strptr));
|
||||
strcpy(S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv6_address,*(S1ParamList.paramarray[l][GNB_MME_IPV6_ADDRESS_IDX].strptr));
|
||||
|
||||
if (strcmp(*(S1ParamList.paramarray[l][GNB_MME_IP_ADDRESS_ACTIVE_IDX].strptr), "yes") == 0) {
|
||||
}
|
||||
if (strcmp(*(S1ParamList.paramarray[l][GNB_MME_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv4") == 0) {
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[j].ipv4 = 1;
|
||||
} else if (strcmp(*(S1ParamList.paramarray[l][GNB_MME_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv6") == 0) {
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[j].ipv6 = 1;
|
||||
} else if (strcmp(*(S1ParamList.paramarray[l][GNB_MME_IP_ADDRESS_PREFERENCE_IDX].strptr), "no") == 0) {
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[j].ipv4 = 1;
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[j].ipv6 = 1;
|
||||
}
|
||||
NGAP_REGISTER_GNB_REQ (msg_p).mcc[l] = *PLMNParamList.paramarray[l][GNB_MOBILE_COUNTRY_CODE_IDX].uptr;
|
||||
NGAP_REGISTER_GNB_REQ (msg_p).mnc[l] = *PLMNParamList.paramarray[l][GNB_MOBILE_NETWORK_CODE_IDX].uptr;
|
||||
NGAP_REGISTER_GNB_REQ (msg_p).mnc_digit_length[l] = *PLMNParamList.paramarray[l][GNB_MNC_DIGIT_LENGTH].u8ptr;
|
||||
NGAP_REGISTER_GNB_REQ (msg_p).default_drx = 0;
|
||||
AssertFatal((NGAP_REGISTER_GNB_REQ (msg_p).mnc_digit_length[l] == 2) ||
|
||||
(NGAP_REGISTER_GNB_REQ (msg_p).mnc_digit_length[l] == 3),
|
||||
"BAD MNC DIGIT LENGTH %d",
|
||||
NGAP_REGISTER_GNB_REQ (msg_p).mnc_digit_length[l]);
|
||||
}
|
||||
sprintf(aprefix,"%s.[%i]",GNB_CONFIG_STRING_GNB_LIST,k);
|
||||
config_getlist( &NGParamList,NGParams,sizeof(NGParams)/sizeof(paramdef_t),aprefix);
|
||||
|
||||
NGAP_REGISTER_GNB_REQ (msg_p).nb_amf = 0;
|
||||
|
||||
for (int l = 0; l < NGParamList.numelt; l++) {
|
||||
|
||||
NGAP_REGISTER_GNB_REQ (msg_p).nb_amf += 1;
|
||||
|
||||
strcpy(NGAP_REGISTER_GNB_REQ (msg_p).amf_ip_address[l].ipv4_address,*(NGParamList.paramarray[l][GNB_AMF_IPV4_ADDRESS_IDX].strptr));
|
||||
strcpy(NGAP_REGISTER_GNB_REQ (msg_p).amf_ip_address[l].ipv6_address,*(NGParamList.paramarray[l][GNB_AMF_IPV6_ADDRESS_IDX].strptr));
|
||||
|
||||
if (S1ParamList.paramarray[l][GNB_MME_BROADCAST_PLMN_INDEX].iptr)
|
||||
S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] = S1ParamList.paramarray[l][GNB_MME_BROADCAST_PLMN_INDEX].numelt;
|
||||
if (strcmp(*(NGParamList.paramarray[l][GNB_AMF_IP_ADDRESS_ACTIVE_IDX].strptr), "yes") == 0) {
|
||||
}
|
||||
if (strcmp(*(NGParamList.paramarray[l][GNB_AMF_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv4") == 0) {
|
||||
NGAP_REGISTER_GNB_REQ (msg_p).amf_ip_address[j].ipv4 = 1;
|
||||
} else if (strcmp(*(NGParamList.paramarray[l][GNB_AMF_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv6") == 0) {
|
||||
NGAP_REGISTER_GNB_REQ (msg_p).amf_ip_address[j].ipv6 = 1;
|
||||
} else if (strcmp(*(NGParamList.paramarray[l][GNB_AMF_IP_ADDRESS_PREFERENCE_IDX].strptr), "no") == 0) {
|
||||
NGAP_REGISTER_GNB_REQ (msg_p).amf_ip_address[j].ipv4 = 1;
|
||||
NGAP_REGISTER_GNB_REQ (msg_p).amf_ip_address[j].ipv6 = 1;
|
||||
}
|
||||
|
||||
if (NGParamList.paramarray[l][GNB_AMF_BROADCAST_PLMN_INDEX].iptr)
|
||||
NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_num[l] = NGParamList.paramarray[l][GNB_AMF_BROADCAST_PLMN_INDEX].numelt;
|
||||
else
|
||||
S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] = 0;
|
||||
NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_num[l] = 0;
|
||||
|
||||
AssertFatal(S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] <= S1AP_REGISTER_ENB_REQ(msg_p).num_plmn,
|
||||
"List of broadcast PLMN to be sent to MME can not be longer than actual "
|
||||
AssertFatal(NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_num[l] <= NGAP_REGISTER_GNB_REQ(msg_p).num_plmn,
|
||||
"List of broadcast PLMN to be sent to AMF can not be longer than actual "
|
||||
"PLMN list (max %d, but is %d)\n",
|
||||
S1AP_REGISTER_ENB_REQ(msg_p).num_plmn,
|
||||
S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l]);
|
||||
NGAP_REGISTER_GNB_REQ(msg_p).num_plmn,
|
||||
NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_num[l]);
|
||||
|
||||
for (int el = 0; el < S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l]; ++el) {
|
||||
for (int el = 0; el < NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_num[l]; ++el) {
|
||||
/* UINTARRAY gets mapped to int, see config_libconfig.c:223 */
|
||||
S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_index[l][el] = S1ParamList.paramarray[l][GNB_MME_BROADCAST_PLMN_INDEX].iptr[el];
|
||||
AssertFatal(S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_index[l][el] >= 0
|
||||
&& S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_index[l][el] < S1AP_REGISTER_ENB_REQ(msg_p).num_plmn,
|
||||
"index for MME's MCC/MNC (%d) is an invalid index for the registered PLMN IDs (%d)\n",
|
||||
S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_index[l][el],
|
||||
S1AP_REGISTER_ENB_REQ(msg_p).num_plmn);
|
||||
NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_index[l][el] = NGParamList.paramarray[l][GNB_AMF_BROADCAST_PLMN_INDEX].iptr[el];
|
||||
AssertFatal(NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_index[l][el] >= 0
|
||||
&& NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_index[l][el] < NGAP_REGISTER_GNB_REQ(msg_p).num_plmn,
|
||||
"index for AMF's MCC/MNC (%d) is an invalid index for the registered PLMN IDs (%d)\n",
|
||||
NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_index[l][el],
|
||||
NGAP_REGISTER_GNB_REQ(msg_p).num_plmn);
|
||||
}
|
||||
|
||||
/* if no broadcasst_plmn array is defined, fill default values */
|
||||
if (S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] == 0) {
|
||||
S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] = S1AP_REGISTER_ENB_REQ(msg_p).num_plmn;
|
||||
if (NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_num[l] == 0) {
|
||||
NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_num[l] = NGAP_REGISTER_GNB_REQ(msg_p).num_plmn;
|
||||
|
||||
for (int el = 0; el < S1AP_REGISTER_ENB_REQ(msg_p).num_plmn; ++el)
|
||||
S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_index[l][el] = el;
|
||||
for (int el = 0; el < NGAP_REGISTER_GNB_REQ(msg_p).num_plmn; ++el)
|
||||
NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_index[l][el] = el;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// SCTP SETTING
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = SCTP_OUT_STREAMS;
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = SCTP_IN_STREAMS;
|
||||
if (EPC_MODE_ENABLED) {
|
||||
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);
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[GNB_SCTP_INSTREAMS_IDX].uptr);
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = (uint16_t)*(SCTPParams[GNB_SCTP_OUTSTREAMS_IDX].uptr);
|
||||
}
|
||||
|
||||
// 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 (EPC_MODE_ENABLED) {
|
||||
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);
|
||||
NGAP_REGISTER_GNB_REQ (msg_p).sctp_out_streams = (uint16_t)*(SCTPParams[GNB_SCTP_OUTSTREAMS_IDX].uptr);
|
||||
}
|
||||
|
||||
sprintf(aprefix,"%s.[%i].%s",GNB_CONFIG_STRING_GNB_LIST,k,GNB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG);
|
||||
// NETWORK_INTERFACES
|
||||
// NETWORK_INTERFACES
|
||||
config_get( NETParams,sizeof(NETParams)/sizeof(paramdef_t),aprefix);
|
||||
|
||||
// S1AP_REGISTER_ENB_REQ (msg_p).enb_interface_name_for_S1U = strdup(enb_interface_name_for_S1U);
|
||||
cidr = *(NETParams[GNB_IPV4_ADDRESS_FOR_S1_MME_IDX].strptr);
|
||||
address = strtok(cidr, "/");
|
||||
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).enb_ip_address.ipv6 = 0;
|
||||
S1AP_REGISTER_ENB_REQ (msg_p).enb_ip_address.ipv4 = 1;
|
||||
|
||||
strcpy(S1AP_REGISTER_ENB_REQ (msg_p).enb_ip_address.ipv4_address, address);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// NGAP_REGISTER_GNB_REQ (msg_p).enb_interface_name_for_NGU = strdup(enb_interface_name_for_NGU);
|
||||
cidr = *(NETParams[GNB_IPV4_ADDRESS_FOR_NG_AMF_IDX].strptr);
|
||||
address = strtok(cidr, "/");
|
||||
|
||||
NGAP_REGISTER_GNB_REQ (msg_p).gnb_ip_address.ipv6 = 0;
|
||||
NGAP_REGISTER_GNB_REQ (msg_p).gnb_ip_address.ipv4 = 1;
|
||||
|
||||
strcpy(NGAP_REGISTER_GNB_REQ (msg_p).gnb_ip_address.ipv4_address, address);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1038,7 +1035,7 @@ int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i) {
|
||||
// Calculate a default eNB ID
|
||||
if (EPC_MODE_ENABLED) {
|
||||
uint32_t hash;
|
||||
hash = s1ap_generate_eNB_id ();
|
||||
hash = ngap_generate_gNB_id ();
|
||||
gnb_id = k + (hash & 0xFFFF8);
|
||||
} else {
|
||||
gnb_id = k;
|
||||
|
||||
@@ -102,7 +102,7 @@ extern void NRRCConfig(void);
|
||||
//void ru_config_display(void);
|
||||
|
||||
void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc);
|
||||
int RCconfig_NR_S1(MessageDef *msg_p, uint32_t i);
|
||||
int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i);
|
||||
int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i);
|
||||
|
||||
#endif /* GNB_CONFIG_H_ */
|
||||
|
||||
@@ -226,34 +226,34 @@ typedef struct ccparams_nr_x2 {
|
||||
|
||||
|
||||
/* MME configuration parameters section name */
|
||||
#define GNB_CONFIG_STRING_MME_IP_ADDRESS "mme_ip_address"
|
||||
#define GNB_CONFIG_STRING_AMF_IP_ADDRESS "amf_ip_address"
|
||||
|
||||
/* SRB1 configuration parameters names */
|
||||
|
||||
|
||||
#define GNB_CONFIG_STRING_MME_IPV4_ADDRESS "ipv4"
|
||||
#define GNB_CONFIG_STRING_MME_IPV6_ADDRESS "ipv6"
|
||||
#define GNB_CONFIG_STRING_MME_IP_ADDRESS_ACTIVE "active"
|
||||
#define GNB_CONFIG_STRING_MME_IP_ADDRESS_PREFERENCE "preference"
|
||||
#define GNB_CONFIG_STRING_MME_BROADCAST_PLMN_INDEX "broadcast_plmn_index"
|
||||
#define GNB_CONFIG_STRING_AMF_IPV4_ADDRESS "ipv4"
|
||||
#define GNB_CONFIG_STRING_AMF_IPV6_ADDRESS "ipv6"
|
||||
#define GNB_CONFIG_STRING_AMF_IP_ADDRESS_ACTIVE "active"
|
||||
#define GNB_CONFIG_STRING_AMF_IP_ADDRESS_PREFERENCE "preference"
|
||||
#define GNB_CONFIG_STRING_AMF_BROADCAST_PLMN_INDEX "broadcast_plmn_index"
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* MME configuration parameters */
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
#define GNBS1PARAMS_DESC { \
|
||||
{GNB_CONFIG_STRING_MME_IPV4_ADDRESS, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_MME_IPV6_ADDRESS, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_MME_IP_ADDRESS_ACTIVE, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_MME_IP_ADDRESS_PREFERENCE, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
#define GNBNGPARAMS_DESC { \
|
||||
{GNB_CONFIG_STRING_AMF_IPV4_ADDRESS, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_AMF_IPV6_ADDRESS, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_AMF_IP_ADDRESS_ACTIVE, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_AMF_IP_ADDRESS_PREFERENCE, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
}
|
||||
|
||||
#define GNB_MME_IPV4_ADDRESS_IDX 0
|
||||
#define GNB_MME_IPV6_ADDRESS_IDX 1
|
||||
#define GNB_MME_IP_ADDRESS_ACTIVE_IDX 2
|
||||
#define GNB_MME_IP_ADDRESS_PREFERENCE_IDX 3
|
||||
#define GNB_MME_BROADCAST_PLMN_INDEX 4
|
||||
#define GNB_AMF_IPV4_ADDRESS_IDX 0
|
||||
#define GNB_AMF_IPV6_ADDRESS_IDX 1
|
||||
#define GNB_AMF_IP_ADDRESS_ACTIVE_IDX 2
|
||||
#define GNB_AMF_IP_ADDRESS_PREFERENCE_IDX 3
|
||||
#define GNB_AMF_BROADCAST_PLMN_INDEX 4
|
||||
/*---------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* SCTP configuration parameters section name */
|
||||
@@ -281,20 +281,20 @@ typedef struct ccparams_nr_x2 {
|
||||
/* S1 interface configuration parameters section name */
|
||||
#define GNB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG "NETWORK_INTERFACES"
|
||||
|
||||
#define GNB_INTERFACE_NAME_FOR_S1_MME_IDX 0
|
||||
#define GNB_IPV4_ADDRESS_FOR_S1_MME_IDX 1
|
||||
#define GNB_INTERFACE_NAME_FOR_S1U_IDX 2
|
||||
#define GNB_IPV4_ADDR_FOR_S1U_IDX 3
|
||||
#define GNB_PORT_FOR_S1U_IDX 4
|
||||
#define GNB_INTERFACE_NAME_FOR_NG_AMF_IDX 0
|
||||
#define GNB_IPV4_ADDRESS_FOR_NG_AMF_IDX 1
|
||||
#define GNB_INTERFACE_NAME_FOR_NGU_IDX 2
|
||||
#define GNB_IPV4_ADDR_FOR_NGU_IDX 3
|
||||
#define GNB_PORT_FOR_NGU_IDX 4
|
||||
#define GNB_IPV4_ADDR_FOR_X2C_IDX 5
|
||||
#define GNB_PORT_FOR_X2C_IDX 6
|
||||
|
||||
/* S1 interface configuration parameters names */
|
||||
#define GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_S1_MME "GNB_INTERFACE_NAME_FOR_S1_MME"
|
||||
#define GNB_CONFIG_STRING_GNB_IPV4_ADDRESS_FOR_S1_MME "GNB_IPV4_ADDRESS_FOR_S1_MME"
|
||||
#define GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_S1U "GNB_INTERFACE_NAME_FOR_S1U"
|
||||
#define GNB_CONFIG_STRING_GNB_IPV4_ADDR_FOR_S1U "GNB_IPV4_ADDRESS_FOR_S1U"
|
||||
#define GNB_CONFIG_STRING_GNB_PORT_FOR_S1U "GNB_PORT_FOR_S1U"
|
||||
#define GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_NG_AMF "GNB_INTERFACE_NAME_FOR_NG_AMF"
|
||||
#define GNB_CONFIG_STRING_GNB_IPV4_ADDRESS_FOR_NG_AMF "GNB_IPV4_ADDRESS_FOR_NG_AMF"
|
||||
#define GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_NGU "GNB_INTERFACE_NAME_FOR_NGU"
|
||||
#define GNB_CONFIG_STRING_GNB_IPV4_ADDR_FOR_NGU "GNB_IPV4_ADDRESS_FOR_NGU"
|
||||
#define GNB_CONFIG_STRING_GNB_PORT_FOR_NGU "GNB_PORT_FOR_NGU"
|
||||
|
||||
/* X2 interface configuration parameters names */
|
||||
#define GNB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_X2C "GNB_IPV4_ADDRESS_FOR_X2C"
|
||||
@@ -305,11 +305,11 @@ typedef struct ccparams_nr_x2 {
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
/*--------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
#define GNBNETPARAMS_DESC { \
|
||||
{GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_S1_MME, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_IPV4_ADDRESS_FOR_S1_MME, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_S1U, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_IPV4_ADDR_FOR_S1U, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_PORT_FOR_S1U, NULL, 0, uptr:NULL, defintval:2152L, TYPE_UINT, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_NG_AMF, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_IPV4_ADDRESS_FOR_NG_AMF, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_NGU, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_IPV4_ADDR_FOR_NGU, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_PORT_FOR_NGU, NULL, 0, uptr:NULL, defintval:2152L, TYPE_UINT, 0}, \
|
||||
{GNB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_X2C, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_ENB_PORT_FOR_X2C, NULL, 0, uptr:NULL, defintval:0L, TYPE_UINT, 0} \
|
||||
}
|
||||
@@ -321,9 +321,9 @@ typedef struct ccparams_nr_x2 {
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
/*--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
#define GNBGTPUPARAMS_DESC { \
|
||||
{GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_S1U, NULL, 0, strptr:&gnb_interface_name_for_S1U, defstrval:"lo", TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_IPV4_ADDR_FOR_S1U, NULL, 0, strptr:&gnb_ipv4_address_for_S1U, defstrval:"127.0.0.1", TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_PORT_FOR_S1U, NULL, 0, uptr:&gnb_port_for_S1U, defintval:2152, TYPE_UINT, 0} \
|
||||
{GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_NGU, NULL, 0, strptr:&gnb_interface_name_for_NGU, defstrval:"lo", TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_IPV4_ADDR_FOR_NGU, NULL, 0, strptr:&gnb_ipv4_address_for_NGU, defstrval:"127.0.0.1", TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_GNB_PORT_FOR_NGU, NULL, 0, uptr:&gnb_port_for_NGU, defintval:2152, TYPE_UINT, 0} \
|
||||
}
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
@@ -2945,10 +2945,10 @@ AMFName ::= PrintableString (SIZE(1..150, ...))
|
||||
AMFPagingTarget ::= CHOICE {
|
||||
globalRANNodeID GlobalRANNodeID,
|
||||
tAI TAI,
|
||||
choice-Extensions ProtocolIE-SingleContainer { {AMFPagingTarget-ExtIEs} }
|
||||
choice-Extensions ProtocolExtensionContainer { {AMFPagingTarget-ExtIEs} }
|
||||
}
|
||||
|
||||
AMFPagingTarget-ExtIEs NGAP-PROTOCOL-IES ::= {
|
||||
AMFPagingTarget-ExtIEs NGAP-PROTOCOL-EXTENSION ::= {
|
||||
...
|
||||
}
|
||||
|
||||
@@ -3121,10 +3121,10 @@ BroadcastCancelledAreaList ::= CHOICE {
|
||||
cellIDCancelledNR CellIDCancelledNR,
|
||||
tAICancelledNR TAICancelledNR,
|
||||
emergencyAreaIDCancelledNR EmergencyAreaIDCancelledNR,
|
||||
choice-Extensions ProtocolIE-SingleContainer { {BroadcastCancelledAreaList-ExtIEs} }
|
||||
choice-Extensions ProtocolExtensionContainer { {BroadcastCancelledAreaList-ExtIEs} }
|
||||
}
|
||||
|
||||
BroadcastCancelledAreaList-ExtIEs NGAP-PROTOCOL-IES ::= {
|
||||
BroadcastCancelledAreaList-ExtIEs NGAP-PROTOCOL-EXTENSION ::= {
|
||||
...
|
||||
}
|
||||
|
||||
@@ -3135,10 +3135,10 @@ BroadcastCompletedAreaList ::= CHOICE {
|
||||
cellIDBroadcastNR CellIDBroadcastNR,
|
||||
tAIBroadcastNR TAIBroadcastNR,
|
||||
emergencyAreaIDBroadcastNR EmergencyAreaIDBroadcastNR,
|
||||
choice-Extensions ProtocolIE-SingleContainer { {BroadcastCompletedAreaList-ExtIEs} }
|
||||
choice-Extensions ProtocolExtensionContainer { {BroadcastCompletedAreaList-ExtIEs} }
|
||||
}
|
||||
|
||||
BroadcastCompletedAreaList-ExtIEs NGAP-PROTOCOL-IES ::= {
|
||||
BroadcastCompletedAreaList-ExtIEs NGAP-PROTOCOL-EXTENSION ::= {
|
||||
...
|
||||
}
|
||||
|
||||
@@ -3220,10 +3220,10 @@ Cause ::= CHOICE {
|
||||
nas CauseNas,
|
||||
protocol CauseProtocol,
|
||||
misc CauseMisc,
|
||||
choice-Extensions ProtocolIE-SingleContainer { {Cause-ExtIEs} }
|
||||
choice-Extensions ProtocolExtensionContainer { {Cause-ExtIEs} }
|
||||
}
|
||||
|
||||
Cause-ExtIEs NGAP-PROTOCOL-IES ::= {
|
||||
Cause-ExtIEs NGAP-PROTOCOL-EXTENSION ::= {
|
||||
...
|
||||
}
|
||||
|
||||
@@ -3367,10 +3367,10 @@ CellIDCancelledNR-Item-ExtIEs NGAP-PROTOCOL-EXTENSION ::= {
|
||||
CellIDListForRestart ::= CHOICE {
|
||||
eUTRA-CGIListforRestart EUTRA-CGIList,
|
||||
nR-CGIListforRestart NR-CGIList,
|
||||
choice-Extensions ProtocolIE-SingleContainer { {CellIDListForRestart-ExtIEs} }
|
||||
choice-Extensions ProtocolExtensionContainer { {CellIDListForRestart-ExtIEs} }
|
||||
}
|
||||
|
||||
CellIDListForRestart-ExtIEs NGAP-PROTOCOL-IES ::= {
|
||||
CellIDListForRestart-ExtIEs NGAP-PROTOCOL-EXTENSION ::= {
|
||||
...
|
||||
}
|
||||
|
||||
@@ -3530,6 +3530,7 @@ CPTransportLayerInformation-ExtIEs NGAP-PROTOCOL-IES ::= {
|
||||
...
|
||||
}
|
||||
|
||||
|
||||
CriticalityDiagnostics ::= SEQUENCE {
|
||||
procedureCode ProcedureCode OPTIONAL,
|
||||
triggeringMessage TriggeringMessage OPTIONAL,
|
||||
@@ -3626,10 +3627,10 @@ DRBsSubjectToStatusTransferItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= {
|
||||
DRBStatusDL ::= CHOICE {
|
||||
dRBStatusDL12 DRBStatusDL12,
|
||||
dRBStatusDL18 DRBStatusDL18,
|
||||
choice-Extensions ProtocolIE-SingleContainer { {DRBStatusDL-ExtIEs} }
|
||||
choice-Extensions ProtocolExtensionContainer { {DRBStatusDL-ExtIEs} }
|
||||
}
|
||||
|
||||
DRBStatusDL-ExtIEs NGAP-PROTOCOL-IES ::= {
|
||||
DRBStatusDL-ExtIEs NGAP-PROTOCOL-EXTENSION ::= {
|
||||
...
|
||||
}
|
||||
|
||||
@@ -3656,10 +3657,10 @@ DRBStatusDL18-ExtIEs NGAP-PROTOCOL-EXTENSION ::= {
|
||||
DRBStatusUL ::= CHOICE {
|
||||
dRBStatusUL12 DRBStatusUL12,
|
||||
dRBStatusUL18 DRBStatusUL18,
|
||||
choice-Extensions ProtocolIE-SingleContainer { {DRBStatusUL-ExtIEs} }
|
||||
choice-Extensions ProtocolExtensionContainer { {DRBStatusUL-ExtIEs} }
|
||||
}
|
||||
|
||||
DRBStatusUL-ExtIEs NGAP-PROTOCOL-IES ::= {
|
||||
DRBStatusUL-ExtIEs NGAP-PROTOCOL-EXTENSION ::= {
|
||||
...
|
||||
}
|
||||
|
||||
@@ -4011,19 +4012,19 @@ GlobalRANNodeID ::= CHOICE {
|
||||
globalGNB-ID GlobalGNB-ID,
|
||||
globalNgENB-ID GlobalNgENB-ID,
|
||||
globalN3IWF-ID GlobalN3IWF-ID,
|
||||
choice-Extensions ProtocolIE-SingleContainer { {GlobalRANNodeID-ExtIEs} }
|
||||
choice-Extensions ProtocolExtensionContainer { {GlobalRANNodeID-ExtIEs} }
|
||||
}
|
||||
|
||||
GlobalRANNodeID-ExtIEs NGAP-PROTOCOL-IES ::= {
|
||||
GlobalRANNodeID-ExtIEs NGAP-PROTOCOL-EXTENSION ::= {
|
||||
...
|
||||
}
|
||||
|
||||
GNB-ID ::= CHOICE {
|
||||
gNB-ID BIT STRING (SIZE(22..32)),
|
||||
choice-Extensions ProtocolIE-SingleContainer { {GNB-ID-ExtIEs} }
|
||||
choice-Extensions ProtocolExtensionContainer { {GNB-ID-ExtIEs} }
|
||||
}
|
||||
|
||||
GNB-ID-ExtIEs NGAP-PROTOCOL-IES ::= {
|
||||
GNB-ID-ExtIEs NGAP-PROTOCOL-EXTENSION ::= {
|
||||
...
|
||||
}
|
||||
|
||||
@@ -4180,10 +4181,10 @@ LastVisitedCellInformation ::= CHOICE {
|
||||
eUTRANCell LastVisitedEUTRANCellInformation,
|
||||
uTRANCell LastVisitedUTRANCellInformation,
|
||||
gERANCell LastVisitedGERANCellInformation,
|
||||
choice-Extensions ProtocolIE-SingleContainer { {LastVisitedCellInformation-ExtIEs} }
|
||||
choice-Extensions ProtocolExtensionContainer { {LastVisitedCellInformation-ExtIEs} }
|
||||
}
|
||||
|
||||
LastVisitedCellInformation-ExtIEs NGAP-PROTOCOL-IES ::= {
|
||||
LastVisitedCellInformation-ExtIEs NGAP-PROTOCOL-EXTENSION ::= {
|
||||
...
|
||||
}
|
||||
|
||||
@@ -4280,10 +4281,10 @@ MobilityRestrictionList-ExtIEs NGAP-PROTOCOL-EXTENSION ::= {
|
||||
|
||||
N3IWF-ID ::= CHOICE {
|
||||
n3IWF-ID BIT STRING (SIZE(16)),
|
||||
choice-Extensions ProtocolIE-SingleContainer { {N3IWF-ID-ExtIEs} }
|
||||
choice-Extensions ProtocolExtensionContainer { {N3IWF-ID-ExtIEs} }
|
||||
}
|
||||
|
||||
N3IWF-ID-ExtIEs NGAP-PROTOCOL-IES ::= {
|
||||
N3IWF-ID-ExtIEs NGAP-PROTOCOL-EXTENSION ::= {
|
||||
...
|
||||
}
|
||||
|
||||
@@ -4310,20 +4311,20 @@ NgENB-ID ::= CHOICE {
|
||||
macroNgENB-ID BIT STRING (SIZE(20)),
|
||||
shortMacroNgENB-ID BIT STRING (SIZE(18)),
|
||||
longMacroNgENB-ID BIT STRING (SIZE(21)),
|
||||
choice-Extensions ProtocolIE-SingleContainer { {NgENB-ID-ExtIEs} }
|
||||
choice-Extensions ProtocolExtensionContainer { {NgENB-ID-ExtIEs} }
|
||||
}
|
||||
|
||||
NgENB-ID-ExtIEs NGAP-PROTOCOL-IES ::= {
|
||||
NgENB-ID-ExtIEs NGAP-PROTOCOL-EXTENSION ::= {
|
||||
...
|
||||
}
|
||||
|
||||
NGRAN-CGI ::= CHOICE {
|
||||
nR-CGI NR-CGI,
|
||||
eUTRA-CGI EUTRA-CGI,
|
||||
choice-Extensions ProtocolIE-SingleContainer { {NGRAN-CGI-ExtIEs} }
|
||||
choice-Extensions ProtocolExtensionContainer { {NGRAN-CGI-ExtIEs} }
|
||||
}
|
||||
|
||||
NGRAN-CGI-ExtIEs NGAP-PROTOCOL-IES ::= {
|
||||
NGRAN-CGI-ExtIEs NGAP-PROTOCOL-EXTENSION ::= {
|
||||
...
|
||||
}
|
||||
|
||||
@@ -4406,10 +4407,10 @@ OverloadAction ::= ENUMERATED {
|
||||
|
||||
OverloadResponse ::= CHOICE {
|
||||
overloadAction OverloadAction,
|
||||
choice-Extensions ProtocolIE-SingleContainer { {OverloadResponse-ExtIEs} }
|
||||
choice-Extensions ProtocolExtensionContainer { {OverloadResponse-ExtIEs} }
|
||||
}
|
||||
|
||||
OverloadResponse-ExtIEs NGAP-PROTOCOL-IES ::= {
|
||||
OverloadResponse-ExtIEs NGAP-PROTOCOL-EXTENSION ::= {
|
||||
...
|
||||
}
|
||||
|
||||
@@ -5185,10 +5186,10 @@ PriorityLevelQos ::= INTEGER (1..127, ...)
|
||||
PWSFailedCellIDList ::= CHOICE {
|
||||
eUTRA-CGI-PWSFailedList EUTRA-CGIList,
|
||||
nR-CGI-PWSFailedList NR-CGIList,
|
||||
choice-Extensions ProtocolIE-SingleContainer { {PWSFailedCellIDList-ExtIEs} }
|
||||
choice-Extensions ProtocolExtensionContainer { {PWSFailedCellIDList-ExtIEs} }
|
||||
}
|
||||
|
||||
PWSFailedCellIDList-ExtIEs NGAP-PROTOCOL-IES ::= {
|
||||
PWSFailedCellIDList-ExtIEs NGAP-PROTOCOL-EXTENSION ::= {
|
||||
...
|
||||
}
|
||||
|
||||
@@ -5197,10 +5198,10 @@ PWSFailedCellIDList-ExtIEs NGAP-PROTOCOL-IES ::= {
|
||||
QosCharacteristics ::= CHOICE {
|
||||
nonDynamic5QI NonDynamic5QIDescriptor,
|
||||
dynamic5QI Dynamic5QIDescriptor,
|
||||
choice-Extensions ProtocolIE-SingleContainer { {QosCharacteristics-ExtIEs} }
|
||||
choice-Extensions ProtocolExtensionContainer { {QosCharacteristics-ExtIEs} }
|
||||
}
|
||||
|
||||
QosCharacteristics-ExtIEs NGAP-PROTOCOL-IES ::= {
|
||||
QosCharacteristics-ExtIEs NGAP-PROTOCOL-EXTENSION ::= {
|
||||
...
|
||||
}
|
||||
|
||||
@@ -5506,10 +5507,10 @@ ResetAll ::= ENUMERATED {
|
||||
ResetType ::= CHOICE {
|
||||
nG-Interface ResetAll,
|
||||
partOfNG-Interface UE-associatedLogicalNG-connectionList,
|
||||
choice-Extensions ProtocolIE-SingleContainer { {ResetType-ExtIEs} }
|
||||
choice-Extensions ProtocolExtensionContainer { {ResetType-ExtIEs} }
|
||||
}
|
||||
|
||||
ResetType-ExtIEs NGAP-PROTOCOL-IES ::= {
|
||||
ResetType-ExtIEs NGAP-PROTOCOL-EXTENSION ::= {
|
||||
...
|
||||
}
|
||||
|
||||
@@ -5692,10 +5693,10 @@ SONConfigurationTransfer-ExtIEs NGAP-PROTOCOL-EXTENSION ::= {
|
||||
SONInformation ::= CHOICE {
|
||||
sONInformationRequest SONInformationRequest,
|
||||
sONInformationReply SONInformationReply,
|
||||
choice-Extensions ProtocolIE-SingleContainer { {SONInformation-ExtIEs} }
|
||||
choice-Extensions ProtocolExtensionContainer { {SONInformation-ExtIEs} }
|
||||
}
|
||||
|
||||
SONInformation-ExtIEs NGAP-PROTOCOL-IES ::= {
|
||||
SONInformation-ExtIEs NGAP-PROTOCOL-EXTENSION ::= {
|
||||
...
|
||||
}
|
||||
|
||||
@@ -5896,10 +5897,10 @@ TargeteNB-ID-ExtIEs NGAP-PROTOCOL-EXTENSION ::= {
|
||||
TargetID ::= CHOICE {
|
||||
targetRANNodeID TargetRANNodeID,
|
||||
targeteNB-ID TargeteNB-ID,
|
||||
choice-Extensions ProtocolIE-SingleContainer { {TargetID-ExtIEs} }
|
||||
choice-Extensions ProtocolExtensionContainer { {TargetID-ExtIEs} }
|
||||
}
|
||||
|
||||
TargetID-ExtIEs NGAP-PROTOCOL-IES ::= {
|
||||
TargetID-ExtIEs NGAP-PROTOCOL-EXTENSION ::= {
|
||||
...
|
||||
}
|
||||
|
||||
@@ -6027,20 +6028,20 @@ UEHistoryInformation ::= SEQUENCE (SIZE(1..maxnoofCellsinUEHistoryInfo)) OF Last
|
||||
|
||||
UEIdentityIndexValue ::= CHOICE {
|
||||
indexLength10 BIT STRING (SIZE(10)),
|
||||
choice-Extensions ProtocolIE-SingleContainer { {UEIdentityIndexValue-ExtIEs} }
|
||||
choice-Extensions ProtocolExtensionContainer { {UEIdentityIndexValue-ExtIEs} }
|
||||
}
|
||||
|
||||
UEIdentityIndexValue-ExtIEs NGAP-PROTOCOL-IES ::= {
|
||||
UEIdentityIndexValue-ExtIEs NGAP-PROTOCOL-EXTENSION ::= {
|
||||
...
|
||||
}
|
||||
|
||||
UE-NGAP-IDs ::= CHOICE {
|
||||
uE-NGAP-ID-pair UE-NGAP-ID-pair,
|
||||
aMF-UE-NGAP-ID AMF-UE-NGAP-ID,
|
||||
choice-Extensions ProtocolIE-SingleContainer { {UE-NGAP-IDs-ExtIEs} }
|
||||
choice-Extensions ProtocolExtensionContainer { {UE-NGAP-IDs-ExtIEs} }
|
||||
}
|
||||
|
||||
UE-NGAP-IDs-ExtIEs NGAP-PROTOCOL-IES ::= {
|
||||
UE-NGAP-IDs-ExtIEs NGAP-PROTOCOL-EXTENSION ::= {
|
||||
...
|
||||
}
|
||||
|
||||
@@ -6057,10 +6058,10 @@ UE-NGAP-ID-pair-ExtIEs NGAP-PROTOCOL-EXTENSION ::= {
|
||||
|
||||
UEPagingIdentity ::= CHOICE {
|
||||
fiveG-S-TMSI FiveG-S-TMSI,
|
||||
choice-Extensions ProtocolIE-SingleContainer { {UEPagingIdentity-ExtIEs} }
|
||||
choice-Extensions ProtocolExtensionContainer { {UEPagingIdentity-ExtIEs} }
|
||||
}
|
||||
|
||||
UEPagingIdentity-ExtIEs NGAP-PROTOCOL-IES ::= {
|
||||
UEPagingIdentity-ExtIEs NGAP-PROTOCOL-EXTENSION ::= {
|
||||
...
|
||||
}
|
||||
|
||||
@@ -6149,10 +6150,10 @@ ULForwarding ::= ENUMERATED {
|
||||
|
||||
UPTransportLayerInformation ::= CHOICE {
|
||||
gTPTunnel GTPTunnel,
|
||||
choice-Extensions ProtocolIE-SingleContainer { {UPTransportLayerInformation-ExtIEs} }
|
||||
choice-Extensions ProtocolExtensionContainer { {UPTransportLayerInformation-ExtIEs} }
|
||||
}
|
||||
|
||||
UPTransportLayerInformation-ExtIEs NGAP-PROTOCOL-IES ::= {
|
||||
UPTransportLayerInformation-ExtIEs NGAP-PROTOCOL-EXTENSION ::= {
|
||||
...
|
||||
}
|
||||
|
||||
@@ -6186,10 +6187,10 @@ UserLocationInformation ::= CHOICE {
|
||||
userLocationInformationEUTRA UserLocationInformationEUTRA,
|
||||
userLocationInformationNR UserLocationInformationNR,
|
||||
userLocationInformationN3IWF UserLocationInformationN3IWF,
|
||||
choice-Extensions ProtocolIE-SingleContainer { {UserLocationInformation-ExtIEs} }
|
||||
choice-Extensions ProtocolExtensionContainer { {UserLocationInformation-ExtIEs} }
|
||||
}
|
||||
|
||||
UserLocationInformation-ExtIEs NGAP-PROTOCOL-IES ::= {
|
||||
UserLocationInformation-ExtIEs NGAP-PROTOCOL-EXTENSION ::= {
|
||||
...
|
||||
}
|
||||
|
||||
@@ -6267,10 +6268,10 @@ WarningAreaList ::= CHOICE {
|
||||
nR-CGIListForWarning NR-CGIListForWarning,
|
||||
tAIListForWarning TAIListForWarning,
|
||||
emergencyAreaIDList EmergencyAreaIDList,
|
||||
choice-Extensions ProtocolIE-SingleContainer { {WarningAreaList-ExtIEs} }
|
||||
choice-Extensions ProtocolExtensionContainer { {WarningAreaList-ExtIEs} }
|
||||
}
|
||||
|
||||
WarningAreaList-ExtIEs NGAP-PROTOCOL-IES ::= {
|
||||
WarningAreaList-ExtIEs NGAP-PROTOCOL-EXTENSION ::= {
|
||||
...
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
#include "NGAP_ProtocolExtensionContainer.h"
|
||||
#include "NGAP_asn_constant.h"
|
||||
#include "NGAP_SupportedTAs-Item.h"
|
||||
#include "NGAP_ServedGUMMEIsItem.h"
|
||||
#include "NGAP_ServedGUAMIsItem.h"
|
||||
|
||||
/* Checking version of ASN1C compiler */
|
||||
#if (ASN1C_ENVIRONMENT_VERSION < ASN1C_MINIMUM_VERSION)
|
||||
@@ -82,7 +82,7 @@ extern int asn1_xer_print;
|
||||
# define NGAP_INFO(x, args...) LOG_I(NGAP, x, ##args)
|
||||
# define NGAP_DEBUG(x, args...) LOG_I(NGAP, x, ##args)
|
||||
#else
|
||||
# include "mme_default_values.h"
|
||||
# include "amf_default_values.h"
|
||||
# define NGAP_ERROR(x, args...) do { fprintf(stdout, "[NGAP][E]"x, ##args); } while(0)
|
||||
# define NGAP_WARN(x, args...) do { fprintf(stdout, "[NGAP][W]"x, ##args); } while(0)
|
||||
# define NGAP_TRAF(x, args...) do { fprintf(stdout, "[NGAP][T]"x, ##args); } while(0)
|
||||
|
||||
+153
-132
@@ -60,16 +60,16 @@
|
||||
|
||||
#include "assertions.h"
|
||||
#include "conversions.h"
|
||||
#if defined(TEST_S1C_MME)
|
||||
#include "oaisim_mme_test_s1c.h"
|
||||
#if defined(TEST_S1C_AMF)
|
||||
#include "oaisim_amf_test_s1c.h"
|
||||
#endif
|
||||
|
||||
ngap_gNB_config_t ngap_config;
|
||||
|
||||
static int ngap_gNB_generate_s1_setup_request(
|
||||
ngap_gNB_instance_t *instance_p, ngap_gNB_mme_data_t *ngap_mme_data_p);
|
||||
static int ngap_gNB_generate_ng_setup_request(
|
||||
ngap_gNB_instance_t *instance_p, ngap_gNB_amf_data_t *ngap_amf_data_p);
|
||||
|
||||
void ngap_gNB_handle_register_gNB(instance_t instance, ngap_register_enb_req_t *ngap_register_gNB);
|
||||
void ngap_gNB_handle_register_gNB(instance_t instance, ngap_register_gnb_req_t *ngap_register_gNB);
|
||||
|
||||
void ngap_gNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp);
|
||||
|
||||
@@ -87,8 +87,8 @@ uint32_t ngap_generate_gNB_id(void) {
|
||||
return gNB_id;
|
||||
}
|
||||
|
||||
static void ngap_gNB_register_mme(ngap_gNB_instance_t *instance_p,
|
||||
net_ip_address_t *mme_ip_address,
|
||||
static void ngap_gNB_register_amf(ngap_gNB_instance_t *instance_p,
|
||||
net_ip_address_t *amf_ip_address,
|
||||
net_ip_address_t *local_ip_addr,
|
||||
uint16_t in_streams,
|
||||
uint16_t out_streams,
|
||||
@@ -96,10 +96,10 @@ static void ngap_gNB_register_mme(ngap_gNB_instance_t *instance_p,
|
||||
uint8_t broadcast_plmn_index[PLMN_LIST_MAX_SIZE]) {
|
||||
MessageDef *message_p = NULL;
|
||||
sctp_new_association_req_t *sctp_new_association_req_p = NULL;
|
||||
ngap_gNB_mme_data_t *ngap_mme_data_p = NULL;
|
||||
struct ngap_gNB_mme_data_s *mme = NULL;
|
||||
ngap_gNB_amf_data_t *ngap_amf_data_p = NULL;
|
||||
struct ngap_gNB_amf_data_s *amf = NULL;
|
||||
DevAssert(instance_p != NULL);
|
||||
DevAssert(mme_ip_address != NULL);
|
||||
DevAssert(amf_ip_address != NULL);
|
||||
message_p = itti_alloc_new_message(TASK_NGAP, SCTP_NEW_ASSOCIATION_REQ);
|
||||
sctp_new_association_req_p = &message_p->ittiMsg.sctp_new_association_req;
|
||||
sctp_new_association_req_p->port = NGAP_PORT_NUMBER;
|
||||
@@ -107,62 +107,62 @@ static void ngap_gNB_register_mme(ngap_gNB_instance_t *instance_p,
|
||||
sctp_new_association_req_p->in_streams = in_streams;
|
||||
sctp_new_association_req_p->out_streams = out_streams;
|
||||
memcpy(&sctp_new_association_req_p->remote_address,
|
||||
mme_ip_address,
|
||||
sizeof(*mme_ip_address));
|
||||
amf_ip_address,
|
||||
sizeof(*amf_ip_address));
|
||||
memcpy(&sctp_new_association_req_p->local_address,
|
||||
local_ip_addr,
|
||||
sizeof(*local_ip_addr));
|
||||
NGAP_INFO("[gNB %d] check the mme registration state\n",instance_p->instance);
|
||||
mme = NULL;
|
||||
NGAP_INFO("[gNB %d] check the amf registration state\n",instance_p->instance);
|
||||
amf = NULL;
|
||||
|
||||
if ( mme == NULL ) {
|
||||
/* Create new MME descriptor */
|
||||
ngap_mme_data_p = calloc(1, sizeof(*ngap_mme_data_p));
|
||||
DevAssert(ngap_mme_data_p != NULL);
|
||||
ngap_mme_data_p->cnx_id = ngap_gNB_fetch_add_global_cnx_id();
|
||||
sctp_new_association_req_p->ulp_cnx_id = ngap_mme_data_p->cnx_id;
|
||||
ngap_mme_data_p->assoc_id = -1;
|
||||
ngap_mme_data_p->broadcast_plmn_num = broadcast_plmn_num;
|
||||
memcpy(&ngap_mme_data_p->mme_s1_ip,
|
||||
mme_ip_address,
|
||||
sizeof(*mme_ip_address));
|
||||
if ( amf == NULL ) {
|
||||
/* Create new AMF descriptor */
|
||||
ngap_amf_data_p = calloc(1, sizeof(*ngap_amf_data_p));
|
||||
DevAssert(ngap_amf_data_p != NULL);
|
||||
ngap_amf_data_p->cnx_id = ngap_gNB_fetch_add_global_cnx_id();
|
||||
sctp_new_association_req_p->ulp_cnx_id = ngap_amf_data_p->cnx_id;
|
||||
ngap_amf_data_p->assoc_id = -1;
|
||||
ngap_amf_data_p->broadcast_plmn_num = broadcast_plmn_num;
|
||||
memcpy(&ngap_amf_data_p->amf_s1_ip,
|
||||
amf_ip_address,
|
||||
sizeof(*amf_ip_address));
|
||||
for (int i = 0; i < broadcast_plmn_num; ++i)
|
||||
ngap_mme_data_p->broadcast_plmn_index[i] = broadcast_plmn_index[i];
|
||||
ngap_amf_data_p->broadcast_plmn_index[i] = broadcast_plmn_index[i];
|
||||
|
||||
ngap_mme_data_p->ngap_gNB_instance = instance_p;
|
||||
STAILQ_INIT(&ngap_mme_data_p->served_gummei);
|
||||
/* Insert the new descriptor in list of known MME
|
||||
ngap_amf_data_p->ngap_gNB_instance = instance_p;
|
||||
STAILQ_INIT(&ngap_amf_data_p->served_guami);
|
||||
/* Insert the new descriptor in list of known AMF
|
||||
* but not yet associated.
|
||||
*/
|
||||
RB_INSERT(ngap_mme_map, &instance_p->ngap_mme_head, ngap_mme_data_p);
|
||||
ngap_mme_data_p->state = NGAP_GNB_STATE_WAITING;
|
||||
instance_p->ngap_mme_nb ++;
|
||||
instance_p->ngap_mme_pending_nb ++;
|
||||
} else if (mme->state == NGAP_GNB_STATE_WAITING) {
|
||||
instance_p->ngap_mme_pending_nb ++;
|
||||
sctp_new_association_req_p->ulp_cnx_id = mme->cnx_id;
|
||||
NGAP_INFO("[gNB %d] MME already registered, retrive the data (state %d, cnx %d, mme_nb %d, mme_pending_nb %d)\n",
|
||||
RB_INSERT(ngap_amf_map, &instance_p->ngap_amf_head, ngap_amf_data_p);
|
||||
ngap_amf_data_p->state = NGAP_GNB_STATE_WAITING;
|
||||
instance_p->ngap_amf_nb ++;
|
||||
instance_p->ngap_amf_pending_nb ++;
|
||||
} else if (amf->state == NGAP_GNB_STATE_WAITING) {
|
||||
instance_p->ngap_amf_pending_nb ++;
|
||||
sctp_new_association_req_p->ulp_cnx_id = amf->cnx_id;
|
||||
NGAP_INFO("[gNB %d] AMF already registered, retrive the data (state %d, cnx %d, amf_nb %d, amf_pending_nb %d)\n",
|
||||
instance_p->instance,
|
||||
mme->state, mme->cnx_id,
|
||||
instance_p->ngap_mme_nb, instance_p->ngap_mme_pending_nb);
|
||||
/*ngap_mme_data_p->cnx_id = mme->cnx_id;
|
||||
sctp_new_association_req_p->ulp_cnx_id = mme->cnx_id;
|
||||
amf->state, amf->cnx_id,
|
||||
instance_p->ngap_amf_nb, instance_p->ngap_amf_pending_nb);
|
||||
/*ngap_amf_data_p->cnx_id = amf->cnx_id;
|
||||
sctp_new_association_req_p->ulp_cnx_id = amf->cnx_id;
|
||||
|
||||
ngap_mme_data_p->assoc_id = -1;
|
||||
ngap_mme_data_p->ngap_gNB_instance = instance_p;
|
||||
ngap_amf_data_p->assoc_id = -1;
|
||||
ngap_amf_data_p->ngap_gNB_instance = instance_p;
|
||||
*/
|
||||
} else {
|
||||
NGAP_WARN("[gNB %d] MME already registered but not in the waiting state, retrive the data (state %d, cnx %d, mme_nb %d, mme_pending_nb %d)\n",
|
||||
NGAP_WARN("[gNB %d] AMF already registered but not in the waiting state, retrive the data (state %d, cnx %d, amf_nb %d, amf_pending_nb %d)\n",
|
||||
instance_p->instance,
|
||||
mme->state, mme->cnx_id,
|
||||
instance_p->ngap_mme_nb, instance_p->ngap_mme_pending_nb);
|
||||
amf->state, amf->cnx_id,
|
||||
instance_p->ngap_amf_nb, instance_p->ngap_amf_pending_nb);
|
||||
}
|
||||
|
||||
itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message_p);
|
||||
}
|
||||
|
||||
|
||||
void ngap_gNB_handle_register_gNB(instance_t instance, ngap_register_enb_req_t *ngap_register_gNB) {
|
||||
void ngap_gNB_handle_register_gNB(instance_t instance, ngap_register_gnb_req_t *ngap_register_gNB) {
|
||||
ngap_gNB_instance_t *new_instance;
|
||||
uint8_t index;
|
||||
DevAssert(ngap_register_gNB != NULL);
|
||||
@@ -187,7 +187,7 @@ void ngap_gNB_handle_register_gNB(instance_t instance, ngap_register_enb_req_t *
|
||||
new_instance = calloc(1, sizeof(ngap_gNB_instance_t));
|
||||
DevAssert(new_instance != NULL);
|
||||
RB_INIT(&new_instance->ngap_ue_head);
|
||||
RB_INIT(&new_instance->ngap_mme_head);
|
||||
RB_INIT(&new_instance->ngap_amf_head);
|
||||
/* Copy usefull parameters */
|
||||
new_instance->instance = instance;
|
||||
new_instance->gNB_name = ngap_register_gNB->gNB_name;
|
||||
@@ -196,8 +196,8 @@ void ngap_gNB_handle_register_gNB(instance_t instance, ngap_register_enb_req_t *
|
||||
new_instance->tac = ngap_register_gNB->tac;
|
||||
|
||||
memcpy(&new_instance->gNB_s1_ip,
|
||||
&ngap_register_gNB->enb_ip_address,
|
||||
sizeof(ngap_register_gNB->enb_ip_address));
|
||||
&ngap_register_gNB->gnb_ip_address,
|
||||
sizeof(ngap_register_gNB->gnb_ip_address));
|
||||
|
||||
for (int i = 0; i < ngap_register_gNB->num_plmn; i++) {
|
||||
new_instance->mcc[i] = ngap_register_gNB->mcc[i];
|
||||
@@ -215,27 +215,27 @@ void ngap_gNB_handle_register_gNB(instance_t instance, ngap_register_enb_req_t *
|
||||
ngap_register_gNB->gNB_id);
|
||||
}
|
||||
|
||||
DevCheck(ngap_register_gNB->nb_mme <= NGAP_MAX_NB_MME_IP_ADDRESS,
|
||||
NGAP_MAX_NB_MME_IP_ADDRESS, ngap_register_gNB->nb_mme, 0);
|
||||
DevCheck(ngap_register_gNB->nb_amf <= NGAP_MAX_NB_AMF_IP_ADDRESS,
|
||||
NGAP_MAX_NB_AMF_IP_ADDRESS, ngap_register_gNB->nb_amf, 0);
|
||||
|
||||
/* Trying to connect to provided list of MME ip address */
|
||||
for (index = 0; index < ngap_register_gNB->nb_mme; index++) {
|
||||
net_ip_address_t *mme_ip = &ngap_register_gNB->mme_ip_address[index];
|
||||
struct ngap_gNB_mme_data_s *mme = NULL;
|
||||
RB_FOREACH(mme, ngap_mme_map, &new_instance->ngap_mme_head) {
|
||||
/* Trying to connect to provided list of AMF ip address */
|
||||
for (index = 0; index < ngap_register_gNB->nb_amf; index++) {
|
||||
net_ip_address_t *amf_ip = &ngap_register_gNB->amf_ip_address[index];
|
||||
struct ngap_gNB_amf_data_s *amf = NULL;
|
||||
RB_FOREACH(amf, ngap_amf_map, &new_instance->ngap_amf_head) {
|
||||
/* Compare whether IPv4 and IPv6 information is already present, in which
|
||||
* wase we do not register again */
|
||||
if (mme->mme_s1_ip.ipv4 == mme_ip->ipv4 && (!mme_ip->ipv4
|
||||
|| strncmp(mme->mme_s1_ip.ipv4_address, mme_ip->ipv4_address, 16) == 0)
|
||||
&& mme->mme_s1_ip.ipv6 == mme_ip->ipv6 && (!mme_ip->ipv6
|
||||
|| strncmp(mme->mme_s1_ip.ipv6_address, mme_ip->ipv6_address, 46) == 0))
|
||||
if (amf->amf_s1_ip.ipv4 == amf_ip->ipv4 && (!amf_ip->ipv4
|
||||
|| strncmp(amf->amf_s1_ip.ipv4_address, amf_ip->ipv4_address, 16) == 0)
|
||||
&& amf->amf_s1_ip.ipv6 == amf_ip->ipv6 && (!amf_ip->ipv6
|
||||
|| strncmp(amf->amf_s1_ip.ipv6_address, amf_ip->ipv6_address, 46) == 0))
|
||||
break;
|
||||
}
|
||||
if (mme)
|
||||
if (amf)
|
||||
continue;
|
||||
ngap_gNB_register_mme(new_instance,
|
||||
mme_ip,
|
||||
&ngap_register_gNB->enb_ip_address,
|
||||
ngap_gNB_register_amf(new_instance,
|
||||
amf_ip,
|
||||
&ngap_register_gNB->gnb_ip_address,
|
||||
ngap_register_gNB->sctp_in_streams,
|
||||
ngap_register_gNB->sctp_out_streams,
|
||||
ngap_register_gNB->broadcast_plmn_num[index],
|
||||
@@ -245,37 +245,37 @@ void ngap_gNB_handle_register_gNB(instance_t instance, ngap_register_enb_req_t *
|
||||
|
||||
void ngap_gNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) {
|
||||
ngap_gNB_instance_t *instance_p;
|
||||
ngap_gNB_mme_data_t *ngap_mme_data_p;
|
||||
ngap_gNB_amf_data_t *ngap_amf_data_p;
|
||||
DevAssert(sctp_new_association_resp != NULL);
|
||||
instance_p = ngap_gNB_get_instance(instance);
|
||||
DevAssert(instance_p != NULL);
|
||||
ngap_mme_data_p = ngap_gNB_get_MME(instance_p, -1,
|
||||
ngap_amf_data_p = ngap_gNB_get_AMF(instance_p, -1,
|
||||
sctp_new_association_resp->ulp_cnx_id);
|
||||
DevAssert(ngap_mme_data_p != NULL);
|
||||
DevAssert(ngap_amf_data_p != NULL);
|
||||
|
||||
if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
|
||||
NGAP_WARN("Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n",
|
||||
sctp_new_association_resp->sctp_state,
|
||||
instance,
|
||||
sctp_new_association_resp->ulp_cnx_id);
|
||||
ngap_handle_s1_setup_message(ngap_mme_data_p, sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN);
|
||||
ngap_handle_ng_setup_message(ngap_amf_data_p, sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Update parameters */
|
||||
ngap_mme_data_p->assoc_id = sctp_new_association_resp->assoc_id;
|
||||
ngap_mme_data_p->in_streams = sctp_new_association_resp->in_streams;
|
||||
ngap_mme_data_p->out_streams = sctp_new_association_resp->out_streams;
|
||||
/* Prepare new S1 Setup Request */
|
||||
ngap_gNB_generate_s1_setup_request(instance_p, ngap_mme_data_p);
|
||||
ngap_amf_data_p->assoc_id = sctp_new_association_resp->assoc_id;
|
||||
ngap_amf_data_p->in_streams = sctp_new_association_resp->in_streams;
|
||||
ngap_amf_data_p->out_streams = sctp_new_association_resp->out_streams;
|
||||
/* Prepare new NG Setup Request */
|
||||
ngap_gNB_generate_ng_setup_request(instance_p, ngap_amf_data_p);
|
||||
}
|
||||
|
||||
static
|
||||
void ngap_gNB_handle_sctp_data_ind(sctp_data_ind_t *sctp_data_ind) {
|
||||
int result;
|
||||
DevAssert(sctp_data_ind != NULL);
|
||||
#if defined(TEST_S1C_MME)
|
||||
mme_test_s1_notify_sctp_data_ind(sctp_data_ind->assoc_id, sctp_data_ind->stream,
|
||||
#if defined(TEST_S1C_AMF)
|
||||
amf_test_s1_notify_sctp_data_ind(sctp_data_ind->assoc_id, sctp_data_ind->stream,
|
||||
sctp_data_ind->buffer, sctp_data_ind->buffer_length);
|
||||
#else
|
||||
ngap_gNB_handle_message(sctp_data_ind->assoc_id, sctp_data_ind->stream,
|
||||
@@ -349,15 +349,15 @@ void *ngap_gNB_process_itti_msg(void *notUsed) {
|
||||
}
|
||||
break;
|
||||
|
||||
case NGAP_E_RAB_SETUP_RESP: {
|
||||
ngap_gNB_e_rab_setup_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
&NGAP_E_RAB_SETUP_RESP(received_msg));
|
||||
case NGAP_PDUSESSION_SETUP_RESP: {
|
||||
ngap_gNB_pdusession_setup_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
&NGAP_PDUSESSION_SETUP_RESP(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
case NGAP_E_RAB_MODIFY_RESP: {
|
||||
ngap_gNB_e_rab_modify_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
&NGAP_E_RAB_MODIFY_RESP(received_msg));
|
||||
case NGAP_PDUSESSION_MODIFY_RESP: {
|
||||
ngap_gNB_pdusession_modify_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
&NGAP_PDUSESSION_MODIFY_RESP(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -373,9 +373,9 @@ void *ngap_gNB_process_itti_msg(void *notUsed) {
|
||||
}
|
||||
break;
|
||||
|
||||
case NGAP_E_RAB_MODIFICATION_IND: {
|
||||
ngap_gNB_generate_E_RAB_Modification_Indication(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
&NGAP_E_RAB_MODIFICATION_IND(received_msg));
|
||||
case NGAP_PDUSESSION_MODIFICATION_IND: {
|
||||
ngap_gNB_generate_PDUSESSION_Modification_Indication(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
&NGAP_PDUSESSION_MODIFICATION_IND(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -402,9 +402,9 @@ void *ngap_gNB_process_itti_msg(void *notUsed) {
|
||||
}
|
||||
break;
|
||||
|
||||
case NGAP_E_RAB_RELEASE_RESPONSE: {
|
||||
ngap_gNB_e_rab_release_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
&NGAP_E_RAB_RELEASE_RESPONSE(received_msg));
|
||||
case NGAP_PDUSESSION_RELEASE_RESPONSE: {
|
||||
ngap_gNB_pdusession_release_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
&NGAP_PDUSESSION_RELEASE_RESPONSE(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -433,97 +433,118 @@ void *ngap_gNB_task(void *arg) {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/*
|
||||
* gNB generate a S1 setup request towards MME
|
||||
* gNB generate a NG setup request towards AMF
|
||||
*/
|
||||
static int ngap_gNB_generate_s1_setup_request(
|
||||
static int ngap_gNB_generate_ng_setup_request(
|
||||
ngap_gNB_instance_t *instance_p,
|
||||
ngap_gNB_mme_data_t *ngap_mme_data_p)
|
||||
ngap_gNB_amf_data_t *ngap_amf_data_p)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
NGAP_NGAP_PDU_t pdu;
|
||||
NGAP_S1SetupRequest_t *out = NULL;
|
||||
NGAP_S1SetupRequestIEs_t *ie = NULL;
|
||||
NGAP_SupportedTAs_Item_t *ta = NULL;
|
||||
NGAP_PLMNidentity_t *plmn = NULL;
|
||||
NGAP_NGSetupRequest_t *out = NULL;
|
||||
NGAP_NGSetupRequestIEs_t *ie = NULL;
|
||||
NGAP_SupportedTAItem_t *ta = NULL;
|
||||
NGAP_BroadcastPLMNItem_t *plmn = NULL;
|
||||
NGAP_SliceSupportItem_t *ssi = NULL;
|
||||
uint8_t *buffer = NULL;
|
||||
uint32_t len = 0;
|
||||
int ret = 0;
|
||||
DevAssert(instance_p != NULL);
|
||||
DevAssert(ngap_mme_data_p != NULL);
|
||||
ngap_mme_data_p->state = NGAP_GNB_STATE_WAITING;
|
||||
DevAssert(ngap_amf_data_p != NULL);
|
||||
ngap_amf_data_p->state = NGAP_GNB_STATE_WAITING;
|
||||
/* Prepare the NGAP message to encode */
|
||||
memset(&pdu, 0, sizeof(pdu));
|
||||
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
|
||||
pdu.choice.initiatingMessage.procedureCode = NGAP_ProcedureCode_id_S1Setup;
|
||||
pdu.choice.initiatingMessage.procedureCode = NGAP_ProcedureCode_id_NGSetup;
|
||||
pdu.choice.initiatingMessage.criticality = NGAP_Criticality_reject;
|
||||
pdu.choice.initiatingMessage.value.present = NGAP_InitiatingMessage__value_PR_S1SetupRequest;
|
||||
out = &pdu.choice.initiatingMessage.value.choice.S1SetupRequest;
|
||||
pdu.choice.initiatingMessage.value.present = NGAP_InitiatingMessage__value_PR_NGSetupRequest;
|
||||
out = &pdu.choice.initiatingMessage.value.choice.NGSetupRequest;
|
||||
/* mandatory */
|
||||
ie = (NGAP_S1SetupRequestIEs_t *)calloc(1, sizeof(NGAP_S1SetupRequestIEs_t));
|
||||
ie->id = NGAP_ProtocolIE_ID_id_Global_GNB_ID;
|
||||
ie = (NGAP_NGSetupRequestIEs_t *)calloc(1, sizeof(NGAP_NGSetupRequestIEs_t));
|
||||
ie->id = NGAP_ProtocolIE_ID_id_GlobalRANNodeID;
|
||||
ie->criticality = NGAP_Criticality_reject;
|
||||
ie->value.present = NGAP_S1SetupRequestIEs__value_PR_Global_GNB_ID;
|
||||
MCC_MNC_TO_PLMNID(instance_p->mcc[ngap_mme_data_p->broadcast_plmn_index[0]],
|
||||
instance_p->mnc[ngap_mme_data_p->broadcast_plmn_index[0]],
|
||||
instance_p->mnc_digit_length[ngap_mme_data_p->broadcast_plmn_index[0]],
|
||||
&ie->value.choice.Global_GNB_ID.pLMNidentity);
|
||||
ie->value.choice.Global_GNB_ID.gNB_ID.present = NGAP_GNB_ID_PR_macroGNB_ID;
|
||||
ie->value.present = NGAP_NGSetupRequestIEs__value_PR_GlobalRANNodeID;
|
||||
ie->value.choice.GlobalRANNodeID.present = NGAP_GlobalRANNodeID_PR_globalGNB_ID;
|
||||
MCC_MNC_TO_PLMNID(instance_p->mcc[ngap_amf_data_p->broadcast_plmn_index[0]],
|
||||
instance_p->mnc[ngap_amf_data_p->broadcast_plmn_index[0]],
|
||||
instance_p->mnc_digit_length[ngap_amf_data_p->broadcast_plmn_index[0]],
|
||||
&ie->value.choice.GlobalRANNodeID.choice.globalGNB_ID.pLMNIdentity);
|
||||
ie->value.choice.GlobalRANNodeID.choice.globalGNB_ID.gNB_ID.present = NGAP_GNB_ID_PR_gNB_ID;
|
||||
MACRO_GNB_ID_TO_BIT_STRING(instance_p->gNB_id,
|
||||
&ie->value.choice.Global_GNB_ID.gNB_ID.choice.macroGNB_ID);
|
||||
&ie->value.choice.GlobalRANNodeID.choice.globalGNB_ID.gNB_ID.choice.gNB_ID);
|
||||
NGAP_INFO("%d -> %02x%02x%02x\n", instance_p->gNB_id,
|
||||
ie->value.choice.Global_GNB_ID.gNB_ID.choice.macroGNB_ID.buf[0],
|
||||
ie->value.choice.Global_GNB_ID.gNB_ID.choice.macroGNB_ID.buf[1],
|
||||
ie->value.choice.Global_GNB_ID.gNB_ID.choice.macroGNB_ID.buf[2]);
|
||||
ie->value.choice.GlobalRANNodeID.choice.globalGNB_ID.gNB_ID.choice.gNB_ID.buf[0],
|
||||
ie->value.choice.GlobalRANNodeID.choice.globalGNB_ID.gNB_ID.choice.gNB_ID.buf[1],
|
||||
ie->value.choice.GlobalRANNodeID.choice.globalGNB_ID.gNB_ID.choice.gNB_ID.buf[2]);
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
/* optional */
|
||||
if (instance_p->gNB_name) {
|
||||
ie = (NGAP_S1SetupRequestIEs_t *)calloc(1, sizeof(NGAP_S1SetupRequestIEs_t));
|
||||
ie->id = NGAP_ProtocolIE_ID_id_gNBname;
|
||||
ie = (NGAP_NGSetupRequestIEs_t *)calloc(1, sizeof(NGAP_NGSetupRequestIEs_t));
|
||||
ie->id = NGAP_ProtocolIE_ID_id_RANNodeName;
|
||||
ie->criticality = NGAP_Criticality_ignore;
|
||||
ie->value.present = NGAP_S1SetupRequestIEs__value_PR_GNBname;
|
||||
OCTET_STRING_fromBuf(&ie->value.choice.GNBname, instance_p->gNB_name,
|
||||
ie->value.present = NGAP_NGSetupRequestIEs__value_PR_RANNodeName;
|
||||
OCTET_STRING_fromBuf(&ie->value.choice.RANNodeName, instance_p->gNB_name,
|
||||
strlen(instance_p->gNB_name));
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
}
|
||||
|
||||
/* mandatory */
|
||||
ie = (NGAP_S1SetupRequestIEs_t *)calloc(1, sizeof(NGAP_S1SetupRequestIEs_t));
|
||||
ie->id = NGAP_ProtocolIE_ID_id_SupportedTAs;
|
||||
ie = (NGAP_NGSetupRequestIEs_t *)calloc(1, sizeof(NGAP_NGSetupRequestIEs_t));
|
||||
ie->id = NGAP_ProtocolIE_ID_id_SupportedTAList;
|
||||
ie->criticality = NGAP_Criticality_reject;
|
||||
ie->value.present = NGAP_S1SetupRequestIEs__value_PR_SupportedTAs;
|
||||
ie->value.present = NGAP_NGSetupRequestIEs__value_PR_SupportedTAList;
|
||||
{
|
||||
ta = (NGAP_SupportedTAs_Item_t *)calloc(1, sizeof(NGAP_SupportedTAs_Item_t));
|
||||
ta = (NGAP_SupportedTAItem_t *)calloc(1, sizeof(NGAP_SupportedTAItem_t));
|
||||
INT16_TO_OCTET_STRING(instance_p->tac, &ta->tAC);
|
||||
{
|
||||
for (int i = 0; i < ngap_mme_data_p->broadcast_plmn_num; ++i) {
|
||||
plmn = (NGAP_PLMNidentity_t *)calloc(1, sizeof(NGAP_PLMNidentity_t));
|
||||
MCC_MNC_TO_TBCD(instance_p->mcc[ngap_mme_data_p->broadcast_plmn_index[i]],
|
||||
instance_p->mnc[ngap_mme_data_p->broadcast_plmn_index[i]],
|
||||
instance_p->mnc_digit_length[ngap_mme_data_p->broadcast_plmn_index[i]],
|
||||
plmn);
|
||||
ASN_SEQUENCE_ADD(&ta->broadcastPLMNs.list, plmn);
|
||||
for (int i = 0; i < ngap_amf_data_p->broadcast_plmn_num; ++i) {
|
||||
plmn = (NGAP_BroadcastPLMNItem_t *)calloc(1, sizeof(NGAP_BroadcastPLMNItem_t));
|
||||
MCC_MNC_TO_TBCD(instance_p->mcc[ngap_amf_data_p->broadcast_plmn_index[i]],
|
||||
instance_p->mnc[ngap_amf_data_p->broadcast_plmn_index[i]],
|
||||
instance_p->mnc_digit_length[ngap_amf_data_p->broadcast_plmn_index[i]],
|
||||
plmn->pLMNIdentity);
|
||||
|
||||
for(int si = 0; si < instance_p->num_nssai[i]; si++) {
|
||||
ssi = (NGAP_SliceSupportItem_t *)calloc(1, sizeof(NGAP_SliceSupportItem_t));
|
||||
INT8_TO_OCTET_STRING(instance_p->s_nssai[i][si].sST, &ssi->s_NSSAI.sST);
|
||||
|
||||
if(instance_p->s_nssai[i].sD_flag) {
|
||||
ssi->s_NSSAI.sD = calloc(1, sizeof(NGAP_SD_t));
|
||||
ssi->s_NSSAI.sD->buf = calloc(3, sizeof(uint8_t));
|
||||
ssi->s_NSSAI.sD->size = 3;
|
||||
ssi->s_NSSAI.sD->buf[0] = instance_p->s_nssai[i][si].sD[0];
|
||||
ssi->s_NSSAI.sD->buf[1] = instance_p->s_nssai[i][si].sD[1];
|
||||
ssi->s_NSSAI.sD->buf[2] = instance_p->s_nssai[i][si].sD[2];
|
||||
}
|
||||
|
||||
|
||||
ASN_SEQUENCE_ADD(&plmn->tAISliceSupportList.list, ssi);
|
||||
}
|
||||
|
||||
ASN_SEQUENCE_ADD(&ta->broadcastPLMNList.list, plmn);
|
||||
}
|
||||
}
|
||||
ASN_SEQUENCE_ADD(&ie->value.choice.SupportedTAs.list, ta);
|
||||
ASN_SEQUENCE_ADD(&ie->value.choice.SupportedTAList.list, ta);
|
||||
}
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
/* mandatory */
|
||||
ie = (NGAP_S1SetupRequestIEs_t *)calloc(1, sizeof(NGAP_S1SetupRequestIEs_t));
|
||||
ie = (NGAP_NGSetupRequestIEs_t *)calloc(1, sizeof(NGAP_NGSetupRequestIEs_t));
|
||||
ie->id = NGAP_ProtocolIE_ID_id_DefaultPagingDRX;
|
||||
ie->criticality = NGAP_Criticality_ignore;
|
||||
ie->value.present = NGAP_S1SetupRequestIEs__value_PR_PagingDRX;
|
||||
ie->value.present = NGAP_NGSetupRequestIEs__value_PR_PagingDRX;
|
||||
ie->value.choice.PagingDRX = instance_p->default_drx;
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
|
||||
if (ngap_gNB_encode_pdu(&pdu, &buffer, &len) < 0) {
|
||||
NGAP_ERROR("Failed to encode S1 setup request\n");
|
||||
NGAP_ERROR("Failed to encode NG setup request\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Non UE-Associated signalling -> stream = 0 */
|
||||
ngap_gNB_itti_send_sctp_data_req(instance_p->instance, ngap_mme_data_p->assoc_id, buffer, len, 0);
|
||||
ngap_gNB_itti_send_sctp_data_req(instance_p->instance, ngap_amf_data_p->assoc_id, buffer, len, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,13 +31,13 @@
|
||||
#define NGAP_GNB_H_
|
||||
|
||||
typedef struct ngap_gNB_config_s {
|
||||
// MME related params
|
||||
unsigned char mme_enabled; ///< MME enabled ?
|
||||
// AMF related params
|
||||
unsigned char amf_enabled; ///< AMF enabled ?
|
||||
} ngap_gNB_config_t;
|
||||
|
||||
extern ngap_gNB_config_t ngap_config;
|
||||
|
||||
#define EPC_MODE_ENABLED ngap_config.mme_enabled
|
||||
#define EPC_MODE_ENABLED ngap_config.amf_enabled
|
||||
|
||||
void *ngap_gNB_process_itti_msg(void*);
|
||||
void ngap_gNB_init(void);
|
||||
|
||||
@@ -68,8 +68,8 @@ int ngap_ue_context_release_complete(instance_t instance,
|
||||
DevAssert(ngap_gNB_instance_p != NULL);
|
||||
|
||||
/*RB_FOREACH(ue_context_p, ngap_ue_map, &ngap_gNB_instance_p->ngap_ue_head) {
|
||||
NGAP_WARN("in ngap_ue_map: UE context gNB_ue_ngap_id %u mme_ue_ngap_id %u state %u\n",
|
||||
ue_context_p->gNB_ue_ngap_id, ue_context_p->mme_ue_ngap_id,
|
||||
NGAP_WARN("in ngap_ue_map: UE context gNB_ue_ngap_id %u amf_ue_ngap_id %u state %u\n",
|
||||
ue_context_p->gNB_ue_ngap_id, ue_context_p->amf_ue_ngap_id,
|
||||
ue_context_p->ue_state);
|
||||
}*/
|
||||
if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p,
|
||||
@@ -90,10 +90,10 @@ int ngap_ue_context_release_complete(instance_t instance,
|
||||
|
||||
/* mandatory */
|
||||
ie = (NGAP_UEContextReleaseComplete_IEs_t *)calloc(1, sizeof(NGAP_UEContextReleaseComplete_IEs_t));
|
||||
ie->id = NGAP_ProtocolIE_ID_id_MME_UE_NGAP_ID;
|
||||
ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID;
|
||||
ie->criticality = NGAP_Criticality_ignore;
|
||||
ie->value.present = NGAP_UEContextReleaseComplete_IEs__value_PR_MME_UE_NGAP_ID;
|
||||
ie->value.choice.MME_UE_NGAP_ID = ue_context_p->mme_ue_ngap_id;
|
||||
ie->value.present = NGAP_UEContextReleaseComplete_IEs__value_PR_AMF_UE_NGAP_ID;
|
||||
ie->value.choice.AMF_UE_NGAP_ID = ue_context_p->amf_ue_ngap_id;
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
/* mandatory */
|
||||
@@ -113,21 +113,21 @@ int ngap_ue_context_release_complete(instance_t instance,
|
||||
|
||||
MSC_LOG_TX_MESSAGE(
|
||||
MSC_NGAP_GNB,
|
||||
MSC_NGAP_MME,
|
||||
MSC_NGAP_AMF,
|
||||
buffer,
|
||||
length,
|
||||
MSC_AS_TIME_FMT" UEContextRelease successfulOutcome gNB_ue_ngap_id %u mme_ue_ngap_id %u",
|
||||
MSC_AS_TIME_FMT" UEContextRelease successfulOutcome gNB_ue_ngap_id %u amf_ue_ngap_id %u",
|
||||
0,0, //MSC_AS_TIME_ARGS(ctxt_pP),
|
||||
ue_release_complete_p->gNB_ue_ngap_id,
|
||||
ue_context_p->mme_ue_ngap_id);
|
||||
ue_context_p->amf_ue_ngap_id);
|
||||
|
||||
/* UE associated signalling -> use the allocated stream */
|
||||
ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance,
|
||||
ue_context_p->mme_ref->assoc_id, buffer,
|
||||
ue_context_p->amf_ref->assoc_id, buffer,
|
||||
length, ue_context_p->tx_stream);
|
||||
|
||||
//LG ngap_gNB_itti_send_sctp_close_association(ngap_gNB_instance_p->instance,
|
||||
// ue_context_p->mme_ref->assoc_id);
|
||||
// ue_context_p->amf_ref->assoc_id);
|
||||
// release UE context
|
||||
struct ngap_gNB_ue_context_s *ue_context2_p = NULL;
|
||||
|
||||
@@ -141,8 +141,8 @@ int ngap_ue_context_release_complete(instance_t instance,
|
||||
ue_context_p->gNB_ue_ngap_id);
|
||||
}
|
||||
/*RB_FOREACH(ue_context_p, ngap_ue_map, &ngap_gNB_instance_p->ngap_ue_head) {
|
||||
NGAP_WARN("in ngap_ue_map: UE context gNB_ue_ngap_id %u mme_ue_ngap_id %u state %u\n",
|
||||
ue_context_p->gNB_ue_ngap_id, ue_context_p->mme_ue_ngap_id,
|
||||
NGAP_WARN("in ngap_ue_map: UE context gNB_ue_ngap_id %u amf_ue_ngap_id %u state %u\n",
|
||||
ue_context_p->gNB_ue_ngap_id, ue_context_p->amf_ue_ngap_id,
|
||||
ue_context_p->ue_state);
|
||||
}*/
|
||||
|
||||
@@ -184,10 +184,10 @@ int ngap_ue_context_release_req(instance_t instance,
|
||||
|
||||
/* mandatory */
|
||||
ie = (NGAP_UEContextReleaseRequest_IEs_t *)calloc(1, sizeof(NGAP_UEContextReleaseRequest_IEs_t));
|
||||
ie->id = NGAP_ProtocolIE_ID_id_MME_UE_NGAP_ID;
|
||||
ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID;
|
||||
ie->criticality = NGAP_Criticality_reject;
|
||||
ie->value.present = NGAP_UEContextReleaseRequest_IEs__value_PR_MME_UE_NGAP_ID;
|
||||
ie->value.choice.MME_UE_NGAP_ID = ue_context_p->mme_ue_ngap_id;
|
||||
ie->value.present = NGAP_UEContextReleaseRequest_IEs__value_PR_AMF_UE_NGAP_ID;
|
||||
ie->value.choice.AMF_UE_NGAP_ID = ue_context_p->amf_ue_ngap_id;
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
/* mandatory */
|
||||
@@ -248,17 +248,17 @@ int ngap_ue_context_release_req(instance_t instance,
|
||||
|
||||
MSC_LOG_TX_MESSAGE(
|
||||
MSC_NGAP_GNB,
|
||||
MSC_NGAP_MME,
|
||||
MSC_NGAP_AMF,
|
||||
buffer,
|
||||
length,
|
||||
MSC_AS_TIME_FMT" UEContextReleaseRequest initiatingMessage gNB_ue_ngap_id %u mme_ue_ngap_id %u",
|
||||
MSC_AS_TIME_FMT" UEContextReleaseRequest initiatingMessage gNB_ue_ngap_id %u amf_ue_ngap_id %u",
|
||||
0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
|
||||
ue_release_req_p->gNB_ue_ngap_id,
|
||||
ue_context_p->mme_ue_ngap_id);
|
||||
ue_context_p->amf_ue_ngap_id);
|
||||
|
||||
/* UE associated signalling -> use the allocated stream */
|
||||
ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance,
|
||||
ue_context_p->mme_ref->assoc_id, buffer,
|
||||
ue_context_p->amf_ref->assoc_id, buffer,
|
||||
length, ue_context_p->tx_stream);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -62,22 +62,22 @@ static int ngap_gNB_decode_initiating_message(NGAP_NGAP_PDU_t *pdu) {
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_E_RABSetup:
|
||||
case NGAP_ProcedureCode_id_PDUSESSIONSetup:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
NGAP_INFO("E_RABSetup initiating message\n");
|
||||
NGAP_INFO("PDUSESSIONSetup initiating message\n");
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_E_RABModify:
|
||||
case NGAP_ProcedureCode_id_PDUSESSIONModify:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
NGAP_INFO("E_RABModify initiating message\n");
|
||||
NGAP_INFO("PDUSESSIONModify initiating message\n");
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_E_RABRelease:
|
||||
case NGAP_ProcedureCode_id_PDUSESSIONRelease:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
NGAP_INFO("TODO E_RABRelease initiating message\n");
|
||||
NGAP_INFO("TODO PDUSESSIONRelease initiating message\n");
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_ErrorIndication:
|
||||
@@ -112,7 +112,7 @@ static int ngap_gNB_decode_successful_outcome(NGAP_NGAP_PDU_t *pdu) {
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_E_RABModificationIndication:
|
||||
case NGAP_ProcedureCode_id_PDUSESSIONModificationIndication:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
+110
-62
@@ -34,13 +34,13 @@
|
||||
typedef enum {
|
||||
/* Disconnected state: initial state for any association. */
|
||||
NGAP_GNB_STATE_DISCONNECTED = 0x0,
|
||||
/* State waiting for S1 Setup response message if gNB is MME accepted or
|
||||
* S1 Setup failure if MME rejects the gNB.
|
||||
/* State waiting for S1 Setup response message if gNB is AMF accepted or
|
||||
* S1 Setup failure if AMF rejects the gNB.
|
||||
*/
|
||||
NGAP_GNB_STATE_WAITING = 0x1,
|
||||
/* The gNB is successfully connected to MME, UE contexts can be created. */
|
||||
/* The gNB is successfully connected to AMF, UE contexts can be created. */
|
||||
NGAP_GNB_STATE_CONNECTED = 0x2,
|
||||
/* The MME has sent an overload start message. Once the MME disables the
|
||||
/* The AMF has sent an overload start message. Once the AMF disables the
|
||||
* OVERLOAD marker, the state of the association will be
|
||||
* NGAP_GNB_STATE_CONNECTED.
|
||||
*/
|
||||
@@ -51,18 +51,17 @@ typedef enum {
|
||||
|
||||
/* If the Overload Action IE in the OVERLOAD START message is set to
|
||||
* - “reject all RRC connection establishments for non-emergency mobile
|
||||
* originated data transfer “ (i.e. reject traffic corresponding to RRC cause
|
||||
* “mo-data “ (TS 36.331 [16])), or
|
||||
* - “reject all RRC connection establishments for signalling “ (i.e. reject
|
||||
* traffic corresponding to RRC cause “modata” and “mo-signalling”
|
||||
* (TS 36.331 [16])),or
|
||||
* originated data transfer E(i.e. reject traffic corresponding to RRC cause
|
||||
* “mo-data E(TS 36.331 [16])), or
|
||||
* - “reject all RRC connection establishments for signalling E(i.e. reject
|
||||
* traffic corresponding to RRC cause “modata Eand “mo-signalling E * (TS 36.331 [16])),or
|
||||
* - “only permit RRC connection establishments for emergency sessions and
|
||||
* mobile terminated services” (i.e. only permit traffic corresponding to RRC
|
||||
* cause “emergency” and “mt-Access” (TS 36.331 [16])).
|
||||
* mobile terminated services E(i.e. only permit traffic corresponding to RRC
|
||||
* cause “emergency Eand “mt-Access E(TS 36.331 [16])).
|
||||
*
|
||||
* NOTE: When the Overload Action IE is set to “only permit RRC connection
|
||||
* establishments for emergency sessions and mobile terminated services”,
|
||||
* emergency calls with RRC cause “highPriorityAcess” from high priority users
|
||||
* establishments for emergency sessions and mobile terminated services E
|
||||
* emergency calls with RRC cause “highPriorityAcess Efrom high priority users
|
||||
* are rejected (TS 24.301 [24]).
|
||||
*/
|
||||
typedef enum {
|
||||
@@ -81,67 +80,106 @@ struct plmn_identity_s {
|
||||
STAILQ_ENTRY(plmn_identity_s) next;
|
||||
};
|
||||
|
||||
/* Served group id element */
|
||||
struct served_group_id_s {
|
||||
uint16_t mme_group_id;
|
||||
STAILQ_ENTRY(served_group_id_s) next;
|
||||
/* Served amf region id for a particular AMF */
|
||||
struct served_region_id_s {
|
||||
uint8_t amf_region_id;
|
||||
STAILQ_ENTRY(served_region_id_s) next;
|
||||
};
|
||||
|
||||
/* Served mme code for a particular MME */
|
||||
struct mme_code_s {
|
||||
uint8_t mme_code;
|
||||
STAILQ_ENTRY(mme_code_s) next;
|
||||
/* Served amf set id for a particular AMF */
|
||||
struct amf_set_id_s {
|
||||
uint16_t amf_set_id;
|
||||
STAILQ_ENTRY(amf_set_id_s) next;
|
||||
};
|
||||
|
||||
/* Served gummei element */
|
||||
struct served_gummei_s {
|
||||
/* Number of MME served PLMNs */
|
||||
/* Served amf pointer for a particular AMF */
|
||||
struct amf_pointer_s {
|
||||
uint8_t amf_pointer;
|
||||
STAILQ_ENTRY(amf_pointer_s) next;
|
||||
};
|
||||
|
||||
|
||||
/* Served guami element */
|
||||
struct served_guami_s {
|
||||
/* Number of AMF served PLMNs */
|
||||
uint8_t nb_served_plmns;
|
||||
/* List of served PLMNs by MME */
|
||||
/* List of served PLMNs by AMF */
|
||||
STAILQ_HEAD(served_plmns_s, plmn_identity_s) served_plmns;
|
||||
|
||||
/* Number of group id in list */
|
||||
uint8_t nb_group_id;
|
||||
/* Number of region id in list */
|
||||
uint8_t nb_region_id;
|
||||
/* Served group id list */
|
||||
STAILQ_HEAD(served_group_ids_s, served_group_id_s) served_group_ids;
|
||||
STAILQ_HEAD(served_region_ids_s, served_region_id_s) served_region_ids;
|
||||
|
||||
/* Number of MME code */
|
||||
uint8_t nb_mme_code;
|
||||
/* MME Code to uniquely identify an MME within an MME pool area */
|
||||
STAILQ_HEAD(mme_codes_s, mme_code_s) mme_codes;
|
||||
/* Number of AMF set id */
|
||||
uint8_t nb_amf_set_id;
|
||||
/* AMF Set id to uniquely identify an AMF within an AMF pool area */
|
||||
STAILQ_HEAD(amf_set_ids_s, amf_set_id_s) amf_set_ids;
|
||||
|
||||
/* Next GUMMEI element */
|
||||
STAILQ_ENTRY(served_gummei_s) next;
|
||||
/* Number of AMF pointer */
|
||||
uint8_t nb_amf_pointer;
|
||||
/* AMF pointer to uniquely identify an AMF within an AMF pool area */
|
||||
STAILQ_HEAD(amf_pointers_s, amf_pointer_s) amf_pointers;
|
||||
|
||||
/* Next GUAMI element */
|
||||
STAILQ_ENTRY(served_guami_s) next;
|
||||
};
|
||||
|
||||
/* slice support element */
|
||||
struct slice_support_s {
|
||||
uint8_t sST;
|
||||
uint8_t sD_flag;
|
||||
uint8_t sD[3];
|
||||
};
|
||||
|
||||
/* plmn support element */
|
||||
struct plmn_support_s {
|
||||
plmn_identity_s plmn_identity;
|
||||
|
||||
/* Number of slice support in list */
|
||||
uint8_t nb_slice_s;
|
||||
/* Served group id list */
|
||||
STAILQ_HEAD(slice_supports_s, slice_support_s) slice_supports;
|
||||
|
||||
/* Next plmn support element */
|
||||
STAILQ_ENTRY(plmn_support_s) next;
|
||||
};
|
||||
|
||||
|
||||
struct ngap_gNB_instance_s;
|
||||
|
||||
/* This structure describes association of a gNB to a MME */
|
||||
typedef struct ngap_gNB_mme_data_s {
|
||||
/* MME descriptors tree, ordered by sctp assoc id */
|
||||
RB_ENTRY(ngap_gNB_mme_data_s) entry;
|
||||
/* This structure describes association of a gNB to a AMF */
|
||||
typedef struct ngap_gNB_amf_data_s {
|
||||
/* AMF descriptors tree, ordered by sctp assoc id */
|
||||
RB_ENTRY(ngap_gNB_amf_data_s) entry;
|
||||
|
||||
/* This is the optional name provided by the MME */
|
||||
char *mme_name;
|
||||
/* This is the optional name provided by the AMF */
|
||||
char *amf_name;
|
||||
|
||||
/* MME NGAP IP address */
|
||||
net_ip_address_t mme_s1_ip;
|
||||
/* AMF NGAP IP address */
|
||||
net_ip_address_t amf_s1_ip;
|
||||
|
||||
/* List of served GUMMEI per MME. There is one GUMMEI per RAT with a max
|
||||
/* List of served GUAMI per AMF. There is one GUAMI per RAT with a max
|
||||
* number of 8 RATs but in our case only one is used. The LTE related pool
|
||||
* configuration is included on the first place in the list.
|
||||
*/
|
||||
STAILQ_HEAD(served_gummeis_s, served_gummei_s) served_gummei;
|
||||
STAILQ_HEAD(served_guamis_s, served_guami_s) served_guami;
|
||||
|
||||
/* Relative processing capacity of an MME with respect to the other MMEs
|
||||
* in the pool in order to load-balance MMEs within a pool as defined
|
||||
/* Relative processing capacity of an AMF with respect to the other AMFs
|
||||
* in the pool in order to load-balance AMFs within a pool as defined
|
||||
* in TS 23.401.
|
||||
*/
|
||||
uint8_t relative_mme_capacity;
|
||||
uint8_t relative_amf_capacity;
|
||||
|
||||
/* Current MME overload information (if any). */
|
||||
/*
|
||||
* List of PLMN Support per AMF.
|
||||
*
|
||||
*/
|
||||
STAILQ_HEAD(plmn_supports_s, plmn_support_s) plmn_supports;
|
||||
|
||||
/* Current AMF overload information (if any). */
|
||||
ngap_overload_state_t overload_state;
|
||||
/* Current gNB->MME NGAP association state */
|
||||
/* Current gNB->AMF NGAP association state */
|
||||
ngap_gNB_state_t state;
|
||||
|
||||
/* Next usable stream for UE signalling */
|
||||
@@ -157,14 +195,21 @@ typedef struct ngap_gNB_mme_data_s {
|
||||
/* SCTP association id */
|
||||
int32_t assoc_id;
|
||||
|
||||
/* This is served PLMN IDs communicated to the MME via an index over the
|
||||
/* This is served PLMN IDs communicated to the AMF via an index over the
|
||||
* MCC/MNC array in ngap_gNB_instance */
|
||||
uint8_t broadcast_plmn_num;
|
||||
uint8_t broadcast_plmn_index[PLMN_LIST_MAX_SIZE];
|
||||
|
||||
|
||||
/* Only meaningfull in virtual mode */
|
||||
struct ngap_gNB_instance_s *ngap_gNB_instance;
|
||||
} ngap_gNB_mme_data_t;
|
||||
} ngap_gNB_amf_data_t;
|
||||
|
||||
typedef struct ngap_gNB_NSSAI_s{
|
||||
uint8_t sST;
|
||||
uint8_t sD_flag;
|
||||
uint8_t sD[3];
|
||||
}ngap_gNB_NSSAI_t;
|
||||
|
||||
typedef struct ngap_gNB_instance_s {
|
||||
/* Next ngap gNB association.
|
||||
@@ -172,16 +217,16 @@ typedef struct ngap_gNB_instance_s {
|
||||
*/
|
||||
STAILQ_ENTRY(ngap_gNB_instance_s) ngap_gNB_entries;
|
||||
|
||||
/* Number of MME requested by gNB (tree size) */
|
||||
uint32_t ngap_mme_nb;
|
||||
/* Number of MME for which association is pending */
|
||||
uint32_t ngap_mme_pending_nb;
|
||||
/* Number of MME successfully associated to gNB */
|
||||
uint32_t ngap_mme_associated_nb;
|
||||
/* Tree of NGAP MME associations ordered by association ID */
|
||||
RB_HEAD(ngap_mme_map, ngap_gNB_mme_data_s) ngap_mme_head;
|
||||
/* Number of AMF requested by gNB (tree size) */
|
||||
uint32_t ngap_amf_nb;
|
||||
/* Number of AMF for which association is pending */
|
||||
uint32_t ngap_amf_pending_nb;
|
||||
/* Number of AMF successfully associated to gNB */
|
||||
uint32_t ngap_amf_associated_nb;
|
||||
/* Tree of NGAP AMF associations ordered by association ID */
|
||||
RB_HEAD(ngap_amf_map, ngap_gNB_amf_data_s) ngap_amf_head;
|
||||
|
||||
/* TODO: add a map ordered by relative MME capacity */
|
||||
/* TODO: add a map ordered by relative AMF capacity */
|
||||
|
||||
/* Tree of UE ordered by gNB_ue_ngap_id's */
|
||||
RB_HEAD(ngap_ue_map, ngap_gNB_ue_context_s) ngap_ue_head;
|
||||
@@ -214,6 +259,9 @@ typedef struct ngap_gNB_instance_s {
|
||||
uint8_t mnc_digit_length[PLMN_LIST_MAX_SIZE];
|
||||
uint8_t num_plmn;
|
||||
|
||||
uint16_t num_nssai[PLMN_LIST_MAX_SIZE];
|
||||
ngap_gNB_NSSAI_t s_nssai[PLMN_LIST_MAX_SIZE][1024];
|
||||
|
||||
/* Default Paging DRX of the gNB as defined in TS 36.304 */
|
||||
paging_drx_t default_drx;
|
||||
} ngap_gNB_instance_t;
|
||||
@@ -231,10 +279,10 @@ typedef struct {
|
||||
} ngap_gNB_internal_data_t;
|
||||
|
||||
int ngap_gNB_compare_assoc_id(
|
||||
struct ngap_gNB_mme_data_s *p1, struct ngap_gNB_mme_data_s *p2);
|
||||
struct ngap_gNB_amf_data_s *p1, struct ngap_gNB_amf_data_s *p2);
|
||||
|
||||
/* Generate the tree management functions */
|
||||
RB_PROTOTYPE(ngap_mme_map, ngap_gNB_mme_data_s, entry,
|
||||
RB_PROTOTYPE(ngap_amf_map, ngap_gNB_amf_data_s, entry,
|
||||
ngap_gNB_compare_assoc_id);
|
||||
|
||||
#endif /* NGAP_GNB_DEFS_H_ */
|
||||
|
||||
@@ -118,7 +118,7 @@ int ngap_gNB_encode_initiating(NGAP_NGAP_PDU_t *pdu,
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_E_RABModificationIndication:
|
||||
case NGAP_ProcedureCode_id_PDUSESSIONModificationIndication:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
break;
|
||||
@@ -157,22 +157,22 @@ int ngap_gNB_encode_successfull_outcome(NGAP_NGAP_PDU_t *pdu,
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_E_RABSetup:
|
||||
case NGAP_ProcedureCode_id_PDUSESSIONSetup:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
NGAP_INFO("E_RABSetup successful message\n");
|
||||
NGAP_INFO("PDUSESSIONSetup successful message\n");
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_E_RABModify:
|
||||
case NGAP_ProcedureCode_id_PDUSESSIONModify:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
NGAP_INFO("E_RABModify successful message\n");
|
||||
NGAP_INFO("PDUSESSIONModify successful message\n");
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_E_RABRelease:
|
||||
case NGAP_ProcedureCode_id_PDUSESSIONRelease:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
NGAP_INFO("E_RAB Release successful message\n");
|
||||
NGAP_INFO("PDUSESSION Release successful message\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
+613
-422
File diff suppressed because it is too large
Load Diff
@@ -22,7 +22,7 @@
|
||||
#ifndef NGAP_GNB_HANDLERS_H_
|
||||
#define NGAP_GNB_HANDLERS_H_
|
||||
|
||||
void ngap_handle_s1_setup_message(ngap_gNB_mme_data_t *mme_desc_p, int sctp_shutdown);
|
||||
void ngap_handle_ng_setup_message(ngap_gNB_amf_data_t *amf_desc_p, int sctp_shutdown);
|
||||
|
||||
int ngap_gNB_handle_message(uint32_t assoc_id, int32_t stream,
|
||||
const uint8_t * const data, const uint32_t data_length);
|
||||
|
||||
@@ -43,10 +43,10 @@
|
||||
|
||||
ngap_gNB_internal_data_t ngap_gNB_internal_data;
|
||||
|
||||
RB_GENERATE(ngap_mme_map, ngap_gNB_mme_data_s, entry, ngap_gNB_compare_assoc_id);
|
||||
RB_GENERATE(ngap_amf_map, ngap_gNB_amf_data_s, entry, ngap_gNB_compare_assoc_id);
|
||||
|
||||
int ngap_gNB_compare_assoc_id(
|
||||
struct ngap_gNB_mme_data_s *p1, struct ngap_gNB_mme_data_s *p2)
|
||||
struct ngap_gNB_amf_data_s *p1, struct ngap_gNB_amf_data_s *p2)
|
||||
{
|
||||
if (p1->assoc_id == -1) {
|
||||
if (p1->cnx_id < p2->cnx_id) {
|
||||
@@ -89,14 +89,14 @@ void ngap_gNB_insert_new_instance(ngap_gNB_instance_t *new_instance_p)
|
||||
new_instance_p, ngap_gNB_entries);
|
||||
}
|
||||
|
||||
struct ngap_gNB_mme_data_s *ngap_gNB_get_MME(
|
||||
struct ngap_gNB_amf_data_s *ngap_gNB_get_AMF(
|
||||
ngap_gNB_instance_t *instance_p,
|
||||
int32_t assoc_id, uint16_t cnx_id)
|
||||
{
|
||||
struct ngap_gNB_mme_data_s temp;
|
||||
struct ngap_gNB_mme_data_s *found;
|
||||
struct ngap_gNB_amf_data_s temp;
|
||||
struct ngap_gNB_amf_data_s *found;
|
||||
|
||||
memset(&temp, 0, sizeof(struct ngap_gNB_mme_data_s));
|
||||
memset(&temp, 0, sizeof(struct ngap_gNB_amf_data_s));
|
||||
|
||||
temp.assoc_id = assoc_id;
|
||||
temp.cnx_id = cnx_id;
|
||||
@@ -104,30 +104,30 @@ struct ngap_gNB_mme_data_s *ngap_gNB_get_MME(
|
||||
if (instance_p == NULL) {
|
||||
STAILQ_FOREACH(instance_p, &ngap_gNB_internal_data.ngap_gNB_instances_head,
|
||||
ngap_gNB_entries) {
|
||||
found = RB_FIND(ngap_mme_map, &instance_p->ngap_mme_head, &temp);
|
||||
found = RB_FIND(ngap_amf_map, &instance_p->ngap_amf_head, &temp);
|
||||
|
||||
if (found != NULL) {
|
||||
return found;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return RB_FIND(ngap_mme_map, &instance_p->ngap_mme_head, &temp);
|
||||
return RB_FIND(ngap_amf_map, &instance_p->ngap_amf_head, &temp);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct ngap_gNB_mme_data_s *ngap_gNB_get_MME_from_instance(
|
||||
struct ngap_gNB_amf_data_s *ngap_gNB_get_AMF_from_instance(
|
||||
ngap_gNB_instance_t *instance_p)
|
||||
{
|
||||
|
||||
struct ngap_gNB_mme_data_s *mme = NULL;
|
||||
struct ngap_gNB_mme_data_s *mme_next = NULL;
|
||||
struct ngap_gNB_amf_data_s *amf = NULL;
|
||||
struct ngap_gNB_amf_data_s *amf_next = NULL;
|
||||
|
||||
for (mme = RB_MIN(ngap_mme_map, &instance_p->ngap_mme_head); mme!=NULL ; mme = mme_next) {
|
||||
mme_next = RB_NEXT(ngap_mme_map, &instance_p->ngap_mme_head, mme);
|
||||
if (mme->ngap_gNB_instance == instance_p) {
|
||||
return mme;
|
||||
for (amf = RB_MIN(ngap_amf_map, &instance_p->ngap_amf_head); amf!=NULL ; amf = amf_next) {
|
||||
amf_next = RB_NEXT(ngap_amf_map, &instance_p->ngap_amf_head, amf);
|
||||
if (amf->ngap_gNB_instance == instance_p) {
|
||||
return amf;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,40 +149,40 @@ ngap_gNB_instance_t *ngap_gNB_get_instance(instance_t instance)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ngap_gNB_remove_mme_desc(ngap_gNB_instance_t * instance)
|
||||
void ngap_gNB_remove_amf_desc(ngap_gNB_instance_t * instance)
|
||||
{
|
||||
|
||||
struct ngap_gNB_mme_data_s *mme = NULL;
|
||||
struct ngap_gNB_mme_data_s *mmeNext = NULL;
|
||||
struct ngap_gNB_amf_data_s *amf = NULL;
|
||||
struct ngap_gNB_amf_data_s *amfNext = NULL;
|
||||
struct plmn_identity_s* plmnInfo;
|
||||
struct served_group_id_s* groupInfo;
|
||||
struct served_gummei_s* gummeiInfo;
|
||||
struct mme_code_s* mmeCode;
|
||||
struct served_guami_s* guamInfo;
|
||||
struct amf_code_s* amfCode;
|
||||
|
||||
for (mme = RB_MIN(ngap_mme_map, &instance->ngap_mme_head); mme; mme = mmeNext) {
|
||||
mmeNext = RB_NEXT(ngap_mme_map, &instance->ngap_mme_head, mme);
|
||||
RB_REMOVE(ngap_mme_map, &instance->ngap_mme_head, mme);
|
||||
while (!STAILQ_EMPTY(&mme->served_gummei)) {
|
||||
gummeiInfo = STAILQ_FIRST(&mme->served_gummei);
|
||||
STAILQ_REMOVE_HEAD(&mme->served_gummei, next);
|
||||
for (amf = RB_MIN(ngap_amf_map, &instance->ngap_amf_head); amf; amf = amfNext) {
|
||||
amfNext = RB_NEXT(ngap_amf_map, &instance->ngap_amf_head, amf);
|
||||
RB_REMOVE(ngap_amf_map, &instance->ngap_amf_head, amf);
|
||||
while (!STAILQ_EMPTY(&amf->served_guami)) {
|
||||
guamInfo = STAILQ_FIRST(&amf->served_guami);
|
||||
STAILQ_REMOVE_HEAD(&amf->served_guami, next);
|
||||
|
||||
while (!STAILQ_EMPTY(&gummeiInfo->served_plmns)) {
|
||||
plmnInfo = STAILQ_FIRST(&gummeiInfo->served_plmns);
|
||||
STAILQ_REMOVE_HEAD(&gummeiInfo->served_plmns, next);
|
||||
while (!STAILQ_EMPTY(&guamInfo->served_plmns)) {
|
||||
plmnInfo = STAILQ_FIRST(&guamInfo->served_plmns);
|
||||
STAILQ_REMOVE_HEAD(&guamInfo->served_plmns, next);
|
||||
free(plmnInfo);
|
||||
}
|
||||
while (!STAILQ_EMPTY(&gummeiInfo->served_group_ids)) {
|
||||
groupInfo = STAILQ_FIRST(&gummeiInfo->served_group_ids);
|
||||
STAILQ_REMOVE_HEAD(&gummeiInfo->served_group_ids, next);
|
||||
while (!STAILQ_EMPTY(&guamInfo->served_group_ids)) {
|
||||
groupInfo = STAILQ_FIRST(&guamInfo->served_group_ids);
|
||||
STAILQ_REMOVE_HEAD(&guamInfo->served_group_ids, next);
|
||||
free(groupInfo);
|
||||
}
|
||||
while (!STAILQ_EMPTY(&gummeiInfo->mme_codes)) {
|
||||
mmeCode = STAILQ_FIRST(&gummeiInfo->mme_codes);
|
||||
STAILQ_REMOVE_HEAD(&gummeiInfo->mme_codes, next);
|
||||
free(mmeCode);
|
||||
while (!STAILQ_EMPTY(&guamInfo->amf_codes)) {
|
||||
amfCode = STAILQ_FIRST(&guamInfo->amf_codes);
|
||||
STAILQ_REMOVE_HEAD(&guamInfo->amf_codes, next);
|
||||
free(amfCode);
|
||||
}
|
||||
free(gummeiInfo);
|
||||
free(guamInfo);
|
||||
}
|
||||
free(mme);
|
||||
free(amf);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,13 +22,13 @@
|
||||
#ifndef NGAP_GNB_MANAGEMENT_PROCEDURES_H_
|
||||
#define NGAP_GNB_MANAGEMENT_PROCEDURES_H_
|
||||
|
||||
struct ngap_gNB_mme_data_s *ngap_gNB_get_MME(
|
||||
struct ngap_gNB_amf_data_s *ngap_gNB_get_AMF(
|
||||
ngap_gNB_instance_t *instance_p,
|
||||
int32_t assoc_id, uint16_t cnx_id);
|
||||
|
||||
struct ngap_gNB_mme_data_s *ngap_gNB_get_MME_from_instance(ngap_gNB_instance_t *instance_p);
|
||||
struct ngap_gNB_amf_data_s *ngap_gNB_get_AMF_from_instance(ngap_gNB_instance_t *instance_p);
|
||||
|
||||
void ngap_gNB_remove_mme_desc(ngap_gNB_instance_t * instance);
|
||||
void ngap_gNB_remove_amf_desc(ngap_gNB_instance_t * instance);
|
||||
|
||||
void ngap_gNB_insert_new_instance(ngap_gNB_instance_t *new_instance_p);
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -41,19 +41,19 @@ int ngap_gNB_initial_ctxt_resp(
|
||||
int ngap_gNB_ue_capabilities(instance_t instance,
|
||||
ngap_ue_cap_info_ind_t *ue_cap_info_ind_p);
|
||||
|
||||
int ngap_gNB_e_rab_setup_resp(instance_t instance,
|
||||
ngap_e_rab_setup_resp_t *e_rab_setup_resp_p);
|
||||
int ngap_gNB_pdusession_setup_resp(instance_t instance,
|
||||
ngap_pdusession_setup_resp_t *pdusession_setup_resp_p);
|
||||
|
||||
int ngap_gNB_e_rab_modify_resp(instance_t instance,
|
||||
ngap_e_rab_modify_resp_t *e_rab_modify_resp_p);
|
||||
int ngap_gNB_pdusession_modify_resp(instance_t instance,
|
||||
ngap_pdusession_modify_resp_t *pdusession_modify_resp_p);
|
||||
|
||||
int ngap_gNB_e_rab_release_resp(instance_t instance,
|
||||
ngap_e_rab_release_resp_t *e_rab_release_resp_p);
|
||||
int ngap_gNB_pdusession_release_resp(instance_t instance,
|
||||
ngap_pdusession_release_resp_t *pdusession_release_resp_p);
|
||||
|
||||
int ngap_gNB_path_switch_req(instance_t instance,
|
||||
ngap_path_switch_req_t *path_switch_req_p);
|
||||
|
||||
int ngap_gNB_generate_E_RAB_Modification_Indication(
|
||||
instance_t instance, ngap_e_rab_modification_ind_t *e_rab_modification_ind);
|
||||
int ngap_gNB_generate_PDUSESSION_Modification_Indication(
|
||||
instance_t instance, ngap_pdusession_modification_ind_t *pdusession_modification_ind);
|
||||
|
||||
#endif /* NGAP_GNB_NAS_PROCEDURES_H_ */
|
||||
|
||||
+145
-145
@@ -36,108 +36,108 @@
|
||||
#include "ngap_gNB_defs.h"
|
||||
#include "ngap_gNB_nnsf.h"
|
||||
|
||||
struct ngap_gNB_mme_data_s *
|
||||
ngap_gNB_nnsf_select_mme(ngap_gNB_instance_t *instance_p,
|
||||
struct ngap_gNB_amf_data_s *
|
||||
ngap_gNB_nnsf_select_amf(ngap_gNB_instance_t *instance_p,
|
||||
rrc_establishment_cause_t cause)
|
||||
{
|
||||
struct ngap_gNB_mme_data_s *mme_data_p = NULL;
|
||||
struct ngap_gNB_mme_data_s *mme_highest_capacity_p = NULL;
|
||||
struct ngap_gNB_amf_data_s *amf_data_p = NULL;
|
||||
struct ngap_gNB_amf_data_s *amf_highest_capacity_p = NULL;
|
||||
uint8_t current_capacity = 0;
|
||||
|
||||
RB_FOREACH(mme_data_p, ngap_mme_map, &instance_p->ngap_mme_head) {
|
||||
if (mme_data_p->state != NGAP_GNB_STATE_CONNECTED) {
|
||||
/* The association between MME and gNB is not ready for the moment,
|
||||
* go to the next known MME.
|
||||
RB_FOREACH(amf_data_p, ngap_amf_map, &instance_p->ngap_amf_head) {
|
||||
if (amf_data_p->state != NGAP_GNB_STATE_CONNECTED) {
|
||||
/* The association between AMF and gNB is not ready for the moment,
|
||||
* go to the next known AMF.
|
||||
*/
|
||||
if (mme_data_p->state == NGAP_GNB_OVERLOAD) {
|
||||
/* MME is overloaded. We have to check the RRC establishment
|
||||
* cause and take decision to the select this MME depending on
|
||||
if (amf_data_p->state == NGAP_GNB_OVERLOAD) {
|
||||
/* AMF is overloaded. We have to check the RRC establishment
|
||||
* cause and take decision to the select this AMF depending on
|
||||
* the overload state.
|
||||
*/
|
||||
if ((cause == RRC_CAUSE_MO_DATA)
|
||||
&& (mme_data_p->overload_state == NGAP_OVERLOAD_REJECT_MO_DATA)) {
|
||||
&& (amf_data_p->overload_state == NGAP_OVERLOAD_REJECT_MO_DATA)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((mme_data_p->overload_state == NGAP_OVERLOAD_REJECT_ALL_SIGNALLING)
|
||||
if ((amf_data_p->overload_state == NGAP_OVERLOAD_REJECT_ALL_SIGNALLING)
|
||||
&& ((cause == RRC_CAUSE_MO_SIGNALLING) || (cause == RRC_CAUSE_MO_DATA))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((mme_data_p->overload_state == NGAP_OVERLOAD_ONLY_EMERGENCY_AND_MT)
|
||||
if ((amf_data_p->overload_state == NGAP_OVERLOAD_ONLY_EMERGENCY_AND_MT)
|
||||
&& ((cause == RRC_CAUSE_MO_SIGNALLING) || (cause == RRC_CAUSE_MO_DATA)
|
||||
|| (cause == RRC_CAUSE_HIGH_PRIO_ACCESS))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* At this point, the RRC establishment can be handled by the MME
|
||||
/* At this point, the RRC establishment can be handled by the AMF
|
||||
* even if it is in overload state.
|
||||
*/
|
||||
} else {
|
||||
/* The MME is not overloaded, association is simply not ready. */
|
||||
/* The AMF is not overloaded, association is simply not ready. */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (current_capacity < mme_data_p->relative_mme_capacity) {
|
||||
/* We find a better MME, keep a reference to it */
|
||||
current_capacity = mme_data_p->relative_mme_capacity;
|
||||
mme_highest_capacity_p = mme_data_p;
|
||||
if (current_capacity < amf_data_p->relative_amf_capacity) {
|
||||
/* We find a better AMF, keep a reference to it */
|
||||
current_capacity = amf_data_p->relative_amf_capacity;
|
||||
amf_highest_capacity_p = amf_data_p;
|
||||
}
|
||||
}
|
||||
|
||||
return mme_highest_capacity_p;
|
||||
return amf_highest_capacity_p;
|
||||
}
|
||||
|
||||
struct ngap_gNB_mme_data_s *
|
||||
ngap_gNB_nnsf_select_mme_by_plmn_id(ngap_gNB_instance_t *instance_p,
|
||||
struct ngap_gNB_amf_data_s *
|
||||
ngap_gNB_nnsf_select_amf_by_plmn_id(ngap_gNB_instance_t *instance_p,
|
||||
rrc_establishment_cause_t cause,
|
||||
int selected_plmn_identity)
|
||||
{
|
||||
struct ngap_gNB_mme_data_s *mme_data_p = NULL;
|
||||
struct ngap_gNB_mme_data_s *mme_highest_capacity_p = NULL;
|
||||
struct ngap_gNB_amf_data_s *amf_data_p = NULL;
|
||||
struct ngap_gNB_amf_data_s *amf_highest_capacity_p = NULL;
|
||||
uint8_t current_capacity = 0;
|
||||
|
||||
RB_FOREACH(mme_data_p, ngap_mme_map, &instance_p->ngap_mme_head) {
|
||||
struct served_gummei_s *gummei_p = NULL;
|
||||
RB_FOREACH(amf_data_p, ngap_amf_map, &instance_p->ngap_amf_head) {
|
||||
struct served_guami_s *guami_p = NULL;
|
||||
struct plmn_identity_s *served_plmn_p = NULL;
|
||||
if (mme_data_p->state != NGAP_GNB_STATE_CONNECTED) {
|
||||
/* The association between MME and gNB is not ready for the moment,
|
||||
* go to the next known MME.
|
||||
if (amf_data_p->state != NGAP_GNB_STATE_CONNECTED) {
|
||||
/* The association between AMF and gNB is not ready for the moment,
|
||||
* go to the next known AMF.
|
||||
*/
|
||||
if (mme_data_p->state == NGAP_GNB_OVERLOAD) {
|
||||
/* MME is overloaded. We have to check the RRC establishment
|
||||
* cause and take decision to the select this MME depending on
|
||||
if (amf_data_p->state == NGAP_GNB_OVERLOAD) {
|
||||
/* AMF is overloaded. We have to check the RRC establishment
|
||||
* cause and take decision to the select this AMF depending on
|
||||
* the overload state.
|
||||
*/
|
||||
if ((cause == RRC_CAUSE_MO_DATA)
|
||||
&& (mme_data_p->overload_state == NGAP_OVERLOAD_REJECT_MO_DATA)) {
|
||||
&& (amf_data_p->overload_state == NGAP_OVERLOAD_REJECT_MO_DATA)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((mme_data_p->overload_state == NGAP_OVERLOAD_REJECT_ALL_SIGNALLING)
|
||||
if ((amf_data_p->overload_state == NGAP_OVERLOAD_REJECT_ALL_SIGNALLING)
|
||||
&& ((cause == RRC_CAUSE_MO_SIGNALLING) || (cause == RRC_CAUSE_MO_DATA))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((mme_data_p->overload_state == NGAP_OVERLOAD_ONLY_EMERGENCY_AND_MT)
|
||||
if ((amf_data_p->overload_state == NGAP_OVERLOAD_ONLY_EMERGENCY_AND_MT)
|
||||
&& ((cause == RRC_CAUSE_MO_SIGNALLING) || (cause == RRC_CAUSE_MO_DATA)
|
||||
|| (cause == RRC_CAUSE_HIGH_PRIO_ACCESS))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* At this point, the RRC establishment can be handled by the MME
|
||||
/* At this point, the RRC establishment can be handled by the AMF
|
||||
* even if it is in overload state.
|
||||
*/
|
||||
} else {
|
||||
/* The MME is not overloaded, association is simply not ready. */
|
||||
/* The AMF is not overloaded, association is simply not ready. */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Looking for served GUMMEI PLMN Identity selected matching the one provided by the UE */
|
||||
STAILQ_FOREACH(gummei_p, &mme_data_p->served_gummei, next) {
|
||||
STAILQ_FOREACH(served_plmn_p, &gummei_p->served_plmns, next) {
|
||||
/* Looking for served GUAMI PLMN Identity selected matching the one provided by the UE */
|
||||
STAILQ_FOREACH(guami_p, &amf_data_p->served_guami, next) {
|
||||
STAILQ_FOREACH(served_plmn_p, &guami_p->served_plmns, next) {
|
||||
if ((served_plmn_p->mcc == instance_p->mcc[selected_plmn_identity]) &&
|
||||
(served_plmn_p->mnc == instance_p->mnc[selected_plmn_identity])) {
|
||||
break;
|
||||
@@ -146,254 +146,254 @@ ngap_gNB_nnsf_select_mme_by_plmn_id(ngap_gNB_instance_t *instance_p,
|
||||
/* if found, we can stop the outer loop, too */
|
||||
if (served_plmn_p) break;
|
||||
}
|
||||
/* if we didn't find such a served PLMN, go on with the next MME */
|
||||
/* if we didn't find such a served PLMN, go on with the next AMF */
|
||||
if (!served_plmn_p) continue;
|
||||
|
||||
if (current_capacity < mme_data_p->relative_mme_capacity) {
|
||||
/* We find a better MME, keep a reference to it */
|
||||
current_capacity = mme_data_p->relative_mme_capacity;
|
||||
mme_highest_capacity_p = mme_data_p;
|
||||
if (current_capacity < amf_data_p->relative_amf_capacity) {
|
||||
/* We find a better AMF, keep a reference to it */
|
||||
current_capacity = amf_data_p->relative_amf_capacity;
|
||||
amf_highest_capacity_p = amf_data_p;
|
||||
}
|
||||
}
|
||||
|
||||
return mme_highest_capacity_p;
|
||||
return amf_highest_capacity_p;
|
||||
}
|
||||
|
||||
struct ngap_gNB_mme_data_s *
|
||||
ngap_gNB_nnsf_select_mme_by_mme_code(ngap_gNB_instance_t *instance_p,
|
||||
struct ngap_gNB_amf_data_s *
|
||||
ngap_gNB_nnsf_select_amf_by_amf_code(ngap_gNB_instance_t *instance_p,
|
||||
rrc_establishment_cause_t cause,
|
||||
int selected_plmn_identity,
|
||||
uint8_t mme_code)
|
||||
uint8_t amf_code)
|
||||
{
|
||||
struct ngap_gNB_mme_data_s *mme_data_p = NULL;
|
||||
struct ngap_gNB_amf_data_s *amf_data_p = NULL;
|
||||
|
||||
RB_FOREACH(mme_data_p, ngap_mme_map, &instance_p->ngap_mme_head) {
|
||||
struct served_gummei_s *gummei_p = NULL;
|
||||
RB_FOREACH(amf_data_p, ngap_amf_map, &instance_p->ngap_amf_head) {
|
||||
struct served_guami_s *guami_p = NULL;
|
||||
|
||||
if (mme_data_p->state != NGAP_GNB_STATE_CONNECTED) {
|
||||
/* The association between MME and gNB is not ready for the moment,
|
||||
* go to the next known MME.
|
||||
if (amf_data_p->state != NGAP_GNB_STATE_CONNECTED) {
|
||||
/* The association between AMF and gNB is not ready for the moment,
|
||||
* go to the next known AMF.
|
||||
*/
|
||||
if (mme_data_p->state == NGAP_GNB_OVERLOAD) {
|
||||
/* MME is overloaded. We have to check the RRC establishment
|
||||
* cause and take decision to the select this MME depending on
|
||||
if (amf_data_p->state == NGAP_GNB_OVERLOAD) {
|
||||
/* AMF is overloaded. We have to check the RRC establishment
|
||||
* cause and take decision to the select this AMF depending on
|
||||
* the overload state.
|
||||
*/
|
||||
if ((cause == RRC_CAUSE_MO_DATA)
|
||||
&& (mme_data_p->overload_state == NGAP_OVERLOAD_REJECT_MO_DATA)) {
|
||||
&& (amf_data_p->overload_state == NGAP_OVERLOAD_REJECT_MO_DATA)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((mme_data_p->overload_state == NGAP_OVERLOAD_REJECT_ALL_SIGNALLING)
|
||||
if ((amf_data_p->overload_state == NGAP_OVERLOAD_REJECT_ALL_SIGNALLING)
|
||||
&& ((cause == RRC_CAUSE_MO_SIGNALLING) || (cause == RRC_CAUSE_MO_DATA))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((mme_data_p->overload_state == NGAP_OVERLOAD_ONLY_EMERGENCY_AND_MT)
|
||||
if ((amf_data_p->overload_state == NGAP_OVERLOAD_ONLY_EMERGENCY_AND_MT)
|
||||
&& ((cause == RRC_CAUSE_MO_SIGNALLING) || (cause == RRC_CAUSE_MO_DATA)
|
||||
|| (cause == RRC_CAUSE_HIGH_PRIO_ACCESS))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* At this point, the RRC establishment can be handled by the MME
|
||||
/* At this point, the RRC establishment can be handled by the AMF
|
||||
* even if it is in overload state.
|
||||
*/
|
||||
} else {
|
||||
/* The MME is not overloaded, association is simply not ready. */
|
||||
/* The AMF is not overloaded, association is simply not ready. */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Looking for MME code matching the one provided by NAS */
|
||||
STAILQ_FOREACH(gummei_p, &mme_data_p->served_gummei, next) {
|
||||
struct mme_code_s *mme_code_p = NULL;
|
||||
/* Looking for AMF code matching the one provided by NAS */
|
||||
STAILQ_FOREACH(guami_p, &amf_data_p->served_guami, next) {
|
||||
struct amf_code_s *amf_code_p = NULL;
|
||||
struct plmn_identity_s *served_plmn_p = NULL;
|
||||
|
||||
STAILQ_FOREACH(served_plmn_p, &gummei_p->served_plmns, next) {
|
||||
STAILQ_FOREACH(served_plmn_p, &guami_p->served_plmns, next) {
|
||||
if ((served_plmn_p->mcc == instance_p->mcc[selected_plmn_identity]) &&
|
||||
(served_plmn_p->mnc == instance_p->mnc[selected_plmn_identity])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
STAILQ_FOREACH(mme_code_p, &gummei_p->mme_codes, next) {
|
||||
if (mme_code_p->mme_code == mme_code) {
|
||||
STAILQ_FOREACH(amf_code_p, &guami_p->amf_codes, next) {
|
||||
if (amf_code_p->amf_code == amf_code) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* The MME matches the parameters provided by the NAS layer ->
|
||||
* the MME is knwown and the association is ready.
|
||||
* Return the reference to the MME to use it for this UE.
|
||||
/* The AMF matches the parameters provided by the NAS layer ->
|
||||
* the AMF is knwown and the association is ready.
|
||||
* Return the reference to the AMF to use it for this UE.
|
||||
*/
|
||||
if (mme_code_p && served_plmn_p) {
|
||||
return mme_data_p;
|
||||
if (amf_code_p && served_plmn_p) {
|
||||
return amf_data_p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* At this point no MME matches the selected PLMN and MME code. In this case,
|
||||
/* At this point no AMF matches the selected PLMN and AMF code. In this case,
|
||||
* return NULL. That way the RRC layer should know about it and reject RRC
|
||||
* connectivity. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct ngap_gNB_mme_data_s *
|
||||
ngap_gNB_nnsf_select_mme_by_gummei(ngap_gNB_instance_t *instance_p,
|
||||
struct ngap_gNB_amf_data_s *
|
||||
ngap_gNB_nnsf_select_amf_by_guami(ngap_gNB_instance_t *instance_p,
|
||||
rrc_establishment_cause_t cause,
|
||||
ngap_gummei_t gummei)
|
||||
ngap_guami_t guami)
|
||||
{
|
||||
struct ngap_gNB_mme_data_s *mme_data_p = NULL;
|
||||
struct ngap_gNB_amf_data_s *amf_data_p = NULL;
|
||||
|
||||
RB_FOREACH(mme_data_p, ngap_mme_map, &instance_p->ngap_mme_head) {
|
||||
struct served_gummei_s *gummei_p = NULL;
|
||||
RB_FOREACH(amf_data_p, ngap_amf_map, &instance_p->ngap_amf_head) {
|
||||
struct served_guami_s *guami_p = NULL;
|
||||
|
||||
if (mme_data_p->state != NGAP_GNB_STATE_CONNECTED) {
|
||||
/* The association between MME and gNB is not ready for the moment,
|
||||
* go to the next known MME.
|
||||
if (amf_data_p->state != NGAP_GNB_STATE_CONNECTED) {
|
||||
/* The association between AMF and gNB is not ready for the moment,
|
||||
* go to the next known AMF.
|
||||
*/
|
||||
if (mme_data_p->state == NGAP_GNB_OVERLOAD) {
|
||||
/* MME is overloaded. We have to check the RRC establishment
|
||||
* cause and take decision to the select this MME depending on
|
||||
if (amf_data_p->state == NGAP_GNB_OVERLOAD) {
|
||||
/* AMF is overloaded. We have to check the RRC establishment
|
||||
* cause and take decision to the select this AMF depending on
|
||||
* the overload state.
|
||||
*/
|
||||
if ((cause == RRC_CAUSE_MO_DATA)
|
||||
&& (mme_data_p->overload_state == NGAP_OVERLOAD_REJECT_MO_DATA)) {
|
||||
&& (amf_data_p->overload_state == NGAP_OVERLOAD_REJECT_MO_DATA)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((mme_data_p->overload_state == NGAP_OVERLOAD_REJECT_ALL_SIGNALLING)
|
||||
if ((amf_data_p->overload_state == NGAP_OVERLOAD_REJECT_ALL_SIGNALLING)
|
||||
&& ((cause == RRC_CAUSE_MO_SIGNALLING) || (cause == RRC_CAUSE_MO_DATA))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((mme_data_p->overload_state == NGAP_OVERLOAD_ONLY_EMERGENCY_AND_MT)
|
||||
if ((amf_data_p->overload_state == NGAP_OVERLOAD_ONLY_EMERGENCY_AND_MT)
|
||||
&& ((cause == RRC_CAUSE_MO_SIGNALLING) || (cause == RRC_CAUSE_MO_DATA)
|
||||
|| (cause == RRC_CAUSE_HIGH_PRIO_ACCESS))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* At this point, the RRC establishment can be handled by the MME
|
||||
/* At this point, the RRC establishment can be handled by the AMF
|
||||
* even if it is in overload state.
|
||||
*/
|
||||
} else {
|
||||
/* The MME is not overloaded, association is simply not ready. */
|
||||
/* The AMF is not overloaded, association is simply not ready. */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Looking for MME gummei matching the one provided by NAS */
|
||||
STAILQ_FOREACH(gummei_p, &mme_data_p->served_gummei, next) {
|
||||
/* Looking for AMF guami matching the one provided by NAS */
|
||||
STAILQ_FOREACH(guami_p, &amf_data_p->served_guami, next) {
|
||||
struct served_group_id_s *group_id_p = NULL;
|
||||
struct mme_code_s *mme_code_p = NULL;
|
||||
struct amf_code_s *amf_code_p = NULL;
|
||||
struct plmn_identity_s *served_plmn_p = NULL;
|
||||
|
||||
STAILQ_FOREACH(served_plmn_p, &gummei_p->served_plmns, next) {
|
||||
if ((served_plmn_p->mcc == gummei.mcc) &&
|
||||
(served_plmn_p->mnc == gummei.mnc)) {
|
||||
STAILQ_FOREACH(served_plmn_p, &guami_p->served_plmns, next) {
|
||||
if ((served_plmn_p->mcc == guami.mcc) &&
|
||||
(served_plmn_p->mnc == guami.mnc)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
STAILQ_FOREACH(mme_code_p, &gummei_p->mme_codes, next) {
|
||||
if (mme_code_p->mme_code == gummei.mme_code) {
|
||||
STAILQ_FOREACH(amf_code_p, &guami_p->amf_codes, next) {
|
||||
if (amf_code_p->amf_code == guami.amf_code) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
STAILQ_FOREACH(group_id_p, &gummei_p->served_group_ids, next) {
|
||||
if (group_id_p->mme_group_id == gummei.mme_group_id) {
|
||||
STAILQ_FOREACH(group_id_p, &guami_p->served_group_ids, next) {
|
||||
if (group_id_p->amf_group_id == guami.amf_group_id) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* The MME matches the parameters provided by the NAS layer ->
|
||||
* the MME is knwown and the association is ready.
|
||||
* Return the reference to the MME to use it for this UE.
|
||||
/* The AMF matches the parameters provided by the NAS layer ->
|
||||
* the AMF is knwown and the association is ready.
|
||||
* Return the reference to the AMF to use it for this UE.
|
||||
*/
|
||||
if ((group_id_p != NULL) &&
|
||||
(mme_code_p != NULL) &&
|
||||
(amf_code_p != NULL) &&
|
||||
(served_plmn_p != NULL)) {
|
||||
return mme_data_p;
|
||||
return amf_data_p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* At this point no MME matches the provided GUMMEI. In this case, return
|
||||
/* At this point no AMF matches the provided GUAMI. In this case, return
|
||||
* NULL. That way the RRC layer should know about it and reject RRC
|
||||
* connectivity. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
struct ngap_gNB_mme_data_s *
|
||||
ngap_gNB_nnsf_select_mme_by_gummei_no_cause(ngap_gNB_instance_t *instance_p,
|
||||
ngap_gummei_t gummei)
|
||||
struct ngap_gNB_amf_data_s *
|
||||
ngap_gNB_nnsf_select_amf_by_guami_no_cause(ngap_gNB_instance_t *instance_p,
|
||||
ngap_guami_t guami)
|
||||
{
|
||||
struct ngap_gNB_mme_data_s *mme_data_p = NULL;
|
||||
struct ngap_gNB_mme_data_s *mme_highest_capacity_p = NULL;
|
||||
struct ngap_gNB_amf_data_s *amf_data_p = NULL;
|
||||
struct ngap_gNB_amf_data_s *amf_highest_capacity_p = NULL;
|
||||
uint8_t current_capacity = 0;
|
||||
|
||||
RB_FOREACH(mme_data_p, ngap_mme_map, &instance_p->ngap_mme_head) {
|
||||
struct served_gummei_s *gummei_p = NULL;
|
||||
RB_FOREACH(amf_data_p, ngap_amf_map, &instance_p->ngap_amf_head) {
|
||||
struct served_guami_s *guami_p = NULL;
|
||||
|
||||
if (mme_data_p->state != NGAP_GNB_STATE_CONNECTED) {
|
||||
/* The association between MME and gNB is not ready for the moment,
|
||||
* go to the next known MME.
|
||||
if (amf_data_p->state != NGAP_GNB_STATE_CONNECTED) {
|
||||
/* The association between AMF and gNB is not ready for the moment,
|
||||
* go to the next known AMF.
|
||||
*/
|
||||
if (mme_data_p->state == NGAP_GNB_OVERLOAD) {
|
||||
/* MME is overloaded. We have to check the RRC establishment
|
||||
* cause and take decision to the select this MME depending on
|
||||
if (amf_data_p->state == NGAP_GNB_OVERLOAD) {
|
||||
/* AMF is overloaded. We have to check the RRC establishment
|
||||
* cause and take decision to the select this AMF depending on
|
||||
* the overload state.
|
||||
*/
|
||||
} else {
|
||||
/* The MME is not overloaded, association is simply not ready. */
|
||||
/* The AMF is not overloaded, association is simply not ready. */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (current_capacity < mme_data_p->relative_mme_capacity) {
|
||||
/* We find a better MME, keep a reference to it */
|
||||
current_capacity = mme_data_p->relative_mme_capacity;
|
||||
mme_highest_capacity_p = mme_data_p;
|
||||
if (current_capacity < amf_data_p->relative_amf_capacity) {
|
||||
/* We find a better AMF, keep a reference to it */
|
||||
current_capacity = amf_data_p->relative_amf_capacity;
|
||||
amf_highest_capacity_p = amf_data_p;
|
||||
}
|
||||
|
||||
/* Looking for MME gummei matching the one provided by NAS */
|
||||
STAILQ_FOREACH(gummei_p, &mme_data_p->served_gummei, next) {
|
||||
/* Looking for AMF guami matching the one provided by NAS */
|
||||
STAILQ_FOREACH(guami_p, &amf_data_p->served_guami, next) {
|
||||
struct served_group_id_s *group_id_p = NULL;
|
||||
struct mme_code_s *mme_code_p = NULL;
|
||||
struct amf_code_s *amf_code_p = NULL;
|
||||
struct plmn_identity_s *served_plmn_p = NULL;
|
||||
|
||||
STAILQ_FOREACH(served_plmn_p, &gummei_p->served_plmns, next) {
|
||||
if ((served_plmn_p->mcc == gummei.mcc) &&
|
||||
(served_plmn_p->mnc == gummei.mnc)) {
|
||||
STAILQ_FOREACH(served_plmn_p, &guami_p->served_plmns, next) {
|
||||
if ((served_plmn_p->mcc == guami.mcc) &&
|
||||
(served_plmn_p->mnc == guami.mnc)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
STAILQ_FOREACH(mme_code_p, &gummei_p->mme_codes, next) {
|
||||
if (mme_code_p->mme_code == gummei.mme_code) {
|
||||
STAILQ_FOREACH(amf_code_p, &guami_p->amf_codes, next) {
|
||||
if (amf_code_p->amf_code == guami.amf_code) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
STAILQ_FOREACH(group_id_p, &gummei_p->served_group_ids, next) {
|
||||
if (group_id_p->mme_group_id == gummei.mme_group_id) {
|
||||
STAILQ_FOREACH(group_id_p, &guami_p->served_group_ids, next) {
|
||||
if (group_id_p->amf_group_id == guami.amf_group_id) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* The MME matches the parameters provided by the NAS layer ->
|
||||
* the MME is knwown and the association is ready.
|
||||
* Return the reference to the MME to use it for this UE.
|
||||
/* The AMF matches the parameters provided by the NAS layer ->
|
||||
* the AMF is knwown and the association is ready.
|
||||
* Return the reference to the AMF to use it for this UE.
|
||||
*/
|
||||
if ((group_id_p != NULL) &&
|
||||
(mme_code_p != NULL) &&
|
||||
(amf_code_p != NULL) &&
|
||||
(served_plmn_p != NULL)) {
|
||||
return mme_data_p;
|
||||
return amf_data_p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* At this point no MME matches the provided GUMMEI. Select the one with the
|
||||
/* At this point no AMF matches the provided GUAMI. Select the one with the
|
||||
* highest relative capacity.
|
||||
* In case the list of known MME is empty, simply return NULL, that way the RRC
|
||||
* In case the list of known AMF is empty, simply return NULL, that way the RRC
|
||||
* layer should know about it and reject RRC connectivity.
|
||||
*/
|
||||
return mme_highest_capacity_p;
|
||||
return amf_highest_capacity_p;
|
||||
}
|
||||
|
||||
@@ -22,28 +22,28 @@
|
||||
#ifndef NGAP_GNB_NNSF_H_
|
||||
#define NGAP_GNB_NNSF_H_
|
||||
|
||||
struct ngap_gNB_mme_data_s *
|
||||
ngap_gNB_nnsf_select_mme(ngap_gNB_instance_t *instance_p,
|
||||
struct ngap_gNB_amf_data_s *
|
||||
ngap_gNB_nnsf_select_amf(ngap_gNB_instance_t *instance_p,
|
||||
rrc_establishment_cause_t cause);
|
||||
|
||||
struct ngap_gNB_mme_data_s *
|
||||
ngap_gNB_nnsf_select_mme_by_plmn_id(ngap_gNB_instance_t *instance_p,
|
||||
struct ngap_gNB_amf_data_s *
|
||||
ngap_gNB_nnsf_select_amf_by_plmn_id(ngap_gNB_instance_t *instance_p,
|
||||
rrc_establishment_cause_t cause,
|
||||
int selected_plmn_identity);
|
||||
|
||||
struct ngap_gNB_mme_data_s*
|
||||
ngap_gNB_nnsf_select_mme_by_mme_code(ngap_gNB_instance_t *instance_p,
|
||||
struct ngap_gNB_amf_data_s*
|
||||
ngap_gNB_nnsf_select_amf_by_amf_code(ngap_gNB_instance_t *instance_p,
|
||||
rrc_establishment_cause_t cause,
|
||||
int selected_plmn_identity,
|
||||
uint8_t mme_code);
|
||||
uint8_t amf_code);
|
||||
|
||||
struct ngap_gNB_mme_data_s*
|
||||
ngap_gNB_nnsf_select_mme_by_gummei(ngap_gNB_instance_t *instance_p,
|
||||
struct ngap_gNB_amf_data_s*
|
||||
ngap_gNB_nnsf_select_amf_by_guami(ngap_gNB_instance_t *instance_p,
|
||||
rrc_establishment_cause_t cause,
|
||||
ngap_gummei_t gummei);
|
||||
ngap_guami_t guami);
|
||||
|
||||
struct ngap_gNB_mme_data_s*
|
||||
ngap_gNB_nnsf_select_mme_by_gummei_no_cause(ngap_gNB_instance_t *instance_p,
|
||||
ngap_gummei_t gummei);
|
||||
struct ngap_gNB_amf_data_s*
|
||||
ngap_gNB_nnsf_select_amf_by_guami_no_cause(ngap_gNB_instance_t *instance_p,
|
||||
ngap_guami_t guami);
|
||||
|
||||
#endif /* NGAP_GNB_NNSF_H_ */
|
||||
|
||||
@@ -47,7 +47,7 @@ int ngap_gNB_handle_overload_start(uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
NGAP_NGAP_PDU_t *pdu)
|
||||
{
|
||||
ngap_gNB_mme_data_t *mme_desc_p;
|
||||
ngap_gNB_amf_data_t *amf_desc_p;
|
||||
NGAP_OverloadStart_t *container;
|
||||
NGAP_OverloadStartIEs_t *ie;
|
||||
|
||||
@@ -65,16 +65,16 @@ int ngap_gNB_handle_overload_start(uint32_t assoc_id,
|
||||
/* Non UE-associated signalling -> stream 0 */
|
||||
DevCheck(stream == 0, stream, 0, 0);
|
||||
|
||||
if ((mme_desc_p = ngap_gNB_get_MME(NULL, assoc_id, 0)) == NULL) {
|
||||
/* No MME context associated */
|
||||
if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) {
|
||||
/* No AMF context associated */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Mark the MME as overloaded and set the overload state according to
|
||||
/* Mark the AMF as overloaded and set the overload state according to
|
||||
* the value received.
|
||||
*/
|
||||
mme_desc_p->state = NGAP_GNB_OVERLOAD;
|
||||
mme_desc_p->overload_state =
|
||||
amf_desc_p->state = NGAP_GNB_OVERLOAD;
|
||||
amf_desc_p->overload_state =
|
||||
ie->value.choice.OverloadResponse.choice.overloadAction;
|
||||
|
||||
return 0;
|
||||
@@ -84,23 +84,23 @@ int ngap_gNB_handle_overload_stop(uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
NGAP_NGAP_PDU_t *pdu)
|
||||
{
|
||||
/* We received Overload stop message, meaning that the MME is no more
|
||||
/* We received Overload stop message, meaning that the AMF is no more
|
||||
* overloaded. This is an empty message, with only message header and no
|
||||
* Information Element.
|
||||
*/
|
||||
DevAssert(pdu != NULL);
|
||||
|
||||
ngap_gNB_mme_data_t *mme_desc_p;
|
||||
ngap_gNB_amf_data_t *amf_desc_p;
|
||||
|
||||
/* Non UE-associated signalling -> stream 0 */
|
||||
DevCheck(stream == 0, stream, 0, 0);
|
||||
|
||||
if ((mme_desc_p = ngap_gNB_get_MME(NULL, assoc_id, 0)) == NULL) {
|
||||
/* No MME context associated */
|
||||
if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) {
|
||||
/* No AMF context associated */
|
||||
return -1;
|
||||
}
|
||||
|
||||
mme_desc_p->state = NGAP_GNB_STATE_CONNECTED;
|
||||
mme_desc_p->overload_state = NGAP_NO_OVERLOAD;
|
||||
amf_desc_p->state = NGAP_GNB_STATE_CONNECTED;
|
||||
amf_desc_p->overload_state = NGAP_NO_OVERLOAD;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
/**
|
||||
* \brief Handle an overload start message
|
||||
**/
|
||||
// int ngap_gNB_handle_overload_start(gNB_mme_desc_t *gNB_desc_p,
|
||||
// int ngap_gNB_handle_overload_start(gNB_amf_desc_t *gNB_desc_p,
|
||||
// sctp_queue_item_t *packet_p,
|
||||
// struct ngap_message_s *message_p);
|
||||
int ngap_gNB_handle_overload_start(uint32_t assoc_id,
|
||||
@@ -35,7 +35,7 @@ int ngap_gNB_handle_overload_start(uint32_t assoc_id,
|
||||
/**
|
||||
* \brief Handle an overload stop message
|
||||
**/
|
||||
// int ngap_gNB_handle_overload_stop(gNB_mme_desc_t *gNB_desc_p,
|
||||
// int ngap_gNB_handle_overload_stop(gNB_amf_desc_t *gNB_desc_p,
|
||||
// sctp_queue_item_t *packet_p,
|
||||
// struct ngap_message_s *message_p);
|
||||
int ngap_gNB_handle_overload_stop(uint32_t assoc_id,
|
||||
|
||||
@@ -62,10 +62,10 @@ void ngap_gNB_generate_trace_failure(struct ngap_gNB_ue_context_s *ue_desc_p,
|
||||
|
||||
/* mandatory */
|
||||
ie = (NGAP_TraceFailureIndicationIEs_t *)calloc(1, sizeof(NGAP_TraceFailureIndicationIEs_t));
|
||||
ie->id = NGAP_ProtocolIE_ID_id_MME_UE_NGAP_ID;
|
||||
ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID;
|
||||
ie->criticality = NGAP_Criticality_reject;
|
||||
ie->value.present = NGAP_TraceFailureIndicationIEs__value_PR_MME_UE_NGAP_ID;
|
||||
ie->value.choice.MME_UE_NGAP_ID = ue_desc_p->mme_ue_ngap_id;
|
||||
ie->value.present = NGAP_TraceFailureIndicationIEs__value_PR_AMF_UE_NGAP_ID;
|
||||
ie->value.choice.AMF_UE_NGAP_ID = ue_desc_p->amf_ue_ngap_id;
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
/* mandatory */
|
||||
@@ -96,8 +96,8 @@ void ngap_gNB_generate_trace_failure(struct ngap_gNB_ue_context_s *ue_desc_p,
|
||||
return;
|
||||
}
|
||||
|
||||
ngap_gNB_itti_send_sctp_data_req(ue_desc_p->mme_ref->ngap_gNB_instance->instance,
|
||||
ue_desc_p->mme_ref->assoc_id, buffer,
|
||||
ngap_gNB_itti_send_sctp_data_req(ue_desc_p->amf_ref->ngap_gNB_instance->instance,
|
||||
ue_desc_p->amf_ref->assoc_id, buffer,
|
||||
length, ue_desc_p->tx_stream);
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ int ngap_gNB_handle_trace_start(uint32_t assoc_id,
|
||||
NGAP_TraceStart_t *container;
|
||||
NGAP_TraceStartIEs_t *ie;
|
||||
struct ngap_gNB_ue_context_s *ue_desc_p = NULL;
|
||||
struct ngap_gNB_mme_data_s *mme_ref_p;
|
||||
struct ngap_gNB_amf_data_s *amf_ref_p;
|
||||
|
||||
DevAssert(pdu != NULL);
|
||||
|
||||
@@ -116,10 +116,10 @@ int ngap_gNB_handle_trace_start(uint32_t assoc_id,
|
||||
|
||||
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_TraceStartIEs_t, ie, container,
|
||||
NGAP_ProtocolIE_ID_id_gNB_UE_NGAP_ID, TRUE);
|
||||
mme_ref_p = ngap_gNB_get_MME(NULL, assoc_id, 0);
|
||||
DevAssert(mme_ref_p != NULL);
|
||||
amf_ref_p = ngap_gNB_get_AMF(NULL, assoc_id, 0);
|
||||
DevAssert(amf_ref_p != NULL);
|
||||
if (ie != NULL) {
|
||||
ue_desc_p = ngap_gNB_get_ue_context(mme_ref_p->ngap_gNB_instance,
|
||||
ue_desc_p = ngap_gNB_get_ue_context(amf_ref_p->ngap_gNB_instance,
|
||||
ie->value.choice.GNB_UE_NGAP_ID);
|
||||
}
|
||||
if (ue_desc_p == NULL) {
|
||||
|
||||
@@ -25,18 +25,18 @@
|
||||
// int ngap_gNB_generate_trace_failure(sctp_data_t *sctp_data_p,
|
||||
// int32_t stream,
|
||||
// uint32_t gNB_ue_ngap_id,
|
||||
// uint32_t mme_ue_ngap_id,
|
||||
// uint32_t amf_ue_ngap_id,
|
||||
// E_UTRAN_Trace_ID_t *trace_id,
|
||||
// Cause_t *cause_p);
|
||||
|
||||
// int ngap_gNB_handle_trace_start(gNB_mme_desc_t *gNB_desc_p,
|
||||
// int ngap_gNB_handle_trace_start(gNB_amf_desc_t *gNB_desc_p,
|
||||
// sctp_queue_item_t *packet_p,
|
||||
// struct ngap_message_s *message_p);
|
||||
int ngap_gNB_handle_trace_start(uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
NGAP_NGAP_PDU_t *pdu);
|
||||
|
||||
// int ngap_gNB_handle_deactivate_trace(gNB_mme_desc_t *gNB_desc_p,
|
||||
// int ngap_gNB_handle_deactivate_trace(gNB_amf_desc_t *gNB_desc_p,
|
||||
// sctp_queue_item_t *packet_p,
|
||||
// struct ngap_message_s *message_p);
|
||||
int ngap_gNB_handle_deactivate_trace(uint32_t assoc_id,
|
||||
|
||||
@@ -28,12 +28,12 @@
|
||||
#define NGAP_GNB_UE_CONTEXT_H_
|
||||
|
||||
// Forward declarations
|
||||
struct ngap_gNB_mme_data_s;
|
||||
struct ngap_gNB_amf_data_s;
|
||||
struct ngap_ue_map;
|
||||
struct gNB_mme_desc_s;
|
||||
struct gNB_amf_desc_s;
|
||||
|
||||
typedef enum {
|
||||
/* UE has not been registered to a MME or UE association has failed. */
|
||||
/* UE has not been registered to a AMF or UE association has failed. */
|
||||
NGAP_UE_DECONNECTED = 0x0,
|
||||
/* UE ngap state is waiting for initial context setup request message. */
|
||||
NGAP_UE_WAITING_CSR = 0x1,
|
||||
@@ -46,7 +46,7 @@ typedef struct ngap_gNB_ue_context_s {
|
||||
/* Tree related data */
|
||||
RB_ENTRY(ngap_gNB_ue_context_s) entries;
|
||||
|
||||
/* Uniquely identifies the UE between MME and gNB within the gNB.
|
||||
/* Uniquely identifies the UE between AMF and gNB within the gNB.
|
||||
* This id is encoded on 24bits.
|
||||
*/
|
||||
unsigned gNB_ue_ngap_id:24;
|
||||
@@ -54,8 +54,8 @@ typedef struct ngap_gNB_ue_context_s {
|
||||
/* UE id for initial connection to NGAP */
|
||||
uint16_t ue_initial_id;
|
||||
|
||||
/* Uniquely identifies the UE within MME. Encoded on 32 bits. */
|
||||
uint32_t mme_ue_ngap_id;
|
||||
/* Uniquely identifies the UE within AMF. Encoded on 32 bits. */
|
||||
uint32_t amf_ue_ngap_id;
|
||||
|
||||
/* Stream used for this particular UE */
|
||||
int32_t tx_stream;
|
||||
@@ -64,8 +64,8 @@ typedef struct ngap_gNB_ue_context_s {
|
||||
/* Current UE state. */
|
||||
ngap_ue_state ue_state;
|
||||
|
||||
/* Reference to MME data this UE is attached to */
|
||||
struct ngap_gNB_mme_data_s *mme_ref;
|
||||
/* Reference to AMF data this UE is attached to */
|
||||
struct ngap_gNB_amf_data_s *amf_ref;
|
||||
|
||||
/* Signaled by the UE in RRC Connection Setup Complete and used in NAS Uplink
|
||||
* to route NAS messages correctly. 0-based, not 1-based as in TS 36.331
|
||||
|
||||
Reference in New Issue
Block a user