NVIDIA Aerial Integration
- Aerial config file - Changes for ARC1.1. Change config file to max MCS 25. Fixed pdu size errors. - Remove taskset from Dockerfile.gNB.aerial.ubuntu20 after changing isolated CPUs - removed the USRP from Docker file Co-authored-by: Florian Kaltenberger <florian.kaltenberger@eurecom.fr> Co-authored-by: Fredrik Molander <fmolander@nvidia.com> Co-authored-by: Reem Bahsoun <reem.bahsoun@openairinterface.org>
This commit is contained in:
committed by
Robert Schmidt
co-authored by
Florian Kaltenberger
Fredrik Molander
Reem Bahsoun
parent
ed65b52c3c
commit
8150a47ba5
@@ -0,0 +1 @@
|
||||
include(${OPENAIR_DIR}/nfapi/oai_integration/aerial/CMakeLists.txt)
|
||||
@@ -0,0 +1,33 @@
|
||||
add_boolean_option(OAI_AERIAL OFF "Activate OAI's AERIAL driver" OFF)
|
||||
if (OAI_AERIAL)
|
||||
message(STATUS "Building with support for Aerial")
|
||||
|
||||
target_sources(
|
||||
nr-softmodem
|
||||
PRIVATE
|
||||
${OPENAIR_DIR}/nfapi/oai_integration/aerial/fapi_nvIPC.c
|
||||
${OPENAIR_DIR}/nfapi/oai_integration/aerial/fapi_vnf_p7.c
|
||||
${OPENAIR_DIR}/nfapi/oai_integration/aerial/fapi_vnf_p5.c )
|
||||
|
||||
find_library(NVIPC_LIB nvipc REQUIRED)
|
||||
if (NOT NVIPC_LIB)
|
||||
message(FATAL_ERROR "-- nvipc library not found")
|
||||
else ()
|
||||
message(STATUS " nvipc library found in ${NVIPC_LIB}")
|
||||
#add_library(nvipc STATIC SHARED IMPORTED GLOBAL)
|
||||
endif ()
|
||||
|
||||
find_library(NVLOG_LIB nvlog REQUIRED)
|
||||
if (NOT NVLOG_LIB)
|
||||
message(FATAL_ERROR "-- nvlog library not found")
|
||||
else ()
|
||||
message(STATUS " nvlog library found in ${NVLOG_LIB}")
|
||||
endif ()
|
||||
|
||||
add_compile_definitions(ENABLE_L2_SLT_RSP)
|
||||
add_compile_definitions(FAPI_BYTE_ORDERING_BIG_ENDIAN)
|
||||
add_compile_definitions(ENABLE_AERIAL)
|
||||
target_link_libraries(nr-softmodem PRIVATE "${NVLOG_LIB}" "${NVIPC_LIB}")
|
||||
else()
|
||||
message(STATUS "No Support for Aerial")
|
||||
endif()
|
||||
@@ -0,0 +1,683 @@
|
||||
/*
|
||||
* 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 fapi/oai-integration/fapi_nvIPC.c
|
||||
* \brief OAI MAC/Aerial L1 interface file using FAPI over shared memory
|
||||
* \author Ruben S. Silva
|
||||
* \date 2023
|
||||
* \version 0.1
|
||||
* \company OpenAirInterface Software Alliance
|
||||
* \email: contact@openairinterface.org, rsilva@allbesmart.pt
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
#ifdef ENABLE_AERIAL
|
||||
#define _GNU_SOURCE
|
||||
#include <sched.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <fcntl.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <termios.h>
|
||||
#include <stdatomic.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/epoll.h>
|
||||
#include "fapi_nvIPC.h"
|
||||
#include "nfapi_interface.h"
|
||||
#include "nfapi.h"
|
||||
#include "nfapi_nr_interface_scf.h"
|
||||
#include "nfapi/open-nFAPI/vnf/inc/vnf_p7.h"
|
||||
|
||||
#include "fapi_vnf_p5.h"
|
||||
#include "fapi_vnf_p7.h"
|
||||
|
||||
#define MAX_EVENTS 10
|
||||
#define RECV_BUF_LEN 8192
|
||||
char cpu_buf_recv[RECV_BUF_LEN];
|
||||
|
||||
uint16_t sfn = 0, slot = 0;
|
||||
nv_ipc_t *ipc;
|
||||
nfapi_vnf_config_t *vnf_config = 0;
|
||||
|
||||
void set_config(nfapi_vnf_config_t *conf)
|
||||
{
|
||||
vnf_config = conf;
|
||||
}
|
||||
static uint16_t old_sfn = 0;
|
||||
static uint16_t old_slot = 0;
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Handle an RX message
|
||||
static int ipc_handle_rx_msg(nv_ipc_t *ipc, nv_ipc_msg_t *msg)
|
||||
{
|
||||
if (msg == NULL) {
|
||||
LOG_E(NFAPI_VNF, "%s: ERROR: buffer is empty\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *p_cpu_data = NULL;
|
||||
if (msg->data_buf != NULL) {
|
||||
int gpu;
|
||||
if (msg->data_pool == NV_IPC_MEMPOOL_CUDA_DATA) {
|
||||
gpu = 1;
|
||||
} else {
|
||||
gpu = 0;
|
||||
}
|
||||
|
||||
#ifdef NVIPC_CUDA_ENABLE
|
||||
// Test CUDA: call CUDA functions to change all string to lower case
|
||||
test_cuda_to_lower_case(test_cuda_device_id, msg->data_buf, TEST_DATA_BUF_LEN, gpu);
|
||||
#endif
|
||||
|
||||
if (gpu) {
|
||||
p_cpu_data = cpu_buf_recv;
|
||||
memset(cpu_buf_recv, 0, RECV_BUF_LEN);
|
||||
ipc->cuda_memcpy_to_host(ipc, p_cpu_data, msg->data_buf, RECV_BUF_LEN);
|
||||
} else {
|
||||
p_cpu_data = msg->data_buf;
|
||||
}
|
||||
}
|
||||
|
||||
int messageBufLen = msg->msg_len;
|
||||
int dataBufLen = msg->data_len;
|
||||
uint8_t msgbuf[messageBufLen];
|
||||
uint8_t databuf[dataBufLen];
|
||||
memcpy(msgbuf, msg->msg_buf, messageBufLen);
|
||||
memcpy(databuf, msg->data_buf, dataBufLen);
|
||||
uint8_t *pReadPackedMessage = msgbuf;
|
||||
uint8_t *pReadData = databuf;
|
||||
uint8_t *end = msgbuf + messageBufLen;
|
||||
uint8_t *data_end = databuf + dataBufLen;
|
||||
|
||||
// unpack FAPI messages and handle them
|
||||
if (vnf_config != 0) {
|
||||
// first, unpack the header
|
||||
fapi_phy_api_msg *fapi_msg = calloc(1, sizeof(fapi_phy_api_msg));
|
||||
if (!(pull8(&pReadPackedMessage, &fapi_msg->num_msg, end) && pull8(&pReadPackedMessage, &fapi_msg->opaque_handle, end)
|
||||
&& pull16(&pReadPackedMessage, &fapi_msg->message_id, end)
|
||||
&& pull32(&pReadPackedMessage, &fapi_msg->message_length, end))) {
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "FAPI message header unpack failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (fapi_msg->message_id) {
|
||||
case NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE:
|
||||
|
||||
if (vnf_config->nr_param_resp) {
|
||||
nfapi_nr_param_response_scf_t msg_param_resp;
|
||||
aerial_unpack_nr_param_response(&pReadPackedMessage, end, &msg_param_resp, &vnf_config->codec_config);
|
||||
(vnf_config->nr_param_resp)(vnf_config, vnf_config->pnf_list->p5_idx, &msg_param_resp);
|
||||
}
|
||||
break;
|
||||
|
||||
case NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE: {
|
||||
// unpack message
|
||||
nfapi_nr_config_response_scf_t msg_config_response;
|
||||
aerial_unpack_nr_config_response(&pReadPackedMessage, end, &msg_config_response, &vnf_config->codec_config);
|
||||
// Check the error code
|
||||
if (msg_config_response.error_code == NFAPI_NR_CONFIG_MSG_OK) {
|
||||
// Invoke the call back
|
||||
if (vnf_config->nr_config_resp) {
|
||||
(vnf_config->nr_config_resp)(vnf_config, vnf_config->pnf_list->p5_idx, &msg_config_response);
|
||||
}
|
||||
} else {
|
||||
// Error code not OK (MSG_INVALID_CONFIG)
|
||||
/* MSG_INVALID_CONFIG.response structure
|
||||
* Error code uint8_t
|
||||
* Number of invalid or unsupported TLVs uint8_t
|
||||
* Number of invalid TLVs that can only be configured in IDLE state uint8_t
|
||||
* Number of invalid TLVs that can only be configured in RUNNING state uint8_t
|
||||
* Number of missing TLVs uint8_t
|
||||
* List of invalid or unsupported TLVs
|
||||
* List of invalid TLVs that can only be configured in IDLE state
|
||||
* List of invalid TLVs that can only be configured in RUNNING state
|
||||
* List of missing TLVs
|
||||
* */
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case NFAPI_NR_PHY_MSG_TYPE_STOP_INDICATION: {
|
||||
// TODO : ADD Support for NFAPI_NR_PHY_MSG_TYPE_STOP_INDICATION (0x06)
|
||||
LOG_D(NFAPI_VNF,"Received NFAPI_NR_PHY_MSG_TYPE_STOP_INDICATION\n");
|
||||
break;
|
||||
}
|
||||
|
||||
case NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION: {
|
||||
// TODO: Add Support for NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION (0x07)
|
||||
LOG_D(NFAPI_VNF,"Received NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION\n");
|
||||
//for (int i = 0; i < msg->msg_len; i++) {
|
||||
// printf(" msg->msg_buf[%d] = 0x%02x\n", i, ((uint8_t *) msg->msg_buf)[i]);
|
||||
//}
|
||||
LOG_D(NFAPI_VNF,"old sfn %u\n", old_sfn);
|
||||
LOG_D(NFAPI_VNF,"old slot %u\n", old_slot);
|
||||
|
||||
break;
|
||||
}
|
||||
// P7 Messages
|
||||
// P7 Message Handlers -> ((vnf_info *)vnf_config->user_data)->p7_vnfs->config->
|
||||
case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION: {
|
||||
nfapi_nr_slot_indication_scf_t ind;
|
||||
aerial_unpack_nr_slot_indication(&pReadPackedMessage,
|
||||
end,
|
||||
&ind,
|
||||
&((vnf_p7_t *)((vnf_info *)vnf_config->user_data)->p7_vnfs->config)->_public.codec_config);
|
||||
// check if the sfn/slot unpacked come wrong at any time, should be old + 1 (slot 0 -- 19, sfn 0 -- 1023)
|
||||
// add 1 to current sfn number
|
||||
uint16_t old_slot_plus = ((old_slot + 1) % 20);
|
||||
uint16_t old_sfn_plus = old_slot_plus == 0 ? ((old_sfn + 1) % 1024) : old_sfn;
|
||||
if (old_slot_plus != ind.slot || old_sfn_plus != ind.sfn) {
|
||||
LOG_E(NFAPI_VNF,
|
||||
"\n============================================================================\n"
|
||||
"sfn slot doesn't match unpacked one! L2->L1 %d.%d vs L1->L2 %d.%d \n"
|
||||
"============================================================================\n",
|
||||
old_sfn,
|
||||
old_slot,
|
||||
ind.sfn,
|
||||
ind.slot);
|
||||
}
|
||||
old_sfn = ind.sfn;
|
||||
old_slot = ind.slot;
|
||||
if (((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_slot_indication) {
|
||||
(((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_slot_indication)(&ind);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION: {
|
||||
nfapi_nr_rx_data_indication_t ind;
|
||||
ind.header.message_id = fapi_msg->message_id;
|
||||
ind.header.message_length = fapi_msg->message_length;
|
||||
aerial_unpack_nr_rx_data_indication(
|
||||
&pReadPackedMessage,
|
||||
end,
|
||||
&pReadData,
|
||||
data_end,
|
||||
&ind,
|
||||
&((vnf_p7_t *)((vnf_info *)vnf_config->user_data)->p7_vnfs->config)->_public.codec_config);
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s: Handling RX Indication\n", __FUNCTION__);
|
||||
if (((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_rx_data_indication) {
|
||||
(((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_rx_data_indication)(&ind);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION: {
|
||||
nfapi_nr_crc_indication_t crc_ind;
|
||||
crc_ind.header.message_id = fapi_msg->message_id;
|
||||
crc_ind.header.message_length = fapi_msg->message_length;
|
||||
aerial_unpack_nr_crc_indication(&pReadPackedMessage,
|
||||
end,
|
||||
&crc_ind,
|
||||
&((vnf_p7_t *)((vnf_info *)vnf_config->user_data)->p7_vnfs->config)->_public.codec_config);
|
||||
if (((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_crc_indication) {
|
||||
(((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_crc_indication)(&crc_ind);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION: {
|
||||
nfapi_nr_uci_indication_t ind;
|
||||
aerial_unpack_nr_uci_indication(&pReadPackedMessage,
|
||||
end,
|
||||
&ind,
|
||||
&((vnf_p7_t *)((vnf_info *)vnf_config->user_data)->p7_vnfs->config)->_public.codec_config);
|
||||
|
||||
if (((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_uci_indication) {
|
||||
(((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_uci_indication)(&ind);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION: {
|
||||
nfapi_nr_srs_indication_t ind;
|
||||
aerial_unpack_nr_srs_indication(&pReadPackedMessage,
|
||||
end,
|
||||
&ind,
|
||||
&((vnf_p7_t *)((vnf_info *)vnf_config->user_data)->p7_vnfs->config)->_public.codec_config);
|
||||
if (((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_srs_indication) {
|
||||
(((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_srs_indication)(&ind);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION: {
|
||||
nfapi_nr_rach_indication_t ind;
|
||||
aerial_unpack_nr_rach_indication(&pReadPackedMessage,
|
||||
end,
|
||||
&ind,
|
||||
&((vnf_p7_t *)((vnf_info *)vnf_config->user_data)->p7_vnfs->config)->_public.codec_config);
|
||||
if (((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_rach_indication) {
|
||||
(((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_rach_indication)(&ind);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s P5 Unknown message ID %d\n", __FUNCTION__, fapi_msg->message_id);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t buf[1024];
|
||||
|
||||
nv_ipc_config_t nv_ipc_config;
|
||||
|
||||
int aerial_send_P5_msg(void *packedBuf, uint32_t packedMsgLength, nfapi_p4_p5_message_header_t *header)
|
||||
{
|
||||
if (ipc == NULL) {
|
||||
return -1;
|
||||
}
|
||||
nv_ipc_msg_t send_msg = {0};
|
||||
// look for the specific message
|
||||
switch (header->message_id) {
|
||||
case NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_START_REQUEST:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE:
|
||||
break;
|
||||
default: {
|
||||
if (header->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && header->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
|
||||
// if(config && config->pack_p4_p5_vendor_extension) {
|
||||
// result = (config->pack_p4_p5_vendor_extension)(header, ppWritePackedMsg, end, config);
|
||||
// } else {
|
||||
// NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve ecoder provided\n", __FUNCTION__, header->message_id);
|
||||
// }
|
||||
} else {
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, header->message_id);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
send_msg.msg_id = header->message_id;
|
||||
send_msg.cell_id = 0;
|
||||
send_msg.msg_len = packedMsgLength + 8; // adding 8 to account for the size of the FAPI header
|
||||
send_msg.data_len = 0;
|
||||
send_msg.data_buf = NULL;
|
||||
send_msg.data_pool = NV_IPC_MEMPOOL_CPU_MSG;
|
||||
|
||||
// procedure is allocate->fill->send
|
||||
int alloc_retval = ipc->tx_allocate(ipc, &send_msg, 0);
|
||||
if (alloc_retval != 0) {
|
||||
LOG_E(NFAPI_VNF, "%s error: allocate TX buffer failed Error: %d\n", __FUNCTION__, alloc_retval);
|
||||
ipc->tx_release(ipc, &send_msg);
|
||||
return alloc_retval;
|
||||
}
|
||||
|
||||
memcpy(send_msg.msg_buf, packedBuf, send_msg.msg_len);
|
||||
LOG_D(NFAPI_VNF,
|
||||
"send: cell_id=%d msg_id=0x%02X msg_len=%d data_len=%d data_pool=%d\n",
|
||||
send_msg.cell_id,
|
||||
send_msg.msg_id,
|
||||
send_msg.msg_len,
|
||||
send_msg.data_len,
|
||||
send_msg.data_pool);
|
||||
// Send the message
|
||||
int send_retval = ipc->tx_send_msg(ipc, &send_msg);
|
||||
if (send_retval < 0) {
|
||||
LOG_E(NFAPI_VNF, "%s error: send TX message failed Error: %d\n", __FUNCTION__, send_retval);
|
||||
ipc->tx_release(ipc, &send_msg);
|
||||
return send_retval;
|
||||
}
|
||||
|
||||
ipc->notify(ipc, 1); // notify that there's 1 message in queue
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aerial_send_P7_msg(void *packedBuf, uint32_t packedMsgLength, nfapi_p7_message_header_t *header)
|
||||
{
|
||||
if (ipc == NULL) {
|
||||
return -1;
|
||||
}
|
||||
nv_ipc_msg_t send_msg;
|
||||
uint8_t *pPacketBodyField = &((uint8_t *)packedBuf)[8];
|
||||
uint8_t *pPackMessageEnd = packedBuf + packedMsgLength + 8;
|
||||
|
||||
uint16_t present_sfn = 0;
|
||||
uint16_t present_slot = 0;
|
||||
pull16(&pPacketBodyField, &present_sfn, pPackMessageEnd);
|
||||
pull16(&pPacketBodyField, &present_slot, pPackMessageEnd);
|
||||
|
||||
if (present_sfn != old_sfn || present_slot != old_slot) {
|
||||
LOG_E(NFAPI_VNF,
|
||||
"\n============================================================================\n"
|
||||
"sfn slot doesn't match unpacked one! L2->L1 %d.%d vs L1->L2 %d.%d \n"
|
||||
"============================================================================\n",
|
||||
present_sfn,
|
||||
present_slot,
|
||||
old_sfn,
|
||||
old_slot);
|
||||
}
|
||||
// look for the specific message
|
||||
switch (header->message_id) {
|
||||
case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
|
||||
case NFAPI_UE_RELEASE_REQUEST:
|
||||
case NFAPI_UE_RELEASE_RESPONSE:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC:
|
||||
case NFAPI_TIMING_INFO:
|
||||
case 0x8f:
|
||||
break;
|
||||
default: {
|
||||
if (header->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && header->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
|
||||
} else {
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, header->message_id);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
send_msg.msg_id = header->message_id;
|
||||
send_msg.cell_id = 0;
|
||||
send_msg.msg_len = packedMsgLength + 8; // adding 8 to account for the size of the FAPI header
|
||||
send_msg.data_len = 0;
|
||||
send_msg.data_buf = NULL;
|
||||
send_msg.data_pool = NV_IPC_MEMPOOL_CPU_MSG;
|
||||
// procedure is allocate->fill->send
|
||||
|
||||
// Allocate buffer for TX message
|
||||
int alloc_retval = ipc->tx_allocate(ipc, &send_msg, 0);
|
||||
if (alloc_retval != 0) {
|
||||
LOG_E(NFAPI_VNF, "%s error: allocate TX buffer failed Error: %d\n", __FUNCTION__, alloc_retval);
|
||||
ipc->tx_release(ipc, &send_msg);
|
||||
return alloc_retval;
|
||||
}
|
||||
|
||||
memcpy(send_msg.msg_buf, packedBuf, send_msg.msg_len);
|
||||
LOG_D(NFAPI_VNF,
|
||||
"send: cell_id=%d msg_id=0x%02X msg_len=%d data_len=%d data_pool=%d\n",
|
||||
send_msg.cell_id,
|
||||
send_msg.msg_id,
|
||||
send_msg.msg_len,
|
||||
send_msg.data_len,
|
||||
send_msg.data_pool);
|
||||
// Send the message
|
||||
int send_retval = ipc->tx_send_msg(ipc, &send_msg);
|
||||
if (send_retval < 0) {
|
||||
LOG_E(NFAPI_VNF, "%s error: send TX message failed Error: %d\n", __FUNCTION__, send_retval);
|
||||
ipc->tx_release(ipc, &send_msg);
|
||||
return send_retval;
|
||||
}
|
||||
|
||||
ipc->notify(ipc, 1); // notify that there's 1 message in queue
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aerial_send_P7_msg_with_data(void *packedBuf,
|
||||
uint32_t packedMsgLength,
|
||||
void *dataBuf,
|
||||
uint32_t dataLength,
|
||||
nfapi_p7_message_header_t *header)
|
||||
{
|
||||
if (ipc == NULL) {
|
||||
return -1;
|
||||
}
|
||||
nv_ipc_msg_t send_msg;
|
||||
uint8_t *pPacketBodyField = &((uint8_t *)packedBuf)[8];
|
||||
uint8_t *pPackMessageEnd = packedBuf + packedMsgLength + 8;
|
||||
uint16_t present_sfn = 0;
|
||||
uint16_t present_slot = 0;
|
||||
pull16(&pPacketBodyField, &present_sfn, pPackMessageEnd);
|
||||
pull16(&pPacketBodyField, &present_slot, pPackMessageEnd);
|
||||
|
||||
if (present_sfn != old_sfn || present_slot != old_slot) {
|
||||
LOG_E(NFAPI_VNF,
|
||||
"\n============================================================================\n"
|
||||
"sfn slot doesn't match unpacked one! L2->L1 %d.%d vs L1->L2 %d.%d \n"
|
||||
"============================================================================\n",
|
||||
present_sfn,
|
||||
present_slot,
|
||||
old_sfn,
|
||||
old_slot);
|
||||
}
|
||||
// look for the specific message
|
||||
switch (header->message_id) {
|
||||
case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
|
||||
case NFAPI_UE_RELEASE_REQUEST:
|
||||
case NFAPI_UE_RELEASE_RESPONSE:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC:
|
||||
case NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC:
|
||||
case NFAPI_TIMING_INFO:
|
||||
break;
|
||||
default: {
|
||||
if (header->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && header->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
|
||||
} else {
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, header->message_id);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
send_msg.msg_id = header->message_id;
|
||||
send_msg.cell_id = 0;
|
||||
send_msg.msg_len = packedMsgLength + 8; // adding 8 to account for the size of the FAPI header
|
||||
send_msg.data_len = dataLength;
|
||||
send_msg.data_pool = NV_IPC_MEMPOOL_CPU_DATA;
|
||||
|
||||
// procedure is allocate->fill->send
|
||||
|
||||
// Allocate buffer for TX message
|
||||
int alloc_retval = ipc->tx_allocate(ipc, &send_msg, 0);
|
||||
if (alloc_retval != 0) {
|
||||
LOG_E(NFAPI_VNF, "%s error: allocate TX buffer failed Error: %d\n", __FUNCTION__, alloc_retval);
|
||||
ipc->tx_release(ipc, &send_msg);
|
||||
return alloc_retval;
|
||||
}
|
||||
|
||||
memcpy(send_msg.msg_buf, packedBuf, send_msg.msg_len);
|
||||
memcpy(send_msg.data_buf, dataBuf, send_msg.data_len);
|
||||
LOG_D(NFAPI_VNF,
|
||||
"send: cell_id=%d msg_id=0x%02X msg_len=%d data_len=%d data_pool=%d\n",
|
||||
send_msg.cell_id,
|
||||
send_msg.msg_id,
|
||||
send_msg.msg_len,
|
||||
send_msg.data_len,
|
||||
send_msg.data_pool);
|
||||
// Send the message
|
||||
int send_retval = ipc->tx_send_msg(ipc, &send_msg);
|
||||
if (send_retval != 0) {
|
||||
LOG_E(NFAPI_VNF, "%s error: send TX message failed Error: %d\n", __FUNCTION__, send_retval);
|
||||
ipc->tx_release(ipc, &send_msg);
|
||||
return send_retval;
|
||||
}
|
||||
|
||||
ipc->notify(ipc, 1); // notify that there's 1 message in queue
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Always allocate message buffer, but allocate data buffer only when data_len > 0
|
||||
static int aerial_recv_msg(nv_ipc_t *ipc, nv_ipc_msg_t *recv_msg)
|
||||
{
|
||||
if (ipc == NULL) {
|
||||
return -1;
|
||||
}
|
||||
recv_msg->msg_buf = NULL;
|
||||
recv_msg->data_buf = NULL;
|
||||
|
||||
// Allocate buffer for TX message
|
||||
if (ipc->rx_recv_msg(ipc, recv_msg) < 0) {
|
||||
LOG_D(NFAPI_VNF, "%s: no more message available\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
LOG_D(NFAPI_VNF,
|
||||
"recv: cell_id=%d msg_id=0x%02X msg_len=%d data_len=%d data_pool=%d\n",
|
||||
recv_msg->cell_id,
|
||||
recv_msg->msg_id,
|
||||
recv_msg->msg_len,
|
||||
recv_msg->data_len,
|
||||
recv_msg->data_pool);
|
||||
ipc_handle_rx_msg(ipc, recv_msg);
|
||||
|
||||
// Release buffer of RX message
|
||||
int release_retval = ipc->rx_release(ipc, recv_msg);
|
||||
if (release_retval != 0) {
|
||||
LOG_E(NFAPI_VNF, "%s error: release RX buffer failed Error: %d\n", __FUNCTION__, release_retval);
|
||||
return release_retval;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool recv_task_running = false;
|
||||
int stick_this_thread_to_core(int core_id)
|
||||
{
|
||||
int num_cores = sysconf(_SC_NPROCESSORS_ONLN);
|
||||
if (core_id < 0 || core_id >= num_cores)
|
||||
return EINVAL;
|
||||
|
||||
cpu_set_t cpuset;
|
||||
CPU_ZERO(&cpuset);
|
||||
CPU_SET(core_id, &cpuset);
|
||||
|
||||
pthread_t current_thread = pthread_self();
|
||||
return pthread_setaffinity_np(current_thread, sizeof(cpu_set_t), &cpuset);
|
||||
}
|
||||
void *epoll_recv_task(void *arg)
|
||||
{
|
||||
struct epoll_event ev, events[MAX_EVENTS];
|
||||
stick_this_thread_to_core(10);
|
||||
LOG_D(NFAPI_VNF,"Aerial recv task start \n");
|
||||
int epoll_fd = epoll_create1(0);
|
||||
if (epoll_fd == -1) {
|
||||
LOG_E(NFAPI_VNF, "%s epoll_create failed\n", __func__);
|
||||
}
|
||||
|
||||
int ipc_rx_event_fd = ipc->get_fd(ipc);
|
||||
ev.events = EPOLLIN;
|
||||
ev.data.fd = ipc_rx_event_fd;
|
||||
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, ev.data.fd, &ev) == -1) {
|
||||
LOG_E(NFAPI_VNF, "%s epoll_ctl failed\n", __func__);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
if (!recv_task_running) {
|
||||
recv_task_running = true;
|
||||
}
|
||||
LOG_D(NFAPI_VNF, "%s: epoll_wait fd_rx=%d ...\n", __func__, ipc_rx_event_fd);
|
||||
|
||||
int nfds;
|
||||
do {
|
||||
// epoll_wait() may return EINTR when get unexpected signal SIGSTOP from system
|
||||
nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
|
||||
} while (nfds == -1 && errno == EINTR);
|
||||
|
||||
if (nfds < 0) {
|
||||
LOG_E(NFAPI_VNF, "epoll_wait failed: epoll_fd=%d nfds=%d err=%d - %s\n", epoll_fd, nfds, errno, strerror(errno));
|
||||
}
|
||||
|
||||
int n = 0;
|
||||
for (n = 0; n < nfds; ++n) {
|
||||
if (events[n].data.fd == ipc_rx_event_fd) {
|
||||
ipc->get_value(ipc);
|
||||
nv_ipc_msg_t recv_msg;
|
||||
while (aerial_recv_msg(ipc, &recv_msg) == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
close(epoll_fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int create_recv_thread(void)
|
||||
{
|
||||
pthread_t thread_id;
|
||||
|
||||
void *(*recv_task)(void *);
|
||||
|
||||
recv_task = epoll_recv_task;
|
||||
|
||||
int ret = pthread_create(&thread_id, NULL, recv_task, NULL);
|
||||
if (ret != 0) {
|
||||
LOG_E(NFAPI_VNF, "%s failed, ret = %d\n", __func__, ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int load_hard_code_config(nv_ipc_config_t *config, int module_type, nv_ipc_transport_t _transport)
|
||||
{
|
||||
// Create configuration
|
||||
config->ipc_transport = _transport;
|
||||
if (set_nv_ipc_default_config(config, module_type) < 0) {
|
||||
LOG_E(NFAPI_VNF, "%s: set configuration failed\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef NVIPC_CUDA_ENABLE
|
||||
int test_cuda_device_id = get_cuda_device_id();
|
||||
#else
|
||||
int test_cuda_device_id = -1;
|
||||
#endif
|
||||
LOG_D(NFAPI_VNF,"CUDA device ID configured : %d \n", test_cuda_device_id);
|
||||
config->transport_config.shm.cuda_device_id = test_cuda_device_id;
|
||||
if (test_cuda_device_id >= 0) {
|
||||
config->transport_config.shm.mempool_size[NV_IPC_MEMPOOL_CUDA_DATA].pool_len = 128;
|
||||
config->transport_config.shm.mempool_size[NV_IPC_MEMPOOL_CPU_DATA].pool_len = 1024;
|
||||
config->transport_config.shm.mempool_size[NV_IPC_MEMPOOL_CPU_MSG].pool_len = 4096;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nvIPC_Init() {
|
||||
// Want to use transport SHM, type epoll, module secondary (reads the created shm from cuphycontroller)
|
||||
load_hard_code_config(&nv_ipc_config, NV_IPC_MODULE_SECONDARY, NV_IPC_TRANSPORT_SHM);
|
||||
// Create nv_ipc_t instance
|
||||
if ((ipc = create_nv_ipc_interface(&nv_ipc_config)) == NULL) {
|
||||
LOG_E(NFAPI_VNF, "%s: create IPC interface failed\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
LOG_I(NFAPI_VNF, "%s: create IPC interface successful\n", __func__);
|
||||
sleep(1);
|
||||
create_recv_thread();
|
||||
while(!recv_task_running){usleep(100000);}
|
||||
aerial_pnf_nr_connection_indication_cb(vnf_config, 1);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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 fapi/oai-integration/fapi_nvIPC.h
|
||||
* \brief Header file for fapi_nvIPC.c
|
||||
* \author Ruben S. Silva
|
||||
* \date 2023
|
||||
* \version 0.1
|
||||
* \company OpenAirInterface Software Alliance
|
||||
* \email: contact@openairinterface.org, rsilva@allbesmart.pt
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
#ifdef ENABLE_AERIAL
|
||||
#ifndef OPENAIRINTERFACE_FAPI_NVIPC_H
|
||||
#define OPENAIRINTERFACE_FAPI_NVIPC_H
|
||||
|
||||
#include "nv_ipc.h"
|
||||
#include "nv_ipc_utils.h"
|
||||
#include "nvlog.h"
|
||||
#include "nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h"
|
||||
#include "openair1/PHY/defs_gNB.h"
|
||||
#include "debug.h"
|
||||
|
||||
typedef struct {
|
||||
uint8_t num_msg;
|
||||
uint8_t opaque_handle;
|
||||
uint16_t message_id;
|
||||
uint32_t message_length;
|
||||
} fapi_phy_api_msg;
|
||||
|
||||
int aerial_send_P5_msg(void *packedBuf, uint32_t packedMsgLength, nfapi_p4_p5_message_header_t *header);
|
||||
int aerial_send_P7_msg(void *packedBuf, uint32_t packedMsgLength, nfapi_p7_message_header_t *header);
|
||||
int aerial_send_P7_msg_with_data(void *packedBuf,
|
||||
uint32_t packedMsgLength,
|
||||
void *dataBuf,
|
||||
uint32_t dataLength,
|
||||
nfapi_p7_message_header_t *header);
|
||||
void set_config(nfapi_vnf_config_t *conf);
|
||||
int nvIPC_Init();
|
||||
|
||||
#endif // OPENAIRINTERFACE_FAPI_NVIPC_H
|
||||
#endif
|
||||
@@ -0,0 +1,765 @@
|
||||
/*
|
||||
* 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 fapi/oai-integration/fapi_vnf_p5.c
|
||||
* \brief OAI FAPI VNF P5 message handler procedures
|
||||
* \author Ruben S. Silva
|
||||
* \date 2023
|
||||
* \version 0.1
|
||||
* \company OpenAirInterface Software Alliance
|
||||
* \email: contact@openairinterface.org, rsilva@allbesmart.pt
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
#ifdef ENABLE_AERIAL
|
||||
#include "fapi_vnf_p5.h"
|
||||
#include "fapi_vnf_p7.h"
|
||||
#include "nfapi/open-nFAPI/nfapi/src/nfapi_p5.c"
|
||||
#include "nfapi/open-nFAPI/vnf/inc/vnf_p7.h"
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
extern UL_RCC_IND_t UL_RCC_INFO;
|
||||
extern int single_thread_flag;
|
||||
extern uint16_t sf_ahead;
|
||||
extern uint16_t slot_ahead;
|
||||
|
||||
|
||||
static pthread_t vnf_aerial_p7_start_pthread;
|
||||
void *aerial_vnf_nr_aerial_p7_start_thread(void *ptr)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s()\n", __FUNCTION__);
|
||||
pthread_setname_np(pthread_self(), "VNF_P7_AERIAL");
|
||||
nfapi_vnf_p7_config_t *config = (nfapi_vnf_p7_config_t *)ptr;
|
||||
aerial_nfapi_nr_vnf_p7_start(config);
|
||||
return config;
|
||||
}
|
||||
|
||||
void *aerial_vnf_nr_p7_thread_start(void *ptr)
|
||||
{
|
||||
// set_thread_priority(79);
|
||||
int s;
|
||||
cpu_set_t cpuset;
|
||||
|
||||
CPU_SET(8, &cpuset);
|
||||
s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
|
||||
if (s != 0)
|
||||
printf("failed to set afinity\n");
|
||||
|
||||
set_priority(79);
|
||||
|
||||
pthread_attr_t ptAttr;
|
||||
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");
|
||||
}
|
||||
|
||||
init_queue(&gnb_rach_ind_queue);
|
||||
init_queue(&gnb_rx_ind_queue);
|
||||
init_queue(&gnb_crc_ind_queue);
|
||||
init_queue(&gnb_uci_ind_queue);
|
||||
init_queue(&gnb_slot_ind_queue);
|
||||
|
||||
vnf_p7_info *p7_vnf = (vnf_p7_info *)ptr;
|
||||
p7_vnf->config->port = p7_vnf->local_port;
|
||||
p7_vnf->config->sync_indication = &aerial_phy_sync_indication;
|
||||
p7_vnf->config->slot_indication = &aerial_phy_slot_indication;
|
||||
p7_vnf->config->harq_indication = &aerial_phy_harq_indication;
|
||||
p7_vnf->config->nr_crc_indication = &aerial_phy_nr_crc_indication;
|
||||
p7_vnf->config->nr_rx_data_indication = &aerial_phy_nr_rx_data_indication;
|
||||
p7_vnf->config->nr_rach_indication = &aerial_phy_nr_rach_indication;
|
||||
p7_vnf->config->nr_uci_indication = &aerial_phy_nr_uci_indication;
|
||||
p7_vnf->config->srs_indication = &aerial_phy_srs_indication;
|
||||
p7_vnf->config->sr_indication = &aerial_phy_sr_indication;
|
||||
p7_vnf->config->cqi_indication = &aerial_phy_cqi_indication;
|
||||
p7_vnf->config->lbt_dl_indication = &aerial_phy_lbt_dl_indication;
|
||||
p7_vnf->config->nb_harq_indication = &aerial_phy_nb_harq_indication;
|
||||
p7_vnf->config->nrach_indication = &aerial_phy_nrach_indication;
|
||||
p7_vnf->config->nr_slot_indication = &aerial_phy_nr_slot_indication;
|
||||
p7_vnf->config->nr_srs_indication = &aerial_phy_nr_srs_indication;
|
||||
p7_vnf->config->malloc = &aerial_vnf_allocate;
|
||||
p7_vnf->config->free = &aerial_vnf_deallocate;
|
||||
p7_vnf->config->vendor_ext = &aerial_phy_vendor_ext;
|
||||
p7_vnf->config->user_data = p7_vnf;
|
||||
p7_vnf->mac->user_data = p7_vnf;
|
||||
p7_vnf->config->codec_config.unpack_p7_vendor_extension = &aerial_phy_unpack_p7_vendor_extension;
|
||||
p7_vnf->config->codec_config.pack_p7_vendor_extension = &aerial_phy_pack_p7_vendor_extension;
|
||||
p7_vnf->config->codec_config.unpack_vendor_extension_tlv = &aerial_phy_unpack_vendor_extension_tlv;
|
||||
p7_vnf->config->codec_config.pack_vendor_extension_tlv = &aerial_phy_pack_vendor_extension_tlv;
|
||||
p7_vnf->config->codec_config.allocate = &aerial_vnf_allocate;
|
||||
p7_vnf->config->codec_config.deallocate = &aerial_vnf_deallocate;
|
||||
p7_vnf->config->allocate_p7_vendor_ext = &aerial_phy_allocate_p7_vendor_ext;
|
||||
p7_vnf->config->deallocate_p7_vendor_ext = &aerial_phy_deallocate_p7_vendor_ext;
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Creating VNF NFAPI P7 start thread %s\n", __FUNCTION__);
|
||||
pthread_create(&vnf_aerial_p7_start_pthread, NULL, &aerial_vnf_nr_aerial_p7_start_thread, p7_vnf->config);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int aerial_pnf_nr_connection_indication_cb(nfapi_vnf_config_t *config, int p5_idx)
|
||||
{
|
||||
printf("[VNF] pnf connection indication idx:%d\n", p5_idx);
|
||||
// in aerial, send first CONFIG.request, not PARAM.request
|
||||
nfapi_nr_config_request_scf_t conf_req;
|
||||
memset(&conf_req, 0, sizeof(conf_req));
|
||||
conf_req.header.message_id = NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST;
|
||||
printf("Try to send first CONFIG.request\n");
|
||||
aerial_nr_send_config_request(config, p5_idx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aerial_pnf_disconnection_indication_cb(nfapi_vnf_config_t *config, int p5_idx)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] pnf disconnection indication idx:%d\n", p5_idx);
|
||||
vnf_info *vnf = (vnf_info *)(config->user_data);
|
||||
pnf_info *pnf = vnf->pnfs;
|
||||
phy_info *phy = pnf->phys;
|
||||
vnf_p7_info *p7_vnf = vnf->p7_vnfs;
|
||||
nfapi_vnf_p7_del_pnf((p7_vnf->config), phy->id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aerial_pnf_nr_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_pnf_param_response_t *resp)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] pnf param response idx:%d error:%d\n", p5_idx, resp->error_code);
|
||||
vnf_info *vnf = (vnf_info *)(config->user_data);
|
||||
pnf_info *pnf = vnf->pnfs;
|
||||
|
||||
for (int i = 0; i < resp->pnf_phy.number_of_phys; ++i) {
|
||||
phy_info phy;
|
||||
memset(&phy, 0, sizeof(phy));
|
||||
phy.index = resp->pnf_phy.phy[i].phy_config_index;
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] (PHY:%d) phy_config_idx:%d\n", i, resp->pnf_phy.phy[i].phy_config_index);
|
||||
nfapi_vnf_allocate_phy(config, p5_idx, &(phy.id));
|
||||
|
||||
for (int j = 0; j < resp->pnf_phy.phy[i].number_of_rfs; ++j) {
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] (PHY:%d) (RF%d) %d\n", i, j, resp->pnf_phy.phy[i].rf_config[j].rf_config_index);
|
||||
phy.rfs[0] = resp->pnf_phy.phy[i].rf_config[j].rf_config_index;
|
||||
}
|
||||
|
||||
pnf->phys[0] = phy;
|
||||
}
|
||||
nfapi_nr_pnf_config_request_t req;
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.header.message_id = NFAPI_PNF_CONFIG_REQUEST;
|
||||
req.pnf_phy_rf_config.tl.tag = NFAPI_PNF_PHY_RF_TAG;
|
||||
req.pnf_phy_rf_config.number_phy_rf_config_info = 2; // DJP pnf.phys.size();
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "DJP:Hard coded num phy rf to 2\n");
|
||||
|
||||
for (unsigned i = 0; i < 2; ++i) {
|
||||
req.pnf_phy_rf_config.phy_rf_config[i].phy_id = pnf->phys[i].id;
|
||||
req.pnf_phy_rf_config.phy_rf_config[i].phy_config_index = pnf->phys[i].index;
|
||||
req.pnf_phy_rf_config.phy_rf_config[i].rf_config_index = pnf->phys[i].rfs[0];
|
||||
}
|
||||
|
||||
nfapi_nr_vnf_pnf_config_req(config, p5_idx, &req);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aerial_pnf_nr_config_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_pnf_config_response_t *resp)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO,
|
||||
"[VNF] pnf config response idx:%d resp[header[phy_id:%u message_id:%02x message_length:%u]]\n",
|
||||
p5_idx,
|
||||
resp->header.phy_id,
|
||||
resp->header.message_id,
|
||||
resp->header.message_length);
|
||||
|
||||
if (1) {
|
||||
nfapi_nr_pnf_start_request_t req;
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.header.phy_id = resp->header.phy_id;
|
||||
req.header.message_id = NFAPI_PNF_START_REQUEST;
|
||||
nfapi_nr_vnf_pnf_start_req(config, p5_idx, &req);
|
||||
} else {
|
||||
// Rather than send the pnf_start_request we will demonstrate
|
||||
// sending a vendor extention message. The start request will be
|
||||
// send when the vendor extension response is received
|
||||
// vnf_info* vnf = (vnf_info*)(config->user_data);
|
||||
vendor_ext_p5_req req;
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.header.message_id = P5_VENDOR_EXT_REQ;
|
||||
req.dummy1 = 45;
|
||||
req.dummy2 = 1977;
|
||||
nfapi_vnf_vendor_extension(config, p5_idx, &req.header);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aerial_pnf_nr_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_pnf_start_response_t *resp)
|
||||
{
|
||||
vnf_info *vnf = (vnf_info *)(config->user_data);
|
||||
vnf_p7_info *p7_vnf = vnf->p7_vnfs;
|
||||
pnf_info *pnf = vnf->pnfs;
|
||||
nfapi_nr_param_request_scf_t req;
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO,
|
||||
"[VNF] pnf start response idx:%d config:%p user_data:%p p7_vnf[config:%p thread_started:%d]\n",
|
||||
p5_idx,
|
||||
config,
|
||||
config->user_data,
|
||||
vnf->p7_vnfs[0].config,
|
||||
vnf->p7_vnfs[0].thread_started);
|
||||
|
||||
if (p7_vnf->thread_started == 0) {
|
||||
pthread_t vnf_p7_thread;
|
||||
pthread_create(&vnf_p7_thread, NULL, &aerial_vnf_nr_p7_thread_start, p7_vnf);
|
||||
p7_vnf->thread_started = 1;
|
||||
} else {
|
||||
// P7 thread already running.
|
||||
}
|
||||
|
||||
// start all the phys in the pnf.
|
||||
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;
|
||||
req.header.phy_id = pnf->phys[0].id;
|
||||
nfapi_nr_vnf_param_req(config, p5_idx, &req);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aerial_nr_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_param_response_scf_t *resp)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Received NFAPI_PARAM_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id);
|
||||
vnf_info *vnf = (vnf_info *)(config->user_data);
|
||||
vnf_p7_info *p7_vnf = vnf->p7_vnfs;
|
||||
pnf_info *pnf = vnf->pnfs;
|
||||
phy_info *phy = pnf->phys;
|
||||
struct sockaddr_in pnf_p7_sockaddr;
|
||||
nfapi_nr_config_request_scf_t *req = &RC.nrmac[0]->config[0]; // check
|
||||
phy->remote_port = resp->nfapi_config.p7_pnf_port.value;
|
||||
// phy->remote_port = 32123;//resp->nfapi_config.p7_pnf_port.value;
|
||||
memcpy(&pnf_p7_sockaddr.sin_addr.s_addr, &(resp->nfapi_config.p7_pnf_address_ipv4.address[0]), 4);
|
||||
phy->remote_addr = inet_ntoa(pnf_p7_sockaddr.sin_addr);
|
||||
// for now just 1
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO,
|
||||
"[VNF] %d.%d pnf p7 %s:%d timing %u %u %u %u\n",
|
||||
p5_idx,
|
||||
phy->id,
|
||||
phy->remote_addr,
|
||||
phy->remote_port,
|
||||
p7_vnf->timing_window,
|
||||
p7_vnf->periodic_timing_period,
|
||||
p7_vnf->aperiodic_timing_enabled,
|
||||
p7_vnf->periodic_timing_period);
|
||||
req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST;
|
||||
req->header.phy_id = phy->id;
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Send NFAPI_CONFIG_REQUEST\n");
|
||||
// NFAPI_TRACE(NFAPI_TRACE_INFO, "\n NR bandP =%d\n",req->nfapi_config.rf_bands.rf_band[0]);
|
||||
|
||||
req->nfapi_config.p7_vnf_port.tl.tag = NFAPI_NR_NFAPI_P7_VNF_PORT_TAG;
|
||||
req->nfapi_config.p7_vnf_port.value = p7_vnf->local_port;
|
||||
req->num_tlv++;
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] DJP local_port:%d\n", ntohs(p7_vnf->local_port));
|
||||
req->nfapi_config.p7_vnf_address_ipv4.tl.tag = NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG;
|
||||
struct sockaddr_in vnf_p7_sockaddr;
|
||||
vnf_p7_sockaddr.sin_addr.s_addr = inet_addr(p7_vnf->local_addr);
|
||||
memcpy(&(req->nfapi_config.p7_vnf_address_ipv4.address[0]), &vnf_p7_sockaddr.sin_addr.s_addr, 4);
|
||||
req->num_tlv++;
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] DJP local_addr:%s\n", p7_vnf->local_addr);
|
||||
req->nfapi_config.timing_window.tl.tag = NFAPI_NR_NFAPI_TIMING_WINDOW_TAG;
|
||||
req->nfapi_config.timing_window.value = p7_vnf->timing_window;
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO,
|
||||
"\n[VNF]Timing window tag : %d Timing window:%u\n",
|
||||
NFAPI_NR_NFAPI_TIMING_WINDOW_TAG,
|
||||
p7_vnf->timing_window);
|
||||
req->num_tlv++;
|
||||
|
||||
if (p7_vnf->periodic_timing_enabled || p7_vnf->aperiodic_timing_enabled) {
|
||||
req->nfapi_config.timing_info_mode.tl.tag = NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG;
|
||||
req->nfapi_config.timing_info_mode.value = (p7_vnf->aperiodic_timing_enabled << 1) | (p7_vnf->periodic_timing_enabled);
|
||||
req->num_tlv++;
|
||||
|
||||
if (p7_vnf->periodic_timing_enabled) {
|
||||
req->nfapi_config.timing_info_period.tl.tag = NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG;
|
||||
req->nfapi_config.timing_info_period.value = p7_vnf->periodic_timing_period;
|
||||
req->num_tlv++;
|
||||
}
|
||||
}
|
||||
// TODO: Assign tag and value for P7 message offsets
|
||||
req->nfapi_config.dl_tti_timing_offset.tl.tag = NFAPI_NR_NFAPI_DL_TTI_TIMING_OFFSET;
|
||||
req->nfapi_config.ul_tti_timing_offset.tl.tag = NFAPI_NR_NFAPI_UL_TTI_TIMING_OFFSET;
|
||||
req->nfapi_config.ul_dci_timing_offset.tl.tag = NFAPI_NR_NFAPI_UL_DCI_TIMING_OFFSET;
|
||||
req->nfapi_config.tx_data_timing_offset.tl.tag = NFAPI_NR_NFAPI_TX_DATA_TIMING_OFFSET;
|
||||
|
||||
vendor_ext_tlv_2 ve2;
|
||||
memset(&ve2, 0, sizeof(ve2));
|
||||
ve2.tl.tag = VENDOR_EXT_TLV_2_TAG;
|
||||
ve2.dummy = 2016;
|
||||
req->vendor_extension = &ve2.tl;
|
||||
nfapi_nr_vnf_config_req(config, p5_idx, req);
|
||||
printf("[VNF] Sent NFAPI_VNF_CONFIG_REQ num_tlv:%u\n", req->num_tlv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aerial_nr_send_config_request(nfapi_vnf_config_t *config, int p5_idx)
|
||||
{
|
||||
vnf_info *vnf = (vnf_info *)(config->user_data);
|
||||
vnf_p7_info *p7_vnf = vnf->p7_vnfs;
|
||||
pnf_info *pnf = vnf->pnfs;
|
||||
phy_info *phy = pnf->phys;
|
||||
|
||||
nfapi_nr_config_request_scf_t *req = &RC.nrmac[0]->config[0]; //&RC.gNB[0]->gNB_config; // check
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO,
|
||||
"[VNF] %d.%d pnf p7 %s:%d timing %u %u %u %u\n",
|
||||
p5_idx,
|
||||
phy->id,
|
||||
phy->remote_addr,
|
||||
phy->remote_port,
|
||||
p7_vnf->timing_window,
|
||||
p7_vnf->periodic_timing_period,
|
||||
p7_vnf->aperiodic_timing_enabled,
|
||||
p7_vnf->periodic_timing_period);
|
||||
req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST;
|
||||
req->header.phy_id = phy->id;
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Send NFAPI_CONFIG_REQUEST\n");
|
||||
|
||||
|
||||
vnf_t *_this = (vnf_t *)(config);
|
||||
|
||||
nfapi_vnf_phy_info_t *vnf_phy = nfapi_vnf_phy_info_list_find(config, req->header.phy_id);
|
||||
|
||||
if (vnf_phy == NULL) {
|
||||
printf("%s failed to find phy information phy_id:%d\n", __FUNCTION__, req->header.phy_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
nfapi_p4_p5_message_header_t *msg = &req->header;
|
||||
uint16_t msg_len = sizeof(nfapi_nr_config_request_scf_t);
|
||||
nfapi_p4_p5_message_header_t *msgFAPI = calloc(1, msg_len);
|
||||
memcpy(msgFAPI, &req->header, msg_len);
|
||||
uint8_t tx_messagebufferFAPI[sizeof(_this->tx_message_buffer)];
|
||||
int packedMessageLengthFAPI = -1;
|
||||
packedMessageLengthFAPI =
|
||||
fapi_nr_p5_message_pack(msgFAPI, msg_len, tx_messagebufferFAPI, sizeof(tx_messagebufferFAPI), &_this->_public.codec_config);
|
||||
|
||||
aerial_send_P5_msg(tx_messagebufferFAPI, packedMessageLengthFAPI, msg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aerial_nr_config_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_config_response_scf_t *resp)
|
||||
{
|
||||
nfapi_nr_start_request_scf_t req;
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Received NFAPI_CONFIG_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id);
|
||||
LOG_I(NFAPI_VNF, "Received CONFIG.response, gNB is ready! \n");
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.header.message_id = NFAPI_NR_PHY_MSG_TYPE_START_REQUEST;
|
||||
req.header.phy_id = resp->header.phy_id;
|
||||
nfapi_nr_vnf_start_req(config, p5_idx, &req);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aerial_nr_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_start_response_scf_t *resp)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Received NFAPI_START_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id);
|
||||
vnf_info *vnf = (vnf_info *)(config->user_data);
|
||||
pnf_info *pnf = vnf->pnfs;
|
||||
phy_info *phy = pnf->phys;
|
||||
vnf_p7_info *p7_vnf = vnf->p7_vnfs;
|
||||
|
||||
nfapi_vnf_p7_add_pnf((p7_vnf->config), phy->remote_addr, phy->remote_port, phy->id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aerial_vendor_ext_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_p4_p5_message_header_t *msg)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] %s\n", __FUNCTION__);
|
||||
|
||||
switch (msg->message_id) {
|
||||
case P5_VENDOR_EXT_RSP: {
|
||||
vendor_ext_p5_rsp *rsp = (vendor_ext_p5_rsp *)msg;
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] P5_VENDOR_EXT_RSP error_code:%d\n", rsp->error_code);
|
||||
// send the start request
|
||||
nfapi_pnf_start_request_t req;
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.header.message_id = NFAPI_PNF_START_REQUEST;
|
||||
nfapi_vnf_pnf_start_req(config, p5_idx, &req);
|
||||
} break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aerial_vnf_unpack_vendor_extension_tlv(nfapi_tl_t *tl,
|
||||
uint8_t **ppReadPackedMessage,
|
||||
uint8_t *end,
|
||||
void **ve,
|
||||
nfapi_p4_p5_codec_config_t *codec)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int aerial_vnf_pack_vendor_extension_tlv(void *vext, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *codec)
|
||||
{
|
||||
nfapi_tl_t *tlv = (nfapi_tl_t *)vext;
|
||||
|
||||
switch (tlv->tag) {
|
||||
case VENDOR_EXT_TLV_2_TAG: {
|
||||
vendor_ext_tlv_2 *ve = (vendor_ext_tlv_2 *)tlv;
|
||||
|
||||
if (!push32(ve->dummy, ppWritePackedMsg, end))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
} break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int aerial_vnf_unpack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t *header,
|
||||
uint8_t **ppReadPackedMessage,
|
||||
uint8_t *end,
|
||||
nfapi_p4_p5_codec_config_t *codec)
|
||||
{
|
||||
if (header->message_id == P5_VENDOR_EXT_RSP) {
|
||||
vendor_ext_p5_rsp *req = (vendor_ext_p5_rsp *)(header);
|
||||
return (!pull16(ppReadPackedMessage, &req->error_code, end));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aerial_vnf_pack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t *header,
|
||||
uint8_t **ppWritePackedMsg,
|
||||
uint8_t *end,
|
||||
nfapi_p4_p5_codec_config_t *codec)
|
||||
{
|
||||
if (header->message_id == P5_VENDOR_EXT_REQ) {
|
||||
vendor_ext_p5_req *req = (vendor_ext_p5_req *)(header);
|
||||
return (!(push16(req->dummy1, ppWritePackedMsg, end) && push16(req->dummy2, ppWritePackedMsg, end)));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
nfapi_p4_p5_message_header_t *aerial_vnf_allocate_p4_p5_vendor_ext(uint16_t message_id, uint16_t *msg_size)
|
||||
{
|
||||
if (message_id == P5_VENDOR_EXT_RSP) {
|
||||
*msg_size = sizeof(vendor_ext_p5_rsp);
|
||||
return (nfapi_p4_p5_message_header_t *)malloc(sizeof(vendor_ext_p5_rsp));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void aerial_vnf_deallocate_p4_p5_vendor_ext(nfapi_p4_p5_message_header_t *header)
|
||||
{
|
||||
free(header);
|
||||
}
|
||||
|
||||
void *aerial_vnf_p5_allocate(size_t size)
|
||||
{
|
||||
// return (void*)memory_pool::allocate(size);
|
||||
return (void *)malloc(size);
|
||||
}
|
||||
|
||||
void aerial_vnf_p5_deallocate(void *ptr)
|
||||
{
|
||||
// memory_pool::deallocate((uint8_t*)ptr);
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
static vnf_info aerial_vnf;
|
||||
void aerial_configure_nr_fapi_vnf()
|
||||
{
|
||||
// TODO: Implement for FAPI
|
||||
// nfapi_setmode(NFAPI_MODE_VNF);
|
||||
memset(&aerial_vnf, 0, sizeof(aerial_vnf));
|
||||
memset(aerial_vnf.p7_vnfs, 0, sizeof(aerial_vnf.p7_vnfs));
|
||||
aerial_vnf.p7_vnfs[0].timing_window = 30;
|
||||
aerial_vnf.p7_vnfs[0].periodic_timing_enabled = 0;
|
||||
aerial_vnf.p7_vnfs[0].aperiodic_timing_enabled = 0;
|
||||
aerial_vnf.p7_vnfs[0].periodic_timing_period = 10;
|
||||
aerial_vnf.p7_vnfs[0].config = nfapi_vnf_p7_config_create();
|
||||
aerial_vnf.p7_vnfs[0].mac = (mac_t *)malloc(sizeof(mac_t));
|
||||
nfapi_vnf_config_t *config = nfapi_vnf_config_create();
|
||||
config->malloc = malloc;
|
||||
config->free = free;
|
||||
config->vnf_ipv4 = 1;
|
||||
config->vnf_ipv6 = 0;
|
||||
config->pnf_list = 0;
|
||||
config->phy_list = 0;
|
||||
|
||||
config->pnf_nr_connection_indication = &aerial_pnf_nr_connection_indication_cb;
|
||||
config->pnf_disconnect_indication = &aerial_pnf_disconnection_indication_cb;
|
||||
|
||||
config->pnf_nr_param_resp = &aerial_pnf_nr_param_resp_cb;
|
||||
config->pnf_nr_config_resp = &aerial_pnf_nr_config_resp_cb;
|
||||
config->pnf_nr_start_resp = &aerial_pnf_nr_start_resp_cb;
|
||||
config->nr_param_resp = &aerial_nr_param_resp_cb;
|
||||
config->nr_config_resp = &aerial_nr_config_resp_cb;
|
||||
config->nr_start_resp = &aerial_nr_start_resp_cb;
|
||||
config->vendor_ext = &aerial_vendor_ext_cb;
|
||||
config->user_data = &aerial_vnf;
|
||||
// To allow custom vendor extentions to be added to nfapi
|
||||
config->codec_config.unpack_vendor_extension_tlv = &aerial_vnf_unpack_vendor_extension_tlv;
|
||||
config->codec_config.pack_vendor_extension_tlv = &aerial_vnf_pack_vendor_extension_tlv;
|
||||
config->codec_config.unpack_p4_p5_vendor_extension = &aerial_vnf_unpack_p4_p5_vendor_extension;
|
||||
config->codec_config.pack_p4_p5_vendor_extension = &aerial_vnf_pack_p4_p5_vendor_extension;
|
||||
config->allocate_p4_p5_vendor_ext = &aerial_vnf_allocate_p4_p5_vendor_ext;
|
||||
config->deallocate_p4_p5_vendor_ext = &aerial_vnf_deallocate_p4_p5_vendor_ext;
|
||||
config->codec_config.allocate = &aerial_vnf_allocate;
|
||||
config->codec_config.deallocate = &aerial_vnf_deallocate;
|
||||
memset(&UL_RCC_INFO, 0, sizeof(UL_RCC_IND_t));
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Creating VNF NFAPI start thread %s\n", __FUNCTION__);
|
||||
set_config(config);
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Created VNF NFAPI start thread %s\n", __FUNCTION__);
|
||||
nfapi_vnf_pnf_info_t *pnf = (nfapi_vnf_pnf_info_t *)malloc(sizeof(nfapi_vnf_pnf_info_t));
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "MALLOC nfapi_vnf_pnf_info_t for pnf_list pnf:%p\n", pnf);
|
||||
memset(pnf, 0, sizeof(nfapi_vnf_pnf_info_t));
|
||||
pnf->p5_idx = 1;
|
||||
pnf->connected = 1;
|
||||
// Add needed parameters
|
||||
|
||||
vnf_info *vnf = (vnf_info *)(config->user_data);
|
||||
pnf_info *pnf_info = vnf->pnfs;
|
||||
|
||||
for (int i = 0; i < 1; ++i) {
|
||||
phy_info phy;
|
||||
memset(&phy, 0, sizeof(phy));
|
||||
phy.index = 0;
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] (PHY:%d) phy_config_idx:%d\n", i, 0);
|
||||
nfapi_vnf_allocate_phy(config, 1, &(phy.id));
|
||||
|
||||
for (int j = 0; j < 1; ++j) {
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] (PHY:%d) (RF%d) %d\n", i, j, 0);
|
||||
phy.rfs[0] = 0;
|
||||
}
|
||||
|
||||
pnf_info->phys[0] = phy;
|
||||
}
|
||||
|
||||
|
||||
nfapi_vnf_pnf_list_add(config, pnf);
|
||||
|
||||
vnf_p7_info *p7_vnf = vnf->p7_vnfs;
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO,
|
||||
"[VNF] pnf start response idx:%d config:%p user_data:%p p7_vnf[config:%p thread_started:%d]\n",
|
||||
1,
|
||||
config,
|
||||
config->user_data,
|
||||
vnf->p7_vnfs[0].config,
|
||||
vnf->p7_vnfs[0].thread_started);
|
||||
|
||||
if (p7_vnf->thread_started == 0) {
|
||||
pthread_t vnf_p7_thread;
|
||||
pthread_create(&vnf_p7_thread, NULL, &aerial_vnf_nr_p7_thread_start, p7_vnf);
|
||||
p7_vnf->thread_started = 1;
|
||||
} else {
|
||||
// P7 thread already running.
|
||||
}
|
||||
}
|
||||
uint8_t aerial_unpack_nr_param_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config)
|
||||
{
|
||||
return unpack_nr_param_response(ppReadPackedMsg, end, msg, config);
|
||||
}
|
||||
uint8_t aerial_unpack_nr_config_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config)
|
||||
{
|
||||
return unpack_nr_config_response(ppReadPackedMsg, end, msg, config);
|
||||
}
|
||||
|
||||
// monitor the p7 endpoints and the timing loop and
|
||||
// send indications to mac
|
||||
int aerial_nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t *config)
|
||||
{
|
||||
if (config == 0)
|
||||
return -1;
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s()\n", __FUNCTION__);
|
||||
|
||||
vnf_p7_t *vnf_p7 = (vnf_p7_t *)config;
|
||||
|
||||
// Create p7 receive udp port
|
||||
// todo : this needs updating for Ipv6
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "Initialising VNF P7 port:%u\n", config->port);
|
||||
|
||||
|
||||
struct timespec ref_time;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ref_time);
|
||||
uint8_t setup_done = 0;
|
||||
while (vnf_p7->terminate == 0) {
|
||||
if (setup_done == 0) {
|
||||
struct timespec curr_time;
|
||||
clock_gettime(CLOCK_MONOTONIC, &curr_time);
|
||||
uint8_t setup_time = curr_time.tv_sec - ref_time.tv_sec;
|
||||
if (setup_time > 3) {
|
||||
setup_done = 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "Closing p7 socket\n");
|
||||
close(vnf_p7->socket);
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() returning\n", __FUNCTION__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fapi_nr_p5_message_pack(void *pMessageBuf, uint32_t messageBufLen, void *pPackedBuf, uint32_t packedBufLen, nfapi_p4_p5_codec_config_t *config){
|
||||
|
||||
nfapi_p4_p5_message_header_t *pMessageHeader = pMessageBuf;
|
||||
uint8_t *pWritePackedMessage = pPackedBuf;
|
||||
|
||||
uint32_t packedMsgLen;
|
||||
//uint16_t packedMsgLen16;
|
||||
|
||||
if (pMessageBuf == NULL || pPackedBuf == NULL) {
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 Pack supplied pointers are null\n");
|
||||
return -1;
|
||||
}
|
||||
uint8_t *pPackMessageEnd = pPackedBuf + packedBufLen;
|
||||
uint8_t *pPackedLengthField = &pWritePackedMessage[4];
|
||||
uint8_t *pPacketBodyField = &pWritePackedMessage[8];
|
||||
uint8_t *pPacketBodyFieldStart = &pWritePackedMessage[8];
|
||||
|
||||
pack_nr_p5_message_body(pMessageHeader, &pPacketBodyField, pPackMessageEnd, config);
|
||||
|
||||
// PHY API message header
|
||||
push8(1, &pWritePackedMessage, pPackMessageEnd); // Number of messages
|
||||
push8(0, &pWritePackedMessage, pPackMessageEnd); // Opaque handle
|
||||
|
||||
// PHY API Message structure
|
||||
push16(pMessageHeader->message_id, &pWritePackedMessage, pPackMessageEnd); // Message type ID
|
||||
|
||||
if(1==1) {
|
||||
// check for a valid message length
|
||||
packedMsgLen = get_packed_msg_len((uintptr_t)pPacketBodyFieldStart, (uintptr_t)pPacketBodyField);
|
||||
packedMsgLen-=1;
|
||||
if(pMessageHeader->message_id == NFAPI_NR_PHY_MSG_TYPE_START_REQUEST){
|
||||
//START.request doesn't have a body, length is 0
|
||||
packedMsgLen = 0;
|
||||
}else if (packedMsgLen > 0xFFFF || packedMsgLen > packedBufLen) {
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Packed message 0x%02x length error %d, buffer supplied %d\n",pMessageHeader->message_id, packedMsgLen, packedBufLen);
|
||||
return -1;
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
// Update the message length in the header
|
||||
if(!push32(packedMsgLen, &pPackedLengthField, pPackMessageEnd))
|
||||
return -1;
|
||||
|
||||
// return the packed length
|
||||
return (packedMsgLen);
|
||||
} else {
|
||||
// Failed to pack the meassage
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 Failed to pack message\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
int oai_fapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req)
|
||||
{
|
||||
nfapi_vnf_p7_config_t *p7_config = aerial_vnf.p7_vnfs[0].config;
|
||||
|
||||
ul_tti_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
|
||||
ul_tti_req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST;
|
||||
|
||||
// int retval = nfapi_vnf_p7_ul_tti_req(p7_config, ul_tti_req);
|
||||
int retval = fapi_nr_pack_and_send_p7_message((vnf_p7_t *)p7_config, &ul_tti_req->header);
|
||||
|
||||
if (retval != 0) {
|
||||
LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval);
|
||||
} else {
|
||||
// Reset number of PDUs so that it is not resent
|
||||
ul_tti_req->n_pdus = 0;
|
||||
ul_tti_req->n_group = 0;
|
||||
ul_tti_req->n_ulcch = 0;
|
||||
ul_tti_req->n_ulsch = 0;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int oai_fapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req)
|
||||
{
|
||||
nfapi_vnf_p7_config_t *p7_config = aerial_vnf.p7_vnfs[0].config;
|
||||
ul_dci_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
|
||||
ul_dci_req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST;
|
||||
// int retval = nfapi_vnf_p7_ul_dci_req(p7_config, ul_dci_req);
|
||||
int retval = fapi_nr_pack_and_send_p7_message((vnf_p7_t *)p7_config, &ul_dci_req->header);
|
||||
if (retval != 0) {
|
||||
LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval);
|
||||
} else {
|
||||
ul_dci_req->numPdus = 0;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int oai_fapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req)
|
||||
{
|
||||
nfapi_vnf_p7_config_t *p7_config = aerial_vnf.p7_vnfs[0].config;
|
||||
tx_data_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
|
||||
tx_data_req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST;
|
||||
// LOG_D(PHY, "[VNF] %s() TX_REQ sfn_sf:%d number_of_pdus:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(tx_data_req->SFN),
|
||||
// tx_data_req->Number_of_PDUs); int retval = nfapi_vnf_p7_tx_data_req(p7_config, tx_data_req);
|
||||
int retval = fapi_nr_pack_and_send_p7_message((vnf_p7_t *)p7_config, &tx_data_req->header);
|
||||
if (retval != 0) {
|
||||
LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval);
|
||||
} else {
|
||||
tx_data_req->Number_of_PDUs = 0;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int oai_fapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req)
|
||||
{
|
||||
nfapi_vnf_p7_config_t *p7_config = aerial_vnf.p7_vnfs[0].config;
|
||||
dl_config_req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST;
|
||||
dl_config_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
|
||||
int retval = fapi_nr_pack_and_send_p7_message((vnf_p7_t *)p7_config, &dl_config_req->header);
|
||||
dl_config_req->dl_tti_request_body.nPDUs = 0;
|
||||
dl_config_req->dl_tti_request_body.nGroup = 0;
|
||||
|
||||
if (retval != 0) {
|
||||
LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int oai_fapi_send_end_request(int cell, uint32_t frame, uint32_t slot){
|
||||
nfapi_vnf_p7_config_t *p7_config = aerial_vnf.p7_vnfs[0].config;
|
||||
nfapi_nr_slot_indication_scf_t *nr_slot_resp = CALLOC(1, sizeof(*nr_slot_resp));
|
||||
nr_slot_resp->header.message_id = 0x8F;
|
||||
nr_slot_resp->sfn = frame;
|
||||
nr_slot_resp->slot = slot;
|
||||
int retval = fapi_nr_pack_and_send_p7_message((vnf_p7_t *)p7_config, &nr_slot_resp->header);
|
||||
if (retval != 0) {
|
||||
LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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 fapi/oai-integration/fapi_vnf_p5.h
|
||||
* \brief Header file for fapi_vnf_p5.c
|
||||
* \author Ruben S. Silva
|
||||
* \date 2023
|
||||
* \version 0.1
|
||||
* \company OpenAirInterface Software Alliance
|
||||
* \email: contact@openairinterface.org, rsilva@allbesmart.pt
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
#ifdef ENABLE_AERIAL
|
||||
#ifndef OPENAIRINTERFACE_FAPI_VNF_P5_H
|
||||
#define OPENAIRINTERFACE_FAPI_VNF_P5_H
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "nfapi_nr_interface_scf.h"
|
||||
#include "nfapi_vnf_interface.h"
|
||||
#include "nfapi_vnf.h"
|
||||
#include "nfapi.h"
|
||||
#include "nfapi/oai_integration/vendor_ext.h"
|
||||
#include "fapi_nvIPC.h"
|
||||
|
||||
#include "PHY/defs_eNB.h"
|
||||
#include "PHY/LTE_TRANSPORT/transport_proto.h"
|
||||
|
||||
#include "common/ran_context.h"
|
||||
#include "openair2/PHY_INTERFACE/queue_t.h"
|
||||
#include "gnb_ind_vars.h"
|
||||
#include "nfapi/open-nFAPI/vnf/inc/vnf.h"
|
||||
|
||||
void aerial_configure_nr_fapi_vnf();
|
||||
int aerial_nr_send_config_request(nfapi_vnf_config_t *config, int p5_idx);
|
||||
int oai_fapi_send_end_request(int cell_id, uint32_t frame, uint32_t slot);
|
||||
uint8_t aerial_unpack_nr_param_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config);
|
||||
uint8_t aerial_unpack_nr_config_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config);
|
||||
int aerial_pnf_nr_connection_indication_cb(nfapi_vnf_config_t *config, int p5_idx);
|
||||
int aerial_nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t *config);
|
||||
int fapi_nr_p5_message_pack(void *pMessageBuf, uint32_t messageBufLen, void *pPackedBuf, uint32_t packedBufLen, nfapi_p4_p5_codec_config_t* config);
|
||||
|
||||
int oai_fapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req);
|
||||
int oai_fapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req);
|
||||
int oai_fapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req);
|
||||
int oai_fapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req);
|
||||
#endif //OPENAIRINTERFACE_FAPI_VNF_P5_H
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,243 @@
|
||||
/*
|
||||
* 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 fapi/oai-integration/fapi_vnf_p7.h
|
||||
* \brief Header file for fapi_vnf_p7.c
|
||||
* \author Ruben S. Silva
|
||||
* \date 2023
|
||||
* \version 0.1
|
||||
* \company OpenAirInterface Software Alliance
|
||||
* \email: contact@openairinterface.org, rsilva@allbesmart.pt
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#ifdef ENABLE_AERIAL
|
||||
#ifndef OPENAIRINTERFACE_FAPI_VNF_P7_H
|
||||
#define OPENAIRINTERFACE_FAPI_VNF_P7_H
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "nfapi_nr_interface_scf.h"
|
||||
#include "nfapi_vnf_interface.h"
|
||||
#include "nfapi_vnf.h"
|
||||
#include "nfapi.h"
|
||||
#include "nfapi/oai_integration/vendor_ext.h"
|
||||
#include "fapi_nvIPC.h"
|
||||
|
||||
#include "PHY/defs_eNB.h"
|
||||
#include "PHY/LTE_TRANSPORT/transport_proto.h"
|
||||
#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
|
||||
#include "lte-softmodem.h"
|
||||
|
||||
#include "common/ran_context.h"
|
||||
#include "openair2/PHY_INTERFACE/queue_t.h"
|
||||
#include "gnb_ind_vars.h"
|
||||
#include "nfapi/open-nFAPI/vnf/inc/vnf.h"
|
||||
#include "nfapi/open-nFAPI/vnf/inc/vnf_p7.h"
|
||||
typedef struct {
|
||||
uint8_t enabled;
|
||||
uint32_t rx_port;
|
||||
uint32_t tx_port;
|
||||
char tx_addr[80];
|
||||
} udp_data;
|
||||
|
||||
typedef struct {
|
||||
uint16_t index;
|
||||
uint16_t id;
|
||||
uint8_t rfs[2];
|
||||
uint8_t excluded_rfs[2];
|
||||
|
||||
udp_data udp;
|
||||
|
||||
char local_addr[80];
|
||||
int local_port;
|
||||
|
||||
char *remote_addr;
|
||||
int remote_port;
|
||||
|
||||
uint8_t duplex_mode;
|
||||
uint16_t dl_channel_bw_support;
|
||||
uint16_t ul_channel_bw_support;
|
||||
uint8_t num_dl_layers_supported;
|
||||
uint8_t num_ul_layers_supported;
|
||||
uint16_t release_supported;
|
||||
uint8_t nmm_modes_supported;
|
||||
|
||||
uint8_t dl_ues_per_subframe;
|
||||
uint8_t ul_ues_per_subframe;
|
||||
|
||||
uint8_t first_subframe_ind;
|
||||
|
||||
// timing information recevied from the vnf
|
||||
uint8_t timing_window;
|
||||
uint8_t timing_info_mode;
|
||||
uint8_t timing_info_period;
|
||||
|
||||
} phy_info;
|
||||
|
||||
typedef struct {
|
||||
uint16_t index;
|
||||
uint16_t band;
|
||||
int16_t max_transmit_power;
|
||||
int16_t min_transmit_power;
|
||||
uint8_t num_antennas_supported;
|
||||
uint32_t min_downlink_frequency;
|
||||
uint32_t max_downlink_frequency;
|
||||
uint32_t max_uplink_frequency;
|
||||
uint32_t min_uplink_frequency;
|
||||
} rf_info;
|
||||
|
||||
typedef struct {
|
||||
int release;
|
||||
phy_info phys[2];
|
||||
rf_info rfs[2];
|
||||
|
||||
uint8_t sync_mode;
|
||||
uint8_t location_mode;
|
||||
uint8_t location_coordinates[6];
|
||||
uint32_t dl_config_timing;
|
||||
uint32_t ul_config_timing;
|
||||
uint32_t tx_timing;
|
||||
uint32_t hi_dci0_timing;
|
||||
|
||||
uint16_t max_phys;
|
||||
uint16_t max_total_bw;
|
||||
uint16_t max_total_dl_layers;
|
||||
uint16_t max_total_ul_layers;
|
||||
uint8_t shared_bands;
|
||||
uint8_t shared_pa;
|
||||
int16_t max_total_power;
|
||||
uint8_t oui;
|
||||
|
||||
uint8_t wireshark_test_mode;
|
||||
|
||||
} pnf_info;
|
||||
|
||||
typedef struct mac mac_t;
|
||||
typedef struct mac {
|
||||
void *user_data;
|
||||
|
||||
void (*dl_config_req)(mac_t *mac, nfapi_dl_config_request_t *req);
|
||||
void (*ul_config_req)(mac_t *mac, nfapi_ul_config_request_t *req);
|
||||
void (*hi_dci0_req)(mac_t *mac, nfapi_hi_dci0_request_t *req);
|
||||
void (*tx_req)(mac_t *mac, nfapi_tx_request_t *req);
|
||||
} mac_t;
|
||||
|
||||
typedef struct {
|
||||
int local_port;
|
||||
char local_addr[80];
|
||||
|
||||
unsigned timing_window;
|
||||
unsigned periodic_timing_enabled;
|
||||
unsigned aperiodic_timing_enabled;
|
||||
unsigned periodic_timing_period;
|
||||
|
||||
// This is not really the right place if we have multiple PHY,
|
||||
// should be part of the phy struct
|
||||
udp_data udp;
|
||||
|
||||
uint8_t thread_started;
|
||||
|
||||
nfapi_vnf_p7_config_t *config;
|
||||
|
||||
mac_t *mac;
|
||||
|
||||
} vnf_p7_info;
|
||||
|
||||
typedef struct {
|
||||
uint8_t wireshark_test_mode;
|
||||
pnf_info pnfs[2];
|
||||
vnf_p7_info p7_vnfs[2];
|
||||
|
||||
} vnf_info;
|
||||
|
||||
int aerial_wake_gNB_rxtx(PHY_VARS_gNB *gNB, uint16_t sfn, uint16_t slot);
|
||||
int aerial_wake_eNB_rxtx(PHY_VARS_eNB *eNB, uint16_t sfn, uint16_t sf);
|
||||
int aerial_phy_sync_indication(struct nfapi_vnf_p7_config *config, uint8_t sync);
|
||||
int aerial_phy_slot_indication(struct nfapi_vnf_p7_config *config, uint16_t phy_id, uint16_t sfn, uint16_t slot);
|
||||
int aerial_phy_harq_indication(struct nfapi_vnf_p7_config *config, nfapi_harq_indication_t *ind);
|
||||
int aerial_phy_nr_crc_indication(nfapi_nr_crc_indication_t *ind);
|
||||
int aerial_phy_nr_rx_data_indication(nfapi_nr_rx_data_indication_t *ind);
|
||||
int aerial_phy_nr_rach_indication(nfapi_nr_rach_indication_t *ind);
|
||||
int aerial_phy_nr_uci_indication(nfapi_nr_uci_indication_t *ind);
|
||||
int aerial_phy_srs_indication(struct nfapi_vnf_p7_config *config, nfapi_srs_indication_t *ind);
|
||||
int aerial_phy_sr_indication(struct nfapi_vnf_p7_config *config, nfapi_sr_indication_t *ind);
|
||||
int aerial_phy_cqi_indication(struct nfapi_vnf_p7_config *config, nfapi_cqi_indication_t *ind);
|
||||
int aerial_phy_lbt_dl_indication(struct nfapi_vnf_p7_config *config, nfapi_lbt_dl_indication_t *ind);
|
||||
int aerial_phy_nb_harq_indication(struct nfapi_vnf_p7_config *config, nfapi_nb_harq_indication_t *ind);
|
||||
int aerial_phy_nrach_indication(struct nfapi_vnf_p7_config *config, nfapi_nrach_indication_t *ind);
|
||||
int aerial_phy_nr_slot_indication(nfapi_nr_slot_indication_scf_t *ind);
|
||||
int aerial_phy_nr_srs_indication(nfapi_nr_srs_indication_t *ind);
|
||||
void *aerial_vnf_allocate(size_t size);
|
||||
void aerial_vnf_deallocate(void *ptr);
|
||||
int aerial_phy_vendor_ext(struct nfapi_vnf_p7_config *config, nfapi_p7_message_header_t *msg);
|
||||
int aerial_phy_unpack_p7_vendor_extension(nfapi_p7_message_header_t *header,
|
||||
uint8_t **ppReadPackedMessage,
|
||||
uint8_t *end,
|
||||
nfapi_p7_codec_config_t *config);
|
||||
int aerial_phy_pack_p7_vendor_extension(nfapi_p7_message_header_t *header,
|
||||
uint8_t **ppWritePackedMsg,
|
||||
uint8_t *end,
|
||||
nfapi_p7_codec_config_t *config);
|
||||
int aerial_phy_unpack_vendor_extension_tlv(nfapi_tl_t *tl,
|
||||
uint8_t **ppReadPackedMessage,
|
||||
uint8_t *end,
|
||||
void **ve,
|
||||
nfapi_p7_codec_config_t *codec);
|
||||
int aerial_phy_pack_vendor_extension_tlv(void *ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *codec);
|
||||
nfapi_p7_message_header_t *aerial_phy_allocate_p7_vendor_ext(uint16_t message_id, uint16_t *msg_size);
|
||||
void aerial_phy_deallocate_p7_vendor_ext(nfapi_p7_message_header_t *header);
|
||||
|
||||
uint8_t aerial_unpack_nr_slot_indication(uint8_t **ppReadPackedMsg,
|
||||
uint8_t *end,
|
||||
nfapi_nr_slot_indication_scf_t *msg,
|
||||
nfapi_p7_codec_config_t *config);
|
||||
uint8_t aerial_unpack_nr_rx_data_indication(uint8_t **ppReadPackedMsg,
|
||||
uint8_t *end,
|
||||
uint8_t **pDataMsg,
|
||||
uint8_t *data_end,
|
||||
nfapi_nr_rx_data_indication_t *msg,
|
||||
nfapi_p7_codec_config_t *config);
|
||||
uint8_t aerial_unpack_nr_crc_indication(uint8_t **ppReadPackedMsg,
|
||||
uint8_t *end,
|
||||
nfapi_nr_crc_indication_t *msg,
|
||||
nfapi_p7_codec_config_t *config);
|
||||
uint8_t aerial_unpack_nr_uci_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config);
|
||||
uint8_t aerial_unpack_nr_srs_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config);
|
||||
uint8_t aerial_unpack_nr_rach_indication(uint8_t **ppReadPackedMsg,
|
||||
uint8_t *end,
|
||||
nfapi_nr_rach_indication_t *msg,
|
||||
nfapi_p7_codec_config_t *config);
|
||||
|
||||
// int fapi_nr_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t* config);
|
||||
int fapi_nr_pack_and_send_p7_message(vnf_p7_t *vnf_p7, nfapi_p7_message_header_t *header);
|
||||
#endif // OPENAIRINTERFACE_FAPI_VNF_P7_H
|
||||
#endif
|
||||
@@ -27,6 +27,7 @@ static const char *const nfapi_str_mode[] = {
|
||||
"MONOLITHIC",
|
||||
"PNF",
|
||||
"VNF",
|
||||
"AERIAL",
|
||||
"UE_STUB_PNF",
|
||||
"UE_STUB_OFFNET",
|
||||
"STANDALONE_PNF",
|
||||
@@ -64,7 +65,7 @@ const char *nfapi_get_strmode(void) {
|
||||
}
|
||||
|
||||
void nfapi_logmode() {
|
||||
LOG_I(ENB_APP,"nfapi running mode: %s\n",nfapi_get_strmode());
|
||||
LOG_I(ENB_APP,"nfapi (%d) running mode: %s\n",nfapi_params.nfapi_mode,nfapi_get_strmode());
|
||||
}
|
||||
|
||||
nfapi_mode_t nfapi_getmode(void) {
|
||||
|
||||
@@ -68,6 +68,7 @@ typedef enum {
|
||||
NFAPI_MONOLITHIC=0,
|
||||
NFAPI_MODE_PNF,
|
||||
NFAPI_MODE_VNF,
|
||||
NFAPI_MODE_AERIAL,
|
||||
NFAPI_UE_STUB_PNF,
|
||||
NFAPI_UE_STUB_OFFNET,
|
||||
NFAPI_MODE_STANDALONE_PNF,
|
||||
|
||||
@@ -328,6 +328,7 @@ typedef struct
|
||||
#define NFAPI_NR_CONFIG_SLOT_CONFIG_TAG 0x1027
|
||||
|
||||
#define NFAPI_NR_CONFIG_RSSI_MEASUREMENT_TAG 0x1028
|
||||
#define NFAPI_NR_CONFIG_TDD_TABLE 0x1035
|
||||
|
||||
//table 3-21
|
||||
typedef struct
|
||||
@@ -1467,11 +1468,9 @@ typedef enum {
|
||||
|
||||
//table 3-58
|
||||
#define NFAPI_NR_MAX_TX_REQUEST_TLV 2
|
||||
typedef struct {
|
||||
uint16_t PDU_length; // SCF 222.10.02 The total length (in bytes) of the PDU description and PDU data, without the padding bytes.
|
||||
// (2 bytes PDU_Length + 2 bytes PDU_Index + 4 bytes num_TLV + TLV size ( 2 bytes tag + 2 bytes length +
|
||||
// value size without padding))
|
||||
// TBS + 12
|
||||
typedef struct
|
||||
{
|
||||
uint32_t PDU_length;
|
||||
uint16_t PDU_index;
|
||||
uint32_t num_TLV;
|
||||
nfapi_nr_tx_data_request_tlv_t TLVs[NFAPI_NR_MAX_TX_REQUEST_TLV];
|
||||
@@ -1505,7 +1504,7 @@ typedef struct
|
||||
uint32_t handle;
|
||||
uint16_t rnti;
|
||||
uint8_t harq_id;
|
||||
uint16_t pdu_length;
|
||||
uint32_t pdu_length;// For Aerial, RX_DATA.indication PDULength is changed to 32 bit field
|
||||
uint8_t ul_cqi;
|
||||
uint16_t timing_advance;//Timing advance 𝑇𝐴 measured for the UE [TS 38.213, Section 4.2] NTA_new = NTA_old + (TA − 31) ⋅ 16 ⋅ 64⁄2μ Value: 0 → 63 0xffff should be set if this field is invalid
|
||||
uint16_t rssi;
|
||||
|
||||
@@ -102,8 +102,13 @@ uint8_t push16(uint16_t in, uint8_t **out, uint8_t *end) {
|
||||
uint8_t *pOut = *out;
|
||||
|
||||
if((end - pOut) >= 2) {
|
||||
#ifdef FAPI_BYTE_ORDERING_BIG_ENDIAN
|
||||
pOut[1] = (in & 0xFF00) >> 8;
|
||||
pOut[0] = (in & 0xFF);
|
||||
#else
|
||||
pOut[0] = (in & 0xFF00) >> 8;
|
||||
pOut[1] = (in & 0xFF);
|
||||
#endif
|
||||
(*out)+=2;
|
||||
return 2;
|
||||
} else {
|
||||
@@ -117,8 +122,13 @@ uint8_t pushs16(int16_t in, uint8_t **out, uint8_t *end) {
|
||||
uint8_t *pOut = *out;
|
||||
|
||||
if((end - pOut) >= 2) {
|
||||
#ifdef FAPI_BYTE_ORDERING_BIG_ENDIAN
|
||||
pOut[1] = (in & 0xFF00) >> 8;
|
||||
pOut[0] = (in & 0xFF);
|
||||
#else
|
||||
pOut[0] = (in & 0xFF00) >> 8;
|
||||
pOut[1] = (in & 0xFF);
|
||||
#endif
|
||||
(*out)+=2;
|
||||
return 2;
|
||||
} else {
|
||||
@@ -132,10 +142,17 @@ uint8_t push32(uint32_t in, uint8_t **out, uint8_t *end) {
|
||||
uint8_t *pOut = *out;
|
||||
|
||||
if((end - pOut) >= 4) {
|
||||
#ifdef FAPI_BYTE_ORDERING_BIG_ENDIAN
|
||||
pOut[3] = (in & 0xFF000000) >> 24;
|
||||
pOut[2] = (in & 0xFF0000) >> 16;
|
||||
pOut[1] = (in & 0xFF00) >> 8;
|
||||
pOut[0] = (in & 0xFF);
|
||||
#else
|
||||
pOut[0] = (in & 0xFF000000) >> 24;
|
||||
pOut[1] = (in & 0xFF0000) >> 16;
|
||||
pOut[2] = (in & 0xFF00) >> 8;
|
||||
pOut[3] = (in & 0xFF);
|
||||
#endif
|
||||
(*out)+=4;
|
||||
return 4;
|
||||
} else {
|
||||
@@ -149,10 +166,17 @@ uint8_t pushs32(int32_t in, uint8_t **out, uint8_t *end) {
|
||||
uint8_t *pOut = *out;
|
||||
|
||||
if((end - pOut) >= 4) {
|
||||
#ifdef FAPI_BYTE_ORDERING_BIG_ENDIAN
|
||||
pOut[3] = (in & 0xFF000000) >> 24;
|
||||
pOut[2] = (in & 0xFF0000) >> 16;
|
||||
pOut[1] = (in & 0xFF00) >> 8;
|
||||
pOut[0] = (in & 0xFF);
|
||||
#else
|
||||
pOut[0] = (in & 0xFF000000) >> 24;
|
||||
pOut[1] = (in & 0xFF0000) >> 16;
|
||||
pOut[2] = (in & 0xFF00) >> 8;
|
||||
pOut[3] = (in & 0xFF);
|
||||
#endif
|
||||
(*out)+=4;
|
||||
return 4;
|
||||
} else {
|
||||
@@ -194,7 +218,11 @@ uint8_t pull16(uint8_t **in, uint16_t *out, uint8_t *end) {
|
||||
uint8_t *pIn = *in;
|
||||
|
||||
if((end - pIn) >=2 ) {
|
||||
#ifdef FAPI_BYTE_ORDERING_BIG_ENDIAN
|
||||
*out = ((pIn[1]) << 8) | pIn[0];
|
||||
#else
|
||||
*out = ((pIn[0]) << 8) | pIn[1];
|
||||
#endif
|
||||
(*in)+=2;
|
||||
return 2;
|
||||
} else {
|
||||
@@ -208,7 +236,11 @@ uint8_t pulls16(uint8_t **in, int16_t *out, uint8_t *end) {
|
||||
uint8_t *pIn = *in;
|
||||
|
||||
if((end - pIn) >=2 ) {
|
||||
#ifdef FAPI_BYTE_ORDERING_BIG_ENDIAN
|
||||
*out = ((pIn[1]) << 8) | pIn[0];
|
||||
#else
|
||||
*out = ((pIn[0]) << 8) | pIn[1];
|
||||
#endif
|
||||
(*in)+=2;
|
||||
return 2;
|
||||
} else {
|
||||
@@ -222,7 +254,11 @@ uint8_t pull32(uint8_t **in, uint32_t *out, uint8_t *end) {
|
||||
uint8_t *pIn = *in;
|
||||
|
||||
if((end - pIn) >= 4) {
|
||||
#ifdef FAPI_BYTE_ORDERING_BIG_ENDIAN
|
||||
*out = ((uint32_t)pIn[3] << 24) | (pIn[2] << 16) | (pIn[1] << 8) | pIn[0];
|
||||
#else
|
||||
*out = ((uint32_t)pIn[0] << 24) | (pIn[1] << 16) | (pIn[2] << 8) | pIn[3];
|
||||
#endif
|
||||
(*in) += 4;
|
||||
return 4;
|
||||
} else {
|
||||
@@ -236,7 +272,11 @@ uint8_t pulls32(uint8_t **in, int32_t *out, uint8_t *end) {
|
||||
uint8_t *pIn = *in;
|
||||
|
||||
if((end - pIn) >=4 ) {
|
||||
#ifdef FAPI_BYTE_ORDERING_BIG_ENDIAN
|
||||
*out = (pIn[3] << 24) | (pIn[2] << 16) | (pIn[1] << 8) | pIn[0];
|
||||
#else
|
||||
*out = (pIn[0] << 24) | (pIn[1] << 16) | (pIn[2] << 8) | pIn[3];
|
||||
#endif
|
||||
(*in)+=4;
|
||||
return 4;
|
||||
} else {
|
||||
@@ -839,7 +879,6 @@ int unpack_nr_tlv_list(unpack_tlv_t unpack_fns[],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <nfapi.h>
|
||||
#include "nfapi_nr_interface.h"
|
||||
#include "nfapi_nr_interface_scf.h"
|
||||
#include "nfapi/oai_integration/vendor_ext.h"
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
@@ -1670,6 +1671,16 @@ static uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uin
|
||||
end,
|
||||
&pack_uint16_tlv_value);
|
||||
numTLVs++;
|
||||
|
||||
if (NFAPI_MODE != NFAPI_MODE_AERIAL) {
|
||||
// TLV not supported by Aerial L1
|
||||
pack_nr_tlv(NFAPI_NR_CONFIG_FREQUENCY_SHIFT_7P5KHZ_TAG,
|
||||
&(pNfapiMsg->carrier_config.frequency_shift_7p5khz),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
}
|
||||
// END Carrier Configuration
|
||||
|
||||
// START Cell Configuration
|
||||
@@ -1695,13 +1706,15 @@ static uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uin
|
||||
end,
|
||||
&pack_uint32_tlv_value);
|
||||
numTLVs++;
|
||||
|
||||
retval &= pack_nr_tlv(NFAPI_NR_CONFIG_BCH_PAYLOAD_TAG,
|
||||
&(pNfapiMsg->ssb_config.bch_payload),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
if (NFAPI_MODE != NFAPI_MODE_AERIAL) {
|
||||
// TLV not supported by Aerial L1
|
||||
retval &= pack_nr_tlv(NFAPI_NR_CONFIG_BCH_PAYLOAD_TAG,
|
||||
&(pNfapiMsg->ssb_config.bch_payload),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
}
|
||||
|
||||
retval &= pack_nr_tlv(NFAPI_NR_CONFIG_SCS_COMMON_TAG,
|
||||
&(pNfapiMsg->ssb_config.scs_common),
|
||||
@@ -1780,6 +1793,16 @@ static uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uin
|
||||
end,
|
||||
&pack_uint16_tlv_value);
|
||||
numTLVs++;
|
||||
for (int k = 0; k < prach_fd_occasion.num_unused_root_sequences.value; k++) {
|
||||
prach_fd_occasion.unused_root_sequences_list[k].tl.tag = NFAPI_NR_CONFIG_UNUSED_ROOT_SEQUENCES_TAG;
|
||||
prach_fd_occasion.unused_root_sequences_list[k].value = 0;
|
||||
pack_nr_tlv(NFAPI_NR_CONFIG_UNUSED_ROOT_SEQUENCES_TAG,
|
||||
&(prach_fd_occasion.unused_root_sequences_list[k]),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint16_tlv_value);
|
||||
numTLVs++;
|
||||
}
|
||||
}
|
||||
|
||||
retval &= pack_nr_tlv(NFAPI_NR_CONFIG_SSB_PER_RACH_TAG,
|
||||
@@ -1788,15 +1811,25 @@ static uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uin
|
||||
end,
|
||||
&pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
pNfapiMsg->prach_config.prach_multiple_carriers_in_a_band.tl.tag = NFAPI_NR_CONFIG_PRACH_MULTIPLE_CARRIERS_IN_A_BAND_TAG;
|
||||
pNfapiMsg->prach_config.prach_multiple_carriers_in_a_band.value = 0;
|
||||
pack_nr_tlv(NFAPI_NR_CONFIG_PRACH_MULTIPLE_CARRIERS_IN_A_BAND_TAG,
|
||||
&(pNfapiMsg->prach_config.prach_multiple_carriers_in_a_band),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
// END PRACH Configuration
|
||||
// START SSB Table
|
||||
retval &= pack_nr_tlv(NFAPI_NR_CONFIG_SSB_OFFSET_POINT_A_TAG,
|
||||
&(pNfapiMsg->ssb_table.ssb_offset_point_a),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint16_tlv_value);
|
||||
numTLVs++;
|
||||
|
||||
if (NFAPI_MODE != NFAPI_MODE_AERIAL) {
|
||||
// TLV not supported by Aerial L1
|
||||
retval &= pack_nr_tlv(NFAPI_NR_CONFIG_SSB_OFFSET_POINT_A_TAG,
|
||||
&(pNfapiMsg->ssb_table.ssb_offset_point_a),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint16_tlv_value);
|
||||
numTLVs++;
|
||||
}
|
||||
retval &=
|
||||
pack_nr_tlv(NFAPI_NR_CONFIG_SSB_PERIOD_TAG, &(pNfapiMsg->ssb_table.ssb_period), ppWritePackedMsg, end, &pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
@@ -1807,7 +1840,10 @@ static uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uin
|
||||
end,
|
||||
&pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
|
||||
/* was unused */
|
||||
pNfapiMsg->ssb_table.MIB.tl.tag = NFAPI_NR_CONFIG_MIB_TAG;
|
||||
pack_nr_tlv(NFAPI_NR_CONFIG_MIB_TAG, &(pNfapiMsg->ssb_table.MIB), ppWritePackedMsg, end, &pack_uint32_tlv_value);
|
||||
numTLVs++;
|
||||
// SCF222.10.02 Table 3-25 : If included there must be two instances of this TLV
|
||||
retval &= pack_nr_tlv(NFAPI_NR_CONFIG_SSB_MASK_TAG,
|
||||
&(pNfapiMsg->ssb_table.ssb_mask_list[0].ssb_mask),
|
||||
@@ -1822,26 +1858,48 @@ static uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uin
|
||||
end,
|
||||
&pack_uint32_tlv_value);
|
||||
numTLVs++;
|
||||
if (NFAPI_MODE != NFAPI_MODE_AERIAL) {
|
||||
// TLV not supported by Aerial L1
|
||||
for (int i = 0; i < 64; i++) {
|
||||
// SCF222.10.02 Table 3-25 : If included there must be 64 instances of this TLV
|
||||
retval &= pack_nr_tlv(NFAPI_NR_CONFIG_BEAM_ID_TAG,
|
||||
&(pNfapiMsg->ssb_table.ssb_beam_id_list[i].beam_id),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 64; i++) {
|
||||
// SCF222.10.02 Table 3-25 : If included there must be 64 instances of this TLV
|
||||
retval &= pack_nr_tlv(NFAPI_NR_CONFIG_BEAM_ID_TAG,
|
||||
&(pNfapiMsg->ssb_table.ssb_beam_id_list[i].beam_id),
|
||||
// END SSB Table
|
||||
// START TDD Table
|
||||
retval &= pack_nr_tlv(NFAPI_NR_CONFIG_TDD_PERIOD_TAG,
|
||||
&(pNfapiMsg->tdd_table.tdd_period),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
// END TDD Table
|
||||
for (int i = 0; i < 40; i++) {
|
||||
for (int k = 0; k < 14; k++) {
|
||||
pack_nr_tlv(NFAPI_NR_CONFIG_SLOT_CONFIG_TAG,
|
||||
&(pNfapiMsg->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[k].slot_config),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// END SSB Table
|
||||
// START TDD Table
|
||||
retval &=
|
||||
pack_nr_tlv(NFAPI_NR_CONFIG_TDD_PERIOD_TAG, &(pNfapiMsg->tdd_table.tdd_period), ppWritePackedMsg, end, &pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
// END TDD Table
|
||||
|
||||
// START Measurement Config
|
||||
// SCF222.10.02 Table 3-27 : Contains only one TLV and is currently unused
|
||||
pNfapiMsg->measurement_config.rssi_measurement.tl.tag = NFAPI_NR_CONFIG_RSSI_MEASUREMENT_TAG;
|
||||
pNfapiMsg->measurement_config.rssi_measurement.value = 1;
|
||||
pack_nr_tlv(NFAPI_NR_CONFIG_RSSI_MEASUREMENT_TAG,
|
||||
&(pNfapiMsg->measurement_config.rssi_measurement),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
// END Measurement Config
|
||||
|
||||
// START Digital Beam Table (DBT) PDU
|
||||
@@ -1851,57 +1909,57 @@ static uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uin
|
||||
// START Precoding Matrix (PM) PDU
|
||||
// Struct in nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h nfapi_nr_pm_pdu_t, currently unused, tag to use for AERIAL
|
||||
// is 0xA011 END Precoding Matrix (PM) PDU
|
||||
|
||||
// START nFAPI TLVs included in CONFIG.request for IDLE and CONFIGURED states
|
||||
retval &= pack_nr_tlv(NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG,
|
||||
&(pNfapiMsg->nfapi_config.p7_vnf_address_ipv4),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_ipv4_address_value);
|
||||
numTLVs++;
|
||||
|
||||
retval &= pack_nr_tlv(NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG,
|
||||
&(pNfapiMsg->nfapi_config.p7_vnf_address_ipv6),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_ipv6_address_value);
|
||||
numTLVs++;
|
||||
|
||||
retval &= pack_nr_tlv(NFAPI_NR_NFAPI_P7_VNF_PORT_TAG,
|
||||
&(pNfapiMsg->nfapi_config.p7_vnf_port),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint16_tlv_value);
|
||||
numTLVs++;
|
||||
|
||||
retval &= pack_nr_tlv(NFAPI_NR_NFAPI_TIMING_WINDOW_TAG,
|
||||
&(pNfapiMsg->nfapi_config.timing_window),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
|
||||
retval &= pack_nr_tlv(NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG,
|
||||
&(pNfapiMsg->nfapi_config.timing_info_mode),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
|
||||
retval &= pack_nr_tlv(NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG,
|
||||
&(pNfapiMsg->nfapi_config.timing_info_period),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
// END nFAPI TLVs included in CONFIG.request for IDLE and CONFIGURED states
|
||||
|
||||
if (pNfapiMsg->vendor_extension != 0 && config != 0) {
|
||||
retval &= pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config);
|
||||
NFAPI_TRACE(NFAPI_TRACE_DEBUG, "Packing CONFIG.request vendor_extension_tlv %d\n", pNfapiMsg->vendor_extension->tag);
|
||||
if(NFAPI_MODE != NFAPI_MODE_AERIAL){
|
||||
// START nFAPI TLVs included in CONFIG.request for IDLE and CONFIGURED states
|
||||
retval &= pack_nr_tlv(NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG,
|
||||
&(pNfapiMsg->nfapi_config.p7_vnf_address_ipv4),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_ipv4_address_value);
|
||||
numTLVs++;
|
||||
}
|
||||
|
||||
retval &= pack_nr_tlv(NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG,
|
||||
&(pNfapiMsg->nfapi_config.p7_vnf_address_ipv6),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_ipv6_address_value);
|
||||
numTLVs++;
|
||||
|
||||
retval &= pack_nr_tlv(NFAPI_NR_NFAPI_P7_VNF_PORT_TAG,
|
||||
&(pNfapiMsg->nfapi_config.p7_vnf_port),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint16_tlv_value);
|
||||
numTLVs++;
|
||||
|
||||
retval &= pack_nr_tlv(NFAPI_NR_NFAPI_TIMING_WINDOW_TAG,
|
||||
&(pNfapiMsg->nfapi_config.timing_window),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
|
||||
retval &= pack_nr_tlv(NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG,
|
||||
&(pNfapiMsg->nfapi_config.timing_info_mode),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
|
||||
retval &= pack_nr_tlv(NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG,
|
||||
&(pNfapiMsg->nfapi_config.timing_info_period),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
// END nFAPI TLVs included in CONFIG.request for IDLE and CONFIGURED states
|
||||
|
||||
if (pNfapiMsg->vendor_extension != 0 && config != 0) {
|
||||
retval &= pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config);
|
||||
NFAPI_TRACE(NFAPI_TRACE_DEBUG, "Packing CONFIG.request vendor_extension_tlv %d\n", pNfapiMsg->vendor_extension->tag);
|
||||
numTLVs++;
|
||||
}
|
||||
}
|
||||
pNfapiMsg->num_tlv = numTLVs;
|
||||
retval &= push8(pNfapiMsg->num_tlv, &pNumTLVFields, end);
|
||||
return retval;
|
||||
@@ -2170,7 +2228,7 @@ static uint8_t pack_p5_message_body(nfapi_p4_p5_message_header_t *header, uint8_
|
||||
|
||||
static uint32_t get_packed_msg_len(uintptr_t msgHead, uintptr_t msgEnd) {
|
||||
if (msgEnd < msgHead) {
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "get_packed_msg_len: Error in pointers supplied %lu, %lu\n", msgHead, msgEnd);
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "get_packed_msg_len: Error in pointers supplied %p, %p\n", &msgHead, &msgEnd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2178,6 +2236,7 @@ static uint32_t get_packed_msg_len(uintptr_t msgHead, uintptr_t msgEnd) {
|
||||
}
|
||||
|
||||
// Main pack function - public
|
||||
|
||||
int nfapi_nr_p5_message_pack(void *pMessageBuf,
|
||||
uint32_t messageBufLen,
|
||||
void *pPackedBuf,
|
||||
|
||||
@@ -328,8 +328,8 @@ static uint8_t pack_dl_tti_pdsch_pdu_rel15_value(void *tlv, uint8_t **ppWritePac
|
||||
}
|
||||
// TODO Add TX power info
|
||||
// Hardcoded values that represent 0db
|
||||
if (!(push8(8, ppWritePackedMsg, end) && // powerControlOffset
|
||||
push8(1, ppWritePackedMsg, end))) { // powerControlOffsetSS
|
||||
if (!(push8(0, ppWritePackedMsg, end) && // powerControlOffset
|
||||
push8(0, ppWritePackedMsg, end))) { // powerControlOffsetSS
|
||||
return 0;
|
||||
}
|
||||
// TODO Add CBG Fields
|
||||
@@ -346,9 +346,8 @@ static uint8_t pack_dl_tti_ssb_pdu_rel15_value(void *tlv, uint8_t **ppWritePacke
|
||||
&& push16(value->ssbOffsetPointA, ppWritePackedMsg, end) && push8(value->bchPayloadFlag, ppWritePackedMsg, end)
|
||||
&& push8((value->bchPayload >> 16) & 0xff, ppWritePackedMsg, end)
|
||||
&& push8((value->bchPayload >> 8) & 0xff, ppWritePackedMsg, end) && push8(value->bchPayload & 0xff, ppWritePackedMsg, end)
|
||||
&& push8(0, ppWritePackedMsg, end) &&
|
||||
&& push8(0, ppWritePackedMsg, end)
|
||||
// TODO add Tx Power Info
|
||||
push8(0, ppWritePackedMsg, end) && push8(0, ppWritePackedMsg, end)
|
||||
&& push16(value->precoding_and_beamforming.num_prgs, ppWritePackedMsg, end)
|
||||
&& push16(value->precoding_and_beamforming.prg_size, ppWritePackedMsg, end)
|
||||
&& push8(value->precoding_and_beamforming.dig_bf_interfaces, ppWritePackedMsg, end))) {
|
||||
@@ -1092,7 +1091,7 @@ static uint8_t pack_ul_tti_request_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, ui
|
||||
}
|
||||
|
||||
static uint8_t pack_ul_tti_request_srs_pdu(nfapi_nr_srs_pdu_t *srs_pdu, uint8_t **ppWritePackedMsg, uint8_t *end) {
|
||||
return(
|
||||
if(!(
|
||||
push16(srs_pdu->rnti, ppWritePackedMsg, end) &&
|
||||
push32(srs_pdu->handle, ppWritePackedMsg, end) &&
|
||||
push16(srs_pdu->bwp_size, ppWritePackedMsg, end) &&
|
||||
@@ -1117,7 +1116,23 @@ static uint8_t pack_ul_tti_request_srs_pdu(nfapi_nr_srs_pdu_t *srs_pdu, uint8_t
|
||||
push16(srs_pdu->t_srs, ppWritePackedMsg, end) &&
|
||||
push16(srs_pdu->t_offset, ppWritePackedMsg, end)
|
||||
// TODO: ignoring beamforming tlv for now
|
||||
);
|
||||
)){
|
||||
return 0;
|
||||
}
|
||||
// Rx Beamforming PDU
|
||||
if(!(push16(srs_pdu->beamforming.num_prgs,ppWritePackedMsg,end) &&
|
||||
push16(srs_pdu->beamforming.prg_size,ppWritePackedMsg,end) &&
|
||||
push8(srs_pdu->beamforming.dig_bf_interface,ppWritePackedMsg,end))){
|
||||
return 0;
|
||||
}
|
||||
for(int prg = 0; prg < srs_pdu->beamforming.num_prgs; prg ++){
|
||||
for(int digInt = 0; digInt < srs_pdu->beamforming.dig_bf_interface; digInt++){
|
||||
if(!push16(srs_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx,ppWritePackedMsg,end)){
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static uint8_t pack_ul_config_request_ulsch_pdu(nfapi_ul_config_ulsch_pdu *ulsch_pdu, uint8_t **ppWritePackedMsg, uint8_t *end) {
|
||||
@@ -2002,6 +2017,7 @@ static uint8_t pack_hi_dci0_request(void *msg, uint8_t **ppWritePackedMsg, uint8
|
||||
static uint8_t pack_tx_data_pdu_list_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
|
||||
{
|
||||
nfapi_nr_pdu_t *value = (nfapi_nr_pdu_t *)tlv;
|
||||
AssertFatal(value->PDU_length <= 0xFFFF,"TX_DATA.request PDU_Length should be within 16 bit, according to SCF222.10.02");
|
||||
if (!(push16(value->PDU_length, ppWritePackedMsg, end) && push16(value->PDU_index, ppWritePackedMsg, end)
|
||||
&& push32(value->num_TLV, ppWritePackedMsg, end)))
|
||||
return 0;
|
||||
@@ -3153,6 +3169,7 @@ return 1;
|
||||
|
||||
static uint8_t pack_nr_rx_data_indication_body(nfapi_nr_rx_data_pdu_t *value, uint8_t **ppWritePackedMsg, uint8_t *end)
|
||||
{
|
||||
AssertFatal(value->pdu_length <= 0xFFFF,"RX_DATA.indication PDU_Length should be within 16 bit, according to SCF222.10.02");
|
||||
if(!(push32(value->handle, ppWritePackedMsg, end) &&
|
||||
push16(value->rnti, ppWritePackedMsg, end) &&
|
||||
push8(value->harq_id, ppWritePackedMsg, end) &&
|
||||
@@ -5886,7 +5903,7 @@ static uint8_t unpack_hi_dci0_request(uint8_t **ppReadPackedMsg, uint8_t *end, v
|
||||
static uint8_t unpack_tx_data_pdu_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg) {
|
||||
nfapi_nr_pdu_t *pNfapiMsg = (nfapi_nr_pdu_t *)msg;
|
||||
|
||||
if(!(pull16(ppReadPackedMsg, &pNfapiMsg->PDU_length, end) &&
|
||||
if(!(pull16(ppReadPackedMsg, (uint16_t *)&pNfapiMsg->PDU_length, end) &&
|
||||
pull16(ppReadPackedMsg, &pNfapiMsg->PDU_index, end) &&
|
||||
pull32(ppReadPackedMsg, &pNfapiMsg->num_TLV, end)
|
||||
))
|
||||
@@ -5939,13 +5956,6 @@ static uint8_t unpack_tx_data_request(uint8_t **ppReadPackedMsg, uint8_t *end, v
|
||||
|
||||
for (int i = 0; i < pNfapiMsg->Number_of_PDUs; i++) {
|
||||
if (!unpack_tx_data_pdu_list_value(ppReadPackedMsg, end, &pNfapiMsg->pdu_list[i])) {
|
||||
printf("%s():%d. Error packing TX_DATA.request PDU #%d, PDU length = %d PDU IDX = %d\n",
|
||||
__FUNCTION__,
|
||||
__LINE__,
|
||||
i,
|
||||
pNfapiMsg->pdu_list[i].PDU_length,
|
||||
pNfapiMsg->pdu_list[i].PDU_index);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -6065,7 +6075,7 @@ static uint8_t unpack_nr_rx_data_indication_body(nfapi_nr_rx_data_pdu_t *value,
|
||||
nfapi_p7_codec_config_t *config)
|
||||
{
|
||||
if (!(pull32(ppReadPackedMsg, &value->handle, end) && pull16(ppReadPackedMsg, &value->rnti, end)
|
||||
&& pull8(ppReadPackedMsg, &value->harq_id, end) && pull16(ppReadPackedMsg, &value->pdu_length, end)
|
||||
&& pull8(ppReadPackedMsg, &value->harq_id, end) && pull16(ppReadPackedMsg, (uint16_t *)&value->pdu_length, end)
|
||||
&& pull8(ppReadPackedMsg, &value->ul_cqi, end) && pull16(ppReadPackedMsg, &value->timing_advance, end)
|
||||
&& pull16(ppReadPackedMsg, &value->rssi, end)))
|
||||
return 0;
|
||||
|
||||
@@ -2040,8 +2040,10 @@ int pnf_read_dispatch_message(pnf_t* pnf)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF Failed to unpack p5 message header\n");
|
||||
return 0;
|
||||
}
|
||||
message_size = header.message_length;
|
||||
}else{
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF Unpack p5 message header success\n");
|
||||
}
|
||||
message_size = header.message_length+header_buffer_size;
|
||||
|
||||
// now have the size of the mesage
|
||||
}
|
||||
@@ -2206,7 +2208,7 @@ int pnf_nr_read_dispatch_message(pnf_t* pnf)
|
||||
// print the received message
|
||||
printf("\n MESSAGE RECEIVED: \n");
|
||||
for(int i=0; i<message_size; i++){
|
||||
printf("%d", read_buffer[i]);
|
||||
printf("read_buffer[%d] = 0x%02x\n",i, read_buffer[i]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
@@ -27,7 +27,11 @@
|
||||
#include "vnf.h"
|
||||
#include "nfapi_nr_interface.h"
|
||||
#include "nfapi_nr_interface_scf.h"
|
||||
|
||||
#ifdef ENABLE_AERIAL
|
||||
#include "nfapi/oai_integration/aerial/fapi_nvIPC.h"
|
||||
#include "nfapi/oai_integration/aerial/fapi_vnf_p5.h"
|
||||
#endif
|
||||
#include "nfapi/oai_integration/vendor_ext.h"
|
||||
|
||||
void* vnf_malloc(nfapi_vnf_config_t* config, size_t size)
|
||||
{
|
||||
@@ -1520,20 +1524,45 @@ int vnf_nr_pack_and_send_p5_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_mes
|
||||
if(pnf)
|
||||
{
|
||||
// pack the message for transmission
|
||||
int packedMessageLength = nfapi_nr_p5_message_pack(msg, msg_len, vnf->tx_message_buffer, sizeof(vnf->tx_message_buffer), &vnf->_public.codec_config);
|
||||
int packedMessageLength = 0;
|
||||
if (NFAPI_MODE == NFAPI_MODE_AERIAL) {
|
||||
#ifdef ENABLE_AERIAL
|
||||
// In case it is a FAPI message, create 2 messages, one with nFAPI header for OAI PNF and one with no nFAPI header for Aerial
|
||||
// L1
|
||||
nfapi_p4_p5_message_header_t *msgFAPI = calloc(1, msg_len);
|
||||
memcpy(msgFAPI, msg, msg_len);
|
||||
// create FAPI tx_buffer
|
||||
uint8_t tx_messagebufferFAPI[sizeof(vnf->tx_message_buffer)];
|
||||
int packedMessageLengthFAPI = -1;
|
||||
packedMessageLengthFAPI =
|
||||
fapi_nr_p5_message_pack(msgFAPI, msg_len, tx_messagebufferFAPI, sizeof(tx_messagebufferFAPI), &vnf->_public.codec_config);
|
||||
return aerial_send_P5_msg(tx_messagebufferFAPI, packedMessageLengthFAPI, msg);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
} else {
|
||||
packedMessageLength = nfapi_nr_p5_message_pack(msg,
|
||||
msg_len,
|
||||
vnf->tx_message_buffer,
|
||||
sizeof(vnf->tx_message_buffer),
|
||||
&vnf->_public.codec_config);
|
||||
|
||||
if (packedMessageLength < 0) {
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi_p5_message_pack failed with return %d\n", packedMessageLength);
|
||||
return -1;
|
||||
}
|
||||
// printf("msg id = 0x%02x, entire message length: %d\n", msg->message_id, packedMessageLength);
|
||||
// for (int i = 0; i < packedMessageLength; i++) {
|
||||
// printf(" msg->msg_buf[%d] = 0x%02x\n", i, ((uint8_t *) vnf->tx_message_buffer)[i]);
|
||||
// }
|
||||
|
||||
return vnf_send_p5_msg(pnf, vnf->tx_message_buffer, packedMessageLength, 0);
|
||||
}
|
||||
} else {
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() cannot find pnf info for p5_idx:%d\n", __FUNCTION__, p5_idx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (packedMessageLength < 0)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi_p5_message_pack failed with return %d\n", packedMessageLength);
|
||||
return -1;
|
||||
}
|
||||
return vnf_send_p5_msg(pnf, vnf->tx_message_buffer, packedMessageLength, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() cannot find pnf info for p5_idx:%d\n", __FUNCTION__, p5_idx);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -25,7 +25,9 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef ENABLE_AERIAL
|
||||
#include "nfapi/oai_integration/aerial/fapi_nvIPC.h"
|
||||
#endif
|
||||
#include "vnf_p7.h"
|
||||
|
||||
#ifdef NDEBUG
|
||||
|
||||
Reference in New Issue
Block a user