From: Ashwin Sridharan Date: Tue, 17 Dec 2019 21:32:53 +0000 (-0500) Subject: Initialization script now passes signal to xapp process X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=commitdiff_plain;h=6f5a7b69bb045ed82506e14cef9b0cdc6554a613;p=ric-app%2Fadmin.git Initialization script now passes signal to xapp process Added processing of call process id in e2ap indication/control process Signed-off-by: Ashwin Sridharan Change-Id: Ib896516f171bcaf8590e565b41a93b1af43b0bc7 --- diff --git a/container-tag.yaml b/container-tag.yaml index b72de81..8173df3 100644 --- a/container-tag.yaml +++ b/container-tag.yaml @@ -1,2 +1,2 @@ --- -tag: '1.0.1' +tag: '1.0.2' diff --git a/init/init_script.py b/init/init_script.py index f357f90..1d6e501 100644 --- a/init/init_script.py +++ b/init/init_script.py @@ -28,8 +28,19 @@ 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); @@ -113,6 +124,10 @@ def getEnvs(config): return True; + +# Global variables ... +xapp_subprocess = None; +xapp_pid = None; ParseSection = {}; xapp_port = 0; ParseSection["rmr"] = getRMRTable; @@ -137,7 +152,7 @@ if __name__ == "__main__": 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: @@ -153,5 +168,22 @@ if __name__ == "__main__": 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; + diff --git a/src/E2AP-c/e2ap_control.cc b/src/E2AP-c/e2ap_control.cc index ccb8703..036d704 100644 --- a/src/E2AP-c/e2ap_control.cc +++ b/src/E2AP-c/e2ap_control.cc @@ -193,6 +193,18 @@ bool ric_control_request::set_fields(E2N_InitiatingMessage_t *initMsg, ric_contr *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; }; @@ -241,7 +253,6 @@ bool ric_control_request:: get_fields(E2N_InitiatingMessage_t * init_msg, ric_c dout.control_ack = memb_ptr->value.choice.RICcontrolAckRequest; break; - default: break; } diff --git a/src/E2AP-c/e2ap_control.hpp b/src/E2AP-c/e2ap_control.hpp index f29ddc5..bbdf987 100644 --- a/src/E2AP-c/e2ap_control.hpp +++ b/src/E2AP-c/e2ap_control.hpp @@ -37,7 +37,7 @@ #include #include -#define NUM_CONTROL_REQUEST_IES 5 +#define NUM_CONTROL_REQUEST_IES 6 class ric_control_request{ diff --git a/src/E2AP-c/e2ap_control_helper.hpp b/src/E2AP-c/e2ap_control_helper.hpp index 2787ef9..904e836 100644 --- a/src/E2AP-c/e2ap_control_helper.hpp +++ b/src/E2AP-c/e2ap_control_helper.hpp @@ -1,6 +1,34 @@ +/* +================================================================================== + + 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{ diff --git a/src/E2AP-c/e2ap_indication.cc b/src/E2AP-c/e2ap_indication.cc index 237c80c..5dd17c2 100644 --- a/src/E2AP-c/e2ap_indication.cc +++ b/src/E2AP-c/e2ap_indication.cc @@ -199,6 +199,20 @@ bool ric_indication::set_fields(E2N_InitiatingMessage_t *initMsg, ric_indication 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; }; @@ -249,6 +263,10 @@ bool ric_indication:: get_fields(E2N_InitiatingMessage_t * init_msg, ric_indica 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; diff --git a/src/E2AP-c/e2ap_indication.hpp b/src/E2AP-c/e2ap_indication.hpp index eede7a0..af43086 100644 --- a/src/E2AP-c/e2ap_indication.hpp +++ b/src/E2AP-c/e2ap_indication.hpp @@ -35,48 +35,33 @@ #include #include #include +#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_ */ diff --git a/src/E2AP-c/e2ap_indication_helper.hpp b/src/E2AP-c/e2ap_indication_helper.hpp new file mode 100644 index 0000000..276a2a7 --- /dev/null +++ b/src/E2AP-c/e2ap_indication_helper.hpp @@ -0,0 +1,47 @@ +/* +================================================================================== + + 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 diff --git a/src/message_processor_class.cc b/src/message_processor_class.cc index e2edaf4..b5b421a 100644 --- a/src/message_processor_class.cc +++ b/src/message_processor_class.cc @@ -62,8 +62,6 @@ bool message_processor::operator()(rmr_mbuf_t *message){ _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); @@ -75,10 +73,7 @@ bool message_processor::operator()(rmr_mbuf_t *message){ 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: @@ -89,10 +84,6 @@ bool message_processor::operator()(rmr_mbuf_t *message){ break; } - //pfile = fopen(filename.c_str(), "wb"); - //fwrite(message->payload, sizeof(char), message->len, pfile); - //fclose(pfile); - e2ap_recv_pdu = 0; e2sm_header = 0; @@ -108,9 +99,11 @@ bool message_processor::operator()(rmr_mbuf_t *message){ 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 ++; @@ -158,7 +151,7 @@ bool message_processor::operator()(rmr_mbuf_t *message){ // 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); @@ -220,7 +213,9 @@ bool message_processor::operator()(rmr_mbuf_t *message){ 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)){ diff --git a/test/run_tests.sh b/test/run_tests.sh index a724bc3..13ba4bf 100755 --- a/test/run_tests.sh +++ b/test/run_tests.sh @@ -1,7 +1,8 @@ #! /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 diff --git a/test/unit_test_e2ap_control.cc b/test/unit_test_e2ap_control.cc index 7164074..a4a56d5 100644 --- a/test/unit_test_e2ap_control.cc +++ b/test/unit_test_e2ap_control.cc @@ -46,6 +46,7 @@ TEST_CASE("E2AP Control Request", "Encoding/Decoding"){ 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"){ @@ -56,16 +57,17 @@ TEST_CASE("E2AP Control Request", "Encoding/Decoding"){ 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; @@ -76,6 +78,9 @@ TEST_CASE("E2AP Control Request", "Encoding/Decoding"){ 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); @@ -92,6 +97,16 @@ TEST_CASE("E2AP Control Request", "Encoding/Decoding"){ 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); diff --git a/test/unit_test_e2ap_indication.cc b/test/unit_test_e2ap_indication.cc index 241337f..f35f4f9 100644 --- a/test/unit_test_e2ap_indication.cc +++ b/test/unit_test_e2ap_indication.cc @@ -45,6 +45,7 @@ TEST_CASE("E2AP Indication", "Encoding/Decoding"){ 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"){ @@ -71,13 +72,16 @@ TEST_CASE("E2AP Indication", "Encoding/Decoding"){ 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; @@ -156,6 +160,14 @@ TEST_CASE("E2AP Indication", "Encoding/Decoding"){ 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);