Initialization script now passes signal to xapp process 53/2053/1
authorAshwin Sridharan <asridharan@research.att.com>
Tue, 17 Dec 2019 21:32:53 +0000 (16:32 -0500)
committerAshwin Sridharan <asridharan@research.att.com>
Tue, 17 Dec 2019 21:32:53 +0000 (16:32 -0500)
Added processing of call process id in e2ap indication/control process

Signed-off-by: Ashwin Sridharan <asridharan@research.att.com>
Change-Id: Ib896516f171bcaf8590e565b41a93b1af43b0bc7

12 files changed:
container-tag.yaml
init/init_script.py
src/E2AP-c/e2ap_control.cc
src/E2AP-c/e2ap_control.hpp
src/E2AP-c/e2ap_control_helper.hpp
src/E2AP-c/e2ap_indication.cc
src/E2AP-c/e2ap_indication.hpp
src/E2AP-c/e2ap_indication_helper.hpp [new file with mode: 0644]
src/message_processor_class.cc
test/run_tests.sh
test/unit_test_e2ap_control.cc
test/unit_test_e2ap_indication.cc

index b72de81..8173df3 100644 (file)
@@ -1,2 +1,2 @@
 ---
-tag: '1.0.1'
+tag: '1.0.2'
index f357f90..1d6e501 100644 (file)
 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;
+                
index ccb8703..036d704 100644 (file)
@@ -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;
       }
index f29ddc5..bbdf987 100644 (file)
@@ -37,7 +37,7 @@
 #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{
index 2787ef9..904e836 100644 (file)
@@ -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{
index 237c80c..5dd17c2 100644 (file)
@@ -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;
index eede7a0..af43086 100644 (file)
 #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_ */
diff --git a/src/E2AP-c/e2ap_indication_helper.hpp b/src/E2AP-c/e2ap_indication_helper.hpp
new file mode 100644 (file)
index 0000000..276a2a7
--- /dev/null
@@ -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
index e2edaf4..b5b421a 100644 (file)
@@ -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)){
index a724bc3..13ba4bf 100755 (executable)
@@ -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
index 7164074..a4a56d5 100644 (file)
@@ -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); 
     
index 241337f..f35f4f9 100644 (file)
@@ -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);