Commit a108c031 authored by Prajna G Acharya's avatar Prajna G Acharya

Handover

parent 2c9a57f0
...@@ -35,3 +35,6 @@ MESSAGE_DEF(XNAP_REGISTER_GNB_REQ, MESSAGE_PRIORITY_MED, xnap_register_gnb_req_t ...@@ -35,3 +35,6 @@ MESSAGE_DEF(XNAP_REGISTER_GNB_REQ, MESSAGE_PRIORITY_MED, xnap_register_gnb_req_t
MESSAGE_DEF(XNAP_SETUP_REQ, MESSAGE_PRIORITY_MED, xnap_setup_req_t, xnap_setup_req) MESSAGE_DEF(XNAP_SETUP_REQ, MESSAGE_PRIORITY_MED, xnap_setup_req_t, xnap_setup_req)
MESSAGE_DEF(XNAP_SETUP_RESP, MESSAGE_PRIORITY_MED, xnap_setup_resp_t, xnap_setup_resp) MESSAGE_DEF(XNAP_SETUP_RESP, MESSAGE_PRIORITY_MED, xnap_setup_resp_t, xnap_setup_resp)
MESSAGE_DEF(XNAP_SETUP_FAILURE, MESSAGE_PRIORITY_MED, xnap_setup_failure_t, xnap_setup_failure) MESSAGE_DEF(XNAP_SETUP_FAILURE, MESSAGE_PRIORITY_MED, xnap_setup_failure_t, xnap_setup_failure)
MESSAGE_DEF(XNAP_HANDOVER_REQ, MESSAGE_PRIORITY_MED, xnap_handover_req_t, xnap_handover_req)
MESSAGE_DEF(XNAP_HANDOVER_REQ_FAILURE, MESSAGE_PRIORITY_MED, xnap_handover_req_failure_t, xnap_handover_req_failure)
MESSAGE_DEF(XNAP_HANDOVER_REQ_ACK, MESSAGE_PRIORITY_MED, xnap_handover_req_ack_t, xnap_handover_req_ack)
...@@ -27,12 +27,18 @@ ...@@ -27,12 +27,18 @@
#ifndef XNAP_MESSAGES_TYPES_H_ #ifndef XNAP_MESSAGES_TYPES_H_
#define XNAP_MESSAGES_TYPES_H_ #define XNAP_MESSAGES_TYPES_H_
#include "s1ap_messages_types.h"
#include "f1ap_messages_types.h"
// Defines to access message fields. // Defines to access message fields.
#define XNAP_REGISTER_GNB_REQ(mSGpTR) (mSGpTR)->ittiMsg.xnap_register_gnb_req #define XNAP_REGISTER_GNB_REQ(mSGpTR) (mSGpTR)->ittiMsg.xnap_register_gnb_req
#define XNAP_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.xnap_setup_req #define XNAP_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.xnap_setup_req
#define XNAP_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.xnap_setup_resp #define XNAP_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.xnap_setup_resp
#define XNAP_SETUP_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.xnap_setup_failure #define XNAP_SETUP_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.xnap_setup_failure
#define XNAP_HANDOVER_REQ(mSGpTR) (mSGpTR)->ittiMsg.xnap_handover_req
#define XNAP_HANDOVER_REQ_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.xnap_handover_req_failure
#define XNAP_HANDOVER_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.xnap_handover_req_ack
#define XNAP_MAX_NB_GNB_IP_ADDRESS 4 #define XNAP_MAX_NB_GNB_IP_ADDRESS 4
...@@ -166,4 +172,128 @@ typedef struct xnap_setup_failure_s { ...@@ -166,4 +172,128 @@ typedef struct xnap_setup_failure_s {
uint16_t time_to_wait; uint16_t time_to_wait;
uint16_t criticality_diagnostics; uint16_t criticality_diagnostics;
} xnap_setup_failure_t; } xnap_setup_failure_t;
typedef struct xnap_guami_s {
xnap_plmn_t plmn_id;
uint8_t amf_region_id;
uint8_t amf_set_id;
uint8_t amf_pointer;
} xnap_guami_t;
typedef struct xnap_allocation_retention_priority_s {
uint16_t priority_level;
preemption_capability_t preemption_capability;
preemption_vulnerability_t preemption_vulnerability;
} xnap_allocation_retention_priority_t;
typedef struct xnap_qos_characteristics_s {
union {
struct {
long fiveqi;
long qos_priority_level;
} non_dynamic;
struct {
long fiveqi; // -1 -> optional
long qos_priority_level;
long packet_delay_budget;
struct {
long per_scalar;
long per_exponent;
} packet_error_rate;
} dynamic;
};
fiveQI_type_t qos_type;
} xnap_qos_characteristics_t;
typedef struct xnap_qos_tobe_setup_item_s {
long qfi;
xnap_qos_characteristics_t qos_params;
xnap_allocation_retention_priority_t allocation_retention_priority;
} xnap_qos_tobe_setup_item_t;
typedef struct xnap_qos_tobe_setup_list_s {
uint8_t num_qos;
xnap_qos_tobe_setup_item_t qos[QOSFLOW_MAX_VALUE]; //QOSFLOW_MAX_VALUE= 64 Put this?
} xnap_qos_tobe_setup_list_t;
typedef struct xnap_pdusession_tobe_setup_item_s {
long pdusession_id;
xnap_snssai_t snssai;
xnap_net_ip_address_t up_ngu_tnl_ip_upf;
teid_t up_ngu_tnl_teid_upf;
pdu_session_type_t pdu_session_type;
xnap_qos_tobe_setup_list_t qos_list;
} xnap_pdusession_tobe_setup_item_t;
typedef struct xnap_pdusession_tobe_setup_list_s {
uint8_t num_pdu;
xnap_pdusession_tobe_setup_item_t pdu[NGAP_MAX_PDUSESSION]; //Is the limit ok?
} xnap_pdusession_tobe_setup_list_t;
typedef struct xnap_ngran_cgi_t {
xnap_plmn_t plmn_id;
uint32_t cgi;
} xnap_ngran_cgi_t;
typedef struct xnap_security_capabilities_s {
uint16_t encryption_algorithms;
uint16_t integrity_algorithms;
} xnap_security_capabilities_t;
typedef struct xnap_ambr_s {
uint64_t br_ul;
uint64_t br_dl;
} xnap_ambr_t;
typedef struct xnap_uehistory_info_s {
xnap_ngran_cgi_t last_visited_cgi;
cell_type_t cell_type; //enumerated -s1ap_messages_types.h
uint64_t time_UE_StayedInCell;
} xnap_uehistory_info_t; //38.413- 9.3.1.97
typedef struct xnap_ue_context_info_s {
uint64_t ngc_ue_sig_ref;// 0-2^40-1
xnap_net_ip_address_t tnl_ip_source;
uint32_t tnl_port_source;
xnap_security_capabilities_t security_capabilities;
//uint8_t kRRCenc[16];
//uint8_t kRRCint[16];
uint32_t as_security_key_ranstar;//bitstring 256, why array?
long as_security_ncc;
xnap_ambr_t ue_ambr;
uint8_t rrc_buffer[8192 /* arbitrary, big enough */];
xnap_pdusession_tobe_setup_list_t pdusession_tobe_setup_list;
int rrc_buffer_size;//rrc msg type needed?
int target_assoc_id;
uint8_t nb_e_rabs_tobesetup;
} xnap_ue_context_info_t;
typedef struct xnap_handover_req_s {
int rnti; /* used for RRC->XNAP in source */
int xn_id; /* used for XNAP->RRC in target*/
uint32_t ng_node_ue_xnap_id;
xnap_plmn_t plmn_id;
xnap_Cause_t cause_type;
xnap_ngran_cgi_t target_cgi;
xnap_guami_t guami;
xnap_ue_context_info_t ue_context;
} xnap_handover_req_t;
typedef struct xnap_handover_req_ack_s {
uint32_t ng_node_ue_xnap_id;
int rnti;
int xn_id_target;
xnap_ngran_cgi_t target_cgi;
xnap_plmn_t plmn_id;
xnap_guami_t guami;
xnap_ue_context_info_t ue_context;
xnap_uehistory_info_t uehistory_info;
} xnap_handover_req_ack_t;
typedef struct xnap_handover_req_failure_s{
uint32_t ng_node_ue_xnap_id;
long cause_value;
xnap_Cause_t cause_type;
xnap_ngran_cgi_t target_cgi;
}xnap_handover_req_failure_t;
#endif /* XNAP_MESSAGES_TYPES_H_ */ #endif /* XNAP_MESSAGES_TYPES_H_ */
...@@ -143,6 +143,10 @@ ...@@ -143,6 +143,10 @@
#include "common/ran_context.h" #include "common/ran_context.h"
#include "conversions.h" #include "conversions.h"
#include "cmake_targets/ran_build/build/openair2/RRC/NR/MESSAGES/NR_HandoverPreparationInformation.h"
#include "cmake_targets/ran_build/build/openair2/RRC/NR/MESSAGES/NR_HandoverPreparationInformation-IEs.h"
#include "cmake_targets/ran_build/build/openair2/RRC/NR/MESSAGES/NR_UE-CapabilityRAT-Container.h"
//#define XER_PRINT //#define XER_PRINT
typedef struct xer_sprint_string_s { typedef struct xer_sprint_string_s {
...@@ -1230,3 +1234,42 @@ uint8_t do_NR_Paging(uint8_t Mod_id, uint8_t *buffer, uint32_t tmsi) ...@@ -1230,3 +1234,42 @@ uint8_t do_NR_Paging(uint8_t Mod_id, uint8_t *buffer, uint32_t tmsi)
return((enc_rval.encoded+7)/8); return((enc_rval.encoded+7)/8);
} }
int do_NRHandoverPreparation(char *ho_buf, int ho_size, NR_UE_NR_Capability_t *ue_nr_cap, int rrc_size) {
asn_enc_rval_t enc_rval;
NR_HandoverPreparationInformation_t ho;
NR_HandoverPreparationInformation_IEs_t *ho_info;
NR_UE_CapabilityRAT_Container_t *ue_cap_rat_container;
char rrc_buf[rrc_size];
memset(rrc_buf, 0, rrc_size);
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UE_NR_Capability,
NULL,
ue_nr_cap,
rrc_buf,
rrc_size);
/* TODO: free the OCTET_STRING */
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
enc_rval.failed_type->name, enc_rval.encoded);
memset(&ho, 0, sizeof(ho));
ho.criticalExtensions.present = NR_HandoverPreparationInformation__criticalExtensions_PR_c1;
ho.criticalExtensions.choice.c1->present = NR_HandoverPreparationInformation__criticalExtensions__c1_PR_handoverPreparationInformation;
ho_info = ho.criticalExtensions.choice.c1->choice.handoverPreparationInformation;
{
ue_cap_rat_container = (NR_UE_CapabilityRAT_Container_t *)calloc(1,sizeof(NR_UE_CapabilityRAT_Container_t));
ue_cap_rat_container->rat_Type = NR_RAT_Type_nr;
AssertFatal (OCTET_STRING_fromBuf(
&ue_cap_rat_container->ue_CapabilityRAT_Container,
rrc_buf, rrc_size) != -1, "fatal: OCTET_STRING_fromBuf failed\n");
asn1cSeqAdd(&ho_info->ue_CapabilityRAT_List.list, ue_cap_rat_container);
}
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_HandoverPreparationInformation,
NULL,
&ho,
ho_buf,
ho_size);
/* TODO: free the OCTET_STRING */
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
enc_rval.failed_type->name, enc_rval.encoded);
return((enc_rval.encoded+7)/8);
}
...@@ -147,4 +147,6 @@ NR_MeasConfig_t *get_defaultMeasConfig(uint32_t absFreqSSB, int band, int scs); ...@@ -147,4 +147,6 @@ NR_MeasConfig_t *get_defaultMeasConfig(uint32_t absFreqSSB, int band, int scs);
void free_defaultMeasConfig(NR_MeasConfig_t *mc); void free_defaultMeasConfig(NR_MeasConfig_t *mc);
uint8_t do_NR_Paging(uint8_t Mod_id, uint8_t *buffer, uint32_t tmsi); uint8_t do_NR_Paging(uint8_t Mod_id, uint8_t *buffer, uint32_t tmsi);
int do_NRHandoverPreparation(char *ho_buf, int ho_size, NR_UE_NR_Capability_t *ue_nr_cap, int rrc_size);
#endif /* __RRC_NR_MESSAGES_ASN1_MSG__H__ */ #endif /* __RRC_NR_MESSAGES_ASN1_MSG__H__ */
...@@ -297,6 +297,7 @@ typedef struct gNB_RRC_UE_s { ...@@ -297,6 +297,7 @@ typedef struct gNB_RRC_UE_s {
nr_rrc_guami_t ue_guami; nr_rrc_guami_t ue_guami;
ngap_security_capabilities_t security_capabilities; ngap_security_capabilities_t security_capabilities;
xnap_security_capabilities_t xnap_security_capabilities;
//NSA block //NSA block
/* Number of NSA e_rab */ /* Number of NSA e_rab */
uint8_t nb_of_e_rabs; uint8_t nb_of_e_rabs;
......
...@@ -97,12 +97,15 @@ ...@@ -97,12 +97,15 @@
#include "openair2/F1AP/f1ap_common.h" #include "openair2/F1AP/f1ap_common.h"
#include "openair2/F1AP/f1ap_ids.h" #include "openair2/F1AP/f1ap_ids.h"
#include "openair2/SDAP/nr_sdap/nr_sdap_entity.h" #include "openair2/SDAP/nr_sdap/nr_sdap_entity.h"
#include "openair2/E1AP/e1ap.h" #include "cmake_targets/ran_build/build/openair2/RRC/NR/MESSAGES/NR_HandoverPreparationInformation.h"
#include "cmake_targets/ran_build/build/openair2/RRC/NR/MESSAGES/NR_UERadioAccessCapabilityInformation-IEs.h"
#include "cucp_cuup_if.h" #include "cucp_cuup_if.h"
#include "openair2/XNAP/xnap_gNB_defs.h"
#include "BIT_STRING.h" #include "BIT_STRING.h"
#include "assertions.h" #include "assertions.h"
#include "openair2/XNAP/xnap_gNB_management_procedures.c"
#include "openair2/COMMON/xnap_messages_types.h"
#include "openair2/XNAP/xnap_gNB_task.h"
#include "openair2/RRC/NR/MESSAGES/asn1_msg.h"
#ifdef E2_AGENT #ifdef E2_AGENT
#include "openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_rc_extern.h" #include "openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_rc_extern.h"
...@@ -1309,6 +1312,18 @@ fallback_rrc_setup: ...@@ -1309,6 +1312,18 @@ fallback_rrc_setup:
return; return;
} }
void rrc_gNB_process_HandoverPreparationInformation(
rrc_gNB_ue_context_t *ue_context_p,
uint8_t *buffer,
int *size)
{
memset(buffer, 0, 8192);
char *ho_buf = (char *) buffer;
int ho_size;
ho_size = do_NRHandoverPreparation(ho_buf, 8192, ue_context_p->ue_context.UE_Capability_nr, ue_context_p->ue_context.UE_Capability_size);
*size = ho_size;
}
static void rrc_gNB_process_MeasurementReport(rrc_gNB_ue_context_t *ue_context, NR_MeasurementReport_t *measurementReport) static void rrc_gNB_process_MeasurementReport(rrc_gNB_ue_context_t *ue_context, NR_MeasurementReport_t *measurementReport)
{ {
if (LOG_DEBUGFLAG(DEBUG_ASN1)) if (LOG_DEBUGFLAG(DEBUG_ASN1))
...@@ -1555,6 +1570,7 @@ static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_ ...@@ -1555,6 +1570,7 @@ static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_
{ {
AssertFatal(ue_context_p != NULL, "Processing %s() for UE %lx, ue_context_p is NULL\n", __func__, ctxt_pP->rntiMaybeUEid); AssertFatal(ue_context_p != NULL, "Processing %s() for UE %lx, ue_context_p is NULL\n", __func__, ctxt_pP->rntiMaybeUEid);
gNB_RRC_UE_t *UE = &ue_context_p->ue_context; gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
gNB_RRC_UE_t *ue_ctxt = &ue_context_p->ue_context;
uint8_t xid = reconfig_complete->rrc_TransactionIdentifier; uint8_t xid = reconfig_complete->rrc_TransactionIdentifier;
UE->ue_reconfiguration_counter++; UE->ue_reconfiguration_counter++;
...@@ -1598,6 +1614,40 @@ static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_ ...@@ -1598,6 +1614,40 @@ static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_
} }
} }
MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, XNAP_HANDOVER_REQ);
/*rrc_gNB_process_HandoverPreparationInformation(
ue_context_p,
XNAP_HANDOVER_REQ(msg).rrc_buffer,
&XNAP_HANDOVER_REQ(msg).rrc_buffer_size); */
XNAP_HANDOVER_REQ(msg).target_cgi.cgi = 12345678; //ue_ctxt->measResults->measResultNeighCells->choice.measResultListNR->list.array[0]->physCellId;
XNAP_HANDOVER_REQ(msg).guami.plmn_id.mcc = ue_ctxt->ue_guami.mcc;
XNAP_HANDOVER_REQ(msg).guami.plmn_id.mnc = ue_ctxt->ue_guami.mnc;
XNAP_HANDOVER_REQ(msg).guami.plmn_id.mnc_digit_length = ue_ctxt->ue_guami.mnc_len;
XNAP_HANDOVER_REQ(msg).guami.amf_region_id = ue_ctxt->ue_guami.amf_region_id;
XNAP_HANDOVER_REQ(msg).guami.amf_set_id = ue_ctxt->ue_guami.amf_set_id;
XNAP_HANDOVER_REQ(msg).guami.amf_pointer = ue_ctxt->ue_guami.amf_pointer;
XNAP_HANDOVER_REQ(msg).ue_context.security_capabilities = ue_ctxt->xnap_security_capabilities;
//nr_derive_key(RRC_ENC_ALG, ue_ctxt->ciphering_algorithm, ue_ctxt->kgnb,XNAP_HANDOVER_REQ(msg).ue_context.security_capabilities.encryption_algorithms);
//nr_derive_key(RRC_INT_ALG, ue_ctxt->integrity_algorithm, ue_ctxt->kgnb,XNAP_HANDOVER_REQ(msg).ue_context.security_capabilities.integrity_algorithms);
/*XNAP_HANDOVER_REQ(msg).ue_context.ngc_ue_sig_ref = ue_ctxt->amf_ue_ngap_id;
XNAP_HANDOVER_REQ(msg).ue_context.as_security_ncc = ue_ctxt->kgnb_ncc;
XNAP_HANDOVER_REQ(msg).ue_context.as_security_key_ranstar = ue_ctxt->kgnb[0];
XNAP_HANDOVER_REQ(msg).ue_context.pdusession_tobe_setup_list.pdu[NGAP_MAX_PDUSESSION].pdusession_id = ue_ctxt->pduSession[NGAP_MAX_PDU_SESSION].param.pdusession_id;
XNAP_HANDOVER_REQ(msg).ue_context.pdusession_tobe_setup_list.pdu[NGAP_MAX_PDUSESSION].snssai.sst = ue_ctxt->pduSession[NGAP_MAX_PDU_SESSION].param.nssai.sst;
XNAP_HANDOVER_REQ(msg).ue_context.pdusession_tobe_setup_list.pdu[NGAP_MAX_PDUSESSION].pdu_session_type = ue_ctxt->pduSession[NGAP_MAX_PDU_SESSION].param.pdu_session_type;
XNAP_HANDOVER_REQ(msg).ue_context.pdusession_tobe_setup_list.pdu[NGAP_MAX_PDUSESSION].up_ngu_tnl_teid_upf = ue_ctxt->pduSession[NGAP_MAX_PDU_SESSION].param.gtp_teid;
XNAP_HANDOVER_REQ(msg).ue_context.pdusession_tobe_setup_list.pdu[NGAP_MAX_PDUSESSION].qos_list.qos[QOSFLOW_MAX_VALUE].qfi = ue_ctxt->pduSession[NGAP_MAX_PDU_SESSION].param.qos[QOSFLOW_MAX_VALUE].qfi;
XNAP_HANDOVER_REQ(msg).ue_context.pdusession_tobe_setup_list.pdu[NGAP_MAX_PDUSESSION].qos_list.qos[QOSFLOW_MAX_VALUE].qos_params.non_dynamic.fiveqi = ue_ctxt->pduSession[NGAP_MAX_PDU_SESSION].param.qos[QOSFLOW_MAX_VALUE].fiveQI;
XNAP_HANDOVER_REQ(msg).ue_context.pdusession_tobe_setup_list.pdu[NGAP_MAX_PDUSESSION].qos_list.qos[QOSFLOW_MAX_VALUE].qos_params.dynamic.qos_priority_level = ue_ctxt->pduSession[NGAP_MAX_PDU_SESSION].param.qos[QOSFLOW_MAX_VALUE].qos_priority;
XNAP_HANDOVER_REQ(msg).ue_context.pdusession_tobe_setup_list.pdu[NGAP_MAX_PDUSESSION].qos_list.num_qos = ue_ctxt->pduSession[NGAP_MAX_PDU_SESSION].param.nb_qos;
XNAP_HANDOVER_REQ(msg).ue_context.pdusession_tobe_setup_list.num_pdu = ue_ctxt->nb_of_pdusessions;*/
itti_send_msg_to_task(TASK_XNAP, 0, msg);
LOG_I(NR_RRC, "Handover triggered :)\n");
gNB_RRC_INST *rrc = RC.nrrrc[0]; gNB_RRC_INST *rrc = RC.nrrrc[0];
f1_ue_data_t ue_data = cu_get_f1_ue_data(UE->rrc_ue_id); f1_ue_data_t ue_data = cu_get_f1_ue_data(UE->rrc_ue_id);
RETURN_IF_INVALID_ASSOC_ID(ue_data); RETURN_IF_INVALID_ASSOC_ID(ue_data);
...@@ -2402,6 +2452,44 @@ static void write_rrc_stats(const gNB_RRC_INST *rrc) ...@@ -2402,6 +2452,44 @@ static void write_rrc_stats(const gNB_RRC_INST *rrc)
fclose(f); fclose(f);
} }
void rrc_gNB_process_handoverprepinfo(sctp_assoc_t assoc_id, xnap_handover_req_t *m)
{
int rnti = taus() & 0xffff;
rrc_gNB_ue_context_t *ue_context_p;
//NR_HandoverPreparationInformation_t *handover;
//NR_HandoverPreparationInformation_IEs_t *handover_info;
instance_t instance;
instance = 0; //for time being
xnap_gNB_instance_t *instance_p;
instance_p = xnap_gNB_get_instance(instance);
ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[0], rnti);
if (ue_context_p != NULL) {
LOG_E(NR_RRC, "\nError in obtaining free UE id in target gNB for handover \n");
return;
}
ue_context_p = rrc_gNB_allocate_new_ue_context(RC.nrrrc[0]);
if (ue_context_p == NULL) {
LOG_E(NR_RRC, "Cannot create new UE context\n");
return;
}
ue_context_p->ue_context.rnti = rnti;
//RB_INSERT(rrc_ue_tree_s, &RC.rrc[mod_id]->rrc_ue_head, ue_context_p);
MessageDef *message_p = itti_alloc_new_message(TASK_XNAP, 0, XNAP_HANDOVER_REQ_ACK);
message_p->ittiMsgHeader.originInstance = assoc_id;
xnap_handover_req_ack_t *ack = &XNAP_HANDOVER_REQ_ACK(message_p);
//ack->x2_id_target = ue_context_p->ue_context.handover_info->x2_id;
ack->target_cgi=m->target_cgi ;
itti_send_msg_to_task(TASK_XNAP, instance_p->instance, message_p);
}
void *rrc_gnb_task(void *args_p) { void *rrc_gnb_task(void *args_p) {
MessageDef *msg_p; MessageDef *msg_p;
instance_t instance; instance_t instance;
...@@ -2528,6 +2616,11 @@ void *rrc_gnb_task(void *args_p) { ...@@ -2528,6 +2616,11 @@ void *rrc_gnb_task(void *args_p) {
rrc_gNB_process_xn_setup_request(ITTI_MSG_ORIGIN_INSTANCE(msg_p), &XNAP_SETUP_REQ(msg_p), instance); rrc_gNB_process_xn_setup_request(ITTI_MSG_ORIGIN_INSTANCE(msg_p), &XNAP_SETUP_REQ(msg_p), instance);
break; break;
case XNAP_HANDOVER_REQ:
LOG_I(NR_RRC,"Received Handover request going into the function \n");
rrc_gNB_process_handoverprepinfo(ITTI_MSG_ORIGIN_INSTANCE(msg_p),&XNAP_HANDOVER_REQ(msg_p));
break;
/* Messages from X2AP */ /* Messages from X2AP */
case X2AP_ENDC_SGNB_ADDITION_REQ: case X2AP_ENDC_SGNB_ADDITION_REQ:
......
...@@ -6,7 +6,9 @@ add_library(xnap ...@@ -6,7 +6,9 @@ add_library(xnap
xnap_gNB_task.c xnap_gNB_task.c
xnap_gNB_itti_messaging.c xnap_gNB_itti_messaging.c
xnap_gNB_handler.c xnap_gNB_handler.c
xnap_gNB_interface_management.c) xnap_gNB_interface_management.c
xnap_timers.c
xnap_ids.c)
target_link_libraries(xnap target_link_libraries(xnap
PUBLIC asn1_xnap PUBLIC asn1_xnap
PRIVATE nr_rrc) PRIVATE nr_rrc)
......
...@@ -53,7 +53,7 @@ int xnap_gNB_encode_pdu(XNAP_XnAP_PDU_t *pdu, uint8_t **buffer, uint32_t *len) ...@@ -53,7 +53,7 @@ int xnap_gNB_encode_pdu(XNAP_XnAP_PDU_t *pdu, uint8_t **buffer, uint32_t *len)
*len = encoded; *len = encoded;
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_XNAP_XnAP_PDU, pdu); //ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_XNAP_XnAP_PDU, pdu);
return encoded; return encoded;
} }
......
...@@ -23,6 +23,8 @@ ...@@ -23,6 +23,8 @@
#include "tree.h" #include "tree.h"
#include "sctp_eNB_defs.h" #include "sctp_eNB_defs.h"
#include "xnap_messages_types.h" #include "xnap_messages_types.h"
#include "xnap_timers.h"
#include "xnap_ids.h"
#ifndef XNAP_GNB_DEFS_H_ #ifndef XNAP_GNB_DEFS_H_
#define XNAP_GNB_DEFS_H_ #define XNAP_GNB_DEFS_H_
...@@ -59,6 +61,7 @@ typedef struct xnap_gNB_data_t { ...@@ -59,6 +61,7 @@ typedef struct xnap_gNB_data_t {
/* gNB descriptors tree, ordered by sctp assoc id */ /* gNB descriptors tree, ordered by sctp assoc id */
RB_ENTRY(xnap_gNB_data_t) entry; RB_ENTRY(xnap_gNB_data_t) entry;
char *gNB_name; char *gNB_name;
long nci;
/* target gNB ID */ /* target gNB ID */
uint64_t gNB_id; uint64_t gNB_id;
/* Current gNB->gNB XnAP association state */ /* Current gNB->gNB XnAP association state */
...@@ -84,7 +87,7 @@ typedef struct xnap_gNB_instance_s { ...@@ -84,7 +87,7 @@ typedef struct xnap_gNB_instance_s {
size_t num_gnbs; size_t num_gnbs;
instance_t instance; instance_t instance;
xnap_setup_req_t setup_req; xnap_setup_req_t setup_req;
xnap_id_manager id_manager;
/* The gNB IP address to bind */ /* The gNB IP address to bind */
xnap_net_config_t net_config; xnap_net_config_t net_config;
/* SCTP information */ /* SCTP information */
......
This diff is collapsed.
...@@ -39,4 +39,8 @@ int xnap_gNB_generate_xn_setup_failure(sctp_assoc_t assoc_id, xnap_setup_failure ...@@ -39,4 +39,8 @@ int xnap_gNB_generate_xn_setup_failure(sctp_assoc_t assoc_id, xnap_setup_failure
int xnap_gNB_set_cause(XNAP_Cause_t *cause_p, XNAP_Cause_PR cause_type, long cause_value); int xnap_gNB_set_cause(XNAP_Cause_t *cause_p, XNAP_Cause_PR cause_type, long cause_value);
int xnap_gNB_generate_xn_handover_request(sctp_assoc_t assoc_id, xnap_handover_req_t *xnap_handover_req);
int xnap_gNB_generate_xn_handover_request_ack(sctp_assoc_t assoc_id, xnap_handover_req_ack_t *xnap_handover_req_ack,instance_t instance);
#endif /* XNAP_GNB_GENERATE_MESSAGES_H_ */ #endif /* XNAP_GNB_GENERATE_MESSAGES_H_ */
...@@ -34,10 +34,11 @@ ...@@ -34,10 +34,11 @@
#include "xnap_gNB_interface_management.h" #include "xnap_gNB_interface_management.h"
#include "assertions.h" #include "assertions.h"
#include "conversions.h" #include "conversions.h"
#include "xnap_ids.h"
/* Placement of callback functions according to XNAP_ProcedureCode.h */ /* Placement of callback functions according to XNAP_ProcedureCode.h */
static const xnap_message_decoded_callback xnap_messages_callback[][3] = { static const xnap_message_decoded_callback xnap_messages_callback[][3] = {
{0, 0, 0}, {xnap_gNB_handle_handover_request, xnap_gNB_handle_handover_response, 0}, /* handoverPreparation */
{0, 0, 0}, {0, 0, 0},
{0, 0, 0}, {0, 0, 0},
{0, 0, 0}, {0, 0, 0},
......
...@@ -336,3 +336,154 @@ int xnap_gNB_handle_xn_setup_failure(instance_t instance, sctp_assoc_t assoc_id, ...@@ -336,3 +336,154 @@ int xnap_gNB_handle_xn_setup_failure(instance_t instance, sctp_assoc_t assoc_id,
return 0; return 0;
} }
int xnap_gNB_handle_handover_request(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, XNAP_XnAP_PDU_t *pdu)
{
XNAP_HandoverRequest_t *xnHandoverRequest;
XNAP_HandoverRequest_IEs_t *ie;
xnap_gNB_instance_t *instance_p;
xnap_id_manager *id_manager;
//xnap_gNB_data_t *xnap_gNB_data;
int ue_id;
instance_p = xnap_gNB_get_instance(instance);
DevAssert(pdu != NULL);
xnHandoverRequest = &pdu->choice.initiatingMessage->value.choice.HandoverRequest;
if(stream !=0)
{
LOG_E(XNAP, "Received new XN handover request on stream != 0\n");
//sending handover failed
MessageDef *message_p = itti_alloc_new_message(TASK_XNAP, 0, XNAP_HANDOVER_REQ_FAILURE);
message_p->ittiMsgHeader.originInstance = assoc_id;
xnap_handover_req_failure_t *fail = &XNAP_HANDOVER_REQ_FAILURE(message_p);
fail->cause_type = XNAP_CAUSE_PROTOCOL;
fail->cause_value = 6;
itti_send_msg_to_task(TASK_XNAP, 0, message_p);
}
LOG_D(XNAP, "Received a new XN handover request\n");
MessageDef *message_p = itti_alloc_new_message(TASK_XNAP, 0, XNAP_HANDOVER_REQ);
message_p->ittiMsgHeader.originInstance = assoc_id;
xnap_handover_req_t *req = &XNAP_HANDOVER_REQ(message_p);
//Source NG-RAN node UE XnAP ID
XNAP_FIND_PROTOCOLIE_BY_ID(XNAP_HandoverRequest_IEs_t, ie, xnHandoverRequest, XNAP_ProtocolIE_ID_id_sourceNG_RANnodeUEXnAPID, true);
if (ie == NULL) {
LOG_E(XNAP, "XNAP_ProtocolIE_ID_id_sourceNG_RANnodeUEXnAPID, is NULL pointer \n");
return -1;
}else{
LOG_I(XNAP, "ue xnap id %d \n", req->ng_node_ue_xnap_id);
}
id_manager = &instance_p->id_manager;
xnap_id_manager_init(id_manager);
ue_id = xnap_allocate_new_id(id_manager);
if (ue_id == -1) {
LOG_E(XNAP,"could not allocate a new XNAP UE ID\n");
/* TODO: cancel handover: send HO preparation failure to source eNB */
exit(1);
}
xnap_set_ids(&instance_p->id_manager, ue_id, 0, ie->value.choice.NG_RANnodeUEXnAPID, ue_id);
xnap_id_set_state(&instance_p->id_manager, ue_id, XNID_STATE_TARGET);
XNAP_HANDOVER_REQ(message_p).xn_id = ue_id;
/*// Target Cell Global ID
XNAP_FIND_PROTOCOLIE_BY_ID(XNAP_HandoverRequest_IEs_t, ie, xnHandoverRequest, XNAP_ProtocolIE_ID_id_TargetCellCGI,true);
if (ie == NULL) {
LOG_E(XNAP, "XNAP_ProtocolIE_ID_id_TargetCellCGI, is NULL pointer \n");
return -1;
}else{
// if (ie->value.choice.Target_CGI.choice.nr->nr_CI.present == XNAP_Target_CGI_PR_nr) { }
PLMNID_TO_MCC_MNC(&ie->value.choice.Target_CGI.choice.nr->plmn_id,
req->target_cgi.plmn_id.mcc,
req->target_cgi.plmn_id.mnc,
req->target_cgi.plmn_id.mnc_digit_length);
BIT_STRING_TO_NR_CELL_IDENTITY( &ie->value.choice.Target_CGI.choice.nr->nr_CI , req->target_cgi.cgi);
}*/
// *c = &ie->value.choice.UEContextInfoHORequest.rrc_Context;
//if (c->size > 8192 /* TODO: this is the size of rrc_buffer in struct x2ap_handover_req_s */){
// printf("%s:%d: fatal: buffer too big\n", __FILE__, __LINE__); abort(); }
//memcpy(XNAP_HANDOVER_REQ(msg).rrc_buffer, c->buf, c->size);
//XNAP_HANDOVER_REQ(msg).rrc_buffer_size = c->size;
itti_send_msg_to_task(TASK_RRC_GNB, instance_p->instance, message_p);
return 0;
}
int xnap_gNB_handle_handover_response(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, XNAP_XnAP_PDU_t *pdu)
{
XNAP_HandoverRequestAcknowledge_t *xnHandoverRequestAck;
XNAP_HandoverRequestAcknowledge_IEs_t *ie;
xnap_gNB_instance_t *instance_p;
instance_p = xnap_gNB_get_instance(instance);
//xnap_id_manager *id_manager;
//xnap_gNB_data_t *xnap_gNB_data;
int ue_id;
int id_source;
int id_target;
int rnti;
DevAssert (pdu != NULL);
xnHandoverRequestAck = &pdu->choice.successfulOutcome->value.choice.HandoverRequestAcknowledge;
if (stream == 0) {
LOG_E(XNAP,"Received new xn handover response on stream == 0\n");
return 0;
}
MessageDef *message_p = itti_alloc_new_message(TASK_XNAP, 0, XNAP_HANDOVER_REQ_ACK);
message_p->ittiMsgHeader.originInstance = assoc_id;
//xnap_handover_req_ack_t *req = &XNAP_HANDOVER_REQ_ACK(message_p);
//Source NG-RAN node UE XnAP ID
XNAP_FIND_PROTOCOLIE_BY_ID(XNAP_HandoverRequestAcknowledge_IEs_t, ie, xnHandoverRequestAck, XNAP_ProtocolIE_ID_id_sourceNG_RANnodeUEXnAPID, true);
if (ie == NULL) {
LOG_E(XNAP, "XNAP_ProtocolIE_ID_id_sourceNG_RANnodeUEXnAPID, is NULL pointer \n");
itti_free(ITTI_MSG_ORIGIN_ID(message_p),message_p);
return -1;
}
id_source = ie->value.choice.NG_RANnodeUEXnAPID;
XNAP_FIND_PROTOCOLIE_BY_ID(XNAP_HandoverRequestAcknowledge_IEs_t, ie, xnHandoverRequestAck, XNAP_ProtocolIE_ID_id_targetCellGlobalID, true);
if (ie == NULL) {
LOG_E(XNAP, "XNAP_ProtocolIE_ID_id_targetCellGlobalID, is NULL pointer \n");
itti_free(ITTI_MSG_ORIGIN_ID(message_p),message_p);
return -1;
}
id_target = ie->value.choice.NG_RANnodeUEXnAPID_1;
ue_id = id_source;
if (ue_id != xnap_find_id_from_id_source(&instance_p->id_manager, id_source)) {
LOG_E(XNAP, "incorrect/unknown XNAP IDs for UE (old ID %d new ID %d), ignoring handover response\n",id_source, id_target);
itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
return 0;
}
rnti = xnap_id_get_rnti(&instance_p->id_manager, ue_id);
xnap_set_ids(&instance_p->id_manager, ue_id, rnti, id_source, id_target);
xnap_id_set_state(&instance_p->id_manager, ue_id, XNID_STATE_SOURCE_OVERALL);
//xnap_set_reloc_overall_timer(&instance_p->id_manager, ue_id,xnap_timer_get_tti(&instance_p->timers));
XNAP_HANDOVER_REQ_ACK(message_p).rnti = rnti;
itti_send_msg_to_task(TASK_RRC_GNB, instance_p->instance, message_p);
return 0;
}
...@@ -32,5 +32,8 @@ ...@@ -32,5 +32,8 @@
int xnap_gNB_handle_xn_setup_request(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, XNAP_XnAP_PDU_t *pdu); int xnap_gNB_handle_xn_setup_request(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, XNAP_XnAP_PDU_t *pdu);
int xnap_gNB_handle_xn_setup_response(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, XNAP_XnAP_PDU_t *pdu); int xnap_gNB_handle_xn_setup_response(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, XNAP_XnAP_PDU_t *pdu);
int xnap_gNB_handle_xn_setup_failure(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, XNAP_XnAP_PDU_t *pdu); int xnap_gNB_handle_xn_setup_failure(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, XNAP_XnAP_PDU_t *pdu);
int xnap_gNB_handle_handover_request(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, XNAP_XnAP_PDU_t *pdu);
int xnap_gNB_handle_handover_response(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, XNAP_XnAP_PDU_t *pdu);
#endif /* XNAP_GNB_INTERFACE_MANAGEMENT_H_ */ #endif /* XNAP_GNB_INTERFACE_MANAGEMENT_H_ */
...@@ -135,6 +135,18 @@ xnap_gNB_instance_t *xnap_gNB_get_instance(instance_t instanceP) ...@@ -135,6 +135,18 @@ xnap_gNB_instance_t *xnap_gNB_get_instance(instance_t instanceP)
return instance_xnap; return instance_xnap;
} }
sctp_assoc_t xnap_gNB_get_assoc_id(xnap_gNB_instance_t *instance, long nci)
{
struct xnap_gNB_data_t *entry;
RB_FOREACH(entry, xnap_gnb_tree, &instance->xnap_gnbs) {
if (entry->nci == nci) {
return entry->assoc_id;
}
}
return 0;
}
void xnap_insert_gnb(instance_t instance, xnap_gNB_data_t *xnap_gnb_data_p) void xnap_insert_gnb(instance_t instance, xnap_gNB_data_t *xnap_gnb_data_p)
{ {
pthread_mutex_lock(&xn_inst_mtx); pthread_mutex_lock(&xn_inst_mtx);
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
// void xnap_gNB_prepare_internal_data(void); // void xnap_gNB_prepare_internal_data(void);
void createXninst(instance_t instanceP, xnap_setup_req_t *req, xnap_net_config_t *nc); void createXninst(instance_t instanceP, xnap_setup_req_t *req, xnap_net_config_t *nc);
void updateXninst(instance_t instanceP, xnap_setup_req_t *req, xnap_net_config_t *nc); void updateXninst(instance_t instanceP, xnap_setup_req_t *req, xnap_net_config_t *nc);
sctp_assoc_t xnap_gNB_get_assoc_id(xnap_gNB_instance_t *instance, long nci);
// void xnap_dump_trees(void); // void xnap_dump_trees(void);
void xnap_dump_trees(const instance_t instance); void xnap_dump_trees(const instance_t instance);
// void xnap_gNB_insert_new_instance(xnap_gNB_instance_t *new_instance_p); // void xnap_gNB_insert_new_instance(xnap_gNB_instance_t *new_instance_p);
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include "conversions.h" #include "conversions.h"
#include "xnap_gNB_generate_messages.h" #include "xnap_gNB_generate_messages.h"
#include "gnb_config.h" #include "gnb_config.h"
#include "xnap_ids.h"
RB_PROTOTYPE(xnap_gnb_tree, xnap_gNB_data_t, entry, xnap_gNB_compare_assoc_id); RB_PROTOTYPE(xnap_gnb_tree, xnap_gNB_data_t, entry, xnap_gNB_compare_assoc_id);
...@@ -101,7 +102,7 @@ static void xnap_gNB_handle_sctp_association_resp(instance_t instance, sctp_new_ ...@@ -101,7 +102,7 @@ static void xnap_gNB_handle_sctp_association_resp(instance_t instance, sctp_new_
xnap_gnb_data_p->state = XNAP_GNB_STATE_WAITING; xnap_gnb_data_p->state = XNAP_GNB_STATE_WAITING;
xnap_gnb_data_p->in_streams = sctp_new_association_resp->in_streams; xnap_gnb_data_p->in_streams = sctp_new_association_resp->in_streams;
xnap_gnb_data_p->out_streams = sctp_new_association_resp->out_streams; xnap_gnb_data_p->out_streams = sctp_new_association_resp->out_streams;
//xnap_dump_trees(instance); xnap_gnb_data_p->nci = 12345678;
xnap_insert_gnb(instance, xnap_gnb_data_p); xnap_insert_gnb(instance, xnap_gnb_data_p);
xnap_dump_trees(instance); xnap_dump_trees(instance);
xnap_gNB_generate_xn_setup_request(sctp_new_association_resp->assoc_id, &instance_xn->setup_req); xnap_gNB_generate_xn_setup_request(sctp_new_association_resp->assoc_id, &instance_xn->setup_req);
...@@ -190,6 +191,7 @@ static void xnap_gNB_handle_sctp_association_ind(instance_t instance, sctp_new_a ...@@ -190,6 +191,7 @@ static void xnap_gNB_handle_sctp_association_ind(instance_t instance, sctp_new_a
xnap_gNB_data_t *xnap_gnb_data_p = calloc(1, sizeof(*xnap_gnb_data_p)); xnap_gNB_data_t *xnap_gnb_data_p = calloc(1, sizeof(*xnap_gnb_data_p));
AssertFatal(xnap_gnb_data_p != NULL, "out of memory\n"); AssertFatal(xnap_gnb_data_p != NULL, "out of memory\n");
xnap_gnb_data_p->assoc_id = sctp_new_association_ind->assoc_id; xnap_gnb_data_p->assoc_id = sctp_new_association_ind->assoc_id;
xnap_gnb_data_p->nci = 12345678;
xnap_gnb_data_p->state = XNAP_GNB_STATE_WAITING; xnap_gnb_data_p->state = XNAP_GNB_STATE_WAITING;
xnap_gnb_data_p->in_streams = sctp_new_association_ind->in_streams; xnap_gnb_data_p->in_streams = sctp_new_association_ind->in_streams;
xnap_gnb_data_p->out_streams = sctp_new_association_ind->out_streams; xnap_gnb_data_p->out_streams = sctp_new_association_ind->out_streams;
...@@ -204,6 +206,49 @@ static void xnap_gNB_handle_sctp_association_ind(instance_t instance, sctp_new_a ...@@ -204,6 +206,49 @@ static void xnap_gNB_handle_sctp_association_ind(instance_t instance, sctp_new_a
xnap_dump_trees(instance); xnap_dump_trees(instance);
} }
static
void xnap_gNB_handle_handover_req(instance_t instance,
xnap_handover_req_t *xnap_handover_req)
{
xnap_gNB_instance_t *instance_p;
//xnap_gNB_data_t *target;
xnap_id_manager *id_manager;
int ue_id;
sctp_assoc_t assoc_id;
int target_nci = xnap_handover_req->target_cgi.cgi;
instance_p = xnap_gNB_get_instance(instance);
DevAssert(instance_p != NULL);
//target = xnap_is_gNB_pci_in_list(target_pci);Write new function for this if needed
//DevAssert(target != NULL);
/* allocate xnap ID */
id_manager = &instance_p->id_manager;
xnap_id_manager_init(id_manager);
ue_id = xnap_allocate_new_id(id_manager);
//MessageDef *message_p = itti_alloc_new_message(TASK_XNAP, 0, XNAP_HANDOVER_REQ);
//message_p->ittiMsgHeader.originInstance = assoc_id;
assoc_id = xnap_gNB_get_assoc_id(instance_p,target_nci);
LOG_I(XNAP, "NR Cell ID: %d \n",target_nci);
LOG_I(XNAP, "Association ID: %d \n",assoc_id);
//xnap_handover_req_t *req = &XNAP_HANDOVER_REQ(message_p);
if (ue_id == -1) {
LOG_E(XNAP,"could not allocate a new XNAP UE ID\n");
/* TODO: cancel handover: send (to be defined) message to RRC */
exit(1);
}
/* id_source is ue_id, id_target is unknown yet */
//xnap_set_ids(id_manager, ue_id, xnap_handover_req->rnti, ue_id, -1); //use?ho req structure wont have rnti- take from where it belongs to.
//xnap_id_set_state(id_manager, ue_id, XNID_STATE_SOURCE_PREPARE);// use?
//xnap_set_reloc_prep_timer(id_manager, ue_id,
//xnap_timer_get_tti(&instance_p->timers));
//xnap_id_set_target(id_manager, ue_id, target);
//xnap_gNB_generate_xn_handover_request(instance_p, target, xnap_handover_req, ue_id); //Review removed target here but needs it
xnap_gNB_generate_xn_handover_request(assoc_id, xnap_handover_req);
}
void *xnap_task(void *arg) void *xnap_task(void *arg)
{ {
...@@ -222,7 +267,9 @@ void *xnap_task(void *arg) ...@@ -222,7 +267,9 @@ void *xnap_task(void *arg)
break; break;
case XNAP_REGISTER_GNB_REQ: { case XNAP_REGISTER_GNB_REQ: {
xnap_setup_req_t *xnsetupmsg = &XNAP_REGISTER_GNB_REQ(received_msg).setup_req;
xnap_net_config_t *xn_nc = &XNAP_REGISTER_GNB_REQ(received_msg).net_config; xnap_net_config_t *xn_nc = &XNAP_REGISTER_GNB_REQ(received_msg).net_config;
createXninst(ITTI_MSG_DESTINATION_INSTANCE(received_msg), xnsetupmsg, xn_nc);
xnap_gNB_init_sctp(ITTI_MSG_DESTINATION_INSTANCE(received_msg), xn_nc); xnap_gNB_init_sctp(ITTI_MSG_DESTINATION_INSTANCE(received_msg), xn_nc);
} break; } break;
...@@ -234,6 +281,16 @@ void *xnap_task(void *arg) ...@@ -234,6 +281,16 @@ void *xnap_task(void *arg)
xnap_gNB_generate_xn_setup_response(ITTI_MSG_ORIGIN_INSTANCE(received_msg), &XNAP_SETUP_RESP(received_msg)); xnap_gNB_generate_xn_setup_response(ITTI_MSG_ORIGIN_INSTANCE(received_msg), &XNAP_SETUP_RESP(received_msg));
break; break;
case XNAP_HANDOVER_REQ: // from rrc
xnap_gNB_handle_handover_req(ITTI_MSG_ORIGIN_INSTANCE(received_msg),
&XNAP_HANDOVER_REQ(received_msg));
break;
case XNAP_HANDOVER_REQ_ACK:
LOG_I(XNAP,"HANDOVER_ACK going into the function \n");
xnap_gNB_generate_xn_handover_request_ack(ITTI_MSG_ORIGIN_INSTANCE(received_msg), &XNAP_HANDOVER_REQ_ACK(received_msg),ITTI_MSG_DESTINATION_INSTANCE(received_msg));
break;
case SCTP_INIT_MSG_MULTI_CNF: case SCTP_INIT_MSG_MULTI_CNF:
xnap_gNB_handle_sctp_init_msg_multi_cnf(ITTI_MSG_DESTINATION_INSTANCE(received_msg), xnap_gNB_handle_sctp_init_msg_multi_cnf(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
&received_msg->ittiMsg.sctp_init_msg_multi_cnf); &received_msg->ittiMsg.sctp_init_msg_multi_cnf);
......
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/* Poornima */
#include "xnap_ids.h"
#include <string.h>
void xnap_id_manager_init(xnap_id_manager *m)
{
int i;
memset(m, 0, sizeof(xnap_id_manager));
for (i = 0; i < XNAP_MAX_IDS; i++)
m->ids[i].rnti = -1;
}
int xnap_allocate_new_id(xnap_id_manager *m)
{
int i;
printf("rnti: %d \n",m->ids[0].rnti);
for (i = 0; i < XNAP_MAX_IDS; i++)
if (m->ids[i].rnti == -1) {
m->ids[i].rnti = 0;
m->ids[i].id_source = -1;
m->ids[i].id_target = -1;
return i;
}
return -1;
}
void xnap_release_id(xnap_id_manager *m, int id)
{
m->ids[id].rnti = -1;
}
int xnap_find_id(xnap_id_manager *m, int id_source, int id_target)
{
int i;
for (i = 0; i < XNAP_MAX_IDS; i++)
if (m->ids[i].rnti != -1 &&
m->ids[i].id_source == id_source &&
m->ids[i].id_target == id_target)
return i;
return -1;
}
int xnap_find_id_from_id_source(xnap_id_manager *m, int id_source)
{
int i;
for (i = 0; i < XNAP_MAX_IDS; i++)
if (m->ids[i].rnti != -1 &&
m->ids[i].id_source == id_source)
return i;
return -1;
}
int xnap_find_id_from_id_target(xnap_id_manager *m, int id_target)
{
int i;
for (i = 0; i < XNAP_MAX_IDS; i++)
if (m->ids[i].rnti != -1 &&
m->ids[i].id_target == id_target)
return i;
return -1;
}
int xnap_find_id_from_rnti(xnap_id_manager *m, int rnti)
{
int i;
for (i = 0; i < XNAP_MAX_IDS; i++)
if (m->ids[i].rnti == rnti)
return i;
return -1;
}
void xnap_set_ids(xnap_id_manager *m, int ue_id, int rnti, int id_source, int id_target)
{
m->ids[ue_id].rnti = rnti;
m->ids[ue_id].id_source = id_source;
m->ids[ue_id].id_target = id_target;
}
/* real type of target is xnap_gNB_data_t * */
void xnap_id_set_target(xnap_id_manager *m, int ue_id, void *target)
{
m->ids[ue_id].target = target;
}
void xnap_id_set_state(xnap_id_manager *m, int ue_id, xnid_state_t state)
{
m->ids[ue_id].state = state;
}
void xnap_set_reloc_prep_timer(xnap_id_manager *m, int ue_id, uint64_t time)
{
m->ids[ue_id].t_reloc_prep_start = time;
}
void xnap_set_reloc_overall_timer(xnap_id_manager *m, int ue_id, uint64_t time)
{
m->ids[ue_id].tx2_reloc_overall_start = time;
}
void xnap_set_dc_prep_timer(xnap_id_manager *m, int ue_id, uint64_t time)
{
m->ids[ue_id].t_dc_prep_start = time;
}
void xnap_set_dc_overall_timer(xnap_id_manager *m, int ue_id, uint64_t time)
{
m->ids[ue_id].t_dc_overall_start = time;
}
int xnap_id_get_id_source(xnap_id_manager *m, int ue_id)
{
return m->ids[ue_id].id_source;
}
int xnap_id_get_id_target(xnap_id_manager *m, int ue_id)
{
return m->ids[ue_id].id_target;
}
int xnap_id_get_rnti(xnap_id_manager *m, int ue_id)
{
return m->ids[ue_id].rnti;
}
void *xnap_id_get_target(xnap_id_manager *m, int ue_id)
{
return m->ids[ue_id].target;
}
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/* Poornima */
#ifndef XNAP_IDS_H_
#define XNAP_IDS_H_
#include <stdio.h>
#include <stdint.h>
/* maximum number of simultaneous handovers, do not set too high */
#define XNAP_MAX_IDS 16
/*
* state:
* - when starting handover in source, UE is in state XNID_STATE_SOURCE_PREPARE
* - after receiving HO_ack in source, UE is in state XNID_STATE_SOURCE_OVERALL
* - in target, UE is in state XNID_STATE_TARGET
* The state is used to check timers.
*/
typedef enum {
XNID_STATE_SOURCE_PREPARE,
XNID_STATE_SOURCE_OVERALL,
XNID_STATE_TARGET,
XNID_STATE_NSA_GNB_PREPARE,
XNID_STATE_NSA_GNB_OVERALL,
} xnid_state_t;
typedef struct {
int rnti; /* -1 when free */
int id_source;
int id_target;
/* the target eNB. Real type is x2ap_eNB_data_t * */
void *target;
/* state: needed to check timers */
xnid_state_t state;
/* timers */
uint64_t t_reloc_prep_start;
uint64_t tx2_reloc_overall_start;
uint64_t t_dc_prep_start;
uint64_t t_dc_overall_start;
} xnap_id;
typedef struct {
xnap_id ids[XNAP_MAX_IDS];
} xnap_id_manager;
void xnap_id_manager_init(xnap_id_manager *m);
int xnap_allocate_new_id(xnap_id_manager *m);
void xnap_release_id(xnap_id_manager *m, int id);
int xnap_find_id(xnap_id_manager *, int id_source, int id_target);
int xnap_find_id_from_id_source(xnap_id_manager *, int id_source);
int xnap_find_id_from_id_target(xnap_id_manager *, int id_source);
int xnap_find_id_from_rnti(xnap_id_manager *, int rnti);
void xnap_set_ids(xnap_id_manager *m, int ue_id, int rnti, int id_source, int id_target);
void xnap_id_set_state(xnap_id_manager *m, int ue_id, xnid_state_t state);
/* real type of target is x2ap_eNB_data_t * */
void xnap_id_set_target(xnap_id_manager *m, int ue_id, void *target);
void xnap_set_reloc_prep_timer(xnap_id_manager *m, int ue_id, uint64_t time);
void xnap_set_reloc_overall_timer(xnap_id_manager *m, int ue_id, uint64_t time);
void xnap_set_dc_prep_timer(xnap_id_manager *m, int ue_id, uint64_t time);
void xnap_set_dc_overall_timer(xnap_id_manager *m, int ue_id, uint64_t time);
int xnap_id_get_id_source(xnap_id_manager *m, int ue_id);
int xnap_id_get_id_target(xnap_id_manager *m, int ue_id);
int xnap_id_get_rnti(xnap_id_manager *m, int ue_id);
void *xnap_id_get_target(xnap_id_manager *m, int ue_id);
#endif /* X2AP_IDS_H_ */
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "xnap_timers.h"
#include "assertions.h"
#include "PHY/defs_common.h" /* TODO: try to not include this */
#include "xnap_messages_types.h"
#include "xnap_gNB_defs.h"
#include "xnap_ids.h"
#include "xnap_gNB_management_procedures.h"
#include "xnap_gNB_generate_messages.h"
void xnap_timers_init(xnap_timers_t *t,
int t_reloc_prep,
int tx2_reloc_overall,
int t_dc_prep,
int t_dc_overall)
{
t->tti = 0;
t->t_reloc_prep = t_reloc_prep;
t->tx2_reloc_overall = tx2_reloc_overall;
t->t_dc_prep = t_dc_prep;
t->t_dc_overall = t_dc_overall;
}
/*
void xnap_check_timers(instance_t instance)
{
xnap_gNB_instance_t *instance_p;
xnap_timers_t *t;
xnap_id_manager *m;
int i;
xnap_handover_cancel_cause_t cause;
void *target;
MessageDef *msg;
int xnap_ongoing;
instance_p = xnap_gNB_get_instance(instance);
DevAssert(instance_p != NULL);
t = &instance_p->timers;
m = &instance_p->id_manager;
// increment subframe count
t->tti++;
xnap_ongoing = 0;
for (i = 0; i < XNAP_MAX_IDS; i++) {
if (m->ids[i].rnti == -1) continue;
if (m->ids[i].state == XNAPID_STATE_SOURCE_PREPARE ||
m->ids[i].state == XNAPID_STATE_SOURCE_OVERALL)
xnap_ongoing++;
if (m->ids[i].state == XNAPID_STATE_SOURCE_PREPARE &&
t->tti > m->ids[i].t_reloc_prep_start + t->t_reloc_prep) {
LOG_I(XNAP, "XNAP timeout reloc prep\n");
// t_reloc_prep timed out
cause = XNAP_T_RELOC_PREP_TIMEOUT;
goto xnap_handover_timeout;
}
if (m->ids[i].state == XNAPID_STATE_SOURCE_OVERALL &&
t->tti > m->ids[i].tx2_reloc_overall_start + t->tx2_reloc_overall) {
LOG_I(XNAP, "XNAP timeout reloc overall\n");
// tx2_reloc_overall timed out
cause = XNAP_TX2_RELOC_OVERALL_TIMEOUT;
goto xnap_handover_timeout;
}
if (m->ids[i].state == XNAPID_STATE_NSA_GNB_PREPARE &&
t->tti > m->ids[i].t_dc_prep_start + t->t_dc_prep) {
int id_source;
int id_target;
LOG_I(XNAP, "XNAP timeout DC prep\n");
// t_dc_prep timed out
target = xnap_id_get_target(m, i);
id_source = xnap_id_get_id_source(m, i);
id_target = xnap_id_get_id_target(m, i);
xnap_gNB_generate_ENDC_xnap_SgNB_release_request(instance_p, target,
id_source, id_target,
XNAP_CAUSE_T_DC_PREP_TIMEOUT);
// inform RRC of timeout
msg = itti_alloc_new_message(TASK_XNAP, 0, XNAP_ENDC_DC_PREP_TIMEOUT);
XNAP_ENDC_DC_PREP_TIMEOUT(msg).rnti = xnap_id_get_rnti(m, i);
itti_send_msg_to_task(TASK_RRC_GNB, instance_p->instance, msg);
// remove UE from XNAP
xnap_release_id(m, i);
continue;
}
if (m->ids[i].state == XNAPID_STATE_NSA_GNB_OVERALL &&
t->tti > m->ids[i].t_dc_overall_start + t->t_dc_overall) {
int id_source;
int id_target;
LOG_I(XNAP, "XNAP timeout DC overall\n");
// t_dc_overall timed out
target = xnap_id_get_target(m, i);
id_source = xnap_id_get_id_source(m, i);
id_target = xnap_id_get_id_target(m, i);
xnap_gNB_generate_ENDC_xnap_SgNB_release_required(instance_p, target,
id_source, id_target, XNAP_CAUSE_T_DC_OVERALL_TIMEOUT);
// inform RRC of timeout
msg = itti_alloc_new_message(TASK_XNAP, 0, XNAP_ENDC_DC_OVERALL_TIMEOUT);
XNAP_ENDC_DC_OVERALL_TIMEOUT(msg).rnti = xnap_id_get_rnti(m, i);
itti_send_msg_to_task(TASK_RRC_GNB, instance_p->instance, msg);
// remove UE from X2AP
xnap_release_id(m, i);
continue;
}
// no timeout -> check next UE
continue;
xnap_handover_timeout:
// inform target about timeout
target = xnap_id_get_target(m, i);
xnap_gNB_generate_xnap_handover_cancel(instance_p, target, i, cause);
// inform RRC of cancellation
msg = itti_alloc_new_message(TASK_XNAP, 0, XNAP_HANDOVER_CANCEL);
XNAP_HANDOVER_CANCEL(msg).rnti = xnap_id_get_rnti(m, i);
XNAP_HANDOVER_CANCEL(msg).cause = cause;
itti_send_msg_to_task(TASK_RRC_GNB, instance_p->instance, msg);
// remove UE from XNAP
xnap_release_id(m, i);
}
if (xnap_ongoing && t->tti % 1000 == 0)
LOG_I(XNAP, "XNAP has %d process ongoing\n", xnap_ongoing);
}
uint64_t xnap_timer_get_tti(xnap_timers_t *t)
{
return t->tti;
} **/
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef XNAP_TIMERS_H_
#define XNAP_TIMERS_H_
#include <stdint.h>
//#include "platform_types.h"
typedef struct {
/* incremented every TTI (every millisecond when in realtime).
* Used to check timers.
* 64 bits gives us more than 500 million years of (realtime) processing.
* It should be enough.
*/
uint64_t tti;
/* timer values (unit: TTI, ie. millisecond when in realtime) */
int t_reloc_prep;
int tx2_reloc_overall;
int t_dc_prep;
int t_dc_overall;
} xnap_timers_t;
void xnap_timers_init(xnap_timers_t *t,
int t_reloc_prep,
int tx2_reloc_overall,
int t_dc_prep,
int t_dc_overall);
//void xnap_check_timers(instance_t instance);
uint64_t xnap_timer_get_tti(xnap_timers_t *t);
#endif /* X2AP_TIMERS_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment