Commit f8607ae6 authored by Vijitha M's avatar Vijitha M

Xn Handover request/ack- split

parent a108c031
......@@ -56,4 +56,5 @@ typedef enum { CPtype = 0, UPtype } E1_t;
#define GTPV1_U_PORT_NUMBER (2152)
typedef enum { non_dynamic, dynamic } fiveQI_type_t;
#define maxSRBs 4
#endif
......@@ -12,6 +12,7 @@
# define NUMBER_OF_SRS_MAX 16
# define NUMBER_OF_SCH_STATS_MAX 16
#define NUMBER_OF_DU_PER_CU_MAX 2
#define MAX_MANAGED_ENB_PER_MOBILE 2
#define MAX_MANAGED_GNB_PER_MOBILE 2
......
......@@ -423,6 +423,12 @@ typedef struct f1ap_ue_context_setup_s {
ReconfigurationCompl_t ReconfigComplOutcome;
uint8_t *rrc_container;
int rrc_container_length;
uint16_t mcc;
uint16_t mnc;
uint8_t mnc_digit_length;
uint16_t *crnti;
uint8_t *transmission_action_indicator;
} f1ap_ue_context_setup_t, f1ap_ue_context_modif_req_t, f1ap_ue_context_modif_resp_t;
typedef enum F1ap_Cause_e {
......@@ -439,6 +445,7 @@ typedef struct f1ap_ue_context_modif_required_t {
du_to_cu_rrc_information_t *du_to_cu_rrc_information;
f1ap_Cause_t cause;
long cause_value;
uint8_t *transmission_action_indicator; //not sure
} f1ap_ue_context_modif_required_t;
typedef struct f1ap_ue_context_modif_confirm_t {
......
......@@ -269,9 +269,10 @@ typedef struct xnap_ue_context_info_s {
} 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;
int ue_id; /* used for RRC->XNAP in source */
//int xn_id; /* used for XNAP->RRC in target*/
uint32_t s_ng_node_ue_xnap_id;
uint32_t t_ng_node_ue_xnap_id;
xnap_plmn_t plmn_id;
xnap_Cause_t cause_type;
xnap_ngran_cgi_t target_cgi;
......@@ -280,14 +281,16 @@ typedef struct xnap_handover_req_s {
} xnap_handover_req_t;
typedef struct xnap_handover_req_ack_s {
uint32_t ng_node_ue_xnap_id;
int rnti;
int xn_id_target;
int ue_id;
uint32_t s_ng_node_ue_xnap_id;
uint32_t t_ng_node_ue_xnap_id;
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;
uint8_t rrc_buffer[8192];
int rrc_buffer_size;
} xnap_handover_req_ack_t;
typedef struct xnap_handover_req_failure_s{
......
......@@ -574,6 +574,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu
// return -1;
// }
LOG_D(F1AP,"F1AP UEContextSetupRequest Encoded %u bits\n", len);
LOG_I(F1AP,"F1AP UEContextSetupRequest Encoded %u bits\n", len);
f1ap_itti_send_sctp_data_req(assoc_id, buffer, len);
return 0;
}
......
......@@ -288,7 +288,7 @@ int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_i
} else {
LOG_W(F1AP, "can't find RRCContainer in UEContextSetupRequestIEs by id %ld \n", F1AP_ProtocolIE_ID_id_RRCContainer);
}
LOG_I(F1AP, "F1AP UE context setup handled in DU\n");
ue_context_setup_request(f1ap_ue_context_setup_req);
return 0;
}
......
......@@ -146,6 +146,7 @@
#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"
#include "NR_HandoverCommand.h"
//#define XER_PRINT
......@@ -1273,3 +1274,30 @@ int do_NRHandoverPreparation(char *ho_buf, int ho_size, NR_UE_NR_Capability_t *
return((enc_rval.encoded+7)/8);
}
int16_t do_NR_HandoverCommand(uint8_t *ho_buf, int16_t ho_size, uint8_t *rrc_buffer, int16_t rrc_size) {
NR_HandoverCommand_t *ho_command = calloc(1,sizeof(NR_HandoverCommand_t));
ho_command->criticalExtensions.present = NR_HandoverCommand__criticalExtensions_PR_c1;
ho_command->criticalExtensions.choice.c1 = calloc(1,sizeof(struct NR_HandoverCommand__criticalExtensions__c1));
ho_command->criticalExtensions.choice.c1->present = NR_HandoverCommand__criticalExtensions__c1_PR_handoverCommand;
ho_command->criticalExtensions.choice.c1->choice.handoverCommand = calloc(1,sizeof(struct NR_HandoverCommand_IEs));
AssertFatal(OCTET_STRING_fromBuf(&ho_command->criticalExtensions.choice.c1->choice.handoverCommand->handoverCommandMessage, (char *)rrc_buffer, rrc_size) != -1,
"fatal: OCTET_STRING_fromBuf failed\n");
xer_fprint(stdout,&asn_DEF_NR_HandoverCommand, ho_command);
asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_HandoverCommand,
NULL,
ho_command,
ho_buf,
ho_size);
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);
}
......@@ -148,5 +148,6 @@ void free_defaultMeasConfig(NR_MeasConfig_t *mc);
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);
int16_t do_NR_HandoverCommand(uint8_t *ho_buf, int16_t ho_size, uint8_t *rrc_buffer, int16_t rrc_size);
#endif /* __RRC_NR_MESSAGES_ASN1_MSG__H__ */
......@@ -251,6 +251,7 @@ typedef enum {
typedef struct gNB_RRC_UE_s {
drb_t established_drbs[MAX_DRBS_PER_UE];
uint8_t DRB_active[MAX_DRBS_PER_UE];
NR_DRB_ToReleaseList_t *DRB_ReleaseList;
NR_SRB_INFO_TABLE_ENTRY Srb[NR_NUM_SRB];
......@@ -437,6 +438,8 @@ typedef struct gNB_RRC_INST_s {
RB_HEAD(rrc_neigh_cell_tree, nr_rrc_neighcells_container_t) neighs; // Neighbouring cells, indexed by assoc_id
size_t num_neighs;
instance_t f1_instance;
} gNB_RRC_INST;
#include "nr_rrc_proto.h" //should be put here otherwise compilation error
......
......@@ -34,5 +34,7 @@
#include "COMMON/mac_rrc_primitives.h"
#include "LAYER2/RLC/rlc.h"
#include "openair2/RRC/common.h"
extern uint16_t ho_rnti_map[NUMBER_OF_DU_PER_CU_MAX][4];
void openair_rrc_gNB_configuration(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *configuration);
#endif
......@@ -99,7 +99,8 @@ rrc_gNB_generate_RRCRelease(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP
);
void rrc_gNB_process_handoverprepinfo(sctp_assoc_t assoc_id, xnap_handover_req_t *m);
void rrc_gNB_process_handover_req_ack(sctp_assoc_t assoc_id, xnap_handover_req_ack_t *m);
/**\brief RRC eNB task.
\param args_p Pointer on arguments to start the task. */
void *rrc_gnb_task(void *args_p);
......
......@@ -106,6 +106,8 @@
#include "openair2/COMMON/xnap_messages_types.h"
#include "openair2/XNAP/xnap_gNB_task.h"
#include "openair2/RRC/NR/MESSAGES/asn1_msg.h"
#include "NR_HandoverCommand.h"
#include "NR_RRCReconfiguration.h"
#ifdef E2_AGENT
#include "openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_rc_extern.h"
......@@ -129,6 +131,73 @@ mui_t rrc_gNB_mui = 0;
///---------------------------------------------------------------------------------------------------------------///
///---------------------------------------------------------------------------------------------------------------///
NR_DRB_ToAddModList_t *fill_DRB_configList(gNB_RRC_UE_t *ue)
{
gNB_RRC_INST *rrc = RC.nrrrc[0];
if (ue->nb_of_pdusessions == 0)
return NULL;
int nb_drb_to_setup = rrc->configuration.drbs;
long drb_priority[MAX_DRBS_PER_UE] = {0};
uint8_t drb_id_to_setup_start = 0;
NR_DRB_ToAddModList_t *DRB_configList = CALLOC(sizeof(*DRB_configList), 1);
for (int i = 0; i < ue->nb_of_pdusessions; i++) {
if (ue->pduSession[i].status >= PDU_SESSION_STATUS_DONE) {
continue;
}
LOG_I(NR_RRC, "adding rnti %x pdusession %d, nb drb %d\n", ue->rnti, ue->pduSession[i].param.pdusession_id, nb_drb_to_setup);
for (long drb_id_add = 1; drb_id_add <= nb_drb_to_setup; drb_id_add++) {
uint8_t drb_id;
// Reference TS23501 Table 5.7.4-1: Standardized 5QI to QoS characteristics mapping
for (int qos_flow_index = 0; qos_flow_index < ue->pduSession[i].param.nb_qos; qos_flow_index++) {
switch (ue->pduSession[i].param.qos[qos_flow_index].fiveQI) {
case 1 ... 4: /* GBR */
drb_id = next_available_drb(ue, &ue->pduSession[i], GBR_FLOW);
break;
case 5 ... 9: /* Non-GBR */
if (rrc->configuration.drbs > 1) { /* Force the creation from gNB Conf file */
LOG_W(NR_RRC, "Adding %d DRBs, from gNB config file (not decided by 5GC\n", rrc->configuration.drbs);
drb_id = next_available_drb(ue, &ue->pduSession[i], GBR_FLOW);
} else {
drb_id = next_available_drb(ue, &ue->pduSession[i], NONGBR_FLOW);
}
break;
default:
LOG_E(NR_RRC, "not supported 5qi %lu\n", ue->pduSession[i].param.qos[qos_flow_index].fiveQI);
ue->pduSession[i].status = PDU_SESSION_STATUS_FAILED;
continue;
}
drb_priority[drb_id - 1] = ue->pduSession[i].param.qos[qos_flow_index].allocation_retention_priority.priority_level;
if (drb_priority[drb_id - 1] < 0 || drb_priority[drb_id - 1] > NGAP_PRIORITY_LEVEL_NO_PRIORITY) {
LOG_E(NR_RRC, "invalid allocation_retention_priority.priority_level %ld set to _NO_PRIORITY\n", drb_priority[drb_id - 1]);
drb_priority[drb_id - 1] = NGAP_PRIORITY_LEVEL_NO_PRIORITY;
}
if (drb_is_active(ue, drb_id)) { /* Non-GBR flow using the same DRB or a GBR flow with no available DRBs*/
nb_drb_to_setup--;
} else {
generateDRB(ue,
drb_id,
&ue->pduSession[i],
rrc->configuration.enable_sdap,
rrc->security.do_drb_integrity,
rrc->security.do_drb_ciphering);
NR_DRB_ToAddMod_t *DRB_config = generateDRB_ASN1(&ue->established_drbs[drb_id - 1]);
if (drb_id_to_setup_start == 0)
drb_id_to_setup_start = DRB_config->drb_Identity;
asn1cSeqAdd(&DRB_configList->list, DRB_config);
}
LOG_D(RRC, "DRB Priority %ld\n", drb_priority[drb_id]); // To supress warning for now
}
}
}
if (DRB_configList->list.count == 0) {
free(DRB_configList);
return NULL;
}
return DRB_configList;
}
static int neigh_compare(const nr_rrc_neighcells_container_t *a, const nr_rrc_neighcells_container_t *b)
{
......@@ -141,6 +210,17 @@ static int neigh_compare(const nr_rrc_neighcells_container_t *a, const nr_rrc_ne
/* Tree management functions */
RB_GENERATE(rrc_neigh_cell_tree, nr_rrc_neighcells_container_t, entries, neigh_compare);
/*
static instance_t get_instance_by_F1_instance(instance_t f1_instance)
{
for (int i = 0; i < RC.nb_nr_inst; i++) {
if (RC.nrrrc[i] && RC.nrrrc[i]->f1_instance == f1_instance) {
return i;
}
}
return -1;
}
*/
static void clear_nas_pdu(ngap_pdu_t *pdu)
{
......@@ -731,6 +811,61 @@ void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const c
nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size);
}
int16_t rrc_gNB_generate_HO_RRCReconfiguration(const protocol_ctxt_t *ctxt_pP,
const uint8_t modid_s,
const uint8_t modid_t,
rrc_gNB_ue_context_t *ue_context_pP,
rrc_gNB_ue_context_t *ue_context_old,
uint8_t *buffer,
const int16_t buffer_size,
NR_CellGroupConfig_t *masterCellGroup){ //NR_CellGroupConfig_t *cellGroupConfig) {
uint8_t rrc_buffer[RRC_BUF_SIZE];
uint8_t xid = rrc_gNB_get_next_transaction_identifier(modid_s);
// SRBs
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
for (int i = 0; i < maxSRBs; i++) {
ue_p->Srb[i].Active = ue_context_old->ue_context.Srb[i].Active;
}
NR_SRB_ToAddModList_t *SRBs = createSRBlist(&ue_context_old->ue_context, false);
// DRBs
for (int i = 0; i < NGAP_MAX_PDU_SESSION; i++) {
ue_p->pduSession[i] = ue_context_old->ue_context.pduSession[i];
ue_p->pduSession[i].status = 0;
}
ue_p->nb_of_pdusessions = ue_context_old->ue_context.nb_of_pdusessions;
NR_DRB_ToAddModList_t *DRBs = fill_DRB_configList(ue_p);
int16_t rrc_size = do_RRCReconfiguration(ue_p,
rrc_buffer,
RRC_BUF_SIZE,
xid,
SRBs,
DRBs,
NULL,
NULL,
NULL, // MeasObj_list,
NULL,
masterCellGroup); //cellGroupConfig);
AssertFatal(rrc_size > 0, "Handover command generation failed in %s, line %i\n", __FILE__, __LINE__);
int16_t do_NR_HandoverCommand(uint8_t *ho_buf, int16_t ho_size, uint8_t *rrc_buffer, int16_t rrc_size);
int16_t ho_size = do_NR_HandoverCommand(buffer,
buffer_size,
rrc_buffer,
rrc_size);
AssertFatal(ho_size > 0, "Handover command generation failed in %s, line %i\n", __FILE__, __LINE__);
freeSRBlist(SRBs);
freeDRBlist(DRBs);
return ho_size;
}
//-----------------------------------------------------------------------------
void
rrc_gNB_modify_dedicatedRRCReconfiguration(
......@@ -1615,21 +1750,21 @@ static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_
}
MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, XNAP_HANDOVER_REQ);
xnap_handover_req_t *req = &XNAP_HANDOVER_REQ(msg);
/*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;
req->ue_id = ue_ctxt->rrc_ue_id;
req->target_cgi.cgi = 12345678; //ue_ctxt->measResults->measResultNeighCells->choice.measResultListNR->list.array[0]->physCellId;
req->guami.plmn_id.mcc = ue_ctxt->ue_guami.mcc;
req->guami.plmn_id.mnc = ue_ctxt->ue_guami.mnc;
req->guami.plmn_id.mnc_digit_length = ue_ctxt->ue_guami.mnc_len;
req->guami.amf_region_id = ue_ctxt->ue_guami.amf_region_id;
req->guami.amf_set_id = ue_ctxt->ue_guami.amf_set_id;
req->guami.amf_pointer = ue_ctxt->ue_guami.amf_pointer;
req->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;
......@@ -2454,21 +2589,20 @@ static void write_rrc_stats(const gNB_RRC_INST *rrc)
void rrc_gNB_process_handoverprepinfo(sctp_assoc_t assoc_id, xnap_handover_req_t *m)
{
int rnti = taus() & 0xffff;
//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);
xnap_gNB_instance_t *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_get_ue_context(RC.nrrrc[0], m->ue_id);
//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]);
......@@ -2477,19 +2611,228 @@ void rrc_gNB_process_handoverprepinfo(sctp_assoc_t assoc_id, xnap_handover_req_t
return;
}
ue_context_p->ue_context.rnti = rnti;
//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 ;
ack->s_ng_node_ue_xnap_id = m->s_ng_node_ue_xnap_id;
ack->t_ng_node_ue_xnap_id = m->t_ng_node_ue_xnap_id;
xnap_set_ids(&instance_p->id_manager, ack->t_ng_node_ue_xnap_id , ue_context_p->ue_context.rrc_ue_id ,ack->s_ng_node_ue_xnap_id, ack->t_ng_node_ue_xnap_id);
xnap_id_set_state(&instance_p->id_manager, ack->t_ng_node_ue_xnap_id, XNID_STATE_TARGET);
//F1 UE context setup
//rrc_gNB_generate_SecurityModeCommand(NULL, ue_context_p, 0, NULL);
itti_send_msg_to_task(TASK_XNAP, instance_p->instance, message_p);
}
/*struct rrc_gNB_ue_context_s *find_ho_ue_context_in_source(uint8_t modid_t, uint8_t *modid_s, uint8_t *ho_idx, sctp_assoc_t assoc_id)
{
for (int ho_id = 0; ho_id < NUMBER_OF_DU_PER_CU_MAX; ho_id++) {
if (ho_rnti_map[ho_id][3] == modid_t) {
if (modid_s != NULL) {
*modid_s = ho_rnti_map[ho_id][1];
}
if (ho_idx != NULL) {
*ho_idx = ho_id;
}
return rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[ho_rnti_map[ho_id][1]],assoc_id,ho_rnti_map[ho_id][0]);
}
}
return NULL;
}*/
void rrc_gNB_process_handover_req_ack(sctp_assoc_t assoc_id, xnap_handover_req_ack_t *m)
{
/* f1ap_ue_context_setup_t *resp = &F1AP_UE_CONTEXT_SETUP_RESP(msg_p);
gNB_RRC_INST *rrc = RC.nrrrc[instance];
uint8_t modid_s;
uint8_t ho_idx;
rrc_gNB_ue_context_t *ho_ue_context_in_source = NULL;
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, resp->gNB_CU_ue_id);
rrc_gNB_ue_context_t *ue_context_old = NULL;
if (ue_context_p == NULL && resp->crnti != NULL) {
uint64_t random_value;
fill_random(&random_value, sizeof(random_value));
random_value = random_value & 0x7fffffffff;
ue_context_p = rrc_gNB_create_ue_context(assoc_id ,*resp->crnti, rrc, random_value, resp->gNB_DU_ue_id);
ho_ue_context_in_source = find_ho_ue_context_in_source(instance, &modid_s, &ho_idx, assoc_id);
ho_rnti_map[ho_idx][2] = resp->gNB_DU_ue_id;
ue_context_old = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[modid_s], assoc_id,ho_rnti_map[ho_idx][0]);
ue_context_p->ue_context.handover_info = ue_context_old->ue_context.handover_info;
}
*/
NR_RRCReconfiguration_t *reconf = NULL;
m->rrc_buffer_size = 8192;
/*{
int i;
//LOG_I(XNAP, "%d: \n", m->rrc_buffer_size);
LOG_I(XNAP, "%d: \n", m->rrc_buffer_size);
for (i=0; i<m->rrc_buffer_size; i++) printf("%2.2x", (unsigned char)m->rrc_buffer[i]);
//for (i=0; i<m->rrc_buffer_size; i++) printf("%2.2x", (unsigned char)m->rrc_buffer[i]);
printf("\n");
}*/
asn_dec_rval_t dec_rval = uper_decode_complete( NULL,
&asn_DEF_NR_DL_DCCH_Message,
(void *)&reconf,
(uint8_t *)m->rrc_buffer,
(int) m->rrc_buffer_size);//m->rrc_buffer_size);
xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message , (void *)&reconf);
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
AssertFatal(1==0,"NR_UL_DCCH_MESSAGE decode error\n");
// free the memory
SEQUENCE_free( &asn_DEF_NR_RRCReconfiguration, reconf, 1 );
return;
}
//xer_fprint(stdout,&asn_DEF_NR_RRCReconfiguration , reconf);
AssertFatal(reconf->criticalExtensions.present == NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration,
"reconf not present\n");
/* OCTET_STRING_t *secondaryCellGroup = calloc(1,sizeof(OCTET_STRING_t));
OCTET_STRING_t *scg = calloc(1,sizeof(OCTET_STRING_t));
scg = reconf->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup;
if(scg){ //reconf->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup) {
// secondaryCellGroup = reconf->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup;
// #ifdef DEBUG_SCG_CONFIG
{
int size_s = reconf->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->size;
int i;
LOG_I(RRC, "Dumping secondaryCellGroup: %d", size_s);
for (i=0; i<size_s; i++) printf("%2.2x", (unsigned char)reconf->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->buf[i]);
printf("\n");
}
// #endif
} else {
LOG_I(RRC, "secondaryCellGroup is not present in the Response message \n");
return;
}
*/
instance_t instance = 0; //for time being
xnap_gNB_instance_t *instance_p = xnap_gNB_get_instance(instance);
gNB_RRC_INST *rrc = RC.nrrrc[instance];
int rrc_ue_id = xnap_id_get_ueid(&instance_p->id_manager, m->s_ng_node_ue_xnap_id);
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, rrc_ue_id);
if (ue_context_p == NULL)
{
LOG_I(RRC,"UE Context is NULL");
}
protocol_ctxt_t ctxt = {.rntiMaybeUEid = rrc_ue_id, .module_id = instance, .instance = instance, .enb_flag = 1, .eNB_index = instance};
// rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p);
// ue_context_p = rrc_gNB_allocate_new_ue_context(RC.nrrrc[0]);
//gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
// NR_CellGroupConfig_t *cellGroupConfig = NULL;
/*NR_HandoverCommand_t *ho_command = NULL;
//==
asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
&asn_DEF_NR_CellGroupConfig,
(void **)&cellGroupConfig,
(uint8_t *)m->rrc_buffer,
(int) m->rrc_buffer_size);
asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
&asn_DEF_NR_HandoverCommand,
(void *)&ho_command,
(uint8_t *)m->rrc_buffer,
(int) m->rrc_buffer_size);
if (LOG_DEBUGFLAG(DEBUG_ASN1))
xer_fprint(stdout,&asn_DEF_NR_HandoverCommand,(void *)&ho_command);
// AssertFatal(dec_rval.code == RC_OK && dec_rval.consumed > 0, "Cell group config decode error\n");
// UE->masterCellGroup = cellGroupConfig;
// NR_CellGroupConfig_t *masterCellGroup = UE->masterCellGroup;
if (dec_rval.code != RC_OK ||
ho_command->criticalExtensions.present != NR_HandoverCommand__criticalExtensions_PR_c1 ||
ho_command->criticalExtensions.choice.c1->present != NR_HandoverCommand__criticalExtensions__c1_PR_handoverCommand) {
LOG_E(NR_RRC, "could not decode Handover Command\n");
abort();
}
unsigned char *buf = ho_command->criticalExtensions.choice.c1->choice.handoverCommand->handoverCommandMessage.buf;
int size = ho_command->criticalExtensions.choice.c1->choice.handoverCommand->handoverCommandMessage.size;
AssertFatal(size > 0, "size is NULL\n");
// memcpy(ue_context_p->ue_context.handover_info->buf, buf, size);
// ue_context_p->ue_context.handover_info->size = size;
/*
if (UE->masterCellGroup) {
ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->masterCellGroup);
LOG_I(RRC, "UE %04x replacing existing CellGroupConfig with new one received from DU\n", UE->rnti);
}
UE->masterCellGroup = cellGroupConfig;
if (LOG_DEBUGFLAG(DEBUG_ASN1))
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, UE->masterCellGroup);
at this point, we don't have to do anything: the UE context setup request
includes the Security Command, whose response will trigger the following
messages (UE capability, to be specific) */
/*
if (ho_ue_context_in_source != NULL) {
MessageDef *message_p;
message_p = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REQ);
f1ap_ue_context_setup_t *req = &F1AP_UE_CONTEXT_MODIFICATION_REQ(message_p);
req->gNB_CU_ue_id = UE->rrc_ue_id;
req->gNB_DU_ue_id = ho_ue_context_in_source->ue_context.rnti;
req->mcc = RC.nrrrc[modid_s]->configuration.mcc[0];
req->mnc = RC.nrrrc[modid_s]->configuration.mnc[0];
req->mnc_digit_length = RC.nrrrc[modid_s]->configuration.mnc_digit_length[0];
req->nr_cellid = RC.nrrrc[modid_s]->nr_cellid;
protocol_ctxt_t ctxt = {.rntiMaybeUEid = ho_rnti_map[ho_idx][0], .module_id = instance, .instance = RC.nrrrc[instance]->f1_instance, .enb_flag = 1, .eNB_index = instance};
req->rrc_container = calloc(1, RRC_BUF_SIZE*sizeof(uint8_t));
req->rrc_container_length = rrc_gNB_generate_HO_RRCReconfiguration(&ctxt,
modid_s,
instance,
ue_context_p,
ue_context_old,
req->rrc_container,
RRC_BUF_SIZE,
masterCellGroup );//cellGroupConfig);
// To DU send the Downlink Data Delivery Status
req->ReconfigComplOutcome = RRCreconf_success;
// To stop the data transmission
req->transmission_action_indicator = calloc(1, sizeof(uint8_t));
*req->transmission_action_indicator = 0;
itti_send_msg_to_task(TASK_CU_F1, RC.nrrrc[modid_s]->f1_instance, message_p);
}*/
MessageDef *message_p;
message_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_MODIFICATION_REQUIRED);
message_p->ittiMsgHeader.originInstance = assoc_id;
f1ap_ue_context_modif_required_t *req = &F1AP_UE_CONTEXT_MODIFICATION_REQUIRED(message_p);
req->transmission_action_indicator = calloc(1, sizeof(uint8_t));
*req->transmission_action_indicator = 0;
itti_send_msg_to_task(TASK_DU_F1, instance_p->instance, message_p);
itti_send_msg_to_task(TASK_XNAP, instance_p->instance, message_p);
}
void *rrc_gnb_task(void *args_p) {
MessageDef *msg_p;
instance_t instance;
......@@ -2621,6 +2964,10 @@ void *rrc_gnb_task(void *args_p) {
rrc_gNB_process_handoverprepinfo(ITTI_MSG_ORIGIN_INSTANCE(msg_p),&XNAP_HANDOVER_REQ(msg_p));
break;
case XNAP_HANDOVER_REQ_ACK:
rrc_gNB_process_handover_req_ack(ITTI_MSG_ORIGIN_INSTANCE(msg_p),&XNAP_HANDOVER_REQ_ACK(msg_p));
break;
/* Messages from X2AP */
case X2AP_ENDC_SGNB_ADDITION_REQ:
......
......@@ -184,6 +184,25 @@ uint8_t get_next_available_drb_id(gNB_RRC_UE_t *ue)
return DRB_INACTIVE;
}
uint8_t next_available_drb(gNB_RRC_UE_t *ue, rrc_pdu_session_param_t *pdusession, bool is_gbr)
{
uint8_t drb_id;
if (0 /*!is_gbr*/) { /* Find if Non-GBR DRB exists in the same PDU Session */
for (drb_id = 0; drb_id < MAX_DRBS_PER_UE; drb_id++)
if (pdusession->param.used_drbs[drb_id] == DRB_ACTIVE_NONGBR)
return drb_id + 1;
}
/* GBR Flow or a Non-GBR DRB does not exist in the same PDU Session, find an available DRB */
for (drb_id = 0; drb_id < MAX_DRBS_PER_UE; drb_id++)
if (ue->DRB_active[drb_id] == DRB_INACTIVE)
return drb_id + 1;
/* From this point, we need to handle the case that all DRBs are already used by the UE. */
LOG_E(RRC, "Error - All the DRBs are used - Handle this\n");
return DRB_INACTIVE;
}
bool drb_is_active(gNB_RRC_UE_t *ue, uint8_t drb_id)
{
drb_t *drb = get_drb(ue, drb_id);
......
......@@ -60,7 +60,7 @@ drb_t *generateDRB(gNB_RRC_UE_t *ue,
/// @brief return the next available (inactive) DRB ID of UE ue
uint8_t get_next_available_drb_id(gNB_RRC_UE_t *ue);
uint8_t next_available_drb(gNB_RRC_UE_t *ue, rrc_pdu_session_param_t *pdusession, bool is_gbr);
/// @brief check if DRB with ID drb_id of UE ue is active
bool drb_is_active(gNB_RRC_UE_t *ue, uint8_t drb_id);
......
......@@ -48,6 +48,13 @@
#include "XNAP_NonDynamic5QIDescriptor.h"
#include "XNAP_Dynamic5QIDescriptor.h"
#include "xnap_ids.h"
#include "NR_HandoverCommand.h"
#include "NR_CellGroupConfig.h"
#include "NR_RRCReconfiguration-IEs.h"
#include "NR_SpCellConfig.h"
#include "NR_ReconfigurationWithSync.h"
#include "NR_DL-DCCH-Message.h"
#include "SIMULATION/TOOLS/sim.h"
int xnap_gNB_generate_xn_setup_request(sctp_assoc_t assoc_id, xnap_setup_req_t *req)
{
......@@ -806,7 +813,7 @@ int xnap_gNB_generate_xn_handover_request (sctp_assoc_t assoc_id, xnap_handover_
ie->id = XNAP_ProtocolIE_ID_id_sourceNG_RANnodeUEXnAPID;
ie->criticality = XNAP_Criticality_reject;
ie->value.present = XNAP_HandoverRequest_IEs__value_PR_NG_RANnodeUEXnAPID;
// ie->value.choice.UE_XnAP_ID = xnap_id_get_id_source(&instance_p->id_manager, ue_id);//// value to be added.
ie->value.choice.NG_RANnodeUEXnAPID = xnap_handover_req->s_ng_node_ue_xnap_id;//// value to be added.
asn1cSeqAdd(&xnhandoverreq->protocolIEs.list, ie);
/* mandatory */
......@@ -962,6 +969,116 @@ if (xnap_gNB_encode_pdu(&pdu, &buffer, &len) < 0) {
return ret;
}
int xnap_gNB_ho_cell_group_config(xnap_handover_req_ack_t *xnhandover_ack,uint8_t *buffer,size_t buffer_size)
{
//NR_ServingCellConfigCommon_t *scc;
NR_RRCReconfiguration_IEs_t *ie;
NR_DL_DCCH_Message_t dl_dcch_msg={0};
asn_enc_rval_t enc_rval;
//NR_FreqBandIndicatorNR_t *dl_frequencyBandList,*ul_frequencyBandList;
//struct NR_SCS_SpecificCarrier *dl_scs_SpecificCarrierList,*ul_scs_SpecificCarrierList;
dl_dcch_msg.message.present = NR_DL_DCCH_MessageType_PR_c1;
asn1cCalloc(dl_dcch_msg.message.choice.c1, c1);// = CALLOC(1, sizeof(struct NR_DL_DCCH_MessageType__c1));
c1->present = NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration;
asn1cCalloc(c1->choice.rrcReconfiguration, rrcReconf); // = calloc(1, sizeof(NR_RRCReconfiguration_t));
//rrcReconf->rrc_TransactionIdentifier = Transaction_id;
rrcReconf->criticalExtensions.present = NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration;
ie = (NR_RRCReconfiguration_IEs_t *)calloc(1, sizeof(NR_RRCReconfiguration_IEs_t));
ie->nonCriticalExtension = calloc(1, sizeof(NR_RRCReconfiguration_v1530_IEs_t));
ie->nonCriticalExtension->masterCellGroup = calloc(1,sizeof(OCTET_STRING_t));
uint8_t *buf = NULL;
NR_CellGroupConfig_t *cell_group_config = CALLOC(1,sizeof(NR_CellGroupConfig_t));
cell_group_config->spCellConfig = CALLOC(1,sizeof(NR_SpCellConfig_t));
cell_group_config->spCellConfig->reconfigurationWithSync = CALLOC(1,sizeof(NR_ReconfigurationWithSync_t));
NR_ReconfigurationWithSync_t *reconfigurationWithSync = cell_group_config->spCellConfig->reconfigurationWithSync;
//NR_ReconfigurationWithSync_t *reconfigurationWithSync = calloc(1, sizeof(*NR_ReconfigurationWithSync_t));
cell_group_config->spCellConfig->reconfigurationWithSync->spCellConfigCommon = CALLOC(1,sizeof(NR_ServingCellConfigCommon_t));
NR_ServingCellConfigCommon_t *scc = cell_group_config->spCellConfig->reconfigurationWithSync->spCellConfigCommon;
// NR_CellGroupConfig_t *secondaryCellGroup = calloc(1, sizeof(*secondaryCellGroup));
//reconfigurationWithSync->spCellConfigCommon = (NR_ServingCellConfigCommon_t *)scc;
reconfigurationWithSync->newUE_Identity = taus() & 0xffff;
reconfigurationWithSync->t304 = NR_ReconfigurationWithSync__t304_ms2000;
reconfigurationWithSync->rach_ConfigDedicated = NULL;
scc->physCellId = CALLOC(1,sizeof(NR_PhysCellId_t));
*scc->physCellId = 0;
/*==scc->dmrs_TypeA_Position=NR_ServingCellConfigCommon__dmrs_TypeA_Position_pos2;
scc->downlinkConfigCommon = CALLOC(1,sizeof(NR_DownlinkConfigCommon_t));
scc->downlinkConfigCommon->frequencyInfoDL = CALLOC(1,sizeof(NR_FrequencyInfoDL_t));
scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB = CALLOC(1,sizeof(NR_ARFCN_ValueNR_t));
*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB = 641280;
scc->ss_PBCH_BlockPower=20;
==*/
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cell_group_config);
ssize_t len = uper_encode_to_new_buffer(&asn_DEF_NR_CellGroupConfig, NULL, cell_group_config, (void **)&buf);
AssertFatal(len > 0, "ASN1 message encoding failed (%lu)!\n", len);
//if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
//xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cell_group_config);
//}
ie->nonCriticalExtension->masterCellGroup = calloc(1,sizeof(OCTET_STRING_t));
ie->nonCriticalExtension->masterCellGroup->buf = buf;
ie->nonCriticalExtension->masterCellGroup->size = len;
dl_dcch_msg.message.choice.c1->choice.rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration = ie;
xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message, (void *)&dl_dcch_msg);
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message, (void *)&dl_dcch_msg);
}
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_DL_DCCH_Message,
NULL,
(void *)&dl_dcch_msg,
buffer,
buffer_size);
AssertFatal(enc_rval.encoded >0, "ASN1 message encoding failed (%s, %lu)!\n",
enc_rval.failed_type->name, enc_rval.encoded);
/* LOG_I(XNAP,"Before Free\n");
xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message, (void *)&dl_dcch_msg);
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NR_DL_DCCH_Message, &dl_dcch_msg);
LOG_I(XNAP,"After Free\n");
xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message, (void *)&dl_dcch_msg);
*/
LOG_I(NR_RRC,
"RRCReconfiguration for UE : Encoded %zd bits (%zd bytes)\n",
enc_rval.encoded,
(enc_rval.encoded + 7) / 8);
return((enc_rval.encoded+7)/8);
}
/*int16_t handover_command(uint8_t *ho_buf, int16_t ho_size, uint8_t *rrc_buffer, int16_t rrc_size) {
NR_HandoverCommand_t *ho_command = calloc(1,sizeof(NR_HandoverCommand_t));
ho_command->criticalExtensions.present = NR_HandoverCommand__criticalExtensions_PR_c1;
ho_command->criticalExtensions.choice.c1 = calloc(1,sizeof(struct NR_HandoverCommand__criticalExtensions__c1));
ho_command->criticalExtensions.choice.c1->present = NR_HandoverCommand__criticalExtensions__c1_PR_handoverCommand;
ho_command->criticalExtensions.choice.c1->choice.handoverCommand = calloc(1,sizeof(struct NR_HandoverCommand_IEs));
AssertFatal(OCTET_STRING_fromBuf(&ho_command->criticalExtensions.choice.c1->choice.handoverCommand->handoverCommandMessage, (char *)rrc_buffer, rrc_size) != -1,
"fatal: OCTET_STRING_fromBuf failed\n");
xer_fprint(stdout,&asn_DEF_NR_HandoverCommand, ho_command);
asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_HandoverCommand,
NULL,
ho_command,
ho_buf,
ho_size);
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);
}
*/
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)
{
XNAP_XnAP_PDU_t pdu;
......@@ -971,18 +1088,14 @@ int xnap_gNB_generate_xn_handover_request_ack(sctp_assoc_t assoc_id, xnap_handov
int ue_id;
int id_source;
//int id_target;
uint8_t rrc_buffer[RRC_BUF_SIZE];
uint8_t *rrc_buff = calloc(1, RRC_BUF_SIZE*sizeof(uint8_t));
uint8_t *buffer;
uint32_t len;
int ret = 0;
//xnap_gNB_instance_t *instance_p;
//xnap_gNB_instance_t *xnap_gNB_get_instance(instance_t instanceP);
//xnap_gNB_instance_t *instance_p = xnap_gNB_get_instance(instance);
xnap_handover_req_ack->xn_id_target = 1;
ue_id = xnap_handover_req_ack->xn_id_target;
printf("%d \n",ue_id);
id_source = 0; //xnap_id_get_id_source(&instance_p->id_manager, ue_id);
//id_target = 1; //ue_id;
memset(&pdu, 0, sizeof(pdu));
pdu.present = XNAP_XnAP_PDU_PR_successfulOutcome;
......@@ -997,28 +1110,59 @@ int xnap_gNB_generate_xn_handover_request_ack(sctp_assoc_t assoc_id, xnap_handov
ie->criticality = XNAP_Criticality_ignore;
ie->value.present = XNAP_HandoverRequest_IEs__value_PR_NG_RANnodeUEXnAPID;
// ie->value.choice.UE_XnAP_ID = xnap_id_get_id_source(&instance_p->id_manager, ue_id);//// value to be added.
ie->value.choice.NG_RANnodeUEXnAPID = id_source;
ie->value.choice.NG_RANnodeUEXnAPID = xnap_handover_req_ack->s_ng_node_ue_xnap_id;//id_source;
asn1cSeqAdd(&xnhandoverreqAck->protocolIEs.list, ie);
/*
ie = (XNAP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(XNAP_HandoverRequestAcknowledge_IEs_t));
ie->id = XNAP_ProtocolIE_ID_id_targetNG_RANnodeUEXnAPID;
ie->criticality = XNAP_Criticality_ignore;
//ie->value.present = XNAP_HandoverRequest_IEs__value_PR_NG_RANnodeUEXnAPID_1;
ie->value.choice.NG_RANnodeUEXnAPID_1 = id_target;
ie->value.present = XNAP_HandoverRequestAcknowledge_IEs__value_PR_NG_RANnodeUEXnAPID_1;
ie->value.choice.NG_RANnodeUEXnAPID_1 = xnap_handover_req_ack->t_ng_node_ue_xnap_id;//id_target;
asn1cSeqAdd(&xnhandoverreqAck->protocolIEs.list, ie);
// ie = (XNAP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(XNAP_HandoverRequestAcknowledge_IEs_t));
// ie->id = XNAP_ProtocolIE_ID_id_PDUSessionAdmittedAddedAddReqAck;
// ie->criticality = XNAP_Criticality_ignore;
/* ie = (XNAP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(XNAP_HandoverRequestAcknowledge_IEs_t));
ie->id = XNAP_ProtocolIE_ID_id_PDUSessionAdmittedAddedAddReqAck;
ie->criticality = XNAP_Criticality_ignore;
*/
//NR_HandoverCommand_t *ho_command = calloc(1,sizeof(NR_HandoverCommand_t));
uint8_t rrc_reconf_containing_cell_group = xnap_gNB_ho_cell_group_config(xnap_handover_req_ack,rrc_buffer,RRC_BUF_SIZE);
ie = (XNAP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(XNAP_HandoverRequestAcknowledge_IEs_t));
ie->id = XNAP_ProtocolIE_ID_id_Target2SourceNG_RANnodeTranspContainer;
ie->criticality= XNAP_Criticality_ignore;
ie->value.present = XNAP_HandoverRequestAcknowledge_IEs__value_PR_OCTET_STRING;
//ie->value.choice.OCTET_STRING.buf = (uint8_t *)calloc(xnap_handover_req_ack->rrc_buffer_size, sizeof(uint8_t));
//ie->value.choice.OCTET_STRING.buf = (uint8_t *)calloc(1,RRC_BUF_SIZE*sizeof(uint8_t));
memcpy(ie->value.choice.OCTET_STRING.buf, rrc_buffer,rrc_reconf_containing_cell_group);
// ie->value.choice.OCTET_STRING.size = xnap_handover_req_ack->rrc_buffer_size;
// OCTET_STRING_fromBuf(&ie->value.choice.OCTET_STRING, (char*)rrc_buffer, RRC_BUF_SIZE);
// OCTET_STRING_fromBuf(&ie->value.choice.OCTET_STRING, (char*) xnap_handover_req_ack->rrc_buffer, xnap_handover_req_ack->rrc_buffer_size);
// uint8_t rrc_reconf_containing_cell_group = xnap_gNB_ho_cell_group_config(xnap_handover_req_ack,rrc_buffer,RRC_BUF_SIZE);
//rrc_reconfig_msg= from asn?
//fill rrc_reconfig_buffer = buf from msg(rrc_reconfig_msg);---------------->generate_ho_rrc_reconfig+do_rrc_reconfig
// NR_HandoverCommand_t *ho_command = calloc(1,sizeof(NR_HandoverCommand_t));
// ho_command->criticalExtensions.present = NR_HandoverCommand__criticalExtensions_PR_c1;
// ho_command->criticalExtensions.choice.c1 = calloc(1,sizeof(struct NR_HandoverCommand__criticalExtensions__c1));
// ho_command->criticalExtensions.choice.c1->present = NR_HandoverCommand__criticalExtensions__c1_PR_handoverCommand;
// ho_command->criticalExtensions.choice.c1->choice.handoverCommand = calloc(1,sizeof(struct NR_HandoverCommand_IEs));
//OCTET_STRING_fromBuf(&ho_command->criticalExtensions.choice.c1->choice.handoverCommand->handoverCommandMessage, (char *)rrc_reconfig_buffer, rrc_reconfig_size);
// OCTET_STRING_fromBuf(&ho_command->criticalExtensions.choice.c1->choice.handoverCommand->handoverCommandMessage, (char *)rrc_buffer, rrc_reconf_containing_cell_group);
//fill rrc_ho_command_buff = buf from msg (ho_command); ---->do_ho_command;
// int16_t ho_size = handover_command(rrc_buff,RRC_BUF_SIZE,rrc_buffer,rrc_reconf_containing_cell_group);
//OCTET_STRING_fromBuf(&ie->value.choice.OCTET_STRING, (char*)rrc_ho_command_buffer, rrc_size);
//OCTET_STRING_fromBuf(&ie->value.choice.OCTET_STRING, (char*)rrc_buff ,ho_size);
if (xnap_gNB_encode_pdu(&pdu, &buffer, &len) < 0) {
asn1cSeqAdd(&xnhandoverreqAck->protocolIEs.list, ie);
if (xnap_gNB_encode_pdu(&pdu, &buffer, &len) < 0) {
LOG_E(XNAP,"Failed to encode XN handover request ack\n");
return -1;
}
xnap_gNB_itti_send_sctp_data_req(assoc_id, buffer, len, 0);
return ret;
xnap_gNB_itti_send_sctp_data_req(assoc_id, buffer, len, 0);
return ret;
}
......@@ -344,7 +344,7 @@ int xnap_gNB_handle_handover_request(instance_t instance, sctp_assoc_t assoc_id,
xnap_gNB_instance_t *instance_p;
xnap_id_manager *id_manager;
//xnap_gNB_data_t *xnap_gNB_data;
int ue_id;
int xn_id;
instance_p = xnap_gNB_get_instance(instance);
......@@ -372,25 +372,26 @@ int xnap_gNB_handle_handover_request(instance_t instance, sctp_assoc_t assoc_id,
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);
req->s_ng_node_ue_xnap_id = ie->value.choice.NG_RANnodeUEXnAPID;
LOG_I(XNAP, "ue xnap id %d \n", req->s_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);
xn_id = xnap_allocate_new_id(id_manager);
if (ue_id == -1) {
if (xn_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_set_ids(&instance_p->id_manager, xn_id , 0, req->s_ng_node_ue_xnap_id, xn_id);
//xnap_id_set_state(&instance_p->id_manager, xn_id, XNID_STATE_TARGET);
XNAP_HANDOVER_REQ(message_p).xn_id = ue_id;
req->t_ng_node_ue_xnap_id = xn_id;
/*// Target Cell Global ID
XNAP_FIND_PROTOCOLIE_BY_ID(XNAP_HandoverRequest_IEs_t, ie, xnHandoverRequest, XNAP_ProtocolIE_ID_id_TargetCellCGI,true);
......@@ -428,27 +429,26 @@ int xnap_gNB_handle_handover_response(instance_t instance, sctp_assoc_t assoc_id
XNAP_HandoverRequestAcknowledge_t *xnHandoverRequestAck;
XNAP_HandoverRequestAcknowledge_IEs_t *ie;
xnap_gNB_instance_t *instance_p;
instance_p = xnap_gNB_get_instance(instance);
instance_p = xnap_gNB_get_instance(0);
//xnap_id_manager *id_manager;
//xnap_gNB_data_t *xnap_gNB_data;
/*xnap_id_manager *id_manager;
xnap_gNB_data_t *xnap_gNB_data;
int ue_id;
int id_source;
int id_target;
int rnti;
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);
xnap_handover_req_ack_t *ack = &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);
......@@ -458,16 +458,35 @@ if (stream == 0) {
return -1;
}
ack->s_ng_node_ue_xnap_id = ie->value.choice.NG_RANnodeUEXnAPID;
id_source = ie->value.choice.NG_RANnodeUEXnAPID;
XNAP_FIND_PROTOCOLIE_BY_ID(XNAP_HandoverRequestAcknowledge_IEs_t, ie, xnHandoverRequestAck, XNAP_ProtocolIE_ID_id_targetCellGlobalID, true);
/* 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;
}
*/
XNAP_FIND_PROTOCOLIE_BY_ID(XNAP_HandoverRequestAcknowledge_IEs_t, ie, xnHandoverRequestAck, XNAP_ProtocolIE_ID_id_Target2SourceNG_RANnodeTranspContainer, true);
if (ie == NULL) {
LOG_E(XNAP, "iXNAP_ProtocolIE_ID_id_Target2SourceNG_RANnodeTranspContainer is NULL pointer \n");
itti_free(ITTI_MSG_ORIGIN_ID(message_p),message_p);
return -1;
}
OCTET_STRING_t *c = &ie->value.choice.OCTET_STRING;
if (c->size > 1024){
LOG_I(XNAP,"c is not NULL");
}
//{ printf("%s:%d: fatal: buffer too big\n", __FILE__, __LINE__); abort(); }
memcpy(ack->rrc_buffer, c->buf, c->size);
ack->rrc_buffer_size = c->size;
//memcpy(XNAP_HANDOVER_REQ_ACK(message_p).rrc_buffer, ie->value.choice.OCTET_STRING.buf, ie->value.choice.OCTET_STRING.size);
//XNAP_HANDOVER_REQ_ACK(message_p).rrc_buffer_size = ie->value.choice.OCTET_STRING.size;
/*
id_target = ie->value.choice.NG_RANnodeUEXnAPID_1;
ue_id = id_source;
......@@ -482,7 +501,7 @@ if (stream == 0) {
//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;
......
......@@ -207,37 +207,34 @@ static void xnap_gNB_handle_sctp_association_ind(instance_t instance, sctp_new_a
}
static
void xnap_gNB_handle_handover_req(instance_t instance,
void xnap_gNB_handle_handover_prep(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);
int target_nci = xnap_handover_req->target_cgi.cgi;
assoc_id = xnap_gNB_get_assoc_id(instance_p,target_nci);
/* 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);
int xn_id = xnap_allocate_new_id(id_manager);
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) {
if (xn_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);
}
xnap_handover_req->s_ng_node_ue_xnap_id = xn_id;
xnap_set_ids(id_manager, xnap_handover_req->s_ng_node_ue_xnap_id, xnap_handover_req->ue_id, xnap_handover_req->s_ng_node_ue_xnap_id, 0);
/* 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?
......@@ -267,9 +264,7 @@ void *xnap_task(void *arg)
break;
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;
createXninst(ITTI_MSG_DESTINATION_INSTANCE(received_msg), xnsetupmsg, xn_nc);
xnap_gNB_init_sctp(ITTI_MSG_DESTINATION_INSTANCE(received_msg), xn_nc);
} break;
......@@ -282,7 +277,7 @@ void *xnap_task(void *arg)
break;
case XNAP_HANDOVER_REQ: // from rrc
xnap_gNB_handle_handover_req(ITTI_MSG_ORIGIN_INSTANCE(received_msg),
xnap_gNB_handle_handover_prep(ITTI_MSG_ORIGIN_INSTANCE(received_msg),
&XNAP_HANDOVER_REQ(received_msg));
break;
case XNAP_HANDOVER_REQ_ACK:
......
......@@ -28,16 +28,16 @@ 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;
m->ids[i].cu_ue_id = -1;
}
int xnap_allocate_new_id(xnap_id_manager *m)
{
int i;
printf("rnti: %d \n",m->ids[0].rnti);
printf("cu_ue_id: %d \n",m->ids[0].cu_ue_id);
for (i = 0; i < XNAP_MAX_IDS; i++)
if (m->ids[i].rnti == -1) {
m->ids[i].rnti = 0;
if (m->ids[i].cu_ue_id == -1) {
m->ids[i].cu_ue_id = 0;
m->ids[i].id_source = -1;
m->ids[i].id_target = -1;
return i;
......@@ -47,14 +47,14 @@ int xnap_allocate_new_id(xnap_id_manager *m)
void xnap_release_id(xnap_id_manager *m, int id)
{
m->ids[id].rnti = -1;
m->ids[id].cu_ue_id = -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 &&
if (m->ids[i].cu_ue_id != -1 &&
m->ids[i].id_source == id_source &&
m->ids[i].id_target == id_target)
return i;
......@@ -65,7 +65,7 @@ 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 &&
if (m->ids[i].cu_ue_id != -1 &&
m->ids[i].id_source == id_source)
return i;
return -1;
......@@ -75,24 +75,24 @@ 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 &&
if (m->ids[i].cu_ue_id != -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 xnap_find_id_from_cu_ue_id(xnap_id_manager *m, int cu_ue_id)
{
int i;
for (i = 0; i < XNAP_MAX_IDS; i++)
if (m->ids[i].rnti == rnti)
if (m->ids[i].cu_ue_id == cu_ue_id)
return i;
return -1;
}
void xnap_set_ids(xnap_id_manager *m, int ue_id, int rnti, int id_source, int id_target)
void xnap_set_ids(xnap_id_manager *m, int ue_id, int cu_ue_id, int id_source, int id_target)
{
m->ids[ue_id].rnti = rnti;
m->ids[ue_id].cu_ue_id = cu_ue_id;
m->ids[ue_id].id_source = id_source;
m->ids[ue_id].id_target = id_target;
}
......@@ -138,9 +138,9 @@ 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)
int xnap_id_get_ueid(xnap_id_manager *m, int xn_id)
{
return m->ids[ue_id].rnti;
return m->ids[xn_id].cu_ue_id;
}
void *xnap_id_get_target(xnap_id_manager *m, int ue_id)
......
......@@ -43,7 +43,7 @@ typedef enum {
} xnid_state_t;
typedef struct {
int rnti; /* -1 when free */
int cu_ue_id; /* -1 when free */
int id_source;
int id_target;
......@@ -81,7 +81,8 @@ 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);
int xnap_id_get_ueid(xnap_id_manager *m, int xn_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_ */
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