Commit d32cdd1f authored by Raymond Knopp's avatar Raymond Knopp

Merge remote-tracking branch 'origin/develop' into develop-nos1-fixes

Conflicts:
	openair1/SCHED/fapi_l1.c
	openair1/SCHED/phy_procedures_lte_eNb.c
	openair2/LAYER2/MAC/config.c
parents 39d33dc4 8489e406
...@@ -27,8 +27,8 @@ cmake_minimum_required (VERSION 2.8) ...@@ -27,8 +27,8 @@ cmake_minimum_required (VERSION 2.8)
# Base directories, compatible with legacy OAI building # Base directories, compatible with legacy OAI building
################################################ ################################################
set (OPENAIR_DIR $ENV{OPENAIR_DIR}) set (OPENAIR_DIR $ENV{OPENAIR_DIR})
#set (NFAPI_DIR $ENV{NFAPI_DIR}) set (NFAPI_DIR ${OPENAIR_DIR}/nfapi/open-nFAPI)
set (NFAPI_DIR ${OPENAIR_DIR}/nfapi) set (NFAPI_USER_DIR ${OPENAIR_DIR}/nfapi/oai_integration)
set (OPENAIR1_DIR ${OPENAIR_DIR}/openair1) set (OPENAIR1_DIR ${OPENAIR_DIR}/openair1)
set (OPENAIR2_DIR ${OPENAIR_DIR}/openair2) set (OPENAIR2_DIR ${OPENAIR_DIR}/openair2)
set (OPENAIR3_DIR ${OPENAIR_DIR}/openair3) set (OPENAIR3_DIR ${OPENAIR_DIR}/openair3)
...@@ -769,7 +769,12 @@ else() ...@@ -769,7 +769,12 @@ else()
include_directories("${OPENAIR2_DIR}/UTIL") include_directories("${OPENAIR2_DIR}/UTIL")
include_directories("${OPENAIR2_DIR}/UTIL/LOG") include_directories("${OPENAIR2_DIR}/UTIL/LOG")
endif() endif()
include_directories("${NFAPI_DIR}") include_directories("${NFAPI_DIR}/nfapi/public_inc")
include_directories("${NFAPI_DIR}/common/public_inc")
include_directories("${NFAPI_DIR}/pnf/public_inc")
include_directories("${NFAPI_DIR}/nfapi/inc")
include_directories("${NFAPI_DIR}/sim_common/inc")
include_directories("${NFAPI_DIR}/pnf_sim/inc")
include_directories("${OPENAIR1_DIR}") include_directories("${OPENAIR1_DIR}")
include_directories("${OPENAIR2_DIR}/NAS") include_directories("${OPENAIR2_DIR}/NAS")
include_directories("${OPENAIR2_DIR}") include_directories("${OPENAIR2_DIR}")
...@@ -1011,6 +1016,58 @@ set(SCHED_SRC ...@@ -1011,6 +1016,58 @@ set(SCHED_SRC
) )
add_library(SCHED_LIB ${SCHED_SRC}) add_library(SCHED_LIB ${SCHED_SRC})
# nFAPI
#################################
set(NFAPI_COMMON_SRC
${NFAPI_DIR}/common/src/debug.c
)
add_library(NFAPI_COMMON_LIB ${NFAPI_COMMON_SRC})
include_directories(${NFAPI_DIR}/common/public_inc)
set(NFAPI_SRC
${NFAPI_DIR}/nfapi/src/nfapi.c
${NFAPI_DIR}/nfapi/src/nfapi_p4.c
${NFAPI_DIR}/nfapi/src/nfapi_p5.c
${NFAPI_DIR}/nfapi/src/nfapi_p7.c
)
add_library(NFAPI_LIB ${NFAPI_SRC})
include_directories(${NFAPI_DIR}/nfapi/public_inc)
include_directories(${NFAPI_DIR}/nfapi/inc)
set(NFAPI_PNF_SRC
${NFAPI_DIR}/pnf/src/pnf.c
${NFAPI_DIR}/pnf/src/pnf_interface.c
${NFAPI_DIR}/pnf/src/pnf_p7.c
${NFAPI_DIR}/pnf/src/pnf_p7_interface.c
)
add_library(NFAPI_PNF_LIB ${NFAPI_PNF_SRC})
include_directories(${NFAPI_DIR}/pnf/public_inc)
include_directories(${NFAPI_DIR}/pnf/inc)
set(NFAPI_VNF_SRC
${NFAPI_DIR}/vnf/src/vnf.c
${NFAPI_DIR}/vnf/src/vnf_interface.c
${NFAPI_DIR}/vnf/src/vnf_p7.c
${NFAPI_DIR}/vnf/src/vnf_p7_interface.c
)
add_library(NFAPI_VNF_LIB ${NFAPI_VNF_SRC})
include_directories(${NFAPI_DIR}/vnf/public_inc)
include_directories(${NFAPI_DIR}/vnf/inc)
# nFAPI user defined code
#############################
set(NFAPI_USER_SRC
${NFAPI_USER_DIR}/nfapi.c
${NFAPI_USER_DIR}/nfapi_pnf.c
${NFAPI_USER_DIR}/nfapi_vnf.c
)
add_library(NFAPI_USER_LIB ${NFAPI_USER_SRC})
include_directories(${NFAPI_USER_DIR})
# Layer 1 # Layer 1
############################# #############################
set(PHY_SRC set(PHY_SRC
...@@ -1206,6 +1263,8 @@ add_library(L2 ...@@ -1206,6 +1263,8 @@ add_library(L2
${ENB_APP_SRC}) ${ENB_APP_SRC})
# ${OPENAIR2_DIR}/RRC/L2_INTERFACE/openair_rrc_L2_interface.c) # ${OPENAIR2_DIR}/RRC/L2_INTERFACE/openair_rrc_L2_interface.c)
include_directories(${NFAPI_USER_DIR})
if (FLEXRAN_AGENT_SB_IF) if (FLEXRAN_AGENT_SB_IF)
#Test for adding a shared library #Test for adding a shared library
...@@ -1619,6 +1678,13 @@ add_library(OPENAIR0_LIB ...@@ -1619,6 +1678,13 @@ add_library(OPENAIR0_LIB
${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c ${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c
) )
include_directories("${NFAPI_DIR}/nfapi/public_inc")
include_directories("${NFAPI_DIR}/common/public_inc")
include_directories("${NFAPI_DIR}/pnf/public_inc")
include_directories("${NFAPI_DIR}/nfapi/inc")
include_directories("${NFAPI_DIR}/sim_common/inc")
include_directories("${NFAPI_DIR}/pnf_sim/inc")
# System packages that are required # System packages that are required
# We use either the cmake buildin, in ubuntu are in: /usr/share/cmake*/Modules/ # We use either the cmake buildin, in ubuntu are in: /usr/share/cmake*/Modules/
# or cmake provide a generic interface to pkg-config that widely used # or cmake provide a generic interface to pkg-config that widely used
...@@ -1785,10 +1851,12 @@ add_executable(lte-softmodem ...@@ -1785,10 +1851,12 @@ add_executable(lte-softmodem
${SHLIB_LOADER_SOURCES} ${SHLIB_LOADER_SOURCES}
) )
target_link_libraries (lte-softmodem -ldl target_link_libraries (lte-softmodem
-Wl,--start-group -Wl,--start-group
RRC_LIB S1AP_LIB S1AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS L2 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${MIH_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 RRC_LIB S1AP_LIB S1AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS L2 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${MIH_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7
-Wl,--end-group ) NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB
NFAPI_USER_LIB
-Wl,--end-group z dl)
target_link_libraries (lte-softmodem ${LIBXML2_LIBRARIES}) target_link_libraries (lte-softmodem ${LIBXML2_LIBRARIES})
target_link_libraries (lte-softmodem pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES}) target_link_libraries (lte-softmodem pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES})
...@@ -1916,17 +1984,18 @@ target_include_directories(oaisim PUBLIC ${OPENAIR_TARGETS}/SIMU/USER) ...@@ -1916,17 +1984,18 @@ target_include_directories(oaisim PUBLIC ${OPENAIR_TARGETS}/SIMU/USER)
target_link_libraries (oaisim target_link_libraries (oaisim
-Wl,-ldl,--start-group -Wl,-ldl,--start-group
RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB GTPV1U SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS ${MSC_LIB} L2 ${RAL_LIB} LIB_NAS_UE SIMU SECU_OSA ${ITTI_LIB} ${MIH_LIB} RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB GTPV1U SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS ${MSC_LIB} L2 ${RAL_LIB} LIB_NAS_UE SIMU SECU_OSA ${ITTI_LIB} ${MIH_LIB}
NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB
NFAPI_USER_LIB
-Wl,--end-group ) -Wl,--end-group )
target_link_libraries (oaisim ${LIBXML2_LIBRARIES} ${LAPACK_LIBRARIES}) target_link_libraries (oaisim ${LIBXML2_LIBRARIES} ${LAPACK_LIBRARIES})
target_link_libraries (oaisim pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp target_link_libraries (oaisim pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp z
${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${OPENPGM_LIBRARIES}) ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${OPENPGM_LIBRARIES} )
#Force link with forms, regardless XFORMS option #Force link with forms, regardless XFORMS option
target_link_libraries (oaisim forms) target_link_libraries (oaisim forms)
target_link_libraries (oaisim ${T_LIB}) target_link_libraries (oaisim ${T_LIB})
# A all in one network simulator # A all in one network simulator
################ ################
add_executable(oaisim_nos1 add_executable(oaisim_nos1
......
...@@ -199,7 +199,7 @@ function main() { ...@@ -199,7 +199,7 @@ function main() {
GDB=1 GDB=1
CMAKE_BUILD_TYPE="Debug" CMAKE_BUILD_TYPE="Debug"
echo_info "Will Compile with gdb symbols and disable compiler optimization" echo_info "Will Compile with gdb symbols and disable compiler optimization"
CMAKE_CMD="$CMAKE_CMD -DCMAKE_BUILD_TYPE=Debug" CMAKE_CMD="$CMAKE_CMD -DCMAKE_BUILD_TYPE=Debug --trace-expand"
shift;; shift;;
--eNB) --eNB)
eNB=1 eNB=1
......
...@@ -95,6 +95,8 @@ get_distribution_release() { ...@@ -95,6 +95,8 @@ get_distribution_release() {
check_supported_distribution() { check_supported_distribution() {
local distribution=$(get_distribution_release) local distribution=$(get_distribution_release)
case "$distribution" in case "$distribution" in
"ubuntu17.10") return 0 ;;
"ubuntu17.04") return 0 ;;
"ubuntu16.04") return 0 ;; "ubuntu16.04") return 0 ;;
"ubuntu14.04") return 0 ;; "ubuntu14.04") return 0 ;;
"fedora24") return 0 ;; "fedora24") return 0 ;;
...@@ -230,6 +232,7 @@ install_protobuf_c_from_source(){ ...@@ -230,6 +232,7 @@ install_protobuf_c_from_source(){
rm -rf /tmp/protobuf-c rm -rf /tmp/protobuf-c
git clone https://github.com/protobuf-c/protobuf-c.git git clone https://github.com/protobuf-c/protobuf-c.git
cd protobuf-c cd protobuf-c
git checkout 2a46af42784abf86804d536f6e0122d47cfeea45
./autogen.sh ./autogen.sh
./configure ./configure
echo "Compiling protobuf-c" echo "Compiling protobuf-c"
...@@ -479,16 +482,26 @@ check_install_oai_software() { ...@@ -479,16 +482,26 @@ check_install_oai_software() {
fi fi
$SUDO $INSTALLER update -y $SUDO $INSTALLER update -y
if [[ "$OS_DISTRO" == "ubuntu" ]]; then if [[ "$OS_DISTRO" == "ubuntu" ]]; then
local LAPACK_LIBNAME="liblapack.so"
local LAPACK_TARGET="/usr/lib/atlas-base/atlas/liblapack.so"
$SUDO apt install -y software-properties-common $SUDO apt install -y software-properties-common
case "$(get_distribution_release)" in case "$(get_distribution_release)" in
"ubuntu14.04") "ubuntu14.04")
specific_packages="libtasn1-3-dev" specific_packages="libtasn1-3-dev gccxml libgnutls-dev libatlas-dev"
# For iperf3 # For iperf3
$SUDO add-apt-repository "deb http://archive.ubuntu.com/ubuntu trusty-backports universe" $SUDO add-apt-repository "deb http://archive.ubuntu.com/ubuntu trusty-backports universe"
$SUDO apt-get update $SUDO apt-get update
;; ;;
"ubuntu16.04") "ubuntu16.04")
specific_packages="libtasn1-6-dev" specific_packages="libtasn1-6-dev gccxml libgnutls-dev libatlas-dev"
;;
"ubuntu17.04")
specific_packages="libtasn1-6-dev castxml libgnutls28-dev libatlas-dev"
;;
"ubuntu17.10")
specific_packages="libtasn1-6-dev castxml libgnutls28-dev"
LAPACK_LIBNAME="liblapack.so-x86_64-linux-gnu"
LAPACK_TARGET="/usr/lib/x86_64-linux-gnu/atlas/liblapack.so"
;; ;;
esac esac
$SUDO apt-get install -y \ $SUDO apt-get install -y \
...@@ -504,7 +517,6 @@ check_install_oai_software() { ...@@ -504,7 +517,6 @@ check_install_oai_software() {
texlive-latex-base \ texlive-latex-base \
ethtool \ ethtool \
flex \ flex \
gccxml \
gdb \ gdb \
git \ git \
graphviz \ graphviz \
...@@ -515,7 +527,6 @@ check_install_oai_software() { ...@@ -515,7 +527,6 @@ check_install_oai_software() {
iptables \ iptables \
iptables-dev \ iptables-dev \
libatlas-base-dev \ libatlas-base-dev \
libatlas-dev \
libblas-dev \ libblas-dev \
libconfig8-dev \ libconfig8-dev \
libffi-dev \ libffi-dev \
...@@ -553,11 +564,9 @@ check_install_oai_software() { ...@@ -553,11 +564,9 @@ check_install_oai_software() {
wget \ wget \
libxpm-dev libxpm-dev
$SUDO update-alternatives --set liblapack.so /usr/lib/atlas-base/atlas/liblapack.so $SUDO update-alternatives --set "$LAPACK_LIBNAME" "$LAPACK_TARGET"
$SUDO apt-get install -y nettle-dev nettle-bin $SUDO apt-get install -y nettle-dev nettle-bin
$SUDO apt-get install -y libgnutls-dev
elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then
if [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "centos" ]]; then if [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "centos" ]]; then
if rpm -q epel-release > /dev/null; then if rpm -q epel-release > /dev/null; then
......
...@@ -128,6 +128,7 @@ int config_get(paramdef_t *params,int numparams, char *prefix) ...@@ -128,6 +128,7 @@ int config_get(paramdef_t *params,int numparams, char *prefix)
{ {
int ret= -1; int ret= -1;
printf("numparams:%d prefix:%s\n", numparams, prefix);
if (CONFIG_ISFLAGSET(CONFIG_ABORT)) { if (CONFIG_ISFLAGSET(CONFIG_ABORT)) {
fprintf(stderr,"[CONFIG] config_get skipped, config module not properly initialized\n"); fprintf(stderr,"[CONFIG] config_get skipped, config module not properly initialized\n");
return ret; return ret;
......
...@@ -29,7 +29,7 @@ typedef struct { ...@@ -29,7 +29,7 @@ typedef struct {
#define T_SHM_FILENAME "/T_shm_segment" #define T_SHM_FILENAME "/T_shm_segment"
/* number of VCD functions (to be kept up to date! see in T_messages.txt) */ /* number of VCD functions (to be kept up to date! see in T_messages.txt) */
#define VCD_NUM_FUNCTIONS 178 #define VCD_NUM_FUNCTIONS 187
/* number of VCD variables (to be kept up to date! see in T_messages.txt) */ /* number of VCD variables (to be kept up to date! see in T_messages.txt) */
#define VCD_NUM_VARIABLES 128 #define VCD_NUM_VARIABLES 128
......
...@@ -2157,3 +2157,39 @@ ID = VCD_FUNCTION_TRX_DECOMPR_IF ...@@ -2157,3 +2157,39 @@ ID = VCD_FUNCTION_TRX_DECOMPR_IF
DESC = VCD function TRX_DECOMPR_IF DESC = VCD function TRX_DECOMPR_IF
GROUP = ALL:VCD:ENB:VCD_FUNCTION GROUP = ALL:VCD:ENB:VCD_FUNCTION
FORMAT = int,value FORMAT = int,value
ID = VCD_FUNCTION_NFAPI
DESC = VCD function NFAPI
GROUP = ALL:VCD:ENB:VCD_FUNCTION
FORMAT = int,value
ID = VCD_FUNCTION_GENERATE_PCFICH
DESC = VCD function GENERATE_PCFICH
GROUP = ALL:VCD:ENB:VCD_FUNCTION
FORMAT = int,value
ID = VCD_FUNCTION_GENERATE_DCI0
DESC = VCD function GENERATE_DCI0
GROUP = ALL:VCD:ENB:VCD_FUNCTION
FORMAT = int,value
ID = VCD_FUNCTION_GENERATE_DLSCH
DESC = VCD function GENERATE_DLSCH
GROUP = ALL:VCD:ENB:VCD_FUNCTION
FORMAT = int,value
ID = VCD_FUNCTION_GENERATE_PHICH
DESC = VCD function GENERATE_PHICH
GROUP = ALL:VCD:ENB:VCD_FUNCTION
FORMAT = int,value
ID = VCD_FUNCTION_PDCCH_SCRAMBLING
DESC = VCD function PDCCH_SCRAMBLING
GROUP = ALL:VCD:ENB:VCD_FUNCTION
FORMAT = int,value
ID = VCD_FUNCTION_PDCCH_MODULATION
DESC = VCD function PDCCH_MODULATION
GROUP = ALL:VCD:ENB:VCD_FUNCTION
FORMAT = int,value
ID = VCD_FUNCTION_PDCCH_INTERLEAVING
DESC = VCD function PDCCH_INTERLEAVING
GROUP = ALL:VCD:ENB:VCD_FUNCTION
FORMAT = int,value
ID = VCD_FUNCTION_PDCCH_TX
DESC = VCD function PDCCH_TX
GROUP = ALL:VCD:ENB:VCD_FUNCTION
FORMAT = int,value
This directory contains the NFAPI code.
It comes in two parts:
1 - open-nFAPI
This is a clone of the github repository
(https://github.com/cisco/open-nFAPI,
commit b3bc579b1697eab829d5d8a2de59c93a61b88fa4).
The patch open-nfapi.oai.patch has then been applied.
2 - oai_integration
This is code written by David Price from Cisco to integrate
open-nFAPI into OpenAirInterface.
/*
* 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
*
* 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 <stdio.h>
#include <pthread.h>
void set_thread_priority(int priority)
{
//printf("%s(priority:%d)\n", __FUNCTION__, priority);
pthread_attr_t ptAttr;
struct sched_param schedParam;
schedParam.__sched_priority = priority; //79;
if(sched_setscheduler(0, SCHED_RR, &schedParam) != 0)
{
printf("Failed to set scheduler to SCHED_RR\n");
}
if(pthread_attr_setschedpolicy(&ptAttr, SCHED_RR) != 0)
{
printf("Failed to set pthread sched policy SCHED_RR\n");
}
pthread_attr_setinheritsched(&ptAttr, PTHREAD_EXPLICIT_SCHED);
struct sched_param thread_params;
thread_params.sched_priority = 20;
if(pthread_attr_setschedparam(&ptAttr, &thread_params) != 0)
{
printf("failed to set sched param\n");
}
}
This diff is collapsed.
/*
* 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
*
* 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
*/
#if !defined(NFAPI_PNF_H__)
#define NFAPI_PNF_H__
void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port);
#endif
This diff is collapsed.
/*
* 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
*
* 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
*/
#if !defined(NFAPI_VNF_H__)
#define NFAPI_VNF_H__
void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port);
#endif
/*
* Copyright 2017 Cisco Systems, Inc.
*
* 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 _VENDOR_EXT_H_
#define _VENDOR_EXT_H_
#include "nfapi_interface.h"
typedef enum {
P5_VENDOR_EXT_REQ = NFAPI_VENDOR_EXT_MSG_MIN,
P5_VENDOR_EXT_RSP,
P7_VENDOR_EXT_REQ,
P7_VENDOR_EXT_IND
} vendor_ext_message_id_e;
typedef struct {
nfapi_p4_p5_message_header_t header;
uint16_t dummy1;
uint16_t dummy2;
} vendor_ext_p5_req;
typedef struct {
nfapi_p4_p5_message_header_t header;
uint16_t error_code;
} vendor_ext_p5_rsp;
typedef struct {
nfapi_p7_message_header_t header;
uint16_t dummy1;
uint16_t dummy2;
} vendor_ext_p7_req;
typedef struct {
nfapi_p7_message_header_t header;
uint16_t error_code;
} vendor_ext_p7_ind;
typedef struct {
nfapi_tl_t tl;
uint32_t dummy;
} vendor_ext_tlv_1;
#define VENDOR_EXT_TLV_1_TAG 0xF001
typedef struct {
nfapi_tl_t tl;
uint32_t dummy;
} vendor_ext_tlv_2;
#define VENDOR_EXT_TLV_2_TAG 0xF002
#endif // _VENDOR_EXT_
env:
global:
# The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
# via the "travis encrypt" command using the project repo's public key
- secure: "oNj8JhGBN/zjzrAU7y2Nn/wxSxA/MDp2Y8fVLLp6fhx+y2mWdlMZhgCjeKSpdbGtroUnxErX1P8t+8EPz2+mMoq+G809Q9t7eJjd1+6nkVhEEfDXN83BmJkvIylC0/IKJiT2wCa8LzbdhpQUFyZ1Gk1WKZozAW5HotfFjm6/NFi/GX4uA7S0tU5E4yC3r4yqH9cLZ+arWMOEY/X0lrx0n6tLjDe921kFwkZQGFzAzrbXN2fZXKQ3xFcpREWEgEWsY7H2n4T7oJI3nEPY4P/4kvCjeQMjnlATEwtcciBiUbHRew4WWSTndF54crRlqFlzFcEf/Ouz27U/d2xYHJWcWNi88l+/qsb+V0uobwhiGUJGbVhf9IkgEO3tr/zbwkPDFrXpa/1xuSoc6jDm8i61gKQkcBhQsRFXlciPvwLhiL07gzeAfZD1Yke3tE+0geHPbEA0czzwtHe35jorAKYWsFXOXmcoK9t9SpnvBRFz6JuEsHPooafze43sTJg3qkgBszkU+U38CneeAVwo/uTA3Zw1ZrtOQv56v0UvAHze/VAF5z3rFJPl1oJl60OI8V5UBg4yIa2bySKhO//zwd4MGmsBpcWwDuu2BHUVasfk0vaetVxVVtdXG/2BuBP+IXinpJtI48NSFs6PT82dHz4cDF/iLDs0hPC6sbV258PY8F0="
language: cpp
dist: trusty
sudo: required
compiler:
- g++
before_install:
- sudo apt-get install doxygen
- sudo apt-get install libcunit1-dev
- sudo apt-get install libz-dev
- sudo apt-get install libsctp-dev
- sudo apt-get install libboost-all-dev
- autoreconf -i
addons:
coverity_scan:
project:
name: cisco-open-nFAPI
version: 1.0
description: Build submitted via Travis CI
notification_email: xxx@cisco.com
build_command_prepend: ./configure
build_command: make
branch_pattern: coverity_scan
script:
- ./configure && make && make check
This diff is collapsed.
ACLOCAL_AMFLAGS = -I m4
SUBDIRS =common/ \
sim_common/ \
nfapi/ \
pnf/ \
vnf/ \
nfapi/tests \
pnf/tests \
vnf/tests \
pnf_sim/ \
vnf_sim/ \
integration_tests/ \
docs/ \
$(NULL)
[![Build Status](https://travis-ci.org/cisco/open-nFAPI.svg?branch=master)](https://travis-ci.org/cisco/open-nFAPI)
[![Coverity Status](https://scan.coverity.com/projects/11791/badge.svg)](https://scan.coverity.com/projects/cisco-open-nfapi)
# open-nFAPI
Open-nFAPI is implementation of the Small Cell Forum's network functional API or nFAPI for short.
nFAPI defines a network protocol that is used to connect a Physical Network Function (PNF)
running LTE Layer 1 to a Virtual Network Function (VNF) running LTE layer 2 and above. The specification
can be found at http://scf.io/documents/082.
The aim of open-nFAPI is to provide an open interface between LTE layer 1 and layer 2 to allow for
interoperability between the PNF and VNF & also to facilitate the sharing of PNF's between
different VNF's
Open-nFAPI implements the P4, P5 and P7 interfaces as defined by the nFAPI specification.
* The P5 interface allows the VNF to query and configure the 'resources' of the PNF; i.e slice it into
1 or more PHY instances.
* The P7 interface is used to send the subframe information between the PNF and VNF for a PHY instance
* The P4 interface allows the VNF to request the PNF PHY instance to perform measurements of the surrounding network
The remaining interfaces are currently outside of the scope of this project.
Supports release 082.09.05 of the nFAPI specification
**The Small Cell Forum cordially requests that any derivative work that looks to
extend the nFAPI libraries use the specified vendor extension techniques,
so ensuring the widest interoperability of the baseline nFAPI specification
in those derivative works.**
## Awards
The Open-nFAPI project has won the Small Cell Forum Judges Choice award 2017. (http://www.smallcellforum.org/awards-2/winners-2017/)
## Licensing
The open-nFAPI libraries are release by CISCO under an Apache 2 license. See `LICENSE.md` file for details
## Downloading
The open-nFAPI project can be pulled from git hub
```
git clone https://github.com/cisco/open-nFAPI.git nfapi
```
The following dependencies are required. These are based on a fresh ubuntu installation.
```
sudo apt-get install autoconf
sudo apt-get install gcc
sudo apt-get install g++
sudo apt-get install libtool
sudo apt-get install make
sudo apt-get install doxygen
sudo apt-get install libcunit1-dev
sudo apt-get install libz-dev
sudo apt-get install libsctp-dev
sudo apt-get install libboost-all-dev
```
## Building
To build the open-nFAPI project
```
autoreconf -i
./configure
make
```
To run the unit and integration tests
```
make check
```
You may notice in the console output of the final integration tests the following
```
*** Missing subframe 123 125
```
Out of the box the machine on which you are running has not be configured for real time operation as a result
the vnf may not be scheduled at the correct times and hence it may risk 'missing' subframe opportunities. This
warning indicates this has happened.
## Running the simulator
The vnf and pnf simulator can be run using the following commands. The pnf and vnf simulator support sourcing and sinking
data over udp. Review the xml configuration files for the details of the port and address to configure. Console logging will show
which address:port is being used
Note : Pinning the simulators to unused cores will produce more consistent behaviour.
Note : You may have to run the processes with sudo to be able to set the real time scheduling and priority
### vnf simulator
To run the vnf simulator you need to specify the port the vnf will listen for p5 connection request upon and also the xml configuration file
```
vnfsim <port> <xml config file>
```
### pnf simulator
To run the vnf simulator you need to specify the addrss & port the pnf will connect to the vnf on and also the xml configuration file
```
pnfsim <address> <port> <xml config file>
```
## Directory structure
```
docs doxgen documentation
common common code used by the nfapi libraries
nfapi the nfapi library including message definitions & encode/decode functions
pnf the pnf library for p4, p5, & p7 interfaces
vnf the vnf library for p4, p5, & p7 interfaces
sim_common common simulation for used by the vnf and pnf sim
vnf_sim a vnf simulator including a stub mac implementation
pnf_sim a pnf simualtor including a fapi interface defintion and stub implementation
xml xml configuration files for the vnf and pnf simulator
wireshark code for a wireshark dissector for the nFAPI protocol
```
## Coverity
Coverity runs on the coverity-scan branch. Changes must be merged to the coverity-scan branch to be checked.
## eNB Integration - Open Air Interface
The open-nFAPI implementation has been integrated with the Open Air Interface solution here (https://gitlab.eurecom.fr/oai/openairinterface5g) and is (at the time of writing) here (https://gitlab.eurecom.fr/daveprice/openairinterface5g/tree/nfapi-ru-rau-split). The open-nFAPI implementation is integrated with the source eNB implementation with any changes required applied as a patch on top of the baseline open-nFAPI library. Any extensions required must be implemented through the vendor extensions as specified by the Small Cell Forum documentation. Any integration wrapping of functionality must be done within the target environment as shown in the Open Air Interface implementation nfapi directory which is defined by the $NFAPI_DIR location at the top level.
#
# Copyright 2017 Cisco Systems, Inc.
#
# 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.
#
AM_CPPFLAGS = -I$(top_srcdir)/common/public_inc -g -Wall -Werror
noinst_LIBRARIES =libnfapi_common.a
libnfapi_common_a_SOURCES = src/debug.c
libnfapi_common_a_CFLAGS =$(AM_CFLAGS)
lib_LTLIBRARIES =libnfapi_common.la
libnfapi_common_la_SOURCES = src/debug.c
/*
* Copyright 2017 Cisco Systems, Inc.
*
* 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 _DEBUG_H_
#define _DEBUG_H_
/*! The trace levels used by the nfapi libraries */
typedef enum nfapi_trace_level
{
NFAPI_TRACE_ERROR = 1,
NFAPI_TRACE_WARN,
NFAPI_TRACE_NOTE,
NFAPI_TRACE_INFO,
NFAPI_TRACE_LEVEL_MAX
} nfapi_trace_level_t;
/*! The trace function pointer */
typedef void (*nfapi_trace_fn_t)(nfapi_trace_level_t level, const char* format, ...);
/*! Global trace function */
extern nfapi_trace_fn_t nfapi_trace_g;
/*! Global trace level */
extern nfapi_trace_level_t nfapi_trace_level_g;
/*! NFAPI trace macro */
//#define NFAPI_TRACE(level, format, ...) { if(nfapi_trace_g && ((nfapi_trace_level_t)level <= nfapi_trace_level_g)) (*nfapi_trace_g)(level, format, ##__VA_ARGS__); }
#define NFAPI_TRACE(level, format, ...) { if (nfapi_trace_g) (*nfapi_trace_g)(level, format, ##__VA_ARGS__); }
/*! Function to change the trace level
* \param new_level The modified trace level
*/
void nfapi_set_trace_level(nfapi_trace_level_t new_level);
#endif /* _DEBUG_H_ */
/*
* Copyright 2017 Cisco Systems, Inc.
*
* 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.
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/types.h>
#include <pthread.h>
#include <syslog.h>
#include <debug.h>
#define MAX_MSG_LENGTH 2096
#define TRACE_HEADER_LENGTH 44
void nfapi_trace_dbg(nfapi_trace_level_t level, const char *format, ...);
// initialize the trace function to 0
void (*nfapi_trace_g)(nfapi_trace_level_t level, const char* format, ...) = &nfapi_trace_dbg;
nfapi_trace_level_t nfapi_trace_level_g = NFAPI_TRACE_INFO;
//nfapi_trace_level_t nfapi_trace_level_g = NFAPI_TRACE_WARN;
void nfapi_set_trace_level(nfapi_trace_level_t new_level)
{
nfapi_trace_level_g = new_level;
}
void nfapi_trace_dbg(nfapi_trace_level_t level, const char *format, ...)
{
char trace_buff[MAX_MSG_LENGTH + TRACE_HEADER_LENGTH];
uint32_t num_chars;
va_list p_args;
struct timeval tv;
pthread_t tid = pthread_self();
(void)gettimeofday(&tv, NULL);
num_chars = (uint32_t)snprintf(trace_buff, TRACE_HEADER_LENGTH, "%04u.%06u: 0x%02x: %10u: ", ((uint32_t)tv.tv_sec) & 0x1FFF, (uint32_t)tv.tv_usec, (uint32_t)level, (uint32_t)tid);
if (num_chars > TRACE_HEADER_LENGTH)
{
printf("trace_dbg: Error, num_chars is too large: %d", num_chars);
return;
}
va_start(p_args, format);
if ((num_chars = (uint32_t)vsnprintf(&trace_buff[num_chars], MAX_MSG_LENGTH, format, p_args)))
{
if (level <= NFAPI_TRACE_WARN)
{
printf("%s", trace_buff);
}
printf("%s", trace_buff);
}
va_end(p_args);
}
AC_INIT([open-nFAPI], [1.0])
AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE([subdir-objects -Wall -Werror foreign serial-tests])
AM_PROG_AR
LT_INIT([shared static])
# Dependencies
AC_PROG_CC
AC_PROG_CXX
AC_PROG_AWK
AC_CONFIG_HEADERS([config.h])
AC_PROG_LIBTOOL
AC_CHECK_FILE([/usr/include/CUnit/CUnit.h],
[CFLAGS_CUNIT=-I/usr/include/CUnit AC_SUBST(CFLAGS_CUNIT)],
[AC_MSG_NOTICE([Have cunit *************])])
# Need doxygen
AC_CHECK_PROGS([DOXYGEN], [doxygen])
if test -z "$DOXYGEN";
then AC_MSG_WARN([Doxygen not found - continuing without Doxygen support])
fi
AM_CONDITIONAL([HAVE_DOXYGEN], [test -n "$DOXYGEN"])AM_COND_IF([HAVE_DOXYGEN], [AC_CONFIG_FILES([docs/Doxyfile])])
AC_REQUIRE_AUX_FILE([tap-driver.sh])
AC_CONFIG_FILES([Makefile
sim_common/Makefile
common/Makefile
nfapi/Makefile
pnf/Makefile
vnf/Makefile
nfapi/tests/Makefile
pnf/tests/Makefile
vnf/tests/Makefile
pnf_sim/Makefile
vnf_sim/Makefile
integration_tests/Makefile
docs/Makefile
])
AC_OUTPUT
This diff is collapsed.
This diff is collapsed.
#
# Copyright 2017 Cisco Systems, Inc.
#
# 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.
#
if HAVE_DOXYGEN
directory = $(top_srcdir)/docs/man/man3/
dist_man_MANS = $(directory)/man_page_1.3 $(directory)/man_page_2.3
$(directory)/man_page_1.3: doxyfile.stamp
$(directory)/man_page_2.3: doxyfile.stamp
doxyfile.stamp:
$(DOXYGEN) Doxyfile
echo Timestamp > doxyfile.stamp
CLEANFILES = doxyfile.stamp
all-local: doxyfile.stamp
clean-local:
rm -rf $(top_srcdir)/docs/man
rm -rf $(top_srcdir)/docs/html
rm -rf $(top_srcdir)/docs/latex
endif
This diff is collapsed.
#
# Copyright 2017 Cisco Systems, Inc.
#
# 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.
#
#vnf unit test
AM_CPPFLAGS = -I../nfapi/inc -I../nfapi/public_inc -I../common/public_inc -I../vnf/public_inc $(CFLAGS_CUNIT) -Wall -Werror
export LD_LIBRARY_PATH=/opt/gcc-4.7.3/lib
check_PROGRAMS= nfapi_integration_tests
nfapi_integration_tests_SOURCES = main.cpp ../common/src/debug.c
nfapi_integration_tests_LDADD= -L$(libdir) -lpthread -lrt -lcunit
LOG_DRIVER = $(top_srcdir)/tap-driver.sh
TESTS=nfapi_integration_tests
EXTRA_DIST=$(TESTS)
/*
* Copyright 2017 Cisco Systems, Inc.
*
* 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.
*/
#include "CUnit.h"
#include "Basic.h"
#include "Automated.h"
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
int start_vnf_proc(int port)
{
char port_str[10];
sprintf(port_str, "%d", port);
const char *argv[] = {"vnfsim", port_str, "../xml/vnf_A.xml", NULL};
int pid = fork();
if(pid == 0)
{
int result = execv("../vnf_sim/vnfsim", (char* const*)argv); //, env_args);
if(result == -1)
{
printf("Failed to exec vnf process %d\n", errno);
}
exit(0);
}
else
{
return pid;
}
}
int start_pnf_proc(const char* addr, int port, const char* file)
{
char port_str[10];
sprintf(port_str, "%d", port);
char filename[256];
sprintf(filename, "../xml/%s", file);
const char * argv[] = {"pnfsim", addr, port_str, filename, NULL};
int pid = fork();
if(pid == 0)
{
int result = execv("../pnf_sim/pnfsim", (char* const*)argv); //, env_args);
if(result == -1)
{
printf("Failed to exec pnf process %d\n", errno);
}
exit(0);
}
else
{
return pid;
}
}
int kill_proc(int pid)
{
kill(pid, SIGKILL);
int status;
int waitpid_result = waitpid(pid, &status, 0);
return waitpid_result;
}
void test_1()
{
int pnf_port = 5655;
const char* pnf_addr = "localhost";
printf("**** starting vnf *****\n");
int vnf_pid = start_vnf_proc(pnf_port);
printf("**** starting pnf *****\n");
int pnf1_pid = start_pnf_proc(pnf_addr, pnf_port, "pnf_phy_1_A.xml");
sleep(10);
printf ("*** Terminating ****\n");
kill_proc(vnf_pid);
kill_proc(pnf1_pid);
}
void test_1a()
{
int pnf_port = 5655;
const char* pnf_addr = "localhost";
printf("**** starting vnf *****\n");
int vnf_pid = start_vnf_proc(pnf_port);
printf("**** starting pnf *****\n");
int pnf1_pid = start_pnf_proc(pnf_addr, pnf_port, "pnf_phy_2_A.xml");
sleep(10);
printf ("*** Terminating ****\n");
kill_proc(vnf_pid);
kill_proc(pnf1_pid);
}
void test_2()
{
int pnf_port = 5655;
const char* pnf_addr = "127.0.0.1";
int vnf_pid = start_vnf_proc(pnf_port);
sleep(2);
int pnf1_pid = start_pnf_proc(pnf_addr, pnf_port, "pnf_phy_1_A.xml");
int pnf2_pid = start_pnf_proc(pnf_addr, pnf_port, "pnf_phy_1_A.xml");
sleep(2);
kill_proc(pnf2_pid);
kill_proc(pnf1_pid);
kill_proc(vnf_pid);
}
void test_32()
{
int pnf_count = 32;
int pnf_pid[pnf_count];
int pnf_port = 5655;
const char* pnf_addr = "127.0.0.1";
int vnf_pid = start_vnf_proc(pnf_port);
sleep(2);
for(int i = 0; i < pnf_count; ++i)
{
pnf_pid[i] = start_pnf_proc(pnf_addr, pnf_port, "pnf_phy_1_A.xml");
}
sleep(5);
printf ("*** Terminating pnfs\n");
for(int i = 0; i < pnf_count; ++i)
{
kill_proc(pnf_pid[i]);
}
printf ("*** Terminating vnf\n");
kill_proc(vnf_pid);
}
int init_suite()
{
return 0;
}
int clean_suite()
{
return 0;
}
int main ( void )
{
CU_pSuite pSuite = NULL;
/* initialize the CUnit test registry */
if ( CUE_SUCCESS != CU_initialize_registry() )
return CU_get_error();
/* add a suite to the registry */
pSuite = CU_add_suite( "integration_test_suite", init_suite, clean_suite );
if ( NULL == pSuite )
{
CU_cleanup_registry();
return CU_get_error();
}
//(NULL == CU_add_test(pSuite, "vnf_test_start_connect_2", vnf_test_start_connect_2))
/* add the tests to the suite */
if ( (NULL == CU_add_test(pSuite, "test_1a", test_1a))
// (NULL == CU_add_test(pSuite, "test_2", test_2)) ||
// (NULL == CU_add_test(pSuite, "test_32", test_32))
)
{
CU_cleanup_registry();
return CU_get_error();
}
// Run all tests using the basic interface
CU_basic_set_mode(CU_BRM_VERBOSE);
CU_set_output_filename("vnf_unit_test_results.xml");
CU_basic_run_tests();
CU_pSuite s = CU_get_registry()->pSuite;
int count = 0;
while(s)
{
CU_pTest t = s->pTest;
while(t)
{
count++;
t = t->pNext;
}
s = s->pNext;
}
printf("%d..%d\n", 1, count);
s = CU_get_registry()->pSuite;
count = 1;
while(s)
{
CU_pTest t = s->pTest;
while(t)
{
int pass = 1;
CU_FailureRecord* failures = CU_get_failure_list();
while(failures)
{
if(strcmp(failures->pSuite->pName, s->pName) == 0 &&
strcmp(failures->pTest->pName, t->pName) == 0)
{
pass = 0;
failures = 0;
}
else
{
failures = failures->pNext;
}
}
if(pass)
printf("ok %d - %s:%s\n", count, s->pName, t->pName);
else
printf("not ok %d - %s:%s\n", count, s->pName, t->pName);
count++;
t = t->pNext;
}
s = s->pNext;
}
CU_cleanup_registry();
return CU_get_error();
}
#
# Copyright 2017 Cisco Systems, Inc.
#
# 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.
#
AUTOMAKE_OPTIONS=subdir-objects
AM_CPPFLAGS = -I$(top_srcdir)/nfapi/inc -I$(top_srcdir)/nfapi/public_inc -I$(top_srcdir)/common/public_inc -I$(top_srcdir)/pnf/public_inc $(BOOST_CPPFLAGS) -Wall -Werror -g
noinst_LIBRARIES = libnfapi.a
libnfapi_a_SOURCES = src/nfapi.c src/nfapi_p5.c src/nfapi_p7.c src/nfapi_p4.c
libnfapi_a_CFLAGS =$(AM_CFLAGS)
lib_LTLIBRARIES = libnfapi.la
libnfapi_la_SOURCES = src/nfapi.c src/nfapi_p5.c src/nfapi_p7.c src/nfapi_p4.c
LDADD= ../pnf/src/libnfapi_pnf.a ../vnf/src/libnfapi_vnf.a ../common/bin/libnfapi_common.a
/*
* Copyright 2017 Cisco Systems, Inc.
*
* 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 _NFAPI_H_
#define _NFAPI_H_
#if defined(__cplusplus)
extern "C" {
#endif
// todo : move to public_inc so can be used by vendor extensions
#define MAX_BAD_TAG 3
uint8_t push8(uint8_t in, uint8_t **out, uint8_t *end);
uint8_t pushs8(int8_t in, uint8_t **out, uint8_t *end);
uint8_t push16(uint16_t in, uint8_t **out, uint8_t *end);
uint8_t pushs16(int16_t in, uint8_t **out, uint8_t *end);
uint8_t push32(uint32_t in, uint8_t **out, uint8_t *end);
uint8_t pushs32(int32_t in, uint8_t **out, uint8_t *end);
uint8_t pull8(uint8_t **in, uint8_t *out, uint8_t *end);
uint8_t pulls8(uint8_t **in, int8_t *out, uint8_t *end);
uint8_t pull16(uint8_t **in, uint16_t *out, uint8_t *end);
uint8_t pulls16(uint8_t **in, int16_t *out, uint8_t *end);
uint8_t pull32(uint8_t **in, uint32_t *out, uint8_t *end);
uint8_t pulls32(uint8_t **in, int32_t *out, uint8_t *end);
uint32_t pullarray8(uint8_t **in, uint8_t out[], uint32_t max_len, uint32_t len, uint8_t *end);
uint32_t pullarray16(uint8_t **in, uint16_t out[], uint32_t max_len, uint32_t len, uint8_t *end);
uint32_t pullarrays16(uint8_t **in, int16_t out[], uint32_t max_len, uint32_t len, uint8_t *end);
uint32_t pusharray8(uint8_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end);
uint32_t pusharray16(uint16_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end);
uint32_t pusharrays16(int16_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end);
typedef uint8_t (*pack_array_elem_fn)(void* elem, uint8_t **ppWritePackedMsg, uint8_t *end);
uint8_t packarray(void* array, uint16_t elem_size, uint16_t max_count, uint16_t count, uint8_t **ppWritePackedMsg, uint8_t *end, pack_array_elem_fn fn);
typedef uint8_t (*unpack_array_elem_fn)(void* elem, uint8_t **ppReadPackedMsg, uint8_t *end);
uint8_t unpackarray(uint8_t **ppReadPackedMsg, void* array, uint16_t elem_size, uint16_t max_count, uint16_t count, uint8_t *end, unpack_array_elem_fn fn);
uint8_t pack_tl(nfapi_tl_t *tl, uint8_t **ppWritePackedMsg, uint8_t *end);
uint8_t unpack_tl(uint8_t **ppReadPackedMsg, nfapi_tl_t *tl, uint8_t *end);
typedef uint8_t (*pack_tlv_fn)(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end);
uint8_t pack_tlv(uint16_t tag, void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end, pack_tlv_fn fn);
uint32_t pack_vendor_extension_tlv(nfapi_tl_t* ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config);
int unpack_vendor_extension(nfapi_tl_t* tl, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config, nfapi_tl_t** ve_tlv);
typedef uint8_t (*unpack_tlv_fn)(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end);
typedef struct
{
uint16_t tag;
void* tlv;
unpack_tlv_fn unpack_func;
} unpack_tlv_t;
int unpack_tlv_list(unpack_tlv_t unpack_fns[], uint16_t size, uint8_t **ppReadPackedMsg, uint8_t* packedMsgEnd, nfapi_p4_p5_codec_config_t* config, nfapi_tl_t** ve);
uint32_t pack_p7_vendor_extension_tlv(nfapi_tl_t *ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config);
typedef uint8_t (*unpack_p7_tlv_fn)(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t*);
typedef struct
{
uint16_t tag;
void* tlv;
unpack_p7_tlv_fn unpack_func;
} unpack_p7_tlv_t;
int unpack_p7_tlv_list(unpack_p7_tlv_t unpack_fns[], uint16_t size, uint8_t **ppReadPackedMsg, uint8_t* packedMsgEnd, nfapi_p7_codec_config_t* config, nfapi_tl_t** ve);
#if defined(__cplusplus)
}
#endif
#endif /* _NFAPI_H_ */
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
#define NFAPI_MAX_NUM_ANTENNAS 8 #define NFAPI_MAX_NUM_ANTENNAS 8
#define NFAPI_MAX_NUM_SUBBANDS 13 #define NFAPI_MAX_NUM_SUBBANDS 13
#define NFAPI_MAX_BF_VECTORS 8 #define NFAPI_MAX_BF_VECTORS 8
#define NFAPI_MAX_CC 2 #define NFAPI_MAX_CC 1
#define NFAPI_MAX_NUM_PHYSICAL_ANTENNAS 8 #define NFAPI_MAX_NUM_PHYSICAL_ANTENNAS 8
#define NFAPI_MAX_RSSI 8 #define NFAPI_MAX_RSSI 8
#define NFAPI_MAX_PSC_LIST 32 #define NFAPI_MAX_PSC_LIST 32
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#
# Copyright 2017 Cisco Systems, Inc.
#
# 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.
#
#nfapi unit test
AUTOMAKE_OPTIONS=subdir-objects
AM_CPPFLAGS = -I$(top_srcdir)/nfapi/inc -I$(top_srcdir)/nfapi/public_inc -I$(top_srcdir)/common/public_inc -I$(top_srcdir)pnf/public_inc $(CFLAGS_CUNIT) -Wall -Werror
AM_CFLAGS = -I$(top_srcdir)/nfapi/inc -I$(top_srcdir)/nfapi/public_inc -I$(top_srcdir)/common/public_inc -I$(top_srcdir)/pnf/public_inc $(CFLAGS_CUNIT) -Wall -Werror
check_PROGRAMS= test_nfapi
test_nfapi_SOURCES = nfapi_cunit_main.c ../src/nfapi.c ../src/nfapi_p7.c ../../common/src/debug.c ../src/nfapi_p5.c ../src/nfapi_p4.c
test_nfapi_LDADD=$(top_builddir)/pnf/libnfapi_pnf.a -L$(libdir) -lpthread -lrt -lsctp -lz -lcunit
#jTEST_LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) $(top_srcdir)/tap-driver.sh --ingore-exit
#TEST_ENVIRONMENT = env AM_TAP_AWK='$(AWK)' $(SHELL) $(top_srcdir)/tap-driver.sh
#AM_TESTS_ENVIRONMENT = env AM_TAP_AWK='$(AWK)' $(SHELL);
LOG_DRIVER = $(top_srcdir)/tap-driver.sh
#AM_LOG_FLAGS = -- test_nfapi
TESTS=$(check_PROGRAMS)
EXTRA_DIST = $(TESTS)
This diff is collapsed.
#
# Copyright 2017 Cisco Systems, Inc.
#
# 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.
#
AUTOMAKE_OPTIONS=subdir-objects
AM_CPPFLAGS = -I$(top_srcdir)/pnf/inc -I$(top_srcdir)/pnf/public_inc -I$(top_srcdir)/nfapi/public_inc -I$(top_srcdir)/common/public_inc -g -Wall -Werror
noinst_LIBRARIES = libnfapi_pnf.a
libnfapi_pnf_a_SOURCES = src/pnf.c\
src/pnf_interface.c\
src/pnf_p7.c\
src/pnf_p7_interface.c
LDADD = -lsctp
/*
* Copyright 2017 Cisco Systems, Inc.
*
* 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_H_
#define _PNF_H_
#include "nfapi_pnf_interface.h"
#define NFAPI_MAX_PACKED_MESSAGE_SIZE 8192
typedef struct {
nfapi_pnf_config_t _public;
int p5_sock;
uint8_t tx_message_buffer[NFAPI_MAX_PACKED_MESSAGE_SIZE];
uint8_t sctp;
uint8_t terminate;
} pnf_t;
int pnf_connect(pnf_t *pnf);
int pnf_message_pump(pnf_t *pnf);
int pnf_pack_and_send_p5_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len);
int pnf_pack_and_send_p4_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len);
int pnf_send_message(pnf_t* pnf, uint8_t* msg, uint32_t msg_len, uint16_t stream_id);
nfapi_pnf_phy_config_t* nfapi_pnf_phy_config_find(nfapi_pnf_config_t* config, uint16_t phy_id);
#endif // _PNF_H_
/*
* Copyright 2017 Cisco Systems, Inc.
*
* 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_P7_H_
#define _PNF_P7_H_
#define TIMEHR_SEC(_time_hr) ((uint32_t)(_time_hr) >> 20)
#define TIMEHR_USEC(_time_hr) ((uint32_t)(_time_hr) & 0xFFFFF)
#define TIME2TIMEHR(_time) (((uint32_t)(_time.tv_sec) & 0xFFF) << 20 | ((uint32_t)(_time.tv_usec) & 0xFFFFF))
#include "nfapi_pnf_interface.h"
#define NFAPI_MAX_PACKED_MESSAGE_SIZE 8192
typedef struct {
uint16_t dl_conf_ontime;
uint16_t dl_conf_late;
uint16_t ul_conf_ontime;
uint16_t ul_conf_late;
uint16_t hi_dci0_ontime;
uint16_t hi_dci0_late;
uint16_t tx_ontime;
uint16_t tx_late;
} pnf_p7_stats_t;
typedef struct {
uint8_t* buffer;
uint16_t length;
} pnf_p7_rx_message_segment_t;
typedef struct pnf_p7_rx_message pnf_p7_rx_message_t;
typedef struct pnf_p7_rx_message {
uint8_t sequence_number;
uint8_t num_segments_received;
uint8_t num_segments_expected;
// the spec allows of upto 128 segments, this does seem excessive
pnf_p7_rx_message_segment_t segments[128];
uint32_t rx_hr_time;
pnf_p7_rx_message_t* next;
} pnf_p7_rx_message_t;
typedef struct {
pnf_p7_rx_message_t* msg_queue;
} pnf_p7_rx_reassembly_queue_t;
typedef struct {
nfapi_pnf_p7_config_t _public;
//private data
int p7_sock;
uint8_t terminate;
uint8_t tx_message_buffer[NFAPI_MAX_PACKED_MESSAGE_SIZE];
uint8_t* rx_message_buffer;
uint16_t rx_message_buffer_size;
pthread_mutex_t mutex; // should we allow the client to specifiy
pthread_mutex_t pack_mutex; // should we allow the client to specifiy
nfapi_pnf_p7_subframe_buffer_t subframe_buffer[30/*NFAPI_MAX_TIMING_WINDOW_SIZE*/];
uint32_t sequence_number;
uint16_t max_num_segments;
pnf_p7_rx_reassembly_queue_t reassembly_queue;
uint8_t* reassemby_buffer;
uint32_t reassemby_buffer_size;
uint16_t sfn_sf;
uint32_t sf_start_time_hr;
int32_t sfn_sf_shift;
uint8_t timing_info_period_counter;
uint8_t timing_info_aperiodic_send; // 0:false 1:true
uint32_t timing_info_ms_counter; // number of ms since last timing info
uint32_t dl_config_jitter;
uint32_t ul_config_jitter;
uint32_t hi_dci0_jitter;
uint32_t tx_jitter;
uint32_t tick;
pnf_p7_stats_t stats;
} pnf_p7_t;
int pnf_p7_message_pump(pnf_p7_t* pnf_p7);
int pnf_p7_pack_and_send_p7_message(pnf_p7_t* pnf_p7, nfapi_p7_message_header_t* msg, uint32_t msg_len);
int pnf_p7_send_message(pnf_p7_t* pnf_p7, uint8_t* msg, uint32_t msg_len);
int pnf_p7_subframe_ind(pnf_p7_t* config, uint16_t phy_id, uint16_t sfn_sf);
pnf_p7_rx_message_t* pnf_p7_rx_reassembly_queue_add_segment(pnf_p7_t* pnf_p7, pnf_p7_rx_reassembly_queue_t* queue, uint32_t rx_hr_time, uint16_t sequence_number, uint16_t segment_number, uint8_t m, uint8_t* data, uint16_t data_len);
void pnf_p7_rx_reassembly_queue_remove_msg(pnf_p7_t* pnf_p7, pnf_p7_rx_reassembly_queue_t* queue, pnf_p7_rx_message_t* msg);
void pnf_p7_rx_reassembly_queue_remove_old_msgs(pnf_p7_t* pnf_p7, pnf_p7_rx_reassembly_queue_t* queue, uint32_t rx_hr_time, uint32_t delta);
#endif /* _PNF_P7_H_ */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#
# Copyright 2017 Cisco Systems, Inc.
#
# 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.
#
#nfapi unit test
AUTOMAKE_OPTIONS=subdir-objects
AM_CPPFLAGS = -I$(top_srcdir)/nfapi/inc -I$(top_srcdir)/nfapi/public_inc -I$(top_srcdir)/common/public_inc -I$(top_srcdir)/pnf/public_inc $(CFLAGS_CUNIT) -Wall -Werror
check_PROGRAMS= test_pnf
test_pnf_SOURCES = pnf_cunit_main.c ../../common/src/debug.c
test_pnf_LDADD=$(top_builddir)/pnf/libnfapi_pnf.a $(top_builddir)/nfapi/libnfapi.a -L$(libdir) -lpthread -lrt -lsctp -lz -lcunit
LOG_DRIVER = $(top_srcdir)/tap-driver.sh
TESTS=$(check_PROGRAMS)
EXTRA_DIST = $(TESTS)
This diff is collapsed.
#
# Copyright 2017 Cisco Systems, Inc.
#
# 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.
#
AUTOMAKE_OPTIONS=subdir-objects
AM_CPPFLAGS = -I$(top_srcdir)/pnf_sim/inc -I$(top_srcdir)/sim_common/inc -I$(top_srcdir)/pnf/public_inc -I$(top_srcdir)/common/inc -I$(top_srcdir)/common/public_inc -I$(top_srcdir)/nfapi/public_inc -I$(top_srcdir)/nfapi/inc $(XML_CFLAGS) -g
AM_CXXFLAGS = -I$(top_srcdir)/pnf_sim/inc -I$(top_srcdir)/sim_common/inc -I$(top_srcdir)/pnf/public_inc -I$(top_srcdir)/common/inc -I$(top_srcdir)/common/public_inc -I$(top_srcdir)/nfapi/public_inc -I$(top_srcdir)/nfapi/inc $(XML_CFLAGS) -std=c++11 $(BOOST_CPPFLAGS) -g
bin_PROGRAMS = pnfsim
pnfsim_SOURCES = src/main.cpp src/fapi_stub.cpp
LDADD= $(top_builddir)/pnf/libnfapi_pnf.a $(top_builddir)/common/libnfapi_common.a $(top_builddir)/nfapi/libnfapi.a $(top_builddir)/sim_common/libnfapi_sim_common.a -L$(libdir) -lpthread -lrt -lsctp -lz
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* Copyright 2017 Cisco Systems, Inc.
*
* 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 diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -174,6 +174,8 @@ int generate_pbch(LTE_eNB_PBCH *eNB_pbch, ...@@ -174,6 +174,8 @@ int generate_pbch(LTE_eNB_PBCH *eNB_pbch,
pbch_E = (frame_parms->Ncp==NORMAL) ? 1920 : 1728; //RE/RB * #RB * bits/RB (QPSK) pbch_E = (frame_parms->Ncp==NORMAL) ? 1920 : 1728; //RE/RB * #RB * bits/RB (QPSK)
// pbch_E_bytes = pbch_coded_bits>>3; // pbch_E_bytes = pbch_coded_bits>>3;
LOG_D(PHY,"%s(eNB_pbch:%p txdataF:%p amp:%d frame_parms:%p pbch_pdu:%p frame_mod4:%d)\n", __FUNCTION__, eNB_pbch, txdataF, amp, frame_parms, pbch_pdu, frame_mod4==0);
if (frame_mod4==0) { if (frame_mod4==0) {
bzero(pbch_a,PBCH_A>>3); bzero(pbch_a,PBCH_A>>3);
bzero(eNB_pbch->pbch_e,pbch_E); bzero(eNB_pbch->pbch_e,pbch_E);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment