From 1f8413361c1b99ea46ee613da035803a1387f65c Mon Sep 17 00:00:00 2001
From: Robert Schmidt <robert.schmidt@openairinterface.org>
Date: Sun, 10 Apr 2022 14:25:38 +0200
Subject: [PATCH] Add E1AP lib

---
 common/utils/LOG/log.h                      |   1 +
 common/utils/T/T_messages.txt               |  21 ++
 common/utils/ocp_itti/intertask_interface.h |   2 +
 openair2/E1AP/CMakeLists.txt                |   6 +
 openair2/E1AP/e1ap.c                        | 385 ++++++++++++++++++++
 openair2/E1AP/e1ap.h                        |  34 ++
 6 files changed, 449 insertions(+)
 create mode 100644 openair2/E1AP/e1ap.c
 create mode 100644 openair2/E1AP/e1ap.h

diff --git a/common/utils/LOG/log.h b/common/utils/LOG/log.h
index 509c4581a92..bd017caf60e 100644
--- a/common/utils/LOG/log.h
+++ b/common/utils/LOG/log.h
@@ -219,6 +219,7 @@ typedef enum {
   SPGW,
   S1AP,
   F1AP,
+  E1AP,
   SCTP,
   HW,
   OSA,
diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt
index b3c06d6be8a..716c77823d5 100644
--- a/common/utils/T/T_messages.txt
+++ b/common/utils/T/T_messages.txt
@@ -1235,6 +1235,27 @@ ID = LEGACY_F1AP_ERROR
     GROUP = ALL:LEGACY_F1AP:LEGACY_GROUP_ERROR:LEGACY
     FORMAT = string,log
 
+ID = LEGACY_E1AP_TRACE
+    DESC = E1AP TRACE LEVEL
+    GROUP = ALL:LEGACY_E1AP:LEGACY_GROUP_TRACE:LEGACY
+    FORMAT = string,log
+ID = LEGACY_E1AP_DEBUG
+    DESC = E1AP DEBUG LEVEL
+    GROUP = ALL:LEGACY_E1AP:LEGACY_GROUP_DEBUG:LEGACY
+    FORMAT = string,log
+ID = LEGACY_E1AP_INFO
+    DESC = E1AP INFO LEVEL
+    GROUP = ALL:LEGACY_E1AP:LEGACY_GROUP_INFO:LEGACY
+    FORMAT = string,log
+ID = LEGACY_E1AP_WARNING
+    DESC = E1AP WARNING LEVEL
+    GROUP = ALL:LEGACY_E1AP:LEGACY_GROUP_WARNING:LEGACY
+    FORMAT = string,log
+ID = LEGACY_E1AP_ERROR
+    DESC = E1AP ERROR LEVEL
+    GROUP = ALL:LEGACY_E1AP:LEGACY_GROUP_ERROR:LEGACY
+    FORMAT = string,log
+
 #################
 #### UE LOGS ####
 #################
diff --git a/common/utils/ocp_itti/intertask_interface.h b/common/utils/ocp_itti/intertask_interface.h
index 9f1fcd17410..a8518af660c 100644
--- a/common/utils/ocp_itti/intertask_interface.h
+++ b/common/utils/ocp_itti/intertask_interface.h
@@ -339,6 +339,8 @@ void *rrc_enb_process_msg(void *);
   TASK_DEF(TASK_GTPV1_U,  TASK_PRIORITY_MED,  1000,NULL, NULL)\
   TASK_DEF(TASK_CU_F1,    TASK_PRIORITY_MED,  200, NULL, NULL) \
   TASK_DEF(TASK_DU_F1,    TASK_PRIORITY_MED,  200, NULL, NULL) \
+  TASK_DEF(TASK_CUCP_E1,  TASK_PRIORITY_MED,  200, NULL, NULL) \
+  TASK_DEF(TASK_CUUP_E1,  TASK_PRIORITY_MED,  200, NULL, NULL) \
   TASK_DEF(TASK_RRC_UE_SIM,   TASK_PRIORITY_MED,  200, NULL, NULL)  \
   TASK_DEF(TASK_RRC_GNB_SIM,  TASK_PRIORITY_MED,  200, NULL, NULL)  \
   TASK_DEF(TASK_RRC_NSA_UE,   TASK_PRIORITY_MED,  200, NULL, NULL)  \
diff --git a/openair2/E1AP/CMakeLists.txt b/openair2/E1AP/CMakeLists.txt
index 7537bd661d7..b600f64d6fa 100644
--- a/openair2/E1AP/CMakeLists.txt
+++ b/openair2/E1AP/CMakeLists.txt
@@ -1 +1,7 @@
 add_subdirectory(MESSAGES)
+
+add_library(E1AP e1ap.c)
+target_link_libraries(E1AP
+                        PUBLIC ASN1_E1AP_LIB
+                        PRIVATE UTIL)
+target_include_directories(E1AP PUBLIC ${CMAKE_CURRENT_DIR})
diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c
new file mode 100644
index 00000000000..b49f4d4ca1b
--- /dev/null
+++ b/openair2/E1AP/e1ap.c
@@ -0,0 +1,385 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (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.openairinterface.org/?page_id=698
+ *
+ * Author and copyright: Laurent Thomas, open-cells.com
+ *
+ * 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.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+#include "e1ap.h"
+
+int asn1_encoder_xer_print = 1;
+
+int e1ap_assoc_id(bool isCu, instance_t instance) {
+  return 0;
+}
+
+int e1ap_encode_send(bool isCu, instance_t instance, E1AP_E1AP_PDU_t *pdu, uint16_t stream, const char *func) {
+  DevAssert(pdu != NULL);
+
+  if (asn1_encoder_xer_print) {
+    LOG_E(E1AP, "----------------- ASN1 ENCODER PRINT START ----------------- \n");
+    xer_fprint(stdout, &asn_DEF_E1AP_E1AP_PDU, pdu);
+    LOG_E(E1AP, "----------------- ASN1 ENCODER PRINT END----------------- \n");
+  }
+
+  char errbuf[2048]; /* Buffer for error message */
+  size_t errlen = sizeof(errbuf); /* Size of the buffer */
+  int ret = asn_check_constraints(&asn_DEF_E1AP_E1AP_PDU, pdu, errbuf, &errlen);
+
+  if(ret) {
+    fprintf(stderr, "%s: Constraint validation failed: %s\n", func, errbuf);
+  }
+
+  void *buffer = NULL;
+  ssize_t encoded = aper_encode_to_new_buffer(&asn_DEF_E1AP_E1AP_PDU, 0, pdu, buffer);
+
+  if (encoded < 0) {
+    LOG_E(E1AP, "%s: Failed to encode E1AP message\n", func);
+    return -1;
+  } else {
+    MessageDef *message = itti_alloc_new_message(isCu?TASK_CUCP_E1:TASK_CUUP_E1, 0, SCTP_DATA_REQ);
+    sctp_data_req_t *s = &message->ittiMsg.sctp_data_req;
+    s->assoc_id      = e1ap_assoc_id(isCu,instance);
+    s->buffer        = buffer;
+    s->buffer_length = encoded;
+    s->stream        = stream;
+    LOG_I(E1AP, "%s: Sending ITTI message to SCTP Task\n", func);
+    itti_send_msg_to_task(TASK_SCTP, instance, message);
+  }
+
+  return encoded;
+}
+
+void e1ap_itti_send_sctp_close_association(bool isCu, instance_t instance) {
+  MessageDef *message = itti_alloc_new_message(TASK_S1AP, 0, SCTP_CLOSE_ASSOCIATION);
+  sctp_close_association_t *sctp_close_association = &message->ittiMsg.sctp_close_association;
+  sctp_close_association->assoc_id      = e1ap_assoc_id(isCu,instance);
+  itti_send_msg_to_task(TASK_SCTP, instance, message);
+}
+
+int e1ap_send_RESET(bool isCu, instance_t instance, E1AP_Reset_t *Reset) {
+  AssertFatal(false,"Not implemented yet\n");
+  E1AP_E1AP_PDU_t pdu= {0};
+  return e1ap_encode_send(isCu, instance, &pdu,0, __func__);
+}
+
+int e1ap_send_RESET_ACKNOWLEDGE(instance_t instance, E1AP_Reset_t *Reset) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1ap_handle_RESET(instance_t instance,
+                      uint32_t assoc_id,
+                      uint32_t stream,
+                      E1AP_E1AP_PDU_t *pdu) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1ap_handle_RESET_ACKNOWLEDGE(instance_t instance,
+                                  uint32_t assoc_id,
+                                  uint32_t stream,
+                                  E1AP_E1AP_PDU_t *pdu) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+/*
+    Error Indication
+*/
+int e1ap_handle_ERROR_INDICATION(instance_t instance,
+                                 uint32_t assoc_id,
+                                 uint32_t stream,
+                                 E1AP_E1AP_PDU_t *pdu) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1ap_send_ERROR_INDICATION(instance_t instance, E1AP_ErrorIndication_t *ErrorIndication) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+
+/*
+    E1 Setup: can be sent on both ways, to be refined
+*/
+
+int e1apCUUP_send_SETUP_REQUEST(instance_t instance, E1AP_Reset_t *Reset) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1apCUCP_send_SETUP_RESPONSE(instance_t instance) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1apCUCP_send_SETUP_FAILURE() {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1apCUCP_handle_SETUP_REQUEST(instance_t instance,
+                                  uint32_t assoc_id,
+                                  uint32_t stream,
+                                  E1AP_E1AP_PDU_t *pdu) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1apCUUP_handle_SETUP_RESPONSE(instance_t instance,
+                                   uint32_t assoc_id,
+                                   uint32_t stream,
+                                   E1AP_E1AP_PDU_t *pdu) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1apCUUP_handle_SETUP_FAILURE(instance_t instance,
+                                  uint32_t assoc_id,
+                                  uint32_t stream,
+                                  E1AP_E1AP_PDU_t *pdu) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+/*
+  E1 configuration update: can be sent in both ways, to be refined
+*/
+
+int e1apCUUP_send_gNB_DU_CONFIGURATION_UPDATE(instance_t instance) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1apCUCP_send_gNB_DU_CONFIGURATION_FAILURE(instance_t instance) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1apCUCP_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1apCUCP_handle_gNB_DU_CONFIGURATION_UPDATE(instance_t instance,
+    uint32_t assoc_id,
+    uint32_t stream,
+    E1AP_E1AP_PDU_t *pdu) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1apCUUP_handle_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
+    uint32_t assoc_id,
+    uint32_t stream,
+    E1AP_E1AP_PDU_t *pdu) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1apCUUP_handle_gNB_DU_CONFIGURATION_FAILURE(instance_t instance,
+    uint32_t assoc_id,
+    uint32_t stream,
+    E1AP_E1AP_PDU_t *pdu) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+/*
+  E1 release
+*/
+
+int e1ap_send_RELEASE_REQUEST(instance_t instance) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1ap_send_RELEASE_ACKNOWLEDGE(instance_t instance) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1ap_handle_RELEASE_REQUEST(instance_t instance,
+                                uint32_t assoc_id,
+                                uint32_t stream,
+                                E1AP_E1AP_PDU_t *pdu) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1ap_handle_RELEASE_ACKNOWLEDGE(instance_t instance,
+                                    uint32_t assoc_id,
+                                    uint32_t stream,
+                                    E1AP_E1AP_PDU_t *pdu) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+/*
+  BEARER CONTEXT SETUP REQUEST
+*/
+
+int e1apCUCP_send_BEARER_CONTEXT_SETUP_REQUEST(instance_t instance) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(instance_t instance) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1apCUUP_send_BEARER_CONTEXT_SETUP_FAILURE(instance_t instance) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1apCUUP_handle_BEARER_CONTEXT_SETUP_REQUEST(instance_t instance,
+                                                 uint32_t assoc_id,
+                                                 uint32_t stream,
+                                                 E1AP_E1AP_PDU_t *pdu) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1apCUCP_handle_BEARER_CONTEXT_SETUP_RESPONSE(instance_t instance,
+                                                  uint32_t assoc_id,
+                                                  uint32_t stream,
+                                                  E1AP_E1AP_PDU_t *pdu) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1apCUCP_handle_BEARER_CONTEXT_SETUP_FAILURE(instance_t instance,
+                                                 uint32_t assoc_id,
+                                                 uint32_t stream,
+                                                 E1AP_E1AP_PDU_t *pdu) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+/*
+  BEARER CONTEXT MODIFICATION REQUEST
+*/
+
+int e1apCUCP_send_BEARER_CONTEXT_MODIFICATION_REQUEST(instance_t instance) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_RESPONSE(instance_t instance) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_FAILURE(instance_t instance) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST(instance_t instance,
+                                                        uint32_t assoc_id,
+                                                        uint32_t stream,
+                                                        E1AP_E1AP_PDU_t *pdu) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1apCUCP_handle_BEARER_CONTEXT_MODIFICATION_RESPONSE(instance_t instance,
+                                                         uint32_t assoc_id,
+                                                         uint32_t stream,
+                                                         E1AP_E1AP_PDU_t *pdu) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1apCUCP_handle_BEARER_CONTEXT_MODIFICATION_FAILURE(instance_t instance,
+                                                        uint32_t assoc_id,
+                                                        uint32_t stream,
+                                                        E1AP_E1AP_PDU_t *pdu) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_REQUIRED(instance_t instance) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1apCUCP_send_BEARER_CONTEXT_MODIFICATION_CONFIRM(instance_t instance) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1apCUCP_handle_BEARER_CONTEXT_MODIFICATION_REQUIRED(instance_t instance,
+                                                         uint32_t assoc_id,
+                                                         uint32_t stream,
+                                                         E1AP_E1AP_PDU_t *pdu) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_CONFIRM(instance_t instance,
+                                                        uint32_t assoc_id,
+                                                        uint32_t stream,
+                                                        E1AP_E1AP_PDU_t *pdu) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+/*
+  BEARER CONTEXT RELEASE
+*/
+
+int e1apCUCP_send_BEARER_CONTEXT_RELEASE_COMMAND(instance_t instance) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(instance_t instance) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1apCUUP_send_BEARER_CONTEXT_RELEASE_REQUEST(instance_t instance) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1apCUUP_handle_BEARER_CONTEXT_RELEASE_COMMAND(instance_t instance,
+                                                   uint32_t assoc_id,
+                                                   uint32_t stream,
+                                                   E1AP_E1AP_PDU_t *pdu) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1apCUCP_handle_BEARER_CONTEXT_RELEASE_COMPLETE(instance_t instance,
+                                                    uint32_t assoc_id,
+                                                    uint32_t stream,
+                                                    E1AP_E1AP_PDU_t *pdu) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1apCUCP_handle_BEARER_CONTEXT_RELEASE_REQUEST(instance_t instance,
+                                                   uint32_t assoc_id,
+                                                   uint32_t stream,
+                                                   E1AP_E1AP_PDU_t *pdu) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+/*
+BEARER CONTEXT INACTIVITY NOTIFICATION
+ */
+
+int e1apCUUP_send_BEARER_CONTEXT_INACTIVITY_NOTIFICATION(instance_t instance) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1apCUCP_handle_BEARER_CONTEXT_INACTIVITY_NOTIFICATION(instance_t instance,
+                                                           uint32_t assoc_id,
+                                                           uint32_t stream,
+                                                           E1AP_E1AP_PDU_t *pdu) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+/*
+  DL DATA
+*/
+
+int e1apCUUP_send_DL_DATA_NOTIFICATION(instance_t instance) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1apCUUP_send_DATA_USAGE_REPORT(instance_t instance) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1apCUCP_handle_DL_DATA_NOTIFICATION(instance_t instance,
+                                         uint32_t assoc_id,
+                                         uint32_t stream,
+                                         E1AP_E1AP_PDU_t *pdu) {
+  AssertFatal(false,"Not implemented yet\n");
+}
+
+int e1apCUCP_handle_send_DATA_USAGE_REPORT(instance_t instance,
+                                           uint32_t assoc_id,
+                                           uint32_t stream,
+                                           E1AP_E1AP_PDU_t *pdu) {
+  AssertFatal(false,"Not implemented yet\n");
+}
diff --git a/openair2/E1AP/e1ap.h b/openair2/E1AP/e1ap.h
new file mode 100644
index 00000000000..c7b2c24e8bb
--- /dev/null
+++ b/openair2/E1AP/e1ap.h
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (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.openairinterface.org/?page_id=698
+ *
+ * Author and copyright: Laurent Thomas, open-cells.com
+ *
+ * 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.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+#ifndef __E1AP_H_
+#define __E1AP_H_
+
+#include <common/utils/LOG/log.h>
+#include "openairinterface5g_limits.h"
+#include <openair2/RRC/NR/MESSAGES/asn1_msg.h>
+
+#include <E1AP_Cause.h>
+#include <E1AP_InitiatingMessage.h>
+#include <E1AP_E1AP-PDU.h>
+#endif
-- 
GitLab