/******************************************************************************* OpenAirInterface Copyright(c) 1999 - 2014 Eurecom OpenAirInterface is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OpenAirInterface is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenAirInterface.The full GNU General Public License is included in this distribution in the file called "COPYING". If not, see . Contact Information OpenAirInterface Admin: openair_admin@eurecom.fr OpenAirInterface Tech : openair_tech@eurecom.fr OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE *******************************************************************************/ /*! \file x2ap_eNB_generate_messages.c * \brief x2ap message generator * \author Navid Nikaein * \date 2015 - 2016 * \version 1.0 * \company Eurecom * \email: navid.nikaein@eurecom.fr */ #include "intertask_interface.h" #include "x2ap_eNB.h" #include "x2ap_eNB_generate_messages.h" #include "x2ap_eNB_encoder.h" #include "x2ap_eNB_itti_messaging.h" #include "RRC/LITE/defs.h" #include "RRC/LITE/extern.h" #include "secu_defs.h" #include "rrc_eNB_UE_context.h" #include "enb_config.h" #include "msc.h" #include "assertions.h" #include "conversions.h" extern unsigned char NB_eNB_INST; extern int x2id_to_source_rnti[1]; int x2ap_eNB_generate_x2_setup_request(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_enb_data_p) { x2ap_message message; X2SetupRequest_IEs_t *x2SetupRequest; X2ap_PLMN_Identity_t plmnIdentity; X2ap_PLMN_Identity_t broadcast_plmnIdentity_1; X2ap_PLMN_Identity_t broadcast_plmnIdentity_2; X2ap_PLMN_Identity_t broadcast_plmnIdentity_3; X2ap_ServedCellItem_t *served_cell= malloc(sizeof(X2ap_ServedCellItem_t)); uint8_t *buffer; uint32_t len; int ret = 0; DevAssert(instance_p != NULL); DevAssert(x2ap_enb_data_p != NULL); memset(&message, 0, sizeof(x2ap_message)); message.direction = X2AP_PDU_PR_initiatingMessage; message.procedureCode = X2ap_ProcedureCode_id_x2Setup; message.criticality = X2ap_Criticality_reject; x2SetupRequest = &message.msg.x2SetupRequest_IEs; memset((void *)&plmnIdentity, 0, sizeof(X2ap_PLMN_Identity_t)); memset((void *)&broadcast_plmnIdentity_1, 0, sizeof(X2ap_PLMN_Identity_t)); memset((void *)&broadcast_plmnIdentity_2, 0, sizeof(X2ap_PLMN_Identity_t)); memset((void *)&broadcast_plmnIdentity_3, 0, sizeof(X2ap_PLMN_Identity_t)); x2ap_enb_data_p->state = X2AP_ENB_STATE_WAITING; //----globalENB_ID------ x2SetupRequest->globalENB_ID.eNB_ID.present = X2ap_ENB_ID_PR_macro_eNB_ID ; MACRO_ENB_ID_TO_BIT_STRING(instance_p->eNB_id, &x2SetupRequest->globalENB_ID.eNB_ID.choice.macro_eNB_ID); MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, &x2SetupRequest->globalENB_ID.pLMN_Identity); X2AP_INFO("%d -> %02x%02x%02x\n", instance_p->eNB_id, x2SetupRequest->globalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[0], x2SetupRequest->globalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[1], x2SetupRequest->globalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[2]); //----served cells------ #warning update the value of the message served_cell->servedCellInfo.pCI = 6; served_cell->servedCellInfo.eUTRA_Mode_Info.present = X2ap_EUTRA_Mode_Info_PR_fDD; served_cell->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_EARFCN = 3350; served_cell->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_EARFCN = 3350; served_cell->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = 0; served_cell->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = 0; MCC_MNC_TO_PLMNID(instance_p->mcc,instance_p->mnc,instance_p->mnc_digit_length, &served_cell->servedCellInfo.cellId.pLMN_Identity); MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc,instance_p->mnc_digit_length,&broadcast_plmnIdentity_1); MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc,instance_p->mnc_digit_length,&broadcast_plmnIdentity_2); MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc,instance_p->mnc_digit_length,&broadcast_plmnIdentity_3); ASN_SEQUENCE_ADD(&served_cell->servedCellInfo.broadcastPLMNs.list, &broadcast_plmnIdentity_1); ASN_SEQUENCE_ADD(&served_cell->servedCellInfo.broadcastPLMNs.list, &broadcast_plmnIdentity_2); ASN_SEQUENCE_ADD(&served_cell->servedCellInfo.broadcastPLMNs.list, &broadcast_plmnIdentity_3); ECI_TO_BIT_STRING(instance_p->eNB_id, &served_cell->servedCellInfo.cellId.eUTRANcellIdentifier); TAC_TO_OCTET_STRING(instance_p->tac, &served_cell->servedCellInfo.tAC); ASN_SEQUENCE_ADD(&x2SetupRequest->servedCells.list, served_cell); if (x2ap_eNB_encode_pdu(&message, &buffer, &len) < 0) { X2AP_ERROR("Failed to encode X2 setup request\n"); return -1; } MSC_LOG_TX_MESSAGE (MSC_X2AP_SRC_ENB, MSC_X2AP_TARGET_ENB, NULL, 0, "0 X2Setup/initiatingMessage assoc_id %u", x2ap_enb_data_p->assoc_id); /* Non UE-Associated signalling -> stream = 0 */ x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_enb_data_p->assoc_id, buffer, len, 0); return ret; } int x2ap_generate_x2_setup_response (x2ap_eNB_data_t * eNB_association) { x2ap_eNB_instance_t *instance=eNB_association->x2ap_eNB_instance; x2ap_message message; X2SetupResponse_IEs_t *x2SetupResponse; // X2ap_PLMN_Identity_t plmnIdentity; X2ap_PLMN_Identity_t broadcast_plmnIdentity_1; X2ap_PLMN_Identity_t broadcast_plmnIdentity_2; X2ap_PLMN_Identity_t broadcast_plmnIdentity_3; X2ap_ServedCellItem_t *served_cell = calloc(1, sizeof(X2ap_ServedCellItem_t));; uint8_t *buffer; uint32_t len; int ret = 0; // get the eNB instance // DevAssert (eNB_association != NULL); // Generating response memset (&message, 0, sizeof (x2ap_message)); message.direction = X2AP_PDU_PR_successfulOutcome; message.procedureCode = X2ap_ProcedureCode_id_x2Setup; message.criticality = X2ap_Criticality_reject; x2SetupResponse = &message.msg.x2SetupResponse_IEs; // memset((void *)&plmnIdentity, 0, sizeof(X2ap_PLMN_Identity_t)); memset((void *)&broadcast_plmnIdentity_1, 0, sizeof(X2ap_PLMN_Identity_t)); memset((void *)&broadcast_plmnIdentity_2, 0, sizeof(X2ap_PLMN_Identity_t)); memset((void *)&broadcast_plmnIdentity_3, 0, sizeof(X2ap_PLMN_Identity_t)); //----globalENB_ID------ x2SetupResponse->globalENB_ID.eNB_ID.present = X2ap_ENB_ID_PR_macro_eNB_ID; MACRO_ENB_ID_TO_BIT_STRING(instance->eNB_id, &x2SetupResponse->globalENB_ID.eNB_ID.choice.macro_eNB_ID); MCC_MNC_TO_PLMNID(instance->mcc, instance->mnc, instance->mnc_digit_length, &x2SetupResponse->globalENB_ID.pLMN_Identity); X2AP_INFO("%d -> %02x%02x%02x\n", instance->eNB_id, x2SetupResponse->globalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[0], x2SetupResponse->globalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[1], x2SetupResponse->globalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[2]); //----served cells------ #warning update the value of the message served_cell->servedCellInfo.pCI = 6; served_cell->servedCellInfo.eUTRA_Mode_Info.present = X2ap_EUTRA_Mode_Info_PR_fDD; served_cell->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_EARFCN = 3350; served_cell->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_EARFCN = 3350; served_cell->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = 0; served_cell->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = 0; MCC_MNC_TO_PLMNID(instance->mcc,instance->mnc,instance->mnc_digit_length,&served_cell->servedCellInfo.cellId.pLMN_Identity); MCC_MNC_TO_PLMNID(instance->mcc, instance->mnc, instance->mnc_digit_length,&broadcast_plmnIdentity_1); MCC_MNC_TO_PLMNID(instance->mcc, instance->mnc, instance->mnc_digit_length,&broadcast_plmnIdentity_2); MCC_MNC_TO_PLMNID(instance->mcc, instance->mnc, instance->mnc_digit_length,&broadcast_plmnIdentity_3); ASN_SEQUENCE_ADD(&served_cell->servedCellInfo.broadcastPLMNs.list, &broadcast_plmnIdentity_1); ASN_SEQUENCE_ADD(&served_cell->servedCellInfo.broadcastPLMNs.list, &broadcast_plmnIdentity_2); ASN_SEQUENCE_ADD(&served_cell->servedCellInfo.broadcastPLMNs.list, &broadcast_plmnIdentity_3); ECI_TO_BIT_STRING(instance->eNB_id, &served_cell->servedCellInfo.cellId.eUTRANcellIdentifier); TAC_TO_OCTET_STRING(instance->tac, &served_cell->servedCellInfo.tAC); ASN_SEQUENCE_ADD(&x2SetupResponse->servedCells.list, served_cell); if (x2ap_eNB_encode_pdu(&message, &buffer, &len) < 0) { X2AP_ERROR("Failed to encode X2 setup request\n"); return -1; } eNB_association->state = X2AP_ENB_STATE_READY; MSC_LOG_TX_MESSAGE (MSC_X2AP_TARGET_ENB, MSC_X2AP_SRC_ENB, NULL, 0, "0 X2Setup/successfulOutcome assoc_id %u", eNB_association->assoc_id); /* * Non-UE signalling -> stream 0 */ x2ap_eNB_itti_send_sctp_data_req (instance->instance, eNB_association->assoc_id, buffer, len, 0); return ret; } int x2ap_eNB_set_cause (X2ap_Cause_t * cause_p, X2ap_Cause_PR cause_type, long cause_value); int x2ap_eNB_generate_x2_setup_failure ( uint32_t assoc_id, X2ap_Cause_PR cause_type, long cause_value, long time_to_wait){ uint8_t *buffer_p; uint32_t length; x2ap_message message; X2SetupFailure_IEs_t *x2_setup_failure_p; int ret = 0; memset (&message, 0, sizeof (x2ap_message)); x2_setup_failure_p = &message.msg.x2SetupFailure_IEs; message.procedureCode = X2ap_ProcedureCode_id_x2Setup; message.direction = X2AP_PDU_PR_unsuccessfulOutcome; x2ap_eNB_set_cause (&x2_setup_failure_p->cause, cause_type, cause_value); if (time_to_wait > -1) { x2_setup_failure_p->presenceMask |= X2SETUPFAILURE_IES_TIMETOWAIT_PRESENT; x2_setup_failure_p->timeToWait = time_to_wait; } if (x2ap_eNB_encode_pdu (&message, &buffer_p, &length) < 0) { X2AP_ERROR ("Failed to encode x2 setup failure\n"); return -1; } MSC_LOG_TX_MESSAGE (MSC_X2AP_SRC_ENB, MSC_X2AP_TARGET_ENB, NULL, 0, "0 X2Setup/unsuccessfulOutcome assoc_id %u cause %u value %u", assoc_id, cause_type, cause_value); x2ap_eNB_itti_send_sctp_data_req (/* instance? */ 0, assoc_id, buffer_p, length, 0); return ret; } int x2ap_eNB_set_cause (X2ap_Cause_t * cause_p, X2ap_Cause_PR cause_type, long cause_value) { DevAssert (cause_p != NULL); cause_p->present = cause_type; switch (cause_type) { case X2ap_Cause_PR_radioNetwork: cause_p->choice.misc = cause_value; break; case X2ap_Cause_PR_transport: cause_p->choice.transport = cause_value; break; case X2ap_Cause_PR_protocol: cause_p->choice.protocol = cause_value; break; case X2ap_Cause_PR_misc: cause_p->choice.misc = cause_value; break; default: return -1; } return 0; } int x2ap_eNB_generate_x2_handover_request(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_enb_data_p, int source_x2id) { /* TODO: set correct values in there */ x2ap_message message; uint8_t *buffer; uint32_t len; int ret = 0; DevAssert(instance_p != NULL); DevAssert(x2ap_enb_data_p != NULL); memset(&message, 0, sizeof(x2ap_message)); message.direction = X2AP_PDU_PR_initiatingMessage; message.procedureCode = X2ap_ProcedureCode_id_handoverPreparation; message.criticality = X2ap_Criticality_reject; message.msg.x2ap_HandoverRequest_IEs.old_eNB_UE_X2AP_ID = source_x2id; message.msg.x2ap_HandoverRequest_IEs.cause.present = X2ap_Cause_PR_radioNetwork; message.msg.x2ap_HandoverRequest_IEs.cause.choice.radioNetwork = X2ap_CauseRadioNetwork_handover_desirable_for_radio_reasons; MCC_MNC_TO_PLMNID(123, 456, 3, &message.msg.x2ap_HandoverRequest_IEs.targetCell_ID.pLMN_Identity); int eci1 = 79; ECI_TO_BIT_STRING(eci1, &message.msg.x2ap_HandoverRequest_IEs.targetCell_ID.eUTRANcellIdentifier); MCC_MNC_TO_PLMNID(456, 123, 3, &message.msg.x2ap_HandoverRequest_IEs.gummei_id.gU_Group_ID.pLMN_Identity); MMEGID_TO_OCTET_STRING(26, &message.msg.x2ap_HandoverRequest_IEs.gummei_id.gU_Group_ID.mME_Group_ID); MMEC_TO_OCTET_STRING(12, &message.msg.x2ap_HandoverRequest_IEs.gummei_id.mME_Code); message.msg.x2ap_HandoverRequest_IEs.uE_ContextInformation.mME_UE_S1AP_ID = 12; ENCRALG_TO_BIT_STRING(0,&message.msg.x2ap_HandoverRequest_IEs.uE_ContextInformation.uESecurityCapabilities.encryptionAlgorithms); INTPROTALG_TO_BIT_STRING(0,&message.msg.x2ap_HandoverRequest_IEs.uE_ContextInformation.uESecurityCapabilities.integrityProtectionAlgorithms); uint8_t KeNB_star[32] = { 0 }; // find UE context // use hack defined in x2ap_eNB.c in x2ap_eNB_handle_handover_req(...): if ((instance_p->instance < 0) || (instance_p->instance >= NB_eNB_INST)) { X2AP_ERROR("Failed to find RRC eNB instance %d\n", instance_p->instance); return -1; } eNB_RRC_INST* rrc_instance = &eNB_rrc_inst[instance_p->instance]; struct rrc_eNB_ue_context_s* rrc_eNB_ue_context = rrc_eNB_get_ue_context(rrc_instance, x2id_to_source_rnti[0]); if (!rrc_eNB_ue_context) { X2AP_ERROR("Failed to find RRC UE context RNTI %X\n", x2id_to_source_rnti[0]); return -1; } const Enb_properties_array_t *enb_properties = enb_config_get(); uint16_t pci = enb_properties->properties[instance_p->instance]->Nid_cell[0]; uint32_t earfcn_dl = (uint32_t)freq_to_arfcn10(enb_properties->properties[instance_p->instance]->eutra_band[0], enb_properties->properties[instance_p->instance]->downlink_frequency[0]); if (rrc_eNB_ue_context->ue_context.nh_ncc >= 0) { derive_keNB_star (rrc_eNB_ue_context->ue_context.nh, pci, earfcn_dl, false, KeNB_star); message.msg.x2ap_HandoverRequest_IEs.uE_ContextInformation.aS_SecurityInformation.nextHopChainingCount = rrc_eNB_ue_context->ue_context.nh_ncc; } else { // first HO derive_keNB_star (rrc_eNB_ue_context->ue_context.kenb, pci, earfcn_dl, false, KeNB_star); // LG: really 1 ? message.msg.x2ap_HandoverRequest_IEs.uE_ContextInformation.aS_SecurityInformation.nextHopChainingCount = 1; } KENB_STAR_TO_BIT_STRING(KeNB_star,&message.msg.x2ap_HandoverRequest_IEs.uE_ContextInformation.aS_SecurityInformation.key_eNodeB_star); UEAGMAXBITRTD_TO_ASN_PRIMITIVES(3L,&message.msg.x2ap_HandoverRequest_IEs.uE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateDownlink); UEAGMAXBITRTU_TO_ASN_PRIMITIVES(6L,&message.msg.x2ap_HandoverRequest_IEs.uE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateUplink); X2ap_E_RABs_ToBeSetup_Item_t *e_RABs_ToBeSetup_Item1 = calloc(1, sizeof(X2ap_E_RABs_ToBeSetup_Item_t)); X2ap_E_RABs_ToBeSetup_ListIEs_t *e_RABs_ToBeSetup_List1 = calloc(1, sizeof(X2ap_E_RABs_ToBeSetup_ListIEs_t)); int i; for (i=0;iue_context.setup_e_rabs;i++){ e_RABs_ToBeSetup_Item1->e_RAB_ID=rrc_eNB_ue_context->ue_context.e_rab[i].param.e_rab_id; e_RABs_ToBeSetup_Item1->e_RAB_Level_QoS_Parameters.qCI=rrc_eNB_ue_context->ue_context.e_rab[i].param.qos.qci; e_RABs_ToBeSetup_Item1->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel = rrc_eNB_ue_context->ue_context.e_rab[i].param.qos.allocation_retention_priority.priority_level ; e_RABs_ToBeSetup_Item1->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionCapability = rrc_eNB_ue_context->ue_context.e_rab[i].param.qos.allocation_retention_priority.pre_emp_capability ; e_RABs_ToBeSetup_Item1->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionVulnerability = rrc_eNB_ue_context->ue_context.e_rab[i].param.qos.allocation_retention_priority.pre_emp_vulnerability; e_RABs_ToBeSetup_Item1->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.iE_Extensions = NULL; e_RABs_ToBeSetup_Item1->uL_GTPtunnelEndpoint.transportLayerAddress.size= (uint8_t)(rrc_eNB_ue_context->ue_context.e_rab[i].param.sgw_addr.length/8); e_RABs_ToBeSetup_Item1->uL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = rrc_eNB_ue_context->ue_context.e_rab[i].param.sgw_addr.length%8; e_RABs_ToBeSetup_Item1->uL_GTPtunnelEndpoint.transportLayerAddress.buf = calloc(1,e_RABs_ToBeSetup_Item1->uL_GTPtunnelEndpoint.transportLayerAddress.size); memcpy (e_RABs_ToBeSetup_Item1->uL_GTPtunnelEndpoint.transportLayerAddress.buf, rrc_eNB_ue_context->ue_context.e_rab[i].param.sgw_addr.buffer, e_RABs_ToBeSetup_Item1->uL_GTPtunnelEndpoint.transportLayerAddress.size); //TRLA_TO_BIT_STRING(rrc_eNB_ue_context->ue_context.e_rab[i].param.sgw_addr.buffer, // &e_RABs_ToBeSetup_Item1->uL_GTPtunnelEndpoint.transportLayerAddress); // IPv4 INT32_TO_OCTET_STRING(rrc_eNB_ue_context->ue_context.e_rab[i].param.gtp_teid, &e_RABs_ToBeSetup_Item1->uL_GTPtunnelEndpoint.gTP_TEID); //GTP_TEID_TO_OCTET_STRING (rrc_eNB_ue_context->ue_context.e_rab[i].param.gtp_teid, // &e_RABs_ToBeSetup_Item1->uL_GTPtunnelEndpoint.gTP_TEID); ASN_SEQUENCE_ADD(e_RABs_ToBeSetup_List1, e_RABs_ToBeSetup_Item1); } x2ap_encode_x2ap_e_rabs_tobesetup_list(&message.msg.x2ap_HandoverRequest_IEs.uE_ContextInformation.e_RABs_ToBeSetup_List, e_RABs_ToBeSetup_List1); #if 0 char RRC[81] = { 0x0a,0x10,0x00,0x00,0x03,0x41,0x60,0x08,0xcf,0x50,0x4a,0x0e,0x07,0x00,0x8c,0xf5,0x04,0xa0,0xe0,0x03,0xc0,0x51,0xc2,0x28, 0xb8,0x56,0xd1,0x80,0x4a,0x00,0x00,0x08,0x18,0x02,0x20,0x42,0x08,0x00,0x80,0x60,0x00,0x20,0x00,0x00,0x03,0x82,0xca,0x04, 0x06,0x14,0x08,0x0f,0x59,0x95,0x64,0x80,0x00,0x02,0x0a,0x5a,0x00,0x20,0x00,0x08,0x04,0x01,0x2f,0x39,0x57,0x96,0xde,0xc0, 0x00,0x88,0xea,0x46,0x7d,0x10,0x00,0x03,0x40 }; #endif char RRC[] = { 0x0A,0x10,0x31,0xC5,0x20,0x00,0x05,0x00,0x10,0x40,0xC1,0xC9,0x85,0x8B,0xF8,0xDF,0xE2,0xFE,0x37,0xF8,0xBF,0x8D,0xFE,0x2F,0xE3,0x7F,0x8B,0xF8,0xDF,0xE2,0xFE,0x37,0xF7,0xF0,0xFF,0xE9,0x88,0x81,0x00,0x87,0x0C,0xA7,0x4A,0x92,0x20,0x20,0x58,0x00,0x00,0x00,0x00,0x00,0x15,0xD8,0x00,0x00,0x06,0x8B,0x02,0x00,0x02,0x90,0x21,0x59,0x70,0x00,0x00,0x72,0xA2,0x40,0x37,0xB0,0x11,0xFA,0x9C,0x0B,0x81,0x1F,0xA9,0xC0,0x83,0xEA,0x26,0xE0,0x25,0x75,0x38,0xA1,0xD8,0x84,0xF9,0x80,0x3E,0x55,0x8F,0xFD,0x15,0x35,0x86,0x1C,0x86,0xC8,0xA1,0x82,0x40,0xA1,0x35,0x00,0x00,0x00,0x24,0x10,0x92,0x80,0x02,0x00,0x00,0x10,0x2C,0x00,0x30,0x00,0x40,0xF6,0x07,0xCA,0xCB,0xB2,0x4C,0x00,0x6C,0x05,0x35,0x00,0x10,0x00,0x04,0x01,0x00,0xF7,0x52,0xAB,0xCA,0xF7,0x20,0x07,0x43,0x45,0xA0,0x1E,0xB8,0xE0, }; OCTET_STRING_fromBuf(&message.msg.x2ap_HandoverRequest_IEs.uE_ContextInformation.rRC_Context, (char*) RRC, sizeof(RRC)); X2ap_LastVisitedCell_Item_t *lastVisitedCell_Item1 = calloc(1, sizeof(X2ap_LastVisitedCell_Item_t)); lastVisitedCell_Item1->present = X2ap_LastVisitedCell_Item_PR_e_UTRAN_Cell; lastVisitedCell_Item1->choice.e_UTRAN_Cell.cellType.cell_Size=1; lastVisitedCell_Item1->choice.e_UTRAN_Cell.time_UE_StayedInCell=2; MCC_MNC_TO_PLMNID(987,765, 3, &lastVisitedCell_Item1->choice.e_UTRAN_Cell.global_Cell_ID.pLMN_Identity); int eci2 = 55; ECI_TO_BIT_STRING(eci2,&lastVisitedCell_Item1->choice.e_UTRAN_Cell.global_Cell_ID.eUTRANcellIdentifier); ASN_SEQUENCE_ADD(&message.msg.x2ap_HandoverRequest_IEs.uE_HistoryInformation.list,lastVisitedCell_Item1); if (x2ap_eNB_encode_pdu(&message, &buffer, &len) < 0) { X2AP_ERROR("Failed to encode X2 setup request\n"); abort(); return -1; } /* TODO: use correct stream, 1 for the moment */ x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_enb_data_p->assoc_id, buffer, len, 1); return ret; } int x2ap_eNB_generate_x2_handover_req_ack(x2ap_eNB_instance_t *instance, x2ap_eNB_data_t *x2ap_enb_data_p, int source_x2id, uint8_t *rrc_buffer, int rrc_buffer_size) { x2ap_message message; uint8_t *buffer; uint32_t len; int ret = 0; // Generating response memset (&message, 0, sizeof (x2ap_message)); X2ap_E_RABs_Admitted_ListIEs_t *e_RABs_Admitted_List1; X2ap_E_RABs_Admitted_Item_t *e_RABs_Admitted_Item1; e_RABs_Admitted_Item1 = calloc(1, sizeof(X2ap_E_RABs_Admitted_Item_t)); e_RABs_Admitted_List1 = calloc(1, sizeof(X2ap_E_RABs_Admitted_ListIEs_t)); asn1_xer_print = 1; asn_debug = 0; X2ap_ProcedureCode_t procedure = X2ap_ProcedureCode_id_handoverPreparation; X2ap_Criticality_t criticality = X2ap_Criticality_reject; X2AP_PDU_PR present; present = X2AP_PDU_PR_successfulOutcome; message.procedureCode = procedure; message.criticality= criticality; message.direction = present; #if 0 //data is in file RRC_Context_acknowledge.txt uint8_t RRC[63] = { 0x01,0xe9,0x00,0x90,0xa8,0x00,0x00,0x22,0x33,0xe9,0x42,0x80,0x02,0xf0,0x80,0x9e,0x20,0x23,0xc6,0x05,0x79,0x00,0xef,0x28, 0x21,0xe1,0x01,0x24,0x38,0x40,0x05,0x00,0x12,0x1c,0xa0,0x00,0x02,0x00,0x88,0x02,0x18,0x06,0x40,0x10,0xa0,0x2b,0x43,0x81, 0x1d,0xd9,0xc0,0x30,0x70,0x00,0xe0,0x21,0xc3,0x17,0x01,0x74,0x60,0x12,0x80 }; #endif message.msg.x2ap_HandoverRequestAcknowledge_IEs.old_eNB_UE_X2AP_ID = source_x2id; message.msg.x2ap_HandoverRequestAcknowledge_IEs.new_eNB_UE_X2AP_ID= 2001; e_RABs_Admitted_Item1->e_RAB_ID=12; e_RABs_Admitted_Item1->iE_Extensions = NULL; ASN_SEQUENCE_ADD(e_RABs_Admitted_List1, e_RABs_Admitted_Item1); memcpy(&message.msg.x2ap_HandoverRequestAcknowledge_IEs.e_RABs_Admitted_List, e_RABs_Admitted_List1, sizeof(X2ap_E_RABs_Admitted_ListIEs_t)); //OCTET_STRING_fromBuf(&message.msg.x2ap_HandoverRequestAcknowledge_IEs.targeteNBtoSource_eNBTransparentContainer, (char*) RRC, sizeof(RRC)); OCTET_STRING_fromBuf(&message.msg.x2ap_HandoverRequestAcknowledge_IEs.targeteNBtoSource_eNBTransparentContainer, (char*)rrc_buffer, rrc_buffer_size); if (x2ap_eNB_encode_pdu(&message, &buffer, &len) < 0) { X2AP_ERROR("Failed to encode X2 handover response\n"); abort(); return -1; } //eNB_association->state = X2AP_ENB_STATE_READY; /* TODO: use correct stream, 1 for the moment */ x2ap_eNB_itti_send_sctp_data_req(instance->instance, x2ap_enb_data_p->assoc_id, buffer, len, 1); return ret; }