---
-tag: '1.0.1'
+tag: '1.0.2'
import json;
import sys;
import os;
+import signal;
+import time;
+def signal_handler(signum, frame):
+ print("Received signal {0}\n".format(signum));
+ if(xapp_subprocess == None or xapp_pid == None):
+ print("No xapp running. Quiting without sending signal to xapp\n");
+ else:
+ print("Sending signal {0} to xapp ...".format(signum));
+ xapp_subprocess.send_signal(signum);
+
+
def parseConfigJson(config):
for key in config:
print("Processing ", key);
return True;
+
+# Global variables ...
+xapp_subprocess = None;
+xapp_pid = None;
ParseSection = {};
xapp_port = 0;
ParseSection["rmr"] = getRMRTable;
sys.exit(1);
if len(sys.argv) > 2:
- cmd = sys.argv[2];
+ cmd[0] = sys.argv[2];
with open(config_file, 'r') as f:
try:
sys.exit(1);
else:
- print("Executing xAPP ....");
- p = subprocess.check_call(cmd);
+
+ # Register signal handlers
+ signal.signal(signal.SIGINT, signal_handler);
+ signal.signal(signal.SIGTERM, signal_handler);
+
+ # Start the xAPP
+ #print("Executing xAPP ....");
+ xapp_subprocess = subprocess.Popen(cmd, shell = False, stdin=None, stdout=None, stderr = None);
+ xapp_pid = xapp_subprocess.pid;
+
+ # Periodically poll the process every 5 seconds to check if still alive
+ while(1):
+ xapp_status = xapp_subprocess.poll();
+ if xapp_status == None:
+ time.sleep(5);
+ else:
+ print("XaPP terminated via signal {0}\n".format(-1 * xapp_status));
+ break;
+
*ricackreq_ie = dinput.control_ack;
ASN_SEQUENCE_ADD(&(ric_control_request->protocolIEs), &(IE_array[ie_index]));
+ ie_index = 5;
+ if(dinput.call_process_id_size > 0){
+ E2N_RICcontrolRequest_IEs_t *ies_callprocid = &IE_array[ie_index];
+ ies_callprocid->criticality = E2N_Criticality_reject;
+ ies_callprocid->id = E2N_ProtocolIE_ID_id_RICcallProcessID;
+ ies_callprocid->value.present = E2N_RICcontrolRequest_IEs__value_PR_RICcallProcessID;
+ E2N_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;
};
dout.control_ack = memb_ptr->value.choice.RICcontrolAckRequest;
break;
-
default:
break;
}
#include <E2N_ProtocolIE-Field.h>
#include <e2ap_control_helper.hpp>
-#define NUM_CONTROL_REQUEST_IES 5
+#define NUM_CONTROL_REQUEST_IES 6
class ric_control_request{
+/*
+==================================================================================
+
+ Copyright (c) 2018-2019 AT&T Intellectual Property.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================================
+*/
+/*
+ * 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{
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;
+ E2N_RICindication_IEs_t *ies_ind_callprocessid = &IE_array[ie_index];
+ ies_ind_callprocessid->criticality = E2N_Criticality_reject;
+ ies_ind_callprocessid->id = E2N_ProtocolIE_ID_id_RICcallProcessID;
+ ies_ind_callprocessid->value.present = E2N_RICindication_IEs__value_PR_RICcallProcessID;
+ E2N_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;
};
case (E2N_ProtocolIE_ID_id_RICactionID):
dout.action_id = memb_ptr->value.choice.RICactionID;
break;
+
+ case (E2N_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;
#include <E2N_InitiatingMessage.h>
#include <E2N_RICindication.h>
#include <E2N_ProtocolIE-Field.h>
+#include "e2ap_indication_helper.hpp"
-#define NUM_INDICATION_IES 7
+#define NUM_INDICATION_IES 8
- 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;
-
- };
+
+class ric_indication{
+public:
+ ric_indication(void);
+ ~ric_indication(void);
- class ric_indication{
-
- public:
- ric_indication(void);
- ~ric_indication(void);
-
- bool encode_e2ap_indication(unsigned char *, size_t *, ric_indication_helper &);
- E2N_InitiatingMessage_t * get_message (void) ;
- bool set_fields(E2N_InitiatingMessage_t *, ric_indication_helper &);
- bool get_fields(E2N_InitiatingMessage_t *, ric_indication_helper &);
- std::string get_error(void) const {return error_string ; };
-
- private:
-
- E2N_E2AP_PDU_t * e2ap_pdu_obj;
- E2N_InitiatingMessage_t *initMsg;
- E2N_RICindication_IEs_t *IE_array;
- std::string error_string;
- char errbuf[128];
- size_t errbuf_len = 128;
- };
+ bool encode_e2ap_indication(unsigned char *, size_t *, ric_indication_helper &);
+ E2N_InitiatingMessage_t * get_message (void) ;
+ bool set_fields(E2N_InitiatingMessage_t *, ric_indication_helper &);
+ bool get_fields(E2N_InitiatingMessage_t *, ric_indication_helper &);
+ std::string get_error(void) const {return error_string ; };
+
+private:
+
+ E2N_E2AP_PDU_t * e2ap_pdu_obj;
+ E2N_InitiatingMessage_t *initMsg;
+ E2N_RICindication_IEs_t *IE_array;
+ std::string error_string;
+ char errbuf[128];
+ size_t errbuf_len = 128;
+};
#endif /* E2AP_RIC_INDICATION_H_ */
--- /dev/null
+/*
+==================================================================================
+
+ Copyright (c) 2018-2019 AT&T Intellectual Property.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================================
+*/
+/*
+ * 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
_num_messages ++;
std::string response;
- //FILE *pfile;
- //std::string filename = "/opt/out/e2ap_" + std::to_string(_num_messages) + ".per";
state = NO_ERROR;
mdclog_write(MDCLOG_DEBUG, "Received RMR message of type %d and size %d\n", message->mtype, message->len);
return false;
}
- // start measurement
- auto start = std::chrono::high_resolution_clock::now();
-
- // main message processing code
+ // routing based on message type
switch(message->mtype){
case RIC_INDICATION:
break;
}
- //pfile = fopen(filename.c_str(), "wb");
- //fwrite(message->payload, sizeof(char), message->len, pfile);
- //fclose(pfile);
-
e2ap_recv_pdu = 0;
e2sm_header = 0;
mdclog_write(MDCLOG_ERR, "Error :: %s, %d :: Could not get fields from RICindication message\n", __FILE__, __LINE__);
goto finished;
}
+
//std::cout <<"+++++++++++++++++++++++ E2AP Indication ++++++++++++++++++++++++" << std::endl;
//xer_fprint(stdout, &asn_DEF_E2N_E2AP_PDU, e2ap_recv_pdu);
//std::cout <<"+++++++++++++++++++++++ E2AP Indication ++++++++++++++++++++++++" << std::endl;
+
}
else{
num_err_indications ++;
// NOTE : We assume RICindicationMessage contains payload (not E2SM message)
- // Send payload to plugin
+ // Send payload to protector plugin
current_index = 0;
remaining_buffer = _buffer_size;
mdclog_write(MDCLOG_DEBUG, "Processing E2AP Indication message of size %lu\n", indication_data.indication_msg_size);
control_data.req_id = indication_data.req_id;
control_data.req_seq_no = indication_data.req_seq_no;
control_data.func_id = indication_data.func_id;
- control_data.control_ack = 2; // no ack required
+ control_data.control_ack = 1; // no ack required
+ control_data.call_process_id = indication_data.call_process_id;
+ control_data.call_process_id_size = indication_data.call_process_id_size;
res = control_request_processor.encode_e2ap_control_request(message->payload, &mlen, control_data);
if(likely(res)){
#! /bin/bash
-test_cases=( "TEST_MESSAGE_PROCESSOR" "TEST_ADMISSION" "TEST_PROTECTOR_PLUGIN" "TEST_SUBSCRIPTION_FLOW" "TEST_SUBSCRIPTION" "TEST_E2AP_INDICATION" "TEST_E2AP_CONTROL" "TEST_E2SM" "TEST_JSON" "TEST_X2_SGNB" "TEST_SLIDING_WINDOW" )
+#test_cases=( "TEST_MESSAGE_PROCESSOR" "TEST_ADMISSION" "TEST_PROTECTOR_PLUGIN" "TEST_SUBSCRIPTION_FLOW" "TEST_SUBSCRIPTION" "TEST_E2AP_INDICATION" "TEST_E2AP_CONTROL" "TEST_E2SM" "TEST_JSON" "TEST_X2_SGNB" "TEST_SLIDING_WINDOW" )
+test_cases=( "TEST_PROTECTOR_PLUGIN" )
# Run through test cases
for((i = 0; i < ${#test_cases[@]}; i++)); do
unsigned char buf_header[BUFFER_SIZE];
unsigned char buf_msg[BUFFER_SIZE];
+ unsigned char buf_callproc[BUFFER_SIZE];
SECTION("Verify E2AP Control Encoding/Decoding Successful"){
strcpy((char *)buf_header, "hello world");
strcpy((char *)buf_msg, "something out there");
- unsigned char buf_proc_id[4] = "25";
-
+ strcpy((char *)buf_callproc, "Call Process ID = 20");
+
dinput.control_header = buf_header;
dinput.control_header_size = strlen((const char *)buf_header);
dinput.control_msg = buf_msg;
dinput.control_msg_size = strlen((const char *)buf_msg);
- dinput.call_process_id = buf_proc_id;
- dinput.call_process_id_size = strlen((const char *)buf_proc_id);
+ dinput.call_process_id = buf_callproc;
+ dinput.call_process_id_size = strlen((const char *)buf_callproc);
+
/* encoding */
size_t data_size = 4096;
E2N_E2AP_PDU_t * e2ap_recv = 0;
asn_dec_rval_t dec_res = asn_decode(0,ATS_ALIGNED_BASIC_PER, &asn_DEF_E2N_E2AP_PDU, (void**)&(e2ap_recv), data, data_size);
+ if(dec_res.code != RC_OK)
+ std::cerr <<"Error = " << strerror(errno) << std::endl;
+
REQUIRE(dec_res.code == RC_OK);
res = control_request_pdu.get_fields(e2ap_recv->choice.initiatingMessage, dout);
din_string.assign((char *)dinput.control_header, dout.control_header_size);
dout_string.assign((char *)dout.control_header, dout.control_header_size);
REQUIRE(din_string == dout_string);
+
+ din_string.assign((char *)dinput.control_msg, dout.control_msg_size);
+ dout_string.assign((char *)dout.control_msg, dout.control_msg_size);
+ REQUIRE(din_string == dout_string);
+
+ din_string.assign((char *)dinput.call_process_id, dout.call_process_id_size);
+ dout_string.assign((char *)dout.call_process_id, dout.call_process_id_size);
+ REQUIRE(din_string == dout_string);
+
+
ASN_STRUCT_FREE(asn_DEF_E2N_E2AP_PDU, e2ap_recv);
unsigned char buf_header[BUFFER_SIZE];
unsigned char buf_msg[BUFFER_SIZE];
+ unsigned char buf_callproc[BUFFER_SIZE];
ric_indication test_check;
SECTION("Incorrect E2AP Indication PDU"){
strcpy((char *)buf_header, "X2AP Header");
strcpy((char *)buf_msg, "X2AP_Message");
+ strcpy((char *)buf_callproc, "Call Process ID=10");
dinput.indication_header = buf_header;
dinput.indication_header_size = strlen((const char *)buf_header);
dinput.indication_msg = buf_msg;
dinput.indication_msg_size = strlen((const char *)buf_msg);
-
+
+ dinput.call_process_id = buf_callproc;
+ dinput.call_process_id_size = strlen((const char *)buf_callproc);
/* encoding */
size_t data_size = 512;
std::string dout_string((const char*)dout.indication_header, dout.indication_header_size);
REQUIRE(din_string == dout_string);
+ din_string.assign((const char *)dinput.indication_msg, dinput.indication_msg_size);
+ dout_string.assign((const char*)dout.indication_msg, dout.indication_msg_size);
+ REQUIRE(din_string == dout_string);
+
+ din_string.assign((const char *)dinput.call_process_id, dinput.call_process_id_size);
+ dout_string.assign((const char*)dout.call_process_id, dout.call_process_id_size);
+ REQUIRE(din_string == dout_string);
+
res = indication_pdu.get_fields(NULL, dout);
REQUIRE(res == false);