diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 6c176a75c24a1c1945d84791e377d12aed305b59..a1b4955b21212ae2dad2c10b37ba0d88556f25b7 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -469,6 +469,7 @@ add_library(X2AP_ENB ${X2AP_DIR}/x2ap_eNB_itti_messaging.c ${X2AP_DIR}/x2ap_eNB_management_procedures.c ${X2AP_DIR}/x2ap_eNB_generate_messages.c + ${X2AP_DIR}/x2ap_ids.c ) add_dependencies(X2AP_ENB rrc_flag x2_flag) diff --git a/openair2/COMMON/x2ap_messages_types.h b/openair2/COMMON/x2ap_messages_types.h index b5e73db3ae2aed2a98c49f5ba46a66d9e490943b..38429b712edc64caf6557a7bc98a710e308586da 100644 --- a/openair2/COMMON/x2ap_messages_types.h +++ b/openair2/COMMON/x2ap_messages_types.h @@ -42,9 +42,9 @@ /* X2AP UE CONTEXT RELEASE */ typedef struct x2ap_ue_context_release_s { - int old_eNB_ue_x2ap_id; - int new_eNB_ue_x2ap_id; - int target_mod_id; + /* used for X2AP->RRC in source and RRC->X2AP in target */ + int rnti; + int source_assoc_id; } x2ap_ue_context_release_t; @@ -138,12 +138,12 @@ typedef struct x2ap_lastvisitedcell_info_s { uint64_t time_UE_StayedInCell; }x2ap_lastvisitedcell_info_t; -//used for src typedef struct x2ap_handover_req_s { - int source_rnti; /* TODO: to be fixed/remove */ - int source_x2id; /* TODO: to be fixed/remove */ + /* used for RRC->X2AP in source eNB */ + int rnti; - int old_eNB_ue_x2ap_id; + /* used for X2AP->RRC in target eNB */ + int x2_id; LTE_PhysCellId_t target_physCellId; @@ -177,16 +177,16 @@ typedef struct x2ap_handover_req_s { uint8_t rrc_buffer[1024 /* arbitrary, big enough */]; int rrc_buffer_size; - /* TODO: this parameter has to be removed */ - int target_mod_id; - int source_assoc_id; + int target_assoc_id; } x2ap_handover_req_t; typedef struct x2ap_handover_req_ack_s { - int source_rnti; /* TODO: to be fixed/remove */ - int source_x2id; /* TODO: to be fixed/remove */ - /* TODO: this parameter has to be removed */ - int target_mod_id; + /* used for RRC->X2AP in target and X2AP->RRC in source */ + int rnti; + + /* used for RRC->X2AP in target */ + int x2_id_target; + int source_assoc_id; uint8_t nb_e_rabs_tobesetup; diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index e9edce2f21d74bd3bcd7e5b2d69a52ccfd612079..22a9332a58c5842e81ac89ce1d1e71c6a99b786d 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -451,13 +451,14 @@ typedef struct HANDOVER_INFO_s { HO_STATE_t state; //current state of handover uint32_t modid_s; //module_idP of serving cell uint32_t modid_t; //module_idP of target cell - int source_assoc_id; + int assoc_id; uint8_t ueid_s; //UE index in serving cell uint8_t ueid_t; //UE index in target cell LTE_AS_Config_t as_config; /* these two parameters are taken from 36.331 section 10.2.2: HandoverPreparationInformation-r8-IEs */ LTE_AS_Context_t as_context; /* They are mandatory for HO */ uint8_t buf[RRC_BUF_SIZE]; /* ASN.1 encoded handoverCommandMessage */ int size; /* size of above message in bytes */ + int x2_id; /* X2AP UE ID in the target eNB */ } HANDOVER_INFO; #define RRC_HEADER_SIZE_MAX 64 diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 16a26fbed84947531d3bdc4b173e64100feaa4c2..49ca46b35dee53563151453a23358f176efbc50b 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -3924,8 +3924,7 @@ rrc_eNB_process_MeasurementReport( ue_context_pP, X2AP_HANDOVER_REQ(msg).rrc_buffer, &X2AP_HANDOVER_REQ(msg).rrc_buffer_size); - X2AP_HANDOVER_REQ(msg).source_rnti = ctxt_pP->rnti; - X2AP_HANDOVER_REQ(msg).old_eNB_ue_x2ap_id = 0; + X2AP_HANDOVER_REQ(msg).rnti = ctxt_pP->rnti; X2AP_HANDOVER_REQ(msg).target_physCellId = measResults2->measResultNeighCells->choice. measResultListEUTRA.list.array[ncell_index]->physCellId; X2AP_HANDOVER_REQ(msg).ue_gummei.mcc = ue_context_pP->ue_context.ue_gummei.mcc; @@ -3982,105 +3981,6 @@ rrc_eNB_generate_HandoverPreparationInformation( *_size = ho_size; } -#if 0 -//----------------------------------------------------------------------------- -void -rrc_eNB_generate_HandoverPreparationInformation( - const protocol_ctxt_t *const ctxt_pP, - rrc_eNB_ue_context_t *const ue_context_pP, - LTE_PhysCellId_t targetPhyId -) -//----------------------------------------------------------------------------- -{ - struct rrc_eNB_ue_context_s *ue_context_target_p = NULL; - //uint8_t UE_id_target = -1; - uint8_t mod_id_target = get_adjacent_cell_mod_id(targetPhyId); - HANDOVER_INFO *handoverInfo = CALLOC(1, sizeof(*handoverInfo)); - /* - uint8_t buffer[100]; - uint8_t size; - struct LTE_PhysicalConfigDedicated **physicalConfigDedicated = &RC.rrc[enb_mod_idP]->physicalConfigDedicated[ue_mod_idP]; - RadioResourceConfigDedicated_t *radioResourceConfigDedicated = CALLOC(1,sizeof(RadioResourceConfigDedicated_t)); - */ - T(T_ENB_RRC_HANDOVER_PREPARATION_INFORMATION, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), - T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - handoverInfo->as_config.antennaInfoCommon.antennaPortsCount = 0; //Not used 0- but check value - handoverInfo->as_config.sourceDl_CarrierFreq = 36090; //Verify! - memcpy((void *)&handoverInfo->as_config.sourceMasterInformationBlock, - (void *)&RC.rrc[ctxt_pP->module_id]->carrier[0] /* CROUX TBC */.mib, sizeof(LTE_MasterInformationBlock_t)); - memcpy((void *)&handoverInfo->as_config.sourceMeasConfig, - (void *)ue_context_pP->ue_context.measConfig, sizeof(LTE_MeasConfig_t)); - // FIXME handoverInfo not used... - free( handoverInfo ); - handoverInfo = 0; - //to be configured - memset((void *)&ue_context_pP->ue_context.handover_info->as_config.sourceSecurityAlgorithmConfig, - 0, sizeof(LTE_SecurityAlgorithmConfig_t)); - memcpy((void *)&ue_context_pP->ue_context.handover_info->as_config.sourceSystemInformationBlockType1, - (void *)&RC.rrc[ctxt_pP->module_id]->carrier[0] /* CROUX TBC */.SIB1, sizeof(LTE_SystemInformationBlockType1_t)); - memcpy((void *)&ue_context_pP->ue_context.handover_info->as_config.sourceSystemInformationBlockType2, - (void *)&RC.rrc[ctxt_pP->module_id]->carrier[0] /* CROUX TBC */.SIB23, sizeof(LTE_SystemInformationBlockType2_t)); - ue_context_pP->ue_context.handover_info->as_context.reestablishmentInfo = - CALLOC(1, sizeof(LTE_ReestablishmentInfo_t)); - ue_context_pP->ue_context.handover_info->as_context.reestablishmentInfo->sourcePhysCellId = - RC.rrc[ctxt_pP->module_id]->carrier[0] /* CROUX TBC */.physCellId; - ue_context_pP->ue_context.handover_info->as_context.reestablishmentInfo->targetCellShortMAC_I.buf = NULL; // Check values later - ue_context_pP->ue_context.handover_info->as_context.reestablishmentInfo->targetCellShortMAC_I.size = 0; - ue_context_pP->ue_context.handover_info->as_context.reestablishmentInfo->targetCellShortMAC_I.bits_unused = 0; - ue_context_pP->ue_context.handover_info->as_context.reestablishmentInfo->additionalReestabInfoList = NULL; - ue_context_pP->ue_context.handover_info->ho_prepare = 0xFF; //0xF0; - ue_context_pP->ue_context.handover_info->ho_complete = 0; - - if (mod_id_target != 0xFF) { - //UE_id_target = rrc_find_free_ue_index(modid_target); - ue_context_target_p = - rrc_eNB_get_ue_context( - RC.rrc[mod_id_target], - ue_context_pP->ue_context.rnti); - - /*UE_id_target = rrc_eNB_get_next_free_UE_index( - mod_id_target, - RC.rrc[ctxt_pP->module_id]->Info.UE_list[ue_mod_idP]); //this should return a new index*/ - - if (ue_context_target_p == NULL) { // if not already in target cell - ue_context_target_p = rrc_eNB_allocate_new_UE_context(RC.rrc[ctxt_pP->module_id]); - ue_context_target_p->ue_id_rnti = ue_context_pP->ue_context.rnti; // LG: should not be the same - ue_context_target_p->ue_context.rnti = ue_context_target_p->ue_id_rnti; // idem - LOG_I(RRC, - "[eNB %d] Frame %d : Emulate sending HandoverPreparationInformation msg from eNB source %d to eNB target %ld: source UE_id %x target UE_id %x source_modId: %d target_modId: %d\n", - ctxt_pP->module_id, - ctxt_pP->frame, - RC.rrc[ctxt_pP->module_id]->carrier[0] /* CROUX TBC */.physCellId, - targetPhyId, - ue_context_pP->ue_context.rnti, - ue_context_target_p->ue_id_rnti, - ctxt_pP->module_id, - mod_id_target); - ue_context_target_p->ue_context.handover_info = - CALLOC(1, sizeof(*(ue_context_target_p->ue_context.handover_info))); - memcpy((void *)&ue_context_target_p->ue_context.handover_info->as_context, - (void *)&ue_context_pP->ue_context.handover_info->as_context, - sizeof(LTE_AS_Context_t)); - memcpy((void *)&ue_context_target_p->ue_context.handover_info->as_config, - (void *)&ue_context_pP->ue_context.handover_info->as_config, - sizeof(LTE_AS_Config_t)); - ue_context_target_p->ue_context.handover_info->ho_prepare = 0x00;// 0xFF; - ue_context_target_p->ue_context.handover_info->ho_complete = 0; - ue_context_pP->ue_context.handover_info->modid_t = mod_id_target; - ue_context_pP->ue_context.handover_info->ueid_s = ue_context_pP->ue_context.rnti; - ue_context_pP->ue_context.handover_info->modid_s = ctxt_pP->module_id; - ue_context_target_p->ue_context.handover_info->modid_t = mod_id_target; - ue_context_target_p->ue_context.handover_info->modid_s = ctxt_pP->module_id; - ue_context_target_p->ue_context.handover_info->ueid_t = ue_context_target_p->ue_context.rnti; - } else { - LOG_E(RRC, "\nError in obtaining free UE id in target eNB %ld for handover \n", targetPhyId); - } - } else { - LOG_E(RRC, "\nError in obtaining Module ID of target eNB for handover \n"); - } -} -#endif - void rrc_eNB_process_handoverPreparationInformation(int mod_id, x2ap_handover_req_t *m) { struct rrc_eNB_ue_context_s *ue_context_target_p = NULL; /* TODO: get proper UE rnti */ @@ -4109,15 +4009,10 @@ void rrc_eNB_process_handoverPreparationInformation(int mod_id, x2ap_handover_re RB_INSERT(rrc_ue_tree_s, &RC.rrc[mod_id]->rrc_ue_head, ue_context_target_p); LOG_D(RRC, "eNB %d: Created new UE context uid %u\n", mod_id, ue_context_target_p->local_uid); ue_context_target_p->ue_context.handover_info = CALLOC(1, sizeof(*(ue_context_target_p->ue_context.handover_info))); - //ue_context_target_p->ue_context.handover_info->source_x2id = m->source_x2id; ue_context_target_p->ue_context.Status = RRC_HO_EXECUTION; ue_context_target_p->ue_context.handover_info->state = HO_ACK; - /* TODO: remove this hack */ - ue_context_target_p->ue_context.handover_info->source_assoc_id = m->source_assoc_id; - //ue_context_target_p->ue_context.handover_info->modid_t = mod_id; - //ue_context_target_p->ue_context.handover_info->modid_t = m->target_mod_id; - //ue_context_target_p->ue_context.handover_info->modid_s = 1-mod_id; - //ue_context_target_p->ue_context.handover_info->ueid_s = m->source_rnti; + ue_context_target_p->ue_context.handover_info->x2_id = m->x2_id; + ue_context_target_p->ue_context.handover_info->assoc_id = m->target_assoc_id; memset (ue_context_target_p->ue_context.nh, 0, 32); ue_context_target_p->ue_context.nh_ncc = -1; memcpy (ue_context_target_p->ue_context.kenb, m->kenb, 32); @@ -4261,28 +4156,6 @@ struct rrc_eNB_ue_context_s *ue_context_p) { } } -#if 0 -//----------------------------------------------------------------------------- -void -rrc_eNB_process_handoverPreparationInformation( - const protocol_ctxt_t *const ctxt_pP, - rrc_eNB_ue_context_t *const ue_context_pP -) -//----------------------------------------------------------------------------- -{ - T(T_ENB_RRC_HANDOVER_PREPARATION_INFORMATION, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), - T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - LOG_I(RRC, - "[eNB %d] Frame %d : Logical Channel UL-DCCH, processing RRCHandoverPreparationInformation, sending LTE_RRCConnectionReconfiguration to UE %d \n", - ctxt_pP->module_id, ctxt_pP->frame, ue_context_pP->ue_context.rnti); - rrc_eNB_generate_RRCConnectionReconfiguration_handover( - ctxt_pP, - ue_context_pP, - NULL, - 0); -} -#endif - void check_handovers( protocol_ctxt_t *const ctxt_pP @@ -4327,12 +4200,10 @@ check_handovers( rrc_eNB_generate_HO_RRCConnectionReconfiguration(ctxt_pP, ue_context_p, X2AP_HANDOVER_REQ_ACK(msg).rrc_buffer, &X2AP_HANDOVER_REQ_ACK(msg).rrc_buffer_size); rrc_eNB_configure_rbs_handover(ue_context_p,ctxt_pP); - /* TODO: remove this hack */ - //X2AP_HANDOVER_REQ_ACK(msg).target_mod_id = 1 - ctxt_pP->module_id; - //X2AP_HANDOVER_REQ_ACK(msg).target_mod_id = ue_context_p->ue_context.handover_info->modid_t; - //X2AP_HANDOVER_REQ_ACK(msg).source_x2id = ue_context_p->ue_context.handover_info->source_x2id; - X2AP_HANDOVER_REQ_ACK(msg).source_assoc_id = ue_context_p->ue_context.handover_info->source_assoc_id; + X2AP_HANDOVER_REQ_ACK(msg).rnti = ue_context_p->ue_context.rnti; + X2AP_HANDOVER_REQ_ACK(msg).x2_id_target = ue_context_p->ue_context.handover_info->x2_id; + X2AP_HANDOVER_REQ_ACK(msg).source_assoc_id = ue_context_p->ue_context.handover_info->assoc_id; /* Call admission control not implemented yet */ X2AP_HANDOVER_REQ_ACK(msg).nb_e_rabs_tobesetup = ue_context_p->ue_context.setup_e_rabs; @@ -4347,70 +4218,6 @@ check_handovers( } } -#if 0 -//----------------------------------------------------------------------------- -void -check_handovers( - protocol_ctxt_t *const ctxt_pP -) -//----------------------------------------------------------------------------- -{ - int result; - struct rrc_eNB_ue_context_s *ue_context_p; - RB_FOREACH(ue_context_p, rrc_ue_tree_s, &RC.rrc[ctxt_pP->module_id]->rrc_ue_head) { - ctxt_pP->rnti = ue_context_p->ue_id_rnti; - - if (ue_context_p->ue_context.handover_info != NULL) { - if (ue_context_p->ue_context.handover_info->ho_prepare == 0xFF) { - LOG_D(RRC, - "[eNB %d] Frame %d: Incoming handover detected for new UE_idx %d (source eNB %d->target eNB %d) \n", - ctxt_pP->module_id, - ctxt_pP->frame, - ctxt_pP->rnti, - ctxt_pP->module_id, - ue_context_p->ue_context.handover_info->modid_t); - // source eNB generates LTE_RRCConnectionreconfiguration to prepare the HO - rrc_eNB_process_handoverPreparationInformation( - ctxt_pP, - ue_context_p); - ue_context_p->ue_context.handover_info->ho_prepare = 0xF1; - } - - if (ue_context_p->ue_context.handover_info->ho_complete == 0xF1) { - LOG_D(RRC, - "[eNB %d] Frame %d: handover Command received for new UE_id %x current eNB %d target eNB: %d \n", - ctxt_pP->module_id, - ctxt_pP->frame, - ctxt_pP->rnti, - ctxt_pP->module_id, - ue_context_p->ue_context.handover_info->modid_t); - //rrc_eNB_process_handoverPreparationInformation(enb_mod_idP,frameP,i); - result = pdcp_data_req(ctxt_pP, - SRB_FLAG_YES, - DCCH, - rrc_eNB_mui++, - SDU_CONFIRM_NO, - ue_context_p->ue_context.handover_info->size, - ue_context_p->ue_context.handover_info->buf, - PDCP_TRANSMISSION_MODE_CONTROL -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,NULL, NULL -#endif - ); - - //AssertFatal(result == TRUE, "PDCP data request failed!\n"); - if(result != TRUE) { - LOG_I(RRC, "PDCP data request failed!\n"); - return; - } - - ue_context_p->ue_context.handover_info->ho_complete = 0xF2; - } - } - } -} -#endif - void rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP, @@ -8210,7 +8017,7 @@ void *rrc_enb_process_itti_msg(void *notUsed) { int CC_id; protocol_ctxt_t ctxt; -// memset(&ctxt, 0, sizeof(ctxt)); + memset(&ctxt, 0, sizeof(ctxt)); // Wait for a message itti_receive_msg(TASK_RRC_ENB, &msg_p); @@ -8341,16 +8148,20 @@ void *rrc_enb_process_itti_msg(void *notUsed) { break; case X2AP_HANDOVER_REQ: - LOG_I(RRC, "[eNB %d] target eNB Receives X2 HO Req %s at frame %d subframe %d\n", instance, msg_name_p, - ctxt.frame, ctxt.subframe); + LOG_I(RRC, "[eNB %d] target eNB Receives X2 HO Req %s\n", instance, msg_name_p); rrc_eNB_process_handoverPreparationInformation(instance, &X2AP_HANDOVER_REQ(msg_p)); break; case X2AP_HANDOVER_REQ_ACK: { struct rrc_eNB_ue_context_s *ue_context_p = NULL; - ue_context_p = rrc_eNB_get_ue_context(RC.rrc[instance], ctxt.rnti); - LOG_I(RRC, "[eNB %d] source eNB receives the X2 HO ACK %s at frame %d subframe %d \n", instance, msg_name_p, - ctxt.frame,ctxt.subframe); + ue_context_p = rrc_eNB_get_ue_context(RC.rrc[instance], X2AP_HANDOVER_REQ_ACK(msg_p).rnti); + if (ue_context_p == NULL) { + /* is it possible? */ + LOG_E(RRC, "could not find UE (rnti %x) while processing X2AP_HANDOVER_REQ_ACK\n", + X2AP_HANDOVER_REQ_ACK(msg_p).rnti); + exit(1); + } + LOG_I(RRC, "[eNB %d] source eNB receives the X2 HO ACK %s\n", instance, msg_name_p); DevAssert(ue_context_p != NULL); if (ue_context_p->ue_context.handover_info->state != HO_REQUEST) abort(); @@ -8362,9 +8173,8 @@ void *rrc_enb_process_itti_msg(void *notUsed) { case X2AP_UE_CONTEXT_RELEASE: { struct rrc_eNB_ue_context_s *ue_context_p = NULL; - ue_context_p = rrc_eNB_get_ue_context(RC.rrc[instance], ctxt.rnti); - LOG_I(RRC, "[eNB %d] source eNB receives the X2 UE CONTEXT RELEASE %s at frame %d subframe %d \n", instance, msg_name_p, - ctxt.frame,ctxt.subframe); + ue_context_p = rrc_eNB_get_ue_context(RC.rrc[instance], X2AP_UE_CONTEXT_RELEASE(msg_p).rnti); + LOG_I(RRC, "[eNB %d] source eNB receives the X2 UE CONTEXT RELEASE %s\n", instance, msg_name_p); DevAssert(ue_context_p != NULL); if (ue_context_p->ue_context.handover_info->state != HO_COMPLETE) abort(); diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index e2e434feb7b1bf873e260a10668265eb81b6f382..82818fcd1ed8c3ec226ba0d718d8fa02dfdc61e3 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -2102,9 +2102,8 @@ int rrc_eNB_send_X2AP_UE_CONTEXT_RELEASE(const protocol_ctxt_t* const ctxt_pP, r msg_p = itti_alloc_new_message (TASK_RRC_ENB, X2AP_UE_CONTEXT_RELEASE); - X2AP_UE_CONTEXT_RELEASE (msg_p).old_eNB_ue_x2ap_id = 0; - X2AP_UE_CONTEXT_RELEASE (msg_p).new_eNB_ue_x2ap_id = 0; - X2AP_UE_CONTEXT_RELEASE (msg_p).source_assoc_id = ue_context_pP->ue_context.handover_info->source_assoc_id; + X2AP_UE_CONTEXT_RELEASE (msg_p).rnti = ue_context_pP->ue_context.rnti; + X2AP_UE_CONTEXT_RELEASE (msg_p).source_assoc_id = ue_context_pP->ue_context.handover_info->assoc_id; itti_send_msg_to_task (TASK_X2AP, ctxt_pP->instance, msg_p); return (0); } diff --git a/openair2/X2AP/x2ap_eNB.c b/openair2/X2AP/x2ap_eNB.c index 19031bceaff5f22d7ffce5ba3326f247edddfdf3..c05495a0c414c79bb5ee1bcf20da02065c9682f8 100644 --- a/openair2/X2AP/x2ap_eNB.c +++ b/openair2/X2AP/x2ap_eNB.c @@ -40,6 +40,7 @@ #include "x2ap_eNB_handler.h" #include "x2ap_eNB_generate_messages.h" #include "x2ap_common.h" +#include "x2ap_ids.h" #include "queue.h" #include "assertions.h" @@ -80,8 +81,8 @@ void x2ap_eNB_handle_handover_req_ack(instance_t instance, x2ap_handover_req_ack_t *x2ap_handover_req_ack); static -void x2ap_eNB_handle_ue_context_release(instance_t instance, - x2ap_ue_context_release_t *x2ap_ue_context_release); +void x2ap_eNB_ue_context_release(instance_t instance, + x2ap_ue_context_release_t *x2ap_ue_context_release); static @@ -299,6 +300,8 @@ void x2ap_eNB_handle_register_eNB(instance_t instance, new_instance->mnc_digit_length = x2ap_register_eNB->mnc_digit_length; new_instance->num_cc = x2ap_register_eNB->num_cc; + x2ap_id_manager_init(&new_instance->id_manager); + for (int i = 0; i< x2ap_register_eNB->num_cc; i++) { new_instance->eutra_band[i] = x2ap_register_eNB->eutra_band[i]; new_instance->downlink_frequency[i] = x2ap_register_eNB->downlink_frequency[i]; @@ -376,15 +379,10 @@ static void x2ap_eNB_handle_handover_req(instance_t instance, x2ap_handover_req_t *x2ap_handover_req) { - /* TODO: remove this hack (the goal is to find the correct - * eNodeB structure for the target) - we need a proper way for RRC - * and X2AP to identify eNodeBs - * RRC knows about mod_id and X2AP knows about eNB_id (eNB_ID in - * the configuration file) - * as far as I understand.. CROUX - */ x2ap_eNB_instance_t *instance_p; x2ap_eNB_data_t *target; + x2ap_id_manager *id_manager; + int ue_id; int target_pci = x2ap_handover_req->target_physCellId; @@ -394,9 +392,18 @@ void x2ap_eNB_handle_handover_req(instance_t instance, target = x2ap_is_eNB_pci_in_list(target_pci); DevAssert(target != NULL); - /* store rnti at index 0 */ - //x2id_to_source_rnti[0] = x2ap_handover_req->source_rnti; - x2ap_eNB_generate_x2_handover_request(instance_p, target, x2ap_handover_req); + /* allocate x2ap ID */ + id_manager = &instance_p->id_manager; + ue_id = x2ap_allocate_new_id(id_manager); + if (ue_id == -1) { + X2AP_ERROR("could not allocate a new X2AP 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 */ + x2ap_set_ids(id_manager, ue_id, x2ap_handover_req->rnti, ue_id, -1); + + x2ap_eNB_generate_x2_handover_request(instance_p, target, x2ap_handover_req, ue_id); } static @@ -413,6 +420,9 @@ void x2ap_eNB_handle_handover_req_ack(instance_t instance, x2ap_eNB_instance_t *instance_p; x2ap_eNB_data_t *target; int source_assoc_id = x2ap_handover_req_ack->source_assoc_id; + int ue_id; + int id_source; + int id_target; instance_p = x2ap_eNB_get_instance(instance); DevAssert(instance_p != NULL); @@ -420,19 +430,23 @@ void x2ap_eNB_handle_handover_req_ack(instance_t instance, target = x2ap_get_eNB(NULL, source_assoc_id, 0); DevAssert(target != NULL); + /* rnti is a new information, save it */ + ue_id = x2ap_handover_req_ack->x2_id_target; + id_source = x2ap_id_get_id_source(&instance_p->id_manager, ue_id); + id_target = ue_id; + x2ap_set_ids(&instance_p->id_manager, ue_id, x2ap_handover_req_ack->rnti, id_source, id_target); + x2ap_eNB_generate_x2_handover_request_ack(instance_p, target, x2ap_handover_req_ack); - //x2ap_eNB_generate_x2_handover_req_ack(instance_p, target, x2ap_handover_req_ack->source_x2id, - //x2ap_handover_req_ack->rrc_buffer, x2ap_handover_req_ack->rrc_buffer_size); } static -void x2ap_eNB_handle_ue_context_release(instance_t instance, - x2ap_ue_context_release_t *x2ap_ue_context_release) +void x2ap_eNB_ue_context_release(instance_t instance, + x2ap_ue_context_release_t *x2ap_ue_context_release) { x2ap_eNB_instance_t *instance_p; x2ap_eNB_data_t *target; int source_assoc_id = x2ap_ue_context_release->source_assoc_id; - + int ue_id; instance_p = x2ap_eNB_get_instance(instance); DevAssert(instance_p != NULL); @@ -440,6 +454,14 @@ void x2ap_eNB_handle_ue_context_release(instance_t instance, DevAssert(target != NULL); x2ap_eNB_generate_x2_ue_context_release(instance_p, target, x2ap_ue_context_release); + + /* free the X2AP UE ID */ + ue_id = x2ap_find_id_from_rnti(&instance_p->id_manager, x2ap_ue_context_release->rnti); + if (ue_id == -1) { + X2AP_ERROR("could not find UE %x\n", x2ap_ue_context_release->rnti); + exit(1); + } + x2ap_release_id(&instance_p->id_manager, ue_id); } void *x2ap_task(void *arg) { @@ -474,7 +496,7 @@ void *x2ap_task(void *arg) { break; case X2AP_UE_CONTEXT_RELEASE: - x2ap_eNB_handle_ue_context_release(ITTI_MESSAGE_GET_INSTANCE(received_msg), + x2ap_eNB_ue_context_release(ITTI_MESSAGE_GET_INSTANCE(received_msg), &X2AP_UE_CONTEXT_RELEASE(received_msg)); break; diff --git a/openair2/X2AP/x2ap_eNB_defs.h b/openair2/X2AP/x2ap_eNB_defs.h index f90176430cf598a128262858d98d4a00a4303298..3356a101b4e632927cc72d9397f850d1a75885ca 100644 --- a/openair2/X2AP/x2ap_eNB_defs.h +++ b/openair2/X2AP/x2ap_eNB_defs.h @@ -33,6 +33,8 @@ #include "sctp_eNB_defs.h" +#include "x2ap_ids.h" + #ifndef X2AP_ENB_DEFS_H_ #define X2AP_ENB_DEFS_H_ @@ -180,6 +182,8 @@ typedef struct x2ap_eNB_instance_s { uint16_t sctp_out_streams; uint32_t enb_port_for_X2C; int multi_sd; + + x2ap_id_manager id_manager; } x2ap_eNB_instance_t; typedef struct { diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c index 27fd766614182ba552212e2893cd051d9cf1d761..c13469d5d4bfc209c523c6b063620a4e6d5c8067 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.c +++ b/openair2/X2AP/x2ap_eNB_generate_messages.c @@ -35,6 +35,7 @@ #include "x2ap_eNB_generate_messages.h" #include "x2ap_eNB_encoder.h" #include "x2ap_eNB_decoder.h" +#include "x2ap_ids.h" #include "x2ap_eNB_itti_messaging.h" @@ -409,7 +410,7 @@ int x2ap_eNB_set_cause (X2AP_Cause_t * cause_p, } int x2ap_eNB_generate_x2_handover_request (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, - x2ap_handover_req_t *x2ap_handover_req) + x2ap_handover_req_t *x2ap_handover_req, int ue_id) { X2AP_X2AP_PDU_t pdu; @@ -439,7 +440,7 @@ int x2ap_eNB_generate_x2_handover_request (x2ap_eNB_instance_t *instance_p, x2ap ie->id = X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID; ie->criticality = X2AP_Criticality_reject; ie->value.present = X2AP_HandoverRequest_IEs__value_PR_UE_X2AP_ID; - ie->value.choice.UE_X2AP_ID = x2ap_handover_req->old_eNB_ue_x2ap_id; + ie->value.choice.UE_X2AP_ID = x2ap_id_get_id_source(&instance_p->id_manager, ue_id); ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); /* mandatory */ @@ -572,6 +573,9 @@ int x2ap_eNB_generate_x2_handover_request_ack (x2ap_eNB_instance_t *instance_p, X2AP_HandoverRequestAcknowledge_IEs_t *ie; X2AP_E_RABs_Admitted_ItemIEs_t *e_RABS_Admitted_ItemIEs; X2AP_E_RABs_Admitted_Item_t *e_RABs_Admitted_Item; + int ue_id; + int id_source; + int id_target; uint8_t *buffer; uint32_t len; @@ -580,6 +584,10 @@ int x2ap_eNB_generate_x2_handover_request_ack (x2ap_eNB_instance_t *instance_p, DevAssert(instance_p != NULL); DevAssert(x2ap_eNB_data_p != NULL); + ue_id = x2ap_handover_req_ack->x2_id_target; + id_source = x2ap_id_get_id_source(&instance_p->id_manager, ue_id); + id_target = ue_id; + /* Prepare the X2AP handover message to encode */ memset(&pdu, 0, sizeof(pdu)); pdu.present = X2AP_X2AP_PDU_PR_successfulOutcome; @@ -593,7 +601,7 @@ int x2ap_eNB_generate_x2_handover_request_ack (x2ap_eNB_instance_t *instance_p, ie->id = X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID; ie->criticality = X2AP_Criticality_ignore; ie->value.present = X2AP_HandoverRequestAcknowledge_IEs__value_PR_UE_X2AP_ID; - ie->value.choice.UE_X2AP_ID = 0; + ie->value.choice.UE_X2AP_ID = id_source; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); /* mandatory */ @@ -601,7 +609,7 @@ int x2ap_eNB_generate_x2_handover_request_ack (x2ap_eNB_instance_t *instance_p, ie->id = X2AP_ProtocolIE_ID_id_New_eNB_UE_X2AP_ID; ie->criticality = X2AP_Criticality_ignore; ie->value.present = X2AP_HandoverRequestAcknowledge_IEs__value_PR_UE_X2AP_ID_1; - ie->value.choice.UE_X2AP_ID_1 = 0; + ie->value.choice.UE_X2AP_ID_1 = id_target; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); /* mandatory */ @@ -655,6 +663,9 @@ int x2ap_eNB_generate_x2_ue_context_release (x2ap_eNB_instance_t *instance_p, x2 X2AP_X2AP_PDU_t pdu; X2AP_UEContextRelease_t *out; X2AP_UEContextRelease_IEs_t *ie; + int ue_id; + int id_source; + int id_target; uint8_t *buffer; uint32_t len; @@ -663,6 +674,14 @@ int x2ap_eNB_generate_x2_ue_context_release (x2ap_eNB_instance_t *instance_p, x2 DevAssert(instance_p != NULL); DevAssert(x2ap_eNB_data_p != NULL); + ue_id = x2ap_find_id_from_rnti(&instance_p->id_manager, x2ap_ue_context_release->rnti); + if (ue_id == -1) { + X2AP_ERROR("could not find UE %x\n", x2ap_ue_context_release->rnti); + exit(1); + } + id_source = x2ap_id_get_id_source(&instance_p->id_manager, ue_id); + id_target = ue_id; + /* Prepare the X2AP ue context relase message to encode */ memset(&pdu, 0, sizeof(pdu)); pdu.present = X2AP_X2AP_PDU_PR_initiatingMessage; @@ -676,7 +695,7 @@ int x2ap_eNB_generate_x2_ue_context_release (x2ap_eNB_instance_t *instance_p, x2 ie->id = X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID; ie->criticality = X2AP_Criticality_reject; ie->value.present = X2AP_UEContextRelease_IEs__value_PR_UE_X2AP_ID; - ie->value.choice.UE_X2AP_ID = x2ap_ue_context_release->old_eNB_ue_x2ap_id; + ie->value.choice.UE_X2AP_ID = id_source; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); /* mandatory */ @@ -684,7 +703,7 @@ int x2ap_eNB_generate_x2_ue_context_release (x2ap_eNB_instance_t *instance_p, x2 ie->id = X2AP_ProtocolIE_ID_id_New_eNB_UE_X2AP_ID; ie->criticality = X2AP_Criticality_reject; ie->value.present = X2AP_UEContextRelease_IEs__value_PR_UE_X2AP_ID_1; - ie->value.choice.UE_X2AP_ID_1 = x2ap_ue_context_release->new_eNB_ue_x2ap_id; + ie->value.choice.UE_X2AP_ID_1 = id_target; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.h b/openair2/X2AP/x2ap_eNB_generate_messages.h index 6636413fc617326f797b02076ab03fc68ac008fd..059d213277599a465876f3ebfb4c6b5fba242ce2 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.h +++ b/openair2/X2AP/x2ap_eNB_generate_messages.h @@ -48,7 +48,7 @@ int x2ap_eNB_set_cause (X2AP_Cause_t * cause_p, long cause_value); int x2ap_eNB_generate_x2_handover_request (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, - x2ap_handover_req_t *x2ap_handover_req); + x2ap_handover_req_t *x2ap_handover_req, int ue_id); int x2ap_eNB_generate_x2_handover_request_ack (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, x2ap_handover_req_ack_t *x2ap_handover_req_ack); diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c index cb216dfc81e6be4e35c71f7ea90a905028263b0c..c07f0643196351a212329329500649f57ef26b1e 100644 --- a/openair2/X2AP/x2ap_eNB_handler.c +++ b/openair2/X2AP/x2ap_eNB_handler.c @@ -36,6 +36,7 @@ #include "x2ap_eNB_defs.h" #include "x2ap_eNB_handler.h" #include "x2ap_eNB_decoder.h" +#include "x2ap_ids.h" #include "x2ap_eNB_management_procedures.h" #include "x2ap_eNB_generate_messages.h" @@ -593,6 +594,7 @@ int x2ap_eNB_handle_handover_preparation (instance_t instance, x2ap_eNB_instance_t *instance_p; x2ap_eNB_data_t *x2ap_eNB_data; MessageDef *msg; + int ue_id; DevAssert (pdu != NULL); x2HandoverRequest = &pdu->choice.initiatingMessage.value.choice.HandoverRequest; @@ -608,19 +610,30 @@ int x2ap_eNB_handle_handover_preparation (instance_t instance, x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0); DevAssert(x2ap_eNB_data != NULL); + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + msg = itti_alloc_new_message(TASK_X2AP, X2AP_HANDOVER_REQ); X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequest_IEs_t, ie, x2HandoverRequest, X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID, true); - //X2AP_HANDOVER_REQ(msg).source_rnti = ctxt_pP->rnti; - //X2AP_HANDOVER_REQ(m).source_x2id = x2HandoverRequest->old_eNB_UE_X2AP_ID; if (ie == NULL ) { X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); return -1; - } else { - X2AP_HANDOVER_REQ(msg).old_eNB_ue_x2ap_id = ie->value.choice.UE_X2AP_ID; } + /* allocate a new X2AP UE ID */ + ue_id = x2ap_allocate_new_id(&instance_p->id_manager); + if (ue_id == -1) { + X2AP_ERROR("could not allocate a new X2AP UE ID\n"); + /* TODO: cancel handover: send HO preparation failure to source eNB */ + exit(1); + } + /* rnti is unknown yet, must not be set to -1, 0 is fine */ + x2ap_set_ids(&instance_p->id_manager, ue_id, 0, ie->value.choice.UE_X2AP_ID, ue_id); + + X2AP_HANDOVER_REQ(msg).x2_id = ue_id; + //X2AP_HANDOVER_REQ(msg).target_physCellId = measResults2->measResultNeighCells->choice. //measResultListEUTRA.list.array[ncell_index]->physCellId; X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequest_IEs_t, ie, x2HandoverRequest, @@ -643,7 +656,7 @@ int x2ap_eNB_handle_handover_preparation (instance_t instance, /* TODO: properly store Target Cell ID */ - X2AP_HANDOVER_REQ(msg).source_assoc_id = assoc_id; + X2AP_HANDOVER_REQ(msg).target_assoc_id = assoc_id; X2AP_HANDOVER_REQ(msg).security_capabilities.encryption_algorithms = BIT_STRING_to_uint16(&ie->value.choice.UE_ContextInformation.uESecurityCapabilities.encryptionAlgorithms); @@ -699,9 +712,6 @@ int x2ap_eNB_handle_handover_preparation (instance_t instance, memcpy(X2AP_HANDOVER_REQ(msg).rrc_buffer, c->buf, c->size); X2AP_HANDOVER_REQ(msg).rrc_buffer_size = c->size; - instance_p = x2ap_eNB_get_instance(instance); - DevAssert(instance_p != NULL); - itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg); return 0; @@ -719,6 +729,10 @@ int x2ap_eNB_handle_handover_response (instance_t instance, x2ap_eNB_instance_t *instance_p; x2ap_eNB_data_t *x2ap_eNB_data; MessageDef *msg; + int ue_id; + int id_source; + int id_target; + int rnti; DevAssert (pdu != NULL); x2HandoverRequestAck = &pdu->choice.successfulOutcome.value.choice.HandoverRequestAcknowledge; @@ -734,12 +748,32 @@ int x2ap_eNB_handle_handover_response (instance_t instance, x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0); DevAssert(x2ap_eNB_data != NULL); + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); msg = itti_alloc_new_message(TASK_X2AP, X2AP_HANDOVER_REQ_ACK); - /* TODO: fill the message */ - //extern int x2id_to_source_rnti[1]; - //X2AP_HANDOVER_REQ_ACK(m).source_x2id = x2HandoverRequestAck->old_eNB_UE_X2AP_ID; - //X2AP_HANDOVER_REQ_ACK(m).source_rnti = x2id_to_source_rnti[x2HandoverRequestAck->old_eNB_UE_X2AP_ID]; + + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequestAcknowledge_IEs_t, ie, x2HandoverRequestAck, + X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID, true); + id_source = ie->value.choice.UE_X2AP_ID; + + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequestAcknowledge_IEs_t, ie, x2HandoverRequestAck, + X2AP_ProtocolIE_ID_id_New_eNB_UE_X2AP_ID, true); + id_target = ie->value.choice.UE_X2AP_ID_1; + + ue_id = id_source; + + if (id_source != x2ap_id_get_id_source(&instance_p->id_manager, ue_id)) { + X2AP_ERROR("incorrect X2AP IDs for UE (old ID %d new ID %d)\n", id_source, id_target); + exit(1); + } + + rnti = x2ap_id_get_rnti(&instance_p->id_manager, ue_id); + + /* id_target is a new information, store it */ + x2ap_set_ids(&instance_p->id_manager, ue_id, rnti, id_source, id_target); + + X2AP_HANDOVER_REQ_ACK(msg).rnti = rnti; X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequestAcknowledge_IEs_t, ie, x2HandoverRequestAck, X2AP_ProtocolIE_ID_id_TargeteNBtoSource_eNBTransparentContainer, true); @@ -752,9 +786,6 @@ int x2ap_eNB_handle_handover_response (instance_t instance, memcpy(X2AP_HANDOVER_REQ_ACK(msg).rrc_buffer, c->buf, c->size); X2AP_HANDOVER_REQ_ACK(msg).rrc_buffer_size = c->size; - instance_p = x2ap_eNB_get_instance(instance); - DevAssert(instance_p != NULL); - itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg); return 0; } @@ -772,6 +803,9 @@ int x2ap_eNB_handle_ue_context_release (instance_t instance, x2ap_eNB_instance_t *instance_p; x2ap_eNB_data_t *x2ap_eNB_data; MessageDef *msg; + int ue_id; + int id_source; + int id_target; DevAssert (pdu != NULL); x2UEContextRelease = &pdu->choice.initiatingMessage.value.choice.UEContextRelease; @@ -787,22 +821,36 @@ int x2ap_eNB_handle_ue_context_release (instance_t instance, x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0); DevAssert(x2ap_eNB_data != NULL); + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + msg = itti_alloc_new_message(TASK_X2AP, X2AP_UE_CONTEXT_RELEASE); X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_UEContextRelease_IEs_t, ie, x2UEContextRelease, X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID, true); - X2AP_UE_CONTEXT_RELEASE(msg).old_eNB_ue_x2ap_id = ie->value.choice.UE_X2AP_ID; + id_source = ie->value.choice.UE_X2AP_ID; X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_UEContextRelease_IEs_t, ie, x2UEContextRelease, X2AP_ProtocolIE_ID_id_New_eNB_UE_X2AP_ID, true); - X2AP_UE_CONTEXT_RELEASE(msg).new_eNB_ue_x2ap_id = ie->value.choice.UE_X2AP_ID; + id_target = ie->value.choice.UE_X2AP_ID_1; - instance_p = x2ap_eNB_get_instance(instance); - DevAssert(instance_p != NULL); + ue_id = id_source; + + if (id_target != x2ap_id_get_id_target(&instance_p->id_manager, ue_id)) { + X2AP_ERROR("UE context release: bad id_target for UE %x (id_source %d) expected %d got %d\n", + x2ap_id_get_rnti(&instance_p->id_manager, ue_id), + id_source, + x2ap_id_get_id_target(&instance_p->id_manager, ue_id), + id_target); + } + + X2AP_UE_CONTEXT_RELEASE(msg).rnti = x2ap_id_get_rnti(&instance_p->id_manager, ue_id); itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg); + x2ap_release_id(&instance_p->id_manager, ue_id); + return 0; } diff --git a/openair2/X2AP/x2ap_ids.c b/openair2/X2AP/x2ap_ids.c new file mode 100644 index 0000000000000000000000000000000000000000..b5607821fe5d97ef6c026000236c738740134963 --- /dev/null +++ b/openair2/X2AP/x2ap_ids.c @@ -0,0 +1,92 @@ +/* + * 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 "x2ap_ids.h" + +#include <string.h> + +void x2ap_id_manager_init(x2ap_id_manager *m) +{ + int i; + memset(m, 0, sizeof(x2ap_id_manager)); + for (i = 0; i < X2AP_MAX_IDS; i++) + m->ids[i].rnti = -1; +} + +int x2ap_allocate_new_id(x2ap_id_manager *m) +{ + int i; + for (i = 0; i < X2AP_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 x2ap_release_id(x2ap_id_manager *m, int id) +{ + m->ids[id].rnti = -1; +} + +int x2ap_find_id(x2ap_id_manager *m, int id_source, int id_target) +{ + int i; + for (i = 0; i < X2AP_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 x2ap_find_id_from_rnti(x2ap_id_manager *m, int rnti) +{ + int i; + for (i = 0; i < X2AP_MAX_IDS; i++) + if (m->ids[i].rnti == rnti) + return i; + return -1; +} + +void x2ap_set_ids(x2ap_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; +} + +int x2ap_id_get_id_source(x2ap_id_manager *m, int ue_id) +{ + return m->ids[ue_id].id_source; +} + +int x2ap_id_get_id_target(x2ap_id_manager *m, int ue_id) +{ + return m->ids[ue_id].id_target; +} + +int x2ap_id_get_rnti(x2ap_id_manager *m, int ue_id) +{ + return m->ids[ue_id].rnti; +} diff --git a/openair2/X2AP/x2ap_ids.h b/openair2/X2AP/x2ap_ids.h new file mode 100644 index 0000000000000000000000000000000000000000..2232308f73dd944cd578e327467edcd017d67e6d --- /dev/null +++ b/openair2/X2AP/x2ap_ids.h @@ -0,0 +1,47 @@ +/* + * 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 X2AP_IDS_H_ +#define X2AP_IDS_H_ + +#define X2AP_MAX_IDS 16 + +typedef struct { + int rnti; /* -1 when free */ + int id_source; + int id_target; +} x2ap_id; + +typedef struct { + x2ap_id ids[X2AP_MAX_IDS]; +} x2ap_id_manager; + +void x2ap_id_manager_init(x2ap_id_manager *m); +int x2ap_allocate_new_id(x2ap_id_manager *m); +void x2ap_release_id(x2ap_id_manager *m, int id); +int x2ap_find_id(x2ap_id_manager *, int id_source, int id_target); +int x2ap_find_id_from_rnti(x2ap_id_manager *, int rnti); +void x2ap_set_ids(x2ap_id_manager *m, int ue_id, int rnti, int id_source, int id_target); +int x2ap_id_get_id_source(x2ap_id_manager *m, int ue_id); +int x2ap_id_get_id_target(x2ap_id_manager *m, int ue_id); +int x2ap_id_get_rnti(x2ap_id_manager *m, int ue_id); + +#endif /* X2AP_IDS_H_ */