Commit 6ebceb6b authored by Sreeshma Shiv's avatar Sreeshma Shiv

HO_REQ_ACK

parent 9f092d00
......@@ -33,3 +33,4 @@ 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_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_HANDOVER_REQ, MESSAGE_PRIORITY_MED, xnap_handover_req_t, xnap_handover_req)
......@@ -27,12 +27,17 @@
#ifndef XNAP_MESSAGES_TYPES_H_
#define XNAP_MESSAGES_TYPES_H_
#include "s1ap_messages_types.h"
#include "ngap_messages_types.h"
#include "NR_PhysCellId.h"
#include "asn_codecs_prim.h"
// Defines to access message fields.
#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_RESP(mSGpTR) (mSGpTR)->ittiMsg.xnap_setup_resp
#define XNAP_SETUP_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.xnap_setup_failure
#define XNAP_HANDOVER_REQ(mSGpTR) (mSGpTR)->ittiMsg.xnap_handover_req
#define XNAP_MAX_NB_GNB_IP_ADDRESS 4
......@@ -45,7 +50,47 @@ typedef struct xnap_net_ip_address_s {
char ipv6_address[46];
} xnap_net_ip_address_t;
<<<<<<< HEAD
typedef struct xnap_sctp_s {
=======
typedef struct xnap_register_gnb_req_s {
uint32_t gNB_id;
char *gNB_name;
/* Tracking area code */
uint16_t tac;
/* Mobile Country Code
* Mobile Network Code
*/
uint16_t mcc;
uint16_t mnc;
uint8_t mnc_digit_length;
int16_t eutra_band;
int32_t nr_band;
int32_t nrARFCN;
uint32_t downlink_frequency;
int32_t uplink_frequency_offset;
uint32_t Nid_cell;
int16_t N_RB_DL;
frame_type_t frame_type;
uint32_t fdd_earfcn_DL;
uint32_t fdd_earfcn_UL;
uint32_t subframeAssignment;
uint32_t specialSubframe;
uint16_t tdd_nRARFCN;
uint16_t tdd_Transmission_Bandwidth;
/* The local gNB IP address to bind */
gnb_ip_address_t gnb_xn_ip_address;
/* Nb of GNB to connect to */
uint8_t nb_xn;
/* List of target gNB to connect to for Xn*/
gnb_ip_address_t target_gnb_xn_ip_address[XNAP_MAX_NB_GNB_IP_ADDRESS];
/* Number of SCTP streams used for associations */
>>>>>>> b05e275c38 (xnap-targetgnb)
uint16_t sctp_in_streams;
uint16_t sctp_out_streams;
} xnap_sctp_t;
......@@ -71,6 +116,7 @@ typedef struct xnap_amf_regioninfo_s {
uint8_t amf_region_id;
} xnap_amf_regioninfo_t;
<<<<<<< HEAD
typedef enum xnap_mode_t { XNAP_MODE_TDD = 0, XNAP_MODE_FDD = 1 } xnap_mode_t;
typedef struct xnap_nr_frequency_info_t {
......@@ -166,4 +212,78 @@ typedef struct xnap_setup_failure_s {
uint16_t time_to_wait;
uint16_t criticality_diagnostics;
} xnap_setup_failure_t;
=======
typedef struct xnap_lastvisitedcell_info_s {
uint16_t mcc;
uint16_t mnc;
uint8_t mnc_len;
NR_PhysCellId_t target_physCellId;
cell_type_t cell_type;
uint64_t time_UE_StayedInCell;
} xnap_lastvisitedcell_info_t;
typedef struct xnap_allocation_retention_priority_s {
ngap_priority_level_t priorityLevel;
ngap_pre_emp_capability_t pre_emp_capability;
ngap_pre_emp_vulnerability_t pre_emp_vulnerability;
} xnap_allocation_retention_priority_t;
typedef struct xnap_pdusession_level_qos_parameter_s {
uint8_t qfi;
long non_dynamic_fiveQI;
long dynamic_priorityLevelQoS;
long dynamic_packetDelayBudget;
long dynamic_packetErrorRate_scalar;
long dynamic_packetErrorRate_exponent;
ngap_allocation_retention_priority_t allocation_retention_priority;
} xnap_pdusession_level_qos_parameter_t;
typedef struct xnap_pdusession_s {
/* Unique pdusession_id for the UE. */
uint8_t pdusession_id;
transport_layer_addr_t gNB_addr;
/* UPF Tunnel endpoint identifier */
uint32_t gtp_teid;
/* Quality of service for this pdusession */
xnap_pdusession_level_qos_parameter_t qos[QOSFLOW_MAX_VALUE];
} xnap_pdusession_t;
typedef struct xnap_handover_req_s {
/* RRC->XNAP in source eNB */
int rnti;
/* XNAP->RRC in target eNB */
int xn_id;
NR_PhysCellId_t target_physCellId;
xnap_guami_t ue_guami;
/*UE-ContextInformation */
/* ? amf UE id */
ASN__PRIMITIVE_TYPE_t ue_ngap_id;
security_capabilities_t security_capabilities;
uint8_t kenb[32]; // keNB or keNB*
/*next_hop_chaining_coun */
long int kenb_ncc;
/* UE aggregate maximum bitrate */
ambr_t ue_ambr;
uint8_t nb_pdu_resources_tobe_setup;
/* list of pdu session to be setup by RRC layers */
xnap_pdusession_t pdu_param[NGAP_MAX_PDUSESSION];
xnap_lastvisitedcell_info_t lastvisitedcell_info;
uint8_t rrc_buffer[8192 /* arbitrary, big enough */];
int rrc_buffer_size;
int target_assoc_id;
} xnap_handover_req_t;
>>>>>>> b05e275c38 (xnap-targetgnb)
#endif /* XNAP_MESSAGES_TYPES_H_ */
......@@ -6,7 +6,7 @@ add_library(xnap
xnap_gNB_itti_messaging.c
xnap_gNB_handler.c
xnap_gNB_interface_management.c
xnap_gNB_generate_messages)
xnap_gNB_generate_messages.c)
target_link_libraries(xnap
PUBLIC asn1_xnap
PRIVATE nr_rrc)
......
......@@ -20,7 +20,8 @@
*/
/*! \file xnap_common.c
* \brief xnap encoder,decoder dunctions for gNB
<<<<<<< HEAD
* \brief xnap common functions for gNB
* \author Sreeshma Shiv <sreeshmau@iisc.ac.in>
* \date Dec 2023
* \version 1.0
......@@ -71,3 +72,27 @@ int xnap_gNB_decode_pdu(XNAP_XnAP_PDU_t *pdu, const uint8_t *const buffer, uint3
}
return 0;
}
int xnap_allocate_new_id(xnap_id_manager *m)
{
int i;
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_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;
}
void xnap_id_set_state(xnap_id_manager *m, int ue_id, xnid_state_t state)
{
m->ids[ue_id].state = state;
}
......@@ -35,9 +35,12 @@
#include "oai_asn1.h"
#ifndef XNAP_PORT
#define XNAP_PORT 38423
#define XNAP_PORT 38422
#endif
/* maximum number of simultaneous handovers */
#define XNAP_MAX_IDS 16
extern int asn1_xer_print;
#define XNAP_FIND_PROTOCOLIE_BY_ID(IE_TYPE, ie, container, IE_ID, mandatory) \
......@@ -58,4 +61,35 @@ extern int asn1_xer_print;
typedef int (*xnap_message_decoded_callback)(instance_t instance, sctp_assoc_t assocId, uint32_t stream, XNAP_XnAP_PDU_t *pdu);
int xnap_gNB_decode_pdu(XNAP_XnAP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length) __attribute__((warn_unused_result));
int xnap_gNB_encode_pdu(XNAP_XnAP_PDU_t *pdu, uint8_t **buffer, uint32_t *len) __attribute__((warn_unused_result));
typedef enum {
XNID_STATE_SOURCE_PREPARE,
XNID_STATE_SOURCE_OVERALL,
XNID_STATE_TARGET,
} xnid_state_t;
typedef struct {
int rnti; /* -1 when free */
int id_source;
int id_target;
void *target;
/* state: needed to check timers */
xnid_state_t state;
/* timers */
uint64_t t_reloc_prep_start;
uint64_t txn_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;
int xnap_allocate_new_id(xnap_id_manager *m);
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);
#endif /* XNAP_COMMON_H_ */
......@@ -23,6 +23,7 @@
#include "tree.h"
#include "sctp_eNB_defs.h"
#include "xnap_messages_types.h"
#include "xnap_common.h"
#ifndef XNAP_GNB_DEFS_H_
#define XNAP_GNB_DEFS_H_
......
......@@ -37,7 +37,7 @@
/* Placement of callback functions according to XNAP_ProcedureCode.h */
static const xnap_message_decoded_callback xnap_messages_callback[][3] = {
{0, 0, 0},
{xnap_gNB_handle_handover_request, 0, 0}, /*handover preperation*/
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
......@@ -199,3 +199,161 @@ int xnap_gNB_handle_message(instance_t instance,
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_XNAP_XnAP_PDU, &pdu);
return ret;
}
static 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_QoSFlowsToBeSetup_Item_t *qosflowstobesetup_item;
XNAP_PDUSessionResourcesToBeSetup_Item_t *pduSession_ToBeSetup_Item;
xnap_gNB_instance_t *instance_p;
xnap_gNB_data_t *xnap_gNB_data;
MessageDef *msg;
int ue_id;
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");
/* TODO: send a xn failure response */
return 0;
}
LOG_D(XNAP, "Received a new XN handover request\n");
xnap_gNB_data = xnap_get_gNB(NULL, assoc_id, 0);
DevAssert(xnap_gNB_data != NULL);
instance_p = xnap_gNB_get_instance(instance);
DevAssert(instance_p != NULL);
msg = itti_alloc_new_message(TASK_XNAP, 0, XNAP_HANDOVER_REQ);
XNAP_FIND_PROTOCOLIE_BY_ID(XNAP_HandoverRequest_IEs_t, ie, xnHandoverRequest, XNAP_ProtocolIE_ID_id_oldNG_RANnodeUEXnAPID, true);
if (ie == NULL) {
LOG_E(XNAP, "%s %d: ie is a NULL pointer \n", __FILE__, __LINE__);
itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
return -1;
}
/* allocate a new XNAP UE ID */
ue_id = xnap_allocate_new_id(&instance_p->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 gNB */
exit(1);
}
/* rnti is unknown yet, must not be set to -1, 0 is fine */
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(msg).xn_id = ue_id;
XNAP_FIND_PROTOCOLIE_BY_ID(XNAP_HandoverRequest_IEs_t, ie, xnHandoverRequest, XNAP_ProtocolIE_ID_id_GUAMI, true);
if (ie == NULL) {
LOG_E(XNAP, "%s %d: ie is a NULL pointer \n", __FILE__, __LINE__);
itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
return -1;
}
TBCD_TO_MCC_MNC(&ie->value.choice.GUAMI.plmn_ID,
XNAP_HANDOVER_REQ(msg).ue_guami.mcc,
XNAP_HANDOVER_REQ(msg).ue_guami.mnc,
XNAP_HANDOVER_REQ(msg).ue_guami.mnc_len);
OCTET_STRING_TO_INT8(&ie->value.choice.GUAMI.amf_region_id, XNAP_HANDOVER_REQ(msg).ue_guami.amf_region_id); // bit string
OCTET_STRING_TO_INT16(&ie->value.choice.GUAMI.amf_set_id, XNAP_HANDOVER_REQ(msg).ue_guami.amf_set_id); // bit string
OCTET_STRING_TO_INT16(&ie->value.choice.GUAMI.amf_pointer, XNAP_HANDOVER_REQ(msg).ue_guami.amf_pointer); // bit string
XNAP_FIND_PROTOCOLIE_BY_ID(XNAP_HandoverRequest_IEs_t, ie, xnHandoverRequest, XNAP_ProtocolIE_ID_id_UEContextInfoHORequest, true);
if (ie == NULL) {
LOG_E(XNAP, "%s %d: ie is a NULL pointer \n", __FILE__, __LINE__);
itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
return -1;
}
XNAP_HANDOVER_REQ(msg).ue_ngap_id = ie->value.choice.UEContextInfoHORequest.ng_c_UE_reference;
/* TODO: properly store Target Cell ID */
XNAP_HANDOVER_REQ(msg).target_assoc_id = assoc_id;
XNAP_HANDOVER_REQ(msg).security_capabilities.encryption_algorithms =
BIT_STRING_to_uint16(&ie->value.choice.UEContextInfoHORequest.ueSecurityCapabilities.nr_EncyptionAlgorithms);
XNAP_HANDOVER_REQ(msg).security_capabilities.integrity_algorithms =
BIT_STRING_to_uint16(&ie->value.choice.UEContextInfoHORequest.ueSecurityCapabilities.nr_IntegrityProtectionAlgorithms);
// XNAP_HANDOVER_REQ(msg).ue_ambr=ue_context_pP->ue_context.ue_ambr;
if ((ie->value.choice.UEContextInfoHORequest.securityInformation.key_NG_RAN_Star.buf)
&& (ie->value.choice.UEContextInfoHORequest.securityInformation.key_NG_RAN_Star.size == 32)) {
memcpy(XNAP_HANDOVER_REQ(msg).kenb, ie->value.choice.UEContextInfoHORequest.securityInformation.key_NG_RAN_Star.buf, 32);
XNAP_HANDOVER_REQ(msg).kenb_ncc = ie->value.choice.UEContextInfoHORequest.securityInformation.ncc;
} else {
LOG_W(XNAP, "Size of key NG-RAN star does not match the expected value\n");
}
if (ie->value.choice.UEContextInfoHORequest.pduSessionResourcesToBeSetup_List.list.count > 0) {
XNAP_HANDOVER_REQ(msg).nb_pdu_resources_tobe_setup =
ie->value.choice.UEContextInfoHORequest.pduSessionResourcesToBeSetup_List.list.count;
for (int i = 0; i < ie->value.choice.UEContextInfoHORequest.pduSessionResourcesToBeSetup_List.list.count; i++) {
pduSession_ToBeSetup_Item = (XNAP_PDUSessionResourcesToBeSetup_Item_t *)
ie->value.choice.UEContextInfoHORequest.pduSessionResourcesToBeSetup_List.list.array[i];
// pduSession_ToBeSetup_Item = &pduSession_ToBeSetup_ItemIEs->value.choice.pduSession_ToBeSetup_Item;
XNAP_HANDOVER_REQ(msg).pdu_param[i].pdusession_id = pduSession_ToBeSetup_Item->pduSessionId;
memcpy(XNAP_HANDOVER_REQ(msg).pdu_param[i].gNB_addr.buffer,
pduSession_ToBeSetup_Item->uL_NG_U_TNLatUPF.choice.gtpTunnel->tnl_address.buf,
pduSession_ToBeSetup_Item->uL_NG_U_TNLatUPF.choice.gtpTunnel->tnl_address.size);
XNAP_HANDOVER_REQ(msg).pdu_param[i].gNB_addr.length =
pduSession_ToBeSetup_Item->uL_NG_U_TNLatUPF.choice.gtpTunnel->tnl_address.size * 8
- pduSession_ToBeSetup_Item->uL_NG_U_TNLatUPF.choice.gtpTunnel->tnl_address.bits_unused;
OCTET_STRING_TO_INT32(&pduSession_ToBeSetup_Item->uL_NG_U_TNLatUPF.choice.gtpTunnel->gtp_teid,
XNAP_HANDOVER_REQ(msg).pdu_param[i].gtp_teid);
for (int j = 0; j < pduSession_ToBeSetup_Item->qosFlowsToBeSetup_List.list.count; j++) {
qosflowstobesetup_item = (XNAP_QoSFlowsToBeSetup_Item_t *)pduSession_ToBeSetup_Item->qosFlowsToBeSetup_List.list.array[j];
XNAP_HANDOVER_REQ(msg).pdu_param[i].qos[j].qfi = qosflowstobesetup_item->qfi;
if (qosflowstobesetup_item->qosFlowLevelQoSParameters.qos_characteristics.present
== XNAP_QoSCharacteristics_PR_non_dynamic) {
XNAP_HANDOVER_REQ(msg).pdu_param[i].qos[j].non_dynamic_fiveQI =
qosflowstobesetup_item->qosFlowLevelQoSParameters.qos_characteristics.choice.non_dynamic->fiveQI;
} else if (qosflowstobesetup_item->qosFlowLevelQoSParameters.qos_characteristics.present
== XNAP_QoSCharacteristics_PR_dynamic) {
XNAP_HANDOVER_REQ(msg).pdu_param[i].qos[j].dynamic_priorityLevelQoS =
qosflowstobesetup_item->qosFlowLevelQoSParameters.qos_characteristics.choice.dynamic->priorityLevelQoS;
XNAP_HANDOVER_REQ(msg).pdu_param[i].qos[j].dynamic_packetDelayBudget =
qosflowstobesetup_item->qosFlowLevelQoSParameters.qos_characteristics.choice.dynamic->packetDelayBudget;
XNAP_HANDOVER_REQ(msg).pdu_param[i].qos[j].dynamic_packetErrorRate_scalar =
qosflowstobesetup_item->qosFlowLevelQoSParameters.qos_characteristics.choice.dynamic->packetErrorRate.pER_Scalar;
XNAP_HANDOVER_REQ(msg).pdu_param[i].qos[j].dynamic_packetErrorRate_exponent =
qosflowstobesetup_item->qosFlowLevelQoSParameters.qos_characteristics.choice.dynamic->packetErrorRate.pER_Exponent;
}
XNAP_HANDOVER_REQ(msg).pdu_param[i].qos[j].allocation_retention_priority.priority_level =
qosflowstobesetup_item->qosFlowLevelQoSParameters.allocationAndRetentionPrio.priorityLevel;
XNAP_HANDOVER_REQ(msg).pdu_param[i].qos[j].allocation_retention_priority.pre_emp_capability =
qosflowstobesetup_item->qosFlowLevelQoSParameters.allocationAndRetentionPrio.pre_emption_capability;
XNAP_HANDOVER_REQ(msg).pdu_param[i].qos[j].allocation_retention_priority.pre_emp_vulnerability =
qosflowstobesetup_item->qosFlowLevelQoSParameters.allocationAndRetentionPrio.pre_emption_vulnerability;
}
}
} else {
LOG_E(XNAP, "Can't decode the QoS to be setup item \n");
}
OCTET_STRING_t *c = &ie->value.choice.UEContextInfoHORequest.rrc_Context;
if (c->size > 8192 /* TODO: this is the size of rrc_buffer in struct xnap_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, msg);
return 0;
}
......@@ -35,5 +35,4 @@ int xnap_gNB_handle_message(instance_t instance,
int32_t stream,
const uint8_t *const data,
const uint32_t data_length);
#endif /* XNAP_GNB_HANDLERS_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