Merge remote-tracking branch 'origin/fapi-stop-exchange' into integration_2025_w48 (!3561)

Implementation of STOP exchange

This implements the STOP.request/indication for all 3 transport mechanisms, the
VNF will send the STOP.request to the PNF, indicating it will disconnect, and
await a STOP.indication from the PNF

The WLS VNF is reworked to be able to start before the PNF, by calling call
rte_eal_init and rte_dev_probe to determine if dpdk has been initialized
properly, before calling rte_eal_init in the intended process when it is
appropriate to do so
This commit is contained in:
Jaroslava Fiedlerova
2025-11-27 15:01:39 +01:00
29 changed files with 525 additions and 136 deletions
+113 -41
View File
@@ -70,10 +70,25 @@
#endif
#define TEST
static nfapi_vnf_config_t *config;
extern RAN_CONTEXT_t RC;
extern UL_RCC_IND_t UL_RCC_INFO;
nfapi_vnf_config_t * get_config()
{
return config;
}
vnf_p7_t *get_p7_vnf()
{
vnf_info *vnf = config->user_data;
return (vnf_p7_t *)vnf->p7_vnfs->config;
}
nfapi_vnf_p7_config_t *get_p7_vnf_config()
{
return &get_p7_vnf()->_public;
}
int vnf_pack_vendor_extension_tlv(void *ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *codec) {
//NFAPI_TRACE(NFAPI_TRACE_INFO, "vnf_pack_vendor_extension_tlv\n");
nfapi_tl_t *tlv = (nfapi_tl_t *)ve;
@@ -1251,7 +1266,6 @@ void *configure_nr_p7_vnf(void *ptr)
p7_vnf->config->hdr_unpack_func = &fapi_nr_p7_message_header_unpack;
p7_vnf->config->pack_func = &fapi_nr_p7_message_pack;
p7_vnf->config->send_p7_msg = &wls_vnf_nr_send_p7_message;
wls_vnf_set_p7_config(p7_vnf->config);
#endif
#ifdef ENABLE_SOCKET
@@ -1645,32 +1659,86 @@ void vnf_start_thread(void *ptr) {
nfapi_vnf_start((nfapi_vnf_config_t *)ptr);
}
static vnf_info vnf;
static bool has_stop_ind = false;
static bool waiting_stop_ind = false;
int nr_stop_ind_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_stop_indication_scf_t *resp)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Received NFAPI_STOP_IND idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id);
has_stop_ind = true;
#ifdef ENABLE_AERIAL
nvIPC_Stop();
#endif
#ifdef ENABLE_SOCKET
nfapi_vnf_p7_stop(get_p7_vnf_config());
#endif
#ifdef ENABLE_WLS
wls_vnf_stop();
#endif
if (!waiting_stop_ind) {
// hasn't been initialized yet, means the PNF stopped before the VNF did
// raise a SIGINT to stop the VNF
raise(SIGINT);
}
return 0;
}
void stop_nr_nfapi_vnf()
{
if (has_stop_ind) {
// If it got here with the STOP.indication flag already set, it means it was triggered by the PNF,
// no need to send a STOP.request
return;
}
#ifdef ENABLE_WLS
wls_vnf_send_stop_request();
#endif
#ifdef ENABLE_AERIAL
nvIPC_send_stop_request();
#endif
#ifdef ENABLE_SOCKET
socket_nfapi_send_stop_request((vnf_t *)config);
#endif
waiting_stop_ind = true;
uint64_t counter = 0;
vnf_p7_t *p7_vnf = get_p7_vnf();
while (p7_vnf->terminate == 0 && counter < 50) {
NFAPI_TRACE(NFAPI_TRACE_DEBUG, "Not terminated yet, counter %ld\n", counter);
usleep(1000);
counter++;
}
if (p7_vnf->terminate == 0) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "STOP.indication timed out, exiting\n");
nfapi_nr_stop_indication_scf_t msg = {.header.message_id = NFAPI_NR_PHY_MSG_TYPE_STOP_INDICATION, .header.phy_id = 0};
config->nr_stop_ind(config, 0, &msg);
} else {
NFAPI_TRACE(NFAPI_TRACE_DEBUG, "Terminated, exiting\n");
}
}
void configure_nr_nfapi_vnf(eth_params_t params)
{
#ifndef ENABLE_AERIAL
nfapi_setmode(NFAPI_MODE_VNF);
#endif
memset(&vnf, 0, sizeof(vnf));
memset(vnf.p7_vnfs, 0, sizeof(vnf.p7_vnfs));
vnf.p7_vnfs[0].timing_window = 30;
vnf.p7_vnfs[0].periodic_timing_enabled = 0;
vnf.p7_vnfs[0].aperiodic_timing_enabled = 0;
vnf.p7_vnfs[0].periodic_timing_period = 1;
vnf.p7_vnfs[0].config = nfapi_vnf_p7_config_create();
vnf_info *vnf = calloc(1, sizeof(vnf_info));
memset(vnf->p7_vnfs, 0, sizeof(vnf->p7_vnfs));
vnf->p7_vnfs[0].timing_window = 30;
vnf->p7_vnfs[0].periodic_timing_enabled = 0;
vnf->p7_vnfs[0].aperiodic_timing_enabled = 0;
vnf->p7_vnfs[0].periodic_timing_period = 1;
vnf->p7_vnfs[0].config = nfapi_vnf_p7_config_create();
#ifndef ENABLE_AERIAL
NFAPI_TRACE(NFAPI_TRACE_INFO,
"[VNF] %s() vnf.p7_vnfs[0].config:%p VNF ADDRESS:%s:%d\n",
"[VNF] %s() vnf->p7_vnfs[0].config:%p VNF ADDRESS:%s:%d\n",
__FUNCTION__,
vnf.p7_vnfs[0].config,
vnf->p7_vnfs[0].config,
params.my_addr,
params.my_portc);
strcpy(vnf.p7_vnfs[0].local_addr, params.my_addr);
vnf.p7_vnfs[0].local_port = params.my_portd;
strcpy(vnf->p7_vnfs[0].local_addr, params.my_addr);
vnf->p7_vnfs[0].local_port = params.my_portd;
#endif
vnf.p7_vnfs[0].mac = (mac_t *)malloc(sizeof(mac_t));
nfapi_vnf_config_t *config = nfapi_vnf_config_create();
vnf->p7_vnfs[0].mac = malloc(sizeof(mac_t));
config = nfapi_vnf_config_create();
config->malloc = malloc;
config->free = free;
config->vnf_p5_port = params.my_portc;
@@ -1688,9 +1756,10 @@ void configure_nr_nfapi_vnf(eth_params_t params)
config->nr_param_resp = &nr_param_resp_cb;
config->nr_config_resp = &nr_config_resp_cb;
config->nr_start_resp = &nr_start_resp_cb;
config->nr_stop_ind = &nr_stop_ind_cb;
config->nr_error_ind = &nr_error_ind_cb;
config->vendor_ext = &vendor_nr_ext_cb;
config->user_data = &vnf;
config->user_data = vnf;
// To allow custom vendor extentions to be added to nfapi
config->codec_config.unpack_vendor_extension_tlv = &vnf_nr_unpack_vendor_extension_tlv;
config->codec_config.pack_vendor_extension_tlv = &vnf_nr_pack_vendor_extension_tlv;
@@ -1727,7 +1796,6 @@ void configure_nr_nfapi_vnf(eth_params_t params)
config->hdr_unpack_func = &fapi_nr_message_header_unpack;
config->pack_func = &fapi_nr_p5_message_pack;
config->send_p5_msg = &aerial_nr_send_p5_message;
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);
@@ -1736,7 +1804,6 @@ void configure_nr_nfapi_vnf(eth_params_t params)
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) {
@@ -1773,18 +1840,23 @@ void configure_nr_nfapi_vnf(eth_params_t params)
void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port) {
nfapi_setmode(NFAPI_MODE_VNF);
memset(&vnf, 0, sizeof(vnf));
memset(vnf.p7_vnfs, 0, sizeof(vnf.p7_vnfs));
vnf.p7_vnfs[0].timing_window = 32;
vnf.p7_vnfs[0].periodic_timing_enabled = 1;
vnf.p7_vnfs[0].aperiodic_timing_enabled = 0;
vnf.p7_vnfs[0].periodic_timing_period = 10;
vnf.p7_vnfs[0].config = nfapi_vnf_p7_config_create();
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] %s() vnf.p7_vnfs[0].config:%p VNF ADDRESS:%s:%d\n", __FUNCTION__, vnf.p7_vnfs[0].config, vnf_addr, vnf_p5_port);
strcpy(vnf.p7_vnfs[0].local_addr, vnf_addr);
vnf.p7_vnfs[0].local_port = vnf_p7_port;
vnf.p7_vnfs[0].mac = (mac_t *)malloc(sizeof(mac_t));
nfapi_vnf_config_t *config = nfapi_vnf_config_create();
vnf_info *vnf = calloc(1, sizeof(vnf_info));
memset(vnf->p7_vnfs, 0, sizeof(vnf->p7_vnfs));
vnf->p7_vnfs[0].timing_window = 32;
vnf->p7_vnfs[0].periodic_timing_enabled = 1;
vnf->p7_vnfs[0].aperiodic_timing_enabled = 0;
vnf->p7_vnfs[0].periodic_timing_period = 10;
vnf->p7_vnfs[0].config = nfapi_vnf_p7_config_create();
NFAPI_TRACE(NFAPI_TRACE_INFO,
"[VNF] %s() vnf.p7_vnfs[0].config:%p VNF ADDRESS:%s:%d\n",
__FUNCTION__,
vnf->p7_vnfs[0].config,
vnf_addr,
vnf_p5_port);
strcpy(vnf->p7_vnfs[0].local_addr, vnf_addr);
vnf->p7_vnfs[0].local_port = vnf_p7_port;
vnf->p7_vnfs[0].mac = malloc(sizeof(mac_t));
config = nfapi_vnf_config_create();
config->malloc = malloc;
config->free = free;
config->vnf_p5_port = vnf_p5_port;
@@ -1803,7 +1875,7 @@ void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port, char *pnf_ip_addr, int
config->config_resp = &config_resp_cb;
config->start_resp = &start_resp_cb;
config->vendor_ext = &vendor_ext_cb;
config->user_data = &vnf;
config->user_data = vnf;
// To allow custom vendor extentions to be added to nfapi
config->codec_config.unpack_vendor_extension_tlv = &vnf_unpack_vendor_extension_tlv;
config->codec_config.pack_vendor_extension_tlv = &vnf_pack_vendor_extension_tlv;
@@ -1820,7 +1892,7 @@ void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port, char *pnf_ip_addr, int
}
int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) {
nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config;
nfapi_vnf_p7_config_t *p7_config = get_p7_vnf_config();
dl_config_req->header.phy_id = 1; // HACK TODO FIXME - need to pass this around!!!!
dl_config_req->header.message_id = NFAPI_DL_CONFIG_REQUEST;
LOG_D(PHY, "[VNF] %s() DL_CONFIG_REQ sfn_sf:%d_%d number_of_pdus:%d\n", __FUNCTION__,
@@ -1856,7 +1928,7 @@ int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) {
int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req)
{
LOG_D(NR_PHY, "Entering oai_nfapi_nr_dl_config_req sfn:%d,slot:%d\n", dl_config_req->SFN, dl_config_req->Slot);
nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config;
nfapi_vnf_p7_config_t *p7_config = get_p7_vnf_config();
dl_config_req->header.message_id= NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST;
dl_config_req->header.phy_id = 1; // HACK TODO FIXME - need to pass this around!!!!
@@ -1875,7 +1947,7 @@ int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req)
int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req)
{
LOG_D(NR_PHY, "Entering oai_nfapi_nr_tx_data_req sfn:%d,slot:%d\n", tx_data_req->SFN, tx_data_req->Slot);
nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config;
nfapi_vnf_p7_config_t *p7_config = get_p7_vnf_config();
tx_data_req->header.phy_id = 1; // 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_req->sfn_sf), tx_req->tx_request_body.number_of_pdus);
@@ -1892,7 +1964,7 @@ int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req)
int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req)
{
nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config;
nfapi_vnf_p7_config_t *p7_config = get_p7_vnf_config();
tx_req->header.phy_id = 1; // HACK TODO FIXME - need to pass this around!!!!
tx_req->header.message_id = NFAPI_TX_REQUEST;
//LOG_D(PHY, "[VNF] %s() TX_REQ sfn_sf:%d number_of_pdus:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(tx_req->sfn_sf), tx_req->tx_request_body.number_of_pdus);
@@ -1908,7 +1980,7 @@ int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req)
}
int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req) {
nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config;
nfapi_vnf_p7_config_t *p7_config = get_p7_vnf_config();
ul_dci_req->header.phy_id = 1; // HACK TODO FIXME - need to pass this around!!!!
ul_dci_req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST;
//LOG_D(PHY, "[VNF] %s() HI_DCI0_REQ sfn_sf:%d dci:%d hi:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(hi_dci0_req->sfn_sf), hi_dci0_req->hi_dci0_request_body.number_of_dci, hi_dci0_req->hi_dci0_request_body.number_of_hi);
@@ -1924,7 +1996,7 @@ int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req) {
}
int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) {
nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config;
nfapi_vnf_p7_config_t *p7_config = get_p7_vnf_config();
hi_dci0_req->header.phy_id = 1; // HACK TODO FIXME - need to pass this around!!!!
hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST;
//LOG_D(PHY, "[VNF] %s() HI_DCI0_REQ sfn_sf:%d dci:%d hi:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(hi_dci0_req->sfn_sf), hi_dci0_req->hi_dci0_request_body.number_of_dci, hi_dci0_req->hi_dci0_request_body.number_of_hi);
@@ -1960,7 +2032,7 @@ static void remove_ul_config_req_pdu(int index, nfapi_ul_config_request_t *ul_co
}
int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req) {
nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config;
nfapi_vnf_p7_config_t *p7_config = get_p7_vnf_config();
ul_tti_req->header.phy_id = 1; // HACK TODO FIXME - need to pass this around!!!!
ul_tti_req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST;
@@ -1980,7 +2052,7 @@ int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req) {
}
int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) {
nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config;
nfapi_vnf_p7_config_t *p7_config = get_p7_vnf_config();
ul_config_req->header.phy_id = 1; // HACK TODO FIXME - need to pass this around!!!!
ul_config_req->header.message_id = NFAPI_UL_CONFIG_REQUEST;
//LOG_D(PHY, "[VNF] %s() header message_id:%02x\n", __FUNCTION__, ul_config_req->header.message_id);
@@ -2040,7 +2112,7 @@ int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) {
int oai_nfapi_ue_release_req(nfapi_ue_release_request_t *release_req){
if(release_req->ue_release_request_body.number_of_TLVs <= 0)
return 0;
nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config;
nfapi_vnf_p7_config_t *p7_config = get_p7_vnf_config();
release_req->header.phy_id = 1; // HACK TODO FIXME - need to pass this around!!!!
release_req->header.message_id = NFAPI_UE_RELEASE_REQUEST;