Fix NFAPI integration

This commit fixes issues introduced by the previous commit.

Summary of work:
- cleanup:
  - fix LOG_XX to be less verbose
  - fix cmake_targets/CMakeLists.txt
  - fix oaienv
  - remove dead code
- bug fixes:
  - in openair1/SCHED/fapi_l1.c we had:
      eNB->pdcch_vars[subframe&1].num_dci           = number_dci;
    should be:
      eNB->pdcch_vars[subframe&1].num_dci           = 0;
    This bug let the PHY send more DCIs than what should have been
    sent because num_dci is incremented later on in the code.
    This fix may be a problem for fapi mode, to be checked.
  - add new T VCD traces
  - revert openair1/PHY/TOOLS/file_output.c to 'develop' version
  - remove thread_id in logRecord/logRecord_mt
  - revert (and adapt) configuration files
  - be careful when doing frame++, we need to % 1024
  - revert target_rx_power in openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
- NFAPI:
  - the open-nFAPI code has been included in the repository. See nfapi/README.
    Maybe we should "git clone" the Cisco repository instead. We have to be
    careful of availability though.

What has been tested:
- monolithic eNB FDD 5/10MHz with one UE, iperf UDP/TCP uplink/downlink

Anything else may fail to work, especially the FAPI mode, which has not
been tested at all.
This commit is contained in:
Cedric Roux
2018-01-15 15:24:50 +01:00
parent 7757b9e7e7
commit 922b5b595a
102 changed files with 48002 additions and 481 deletions
+32
View File
@@ -0,0 +1,32 @@
#
# Copyright 2017 Cisco Systems, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
AUTOMAKE_OPTIONS=subdir-objects
AM_CPPFLAGS = -I$(top_srcdir)/pnf/inc -I$(top_srcdir)/pnf/public_inc -I$(top_srcdir)/nfapi/public_inc -I$(top_srcdir)/common/public_inc -g -Wall -Werror
noinst_LIBRARIES = libnfapi_pnf.a
libnfapi_pnf_a_SOURCES = src/pnf.c\
src/pnf_interface.c\
src/pnf_p7.c\
src/pnf_p7_interface.c
LDADD = -lsctp
+49
View File
@@ -0,0 +1,49 @@
/*
* Copyright 2017 Cisco Systems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _PNF_H_
#define _PNF_H_
#include "nfapi_pnf_interface.h"
#define NFAPI_MAX_PACKED_MESSAGE_SIZE 8192
typedef struct {
nfapi_pnf_config_t _public;
int p5_sock;
uint8_t tx_message_buffer[NFAPI_MAX_PACKED_MESSAGE_SIZE];
uint8_t sctp;
uint8_t terminate;
} pnf_t;
int pnf_connect(pnf_t *pnf);
int pnf_message_pump(pnf_t *pnf);
int pnf_pack_and_send_p5_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len);
int pnf_pack_and_send_p4_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len);
int pnf_send_message(pnf_t* pnf, uint8_t* msg, uint32_t msg_len, uint16_t stream_id);
nfapi_pnf_phy_config_t* nfapi_pnf_phy_config_find(nfapi_pnf_config_t* config, uint16_t phy_id);
#endif // _PNF_H_
+126
View File
@@ -0,0 +1,126 @@
/*
* Copyright 2017 Cisco Systems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _PNF_P7_H_
#define _PNF_P7_H_
#define TIMEHR_SEC(_time_hr) ((uint32_t)(_time_hr) >> 20)
#define TIMEHR_USEC(_time_hr) ((uint32_t)(_time_hr) & 0xFFFFF)
#define TIME2TIMEHR(_time) (((uint32_t)(_time.tv_sec) & 0xFFF) << 20 | ((uint32_t)(_time.tv_usec) & 0xFFFFF))
#include "nfapi_pnf_interface.h"
#define NFAPI_MAX_PACKED_MESSAGE_SIZE 8192
typedef struct {
uint16_t dl_conf_ontime;
uint16_t dl_conf_late;
uint16_t ul_conf_ontime;
uint16_t ul_conf_late;
uint16_t hi_dci0_ontime;
uint16_t hi_dci0_late;
uint16_t tx_ontime;
uint16_t tx_late;
} pnf_p7_stats_t;
typedef struct {
uint8_t* buffer;
uint16_t length;
} pnf_p7_rx_message_segment_t;
typedef struct pnf_p7_rx_message pnf_p7_rx_message_t;
typedef struct pnf_p7_rx_message {
uint8_t sequence_number;
uint8_t num_segments_received;
uint8_t num_segments_expected;
// the spec allows of upto 128 segments, this does seem excessive
pnf_p7_rx_message_segment_t segments[128];
uint32_t rx_hr_time;
pnf_p7_rx_message_t* next;
} pnf_p7_rx_message_t;
typedef struct {
pnf_p7_rx_message_t* msg_queue;
} pnf_p7_rx_reassembly_queue_t;
typedef struct {
nfapi_pnf_p7_config_t _public;
//private data
int p7_sock;
uint8_t terminate;
uint8_t tx_message_buffer[NFAPI_MAX_PACKED_MESSAGE_SIZE];
uint8_t* rx_message_buffer;
uint16_t rx_message_buffer_size;
pthread_mutex_t mutex; // should we allow the client to specifiy
pthread_mutex_t pack_mutex; // should we allow the client to specifiy
nfapi_pnf_p7_subframe_buffer_t subframe_buffer[30/*NFAPI_MAX_TIMING_WINDOW_SIZE*/];
uint32_t sequence_number;
uint16_t max_num_segments;
pnf_p7_rx_reassembly_queue_t reassembly_queue;
uint8_t* reassemby_buffer;
uint32_t reassemby_buffer_size;
uint16_t sfn_sf;
uint32_t sf_start_time_hr;
int32_t sfn_sf_shift;
uint8_t timing_info_period_counter;
uint8_t timing_info_aperiodic_send; // 0:false 1:true
uint32_t timing_info_ms_counter; // number of ms since last timing info
uint32_t dl_config_jitter;
uint32_t ul_config_jitter;
uint32_t hi_dci0_jitter;
uint32_t tx_jitter;
uint32_t tick;
pnf_p7_stats_t stats;
} pnf_p7_t;
int pnf_p7_message_pump(pnf_p7_t* pnf_p7);
int pnf_p7_pack_and_send_p7_message(pnf_p7_t* pnf_p7, nfapi_p7_message_header_t* msg, uint32_t msg_len);
int pnf_p7_send_message(pnf_p7_t* pnf_p7, uint8_t* msg, uint32_t msg_len);
int pnf_p7_subframe_ind(pnf_p7_t* config, uint16_t phy_id, uint16_t sfn_sf);
pnf_p7_rx_message_t* pnf_p7_rx_reassembly_queue_add_segment(pnf_p7_t* pnf_p7, pnf_p7_rx_reassembly_queue_t* queue, uint32_t rx_hr_time, uint16_t sequence_number, uint16_t segment_number, uint8_t m, uint8_t* data, uint16_t data_len);
void pnf_p7_rx_reassembly_queue_remove_msg(pnf_p7_t* pnf_p7, pnf_p7_rx_reassembly_queue_t* queue, pnf_p7_rx_message_t* msg);
void pnf_p7_rx_reassembly_queue_remove_old_msgs(pnf_p7_t* pnf_p7, pnf_p7_rx_reassembly_queue_t* queue, uint32_t rx_hr_time, uint32_t delta);
#endif /* _PNF_P7_H_ */
@@ -0,0 +1,803 @@
/*
* Copyright 2017 Cisco Systems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _NFAPI_PNF_INTERFACE_H_
#define _NFAPI_PNF_INTERFACE_H_
#if defined(__cplusplus)
extern "C" {
#endif
#include "nfapi_interface.h"
#include "debug.h"
#include <sys/types.h>
/*! This enum is used to describe the states of the pnf
*/
typedef enum
{
NFAPI_PNF_IDLE = 0,
NFAPI_PNF_CONFIGURED,
NFAPI_PNF_RUNNING
} nfapi_pnf_state_e;
/*! This enum is used to describe the states of a phy instance of a pnf
*/
typedef enum
{
NFAPI_PNF_PHY_IDLE = 0,
NFAPI_PNF_PHY_CONFIGURED = 1,
NFAPI_PNF_PHY_RUNNING = 2
} nfapi_pnf_phy_state_e;
typedef struct nfapi_pnf_phy_config nfapi_pnf_phy_config_t;
/*! Configuration information for a pnf phy instance
*/
typedef struct nfapi_pnf_phy_config
{
/*! The PHY id*/
uint16_t phy_id;
/*! The state of the PNF PHY instance*/
nfapi_pnf_phy_state_e state;
/*! Optional user defined data that will be passed back in the callbacks*/
void* user_data;
/*! Pointer for use in a linked list */
struct nfapi_pnf_phy_config* next;
} nfapi_pnf_phy_config_t;
typedef struct nfapi_pnf_config nfapi_pnf_config_t;
/*! Configuration information for the pnf created by calling nfapi_pnf_create
*/
typedef struct nfapi_pnf_config
{
/*! A user define callback to override the default memory allocation
* \param size The size of the data buffer to allocate
* \return A pointer to a data buffer
*/
void* (*malloc)(size_t size);
/*! A user define callback to override the default memory deallocation
* \param ptr Pointer to a data buffer to be deallocated
*/
void (*free)(void* ptr);
/*! A user define callback to handle trace from the pnf
* \param level The trace level
* \param message The trace string
*
* This is a vardic function.
*/
void (*trace)(nfapi_trace_level_t level, const char* message, ...);
/*! The ip address of the VNF
*
*/
char* vnf_ip_addr;
/*! The ip port of the VNF
*/
int vnf_p5_port;
/*! The state of the PNF */
nfapi_pnf_state_e state;
/*! List of PHY instances configured for this PNF */
nfapi_pnf_phy_config_t* phys;
/*! Configuation option of the p4 p5 encode decode functions */
nfapi_p4_p5_codec_config_t codec_config;
/*! Optional user defined data that will be passed back in the callbacks*/
void* user_data;
/*! A callback for the PNF_PARAM.request
* \param config A pointer to the pnf configuration
* \param req A data structure for the decoded PNF_PARAM.request. This will have
* been allocated on the stack
* \return not currently used
*
* The client is expected to send the PNF_PARAM.response after receiving the
* PNF_PARAM.request. This can be done in the call back.
*/
int (*pnf_param_req)(nfapi_pnf_config_t* config, nfapi_pnf_param_request_t* req);
/*! A callback for the PNF_CONFIG.request
* \param config A pointer to the pnf configuration
* \param req A data structure for the decoded PNF_CONFIG.request. This will have
* been allocated on the stack
* \return not currently used
*
* The client is expected to send the PNF_CONFIG.response after receiving the
* PNF_CONFIG.request. This can be done in the call back.
*/
int (*pnf_config_req)(nfapi_pnf_config_t* config, nfapi_pnf_config_request_t* req);
/*! A callback for the PNF_START.request
* \param config A pointer to the pnf configuration
* \param req A data structure for the decoded PNF_CONFIG.request. This will have
* been allocated on the stack
* \return not currently used
*
* The client is expected to send the PNF_START.response after receiving the
* PNF_START.request. This can be done in the call back.
*/
int (*pnf_start_req)(nfapi_pnf_config_t* config, nfapi_pnf_start_request_t* req);
/*! A callback for the PNF_STOP.request
* \param config A pointer to the pnf configuration
* \param req A data structure for the decoded PNF_STOP.request. This will have
* been allocated on the stack
* \return not currently used
*
* The client is expected to send the PNF_STOP.response after receiving the
* PNF_STOP.request. This can be done in the call back.
*/
int (*pnf_stop_req)(nfapi_pnf_config_t* config, nfapi_pnf_stop_request_t* req);
/*! A callback for the PARAM.request
* \param config A pointer to the pnf configuration
* \param phy A pointer to the pnf phy configuration
* \param req A data structure for the decoded PARAM.request. This will have
* been allocated on the stack
* \return not currently used
*
* The client is expected to send the PARAM.response after receiving the
* PARAM.request. This can be done in the call back.
*/
int (*param_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_param_request_t* req);
/*! A callback for the CONFIG.request
* \param config A pointer to the pnf configuration
* \param phy A pointer to the pnf phy configuration
* \param req A data structure for the decoded CONFIG.request. This will have
* been allocated on the stack
* \return not currently used
*
* The client is expected to send the CONFIG.response after receiving the
* CONFIG.request. This can be done in the call back.
*/
int (*config_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_config_request_t* req);
/*! A callback for the START.request
* \param config A pointer to the pnf configuration
* \param phy A pointer to the pnf phy configuration
* \param req A data structure for the decoded START.request. This will have
* been allocated on the stack
* \return not currently used
*
* The client is expected to send the START.response after the client has received the
* first subframe indication from FAPI.
*/
int (*start_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_start_request_t* req);
/*! A callback for the STOP.request
* \param config A pointer to the pnf configuration
* \param phy A pointer to the pnf phy configuration
* \param req A data structure for the decoded STOP.request. This will have
* been allocated on the stack
* \return not currently used
*
* The client is expected to send the STOP.response after receiving the
* STOP.request. This can be done in the call back.
*/
int (*stop_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_stop_request_t* req);
/*! A callback for the MEASUREMENT.request
* \param config A pointer to the pnf configuration
* \param phy A pointer to the pnf phy configuration
* \param req A data structure for the decoded MEASUREMENT.request. This will have
* been allocated on the stack
* \return not currently used
*
* The client is expected to send the MEASUREMENT.response after receiving the
* MEASUREMENT.request. This can be done in the call back.
*/
int (*measurement_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_measurement_request_t* req);
/*! A callback for the RSSI.request
* \param config A pointer to the pnf configuration
* \param phy A pointer to the pnf phy configuration
* \param req A data structure for the decoded RSSI.request. This will have
* been allocated on the stack
* \return not currently used
*
* The client is expected to send the RSSI.response after receiving the
* RSSI.request. This can be done in the call back.
*/
int (*rssi_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_rssi_request_t* req);
/*! A callback for the CELL_SEARCH.request
* \param config A pointer to the pnf configuration
* \param phy A pointer to the pnf phy configuration
* \param req A data structure for the decoded CELL_SEARCH.request. This will have
* been allocated on the stack
* \return not currently used
*
* The client is expected to send the CELL_SEARCH.response after receiving the
* CELL_SEARCH.request. This can be done in the call back.
*/
int (*cell_search_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_cell_search_request_t* req);
/*! A callback for the BROADCAST_DETECT.request
* \param config A pointer to the pnf configuration
* \param phy A pointer to the pnf phy configuration
* \param req A data structure for the decoded BROADCAST_DETECT.request. This will have
* been allocated on the stack
* \return not currently used
*
* The client is expected to send the BROADCAST_DETECT.response after receiving the
* BROADCAST_DETECT.request. This can be done in the call back.
*/
int (*broadcast_detect_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_broadcast_detect_request_t* req);
/*! A callback for the SYSTEM_INFORMATION_SCHEDULE.request
* \param config A pointer to the pnf configuration
* \param phy A pointer to the pnf phy configuration
* \param req A data structure for the decoded SYSTEM_INFORMATION_SCHEDULE.request. This will have
* been allocated on the stack
* \return not currently used
*
* The client is expected to send the SYSTEM_INFORMATION_SCHEDULE.response after receiving the
* SYSTEM_INFORMATION_SCHEDULE.request. This can be done in the call back.
*/
int (*system_information_schedule_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_system_information_schedule_request_t* req);
/*! A callback for the SYSTEM_INFORMATION.request
* \param config A pointer to the pnf configuration
* \param phy A pointer to the pnf phy configuration
* \param req A data structure for the decoded SYSTEM_INFORMATION.request. This will have
* been allocated on the stack
* \return not currently used
*
* The client is expected to send the SYSTEM_INFORMATION.response after receiving the
* SYSTEM_INFORMATION.request. This can be done in the call back.
*/
int (*system_information_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_system_information_request_t* req);
/*! A callback for the NMM_STOP.request
* \param config A pointer to the pnf configuration
* \param phy A pointer to the pnf phy configuration
* \param req A data structure for the decoded NMM_STOP.request. This will have
* been allocated on the stack
* \return not currently used
*
* The client is expected to send the NMM_STOP.response after receiving the
* NMM_STOP.request. This can be done in the call back.
*/
int (*nmm_stop_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_nmm_stop_request_t* req);
/*! A callback for any vendor extension messages recevied
* \param config A pointer to the pnf configuration
* \param msg A pointer to the decode P4/P5 message
* \return not current used
*/
int (*vendor_ext)(nfapi_pnf_config_t* config, nfapi_p4_p5_message_header_t* msg);
/*! A callback to allocate vendor extension message
* \param message_id The message id from the decode P4/P5 message header
* \param msg_size A pointer a the size of the allocated message structure. The callee should set this
* \return A pointer to a allocated P4/P5 message structure
*/
nfapi_p4_p5_message_header_t* (*allocate_p4_p5_vendor_ext)(uint16_t message_id, uint16_t* msg_size);
/*! A callback to deallocate vendor extension message
* \param header A pointer to an P4/P5 message structure
*/
void (*deallocate_p4_p5_vendor_ext)(nfapi_p4_p5_message_header_t* header);
} nfapi_pnf_config_t;
/*! Create a pnf configuration
* \return A pointer to a pnf configuration struture
*
* This function will create and initialize a pnf instance. It is expected that
* the client will set the callback and parameters need before calling nfapi_pnf_start
*
* 0 will be returned if it fails.
*
* \code
* nfapi_pnf_config_t* config = nfapi_pnf_config_create(void);
* \endcode
*/
nfapi_pnf_config_t* nfapi_pnf_config_create(void);
/*! Delete a pnf configuration
* \param config A pointer to a pnf configuraiton
* \return 0 is success, -1 for failure
*/
int nfapi_pnf_config_destroy(nfapi_pnf_config_t* config);
/*! Start the PNF library.
* \param config A pointer to the pnf configuration
* \return 0 is success, -1 for failure
*
* This function will not return until nfapi_pnf_stop is called
*
* \code
* // Create the pnf config
* nfapi_pnf_config_t* config = nfapi_pnf_config_create();
*
* // Assumed that the vnf_address and vnf_port are provided over the P9 interface
* config->vnf_ip_addr = vnf_address;
* config->vnf_p5_port = vnf_port;
*
* // Set the required callbacks
* config->pnf_param_req = &pnf_param_request;
* ...
*
* // Call start for the PNF to initiate a connection to the VNF
* nfai_pnf_start(config);
*
* \endcode
*/
int nfapi_pnf_start(nfapi_pnf_config_t* config);
/*! Stop the PNF library.
* \param config A pointer to the pnf configuration
* \return 0 is success, -1 for failure
*
* This function will cause the nfapi_pnf_start function to return
*/
int nfapi_pnf_stop(nfapi_pnf_config_t* config);
/*! Send the PNF_PARAM.response
* \param config A pointer to a pnf configuraiton
* \param resp A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_pnf_param_response_t* resp);
/*! Send the PNF_CONFIG.response
* \param config A pointer to a pnf configuraiton
* \param resp A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_pnf_config_response_t* resp);
/*! Send the PNF_START.response
* \param config A pointer to a pnf configuraiton
* \param resp A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_pnf_start_response_t* resp);
/*! Send the PNF_STOP.response
* \param config A pointer to a pnf configuraiton
* \param resp A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_pnf_stop_resp(nfapi_pnf_config_t* config, nfapi_pnf_stop_response_t* resp);
/*! Send the PARAM.response
* \param config A pointer to a pnf configuraiton
* \param resp A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_param_response_t* resp);
/*! Send the CONFIG.response
* \param config A pointer to a pnf configuraiton
* \param resp A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_config_response_t* resp);
/*! Send the START.response
* \param config A pointer to a pnf configuraiton
* \param resp A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_start_response_t* resp);
/*! Send the STOP.response
* \param config A pointer to a pnf configuraiton
* \param resp A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_stop_resp(nfapi_pnf_config_t* config, nfapi_stop_response_t* resp);
/*! Send the MEASUREMENT.response
* \param config A pointer to a pnf configuraiton
* \param resp A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_measurement_resp(nfapi_pnf_config_t* config, nfapi_measurement_response_t* resp);
/*! Send the RSSI.response
* \param config A pointer to a pnf configuraiton
* \param resp A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_rssi_resp(nfapi_pnf_config_t* config, nfapi_rssi_response_t* resp);
/*! Send the RSSI.indication
* \param config A pointer to a pnf configuraiton
* \param ind A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_rssi_ind(nfapi_pnf_config_t* config, nfapi_rssi_indication_t* ind);
/*! Send the CELL_SEARCH.response
* \param config A pointer to a pnf configuraiton
* \param resp A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_cell_search_resp(nfapi_pnf_config_t* config, nfapi_cell_search_response_t* resp);
/*! Send the CELL_SEARCH.indication
* \param config A pointer to a pnf configuraiton
* \param ind A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_cell_search_ind(nfapi_pnf_config_t* config, nfapi_cell_search_indication_t* ind);
/*! Send the BROADCAST_DETECT.response
* \param config A pointer to a pnf configuraiton
* \param resp A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_broadcast_detect_resp(nfapi_pnf_config_t* config, nfapi_broadcast_detect_response_t* resp);
/*! Send the BROADCAST_DETECT.indication
* \param config A pointer to a pnf configuraiton
* \param ind A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_broadcast_detect_ind(nfapi_pnf_config_t* config, nfapi_broadcast_detect_indication_t* ind);
/*! Send the SYSTEM_INFORMATION_SCHEDULE.response
* \param config A pointer to a pnf configuraiton
* \param resp A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_system_information_schedule_resp(nfapi_pnf_config_t* config, nfapi_system_information_schedule_response_t* resp);
/*! Send the SYSTEM_INFORMATION_SCHEDULE.indication
* \param config A pointer to a pnf configuraiton
* \param ind A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_system_information_schedule_ind(nfapi_pnf_config_t* config, nfapi_system_information_schedule_indication_t* ind);
/*! Send the SYSTEM_INFORMATION.response
* \param config A pointer to a pnf configuraiton
* \param resp A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_system_information_resp(nfapi_pnf_config_t* config, nfapi_system_information_response_t* resp);
/*! Send the SYSTEM_INFORMATION.indication
* \param config A pointer to a pnf configuraiton
* \param ind A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_system_information_ind(nfapi_pnf_config_t* config, nfapi_system_information_indication_t* ind);
/*! Send the NMM_STOP.response
* \param config A pointer to a pnf configuraiton
* \param resp A pointer to the message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_nmm_stop_resp(nfapi_pnf_config_t* config, nfapi_nmm_stop_response_t* resp);
/*! Send a vendor extension message
* \param config A pointer to a pnf configuraiton
* \param msg A pointer to the vendor extention message structure
* \param msg_len The size of the vendor extention message structure
* \return 0 for success, -1 for failure
*
*/
int nfapi_pnf_vendor_extension(nfapi_pnf_config_t* config, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len);
//--------------------------
/*! A subframe buffer structure which can be used by the client to
* to configure the dummy information
*/
typedef struct
{
uint16_t sfn_sf;
nfapi_dl_config_request_t* dl_config_req;
nfapi_ul_config_request_t* ul_config_req;
nfapi_hi_dci0_request_t* hi_dci0_req;
nfapi_tx_request_t* tx_req;
nfapi_lbt_dl_config_request_t* lbt_dl_config_req;
} nfapi_pnf_p7_subframe_buffer_t;
typedef struct nfapi_pnf_p7_config nfapi_pnf_p7_config_t;
/*! The nfapi PNF PHY P7 configuration information created using the nfapi_pnf_p7_create function
*/
typedef struct nfapi_pnf_p7_config
{
/*! A user define callback to override the default memory allocation
* \param size The size of the buffer to allocate
* \return An allocated buffer. 0 in the case of failure
*
* If not set malloc will be used
*/
void* (*malloc)(size_t size);
/*! A user define callback to override the default memory deallocation
* \param ptr Pointer to a buffer to dellocate
*
* If not set free will be used
*/
void (*free)(void* ptr);
/*! A user define callback to handle trace from the pnf
* \param level The trace level
* \param message The message string
*/
void (*trace)(nfapi_trace_level_t level, const char* message, ...);
/*! The PHY id*/
uint16_t phy_id;
// remote
/*! The VNF P7 UDP port */
int remote_p7_port;
/*! The VNF P7 UDP address */
char* remote_p7_addr;
// local
/*! The PNF P7 UDP port */
int local_p7_port;
/*! The PNF P7 UDP address */
char* local_p7_addr;
/*! Flag to indicate of the pnf should use the P7 checksum */
uint8_t checksum_enabled;
/*! The maxium size of a P7 segement. If a message is large that this it
* will be segemented */
uint16_t segment_size;
/*! The dummy subframe buffer structure that should be used in case there
* are no 'valid' subframe messages */
nfapi_pnf_p7_subframe_buffer_t dummy_subframe;
/*! Configuration options for the p7 pack unpack functions*/
nfapi_p7_codec_config_t codec_config;
/*! Optional userdata that will be passed back in the callbacks*/
void* user_data;
// tdb : if these should be public
uint16_t subframe_buffer_size;
uint8_t timing_info_mode_periodic; // 0:false 1:true
uint8_t timing_info_mode_aperiodic; // 0:false 1:true
uint8_t timing_info_period; // 1..225 in subframes
/*! A callback for the DL_CONFIG.request
* \param config A poiner to the PNF P7 config
* \param req A pointer to the dl config request message structure
* \return not currently used
*/
int (*dl_config_req)(nfapi_pnf_p7_config_t* config, nfapi_dl_config_request_t* req);
/*! A callback for the UL_CONFIG.request
* \param config A poiner to the PNF P7 config
* \param req A pointer to the ul config request message structure
* \return not currently used
*/
int (*ul_config_req)(nfapi_pnf_p7_config_t* config, nfapi_ul_config_request_t* req);
/*! A callback for the HI_DCI0.request
* \param config A poiner to the PNF P7 config
* \param req A pointer to the hi dci0 request message structure
* \return not currently used
*/
int (*hi_dci0_req)(nfapi_pnf_p7_config_t* config, nfapi_hi_dci0_request_t* req);
/*! A callback for the TX_REQ.request
* \param config A poiner to the PNF P7 config
* \param req A pointer to the tx request message structure
* \return not currently used
*
* The TX request contains pointers to the downlink PDUs to be sent. In the case that the FAPI interface
* will 'keep' the pointers until they are transmitted the callee should set the pointers in the req to 0
* and then use the p7 codec config free function to release the pdu's when appropriate.
*/
int (*tx_req)(nfapi_pnf_p7_config_t* config, nfapi_tx_request_t* req);
/*! A callback for the LBT_DL_CONFIG.request
* \param config A poiner to the PNF P7 config
* \param req A pointer to the lbt dl request message structure
* \return not currently used
*/
int (*lbt_dl_config_req)(nfapi_pnf_p7_config_t* config, nfapi_lbt_dl_config_request_t* req);
/*! A callback for vendor extension messages
* \param config A poiner to the PNF P7 config
* \param msg A pointer to a decode vendor extention message
* \return not currently used
*/
int (*vendor_ext)(nfapi_pnf_p7_config_t* config, nfapi_p7_message_header_t* msg);
/*! A callback to allocate vendor extension message
* \param message_id The vendor extention message id from the decode message header
* \param msg_size A pointer to size of the allocate vendor extention message. Set by the callee
* \return A pointer to an allocated vendor extention message structure. 0 if failed
*
*
*/
nfapi_p7_message_header_t* (*allocate_p7_vendor_ext)(uint16_t message_id, uint16_t* msg_size);
/*! A callback to deallocate vendor extension message
* \param header A pointer to a p7 vendor extention message
*/
void (*deallocate_p7_vendor_ext)(nfapi_p7_message_header_t* header);
} nfapi_pnf_p7_config_t;
/*! Create and initialise a nfapi_pnf_p7_config structure
* \return A pointer to a PNF P7 config structure
*/
nfapi_pnf_p7_config_t* nfapi_pnf_p7_config_create(void);
/*! Delete an nfapi_pnf_p7_config structure
* \param config
*/
int nfapi_pnf_p7_config_destroy(nfapi_pnf_p7_config_t* config);
/*! Start the PNF P7 library.
* \param config A pointer to a PNF P7 config
* \return 0 means success, -1 means failure
*
* This function will not return until nfapi_pnf_p7_stop is called.
*/
int nfapi_pnf_p7_start(nfapi_pnf_p7_config_t* config);
/*! Stop the PNF P7 library.
* \param config A pointer to a PNF P7 config
* \return 0 means success, -1 means failure
*
* This function will cause the nfapi_pnf_p7_start to return
*/
int nfapi_pnf_p7_stop(nfapi_pnf_p7_config_t* config);
/*! Subframe indication
* \param config A pointer to a PNF P7 config
* \param phy_id The phy_id for the phy instance
* \param sfn_sf The SFN and SF in the format of FAPI
* \return 0 means success, -1 means failure
*
* The client should call the subframe indication every 1ms. The PNF will
* respond by invoking the pnf p7 subframe callbacks with the messages from the subframe buffer
*
* If messages are not in the subframe buffer, they dummy subframe messages will be sent
*/
int nfapi_pnf_p7_subframe_ind(nfapi_pnf_p7_config_t* config, uint16_t phy_id, uint16_t sfn_sf);
/*! Send the HARQ.indication
* \param config A pointer to a PNF P7 config
* \param ind A pointer to the harq indication message structure
* \return 0 means success, -1 means failure
*/
int nfapi_pnf_p7_harq_ind(nfapi_pnf_p7_config_t* config, nfapi_harq_indication_t* ind);
/*! Send the CRC.indication
* \param config A pointer to a PNF P7 config
* \param ind A pointer to the crc indication message structure
* \return 0 means success, -1 means failure
*/
int nfapi_pnf_p7_crc_ind(nfapi_pnf_p7_config_t* config, nfapi_crc_indication_t* ind);
/*! Send the RX.indication
* \param config A pointer to a PNF P7 config
* \param ind A pointer to the rx indication message structure
* \return 0 means success, -1 means failure
*/
int nfapi_pnf_p7_rx_ind(nfapi_pnf_p7_config_t* config, nfapi_rx_indication_t* ind);
/*! Send the RACH.indication
* \param config A pointer to a PNF P7 config
* \param ind A pointer to the rach indication message structure
* \return 0 means success, -1 means failure
*/
int nfapi_pnf_p7_rach_ind(nfapi_pnf_p7_config_t* config, nfapi_rach_indication_t* ind);
/*! Send the SRS.indication
* \param config A pointer to a PNF P7 config
* \param ind A pointer to the srs indication message structure
* \return 0 means success, -1 means failure
*/
int nfapi_pnf_p7_srs_ind(nfapi_pnf_p7_config_t* config, nfapi_srs_indication_t* ind);
/*! Send the SR.indication
* \param config A pointer to a PNF P7 config
* \param ind A pointer to the sr indication message structure
* \return 0 means success, -1 means failure
*/
int nfapi_pnf_p7_sr_ind(nfapi_pnf_p7_config_t* config, nfapi_sr_indication_t* ind);
/*! Send the CQI.indication
* \param config A pointer to a PNF P7 config
* \param ind A pointer to the cqi indication message structure
* \return 0 means success, -1 means failure
*/
int nfapi_pnf_p7_cqi_ind(nfapi_pnf_p7_config_t* config, nfapi_cqi_indication_t* ind);
/*! Send the LBT_DL.indication
* \param config A pointer to a PNF P7 config
* \param ind A pointer to the lbt dl indication message structure
* \return 0 means success, -1 means failure
*/
int nfapi_pnf_p7_lbt_dl_ind(nfapi_pnf_p7_config_t* config, nfapi_lbt_dl_indication_t* ind);
/*! Send the NB_HARQ.indication
* \param config A pointer to a PNF P7 config
* \param ind A pointer to the lbt dl indication message structure
* \return 0 means success, -1 means failure
*/
int nfapi_pnf_p7_nb_harq_ind(nfapi_pnf_p7_config_t* config, nfapi_nb_harq_indication_t* ind);
/*! Send the NRACH.indication
* \param config A pointer to a PNF P7 config
* \param ind A pointer to the lbt dl indication message structure
* \return 0 means success, -1 means failure
*/
int nfapi_pnf_p7_nrach_ind(nfapi_pnf_p7_config_t* config, nfapi_nrach_indication_t* ind);
/*! Send a vendor exntesion message
* \param config A pointer to a PNF P7 config
* \param msg A pointer to the lbt dl indication message structure
* \return 0 means success, -1 means failure
*/
int nfapi_pnf_p7_vendor_extension(nfapi_pnf_p7_config_t* config, nfapi_p7_message_header_t* msg);
#if defined(__cplusplus)
}
#endif
#endif // _NFAPI_PNF_INTERFACE_H_
File diff suppressed because it is too large Load Diff
+432
View File
@@ -0,0 +1,432 @@
/*
* Copyright 2017 Cisco Systems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "pnf.h"
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
nfapi_pnf_config_t* nfapi_pnf_config_create()
{
pnf_t* _this = (pnf_t*)malloc(sizeof(pnf_t));
if(_this == 0)
return 0;
memset(_this, 0, sizeof(pnf_t));
_this->sctp = 1; // enable sctp
_this->_public.vnf_p5_port = NFAPI_P5_SCTP_PORT;
_this->_public.malloc = &malloc;
_this->_public.free = &free;
_this->_public.codec_config.allocate = &malloc;
_this->_public.codec_config.deallocate = &free;
return &(_this->_public);
}
void nfapi_pnf_config_destory(nfapi_pnf_config_t* config)
{
free(config);
}
int nfapi_pnf_start(nfapi_pnf_config_t* config)
{
// Verify that config is not null
if(config == 0)
return -1;
// Make sure to set the defined trace function before using NFAPI_TRACE
if(config->trace)
nfapi_trace_g = config->trace;
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
pnf_t* _this = (pnf_t*)(config);
while (_this->terminate == 0)
{
int connect_result = pnf_connect(_this);
if(connect_result > 0)
{
pnf_message_pump(_this);
}
else if(connect_result < 0)
{
return connect_result;
}
sleep(1);
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() terminate=1 - EXITTING............\n", __FUNCTION__);
return 0;
}
int nfapi_pnf_stop(nfapi_pnf_config_t* config)
{
// Verify that config is not null
if(config == 0)
return -1;
pnf_t* _this = (pnf_t*)(config);
_this->terminate = 1;
// todo wait for the pnf to stop before returning
return 0;
}
int nfapi_pnf_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_pnf_param_response_t* resp)
{
// ensure it's valid
if (config == NULL || resp == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
return -1;
}
pnf_t* _this = (pnf_t*)(config);
return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_pnf_param_response_t));
}
int nfapi_pnf_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_pnf_config_response_t* resp)
{
// ensure it's valid
if (config == NULL || resp == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
return -1;
}
if(resp->error_code == NFAPI_MSG_OK)
{
config->state = NFAPI_PNF_CONFIGURED;
}
pnf_t* _this = (pnf_t*)(config);
return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_pnf_config_response_t));
}
int nfapi_pnf_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_pnf_start_response_t* resp)
{
// ensure it's valid
if (config == NULL || resp == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
return -1;
}
if(resp->error_code == NFAPI_MSG_OK)
{
config->state = NFAPI_PNF_RUNNING;
}
pnf_t* _this = (pnf_t*)(config);
return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_pnf_start_response_t));
}
int nfapi_pnf_pnf_stop_resp(nfapi_pnf_config_t* config, nfapi_pnf_stop_response_t* resp)
{
// ensure it's valid
if (config == NULL || resp == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
return -1;
}
if(resp->error_code == NFAPI_MSG_OK)
{
config->state = NFAPI_PNF_CONFIGURED;
}
pnf_t* _this = (pnf_t*)(config);
return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_pnf_stop_response_t));
}
int nfapi_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_param_response_t* resp)
{
if (config == NULL || resp == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
return -1;
}
pnf_t* _this = (pnf_t*)(config);
return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_param_response_t));
}
int nfapi_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_config_response_t* resp)
{
if (config == NULL || resp == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
return -1;
}
pnf_t* _this = (pnf_t*)(config);
nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, resp->header.phy_id);
if(phy)
{
if(resp->error_code == NFAPI_MSG_OK)
{
phy->state = NFAPI_PNF_PHY_CONFIGURED;
}
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: unknow phy id %d\n", __FUNCTION__, resp->header.phy_id);
return -1;
}
return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_config_response_t));
}
int nfapi_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_start_response_t* resp)
{
if (config == NULL || resp == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
return -1;
}
pnf_t* _this = (pnf_t*)(config);
nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, resp->header.phy_id);
if(phy)
{
if(resp->error_code == NFAPI_MSG_OK)
{
phy->state = NFAPI_PNF_PHY_RUNNING;
}
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: unknown phy id %d\n", __FUNCTION__, resp->header.phy_id);
return -1;
}
return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_start_response_t));
}
int nfapi_pnf_stop_resp(nfapi_pnf_config_t* config, nfapi_stop_response_t* resp)
{
if (config == NULL || resp == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
return -1;
}
pnf_t* _this = (pnf_t*)(config);
nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, resp->header.phy_id);
if(phy)
{
if(resp->error_code == NFAPI_MSG_OK)
{
phy->state = NFAPI_PNF_PHY_CONFIGURED;
}
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: unknow phy id %d\n", __FUNCTION__, resp->header.phy_id);
return -1;
}
return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_stop_response_t));
}
int nfapi_pnf_measurement_resp(nfapi_pnf_config_t* config, nfapi_measurement_response_t* resp)
{
if (config == NULL || resp == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
return -1;
}
pnf_t* _this = (pnf_t*)(config);
return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_measurement_response_t));
}
int nfapi_pnf_rssi_resp(nfapi_pnf_config_t* config, nfapi_rssi_response_t* resp)
{
if (config == NULL || resp == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
return -1;
}
pnf_t* _this = (pnf_t*)(config);
return pnf_pack_and_send_p4_message(_this, &(resp->header), sizeof(nfapi_rssi_response_t));
}
int nfapi_pnf_rssi_ind(nfapi_pnf_config_t* config, nfapi_rssi_indication_t* ind)
{
if (config == NULL || ind == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
return -1;
}
pnf_t* _this = (pnf_t*)(config);
return pnf_pack_and_send_p4_message(_this, &(ind->header), sizeof(nfapi_rssi_indication_t));
}
int nfapi_pnf_cell_search_resp(nfapi_pnf_config_t* config, nfapi_cell_search_response_t* resp)
{
if (config == NULL || resp == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
return -1;
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "Send CELL_SEARCH.response\n");
pnf_t* _this = (pnf_t*)(config);
return pnf_pack_and_send_p4_message(_this, &(resp->header), sizeof(nfapi_cell_search_response_t));
}
int nfapi_pnf_cell_search_ind(nfapi_pnf_config_t* config, nfapi_cell_search_indication_t* ind)
{
if (config == NULL || ind == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
return -1;
}
pnf_t* _this = (pnf_t*)(config);
return pnf_pack_and_send_p4_message(_this, &(ind->header), sizeof(nfapi_cell_search_indication_t));
}
int nfapi_pnf_broadcast_detect_resp(nfapi_pnf_config_t* config, nfapi_broadcast_detect_response_t* resp)
{
if (config == NULL || resp == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
return -1;
}
pnf_t* _this = (pnf_t*)(config);
return pnf_pack_and_send_p4_message(_this, &(resp->header), sizeof(nfapi_broadcast_detect_response_t));
}
int nfapi_pnf_broadcast_detect_ind(nfapi_pnf_config_t* config, nfapi_broadcast_detect_indication_t* ind)
{
if (config == NULL || ind == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
return -1;
}
pnf_t* _this = (pnf_t*)(config);
return pnf_pack_and_send_p4_message(_this, &(ind->header), sizeof(nfapi_broadcast_detect_indication_t));
}
int nfapi_pnf_system_information_schedule_resp(nfapi_pnf_config_t* config, nfapi_system_information_schedule_response_t* resp)
{
if (config == NULL || resp == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
return -1;;
}
pnf_t* _this = (pnf_t*)(config);
return pnf_pack_and_send_p4_message(_this, &(resp->header), sizeof(nfapi_system_information_schedule_response_t));
}
int nfapi_pnf_system_information_schedule_ind(nfapi_pnf_config_t* config, nfapi_system_information_schedule_indication_t* ind)
{
if (config == NULL || ind == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
return -1;
}
pnf_t* _this = (pnf_t*)(config);
return pnf_pack_and_send_p4_message(_this, &(ind->header), sizeof(nfapi_system_information_schedule_indication_t));
}
int nfapi_pnf_system_information_resp(nfapi_pnf_config_t* config, nfapi_system_information_response_t* resp)
{
if (config == NULL || resp == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
return -1;
}
pnf_t* _this = (pnf_t*)(config);
return pnf_pack_and_send_p4_message(_this, &(resp->header), sizeof(nfapi_system_information_response_t));
}
int nfapi_pnf_system_information_ind(nfapi_pnf_config_t* config, nfapi_system_information_indication_t* ind)
{
if (config == NULL || ind == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
return -1;
}
pnf_t* _this = (pnf_t*)(config);
return pnf_pack_and_send_p4_message(_this, &(ind->header), sizeof(nfapi_system_information_indication_t));
}
int nfapi_pnf_nmm_stop_resp(nfapi_pnf_config_t* config, nfapi_nmm_stop_response_t* resp)
{
// ensure it's valid
if (config == NULL || resp == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
return -1;
}
pnf_t* _this = (pnf_t*)(config);
return pnf_pack_and_send_p4_message(_this, &(resp->header), sizeof(nfapi_nmm_stop_request_t));
}
int nfapi_pnf_vendor_extension(nfapi_pnf_config_t* config, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len)
{
// ensure it's valid
if (config == NULL || msg == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
return -1;
}
pnf_t* _this = (pnf_t*)(config);
return pnf_pack_and_send_p5_message(_this, msg, msg_len);
}
File diff suppressed because it is too large Load Diff
+225
View File
@@ -0,0 +1,225 @@
/*
* Copyright 2017 Cisco Systems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "pnf_p7.h"
#include <stdlib.h>
#include <string.h>
nfapi_pnf_p7_config_t* nfapi_pnf_p7_config_create()
{
pnf_p7_t* _this = (pnf_p7_t*)calloc(1, sizeof(pnf_p7_t));
if(_this == 0)
return 0;
// set the default parameters
_this->_public.segment_size = 1400;
_this->max_num_segments = 8;
_this->_public.subframe_buffer_size = 8;
_this->_public.timing_info_mode_periodic = 1;
_this->_public.timing_info_period = 32;
_this->_public.timing_info_mode_aperiodic = 1;
_this->_public.checksum_enabled = 1;
_this->_public.malloc = &malloc;
_this->_public.free = &free;
_this->_public.codec_config.allocate = &malloc;
_this->_public.codec_config.deallocate = &free;
return &(_this->_public);
}
void nfapi_pnf_p7_config_destory(nfapi_pnf_p7_config_t* config)
{
if(config == 0)
return ;
free(config);
}
int nfapi_pnf_p7_start(nfapi_pnf_p7_config_t* config)
{
// Verify that config is not null
if(config == 0)
return -1;
// Make sure to set the defined trace function before using NFAPI_TRACE
if(config->trace)
nfapi_trace_g = config->trace;
pnf_p7_t* _this = (pnf_p7_t*)(config);
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
pnf_p7_message_pump(_this);
return 0;
}
int nfapi_pnf_p7_stop(nfapi_pnf_p7_config_t* config)
{
// Verify that config is not null
if(config == 0)
return -1;
pnf_p7_t* _this = (pnf_p7_t*)(config);
_this->terminate = 1;
return 0;
}
int nfapi_pnf_p7_subframe_ind(nfapi_pnf_p7_config_t* config, uint16_t phy_id, uint16_t sfn_sf)
{
// Verify that config is not null
if(config == 0)
return -1;
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_p7_subframe_ind(_this, phy_id, sfn_sf);
}
int nfapi_pnf_p7_harq_ind(nfapi_pnf_p7_config_t* config, nfapi_harq_indication_t* ind)
{
if(config == NULL || ind == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
return -1;
}
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_harq_indication_t));
}
int nfapi_pnf_p7_crc_ind(nfapi_pnf_p7_config_t* config, nfapi_crc_indication_t* ind)
{
if(config == NULL || ind == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
return -1;
}
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_crc_indication_t));
}
int nfapi_pnf_p7_rx_ind(nfapi_pnf_p7_config_t* config, nfapi_rx_indication_t* ind)
{
if(config == NULL || ind == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
return -1;
}
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_rx_indication_t));
}
int nfapi_pnf_p7_rach_ind(nfapi_pnf_p7_config_t* config, nfapi_rach_indication_t* ind)
{
if(config == NULL || ind == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
return -1;
}
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_rach_indication_t));
}
int nfapi_pnf_p7_srs_ind(nfapi_pnf_p7_config_t* config, nfapi_srs_indication_t* ind)
{
if(config == NULL || ind == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
return -1;
}
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_srs_indication_t));
}
int nfapi_pnf_p7_sr_ind(nfapi_pnf_p7_config_t* config, nfapi_sr_indication_t* ind)
{
if(config == NULL || ind == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
return -1;
}
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_sr_indication_t));
}
int nfapi_pnf_p7_cqi_ind(nfapi_pnf_p7_config_t* config, nfapi_cqi_indication_t* ind)
{
if(config == NULL || ind == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
return -1;
}
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_cqi_indication_t));
}
int nfapi_pnf_p7_lbt_dl_ind(nfapi_pnf_p7_config_t* config, nfapi_lbt_dl_indication_t* ind)
{
if(config == NULL || ind == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
return -1;
}
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_lbt_dl_indication_t));
}
int nfapi_pnf_p7_nb_harq_ind(nfapi_pnf_p7_config_t* config, nfapi_nb_harq_indication_t* ind)
{
if(config == NULL || ind == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
return -1;
}
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_nb_harq_indication_t));
}
int nfapi_pnf_p7_nrach_ind(nfapi_pnf_p7_config_t* config, nfapi_nrach_indication_t* ind)
{
if(config == NULL || ind == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
return -1;
}
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_nrach_indication_t));
}
int nfapi_pnf_p7_vendor_extension(nfapi_pnf_p7_config_t* config, nfapi_p7_message_header_t* msg)
{
if(config == NULL || msg == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
return -1;
}
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_p7_pack_and_send_p7_message(_this, msg, 0);
}
+28
View File
@@ -0,0 +1,28 @@
#
# Copyright 2017 Cisco Systems, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#nfapi unit test
AUTOMAKE_OPTIONS=subdir-objects
AM_CPPFLAGS = -I$(top_srcdir)/nfapi/inc -I$(top_srcdir)/nfapi/public_inc -I$(top_srcdir)/common/public_inc -I$(top_srcdir)/pnf/public_inc $(CFLAGS_CUNIT) -Wall -Werror
check_PROGRAMS= test_pnf
test_pnf_SOURCES = pnf_cunit_main.c ../../common/src/debug.c
test_pnf_LDADD=$(top_builddir)/pnf/libnfapi_pnf.a $(top_builddir)/nfapi/libnfapi.a -L$(libdir) -lpthread -lrt -lsctp -lz -lcunit
LOG_DRIVER = $(top_srcdir)/tap-driver.sh
TESTS=$(check_PROGRAMS)
EXTRA_DIST = $(TESTS)
File diff suppressed because it is too large Load Diff