From b416061f5a237cbabbe09c6d81fe92df9e33fd72 Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani <velumani@eurecom.fr> Date: Fri, 15 Apr 2022 18:46:27 +0530 Subject: [PATCH] Setup request and response messages --- openair2/E1AP/e1ap.c | 231 ++++++++++++++++++++++++++++++++++-- openair2/E1AP/e1ap_common.c | 68 +++++++++++ openair2/E1AP/e1ap_common.h | 50 ++++++++ 3 files changed, 340 insertions(+), 9 deletions(-) create mode 100644 openair2/E1AP/e1ap_common.c create mode 100644 openair2/E1AP/e1ap_common.h diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index b49f4d4ca1b..bdc0f288821 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -117,44 +117,252 @@ int e1ap_send_ERROR_INDICATION(instance_t instance, E1AP_ErrorIndication_t *Erro */ int e1apCUUP_send_SETUP_REQUEST(instance_t instance, E1AP_Reset_t *Reset) { - AssertFatal(false,"Not implemented yet\n"); + E1AP_E1AP_PDU_t pdu = {0}; + /* Create */ + /* 0. pdu Type */ + pdu.present = E1AP_E1AP_PDU_PR_initiatingMessage; + asn1cCalloc(pdu.choice.initiatingMessage, initMsg); + initMsg->procedureCode = E1AP_ProcedureCode_id_gNB_CU_UP_E1Setup; + initMsg->criticality = E1AP_Criticality_reject; + initMsg->present = E1AP_InitiatingMessage__value_PR_GNB_CU_UP_E1SetupRequest; + E1AP_GNB_CU_UP_E1SetupRequest_t *e1SetupUP = &initMsg->value.choice.GNB_CU_UP_E1SetupRequest; + /* mandatory */ + /* c1. Transaction ID (integer value) */ + asn1cSequenceAdd(e1SetupUP->protocolIEs.list, E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ieC1); + ieC1->id = E1AP_ProtocolIE_ID_id_TransactionID; + ieC1->criticality = E1AP_Criticality_reject; + ieC1->value.present = E1AP_GNB_CU_UP_E1SetupRequestIEs__value_PR_TransactionID; + ieC1->value.choice.TransactionID = E1AP_get_next_transaction_identifier(); + /* mandatory */ + /* c2. GNB_CU_ID (integer value) */ + asn1cSequenceAdd(e1SetupUP->protocolIEs.list, E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ieC2); + ieC2->id = E1AP_ProtocolIE_ID_id_gNB_CU_UP_ID; + ieC2->criticality = E1AP_Criticality_reject; + ieC2->value.present = E1AP_GNB_CU_UP_E1SetupRequestIEs__value_PR_GNB_CU_UP_ID; + asn_int642INTEGER(&ieC2->value.choice.GNB_CU_UP_ID, 0); + /* mandatory */ + /* c4. CN Support */ + asn1cSequenceAdd(e1SetupUP->protocolIEs.list, E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ieC4); + iec4->id = E1AP_ProtocolIE_ID_id_CNSupport; + ieC4->criticality = E1AP_Criticality_reject; + iec4->value.present = E1AP_GNB_CU_UP_E1SetupRequestIEs__value_PR_CNSupport; + iec4->value.choice.CNSupport = E1AP_CNSupport_c_5gc; + + /* mandatory */ + /* c5. Supported PLMNs */ + asn1cSequenceAdd(e1SetupUP->protocolIEs.list, E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ieC5); + iec5->id = E1AP_ProtocolIE_ID_id_SupportedPLMNs; + iec5->criticality = E1AP_Criticality_reject; + iec5->value.present = E1AP_GNB_CU_UP_E1SetupRequestIEs__value_PR_SupportedPLMNs_List; + + int numSupportedPLMNs = 1; + + for (int i=0; i < numSupportedPLMNs; i++) { + asn1cSequenceAdd(iec5->value.choice.SupportedPLMNs_List.list, E1AP_SupportedPLMNs_Item_t, supportedPLMN); + /* 5.1 PLMN Identity */ + OCTET_STRING_fromBuf(&supportedPLMN->pLMN_Identity, "OAI", strlen("OAI")); + } + + e1ap_encode_send(0, instance, pdu, 0, __func__); } int e1apCUCP_send_SETUP_RESPONSE(instance_t instance) { - AssertFatal(false,"Not implemented yet\n"); + E1AP_E1AP_PDU_t pdu = {0}; + /* Create */ + /* 0. pdu Type */ + pdu.present = E1AP_E1AP_PDU_PR_successfulOutcome; + asn1cCalloc(pdu.choice.successfulOutcome, initMsg); + initMsg->procedureCode = E1AP_ProcedureCode_id_gNB_CU_UP_E1Setup; + initMsg->criticality = E1AP_Criticality_reject; + initMsg->value.present = E1AP_SuccessfulOutcome__value_PR_GNB_CU_UP_E1SetupResponse; + E1AP_GNB_CU_UP_E1SetupResponse_t *out = &pdu.choice.successfulOutcome->value.choice.GNB_CU_UP_E1SetupResponse; + /* mandatory */ + /* c1. Transaction ID (integer value) */ + asn1cSequenceAdd(out->protocolIEs.list, E1AP_GNB_CU_UP_E1SetupResponseIEs, ieC1); + ieC1->id = E1AP_ProtocolIE_ID_id_TransactionID; + ieC1->criticality = E1AP_Criticality_reject; + ieC1->value.present = E1AP_GNB_CU_UP_E1SetupResponseIEs__value_PR_TransactionID; + ieC1->value.choice.TransactionID = //get this from stored transaction IDs in CU + + e1ap_encode_send(0, instance, pdu, 0, __func__); } int e1apCUCP_send_SETUP_FAILURE() { - AssertFatal(false,"Not implemented yet\n"); + E1AP_E1AP_PDU_t pdu = {0}; + /* Create */ + /* 0. pdu Type */ + pdu.present = E1AP_E1AP_PDU_PR_unsuccessfulOutcome; + asn1cCalloc(pdu.choice.unsuccessfulOutcome, initMsg); + initMsg->procedureCode = E1AP_ProcedureCode_id_gNB_CU_UP_E1Setup; + initMsg->criticality = E1AP_Criticality_reject; + initMsg->value.present = E1AP_UnsuccessfulOutcome__value_PR_GNB_CU_UP_E1SetupFailure; + E1AP_GNB_CU_UP_E1SetupFailure_t *out = &pdu.choice.successfulOutcome->value.choice.GNB_CU_UP_E1SetupFailure; + /* mandatory */ + /* c1. Transaction ID (integer value) */ + asn1cSequenceAdd(out->protocolIEs.list, E1AP_GNB_CU_UP_E1SetupFailureIEs, ieC1); + ieC1->id = E1AP_ProtocolIE_ID_id_TransactionID; + ieC1->criticality = E1AP_Criticality_reject; + ieC1->value.present = E1AP_GNB_CU_UP_E1SetupResponseIEs__value_PR_TransactionID; + ieC1->value.choice.TransactionID = //get this from stored transaction IDs in CU + /* mandatory */ + /* c2. cause (integer value) */ + asn1cSequenceAdd(out->protocolIEs.list, E1AP_GNB_CU_UP_E1SetupFailureIEs, ieC2); + ieC2->id = E1AP_ProtocolIE_ID_id_Cause; + ieC2->criticality = E1AP_Criticality_ignore; + ieC2->value.present = E1AP_GNB_CU_UP_E1SetupFailureIEs__value_PR_Cause; + ieC2->value.choice.Cause.present = E1AP_Cause_PR_radioNetwork; //choose this accordingly + ieC2->value.choice.Cause.choice.ratioNetwork = E1AP_CauseRadioNetwork_unspecified; + + e1ap_encode_send(0, instance, pdu, 0, __func__); } int e1apCUCP_handle_SETUP_REQUEST(instance_t instance, uint32_t assoc_id, uint32_t stream, E1AP_E1AP_PDU_t *pdu) { - AssertFatal(false,"Not implemented yet\n"); + + E1AP_GNB_CU_UP_E1SetupRequestIEs_t *ie; + DevAssert(pdu != NULL); + E1AP_GNB_CU_UP_E1SetupRequest_t *in = pdu->choice.initiatingMessage->value.choice.GNB_CU_UP_E1SetupRequest; + + e1ap_setup_req_t *req = &getCxt(CPtype, instance)->setupReq; + + /* assoc_id */ + req->assoc_id = assoc_id; + + /* transac_id */ + F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ie, in, + E1AP_ProtocolIE_ID_id_TransactionID, true); + asn_INTEGER2ulong(&ie->value.choice.TransactionID, &req->transac_id); + LOG_D(E1AP, "gNB CU UP E1 setup request transaction ID: %d\n", req->transac_id); + + /* gNB CU UP ID */ + F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ie, in, + E1AP_ProtocolIE_ID_id_gNB_CU_UP_ID, true); + asn_INTEGER2ulong(&ie->value.choice.GNB_CU_UP_ID, &req->gNB_cu_up_id); + LOG_D(E1AP, "gNB CU UP ID: %d\n", req->gNB_cu_up_id); + + /* CN Support */ + F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ie, in, + E1AP_ProtocolIE_ID_id_CNSupport, true); + asn_INTEGER2ulong(&ie->value.choice.GNB_CU_UP_ID, &req->cn_support); + LOG_D(E1AP, "E1ap CN support: %d\n", req->cn_support); + + /* Supported PLMNs */ + F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ie, in, + E1AP_ProtocolIE_ID_id_SupportedPLMNs, true); + req->supported_plmns = ie->value.choice.SupportedPLMNs_List.list.count; + LOG_D(E1AP, "Number of supported PLMNs: %d\n", req->supported_plmns); + + for (int i=0; i < req->supported_plmns; i++) { + E1AP_SupportedPLMNs_Item_t *supported_plmn_item = (E1AP_SupportedPLMNs_Item_t *)(ie->value.choice.SupportedPLMNs_List.list.array[i]); + + /* PLMN Identity */ + OCTET_STRING_TO_INT16(supported_plmn_item.pLMN_Identity, req->plmns[i].id); + LOG_D(E1AP, "PLMN %d ID: %d\n", i, req->plmns[i].id); + } + + /* Create ITTI message and send to queue */ + } int e1apCUUP_handle_SETUP_RESPONSE(instance_t instance, uint32_t assoc_id, uint32_t stream, E1AP_E1AP_PDU_t *pdu) { - AssertFatal(false,"Not implemented yet\n"); + LOG_D(E1AP, "%s\n", __func__); + AssertFatal(pdu->present == E1AP_E1AP_PDU_PR_successfulOutcome, + "pdu->present != E1AP_E1AP_PDU_PR_successfulOutcome\n"); + AssertFatal(pdu->choice.successfulOutcome->procedureCode == E1AP_ProcedureCode_id_gNB_CU_UP_E1Setup, + "pdu->choice.successfulOutcome->procedureCode != E1AP_ProcedureCode_id_gNB_CU_UP_E1Setup\n"); + AssertFatal(pdu->choice.successfulOutcome->criticality == E1AP_Criticality_reject, + "pdu->choice.successfulOutcome->criticality != E1AP_Criticality_reject\n"); + AssertFatal(pdu->choice.successfulOutcome->value.present == E1AP_SuccessfulOutcome__value_PR_GNB_CU_UP_E1SetupResponse, + "pdu->choice.successfulOutcome->value.present != E1AP_SuccessfulOutcome__value_PR_GNB_CU_UP_E1SetupResponse\n"); + + E1AP_GNB_CU_UP_E1SetupResponse_t *in = &pdu.choice.successfulOutcome->value.choice.GNB_CU_UP_E1SetupResponse; + E1AP_GNB_CU_UP_E1SetupResponseIEs *ie; + + /* transac_id */ + int transaction_id; + F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupResponseIEs, ie, in, + E1AP_ProtocolIE_ID_id_TransactionID, true); + asn_INTEGER2ulong(&ie->value.choice.TransactionID, &transaction_id); + LOG_D(E1AP, "gNB CU UP E1 setup response transaction ID: %d\n", transaction_id); + + /* do the required processing */ + } int e1apCUUP_handle_SETUP_FAILURE(instance_t instance, uint32_t assoc_id, uint32_t stream, E1AP_E1AP_PDU_t *pdu) { - AssertFatal(false,"Not implemented yet\n"); + E1AP_GNB_CU_UP_E1SetupFailureIEs_t *ie; + DevAssert(pdu != NULL); + E1AP_GNB_CU_UP_E1SetupFailure_t *in = pdu->choice.unsuccessfulOutcome->value.choice.GNB_CU_UP_E1SetupFailure; + /* Transaction ID */ + F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupFailureIEs_t, ie, in, + E1AP_ProtocolIE_ID_id_TransactionID, true); + /* Cause */ + F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupFailureIEs_t, ie, in, + E1AP_ProtocolIE_ID_id_Cause, true); + + return 0; } /* E1 configuration update: can be sent in both ways, to be refined */ -int e1apCUUP_send_gNB_DU_CONFIGURATION_UPDATE(instance_t instance) { - AssertFatal(false,"Not implemented yet\n"); +int e1apCUUP_send_CONFIGURATION_UPDATE(instance_t instance) { + E1AP_E1AP_PDU_t pdu = {0}; + /* Create */ + /* 0. pdu Type */ + pdu.present = E1AP_E1AP_PDU_PR_initiatingMessage; + asn1cCalloc(pdu.choice.initiatingMessage, msg); + msg->procedureCode = E1AP_ProcedureCode_id_gNB_CU_UP_ConfigurationUpdate; + msg->criticality = E1AP_Criticality_reject; + msg->value.present = E1AP_InitiatingMessage__value_PR_GNB_CU_UP_ConfigurationUpdate; + E1AP_GNB_CU_UP_ConfigurationUpdate_t *out = &pdu.choice.successfulOutcome->value.choice.GNB_CU_UP_ConfigurationUpdate; + /* mandatory */ + /* c1. Transaction ID (integer value) */ + asn1cSequenceAdd(out->protocolIEs.list, E1AP_GNB_CU_UP_ConfigurationUpdateIEs_t, ieC1); + ieC1->id = E1AP_ProtocolIE_ID_id_TransactionID; + ieC1->criticality = E1AP_Criticality_reject; + ieC1->value.present = E1AP_GNB_CU_UP_ConfigurationUpdateIEs__value_PR_TransactionID; + ieC1->value.choice.TransactionID = //get this from stored transaction IDs in CU + /* mandatory */ + /* c2. Supported PLMNs */ + asn1cSequenceAdd(out->protocolIEs.list, E1AP_GNB_CU_UP_ConfigurationUpdateIEs_t, ieC2); + iec2->id = E1AP_ProtocolIE_ID_id_SupportedPLMNs; + iec2->criticality = E1AP_Criticality_reject; + iec2->value.present = E1AP_GNB_CU_UP_ConfigurationUpdateIEs__value_PR_SupportedPLMNs_List; + + int numSupportedPLMNs = 1; + + for (int i=0; i < numSupportedPLMNs; i++) { + asn1cSequenceAdd(iec2->value.choice.SupportedPLMNs_List.list, E1AP_SupportedPLMNs_Item_t, supportedPLMN); + /* 5.1 PLMN Identity */ + OCTET_STRING_fromBuf(&supportedPLMN->pLMN_Identity, "OAI", strlen("OAI")); + } + + /* mandatory */ + /* c3. TNLA to remove list */ + asn1cSequenceAdd(out->protocolIEs.list, E1AP_GNB_CU_UP_ConfigurationUpdateIEs_t, ieC3); + iec3->id = E1AP_ProtocolIE_ID_id_GNB_CU_UP_TNLA_To_Remove_List; + iec3->criticality = E1AP_Criticality_reject; + iec3->value.present = E1AP_GNB_CU_UP_ConfigurationUpdateIEs__value_PR_GNB_CU_UP_TNLA_To_Remove_List; + + int numTNLAtoRemoveList = 1; + + for (int i=0; i < numTNLAtoRemoveList; i++) { + asn1cSequenceAdd(iec2->value.choice.GNB_CU_UP_TNLA_To_Remove_List.list, E1AP_GNB_CU_UP_TNLA_To_Remove_Item_t, TNLAtoRemove); + TNLAtoRemove->tNLAssociationTransportLayerAddress.present = E1AP_CP_TNL_Information_PR_endpoint_IP_Address; + TNLAtoRemove->tNLAssociationTransportLayerAddress.choice.endpoint_IP_Address = // TODO: include the ip + } + + e1ap_encode_send(0, instance, pdu, 0, __func__); } int e1apCUCP_send_gNB_DU_CONFIGURATION_FAILURE(instance_t instance) { @@ -165,10 +373,15 @@ int e1apCUCP_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance) { AssertFatal(false,"Not implemented yet\n"); } -int e1apCUCP_handle_gNB_DU_CONFIGURATION_UPDATE(instance_t instance, +int e1apCUCP_handle_CONFIGURATION_UPDATE(instance_t instance, uint32_t assoc_id, uint32_t stream, E1AP_E1AP_PDU_t *pdu) { + + E1AP_GNB_CU_UP_E1SetupRequestIEs_t *ie; + DevAssert(pdu != NULL); + E1AP_GNB_CU_UP_E1SetupRequest_t *in = pdu->choice.initiatingMessage->value.choice.GNB_CU_UP_E1SetupRequest; + AssertFatal(false,"Not implemented yet\n"); } diff --git a/openair2/E1AP/e1ap_common.c b/openair2/E1AP/e1ap_common.c new file mode 100644 index 00000000000..91110702ed6 --- /dev/null +++ b/openair2/E1AP/e1ap_common.c @@ -0,0 +1,68 @@ +/* + * 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 + * + * Author and copyright: Laurent Thomas, open-cells.com + * + * 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 <time.h> +#include <stdlib.h> +#include "e1ap_common.h" + +static e1ap_upcp_inst_t *e1_cp_inst[NUMBER_OF_gNB_MAX] = {0}; +static e1ap_upcp_inst_t *e1_up_inst[NUMBER_OF_gNB_MAX] = {0}; + +e1ap_upcp_inst_t *getCxt(E1_t type, instance_t instance) { + AssertFatal( instance < sizeofArray(e1_cp_inst), "instance exceeds limit\n"); + return type ? e1_up_inst[instance] : e1_cp_inst[instance]; +} + +E1AP_TransactionID_t transacID[MAX_NUM_TRANSAC_IDS] = {0}; +srand(time(NULL)); + +bool check_transac_id(E1AP_TransactionID_t id, int *freeIdx) { + + bool isFreeIdxSet = false; + for (int i=0; i < MAX_NUM_TRANSAC_IDS; i++) { + if (id == transacID[i]) + return false; + else if (!isFreeIdxSet && (transacID[i] == 0)) { + *freeIdx = i; + isFreeIdxSet = true; + } + } + + return true; +} + +E1AP_TransactionID_t E1AP_get_next_transaction_identifier() { + E1AP_TransactionID_t genTransacId; + bool isTransacIdValid = false; + int freeIdx; + + while (!isTransacIdValid) { + genTransacId = rand(); + isTransacIdValid = check_transac_Id(genTransacId, &freeIdx); + } + + AssertFatal(freeIdx < MAX_NUM_TRANSAC_IDS, "Free Index exceeds array length\n"); + transacID[freeIdx] = genTransacId; + return genTransacId; +} + diff --git a/openair2/E1AP/e1ap_common.h b/openair2/E1AP/e1ap_common.h new file mode 100644 index 00000000000..7f60d65144c --- /dev/null +++ b/openair2/E1AP/e1ap_common.h @@ -0,0 +1,50 @@ +/* + * 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 + * + * Author and copyright: Laurent Thomas, open-cells.com + * + * 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 "E1AP_TransactionID.h" + +#define MAX_NUM_TRANSAC_IDS 8 +#define E1AP_MAX_NUM_PLMNS + +typedef struct PLMN_ID_s { + int id; +} PLMN_ID_t; + +typedef struct e1ap_setup_req_s { + uint64_t gNB_cu_up_id; + char *gNB_cu_up_name; + uint64_t transac_id; + uint64_t cn_support; + int supported_plmns; + PLMN_ID_t plmns[E1AP_MAX_NUM_PLMNS]; +} e1ap_setup_req_t; + +typedef struct e1ap_upcp_inst_s { + e1ap_setup_req_t setupReq; + uint32_t assoc_id; +} e1ap_upcp_inst_t; + +typedef enum { + CPtype = 0, + UPtype +} E1_t; -- GitLab