/* ================================================================================== 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. ================================================================================== */ /* * 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 #define IE_SIZE ((int)128) template class E2APIndication{ public: E2APIndication(); E2APIndication(unsigned char *, size_t *, bool&); ~E2APIndication(void); 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; public: IndicationIEs(void) : ricRequestorID(0), ranFunctionID(0), ricActionID(0),ricIndicationSN(0), ricIndicationType(0){}; void* get_ricIndicationMessage(){return this->ricIndicationMessage; }; void* get_ricIndicationHeader(){return this->ricIndicationHeader; }; void* get_ricCallProcessId(){return this->ricCallProcessId;}; size_t get_ricIndicationMessageSize(){return this->ricIndicationMessage_size; }; size_t get_ricIndicationHeaderSize(){return this->ricIndicationHeader_size; }; size_t get_ricCallProcessIdSize(){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_ricIndicationSN(){return this->ricIndicationSN;}; 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){ 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; return *this;} }; 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; unsigned int ricIndicationIEs_Count; std::string _error_string; char _errbuf[128]; size_t _errbuf_len = 128; bool setfields( InitiatingMessage_t *); }; template E2APIndication::E2APIndication(){ ricIndicationIEs_Count = 8; 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(ricIndicationIEs_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(); }; template E2APIndication::E2APIndication(unsigned char *buf, size_t *size, bool &status){ e2ap_pdu_obj = 0; initMsg = 0; IE_array = 0; _indicationIEs = std::make_unique(); status = this->decode(buf, size); } // 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->ricRequestorID; ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index])); ie_index = 1; 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->ranFunctionID; ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index])); ie_index = 2; 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->ricActionID; ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index])); ie_index = 3; 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->ricIndicationSN; ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index])); ie_index = 4; 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->ricIndicationType; ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index])); ie_index = 5; 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 = _indicationIEs->ricIndicationHeader; richeader_ie->size = _indicationIEs->ricIndicationHeader_size; ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index])); ie_index = 6; 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 = _indicationIEs->ricIndicationMessage; ricmsg_ie->size = _indicationIEs->ricIndicationMessage_size; ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index])); // optional call process id .. if (_indicationIEs->call_process_id_size > 0){ ie_index = 7; 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 = _indicationIEs->call_process_id; riccallprocessid_ie->size = _indicationIEs->call_process_id_size; ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index])); } return true; }; #endif /* SRC_XAPP_ASN_E2AP_E2AP_INDICATION_HPP_ */