X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=src%2FX2AP%2Fsgnb_addition_response.cc;fp=src%2FX2AP%2Fsgnb_addition_response.cc;h=d64f620b499aa513757a12f47329d117959db2db;hb=b9d7e9c232a4371ddfed51c58e5a57f87b057229;hp=0000000000000000000000000000000000000000;hpb=59f84608ec15c016958a6e0e0ddd813f376c0925;p=ric-app%2Fadmin.git diff --git a/src/X2AP/sgnb_addition_response.cc b/src/X2AP/sgnb_addition_response.cc new file mode 100644 index 0000000..d64f620 --- /dev/null +++ b/src/X2AP/sgnb_addition_response.cc @@ -0,0 +1,434 @@ +/* +================================================================================== + Copyright (c) 2018-2019 AT&T Intellectual Property. + + Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 + + 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. +================================================================================== +*/ +/* + * sgnb_addition_response.cc + * + * Created on: Aug 22, 2019 + * Author: sjana + */ + +#include + +sgnb_addition_response::sgnb_addition_response(void ) { + + + x2ap_pdu_obj = 0; + x2ap_pdu_obj = (X2AP_PDU_t * )calloc(1, sizeof(X2AP_PDU_t)); + assert(x2ap_pdu_obj != 0); + + successMsg = 0; + successMsg = (X2SuccessfulOutcome_t * )calloc(1, sizeof(X2SuccessfulOutcome_t)); + assert(successMsg != 0); + + unsuccessMsg = 0; + unsuccessMsg = (X2UnsuccessfulOutcome_t * )calloc(1, sizeof(X2UnsuccessfulOutcome_t)); + assert(unsuccessMsg != 0); + + IE_array = 0; + IE_array = (SgNBAdditionRequestAcknowledge_IEs_t *)calloc(NUM_SGNB_ADDITION_RESPONSE_ACKNOWLEDGE_IES, sizeof(SgNBAdditionRequestAcknowledge_IEs_t)); + assert(IE_array != 0); + + IE_reject_array = 0; + IE_reject_array = (SgNBAdditionRequestReject_IEs_t *)calloc(NUM_SGNB_ADDITION_RESPONSE_FAILURE_IES, sizeof(SgNBAdditionRequestReject_IEs_t)); + assert(IE_reject_array != 0); + + + erab_admit_array = 0; + erab_admit_array = (E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs_t * ) calloc(INITIAL_SIZE, sizeof(E_RABs_ToBeAdded_SgNBAddReq_ItemIEs_t)); + assert(erab_admit_array != 0); + erab_admit_array_size = INITIAL_SIZE; + + + erab_sgnb_present_array = 0; + erab_sgnb_present_array = (E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item_SgNBPDCPpresent_t *) calloc(INITIAL_SIZE, sizeof(E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item_SgNBPDCPpresent_t)); + assert(erab_sgnb_present_array != 0); + erab_sgnb_present_array_size = INITIAL_SIZE; + + erab_sgnb_notpresent_array = 0; + erab_sgnb_notpresent_array = (E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item_SgNBPDCPnotpresent_t *) calloc(INITIAL_SIZE, sizeof(E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item_SgNBPDCPnotpresent_t)); + assert(erab_sgnb_notpresent_array != 0); + erab_sgnb_notpresent_array_size = INITIAL_SIZE; + + SgNBAdditionRequestAcknowledge_t * sgnb_ack = &(successMsg->value.choice.SgNBAdditionRequestAcknowledge); + for(int i = 0; i < NUM_SGNB_ADDITION_RESPONSE_ACKNOWLEDGE_IES; i++){ + ASN_SEQUENCE_ADD(&(sgnb_ack->protocolIEs), &(IE_array[i])); + } + + + SgNBAdditionRequestReject_t * sgnb_reject = &(unsuccessMsg->value.choice.SgNBAdditionRequestReject); + for(int i = 0; i < NUM_SGNB_ADDITION_RESPONSE_FAILURE_IES; i++){ + ASN_SEQUENCE_ADD(&(sgnb_reject->protocolIEs), &(IE_reject_array[i])); + } + +} + +sgnb_addition_response::~sgnb_addition_response(void){ + + mdclog_write(MDCLOG_INFO, "Freeing X2AP SgNB Addition Response object memory"); + + E_RABs_Admitted_ToBeAdded_SgNBAddReqAckList_t * erabs_toadd_list = &(IE_array[3].value.choice.E_RABs_Admitted_ToBeAdded_SgNBAddReqAckList); + for(int i = 0; i < erabs_toadd_list->list.size; i++){ + erabs_toadd_list->list.array[i] = 0; + } + if (erabs_toadd_list->list.size > 0){ + free(erabs_toadd_list->list.array); + erabs_toadd_list->list.array = 0; + erabs_toadd_list->list.size = 0; + erabs_toadd_list->list.count= 0; + } + + free(erab_sgnb_present_array); + free(erab_sgnb_notpresent_array); + free(erab_admit_array); + + SgNBAdditionRequestAcknowledge_t *sgnb_ack = &(successMsg->value.choice.SgNBAdditionRequestAcknowledge); + for(int i = 0; i < sgnb_ack->protocolIEs.list.size; i++){ + sgnb_ack->protocolIEs.list.array[i] = 0; + } + + if (sgnb_ack->protocolIEs.list.size > 0){ + free(sgnb_ack->protocolIEs.list.array); + sgnb_ack->protocolIEs.list.array = 0; + sgnb_ack->protocolIEs.list.size = 0; + } + + SgNBAdditionRequestReject_t *sgnb_reject = &(unsuccessMsg->value.choice.SgNBAdditionRequestReject); + for(int i = 0; i < sgnb_reject->protocolIEs.list.size; i++){ + sgnb_reject->protocolIEs.list.array[i] = 0; + } + + if (sgnb_reject->protocolIEs.list.size > 0){ + free(sgnb_reject->protocolIEs.list.array); + sgnb_reject->protocolIEs.list.array = 0; + sgnb_reject->protocolIEs.list.size = 0; + } + + + free(IE_array); + free(IE_reject_array); + free(successMsg); + free(unsuccessMsg); + + x2ap_pdu_obj->choice.initiatingMessage = NULL; + x2ap_pdu_obj->present = X2AP_PDU_PR_NOTHING; + + ASN_STRUCT_FREE(asn_DEF_X2AP_PDU, x2ap_pdu_obj); + + mdclog_write(MDCLOG_INFO, "Freed X2AP SgNB Addition Response object memory"); +} + +bool sgnb_addition_response::set_fields(X2UnsuccessfulOutcome_t * unsuccessMsg, sgnb_addition_helper &sgnb_data){ + + unsigned ie_index = 0; + + if (unsuccessMsg == 0){ + error_string = "Invalid reference for X2AP Sgnb Addition Reject message in set_fields"; + return false; + } + SgNBAdditionRequestReject_IEs_t *ies_sgnb_add_reject; + + ie_index = 0; + ies_sgnb_add_reject= &IE_reject_array[ie_index]; + ies_sgnb_add_reject->criticality = Criticality_reject; + ies_sgnb_add_reject->id = ProtocolIE_ID_id_MeNB_UE_X2AP_ID; + ies_sgnb_add_reject->value.present = SgNBAdditionRequestReject_IEs__value_PR_UE_X2AP_ID; + ies_sgnb_add_reject->value.choice.UE_X2AP_ID = sgnb_data.menb_ue_x2ap_id; + + + ie_index = 1; + ies_sgnb_add_reject= &IE_reject_array[ie_index]; + ies_sgnb_add_reject->criticality = Criticality_reject; + ies_sgnb_add_reject->id = ProtocolIE_ID_id_SgNB_UE_X2AP_ID; + ies_sgnb_add_reject->value.present = SgNBAdditionRequestReject_IEs__value_PR_SgNB_UE_X2AP_ID; + ies_sgnb_add_reject->value.choice.SgNB_UE_X2AP_ID = sgnb_data.sgnb_ue_x2ap_id; + + + ie_index = 2; + ies_sgnb_add_reject= &IE_reject_array[ie_index]; + ies_sgnb_add_reject->criticality = Criticality_reject; + ies_sgnb_add_reject->id = ProtocolIE_ID_id_Cause; + ies_sgnb_add_reject->value.present = SgNBAdditionRequestReject_IEs__value_PR_Cause; + Cause_t *caus = &ies_sgnb_add_reject->value.choice.Cause; + + switch(sgnb_data.cause) + { + case Cause_PR_misc: //Misc + caus->present = Cause_PR_misc; + caus->choice.misc = sgnb_data.cause_desc; + break; + case Cause_PR_radioNetwork: //radio network + caus->present = Cause_PR_radioNetwork; + caus->choice.radioNetwork = sgnb_data.cause_desc; + break; + case Cause_PR_protocol : //protocol + caus->present = Cause_PR_protocol; + caus->choice.protocol = sgnb_data.cause_desc; + break; + case Cause_PR_transport: //transport + caus->present = Cause_PR_transport; + caus->choice.transport = sgnb_data.cause_desc; + break; + + default: + caus->present = Cause_PR_NOTHING; + break; + } + + return true; + +} + + +bool sgnb_addition_response::set_fields(X2SuccessfulOutcome_t * successMsg, sgnb_addition_helper &sgnb_data){ + + unsigned ie_index = 0; + + if (successMsg == 0){ + error_string = "Invalid reference for X2AP Sgnb Addition Acknowledge message in set_fields"; + return false; + } + + SgNBAdditionRequestAcknowledge_IEs_t *ies_sgnb_add_ack; + + ie_index = 0; + ies_sgnb_add_ack= &IE_array[ie_index]; + ies_sgnb_add_ack->criticality = Criticality_reject; + ies_sgnb_add_ack->id = ProtocolIE_ID_id_MeNB_UE_X2AP_ID; + ies_sgnb_add_ack->value.present = SgNBAdditionRequestAcknowledge_IEs__value_PR_UE_X2AP_ID; + ies_sgnb_add_ack->value.choice.UE_X2AP_ID = sgnb_data.menb_ue_x2ap_id; + + + ie_index = 1; + ies_sgnb_add_ack= &IE_array[ie_index]; + ies_sgnb_add_ack->criticality = Criticality_reject; + ies_sgnb_add_ack->id = ProtocolIE_ID_id_SgNB_UE_X2AP_ID; + ies_sgnb_add_ack->value.present = SgNBAdditionRequestAcknowledge_IEs__value_PR_SgNB_UE_X2AP_ID; + ies_sgnb_add_ack->value.choice.SgNB_UE_X2AP_ID = sgnb_data.sgnb_ue_x2ap_id; + + ie_index = 2; + ies_sgnb_add_ack= &IE_array[ie_index]; + ies_sgnb_add_ack->criticality = Criticality_reject; + ies_sgnb_add_ack->id = ProtocolIE_ID_id_SgNBtoMeNBContainer; + ies_sgnb_add_ack->value.present = SgNBAdditionRequestAcknowledge_IEs__value_PR_SgNBtoMeNBContainer; + SgNBtoMeNBContainer_t *container = &ies_sgnb_add_ack->value.choice.SgNBtoMeNBContainer; + container->buf = sgnb_data.menb_sgnb_container; + container->size = sgnb_data.menb_sgnb_container_size; + + ie_index = 3; + ies_sgnb_add_ack = &IE_array[ie_index]; + ies_sgnb_add_ack->criticality = Criticality_reject; + ies_sgnb_add_ack->id = ProtocolIE_ID_id_E_RABs_Admitted_ToBeAdded_SgNBAddReqAckList; + ies_sgnb_add_ack->value.present = SgNBAdditionRequestAcknowledge_IEs__value_PR_E_RABs_Admitted_ToBeAdded_SgNBAddReqAckList; + E_RABs_Admitted_ToBeAdded_SgNBAddReqAckList_t * erabs_toadd_list = &(ies_sgnb_add_ack->value.choice.E_RABs_Admitted_ToBeAdded_SgNBAddReqAckList); + + + int lcount = sgnb_data.erab_list.size(); + //std::cout <<"Adding " << lcount << " erabs in response" << std::endl; + + //resize empty array in constructor + if (lcount >= erab_admit_array_size){ + erab_admit_array_size = 2*lcount; + + E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs_t * new_ref = 0; + new_ref = (E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs_t *)realloc(erab_admit_array, erab_admit_array_size * sizeof(E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item_t)); + assert(new_ref != 0); + erab_admit_array = new_ref; + + erab_sgnb_present_array_size = 2 * lcount; + E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item_SgNBPDCPpresent_t * new_present = 0; + new_present = (E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item_SgNBPDCPpresent_t *)realloc(erab_sgnb_present_array, erab_sgnb_present_array_size * sizeof(E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item_SgNBPDCPpresent_t )); + assert(new_present != 0); + erab_sgnb_present_array = new_present; + + erab_sgnb_notpresent_array_size = 2 * lcount; + E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item_SgNBPDCPnotpresent_t * new_notpresent = 0; + new_notpresent = (E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item_SgNBPDCPnotpresent_t *)realloc(erab_sgnb_notpresent_array, erab_sgnb_notpresent_array_size * sizeof(E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item_SgNBPDCPnotpresent_t )); + assert(new_notpresent != 0); + erab_sgnb_notpresent_array = new_notpresent; + } + + std::vector * ref_erab_input = &(sgnb_data.erab_list); + erabs_toadd_list->list.count = 0; + + int sgnb_present_index = 0; + int sgnb_notpresent_index = 0; + + for(unsigned int i = 0; i < lcount; i++){ + + erab_admit_array[i].id = ProtocolIE_ID_id_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item ; + erab_admit_array[i].criticality = Criticality_ignore; + erab_admit_array[i].value.present = E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs__value_PR_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item; + + E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item_t * erab_item = &(erab_admit_array[i].value.choice.E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item); + + erab_item->e_RAB_ID = (*ref_erab_input)[i].erab_id; + erab_item->en_DC_ResourceConfiguration.pDCPatSgNB = (*ref_erab_input)[i].pdcp_at_sgnb; + erab_item->en_DC_ResourceConfiguration.mCGresources = (*ref_erab_input)[i].mcg_resources; + erab_item->en_DC_ResourceConfiguration.sCGresources = (*ref_erab_input)[i].scg_resources; + + + erab_item->resource_configuration.present = (E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item__resource_configuration_PR)(*ref_erab_input)[i].sgnb_pdcp_present; + if( erab_item->resource_configuration.present == E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item__resource_configuration_PR_sgNBPDCPpresent){ + + erab_sgnb_present_array[sgnb_present_index].s1_DL_GTPtunnelEndpoint.transportLayerAddress.buf = (*ref_erab_input)[i].sgnb_item.transport_layer_addr; + erab_sgnb_present_array[sgnb_present_index].s1_DL_GTPtunnelEndpoint.transportLayerAddress.size = (*ref_erab_input)[i].sgnb_item.transport_layer_addr_size; + erab_sgnb_present_array[sgnb_present_index].s1_DL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = (*ref_erab_input)[i].sgnb_item.transport_layer_addr_unused; + + erab_sgnb_present_array[sgnb_present_index].s1_DL_GTPtunnelEndpoint.gTP_TEID.buf = (*ref_erab_input)[i].sgnb_item.gtp_tei; + erab_sgnb_present_array[sgnb_present_index].s1_DL_GTPtunnelEndpoint.gTP_TEID.size = (*ref_erab_input)[i].sgnb_item.gtp_tei_size; + + /* Force all optional parameters that are not set to NULL */ + erab_sgnb_present_array[sgnb_present_index].sgNB_UL_GTP_TEIDatPDCP = NULL; + + /* validate constraints ..*/ + int ret_constr; + ret_constr = asn_check_constraints(&asn_DEF_GTP_TEI, &erab_sgnb_present_array[sgnb_present_index].s1_DL_GTPtunnelEndpoint.gTP_TEID, errbuf, &errbuf_len); + if(ret_constr){ + error_string.assign(&errbuf[0], errbuf_len); + error_string = "Error in constraints for GTP TEID.. Reason = " + error_string; + return false; + } + + ret_constr = asn_check_constraints(&asn_DEF_GTPtunnelEndpoint, &erab_sgnb_present_array[sgnb_present_index].s1_DL_GTPtunnelEndpoint, errbuf, &errbuf_len); + if(ret_constr){ + error_string.assign(&errbuf[0], errbuf_len); + error_string = "Error in constraints for GTP tunnel endpoint .. Reason = " + error_string; + return false; + } + + ret_constr = asn_check_constraints(&asn_DEF_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item_SgNBPDCPpresent, &erab_sgnb_present_array[sgnb_present_index], errbuf, &errbuf_len); + if(ret_constr){ + error_string.assign(&errbuf[0], errbuf_len); + error_string = "Error in constraints for E_RABS_ToBeAdded_SgNBAddReq_SgNBPDCPpresent.. Reason = " + error_string; + return false; + } + + erab_item->resource_configuration.choice.sgNBPDCPpresent = &erab_sgnb_present_array[sgnb_present_index]; + sgnb_present_index ++; + + } + else if (erab_item->resource_configuration.present == E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item__resource_configuration_PR_sgNBPDCPnotpresent){ + + erab_sgnb_notpresent_array[sgnb_notpresent_index].sgNB_DL_GTP_TEIDatSCG.transportLayerAddress.buf = (*ref_erab_input)[i].sgnb_item.transport_layer_addr; + erab_sgnb_notpresent_array[sgnb_notpresent_index].sgNB_DL_GTP_TEIDatSCG.transportLayerAddress.size = (*ref_erab_input)[i].sgnb_item.transport_layer_addr_size; + erab_sgnb_notpresent_array[sgnb_notpresent_index].sgNB_DL_GTP_TEIDatSCG.transportLayerAddress.bits_unused = (*ref_erab_input)[i].sgnb_item.transport_layer_addr_unused; + + erab_sgnb_notpresent_array[sgnb_notpresent_index].sgNB_DL_GTP_TEIDatSCG.gTP_TEID.buf = (unsigned char *)(*ref_erab_input)[i].sgnb_item.gtp_tei; + erab_sgnb_notpresent_array[sgnb_notpresent_index].sgNB_DL_GTP_TEIDatSCG.gTP_TEID.size = (*ref_erab_input)[i].sgnb_item.gtp_tei_size; + + erab_sgnb_notpresent_array[sgnb_notpresent_index].secondary_sgNB_DL_GTP_TEIDatSCG = NULL; + + /* validate constraints ..*/ + int ret_constr; + ret_constr = asn_check_constraints(&asn_DEF_GTPtunnelEndpoint, &erab_sgnb_notpresent_array[sgnb_notpresent_index].sgNB_DL_GTP_TEIDatSCG, errbuf, &errbuf_len); + if(ret_constr){ + error_string.assign(&errbuf[0], errbuf_len); + error_string = "Error in constraints for GTP tunnel endpoint .. Reason = " + error_string; + return false; + } + + + ret_constr = asn_check_constraints(&asn_DEF_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item_SgNBPDCPnotpresent, &erab_sgnb_notpresent_array[sgnb_notpresent_index], errbuf, &errbuf_len); + if(ret_constr){ + error_string.assign(&errbuf[0], errbuf_len); + error_string = "Error in constraints for E_RABS_ToBeAdded_SgNBAddReq_SgNBPDCPnotpresent.. Reason = " + error_string; + return false; + } + + erab_item->resource_configuration.choice.sgNBPDCPnotpresent = &erab_sgnb_notpresent_array[sgnb_notpresent_index]; ; + sgnb_notpresent_index ++; + } + else { + std::cerr <<"Could not find a pdcp present or not present flag. not adding erab item .." << std::endl; + continue; + } + + // check constraint + int ret_constr = asn_check_constraints(&asn_DEF_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs, &erab_admit_array[i], errbuf, &errbuf_len); + if(ret_constr){ + error_string.assign(&errbuf[0], errbuf_len); + error_string = "Error in constraints for E_RABS_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs.. Reason = " + error_string; + return false; + } + + ASN_SEQUENCE_ADD(erabs_toadd_list, &erab_admit_array[i]); + } + + return true; +} + +bool sgnb_addition_response::encode_sgnb_addition_response(unsigned char* data_buf, size_t *data_size, sgnb_addition_helper &sgnb_data, bool sgnb_response) +{ + + bool res; + if(sgnb_response == true){ + + x2ap_pdu_obj->present = X2AP_PDU_PR_successfulOutcome; + x2ap_pdu_obj->choice.successfulOutcome = successMsg; + + successMsg->procedureCode = ProcedureCode_id_sgNBAdditionPreparation; + successMsg->criticality = Criticality_ignore; + successMsg->value.present = X2SuccessfulOutcome__value_PR_SgNBAdditionRequestAcknowledge; + + res = set_fields(successMsg, sgnb_data); + + } else { + + x2ap_pdu_obj->present = X2AP_PDU_PR_unsuccessfulOutcome; + x2ap_pdu_obj->choice.unsuccessfulOutcome = unsuccessMsg; + + + unsuccessMsg->procedureCode = ProcedureCode_id_sgNBAdditionPreparation; + unsuccessMsg->criticality = Criticality_ignore; + unsuccessMsg->value.present = X2UnsuccessfulOutcome__value_PR_SgNBAdditionRequestReject; + + res = set_fields(unsuccessMsg, sgnb_data); + } + + if (!res){ + return false; + } + int ret_constr = asn_check_constraints(&asn_DEF_X2AP_PDU, x2ap_pdu_obj, errbuf, &errbuf_len); + if(ret_constr){ + error_string.assign(&errbuf[0], errbuf_len); + error_string = "Error encoding X2AP Sgnb Addition Response message. Reason = " + error_string; + return false; + } + + //xer_fprint(stdout, &asn_DEF_X2AP_PDU, x2ap_pdu_obj); + + asn_enc_rval_t retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_X2AP_PDU, x2ap_pdu_obj, data_buf, *data_size); + if(retval.encoded == -1){ + error_string.assign(strerror(errno)); + return false; + } + + else { + if(*data_size < retval.encoded){ + std::stringstream ss; + ss <<"Error encoding SgNB Addition Request Response. Reason = encoded pdu size " << retval.encoded << " exceeds buffer size " << *data_size << std::endl; + error_string = ss.str(); + return false; + } + } + + *data_size = retval.encoded; + return true; +} + +