xapp-bs-connector --> xapp-sm-connector

This commit is contained in:
Leonardo Bonati
2021-12-22 13:33:15 -05:00
parent 6210e621ba
commit 185e97c221
427 changed files with 13 additions and 13 deletions

View File

@@ -0,0 +1,266 @@
/*
==================================================================================
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.
==================================================================================
*/
/*
* ric_control_request.c
*
* Created on: Jul 11, 2019
* Author: sjana, Ashwin Sridharan
*/
#include "e2ap_control.hpp"
// Set up memory allocations for each IE for encoding
// We are responsible for memory management for each IE for encoding
// Hence destructor should clear out memory
// When decoding, we rely on asn1c macro (ASN_STRUCT_FREE to be called
// for releasing memory by external calling function)
ric_control_request::ric_control_request(void){
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 = (RICcontrolRequest_IEs_t *)calloc(NUM_CONTROL_REQUEST_IES, sizeof(RICcontrolRequest_IEs_t));
assert(IE_array != 0);
e2ap_pdu_obj->present = E2AP_PDU_PR_initiatingMessage;
e2ap_pdu_obj->choice.initiatingMessage = initMsg;
};
// Clear assigned protocolIE list from RIC control_request IE container
ric_control_request::~ric_control_request(void){
mdclog_write(MDCLOG_DEBUG, "Freeing E2AP Control Request object memory");
RICcontrolRequest_t *ricControl_Request = &(initMsg->value.choice.RICcontrolRequest);
for(int i = 0; i < ricControl_Request->protocolIEs.list.size; i++){
ricControl_Request->protocolIEs.list.array[i] = 0;
}
if (ricControl_Request->protocolIEs.list.size > 0){
free(ricControl_Request->protocolIEs.list.array);
ricControl_Request->protocolIEs.list.size = 0;
ricControl_Request->protocolIEs.list.count = 0;
}
free(IE_array);
free(initMsg);
e2ap_pdu_obj->choice.initiatingMessage = 0;
ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, e2ap_pdu_obj);
mdclog_write(MDCLOG_DEBUG, "Freed E2AP Control Request object mempory");
}
bool ric_control_request::encode_e2ap_control_request(unsigned char *buf, size_t *size, ric_control_helper & dinput){
initMsg->procedureCode = ProcedureCode_id_RICcontrol;
initMsg->criticality = Criticality_ignore;
initMsg->value.present = InitiatingMessage__value_PR_RICcontrolRequest;
bool res;
res = set_fields(initMsg, dinput);
if (!res){
return false;
}
int ret_constr = asn_check_constraints(&asn_DEF_E2AP_PDU, (void *) e2ap_pdu_obj, errbuf, &errbuf_len);
if(ret_constr){
error_string.assign(errbuf, errbuf_len);
error_string = "Constraints failed for encoding control . Reason = " + error_string;
return false;
}
//xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2ap_pdu_obj);
asn_enc_rval_t 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 event trigger definition. Reason = encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
error_string = ss.str();
return false;
}
}
*size = retval.encoded;
return true;
}
bool ric_control_request::set_fields(InitiatingMessage_t *initMsg, ric_control_helper &dinput){
unsigned int ie_index;
if (initMsg == 0){
error_string = "Invalid reference for E2AP Control_Request message in set_fields";
return false;
}
RICcontrolRequest_t * ric_control_request = &(initMsg->value.choice.RICcontrolRequest);
ric_control_request->protocolIEs.list.count = 0; // reset
// for(i = 0; i < NUM_CONTROL_REQUEST_IES;i++){
// memset(&(IE_array[i]), 0, sizeof(RICcontrolRequest_IEs_t));
// }
// Mandatory IE
ie_index = 0;
RICcontrolRequest_IEs_t *ies_ricreq = &IE_array[ie_index];
ies_ricreq->criticality = Criticality_reject;
ies_ricreq->id = ProtocolIE_ID_id_RICrequestID;
ies_ricreq->value.present = RICcontrolRequest_IEs__value_PR_RICrequestID;
RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
ricrequest_ie->ricRequestorID = dinput.req_id;
//ricrequest_ie->ricRequestSequenceNumber = dinput.req_seq_no;
ASN_SEQUENCE_ADD(&(ric_control_request->protocolIEs), &(IE_array[ie_index]));
// Mandatory IE
ie_index = 1;
RICcontrolRequest_IEs_t *ies_ranfunc = &IE_array[ie_index];
ies_ranfunc->criticality = Criticality_reject;
ies_ranfunc->id = ProtocolIE_ID_id_RANfunctionID;
ies_ranfunc->value.present = RICcontrolRequest_IEs__value_PR_RANfunctionID;
RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
*ranfunction_ie = dinput.func_id;
ASN_SEQUENCE_ADD(&(ric_control_request->protocolIEs), &(IE_array[ie_index]));
// Mandatory IE
ie_index = 2;
RICcontrolRequest_IEs_t *ies_richead = &IE_array[ie_index];
ies_richead->criticality = Criticality_reject;
ies_richead->id = ProtocolIE_ID_id_RICcontrolHeader;
ies_richead->value.present = RICcontrolRequest_IEs__value_PR_RICcontrolHeader;
RICcontrolHeader_t *richeader_ie = &ies_richead->value.choice.RICcontrolHeader;
richeader_ie->buf = dinput.control_header;
richeader_ie->size = dinput.control_header_size;
ASN_SEQUENCE_ADD(&(ric_control_request->protocolIEs), &(IE_array[ie_index]));
// Mandatory IE
ie_index = 3;
RICcontrolRequest_IEs_t *ies_indmsg = &IE_array[ie_index];
ies_indmsg->criticality = Criticality_reject;
ies_indmsg->id = ProtocolIE_ID_id_RICcontrolMessage;
ies_indmsg->value.present = RICcontrolRequest_IEs__value_PR_RICcontrolMessage;
RICcontrolMessage_t *ricmsg_ie = &ies_indmsg->value.choice.RICcontrolMessage;
ricmsg_ie->buf = dinput.control_msg;
ricmsg_ie->size = dinput.control_msg_size;
ASN_SEQUENCE_ADD(&(ric_control_request->protocolIEs), &(IE_array[ie_index]));
// Optional IE
ie_index = 4;
if (dinput.control_ack >= 0){
RICcontrolRequest_IEs_t *ies_indtyp = &IE_array[ie_index];
ies_indtyp->criticality = Criticality_reject;
ies_indtyp->id = ProtocolIE_ID_id_RICcontrolAckRequest;
ies_indtyp->value.present = RICcontrolRequest_IEs__value_PR_RICcontrolAckRequest;
RICcontrolAckRequest_t *ricackreq_ie = &ies_indtyp->value.choice.RICcontrolAckRequest;
*ricackreq_ie = dinput.control_ack;
ASN_SEQUENCE_ADD(&(ric_control_request->protocolIEs), &(IE_array[ie_index]));
}
// Optional IE
ie_index = 5;
if(dinput.call_process_id_size > 0){
RICcontrolRequest_IEs_t *ies_callprocid = &IE_array[ie_index];
ies_callprocid->criticality = Criticality_reject;
ies_callprocid->id = ProtocolIE_ID_id_RICcallProcessID;
ies_callprocid->value.present = RICcontrolRequest_IEs__value_PR_RICcallProcessID;
RICcallProcessID_t *riccallprocessid_ie = &ies_callprocid->value.choice.RICcallProcessID;
riccallprocessid_ie->buf = dinput.call_process_id;
riccallprocessid_ie->size = dinput.call_process_id_size;
ASN_SEQUENCE_ADD(&(ric_control_request->protocolIEs), &(IE_array[ie_index]));
}
return true;
};
bool ric_control_request:: get_fields(InitiatingMessage_t * init_msg, ric_control_helper &dout)
{
if (init_msg == 0){
error_string = "Invalid reference for E2AP Control_Request message in get_fields";
return false;
}
for(int edx = 0; edx < init_msg->value.choice.RICcontrolRequest.protocolIEs.list.count; edx++) {
RICcontrolRequest_IEs_t *memb_ptr = init_msg->value.choice.RICcontrolRequest.protocolIEs.list.array[edx];
switch(memb_ptr->id)
{
case (ProtocolIE_ID_id_RICcontrolHeader):
dout.control_header = memb_ptr->value.choice.RICcontrolHeader.buf;
dout.control_header_size = memb_ptr->value.choice.RICcontrolHeader.size;
break;
case (ProtocolIE_ID_id_RICcontrolMessage):
dout.control_msg = memb_ptr->value.choice.RICcontrolMessage.buf;
dout.control_msg_size = memb_ptr->value.choice.RICcontrolMessage.size;
break;
case (ProtocolIE_ID_id_RICcallProcessID):
dout.call_process_id = memb_ptr->value.choice.RICcallProcessID.buf;
dout.call_process_id_size = memb_ptr->value.choice.RICcallProcessID.size;
break;
case (ProtocolIE_ID_id_RICrequestID):
dout.req_id = memb_ptr->value.choice.RICrequestID.ricRequestorID;
//dout.req_seq_no = memb_ptr->value.choice.RICrequestID.ricRequestSequenceNumber;
break;
case (ProtocolIE_ID_id_RANfunctionID):
dout.func_id = memb_ptr->value.choice.RANfunctionID;
break;
case (ProtocolIE_ID_id_RICcontrolAckRequest):
dout.control_ack = memb_ptr->value.choice.RICcontrolAckRequest;
break;
default:
break;
}
}
return true;
}
InitiatingMessage_t * ric_control_request::get_message(void) {
return initMsg;
}

View File

@@ -0,0 +1,66 @@
/*
==================================================================================
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.
==================================================================================
*/
/*
* ric_indication.h
*
* Created on: Jul 11, 2019
* Author: sjana, Ashwin Sridharan
*/
#ifndef E2AP_RIC_CONTROL_REQUEST_H_
#define E2AP_RIC_CONTROL_REQUEST_H_
#include <iostream>
#include <errno.h>
#include <mdclog/mdclog.h>
#include <sstream>
#include <E2AP-PDU.h>
#include <InitiatingMessage.h>
#include <RICcontrolRequest.h>
#include <ProtocolIE-Field.h>
#include "e2ap_control_helper.hpp"
#define NUM_CONTROL_REQUEST_IES 6
class ric_control_request{
public:
ric_control_request(void);
~ric_control_request(void);
bool encode_e2ap_control_request(unsigned char *, size_t *, ric_control_helper &);
InitiatingMessage_t * get_message (void) ;
bool set_fields(InitiatingMessage_t *, ric_control_helper &);
bool get_fields(InitiatingMessage_t *, ric_control_helper &);
std::string get_error(void) const {return error_string ; };
private:
E2AP_PDU_t * e2ap_pdu_obj;
InitiatingMessage_t *initMsg;
RICcontrolRequest_IEs_t *IE_array;
std::string error_string;
char errbuf[128];
size_t errbuf_len = 128;
};
#endif /* E2AP_RIC_CONTROL_REQUEST_H_ */

View File

@@ -0,0 +1,50 @@
/*
==================================================================================
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.
==================================================================================
*/
/*
* ric_indication.h
*
* Created on: Jul 11, 2019
* Author: sjana, Ashwin Sridharan
*/
#ifndef CONTROL_HELPER_H
#define CONTROL_HELPER_H
// control and indication helper objects are very similar and can be merged into one
// currently leaving them as two distnict entities till final design becomes clear
typedef struct ric_control_helper ric_control_helper;
struct ric_control_helper{
ric_control_helper(void):req_id(1), req_seq_no(1), func_id(0), action_id(1), control_ack(-1), cause(0), sub_cause(0), control_status(1), control_msg(0), control_msg_size(0), control_header(0), control_header_size(0), call_process_id(0), call_process_id_size(0){};
long int req_id, req_seq_no, func_id, action_id, control_ack, cause, sub_cause, control_status;
unsigned char* control_msg;
size_t control_msg_size;
unsigned char* control_header;
size_t control_header_size;
unsigned char *call_process_id;
size_t call_process_id_size;
};
#endif

View File

@@ -0,0 +1,415 @@
/*
==================================================================================
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.
==================================================================================
*/
/*
* ric_control_response.c
*
* Created on: Jul 11, 2019
* Author: sjana, Ashwin Sridharan
*/
#include "e2ap_control_response.hpp"
// Set up the initiating message and also allocate protocolIEs in container
// Note : this bypasses requirement to use ASN_SEQUENCE_ADD. We can directly
// assign pointers to the array in ProtocolIE. However, this also leaves us on the
// hook to manually clear the memory
ric_control_response::ric_control_response(void){
e2ap_pdu_obj = 0;
e2ap_pdu_obj = (E2AP_PDU_t * )calloc(1, sizeof(E2AP_PDU_t));
assert(e2ap_pdu_obj != 0);
successMsg = 0;
successMsg = (SuccessfulOutcome_t * )calloc(1, sizeof(SuccessfulOutcome_t));
assert(successMsg != 0);
successMsg->procedureCode = ProcedureCode_id_RICcontrol;
successMsg->criticality = Criticality_reject;
successMsg->value.present = SuccessfulOutcome__value_PR_RICcontrolAcknowledge;
unsuccessMsg = 0;
unsuccessMsg = (UnsuccessfulOutcome_t * )calloc(1, sizeof(UnsuccessfulOutcome_t));
assert(unsuccessMsg != 0);
unsuccessMsg->procedureCode = ProcedureCode_id_RICcontrol;
unsuccessMsg->criticality = Criticality_reject;
unsuccessMsg->value.present = UnsuccessfulOutcome__value_PR_RICcontrolFailure;
IE_array = 0;
IE_array = (RICcontrolAcknowledge_IEs_t *)calloc(NUM_CONTROL_ACKNOWLEDGE_IES, sizeof(RICcontrolAcknowledge_IEs_t));
assert(IE_array != 0);
RICcontrolAcknowledge_t * ric_acknowledge = &(successMsg->value.choice.RICcontrolAcknowledge);
for(int i = 0; i < NUM_CONTROL_ACKNOWLEDGE_IES; i++){
ASN_SEQUENCE_ADD(&(ric_acknowledge->protocolIEs), &(IE_array[i]));
}
IE_failure_array = 0;
IE_failure_array = (RICcontrolFailure_IEs_t *)calloc(NUM_CONTROL_FAILURE_IES, sizeof(RICcontrolFailure_IEs_t));
assert(IE_failure_array != 0);
RICcontrolFailure_t * ric_failure = &(unsuccessMsg->value.choice.RICcontrolFailure);
for(int i = 0; i < NUM_CONTROL_FAILURE_IES; i++){
ASN_SEQUENCE_ADD(&(ric_failure->protocolIEs), &(IE_failure_array[i]));
}
};
// Clear assigned protocolIE list from RIC control_request IE container
ric_control_response::~ric_control_response(void){
mdclog_write(MDCLOG_DEBUG, "Freeing E2AP Control Response object memory");
RICcontrolAcknowledge_t * ric_acknowledge = &(successMsg->value.choice.RICcontrolAcknowledge);
for(int i = 0; i < ric_acknowledge->protocolIEs.list.size; i++){
ric_acknowledge->protocolIEs.list.array[i] = 0;
}
if (ric_acknowledge->protocolIEs.list.size > 0){
free(ric_acknowledge->protocolIEs.list.array);
ric_acknowledge->protocolIEs.list.array = 0;
ric_acknowledge->protocolIEs.list.count = 0;
}
RICcontrolFailure_t * ric_failure = &(unsuccessMsg->value.choice.RICcontrolFailure);
for(int i = 0; i < ric_failure->protocolIEs.list.size; i++){
ric_failure->protocolIEs.list.array[i] = 0;
}
if (ric_failure->protocolIEs.list.size > 0){
free(ric_failure->protocolIEs.list.array);
ric_failure->protocolIEs.list.array = 0;
ric_failure->protocolIEs.list.count = 0;
}
free(IE_array);
free(IE_failure_array);
free(successMsg);
free(unsuccessMsg);
e2ap_pdu_obj->choice.initiatingMessage = 0;
e2ap_pdu_obj->present = E2AP_PDU_PR_initiatingMessage;
ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, e2ap_pdu_obj);
mdclog_write(MDCLOG_DEBUG, "Freed E2AP Control Response object mempory");
}
bool ric_control_response::encode_e2ap_control_response(unsigned char *buf, size_t *size, ric_control_helper & dinput, bool is_success){
bool res;
if (is_success){
res = set_fields(successMsg, dinput);
}
else{
res = set_fields(unsuccessMsg, dinput);
}
if (!res){
return false;
}
if (is_success){
e2ap_pdu_obj->choice.successfulOutcome = successMsg;
e2ap_pdu_obj->present = E2AP_PDU_PR_successfulOutcome ;
}
else{
e2ap_pdu_obj->choice.unsuccessfulOutcome = unsuccessMsg;
e2ap_pdu_obj->present = E2AP_PDU_PR_unsuccessfulOutcome ;
}
//xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2ap_pdu_obj);
int ret_constr = asn_check_constraints(&asn_DEF_E2AP_PDU, (void *) e2ap_pdu_obj, errbuf, &errbuf_len);
if(ret_constr){
error_string.assign(errbuf, errbuf_len);
error_string = "Constraints failed for encoding control response. Reason = " + error_string;
return false;
}
asn_enc_rval_t 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 Control response . Reason = encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
error_string = ss.str();
return false;
}
}
*size = retval.encoded;
return true;
}
bool ric_control_response::set_fields(SuccessfulOutcome_t *successMsg, ric_control_helper &dinput){
unsigned int ie_index;
if (successMsg == 0){
error_string = "Invalid reference for E2AP Control Acknowledge in set_fields";
return false;
}
// for(i = 0; i < NUM_CONTROL_ACKNOWLEDGE_IES;i++){
// memset(&(IE_array[i]), 0, sizeof(RICcontrolAcknowledge_IEs_t));
// }
//RICcontrolAcknowledge_t * ric_acknowledge = &(successMsg->value.choice.RICcontrolAcknowledge);
//ric_acknowledge->protocolIEs.list.count = 0;
ie_index = 0;
RICcontrolAcknowledge_IEs_t *ies_ricreq = &IE_array[ie_index];
ies_ricreq->criticality = Criticality_reject;
ies_ricreq->id = ProtocolIE_ID_id_RICrequestID;
ies_ricreq->value.present = RICcontrolAcknowledge_IEs__value_PR_RICrequestID;
RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
ricrequest_ie->ricRequestorID = dinput.req_id;
//ricrequest_ie->ricRequestSequenceNumber = dinput.req_seq_no;
//ASN_SEQUENCE_ADD(&(ric_acknowledge->protocolIEs), ies_ricreq);
ie_index = 1;
RICcontrolAcknowledge_IEs_t *ies_ranfunc = &IE_array[ie_index];
ies_ranfunc->criticality = Criticality_reject;
ies_ranfunc->id = ProtocolIE_ID_id_RANfunctionID;
ies_ranfunc->value.present = RICcontrolAcknowledge_IEs__value_PR_RANfunctionID;
RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
*ranfunction_ie = dinput.func_id;
//ASN_SEQUENCE_ADD(&(ric_acknowledge->protocolIEs), ies_ranfunc);
// ie_index = 2;
// RICcontrolAcknowledge_IEs_t *ies_riccallprocessid = &IE_array[ie_index];
// ies_riccallprocessid->criticality = Criticality_reject;
// ies_riccallprocessid->id = ProtocolIE_ID_id_RICcallProcessID;
// ies_riccallprocessid->value.present = RICcontrolAcknowledge_IEs__value_PR_RICcallProcessID;
// RICcallProcessID_t *riccallprocessid_ie = &ies_riccallprocessid->value.choice.RICcallProcessID;
// riccallprocessid_ie->buf = dinput.call_process_id;
// riccallprocessid_ie->size = dinput.call_process_id_size;
// ASN_SEQUENCE_ADD(&(ric_acknowledge->protocolIEs), ies_riccallprocessid);
ie_index = 2;
RICcontrolAcknowledge_IEs_t *ies_ric_cause = &IE_array[ie_index];
ies_ric_cause->criticality = Criticality_reject;
ies_ric_cause->id = ProtocolIE_ID_id_RICcontrolStatus;
ies_ric_cause->value.present = RICcontrolAcknowledge_IEs__value_PR_RICcontrolStatus;
ies_ric_cause->value.choice.RICcontrolStatus = dinput.control_status;
//ASN_SEQUENCE_ADD(&(ric_acknowledge->protocolIEs), ies_ric_cause);
return true;
};
bool ric_control_response::set_fields(UnsuccessfulOutcome_t *unsuccessMsg, ric_control_helper &dinput){
unsigned int ie_index;
if (unsuccessMsg == 0){
error_string = "Invalid reference for E2AP Control Failure in set_fields";
return false;
}
// for(i = 0; i < NUM_CONTROL_FAILURE_IES;i++){
// memset(&(IE_failure_array[i]), 0, sizeof(RICcontrolFailure_IEs_t));
// }
//RICcontrolFailure_t * ric_failure = &(unsuccessMsg->value.choice.RICcontrolFailure);
//ric_failure->protocolIEs.list.count = 0;
ie_index = 0;
RICcontrolFailure_IEs_t *ies_ricreq = &IE_failure_array[ie_index];
ies_ricreq->criticality = Criticality_reject;
ies_ricreq->id = ProtocolIE_ID_id_RICrequestID;
ies_ricreq->value.present = RICcontrolFailure_IEs__value_PR_RICrequestID;
RICrequestID_t *ricrequest_ie = &(ies_ricreq->value.choice.RICrequestID);
ricrequest_ie->ricRequestorID = dinput.req_id;
//ricrequest_ie->ricRequestSequenceNumber = dinput.req_seq_no;
//ASN_SEQUENCE_ADD(&(ric_failure->protocolIEs), ies_ricreq);
ie_index = 1;
RICcontrolFailure_IEs_t *ies_ranfunc = &IE_failure_array[ie_index];
ies_ranfunc->criticality = Criticality_reject;
ies_ranfunc->id = ProtocolIE_ID_id_RANfunctionID;
ies_ranfunc->value.present = RICcontrolFailure_IEs__value_PR_RANfunctionID;
RANfunctionID_t *ranfunction_ie = &(ies_ranfunc->value.choice.RANfunctionID);
*ranfunction_ie = dinput.func_id;
//ASN_SEQUENCE_ADD(&(ric_failure->protocolIEs), ies_ranfunc);
// ie_index = 2;
// RICcontrolFailure_IEs_t *ies_riccallprocessid = &IE_failure_array[i];
// ies_riccallprocessid->criticality = Criticality_reject;
// ies_riccallprocessid->id = ProtocolIE_ID_id_RICcallProcessID;
// ies_riccallprocessid->value.present = RICcontrolFailure_IEs__value_PR_RICcallProcessID;
// RICcallProcessID_t *riccallprocessid_ie = &(ies_riccallprocessid->value.choice.RICcallProcessID);
// riccallprocessid_ie->buf = dinput.call_process_id;
// riccallprocessid_ie->size = dinput.call_process_id_size;
// ASN_SEQUENCE_ADD(&(ric_failure->protocolIEs), ies_riccallprocessid);
ie_index = 2;
RICcontrolFailure_IEs_t *ies_ric_cause = &IE_failure_array[ie_index];
ies_ric_cause->criticality = Criticality_ignore;
ies_ric_cause->id = ProtocolIE_ID_id_Cause;
ies_ric_cause->value.present = RICcontrolFailure_IEs__value_PR_Cause;
Cause_t * ric_cause = &(ies_ric_cause->value.choice.Cause);
ric_cause->present = (Cause_PR)dinput.cause;
switch(dinput.cause){
case Cause_PR_ricService:
ric_cause->choice.ricService = dinput.sub_cause;
break;
case Cause_PR_transport:
ric_cause->choice.transport = dinput.sub_cause;
break;
case Cause_PR_protocol:
ric_cause->choice.protocol= dinput.sub_cause;
break;
case Cause_PR_misc:
ric_cause->choice.misc = dinput.sub_cause;
break;
case Cause_PR_ricRequest:
ric_cause->choice.ricRequest = dinput.sub_cause;
break;
default:
std::cout <<"Error ! Illegal cause enum" << dinput.cause << std::endl;
return false;
}
//ASN_SEQUENCE_ADD(&(ric_failure->protocolIEs), ies_ric_cause);
return true;
};
bool ric_control_response:: get_fields(SuccessfulOutcome_t * success_msg, ric_control_helper &dout)
{
if (success_msg == 0){
error_string = "Invalid reference for E2AP Control Acknowledge message in get_fields";
return false;
}
for(int edx = 0; edx < success_msg->value.choice.RICcontrolAcknowledge.protocolIEs.list.count; edx++) {
RICcontrolAcknowledge_IEs_t *memb_ptr = success_msg->value.choice.RICcontrolAcknowledge.protocolIEs.list.array[edx];
switch(memb_ptr->id)
{
case (ProtocolIE_ID_id_RICcallProcessID):
dout.call_process_id = memb_ptr->value.choice.RICcallProcessID.buf;
dout.call_process_id_size = memb_ptr->value.choice.RICcallProcessID.size;
break;
case (ProtocolIE_ID_id_RICrequestID):
dout.req_id = memb_ptr->value.choice.RICrequestID.ricRequestorID;
//dout.req_seq_no = memb_ptr->value.choice.RICrequestID.ricRequestSequenceNumber;
break;
case (ProtocolIE_ID_id_RANfunctionID):
dout.func_id = memb_ptr->value.choice.RANfunctionID;
break;
case (ProtocolIE_ID_id_Cause):
dout.control_status = memb_ptr->value.choice.RICcontrolStatus;
break;
}
}
return true;
}
bool ric_control_response:: get_fields(UnsuccessfulOutcome_t * unsuccess_msg, ric_control_helper &dout)
{
if (unsuccess_msg == 0){
error_string = "Invalid reference for E2AP Control Failure message in get_fields";
return false;
}
for(int edx = 0; edx < unsuccess_msg->value.choice.RICcontrolFailure.protocolIEs.list.count; edx++) {
RICcontrolFailure_IEs_t *memb_ptr = unsuccess_msg->value.choice.RICcontrolFailure.protocolIEs.list.array[edx];
switch(memb_ptr->id)
{
case (ProtocolIE_ID_id_RICcallProcessID):
dout.call_process_id = memb_ptr->value.choice.RICcallProcessID.buf;
dout.call_process_id_size = memb_ptr->value.choice.RICcallProcessID.size;
break;
case (ProtocolIE_ID_id_RICrequestID):
dout.req_id = memb_ptr->value.choice.RICrequestID.ricRequestorID;
//dout.req_seq_no = memb_ptr->value.choice.RICrequestID.ricRequestSequenceNumber;
break;
case (ProtocolIE_ID_id_RANfunctionID):
dout.func_id = memb_ptr->value.choice.RANfunctionID;
break;
case (ProtocolIE_ID_id_Cause):
dout.cause = memb_ptr->value.choice.Cause.present;
switch(dout.cause){
case Cause_PR_ricService :
dout.sub_cause = memb_ptr->value.choice.Cause.choice.ricService;
break;
case Cause_PR_transport :
dout.sub_cause = memb_ptr->value.choice.Cause.choice.transport;
break;
case Cause_PR_protocol :
dout.sub_cause = memb_ptr->value.choice.Cause.choice.protocol;
break;
case Cause_PR_misc :
dout.sub_cause = memb_ptr->value.choice.Cause.choice.misc;
break;
case Cause_PR_ricRequest :
dout.sub_cause = memb_ptr->value.choice.Cause.choice.ricRequest;
break;
default:
dout.sub_cause = -1;
break;
}
default:
break;
}
}
return true;
}

View File

@@ -0,0 +1,79 @@
/*
==================================================================================
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.
==================================================================================
*/
/*
* ric_indication.h
*
* Created on: Jul 11, 2019
* Author: sjana, Ashwin Sridharan
*/
#ifndef E2AP_RIC_CONTROL_RESPONSE_H_
#define E2AP_RIC_CONTROL_RESPONSE_H_
#include <iostream>
#include <errno.h>
#include <mdclog/mdclog.h>
#include <sstream>
#include <E2AP-PDU.h>
#include <SuccessfulOutcome.h>
#include <UnsuccessfulOutcome.h>
#include <RICcontrolAcknowledge.h>
#include <RICcontrolFailure.h>
#include <ProtocolIE-Field.h>
#include "e2ap_control_helper.hpp"
#define NUM_CONTROL_ACKNOWLEDGE_IES 3
#define NUM_CONTROL_FAILURE_IES 3
class ric_control_response{
public:
ric_control_response(void);
~ric_control_response(void);
bool encode_e2ap_control_response(unsigned char *, size_t *, ric_control_helper &, bool);
bool set_fields(SuccessfulOutcome_t *, ric_control_helper &);
bool get_fields(SuccessfulOutcome_t *, ric_control_helper &);
bool set_fields(UnsuccessfulOutcome_t *, ric_control_helper &);
bool get_fields(UnsuccessfulOutcome_t *, ric_control_helper &);
std::string get_error(void) const {return error_string ; };
private:
E2AP_PDU_t * e2ap_pdu_obj;
SuccessfulOutcome_t * successMsg;
UnsuccessfulOutcome_t * unsuccessMsg;
RICcontrolAcknowledge_IEs_t *IE_array;
RICcontrolFailure_IEs_t *IE_failure_array;
std::string error_string;
char errbuf[128];
size_t errbuf_len = 128;
};
#endif /* E2AP_RIC_CONTROL_RESPONSE_H_ */

View File

@@ -0,0 +1,283 @@
/*
==================================================================================
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.
==================================================================================
*/
/*
* ric_indication.c
*
* Created on: Jul 11, 2019
* Author: sjana, Ashwin Sridharan
*/
#include "e2ap_indication.hpp"
// Set up memory allocations for each IE for encoding
// We are responsible for memory management for each IE for encoding
// Hence destructor should clear out memory
// When decoding, we rely on asn1c macro (ASN_STRUCT_FREE to be called
// for releasing memory by external calling function)
ric_indication::ric_indication(void){
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(NUM_INDICATION_IES, sizeof(RICindication_IEs_t));
assert(IE_array != 0);
e2ap_pdu_obj->present = E2AP_PDU_PR_initiatingMessage;
e2ap_pdu_obj->choice.initiatingMessage = initMsg;
};
// Clear assigned protocolIE list from RIC indication IE container
ric_indication::~ric_indication(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 mempory");
}
bool ric_indication::encode_e2ap_indication(unsigned char *buf, size_t *size, ric_indication_helper & dinput){
initMsg->procedureCode = ProcedureCode_id_RICindication;
initMsg->criticality = Criticality_ignore;
initMsg->value.present = InitiatingMessage__value_PR_RICindication;
bool res;
asn_enc_rval_t retval;
res = set_fields(initMsg, dinput);
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;
}
// std::cout <<"Constraint check ok ...." << std::endl;
// 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;
}
bool ric_indication::set_fields(InitiatingMessage_t *initMsg, ric_indication_helper &dinput){
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 = dinput.req_id;
//ricrequest_ie->ricRequestSequenceNumber = dinput.req_seq_no;
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 = dinput.func_id;
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 = dinput.action_id;
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 = dinput.indication_sn;
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 = dinput.indication_type;
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 = dinput.indication_header;
richeader_ie->size = dinput.indication_header_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 = dinput.indication_msg;
ricmsg_ie->size = dinput.indication_msg_size;
ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index]));
// optional call process id ..
if (dinput.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 = dinput.indication_msg;
riccallprocessid_ie->size = dinput.indication_msg_size;
ASN_SEQUENCE_ADD(&(ric_indication->protocolIEs), &(IE_array[ie_index]));
}
return true;
};
bool ric_indication:: get_fields(InitiatingMessage_t * init_msg, ric_indication_helper &dout)
{
if (init_msg == 0){
error_string = "Invalid reference for E2AP Indication message in get_fields";
return false;
}
for(int edx = 0; edx < init_msg->value.choice.RICindication.protocolIEs.list.count; edx++) {
RICindication_IEs_t *memb_ptr = init_msg->value.choice.RICindication.protocolIEs.list.array[edx];
switch(memb_ptr->id)
{
case (ProtocolIE_ID_id_RICindicationHeader):
dout.indication_header = memb_ptr->value.choice.RICindicationHeader.buf;
dout.indication_header_size = memb_ptr->value.choice.RICindicationHeader.size;
break;
case (ProtocolIE_ID_id_RICindicationMessage):
dout.indication_msg = memb_ptr->value.choice.RICindicationMessage.buf;
dout.indication_msg_size = memb_ptr->value.choice.RICindicationMessage.size;
break;
case (ProtocolIE_ID_id_RICrequestID):
dout.req_id = memb_ptr->value.choice.RICrequestID.ricRequestorID;
//dout.req_seq_no = memb_ptr->value.choice.RICrequestID.ricRequestSequenceNumber;
break;
case (ProtocolIE_ID_id_RANfunctionID):
dout.func_id = memb_ptr->value.choice.RANfunctionID;
break;
case (ProtocolIE_ID_id_RICindicationSN):
dout.indication_sn = memb_ptr->value.choice.RICindicationSN;
break;
case (ProtocolIE_ID_id_RICindicationType):
dout.indication_type = memb_ptr->value.choice.RICindicationType;
break;
case (ProtocolIE_ID_id_RICactionID):
dout.action_id = memb_ptr->value.choice.RICactionID;
break;
case (ProtocolIE_ID_id_RICcallProcessID):
dout.call_process_id = memb_ptr->value.choice.RICcallProcessID.buf;
dout.call_process_id_size = memb_ptr->value.choice.RICcallProcessID.size;
default:
break;
}
}
return true;
}
InitiatingMessage_t * ric_indication::get_message(void) {
return initMsg;
}

View File

@@ -0,0 +1,67 @@
/*
==================================================================================
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.
==================================================================================
*/
/*
* ric_indication.h
*
* Created on: Jul 11, 2019
* Author: sjana, Ashwin Sridharan
*/
#ifndef E2AP_RIC_INDICATION_H_
#define E2AP_RIC_INDICATION_H_
#include <iostream>
#include <errno.h>
#include <mdclog/mdclog.h>
#include <sstream>
#include <E2AP-PDU.h>
#include <InitiatingMessage.h>
#include <RICindication.h>
#include <ProtocolIE-Field.h>
#include "e2ap_indication_helper.hpp"
#define NUM_INDICATION_IES 8
class ric_indication{
public:
ric_indication(void);
~ric_indication(void);
bool encode_e2ap_indication(unsigned char *, size_t *, ric_indication_helper &);
InitiatingMessage_t * get_message (void) ;
bool set_fields(InitiatingMessage_t *, ric_indication_helper &);
bool get_fields(InitiatingMessage_t *, ric_indication_helper &);
std::string get_error(void) const {return error_string ; };
private:
E2AP_PDU_t * e2ap_pdu_obj;
InitiatingMessage_t *initMsg;
RICindication_IEs_t *IE_array;
std::string error_string;
char errbuf[128];
size_t errbuf_len = 128;
};
#endif /* E2AP_RIC_INDICATION_H_ */

View File

@@ -0,0 +1,47 @@
/*
==================================================================================
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.
==================================================================================
*/
/*
* ric_indication.h
*
* Created on: Jul 11, 2019
* Author: sjana, Ashwin Sridharan
*/
#ifndef E2AP_INDICATION_HELPER_
#define E2AP_INDICATION_HELPER_
typedef struct ric_indication_helper ric_indication_helper;
struct ric_indication_helper{
ric_indication_helper(void) : req_id(1), req_seq_no(1), func_id(0), action_id(1), indication_type(0), indication_sn(0), indication_msg(0), indication_msg_size(0), indication_header(0), indication_header_size(0), call_process_id(0), call_process_id_size(0) {};
long int req_id, req_seq_no, func_id, action_id, indication_type, indication_sn;
unsigned char* indication_msg;
size_t indication_msg_size;
unsigned char* indication_header;
size_t indication_header_size;
unsigned char *call_process_id;
size_t call_process_id_size;
};
#endif

View File

@@ -0,0 +1,49 @@
/*
==================================================================================
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.
==================================================================================
*/
#pragma once
#ifndef GENERIC_HELPERS
#define GENERIC_HELPERS
#include <cstddef>
/* Utilities */
class octet_helper {
public:
octet_helper(void):_ref(NULL), _size(0){};
octet_helper(const void *ref, int size):_ref(ref), _size(size){};
void set_ref(const void *ref){
_ref = ref;
}
void set_size(size_t size){
_size = size;
}
const void * get_ref(void){return _ref ; };
size_t get_size(void) const {return _size ; } ;
private:
const void *_ref;
size_t _size;
};
#endif

View File

@@ -0,0 +1,181 @@
/*
==================================================================================
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.
==================================================================================
*/
#pragma once
#ifndef S_RESPONSE_HELPER_
#define S_RESPONSE_HELPER_
#include <vector>
#include <memory>
/* Simple structure to store action for RICaction of the Subscription response based on E2 v0.31 */
struct ActionResponse {
public:
ActionResponse(int id): _is_admit(true), _id(id), _cause(-1), _sub_cause(-1){};
ActionResponse(int id, int cause, int sub_cause): _is_admit(false), _id(id), _cause(cause), _sub_cause(sub_cause){};
int get_id() const{
return _id;
};
int get_cause() const{
return _cause;
};
int get_sub_cause() const{
return _sub_cause;
};
bool is_admitted(void){
return _is_admit;
};
private:
bool _is_admit;
int _id, _cause, _sub_cause;
};
struct subscription_response_helper {
public:
using action_t = std::vector<ActionResponse>;
subscription_response_helper(void){
_action_admitted_ref = std::make_unique<action_t>();
_action_not_admitted_ref = std::make_unique<action_t>();
};
// copy operator
subscription_response_helper(const subscription_response_helper &he ){
_action_admitted_ref = std::make_unique<action_t>();
_action_not_admitted_ref = std::make_unique<action_t>();
_req_id = he.get_request_id();
_req_seq_no = he.get_req_seq();
_func_id = he.get_function_id();
// Take care of the actions
for (auto const & e: *(he.get_admitted_list())){
add_action(e.get_id());
}
for(auto const & e: *(he.get_not_admitted_list())){
add_action(e.get_id(), e.get_cause(), e.get_sub_cause());
};
}
// assignment operator
void operator=(const subscription_response_helper & he){
_action_admitted_ref = std::make_unique<action_t>();
_action_not_admitted_ref = std::make_unique<action_t>();
_req_id = he.get_request_id();
_req_seq_no = he.get_req_seq();
_func_id = he.get_function_id();
// Take care of the actions
for (auto const & e: *(he.get_admitted_list())){
add_action(e.get_id());
}
for(auto const & e: *(he.get_not_admitted_list())){
add_action(e.get_id(), e.get_cause(), e.get_sub_cause());
};
}
action_t * get_admitted_list (void ) const {return _action_admitted_ref.get();};
action_t * get_not_admitted_list (void ) const{return _action_not_admitted_ref.get();};
void set_request(int id, int seq_no){
_req_id = id;
_req_seq_no = seq_no;
};
void clear(void){
_action_admitted_ref.get()->clear();
_action_not_admitted_ref.get()->clear();
}
void set_function_id(int id){
_func_id = id;
};
void add_action(int id){
ActionResponse a(id) ;
_action_admitted_ref.get()->push_back(a);
};
void add_action(int id, int cause, int sub_cause){
ActionResponse a (id, cause, sub_cause);
_action_not_admitted_ref.get()->push_back(a);
};
int get_request_id(void) const{
return _req_id;
}
int get_req_seq(void) const{
return _req_seq_no;
}
int get_function_id(void) const{
return _func_id;
}
std::string to_string(void){
std::string Info;
Info += "Request ID = " + std::to_string(_req_id) + "\n";
Info += "Request Sequence No = " + std::to_string(_req_seq_no) + "\n";
Info += "RAN Function ID = " + std::to_string(_func_id) + "\n";
Info += "Actions Admitted =\n";
int i = 0;
for(auto & e: *(_action_admitted_ref)){
Info += std::to_string(i) + ": ID=" + std::to_string(e.get_id()) + "\n";
i++;
}
Info += "Actions Not Admitted =\n";
i = 0;
for(auto & e: *(_action_not_admitted_ref)){
Info += std::to_string(i) + ": ID=" + std::to_string(e.get_id()) + ": Cause =" + std::to_string(e.get_cause()) + ": Sub-Cause=" + std::to_string(e.get_sub_cause()) + "\n";
i++;
}
return Info;
}
private:
int _req_id, _req_seq_no, _func_id;
std::unique_ptr<action_t> _action_admitted_ref;
std::unique_ptr<action_t> _action_not_admitted_ref;
};
#endif

View File

@@ -0,0 +1,180 @@
/*
==================================================================================
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.
==================================================================================
*/
#include "subscription_delete_request.hpp"
subscription_delete::subscription_delete(void){
_name = "default";
e2ap_pdu_obj = (E2AP_PDU_t * )calloc(1, sizeof(E2AP_PDU_t));
assert(e2ap_pdu_obj != 0);
initMsg = (InitiatingMessage_t * )calloc(1, sizeof(InitiatingMessage_t));
assert(initMsg != 0);
IE_array = (RICsubscriptionDeleteRequest_IEs_t *)calloc(NUM_SUBSCRIPTION_DELETE_IES, sizeof(RICsubscriptionDeleteRequest_IEs_t));
assert(IE_array != 0);
RICsubscriptionDeleteRequest_t * subscription_delete = &(initMsg->value.choice.RICsubscriptionDeleteRequest);
for(int i = 0; i < NUM_SUBSCRIPTION_DELETE_IES; i++){
ASN_SEQUENCE_ADD(&subscription_delete->protocolIEs, &(IE_array[i]));
}
};
// Clear assigned protocolIE list from RIC indication IE container
subscription_delete::~subscription_delete(void){
mdclog_write(MDCLOG_DEBUG, "Freeing subscription delete request object memory");
RICsubscriptionDeleteRequest_t * subscription_delete = &(initMsg->value.choice.RICsubscriptionDeleteRequest);
for(int i = 0; i < subscription_delete->protocolIEs.list.size; i++){
subscription_delete->protocolIEs.list.array[i] = 0;
}
if (subscription_delete->protocolIEs.list.size > 0){
free(subscription_delete->protocolIEs.list.array);
subscription_delete->protocolIEs.list.count = 0;
subscription_delete->protocolIEs.list.size = 0;
subscription_delete->protocolIEs.list.array = 0;
}
free(IE_array);
free(initMsg);
e2ap_pdu_obj->choice.initiatingMessage = 0;
ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, e2ap_pdu_obj);
mdclog_write(MDCLOG_DEBUG, "Freed subscription delete request object memory");
};
bool subscription_delete::encode_e2ap_subscription(unsigned char *buf, size_t *size, subscription_helper &dinput){
e2ap_pdu_obj->choice.initiatingMessage = initMsg;
e2ap_pdu_obj->present = E2AP_PDU_PR_initiatingMessage;
set_fields( dinput);
initMsg->procedureCode = ProcedureCode_id_RICsubscriptionDelete;
initMsg->criticality = Criticality_reject;
initMsg->value.present = InitiatingMessage__value_PR_RICsubscriptionDeleteRequest;
//xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2ap_pdu_obj);
int ret_constr = asn_check_constraints(&asn_DEF_E2AP_PDU, (void *) e2ap_pdu_obj, errbuf, &errbuf_len);
if(ret_constr){
error_string.assign(errbuf, errbuf_len);
error_string = "Constraints failed for encoding subscription delete request. Reason = " + error_string;
return false;
}
asn_enc_rval_t res = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2AP_PDU, e2ap_pdu_obj, buf, *size);
if(res.encoded == -1){
error_string.assign(strerror(errno));
error_string = "Error encoding Subscription Delete Request. Reason = " + error_string;
return false;
}
else {
if(*size < res.encoded){
std::stringstream ss;
ss <<"Error encoding Subscription Delete Request . Reason = encoded pdu size " << res.encoded << " exceeds buffer size " << *size << std::endl;
error_string = ss.str();
res.encoded = -1;
return false;
}
}
*size = res.encoded;
return true;
}
bool subscription_delete::set_fields( subscription_helper &helper){
unsigned int ie_index;
ie_index = 0;
RICsubscriptionDeleteRequest_IEs_t *ies_ricreq = &IE_array[ie_index];
ies_ricreq->criticality = Criticality_reject;
ies_ricreq->id = ProtocolIE_ID_id_RICrequestID;
ies_ricreq->value.present = RICsubscriptionDeleteRequest_IEs__value_PR_RICrequestID;
RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
ricrequest_ie->ricRequestorID = helper.get_request_id();
//ricrequest_ie->ricRequestSequenceNumber = helper.get_req_seq();
ie_index = 1;
RICsubscriptionDeleteRequest_IEs_t *ies_ranfunc = &IE_array[ie_index];
ies_ranfunc->criticality = Criticality_reject;
ies_ranfunc->id = ProtocolIE_ID_id_RANfunctionID;
ies_ranfunc->value.present = RICsubscriptionDeleteRequest_IEs__value_PR_RANfunctionID;
RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
*ranfunction_ie = helper.get_function_id();
return true;
};
bool subscription_delete:: get_fields(InitiatingMessage_t * init_msg, subscription_helper & dout)
{
if (init_msg == 0){
error_string = "Invalid reference for initiating message for get string";
return false;
}
RICrequestID_t *requestid;
RANfunctionID_t * ranfunctionid;
for(int edx = 0; edx < init_msg->value.choice.RICsubscriptionDeleteRequest.protocolIEs.list.count; edx++) {
RICsubscriptionDeleteRequest_IEs_t *memb_ptr = init_msg->value.choice.RICsubscriptionDeleteRequest.protocolIEs.list.array[edx];
switch(memb_ptr->id)
{
case (ProtocolIE_ID_id_RICrequestID):
requestid = &memb_ptr->value.choice.RICrequestID;
//dout.set_request(requestid->ricRequestorID, requestid->ricRequestSequenceNumber);
break;
case (ProtocolIE_ID_id_RANfunctionID):
ranfunctionid = &memb_ptr->value.choice.RANfunctionID;
dout.set_function_id(*ranfunctionid);
break;
}
//asn_fprint(stdout, &asn_DEF_E2AP_PDU, e2pdu);
}
return true;
}

View File

@@ -0,0 +1,67 @@
/*
==================================================================================
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.
==================================================================================
*/
#pragma once
#ifndef S_DELETE_
#define S_DELETE_
#include <mdclog/mdclog.h>
#include <vector>
#include <sstream>
#include <mdclog/mdclog.h>
#include <asn_application.h>
#include <E2AP-PDU.h>
#include <InitiatingMessage.h>
#include <RICsubscriptionDeleteRequest.h>
#include <ProtocolIE-Field.h>
#include "subscription_helper.hpp"
#define NUM_SUBSCRIPTION_DELETE_IES 2
class subscription_delete{
public:
subscription_delete(void);
~subscription_delete(void);
bool encode_e2ap_subscription(unsigned char *, size_t *, subscription_helper &);
bool set_fields(subscription_helper &);
bool get_fields(InitiatingMessage_t *, subscription_helper &);
std::string get_error(void) const {
return error_string ;
}
private:
InitiatingMessage_t *initMsg;
E2AP_PDU_t * e2ap_pdu_obj;
RICsubscriptionDeleteRequest_IEs_t * IE_array;
char errbuf[128];
size_t errbuf_len = 128;
std::string _name;
std::string error_string;
};
#endif

View File

@@ -0,0 +1,292 @@
/*
==================================================================================
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.
==================================================================================
*/
#include "subscription_delete_response.hpp"
/* The xAPP need only worry about the get_fields from a response, since it does
not generate a response. Generating response however is included to support testing.
*/
// Primarly for generation
subscription_delete_response::subscription_delete_response(void){
e2ap_pdu_obj = 0;
e2ap_pdu_obj = (E2AP_PDU_t *)calloc(1, sizeof(E2AP_PDU_t));
assert(e2ap_pdu_obj != 0);
successMsg = 0;
successMsg = (SuccessfulOutcome_t *)calloc(1, sizeof(SuccessfulOutcome_t));
assert(successMsg != 0);
unsuccessMsg = 0;
unsuccessMsg = (UnsuccessfulOutcome_t *)calloc(1, sizeof(UnsuccessfulOutcome_t));
assert(unsuccessMsg != 0);
IE_array = 0;
IE_array = (RICsubscriptionDeleteResponse_IEs_t *)calloc(NUM_SUBSCRIPTION_DELETE_RESPONSE_IES, sizeof(RICsubscriptionDeleteResponse_IEs_t));
assert(IE_array != 0);
IE_Failure_array = 0;
IE_Failure_array = (RICsubscriptionDeleteFailure_IEs_t *)calloc(NUM_SUBSCRIPTION_DELETE_FAILURE_IES, sizeof(RICsubscriptionDeleteFailure_IEs_t));
assert(IE_Failure_array != 0);
};
// Clear assigned protocolIE list from RIC indication IE container
subscription_delete_response::~subscription_delete_response(void){
mdclog_write(MDCLOG_DEBUG, "Freeing subscription delete response memory");
RICsubscriptionDeleteResponse_t * ric_subscription_delete_response = &(successMsg->value.choice.RICsubscriptionDeleteResponse);
for(unsigned int i = 0; i < ric_subscription_delete_response->protocolIEs.list.size ; i++){
ric_subscription_delete_response->protocolIEs.list.array[i] = 0;
}
RICsubscriptionDeleteFailure_t * ric_subscription_failure = &(unsuccessMsg->value.choice.RICsubscriptionDeleteFailure);
for(unsigned int i = 0; i < ric_subscription_failure->protocolIEs.list.size; i++){
ric_subscription_failure->protocolIEs.list.array[i] = 0;
}
free(IE_array);
free(IE_Failure_array);
ASN_STRUCT_FREE(asn_DEF_SuccessfulOutcome, successMsg);
ASN_STRUCT_FREE(asn_DEF_UnsuccessfulOutcome, unsuccessMsg);
e2ap_pdu_obj->choice.successfulOutcome = NULL;
e2ap_pdu_obj->choice.unsuccessfulOutcome = NULL;
ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, e2ap_pdu_obj);
mdclog_write(MDCLOG_DEBUG, "Freed subscription delete response memory");
};
bool subscription_delete_response::encode_e2ap_subscription_delete_response(unsigned char *buf, size_t *size, subscription_response_helper &dinput, bool is_success){
bool res;
if(is_success){
res = set_fields(successMsg, dinput);
if (!res){
return false;
}
e2ap_pdu_obj->present = E2AP_PDU_PR_successfulOutcome;
e2ap_pdu_obj->choice.successfulOutcome = successMsg;
}
else{
res = set_fields(unsuccessMsg, dinput);
if(! res){
return false;
}
e2ap_pdu_obj->present = E2AP_PDU_PR_unsuccessfulOutcome;
e2ap_pdu_obj->choice.unsuccessfulOutcome = unsuccessMsg;
}
int ret_constr = asn_check_constraints(&asn_DEF_E2AP_PDU, (void *) e2ap_pdu_obj, errbuf, &errbuf_len);
if(ret_constr){
error_string.assign(errbuf, errbuf_len);
return false;
}
//xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2ap_pdu_obj);
asn_enc_rval_t 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));
error_string = "Error encoding subcription delete response. Reason = " + error_string;
return false;
}
else {
if(*size < retval.encoded){
std::stringstream ss;
ss <<"Error encoding Subscription Delete Response . Reason = encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
error_string = ss.str();
retval.encoded = -1;
return false;
}
}
*size = retval.encoded;
return true;
}
bool subscription_delete_response::set_fields(SuccessfulOutcome_t *success, subscription_response_helper &helper){
if (success == 0){
error_string = "Invalid reference to success message in set fields subscription delete response";
return false;
}
unsigned int ie_index;
success->procedureCode = ProcedureCode_id_RICsubscriptionDelete;
success->criticality = Criticality_reject;
success->value.present = SuccessfulOutcome__value_PR_RICsubscriptionDeleteResponse;
RICsubscriptionDeleteResponse_t * subscription_delete_response = &(success->value.choice.RICsubscriptionDeleteResponse);
subscription_delete_response->protocolIEs.list.count = 0;
ie_index = 0;
RICsubscriptionDeleteResponse_IEs_t *ies_ricreq = &IE_array[ie_index];
ies_ricreq->criticality = Criticality_reject;
ies_ricreq->id = ProtocolIE_ID_id_RICrequestID;
ies_ricreq->value.present = RICsubscriptionDeleteResponse_IEs__value_PR_RICrequestID;
RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
ricrequest_ie->ricRequestorID = helper.get_request_id();
//ricrequest_ie->ricRequestSequenceNumber = helper.get_req_seq();
ASN_SEQUENCE_ADD(&subscription_delete_response->protocolIEs, ies_ricreq);
ie_index = 1;
RICsubscriptionDeleteResponse_IEs_t *ies_ranfunc = &IE_array[ie_index];
ies_ranfunc->criticality = Criticality_reject;
ies_ranfunc->id = ProtocolIE_ID_id_RANfunctionID;
ies_ranfunc->value.present = RICsubscriptionDeleteResponse_IEs__value_PR_RANfunctionID;
RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
*ranfunction_ie = helper.get_function_id();
ASN_SEQUENCE_ADD(&subscription_delete_response->protocolIEs, ies_ranfunc);
return true;
}
bool subscription_delete_response:: get_fields(SuccessfulOutcome_t * success_msg, subscription_response_helper & dout)
{
if (success_msg == 0){
error_string = "Invalid reference to success message inn get fields subscription delete response";
return false;
}
RICrequestID_t *requestid;
RANfunctionID_t * ranfunctionid;
for(int edx = 0; edx < success_msg->value.choice.RICsubscriptionDeleteResponse.protocolIEs.list.count; edx++) {
RICsubscriptionDeleteResponse_IEs_t *memb_ptr = success_msg->value.choice.RICsubscriptionDeleteResponse.protocolIEs.list.array[edx];
switch(memb_ptr->id)
{
case (ProtocolIE_ID_id_RICrequestID):
requestid = &memb_ptr->value.choice.RICrequestID;
//dout.set_request(requestid->ricRequestorID, requestid->ricRequestSequenceNumber);
break;
case (ProtocolIE_ID_id_RANfunctionID):
ranfunctionid = &memb_ptr->value.choice.RANfunctionID;
dout.set_function_id(*ranfunctionid);
break;
}
}
return true;
//asn_fprint(stdout, &asn_DEF_E2AP_PDU, e2pdu);
}
bool subscription_delete_response::set_fields(UnsuccessfulOutcome_t *unsuccess, subscription_response_helper &helper){
if (unsuccess == 0){
error_string = "Invalid reference to unsuccess message in set fields subscription delete response";
return false;
}
unsigned int ie_index;
unsuccess->procedureCode = ProcedureCode_id_RICsubscriptionDelete;
unsuccess->criticality = Criticality_reject;
unsuccess->value.present = UnsuccessfulOutcome__value_PR_RICsubscriptionDeleteFailure;
RICsubscriptionDeleteFailure_t * ric_subscription_failure = &(unsuccess->value.choice.RICsubscriptionDeleteFailure);
ric_subscription_failure->protocolIEs.list.count = 0;
ie_index = 0;
RICsubscriptionDeleteFailure_IEs_t *ies_ricreq = &IE_Failure_array[ie_index];
ies_ricreq->criticality = Criticality_reject;
ies_ricreq->id = ProtocolIE_ID_id_RICrequestID;
ies_ricreq->value.present = RICsubscriptionDeleteFailure_IEs__value_PR_RICrequestID;
RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
ricrequest_ie->ricRequestorID = helper.get_request_id();
//ricrequest_ie->ricRequestSequenceNumber = helper.get_req_seq();
ASN_SEQUENCE_ADD(&ric_subscription_failure->protocolIEs, ies_ricreq);
ie_index = 1;
RICsubscriptionDeleteFailure_IEs_t *ies_ranfunc = &IE_Failure_array[ie_index];
ies_ranfunc->criticality = Criticality_reject;
ies_ranfunc->id = ProtocolIE_ID_id_RANfunctionID;
ies_ranfunc->value.present = RICsubscriptionDeleteFailure_IEs__value_PR_RANfunctionID;
RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
*ranfunction_ie = helper.get_function_id();
ASN_SEQUENCE_ADD(&ric_subscription_failure->protocolIEs, ies_ranfunc);
return true;
}
bool subscription_delete_response:: get_fields(UnsuccessfulOutcome_t * unsuccess_msg, subscription_response_helper & dout)
{
if (unsuccess_msg == 0){
error_string = "Invalid reference to unsuccess message in get fields subscription delete response";
return false;
}
RICrequestID_t *requestid;
RANfunctionID_t * ranfunctionid;
for(int edx = 0; edx < unsuccess_msg->value.choice.RICsubscriptionDeleteFailure.protocolIEs.list.count; edx++) {
RICsubscriptionDeleteFailure_IEs_t *memb_ptr = unsuccess_msg->value.choice.RICsubscriptionDeleteFailure.protocolIEs.list.array[edx];
switch(memb_ptr->id)
{
case (ProtocolIE_ID_id_RICrequestID):
requestid = &memb_ptr->value.choice.RICrequestID;
//dout.set_request(requestid->ricRequestorID, requestid->ricRequestSequenceNumber);
break;
case (ProtocolIE_ID_id_RANfunctionID):
ranfunctionid = &memb_ptr->value.choice.RANfunctionID;
dout.set_function_id(*ranfunctionid);
break;
}
}
return true;
//asn_fprint(stdout, &asn_DEF_E2AP_PDU, e2pdu);
}

View File

@@ -0,0 +1,79 @@
/*
==================================================================================
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.
==================================================================================
*/
#pragma once
#ifndef S_DEL_RESPONSE_
#define S_DEL_RESPONSE_
#include <mdclog/mdclog.h>
#include <vector>
#include <iostream>
#include <sstream>
#include <mdclog/mdclog.h>
#include <asn_application.h>
#include <E2AP-PDU.h>
#include <SuccessfulOutcome.h>
#include <UnsuccessfulOutcome.h>
#include <RICsubscriptionDeleteResponse.h>
#include <RICsubscriptionDeleteFailure.h>
#include <ProtocolIE-Field.h>
#include <ProcedureCode.h>
#include "response_helper.hpp"
#define NUM_SUBSCRIPTION_DELETE_RESPONSE_IES 2
#define NUM_SUBSCRIPTION_DELETE_FAILURE_IES 2
class subscription_delete_response {
public:
subscription_delete_response(void);
~subscription_delete_response(void);
bool encode_e2ap_subscription_delete_response(unsigned char *, size_t *, subscription_response_helper &, bool);
bool set_fields(SuccessfulOutcome_t *, subscription_response_helper &);
bool get_fields(SuccessfulOutcome_t *, subscription_response_helper &);
bool set_fields(UnsuccessfulOutcome_t *, subscription_response_helper &);
bool get_fields(UnsuccessfulOutcome_t *, subscription_response_helper &);
std::string get_error_string(void) const {
return error_string;
}
private:
E2AP_PDU_t * e2ap_pdu_obj;
SuccessfulOutcome_t * successMsg;
UnsuccessfulOutcome_t * unsuccessMsg;
RICsubscriptionDeleteResponse_IEs_t *IE_array;
RICsubscriptionDeleteFailure_IEs_t *IE_Failure_array;
char errbuf[128];
size_t errbuf_len = 128;
std::string error_string;
};
#endif

View File

@@ -0,0 +1,181 @@
/*
==================================================================================
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.
==================================================================================
*/
#ifndef SUB_HELPER_
#define SUB_HELPER_
/*
Simple structure to store action related information based on E2 v0.22
Used for subscription request, response etc
ricActionID RICactionID,
ricActionType RICactionType,
ricActionDefinition RICactionDefinition OPTIONAL,
ricSubsequentAction RICsubsequentAction OPTIONAL,
ricCause
*/
#include <iostream>
#include <vector>
#include <memory>
#include "generic_helpers.hpp"
// Note : if no action definition specified, octet length of action definition is NULL
// If no subsequent action specified, default is subsequent_action = 0, time to wait is 0
struct Action {
public:
Action(int id, int type): _is_def(false), _is_subs_act(false), _id(id), _type(type), _next_action(0){};
Action(int id, int type, const void *def, size_t def_size, int next_action): _is_def(false), _is_subs_act(false), _id(id), _type(type){
_is_def = true;
_action_definition.set_ref(def);
_action_definition.set_size(def_size);
_is_subs_act = true;
_next_action = next_action;
};
int get_id() const{
return _id;
}
int get_type() const {
return _type;
}
const void * get_definition(void ) {
return _action_definition.get_ref();
}
int get_definition_size(void) const {
return _action_definition.get_size();
};
int get_subsequent_action() const {
return _next_action;
};
bool is_definition() const{
return _is_def;
}
bool is_subsequent_action() const{
return _is_subs_act;
}
private:
bool _is_def;
bool _is_subs_act;
int _id, _type, _next_action, _cause, _sub_cause;
bool _is_admit;
octet_helper _action_definition;
};
/*
Helper class that stores subscription data
*/
struct subscription_helper {
public:
using action_t = std::vector<Action>;
subscription_helper(){
_action_ref = std::make_unique<action_t>();
};
action_t * get_list() const {return _action_ref.get();};
void clear(void){
_action_ref.get()->clear();
}
void set_request(int id){
_req_id = id;
};
void set_function_id(int id){
_func_id = id;
};
void set_event_def(const void *ref, size_t size){
_event_def.set_ref(ref);
_event_def.set_size(size);
};
void add_action(int id, int type){
Action a(id, type) ;
_action_ref.get()->push_back(a);
};
void add_action(int id, int type, const void *action_def, size_t size, int next_action){
Action a (id, type, action_def, size, next_action);
_action_ref.get()->push_back(a);
};
int get_request_id(void) const{
return _req_id;
}
int get_function_id(void) const{
return _func_id;
}
const void * get_event_def(void) {
return _event_def.get_ref();
}
int get_event_def_size(void) const {
return _event_def.get_size();
}
void print_sub_info(void){
std::cout <<"Request ID = " << _req_id << std::endl;
std::cout <<"RAN Function ID = " << _func_id << std::endl;
for(auto const & e: *(_action_ref.get())){
std::cout <<"Action ID = " << e.get_id() << " Action Type = " << e.get_type() << std::endl;
}
};
private:
std::unique_ptr<action_t> _action_ref;
int curr_index;
int _req_id, _func_id;
octet_helper _event_def;
};
#endif

View File

@@ -0,0 +1,306 @@
/*
==================================================================================
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.
==================================================================================
*/
#include "subscription_request.hpp"
// Set up memory allocations for each IE for encoding
// We are responsible for memory management for each IE for encoding
// Hence destructor should clear out memory
// When decoding, we rely on asn1c macro (ASN_STRUCT_FREE to be called
// for releasing memory by external calling function)
subscription_request::subscription_request(void){
_name = "default";
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 = (RICsubscriptionRequest_IEs_t *)calloc(NUM_SUBSCRIPTION_REQUEST_IES, sizeof(RICsubscriptionRequest_IEs_t));
assert(IE_array != 0);
action_array = 0;
action_array = (RICaction_ToBeSetup_ItemIEs_t *)calloc(INITIAL_REQUEST_LIST_SIZE, sizeof(RICaction_ToBeSetup_ItemIEs_t));
assert(action_array != 0);
action_array_size = INITIAL_REQUEST_LIST_SIZE;
// also need to add subsequent action and time to wait ..
for (unsigned int i = 0; i < action_array_size; i++){
action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction = (struct RICsubsequentAction *)calloc(1, sizeof(struct RICsubsequentAction));
assert(action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction != 0);
}
e2ap_pdu_obj->choice.initiatingMessage = initMsg;
e2ap_pdu_obj->present = E2AP_PDU_PR_initiatingMessage;
};
// Clear assigned protocolIE list from RIC indication IE container
subscription_request::~subscription_request(void){
mdclog_write(MDCLOG_DEBUG, "Freeing subscription request memory");;
// Sequence of actions to be admitted causes special heart-ache. Free ric subscription element manually and reset the ie pointer
RICsubscriptionDetails_t * ricsubscription_ie = &(IE_array[2].value.choice.RICsubscriptionDetails);
for(int i = 0; i < ricsubscription_ie->ricAction_ToBeSetup_List.list.size; i++){
ricsubscription_ie->ricAction_ToBeSetup_List.list.array[i] = 0;
}
if (ricsubscription_ie->ricAction_ToBeSetup_List.list.size > 0){
free(ricsubscription_ie->ricAction_ToBeSetup_List.list.array);
ricsubscription_ie->ricAction_ToBeSetup_List.list.size = 0;
ricsubscription_ie->ricAction_ToBeSetup_List.list.count = 0;
ricsubscription_ie->ricAction_ToBeSetup_List.list.array = 0;
}
// clear subsequent action array
for (unsigned int i = 0; i < action_array_size; i++){
free(action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction );
}
free(action_array);
RICsubscriptionRequest_t * subscription_request = &(initMsg->value.choice.RICsubscriptionRequest);
for(int i = 0; i < subscription_request->protocolIEs.list.size; i++){
subscription_request->protocolIEs.list.array[i] = 0;
}
if( subscription_request->protocolIEs.list.size > 0){
free( subscription_request->protocolIEs.list.array);
subscription_request->protocolIEs.list.array = 0;
subscription_request->protocolIEs.list.size = 0;
subscription_request->protocolIEs.list.count = 0;
}
free(IE_array);
free(initMsg);
e2ap_pdu_obj->choice.initiatingMessage = 0;
ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, e2ap_pdu_obj);
mdclog_write(MDCLOG_DEBUG, "Freed subscription request memory ");
};
bool subscription_request::encode_e2ap_subscription(unsigned char *buf, size_t *size, subscription_helper &dinput){
bool res;
initMsg->procedureCode = ProcedureCode_id_RICsubscription;
initMsg->criticality = Criticality_ignore;
initMsg->value.present = InitiatingMessage__value_PR_RICsubscriptionRequest;
res = set_fields(initMsg, dinput);
if (!res){
return false;
}
int ret_constr = asn_check_constraints(&asn_DEF_E2AP_PDU, (void *) e2ap_pdu_obj, errbuf, &errbuf_len);
if(ret_constr){
error_string.assign(errbuf, errbuf_len);
error_string = "Constraints failed for encoding subscription request. Reason = " + error_string;
return false;
}
//xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2ap_pdu_obj);
asn_enc_rval_t 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));
error_string = "Error encoding Subscription Request. Reason = " + error_string;
return false;
}
else {
if(*size < retval.encoded){
std::stringstream ss;
ss <<"Error encoding Subscription Request . Reason = encoded pdu size " << retval.encoded << " exceeds buffer size " << *size << std::endl;
error_string = ss.str();
retval.encoded = -1;
return false;
}
}
*size = retval.encoded;
return true;
}
bool subscription_request::set_fields( InitiatingMessage_t * init_msg, subscription_helper &helper){
int ie_index;
int result = 0;
if (init_msg == 0){
error_string = "Error. Invalid reference when getting fields from subscription request";
return false;
}
RICsubscriptionRequest_t * ric_subscription = &(init_msg->value.choice.RICsubscriptionRequest);
ric_subscription->protocolIEs.list.count = 0;
ie_index = 0;
RICsubscriptionRequest_IEs_t *ies_ricreq = &IE_array[ie_index];
ies_ricreq->criticality = Criticality_reject;
ies_ricreq->id = ProtocolIE_ID_id_RICrequestID;
ies_ricreq->value.present = RICsubscriptionRequest_IEs__value_PR_RICrequestID;
RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
ricrequest_ie->ricRequestorID = helper.get_request_id();
//ricrequest_ie->ricRequestSequenceNumber = helper.get_req_seq();
result = ASN_SEQUENCE_ADD(&(ric_subscription->protocolIEs), &IE_array[ie_index]);
assert(result == 0);
ie_index = 1;
RICsubscriptionRequest_IEs_t *ies_ranfunc = &IE_array[ie_index];
ies_ranfunc->criticality = Criticality_reject;
ies_ranfunc->id = ProtocolIE_ID_id_RANfunctionID;
ies_ranfunc->value.present = RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
*ranfunction_ie = helper.get_function_id();
result = ASN_SEQUENCE_ADD(&(ric_subscription->protocolIEs), &IE_array[ie_index]);
assert(result == 0);
ie_index = 2;
RICsubscriptionRequest_IEs_t *ies_actid = &IE_array[ie_index];
ies_actid->criticality = Criticality_reject;
ies_actid->id = ProtocolIE_ID_id_RICsubscriptionDetails;
ies_actid->value.present = RICsubscriptionRequest_IEs__value_PR_RICsubscriptionDetails;
RICsubscriptionDetails_t *ricsubscription_ie = &ies_actid->value.choice.RICsubscriptionDetails;
ricsubscription_ie->ricEventTriggerDefinition.buf = (uint8_t *) helper.get_event_def();
ricsubscription_ie->ricEventTriggerDefinition.size = helper.get_event_def_size();
std::vector<Action> * ref_action_array = helper.get_list();
// do we need to resize ?
// we don't care about contents, so just do a free/calloc
if(action_array_size < ref_action_array->size()){
std::cout <<"re-allocating action array from " << action_array_size << " to " << 2 * ref_action_array->size() << std::endl;
// free subsequent allocation
for (unsigned int i = 0; i < action_array_size; i++){
free(action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction );
}
action_array_size = 2 * ref_action_array->size();
free(action_array);
action_array = (RICaction_ToBeSetup_ItemIEs_t *)calloc(action_array_size, sizeof(RICaction_ToBeSetup_ItemIEs_t));
assert(action_array != 0);
// also need to add subsequent action and time to wait ..
for (unsigned int i = 0; i < action_array_size; i++){
action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction = (struct RICsubsequentAction *)calloc(1, sizeof(struct RICsubsequentAction));
assert(action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction != 0);
}
}
// reset the list count on ricAction_ToBeSetup_List;
ricsubscription_ie->ricAction_ToBeSetup_List.list.count = 0;
for(unsigned int i = 0; i < ref_action_array->size(); i ++){
action_array[i].criticality = Criticality_ignore;
action_array[i].id = ProtocolIE_ID_id_RICaction_ToBeSetup_Item ;
action_array[i].value.present = RICaction_ToBeSetup_ItemIEs__value_PR_RICaction_ToBeSetup_Item;
action_array[i].value.choice.RICaction_ToBeSetup_Item.ricActionID = (*ref_action_array)[i].get_id();
action_array[i].value.choice.RICaction_ToBeSetup_Item.ricActionType = (*ref_action_array)[i].get_type();
action_array[i].value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction->ricSubsequentActionType = (*ref_action_array)[i].get_subsequent_action();
result = ASN_SEQUENCE_ADD(&ricsubscription_ie->ricAction_ToBeSetup_List, &(action_array[i]));
if (result == -1){
error_string = "Erorr : Unable to assign memory to add Action item to set up list";
return false;
}
}
result = ASN_SEQUENCE_ADD(&(ric_subscription->protocolIEs), &IE_array[ie_index]);
assert(result == 0);
return true;
};
bool subscription_request:: get_fields(InitiatingMessage_t * init_msg, subscription_helper & dout)
{
if (init_msg == 0){
error_string = "Error. Invalid reference when getting fields from subscription request";
return false;
}
RICrequestID_t *requestid;
RANfunctionID_t * ranfunctionid;
RICsubscriptionDetails_t * ricsubscription;
for(int edx = 0; edx < init_msg->value.choice.RICsubscriptionRequest.protocolIEs.list.count; edx++) {
RICsubscriptionRequest_IEs_t *memb_ptr = init_msg->value.choice.RICsubscriptionRequest.protocolIEs.list.array[edx];
switch(memb_ptr->id)
{
case (ProtocolIE_ID_id_RICrequestID):
requestid = &memb_ptr->value.choice.RICrequestID;
//dout.set_request(requestid->ricRequestorID, requestid->ricRequestSequenceNumber);
break;
case (ProtocolIE_ID_id_RANfunctionID):
ranfunctionid = &memb_ptr->value.choice.RANfunctionID;
dout.set_function_id(*ranfunctionid);
break;
case (ProtocolIE_ID_id_RICsubscriptionDetails):
ricsubscription = &memb_ptr->value.choice.RICsubscriptionDetails;
dout.set_event_def(ricsubscription->ricEventTriggerDefinition.buf, ricsubscription->ricEventTriggerDefinition.size);
for(int index = 0; index < ricsubscription->ricAction_ToBeSetup_List.list.count; index ++){
RICaction_ToBeSetup_ItemIEs_t * item = (RICaction_ToBeSetup_ItemIEs_t *)ricsubscription->ricAction_ToBeSetup_List.list.array[index];
if (item->value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction == NULL){
dout.add_action(item->value.choice.RICaction_ToBeSetup_Item.ricActionID, item->value.choice.RICaction_ToBeSetup_Item.ricActionType);
}
else{
std::string action_def = ""; // for now we are ignoring action definition
}
};
break;
}
}
//asn_fprint(stdout, &asn_DEF_E2AP_PDU, e2pdu);
return true;
};

View File

@@ -0,0 +1,73 @@
/*
==================================================================================
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.
==================================================================================
*/
#pragma once
#ifndef S_REQUEST_
#define S_REQUEST_
#include <mdclog/mdclog.h>
#include <vector>
#include <sstream>
#include <asn_application.h>
#include <E2AP-PDU.h>
#include <InitiatingMessage.h>
#include <RICsubscriptionRequest.h>
#include <RICsubscriptionRequest.h>
#include <ProtocolIE-Field.h>
#include <ProtocolIE-SingleContainer.h>
#include <RICactions-ToBeSetup-List.h>
#include <RICsubsequentAction.h>
#include "subscription_helper.hpp"
#define NUM_SUBSCRIPTION_REQUEST_IES 3
#define INITIAL_REQUEST_LIST_SIZE 4
class subscription_request{
public:
subscription_request(std::string name);
subscription_request(void);
~subscription_request(void);
bool encode_e2ap_subscription(unsigned char *, size_t *, subscription_helper &);
bool set_fields(InitiatingMessage_t *, subscription_helper &);
bool get_fields(InitiatingMessage_t *, subscription_helper &);
std::string get_error(void) const{
return error_string;
}
private:
InitiatingMessage_t *initMsg;
E2AP_PDU_t * e2ap_pdu_obj;
RICsubscriptionRequest_IEs_t * IE_array;
RICaction_ToBeSetup_ItemIEs_t * action_array;
unsigned int action_array_size;
char errbuf[128];
size_t errbuf_len = 128;
std::string _name;
std::string error_string;
};
#endif

View File

@@ -0,0 +1,583 @@
/*
==================================================================================
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.
==================================================================================
*/
#include "subscription_response.hpp"
/* The xAPP need only worry about the get_fields from a response, since it does
not generate a response. Generating response however is included to support testing.
*/
// Primarly for generation
subscription_response::subscription_response(void){
e2ap_pdu_obj = 0;
e2ap_pdu_obj = (E2AP_PDU_t *)calloc(1, sizeof(E2AP_PDU_t));
assert(e2ap_pdu_obj != 0);
successMsg = 0;
successMsg = (SuccessfulOutcome_t *)calloc(1, sizeof(SuccessfulOutcome_t));
assert(successMsg != 0);
unsuccessMsg = 0;
unsuccessMsg = (UnsuccessfulOutcome_t *)calloc(1, sizeof(UnsuccessfulOutcome_t));
assert(unsuccessMsg != 0);
IE_array = 0;
IE_array = (RICsubscriptionResponse_IEs_t *)calloc(NUM_SUBSCRIPTION_RESPONSE_IES, sizeof(RICsubscriptionResponse_IEs_t));
assert(IE_array != 0);
IE_Failure_array = 0;
IE_Failure_array = (RICsubscriptionFailure_IEs_t *)calloc(NUM_SUBSCRIPTION_FAILURE_IES, sizeof(RICsubscriptionFailure_IEs_t));
assert(IE_Failure_array != 0);
ie_admitted_list = 0;
ie_admitted_list = (RICaction_Admitted_ItemIEs_t *)calloc(INITIAL_RESPONSE_LIST_SIZE, sizeof(RICaction_Admitted_ItemIEs_t));
assert(ie_admitted_list != 0);
ie_admitted_list_size = INITIAL_RESPONSE_LIST_SIZE;
ie_not_admitted_list = 0;
ie_not_admitted_list = (RICaction_NotAdmitted_ItemIEs_t *)calloc(INITIAL_RESPONSE_LIST_SIZE, sizeof(RICaction_NotAdmitted_ItemIEs_t));
assert(ie_not_admitted_list != 0);
ie_not_admitted_list_size = INITIAL_RESPONSE_LIST_SIZE;
};
// Clear assigned protocolIE list from RIC indication IE container
subscription_response::~subscription_response(void){
mdclog_write(MDCLOG_DEBUG, "Freeing subscription response memory");
RICaction_Admitted_List_t * response_admitted_list = (RICaction_Admitted_List_t *) &(IE_array[2].value.choice.RICaction_Admitted_List);
for(int i = 0; i < response_admitted_list->list.size; i++){
response_admitted_list->list.array[i] = 0;
}
if (response_admitted_list->list.size > 0){
free(response_admitted_list->list.array);
response_admitted_list->list.array = 0;
response_admitted_list->list.size = 0;
response_admitted_list->list.count = 0;
}
RICaction_NotAdmitted_List_t * response_not_admitted_list = &(IE_array[3].value.choice.RICaction_NotAdmitted_List);
for(int i = 0; i < response_not_admitted_list->list.size; i++){
response_not_admitted_list->list.array[i] = 0;
}
if (response_not_admitted_list->list.size > 0){
free(response_not_admitted_list->list.array);
response_not_admitted_list->list.array = 0;
response_not_admitted_list->list.size = 0;
response_not_admitted_list->list.count = 0;
}
RICsubscriptionResponse_t * ric_subscription_response = &(successMsg->value.choice.RICsubscriptionResponse);
for(int i = 0; i < ric_subscription_response->protocolIEs.list.size ; i++){
ric_subscription_response->protocolIEs.list.array[i] = 0;
}
if (ric_subscription_response->protocolIEs.list.size > 0){
free(ric_subscription_response->protocolIEs.list.array);
ric_subscription_response->protocolIEs.list.array = 0;
ric_subscription_response->protocolIEs.list.size = 0;
ric_subscription_response->protocolIEs.list.count = 0;
}
RICaction_NotAdmitted_List_t * failure_not_admitted_list = &(IE_Failure_array[2].value.choice.RICaction_NotAdmitted_List);
for(int i = 0; i < failure_not_admitted_list->list.size; i++){
failure_not_admitted_list->list.array[i] = 0;
}
if ( failure_not_admitted_list->list.size > 0){
free( failure_not_admitted_list->list.array);
failure_not_admitted_list->list.array = 0;
failure_not_admitted_list->list.size = 0;
failure_not_admitted_list->list.count = 0;
}
RICsubscriptionFailure_t * ric_subscription_failure = &(unsuccessMsg->value.choice.RICsubscriptionFailure);
for(int i = 0; i < ric_subscription_failure->protocolIEs.list.size; i++){
ric_subscription_failure->protocolIEs.list.array[i] = 0;
}
if ( ric_subscription_failure->protocolIEs.list.size > 0){
free(ric_subscription_failure->protocolIEs.list.array);
ric_subscription_failure->protocolIEs.list.array = 0;
ric_subscription_failure->protocolIEs.list.size = 0;
ric_subscription_failure->protocolIEs.list.count = 0;
}
free(ie_admitted_list);
free(ie_not_admitted_list);
free(IE_Failure_array);
free(IE_array);
ASN_STRUCT_FREE(asn_DEF_SuccessfulOutcome, successMsg);
ASN_STRUCT_FREE(asn_DEF_UnsuccessfulOutcome, unsuccessMsg);
e2ap_pdu_obj->choice.initiatingMessage = NULL;
e2ap_pdu_obj->present = E2AP_PDU_PR_NOTHING;
ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, e2ap_pdu_obj);
mdclog_write(MDCLOG_DEBUG, "Freed subscription response memory ");
};
bool subscription_response::encode_e2ap_subscription_response(unsigned char *buf, size_t *size, subscription_response_helper &dinput, bool is_success){
if(is_success){
set_fields_success(dinput);
e2ap_pdu_obj->present = E2AP_PDU_PR_successfulOutcome;
e2ap_pdu_obj->choice.successfulOutcome = successMsg;
successMsg->procedureCode = ProcedureCode_id_RICsubscription;
successMsg->criticality = Criticality_reject;
successMsg->value.present = SuccessfulOutcome__value_PR_RICsubscriptionResponse;
}
else{
set_fields_unsuccess(dinput);
e2ap_pdu_obj->present = E2AP_PDU_PR_unsuccessfulOutcome;
e2ap_pdu_obj->choice.unsuccessfulOutcome = unsuccessMsg;
unsuccessMsg->procedureCode = ProcedureCode_id_RICsubscription;
unsuccessMsg->criticality = Criticality_reject;
unsuccessMsg->value.present = UnsuccessfulOutcome__value_PR_RICsubscriptionFailure;
}
//xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2ap_pdu_obj);
int ret_constr = asn_check_constraints(&asn_DEF_E2AP_PDU, (void *) e2ap_pdu_obj, errbuf, &errbuf_len);
if(ret_constr){
error_string.assign(errbuf, errbuf_len);
error_string = "Constraints failed for encoding subscription response. Reason = " + error_string;
return false;
}
asn_enc_rval_t res = asn_encode_to_buffer(0, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2AP_PDU, e2ap_pdu_obj, buf, *size);
if(res.encoded == -1){
std::cout <<"Error encoding PDU. Reason =" << strerror(errno) << std::endl;
return false;
}
else {
if(*size < res.encoded){
fprintf(stderr, "Buffer assigned too small to encode: %s",(char *)(asn_DEF_E2AP_PDU.name));
res.encoded = -1;
return false;
}
}
*size = res.encoded;
return true;
}
void subscription_response::set_fields_success(subscription_response_helper &helper){
int ie_index;
RICsubscriptionResponse_t * subscription_response = &(successMsg->value.choice.RICsubscriptionResponse);
//reset list count ..
subscription_response->protocolIEs.list.count = 0;
ie_index = 0;
RICsubscriptionResponse_IEs_t *ies_ricreq = &IE_array[ie_index];
ies_ricreq->criticality = Criticality_reject;
ies_ricreq->id = ProtocolIE_ID_id_RICrequestID;
ies_ricreq->value.present = RICsubscriptionResponse_IEs__value_PR_RICrequestID;
RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
ricrequest_ie->ricRequestorID = helper.get_request_id();
// ricrequest_ie->ricRequestSequenceNumber = helper.get_req_seq();
ASN_SEQUENCE_ADD(&subscription_response->protocolIEs, &(IE_array[ie_index]));
ie_index = 1;
RICsubscriptionResponse_IEs_t *ies_ranfunc = &IE_array[ie_index];
ies_ranfunc->criticality = Criticality_reject;
ies_ranfunc->id = ProtocolIE_ID_id_RANfunctionID;
ies_ranfunc->value.present = RICsubscriptionResponse_IEs__value_PR_RANfunctionID;
RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
*ranfunction_ie = helper.get_function_id();
ASN_SEQUENCE_ADD(&subscription_response->protocolIEs, &(IE_array[ie_index]));
ie_index = 2;
RICsubscriptionResponse_IEs_t *ies_admitted_actid = &IE_array[ie_index];
ies_admitted_actid->criticality = Criticality_reject;
ies_admitted_actid->id = ProtocolIE_ID_id_RICactions_Admitted;
RICaction_Admitted_List_t *ric_admitted_actions_ie = &ies_admitted_actid->value.choice.RICaction_Admitted_List;
ric_admitted_actions_ie->list.count = 0;
std::vector<ActionResponse> * ref_admitted_action_array = helper.get_admitted_list();
if(ref_admitted_action_array->size() == 0){
ies_admitted_actid->value.present = RICsubscriptionResponse_IEs__value_PR_NOTHING;
}
else{
ies_admitted_actid->value.present = RICsubscriptionResponse_IEs__value_PR_RICaction_Admitted_List;
// resize memory ?
if (ref_admitted_action_array->size() >= ie_admitted_list_size){
ie_admitted_list_size = 2 * ref_admitted_action_array->size();
free(ie_admitted_list);
ie_admitted_list = (RICaction_Admitted_ItemIEs_t *)calloc(ie_admitted_list_size, sizeof(RICaction_Admitted_ItemIEs_t));
assert(ie_admitted_list != 0);
};
for(unsigned int i = 0; i < ref_admitted_action_array->size(); i ++){
ie_admitted_list[i].criticality = Criticality_ignore;
ie_admitted_list[i].id = ProtocolIE_ID_id_RICaction_Admitted_Item ;
ie_admitted_list[i].value.present = RICaction_Admitted_ItemIEs__value_PR_RICaction_Admitted_Item;
ie_admitted_list[i].value.choice.RICaction_Admitted_Item.ricActionID = (*ref_admitted_action_array)[i].get_id();
ASN_SEQUENCE_ADD(ric_admitted_actions_ie, &(ie_admitted_list[i]));
}
}
ASN_SEQUENCE_ADD(&subscription_response->protocolIEs, &(IE_array[ie_index]));
// optional IE : add only if non-zero list
ie_index = 3;
std::vector<ActionResponse> * ref_notadmitted_action_array = helper.get_not_admitted_list();
if (ref_notadmitted_action_array->size() > 0){
RICsubscriptionResponse_IEs_t *ies_notadmitted_actid = &IE_array[ie_index];
ies_notadmitted_actid->criticality = Criticality_reject;
ies_notadmitted_actid->id = ProtocolIE_ID_id_RICactions_NotAdmitted;
RICaction_NotAdmitted_List_t *ric_not_admitted_actions_ie = &ies_notadmitted_actid->value.choice.RICaction_NotAdmitted_List;
ric_not_admitted_actions_ie->list.count = 0;
ies_notadmitted_actid->value.present = RICsubscriptionResponse_IEs__value_PR_RICaction_NotAdmitted_List;
// resize memory ?
if (ref_notadmitted_action_array->size() >= ie_not_admitted_list_size){
ie_not_admitted_list_size = 2 * ref_notadmitted_action_array->size();
free(ie_not_admitted_list);
ie_not_admitted_list = (RICaction_NotAdmitted_ItemIEs_t *)calloc(ie_not_admitted_list_size, sizeof(RICaction_NotAdmitted_ItemIEs_t));
assert(ie_not_admitted_list != 0);
};
for(unsigned int i = 0; i < ref_notadmitted_action_array->size(); i ++){
ie_not_admitted_list[i].criticality = Criticality_ignore;
ie_not_admitted_list[i].id = ProtocolIE_ID_id_RICaction_NotAdmitted_Item ;
ie_not_admitted_list[i].value.present = RICaction_NotAdmitted_ItemIEs__value_PR_RICaction_NotAdmitted_Item;;
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.ricActionID = (*ref_notadmitted_action_array)[i].get_id();
int cause = (*ref_notadmitted_action_array)[i].get_cause();
switch(cause){
case Cause_PR_ricService:
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.cause.choice.ricService = (*ref_notadmitted_action_array)[i].get_sub_cause();
break;
case Cause_PR_transport:
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.cause.choice.transport = (*ref_notadmitted_action_array)[i].get_sub_cause();
break;
case Cause_PR_protocol:
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.cause.choice.protocol= (*ref_notadmitted_action_array)[i].get_sub_cause();
break;
case Cause_PR_misc:
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.cause.choice.misc = (*ref_notadmitted_action_array)[i].get_sub_cause();
break;
case Cause_PR_ricRequest:
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.cause.choice.ricRequest = (*ref_notadmitted_action_array)[i].get_sub_cause();
break;
default:
mdclog_write(MDCLOG_ERR, "Error :: %s, %d : Unknown RIC cause %d\n", __FILE__, __LINE__, cause);
return;
}
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.cause.present = (Cause_PR)cause;
ASN_SEQUENCE_ADD(ric_not_admitted_actions_ie, &(ie_not_admitted_list[i]));
}
ASN_SEQUENCE_ADD(&subscription_response->protocolIEs, &(IE_array[ie_index]));
}
}
void subscription_response:: get_fields(SuccessfulOutcome_t * success_msg, subscription_response_helper & dout)
{
assert(success_msg != NULL);
RICrequestID_t *requestid;
RANfunctionID_t * ranfunctionid;
RICaction_Admitted_List_t * ric_admitted_action_list;
RICaction_NotAdmitted_List_t * ric_not_admitted_action_list;
for(int edx = 0; edx < success_msg->value.choice.RICsubscriptionResponse.protocolIEs.list.count; edx++) {
RICsubscriptionResponse_IEs_t *memb_ptr = success_msg->value.choice.RICsubscriptionResponse.protocolIEs.list.array[edx];
switch(memb_ptr->id)
{
case (ProtocolIE_ID_id_RICrequestID):
requestid = &memb_ptr->value.choice.RICrequestID;
//dout.set_request(requestid->ricRequestorID, requestid->ricRequestSequenceNumber);
break;
case (ProtocolIE_ID_id_RANfunctionID):
ranfunctionid = &memb_ptr->value.choice.RANfunctionID;
dout.set_function_id(*ranfunctionid);
break;
case (ProtocolIE_ID_id_RICactions_Admitted):
ric_admitted_action_list = &memb_ptr->value.choice.RICaction_Admitted_List;
// admitted actions
for(int index = 0; index < ric_admitted_action_list->list.count; index ++){
RICaction_Admitted_ItemIEs_t * item = (RICaction_Admitted_ItemIEs_t *)ric_admitted_action_list->list.array[index];
long int id = item->value.choice.RICaction_Admitted_Item.ricActionID;
dout.get_admitted_list()->push_back(ActionResponse(id));
};
break;
case (ProtocolIE_ID_id_RICactions_NotAdmitted):
ric_not_admitted_action_list = &memb_ptr->value.choice.RICaction_NotAdmitted_List;
for(int index = 0; index < ric_not_admitted_action_list->list.count; index ++){
RICaction_NotAdmitted_ItemIEs_t * item = (RICaction_NotAdmitted_ItemIEs_t *)ric_not_admitted_action_list->list.array[index];
long int id = item->value.choice.RICaction_NotAdmitted_Item.ricActionID;
int cause = item->value.choice.RICaction_NotAdmitted_Item.cause.present;
int sub_cause;
switch(cause){
case Cause_PR_ricService :
sub_cause = item->value.choice.RICaction_NotAdmitted_Item.cause.choice.ricService;
break;
case Cause_PR_transport :
sub_cause = item->value.choice.RICaction_NotAdmitted_Item.cause.choice.transport;
break;
case Cause_PR_protocol :
sub_cause = item->value.choice.RICaction_NotAdmitted_Item.cause.choice.protocol;
break;
case Cause_PR_misc :
sub_cause = item->value.choice.RICaction_NotAdmitted_Item.cause.choice.misc;
break;
case Cause_PR_ricRequest :
sub_cause = item->value.choice.RICaction_NotAdmitted_Item.cause.choice.ricRequest;
break;
default:
std::cout <<"Error ! Illegal cause enum" << cause << std::endl;
return;
}
dout.get_not_admitted_list()->push_back(ActionResponse(id, cause, sub_cause));
}
break;
}
}
//asn_fprint(stdout, &asn_DEF_E2AP_PDU, e2pdu);
}
void subscription_response::set_fields_unsuccess( subscription_response_helper &helper){
int ie_index;
RICsubscriptionFailure_t * ric_subscription_failure = &(unsuccessMsg->value.choice.RICsubscriptionFailure);
// reset list count
ric_subscription_failure->protocolIEs.list.count = 0;
ie_index = 0;
RICsubscriptionFailure_IEs_t *ies_ricreq = &IE_Failure_array[ie_index];
ies_ricreq->criticality = Criticality_reject;
ies_ricreq->id = ProtocolIE_ID_id_RICrequestID;
ies_ricreq->value.present = RICsubscriptionFailure_IEs__value_PR_RICrequestID;
RICrequestID_t *ricrequest_ie = &ies_ricreq->value.choice.RICrequestID;
ricrequest_ie->ricRequestorID = helper.get_request_id();
// ricrequest_ie->ricRequestSequenceNumber = helper.get_req_seq();
ASN_SEQUENCE_ADD(&ric_subscription_failure->protocolIEs, &(IE_Failure_array[ie_index]));
ie_index = 1;
RICsubscriptionFailure_IEs_t *ies_ranfunc = &IE_Failure_array[ie_index];
ies_ranfunc->criticality = Criticality_reject;
ies_ranfunc->id = ProtocolIE_ID_id_RANfunctionID;
ies_ranfunc->value.present = RICsubscriptionFailure_IEs__value_PR_RANfunctionID;
RANfunctionID_t *ranfunction_ie = &ies_ranfunc->value.choice.RANfunctionID;
*ranfunction_ie = helper.get_function_id();
ASN_SEQUENCE_ADD(&ric_subscription_failure->protocolIEs, &(IE_Failure_array[ie_index]));
ie_index = 2;
RICsubscriptionFailure_IEs_t *ies_notadmitted_actid = &IE_Failure_array[ie_index];
ies_notadmitted_actid->criticality = Criticality_reject;
ies_notadmitted_actid->id = ProtocolIE_ID_id_RICactions_NotAdmitted;
RICaction_NotAdmitted_List_t *ric_not_admitted_actions_ie = &ies_notadmitted_actid->value.choice.RICaction_NotAdmitted_List;
ric_not_admitted_actions_ie->list.count = 0;
std::vector<ActionResponse> * ref_notadmitted_action_array = helper.get_not_admitted_list();
if(ref_notadmitted_action_array->size() == 0){
ies_notadmitted_actid->value.present = RICsubscriptionFailure_IEs__value_PR_NOTHING;
}
else{
ies_notadmitted_actid->value.present = RICsubscriptionFailure_IEs__value_PR_RICaction_NotAdmitted_List;
// resize memory ?
if (ref_notadmitted_action_array->size() >= ie_not_admitted_list_size){
ie_not_admitted_list_size = 2 * ref_notadmitted_action_array->size();
free(ie_not_admitted_list);
ie_not_admitted_list = (RICaction_NotAdmitted_ItemIEs_t *)calloc(ie_not_admitted_list_size, sizeof(RICaction_NotAdmitted_ItemIEs_t));
assert(ie_not_admitted_list != 0);
};
// reset the list count on ricAction_ToBeSetup_List;
for(unsigned int i = 0; i < ref_notadmitted_action_array->size(); i ++){
ie_not_admitted_list[i].criticality = Criticality_ignore;
ie_not_admitted_list[i].id = ProtocolIE_ID_id_RICaction_NotAdmitted_Item ;
ie_not_admitted_list[i].value.present = RICaction_NotAdmitted_ItemIEs__value_PR_RICaction_NotAdmitted_Item;;
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.ricActionID = (*ref_notadmitted_action_array)[i].get_id();
int cause = (*ref_notadmitted_action_array)[i].get_cause();
switch(cause){
case Cause_PR_ricService:
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.cause.choice.ricService = (*ref_notadmitted_action_array)[i].get_sub_cause();
break;
case Cause_PR_transport:
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.cause.choice.transport = (*ref_notadmitted_action_array)[i].get_sub_cause();
break;
case Cause_PR_protocol:
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.cause.choice.protocol= (*ref_notadmitted_action_array)[i].get_sub_cause();
break;
case Cause_PR_misc:
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.cause.choice.misc = (*ref_notadmitted_action_array)[i].get_sub_cause();
break;
case Cause_PR_ricRequest:
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.cause.choice.ricRequest = (*ref_notadmitted_action_array)[i].get_sub_cause();
break;
default:
mdclog_write(MDCLOG_ERR, "Error :: %s, %d : Unknown RIC cause %d\n", __FILE__, __LINE__, cause);
return ;
}
ie_not_admitted_list[i].value.choice.RICaction_NotAdmitted_Item.cause.present = (Cause_PR)cause;
ASN_SEQUENCE_ADD(ric_not_admitted_actions_ie, &(ie_not_admitted_list[i]));
}
}
ASN_SEQUENCE_ADD(&ric_subscription_failure->protocolIEs, &(IE_Failure_array[ie_index]));
// // criticality diagnostics is not generated/parsed currently since optional
// i = 3;
// RICsubscriptionFailure_IEs_t *ies_criticality_diagnostics= &IE_Failure_array[i];
// ies_criticality_diagnostics->criticality = Criticality_ignore;
// ies_criticality_diagnostics->id = ProtocolIE_ID_id_CriticalityDiagnostics ;
// ies_criticality_diagnostics->value.present = RICsubscriptionFailure_IEs__value_PR_NOTHING;
}
void subscription_response:: get_fields(UnsuccessfulOutcome_t * unsuccess_msg, subscription_response_helper & dout)
{
assert(unsuccess_msg != NULL);
RICrequestID_t *requestid;
RANfunctionID_t * ranfunctionid;
RICaction_NotAdmitted_List_t * ric_not_admitted_action_list;
for(int edx = 0; edx < unsuccess_msg->value.choice.RICsubscriptionFailure.protocolIEs.list.count; edx++) {
RICsubscriptionFailure_IEs_t *memb_ptr = unsuccess_msg->value.choice.RICsubscriptionFailure.protocolIEs.list.array[edx];
switch(memb_ptr->id)
{
case (ProtocolIE_ID_id_RICrequestID):
requestid = &memb_ptr->value.choice.RICrequestID;
//dout.set_request(requestid->ricRequestorID, requestid->ricRequestSequenceNumber);
break;
case (ProtocolIE_ID_id_RANfunctionID):
ranfunctionid = &memb_ptr->value.choice.RANfunctionID;
dout.set_function_id(*ranfunctionid);
break;
case (ProtocolIE_ID_id_RICactions_NotAdmitted):
ric_not_admitted_action_list = &memb_ptr->value.choice.RICaction_NotAdmitted_List;
for(int index = 0; index < ric_not_admitted_action_list->list.count; index ++){
RICaction_NotAdmitted_ItemIEs_t * item = (RICaction_NotAdmitted_ItemIEs_t *)ric_not_admitted_action_list->list.array[index];
long int id = item->value.choice.RICaction_NotAdmitted_Item.ricActionID;
int cause = item->value.choice.RICaction_NotAdmitted_Item.cause.present;
int sub_cause;
switch(cause){
case Cause_PR_ricService :
sub_cause = item->value.choice.RICaction_NotAdmitted_Item.cause.choice.ricService;
break;
case Cause_PR_transport :
sub_cause = item->value.choice.RICaction_NotAdmitted_Item.cause.choice.transport;
break;
case Cause_PR_protocol :
sub_cause = item->value.choice.RICaction_NotAdmitted_Item.cause.choice.protocol;
break;
case Cause_PR_misc :
sub_cause = item->value.choice.RICaction_NotAdmitted_Item.cause.choice.misc;
break;
case Cause_PR_ricRequest :
sub_cause = item->value.choice.RICaction_NotAdmitted_Item.cause.choice.ricRequest;
break;
default:
mdclog_write(MDCLOG_ERR, "Error :: %s, %d : Unknown RIC cause %d\n", __FILE__, __LINE__, cause);
return;
}
dout.get_not_admitted_list()->push_back(ActionResponse(id, cause, sub_cause));
}
break;
}
}
//asn_fprint(stdout, &asn_DEF_E2AP_PDU, e2pdu);
}

View File

@@ -0,0 +1,81 @@
/*
==================================================================================
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.
==================================================================================
*/
#pragma once
#ifndef S_RESPONSE_
#define S_RESPONSE_
#include <mdclog/mdclog.h>
#include <vector>
#include <iostream>
#include <sstream>
#include <asn_application.h>
#include <E2AP-PDU.h>
#include <SuccessfulOutcome.h>
#include <UnsuccessfulOutcome.h>
#include <ProtocolIE-Field.h>
#include <ProtocolIE-SingleContainer.h>
#include <ProcedureCode.h>
#include "response_helper.hpp"
#define NUM_SUBSCRIPTION_RESPONSE_IES 4
#define NUM_SUBSCRIPTION_FAILURE_IES 3
#define INITIAL_RESPONSE_LIST_SIZE 4
class subscription_response{
public:
subscription_response(void);
~subscription_response(void);
bool encode_e2ap_subscription_response(unsigned char *, size_t *, subscription_response_helper &, bool);
void get_fields(SuccessfulOutcome_t *, subscription_response_helper &);
void get_fields(UnsuccessfulOutcome_t *, subscription_response_helper &);
std::string get_error(void) const{
return error_string;
}
private:
void set_fields_success( subscription_response_helper &);
void set_fields_unsuccess( subscription_response_helper &);
E2AP_PDU_t * e2ap_pdu_obj;
SuccessfulOutcome_t * successMsg;
UnsuccessfulOutcome_t * unsuccessMsg;
RICsubscriptionResponse_IEs_t *IE_array;
RICsubscriptionFailure_IEs_t *IE_Failure_array;
RICaction_Admitted_ItemIEs_t * ie_admitted_list;
RICaction_NotAdmitted_ItemIEs_t * ie_not_admitted_list;
unsigned int ie_admitted_list_size, ie_not_admitted_list_size;
char errbuf[128];
size_t errbuf_len = 128;
std::string error_string;
};
#endif