SIM-118: Enable to set RAN function id via environment variable 22/12922/1
authorTuan Nguyen <hoang.su.tk@gmail.com>
Thu, 23 May 2024 11:35:44 +0000 (11:35 +0000)
committerTuan Nguyen <hoang.su.tk@gmail.com>
Thu, 23 May 2024 11:35:44 +0000 (11:35 +0000)
Improve log message, remove unused files

Change-Id: Ie1b7fa634c6f2db434f064784b92b42a89993aa2
Signed-off-by: Tuan Nguyen <hoang.su.tk@gmail.com>
e2sim/e2sm_examples/kpm_e2sm/e2sim-dev_1.0.0_amd64.deb [deleted file]
e2sim/e2sm_examples/kpm_e2sm/e2sim_1.0.0_amd64.deb [deleted file]
e2sim/e2sm_examples/kpm_e2sm/src/kpm/kpm_callbacks.cpp
e2sim/src/DEF/e2sim_defs.h
e2sim/src/base/e2sim.cpp
e2sim/src/messagerouting/e2ap_asn1c_codec.c
e2sim/src/messagerouting/e2ap_message_handler.cpp

diff --git a/e2sim/e2sm_examples/kpm_e2sm/e2sim-dev_1.0.0_amd64.deb b/e2sim/e2sm_examples/kpm_e2sm/e2sim-dev_1.0.0_amd64.deb
deleted file mode 100755 (executable)
index 7abedad..0000000
Binary files a/e2sim/e2sm_examples/kpm_e2sm/e2sim-dev_1.0.0_amd64.deb and /dev/null differ
diff --git a/e2sim/e2sm_examples/kpm_e2sm/e2sim_1.0.0_amd64.deb b/e2sim/e2sm_examples/kpm_e2sm/e2sim_1.0.0_amd64.deb
deleted file mode 100755 (executable)
index 7dda0da..0000000
Binary files a/e2sim/e2sm_examples/kpm_e2sm/e2sim_1.0.0_amd64.deb and /dev/null differ
index 59bd744..2c94856 100755 (executable)
@@ -50,11 +50,13 @@ extern "C" {
 #include "viavi_connector.hpp"
 #include "errno.h"
 #include "e2sim_defs.h"
+#include <cstdlib>
+
 using json = nlohmann::json;
 
 using namespace std;
 class E2Sim;
-
+int gFuncId;
 
 E2Sim e2sim;
 
@@ -97,10 +99,12 @@ int main(int argc, char* argv[]) {
   ranfunc_ostr->buf = (uint8_t*)calloc(1,er.encoded);
   ranfunc_ostr->size = er.encoded;
   memcpy(ranfunc_ostr->buf,e2smbuffer,er.encoded);
-  e2sim.register_e2sm(0,ranfunc_ostr);
-  e2sim.register_subscription_callback(0,&callback_kpm_subscription_request);
 
+  const char* func_id_str = std::getenv("RAN_FUNC_ID");
+  ::gFuncId = func_id_str == nullptr ? 0 : std::stoi(func_id_str);
+
+  e2sim.register_e2sm(gFuncId, ranfunc_ostr);
+  e2sim.register_subscription_callback(gFuncId, &callback_kpm_subscription_request);
   e2sim.run_loop(argc, argv);
 
 }
@@ -337,7 +341,7 @@ void run_report_loop(long requestorId, long instanceId, long ranFunctionId, long
                                LOG_I("Buffer of size %zu is too small for %s, need %zu\n", e2sm_message_buf_size_cucp_ue, asn_DEF_E2SM_KPM_IndicationMessage.name, er_message_cucp_ue.encoded);
                                exit(1);
                        } else {
-                               LOG_I("Encoded UE indication message succesfully, size in bytes: %d", er_message_cucp_ue.encoded)
+                               LOG_I("Encoded UE indication message succesfully, size in bytes: %zu", er_message_cucp_ue.encoded)
                        }
 
                        ASN_STRUCT_FREE(asn_DEF_E2SM_KPM_IndicationMessage, ind_msg_cucp_ue); 
@@ -362,7 +366,7 @@ void run_report_loop(long requestorId, long instanceId, long ranFunctionId, long
                                LOG_I("Buffer of size %zu is too small for %s, need %zu\n", e2sm_header_buf_size_cucp_ue, asn_DEF_E2SM_KPM_IndicationHeader.name, er_header_cucp_ue.encoded);
                                exit(1);
                        } else {
-                               LOG_I("Encoded UE indication header succesfully, size in bytes: %d", er_header_cucp_ue.encoded);
+                               LOG_I("Encoded UE indication header succesfully, size in bytes: %zu", er_header_cucp_ue.encoded);
                                for(int i = 0; i < er_header_cucp_ue.encoded; i ++) {
                                        printf("%x ", e2sm_header_buf_cucp_ue[i]);
                                }
@@ -381,7 +385,7 @@ void run_report_loop(long requestorId, long instanceId, long ranFunctionId, long
                                                                                        er_message_cucp_ue.encoded);
                        
                        e2sim.encode_and_send_sctp_data(pdu_cucp_ue);
-                       LOG_I("Measurement report for UE %d has been sent\n", i);
+                       LOG_I("Measurement report for UE %d has been sent", i);
                        seqNum++;
                        std::this_thread::sleep_for (std::chrono::milliseconds(50));
                }
@@ -473,13 +477,13 @@ void run_report_loop(long requestorId, long instanceId, long ranFunctionId, long
                                                                                e2sm_message_buf_style1, e2sm_message_buf_size_style1);
                        
                        if(er_message_style1.encoded == -1) {
-                               LOG_I("Failed to serialize data. Detail: %s.\n", asn_DEF_E2SM_KPM_IndicationMessage.name);
+                               LOG_I("Failed to serialize data. Detail: %s.", asn_DEF_E2SM_KPM_IndicationMessage.name);
                                exit(1);
                        } else if(er_message_style1.encoded > e2sm_message_buf_size_style1) {
                                LOG_I("Buffer of size %zu is too small for %s, need %zu\n", e2sm_message_buf_size_style1, asn_DEF_E2SM_KPM_IndicationMessage.name, er_message_style1.encoded);
                                exit(1);
                        } else {
-                               LOG_I("Encoded Cell indication message succesfully, size in bytes: %d", er_message_style1.encoded)
+                               LOG_I("Encoded Cell indication message succesfully, size in bytes: %ld", er_message_style1.encoded)
                        }
 
                        ASN_STRUCT_FREE(asn_DEF_E2SM_KPM_IndicationMessage, ind_message_style1);
@@ -531,8 +535,6 @@ void run_report_loop(long requestorId, long instanceId, long ranFunctionId, long
 
 void callback_kpm_subscription_request(E2AP_PDU_t *sub_req_pdu) {
 
-  fprintf(stderr, "[%s:%d]Calling callback_kpm_subscription_request");
-
   //Record RIC Request ID
   //Go through RIC action to be Setup List
   //Find first entry with REPORT action Type
@@ -563,79 +565,70 @@ void callback_kpm_subscription_request(E2AP_PDU_t *sub_req_pdu) {
     RICsubscriptionRequest_IEs_t *next_ie = ies[i];
     pres = next_ie->value.present;
     
-    LOG_I("The next present value %d\n", pres);
+    LOG_I("The next present value %d", pres);
 
     switch(pres) {
-    case RICsubscriptionRequest_IEs__value_PR_RICrequestID:
-      {
-       LOG_I("in case request id");    
-       RICrequestID_t reqId = next_ie->value.choice.RICrequestID;
-       long requestorId = reqId.ricRequestorID;
-       long instanceId = reqId.ricInstanceID;
-       LOG_I("requestorId %d\n", requestorId);
-       LOG_I("instanceId %d\n", instanceId);
-       reqRequestorId = requestorId;
-       reqInstanceId = instanceId;
-
-       break;
-      }
-    case RICsubscriptionRequest_IEs__value_PR_RANfunctionID:
-      {
-       LOG_I("in case ran func id");   
-       break;
-      }
-    case RICsubscriptionRequest_IEs__value_PR_RICsubscriptionDetails:
-      {
-       RICsubscriptionDetails_t subDetails = next_ie->value.choice.RICsubscriptionDetails;
-       RICeventTriggerDefinition_t triggerDef = subDetails.ricEventTriggerDefinition;
-       RICactions_ToBeSetup_List_t actionList = subDetails.ricAction_ToBeSetup_List;
-       //We are ignoring the trigger definition
-
-       //We identify the first action whose type is REPORT
-       //That is the only one accepted; all others are rejected
-       
-       int actionCount = actionList.list.count;
-       LOG_I("Action count%d\n", actionCount);
+               case RICsubscriptionRequest_IEs__value_PR_RICrequestID: {
+                       LOG_I("in case request id");
+                       RICrequestID_t reqId = next_ie->value.choice.RICrequestID;
+                       long requestorId = reqId.ricRequestorID;
+                       long instanceId = reqId.ricInstanceID;
 
-       auto **item_array = actionList.list.array;
+                       LOG_I("requestorId: %ld, InstanceID: %ld", requestorId, instanceId);
 
-       bool foundAction = false;
+                       reqRequestorId = requestorId;
+                       reqInstanceId = instanceId;
 
-       for (int i=0; i < actionCount; i++) {
+                       break;
+               }
+               case RICsubscriptionRequest_IEs__value_PR_RANfunctionID: {
+                       LOG_I("in case ran func id");
+                       break;
+               }
+               case RICsubscriptionRequest_IEs__value_PR_RICsubscriptionDetails: {
+                       RICsubscriptionDetails_t subDetails = next_ie->value.choice.RICsubscriptionDetails;
+                       RICeventTriggerDefinition_t triggerDef = subDetails.ricEventTriggerDefinition;
+                       RICactions_ToBeSetup_List_t actionList = subDetails.ricAction_ToBeSetup_List;
+                       //We are ignoring the trigger definition
 
-         auto *next_item = item_array[i];
-         RICactionID_t actionId = ((RICaction_ToBeSetup_ItemIEs*)next_item)->value.choice.RICaction_ToBeSetup_Item.ricActionID;
-         RICactionType_t actionType = ((RICaction_ToBeSetup_ItemIEs*)next_item)->value.choice.RICaction_ToBeSetup_Item.ricActionType;
+                       //We identify the first action whose type is REPORT
+                       //That is the only one accepted; all others are rejected
 
-         if (!foundAction && actionType == RICactionType_report) {
-           reqActionId = actionId;
-           actionIdsAccept.push_back(reqActionId);
-           foundAction = true;
-         } else {
-           reqActionId = actionId;
-           actionIdsReject.push_back(reqActionId);
-         }
-       }
-       
-       break;
-      }
-    default:
-      {
-       break;
-      }      
+                       int actionCount = actionList.list.count;
+                       LOG_I("Action count%d", actionCount);
+
+                       auto **item_array = actionList.list.array;
+
+                       bool foundAction = false;
+
+                       for (int i=0; i < actionCount; i++) {
+                               auto *next_item = item_array[i];
+                               RICactionID_t actionId = ((RICaction_ToBeSetup_ItemIEs*)next_item)->value.choice.RICaction_ToBeSetup_Item.ricActionID;
+                               RICactionType_t actionType = ((RICaction_ToBeSetup_ItemIEs*)next_item)->value.choice.RICaction_ToBeSetup_Item.ricActionType;
+
+                               if (!foundAction && actionType == RICactionType_report) {
+                                       reqActionId = actionId;
+                                       actionIdsAccept.push_back(reqActionId);
+                                       foundAction = true;
+                               } else {
+                                       reqActionId = actionId;
+                                       actionIdsReject.push_back(reqActionId);
+                               }
+                       }
+
+                       break;
+               }
+               default: {
+                       break;
+               }
     }
     
   }
 
   LOG_I("After Processing Subscription Request");
 
-  LOG_I("requestorId %d\n", reqRequestorId);
-  LOG_I("instanceId %d\n", reqInstanceId);
-
-
   for (int i=0; i < actionIdsAccept.size(); i++) {
-    LOG_I("Action ID %d %ld\n", i, actionIdsAccept.at(i));
-    
+    LOG_D("Action ID %d %ld\n", i, actionIdsAccept.at(i));
   }
 
   E2AP_PDU *e2ap_pdu = (E2AP_PDU*)calloc(1,sizeof(E2AP_PDU));
@@ -650,8 +643,7 @@ void callback_kpm_subscription_request(E2AP_PDU_t *sub_req_pdu) {
   LOG_I("Encode and sending E2AP subscription success response via SCTP");
   e2sim.encode_and_send_sctp_data(e2ap_pdu);
 
-  long funcId = 0;
-
-  run_report_loop(reqRequestorId, reqInstanceId, funcId, reqActionId);
+  LOG_I("Now generating data for subscription request");
+  run_report_loop(reqRequestorId, reqInstanceId, gFuncId, reqActionId);
 
 }
index d2407a8..dc469ba 100755 (executable)
@@ -49,12 +49,40 @@ char* time_stamp(void);
         else { \
             fileName = file; \
         } \
-        printf("[%s:%d] ", fileName, __LINE__); \
-        printf(format, ##__VA_ARGS__); \
-        printf("\n"); \
+        fprintf(stderr, "[%s:%d] [INFO] ", fileName, __LINE__); \
+        fprintf(stderr, format, ##__VA_ARGS__); \
+        fprintf(stderr, "\n"); \
+    } while (0);
+
+#define LOG_D(format, ...) \
+    do { \
+        const char *file = __FILE__; \
+        const char *fileName = strrchr(file, '/'); \
+        if (fileName != NULL) { \
+            fileName++; \
+        } \
+        else { \
+            fileName = file; \
+        } \
+        fprintf(stderr, "[%s:%d] [DEBUG] ", fileName, __LINE__); \
+        fprintf(stderr, format, ##__VA_ARGS__); \
+        fprintf(stderr, "\n"); \
+    } while (0);
+
+#define LOG_E(format, ...) \
+    do { \
+        const char *file = __FILE__; \
+        const char *fileName = strrchr(file, '/'); \
+        if (fileName != NULL) { \
+            fileName++; \
+        } \
+        else { \
+            fileName = file; \
+        } \
+        fprintf(stderr, "[%s:%d] [ERROR] ", fileName, __LINE__); \
+        fprintf(stderr, format, ##__VA_ARGS__); \
+        fprintf(stderr, "\n"); \
     } while (0);
-#define LOG_E(...) {printf(__VA_ARGS__); printf("\n");}
-#define LOG_D(...) {printf(__VA_ARGS__); printf("\n");}
 
 typedef struct SCTP_DATA {
   unsigned char *data;
index 83535b3..6203171 100755 (executable)
@@ -40,7 +40,7 @@ std::unordered_map<long, OCTET_STRING_t*> E2Sim::getRegistered_ran_functions() {
 }
 
 void E2Sim::register_subscription_callback(long func_id, SubscriptionCallback cb) {
-  LOG_I("About to register callback for subscription for func_id %d", func_id);
+  LOG_I("About to register callback for subscription for RAN function with ID %d", func_id);
   subscription_callbacks[func_id] = cb;
   
 }
@@ -62,7 +62,7 @@ void E2Sim::register_e2sm(long func_id, OCTET_STRING_t *ostr) {
 
   //Error conditions:
   //If we already have an entry for func_id
-  LOG_I("About to register e2sm func desc for %d", func_id);
+  LOG_I("About to register E2SM RAN function description with ID %d", func_id);
   ran_functions_registered[func_id] = ostr;
 }
 
@@ -101,7 +101,7 @@ void E2Sim::generate_e2apv1_indication_request_parameterized(E2AP_PDU *e2ap_pdu,
 
 int E2Sim::run_loop(int argc, char* argv[]){
 
-  printf("Start E2 Agent (E2 Simulator\n");
+  LOG_I("Start E2 Agent (E2 Simulator)");
 
   ifstream simfile;
   string line;
@@ -122,7 +122,7 @@ int E2Sim::run_loop(int argc, char* argv[]){
 
   options_t ops = read_input_options(argc, argv);
 
-  printf("After reading input options\n");
+  LOG_I("After reading input options");
 
   //E2 Agent will automatically restart upon sctp disconnection
   //  int server_fd = sctp_start_server(ops.server_ip, ops.server_port);
@@ -130,8 +130,7 @@ int E2Sim::run_loop(int argc, char* argv[]){
   client_fd = sctp_start_client(ops.server_ip, ops.server_port);
   E2AP_PDU_t* pdu_setup = (E2AP_PDU_t*)calloc(1,sizeof(E2AP_PDU));
 
-  printf("After starting client\n");
-  printf("client_fd value is %d\n", client_fd);
+  LOG_I("SCTP client has been started");
   
   std::vector<encoding::ran_func_info> all_funcs;
   RANfunctionOID_t *ranFunctionOIDe = (RANfunctionOID_t*)calloc(1,sizeof(RANfunctionOID_t));
@@ -141,9 +140,14 @@ int E2Sim::run_loop(int argc, char* argv[]){
   ranFunctionOIDe->size = strlen((char*)buf);
 
   //Loop through RAN function definitions that are registered
-
+  LOG_I("Constructing a list of RAN functions based on registered information");
   for (std::pair<long, OCTET_STRING_t*> elem : ran_functions_registered) {
-    printf("looping through ran func\n");
+    char* ran_desc = (char*) calloc(1, elem.second->size+1);
+    ran_desc = (char*)elem.second->buf;
+    ran_desc[elem.second->size] = '\0';
+
+    LOG_I("Adding RAN function ID %ld, description: %s to the list", elem.first, ran_desc);
+
     encoding::ran_func_info next_func;
 
     next_func.ranFunctionId = elem.first;
@@ -154,15 +158,11 @@ int E2Sim::run_loop(int argc, char* argv[]){
     all_funcs.push_back(next_func);
   }
     
-  printf("about to call setup request encode\n");
+  LOG_I("Generate E2AP v1 setup request for all registered RAN functions");
   generate_e2apv1_setup_request_parameterized(pdu_setup, all_funcs);
 
-  printf("After generating e2setup req\n");
-
   xer_fprint(stderr, &asn_DEF_E2AP_PDU, pdu_setup);
 
-  printf("After XER Encoding\n");
-
   auto buffer_size = MAX_SCTP_BUFFER;
   unsigned char buffer[MAX_SCTP_BUFFER];
   
@@ -172,66 +172,41 @@ int E2Sim::run_loop(int argc, char* argv[]){
   size_t errlen = 0;
 
   asn_check_constraints(&asn_DEF_E2AP_PDU, pdu_setup, error_buf, &errlen);
-  printf("error length %d\n", errlen);
-  printf("error buf %s\n", error_buf);
+  LOG_I("Error length %d, error buf %s", errlen, error_buf);
 
   auto er = asn_encode_to_buffer(nullptr, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2AP_PDU, pdu_setup, buffer, buffer_size);
 
   data.len = er.encoded;
 
-  fprintf(stderr, "er encded is %d\n", er.encoded);
+  LOG_I("Error encoded %d", er.encoded);
 
   memcpy(data.buffer, buffer, er.encoded);
 
   if(sctp_send_data(client_fd, data) > 0) {
-    LOG_I("[SCTP] Sent E2-SETUP-REQUEST");
+    LOG_I("Sent E2-SETUP-REQUEST as E2AP message");
   } else {
-    LOG_E("[SCTP] Unable to send E2-SETUP-REQUEST to peer");
+    LOG_E("Fail to send E2-SETUP-REQUEST to peer");
   }
 
   buffer_size = MAX_SCTP_BUFFER;
   memset(buffer, '\0', sizeof(buffer));
-  E2AP_PDU_t* pdu = (E2AP_PDU_t*)calloc(1,sizeof(E2AP_PDU));
-
-  LOG_D("about to call E2ResetRequest encode\n");
-
-  encoding::generate_e2apv2_reset_request(pdu);
-
-  LOG_D("[E2AP] Created E2ResetRequest");
-
-  e2ap_asn1c_print_pdu(pdu);
-
-  sctp_buffer_t resetdata;
-
-  error_buf[300] = {0, };
-   errlen = 0;
-
-  asn_check_constraints(&asn_DEF_E2AP_PDU, pdu, error_buf, &errlen);
-  printf("error length %d\n", errlen);
-  printf("error buf %s\n", error_buf);
-  er = asn_encode_to_buffer(nullptr, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2AP_PDU, pdu, buffer, buffer_size);
-
-  resetdata.len = er.encoded;
-  fprintf(stderr, "er encoded is %d\n", er.encoded);
-
-  memcpy(resetdata.buffer, buffer, er.encoded);
-
-  LOG_I("Test to delete ReSet code");
 
   sctp_buffer_t recv_buf;
 
-  LOG_I("[SCTP] Waiting for SCTP data");
+  LOG_I("Waiting for SCTP data");
 
   while(1) //constantly looking for data on SCTP interface
   {
     if(sctp_receive_data(client_fd, recv_buf) <= 0)
       break;
 
-    LOG_I("[SCTP] Received new data of size %d", recv_buf.len);
+    LOG_I("Received new data of size %d", recv_buf.len);
 
     e2ap_handle_sctp_data(client_fd, recv_buf, xmlenc, this);
     if (xmlenc) xmlenc = false;
   }
 
+  close(client_fd);
+
   return 0;
 }
index b17431e..8e1bff2 100755 (executable)
 
 void e2ap_asn1c_print_pdu(const E2AP_PDU_t* pdu)
 {
-  printf("before\n");
   //  xer_fprint(stdout, &asn_DEF_E2AP_PDU, (void *)pdu);
   xer_fprint(stdout, &asn_DEF_E2AP_PDU, pdu);
-  printf("after\n");
-  printf("\n");
 }
 
 void asn1c_xer_print(asn_TYPE_descriptor_t *typeDescriptor, void *data)
 {
   xer_fprint(stdout, typeDescriptor, (void *)data);
-  printf("\n");
 }
 
 
@@ -208,7 +204,7 @@ int e2ap_asn1c_get_procedureCode(E2AP_PDU_t* pdu)
   switch(pdu->present)
   {
     case E2AP_PDU_PR_initiatingMessage:
-      fprintf(stderr,"initiating message\n");
+      LOG_I("Initiating E2AP PDU PR message");
       procedureCode = pdu->choice.initiatingMessage->procedureCode;
       break;
 
index ef21c13..7b712a7 100755 (executable)
@@ -46,13 +46,13 @@ void e2ap_handle_sctp_data(int& socket_fd, sctp_buffer_t& data, bool xmlenc, E2S
       break;\r
   }\r
 \r
-  int procedureCode = e2ap_asn1c_get_procedureCode(pdu);\r
-  int index = (int)pdu->present;\r
-\r
-  LOG_D("Unpacked E2AP-PDU: index = %d, procedureCode = %d\n", index, procedureCode);\r
-\r
-  switch (procedureCode) {\r
-    case ProcedureCode_id_E2setup:\r
+  int procedureCode = e2ap_asn1c_get_procedureCode(pdu);
+  int index = (int)pdu->present;
+
+  LOG_D("Unpacked E2AP-PDU: index = %d, procedureCode = %d", index, procedureCode);
+
+  switch (procedureCode) {
+    case ProcedureCode_id_E2setup:
       LOG_I("Received a message of E2 setup procedure");\r
       switch (index) {\r
         case E2AP_PDU_PR_initiatingMessage:\r
@@ -94,35 +94,26 @@ void e2ap_handle_sctp_data(int& socket_fd, sctp_buffer_t& data, bool xmlenc, E2S
       break;\r
 \r
     case ProcedureCode_id_RICsubscription:  // RIC SUBSCRIPTION = 201\r
-      LOG_I("Received a message of RIC subscription procedure");\r
-      switch (index) {\r
-        case E2AP_PDU_PR_initiatingMessage: {  // initiatingMessage\r
-          LOG_I("Received RIC-SUBSCRIPTION-REQUEST");\r
-          //          e2ap_handle_RICSubscriptionRequest(pdu, socket_fd);\r
-          long func_id = encoding::get_function_id_from_subscription(pdu);\r
-          fprintf(stderr, "Function Id of message is %d\n", func_id);\r
-          SubscriptionCallback cb;\r
-\r
-          bool func_exists = true;\r
-\r
-          try {\r
-            cb = e2sim->get_subscription_callback(func_id);\r
-          } catch (const std::out_of_range& e) {\r
-            func_exists = false;\r
-          }\r
-\r
-          if (func_exists) {\r
-            fprintf(stderr, "Calling callback function\n");\r
-            cb(pdu);\r
-          } else {\r
-            fprintf(stderr, "Error: No RAN Function with this ID exists\n");\r
-          }\r
-          //     callback_kpm_subscription_request(pdu, socket_fd);\r
-\r
-        } break;\r
-\r
-        case E2AP_PDU_PR_successfulOutcome:\r
-          LOG_I("Received RIC-SUBSCRIPTION-RESPONSE");\r
+      LOG_I("Received a message of RIC subscription procedure");
+      switch (index) {
+        case E2AP_PDU_PR_initiatingMessage: {  // initiatingMessage
+          long func_id = encoding::get_function_id_from_subscription(pdu);
+          LOG_I("Received RIC subscription request for function with ID %d", func_id);
+
+          try {
+            SubscriptionCallback cb;
+            cb = e2sim->get_subscription_callback(func_id);
+            LOG_I("Calling callback subscription function to handle subscription request to function with ID %d", func_id);
+            cb(pdu);
+          } catch (const std::out_of_range& e) {
+            LOG_E("No RAN Function with this ID exists\n");
+          }
+
+          break;
+        }
+
+        case E2AP_PDU_PR_successfulOutcome:
+          LOG_I("Received RIC-SUBSCRIPTION-RESPONSE");
           break;\r
 \r
         case E2AP_PDU_PR_unsuccessfulOutcome:\r