/* ================================================================================== Copyright (c) 2019-2020 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. ================================================================================== */ /* * e2ap_indication.hpp * * Created on: Sep 18, 2020 * Author: Shraboni Jana */ /*-- ************************************************************** -- -- RIC Indication Elementary Procedure -- -- ************************************************************** -- ************************************************************** -- -- RIC INDICATION -- -- ************************************************************** RICindication ::= SEQUENCE { protocolIEs ProtocolIE-Container {{RICindication-IEs}}, ... } RICindication-IEs E2AP-PROTOCOL-IES ::= { { ID id-RICrequestID CRITICALITY reject TYPE RICrequestID PRESENCE mandatory }| { ID id-RANfunctionID CRITICALITY reject TYPE RANfunctionID PRESENCE mandatory }| { ID id-RICactionID CRITICALITY reject TYPE RICactionID PRESENCE mandatory }| { ID id-RICindicationSN CRITICALITY reject TYPE RICindicationSN PRESENCE optional }| { ID id-RICindicationType CRITICALITY reject TYPE RICindicationType PRESENCE mandatory }| { ID id-RICindicationHeader CRITICALITY reject TYPE RICindicationHeader PRESENCE mandatory }| { ID id-RICindicationMessage CRITICALITY reject TYPE RICindicationMessage PRESENCE mandatory }| { ID id-RICcallProcessID CRITICALITY reject TYPE RICcallProcessID PRESENCE optional }, ... }*/ #ifndef SRC_XAPP_ASN_E2AP_E2AP_INDICATION_HPP_ #define SRC_XAPP_ASN_E2AP_E2AP_INDICATION_HPP_ #include #include #include #include #include #include #include #include #include #include #include "e2ap_consts.hpp" template class E2APIndication{ public: class IndicationIEs{ private: long int ricRequestorID, ranFunctionID, ricActionID, ricIndicationSN, ricIndicationType; size_t ricIndicationHeader_size = IE_SIZE; unsigned char ricIndicationHeader[IE_SIZE]; size_t ricIndicationMessage_size = IE_SIZE; unsigned char ricIndicationMessage[IE_SIZE]; unsigned char ricCallProcessId[IE_SIZE]; size_t ricCallProcessId_size = IE_SIZE; bool is_callProcessID, is_ricIndicationSN; public: IndicationIEs(void) : ricRequestorID(0), ranFunctionID(0), ricActionID(0),ricIndicationSN(0), ricIndicationType(0),is_callProcessID(false),is_ricIndicationSN(false){}; void* get_ricIndicationMessage(){return this->ricIndicationMessage; }; void* get_ricIndicationHeader(){return this->ricIndicationHeader; }; void* get_ricCallProcessId(){return this->ricCallProcessId;}; size_t get_ricIndicationMessage_size(){return this->ricIndicationMessage_size; }; size_t get_ricIndicationHeader_size(){return this->ricIndicationHeader_size; }; size_t get_ricCallProcessId_size(){return this->ricCallProcessId_size;}; long int get_ricRequestorID(){return this->ricRequestorID;}; long int get_ranFunctionID(){return this->ranFunctionID;}; long int get_ricActionID(){return this->ricActionID;}; long int get_ricIndicationType(){return this->ricIndicationType;} long int get_ricIndicationSN(){return this->ricIndicationSN;}; bool get_is_ricIndicationSN(){return this->is_ricIndicationSN;}; bool get_is_callProcessID(){return this->is_callProcessID;}; IndicationIEs& set_ricIndicationHeader(E2SMIndicationHeader e2smObj){ bool res = e2smObj.encode(&(this->ricIndicationHeader)[0],&this->ricIndicationHeader_size); if(!res){ mdclog_write(MDCLOG_ERR, "Failed to encode: %s","RIC Indication Header"); mdclog_write(MDCLOG_ERR, "Error during encode: %s",e2smObj.get_error()); } else { mdclog_write(MDCLOG_INFO, "Successfully encoded: %s","RIC Indication Header"); } return *this; } IndicationIEs& set_ricIndicationMessage(E2SMIndicationMessage e2smObj){ bool res = e2smObj.encode(&(this->ricIndicationMessage)[0],&this->ricIndicationMessage_size); if(!res){ mdclog_write(MDCLOG_ERR, "Failed to encode: %s","RIC Indication Message"); mdclog_write(MDCLOG_ERR, "Error during encode: %s",e2smObj.get_error()); } else { mdclog_write(MDCLOG_INFO, "Successfully encoded: %s","RIC Indication Message"); } return *this; } IndicationIEs& set_ricIndicationHeader(unsigned char* header, size_t header_size){ memcpy(ricIndicationHeader,header,header_size); ricIndicationHeader_size = header_size; return *this; } IndicationIEs& set_ricIndicationMessage(unsigned char* message, size_t message_size){ memcpy(ricIndicationHeader,message,message_size); ricIndicationMessage_size = message_size; return *this;} IndicationIEs& set_ricCallProcessID(unsigned char* callproc, size_t callproc_size){ is_callProcessID = true; memcpy(ricCallProcessId, callproc, callproc_size); ricCallProcessId_size = callproc_size; return *this; } IndicationIEs& set_ricRequestorID(long int reqID){this->ricRequestorID = reqID; return *this;} IndicationIEs& set_ranFunctionID(long int funcID){this->ranFunctionID = funcID; return *this;} IndicationIEs& set_ricActionID(long int actID){ this->ricActionID = actID; return *this;} IndicationIEs& set_ricIndicationType(long int typ){ this->ricIndicationType = typ; return *this;} IndicationIEs& set_ricIndicationSN(long int sn){ this->ricIndicationSN = sn; is_ricIndicationSN=true; return *this;} }; E2APIndication(IndicationIEs&); E2APIndication(unsigned char *, size_t *); ~E2APIndication(void); IndicationIEs getIndicationIEs(){ return *_indicationIEs.get(); } std::string get_error(void) const {return _error_string ; }; bool encode(unsigned char *buf, size_t *size); bool decode(unsigned char *buf, size_t *size); private: E2AP_PDU_t * e2ap_pdu_obj; InitiatingMessage_t *initMsg; RICindication_IEs_t *IE_array; std::unique_ptr _indicationIEs; std::string _error_string; char _errbuf[128]; size_t _errbuf_len = 128; bool setfields( InitiatingMessage_t *); }; template E2APIndication::E2APIndication(IndicationIEs& ieObj){ e2ap_pdu_obj = 0; e2ap_pdu_obj = (E2AP_PDU_t * )calloc(1, sizeof(E2AP_PDU_t)); assert(e2ap_pdu_obj != 0); initMsg = 0; initMsg = (InitiatingMessage_t * )calloc(1, sizeof(InitiatingMessage_t)); assert(initMsg != 0); IE_array = 0; IE_array = (RICindication_IEs_t *)calloc(RIC_INDICATION_IES_COUNT, sizeof(RICindication_IEs_t)); assert(IE_array != 0); e2ap_pdu_obj->present = E2AP_PDU_PR_initiatingMessage; e2ap_pdu_obj->choice.initiatingMessage = initMsg; _indicationIEs = std::make_unique(); *_indicationIEs = ieObj; }; template E2APIndication::E2APIndication(unsigned char *buf, size_t *size){ e2ap_pdu_obj = 0; initMsg = 0; IE_array = 0; _indicationIEs = std::make_unique(); bool status = this->decode(buf, size); if(!status) throw "E2AP Indication Decode Failed: "+this->get_error(); } // Clear assigned protocolIE list from RIC indication IE container template E2APIndication::~E2APIndication(void){ mdclog_write(MDCLOG_DEBUG, "Freeing E2AP Indication object memory"); RICindication_t *ricIndication = &(initMsg->value.choice.RICindication); for(int i = 0; i < ricIndication->protocolIEs.list.size; i++){ ricIndication->protocolIEs.list.array[i] = 0; } if (ricIndication->protocolIEs.list.size > 0){ free(ricIndication->protocolIEs.list.array); ricIndication->protocolIEs.list.array = 0; ricIndication->protocolIEs.list.count = 0; ricIndication->protocolIEs.list.size = 0; } free(IE_array); ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, e2ap_pdu_obj); mdclog_write(MDCLOG_DEBUG, "Freed E2AP Indication object memory"); } template bool E2APIndication::decode(unsigned char *buf, size_t *size) { asn_dec_rval_t dec_res = asn_decode(0,ATS_ALIGNED_BASIC_PER, &asn_DEF_E2AP_PDU, (void**)&(e2ap_pdu_obj), buf, *size); if(dec_res.code != RC_OK){ mdclog_write(MDCLOG_ERR, "Failed to decode: %s","RIC Indication Message"); return false; } else { mdclog_write(MDCLOG_INFO, "Successfully decoded: %s","RIC Indication Message"); } xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2ap_pdu_obj); initMsg = e2ap_pdu_obj->choice.initiatingMessage; //write the decoding code. if (initMsg == 0){ _error_string = "Invalid reference for E2AP Indication message in get_fields"; return false; } for(int edx = 0; edx < initMsg->value.choice.RICindication.protocolIEs.list.count; edx++) { RICindication_IEs_t *memb_ptr = initMsg->value.choice.RICindication.protocolIEs.list.array[edx]; switch(memb_ptr->id) { case (ProtocolIE_ID_id_RICindicationHeader): _indicationIEs->set_ricIndicationHeader(memb_ptr->value.choice.RICindicationHeader.buf, memb_ptr->value.choice.RICindicationHeader.size); break; case (ProtocolIE_ID_id_RICindicationMessage): _indicationIEs->set_ricIndicationMessage(memb_ptr->value.choice.RICindicationMessage.buf, memb_ptr->value.choice.RICindicationMessage.size); break; case (ProtocolIE_ID_id_RICrequestID): _indicationIEs->set_ricRequestorID(memb_ptr->value.choice.RICrequestID.ricRequestorID); break; case (ProtocolIE_ID_id_RANfunctionID): _indicationIEs->set_ranFunctionID(memb_ptr->value.choice.RANfunctionID); break; case (ProtocolIE_ID_id_RICindicationSN): _indicationIEs->set_ricIndicationSN(memb_ptr->value.choice.RICindicationSN); break; case (ProtocolIE_ID_id_RICindicationType): _indicationIEs->set_ricIndicationType(memb_ptr->value.choice.RICindicationType); break; case (ProtocolIE_ID_id_RICactionID): _indicationIEs->set_ricActionID(memb_ptr->value.choice.RICactionID); break; case (ProtocolIE_ID_id_RICcallProcessID): _indicationIEs->set_ricCallProcessID(memb_ptr->value.choice.RICcallProcessID.buf,memb_ptr->value.choice.RICcallProcessID.size); break; default: break; } } return true; } template bool E2APIndication::encode(unsigned char *buf, size_t *size){ initMsg->procedureCode = ProcedureCode_id_RICindication; initMsg->criticality = Criticality_ignore; initMsg->value.present = InitiatingMessage__value_PR_RICindication; bool res; asn_enc_rval_t retval; res = setfields(initMsg); if (!res){ return false; } int ret_constr = asn_check_constraints(&asn_DEF_E2AP_PDU, e2ap_pdu_obj, _errbuf, &_errbuf_len); if(ret_constr){ _error_string.assign(&_errbuf[0], _errbuf_len); _error_string = "Error encoding E2AP Indication message. Reason = " + _error_string; return false; } xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2ap_pdu_obj); retval = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2AP_PDU, e2ap_pdu_obj, buf, *size); if(retval.encoded == -1){ _error_string.assign(strerror(errno)); return false; } else { if(*size < retval.encoded){ std::stringstream ss; ss <<"Error encoding E2AP Indication . Reason = encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl; _error_string = ss.str(); return false; } } *size = retval.encoded; return true; } template bool E2APIndication::setfields(InitiatingMessage_t *initMsg){ unsigned int ie_index; if (initMsg == 0){ _error_string = "Invalid reference for E2AP Indication message in set_fields"; return false; } RICindication_t * ric_indication = &(initMsg->value.choice.RICindication); ric_indication->protocolIEs.list.count = 0; ie_index = 0; RICindication_IEs_t *ies_ricreq = &IE_array[ie_index]; ies_ricreq->criticality = Criticality_reject; ies_ricreq->id = ProtocolIE_ID_id_RICrequestID; ies_ricreq->value.present = RICindication_IEs__value_PR_RICrequestID; RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID; ricrequest_ie->ricRequestorID = _indicationIEs->get_ricRequestorID(); ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index])); ie_index++; RICindication_IEs_t *ies_ranfunc = &IE_array[ie_index]; ies_ranfunc->criticality = Criticality_reject; ies_ranfunc->id = ProtocolIE_ID_id_RANfunctionID; ies_ranfunc->value.present = RICindication_IEs__value_PR_RANfunctionID; RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID; *ranfunction_ie = _indicationIEs->get_ranFunctionID(); ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index])); ie_index++; RICindication_IEs_t *ies_actid = &IE_array[ie_index]; ies_actid->criticality = Criticality_reject; ies_actid->id = ProtocolIE_ID_id_RICactionID; ies_actid->value.present = RICindication_IEs__value_PR_RICactionID; RICactionID_t *ricaction_ie = &ies_actid->value.choice.RICactionID; *ricaction_ie = _indicationIEs->get_ricActionID(); ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index])); if(_indicationIEs->get_is_ricIndicationSN()) { ie_index++; RICindication_IEs_t *ies_ricsn = &IE_array[ie_index]; ies_ricsn->criticality = Criticality_reject; ies_ricsn->id = ProtocolIE_ID_id_RICindicationSN; ies_ricsn->value.present = RICindication_IEs__value_PR_RICindicationSN; RICindicationSN_t *ricsn_ie = &ies_ricsn->value.choice.RICindicationSN; *ricsn_ie = _indicationIEs->get_ricIndicationSN(); ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index])); } ie_index++; RICindication_IEs_t *ies_indtyp = &IE_array[ie_index]; ies_indtyp->criticality = Criticality_reject; ies_indtyp->id = ProtocolIE_ID_id_RICindicationType; ies_indtyp->value.present = RICindication_IEs__value_PR_RICindicationType; RICindicationType_t *rictype_ie = &ies_indtyp->value.choice.RICindicationType; *rictype_ie = _indicationIEs->get_ricIndicationType(); ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index])); ie_index++; RICindication_IEs_t *ies_richead = &IE_array[ie_index]; ies_richead->criticality = Criticality_reject; ies_richead->id = ProtocolIE_ID_id_RICindicationHeader; ies_richead->value.present = RICindication_IEs__value_PR_RICindicationHeader; RICindicationHeader_t *richeader_ie = &ies_richead->value.choice.RICindicationHeader; richeader_ie->buf = (uint8_t*)_indicationIEs->get_ricIndicationHeader(); richeader_ie->size = _indicationIEs->get_ricIndicationHeader_size(); ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index])); ie_index++; RICindication_IEs_t *ies_indmsg = &IE_array[ie_index]; ies_indmsg->criticality = Criticality_reject; ies_indmsg->id = ProtocolIE_ID_id_RICindicationMessage; ies_indmsg->value.present = RICindication_IEs__value_PR_RICindicationMessage; RICindicationMessage_t *ricmsg_ie = &ies_indmsg->value.choice.RICindicationMessage; ricmsg_ie->buf = (uint8_t*)_indicationIEs->get_ricIndicationMessage(); ricmsg_ie->size = _indicationIEs->get_ricIndicationMessage_size(); ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index])); // optional call process id .. if (_indicationIEs->get_is_callProcessID()){ ie_index++; RICindication_IEs_t *ies_ind_callprocessid = &IE_array[ie_index]; ies_ind_callprocessid->criticality = Criticality_reject; ies_ind_callprocessid->id = ProtocolIE_ID_id_RICcallProcessID; ies_ind_callprocessid->value.present = RICindication_IEs__value_PR_RICcallProcessID; RICcallProcessID_t *riccallprocessid_ie = &ies_ind_callprocessid->value.choice.RICcallProcessID; riccallprocessid_ie->buf = (uint8_t*)_indicationIEs->get_ricCallProcessId(); riccallprocessid_ie->size = _indicationIEs->get_ricCallProcessId_size(); ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index])); } return true; }; #endif /* SRC_XAPP_ASN_E2AP_E2AP_INDICATION_HPP_ */