Commit 8f36aeef authored by Rúben Soares Silva's avatar Rúben Soares Silva

Initial Commit with integration of WLS library for communication with Radisys VNF

parent 2ee482af
......@@ -748,7 +748,9 @@ set(NFAPI_PNF_SRC
)
add_library(NFAPI_PNF_LIB ${NFAPI_PNF_SRC})
target_link_libraries(NFAPI_PNF_LIB PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
if(OAI_WLS)
target_compile_definitions(NFAPI_PNF_LIB PRIVATE ENABLE_WLS)
endif()
include_directories(${NFAPI_DIR}/pnf/public_inc)
include_directories(${NFAPI_DIR}/pnf/inc)
......@@ -776,6 +778,9 @@ set(NFAPI_USER_SRC
${NFAPI_USER_DIR}/gnb_ind_vars.c
)
add_library(NFAPI_USER_LIB ${NFAPI_USER_SRC})
if(OAI_WLS)
target_compile_definitions(NFAPI_USER_LIB PRIVATE ENABLE_WLS)
endif()
target_link_libraries(NFAPI_USER_LIB PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
include_directories(${NFAPI_USER_DIR})
......@@ -2078,6 +2083,11 @@ target_link_libraries(nr-softmodem PRIVATE pthread m CONFIG_LIB rt sctp)
target_link_libraries(nr-softmodem PRIVATE ${T_LIB})
target_link_libraries(nr-softmodem PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
target_link_libraries(nr-softmodem PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
add_boolean_option(OAI_WLS OFF "Activate OAI's WLS driver" OFF)
if (OAI_WLS)
target_compile_definitions(nr-softmodem PUBLIC ENABLE_WLS)
target_link_libraries(nr-softmodem PUBLIC wls_integration_lib)
endif()
add_boolean_option(OAI_AERIAL OFF "Activate OAI's AERIAL driver" OFF)
if (OAI_AERIAL)
target_compile_definitions(nr-softmodem PUBLIC ENABLE_AERIAL)
......
......@@ -96,7 +96,7 @@ Options:
USRP, BLADERF, LMSSDR, IRIS, SIMU, AW2SORI, AERIAL, None (Default)
Adds this RF board support (in external packages installation and in compilation)
-t | --transport
Selects the transport protocol type, options: None, Ethernet, benetel4g, benetel5g, oran_fhlib_5g
Selects the transport protocol type, options: None, Ethernet, benetel4g, benetel5g, oran_fhlib_5g, WLS
-P | --phy_simulators
Makes the unitary tests Layer 1 simulators
-S | --core_simulators
......@@ -314,6 +314,9 @@ function main() {
TARGET_LIST="$TARGET_LIST $2"
CMAKE_CMD="$CMAKE_CMD -DOAI_FHI72=ON"
;;
"WLS"|"Wls"|"wls")
CMAKE_CMD="$CMAKE_CMD -DOAI_WLS=ON"
;;
"None")
;;
*)
......
add_subdirectory(oai_integration/aerial)
add_subdirectory(oai_integration/wls_integration)
add_subdirectory(open-nFAPI)
add_subdirectory(tests)
......@@ -63,6 +63,10 @@
#include "executables/lte-softmodem.h"
#include "nfapi/open-nFAPI/pnf/inc/pnf_p7.h"
#ifdef ENABLE_WLS
#include "nfapi/oai_integration/wls_integration/include/wls_pnf.h"
#endif
#define NUM_P5_PHY 2
#define _GNU_SOURCE
......@@ -2148,7 +2152,7 @@ void *pnf_nr_start_thread(void *ptr) {
}
void configure_nr_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port) {
printf("%s() PNF\n\n\n\n\n\n", __FUNCTION__);
printf("%s() PNF\n", __FUNCTION__);
nfapi_setmode(NFAPI_MODE_PNF); // PNF!
nfapi_pnf_config_t *config = nfapi_pnf_config_create();
......@@ -2194,9 +2198,18 @@ void configure_nr_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_add
config->deallocate_p4_p5_vendor_ext = &pnf_sim_deallocate_p4_p5_vendor_ext;
config->codec_config.unpack_p4_p5_vendor_extension = &pnf_sim_unpack_p4_p5_vendor_extension;
config->codec_config.pack_p4_p5_vendor_extension = &pnf_sim_pack_p4_p5_vendor_extension;
#ifdef ENABLE_WLS
printf("WLS MODE PNF\n");
NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] Creating WLS PNF NFAPI start thread %s\n", __FUNCTION__);
//wls_fapi_pnf_nr_start_thread(config);
pthread_create(&pnf_start_pthread, NULL, &wls_fapi_pnf_nr_start_thread, config);
pthread_setname_np(pnf_start_pthread, "NFAPI_WLS_PNF");
#else
NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] Creating PNF NFAPI start thread %s\n", __FUNCTION__);
pthread_create(&pnf_start_pthread, NULL, &pnf_nr_start_thread, config);
pthread_setname_np(pnf_start_pthread, "NFAPI_PNF");
#endif
}
void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port) {
......
if (OAI_WLS)
message(STATUS "Building with support for WLS")
add_library(wls_integration_lib
wls_pnf.c
)
find_library(WLS_LIB wls REQUIRED)
if (NOT WLS_LIB)
message(FATAL_ERROR "-- wls library not found")
else ()
message(STATUS " wls library found in ${WLS_LIB}")
endif ()
find_library(hugetlbfs_LIB hugetlbfs REQUIRED)
if (NOT hugetlbfs_LIB)
message(FATAL_ERROR "-- hugetlbfs library not found")
else ()
message(STATUS " hugetlbfs library found in ${hugetlbfs_LIB}")
endif ()
pkg_check_modules(dpdk REQUIRED libdpdk=20.11.3)
target_link_libraries(wls_integration_lib PRIVATE ${dpdk_LINK_LIBRARIES})
target_include_directories(wls_integration_lib PRIVATE ${dpdk_INCLUDE_DIRS})
target_compile_definitions(wls_integration_lib PUBLIC ENABLE_WLS)
target_link_libraries(wls_integration_lib PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
target_link_libraries(wls_integration_lib PRIVATE "${hugetlbfs_LIB}" "${WLS_LIB}")
else ()
message(STATUS "No Support for WLS")
endif ()
/*
* 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
*/
/*! \file nfapi/oai_integration/wls_integration/wls_pnf.h
* \brief
* \author Ruben S. Silva
* \date 2024
* \version 0.1
* \company OpenAirInterface Software Alliance
* \email: contact@openairinterface.org, rsilva@allbesmart.pt
* \note
* \warning
*/
#ifndef OPENAIRINTERFACE_WLS_PNF_H
#define OPENAIRINTERFACE_WLS_PNF_H
#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
#include <rte_eal.h>
#include <rte_cfgfile.h>
#include <rte_string_fns.h>
#include <rte_common.h>
#include <rte_string_fns.h>
#include <rte_lcore.h>
#include <rte_debug.h>
#include <rte_launch.h>
#include <hugetlbfs.h>
#include "wls_lib.h"
#include "nfapi_pnf_interface.h"
#include "nfapi/open-nFAPI/fapi/inc/nr_fapi.h"
#include "nfapi/open-nFAPI/fapi/inc/nr_fapi_p5_utils.h"
/* ----- WLS Operation --- */
#define FAPI_VENDOR_MSG_HEADER_IND 0x1A
// Linked list header present at the top of all messages
typedef struct _fapi_api_queue_elem {
struct _fapi_api_queue_elem *p_next;
// p_tx_data_elm_list used for TX_DATA.request processing
struct _fapi_api_queue_elem *p_tx_data_elm_list;
uint8_t msg_type;
uint8_t num_message_in_block;
uint32_t msg_len;
uint32_t align_offset;
uint64_t time_stamp;
} fapi_api_queue_elem_t,
*p_fapi_api_queue_elem_t;
/* ----------------------- */
//taken from intel_fapi/fapi_interface, to later remove
typedef struct {
uint16_t msg_id;
uint16_t pad;
uint32_t length; // Length of the message body in bytes 5G FAPI Table 3-3
} fapi_msg_t;
void *wls_fapi_pnf_nr_start_thread(void *ptr);
int wls_fapi_nr_pnf_start(nfapi_pnf_config_t* config);
#endif // OPENAIRINTERFACE_WLS_PNF_H
/*
* 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
*/
/*! \file nfapi/oai_integration/wls_integration/wls_pnf.c
* \brief
* \author Ruben S. Silva
* \date 2024
* \version 0.1
* \company OpenAirInterface Software Alliance
* \email: contact@openairinterface.org, rsilva@allbesmart.pt
* \note
* \warning
*/
#include "nfapi/oai_integration/wls_integration/include/wls_pnf.h"
#include "pnf.h"
#define WLS_TEST_DEV_NAME "wls"
#define WLS_TEST_MSG_ID 1
#define WLS_TEST_MSG_SIZE 100
#define WLS_MAC_MEMORY_SIZE 0x3EA80000
#define WLS_PHY_MEMORY_SIZE 0x18000000
#define NUM_PHY_MSGS 16
typedef void *WLS_HANDLE;
void *g_shmem;
uint64_t g_shmem_size;
WLS_HANDLE g_phy_wls;
uint8_t phy_dpdk_init(void);
uint8_t phy_wls_init(const char *dev_name, uint64_t nWlsMacMemSize, uint64_t nWlsPhyMemSize);
uint64_t phy_mac_recv();
uint8_t phy_mac_send();
pnf_t *_this = NULL;
void *wls_fapi_pnf_nr_start_thread(void *ptr)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] IN WLS PNF NFAPI start thread %s\n", __FUNCTION__);
nfapi_pnf_config_t *config = (nfapi_pnf_config_t *)ptr;
struct sched_param sp;
sp.sched_priority = 20;
pthread_setschedparam(pthread_self(), SCHED_FIFO, &sp);
wls_fapi_nr_pnf_start(config);
return (void *)0;
}
int wls_fapi_nr_pnf_start(nfapi_pnf_config_t *config)
{
int64_t ret;
uint64_t p_msg;
// Verify that config is not null
if (config == 0)
return -1;
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
_this = (pnf_t *)(config);
_this->terminate == 0;
// DPDK init
ret = phy_dpdk_init();
if (!ret) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "[PNF] DPDK Init - Failed\n");
return false;
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "\n[PHY] DPDK Init - Done\n");
// WLS init
ret = phy_wls_init(WLS_TEST_DEV_NAME, WLS_MAC_MEMORY_SIZE, WLS_PHY_MEMORY_SIZE);
if (!ret) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "[PNF] WLS Init - Failed\n");
return false;
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "\n[PHY] WLS Init - Done\n");
// Start Receiving loop from the VNF
p_msg = phy_mac_recv();
if (!p_msg) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "[PNF] Receive from FAPI - Failed\n");
return false;
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "\n[PHY] Receive from FAPI - Done\n");
// Should never get here, to be removed, align with present implementation of PNF loop
// Send to MAC WLS
ret = phy_mac_send();
if (!ret) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "[PNF] Send to FAPI FAPI - Failed\n");
return false;
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "\n[PHY] Send to FAPI - Done\n");
NFAPI_TRACE(NFAPI_TRACE_INFO, "\n[PHY] Exiting...\n");
return true;
}
uint8_t phy_dpdk_init(void)
{
unsigned long i;
char *argv[] = {"phy_app", "--proc-type=primary", "--file-prefix", "wls", "--iova-mode=pa", "--no-pci"};
int argc = RTE_DIM(argv);
/* initialize EAL first */
NFAPI_TRACE(NFAPI_TRACE_INFO, "\n[PHY] Calling rte_eal_init: ");
for (i = 0; i < RTE_DIM(argv); i++) {
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s ", argv[i]);
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "\n");
if (rte_eal_init(argc, argv) < 0)
rte_panic("Cannot init EAL\n");
return true;
}
uint8_t phy_wls_init(const char *dev_name, uint64_t nWlsMacMemSize, uint64_t nWlsPhyMemSize)
{
g_phy_wls = WLS_Open(dev_name, WLS_SLAVE_CLIENT, &nWlsMacMemSize, &nWlsPhyMemSize);
if (NULL == g_phy_wls) {
return false;
}
g_shmem_size = nWlsMacMemSize + nWlsPhyMemSize;
g_shmem = WLS_Alloc(g_phy_wls, g_shmem_size);
if (NULL == g_shmem) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unable to alloc WLS Memory\n");
return false;
}
return true;
}
static void procPhyMessages(uint32_t msgSize, void *msg)
{
//Should be able to be casted into already present fapi p5 header format, to fix, dependent on changes on L2 to follow fapi_message_header_t in nr_fapi.h
fapi_msg_t *header = (fapi_msg_t *)msg;
NFAPI_TRACE(NFAPI_TRACE_INFO, "[PHY] Received Msg ID 0x%02x\n", header->msg_id);
switch (header->msg_id) {
case NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST: {
#if 0 // To print TLVs, only for debug purposes
fapi_config_req_t *wls_conf_req = (fapi_config_req_t *)msg;
printf("number_of_tlvs %d \n", wls_conf_req->number_of_tlvs);
for (int i = 0; i < wls_conf_req->number_of_tlvs; ++i) {
printf("TLV #%d tag 0x%02x length 0x%02x value 0x%02x\n",
i,
wls_conf_req->tlvs[i].tl.tag,
wls_conf_req->tlvs[i].tl.length,
wls_conf_req->tlvs[i].value);
}
#endif
nfapi_nr_config_request_scf_t unpacked_req = {0};
int unpack_result = fapi_nr_p5_message_unpack(msg, msgSize, &unpacked_req, sizeof(unpacked_req), NULL);
// TODO: Process and use the message
// Free at the end
free_config_request(&unpacked_req);
break;
}
default:
break;
}
}
uint64_t phy_mac_recv()
{
uint32_t numMsgToGet; /* Number of Memory blocks to get */
uint64_t l2Msg; /* Message received */
void *l2MsgPtr;
uint32_t msgSize;
uint16_t msgType;
uint16_t flags;
uint32_t i = 0;
p_fapi_api_queue_elem_t currElem = NULL;
while (_this->terminate == 0) {
numMsgToGet = WLS_Wait(g_phy_wls);
if (numMsgToGet == 0) {
continue;
}
while (numMsgToGet--) {
currElem = NULL;
l2Msg = (uint64_t)NULL;
l2MsgPtr = NULL;
l2Msg = WLS_Get(g_phy_wls, &msgSize, &msgType, &flags);
if (l2Msg) {
NFAPI_TRACE(NFAPI_TRACE_INFO, "\n[PHY] MAC2PHY WLS Received Block %d\n", i);
i++;
l2MsgPtr = WLS_PA2VA(g_phy_wls, l2Msg);
currElem = (p_fapi_api_queue_elem_t)l2MsgPtr;
if (currElem->msg_type != FAPI_VENDOR_MSG_HEADER_IND) {
procPhyMessages(currElem->msg_len, (void *)(currElem + 1));
}
currElem = NULL;
} else {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "\n[PHY] MAC2PHY WLS Get Error for msg %d\n", i);
break;
}
if (flags & WLS_TF_FIN) {
// Don't return, the messages responses will be handled in procPhyMessages
}
}
}
return l2Msg;
}
uint8_t phy_mac_send()
{
uint64_t pa_block = 0;
uint8_t ret = false;
uint32_t i;
for (i = 0; i < NUM_PHY_MSGS; i++) {
pa_block = (uint64_t)WLS_DequeueBlock((void *)g_phy_wls);
if (!pa_block) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "\n[PHY] FAPI2PHY WLS Dequeue block %d error\n", i);
return false;
}
ret = WLS_Put(g_phy_wls, pa_block, WLS_TEST_MSG_SIZE, WLS_TEST_MSG_ID, (i == (NUM_PHY_MSGS - 1)) ? WLS_TF_FIN : 0) == 0 ? true
: false;
NFAPI_TRACE(NFAPI_TRACE_INFO, "\n[PHY] FAPI2PHY WLS Put Msg %d \n", i);
if (ret == false) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "\n[PHY] FAPI2PHY WLS Put Msg Error %d \n", i);
}
}
return ret;
}
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