[Epic-Id: ODUHIGH-576] [Task-Id: ODUHIGH-586] [SubTask-Id: ODUHIGH-587] PNF P5 Interf... 76/12776/5
authorsvaidhya <svaidhya@radisys.com>
Thu, 25 Apr 2024 11:23:16 +0000 (16:53 +0530)
committersvaidhya <svaidhya@radisys.com>
Thu, 2 May 2024 10:00:44 +0000 (15:30 +0530)
Change-Id: I381a146c16610d765c92403e2e205f8db861f20b
Signed-off-by: svaidhya <svaidhya@radisys.com>
19 files changed:
build/common/pnf_stub.mak [new file with mode: 0644]
build/config/fdd_odu_config.xml
build/config/startup_config.xml
build/config/tdd_odu_config.xml
build/odu/makefile
build/scripts/start_gnb.sh
build/scripts/start_pnf_stub_logging.sh [new file with mode: 0755]
src/5gnrmac/lwr_mac_ex_ms.c
src/5gnrmac/lwr_mac_nfapi.h
src/cm/lwr_mac_sctp_inf.h [new file with mode: 0644]
src/du_app/du_cfg.c
src/du_app/du_cfg.h
src/du_app/du_msg_hdl.c
src/du_app/du_sctp.c
src/intel_fapi/nfapi_interface.h
src/pnf_stub/pnf_stub.c [new file with mode: 0644]
src/pnf_stub/pnf_stub.h [new file with mode: 0644]
src/pnf_stub/pnf_stub_sctp.c [new file with mode: 0644]
src/pnf_stub/pnf_stub_sctp.h [new file with mode: 0644]

diff --git a/build/common/pnf_stub.mak b/build/common/pnf_stub.mak
new file mode 100644 (file)
index 0000000..4a7c14d
--- /dev/null
@@ -0,0 +1,56 @@
+################################################################################
+#   Copyright (c) [2017-2019] [Radisys]                                        #
+#                                                                              #
+#   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.                                             #
+################################################################################
+
+# This is makefile for PNF STUB
+
+include ../common/rsys_fancy.mak
+include ../common/env.mak
+COLOR=$(COLOR_RED)
+
+SRC_DIR=$(ROOT_DIR)/src/pnf_stub/
+C_SRCS=$(wildcard $(SRC_DIR)/*.c)
+C_OBJS=$(patsubst $(SRC_DIR)/%.c,$(OBJ_DIR)/%.o,$(C_SRCS))
+
+# prepare the list of common header files
+HDR_FILES+=$(wildcard $(CM_DIR)/env*.[hx])
+HDR_FILES+=$(wildcard $(CM_DIR)/gen*.[hx])
+HDR_FILES+=$(wildcard $(CM_DIR)/ssi*.[hx])
+HDR_FILES+=$(wildcard $(CM_DIR)/cm*.[hx])
+
+
+lib: $(LIB_DIR)/libpnf.a
+include $(COM_BUILD_DIR)/compile.mak
+
+I_OPTS+=-I$(ROOT_DIR)/src/mt
+
+#-------------------------------------------------------------#
+#Linker macros
+#-------------------------------------------------------------#
+$(LIB_DIR)/libpnf.a:$(C_OBJS)
+                 @echo -e "Creating Archive $(COLOR) $@ $(REVERT_COLOR)"
+                 $(Q)ar -cr $(LIB_DIR)/libpnf.a $(C_OBJS) 
+
+#-------------------------------------------------------------#
+#Clean macros
+#-------------------------------------------------------------#
+clean:
+                 @echo -e "$(COLOR_RED)Cleaning PNF STUB$(REVERT_COLOR)"
+                 @echo $(SRC_DIR) $(CM_DIR)
+                 $(Q)\rm -f $(LIB_DIR)/libpnf.a $(C_OBJS)
+
+#**********************************************************************
+#         End of file
+#**********************************************************************
index d61ad42..54a1100 100644 (file)
    <DU_IP_V4_ADDR>192.168.130.81</DU_IP_V4_ADDR>
    <CU_IP_V4_ADDR>192.168.130.82</CU_IP_V4_ADDR>
    <RIC_IP_V4_ADDR>192.168.130.80</RIC_IP_V4_ADDR>
+   <PNF_P5_IP_V4_ADDR>192.168.130.79</PNF_P5_IP_V4_ADDR>
    <SCTP>
       <F1_SCTP_PORT>38472</F1_SCTP_PORT>
       <E2_SCTP_PORT>36421</E2_SCTP_PORT>
-      <MAX_DU_PORT>2</MAX_DU_PORT>
+      <PNF_P5_SCTP_PORT>7701</PNF_P5_SCTP_PORT>
+      <MAX_DU_PORT>3</MAX_DU_PORT>
    </SCTP>
    <EGTP>
       <LOCAL_F1_EGTP_PORT>2152</LOCAL_F1_EGTP_PORT>
index 045c1c2..3a816c1 100644 (file)
 <interface-address>192.168.130.80</interface-address>
 <port>36422</port>
 </interface>
+<interface>
+<interface-name>pnf</interface-name>
+<interface-address>192.168.130.79</interface-address>
+<port>7701</port>
+</interface>
 </interfaces>
 </odu>
index de19fde..206303b 100644 (file)
    <DU_IP_V4_ADDR>192.168.130.81</DU_IP_V4_ADDR>
    <CU_IP_V4_ADDR>192.168.130.82</CU_IP_V4_ADDR>
    <RIC_IP_V4_ADDR>192.168.130.80</RIC_IP_V4_ADDR>
+   <PNF_P5_IP_V4_ADDR>192.168.130.79</PNF_P5_IP_V4_ADDR>
    <SCTP>
       <F1_SCTP_PORT>38472</F1_SCTP_PORT>
       <E2_SCTP_PORT>36421</E2_SCTP_PORT>
-      <MAX_DU_PORT>2</MAX_DU_PORT>
+      <PNF_P5_SCTP_PORT>7701</PNF_P5_SCTP_PORT>
+      <MAX_DU_PORT>3</MAX_DU_PORT>
    </SCTP>
    <EGTP>
       <LOCAL_F1_EGTP_PORT>2152</LOCAL_F1_EGTP_PORT>
index e1b0d40..90860b2 100644 (file)
@@ -74,7 +74,7 @@ endif
 # macro for output file name and makefile name
 #
 
-PLTFRM_FLAGS=-UMSPD -DODU -DINTEL_FAPI -UODU_MEMORY_DEBUG_LOG -DDEBUG_ASN_PRINT -UDEBUG_PRINT -DERROR_PRINT -USTART_DL_UL_DATA -UNR_DRX -UCALL_FLOW_DEBUG_LOG -UODU_SLOT_IND_DEBUG_LOG -UNFAPI_ENABLED
+PLTFRM_FLAGS=-UMSPD -DODU -DINTEL_FAPI -UODU_MEMORY_DEBUG_LOG -DDEBUG_ASN_PRINT -UDEBUG_PRINT -DERROR_PRINT -USTART_DL_UL_DATA -UNR_DRX -UCALL_FLOW_DEBUG_LOG -UODU_SLOT_IND_DEBUG_LOG -DNFAPI_ENABLED
 
 ifeq ($(MODE),TDD)
    PLTFRM_FLAGS += -DNR_TDD
@@ -152,13 +152,15 @@ help:
                @echo -e "$(RULE)odu       - Builds all components of ODU$(NORM)"
                @echo -e "$(RULE)cu_stub   - Builds all CU Stub$(NORM)"
                @echo -e "$(RULE)ric_stub   - Builds all RIC_Stub$(NORM)"
+               @echo -e "$(RULE)pnf_stub   - Builds all PNF_Stub$(NORM)"
                @echo -e "$(RULE)clean_odu - clean up ODU$(NORM)"
                @echo -e "$(RULE)clean_cu  - clean up CU Stub$(NORM)"
                @echo -e "$(RULE)clean_ric  - clean up RIC Stub$(NORM)"
+               @echo -e "$(RULE)clean_pnf  - clean up PNF Stub$(NORM)"
                @echo -e "$(RULE)clean_all - cleanup everything$(NORM)"
                @echo -e "$(OPTS)options: $(NORM)"
                @echo -e "$(OPTS)    MACHINE=BIT64/BIT32  - Default is BIT32$(NORM)"
-               @echo -e "$(OPTS)    NODE=TEST_STUB       - Mandatory option for cu_stub/ric_stub$(NORM)"
+               @echo -e "$(OPTS)    NODE=TEST_STUB       - Mandatory option for cu_stub/ric_stub/pnf_stub$(NORM)"
                @echo -e "$(OPTS)    MODE=TDD             - If not specified, MODE=FDD$(NORM)"
                @echo -e "$(OPTS)    PHY=INTEL_L1         - If not specified, Phy stub is used$(NORM)"
                @echo -e "$(OPTS)    PHY_MODE=TIMER       - Testing mode for INTEL_L1"
@@ -188,6 +190,13 @@ prepare_ric_dirs:
         $(Q)mkdir -p $(BIN_DIR)/ric_stub
         $(Q)echo -e "Directories are successfully prepared"
 
+prepare_pnf_dirs:
+        $(Q)echo -e "Preparing directories for build..."
+        $(Q)mkdir -p $(BUILD_DIR)/obj/pnf_stub
+        $(Q)mkdir -p $(LIB_ROOT)/pnf_stub
+        $(Q)mkdir -p $(BIN_DIR)/pnf_stub
+        $(Q)echo -e "Directories are successfully prepared"
+
 du:
                $(Q)$(MAKE) -j -f $(COM_BUILD_DIR)/asn_common.mak OBJ_DIR=$(OBJ_ROOT)/odu LIB_DIR=$(LIB_ROOT)/odu LOG_DIR=$(LOG_ROOT)/odu CC='$(CC1)'
                $(Q)$(MAKE) -j -f $(COM_BUILD_DIR)/asn_f1ap.mak OBJ_DIR=$(OBJ_ROOT)/odu LIB_DIR=$(LIB_ROOT)/odu LOG_DIR=$(LOG_ROOT)/odu CC='$(CC1)'
@@ -239,7 +248,7 @@ endif
           $(Q)rm -rf $(ROOT_DIR)/bin/odu
           $(Q)echo -e "***** ODU CLEAN COMPLETE *****"
 
-clean_all: clean_odu clean_cu clean_ric
+clean_all: clean_odu clean_cu clean_ric clean_pnf
                          $(Q)rm -rf $(OBJ_ROOT)
                          $(Q)rm -rf $(LIB_ROOT)
                          $(Q)rm -rf $(LOG_ROOT)
@@ -323,6 +332,29 @@ link_ric:
                $(Q)cp -f ../scripts/start_ric_stub_logging.sh $(ROOT_DIR)/bin/ric_stub
                $(Q)echo -e "***** RIC STUB BUILD COMPLETE *****"
 
+pnf: 
+        $(Q)$(MAKE) -j -f $(COM_BUILD_DIR)/pnf_stub.mak OBJ_DIR=$(OBJ_ROOT)/pnf_stub LIB_DIR=$(LIB_ROOT)/pnf_stub LOG_DIR=$(LOG_ROOT)/pnf_stub CC='$(CC1)'
+        $(Q)$(MAKE) -j -f $(COM_BUILD_DIR)/cm.mak OBJ_DIR=$(OBJ_ROOT)/pnf_stub LIB_DIR=$(LIB_ROOT)/pnf_stub LOG_DIR=$(LOG_ROOT)/pnf_stub CC='$(CC1)'
+        $(Q)$(MAKE) -j -f $(COM_BUILD_DIR)/mt.mak OBJ_DIR=$(OBJ_ROOT)/pnf_stub LIB_DIR=$(LIB_ROOT)/pnf_stub LOG_DIR=$(LOG_ROOT)/pnf_stub CC='$(CC1)'
+
+clean_pnf:
+        $(Q)$(MAKE) -j -f $(COM_BUILD_DIR)/pnf_stub.mak clean OBJ_DIR=$(OBJ_ROOT)/pnf_stub LIB_DIR=$(LIB_ROOT)/pnf_stub LOG_DIR=$(LOG_ROOT)/pnf_stub CC='$(CC1)'
+        $(Q)$(MAKE) -j -f $(COM_BUILD_DIR)/cm.mak clean OBJ_DIR=$(OBJ_ROOT)/pnf_stub LIB_DIR=$(LIB_ROOT)/pnf_stub LOG_DIR=$(LOG_ROOT)/pnf_stub CC='$(CC1)'
+        $(Q)$(MAKE) -j -f $(COM_BUILD_DIR)/mt.mak clean OBJ_DIR=$(OBJ_ROOT)/pnf_stub LIB_DIR=$(LIB_ROOT)/pnf_stub LOG_DIR=$(LOG_ROOT)/pnf_stub CC='$(CC1)'
+        $(Q)rm -rf $(OBJ_ROOT)/pnf_stub/*
+        $(Q)rm -rf $(LIB_ROOT)/pnf_stub/*
+        $(Q)rm -rf $(BIN_DIR)/pnf_stub/*
+        $(Q)rm -rf $(ROOT_DIR)/bin/pnf_stub
+        $(Q)echo -e "***** PNF STUB CLEAN COMPLETE *****"
+
+
+link_pnf: 
+               $(Q)$(CC1) -g -o $(OBJ_ROOT)/pnf_stub/pnf_stub -Wl,-R../lib/:. $(OBJ_ROOT)/pnf_stub/*.o\
+               $(L_OPTS) -L$(LIB_ROOT)/pnf_stub -L$(ROOT_DIR)/libs/pnf_stub
+               $(Q)cp -f ./obj/pnf_stub/pnf_stub ./bin/pnf_stub
+               $(Q)cp -rf ./bin/pnf_stub $(ROOT_DIR)/bin/
+               $(Q)cp -f ../scripts/start_pnf_stub_logging.sh $(ROOT_DIR)/bin/pnf_stub
+               $(Q)echo -e "***** PNF STUB BUILD COMPLETE *****"
 
 copy_build: link_du
                        $(Q)cp -f ./obj/odu/odu ./bin/odu
@@ -335,6 +367,7 @@ copy_build: link_du
 odu: prepare_dirs copy_build
 cu_stub: prepare_cu_dirs cu link_cu
 ric_stub: prepare_ric_dirs ric link_ric
+pnf_stub: prepare_pnf_dirs pnf link_pnf
 
 #**********************************************************************
 #         End of file
index 8c9a47c..2c08a6c 100755 (executable)
@@ -30,6 +30,9 @@ make cu_stub NODE=TEST_STUB MACHINE=BIT64 MODE=FDD
 echo ""
 echo "***** Building RIC Stub Binary *****"
 make ric_stub NODE=TEST_STUB MACHINE=BIT64 MODE=FDD
+echo ""
+echo "***** Building PNF Stub Binary *****"
+make pnf_stub NODE=TEST_STUB MACHINE=BIT64 MODE=FDD
 
 echo ""
 echo "***** Assigning IP addresses *****"
@@ -38,11 +41,14 @@ INTERFACE="$(echo -e "${INTERFACE}" | tr -d '[:space:]')"
 ifconfig $INTERFACE:ODU "192.168.130.81"
 ifconfig $INTERFACE:CU_STUB "192.168.130.82"
 ifconfig $INTERFACE:RIC_STUB "192.168.130.80"
+ifconfig $INTERFACE:PNF_STUB "192.168.130.79"
 
 xterm -hold -e "cd $ROOT_DIR/bin/cu_stub; chmod 777 *; ./start_cu_stub_logging.sh && ./cu_stub" &
 sleep 2
 xterm -hold -e "cd $ROOT_DIR/bin/ric_stub; chmod 777 *; ./start_ric_stub_logging.sh && ./ric_stub" &
 sleep 2
+xterm -hold -e "cd $ROOT_DIR/bin/pnf_stub; chmod 777 *; ./start_pnf_stub_logging.sh && ./pnf_stub" &
+sleep 2
 xterm -hold -e "cd $ROOT_DIR/bin/odu; chmod 777 *; ./start_du_logging.sh && ./odu" &
 
 ################################################################################
diff --git a/build/scripts/start_pnf_stub_logging.sh b/build/scripts/start_pnf_stub_logging.sh
new file mode 100755 (executable)
index 0000000..6b11c28
--- /dev/null
@@ -0,0 +1,35 @@
+################################################################################
+#   Copyright (c) [2017-2019] [Radisys]                                        #
+#                                                                              #
+#   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.                                             #
+################################################################################
+# This script is used to log PNF stub
+#!/bin/sh
+
+ROOT_DIR=$PWD
+d=`date +%Y_%m_%d_%I_%M_%S`
+
+touch  $ROOT_DIR/"log_pnf_stub_$d.txt"
+chmod -c 777 $ROOT_DIR/"log_pnf_stub_$d.txt"
+touch /etc/rsyslog.d/rsyslog_loginauth.conf
+cp /dev/null /etc/rsyslog.d/rsyslog_loginauth.conf
+echo "if \$programname == \"PNF_STUB\" then" >> \
+/etc/rsyslog.d/rsyslog_loginauth.conf
+echo "$ROOT_DIR/../pnf_stub/log_pnf_stub_$d.txt" >> \
+/etc/rsyslog.d/rsyslog_loginauth.conf
+systemctl restart rsyslog
+
+
+#**********************************************************************
+#        End of file
+#**********************************************************************
index fe25953..efa92ea 100644 (file)
@@ -29,6 +29,9 @@
 #ifndef INTEL_WLS_MEM\r
 #include "lwr_mac_phy_stub_inf.h"\r
 #endif\r
+#ifdef NFAPI_ENABLED\r
+#include "lwr_mac_sctp_inf.h"\r
+#endif\r
 \r
 /**************************************************************************\r
  * @brief Task Initiation callback function. \r
@@ -126,6 +129,26 @@ void callFlowlwrMacActvTsk(Pst *pst)
             break;\r
          }\r
 #endif\r
+     case ENTSCTP:\r
+     {\r
+         strcpy(sourceTask,"SCTP");\r
+         switch(pst->event)\r
+         {\r
+#ifdef NFAPI_ENABLED\r
+             case EVENT_PNF_DATA:\r
+               {\r
+                  strcpy(message,"EVENT_PNF_DATA");\r
+                  break;\r
+               }\r
+#endif\r
+             default:\r
+               {\r
+                  strcpy(message,"Invalid Event");\r
+                  break;\r
+               }\r
+         }\r
+         break;\r
+      }\r
 \r
       default:\r
          {\r
@@ -229,7 +252,24 @@ uint8_t lwrMacActvTsk(Pst *pst, Buffer *mBuf)
             break;\r
          }\r
 #endif\r
-\r
+     case ENTSCTP:\r
+       {\r
+          switch(pst->event)\r
+           {\r
+#ifdef NFAPI_ENABLED\r
+             case EVENT_PNF_DATA:\r
+               {\r
+                   \r
+                   break;\r
+               }\r
+#endif\r
+             default:\r
+                {\r
+                    DU_LOG("\nERROR  -->  LWR_MAC: Invalid event %d received from SCTP", pst->event);\r
+                }\r
+           }\r
+           break;\r
+       }\r
       default:\r
          {\r
             ODU_PUT_MSG_BUF(mBuf);\r
index 995f823..e73a04d 100644 (file)
@@ -16,8 +16,8 @@
  ################################################################################
  *******************************************************************************/
 
- #ifndef _LWR_MAC_NFAPI_H_
- #define _LWR_MAC_NFAPI_H_
+#ifndef _LWR_MAC_NFAPI_H_
+#define _LWR_MAC_NFAPI_H_
 
 #include "nfapi_interface.h"
 
diff --git a/src/cm/lwr_mac_sctp_inf.h b/src/cm/lwr_mac_sctp_inf.h
new file mode 100644 (file)
index 0000000..c7d2cd1
--- /dev/null
@@ -0,0 +1,24 @@
+
+/*******************************************************************************
+################################################################################
+#   Copyright (c) [2017-2019] [Radisys]                                        #
+#                                                                              #
+#   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.                                             #
+################################################################################
+*******************************************************************************/
+
+#define EVENT_PNF_DATA 11
+
+/**********************************************************************
+  End of file
+***********************************************************************/
index b5d6345..cb65690 100644 (file)
@@ -206,6 +206,9 @@ uint8_t parseSctpParams(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur, SctpParams *
    uint8_t max_du_port = 0;
    uint16_t f1_sctp_port = 0;
    uint16_t e2_sctp_port = 0;
+#ifdef NFAPI_ENABLED
+   uint16_t pnf_p5_sctp_port = 0;
+#endif
 
    memset(sctp, 0, sizeof(SctpParams));
    cur = cur->xmlChildrenNode;
@@ -220,7 +223,7 @@ uint8_t parseSctpParams(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur, SctpParams *
       if ((!xmlStrcmp(cur->name, (const xmlChar *)"MAX_DU_PORT")) && (cur->ns == ns))
       {
          max_du_port = atoi((char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1));
-         if (max_du_port == 2 )
+         if (max_du_port >= 2 )
          {
             sctp->duPort[F1_INTERFACE] = f1_sctp_port;     /* DU Port idx  0  */
             sctp->duPort[E2_INTERFACE] = e2_sctp_port;    /* RIC Port idx 1  */
@@ -238,6 +241,20 @@ uint8_t parseSctpParams(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur, SctpParams *
 
       sctp->cuPort = f1_sctp_port;
       sctp->ricPort = e2_sctp_port;
+#endif
+#ifdef NFAPI_ENABLED
+      /*TODO: Need to add PNF_PF Interface's SCTP confg in O1 Module then can be
+       * moved inside O1_ENABLE flag*/
+      if(max_du_port == 3)
+      {
+         sctp->duPort[PNF_P5_INTERFACE] = pnf_p5_sctp_port;
+      }
+
+      if ((!xmlStrcmp(cur->name, (const xmlChar *)"PNF_P5_SCTP_PORT")) && (cur->ns == ns))
+      {
+         pnf_p5_sctp_port = atoi((char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1));
+      }
+      sctp->pnfP5Port = pnf_p5_sctp_port;
 #endif
       cur = cur->next;
    }
@@ -5163,6 +5180,10 @@ uint8_t parseDuCfgParams(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur)
    char *duIpV4Addr;
    char *cuIpV4Addr;
    char *ricIpV4Addr;
+#ifdef NFAPI_ENABLED
+   char *pnfP5IpV4Addr;
+   CmInetIpAddr pnfP5Ip;
+#endif
    CmInetIpAddr duIp;
    CmInetIpAddr cuIp;
    CmInetIpAddr ricIp;
@@ -5237,7 +5258,13 @@ uint8_t parseDuCfgParams(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur)
          cmInetAddr(ricIpV4Addr, &(ricIp));
       }
 #endif
-
+#ifdef NFAPI_ENABLED
+      if ((!xmlStrcmp(cur->name, (const xmlChar *)"PNF_P5_IP_V4_ADDR")) && (cur->ns == ns))
+      {
+         pnfP5IpV4Addr = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+         cmInetAddr(pnfP5IpV4Addr, &(pnfP5Ip));
+      }
+#endif
       if ((!xmlStrcmp(cur->name, (const xmlChar *)"SCTP")) && (cur->ns == ns))
       {
          if(parseSctpParams(doc, ns, cur, &duCfgParam.sctpParams) != ROK)
@@ -5251,6 +5278,10 @@ uint8_t parseDuCfgParams(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur)
          duCfgParam.sctpParams.cuIpAddr.ipV4Addr = cuIp;
          duCfgParam.sctpParams.ricIpAddr.ipV4Pres = true;
          duCfgParam.sctpParams.ricIpAddr.ipV4Addr = ricIp;
+#ifdef NFAPI_ENABLED
+         duCfgParam.sctpParams.pnfP5IpAddr.ipV4Pres = true;
+         duCfgParam.sctpParams.pnfP5IpAddr.ipV4Addr = pnfP5Ip;
+#endif
       }
 
       if ((!xmlStrcmp(cur->name, (const xmlChar *)"EGTP")) && (cur->ns == ns))
@@ -5556,10 +5587,18 @@ void printDuConfig()
    DU_LOG("CU IP Address %u\n", sctp->cuIpAddr.ipV4Addr);
    DU_LOG("RIC IPv4 Address present %u\n", sctp->ricIpAddr.ipV4Pres);
    DU_LOG("RIC IP Address %u\n", sctp->ricIpAddr.ipV4Addr);
+#ifdef NFAPI_ENABLED
+   DU_LOG("PNF P5 IPv4 Address present %u\n", sctp->pnfP5IpAddr.ipV4Pres);
+   DU_LOG("PNF P5 IP Address %u\n", sctp->pnfP5IpAddr.ipV4Addr);
+#endif
    DU_LOG("SCTP Port at DU for F1 Interface %d\n", sctp->duPort[F1_INTERFACE]);
    DU_LOG("SCTP Port at CU for F1 Interface %d\n", sctp->cuPort);
    DU_LOG("SCTP Port at DU for E2 Interface %d\n", sctp->duPort[E2_INTERFACE]);
    DU_LOG("SCTP Port at RIC for E2 Interface %d\n", sctp->ricPort);
+#ifdef NFAPI_ENABLED
+   DU_LOG("SCTP Port at DU for PNF P5 Interface %d\n", sctp->duPort[PNF_P5_INTERFACE]);
+   DU_LOG("SCTP Port at PNF for PNF P5 Interface %d\n", sctp->pnfP5Port);
+#endif
 
    egtp = &duCfgParam.egtpParams;
    DU_LOG("\n ** EGTP PARAMETER ** \n");
index b373253..2cd3cc2 100644 (file)
 #define DU_PROC  0
 #define DU_INST 0
 #define DU_POOL  1
-#define MAX_DU_PORT 2
+#define MAX_DU_PORT 3
 #define F1_INTERFACE 0
 #define E2_INTERFACE 1
 
+#ifdef NFAPI_ENABLED
+#define PNF_P5_INTERFACE 2
+#endif
+
 #define SCTP_INST 0
 #define EGTP_INST 0
 
@@ -924,11 +928,15 @@ typedef struct f1Ipaddr
 typedef struct sctpParams
 {
    F1IpAddr  duIpAddr;
-   uint16_t       duPort[MAX_DU_PORT];
+   uint16_t  duPort[MAX_DU_PORT];
    F1IpAddr  cuIpAddr;
-   uint16_t       cuPort;
+   uint16_t  cuPort;
    F1IpAddr  ricIpAddr;
-   uint16_t       ricPort;
+   uint16_t  ricPort;
+#ifdef NFAPI_ENABLED
+   F1IpAddr  pnfP5IpAddr;
+   uint16_t  pnfP5Port;
+#endif
 }SctpParams;
 
 typedef struct f1EgtpParams
index 5a17932..b2ab028 100644 (file)
@@ -1398,7 +1398,13 @@ uint8_t duLayerConfigComplete()
       DU_LOG("\nERROR  -->  DU_APP : Failed to send AssocReq E2");
       ret = RFAILED;
    }
-
+#ifdef NFAPI_ENABLED
+   if((ret = duSctpAssocReq(PNF_P5_INTERFACE)) != ROK)
+   {
+      DU_LOG("\nERROR  -->  DU_APP : Failed to send AssocReq PNF P5");
+      ret = RFAILED;
+   }
+#endif
    return (ret); 
 } 
 
index fbb28e1..342b1fd 100644 (file)
@@ -33,6 +33,8 @@
 #include "du_app_rlc_inf.h"
 #include "du_mgr.h"
 #include "du_utils.h"
+#include "lwr_mac_sctp_inf.h"
+
 /* Global variable declaration */
 uint8_t   socket_type;      /* Socket type */
 bool nonblocking;      /* Blocking/Non-blocking socket */
@@ -43,6 +45,9 @@ CmInetNetAddrLst remoteAddrLst;
 /* Global variable declaration */
 DuSctpDestCb f1Params;     /* SCTP configurations at DU */ 
 DuSctpDestCb ricParams;    /* SCTP configurations at DU */ 
+#ifdef NFAPI_ENABLED
+DuSctpDestCb pnfP5Params;    /* SCTP configurations for PNF */ 
+#endif
 
 /**************************************************************************
  * @brief Task Initiation callback function. 
@@ -74,6 +79,10 @@ uint8_t sctpActvInit(Ent entity, Inst inst, Region region, Reason reason)
    f1Params.assocId = -1;
    memset(&ricParams, 0, sizeof(DuSctpDestCb));
    ricParams.assocId = -1;
+#ifdef NFAPI_ENABLED
+   memset(&pnfP5Params, 0, sizeof(DuSctpDestCb));
+   pnfP5Params.assocId = -1;
+#endif
    nonblocking = FALSE;
    return ROK;
 
@@ -236,6 +245,18 @@ uint8_t duSctpCfgReq(SctpParams sctpCfg)
    fillDestNetAddr(&ricParams.destIpNetAddr, &ricParams.destIpAddr);
    fillAddrLst(&ricParams.destAddrLst, &ricParams.destIpAddr);
 
+#ifdef NFAPI_ENABLED
+/* Fill PNF Params */
+   pnfP5Params.destIpAddr.ipV4Pres  = sctpCfg.pnfP5IpAddr.ipV4Pres;
+   pnfP5Params.destIpAddr.ipV4Addr  = sctpCfg.pnfP5IpAddr.ipV4Addr;
+   pnfP5Params.destPort             = sctpCfg.pnfP5Port;
+   pnfP5Params.itfState             = DU_SCTP_DOWN;
+   pnfP5Params.srcPort              = sctpCfg.duPort[PNF_P5_INTERFACE];
+   memset (&pnfP5Params.sockFd, -1, sizeof(CmInetFd));
+   fillDestNetAddr(&pnfP5Params.destIpNetAddr, &pnfP5Params.destIpAddr);
+   fillAddrLst(&pnfP5Params.destAddrLst, &pnfP5Params.destIpAddr);
+#endif
+
 /* Fill AddressList */
    fillAddrLst(&localAddrLst, &sctpCfg.duIpAddr);
 
@@ -422,6 +443,14 @@ uint8_t duSctpAssocReq(uint8_t itfType)
          ret = establishReq(paramPtr);
          break;
       }
+#ifdef NFAPI_ENABLED
+      case PNF_P5_INTERFACE:
+      {
+         paramPtr = &pnfP5Params;
+         ret = establishReq(paramPtr);
+         break;
+      }
+#endif
       default:
       {
          DU_LOG("\nERROR  -->  SCTP : Invalid Interface Type %d", itfType);
@@ -559,9 +588,55 @@ void sendToDuApp(Buffer *mBuf, Event event)
 
    if (ODU_POST_TASK(&pst, mBuf) != ROK)
    {
-      DU_LOG("\nERROR  -->  SCTP : ODU_POST_TASK failed in duReadCfg");
+      DU_LOG("\nERROR  -->  SCTP : ODU_POST_TASK failed in sendToDuApp");
+   }
+}
+
+#ifdef NFAPI_ENABLED
+/*******************************************************************
+ *
+ * @brief Post received data/notification to LWR_MAC 
+ *
+ * @details
+ *
+ *    Function : sendToLwrMac
+ *
+ *    Functionality:
+ *         Post received data/notification to LWR_MAC
+ *
+ * @params[in]  Message buffer
+ *              Message event
+ *
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+void sendToLwrMac(Buffer *mBuf, Event event)
+{
+   Pst pst;
+   DU_LOG("\nDEBUG   -->  SCTP : Forwarding received message to Lwr MAC");
+   ODU_PRINT_MSG(mBuf, 0, 0);
+
+   ODU_GET_MSG_BUF(pst.region, pst.pool, &mBuf);
+
+   memset(&(pst), 0, sizeof(Pst));
+   pst.srcEnt = (Ent)ENTSCTP;
+   pst.srcInst = (Inst)SCTP_INST;
+   pst.srcProcId = DU_PROC;
+   pst.dstEnt = (Ent)ENTLWRMAC;
+   pst.dstInst = 0;
+   pst.dstProcId = pst.srcProcId;
+   pst.event = event;
+   pst.selector = ODU_SELECTOR_LWLC;
+   pst.pool= DU_POOL;
+   pst.region = DFLT_REGION;
+
+   if (ODU_POST_TASK(&pst, mBuf) != ROK)
+   {
+      DU_LOG("\nERROR  -->  SCTP : ODU_POST_TASK failed in sendToLwrMac");
    }
 }
+#endif
 
 /*******************************************************************
  *
@@ -651,25 +726,36 @@ uint8_t sctpNtfyHdlr(CmInetSctpNotification *ntfy, uint8_t *itfState, uint8_t in
          break;
    }
 
-   /* Pack notification and send to APP */
-   DU_LOG("\nDEBUG   -->  SCTP : Forwarding received message to duApp");
-    
-   memset(&(pst), 0, sizeof(Pst));
-   pst.srcEnt = (Ent)ENTSCTP;
-   pst.srcInst = (Inst)SCTP_INST;
-   pst.srcProcId = DU_PROC;
-   pst.dstEnt = (Ent)ENTDUAPP;
-   pst.dstInst = (Inst)DU_INST;
-   pst.dstProcId = pst.srcProcId;
-   pst.event = EVENT_SCTP_NTFY;
-   pst.selector = ODU_SELECTOR_LC;
-   pst.pool= DU_POOL;
-   pst.region = DU_APP_MEM_REGION;
-   
-   if(cmPkSctpNtfy(&pst, ntfy) != ROK)
+#ifdef NFAPI_ENABLED
+   if(interface == PNF_P5_INTERFACE)
    {
-      DU_LOG("\nERROR  -->  SCTP : Failed to pack SCTP notification");
-      return RFAILED;
+      /*TODO: Need to check if SCTP Notification for this interface has to be handled*/
+      DU_LOG("\nDEBUG   -->  SCTP : SCTP Notification received for PNF_P5 Interface");
+      return ROK;
+   }
+   else
+#endif
+   {
+      /* Pack notification and send to APP */
+      DU_LOG("\nDEBUG   -->  SCTP : Forwarding received message to duApp");
+
+      memset(&(pst), 0, sizeof(Pst));
+      pst.srcEnt = (Ent)ENTSCTP;
+      pst.srcInst = (Inst)SCTP_INST;
+      pst.srcProcId = DU_PROC;
+      pst.dstEnt = (Ent)ENTDUAPP;
+      pst.dstInst = (Inst)DU_INST;
+      pst.dstProcId = pst.srcProcId;
+      pst.event = EVENT_SCTP_NTFY;
+      pst.selector = ODU_SELECTOR_LC;
+      pst.pool= DU_POOL;
+      pst.region = DU_APP_MEM_REGION;
+
+      if(cmPkSctpNtfy(&pst, ntfy) != ROK)
+      {
+         DU_LOG("\nERROR  -->  SCTP : Failed to pack SCTP notification");
+         return RFAILED;
+      }
    }
    return ROK;
 }
@@ -710,7 +796,6 @@ uint8_t  processPolling(sctpSockPollParams *pollParams, CmInetFd *sockFd, uint32
       if(ret != ROK)
       {
          DU_LOG("\nERROR   -->  SCTP: Failed to receive sctp msg for sockFd[%d]\n", sockFd->fd);
-         ret = RFAILED;
       }
       else
       {
@@ -734,6 +819,14 @@ uint8_t  processPolling(sctpSockPollParams *pollParams, CmInetFd *sockFd, uint32
                DU_LOG("\nDEBUG   -->  SCTP : AssocId assigned to ricParams from PollParams [%d]\n", ricParams.assocId);
                ret = sctpNtfyHdlr(&pollParams->ntfy, &ricParams.itfState, E2_INTERFACE);
             }
+#ifdef NFAPI_ENABLED
+            else if(pollParams->port == pnfP5Params.destPort)
+            {
+               pnfP5Params.assocId = pollParams->ntfy.u.assocChange.assocId;
+               DU_LOG("\nDEBUG   -->  SCTP : AssocId assigned to PNF_P5 Params from PollParams [%d]\n", pnfP5Params.assocId);
+               ret = sctpNtfyHdlr(&pollParams->ntfy, &pnfP5Params.itfState, PNF_P5_INTERFACE);
+            }
+#endif
             else
             {
                DU_LOG("\nERROR  -->  SCTP : Failed to fill AssocId\n");
@@ -752,14 +845,19 @@ uint8_t  processPolling(sctpSockPollParams *pollParams, CmInetFd *sockFd, uint32
          {  
             sendToDuApp(pollParams->mBuf, EVENT_RIC_DATA);
          }
-
+#ifdef NFAPI_ENABLED
+         else if(pnfP5Params.itfState & (pollParams->port == pnfP5Params.destPort))
+         {
+            sendToLwrMac(pollParams->mBuf, EVENT_PNF_DATA);
+         }
+#endif
          else
          {
             ODU_PUT_MSG_BUF(pollParams->mBuf);
          }
       }
   }
-  return ret;
+  return ROK;
 }
 /*******************************************************************
  *
@@ -784,14 +882,25 @@ uint8_t sctpSockPoll()
    uint32_t *timeout_Ptr;
    CmInetMemInfo memInfo;
    sctpSockPollParams f1PollParams, e2PollParams;
+#ifdef NFAPI_ENABLED
+   sctpSockPollParams pnfP5PollParams;
+#endif
 
    memset(&f1PollParams, 0, sizeof(sctpSockPollParams));
    memset(&e2PollParams, 0, sizeof(sctpSockPollParams));
+#ifdef NFAPI_ENABLED
+   memset(&pnfP5PollParams, 0, sizeof(sctpSockPollParams));
+#endif
 
    if (f1Params.sockFd.blocking & ricParams.sockFd.blocking)
    {
-      /* blocking */
-      timeout_Ptr = NULLP;
+#ifdef NFAPI_ENABLED
+      if(pnfP5Params.sockFd.blocking)
+#endif
+      {
+         /* blocking */
+         timeout_Ptr = NULLP;
+      }
    }
    else
    {
@@ -804,6 +913,9 @@ uint8_t sctpSockPoll()
 
    CM_INET_FD_ZERO(&f1PollParams.readFd);
    CM_INET_FD_ZERO(&e2PollParams.readFd);
+#ifdef NFAPI_ENABLED
+   CM_INET_FD_ZERO(&pnfP5PollParams.readFd);
+#endif
 
    DU_LOG("\nINFO   -->  SCTP : Polling started at DU\n");
    while(true)
@@ -822,6 +934,15 @@ uint8_t sctpSockPoll()
             DU_LOG("\nERROR  -->  SCTP : Failed to RecvMsg for E2\n");
          }
       }
+#ifdef NFAPI_ENABLED
+      if(pnfP5Params.itfState)
+      {
+         if((ret = processPolling(&pnfP5PollParams, &pnfP5Params.sockFd, timeout_Ptr, &memInfo)) != ROK)
+         {
+            DU_LOG("\nERROR  -->  SCTP : Failed to RecvMsg for E2\n");
+         }
+      }
+#endif
    };
    return (ret);
 }/* End of sctpSockPoll() */
@@ -879,7 +1000,16 @@ uint8_t sctpSend(Buffer *mBuf, uint8_t itfType)
 #endif
       ret = cmInetSctpSendMsg(&ricParams.sockFd, &ricParams.destIpNetAddr, ricParams.destPort, &memInfo, mBuf, &len, 0, FALSE, 0, 0/*SCT_PROTID_NONE*/, RWOULDBLOCK);
    }
-
+#ifdef NFAPI_ENABLED
+   if(itfType == PNF_P5_INTERFACE)
+   {
+      DU_LOG("\nDEBUG  -->  SCTP : sending the message to PNF");
+#ifdef CALL_FLOW_DEBUG_LOG
+      DU_LOG("\nCall Flow: ENTSCTP -> PNF : EVENT_P5_MSG_TO_PNF\n");
+#endif
+      ret = cmInetSctpSendMsg(&pnfP5Params.sockFd, &pnfP5Params.destIpNetAddr, pnfP5Params.destPort, &memInfo, mBuf, &len, 0, FALSE, 0, 0/*SCT_PROTID_NONE*/, RWOULDBLOCK);
+   }
+#endif
    if(ret != ROK && ret != RWOULDBLOCK)
    {
       DU_LOG("\nERROR  -->  SCTP : Failed sending the message");
index d29c9ef..2859226 100644 (file)
 /*Table 2-7 Dedicated NFAPI message IDs*/
 
 /*P5 Messages*/
-#define NFAPI_PNF_PARAM_REQ    0x0100
-#define NFAPI_PNF_PARAM_RESP   0x0101
-#define NFAPI_PNF_CONFIG_REQ   0x0102
-#define NFAPI_PNF_CONFIG_RESP  0x0103
-#define NFAPI_PNF_START_REQ    0x0104
-#define NFAPI_PNF_START_RESP   0x0105
-#define NFAPI_PNF_STOP_REQ     0x0106
-#define NFAPI_PNF_STOP_RESP    0x0107
-#define NFAPI_START_RESPONSE         0x0108
-#define NFAPI_PNF_READY_IND    0x0109
-
-/*Reserved for P5 Dedicated NFAPI Messages 0x010A - 0x017F */
+#define TAG_NFAPI_PNF_PARAM_REQ    0x0100
+#define TAG_NFAPI_PNF_PARAM_RESP   0x0101
+#define TAG_NFAPI_PNF_CONFIG_REQ   0x0102
+#define TAG_NFAPI_PNF_CONFIG_RESP  0x0103
+#define TAG_NFAPI_PNF_START_REQ    0x0104
+#define TAG_NFAPI_PNF_START_RESP   0x0105
+#define TAG_NFAPI_PNF_STOP_REQ     0x0106
+#define TAG_NFAPI_PNF_STOP_RESP    0x0107
+#define TAG_NFAPI_START_RESPONSE         0x0108
+#define TAG_NFAPI_PNF_READY_IND    0x0109
+
+/*Reserved for P5 Dedicated TAG_NFAPI Messages 0x010A - 0x017F */
 
 /*P7 messages*/
-#define NFAPI_DL_NODE_SYNC     0x0180
-#define NFAPI_UL_NODE_SYNC     0x0181
-#define NFAPI_TIMING_INFO      0x0182
+#define TAG_NFAPI_DL_NODE_SYNC     0x0180
+#define TAG_NFAPI_UL_NODE_SYNC     0x0181
+#define TAG_NFAPI_TIMING_INFO      0x0182
 
-/*Reserved for P7 Dedicated NFAPI Messages 0x0183 - 0x01ff*/
+/*Reserved for P7 Dedicated TAG_NFAPI Messages 0x0183 - 0x01ff*/
 /*RESERVED for Vendor Extension messages 0x0300 - 0x03ff*/
 
 /*Table 3-16 nFAPI TLVs included in PARAM.response and 
  *Table 3-19 nFAPI TLVs included in CONFIG.request*/
 //PNF and VNF Parameters
-#define NFAPI_P7_VNF_ADD_IPV4              0x0100
-#define NFAPI_P7_VNF_ADD_IPV6              0x0101
-#define NFAPI_P7_VNF_PORT                  0x0102
-#define NFAPI_P7_PNF_ADD_IPV4              0x0103
-#define NFAPI_P7_PNF_ADD_IPV6              0x0104
-#define NFAPI_P7_PNF_PORT                  0x0105
+#define TAG_NFAPI_P7_VNF_ADD_IPV4              0x0100
+#define TAG_NFAPI_P7_VNF_ADD_IPV6              0x0101
+#define TAG_NFAPI_P7_VNF_PORT                  0x0102
+#define TAG_NFAPI_P7_PNF_ADD_IPV4              0x0103
+#define TAG_NFAPI_P7_PNF_ADD_IPV6              0x0104
+#define TAG_NFAPI_P7_PNF_PORT                  0x0105
 //TTI Related Parameters
-#define NFAPI_DL_TTI_TIMING_OFFSET         0x0106
-#define NFAPI_UL_TTI_TIMING_OFFSET         0x0107
-#define NFAPI_UL_DCI_TIMING_OFFSET         0x0108
-#define NFAPI_TX_DATA_TIMING_OFFSET        0x0109
+#define TAG_NFAPI_DL_TTI_TIMING_OFFSET         0x0106
+#define TAG_NFAPI_UL_TTI_TIMING_OFFSET         0x0107
+#define TAG_NFAPI_UL_DCI_TIMING_OFFSET         0x0108
+#define TAG_NFAPI_TX_DATA_TIMING_OFFSET        0x0109
 //Timing Related Parameters
-#define NFAPI_TIMING_WINDOW                0x011E
-#define NFAPI_TIMING_INFO_MODE             0x011F
-#define NFAPI_TIMING_INFO_PERIOD           0x0120
+#define TAG_NFAPI_TIMING_WINDOW                0x011E
+#define TAG_NFAPI_TIMING_INFO_MODE             0x011F
+#define TAG_NFAPI_TIMING_INFO_PERIOD           0x0120
 //P7 Transport Related Parameters
-#define NFAPI_P7_IP_FRAGMENTATION_ALLOWED  0x0121
-#define NFAPI_P7_TRANSPORT                 0x0122
-#define NFAPI_P7_PNF_ETHERNET_ADD          0x0123
-#define NFAPI_P7_VNF_ETHERNET_ADD          0x0124
+#define TAG_NFAPI_P7_IP_FRAGMENTATION_ALLOWED  0x0121
+#define TAG_NFAPI_P7_TRANSPORT                 0x0122
+#define TAG_NFAPI_P7_PNF_ETHERNET_ADD          0x0123
+#define TAG_NFAPI_P7_VNF_ETHERNET_ADD          0x0124
 //CPRI Related Parameters
-#define NFAPI_ECPRI_MSG_TYPE               0x0125
-#define NFAPI_ECPRI_PHY_TRANSPORT_ID       0x0126
+#define TAG_NFAPI_ECPRI_MSG_TYPE               0x0125
+#define TAG_NFAPI_ECPRI_PHY_TRANSPORT_ID       0x0126
 
-#define NFAPI_5G_FAPI_MSG_BODY             0x0F00
+#define TAG_NFAPI_5G_FAPI_MSG_BODY             0x0F00
 
 /*Table 3-2*/
-#define NFAPI_PNF_PARAM_GENERAL            0x1000 
+#define TAG_NFAPI_PNF_PARAM_GENERAL            0x1000 
 
 /*As per Table 3-15 and Table 3-17*/
 #define MAX_NUM_TLV_IN_PARAM_RESP          19
diff --git a/src/pnf_stub/pnf_stub.c b/src/pnf_stub/pnf_stub.c
new file mode 100644 (file)
index 0000000..fc0021d
--- /dev/null
@@ -0,0 +1,163 @@
+/*******************************************************************************
+ * ################################################################################
+ * #   Copyright (c) [2017-2019] [Radisys]
+ * #
+ * #
+ * #
+ * #   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.
+ * #
+ * ################################################################################
+ * *******************************************************************************/
+
+/* This functions contains main() for pnf simulator */
+#include "common_def.h"
+#include <unistd.h>
+#include "pnf_stub_sctp.h"
+#include "pnf_stub.h"
+
+PnfGlobalCb pnfCb;
+
+void init_log()
+{
+       openlog("RIC_STUB",LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
+}
+
+/*******************************************************************
+ *
+ * @brief Read PNF related configuration
+ *
+ * @details
+ *
+ *    Function : readPnfCfg
+ *
+ *    Functionality:
+ *            - RRead PNF related configuration
+ *
+ * @params[in] 
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+
+void readPnfCfg()
+{
+   uint8_t  cntNumVnf = 0;
+   uint32_t ipv4_vnf = 0, ipv4_pnf = 0;
+
+   DU_LOG("\nDEBUG  -->  PNF_STUB : Reading PNF P5 configurations");
+
+   pnfCb.pnfCfgParams.pnfId = PNF_ID;
+   strcpy(pnfCb.pnfCfgParams.pnfName, PNF_NAME);
+
+   /* PNF IP Address and Port*/
+   memset(&ipv4_pnf, 0, sizeof(uint32_t));
+   cmInetAddr((S8*)LOCAL_IP_PNF, &ipv4_pnf);
+
+   /*PNF SCTP Configuration at PNF P5 Interface*/
+   pnfCb.pnfCfgParams.pnfP5SctpParams.pnfP5localIpAddr.ipV4Pres = true;
+   pnfCb.pnfCfgParams.pnfP5SctpParams.pnfP5localIpAddr.ipV4Addr = ipv4_pnf;
+   pnfCb.pnfCfgParams.pnfP5SctpParams.pnfP5localIpAddr.ipV6Pres = false;
+   pnfCb.pnfCfgParams.pnfP5SctpParams.pnfP5SctpPort = PNF_P5_SCTP_PORT;
+   
+   cntNumVnf = 0;
+   while(cntNumVnf < NUM_PNF_P5_ASSOC)
+   {
+      /* VNF IP Address */
+      memset(&ipv4_vnf, 0, sizeof(uint32_t));
+      cmInetAddr((S8*)REMOTE_IP_DU[cntNumVnf], &ipv4_vnf);
+      
+      /* VNF SCTP Parameters */
+      pnfCb.pnfCfgParams.pnfP5SctpParams.destCb[cntNumVnf].destIpAddr.ipV4Addr = ipv4_vnf;
+      pnfCb.pnfCfgParams.pnfP5SctpParams.destCb[cntNumVnf].destIpAddr.ipV6Pres = false;
+      pnfCb.pnfCfgParams.pnfP5SctpParams.destCb[cntNumVnf].destPort = PNF_P5_SCTP_PORT;
+
+           
+      (cntNumVnf)++;
+   }
+
+   pnfCb.pnfCfgParams.pnfP5SctpParams.numDestNode = cntNumVnf;
+  
+} /* End of readPnfCfg */
+
+
+/*******************************************************************
+ *
+ * @brief Main function of PNF SIMULATOR
+ *
+ * @details
+ *
+ *    Function : main
+ *
+ *    Functionality:
+ *         - Initialize SCTP Parameters
+ *         - Start SCTP receiver thread
+ *
+ * @params[in] 
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+
+uint8_t tst()
+{
+#if 0
+   int retVal=0;
+   pthread_t conThrdId;
+   pthread_attr_t attr;
+#endif
+
+   init_log();   
+   DU_LOG("\nINFO   -->  PNF_STUB : Starting PNF_STUB\n");
+
+   /* TODO: Start thread to receive console input */
+#if 0
+   pthread_attr_init(&attr);
+   pthread_attr_setstacksize(&attr, (size_t)NULLD);
+   pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
+   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+   retVal = pthread_create(&conThrdId, &attr, vnfConsoleHandler, NULLP);
+   if(retVal != 0)
+   {
+      DU_LOG("\nERROR  -->  PNF_STUB :  Thread creation failed. Cause %d", retVal);
+   }
+   pthread_attr_destroy(&attr);
+#endif
+   /* Read PNF configurations */
+   readPnfCfg();
+
+   /* Initializing SCTP global parameters */
+   pnfP5SctpActvInit();
+   /* Start PNF-P5-SCTP to listen on incoming connection */
+   pnfP5SctpCfgReq();
+   
+   /*Sleep is introduced for GDB to increase the waiting time for PNF Configuration from VNF*/
+   sleep(1);
+   
+   pnfP5SctpStartReq();
+
+   return ROK;
+}
+
+
+
diff --git a/src/pnf_stub/pnf_stub.h b/src/pnf_stub/pnf_stub.h
new file mode 100644 (file)
index 0000000..2b4acce
--- /dev/null
@@ -0,0 +1,51 @@
+/*******************************************************************************
+################################################################################
+#   Copyright (c) [2017-2019] [Radisys]                                        #
+#                                                                              #
+#   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.                                             #
+################################################################################
+*******************************************************************************/
+
+#ifndef __PNF_MAIN_H
+#define __PNF_MAIN_H
+
+#define PNF_NAME_LEN_MAX 30
+#define PNF_ID 1
+#define PNF_NAME "ORAN_OAM_PNF"
+
+#define LOCAL_IP_PNF "192.168.130.79"
+
+#define PNF_P5_SCTP_PORT 7701
+#define NUM_PNF_P5_ASSOC 1 
+#define REMOTE_IP_DU (char*[]){"192.168.130.81", "192.168.130.83"}
+
+#define PNF_APP_MEM_REG 1
+#define PNF_POOL 1
+
+typedef struct pnfCfgParams
+{
+   uint32_t          pnfId;
+   char              pnfName[PNF_NAME_LEN_MAX];
+   PnfP5SctpParams   pnfP5SctpParams;
+}PnfCfgParams;
+
+typedef struct pnfGlobalCb
+{
+   PnfCfgParams pnfCfgParams;
+   uint8_t      numDu;
+   //DuDb         duInfo[MAX_DU_SUPPORTED]; /*TODO: VNF Database can be added*/
+}PnfGlobalCb;
+
+extern PnfGlobalCb pnfCb;
+
+#endif
diff --git a/src/pnf_stub/pnf_stub_sctp.c b/src/pnf_stub/pnf_stub_sctp.c
new file mode 100644 (file)
index 0000000..e4b12e1
--- /dev/null
@@ -0,0 +1,534 @@
+/*******************************************************************************
+################################################################################
+#   Copyright (c) [2017-2019] [Radisys]                                        #
+#                                                                              #
+#   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.                                             #
+################################################################################
+*******************************************************************************/
+
+/* This file contains all SCTP related functionality */
+
+#include "common_def.h" 
+#include "pnf_stub_sctp.h"
+#include "pnf_stub.h"
+
+uint8_t   socket_type;      /* Socket type */
+PnfP5SctpGlobalCb pnfP5SctpCb;
+
+/**************************************************************************
+ * @brief Task Initiation callback function. 
+ *
+ * @details
+ *
+ *     Function : pnfP5SctpActvInit 
+ *    
+ *     Functionality:
+ *             This function is supplied as one of parameters during SCTP's 
+ *             task registration. SSI will invoke this function once, after
+ *             it creates and attaches this TAPA Task to a system task.
+ *     
+ * @param[in]  Ent entity, the entity ID of this task.     
+ * @param[in]  Inst inst, the instance ID of this task.
+ * @param[in]  Region region, the region ID registered for memory 
+ *              usage of this task.
+ * @param[in]  Reason reason.
+ * @return ROK     - success
+ *         RFAILED - failure
+ ***************************************************************************/
+uint8_t pnfP5SctpActvInit()
+{
+   DU_LOG("\n\nDEBUG  -->  SCTP : Initializing");
+   memset(&pnfP5SctpCb, 0, sizeof(PnfP5SctpGlobalCb));
+   pnfP5SctpCb.pnfP5SctpCfg = pnfCb.pnfCfgParams.pnfP5SctpParams;
+   return ROK;
+}
+
+/*******************************************************************
+ *
+ * @brief Fills the address List of the source Ip Address
+ *
+ * @details
+ *
+ *    Function : fillAddrLst
+ *
+ *    Functionality:
+ *       Fills the address List of source Ip Address
+ *
+ * @params[in] CmInetNetAddrLst *addrLstPtr, Address List pointer
+ * @params[in] F1IpAddr *srcIpAddr, src Ip Adrress to be filled in the Address List
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ ******************************************************************/
+
+uint8_t fillAddrLst(CmInetNetAddrLst *addrLstPtr, PnfP5SctpIpAddr *ipAddr)
+{ 
+   addrLstPtr->addrs[addrLstPtr->count].type = CM_INET_IPV4ADDR_TYPE;
+   addrLstPtr->addrs[addrLstPtr->count].u.ipv4NetAddr = CM_INET_NTOH_UINT32(ipAddr->ipV4Addr);
+   addrLstPtr->count++;
+
+   return ROK;
+}
+
+/******************************************************************************
+ *
+ * @brief Fills the address List of the source Ip Address
+ *
+ * @details
+ *
+ *    Function : fillDestNetAddr
+ *
+ *    Functionality:
+ *       Fills the address List of destinatoion Ip Address
+ *
+ * @params[in] CmInetNetAddr *destAddrPtr, Address List pointer
+ * @params[in] F1IpAddr *dstIpAddr, destIp Address to be filled in the Address List
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ *******************************************************************************/
+uint8_t fillDestNetAddr(CmInetNetAddr *destAddrPtr, PnfP5SctpIpAddr *dstIpPtr)
+{
+   /* Filling destination address */
+   destAddrPtr->type = CM_INET_IPV4ADDR_TYPE;
+   destAddrPtr->u.ipv4NetAddr = CM_INET_NTOH_UINT32(dstIpPtr->ipV4Addr);
+   return ROK;
+}
+
+/**************************************************************************
+ * @brief Function to configure the Sctp Params during config Request
+ *
+ * @details
+ *
+ *      Function : pnfP5SctpCfgReq
+ * 
+ *      Functionality:
+ *           This function configures SCTP Params during the config Request
+ *     
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ ***************************************************************************/
+
+uint8_t pnfP5SctpCfgReq()
+{
+   int destIdx = 0, assocIdx = 0;
+  
+   fillAddrLst(&pnfP5SctpCb.localAddrLst, &pnfP5SctpCb.pnfP5SctpCfg.pnfP5localIpAddr);
+   memset(&pnfP5SctpCb.pnfP5LstnSockFd, -1, sizeof(CmInetFd));
+   for(destIdx=0; destIdx < pnfP5SctpCb.pnfP5SctpCfg.numDestNode; destIdx++)
+   {   
+      pnfP5SctpCb.assocCb[assocIdx].destPort = pnfP5SctpCb.pnfP5SctpCfg.destCb[destIdx].destPort;
+      memset(&pnfP5SctpCb.assocCb[assocIdx].sockFd, -1, sizeof(CmInetFd));
+      fillDestNetAddr(&pnfP5SctpCb.assocCb[assocIdx].destIpNetAddr, &pnfP5SctpCb.pnfP5SctpCfg.destCb[destIdx].destIpAddr);
+      pnfP5SctpCb.assocCb[assocIdx].connUp = false;
+      assocIdx++;
+   }   
+   pnfP5SctpCb.numAssoc = assocIdx;
+   return ROK;
+}
+
+/******************************************************************************
+ *
+ * @brief Eastablishes the Assoc Req for the received interface type
+ *
+ * @details
+ *
+ *    Function : pnfP5SctpStartReq
+ *
+ *    Functionality:
+ *       Eastablishes the Socket Connection
+ *
+ * @params[in] 
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ *******************************************************************************/
+
+uint8_t pnfP5SctpStartReq()
+{
+   uint8_t assocIdx  = 0;
+   uint8_t ret = ROK;
+
+   socket_type = CM_INET_STREAM;
+
+   if(pnfP5SctpCb.numAssoc)
+   {
+
+      if((ret = cmInetSocket(socket_type, &pnfP5SctpCb.pnfP5LstnSockFd, IPPROTO_SCTP) != ROK))
+      {
+         DU_LOG("\nERROR  -->  SCTP : Socket[%d] coudnt open for listening", pnfP5SctpCb.pnfP5LstnSockFd.fd);
+      } 
+      else if((ret = cmInetSctpBindx(&pnfP5SctpCb.pnfP5LstnSockFd, &pnfP5SctpCb.localAddrLst, pnfP5SctpCb.pnfP5SctpCfg.pnfP5SctpPort)) != ROK)
+      {
+         DU_LOG("\nERROR  -->  SCTP: Binding failed at PNF");
+      }
+      else if((ret = cmInetListen(&pnfP5SctpCb.pnfP5LstnSockFd, 1)) != ROK)
+      {
+         DU_LOG("\nERROR  -->  SCTP: Unable to accept the connection at PNF");
+         DU_LOG("\nERROR  -->  SCTP : Listening on socket failed");
+         cmInetClose(&pnfP5SctpCb.pnfP5LstnSockFd);
+         return RFAILED;
+      }
+      else
+      {
+         for(assocIdx=0; assocIdx < pnfP5SctpCb.numAssoc; assocIdx++)
+         {
+            if((ret = pnfP5SctpAccept(&pnfP5SctpCb.assocCb[assocIdx])) != ROK)
+            {
+               DU_LOG("\nERROR  -->  SCTP: Unable to accept the connection at PNF");
+            }
+         }
+      }
+   }
+
+   if(ret == ROK)
+   {
+      if(pnfP5SctpSockPoll() != ROK)
+      {
+         DU_LOG("\nERROR  -->  SCTP: Polling failed to start at PNF");
+      }
+   }
+   return (ret);
+}
+
+/*******************************************************************
+ *
+ * @brief Initiates connection with peer SCTP
+ *
+ * @details
+ *
+ *    Function : pnfP5SctpAccept
+ *
+ *    Functionality:
+ *       Establishes SCTP connection with peer.
+ *       Here, VNF-P5-SCTP will initate connection towards PNF-P5-SCTP
+ *
+ * @params[in] 
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+uint8_t pnfP5SctpAccept(PnfP5SctpAssocCb *assocCb)
+{
+   uint8_t  ret;
+
+   DU_LOG("\nINFO   -->  SCTP : Connecting");
+
+   while(!assocCb->connUp)
+   {
+      ret = cmInetAccept(&pnfP5SctpCb.pnfP5LstnSockFd, &assocCb->peerAddr, &assocCb->sockFd);
+      if (ret == ROKDNA)
+      {
+         continue;
+      }
+      else if(ret != ROK)
+      {
+         DU_LOG("\nERROR  -->  SCTP : Failed to accept connection");
+         return RFAILED;
+      }
+      else
+      {
+         assocCb->connUp = TRUE;
+         pnfP5SctpSetSockOpts(&assocCb->sockFd);
+         break;
+      }
+   }
+   DU_LOG("\nINFO   -->  SCTP : Connection established");
+
+   return ROK;
+}
+
+/*******************************************************************
+ *
+ * @brief Sets socket options as per requirement
+ *
+ * @details
+ *
+ *    Function : pnfP5SctpSetSockOpts
+ *
+ *    Functionality: 
+ *       Sets socket options as per requirement
+ *
+ * @params[in] 
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+uint8_t pnfP5SctpSetSockOpts(CmInetFd *sock_Fd)
+{
+   S16 ret = ROK;
+   CmSctpEvent sctpEvent;
+  
+   sctpEvent.dataIoEvent          = TRUE;
+   sctpEvent.associationEvent     = TRUE;
+   sctpEvent.addressEvent         = TRUE;
+   sctpEvent.sendFailureEvent     = TRUE;
+   sctpEvent.peerErrorEvent       = TRUE;
+   sctpEvent.shutdownEvent        = TRUE;
+   sctpEvent.partialDeliveryEvent = TRUE;
+   sctpEvent.adaptationLayerEvent = TRUE;
+
+   if((ret = cmInetSetOpt(sock_Fd, CM_SOCKOPT_LEVEL_SCTP, CM_SOCKOPT_OPT_SCTP_EVENTS, &sctpEvent)) != ROK)
+   {
+     ret = RFAILED;
+   }
+  
+   return (ret);
+}
+
+/*******************************************************************
+ *
+ * @brief Receives message on the socket
+ *
+ * @details
+ *
+ *    Function : pnfP5SctpSockPoll
+ *
+ *    Functionality:
+ *      Receives message on the socket
+ *
+ * @params[in] 
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+uint8_t pnfP5SctpSockPoll()
+{
+   uint8_t            assocIdx;
+   uint16_t           ret = ROK;
+   uint32_t           timeout;
+   uint32_t           *timeoutPtr;
+   CmInetMemInfo      memInfo;
+   PnfP5SctpSockPollParams pnfP5PollParams;
+
+   memset(&pnfP5PollParams, 0, sizeof(PnfP5SctpSockPollParams));
+    
+   /* All sockets are non-blocking */
+   timeout = 0;
+   timeoutPtr = &timeout;
+   memInfo.region = PNF_APP_MEM_REG;
+   memInfo.pool   = PNF_POOL;
+
+   CM_INET_FD_ZERO(&pnfP5PollParams.readFd);
+
+   DU_LOG("\nINFO  -->  SCTP : Polling started at PNF\n");
+   while(1)
+   {
+      /* Receiving SCTP data */
+      for(assocIdx = 0; assocIdx < pnfP5SctpCb.numAssoc; assocIdx++)
+      {
+         if((ret = pnfP5ProcessPolling(&pnfP5PollParams, &pnfP5SctpCb.assocCb[assocIdx], timeoutPtr, &memInfo)) != ROK)
+         {
+            DU_LOG("\nERROR  -->  SCTP : Failed to RecvMsg for PNF at P5 Interface \n");
+         }
+      }
+   };
+   return (ret);
+}/* End of sctpSockPoll() */
+
+/*******************************************************************
+ *
+ * @brief checks for valid readFd and process the InetSctpRecvMsg
+ * during polling 
+ *
+ * @details
+ *
+ *    Function : pnfP5ProcessPolling
+ *
+ *    Functionality:
+ *         checks for valid readFd and process the InetSctpRecvMsg
+ *         during polling
+ *
+ * @params[in]  Params required for polling
+ * @params[in]  SockFd for file descriptor
+ * @params[in]  timeoutPtr indicates the timeout value
+ * @params[in]  MemInfo indicates memory region
+ *
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+uint8_t pnfP5ProcessPolling(PnfP5SctpSockPollParams *pollParams, PnfP5SctpAssocCb *assocCb, uint32_t *timeoutPtr, CmInetMemInfo *memInfo)
+{
+   uint16_t ret = ROK;
+
+   CM_INET_FD_SET(&assocCb->sockFd, &pollParams->readFd);
+   ret = cmInetSelect(&pollParams->readFd, NULLP, timeoutPtr, &pollParams->numFd);
+   if(CM_INET_FD_ISSET(&assocCb->sockFd, &pollParams->readFd))
+   {
+      CM_INET_FD_CLR(&assocCb->sockFd, &pollParams->readFd);
+      ret = cmInetSctpRecvMsg(&assocCb->sockFd, &pollParams->addr, &pollParams->port, memInfo, &pollParams->mBuf, \
+          &pollParams->bufLen, &pollParams->info, &pollParams->flag, &pollParams->ntfy);
+      if(assocCb->connUp & (ret != ROK))
+      {
+         DU_LOG("\nERROR  -->  SCTP: Sctp Recv Failed at PNF P5 Interface");
+      //   ret = RFAILED;
+      }
+      else
+      {
+         if(((pollParams->flag & CM_INET_SCTP_MSG_NOTIFICATION) != 0) && (ret == ROK))
+         {
+            ret = pnfP5SctpNtfyHdlr(assocCb, &pollParams->ntfy);
+            if(ret != ROK)
+            {
+               DU_LOG("\nERROR  -->  SCTP : Failed to process sctp notify msg\n");
+               ret = RFAILED;
+            }
+         }
+         else if(assocCb->connUp)
+         {  
+             /*TODO: Add the Handler of PNF P5 msgs*/
+            //E2APMsgHdlr(&assocCb->duId, pollParams->mBuf);
+            ODU_PUT_MSG_BUF(pollParams->mBuf);
+         }
+         else
+         {
+            ODU_PUT_MSG_BUF(pollParams->mBuf);
+         }
+      } 
+  }
+  return ROK;
+}/* End of pnfP5ProcessPolling() */
+
+/*******************************************************************
+ *
+ * @brief Handles an SCTP notification message
+ *
+ * @details
+ *
+ *    Function : pnfP5SctpNtfyHdlr
+ *
+ *    Functionality:
+ *      Handles an SCTP notification message
+ *
+ * @params[in] Notify message
+ *
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+uint8_t pnfP5SctpNtfyHdlr(PnfP5SctpAssocCb *assocCb, CmInetSctpNotification *ntfy)
+{
+   switch(ntfy->header.nType)
+   {
+      case CM_INET_SCTP_ASSOC_CHANGE :
+         DU_LOG("\nINFO   -->  SCTP : Assoc change notification received");
+         switch(ntfy->u.assocChange.state)
+         {
+            case CM_INET_SCTP_COMM_UP:
+               DU_LOG("\nINFO   -->  Event : COMMUNICATION UP");
+               assocCb->connUp = TRUE;
+               break;
+            case CM_INET_SCTP_COMM_LOST:
+               DU_LOG("\nINFO   -->  Event : COMMUNICATION LOST");
+               assocCb->connUp = FALSE;
+               break;
+            case CM_INET_SCTP_RESTART:
+               DU_LOG("\nINFO   -->  Event : SCTP RESTART");
+               assocCb->connUp = FALSE;
+               break;
+            case CM_INET_SCTP_SHUTDOWN_COMP: /* association gracefully shutdown */
+               DU_LOG("\nINFO   -->  Event : SHUTDOWN COMPLETE");
+               assocCb->connUp = FALSE;
+               break;
+            case CM_INET_SCTP_CANT_STR_ASSOC:
+               DU_LOG("\nINFO   -->  Event : CANT START ASSOC");
+               assocCb->connUp = FALSE;
+               break;
+            default:
+               DU_LOG("\nERROR   -->  Invalid event");
+               break;
+         }
+         break;
+      case CM_INET_SCTP_PEER_ADDR_CHANGE :
+         DU_LOG("\nINFO   -->  SCTP : Peer Address Change notificarion received");
+         /* Need to add handler */
+         break;
+      case CM_INET_SCTP_REMOTE_ERROR :
+         DU_LOG("\nINFO   -->  SCTP : Remote Error notification received");
+         break;
+      case CM_INET_SCTP_SEND_FAILED :
+         DU_LOG("\nINFO   -->  SCTP : Send Failed notification received\n");
+         break;
+      case CM_INET_SCTP_SHUTDOWN_EVENT : /* peer socket gracefully closed */
+         DU_LOG("\nINFO   -->  SCTP : Shutdown Event notification received\n");
+         assocCb->connUp = FALSE;
+         /*TODO: delete vnf info or database*/
+         //deleteE2NodeInfo(&ricCb.duInfo[0]);
+         exit(0);
+         break;
+      case CM_INET_SCTP_ADAPTATION_INDICATION :
+         DU_LOG("\nINFO   -->  SCTP : Adaptation Indication received\n");
+         break;
+      case CM_INET_SCTP_PARTIAL_DELIVERY_EVENT:
+         DU_LOG("\nINFO   -->  SCTP : Partial Delivery Event received\n");
+         break;
+      default:
+         DU_LOG("\nERROR   -->  SCTP : Invalid notification type\n");
+         break;
+   }
+
+   return ROK;
+}/* End of pnfP5SctpNtfyHdlr */
+
+/*******************************************************************
+ *
+ * @brief Send message on SCTP socket
+ *
+ * @details
+ *
+ *    Function : sctpSend 
+ *
+ *    Functionality:
+ *        Send message on SCTP socket
+ *
+ * @params[in] 
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+//uint8_t pnfP5SctpSend(uint32_t vnfId, Buffer *mBuf) /*TODO: To check the VNF ID requirement here*/
+uint8_t pnfP5SctpSend(Buffer *mBuf)
+{
+   uint8_t          assocIdx;
+   uint8_t          ret;
+   MsgLen           len;          /* number of actually sent octets */
+   CmInetMemInfo    memInfo;                        
+   
+   memInfo.region = PNF_APP_MEM_REG;               
+   memInfo.pool   = PNF_POOL;
+
+   for(assocIdx = 0; assocIdx < pnfP5SctpCb.numAssoc; assocIdx++)
+   {
+      /*TODO: To check whether below check req using VNFID*/
+     // if(sctpCb.assocCb[assocIdx].duId == duId)
+      {
+         ret = cmInetSctpSendMsg(&pnfP5SctpCb.assocCb[assocIdx].sockFd, &pnfP5SctpCb.assocCb[assocIdx].destIpNetAddr, \
+               pnfP5SctpCb.assocCb[assocIdx].destPort, &memInfo, mBuf, &len, 0, FALSE, 0, 0/*SCT_PROTID_NONE*/, RWOULDBLOCK);
+
+         if(ret != ROK && ret != RWOULDBLOCK)
+         {
+            DU_LOG("\nERROR  -->  SCTP : Send message failed");
+            return RFAILED;
+         }
+      }
+   }
+   return ROK;
+} /* End of pnfP5SctpSend */
+/**********************************************************************
+         End of file
+**********************************************************************/
+
+
diff --git a/src/pnf_stub/pnf_stub_sctp.h b/src/pnf_stub/pnf_stub_sctp.h
new file mode 100644 (file)
index 0000000..7912cb7
--- /dev/null
@@ -0,0 +1,103 @@
+/*******************************************************************************
+################################################################################
+#   Copyright (c) [2017-2019] [Radisys]                                        #
+#                                                                              #
+#   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.                                             #
+################################################################################
+*******************************************************************************/
+
+/* This file contains all SCTP related functionality */
+
+#ifndef __PNF_SCTP_H__
+#define __PNF_SCTP_H__
+
+#define MAX_RETRY 5
+#define MAX_IPV6_LEN 16
+#define MAX_VNF_SUPPORTED 2
+#define MAX_ASSOC_SUPPORTED MAX_VNF_SUPPORTED
+
+/* Global variable declaration */
+extern uint8_t   socket_type;      /* Socket type */
+
+typedef struct pnfP5SctpSockPollParams
+{
+   uint16_t           numFd;
+   uint16_t           port;   
+   uint32_t           flag;
+   Buffer            *mBuf;
+   MsgLen             bufLen; 
+   CmInetNetAddr      addr;
+   CmInetFdSet        readFd;
+   CmInetSctpSndRcvInfo   info;
+   CmInetSctpNotification ntfy;
+}PnfP5SctpSockPollParams;
+
+typedef struct pnfP5SctpAssocCb
+{
+   uint32_t              vnfId;
+   uint16_t              destPort;         /* VNF PORTS */
+   CmInetFd              sockFd;           /* Socket file descriptor */
+   CmInetAddr            peerAddr;
+   CmInetNetAddr         destIpNetAddr;    /* VNF Ip address */ 
+   Bool                  connUp;
+}PnfP5SctpAssocCb;
+
+typedef struct pnfP5SctpIpAddr
+{
+ bool      ipV4Pres;
+ uint32_t  ipV4Addr;
+ bool      ipV6Pres;
+ uint8_t   ipV6Addr[MAX_IPV6_LEN];
+}PnfP5SctpIpAddr;
+
+typedef struct pnfP5SctpDestInfo
+{
+   PnfP5SctpIpAddr  destIpAddr;
+   uint16_t         destPort;
+}PnfP5SctpDestInfo;
+
+typedef struct pnfP5SctpParams
+{
+   PnfP5SctpIpAddr     pnfP5localIpAddr;
+   uint16_t            pnfP5SctpPort;
+   uint8_t             numDestNode;
+   PnfP5SctpDestInfo   destCb[MAX_VNF_SUPPORTED];
+}PnfP5SctpParams;
+
+typedef struct pnfP5SctpGlobalCb
+{
+   PnfP5SctpParams    pnfP5SctpCfg;
+   CmInetNetAddrLst   localAddrLst;
+   CmInetFd           pnfP5LstnSockFd;       /* Listening Socket file descriptor*/
+   uint8_t            numAssoc;
+   PnfP5SctpAssocCb   assocCb[MAX_ASSOC_SUPPORTED]; 
+}PnfP5SctpGlobalCb;
+
+extern PnfP5SctpGlobalCb pnfP5SctpCb;
+
+uint8_t pnfP5SctpActvInit();
+uint8_t pnfP5SctpCfgReq();
+uint8_t pnfP5SctpStartReq();
+uint8_t pnfP5SctpAccept(PnfP5SctpAssocCb *assocCb);
+uint8_t pnfP5SctpSetSockOpts(CmInetFd *sock_Fd);
+uint8_t pnfP5SctpAccept(PnfP5SctpAssocCb *assocCb);
+uint8_t pnfP5SctpSockPoll();
+uint8_t pnfP5ProcessPolling(PnfP5SctpSockPollParams *pollParams, PnfP5SctpAssocCb *assocCb, uint32_t *timeoutPtr, CmInetMemInfo *memInfo);
+uint8_t pnfP5SctpNtfyHdlr(PnfP5SctpAssocCb *assocCb, CmInetSctpNotification *ntfy);
+uint8_t pnfP5SctpSend(Buffer *mBuf);
+
+#endif
+
+/**********************************************************************
+         End of file
+ **********************************************************************/