Implementation of VNF using WLS as message transport

Add check to vnf_nr_handle_param_response for when phy_info is not found

The WLS VNF is in charge of Enqueueing the used blocks after usage for transport, this is done by keeping track of all blocks used, and calling WLS_Enqueue for all of them upon receiving a SLOT.indication
This commit is contained in:
Rúben Soares Silva
2025-07-11 10:01:26 +01:00
parent 3d34917626
commit 6d05d279b0
8 changed files with 514 additions and 31 deletions
+3
View File
@@ -754,6 +754,9 @@ endif()
include_directories(${NFAPI_DIR}/vnf/public_inc)
include_directories(${NFAPI_DIR}/vnf/inc)
if(OAI_WLS)
target_compile_definitions(NFAPI_VNF_LIB PRIVATE ENABLE_WLS)
endif()
# nFAPI user defined code
#############################
set(NFAPI_USER_SRC
+26 -3
View File
@@ -36,12 +36,15 @@
#include "nfapi_vnf.h"
#include <vnf.h>
#include <vnf_p7.h>
#ifdef ENABLE_WLS
#include <wls_integration/include/wls_vnf.h>
#include "nr_fapi_p5.h"
#include "nr_fapi_p7.h"
#endif
#ifdef ENABLE_SOCKET
#include <socket/include/socket_vnf.h>
#endif
#include <vnf.h>
#include <vnf_p7.h>
#include "nfapi.h"
#include "vendor_ext.h"
@@ -1450,6 +1453,13 @@ void *configure_nr_p7_vnf(void *ptr)
p7_vnf->config->unpack_func = &nfapi_nr_p7_message_unpack;
p7_vnf->config->hdr_unpack_func = &nfapi_nr_p7_message_header_unpack;
p7_vnf->config->pack_func = &nfapi_nr_p7_message_pack;
#ifdef ENABLE_WLS
p7_vnf->config->unpack_func = &fapi_nr_p7_message_unpack;
p7_vnf->config->hdr_unpack_func = &fapi_nr_p7_message_header_unpack;
p7_vnf->config->pack_func = &fapi_nr_p7_message_pack;
p7_vnf->config->send_p7_msg = &wls_vnf_nr_send_p7_message;
wls_vnf_set_p7_config(p7_vnf->config);
#endif
#ifdef ENABLE_SOCKET
p7_vnf->config->unpack_func = &nfapi_nr_p7_message_unpack;
@@ -1516,7 +1526,9 @@ int pnf_nr_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_pnf_st
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Sending NFAPI_VNF_PARAM_REQUEST phy_id:%d\n", pnf->phys[0].id);
memset(&req, 0, sizeof(req));
req.header.message_id = NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST;
#ifdef ENABLE_WLS
req.header.phy_id = 0;
#endif
#ifdef ENABLE_SOCKET
req.header.phy_id = pnf->phys[0].id;
#endif
@@ -1867,6 +1879,17 @@ void configure_nr_nfapi_vnf(char *vnf_addr, int vnf_p5_port, char *pnf_ip_addr,
config->codec_config.deallocate = &vnf_nr_deallocate;
memset(&UL_RCC_INFO, 0, sizeof(UL_RCC_IND_t));
#ifdef ENABLE_WLS
config->unpack_func = &fapi_nr_p5_message_unpack;
config->hdr_unpack_func = &fapi_nr_message_header_unpack;
config->pack_func = &fapi_nr_p5_message_pack;
config->send_p5_msg = &wls_vnf_nr_send_p5_message;
printf("WLS MODE PNF\n");
NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] Creating WLS VNF NFAPI start thread %s\n", __FUNCTION__);
//wls_fapi_pnf_nr_start_thread(config);
threadCreate(&vnf_p5_init_and_receive_pthread, wls_fapi_vnf_nr_start_thread, config, "NFAPI_WLS_VNF", -1, OAI_PRIORITY_RT_MAX);
#endif
#ifdef ENABLE_SOCKET
config->unpack_func = &nfapi_nr_p5_message_unpack;
config->hdr_unpack_func = &nfapi_nr_p5_message_header_unpack;
@@ -1,6 +1,7 @@
message(STATUS "Building with support for WLS")
add_library(wls_integration_lib
wls_pnf.c
wls_vnf.c
wls_common.c
)
@@ -0,0 +1,33 @@
/*
* 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
*/
#ifndef OPENAIRINTERFACE_WLS_VNF_H
#define OPENAIRINTERFACE_WLS_VNF_H
#include "nfapi_vnf_interface.h"
#include "vnf.h"
#include "wls_common.h"
void *wls_fapi_vnf_nr_start_thread(void *ptr);
int wls_fapi_nr_vnf_start();
void wls_vnf_set_p7_config(void *p7_config);
bool wls_vnf_nr_send_p5_message(vnf_t *vnf,uint16_t p5_idx, nfapi_nr_p4_p5_message_header_t* msg, uint32_t msg_len);
bool wls_vnf_nr_send_p7_message(vnf_p7_t* vnf_p7,nfapi_nr_p7_message_header_t* msg);
#endif //OPENAIRINTERFACE_WLS_VNF_H
@@ -0,0 +1,418 @@
/*
* 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 "wls_vnf.h"
#include "vnf_p7.h"
#include <rte_eal.h>
#include <rte_string_fns.h>
#include <rte_common.h>
#include <rte_lcore.h>
#include <rte_debug.h>
#include <nr_fapi_p5.h>
#include <common/platform_constants.h>
static nfapi_vnf_config_t *config;
static WLS_MAC_CTX wls_mac_iface;
vnf_t *_vnf = NULL;
// A copy of the VNF P7 config is needed for the message processing thread, in other transport mechanisms where P7 is handled in a
// different thread, the config is passed to it upon the thread creation
nfapi_vnf_p7_config_t *wls_vnf_p7_config = NULL;
void wls_vnf_set_p7_config(void *p7_config)
{
wls_vnf_p7_config = (nfapi_vnf_p7_config_t *)p7_config;
}
static PWLS_MAC_CTX wls_mac_get_ctx(void)
{
return &wls_mac_iface;
}
static uint8_t alloc_track[ALLOC_TRACK_SIZE];
//-------------------------------------------------------------------------------------------
/** @ingroup group_testmac
*
* @param[in] pMemArray Pointer to WLS Memory management structure
* @param[in] pMemArrayMemory Pointer to flat buffer that was allocated
* @param[in] totalSize Total Size of flat buffer allocated
* @param[in] nBlockSize Size of each block that needs to be partitioned by memory manager
*
* @return 0 if SUCCESS
*
* @description
* This function creates memory blocks from a flat buffer which will be used for communciation
* between MAC and PHY
*
**/
//-------------------------------------------------------------------------------------------
static bool wls_mac_create_mem_array(PWLS_MAC_MEM_SRUCT pMemArray, void *pMemArrayMemory, uint32_t totalSize, uint32_t nBlockSize)
{
const uint32_t numBlocks = totalSize / nBlockSize;
printf("wls_mac_create_mem_array: pMemArray[%p] pMemArrayMemory[%p] totalSize[%d] nBlockSize[%d] numBlocks[%d]\n",
pMemArray,
pMemArrayMemory,
totalSize,
nBlockSize,
numBlocks);
AssertFatal(nBlockSize >= sizeof(void *), "WLS nBlockSize too small");
AssertFatal(totalSize > sizeof(void *), "WLS Can't allocate less than 1 block");
pMemArray->ppFreeBlock = (void **)pMemArrayMemory;
pMemArray->pStorage = pMemArrayMemory;
pMemArray->pEndOfStorage = ((unsigned long *)pMemArrayMemory) + numBlocks * nBlockSize / sizeof(unsigned long);
pMemArray->nBlockSize = nBlockSize;
pMemArray->nBlockCount = numBlocks;
// Initialize single-linked list of free blocks;
void **ptr = (void **)pMemArrayMemory;
for (uint32_t i = 0; i < pMemArray->nBlockCount; i++) {
if (i == pMemArray->nBlockCount - 1) {
*ptr = NULL; // End of list
} else {
// Points to the next block
*ptr = (void **)(((uint8_t *)ptr) + nBlockSize);
ptr += nBlockSize / sizeof(unsigned long);
}
}
memset(alloc_track, 0, sizeof(uint8_t) * ALLOC_TRACK_SIZE);
return true;
}
void mac_dpdk_init()
{
char *my_argv[] = {"OAI_VNF", "-c3", "--proc-type=auto", "--file-prefix", WLS_DEV_NAME, "--iova-mode=pa"};
printf("\nCalling rte_eal_init: ");
for (unsigned long i = 0; i < RTE_DIM(my_argv); i++) {
printf("%s ", my_argv[i]);
}
printf("\n");
if (rte_eal_init(RTE_DIM(my_argv), my_argv) < 0)
rte_panic("\nCannot init EAL\n");
}
static uint32_t wls_mac_alloc_mem_array(PWLS_MAC_MEM_SRUCT pMemArray, void **ppBlock)
{
int idx;
if (pMemArray->ppFreeBlock == NULL) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "wls_mac_alloc_mem_array pMemArray->ppFreeBlock = NULL\n");
return 1;
}
// FIXME: Remove after debugging
if (((void *)pMemArray->ppFreeBlock < pMemArray->pStorage) || ((void *)pMemArray->ppFreeBlock >= pMemArray->pEndOfStorage)) {
NFAPI_TRACE(NFAPI_TRACE_ERROR,
"wls_mac_alloc_mem_array ERROR: Corrupted MemArray;Arr=%p,Stor=%p,Free=%p\n",
pMemArray,
pMemArray->pStorage,
pMemArray->ppFreeBlock);
return 1;
}
pMemArray->ppFreeBlock = (void **)((unsigned long)pMemArray->ppFreeBlock & 0xFFFFFFFFFFFFFFF0);
*pMemArray->ppFreeBlock = (void **)((unsigned long)*pMemArray->ppFreeBlock & 0xFFFFFFFFFFFFFFF0);
if ((*pMemArray->ppFreeBlock != NULL)
&& (((*pMemArray->ppFreeBlock) < pMemArray->pStorage) || ((*pMemArray->ppFreeBlock) >= pMemArray->pEndOfStorage))) {
fprintf(stderr,
"ERROR: Corrupted MemArray;Arr=%p,Stor=%p,Free=%p,Curr=%p\n",
pMemArray,
pMemArray->pStorage,
pMemArray->ppFreeBlock,
*pMemArray->ppFreeBlock);
return 1;
}
*ppBlock = (void *)pMemArray->ppFreeBlock;
pMemArray->ppFreeBlock = (void **)(*pMemArray->ppFreeBlock);
idx = (((uint64_t)*ppBlock - (uint64_t)pMemArray->pStorage)) / pMemArray->nBlockSize;
if (alloc_track[idx]) {
NFAPI_TRACE(NFAPI_TRACE_ERROR,
"wls_mac_alloc_mem_array Double alloc Arr=%p,Stor=%p,Free=%p,Curr=%p\n",
pMemArray,
pMemArray->pStorage,
pMemArray->ppFreeBlock,
*pMemArray->ppFreeBlock);
} else {
alloc_track[idx] = 1;
}
return 0;
}
void wls_mac_print_stats(void)
{
PWLS_MAC_CTX pWls = wls_mac_get_ctx();
NFAPI_TRACE(NFAPI_TRACE_DEBUG, "wls_mac_free_list_all:\n");
NFAPI_TRACE(NFAPI_TRACE_DEBUG,
" nTotalBlocks[%d] nAllocBlocks[%d] nFreeBlocks[%d]\n",
pWls->nTotalBlocks,
pWls->nAllocBlocks,
(pWls->nTotalBlocks - pWls->nAllocBlocks));
NFAPI_TRACE(NFAPI_TRACE_DEBUG,
" nTotalAllocCnt[%d] nTotalFreeCnt[%d] Diff[%d]\n",
pWls->nTotalAllocCnt,
pWls->nTotalFreeCnt,
(pWls->nTotalAllocCnt - pWls->nTotalFreeCnt));
NFAPI_TRACE(NFAPI_TRACE_DEBUG,
" nDlBufAllocCnt[%d] nDlBufFreeCnt[%d] Diff[%d]\n",
pWls->nTotalDlBufAllocCnt,
pWls->nTotalDlBufFreeCnt,
(pWls->nTotalDlBufAllocCnt - pWls->nTotalDlBufFreeCnt));
NFAPI_TRACE(NFAPI_TRACE_DEBUG,
" nUlBufAllocCnt[%d] nUlBufFreeCnt[%d] Diff[%d]\n\n",
pWls->nTotalUlBufAllocCnt,
pWls->nTotalUlBufFreeCnt,
(pWls->nTotalUlBufAllocCnt - pWls->nTotalUlBufFreeCnt));
}
static void *wls_mac_alloc_buffer(PWLS_MAC_CTX pWls, uint32_t size, uint32_t loc)
{
void *pBlock = NULL;
pthread_mutex_lock((pthread_mutex_t *)&pWls->lock_alloc);
if (wls_mac_alloc_mem_array(&pWls->sWlsStruct, &pBlock) != 0) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "wls_mac_alloc_buffer alloc error size[%d] loc[%d]\n", size, loc);
wls_mac_print_stats();
pthread_mutex_unlock((pthread_mutex_t *)&pWls->lock_alloc);
return NULL;
}
pWls->nAllocBlocks++;
pWls->nTotalAllocCnt++;
if (loc < MAX_DL_BUF_LOCATIONS)
pWls->nTotalDlBufAllocCnt++;
else if (loc < MAX_UL_BUF_LOCATIONS)
pWls->nTotalUlBufAllocCnt++;
pthread_mutex_unlock((pthread_mutex_t *)&pWls->lock_alloc);
return pBlock;
}
static bool mac_wls_init()
{
uint64_t nWlsMacMemorySize = 0;
uint64_t nWlsPhyMemorySize = 0;
PWLS_MAC_CTX pWls = wls_mac_get_ctx();
pthread_mutex_init((pthread_mutex_t *)&pWls->lock, NULL);
pthread_mutex_init((pthread_mutex_t *)&pWls->lock_alloc, NULL);
pWls->nTotalAllocCnt = 0;
pWls->nTotalFreeCnt = 0;
pWls->nTotalUlBufAllocCnt = 0;
pWls->nTotalUlBufFreeCnt = 0;
pWls->nTotalDlBufAllocCnt = 0;
pWls->nTotalDlBufFreeCnt = 0;
/* Start by opening the WLS instance with WLS_MASTER_CLIENT */
if ((pWls->hWls = WLS_Open(WLS_DEV_NAME, WLS_MASTER_CLIENT, &nWlsMacMemorySize, &nWlsPhyMemorySize)) == NULL) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "\nCould not open WLS Interface \n");
return false;
}
/* WLS_Open was successful, we can allocate memory */
if ((pWls->pWlsMemBase = WLS_Alloc(pWls->hWls, nWlsMacMemorySize + nWlsPhyMemorySize)) == NULL) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "\nCould not allocate WLS Memory \n");
return false;
}
/* Set the total memory that MAC has access to */
pWls->nTotalMemorySize = nWlsMacMemorySize;
/* Partition the WLS memory */
memset(pWls->pWlsMemBase, 0xCC, pWls->nTotalMemorySize);
pWls->pPartitionMemBase = pWls->pWlsMemBase;
pWls->nPartitionMemSize = pWls->nTotalMemorySize;
pWls->nTotalBlocks = pWls->nTotalMemorySize / (NFAPI_MAX_PACKED_MESSAGE_SIZE);
/* Create the memory array */
if (!wls_mac_create_mem_array(&pWls->sWlsStruct, pWls->pPartitionMemBase, pWls->nPartitionMemSize, NFAPI_MAX_PACKED_MESSAGE_SIZE)) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "\nCould not create WLS Memory Array \n");
return false;
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "\nTotalBlocks is %d \n", pWls->nTotalBlocks);
int nBlocks = 0;
for(int i = 0 ; i< pWls->nTotalBlocks; i++){
void* pMsg = wls_mac_alloc_buffer(pWls, 0, i);
/* Enqueue all blocks */
nBlocks += WLS_EnqueueBlock(pWls->hWls, WLS_VA2PA(pWls->hWls, pMsg));
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "\nAllocated %d Blocks \n", nBlocks);
return true;
}
static int vnf_wls_init()
{
mac_dpdk_init();
if (!mac_wls_init()) {
return 0;
}
return 1;
}
void *wls_fapi_vnf_nr_start_thread(void *ptr)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] IN WLS PNF NFAPI start thread %s\n", __FUNCTION__);
wls_fapi_nr_vnf_start((nfapi_vnf_config_t *)ptr);
return (void *)0;
}
static void procPhyMessages(uint32_t msg_size, void *msg_buf, uint16_t msg_id)
{
NFAPI_TRACE(NFAPI_TRACE_DEBUG, "[VNF] Received Msg ID 0x%02x\n", msg_id);
if (msg_buf == NULL || _vnf == NULL) {
AssertFatal(msg_buf != NULL && _vnf != NULL, "%s: NULL parameters\n", __FUNCTION__);
}
// Add the size of the header to the message_size, because the size in the header does not include the header length
msg_size += NFAPI_NR_P5_HEADER_LENGTH;
switch (msg_id) {
case NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE:
case NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE:
case NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE:
case NFAPI_NR_PHY_MSG_TYPE_STOP_INDICATION:
vnf_nr_handle_p4_p5_message(msg_buf, msg_size, 0, config);
break;
case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST ... NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION: {
vnf_nr_handle_p7_message(msg_buf, msg_size + NFAPI_NR_P7_HEADER_LENGTH, (vnf_p7_t *)wls_vnf_p7_config);
break;
}
default:
break;
}
}
int wls_fapi_nr_vnf_start(nfapi_vnf_config_t *cfg)
{
config = cfg;
if (config == 0) {
return -1;
}
_vnf = (vnf_t *)(config);
// init WLS connection
if (vnf_wls_init() == 0) {
return -1;
}
_vnf->terminate = 0;
// Connect to the PNF
if (config->pnf_nr_start_resp != 0) {
(config->pnf_nr_start_resp)(config, 0, NULL);
}
/* VNF receive loop */
/* Number of Memory blocks to get */
uint32_t msgSize;
uint16_t msgType;
uint16_t flags;
PWLS_MAC_CTX pWls = wls_mac_get_ctx();
while (_vnf->terminate == 0) {
int numMsgToGet = WLS_Wait(pWls->hWls);
if (numMsgToGet == 0) {
continue;
}
uint64_t PAs[numMsgToGet];
uint8_t pa_idx = 0;
while (numMsgToGet--) {
PAs[pa_idx] = WLS_Get(pWls->hWls, &msgSize, &msgType, &flags);
pa_idx++;
}
for (int i = 0; i < pa_idx; i++) {
p_fapi_api_queue_elem_t msg = WLS_PA2VA(pWls->hWls, PAs[i]);
if (msg->msg_type != FAPI_VENDOR_MSG_HEADER_IND) {
uint8_t *msgt = (uint8_t *)(msg + 1);
uint32_t len = msgt[7] | (msgt[6] << 8) | (msgt[5] << 16) | (msgt[4] << 24);
procPhyMessages(len, (void *)(msg + 1), msg->msg_type);
}
}
for (int i = 0; i < pa_idx; i++) {
if (WLS_EnqueueBlock(pWls->hWls, PAs[i]) == -1) {
NFAPI_TRACE(NFAPI_TRACE_DEBUG, "Error in WLS_EnqueueBlock for block %lu\n", PAs[i]);
}
}
}
return 1;
}
bool wls_vnf_nr_send_p5_message(vnf_t *vnf, uint16_t p5_idx, nfapi_nr_p4_p5_message_header_t *msg, uint32_t msg_len)
{
UNUSED_VARIABLE(p5_idx);
int packed_len =
vnf->_public.pack_func(msg, msg_len, vnf->tx_message_buffer, sizeof(vnf->tx_message_buffer), &vnf->_public.codec_config);
if (packed_len < 0) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi_p5_message_pack failed (%d)\n", packed_len);
return false;
}
// printf("fapi_nr_p5_message_pack succeeded having packed %d bytes\n", packed_len);
// printf("in msg, msg_len is %d\n", msg->message_length);
PWLS_MAC_CTX pWls = wls_mac_get_ctx();
int retval = wls_send_fapi_msg(pWls, msg->message_id, packed_len, vnf->tx_message_buffer);
if (retval) {
NFAPI_TRACE(NFAPI_TRACE_DEBUG, "wls_send_fapi_msg success\n");
}
return retval;
}
bool wls_vnf_nr_send_p7_message(vnf_p7_t *vnf_p7, nfapi_nr_p7_message_header_t *msg)
{
uint32_t message_id = msg->message_id;
PWLS_MAC_CTX pWls = wls_mac_get_ctx();
int num_avail_blocks = WLS_NumBlocks(pWls->hWls);
NFAPI_TRACE(NFAPI_TRACE_DEBUG,"num_avail_blocks is %d\n", num_avail_blocks);
while (num_avail_blocks < 2) {
num_avail_blocks = WLS_NumBlocks(pWls->hWls);
NFAPI_TRACE(NFAPI_TRACE_DEBUG,"num_avail_blocks is %d\n", num_avail_blocks);
}
/* get PA blocks for header and msg */
uint64_t pa_hdr = dequeueBlock(pWls);
AssertFatal(pa_hdr, "WLS_DequeueBlock failed for pa_hdr\n");
uint64_t pa_msg = dequeueBlock(pWls);
AssertFatal(pa_msg, "WLS_DequeueBlock failed for pa_msg\n");
p_fapi_api_queue_elem_t headerElem = WLS_PA2VA(pWls->hWls, pa_hdr);
AssertFatal(headerElem, "WLS_PA2VA failed for headerElem\n");
p_fapi_api_queue_elem_t fapiMsgElem = WLS_PA2VA(pWls->hWls, pa_msg);
AssertFatal(fapiMsgElem, "WLS_PA2VA failed for fapiMsgElem\n");
//memcpy((uint8_t *)(fapiMsgElem + 1), message, packed_len + NFAPI_HEADER_LENGTH);
const uint8_t wls_header[] = {1, 0}; // num_messages , opaque_handle
fill_fapi_list_elem(headerElem, fapiMsgElem, FAPI_VENDOR_MSG_HEADER_IND, 1, 2);
memcpy((uint8_t *)(headerElem + 1), wls_header, 2);
int packed_len = ((nfapi_vnf_p7_config_t *)vnf_p7)->pack_func(msg, (fapiMsgElem + 1), NFAPI_MAX_PACKED_MESSAGE_SIZE, NULL);
if (packed_len < 0) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "fapi_p7_message_pack failed (%d)\n", packed_len);
return false;
}
fill_fapi_list_elem(fapiMsgElem, NULL, message_id, 1, packed_len + NFAPI_HEADER_LENGTH);
uint8_t retval = wls_msg_send(pWls->hWls, headerElem);
return retval;
//return wls_send_fapi_msg(pWls, msg->message_id, packed_len, _vnf->tx_message_buffer);
}
+28 -27
View File
@@ -32,6 +32,9 @@
#include "nfapi/oai_integration/aerial/fapi_vnf_p5.h"
#include "nr_fapi_p5.h"
#endif
#ifdef ENABLE_WLS
#include <wls_integration/include/wls_vnf.h>
#endif // ENABLE_WLS
#include <unistd.h>
@@ -437,38 +440,36 @@ void vnf_nr_handle_param_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_conf
const bool result = config->unpack_func(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config);
if (result)
{
if (msg.error_code == NFAPI_NR_PARAM_MSG_OK) {
nfapi_vnf_phy_info_t *phy_info = nfapi_vnf_phy_info_list_find(config, msg.header.phy_id);
if (phy_info) {
if (msg.nfapi_config.p7_pnf_address_ipv4.tl.tag) {
struct sockaddr_in sockAddr;
if (msg.error_code == NFAPI_NR_PARAM_MSG_OK)
{
nfapi_vnf_phy_info_t* phy_info = nfapi_vnf_phy_info_list_find(config, msg.header.phy_id);
(void)memcpy(&sockAddr.sin_addr.s_addr, msg.nfapi_config.p7_pnf_address_ipv4.address, NFAPI_IPV4_ADDRESS_LENGTH);
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 IPv4 address: %s\n", inet_ntoa(sockAddr.sin_addr));
if(msg.nfapi_config.p7_pnf_address_ipv4.tl.tag)
{
struct sockaddr_in sockAddr;
// store address
phy_info->p7_pnf_address.sin_addr = sockAddr.sin_addr;
}
(void)memcpy(&sockAddr.sin_addr.s_addr, msg.nfapi_config.p7_pnf_address_ipv4.address, NFAPI_IPV4_ADDRESS_LENGTH);
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 IPv4 address: %s\n", inet_ntoa(sockAddr.sin_addr));
if (msg.nfapi_config.p7_pnf_address_ipv6.tl.tag) {
struct sockaddr_in6 sockAddr6;
char addr6[64];
(void)memcpy(&sockAddr6.sin6_addr, msg.nfapi_config.p7_pnf_address_ipv6.address, NFAPI_IPV6_ADDRESS_LENGTH);
NFAPI_TRACE(NFAPI_TRACE_INFO,
"PNF P7 IPv6 address: %s\n",
inet_ntop(AF_INET6, &sockAddr6.sin6_addr, addr6, sizeof(addr6)));
}
// store address
phy_info->p7_pnf_address.sin_addr = sockAddr.sin_addr;
}
if (msg.nfapi_config.p7_pnf_port.tl.tag) {
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 Port: %d\n", msg.nfapi_config.p7_pnf_port.value);
if(msg.nfapi_config.p7_pnf_address_ipv6.tl.tag)
{
struct sockaddr_in6 sockAddr6;
char addr6[64];
(void)memcpy(&sockAddr6.sin6_addr, msg.nfapi_config.p7_pnf_address_ipv6.address, NFAPI_IPV6_ADDRESS_LENGTH);
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 IPv6 address: %s\n", inet_ntop(AF_INET6, &sockAddr6.sin6_addr, addr6, sizeof(addr6)));
}
if (msg.nfapi_config.p7_pnf_port.tl.tag)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 Port: %d\n", msg.nfapi_config.p7_pnf_port.value);
// store port
phy_info->p7_pnf_address.sin_port = htons(msg.nfapi_config.p7_pnf_port.value);
}
}
// store port
phy_info->p7_pnf_address.sin_port = htons(msg.nfapi_config.p7_pnf_port.value);
}
}
}
if(config->nr_param_resp)
{
+2 -1
View File
@@ -579,6 +579,7 @@ int nfapi_nr_vnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_con
return -1;
AssertFatal(config->send_p5_msg, "Function pointer must be configured\n");
vnf_t* _this = (vnf_t*)(config);
#ifndef ENABLE_WLS
nfapi_vnf_phy_info_t* phy = nfapi_vnf_phy_info_list_find(config, req->header.phy_id);
@@ -600,7 +601,7 @@ int nfapi_nr_vnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_con
req->nfapi_config.timing_info_period.tl.tag = NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG;
req->nfapi_config.timing_info_period.value = phy->timing_info_period;
req->num_tlv++;
#endif
return config->send_p5_msg(_this, p5_idx, &req->header, sizeof(nfapi_nr_config_request_scf_t));
}
+3
View File
@@ -29,6 +29,9 @@
#include "nfapi/oai_integration/aerial/fapi_nvIPC.h"
#endif
#include "vnf_p7.h"
#ifdef ENABLE_WLS
#include <wls_integration/include/wls_vnf.h>
#endif
#include "nr_fapi_p7_utils.h"
#ifdef NDEBUG