Merge remote-tracking branch 'origin/rework-ngap' into integration_2023_w11b
This commit is contained in:
@@ -169,7 +169,7 @@ gNBs =
|
||||
|
||||
|
||||
////////// AMF parameters:
|
||||
amf_ip_address = ( { ipv4 = "192.168.5.233";
|
||||
amf_ip_address = ( { ipv4 = "192.168.70.132";
|
||||
ipv6 = "192:168:30::17";
|
||||
active = "yes";
|
||||
preference = "ipv4";
|
||||
@@ -178,11 +178,10 @@ gNBs =
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
GNB_INTERFACE_NAME_FOR_NG_AMF = "eth0";
|
||||
GNB_IPV4_ADDRESS_FOR_NG_AMF = "CI_GNB_IP_ADDR";
|
||||
GNB_INTERFACE_NAME_FOR_NGU = "eth0";
|
||||
GNB_IPV4_ADDRESS_FOR_NGU = "CI_GNB_IP_ADDR";
|
||||
GNB_INTERFACE_NAME_FOR_NG_AMF = "demo-oai";
|
||||
GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.70.129/24";
|
||||
GNB_INTERFACE_NAME_FOR_NGU = "demo-oai";
|
||||
GNB_IPV4_ADDRESS_FOR_NGU = "192.168.70.129/24";
|
||||
GNB_PORT_FOR_S1U = 2152; # Spec 2152
|
||||
};
|
||||
}
|
||||
|
||||
@@ -54,4 +54,7 @@ typedef enum { CPtype = 0, UPtype } E1_t;
|
||||
#define NODE_IS_DU(nOdE_TyPe) ((nOdE_TyPe) == ngran_eNB_DU || (nOdE_TyPe) == ngran_gNB_DU)
|
||||
#define NODE_IS_MBMS(nOdE_TyPe) ((nOdE_TyPe) == ngran_eNB_MBMS_STA)
|
||||
#define GTPV1_U_PORT_NUMBER (2152)
|
||||
|
||||
typedef enum { non_dynamic, dynamic } fiveQI_type_t;
|
||||
#define maxSRBs 4
|
||||
#endif
|
||||
|
||||
@@ -49,7 +49,7 @@ static int get_single_ue_rnti(void)
|
||||
return -1;
|
||||
|
||||
// verify it exists in RRC as well
|
||||
rrc_gNB_ue_context_t *rrcue = rrc_gNB_get_ue_context(RC.nrrrc[0], ue->rnti);
|
||||
rrc_gNB_ue_context_t *rrcue = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], ue->rnti);
|
||||
if (!rrcue)
|
||||
return -1;
|
||||
|
||||
@@ -82,7 +82,7 @@ int get_reestab_count(char *buf, int debug, telnet_printfunc_t prnt)
|
||||
ERROR_MSG_RET("RNTI needs to be [1,0xfffe]\n");
|
||||
}
|
||||
|
||||
rrc_gNB_ue_context_t *ue = rrc_gNB_get_ue_context(RC.nrrrc[0], rnti);
|
||||
rrc_gNB_ue_context_t *ue = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], rnti);
|
||||
if (!ue)
|
||||
ERROR_MSG_RET("could not find UE with RNTI %04x\n", rnti);
|
||||
|
||||
@@ -107,7 +107,7 @@ int trigger_reestab(char *buf, int debug, telnet_printfunc_t prnt)
|
||||
}
|
||||
|
||||
// verify it exists in RRC as well
|
||||
rrc_gNB_ue_context_t *rrcue = rrc_gNB_get_ue_context(RC.nrrrc[0], rnti);
|
||||
rrc_gNB_ue_context_t *rrcue = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], rnti);
|
||||
if (!rrcue)
|
||||
ERROR_MSG_RET("could not find UE with RNTI %04x\n", rnti);
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#ifndef E1AP_MESSAGES_TYPES_H
|
||||
#define E1AP_MESSAGES_TYPES_H
|
||||
|
||||
#include "common/ngran_types.h"
|
||||
#include "f1ap_messages_types.h"
|
||||
#include "ngap_messages_types.h"
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
#ifndef NGAP_MESSAGES_TYPES_H_
|
||||
#define NGAP_MESSAGES_TYPES_H_
|
||||
|
||||
#include "common/ngran_types.h"
|
||||
#include "LTE_asn_constant.h"
|
||||
//-------------------------------------------------------------------------------------------//
|
||||
// Defines to access message fields.
|
||||
@@ -49,7 +49,7 @@
|
||||
#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_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_SETUP_FAIL(mSGpTR) (mSGpTR)->ittiMsg.ngap_pdusession_setup_request_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
|
||||
@@ -194,6 +194,13 @@ typedef enum ngap_rrc_establishment_cause_e {
|
||||
NGAP_RRC_CAUSE_LAST
|
||||
} ngap_rrc_establishment_cause_t;
|
||||
|
||||
typedef struct pdusession_level_qos_parameter_s {
|
||||
uint8_t qfi;
|
||||
uint64_t fiveQI;
|
||||
fiveQI_type_t fiveQI_type;
|
||||
ngap_allocation_retention_priority_t allocation_retention_priority;
|
||||
} pdusession_level_qos_parameter_t;
|
||||
|
||||
typedef struct ngap_guami_s {
|
||||
uint16_t mcc;
|
||||
uint16_t mnc;
|
||||
@@ -242,7 +249,7 @@ typedef struct ngap_nas_pdu_s {
|
||||
uint8_t *buffer;
|
||||
/* Length of the octet string */
|
||||
uint32_t length;
|
||||
} ngap_nas_pdu_t, ngap_ue_radio_cap_t;
|
||||
} ngap_pdu_t;
|
||||
|
||||
typedef struct ngap_mobility_restriction_s{
|
||||
ngap_plmn_identity_t serving_plmn;
|
||||
@@ -267,43 +274,22 @@ typedef struct ngap_transport_layer_addr_s {
|
||||
uint8_t buffer[20]; // in network byte order
|
||||
} ngap_transport_layer_addr_t;
|
||||
|
||||
#define TRANSPORT_LAYER_ADDR_COPY(dEST,sOURCE) \
|
||||
do { \
|
||||
AssertFatal(sOURCE.len <= 20); \
|
||||
memcpy(dEST.buffer, sOURCE.buffer, sOURCE.len); \
|
||||
dEST.length = sOURCE.length; \
|
||||
} while (0)
|
||||
|
||||
typedef enum {
|
||||
non_dynamic,
|
||||
dynamic
|
||||
} fiveQI_type_t;
|
||||
|
||||
typedef struct pdusession_level_qos_parameter_s {
|
||||
uint8_t qfi;
|
||||
uint64_t fiveQI;
|
||||
fiveQI_type_t fiveQI_type;
|
||||
ngap_allocation_retention_priority_t allocation_retention_priority;
|
||||
} pdusession_level_qos_parameter_t;
|
||||
|
||||
typedef struct pdusession_s {
|
||||
/* Unique pdusession_id for the UE. */
|
||||
uint8_t pdusession_id;
|
||||
|
||||
uint8_t nb_qos;
|
||||
int pdusession_id;
|
||||
ngap_pdu_t nas_pdu;
|
||||
ngap_pdu_t pdusessionTransfer;
|
||||
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 */
|
||||
ngap_nas_pdu_t nas_pdu;
|
||||
/* The transport layer address for the IP packets */
|
||||
ngap_transport_layer_addr_t upf_addr;
|
||||
ngap_transport_layer_addr_t upf_addr;
|
||||
/* S-GW Tunnel endpoint identifier */
|
||||
uint32_t gtp_teid;
|
||||
uint32_t gtp_teid;
|
||||
/* Stores the DRB ID of the DRBs used by this PDU Session */
|
||||
uint8_t used_drbs[NGAP_MAX_DRBS_PER_UE];
|
||||
uint8_t used_drbs[NGAP_MAX_DRBS_PER_UE];
|
||||
} pdusession_t;
|
||||
|
||||
|
||||
typedef enum pdusession_qosflow_mapping_ind_e{
|
||||
QOSFLOW_MAPPING_INDICATION_UL = 0,
|
||||
QOSFLOW_MAPPING_INDICATION_DL = 1,
|
||||
@@ -313,7 +299,7 @@ typedef enum pdusession_qosflow_mapping_ind_e{
|
||||
typedef struct pdusession_associate_qosflow_s{
|
||||
uint8_t qfi;
|
||||
pdusession_qosflow_mapping_ind_t qos_flow_mapping_ind;
|
||||
}pdusession_associate_qosflow_t;
|
||||
} pdusession_associate_qosflow_t;
|
||||
|
||||
typedef struct pdusession_setup_s {
|
||||
/* Unique pdusession_id for the UE. */
|
||||
@@ -332,36 +318,6 @@ typedef struct pdusession_setup_s {
|
||||
pdusession_associate_qosflow_t associated_qos_flows[QOSFLOW_MAX_VALUE];
|
||||
} pdusession_setup_t;
|
||||
|
||||
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 */
|
||||
ngap_transport_layer_addr_t upf_addr;
|
||||
|
||||
/* S-GW Tunnel endpoint identifier */
|
||||
uint32_t gtp_teid;
|
||||
} pdusession_tobe_added_t;
|
||||
|
||||
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;
|
||||
|
||||
/* The transport layer address for the IP packets */
|
||||
ngap_transport_layer_addr_t gnb_addr;
|
||||
|
||||
/* S-GW Tunnel endpoint identifier */
|
||||
uint32_t gtp_teid;
|
||||
} pdusession_admitted_tobe_added_t;
|
||||
|
||||
|
||||
|
||||
typedef struct pdusession_tobeswitched_s {
|
||||
/* Unique pdusession_id for the UE. */
|
||||
uint8_t pdusession_id;
|
||||
@@ -394,9 +350,12 @@ typedef enum ngap_Cause_e {
|
||||
NGAP_CAUSE_NAS,
|
||||
NGAP_CAUSE_PROTOCOL,
|
||||
NGAP_CAUSE_MISC,
|
||||
/* Extensions may appear below */
|
||||
|
||||
} ngap_Cause_t;
|
||||
NGAP_Cause_PR_choice_ExtensionS,
|
||||
//Evilish manual duplicate of asn.1 grammar
|
||||
//because it is human work, whereas it can be generated by machine
|
||||
//and because humans manual copy creates bugs
|
||||
//and we create multiple names for the same thing, that is a source of confusion
|
||||
} ngap_Cause_t;
|
||||
|
||||
typedef enum ngap_Cause_radio_network_e {
|
||||
NGAP_CAUSE_RADIO_NETWORK_UNSPECIFIED,
|
||||
@@ -453,7 +412,6 @@ 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;
|
||||
} pdusession_failed_t;
|
||||
@@ -541,7 +499,7 @@ typedef struct ngap_deregistered_gnb_ind_s {
|
||||
*/
|
||||
typedef struct ngap_nas_first_req_s {
|
||||
/* UE id for initial connection to NGAP */
|
||||
uint16_t ue_initial_id;
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
|
||||
/* the chosen PLMN identity as index, see TS 36.331 6.2.2 RRC Connection
|
||||
* Setup Complete. This index here is zero-based, unlike the standard! */
|
||||
@@ -551,7 +509,7 @@ typedef struct ngap_nas_first_req_s {
|
||||
ngap_rrc_establishment_cause_t establishment_cause;
|
||||
|
||||
/* NAS PDU */
|
||||
ngap_nas_pdu_t nas_pdu;
|
||||
ngap_pdu_t nas_pdu;
|
||||
|
||||
/* If this flag is set NGAP layer is expecting the GUAMI. If = 0,
|
||||
* the temporary s-tmsi is used.
|
||||
@@ -561,15 +519,14 @@ typedef struct ngap_nas_first_req_s {
|
||||
|
||||
typedef struct ngap_uplink_nas_s {
|
||||
/* Unique UE identifier within an gNB */
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
/* NAS pdu */
|
||||
ngap_nas_pdu_t nas_pdu;
|
||||
ngap_pdu_t nas_pdu;
|
||||
} ngap_uplink_nas_t;
|
||||
|
||||
typedef struct ngap_ue_cap_info_ind_s {
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
ngap_ue_radio_cap_t ue_radio_cap;
|
||||
ngap_pdu_t ue_radio_cap;
|
||||
} ngap_ue_cap_info_ind_t;
|
||||
|
||||
typedef struct ngap_initial_context_setup_resp_s {
|
||||
@@ -594,7 +551,7 @@ typedef struct ngap_initial_context_setup_fail_s {
|
||||
|
||||
typedef struct ngap_nas_non_delivery_ind_s {
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
ngap_nas_pdu_t nas_pdu;
|
||||
ngap_pdu_t nas_pdu;
|
||||
/* TODO: add cause */
|
||||
} ngap_nas_non_delivery_ind_t;
|
||||
|
||||
@@ -621,33 +578,24 @@ typedef struct ngap_ue_ctxt_modification_resp_s {
|
||||
} ngap_ue_ctxt_modification_resp_t;
|
||||
|
||||
typedef struct ngap_ue_release_complete_s {
|
||||
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
|
||||
} ngap_ue_release_complete_t;
|
||||
|
||||
//-------------------------------------------------------------------------------------------//
|
||||
// NGAP -> RRC messages
|
||||
typedef struct ngap_downlink_nas_s {
|
||||
/* UE id for initial connection to NGAP */
|
||||
uint16_t ue_initial_id;
|
||||
|
||||
/* Unique UE identifier within an gNB */
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
/* NAS pdu */
|
||||
ngap_nas_pdu_t nas_pdu;
|
||||
ngap_pdu_t nas_pdu;
|
||||
} ngap_downlink_nas_t;
|
||||
|
||||
|
||||
typedef struct ngap_initial_context_setup_req_s {
|
||||
/* UE id for initial connection to NGAP */
|
||||
uint16_t ue_initial_id;
|
||||
|
||||
/* gNB ue ngap id as initialized by NGAP layer */
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
|
||||
uint64_t amf_ue_ngap_id:40;
|
||||
uint64_t amf_ue_ngap_id;
|
||||
|
||||
/* UE aggregate maximum bitrate */
|
||||
ngap_ambr_t ue_ambr;
|
||||
@@ -676,7 +624,7 @@ typedef struct ngap_initial_context_setup_req_s {
|
||||
|
||||
/* Nas Pdu */
|
||||
uint8_t nas_pdu_flag;
|
||||
ngap_nas_pdu_t nas_pdu;
|
||||
ngap_pdu_t nas_pdu;
|
||||
} ngap_initial_context_setup_req_t;
|
||||
|
||||
|
||||
@@ -702,17 +650,22 @@ typedef struct ngap_paging_ind_s {
|
||||
ngap_paging_priority_t paging_priority;
|
||||
} ngap_paging_ind_t;
|
||||
|
||||
typedef struct {
|
||||
/* Unique pdusession_id for the UE. */
|
||||
int pdusession_id;
|
||||
ngap_pdu_t nas_pdu;
|
||||
ngap_pdu_t pdusessionTransfer;
|
||||
} pdusession_setup_req_t;
|
||||
|
||||
typedef struct ngap_pdusession_setup_req_s {
|
||||
/* UE id for initial connection to NGAP */
|
||||
uint16_t ue_initial_id;
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
|
||||
/* AMF UE id */
|
||||
uint64_t amf_ue_ngap_id:40;
|
||||
|
||||
/* gNB ue ngap id as initialized by NGAP layer */
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
uint64_t amf_ue_ngap_id;
|
||||
|
||||
/* S-NSSAI */
|
||||
// Fixme: illogical, nssai is part of each pdu session
|
||||
ngap_allowed_NSSAI_t allowed_nssai[8];
|
||||
|
||||
/* Number of pdusession to be setup in the list */
|
||||
@@ -730,8 +683,7 @@ typedef struct ngap_pdusession_setup_req_s {
|
||||
} ngap_pdusession_setup_req_t;
|
||||
|
||||
typedef struct ngap_pdusession_setup_resp_s {
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
/* Number of pdusession setup-ed in the list */
|
||||
uint8_t nb_of_pdusessions;
|
||||
/* list of pdusession setup-ed by RRC layers */
|
||||
@@ -744,7 +696,6 @@ typedef struct ngap_pdusession_setup_resp_s {
|
||||
} ngap_pdusession_setup_resp_t;
|
||||
|
||||
typedef struct ngap_path_switch_req_s {
|
||||
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
|
||||
/* Number of pdusession setup-ed in the list */
|
||||
@@ -754,13 +705,12 @@ typedef struct ngap_path_switch_req_s {
|
||||
pdusession_setup_t pdusessions_tobeswitched[NGAP_MAX_PDUSESSION];
|
||||
|
||||
/* AMF UE id */
|
||||
uint64_t amf_ue_ngap_id:40;
|
||||
uint64_t amf_ue_ngap_id;
|
||||
|
||||
ngap_guami_t ue_guami;
|
||||
|
||||
uint16_t ue_initial_id;
|
||||
|
||||
/* Security algorithms */
|
||||
/* Security algorithms */
|
||||
ngap_security_capabilities_t security_capabilities;
|
||||
|
||||
} ngap_path_switch_req_t;
|
||||
@@ -773,7 +723,7 @@ typedef struct ngap_path_switch_req_ack_s {
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
|
||||
/* AMF UE id */
|
||||
uint64_t amf_ue_ngap_id:40;
|
||||
uint64_t amf_ue_ngap_id;
|
||||
|
||||
/* UE aggregate maximum bitrate */
|
||||
ngap_ambr_t ue_ambr;
|
||||
@@ -801,7 +751,7 @@ typedef struct ngap_pdusession_modification_ind_s {
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
|
||||
/* AMF UE id */
|
||||
uint64_t amf_ue_ngap_id:40;
|
||||
uint64_t amf_ue_ngap_id;
|
||||
|
||||
/* Number of pdusession setup-ed in the list */
|
||||
uint8_t nb_of_pdusessions_tobemodified;
|
||||
@@ -830,10 +780,7 @@ typedef struct ngap_ue_release_command_s {
|
||||
typedef struct pdusession_release_s {
|
||||
/* Unique pdusession_id for the UE. */
|
||||
uint8_t pdusession_id;
|
||||
/* Octet string data */
|
||||
uint8_t *transfer_buffer;
|
||||
/* Length of the octet string */
|
||||
uint32_t transfer_length;
|
||||
ngap_pdu_t data;
|
||||
} pdusession_release_t;
|
||||
|
||||
typedef struct ngap_ue_release_req_s {
|
||||
@@ -842,16 +789,13 @@ typedef struct ngap_ue_release_req_s {
|
||||
uint8_t nb_of_pdusessions;
|
||||
/* list of pdusession resource by RRC layers */
|
||||
pdusession_release_t pdusessions[NGAP_MAX_PDUSESSION];
|
||||
ngap_Cause_t cause;
|
||||
ngap_Cause_t cause;
|
||||
long cause_value;
|
||||
} ngap_ue_release_req_t, ngap_ue_release_resp_t;
|
||||
|
||||
typedef struct ngap_pdusession_modify_req_s {
|
||||
/* UE id for initial connection to NGAP */
|
||||
uint16_t ue_initial_id;
|
||||
|
||||
/* AMF UE id */
|
||||
uint64_t amf_ue_ngap_id:40;
|
||||
uint64_t amf_ue_ngap_id;
|
||||
|
||||
/* gNB ue ngap id as initialized by NGAP layer */
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
@@ -879,13 +823,13 @@ typedef struct ngap_pdusession_modify_resp_s {
|
||||
|
||||
typedef struct ngap_pdusession_release_command_s {
|
||||
/* AMF UE id */
|
||||
uint64_t amf_ue_ngap_id:40;
|
||||
uint64_t amf_ue_ngap_id;
|
||||
|
||||
/* gNB ue ngap id as initialized by NGAP layer */
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
|
||||
/* The NAS PDU should be forwarded by the RRC layer to the NAS layer */
|
||||
ngap_nas_pdu_t nas_pdu;
|
||||
ngap_pdu_t nas_pdu;
|
||||
|
||||
/* Number of pdusession to be released in the list */
|
||||
uint8_t nb_pdusessions_torelease;
|
||||
@@ -897,7 +841,7 @@ typedef struct ngap_pdusession_release_command_s {
|
||||
|
||||
typedef struct ngap_pdusession_release_resp_s {
|
||||
/* AMF UE id */
|
||||
uint64_t amf_ue_ngap_id:40;
|
||||
uint64_t amf_ue_ngap_id;
|
||||
|
||||
/* gNB ue ngap id as initialized by NGAP layer */
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
|
||||
@@ -230,8 +230,7 @@ typedef struct protocol_ctxt_s {
|
||||
#define ENB_INSTANCE_TO_MODULE_ID( iNSTANCE )iNSTANCE
|
||||
|
||||
//NR
|
||||
#define GNB_MODULE_ID_TO_INSTANCE( mODULE_iD ) mODULE_iD
|
||||
#define GNB_INSTANCE_TO_MODULE_ID( iNSTANCE )iNSTANCE
|
||||
#define GNB_MODULE_ID_TO_INSTANCE(mODULE_iD) mODULE_iD
|
||||
|
||||
#define MODULE_ID_TO_INSTANCE(mODULE_iD, iNSTANCE, eNB_fLAG) \
|
||||
do { \
|
||||
|
||||
@@ -220,16 +220,15 @@ int e1ap_encode_send(E1_t type, e1ap_setup_req_t *setupReq, E1AP_E1AP_PDU_t *pdu
|
||||
if (encoded < 0) {
|
||||
LOG_E(E1AP, "%s: Failed to encode E1AP message\n", func);
|
||||
return -1;
|
||||
} else {
|
||||
MessageDef *message = itti_alloc_new_message((type==CPtype)?TASK_CUCP_E1:TASK_CUUP_E1, 0, SCTP_DATA_REQ);
|
||||
sctp_data_req_t *s = &message->ittiMsg.sctp_data_req;
|
||||
s->assoc_id = setupReq->assoc_id;
|
||||
s->buffer = buffer;
|
||||
s->buffer_length = encoded;
|
||||
s->stream = stream;
|
||||
LOG_I(E1AP, "%s: Sending ITTI message to SCTP Task\n", func);
|
||||
itti_send_msg_to_task(TASK_SCTP, 0 /*unused by callee*/, message);
|
||||
}
|
||||
MessageDef *message = itti_alloc_new_message((type == CPtype) ? TASK_CUCP_E1 : TASK_CUUP_E1, 0, SCTP_DATA_REQ);
|
||||
sctp_data_req_t *s = &message->ittiMsg.sctp_data_req;
|
||||
s->assoc_id = setupReq->assoc_id;
|
||||
s->buffer = buffer;
|
||||
s->buffer_length = encoded;
|
||||
s->stream = stream;
|
||||
LOG_I(E1AP, "%s: Sending ITTI message to SCTP Task\n", func);
|
||||
itti_send_msg_to_task(TASK_SCTP, 0 /*unused by callee*/, message);
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ static void cu_task_handle_sctp_association_ind(instance_t instance, sctp_new_as
|
||||
f1ap_cu_data->sctp_in_streams = sctp_new_association_ind->in_streams;
|
||||
f1ap_cu_data->sctp_out_streams = sctp_new_association_ind->out_streams;
|
||||
f1ap_cu_data->default_sctp_stream_id = 0;
|
||||
if (RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)]->node_type != ngran_gNB_CUCP) {
|
||||
if (RC.nrrrc[instance]->node_type != ngran_gNB_CUCP) {
|
||||
getCxt(CUtype, instance)->gtpInst = cu_task_create_gtpu_instance(IPaddrs);
|
||||
AssertFatal(getCxt(CUtype, instance)->gtpInst > 0, "Failed to create CU F1-U UDP listener");
|
||||
} else
|
||||
|
||||
@@ -947,13 +947,13 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance,
|
||||
protocol_ctxt_t ctxt;
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, instance, GNB_FLAG_YES, rnti, 0, 0, instance);
|
||||
|
||||
struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], rnti);
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[instance], rnti);
|
||||
|
||||
if (ue_context_p) {
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_CU_F1, 0, NGAP_UE_CONTEXT_RELEASE_COMPLETE);
|
||||
NGAP_UE_CONTEXT_RELEASE_COMPLETE(msg).gNB_ue_ngap_id = ue_context_p->ue_context.gNB_ue_ngap_id;
|
||||
itti_send_msg_to_task(TASK_NGAP, instance, msg);
|
||||
rrc_gNB_remove_ue_context(&ctxt, RC.nrrrc[instance], ue_context_p);
|
||||
rrc_gNB_remove_ue_context(RC.nrrrc[instance], ue_context_p);
|
||||
} else {
|
||||
LOG_E(F1AP, "could not find ue_context of UE RNTI %x\n", rnti);
|
||||
}
|
||||
@@ -1600,7 +1600,7 @@ int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance,
|
||||
F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
|
||||
f1ap_ue_context_modification_resp->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
|
||||
|
||||
LOG_D(F1AP, "f1ap_ue_context_setup_resp->gNB_DU_ue_id is: %d \n", f1ap_ue_context_modification_resp->gNB_DU_ue_id);
|
||||
LOG_D(F1AP, "f1ap_ue_context_modification_resp->gNB_DU_ue_id is: %d \n", f1ap_ue_context_modification_resp->gNB_DU_ue_id);
|
||||
|
||||
f1ap_ue_context_modification_resp->rnti =
|
||||
f1ap_get_rnti_by_du_id(CUtype, instance, f1ap_ue_context_modification_resp->gNB_DU_ue_id);
|
||||
|
||||
@@ -31,7 +31,7 @@ void f1ap_itti_send_sctp_data_req(bool isCu, instance_t instance, uint8_t *buffe
|
||||
sctp_data_req->assoc_id = f1ap_assoc_id(isCu,instance);
|
||||
sctp_data_req->buffer = buffer;
|
||||
sctp_data_req->buffer_length = buffer_length;
|
||||
sctp_data_req->stream = stream;
|
||||
sctp_data_req->stream = stream;
|
||||
LOG_D(F1AP, "Sending ITTI message to SCTP Task\n");
|
||||
itti_send_msg_to_task(TASK_SCTP, instance, message_p);
|
||||
}
|
||||
|
||||
@@ -2810,10 +2810,12 @@ void nr_mac_update_timers(module_id_t module_id,
|
||||
|
||||
NR_CellGroupConfig_t *cg = NULL;
|
||||
uper_decode(NULL,
|
||||
&asn_DEF_NR_CellGroupConfig, //might be added prefix later
|
||||
&asn_DEF_NR_CellGroupConfig, // might be added prefix later
|
||||
(void **)&cg,
|
||||
(uint8_t *)UE->cg_buf,
|
||||
(UE->enc_rval.encoded+7)/8, 0, 0);
|
||||
(UE->enc_rval.encoded + 7) / 8,
|
||||
0,
|
||||
0);
|
||||
UE->CellGroup = cg;
|
||||
|
||||
if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
|
||||
@@ -2918,13 +2920,8 @@ void send_initial_ul_rrc_message(module_id_t module_id,
|
||||
sdu_len, rnti);
|
||||
|
||||
/* TODO REMOVE_DU_RRC: the RRC in the DU is a hack and should be taken out in the future */
|
||||
if (NODE_IS_DU(RC.nrrrc[module_id]->node_type)) {
|
||||
struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_allocate_new_UE_context(RC.nrrrc[module_id]);
|
||||
ue_context_p->ue_id_rnti = rnti;
|
||||
ue_context_p->ue_context.rnti = rnti;
|
||||
ue_context_p->ue_context.random_ue_identity = rnti;
|
||||
RB_INSERT(rrc_nr_ue_tree_s, &RC.nrrrc[module_id]->rrc_ue_head, ue_context_p);
|
||||
}
|
||||
if (NODE_IS_DU(RC.nrrrc[module_id]->node_type))
|
||||
rrc_gNB_create_ue_context(rnti, RC.nrrrc[module_id], rnti);
|
||||
|
||||
const NR_ServingCellConfigCommon_t *scc = RC.nrrrc[module_id]->carrier.servingcellconfigcommon;
|
||||
const NR_ServingCellConfig_t *sccd = RC.nrrrc[module_id]->configuration.scd;
|
||||
|
||||
@@ -106,7 +106,7 @@ int dl_rrc_message_rrcSetup(module_id_t module_id, const f1ap_dl_rrc_message_t *
|
||||
|
||||
/* TODO: drop the RRC context */
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[module_id];
|
||||
struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(rrc, dl_rrc->rnti);
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, dl_rrc->rnti);
|
||||
gNB_RRC_UE_t *ue_p = &ue_context_p->ue_context;
|
||||
ue_p->SRB_configList = rrcSetup_ies->radioBearerConfig.srb_ToAddModList;
|
||||
ue_p->masterCellGroup = cellGroup;
|
||||
|
||||
@@ -162,8 +162,7 @@ int8_t nr_mac_rrc_bwp_switch_req(const module_id_t module_idP,
|
||||
const rnti_t rntiP,
|
||||
const int dl_bwp_id,
|
||||
const int ul_bwp_id) {
|
||||
|
||||
struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[module_idP], rntiP);
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[module_idP], rntiP);
|
||||
|
||||
protocol_ctxt_t ctxt;
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, GNB_FLAG_YES, rntiP, frameP, sub_frameP, 0);
|
||||
@@ -177,10 +176,7 @@ void nr_mac_gNB_rrc_ul_failure(const module_id_t Mod_instP,
|
||||
const frame_t frameP,
|
||||
const sub_frame_t subframeP,
|
||||
const rnti_t rntiP) {
|
||||
struct rrc_gNB_ue_context_s *ue_context_p = NULL;
|
||||
ue_context_p = rrc_gNB_get_ue_context(
|
||||
RC.nrrrc[Mod_instP],
|
||||
rntiP);
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[Mod_instP], rntiP);
|
||||
|
||||
if (ue_context_p != NULL) {
|
||||
LOG_D(RRC,"Frame %d, Subframe %d: UE %x UL failure, activating timer\n",frameP,subframeP,rntiP);
|
||||
@@ -195,8 +191,7 @@ void nr_mac_gNB_rrc_ul_failure_reset(const module_id_t Mod_instP,
|
||||
const frame_t frameP,
|
||||
const sub_frame_t subframeP,
|
||||
const rnti_t rntiP) {
|
||||
struct rrc_gNB_ue_context_s *ue_context_p = NULL;
|
||||
ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[Mod_instP], rntiP);
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[Mod_instP], rntiP);
|
||||
if (ue_context_p != NULL) {
|
||||
LOG_W(RRC,"Frame %d, Subframe %d: UE %x UL failure reset, deactivating timer\n",frameP,subframeP,rntiP);
|
||||
ue_context_p->ue_context.ul_failure_timer=0;
|
||||
|
||||
@@ -1298,27 +1298,24 @@ uint8_t do_NR_SecurityModeCommand(
|
||||
uint8_t *const buffer,
|
||||
const uint8_t Transaction_id,
|
||||
const uint8_t cipheringAlgorithm,
|
||||
NR_IntegrityProtAlgorithm_t *integrityProtAlgorithm
|
||||
NR_IntegrityProtAlgorithm_t integrityProtAlgorithm
|
||||
)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
NR_DL_DCCH_Message_t dl_dcch_msg;
|
||||
NR_DL_DCCH_Message_t dl_dcch_msg={0};
|
||||
asn_enc_rval_t enc_rval;
|
||||
memset(&dl_dcch_msg,0,sizeof(NR_DL_DCCH_Message_t));
|
||||
dl_dcch_msg.message.present = NR_DL_DCCH_MessageType_PR_c1;
|
||||
dl_dcch_msg.message.choice.c1=CALLOC(1,sizeof(struct NR_DL_DCCH_MessageType__c1));
|
||||
dl_dcch_msg.message.choice.c1->present = NR_DL_DCCH_MessageType__c1_PR_securityModeCommand;
|
||||
dl_dcch_msg.message.choice.c1->choice.securityModeCommand = CALLOC(1, sizeof(struct NR_SecurityModeCommand));
|
||||
dl_dcch_msg.message.choice.c1->choice.securityModeCommand->rrc_TransactionIdentifier = Transaction_id;
|
||||
dl_dcch_msg.message.choice.c1->choice.securityModeCommand->criticalExtensions.present = NR_SecurityModeCommand__criticalExtensions_PR_securityModeCommand;
|
||||
asn1cCalloc(dl_dcch_msg.message.choice.c1, c1);
|
||||
c1->present = NR_DL_DCCH_MessageType__c1_PR_securityModeCommand;
|
||||
asn1cCalloc(c1->choice.securityModeCommand,scm);
|
||||
scm->rrc_TransactionIdentifier = Transaction_id;
|
||||
scm->criticalExtensions.present = NR_SecurityModeCommand__criticalExtensions_PR_securityModeCommand;
|
||||
|
||||
dl_dcch_msg.message.choice.c1->choice.securityModeCommand->criticalExtensions.choice.securityModeCommand =
|
||||
CALLOC(1, sizeof(struct NR_SecurityModeCommand_IEs));
|
||||
asn1cCalloc(scm->criticalExtensions.choice.securityModeCommand,scmIE);
|
||||
// the two following information could be based on the mod_id
|
||||
dl_dcch_msg.message.choice.c1->choice.securityModeCommand->criticalExtensions.choice.securityModeCommand->securityConfigSMC.securityAlgorithmConfig.cipheringAlgorithm
|
||||
scmIE->securityConfigSMC.securityAlgorithmConfig.cipheringAlgorithm
|
||||
= (NR_CipheringAlgorithm_t)cipheringAlgorithm;
|
||||
dl_dcch_msg.message.choice.c1->choice.securityModeCommand->criticalExtensions.choice.securityModeCommand->securityConfigSMC.securityAlgorithmConfig.integrityProtAlgorithm
|
||||
= integrityProtAlgorithm;
|
||||
asn1cCallocOne(scmIE->securityConfigSMC.securityAlgorithmConfig.integrityProtAlgorithm, integrityProtAlgorithm);
|
||||
|
||||
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
|
||||
xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message, (void *)&dl_dcch_msg);
|
||||
@@ -1332,7 +1329,7 @@ uint8_t do_NR_SecurityModeCommand(
|
||||
|
||||
AssertFatal(enc_rval.encoded >0 , "ASN1 message encoding failed (%s, %lu)!\n",
|
||||
enc_rval.failed_type->name, enc_rval.encoded);
|
||||
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NR_DL_DCCH_Message,&dl_dcch_msg);
|
||||
LOG_D(NR_RRC, "[gNB %d] securityModeCommand for UE %lx Encoded %zd bits (%zd bytes)\n", ctxt_pP->module_id, ctxt_pP->rntiMaybeUEid, enc_rval.encoded, (enc_rval.encoded + 7) / 8);
|
||||
|
||||
// rrc_ue_process_ueCapabilityEnquiry(0,1000,&dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry,0);
|
||||
@@ -1521,10 +1518,7 @@ int16_t do_RRCReconfiguration(
|
||||
}
|
||||
|
||||
if(cellGroupConfig!=NULL){
|
||||
update_cellGroupConfig(cellGroupConfig,
|
||||
ue_context_pP->local_uid,
|
||||
ue_context_pP ? ue_context_pP->ue_context.UE_Capability_nr : NULL,
|
||||
configuration);
|
||||
update_cellGroupConfig(cellGroupConfig, ue_context_pP->ue_context.gNB_ue_ngap_id, ue_context_pP ? ue_context_pP->ue_context.UE_Capability_nr : NULL, configuration);
|
||||
|
||||
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig,
|
||||
NULL,
|
||||
@@ -1754,29 +1748,27 @@ do_NR_DLInformationTransfer(
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
ssize_t encoded;
|
||||
NR_DL_DCCH_Message_t dl_dcch_msg;
|
||||
memset(&dl_dcch_msg, 0, sizeof(NR_DL_DCCH_Message_t));
|
||||
NR_DL_DCCH_Message_t dl_dcch_msg={0};
|
||||
dl_dcch_msg.message.present = NR_DL_DCCH_MessageType_PR_c1;
|
||||
dl_dcch_msg.message.choice.c1 = CALLOC(1, sizeof(struct NR_DL_DCCH_MessageType__c1));
|
||||
dl_dcch_msg.message.choice.c1->present = NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer;
|
||||
asn1cCalloc(dl_dcch_msg.message.choice.c1, c1);
|
||||
c1->present = NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer;
|
||||
|
||||
dl_dcch_msg.message.choice.c1->choice.dlInformationTransfer = CALLOC(1, sizeof(NR_DLInformationTransfer_t));
|
||||
dl_dcch_msg.message.choice.c1->choice.dlInformationTransfer->rrc_TransactionIdentifier = transaction_id;
|
||||
dl_dcch_msg.message.choice.c1->choice.dlInformationTransfer->criticalExtensions.present =
|
||||
asn1cCalloc(c1->choice.dlInformationTransfer, infoTransfer);
|
||||
infoTransfer->rrc_TransactionIdentifier = transaction_id;
|
||||
infoTransfer->criticalExtensions.present =
|
||||
NR_DLInformationTransfer__criticalExtensions_PR_dlInformationTransfer;
|
||||
|
||||
dl_dcch_msg.message.choice.c1->choice.dlInformationTransfer->
|
||||
criticalExtensions.choice.dlInformationTransfer = CALLOC(1, sizeof(NR_DLInformationTransfer_IEs_t));
|
||||
dl_dcch_msg.message.choice.c1->choice.dlInformationTransfer->
|
||||
criticalExtensions.choice.dlInformationTransfer->dedicatedNAS_Message = CALLOC(1, sizeof(NR_DedicatedNAS_Message_t));
|
||||
dl_dcch_msg.message.choice.c1->choice.dlInformationTransfer->
|
||||
criticalExtensions.choice.dlInformationTransfer->dedicatedNAS_Message->buf = pdu_buffer;
|
||||
dl_dcch_msg.message.choice.c1->choice.dlInformationTransfer->
|
||||
criticalExtensions.choice.dlInformationTransfer->dedicatedNAS_Message->size = pdu_length;
|
||||
asn1cCalloc(infoTransfer->criticalExtensions.choice.dlInformationTransfer, dlInfoTransfer);
|
||||
asn1cCalloc(dlInfoTransfer->dedicatedNAS_Message,msg);
|
||||
// we will free the caller buffer, that is ok in the present code logic (else it will leak memory) but not natural,
|
||||
// comprehensive code design
|
||||
msg->buf = pdu_buffer;
|
||||
msg->size = pdu_length;
|
||||
|
||||
encoded = uper_encode_to_new_buffer (&asn_DEF_NR_DL_DCCH_Message, NULL, (void *) &dl_dcch_msg, (void **)buffer);
|
||||
AssertFatal(encoded > 0,"ASN1 message encoding failed (%s, %ld)!\n",
|
||||
"DLInformationTransfer", encoded);
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NR_DL_DCCH_Message,&dl_dcch_msg );
|
||||
LOG_D(NR_RRC,"DLInformationTransfer Encoded %zd bytes\n", encoded);
|
||||
//for (int i=0;i<encoded;i++) printf("%02x ",(*buffer)[i]);
|
||||
return encoded;
|
||||
|
||||
@@ -113,7 +113,7 @@ uint8_t do_NR_SecurityModeCommand(
|
||||
uint8_t *const buffer,
|
||||
const uint8_t Transaction_id,
|
||||
const uint8_t cipheringAlgorithm,
|
||||
NR_IntegrityProtAlgorithm_t *integrityProtAlgorithm);
|
||||
NR_IntegrityProtAlgorithm_t integrityProtAlgorithm);
|
||||
|
||||
uint8_t do_NR_SA_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP,
|
||||
uint8_t *const buffer,
|
||||
|
||||
@@ -107,18 +107,19 @@ static int drb_config_gtpu_create(const protocol_ctxt_t *const ctxt_p,
|
||||
|
||||
gtpv1u_gnb_create_tunnel_req_t create_tunnel_req={0};
|
||||
gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp={0};
|
||||
|
||||
int i = ue_context_p->ue_context.nb_of_pdusessions - 1;
|
||||
pdu_session_param_t *pdu = ue_context_p->ue_context.pduSession + i;
|
||||
create_tunnel_req.pdusession_id[0] = pdu->param.pdusession_id;
|
||||
create_tunnel_req.incoming_rb_id[0] = i + 1;
|
||||
create_tunnel_req.outgoing_qfi[0] = req->pduSession[i].DRBnGRanList[0].qosFlows[0].id;
|
||||
memcpy(&create_tunnel_req.dst_addr[0].buffer, &pdu->param.upf_addr.buffer, sizeof(create_tunnel_req.dst_addr[0].buffer));
|
||||
create_tunnel_req.dst_addr[0].length = pdu->param.upf_addr.length;
|
||||
create_tunnel_req.outgoing_teid[0] = pdu->param.gtp_teid;
|
||||
|
||||
create_tunnel_req.num_tunnels = 1;
|
||||
create_tunnel_req.ue_id = ue_context_p->ue_context.rnti;
|
||||
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
|
||||
LOG_W(NR_RRC, "recreate existing tunnels, while adding new ones\n");
|
||||
for (int i = 0; i < UE->nb_of_pdusessions; i++) {
|
||||
rrc_pdu_session_param_t *pdu = UE->pduSession + i;
|
||||
create_tunnel_req.pdusession_id[i] = pdu->param.pdusession_id;
|
||||
create_tunnel_req.incoming_rb_id[i] = i + 1;
|
||||
create_tunnel_req.outgoing_qfi[i] = req->pduSession[i].DRBnGRanList[0].qosFlows[0].id;
|
||||
memcpy(&create_tunnel_req.dst_addr[i].buffer, &pdu->param.upf_addr.buffer, sizeof(create_tunnel_req.dst_addr[0].buffer));
|
||||
create_tunnel_req.dst_addr[i].length = pdu->param.upf_addr.length;
|
||||
create_tunnel_req.outgoing_teid[i] = pdu->param.gtp_teid;
|
||||
}
|
||||
create_tunnel_req.num_tunnels = UE->nb_of_pdusessions;
|
||||
create_tunnel_req.ue_id = UE->rnti;
|
||||
int ret = gtpv1u_create_ngu_tunnel(getCxtE1(instance)->gtpInstN3, &create_tunnel_req, &create_tunnel_resp);
|
||||
|
||||
if (ret != 0) {
|
||||
@@ -127,7 +128,7 @@ static int drb_config_gtpu_create(const protocol_ctxt_t *const ctxt_p,
|
||||
return ret;
|
||||
}
|
||||
|
||||
nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(ctxt_p, &create_tunnel_resp, i);
|
||||
nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(ctxt_p, &create_tunnel_resp, 0);
|
||||
|
||||
uint8_t *kRRCenc = NULL;
|
||||
uint8_t *kRRCint = NULL;
|
||||
@@ -135,39 +136,27 @@ static int drb_config_gtpu_create(const protocol_ctxt_t *const ctxt_p,
|
||||
uint8_t *kUPint = NULL;
|
||||
/* Derive the keys from kgnb */
|
||||
if (DRB_configList != NULL) {
|
||||
nr_derive_key_up_enc(ue_context_p->ue_context.ciphering_algorithm,
|
||||
ue_context_p->ue_context.kgnb,
|
||||
&kUPenc);
|
||||
nr_derive_key_up_int(ue_context_p->ue_context.integrity_algorithm,
|
||||
ue_context_p->ue_context.kgnb,
|
||||
&kUPint);
|
||||
nr_derive_key_up_enc(UE->ciphering_algorithm, UE->kgnb, &kUPenc);
|
||||
nr_derive_key_up_int(UE->integrity_algorithm, UE->kgnb, &kUPint);
|
||||
}
|
||||
|
||||
nr_derive_key_rrc_enc(ue_context_p->ue_context.ciphering_algorithm,
|
||||
ue_context_p->ue_context.kgnb,
|
||||
&kRRCenc);
|
||||
nr_derive_key_rrc_int(ue_context_p->ue_context.integrity_algorithm,
|
||||
ue_context_p->ue_context.kgnb,
|
||||
&kRRCint);
|
||||
nr_derive_key_rrc_enc(UE->ciphering_algorithm, UE->kgnb, &kRRCenc);
|
||||
nr_derive_key_rrc_int(UE->integrity_algorithm, UE->kgnb, &kRRCint);
|
||||
/* Refresh SRBs/DRBs */
|
||||
|
||||
LOG_D(NR_RRC,"Configuring PDCP DRBs/SRBs for UE %x\n",ue_context_p->ue_context.rnti);
|
||||
LOG_D(NR_RRC, "Configuring PDCP DRBs/SRBs for UE %x\n", UE->rnti);
|
||||
|
||||
nr_pdcp_add_srbs(ctxt_p->enb_flag, ctxt_p->rntiMaybeUEid,
|
||||
SRB_configList,
|
||||
(ue_context_p->ue_context.integrity_algorithm << 4)
|
||||
| ue_context_p->ue_context.ciphering_algorithm,
|
||||
kRRCenc,
|
||||
kRRCint);
|
||||
|
||||
nr_pdcp_add_drbs(ctxt_p->enb_flag, ctxt_p->rntiMaybeUEid, 0,
|
||||
nr_pdcp_add_srbs(ctxt_p->enb_flag, ctxt_p->rntiMaybeUEid, SRB_configList, (UE->integrity_algorithm << 4) | UE->ciphering_algorithm, kRRCenc, kRRCint);
|
||||
|
||||
nr_pdcp_add_drbs(ctxt_p->enb_flag,
|
||||
ctxt_p->rntiMaybeUEid,
|
||||
0,
|
||||
DRB_configList,
|
||||
(ue_context_p->ue_context.integrity_algorithm << 4)
|
||||
| ue_context_p->ue_context.ciphering_algorithm,
|
||||
(UE->integrity_algorithm << 4) | UE->ciphering_algorithm,
|
||||
kUPenc,
|
||||
kUPint,
|
||||
get_softmodem_params()->sa ? ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL);
|
||||
|
||||
get_softmodem_params()->sa ? UE->masterCellGroup->rlc_BearerToAddModList : NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -187,17 +176,18 @@ static NR_SRB_ToAddModList_t **generateSRB2_confList(gNB_RRC_UE_t *ue, NR_SRB_To
|
||||
return SRB_configList2;
|
||||
}
|
||||
static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const req, instance_t instance) {
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)], req->rnti);
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[instance], req->rnti);
|
||||
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
|
||||
protocol_ctxt_t ctxt = {0};
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, 0);
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, UE->rnti, 0, 0, 0);
|
||||
|
||||
fill_DRB_configList(&ctxt, ue_context_p);
|
||||
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
|
||||
// Fixme: xid not random, but almost!
|
||||
NR_SRB_ToAddModList_t **SRB_configList2 = generateSRB2_confList(&ue_context_p->ue_context, ue_context_p->ue_context.SRB_configList, ue_context_p->ue_context.pduSession[0].xid);
|
||||
NR_SRB_ToAddModList_t **SRB_configList2 = generateSRB2_confList(UE, UE->SRB_configList, UE->pduSession[0].xid);
|
||||
// GTP tunnel for UL
|
||||
int ret = drb_config_gtpu_create(&ctxt, ue_context_p, req, ue_context_p->ue_context.DRB_configList, *SRB_configList2, rrc->e1_inst);
|
||||
int ret = drb_config_gtpu_create(&ctxt, ue_context_p, req, UE->DRB_configList, *SRB_configList2, rrc->e1_inst);
|
||||
if (ret < 0) AssertFatal(false, "Unable to configure DRB or to create GTP Tunnel\n");
|
||||
|
||||
if(!NODE_IS_CU(RC.nrrrc[ctxt.module_id]->node_type)) {
|
||||
@@ -208,7 +198,7 @@ static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const
|
||||
in_addr_t my_addr = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.my_addr);
|
||||
instance_t gtpInst = getCxt(CUtype, instance)->gtpInst;
|
||||
// GTP tunnel for DL
|
||||
fill_e1ap_bearer_setup_resp(&resp, req, gtpInst, ue_context_p->ue_context.rnti, remote_port, my_addr);
|
||||
fill_e1ap_bearer_setup_resp(&resp, req, gtpInst, UE->rnti, remote_port, my_addr);
|
||||
|
||||
prepare_and_send_ue_context_modification_f1(ue_context_p, &resp);
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
extern RAN_CONTEXT_t RC;
|
||||
|
||||
static void cucp_cuup_bearer_context_setup_e1ap(e1ap_bearer_setup_req_t *const req, instance_t instance) {
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)], req->rnti);
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[instance], req->rnti);
|
||||
protocol_ctxt_t ctxt = {0};
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, 0);
|
||||
|
||||
|
||||
@@ -269,7 +269,7 @@ typedef struct pdu_session_param_s {
|
||||
uint8_t xid; // transaction_id
|
||||
ngap_Cause_t cause;
|
||||
uint8_t cause_value;
|
||||
} __attribute__ ((__packed__)) pdu_session_param_t;
|
||||
} rrc_pdu_session_param_t;
|
||||
|
||||
typedef struct gNB_RRC_UE_s {
|
||||
uint8_t primaryCC_id;
|
||||
@@ -281,8 +281,7 @@ typedef struct gNB_RRC_UE_s {
|
||||
uint8_t DRB_active[NGAP_MAX_DRBS_PER_UE];
|
||||
|
||||
NR_SRB_INFO SI;
|
||||
NR_SRB_INFO_TABLE_ENTRY Srb1;
|
||||
NR_SRB_INFO_TABLE_ENTRY Srb2;
|
||||
NR_SRB_INFO_TABLE_ENTRY Srb[maxSRBs]; // 3gpp max is 3 SRBs, number 1..3, we waste the entry 0 for code simplicity
|
||||
NR_MeasConfig_t *measConfig;
|
||||
NR_HANDOVER_INFO *handover_info;
|
||||
NR_MeasResults_t *measResults;
|
||||
@@ -332,7 +331,7 @@ typedef struct gNB_RRC_UE_s {
|
||||
/* Information from S1AP initial_context_setup_req */
|
||||
uint32_t gNB_ue_s1ap_id :24;
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
uint64_t amf_ue_ngap_id:40;
|
||||
uint64_t amf_ue_ngap_id;
|
||||
nr_rrc_guami_t ue_guami;
|
||||
|
||||
ngap_security_capabilities_t security_capabilities;
|
||||
@@ -350,11 +349,11 @@ typedef struct gNB_RRC_UE_s {
|
||||
/* Number of e_rab to be modified in the list */
|
||||
uint8_t nb_of_modify_pdusessions;
|
||||
uint8_t nb_of_failed_pdusessions;
|
||||
pdu_session_param_t modify_pdusession[NR_NB_RB_MAX];
|
||||
rrc_pdu_session_param_t modify_pdusession[NR_NB_RB_MAX];
|
||||
/* list of e_rab to be setup by RRC layers */
|
||||
/* list of pdu session to be setup by RRC layers */
|
||||
nr_e_rab_param_t e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB];
|
||||
pdu_session_param_t pduSession[NGAP_MAX_PDU_SESSION];
|
||||
rrc_pdu_session_param_t pduSession[NGAP_MAX_PDU_SESSION];
|
||||
//release e_rabs
|
||||
uint8_t nb_release_of_e_rabs;
|
||||
e_rab_failed_t e_rabs_release_failed[S1AP_MAX_E_RAB];
|
||||
@@ -396,23 +395,13 @@ typedef struct gNB_RRC_UE_s {
|
||||
struct NR_PhysicalCellGroupConfig *physicalCellGroupConfig;
|
||||
|
||||
/* Nas Pdu */
|
||||
uint8_t nas_pdu_flag;
|
||||
ngap_nas_pdu_t nas_pdu;
|
||||
ngap_pdu_t nas_pdu;
|
||||
|
||||
} gNB_RRC_UE_t;
|
||||
|
||||
typedef struct rrc_gNB_ue_context_s {
|
||||
/* Tree related data */
|
||||
RB_ENTRY(rrc_gNB_ue_context_s) entries;
|
||||
|
||||
/* Uniquely identifies the UE between MME and eNB within the eNB.
|
||||
* This id is encoded on 24bits.
|
||||
*/
|
||||
ue_id_t ue_id_rnti;
|
||||
|
||||
// another key for protocol layers but should not be used as a key for RB tree
|
||||
uid_t local_uid;
|
||||
|
||||
/* UE id for initial connection to NGAP */
|
||||
struct gNB_RRC_UE_s ue_context;
|
||||
} rrc_gNB_ue_context_t;
|
||||
@@ -492,13 +481,7 @@ typedef struct gNB_RRC_INST_s {
|
||||
eth_params_t eth_params_s;
|
||||
rrc_gNB_carrier_data_t carrier;
|
||||
uid_allocator_t uid_allocator;
|
||||
RB_HEAD(rrc_nr_ue_tree_s, rrc_gNB_ue_context_s) rrc_ue_head; // ue_context tree key search by rnti
|
||||
int Nb_ue;
|
||||
hash_table_t *initial_id2_s1ap_ids; // key is content is rrc_ue_s1ap_ids_t
|
||||
hash_table_t *s1ap_id2_s1ap_ids ; // key is content is rrc_ue_s1ap_ids_t
|
||||
hash_table_t *initial_id2_ngap_ids;
|
||||
hash_table_t *ngap_id2_ngap_ids ;
|
||||
|
||||
RB_HEAD(rrc_nr_ue_tree_s, rrc_gNB_ue_context_s) rrc_ue_head; // ue_context tree key search by rnti
|
||||
/// NR cell id
|
||||
uint64_t nr_cellid;
|
||||
|
||||
|
||||
@@ -64,11 +64,11 @@ void rrc_gNB_generate_SgNBAdditionRequestAcknowledge(
|
||||
rrc_gNB_ue_context_t *const ue_context_pP
|
||||
);
|
||||
|
||||
struct rrc_gNB_ue_context_s *rrc_gNB_allocate_new_UE_context(gNB_RRC_INST *rrc_instance_pP);
|
||||
rrc_gNB_ue_context_t *rrc_gNB_allocate_new_UE_context(gNB_RRC_INST *rrc_instance_pP);
|
||||
|
||||
void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc,NR_UE_CapabilityRAT_ContainerList_t *UE_CapabilityRAT_ContainerList, x2ap_ENDC_sgnb_addition_req_t *m, NR_CG_ConfigInfo_IEs_t * cg_config_info);
|
||||
|
||||
void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_p, x2ap_ENDC_sgnb_addition_req_t *m);
|
||||
void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2ap_ENDC_sgnb_addition_req_t *m);
|
||||
|
||||
void rrc_remove_nsa_user(gNB_RRC_INST *rrc, int rnti);
|
||||
|
||||
@@ -163,12 +163,6 @@ int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP
|
||||
const int dl_bwp_id,
|
||||
const int ul_bwp_id);
|
||||
|
||||
int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP,
|
||||
const uint8_t *buffer,
|
||||
int buffer_length,
|
||||
const uint8_t *du_to_cu_rrc_container,
|
||||
int du_to_cu_rrc_container_length);
|
||||
|
||||
void
|
||||
rrc_gNB_generate_dedicatedRRCReconfiguration_release(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
@@ -217,9 +211,5 @@ void nr_pdcp_add_drbs(eNB_flag_t enb_flag,
|
||||
uint8_t *const kUPint,
|
||||
struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list);
|
||||
|
||||
int rrc_gNB_generate_pcch_msg(uint32_t tmsi,
|
||||
uint8_t paging_drx,
|
||||
instance_t instance,
|
||||
uint8_t CC_id);
|
||||
|
||||
int rrc_gNB_generate_pcch_msg(uint32_t tmsi, uint8_t paging_drx, instance_t instance, uint8_t CC_id);
|
||||
#endif
|
||||
|
||||
+699
-951
File diff suppressed because it is too large
Load Diff
@@ -44,68 +44,64 @@
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
|
||||
int
|
||||
rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP,
|
||||
uint8_t *inde_list
|
||||
) {
|
||||
int i;
|
||||
struct rrc_gNB_ue_context_s *ue_context_p = NULL;
|
||||
|
||||
if (create_tunnel_resp_pP) {
|
||||
LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" RX CREATE_TUNNEL_RESP num tunnels %u \n",
|
||||
PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
|
||||
create_tunnel_resp_pP->num_tunnels);
|
||||
ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rntiMaybeUEid);
|
||||
|
||||
for (i = 0; i < create_tunnel_resp_pP->num_tunnels; i++) {
|
||||
ue_context_p->ue_context.gnb_gtp_teid[inde_list[i]] = create_tunnel_resp_pP->enb_S1u_teid[i];
|
||||
ue_context_p->ue_context.gnb_gtp_addrs[inde_list[i]] = create_tunnel_resp_pP->enb_addr;
|
||||
ue_context_p->ue_context.gnb_gtp_ebi[inde_list[i]] = create_tunnel_resp_pP->eps_bearer_id[i];
|
||||
LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP tunnel (%u, %u) bearer UE context index %u, msg index %u, id %u, gtp addr len %d \n",
|
||||
PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
|
||||
create_tunnel_resp_pP->enb_S1u_teid[i],
|
||||
ue_context_p->ue_context.gnb_gtp_teid[inde_list[i]],
|
||||
inde_list[i],
|
||||
i,
|
||||
create_tunnel_resp_pP->eps_bearer_id[i],
|
||||
create_tunnel_resp_pP->enb_addr.length);
|
||||
}
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
int rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(const protocol_ctxt_t *const ctxt_pP, const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP, uint8_t *inde_list)
|
||||
{
|
||||
if (!create_tunnel_resp_pP) {
|
||||
LOG_E(NR_RRC, "create_tunnel_resp_pP error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT " RX CREATE_TUNNEL_RESP num tunnels %u \n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), create_tunnel_resp_pP->num_tunnels);
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rntiMaybeUEid);
|
||||
if (!ue_context_p) {
|
||||
LOG_E(NR_RRC, "UE table error\n");
|
||||
return -1;
|
||||
}
|
||||
for (int i = 0; i < create_tunnel_resp_pP->num_tunnels; i++) {
|
||||
ue_context_p->ue_context.gnb_gtp_teid[inde_list[i]] = create_tunnel_resp_pP->enb_S1u_teid[i];
|
||||
ue_context_p->ue_context.gnb_gtp_addrs[inde_list[i]] = create_tunnel_resp_pP->enb_addr;
|
||||
ue_context_p->ue_context.gnb_gtp_ebi[inde_list[i]] = create_tunnel_resp_pP->eps_bearer_id[i];
|
||||
LOG_I(RRC,
|
||||
PROTOCOL_RRC_CTXT_UE_FMT " rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP tunnel (%u, %u) bearer UE context index %u, msg index %u, id %u, gtp addr len %d \n",
|
||||
PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
|
||||
create_tunnel_resp_pP->enb_S1u_teid[i],
|
||||
ue_context_p->ue_context.gnb_gtp_teid[inde_list[i]],
|
||||
inde_list[i],
|
||||
i,
|
||||
create_tunnel_resp_pP->eps_bearer_id[i],
|
||||
create_tunnel_resp_pP->enb_addr.length);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(const protocol_ctxt_t *const ctxt_pP, const gtpv1u_gnb_create_tunnel_resp_t *const create_tunnel_resp_pP, int offset)
|
||||
{
|
||||
int i;
|
||||
struct rrc_gNB_ue_context_s *ue_context_p = NULL;
|
||||
|
||||
if (create_tunnel_resp_pP) {
|
||||
LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" RX CREATE_TUNNEL_RESP num tunnels %u \n",
|
||||
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
|
||||
create_tunnel_resp_pP->num_tunnels);
|
||||
ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rntiMaybeUEid);
|
||||
|
||||
for (i = 0; i < create_tunnel_resp_pP->num_tunnels; i++) {
|
||||
ue_context_p->ue_context.gnb_gtp_teid[i + offset] = create_tunnel_resp_pP->gnb_NGu_teid[i];
|
||||
ue_context_p->ue_context.gnb_gtp_addrs[i + offset] = create_tunnel_resp_pP->gnb_addr;
|
||||
ue_context_p->ue_context.gnb_gtp_psi[i + offset] = create_tunnel_resp_pP->pdusession_id[i];
|
||||
LOG_I(NR_RRC,
|
||||
PROTOCOL_NR_RRC_CTXT_UE_FMT " nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP tunnel (%u, %u) bearer UE context index %u, id %u, gtp addr len %d \n",
|
||||
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
|
||||
create_tunnel_resp_pP->gnb_NGu_teid[i],
|
||||
ue_context_p->ue_context.gnb_gtp_teid[i + offset],
|
||||
i,
|
||||
create_tunnel_resp_pP->pdusession_id[i],
|
||||
create_tunnel_resp_pP->gnb_addr.length);
|
||||
}
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
if (!create_tunnel_resp_pP) {
|
||||
LOG_E(NR_RRC, "create_tunnel_resp_pP error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT " RX CREATE_TUNNEL_RESP num tunnels %u \n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), create_tunnel_resp_pP->num_tunnels);
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rntiMaybeUEid);
|
||||
if (!ue_context_p) {
|
||||
LOG_E(NR_RRC, "UE table error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < create_tunnel_resp_pP->num_tunnels; i++) {
|
||||
ue_context_p->ue_context.gnb_gtp_teid[i + offset] = create_tunnel_resp_pP->gnb_NGu_teid[i];
|
||||
ue_context_p->ue_context.gnb_gtp_addrs[i + offset] = create_tunnel_resp_pP->gnb_addr;
|
||||
ue_context_p->ue_context.gnb_gtp_psi[i + offset] = create_tunnel_resp_pP->pdusession_id[i];
|
||||
LOG_I(NR_RRC,
|
||||
PROTOCOL_NR_RRC_CTXT_UE_FMT " nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP tunnel (%u, %u) bearer UE context index %u, id %u, gtp addr len %d \n",
|
||||
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
|
||||
create_tunnel_resp_pP->gnb_NGu_teid[i],
|
||||
ue_context_p->ue_context.gnb_gtp_teid[i + offset],
|
||||
i,
|
||||
create_tunnel_resp_pP->pdusession_id[i],
|
||||
create_tunnel_resp_pP->gnb_addr.length);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+775
-1106
File diff suppressed because it is too large
Load Diff
@@ -40,18 +40,6 @@
|
||||
#include "NR_UL-DCCH-Message.h"
|
||||
#include "NGAP_CauseRadioNetwork.h"
|
||||
|
||||
typedef struct rrc_ue_ngap_ids_s {
|
||||
/* Tree related data */
|
||||
RB_ENTRY(rrc_ue_ngap_ids_s) entries;
|
||||
|
||||
// keys
|
||||
uint16_t ue_initial_id;
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
|
||||
// value
|
||||
rnti_t ue_rnti;
|
||||
} rrc_ue_ngap_ids_t;
|
||||
|
||||
void
|
||||
rrc_gNB_send_NGAP_NAS_FIRST_REQ(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
@@ -59,12 +47,7 @@ rrc_gNB_send_NGAP_NAS_FIRST_REQ(
|
||||
NR_RRCSetupComplete_IEs_t *rrcSetupComplete
|
||||
);
|
||||
|
||||
int
|
||||
rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(
|
||||
MessageDef *msg_p,
|
||||
const char *msg_name,
|
||||
instance_t instance
|
||||
);
|
||||
int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t instance);
|
||||
|
||||
void
|
||||
rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(
|
||||
@@ -72,20 +55,7 @@ rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(
|
||||
rrc_gNB_ue_context_t *const ue_context_pP
|
||||
);
|
||||
|
||||
int
|
||||
rrc_gNB_process_security(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
ngap_security_capabilities_t *security_capabilities_pP
|
||||
);
|
||||
|
||||
int
|
||||
rrc_gNB_process_NGAP_DOWNLINK_NAS(
|
||||
MessageDef *msg_p,
|
||||
const char *msg_name,
|
||||
instance_t instance,
|
||||
mui_t *rrc_gNB_mui
|
||||
);
|
||||
int rrc_gNB_process_NGAP_DOWNLINK_NAS(MessageDef *msg_p, instance_t instance, mui_t *rrc_gNB_mui);
|
||||
|
||||
void
|
||||
rrc_gNB_send_NGAP_UPLINK_NAS(
|
||||
@@ -101,19 +71,9 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(
|
||||
uint8_t xid
|
||||
);
|
||||
|
||||
void
|
||||
rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(
|
||||
MessageDef *msg_p,
|
||||
const char *msg_name,
|
||||
instance_t instance
|
||||
);
|
||||
void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t instance);
|
||||
|
||||
int
|
||||
rrc_gNB_process_NGAP_PDUSESSION_MODIFY_REQ(
|
||||
MessageDef *msg_p,
|
||||
const char *msg_name,
|
||||
instance_t instance
|
||||
);
|
||||
int rrc_gNB_process_NGAP_PDUSESSION_MODIFY_REQ(MessageDef *msg_p, instance_t instance);
|
||||
|
||||
int
|
||||
rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP(
|
||||
@@ -128,38 +88,13 @@ rrc_gNB_modify_dedicatedRRCReconfiguration(
|
||||
rrc_gNB_ue_context_t *ue_context_pP
|
||||
);
|
||||
|
||||
void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(const module_id_t gnb_mod_idP, const rrc_gNB_ue_context_t *const ue_context_pP, const ngap_Cause_t causeP, const long cause_valueP);
|
||||
|
||||
void
|
||||
rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(
|
||||
const module_id_t gnb_mod_idP,
|
||||
const rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
const ngap_Cause_t causeP,
|
||||
const long cause_valueP
|
||||
);
|
||||
int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_REQ(MessageDef *msg_p, instance_t instance);
|
||||
|
||||
int
|
||||
rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_REQ (
|
||||
MessageDef *msg_p,
|
||||
const char *msg_name,
|
||||
instance_t instance
|
||||
);
|
||||
int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(MessageDef *msg_p, instance_t instance);
|
||||
|
||||
int
|
||||
rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(
|
||||
MessageDef *msg_p,
|
||||
const char *msg_name,
|
||||
instance_t instance
|
||||
);
|
||||
|
||||
void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(
|
||||
instance_t instance,
|
||||
uint32_t gNB_ue_ngap_id);
|
||||
|
||||
void
|
||||
rrc_gNB_NGAP_remove_ue_ids(
|
||||
gNB_RRC_INST *const rrc_instance_pP,
|
||||
struct rrc_ue_ngap_ids_s *const ue_ids_pP
|
||||
);
|
||||
void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, uint32_t gNB_ue_ngap_id);
|
||||
|
||||
void
|
||||
rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(
|
||||
@@ -168,12 +103,7 @@ rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(
|
||||
NR_UL_DCCH_Message_t *const ul_dcch_msg
|
||||
);
|
||||
|
||||
int
|
||||
rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(
|
||||
MessageDef *msg_p,
|
||||
const char *msg_name,
|
||||
instance_t instance
|
||||
);
|
||||
int rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(MessageDef *msg_p, instance_t instance);
|
||||
|
||||
void
|
||||
rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(
|
||||
@@ -189,17 +119,6 @@ nr_rrc_pdcp_config_security(
|
||||
const uint8_t send_security_mode_command
|
||||
);
|
||||
|
||||
struct rrc_gNB_ue_context_s *
|
||||
rrc_gNB_get_ue_context_from_ngap_ids(
|
||||
const instance_t instanceP,
|
||||
const uint16_t ue_initial_idP,
|
||||
const uint32_t gNB_ue_ngap_idP
|
||||
);
|
||||
|
||||
int
|
||||
rrc_gNB_process_PAGING_IND(
|
||||
MessageDef *msg_p,
|
||||
const char *msg_name,
|
||||
instance_t instance);
|
||||
int rrc_gNB_process_PAGING_IND(MessageDef *msg_p, instance_t instance);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -38,15 +38,14 @@
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int rrc_gNB_compare_ue_rnti_id(
|
||||
struct rrc_gNB_ue_context_s *c1_pP, struct rrc_gNB_ue_context_s *c2_pP)
|
||||
int rrc_gNB_compare_ue_rnti_id(rrc_gNB_ue_context_t *c1_pP, rrc_gNB_ue_context_t *c2_pP)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
if (c1_pP->ue_id_rnti > c2_pP->ue_id_rnti) {
|
||||
if (c1_pP->ue_context.gNB_ue_ngap_id > c2_pP->ue_context.gNB_ue_ngap_id) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (c1_pP->ue_id_rnti < c2_pP->ue_id_rnti) {
|
||||
if (c1_pP->ue_context.gNB_ue_ngap_id < c2_pP->ue_context.gNB_ue_ngap_id) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -57,25 +56,17 @@ int rrc_gNB_compare_ue_rnti_id(
|
||||
RB_GENERATE(rrc_nr_ue_tree_s, rrc_gNB_ue_context_s, entries,
|
||||
rrc_gNB_compare_ue_rnti_id);
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
struct rrc_gNB_ue_context_s *
|
||||
rrc_gNB_allocate_new_UE_context(
|
||||
gNB_RRC_INST *rrc_instance_pP
|
||||
)
|
||||
rrc_gNB_ue_context_t *rrc_gNB_allocate_new_ue_context(gNB_RRC_INST *rrc_instance_pP)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
struct rrc_gNB_ue_context_s *new_p;
|
||||
new_p = (struct rrc_gNB_ue_context_s * )malloc(sizeof(struct rrc_gNB_ue_context_s));
|
||||
rrc_gNB_ue_context_t *new_p = calloc(1, sizeof(*new_p));
|
||||
|
||||
if (new_p == NULL) {
|
||||
LOG_E(RRC, "Cannot allocate new ue context\n");
|
||||
LOG_E(NR_RRC, "Cannot allocate new ue context\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(new_p, 0, sizeof(struct rrc_gNB_ue_context_s));
|
||||
new_p->local_uid = uid_linear_allocator_new(&rrc_instance_pP->uid_allocator);
|
||||
new_p->ue_context.gNB_ue_ngap_id = uid_linear_allocator_new(&rrc_instance_pP->uid_allocator);
|
||||
|
||||
for(int i = 0; i < NB_RB_MAX; i++) {
|
||||
new_p->ue_context.e_rab[i].xid = -1;
|
||||
@@ -83,94 +74,66 @@ rrc_gNB_allocate_new_UE_context(
|
||||
new_p->ue_context.modify_e_rab[i].xid = -1;
|
||||
}
|
||||
|
||||
LOG_D(NR_RRC,"Returning new UE context at %p\n",new_p);
|
||||
LOG_I(NR_RRC, "Returning new RRC UE context RRC ue id: %d\n", new_p->ue_context.gNB_ue_ngap_id);
|
||||
return(new_p);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
struct rrc_gNB_ue_context_s *
|
||||
rrc_gNB_get_ue_context(
|
||||
gNB_RRC_INST *rrc_instance_pP,
|
||||
rnti_t rntiP)
|
||||
rrc_gNB_ue_context_t *rrc_gNB_get_ue_context(gNB_RRC_INST *rrc_instance_pP, ue_id_t ue)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
rrc_gNB_ue_context_t temp;
|
||||
memset(&temp, 0, sizeof(struct rrc_gNB_ue_context_s));
|
||||
/* gNB ue rrc id = 24 bits wide */
|
||||
temp.ue_id_rnti = rntiP;
|
||||
struct rrc_gNB_ue_context_s *ue_context_p = NULL;
|
||||
ue_context_p = RB_FIND(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, &temp);
|
||||
|
||||
if ( ue_context_p != NULL) {
|
||||
return ue_context_p;
|
||||
} else {
|
||||
RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &(rrc_instance_pP->rrc_ue_head)) {
|
||||
if (ue_context_p->ue_context.rnti == rntiP) {
|
||||
return ue_context_p;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
temp.ue_context.gNB_ue_ngap_id = ue;
|
||||
return RB_FIND(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, &temp);
|
||||
}
|
||||
|
||||
void rrc_gNB_free_mem_UE_context(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
struct rrc_gNB_ue_context_s *const ue_context_pP
|
||||
)
|
||||
rrc_gNB_ue_context_t *rrc_gNB_get_ue_context_by_rnti(gNB_RRC_INST *rrc_instance_pP, rnti_t rntiP)
|
||||
{
|
||||
rrc_gNB_ue_context_t *ue_context_p;
|
||||
RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &(rrc_instance_pP->rrc_ue_head))
|
||||
{
|
||||
if (ue_context_p->ue_context.rnti == rntiP)
|
||||
return ue_context_p;
|
||||
}
|
||||
LOG_W(NR_RRC, "search by rnti not found %04x\n", rntiP);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void rrc_gNB_free_mem_ue_context(rrc_gNB_ue_context_t *const ue_context_pP)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
|
||||
LOG_T(RRC,
|
||||
PROTOCOL_NR_RRC_CTXT_UE_FMT" Clearing UE context 0x%p (free internal structs)\n",
|
||||
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
|
||||
ue_context_pP);
|
||||
|
||||
//ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_LTE_SCellToAddMod_r10, &ue_context_pP->ue_context.sCell_config[0]);
|
||||
//ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_LTE_SCellToAddMod_r10, &ue_context_pP->ue_context.sCell_config[1]);
|
||||
|
||||
// empty the internal fields of the UE context here
|
||||
free(ue_context_pP);
|
||||
LOG_T(NR_RRC, " Clearing UE context 0x%p (free internal structs)\n", ue_context_pP);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void rrc_gNB_remove_ue_context(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
gNB_RRC_INST *rrc_instance_pP,
|
||||
struct rrc_gNB_ue_context_s *ue_context_pP)
|
||||
void rrc_gNB_remove_ue_context(gNB_RRC_INST *rrc_instance_pP, rrc_gNB_ue_context_t *ue_context_pP)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
if (rrc_instance_pP == NULL) {
|
||||
LOG_E(RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Bad RRC instance\n",
|
||||
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP));
|
||||
LOG_E(NR_RRC, " Bad RRC instance\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ue_context_pP == NULL) {
|
||||
LOG_E(RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Trying to free a NULL UE context\n",
|
||||
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP));
|
||||
LOG_E(NR_RRC, "Trying to free a NULL UE context\n");
|
||||
return;
|
||||
}
|
||||
|
||||
RB_REMOVE(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, ue_context_pP);
|
||||
rrc_gNB_free_mem_UE_context(ctxt_pP, ue_context_pP);
|
||||
uid_linear_allocator_free(&rrc_instance_pP->uid_allocator, ue_context_pP->local_uid);
|
||||
free(ue_context_pP);
|
||||
rrc_instance_pP->Nb_ue --;
|
||||
LOG_I(RRC,
|
||||
PROTOCOL_NR_RRC_CTXT_UE_FMT" Removed UE context\n",
|
||||
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP));
|
||||
uid_linear_allocator_free(&rrc_instance_pP->uid_allocator, ue_context_pP->ue_context.gNB_ue_ngap_id);
|
||||
rrc_gNB_free_mem_ue_context(ue_context_pP);
|
||||
LOG_I(NR_RRC, "Removed UE context\n");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// return the ue context if there is already an UE with ue_identityP, NULL otherwise
|
||||
struct rrc_gNB_ue_context_s *
|
||||
rrc_gNB_ue_context_random_exist(
|
||||
gNB_RRC_INST *rrc_instance_pP,
|
||||
const uint64_t ue_identityP
|
||||
)
|
||||
rrc_gNB_ue_context_t *rrc_gNB_ue_context_random_exist(gNB_RRC_INST *rrc_instance_pP, const uint64_t ue_identityP)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
struct rrc_gNB_ue_context_s *ue_context_p = NULL;
|
||||
rrc_gNB_ue_context_t *ue_context_p = NULL;
|
||||
RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head) {
|
||||
if (ue_context_p->ue_context.random_ue_identity == ue_identityP)
|
||||
return ue_context_p;
|
||||
@@ -180,63 +143,48 @@ rrc_gNB_ue_context_random_exist(
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// return the ue context if there is already an UE with the same S-TMSI, NULL otherwise
|
||||
struct rrc_gNB_ue_context_s *
|
||||
rrc_gNB_ue_context_5g_s_tmsi_exist(
|
||||
gNB_RRC_INST *rrc_instance_pP,
|
||||
const uint64_t s_TMSI
|
||||
)
|
||||
rrc_gNB_ue_context_t *rrc_gNB_ue_context_5g_s_tmsi_exist(gNB_RRC_INST *rrc_instance_pP, const uint64_t s_TMSI)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
struct rrc_gNB_ue_context_s *ue_context_p = NULL;
|
||||
RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head) {
|
||||
LOG_I(NR_RRC,"Checking for UE 5G S-TMSI %ld: RNTI %04x\n",
|
||||
s_TMSI, ue_context_p->ue_context.rnti);
|
||||
|
||||
if (ue_context_p->ue_context.ng_5G_S_TMSI_Part1 == s_TMSI) {
|
||||
return ue_context_p;
|
||||
}
|
||||
}
|
||||
rrc_gNB_ue_context_t *ue_context_p = NULL;
|
||||
RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head)
|
||||
{
|
||||
LOG_I(NR_RRC, "Checking for UE 5G S-TMSI %ld: RNTI %04x\n", s_TMSI, ue_context_p->ue_context.rnti);
|
||||
if (ue_context_p->ue_context.ng_5G_S_TMSI_Part1 == s_TMSI)
|
||||
return ue_context_p;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void rrc_gNB_update_ue_context_rnti(rnti_t rnti, gNB_RRC_INST *rrc_instance_pP, uint32_t gNB_ue_ngap_id)
|
||||
{
|
||||
// rnti will need to be a fast access key, with indexing, today it is sequential search
|
||||
// This function will update the index when it will be made
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc_instance_pP, gNB_ue_ngap_id);
|
||||
if (ue_context_p)
|
||||
ue_context_p->ue_context.rnti = rnti;
|
||||
else
|
||||
LOG_E(NR_RRC, "update rnti on a wrong UE id\n");
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// return a new ue context structure if ue_identityP, ctxt_pP->rnti not found in collection
|
||||
struct rrc_gNB_ue_context_s *
|
||||
rrc_gNB_get_next_free_ue_context(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
gNB_RRC_INST *rrc_instance_pP,
|
||||
const uint64_t ue_identityP
|
||||
)
|
||||
// return a new ue context structure if ue_identityP, rnti not found in collection
|
||||
rrc_gNB_ue_context_t *rrc_gNB_create_ue_context(rnti_t rnti, gNB_RRC_INST *rrc_instance_pP, const uint64_t ue_identityP)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
struct rrc_gNB_ue_context_s *ue_context_p = NULL;
|
||||
ue_context_p = rrc_gNB_get_ue_context(rrc_instance_pP, ctxt_pP->rntiMaybeUEid);
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc_instance_pP, rnti);
|
||||
|
||||
if (ue_context_p == NULL) {
|
||||
ue_context_p = rrc_gNB_allocate_new_UE_context(rrc_instance_pP);
|
||||
|
||||
if (ue_context_p == NULL) {
|
||||
LOG_E(NR_RRC,
|
||||
PROTOCOL_NR_RRC_CTXT_UE_FMT" Cannot create new UE context, no memory\n",
|
||||
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ue_context_p->ue_id_rnti = ctxt_pP->rntiMaybeUEid; // here ue_id_rnti is just a key, may be something else
|
||||
ue_context_p->ue_context.rnti = ctxt_pP->rntiMaybeUEid; // yes duplicate, 1 may be removed
|
||||
ue_context_p->ue_context.random_ue_identity = ue_identityP;
|
||||
RB_INSERT(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, ue_context_p);
|
||||
LOG_D(NR_RRC,
|
||||
PROTOCOL_NR_RRC_CTXT_UE_FMT" Created new UE context uid %u\n",
|
||||
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
|
||||
ue_context_p->local_uid);
|
||||
if (ue_context_p) {
|
||||
LOG_E(NR_RRC, "Cannot create new UE context, already exist rnti: %04x\n", rnti);
|
||||
return ue_context_p;
|
||||
} else {
|
||||
LOG_E(NR_RRC,
|
||||
PROTOCOL_NR_RRC_CTXT_UE_FMT" Cannot create new UE context, already exist\n",
|
||||
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return(ue_context_p);
|
||||
ue_context_p = rrc_gNB_allocate_new_ue_context(rrc_instance_pP);
|
||||
if (ue_context_p == NULL)
|
||||
return NULL;
|
||||
|
||||
ue_context_p->ue_context.rnti = rnti;
|
||||
ue_context_p->ue_context.random_ue_identity = ue_identityP;
|
||||
RB_INSERT(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, ue_context_p);
|
||||
LOG_W(NR_RRC, " Created new UE context rnti: %04x, random ue id %lx, RRC ue id %u\n", rnti, ue_identityP, ue_context_p->ue_context.gNB_ue_ngap_id);
|
||||
return ue_context_p;
|
||||
}
|
||||
|
||||
@@ -34,52 +34,23 @@
|
||||
#include "COMMON/platform_types.h"
|
||||
#include "nr_rrc_defs.h"
|
||||
|
||||
int rrc_gNB_compare_ue_rnti_id(
|
||||
struct rrc_gNB_ue_context_s* c1_pP,
|
||||
struct rrc_gNB_ue_context_s* c2_pP
|
||||
);
|
||||
int rrc_gNB_compare_ue_rnti_id(rrc_gNB_ue_context_t* c1_pP, rrc_gNB_ue_context_t* c2_pP);
|
||||
|
||||
RB_PROTOTYPE(rrc_nr_ue_tree_s, rrc_gNB_ue_context_s, entries, rrc_gNB_compare_ue_rnti_id);
|
||||
|
||||
struct rrc_gNB_ue_context_s*
|
||||
rrc_gNB_allocate_new_UE_context(
|
||||
gNB_RRC_INST* rrc_instance_pP
|
||||
);
|
||||
rrc_gNB_ue_context_t* rrc_gNB_allocate_new_ue_context(gNB_RRC_INST* rrc_instance_pP);
|
||||
|
||||
struct rrc_gNB_ue_context_s*
|
||||
rrc_gNB_get_ue_context(
|
||||
gNB_RRC_INST* rrc_instance_pP,
|
||||
rnti_t rntiP
|
||||
);
|
||||
rrc_gNB_ue_context_t* rrc_gNB_get_ue_context(gNB_RRC_INST* rrc_instance_pP, ue_id_t ue);
|
||||
rrc_gNB_ue_context_t* rrc_gNB_get_ue_context_by_rnti(gNB_RRC_INST* rrc_instance_pP, rnti_t rntiP);
|
||||
|
||||
void rrc_gNB_free_mem_UE_context(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
struct rrc_gNB_ue_context_s *const ue_context_pP
|
||||
);
|
||||
void rrc_gNB_free_mem_ue_context(rrc_gNB_ue_context_t* const ue_context_pP);
|
||||
|
||||
void rrc_gNB_remove_ue_context(
|
||||
const protocol_ctxt_t* const ctxt_pP,
|
||||
gNB_RRC_INST* rrc_instance_pP,
|
||||
struct rrc_gNB_ue_context_s* ue_context_pP
|
||||
);
|
||||
void rrc_gNB_remove_ue_context(gNB_RRC_INST* rrc_instance_pP, rrc_gNB_ue_context_t* ue_context_pP);
|
||||
|
||||
struct rrc_gNB_ue_context_s *
|
||||
rrc_gNB_ue_context_random_exist(
|
||||
gNB_RRC_INST *rrc_instance_pP,
|
||||
const uint64_t ue_identityP
|
||||
);
|
||||
rrc_gNB_ue_context_t* rrc_gNB_ue_context_random_exist(gNB_RRC_INST* rrc_instance_pP, const uint64_t ue_identityP);
|
||||
|
||||
struct rrc_gNB_ue_context_s *
|
||||
rrc_gNB_ue_context_5g_s_tmsi_exist(
|
||||
gNB_RRC_INST *rrc_instance_pP,
|
||||
const uint64_t s_TMSI
|
||||
);
|
||||
|
||||
struct rrc_gNB_ue_context_s *
|
||||
rrc_gNB_get_next_free_ue_context(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
gNB_RRC_INST *rrc_instance_pP,
|
||||
const uint64_t ue_identityP
|
||||
);
|
||||
rrc_gNB_ue_context_t* rrc_gNB_ue_context_5g_s_tmsi_exist(gNB_RRC_INST* rrc_instance_pP, const uint64_t s_TMSI);
|
||||
void rrc_gNB_update_ue_context_rnti(rnti_t rnti, gNB_RRC_INST* rrc_instance_pP, uint32_t gNB_ue_ngap_id);
|
||||
rrc_gNB_ue_context_t* rrc_gNB_create_ue_context(rnti_t rnti, gNB_RRC_INST* rrc_instance_pP, const uint64_t ue_identityP);
|
||||
|
||||
#endif
|
||||
|
||||
+84
-110
@@ -45,9 +45,8 @@
|
||||
#include <openair2/RRC/NR/nr_rrc_proto.h>
|
||||
#include "pdcp.h"
|
||||
|
||||
void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc, NR_UE_CapabilityRAT_ContainerList_t *UE_CapabilityRAT_ContainerList, x2ap_ENDC_sgnb_addition_req_t *m, NR_CG_ConfigInfo_IEs_t *cg_config_info) {
|
||||
struct rrc_gNB_ue_context_s *ue_context_p = NULL;
|
||||
|
||||
void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc, NR_UE_CapabilityRAT_ContainerList_t *UE_CapabilityRAT_ContainerList, x2ap_ENDC_sgnb_addition_req_t *m, NR_CG_ConfigInfo_IEs_t *cg_config_info)
|
||||
{
|
||||
OCTET_STRING_t *ueCapabilityRAT_Container_nr=NULL;
|
||||
OCTET_STRING_t *ueCapabilityRAT_Container_MRDC=NULL;
|
||||
asn_dec_rval_t dec_rval;
|
||||
@@ -62,36 +61,27 @@ void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc, NR_UE_CapabilityRAT_ContainerL
|
||||
}
|
||||
|
||||
// decode and store capabilities
|
||||
ue_context_p = rrc_gNB_allocate_new_UE_context(rrc);
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_allocate_new_ue_context(rrc);
|
||||
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
|
||||
|
||||
if (ueCapabilityRAT_Container_nr != NULL) {
|
||||
dec_rval = uper_decode(NULL,
|
||||
&asn_DEF_NR_UE_NR_Capability,
|
||||
(void **)&ue_context_p->ue_context.UE_Capability_nr,
|
||||
ueCapabilityRAT_Container_nr->buf,
|
||||
ueCapabilityRAT_Container_nr->size, 0, 0);
|
||||
dec_rval = uper_decode(NULL, &asn_DEF_NR_UE_NR_Capability, (void **)&UE->UE_Capability_nr, ueCapabilityRAT_Container_nr->buf, ueCapabilityRAT_Container_nr->size, 0, 0);
|
||||
|
||||
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
|
||||
LOG_E(RRC, "Failed to decode UE NR capabilities (%zu bytes) container size %lu\n", dec_rval.consumed,ueCapabilityRAT_Container_nr->size);
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability,
|
||||
ue_context_p->ue_context.UE_Capability_nr);
|
||||
ue_context_p->ue_context.UE_Capability_nr = 0;
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, UE->UE_Capability_nr);
|
||||
UE->UE_Capability_nr = 0;
|
||||
AssertFatal(1==0,"exiting\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (ueCapabilityRAT_Container_MRDC != NULL) {
|
||||
dec_rval = uper_decode(NULL,
|
||||
&asn_DEF_NR_UE_MRDC_Capability,
|
||||
(void **)&ue_context_p->ue_context.UE_Capability_MRDC,
|
||||
ueCapabilityRAT_Container_MRDC->buf,
|
||||
ueCapabilityRAT_Container_MRDC->size, 0, 0);
|
||||
dec_rval = uper_decode(NULL, &asn_DEF_NR_UE_MRDC_Capability, (void **)&UE->UE_Capability_MRDC, ueCapabilityRAT_Container_MRDC->buf, ueCapabilityRAT_Container_MRDC->size, 0, 0);
|
||||
|
||||
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
|
||||
LOG_E(RRC, "Failed to decode UE MRDC capabilities (%zu bytes)\n", dec_rval.consumed);
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability,
|
||||
ue_context_p->ue_context.UE_Capability_MRDC);
|
||||
ue_context_p->ue_context.UE_Capability_MRDC = 0;
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability, UE->UE_Capability_MRDC);
|
||||
UE->UE_Capability_MRDC = 0;
|
||||
AssertFatal(1==0,"exiting\n");
|
||||
}
|
||||
}
|
||||
@@ -99,16 +89,16 @@ void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc, NR_UE_CapabilityRAT_ContainerL
|
||||
// dump ue_capabilities
|
||||
|
||||
if ( LOG_DEBUGFLAG(DEBUG_ASN1) && ueCapabilityRAT_Container_nr != NULL ) {
|
||||
xer_fprint(stdout, &asn_DEF_NR_UE_NR_Capability, ue_context_p->ue_context.UE_Capability_nr);
|
||||
xer_fprint(stdout, &asn_DEF_NR_UE_NR_Capability, UE->UE_Capability_nr);
|
||||
}
|
||||
|
||||
if ( LOG_DEBUGFLAG(DEBUG_ASN1) && ueCapabilityRAT_Container_MRDC != NULL ) {
|
||||
xer_fprint(stdout, &asn_DEF_NR_UE_MRDC_Capability, ue_context_p->ue_context.UE_Capability_MRDC);
|
||||
xer_fprint(stdout, &asn_DEF_NR_UE_MRDC_Capability, UE->UE_Capability_MRDC);
|
||||
}
|
||||
LOG_A(NR_RRC, "Successfully decoded UE NR capabilities (NR and MRDC)\n");
|
||||
|
||||
ue_context_p->ue_context.spCellConfig = calloc(1, sizeof(struct NR_SpCellConfig));
|
||||
ue_context_p->ue_context.spCellConfig->spCellConfigDedicated = rrc->carrier.servingcellconfig;
|
||||
UE->spCellConfig = calloc(1, sizeof(struct NR_SpCellConfig));
|
||||
UE->spCellConfig->spCellConfigDedicated = rrc->carrier.servingcellconfig;
|
||||
LOG_I(NR_RRC,"Adding new NSA user (%p)\n",ue_context_p);
|
||||
rrc_add_nsa_user(rrc,ue_context_p, m);
|
||||
}
|
||||
@@ -117,7 +107,8 @@ void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc, NR_UE_CapabilityRAT_ContainerL
|
||||
RB_PROTOTYPE(rrc_nr_ue_tree_s, rrc_gNB_ue_context_s, entries,
|
||||
rrc_gNB_compare_ue_rnti_id);
|
||||
|
||||
void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_p, x2ap_ENDC_sgnb_addition_req_t *m) {
|
||||
void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2ap_ENDC_sgnb_addition_req_t *m)
|
||||
{
|
||||
// generate nr-Config-r15 containers for LTE RRC : inside message for X2 EN-DC (CG-Config Message from 38.331)
|
||||
rrc_gNB_carrier_data_t *carrier=&rrc->carrier;
|
||||
const gNB_RrcConfigurationReq *configuration = &rrc->configuration;
|
||||
@@ -129,6 +120,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
|
||||
unsigned char *kUPenc = NULL;
|
||||
unsigned char *kUPint = NULL;
|
||||
int i;
|
||||
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
|
||||
|
||||
// In case of phy-test and do-ra mode, read UE capabilities directly from file
|
||||
if (get_softmodem_params()->phy_test == 1 || get_softmodem_params()->do_ra == 1) {
|
||||
@@ -150,25 +142,20 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
|
||||
}
|
||||
else
|
||||
LOG_E(NR_RRC,"Could not open UE Capabilities input file. Not handling OAI UE Capabilities.\n");
|
||||
ue_context_p->ue_context.UE_Capability_nr = UE_Capability_nr;
|
||||
UE->UE_Capability_nr = UE_Capability_nr;
|
||||
}
|
||||
|
||||
// NR RRCReconfiguration
|
||||
AssertFatal(rrc->Nb_ue < MAX_NR_RRC_UE_CONTEXTS,"cannot add another UE\n");
|
||||
ue_context_p->ue_context.reconfig = calloc(1,sizeof(NR_RRCReconfiguration_t));
|
||||
ue_context_p->ue_context.secondaryCellGroup = calloc(1,sizeof(NR_CellGroupConfig_t));
|
||||
memset((void *)ue_context_p->ue_context.reconfig,0,sizeof(NR_RRCReconfiguration_t));
|
||||
ue_context_p->ue_context.reconfig->rrc_TransactionIdentifier=0;
|
||||
ue_context_p->ue_context.reconfig->criticalExtensions.present = NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration;
|
||||
UE->reconfig = calloc(1, sizeof(NR_RRCReconfiguration_t));
|
||||
UE->secondaryCellGroup = calloc(1, sizeof(NR_CellGroupConfig_t));
|
||||
memset((void *)UE->reconfig, 0, sizeof(NR_RRCReconfiguration_t));
|
||||
UE->reconfig->rrc_TransactionIdentifier = 0;
|
||||
UE->reconfig->criticalExtensions.present = NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration;
|
||||
NR_RRCReconfiguration_IEs_t *reconfig_ies=calloc(1,sizeof(NR_RRCReconfiguration_IEs_t));
|
||||
ue_context_p->ue_context.reconfig->criticalExtensions.choice.rrcReconfiguration = reconfig_ies;
|
||||
ue_context_p->ue_context.rb_config = calloc(1,sizeof(NR_RRCReconfiguration_t));
|
||||
UE->reconfig->criticalExtensions.choice.rrcReconfiguration = reconfig_ies;
|
||||
UE->rb_config = calloc(1, sizeof(NR_RRCReconfiguration_t));
|
||||
if (get_softmodem_params()->phy_test == 1 || get_softmodem_params()->do_ra == 1 || get_softmodem_params()->sa == 1){
|
||||
fill_default_rbconfig(ue_context_p->ue_context.rb_config,
|
||||
10 /* EPS bearer ID */,
|
||||
1 /* drb ID */,
|
||||
NR_CipheringAlgorithm_nea0,
|
||||
NR_SecurityConfig__keyToUse_master);
|
||||
fill_default_rbconfig(UE->rb_config, 10 /* EPS bearer ID */, 1 /* drb ID */, NR_CipheringAlgorithm_nea0, NR_SecurityConfig__keyToUse_master);
|
||||
} else {
|
||||
/* TODO: handle more than one bearer */
|
||||
if (m == NULL) {
|
||||
@@ -181,9 +168,9 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
|
||||
}
|
||||
|
||||
/* store security key and security capabilities */
|
||||
memcpy(ue_context_p->ue_context.kgnb, m->kgnb, 32);
|
||||
ue_context_p->ue_context.security_capabilities.nRencryption_algorithms = m->security_capabilities.encryption_algorithms;
|
||||
ue_context_p->ue_context.security_capabilities.nRintegrity_algorithms = m->security_capabilities.integrity_algorithms;
|
||||
memcpy(UE->kgnb, m->kgnb, 32);
|
||||
UE->security_capabilities.nRencryption_algorithms = m->security_capabilities.encryption_algorithms;
|
||||
UE->security_capabilities.nRintegrity_algorithms = m->security_capabilities.integrity_algorithms;
|
||||
|
||||
/* Select ciphering algorithm based on gNB configuration file and
|
||||
* UE's supported algorithms.
|
||||
@@ -191,7 +178,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
|
||||
* The ordering of the list comes from the configuration file.
|
||||
*/
|
||||
/* preset nea0 as fallback */
|
||||
ue_context_p->ue_context.ciphering_algorithm = 0;
|
||||
UE->ciphering_algorithm = 0;
|
||||
for (i = 0; i < rrc->security.ciphering_algorithms_count; i++) {
|
||||
int nea_mask[4] = {
|
||||
0,
|
||||
@@ -203,13 +190,13 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
|
||||
/* nea0 already preselected */
|
||||
break;
|
||||
}
|
||||
if (ue_context_p->ue_context.security_capabilities.nRencryption_algorithms & nea_mask[rrc->security.ciphering_algorithms[i]]) {
|
||||
ue_context_p->ue_context.ciphering_algorithm = rrc->security.ciphering_algorithms[i];
|
||||
if (UE->security_capabilities.nRencryption_algorithms & nea_mask[rrc->security.ciphering_algorithms[i]]) {
|
||||
UE->ciphering_algorithm = rrc->security.ciphering_algorithms[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_I(RRC, "selecting ciphering algorithm %d\n", (int)ue_context_p->ue_context.ciphering_algorithm);
|
||||
LOG_I(RRC, "selecting ciphering algorithm %d\n", (int)UE->ciphering_algorithm);
|
||||
|
||||
/* integrity: no integrity protection for DRB in ENDC mode
|
||||
* as written in 38.331: "If UE is connected to E-UTRA/EPC, this field
|
||||
@@ -218,49 +205,46 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
|
||||
* So nothing for DRB. Plus a test with a COTS UE revealed that it
|
||||
* did not apply integrity on the DRB.
|
||||
*/
|
||||
ue_context_p->ue_context.integrity_algorithm = 0;
|
||||
UE->integrity_algorithm = 0;
|
||||
|
||||
LOG_I(RRC, "selecting integrity algorithm %d\n", ue_context_p->ue_context.integrity_algorithm);
|
||||
LOG_I(RRC, "selecting integrity algorithm %d\n", UE->integrity_algorithm);
|
||||
|
||||
/* derive UP security key */
|
||||
nr_derive_key_up_enc(ue_context_p->ue_context.ciphering_algorithm,
|
||||
ue_context_p->ue_context.kgnb,
|
||||
&kUPenc);
|
||||
nr_derive_key_up_int(ue_context_p->ue_context.integrity_algorithm,
|
||||
ue_context_p->ue_context.kgnb,
|
||||
&kUPint);
|
||||
nr_derive_key_up_enc(UE->ciphering_algorithm, UE->kgnb, &kUPenc);
|
||||
nr_derive_key_up_int(UE->integrity_algorithm, UE->kgnb, &kUPint);
|
||||
|
||||
e_NR_CipheringAlgorithm cipher_algo;
|
||||
switch (ue_context_p->ue_context.ciphering_algorithm) {
|
||||
case 0: cipher_algo = NR_CipheringAlgorithm_nea0; break;
|
||||
case 1: cipher_algo = NR_CipheringAlgorithm_nea1; break;
|
||||
case 2: cipher_algo = NR_CipheringAlgorithm_nea2; break;
|
||||
case 3: cipher_algo = NR_CipheringAlgorithm_nea3; break;
|
||||
default: LOG_E(RRC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); exit(1);
|
||||
switch (UE->ciphering_algorithm) {
|
||||
case 0:
|
||||
cipher_algo = NR_CipheringAlgorithm_nea0;
|
||||
break;
|
||||
case 1:
|
||||
cipher_algo = NR_CipheringAlgorithm_nea1;
|
||||
break;
|
||||
case 2:
|
||||
cipher_algo = NR_CipheringAlgorithm_nea2;
|
||||
break;
|
||||
case 3:
|
||||
cipher_algo = NR_CipheringAlgorithm_nea3;
|
||||
break;
|
||||
default:
|
||||
LOG_E(RRC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fill_default_rbconfig(ue_context_p->ue_context.rb_config,
|
||||
m->e_rabs_tobeadded[0].e_rab_id,
|
||||
m->e_rabs_tobeadded[0].drb_ID,
|
||||
cipher_algo,
|
||||
NR_SecurityConfig__keyToUse_secondary);
|
||||
fill_default_rbconfig(UE->rb_config, m->e_rabs_tobeadded[0].e_rab_id, m->e_rabs_tobeadded[0].drb_ID, cipher_algo, NR_SecurityConfig__keyToUse_secondary);
|
||||
}
|
||||
|
||||
NR_ServingCellConfig_t *scc = ue_context_p->ue_context.spCellConfig ?
|
||||
ue_context_p->ue_context.spCellConfig->spCellConfigDedicated : NULL;
|
||||
fill_default_reconfig(carrier->servingcellconfigcommon,
|
||||
scc,
|
||||
reconfig_ies,
|
||||
ue_context_p->ue_context.secondaryCellGroup,
|
||||
ue_context_p->ue_context.UE_Capability_nr,
|
||||
configuration,
|
||||
ue_context_p->local_uid);
|
||||
|
||||
ue_context_p->ue_id_rnti = ue_context_p->ue_context.secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity;
|
||||
NR_ServingCellConfig_t *scc = UE->spCellConfig ? UE->spCellConfig->spCellConfigDedicated : NULL;
|
||||
fill_default_reconfig(carrier->servingcellconfigcommon, scc, reconfig_ies, UE->secondaryCellGroup, UE->UE_Capability_nr, configuration, ue_context_p->ue_context.gNB_ue_ngap_id);
|
||||
// the UE context is not yet inserted in the RRC UE manager
|
||||
// rrc_gNB_update_ue_context_rnti(UE->secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity, rrc,
|
||||
// UE->gNB_ue_ngap_id);
|
||||
UE->rnti = UE->secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity;
|
||||
NR_CG_Config_t *CG_Config = calloc(1,sizeof(*CG_Config));
|
||||
memset((void *)CG_Config,0,sizeof(*CG_Config));
|
||||
//int CG_Config_size = generate_CG_Config(rrc,CG_Config,ue_context_p->ue_context.reconfig,ue_context_p->ue_context.rb_config);
|
||||
generate_CG_Config(rrc,CG_Config,ue_context_p->ue_context.reconfig,ue_context_p->ue_context.rb_config);
|
||||
// int CG_Config_size = generate_CG_Config(rrc,CG_Config,UE->reconfig,UE->rb_config);
|
||||
generate_CG_Config(rrc, CG_Config, UE->reconfig, UE->rb_config);
|
||||
|
||||
if(m!=NULL) {
|
||||
uint8_t inde_list[m->nb_e_rabs_tobeadded];
|
||||
@@ -268,15 +252,15 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
|
||||
|
||||
if (m->nb_e_rabs_tobeadded>0) {
|
||||
for (int i=0; i<m->nb_e_rabs_tobeadded; i++) {
|
||||
// Add the new E-RABs at the corresponding rrc ue context of the gNB
|
||||
ue_context_p->ue_context.e_rab[i].param.e_rab_id = m->e_rabs_tobeadded[i].e_rab_id;
|
||||
ue_context_p->ue_context.e_rab[i].param.gtp_teid = m->e_rabs_tobeadded[i].gtp_teid;
|
||||
memcpy(&ue_context_p->ue_context.e_rab[i].param.sgw_addr, &m->e_rabs_tobeadded[i].sgw_addr, sizeof(transport_layer_addr_t));
|
||||
ue_context_p->ue_context.nb_of_e_rabs++;
|
||||
// Add the new E-RABs at the corresponding rrc ue context of the gNB
|
||||
UE->e_rab[i].param.e_rab_id = m->e_rabs_tobeadded[i].e_rab_id;
|
||||
UE->e_rab[i].param.gtp_teid = m->e_rabs_tobeadded[i].gtp_teid;
|
||||
memcpy(&UE->e_rab[i].param.sgw_addr, &m->e_rabs_tobeadded[i].sgw_addr, sizeof(transport_layer_addr_t));
|
||||
UE->nb_of_e_rabs++;
|
||||
//Fill the required E-RAB specific information for the creation of the S1-U tunnel between the gNB and the SGW
|
||||
create_tunnel_req.eps_bearer_id[i] = ue_context_p->ue_context.e_rab[i].param.e_rab_id;
|
||||
create_tunnel_req.sgw_S1u_teid[i] = ue_context_p->ue_context.e_rab[i].param.gtp_teid;
|
||||
memcpy(&create_tunnel_req.sgw_addr[i], &ue_context_p->ue_context.e_rab[i].param.sgw_addr, sizeof(transport_layer_addr_t));
|
||||
create_tunnel_req.eps_bearer_id[i] = UE->e_rab[i].param.e_rab_id;
|
||||
create_tunnel_req.sgw_S1u_teid[i] = UE->e_rab[i].param.gtp_teid;
|
||||
memcpy(&create_tunnel_req.sgw_addr[i], &UE->e_rab[i].param.sgw_addr, sizeof(transport_layer_addr_t));
|
||||
inde_list[i] = i;
|
||||
LOG_I(RRC,"S1-U tunnel: index %d target sgw ip %d.%d.%d.%d length %d gtp teid %u\n",
|
||||
i,
|
||||
@@ -288,10 +272,10 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
|
||||
create_tunnel_req.sgw_S1u_teid[i]);
|
||||
}
|
||||
|
||||
create_tunnel_req.rnti = ue_context_p->ue_id_rnti;
|
||||
create_tunnel_req.rnti = ue_context_p->ue_context.rnti;
|
||||
create_tunnel_req.num_tunnels = m->nb_e_rabs_tobeadded;
|
||||
RB_INSERT(rrc_nr_ue_tree_s, &RC.nrrrc[rrc->module_id]->rrc_ue_head, ue_context_p);
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, ue_context_p->ue_id_rnti, 0, 0,rrc->module_id);
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, rrc->module_id);
|
||||
memset(&create_tunnel_resp, 0, sizeof(create_tunnel_resp));
|
||||
if (!IS_SOFTMODEM_NOS1) {
|
||||
LOG_D(RRC, "Calling gtpv1u_create_s1u_tunnel()\n");
|
||||
@@ -307,8 +291,8 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).nb_e_rabs_admitted_tobeadded = m->nb_e_rabs_tobeadded;
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).target_assoc_id = m->target_assoc_id;
|
||||
|
||||
for(int i=0; i<ue_context_p->ue_context.nb_of_e_rabs; i++) {
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].e_rab_id = ue_context_p->ue_context.e_rab[i].param.e_rab_id;
|
||||
for (int i = 0; i < UE->nb_of_e_rabs; i++) {
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].e_rab_id = UE->e_rab[i].param.e_rab_id;
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gtp_teid = create_tunnel_resp.enb_S1u_teid[i];
|
||||
memcpy(&X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gnb_addr, &create_tunnel_resp.enb_addr, sizeof(transport_layer_addr_t));
|
||||
//The length field in the X2AP targetting structure is expected in bits but the create_tunnel_resp returns the address length in bytes
|
||||
@@ -334,7 +318,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
|
||||
LOG_W(RRC, "No E-RAB to be added received from SgNB Addition Request message \n");
|
||||
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).MeNB_ue_x2_id = m->ue_x2_id;
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).SgNB_ue_x2_id = ue_context_p->ue_context.secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity;
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).SgNB_ue_x2_id = UE->secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity;
|
||||
//X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer_size = CG_Config_size; //Need to verify correct value for the buffer_size
|
||||
// Send to X2 entity to transport to MeNB
|
||||
asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CG_Config,
|
||||
@@ -346,18 +330,17 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
|
||||
itti_send_msg_to_task(TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(0), msg); //Check right id instead of hardcoding
|
||||
}
|
||||
|
||||
rrc->Nb_ue++;
|
||||
// configure MAC and RLC
|
||||
bool ret = false;
|
||||
if (get_softmodem_params()->phy_test) {
|
||||
// phytest mode: we don't set up RA, etc
|
||||
ret = nr_mac_add_test_ue(RC.nrmac[rrc->module_id], ue_context_p->ue_id_rnti, ue_context_p->ue_context.secondaryCellGroup);
|
||||
ret = nr_mac_add_test_ue(RC.nrmac[rrc->module_id] , ue_context_p->ue_context.rnti, ue_context_p->ue_context.secondaryCellGroup);
|
||||
} else {
|
||||
ret = nr_mac_prepare_ra_nsa_ue(RC.nrmac[rrc->module_id], ue_context_p->ue_id_rnti, ue_context_p->ue_context.secondaryCellGroup);
|
||||
ret = nr_mac_prepare_ra_nsa_ue(RC.nrmac[rrc->module_id], ue_context_p->ue_context.rnti, ue_context_p->ue_context.secondaryCellGroup);
|
||||
}
|
||||
AssertFatal(ret, "cannot add NSA UE in MAC, aborting\n");
|
||||
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, ue_context_p->ue_id_rnti, 0, 0, rrc->module_id);
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, rrc->module_id);
|
||||
if (get_softmodem_params()->do_ra) ctxt.enb_flag = 0;
|
||||
LOG_W(RRC,
|
||||
"Calling RRC PDCP/RLC ASN1 request functions for protocol context %p with module_id %d, rnti %lx, frame %d, subframe %d eNB_index %d \n",
|
||||
@@ -368,20 +351,11 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
|
||||
ctxt.subframe,
|
||||
ctxt.eNB_index);
|
||||
|
||||
nr_pdcp_add_drbs(ctxt.enb_flag,
|
||||
ctxt.rntiMaybeUEid,
|
||||
0,
|
||||
ue_context_p->ue_context.rb_config->drb_ToAddModList,
|
||||
(ue_context_p->ue_context.integrity_algorithm << 4) | ue_context_p->ue_context.ciphering_algorithm,
|
||||
kUPenc,
|
||||
kUPint,
|
||||
ue_context_p->ue_context.secondaryCellGroup->rlc_BearerToAddModList);
|
||||
nr_pdcp_add_drbs(
|
||||
ctxt.enb_flag, ctxt.rntiMaybeUEid, 0, UE->rb_config->drb_ToAddModList, (UE->integrity_algorithm << 4) | UE->ciphering_algorithm, kUPenc, kUPint, UE->secondaryCellGroup->rlc_BearerToAddModList);
|
||||
|
||||
nr_rrc_rlc_config_asn1_req(&ctxt,
|
||||
get_softmodem_params()->sa ? ue_context_p->ue_context.rb_config->srb_ToAddModList : NULL,
|
||||
ue_context_p->ue_context.rb_config->drb_ToAddModList,
|
||||
ue_context_p->ue_context.rb_config->drb_ToReleaseList,
|
||||
ue_context_p->ue_context.secondaryCellGroup->rlc_BearerToAddModList);
|
||||
nr_rrc_rlc_config_asn1_req(
|
||||
&ctxt, get_softmodem_params()->sa ? UE->rb_config->srb_ToAddModList : NULL, UE->rb_config->drb_ToAddModList, UE->rb_config->drb_ToReleaseList, UE->secondaryCellGroup->rlc_BearerToAddModList);
|
||||
|
||||
LOG_D(RRC, "%s:%d: done RRC PDCP/RLC ASN1 request for UE rnti %lx\n", __FUNCTION__, __LINE__, ctxt.rntiMaybeUEid);
|
||||
}
|
||||
@@ -394,7 +368,7 @@ void rrc_remove_nsa_user(gNB_RRC_INST *rrc, int rnti) {
|
||||
LOG_D(RRC, "calling rrc_remove_nsa_user rnti %d\n", rnti);
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, rnti, 0, 0, rrc->module_id);
|
||||
|
||||
ue_context = rrc_gNB_get_ue_context(rrc, rnti);
|
||||
ue_context = rrc_gNB_get_ue_context_by_rnti(rrc, rnti);
|
||||
if (ue_context == NULL) {
|
||||
LOG_W(RRC, "rrc_remove_nsa_user: rnti %d not found\n", rnti);
|
||||
return;
|
||||
@@ -419,5 +393,5 @@ void rrc_remove_nsa_user(gNB_RRC_INST *rrc, int rnti) {
|
||||
}
|
||||
gtpv1u_delete_s1u_tunnel(rrc->module_id, &tmp);
|
||||
/* remove context */
|
||||
rrc_gNB_remove_ue_context(&ctxt, rrc, ue_context);
|
||||
rrc_gNB_remove_ue_context(rrc, ue_context);
|
||||
}
|
||||
|
||||
@@ -22,19 +22,30 @@
|
||||
#include "rrc_gNB_radio_bearers.h"
|
||||
#include "oai_asn1.h"
|
||||
|
||||
NR_DRB_ToAddMod_t *generateDRB(gNB_RRC_UE_t *ue, uint8_t drb_id, pdu_session_param_t *pduSession, bool enable_sdap, int do_drb_integrity, int do_drb_ciphering)
|
||||
rrc_pdu_session_param_t *find_pduSession(gNB_RRC_UE_t *ue, int id, bool create)
|
||||
{
|
||||
NR_DRB_ToAddMod_t *DRB_config = NULL;
|
||||
NR_SDAP_Config_t *SDAP_config = NULL;
|
||||
int j;
|
||||
for (j = 0; j < ue->nb_of_pdusessions; j++)
|
||||
if (id == ue->pduSession[j].param.pdusession_id)
|
||||
break;
|
||||
if (j == ue->nb_of_pdusessions && create)
|
||||
ue->nb_of_pdusessions++;
|
||||
else
|
||||
return NULL;
|
||||
AssertFatal(ue->nb_of_pdusessions < NGAP_MAX_PDU_SESSION, "");
|
||||
return ue->pduSession + j;
|
||||
}
|
||||
|
||||
DRB_config = CALLOC(1, sizeof(*DRB_config));
|
||||
NR_DRB_ToAddMod_t *generateDRB(gNB_RRC_UE_t *ue, uint8_t drb_id, rrc_pdu_session_param_t *pduSession, bool enable_sdap, int do_drb_integrity, int do_drb_ciphering)
|
||||
{
|
||||
NR_DRB_ToAddMod_t *DRB_config = CALLOC(1, sizeof(*DRB_config));
|
||||
DRB_config->drb_Identity = drb_id;
|
||||
DRB_config->cnAssociation = CALLOC(1, sizeof(*DRB_config->cnAssociation));
|
||||
DRB_config->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config;
|
||||
|
||||
asn1cCalloc(DRB_config->cnAssociation, association);
|
||||
association->present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config;
|
||||
|
||||
/* SDAP Configuration */
|
||||
SDAP_config = CALLOC(1, sizeof(NR_SDAP_Config_t));
|
||||
SDAP_config->mappedQoS_FlowsToAdd = calloc(1, sizeof(struct NR_SDAP_Config__mappedQoS_FlowsToAdd));
|
||||
NR_SDAP_Config_t *SDAP_config = CALLOC(1, sizeof(NR_SDAP_Config_t));
|
||||
asn1cCalloc(SDAP_config->mappedQoS_FlowsToAdd, sdapFlows);
|
||||
|
||||
SDAP_config->pdu_Session = pduSession->param.pdusession_id;
|
||||
|
||||
@@ -50,53 +61,36 @@ NR_DRB_ToAddMod_t *generateDRB(gNB_RRC_UE_t *ue, uint8_t drb_id, pdu_session_par
|
||||
|
||||
for (int qos_flow_index = 0; qos_flow_index < pduSession->param.nb_qos; qos_flow_index++)
|
||||
{
|
||||
NR_QFI_t *qfi = calloc(1, sizeof(NR_QFI_t));
|
||||
asn1cSequenceAdd(sdapFlows->list, NR_QFI_t, qfi);
|
||||
*qfi = pduSession->param.qos[qos_flow_index].qfi;
|
||||
asn1cSeqAdd(&SDAP_config->mappedQoS_FlowsToAdd->list, qfi);
|
||||
|
||||
if(pduSession->param.qos[qos_flow_index].fiveQI > 5)
|
||||
pduSession->param.used_drbs[drb_id - 1] = DRB_ACTIVE_NONGBR;
|
||||
else
|
||||
pduSession->param.used_drbs[drb_id - 1] = DRB_ACTIVE;
|
||||
}
|
||||
|
||||
SDAP_config->mappedQoS_FlowsToRelease = NULL;
|
||||
DRB_config->cnAssociation->choice.sdap_Config = SDAP_config;
|
||||
|
||||
|
||||
association->choice.sdap_Config = SDAP_config;
|
||||
|
||||
/* PDCP Configuration */
|
||||
DRB_config->reestablishPDCP = NULL;
|
||||
DRB_config->recoverPDCP = NULL;
|
||||
DRB_config->pdcp_Config = calloc(1, sizeof(*DRB_config->pdcp_Config));
|
||||
DRB_config->pdcp_Config->drb = calloc(1,sizeof(*DRB_config->pdcp_Config->drb));
|
||||
asn1cCalloc(DRB_config->pdcp_Config, pdcpConfig);
|
||||
asn1cCalloc(pdcpConfig->drb, drb);
|
||||
|
||||
DRB_config->pdcp_Config->drb->discardTimer = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->discardTimer));
|
||||
*DRB_config->pdcp_Config->drb->discardTimer = NR_PDCP_Config__drb__discardTimer_infinity;
|
||||
DRB_config->pdcp_Config->drb->pdcp_SN_SizeUL = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->pdcp_SN_SizeUL));
|
||||
*DRB_config->pdcp_Config->drb->pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits;
|
||||
DRB_config->pdcp_Config->drb->pdcp_SN_SizeDL = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->pdcp_SN_SizeDL));
|
||||
*DRB_config->pdcp_Config->drb->pdcp_SN_SizeDL = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits;
|
||||
asn1cCallocOne(drb->discardTimer, NR_PDCP_Config__drb__discardTimer_infinity);
|
||||
|
||||
DRB_config->pdcp_Config->drb->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed;
|
||||
DRB_config->pdcp_Config->drb->headerCompression.choice.notUsed = 0;
|
||||
|
||||
DRB_config->pdcp_Config->drb->integrityProtection = NULL;
|
||||
DRB_config->pdcp_Config->drb->statusReportRequired = NULL;
|
||||
DRB_config->pdcp_Config->drb->outOfOrderDelivery = NULL;
|
||||
DRB_config->pdcp_Config->moreThanOneRLC = NULL;
|
||||
|
||||
DRB_config->pdcp_Config->t_Reordering = calloc(1, sizeof(*DRB_config->pdcp_Config->t_Reordering));
|
||||
*DRB_config->pdcp_Config->t_Reordering = NR_PDCP_Config__t_Reordering_ms100;
|
||||
DRB_config->pdcp_Config->ext1 = NULL;
|
||||
asn1cCallocOne(drb->pdcp_SN_SizeUL, NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits);
|
||||
asn1cCallocOne(drb->pdcp_SN_SizeDL, NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits);
|
||||
|
||||
drb->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed;
|
||||
drb->headerCompression.choice.notUsed = 0;
|
||||
|
||||
asn1cCallocOne(pdcpConfig->t_Reordering, NR_PDCP_Config__t_Reordering_ms100);
|
||||
|
||||
if (do_drb_integrity) {
|
||||
DRB_config->pdcp_Config->drb->integrityProtection = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->integrityProtection));
|
||||
*DRB_config->pdcp_Config->drb->integrityProtection = NR_PDCP_Config__drb__integrityProtection_enabled;
|
||||
asn1cCallocOne(drb->integrityProtection, NR_PDCP_Config__drb__integrityProtection_enabled);
|
||||
}
|
||||
|
||||
if (!do_drb_ciphering) {
|
||||
DRB_config->pdcp_Config->ext1 = calloc(1, sizeof(*DRB_config->pdcp_Config->ext1));
|
||||
DRB_config->pdcp_Config->ext1->cipheringDisabled = calloc(1, sizeof(*DRB_config->pdcp_Config->ext1->cipheringDisabled));
|
||||
*DRB_config->pdcp_Config->ext1->cipheringDisabled = NR_PDCP_Config__ext1__cipheringDisabled_true;
|
||||
asn1cCalloc(pdcpConfig->ext1, ext1);
|
||||
asn1cCallocOne(ext1->cipheringDisabled, NR_PDCP_Config__ext1__cipheringDisabled_true);
|
||||
}
|
||||
|
||||
ue->DRB_active[drb_id-1] = DRB_ACTIVE;
|
||||
@@ -104,7 +98,7 @@ NR_DRB_ToAddMod_t *generateDRB(gNB_RRC_UE_t *ue, uint8_t drb_id, pdu_session_par
|
||||
return DRB_config;
|
||||
}
|
||||
|
||||
uint8_t next_available_drb(gNB_RRC_UE_t *ue, pdu_session_param_t *pdusession, bool is_gbr)
|
||||
uint8_t next_available_drb(gNB_RRC_UE_t *ue, rrc_pdu_session_param_t *pdusession, bool is_gbr)
|
||||
{
|
||||
uint8_t drb_id;
|
||||
|
||||
|
||||
@@ -35,10 +35,10 @@
|
||||
#define GBR_FLOW (1)
|
||||
#define NONGBR_FLOW (0)
|
||||
|
||||
NR_DRB_ToAddMod_t *generateDRB(gNB_RRC_UE_t *rrc_ue, uint8_t drb_id, pdu_session_param_t *pduSession, bool enable_sdap, int do_drb_integrity, int do_drb_ciphering);
|
||||
|
||||
uint8_t next_available_drb(gNB_RRC_UE_t *ue, pdu_session_param_t *pdusession, bool is_gbr);
|
||||
|
||||
NR_DRB_ToAddMod_t *generateDRB(gNB_RRC_UE_t *rrc_ue, uint8_t drb_id, rrc_pdu_session_param_t *pduSession, bool enable_sdap, int do_drb_integrity, int do_drb_ciphering);
|
||||
uint8_t next_available_drb(gNB_RRC_UE_t *ue, rrc_pdu_session_param_t *pdusession, bool is_gbr);
|
||||
bool drb_is_active(gNB_RRC_UE_t *ue, uint8_t drb_id);
|
||||
|
||||
rrc_pdu_session_param_t *find_pduSession(gNB_RRC_UE_t *ue, int id, bool create);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -435,14 +435,9 @@ nr_sdap_entity_t *new_nr_sdap_entity(int is_gnb, bool has_sdap_rx, bool has_sdap
|
||||
if(is_defaultDRB) {
|
||||
sdap_entity->default_drb = drb_identity;
|
||||
LOG_I(SDAP, "Default DRB for the created SDAP entity: %ld \n", sdap_entity->default_drb);
|
||||
|
||||
if(mappedQFIs2AddCount) {
|
||||
LOG_D(SDAP, "RRC updating mapping rules\n");
|
||||
for (int i = 0; i < mappedQFIs2AddCount; i++)
|
||||
{
|
||||
sdap_entity->qfi2drb_map_update(sdap_entity, mapped_qfi_2_add[i], sdap_entity->default_drb, has_sdap_rx, has_sdap_tx);
|
||||
}
|
||||
}
|
||||
LOG_D(SDAP, "RRC updating mapping rules: %d\n", mappedQFIs2AddCount);
|
||||
for (int i = 0; i < mappedQFIs2AddCount; i++)
|
||||
sdap_entity->qfi2drb_map_update(sdap_entity, mapped_qfi_2_add[i], sdap_entity->default_drb, has_sdap_rx, has_sdap_tx);
|
||||
}
|
||||
|
||||
sdap_entity->next_entity = sdap_info.sdap_entity_llist;
|
||||
|
||||
@@ -43,7 +43,7 @@ void x2ap_eNB_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uin
|
||||
sctp_data_req->assoc_id = assoc_id;
|
||||
sctp_data_req->buffer = buffer;
|
||||
sctp_data_req->buffer_length = buffer_length;
|
||||
sctp_data_req->stream = stream;
|
||||
sctp_data_req->stream = stream;
|
||||
|
||||
itti_send_msg_to_task(TASK_SCTP, instance, message_p);
|
||||
}
|
||||
|
||||
@@ -859,6 +859,7 @@ void *nas_nrue_task(void *args_p)
|
||||
instance = msg_p->ittiMsgHeader.originInstance;
|
||||
Mod_id = instance ;
|
||||
uicc_t *uicc=checkUicc(Mod_id);
|
||||
LOG_I(NAS, "[UE %d] Received %s\n", Mod_id, ITTI_MSG_NAME(msg_p));
|
||||
|
||||
if (instance == INSTANCE_DEFAULT) {
|
||||
printf("%s:%d: FATAL: instance is INSTANCE_DEFAULT, should not happen.\n",
|
||||
@@ -867,84 +868,83 @@ void *nas_nrue_task(void *args_p)
|
||||
}
|
||||
|
||||
switch (ITTI_MSG_ID(msg_p)) {
|
||||
case INITIALIZE_MESSAGE:
|
||||
LOG_I(NAS, "[UE %d] Received %s\n", Mod_id, ITTI_MSG_NAME (msg_p));
|
||||
case INITIALIZE_MESSAGE:
|
||||
|
||||
break;
|
||||
break;
|
||||
|
||||
case TERMINATE_MESSAGE:
|
||||
itti_exit_task ();
|
||||
break;
|
||||
case TERMINATE_MESSAGE:
|
||||
itti_exit_task();
|
||||
break;
|
||||
|
||||
case MESSAGE_TEST:
|
||||
LOG_I(NAS, "[UE %d] Received %s\n", Mod_id, ITTI_MSG_NAME (msg_p));
|
||||
break;
|
||||
case MESSAGE_TEST:
|
||||
break;
|
||||
|
||||
case NAS_CELL_SELECTION_CNF:
|
||||
LOG_I(NAS, "[UE %d] Received %s: errCode %u, cellID %u, tac %u\n", Mod_id, ITTI_MSG_NAME (msg_p),
|
||||
NAS_CELL_SELECTION_CNF (msg_p).errCode, NAS_CELL_SELECTION_CNF (msg_p).cellID, NAS_CELL_SELECTION_CNF (msg_p).tac);
|
||||
// as_stmsi_t s_tmsi={0, 0};
|
||||
// as_nas_info_t nas_info;
|
||||
// plmn_t plmnID={0, 0, 0, 0};
|
||||
// generateRegistrationRequest(&nas_info);
|
||||
// nr_nas_itti_nas_establish_req(0, AS_TYPE_ORIGINATING_SIGNAL, s_tmsi, plmnID, nas_info.data, nas_info.length, 0);
|
||||
break;
|
||||
case NAS_CELL_SELECTION_CNF:
|
||||
LOG_I(NAS,
|
||||
"[UE %d] Received %s: errCode %u, cellID %u, tac %u\n",
|
||||
Mod_id,
|
||||
ITTI_MSG_NAME(msg_p),
|
||||
NAS_CELL_SELECTION_CNF(msg_p).errCode,
|
||||
NAS_CELL_SELECTION_CNF(msg_p).cellID,
|
||||
NAS_CELL_SELECTION_CNF(msg_p).tac);
|
||||
// as_stmsi_t s_tmsi={0, 0};
|
||||
// as_nas_info_t nas_info;
|
||||
// plmn_t plmnID={0, 0, 0, 0};
|
||||
// generateRegistrationRequest(&nas_info);
|
||||
// nr_nas_itti_nas_establish_req(0, AS_TYPE_ORIGINATING_SIGNAL, s_tmsi, plmnID, nas_info.data, nas_info.length, 0);
|
||||
break;
|
||||
|
||||
case NAS_CELL_SELECTION_IND:
|
||||
LOG_I(NAS, "[UE %d] Received %s: cellID %u, tac %u\n", Mod_id, ITTI_MSG_NAME (msg_p),
|
||||
NAS_CELL_SELECTION_IND (msg_p).cellID, NAS_CELL_SELECTION_IND (msg_p).tac);
|
||||
case NAS_CELL_SELECTION_IND:
|
||||
LOG_I(NAS, "[UE %d] Received %s: cellID %u, tac %u\n", Mod_id, ITTI_MSG_NAME(msg_p), NAS_CELL_SELECTION_IND(msg_p).cellID, NAS_CELL_SELECTION_IND(msg_p).tac);
|
||||
|
||||
/* TODO not processed by NAS currently */
|
||||
break;
|
||||
/* TODO not processed by NAS currently */
|
||||
break;
|
||||
|
||||
case NAS_PAGING_IND:
|
||||
LOG_I(NAS, "[UE %d] Received %s: cause %u\n", Mod_id, ITTI_MSG_NAME (msg_p),
|
||||
NAS_PAGING_IND (msg_p).cause);
|
||||
case NAS_PAGING_IND:
|
||||
LOG_I(NAS, "[UE %d] Received %s: cause %u\n", Mod_id, ITTI_MSG_NAME(msg_p), NAS_PAGING_IND(msg_p).cause);
|
||||
|
||||
/* TODO not processed by NAS currently */
|
||||
break;
|
||||
/* TODO not processed by NAS currently */
|
||||
break;
|
||||
|
||||
case NAS_CONN_ESTABLI_CNF:
|
||||
{
|
||||
LOG_I(NAS, "[UE %d] Received %s: errCode %u, length %u\n", Mod_id, ITTI_MSG_NAME (msg_p),
|
||||
NAS_CONN_ESTABLI_CNF (msg_p).errCode, NAS_CONN_ESTABLI_CNF (msg_p).nasMsg.length);
|
||||
case NAS_CONN_ESTABLI_CNF: {
|
||||
LOG_I(NAS, "[UE %d] Received %s: errCode %u, length %u\n", Mod_id, ITTI_MSG_NAME(msg_p), NAS_CONN_ESTABLI_CNF(msg_p).errCode, NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length);
|
||||
|
||||
pdu_buffer = NAS_CONN_ESTABLI_CNF (msg_p).nasMsg.data;
|
||||
msg_type = get_msg_type(pdu_buffer, NAS_CONN_ESTABLI_CNF (msg_p).nasMsg.length);
|
||||
pdu_buffer = NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.data;
|
||||
msg_type = get_msg_type(pdu_buffer, NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length);
|
||||
|
||||
if(msg_type == REGISTRATION_ACCEPT){
|
||||
LOG_I(NAS, "[UE] Received REGISTRATION ACCEPT message\n");
|
||||
if (msg_type == REGISTRATION_ACCEPT) {
|
||||
LOG_I(NAS, "[UE] Received REGISTRATION ACCEPT message\n");
|
||||
|
||||
as_nas_info_t initialNasMsg;
|
||||
memset(&initialNasMsg, 0, sizeof(as_nas_info_t));
|
||||
generateRegistrationComplete(Mod_id,&initialNasMsg, NULL);
|
||||
if(initialNasMsg.length > 0){
|
||||
MessageDef *message_p;
|
||||
message_p = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_UPLINK_DATA_REQ);
|
||||
NAS_UPLINK_DATA_REQ(message_p).UEid = Mod_id;
|
||||
NAS_UPLINK_DATA_REQ(message_p).nasMsg.data = (uint8_t *)initialNasMsg.data;
|
||||
NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = initialNasMsg.length;
|
||||
itti_send_msg_to_task(TASK_RRC_NRUE, instance, message_p);
|
||||
LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(RegistrationComplete)\n");
|
||||
as_nas_info_t initialNasMsg;
|
||||
memset(&initialNasMsg, 0, sizeof(as_nas_info_t));
|
||||
generateRegistrationComplete(Mod_id, &initialNasMsg, NULL);
|
||||
if (initialNasMsg.length > 0) {
|
||||
MessageDef *message_p;
|
||||
message_p = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_UPLINK_DATA_REQ);
|
||||
NAS_UPLINK_DATA_REQ(message_p).UEid = Mod_id;
|
||||
NAS_UPLINK_DATA_REQ(message_p).nasMsg.data = (uint8_t *)initialNasMsg.data;
|
||||
NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = initialNasMsg.length;
|
||||
itti_send_msg_to_task(TASK_RRC_NRUE, instance, message_p);
|
||||
LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(RegistrationComplete)\n");
|
||||
}
|
||||
|
||||
as_nas_info_t pduEstablishMsg;
|
||||
memset(&pduEstablishMsg, 0, sizeof(as_nas_info_t));
|
||||
generatePduSessionEstablishRequest(Mod_id, uicc, &pduEstablishMsg);
|
||||
if (pduEstablishMsg.length > 0) {
|
||||
MessageDef *message_p;
|
||||
message_p = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_UPLINK_DATA_REQ);
|
||||
NAS_UPLINK_DATA_REQ(message_p).UEid = Mod_id;
|
||||
NAS_UPLINK_DATA_REQ(message_p).nasMsg.data = (uint8_t *)pduEstablishMsg.data;
|
||||
NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = pduEstablishMsg.length;
|
||||
itti_send_msg_to_task(TASK_RRC_NRUE, instance, message_p);
|
||||
LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(PduSessionEstablishRequest)\n");
|
||||
}
|
||||
} else if (msg_type == FGS_PDU_SESSION_ESTABLISHMENT_ACC) {
|
||||
capture_pdu_session_establishment_accept_msg(pdu_buffer, NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length);
|
||||
}
|
||||
|
||||
as_nas_info_t pduEstablishMsg;
|
||||
memset(&pduEstablishMsg, 0, sizeof(as_nas_info_t));
|
||||
generatePduSessionEstablishRequest(Mod_id, uicc, &pduEstablishMsg);
|
||||
if(pduEstablishMsg.length > 0){
|
||||
MessageDef *message_p;
|
||||
message_p = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_UPLINK_DATA_REQ);
|
||||
NAS_UPLINK_DATA_REQ(message_p).UEid = Mod_id;
|
||||
NAS_UPLINK_DATA_REQ(message_p).nasMsg.data = (uint8_t *)pduEstablishMsg.data;
|
||||
NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = pduEstablishMsg.length;
|
||||
itti_send_msg_to_task(TASK_RRC_NRUE, instance, message_p);
|
||||
LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(PduSessionEstablishRequest)\n");
|
||||
}
|
||||
} else if(msg_type == FGS_PDU_SESSION_ESTABLISHMENT_ACC){
|
||||
capture_pdu_session_establishment_accept_msg(pdu_buffer, NAS_CONN_ESTABLI_CNF (msg_p).nasMsg.length);
|
||||
}
|
||||
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
case NAS_CONN_RELEASE_IND:
|
||||
|
||||
+20
-20
@@ -113,27 +113,27 @@ extern int asn1_xer_print;
|
||||
# define NGAP_DEBUG(x, args...) do { fprintf(stdout, "[NGAP][D]"x, ##args); } while(0)
|
||||
#endif
|
||||
|
||||
#define NGAP_FIND_PROTOCOLIE_BY_ID(IE_TYPE, ie, container, IE_ID, mandatory) \
|
||||
do { \
|
||||
IE_TYPE **ptr; \
|
||||
ie = NULL; \
|
||||
for (ptr = container->protocolIEs.list.array; ptr < &container->protocolIEs.list.array[container->protocolIEs.list.count]; ptr++) { \
|
||||
if ((*ptr)->id == IE_ID) { \
|
||||
ie = *ptr; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
if (ie == NULL) { \
|
||||
if (mandatory) { \
|
||||
AssertFatal(NGAP, "NGAP_FIND_PROTOCOLIE_BY_ID ie is NULL (searching for ie: %ld)\n", IE_ID); \
|
||||
} else { \
|
||||
NGAP_INFO("NGAP_FIND_PROTOCOLIE_BY_ID ie is NULL (searching for ie: %ld)\n", IE_ID); \
|
||||
} \
|
||||
} \
|
||||
} while (0); \
|
||||
if (mandatory && !ie) \
|
||||
return -1
|
||||
|
||||
#define NGAP_FIND_PROTOCOLIE_BY_ID(IE_TYPE, ie, container, IE_ID, mandatory) \
|
||||
do {\
|
||||
IE_TYPE **ptr; \
|
||||
ie = NULL; \
|
||||
for (ptr = container->protocolIEs.list.array; \
|
||||
ptr < &container->protocolIEs.list.array[container->protocolIEs.list.count]; \
|
||||
ptr++) { \
|
||||
if((*ptr)->id == IE_ID) { \
|
||||
ie = *ptr; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
if (ie == NULL ) { \
|
||||
if (mandatory) {\
|
||||
NGAP_ERROR("NGAP_FIND_PROTOCOLIE_BY_ID: %s %d: ie is NULL (searching for ie: %ld)\n",__FILE__,__LINE__, IE_ID);\
|
||||
abort();\
|
||||
}\
|
||||
else NGAP_INFO("NGAP_FIND_PROTOCOLIE_BY_ID: %s %d: ie is NULL (searching for ie: %ld)\n",__FILE__,__LINE__, IE_ID);\
|
||||
} \
|
||||
} while(0)
|
||||
/** \brief Function callback prototype.
|
||||
**/
|
||||
typedef int (*ngap_message_decoded_callback)(
|
||||
|
||||
+77
-117
@@ -162,7 +162,6 @@ void ngap_gNB_handle_register_gNB(instance_t instance, ngap_register_gnb_req_t *
|
||||
} else {
|
||||
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_amf_head);
|
||||
/* Copy usefull parameters */
|
||||
new_instance->instance = instance;
|
||||
@@ -276,127 +275,88 @@ void *ngap_gNB_process_itti_msg(void *notUsed) {
|
||||
MessageDef *received_msg = NULL;
|
||||
int result;
|
||||
itti_receive_msg(TASK_NGAP, &received_msg);
|
||||
if (received_msg) {
|
||||
instance_t instance = ITTI_MSG_DESTINATION_INSTANCE(received_msg);
|
||||
LOG_D(RRC, "Received message %s\n", ITTI_MSG_NAME(received_msg));
|
||||
switch (ITTI_MSG_ID(received_msg)) {
|
||||
case TERMINATE_MESSAGE:
|
||||
NGAP_WARN(" *** Exiting NGAP thread\n");
|
||||
itti_exit_task();
|
||||
break;
|
||||
|
||||
switch (ITTI_MSG_ID(received_msg)) {
|
||||
case TERMINATE_MESSAGE:
|
||||
NGAP_WARN(" *** Exiting NGAP thread\n");
|
||||
itti_exit_task();
|
||||
break;
|
||||
case NGAP_REGISTER_GNB_REQ:
|
||||
/* Register a new gNB.
|
||||
* in Virtual mode gNBs will be distinguished using the mod_id/
|
||||
* Each gNB has to send an NGAP_REGISTER_GNB message with its
|
||||
* own parameters.
|
||||
*/
|
||||
ngap_gNB_handle_register_gNB(instance, &NGAP_REGISTER_GNB_REQ(received_msg));
|
||||
break;
|
||||
|
||||
case NGAP_REGISTER_GNB_REQ: {
|
||||
/* Register a new gNB.
|
||||
* in Virtual mode gNBs will be distinguished using the mod_id/
|
||||
* Each gNB has to send an NGAP_REGISTER_GNB message with its
|
||||
* own parameters.
|
||||
*/
|
||||
ngap_gNB_handle_register_gNB(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&NGAP_REGISTER_GNB_REQ(received_msg));
|
||||
case SCTP_NEW_ASSOCIATION_RESP:
|
||||
ngap_gNB_handle_sctp_association_resp(instance, &received_msg->ittiMsg.sctp_new_association_resp);
|
||||
break;
|
||||
|
||||
case SCTP_DATA_IND:
|
||||
ngap_gNB_handle_sctp_data_ind(&received_msg->ittiMsg.sctp_data_ind);
|
||||
break;
|
||||
|
||||
case NGAP_NAS_FIRST_REQ:
|
||||
ngap_gNB_handle_nas_first_req(instance, &NGAP_NAS_FIRST_REQ(received_msg));
|
||||
break;
|
||||
|
||||
case NGAP_UPLINK_NAS:
|
||||
ngap_gNB_nas_uplink(instance, &NGAP_UPLINK_NAS(received_msg));
|
||||
break;
|
||||
|
||||
case NGAP_UE_CAPABILITIES_IND:
|
||||
ngap_gNB_ue_capabilities(instance, &NGAP_UE_CAPABILITIES_IND(received_msg));
|
||||
break;
|
||||
|
||||
case NGAP_INITIAL_CONTEXT_SETUP_RESP:
|
||||
ngap_gNB_initial_ctxt_resp(instance, &NGAP_INITIAL_CONTEXT_SETUP_RESP(received_msg));
|
||||
break;
|
||||
|
||||
case NGAP_PDUSESSION_SETUP_RESP:
|
||||
ngap_gNB_pdusession_setup_resp(instance, &NGAP_PDUSESSION_SETUP_RESP(received_msg));
|
||||
break;
|
||||
|
||||
case NGAP_PDUSESSION_MODIFY_RESP:
|
||||
ngap_gNB_pdusession_modify_resp(instance, &NGAP_PDUSESSION_MODIFY_RESP(received_msg));
|
||||
break;
|
||||
|
||||
case NGAP_NAS_NON_DELIVERY_IND:
|
||||
ngap_gNB_nas_non_delivery_ind(instance, &NGAP_NAS_NON_DELIVERY_IND(received_msg));
|
||||
break;
|
||||
|
||||
case NGAP_PATH_SWITCH_REQ:
|
||||
ngap_gNB_path_switch_req(instance, &NGAP_PATH_SWITCH_REQ(received_msg));
|
||||
break;
|
||||
|
||||
case NGAP_PDUSESSION_MODIFICATION_IND:
|
||||
ngap_gNB_generate_PDUSESSION_Modification_Indication(instance, &NGAP_PDUSESSION_MODIFICATION_IND(received_msg));
|
||||
break;
|
||||
|
||||
case NGAP_UE_CONTEXT_RELEASE_COMPLETE:
|
||||
ngap_ue_context_release_complete(instance, &NGAP_UE_CONTEXT_RELEASE_COMPLETE(received_msg));
|
||||
break;
|
||||
|
||||
case NGAP_UE_CONTEXT_RELEASE_REQ:
|
||||
ngap_ue_context_release_req(instance, &NGAP_UE_CONTEXT_RELEASE_REQ(received_msg));
|
||||
break;
|
||||
|
||||
case NGAP_PDUSESSION_RELEASE_RESPONSE:
|
||||
ngap_gNB_pdusession_release_resp(instance, &NGAP_PDUSESSION_RELEASE_RESPONSE(received_msg));
|
||||
break;
|
||||
|
||||
default:
|
||||
NGAP_ERROR("Received unhandled message: %d:%s\n", ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case SCTP_NEW_ASSOCIATION_RESP: {
|
||||
ngap_gNB_handle_sctp_association_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&received_msg->ittiMsg.sctp_new_association_resp);
|
||||
}
|
||||
break;
|
||||
|
||||
case SCTP_DATA_IND: {
|
||||
ngap_gNB_handle_sctp_data_ind(&received_msg->ittiMsg.sctp_data_ind);
|
||||
}
|
||||
break;
|
||||
|
||||
case NGAP_NAS_FIRST_REQ: {
|
||||
ngap_gNB_handle_nas_first_req(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&NGAP_NAS_FIRST_REQ(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
case NGAP_UPLINK_NAS: {
|
||||
ngap_gNB_nas_uplink(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&NGAP_UPLINK_NAS(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
case NGAP_UE_CAPABILITIES_IND: {
|
||||
ngap_gNB_ue_capabilities(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&NGAP_UE_CAPABILITIES_IND(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
case NGAP_INITIAL_CONTEXT_SETUP_RESP: {
|
||||
ngap_gNB_initial_ctxt_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&NGAP_INITIAL_CONTEXT_SETUP_RESP(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
case NGAP_PDUSESSION_SETUP_RESP: {
|
||||
ngap_gNB_pdusession_setup_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&NGAP_PDUSESSION_SETUP_RESP(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
case NGAP_PDUSESSION_MODIFY_RESP: {
|
||||
ngap_gNB_pdusession_modify_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&NGAP_PDUSESSION_MODIFY_RESP(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
case NGAP_NAS_NON_DELIVERY_IND: {
|
||||
ngap_gNB_nas_non_delivery_ind(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&NGAP_NAS_NON_DELIVERY_IND(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
case NGAP_PATH_SWITCH_REQ: {
|
||||
ngap_gNB_path_switch_req(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&NGAP_PATH_SWITCH_REQ(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
case NGAP_PDUSESSION_MODIFICATION_IND: {
|
||||
ngap_gNB_generate_PDUSESSION_Modification_Indication(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&NGAP_PDUSESSION_MODIFICATION_IND(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
case NGAP_UE_CONTEXT_RELEASE_COMPLETE: {
|
||||
ngap_ue_context_release_complete(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&NGAP_UE_CONTEXT_RELEASE_COMPLETE(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
case NGAP_UE_CONTEXT_RELEASE_REQ: {
|
||||
ngap_gNB_instance_t *ngap_gNB_instance_p = NULL; // test
|
||||
struct ngap_gNB_ue_context_s *ue_context_p = NULL; // test
|
||||
ngap_ue_context_release_req(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&NGAP_UE_CONTEXT_RELEASE_REQ(received_msg));
|
||||
ngap_gNB_instance_p = ngap_gNB_get_instance(ITTI_MSG_DESTINATION_INSTANCE(received_msg)); // test
|
||||
DevAssert(ngap_gNB_instance_p != NULL); // test
|
||||
|
||||
if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p,
|
||||
NGAP_UE_CONTEXT_RELEASE_REQ(received_msg).gNB_ue_ngap_id)) == NULL) { // test
|
||||
/* The context for this gNB ue ngap id doesn't exist in the map of gNB UEs */
|
||||
NGAP_ERROR("Failed to find ue context associated with gNB ue ngap id: %u\n",
|
||||
NGAP_UE_CONTEXT_RELEASE_REQ(received_msg).gNB_ue_ngap_id); // test
|
||||
} // test
|
||||
}
|
||||
break;
|
||||
|
||||
case NGAP_PDUSESSION_RELEASE_RESPONSE: {
|
||||
ngap_gNB_pdusession_release_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&NGAP_PDUSESSION_RELEASE_RESPONSE(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
NGAP_ERROR("Received unhandled message: %d:%s\n",
|
||||
ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg));
|
||||
break;
|
||||
result = itti_free(ITTI_MSG_ORIGIN_ID(received_msg), received_msg);
|
||||
AssertFatal(result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
|
||||
}
|
||||
|
||||
result = itti_free (ITTI_MSG_ORIGIN_ID(received_msg), received_msg);
|
||||
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
|
||||
received_msg = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -58,9 +58,7 @@ int ngap_ue_context_release_complete(instance_t instance,
|
||||
|
||||
ngap_gNB_instance_t *ngap_gNB_instance_p = NULL;
|
||||
struct ngap_gNB_ue_context_s *ue_context_p = NULL;
|
||||
NGAP_NGAP_PDU_t pdu;
|
||||
NGAP_UEContextReleaseComplete_t *out;
|
||||
NGAP_UEContextReleaseComplete_IEs_t *ie;
|
||||
NGAP_NGAP_PDU_t pdu = {0};
|
||||
uint8_t *buffer;
|
||||
uint32_t length;
|
||||
|
||||
@@ -70,44 +68,37 @@ int ngap_ue_context_release_complete(instance_t instance,
|
||||
DevAssert(ue_release_complete_p != NULL);
|
||||
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 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,
|
||||
ue_release_complete_p->gNB_ue_ngap_id)) == NULL) {
|
||||
if ((ue_context_p = ngap_get_ue_context(ue_release_complete_p->gNB_ue_ngap_id)) == NULL) {
|
||||
/* The context for this gNB ue ngap id doesn't exist in the map of gNB UEs */
|
||||
NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: %u\n",
|
||||
ue_release_complete_p->gNB_ue_ngap_id);
|
||||
NGAP_ERROR("Failed to find ue context associated with gNB ue ngap id: %u\n", ue_release_complete_p->gNB_ue_ngap_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Prepare the NGAP message to encode */
|
||||
memset(&pdu, 0, sizeof(pdu));
|
||||
pdu.present = NGAP_NGAP_PDU_PR_successfulOutcome;
|
||||
pdu.choice.successfulOutcome = CALLOC(1, sizeof(struct NGAP_SuccessfulOutcome));
|
||||
pdu.choice.successfulOutcome->procedureCode = NGAP_ProcedureCode_id_UEContextRelease;
|
||||
pdu.choice.successfulOutcome->criticality = NGAP_Criticality_reject;
|
||||
pdu.choice.successfulOutcome->value.present = NGAP_SuccessfulOutcome__value_PR_UEContextReleaseComplete;
|
||||
out = &pdu.choice.successfulOutcome->value.choice.UEContextReleaseComplete;
|
||||
asn1cCalloc(pdu.choice.successfulOutcome, head);
|
||||
head->procedureCode = NGAP_ProcedureCode_id_UEContextRelease;
|
||||
head->criticality = NGAP_Criticality_reject;
|
||||
head->value.present = NGAP_SuccessfulOutcome__value_PR_UEContextReleaseComplete;
|
||||
NGAP_UEContextReleaseComplete_t *out = &head->value.choice.UEContextReleaseComplete;
|
||||
|
||||
/* mandatory */
|
||||
ie = (NGAP_UEContextReleaseComplete_IEs_t *)calloc(1, sizeof(NGAP_UEContextReleaseComplete_IEs_t));
|
||||
ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID;
|
||||
ie->criticality = NGAP_Criticality_ignore;
|
||||
ie->value.present = NGAP_UEContextReleaseComplete_IEs__value_PR_AMF_UE_NGAP_ID;
|
||||
asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id);
|
||||
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
||||
{
|
||||
asn1cSequenceAdd(out->protocolIEs.list, NGAP_UEContextReleaseComplete_IEs_t, ie);
|
||||
ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID;
|
||||
ie->criticality = NGAP_Criticality_ignore;
|
||||
ie->value.present = NGAP_UEContextReleaseComplete_IEs__value_PR_AMF_UE_NGAP_ID;
|
||||
asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id);
|
||||
}
|
||||
|
||||
/* mandatory */
|
||||
ie = (NGAP_UEContextReleaseComplete_IEs_t *)calloc(1, sizeof(NGAP_UEContextReleaseComplete_IEs_t));
|
||||
ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID;
|
||||
ie->criticality = NGAP_Criticality_ignore;
|
||||
ie->value.present = NGAP_UEContextReleaseComplete_IEs__value_PR_RAN_UE_NGAP_ID;
|
||||
ie->value.choice.RAN_UE_NGAP_ID = ue_release_complete_p->gNB_ue_ngap_id;
|
||||
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
||||
|
||||
{
|
||||
asn1cSequenceAdd(out->protocolIEs.list, NGAP_UEContextReleaseComplete_IEs_t, ie);
|
||||
ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID;
|
||||
ie->criticality = NGAP_Criticality_ignore;
|
||||
ie->value.present = NGAP_UEContextReleaseComplete_IEs__value_PR_RAN_UE_NGAP_ID;
|
||||
ie->value.choice.RAN_UE_NGAP_ID = ue_release_complete_p->gNB_ue_ngap_id;
|
||||
}
|
||||
|
||||
if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) {
|
||||
/* Encode procedure has failed... */
|
||||
@@ -123,35 +114,18 @@ int ngap_ue_context_release_complete(instance_t instance,
|
||||
//LG ngap_gNB_itti_send_sctp_close_association(ngap_gNB_instance_p->instance,
|
||||
// ue_context_p->amf_ref->assoc_id);
|
||||
// release UE context
|
||||
struct ngap_gNB_ue_context_s *ue_context2_p = NULL;
|
||||
|
||||
if ((ue_context2_p = RB_REMOVE(ngap_ue_map, &ngap_gNB_instance_p->ngap_ue_head, ue_context_p))
|
||||
!= NULL) {
|
||||
NGAP_WARN("Removed UE context gNB_ue_ngap_id %u\n",
|
||||
ue_context2_p->gNB_ue_ngap_id);
|
||||
ngap_gNB_free_ue_context(ue_context2_p);
|
||||
} else {
|
||||
NGAP_WARN("Removing UE context gNB_ue_ngap_id %u: did not find context\n",
|
||||
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 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);
|
||||
}*/
|
||||
|
||||
ngap_gNB_ue_context_t *tmp = ngap_detach_ue_context(ue_release_complete_p->gNB_ue_ngap_id);
|
||||
if (tmp)
|
||||
free(tmp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int ngap_ue_context_release_req(instance_t instance,
|
||||
ngap_ue_release_req_t *ue_release_req_p)
|
||||
{
|
||||
ngap_gNB_instance_t *ngap_gNB_instance_p = NULL;
|
||||
struct ngap_gNB_ue_context_s *ue_context_p = NULL;
|
||||
NGAP_NGAP_PDU_t pdu;
|
||||
NGAP_UEContextReleaseRequest_t *out;
|
||||
NGAP_UEContextReleaseRequest_IEs_t *ie;
|
||||
NGAP_NGAP_PDU_t pdu = {0};
|
||||
uint8_t *buffer = NULL;
|
||||
uint32_t length;
|
||||
/* Retrieve the NGAP gNB instance associated with Mod_id */
|
||||
@@ -160,8 +134,7 @@ int ngap_ue_context_release_req(instance_t instance,
|
||||
DevAssert(ue_release_req_p != NULL);
|
||||
DevAssert(ngap_gNB_instance_p != NULL);
|
||||
|
||||
if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p,
|
||||
ue_release_req_p->gNB_ue_ngap_id)) == NULL) {
|
||||
if ((ue_context_p = ngap_get_ue_context(ue_release_req_p->gNB_ue_ngap_id)) == NULL) {
|
||||
/* The context for this gNB ue ngap id doesn't exist in the map of gNB UEs */
|
||||
NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: %u\n",
|
||||
ue_release_req_p->gNB_ue_ngap_id);
|
||||
@@ -169,33 +142,34 @@ int ngap_ue_context_release_req(instance_t instance,
|
||||
}
|
||||
|
||||
/* Prepare the NGAP message to encode */
|
||||
memset(&pdu, 0, sizeof(pdu));
|
||||
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
|
||||
pdu.choice.initiatingMessage = CALLOC(1, sizeof(struct NGAP_InitiatingMessage));
|
||||
pdu.choice.initiatingMessage->procedureCode = NGAP_ProcedureCode_id_UEContextReleaseRequest;
|
||||
pdu.choice.initiatingMessage->criticality = NGAP_Criticality_ignore;
|
||||
pdu.choice.initiatingMessage->value.present = NGAP_InitiatingMessage__value_PR_UEContextReleaseRequest;
|
||||
out = &pdu.choice.initiatingMessage->value.choice.UEContextReleaseRequest;
|
||||
asn1cCalloc(pdu.choice.initiatingMessage, head);
|
||||
head->procedureCode = NGAP_ProcedureCode_id_UEContextReleaseRequest;
|
||||
head->criticality = NGAP_Criticality_ignore;
|
||||
head->value.present = NGAP_InitiatingMessage__value_PR_UEContextReleaseRequest;
|
||||
NGAP_UEContextReleaseRequest_t *out = &head->value.choice.UEContextReleaseRequest;
|
||||
|
||||
/* mandatory */
|
||||
ie = (NGAP_UEContextReleaseRequest_IEs_t *)calloc(1, sizeof(NGAP_UEContextReleaseRequest_IEs_t));
|
||||
ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID;
|
||||
ie->criticality = NGAP_Criticality_reject;
|
||||
ie->value.present = NGAP_UEContextReleaseRequest_IEs__value_PR_AMF_UE_NGAP_ID;
|
||||
asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id);
|
||||
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
||||
{
|
||||
asn1cSequenceAdd(out->protocolIEs.list, NGAP_UEContextReleaseRequest_IEs_t, ie);
|
||||
ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID;
|
||||
ie->criticality = NGAP_Criticality_reject;
|
||||
ie->value.present = NGAP_UEContextReleaseRequest_IEs__value_PR_AMF_UE_NGAP_ID;
|
||||
asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id);
|
||||
}
|
||||
|
||||
/* mandatory */
|
||||
ie = (NGAP_UEContextReleaseRequest_IEs_t *)calloc(1, sizeof(NGAP_UEContextReleaseRequest_IEs_t));
|
||||
ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID;
|
||||
ie->criticality = NGAP_Criticality_reject;
|
||||
ie->value.present = NGAP_UEContextReleaseRequest_IEs__value_PR_RAN_UE_NGAP_ID;
|
||||
ie->value.choice.RAN_UE_NGAP_ID = ue_release_req_p->gNB_ue_ngap_id;
|
||||
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
||||
{
|
||||
asn1cSequenceAdd(out->protocolIEs.list, NGAP_UEContextReleaseRequest_IEs_t, ie);
|
||||
ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID;
|
||||
ie->criticality = NGAP_Criticality_reject;
|
||||
ie->value.present = NGAP_UEContextReleaseRequest_IEs__value_PR_RAN_UE_NGAP_ID;
|
||||
ie->value.choice.RAN_UE_NGAP_ID = ue_release_req_p->gNB_ue_ngap_id;
|
||||
}
|
||||
|
||||
/* optional */
|
||||
if (ue_release_req_p->nb_of_pdusessions > 0) {
|
||||
ie = (NGAP_UEContextReleaseRequest_IEs_t *)calloc(1, sizeof(NGAP_UEContextReleaseRequest_IEs_t));
|
||||
asn1cSequenceAdd(out->protocolIEs.list, NGAP_UEContextReleaseRequest_IEs_t, ie);
|
||||
ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceListCxtRelReq;
|
||||
ie->criticality = NGAP_Criticality_reject;
|
||||
ie->value.present = NGAP_UEContextReleaseRequest_IEs__value_PR_PDUSessionResourceListCxtRelReq;
|
||||
@@ -205,51 +179,19 @@ int ngap_ue_context_release_req(instance_t instance,
|
||||
item->pDUSessionID = ue_release_req_p->pdusessions[i].pdusession_id;
|
||||
asn1cSeqAdd(&ie->value.choice.PDUSessionResourceListCxtRelReq.list, item);
|
||||
}
|
||||
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
||||
}
|
||||
|
||||
/* mandatory */
|
||||
ie = (NGAP_UEContextReleaseRequest_IEs_t *)calloc(1, sizeof(NGAP_UEContextReleaseRequest_IEs_t));
|
||||
ie->id = NGAP_ProtocolIE_ID_id_Cause;
|
||||
ie->criticality = NGAP_Criticality_ignore;
|
||||
ie->value.present = NGAP_UEContextReleaseRequest_IEs__value_PR_Cause;
|
||||
|
||||
switch (ue_release_req_p->cause) {
|
||||
case NGAP_Cause_PR_radioNetwork:
|
||||
ie->value.choice.Cause.present = NGAP_Cause_PR_radioNetwork;
|
||||
ie->value.choice.Cause.choice.radioNetwork = ue_release_req_p->cause_value;
|
||||
break;
|
||||
|
||||
case NGAP_Cause_PR_transport:
|
||||
ie->value.choice.Cause.present = NGAP_Cause_PR_transport;
|
||||
ie->value.choice.Cause.choice.transport = ue_release_req_p->cause_value;
|
||||
break;
|
||||
|
||||
case NGAP_Cause_PR_nas:
|
||||
ie->value.choice.Cause.present = NGAP_Cause_PR_nas;
|
||||
ie->value.choice.Cause.choice.nas = ue_release_req_p->cause_value;
|
||||
break;
|
||||
|
||||
case NGAP_Cause_PR_protocol:
|
||||
ie->value.choice.Cause.present = NGAP_Cause_PR_protocol;
|
||||
ie->value.choice.Cause.choice.protocol = ue_release_req_p->cause_value;
|
||||
break;
|
||||
|
||||
case NGAP_Cause_PR_misc:
|
||||
ie->value.choice.Cause.present = NGAP_Cause_PR_misc;
|
||||
ie->value.choice.Cause.choice.misc = ue_release_req_p->cause_value;
|
||||
break;
|
||||
|
||||
case NGAP_Cause_PR_NOTHING:
|
||||
default:
|
||||
ie->value.choice.Cause.present = NGAP_Cause_PR_NOTHING;
|
||||
break;
|
||||
{
|
||||
asn1cSequenceAdd(out->protocolIEs.list, NGAP_UEContextReleaseRequest_IEs_t, ie);
|
||||
ie->id = NGAP_ProtocolIE_ID_id_Cause;
|
||||
ie->criticality = NGAP_Criticality_ignore;
|
||||
ie->value.present = NGAP_UEContextReleaseRequest_IEs__value_PR_Cause;
|
||||
DevAssert(ue_release_req_p->cause <= NGAP_Cause_PR_choice_ExtensionS);
|
||||
ie->value.choice.Cause.present = ue_release_req_p->cause;
|
||||
ie->value.choice.Cause.choice.misc = ue_release_req_p->cause_value;
|
||||
}
|
||||
|
||||
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
||||
|
||||
|
||||
|
||||
if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) {
|
||||
/* Encode procedure has failed... */
|
||||
NGAP_ERROR("Failed to encode UE context release complete\n");
|
||||
|
||||
@@ -156,13 +156,8 @@ int ngap_gNB_decode_pdu(NGAP_NGAP_PDU_t *pdu, const uint8_t *const buffer,
|
||||
asn_dec_rval_t dec_ret;
|
||||
DevAssert(pdu != NULL);
|
||||
DevAssert(buffer != NULL);
|
||||
dec_ret = aper_decode(NULL,
|
||||
&asn_DEF_NGAP_NGAP_PDU,
|
||||
(void **)&pdu,
|
||||
buffer,
|
||||
length,
|
||||
0,
|
||||
0);
|
||||
asn_codec_ctx_t st = {.max_stack_size = 100 * 1000}; // if we enable asn1c debug the stack size become large
|
||||
dec_ret = aper_decode(&st, &asn_DEF_NGAP_NGAP_PDU, (void **)&pdu, buffer, length, 0, 0);
|
||||
|
||||
if (dec_ret.code != RC_OK) {
|
||||
NGAP_ERROR("Failed to decode pdu\n");
|
||||
|
||||
@@ -236,11 +236,6 @@ typedef struct ngap_gNB_instance_s {
|
||||
/* 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 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;
|
||||
|
||||
/* For virtual mode, mod_id as defined in the rest of the L1/L2 stack */
|
||||
instance_t instance;
|
||||
|
||||
|
||||
@@ -38,23 +38,84 @@
|
||||
#include "ngap_common.h"
|
||||
#include "ngap_gNB_encoder.h"
|
||||
|
||||
static inline int ngap_gNB_encode_initiating(NGAP_NGAP_PDU_t *pdu,
|
||||
uint8_t **buffer,
|
||||
uint32_t *len);
|
||||
static inline int ngap_gNB_encode_initiating(NGAP_NGAP_PDU_t *pdu, uint8_t **buffer, uint32_t *len)
|
||||
{
|
||||
DevAssert(pdu != NULL);
|
||||
|
||||
static inline int ngap_gNB_encode_successfull_outcome(NGAP_NGAP_PDU_t *pdu,
|
||||
uint8_t **buffer, uint32_t *len);
|
||||
const NGAP_ProcedureCode_t tmp[] = {NGAP_ProcedureCode_id_NGSetup,
|
||||
NGAP_ProcedureCode_id_UplinkNASTransport,
|
||||
NGAP_ProcedureCode_id_UERadioCapabilityInfoIndication,
|
||||
NGAP_ProcedureCode_id_InitialUEMessage,
|
||||
NGAP_ProcedureCode_id_NASNonDeliveryIndication,
|
||||
NGAP_ProcedureCode_id_UEContextReleaseRequest,
|
||||
NGAP_ProcedureCode_id_PathSwitchRequest,
|
||||
NGAP_ProcedureCode_id_PDUSessionResourceModifyIndication};
|
||||
int i;
|
||||
for (i = 0; i < sizeofArray(tmp); i++)
|
||||
if (pdu->choice.initiatingMessage->procedureCode == tmp[i])
|
||||
break;
|
||||
if (i == sizeofArray(tmp)) {
|
||||
NGAP_DEBUG("Unknown procedure ID (%d) for initiating message\n", (int)pdu->choice.initiatingMessage->procedureCode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int ngap_gNB_encode_unsuccessfull_outcome(NGAP_NGAP_PDU_t *pdu,
|
||||
uint8_t **buffer, uint32_t *len);
|
||||
asn_encode_to_new_buffer_result_t res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
AssertFatal(res.result.encoded > 0, "failed to encode NGAP msg\n");
|
||||
*buffer = res.buffer;
|
||||
*len = res.result.encoded;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ngap_gNB_encode_pdu(NGAP_NGAP_PDU_t *pdu, uint8_t **buffer, uint32_t *len) {
|
||||
static inline int ngap_gNB_encode_successfull_outcome(NGAP_NGAP_PDU_t *pdu, uint8_t **buffer, uint32_t *len)
|
||||
{
|
||||
DevAssert(pdu != NULL);
|
||||
const NGAP_ProcedureCode_t tmp[] = {NGAP_ProcedureCode_id_InitialContextSetup,
|
||||
NGAP_ProcedureCode_id_UEContextRelease,
|
||||
NGAP_ProcedureCode_id_PDUSessionResourceSetup,
|
||||
NGAP_ProcedureCode_id_PDUSessionResourceModify,
|
||||
NGAP_ProcedureCode_id_PDUSessionResourceRelease};
|
||||
int i;
|
||||
for (i = 0; i < sizeofArray(tmp); i++)
|
||||
if (pdu->choice.successfulOutcome->procedureCode == tmp[i])
|
||||
break;
|
||||
if (i == sizeofArray(tmp)) {
|
||||
NGAP_WARN("Unknown procedure ID (%ld) for successfull outcome message\n", pdu->choice.successfulOutcome->procedureCode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
asn_encode_to_new_buffer_result_t res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
AssertFatal(res.result.encoded > 0, "failed to encode NGAP msg\n");
|
||||
*buffer = res.buffer;
|
||||
*len = res.result.encoded;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int ngap_gNB_encode_unsuccessfull_outcome(NGAP_NGAP_PDU_t *pdu, uint8_t **buffer, uint32_t *len)
|
||||
{
|
||||
DevAssert(pdu != NULL);
|
||||
|
||||
if (pdu->choice.unsuccessfulOutcome->procedureCode != NGAP_ProcedureCode_id_InitialContextSetup) {
|
||||
NGAP_DEBUG("Unknown procedure ID (%d) for unsuccessfull outcome message\n", (int)pdu->choice.unsuccessfulOutcome->procedureCode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
asn_encode_to_new_buffer_result_t res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
AssertFatal(res.result.encoded > 0, "failed to encode NGAP msg\n");
|
||||
*buffer = res.buffer;
|
||||
*len = res.result.encoded;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ngap_gNB_encode_pdu(NGAP_NGAP_PDU_t *pdu, uint8_t **buffer, uint32_t *len)
|
||||
{
|
||||
int ret = -1;
|
||||
DevAssert(pdu != NULL);
|
||||
DevAssert(buffer != NULL);
|
||||
DevAssert(len != NULL);
|
||||
|
||||
switch(pdu->present) {
|
||||
if (asn1_xer_print) {
|
||||
xer_fprint(stdout, &asn_DEF_NGAP_NGAP_PDU, (void *)pdu);
|
||||
}
|
||||
switch (pdu->present) {
|
||||
case NGAP_NGAP_PDU_PR_initiatingMessage:
|
||||
ret = ngap_gNB_encode_initiating(pdu, buffer, len);
|
||||
break;
|
||||
@@ -68,156 +129,9 @@ int ngap_gNB_encode_pdu(NGAP_NGAP_PDU_t *pdu, uint8_t **buffer, uint32_t *len) {
|
||||
break;
|
||||
|
||||
default:
|
||||
NGAP_DEBUG("Unknown message outcome (%d) or not implemented",
|
||||
(int)pdu->present);
|
||||
NGAP_DEBUG("Unknown message outcome (%d) or not implemented", (int)pdu->present);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline
|
||||
int ngap_gNB_encode_initiating(NGAP_NGAP_PDU_t *pdu,
|
||||
uint8_t **buffer, uint32_t *len) {
|
||||
asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} };
|
||||
DevAssert(pdu != NULL);
|
||||
|
||||
switch(pdu->choice.initiatingMessage->procedureCode) {
|
||||
case NGAP_ProcedureCode_id_NGSetup:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_UplinkNASTransport:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_UERadioCapabilityInfoIndication:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_InitialUEMessage:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_NASNonDeliveryIndication:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_UEContextReleaseRequest:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_PathSwitchRequest:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_PDUSessionResourceModifyIndication:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
default:
|
||||
NGAP_DEBUG("Unknown procedure ID (%d) for initiating message\n",
|
||||
(int)pdu->choice.initiatingMessage->procedureCode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (asn1_xer_print) {
|
||||
xer_fprint(stdout, &asn_DEF_NGAP_NGAP_PDU, (void *)pdu);
|
||||
}
|
||||
|
||||
memset(&res, 0, sizeof(res));
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
*buffer = res.buffer;
|
||||
*len = res.result.encoded;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline
|
||||
int ngap_gNB_encode_successfull_outcome(NGAP_NGAP_PDU_t *pdu,
|
||||
uint8_t **buffer, uint32_t *len) {
|
||||
asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} };
|
||||
DevAssert(pdu != NULL);
|
||||
|
||||
switch(pdu->choice.successfulOutcome->procedureCode) {
|
||||
case NGAP_ProcedureCode_id_InitialContextSetup:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_UEContextRelease:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_PDUSessionResourceSetup:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
NGAP_INFO("PDUSESSIONSetup successful message\n");
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_PDUSessionResourceModify:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
NGAP_INFO("PDUSESSIONModify successful message\n");
|
||||
break;
|
||||
|
||||
case NGAP_ProcedureCode_id_PDUSessionResourceRelease:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
NGAP_INFO("PDUSESSION Release successful message\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
NGAP_WARN("Unknown procedure ID (%d) for successfull outcome message\n",
|
||||
(int)pdu->choice.successfulOutcome->procedureCode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (asn1_xer_print) {
|
||||
xer_fprint(stdout, &asn_DEF_NGAP_NGAP_PDU, (void *)pdu);
|
||||
}
|
||||
|
||||
memset(&res, 0, sizeof(res));
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
*buffer = res.buffer;
|
||||
*len = res.result.encoded;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline
|
||||
int ngap_gNB_encode_unsuccessfull_outcome(NGAP_NGAP_PDU_t *pdu,
|
||||
uint8_t **buffer, uint32_t *len) {
|
||||
asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} };
|
||||
DevAssert(pdu != NULL);
|
||||
|
||||
switch(pdu->choice.unsuccessfulOutcome->procedureCode) {
|
||||
case NGAP_ProcedureCode_id_InitialContextSetup:
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
free(res.buffer);
|
||||
break;
|
||||
|
||||
default:
|
||||
NGAP_DEBUG("Unknown procedure ID (%d) for unsuccessfull outcome message\n",
|
||||
(int)pdu->choice.unsuccessfulOutcome->procedureCode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (asn1_xer_print) {
|
||||
xer_fprint(stdout, &asn_DEF_NGAP_NGAP_PDU, (void *)pdu);
|
||||
}
|
||||
|
||||
memset(&res, 0, sizeof(res));
|
||||
res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
*buffer = res.buffer;
|
||||
*len = res.result.encoded;
|
||||
return 0;
|
||||
}
|
||||
|
||||
+274
-833
File diff suppressed because it is too large
Load Diff
@@ -44,16 +44,12 @@ void ngap_gNB_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uin
|
||||
sctp_data_req->assoc_id = assoc_id;
|
||||
sctp_data_req->buffer = buffer;
|
||||
sctp_data_req->buffer_length = buffer_length;
|
||||
sctp_data_req->stream = stream;
|
||||
sctp_data_req->stream = stream;
|
||||
|
||||
itti_send_msg_to_task(TASK_SCTP, instance, message_p);
|
||||
}
|
||||
|
||||
void ngap_gNB_itti_send_nas_downlink_ind(instance_t instance,
|
||||
uint16_t ue_initial_id,
|
||||
uint32_t gNB_ue_ngap_id,
|
||||
uint8_t *nas_pdu,
|
||||
uint32_t nas_pdu_length)
|
||||
void ngap_gNB_itti_send_nas_downlink_ind(instance_t instance, uint32_t gNB_ue_ngap_id, uint8_t *nas_pdu, uint32_t nas_pdu_length)
|
||||
{
|
||||
MessageDef *message_p;
|
||||
ngap_downlink_nas_t *ngap_downlink_nas;
|
||||
@@ -62,7 +58,6 @@ void ngap_gNB_itti_send_nas_downlink_ind(instance_t instance,
|
||||
|
||||
ngap_downlink_nas = &message_p->ittiMsg.ngap_downlink_nas;
|
||||
|
||||
ngap_downlink_nas->ue_initial_id = ue_initial_id;
|
||||
ngap_downlink_nas->gNB_ue_ngap_id = gNB_ue_ngap_id;
|
||||
ngap_downlink_nas->nas_pdu.buffer = malloc(sizeof(uint8_t) * nas_pdu_length);
|
||||
memcpy(ngap_downlink_nas->nas_pdu.buffer, nas_pdu, nas_pdu_length);
|
||||
|
||||
@@ -33,11 +33,7 @@
|
||||
void ngap_gNB_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer,
|
||||
uint32_t buffer_length, uint16_t stream);
|
||||
|
||||
void ngap_gNB_itti_send_nas_downlink_ind(instance_t instance,
|
||||
uint16_t ue_initial_id,
|
||||
uint32_t gNB_ue_ngap_id,
|
||||
uint8_t *nas_pdu,
|
||||
uint32_t nas_pdu_length);
|
||||
void ngap_gNB_itti_send_nas_downlink_ind(instance_t instance, uint32_t gNB_ue_ngap_id, uint8_t *nas_pdu, uint32_t nas_pdu_length);
|
||||
|
||||
void ngap_gNB_itti_send_sctp_close_association(instance_t instance,
|
||||
int32_t assoc_id);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -30,23 +30,10 @@
|
||||
#ifndef NGAP_GNB_TRACE_H_
|
||||
#define NGAP_GNB_TRACE_H_
|
||||
|
||||
// int ngap_gNB_generate_trace_failure(sctp_data_t *sctp_data_p,
|
||||
// int32_t stream,
|
||||
// uint32_t gNB_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_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_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,
|
||||
uint32_t stream,
|
||||
NGAP_NGAP_PDU_t *pdu);
|
||||
|
||||
@@ -40,8 +40,15 @@
|
||||
#include "ngap_gNB_defs.h"
|
||||
#include "ngap_gNB_ue_context.h"
|
||||
|
||||
int ngap_gNB_compare_gNB_ue_ngap_id(
|
||||
struct ngap_gNB_ue_context_s *p1, struct ngap_gNB_ue_context_s *p2)
|
||||
/* Tree of UE ordered by gNB_ue_ngap_id's
|
||||
* NO INSTANCE, the 32 bits id is large enough to handle all UEs, regardless the cell, gNB, ...
|
||||
*/
|
||||
static RB_HEAD(ngap_ue_map, ngap_gNB_ue_context_s) ngap_ue_head = RB_INITIALIZER(&ngap_ue_head);
|
||||
|
||||
/* Generate the tree management functions prototypes */
|
||||
RB_PROTOTYPE(ngap_ue_map, ngap_gNB_ue_context_s, entries, ngap_gNB_compare_gNB_ue_ngap_id);
|
||||
|
||||
static int ngap_gNB_compare_gNB_ue_ngap_id(struct ngap_gNB_ue_context_s *p1, struct ngap_gNB_ue_context_s *p2)
|
||||
{
|
||||
if (p1->gNB_ue_ngap_id > p2->gNB_ue_ngap_id) {
|
||||
return 1;
|
||||
@@ -58,46 +65,26 @@ int ngap_gNB_compare_gNB_ue_ngap_id(
|
||||
RB_GENERATE(ngap_ue_map, ngap_gNB_ue_context_s, entries,
|
||||
ngap_gNB_compare_gNB_ue_ngap_id);
|
||||
|
||||
struct ngap_gNB_ue_context_s *ngap_gNB_allocate_new_UE_context(void)
|
||||
void ngap_store_ue_context(struct ngap_gNB_ue_context_s *ue_desc_p)
|
||||
{
|
||||
struct ngap_gNB_ue_context_s *new_p;
|
||||
if (RB_INSERT(ngap_ue_map, &ngap_ue_head, ue_desc_p))
|
||||
LOG_E(NGAP, "Bug in UE uniq number allocation %u, we try to add a existing UE\n", ue_desc_p->gNB_ue_ngap_id);
|
||||
return;
|
||||
}
|
||||
|
||||
new_p = malloc(sizeof(struct ngap_gNB_ue_context_s));
|
||||
struct ngap_gNB_ue_context_s *ngap_get_ue_context(uint32_t gNB_ue_ngap_id)
|
||||
{
|
||||
ngap_gNB_ue_context_t temp = {.gNB_ue_ngap_id = gNB_ue_ngap_id};
|
||||
return RB_FIND(ngap_ue_map, &ngap_ue_head, &temp);
|
||||
}
|
||||
|
||||
if (new_p == NULL) {
|
||||
NGAP_ERROR("Cannot allocate new ue context\n");
|
||||
struct ngap_gNB_ue_context_s *ngap_detach_ue_context(uint32_t gNB_ue_ngap_id)
|
||||
{
|
||||
struct ngap_gNB_ue_context_s *tmp = ngap_get_ue_context(gNB_ue_ngap_id);
|
||||
if (tmp == NULL) {
|
||||
NGAP_ERROR("Trying to free a NULL UE context, %u\n", gNB_ue_ngap_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(new_p, 0, sizeof(struct ngap_gNB_ue_context_s));
|
||||
|
||||
return new_p;
|
||||
}
|
||||
|
||||
struct ngap_gNB_ue_context_s *ngap_gNB_get_ue_context(
|
||||
ngap_gNB_instance_t *instance_p,
|
||||
uint32_t gNB_ue_ngap_id)
|
||||
{
|
||||
ngap_gNB_ue_context_t temp;
|
||||
|
||||
memset(&temp, 0, sizeof(struct ngap_gNB_ue_context_s));
|
||||
|
||||
/* gNB ue ngap id = 32 bits wide */
|
||||
temp.gNB_ue_ngap_id = gNB_ue_ngap_id & 0xFFFFFFFF;
|
||||
|
||||
return RB_FIND(ngap_ue_map, &instance_p->ngap_ue_head, &temp);
|
||||
}
|
||||
|
||||
void ngap_gNB_free_ue_context(struct ngap_gNB_ue_context_s *ue_context_p)
|
||||
{
|
||||
if (ue_context_p == NULL) {
|
||||
NGAP_ERROR("Trying to free a NULL context\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO: check that context is currently not in the tree of known
|
||||
* contexts.
|
||||
*/
|
||||
|
||||
free(ue_context_p);
|
||||
RB_REMOVE(ngap_ue_map, &ngap_ue_head, tmp);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
|
||||
// Forward declarations
|
||||
struct ngap_gNB_amf_data_s;
|
||||
struct ngap_ue_map;
|
||||
struct gNB_amf_desc_s;
|
||||
|
||||
typedef enum {
|
||||
@@ -59,11 +58,7 @@ typedef struct ngap_gNB_ue_context_s {
|
||||
*/
|
||||
uint32_t gNB_ue_ngap_id;
|
||||
|
||||
/* UE id for initial connection to NGAP */
|
||||
uint16_t ue_initial_id;
|
||||
|
||||
/* Uniquely identifies the UE within AMF. Encoded on 32 bits. */
|
||||
uint64_t amf_ue_ngap_id:40;
|
||||
uint64_t amf_ue_ngap_id;
|
||||
|
||||
/* Stream used for this particular UE */
|
||||
int32_t tx_stream;
|
||||
@@ -84,20 +79,9 @@ typedef struct ngap_gNB_ue_context_s {
|
||||
ngap_gNB_instance_t *gNB_instance;
|
||||
} ngap_gNB_ue_context_t;
|
||||
|
||||
int ngap_gNB_compare_gNB_ue_ngap_id(
|
||||
struct ngap_gNB_ue_context_s *p1, struct ngap_gNB_ue_context_s *p2);
|
||||
|
||||
/* Generate the tree management functions prototypes */
|
||||
RB_PROTOTYPE(ngap_ue_map, ngap_gNB_ue_context_s, entries,
|
||||
ngap_gNB_compare_gNB_ue_ngap_id);
|
||||
|
||||
struct ngap_gNB_ue_context_s *ngap_gNB_allocate_new_UE_context(void);
|
||||
|
||||
struct ngap_gNB_ue_context_s *ngap_gNB_get_ue_context(
|
||||
ngap_gNB_instance_t *instance_p,
|
||||
uint32_t gNB_ue_ngap_id);
|
||||
|
||||
void ngap_gNB_free_ue_context(struct ngap_gNB_ue_context_s *ue_context_p);
|
||||
void ngap_store_ue_context(ngap_gNB_ue_context_t *ue_desc_p);
|
||||
|
||||
ngap_gNB_ue_context_t *ngap_get_ue_context(uint32_t gNB_ue_ngap_id);
|
||||
ngap_gNB_ue_context_t *ngap_detach_ue_context(uint32_t gNB_ue_ngap_id);
|
||||
|
||||
#endif /* NGAP_GNB_UE_CONTEXT_H_ */
|
||||
|
||||
@@ -650,7 +650,7 @@ static void sctp_send_data(sctp_data_req_t *sctp_data_req_p)
|
||||
/* TODO: notify upper layer */
|
||||
return;
|
||||
}
|
||||
|
||||
free(sctp_data_req_p->buffer); // assuming it has been malloced
|
||||
SCTP_DEBUG("Successfully sent %u bytes on stream %d for assoc_id %u\n",
|
||||
sctp_data_req_p->buffer_length, sctp_data_req_p->stream,
|
||||
sctp_cnx->assoc_id);
|
||||
|
||||
Reference in New Issue
Block a user