Merge remote-tracking branch 'origin/develop' into oairu

This commit is contained in:
Raymond Knopp
2021-02-23 11:51:29 +01:00
73 changed files with 10416 additions and 444 deletions
@@ -120,6 +120,17 @@ typedef struct {
} nfapi_tl_t;
#define NFAPI_TAG_LENGTH_PACKED_LEN 4
// Convenience methods to convert between SFN/SLOT formats
#define NFAPI_SFNSLOT2DEC(_sfn,_slot) ( _sfn*20 + _slot ) // total count of slots
#define NFAPI_SFNSLOTDEC2SFNSLOT(_sfnslot_dec) ((((_sfnslot_dec) / 20) << 4) | (((_sfnslot_dec) - (((_sfnslot_dec) / 20) * 10)) & 0x3F))
#define NFAPI_SFNSLOT2SFN(_sfnslot) ((_sfnslot) >> 6)
#define NFAPI_SFNSLOT2SLOT(_sfnslot) ((_sfnslot) & 0x3F)
#define NFAPI_SFNSLOTDEC2SFN(_sfnslot_dec) ((_sfnslot_dec) / 20)
#define NFAPI_SFNSLOTDEC2SLOT(_sfnslot_dec) ((_sfnslot_dec) % 20)
#define NFAPI_MAX_SFNSLOTDEC 1024*20 // 20 is for numerology 1
// Convenience methods to convert between SFN/SFN formats
#define NFAPI_SFNSF2DEC(_sfnsf) ((((_sfnsf) >> 4) * 10) + ((_sfnsf) & 0xF))
#define NFAPI_SFNSFDEC2SFNSF(_sfnsf_dec) ((((_sfnsf_dec) / 10) << 4) | (((_sfnsf_dec) - (((_sfnsf_dec) / 10) * 10)) & 0xF))
@@ -176,7 +187,6 @@ typedef enum {
NFAPI_DL_NODE_SYNC,
NFAPI_TIMING_INFO,
NFAPI_RSSI_REQUEST = 0x0200,
NFAPI_RSSI_RESPONSE,
NFAPI_RSSI_INDICATION,
@@ -587,6 +597,26 @@ typedef struct {
#define NFAPI_PNF_PHY_RF_TAG 0x1003
// Generic strucutre for single tlv value.
typedef struct {
nfapi_tl_t tl;
int32_t value;
} nfapi_int32_tlv_t;
typedef struct {
nfapi_tl_t tl;
uint32_t value;
} nfapi_uint32_tlv_t;
typedef struct {
nfapi_tl_t tl;
int64_t value;
} nfapi_int64_tlv_t;
typedef struct {
nfapi_tl_t tl;
uint64_t value;
} nfapi_uint64_tlv_t;
typedef struct {
nfapi_tl_t tl;
uint16_t value;
@@ -1106,6 +1136,7 @@ typedef struct {
typedef struct {
nfapi_p4_p5_message_header_t header;
uint8_t num_tlvs;
nfapi_pnf_phy_rf_config_t pnf_phy_rf_config;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_pnf_config_request_t;
@@ -2466,7 +2497,7 @@ typedef struct {
typedef struct {
nfapi_p7_message_header_t header;
uint32_t t1;
int32_t delta_sfn_sf;
int32_t delta_sfn_sf;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_dl_node_sync_t;
@@ -2481,22 +2512,50 @@ typedef struct {
typedef struct {
nfapi_p7_message_header_t header;
uint32_t last_sfn_sf;
uint32_t time_since_last_timing_info;
uint32_t dl_config_jitter;
uint32_t tx_request_jitter;
uint32_t ul_config_jitter;
uint32_t hi_dci0_jitter;
int32_t dl_config_latest_delay;
int32_t tx_request_latest_delay;
int32_t ul_config_latest_delay;
int32_t hi_dci0_latest_delay;
int32_t dl_config_earliest_arrival;
int32_t tx_request_earliest_arrival;
int32_t ul_config_earliest_arrival;
int32_t hi_dci0_earliest_arrival;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_timing_info_t;
typedef struct {
nfapi_p7_message_header_t header;
uint32_t last_sfn;
uint32_t last_slot;
uint32_t time_since_last_timing_info;
uint32_t dl_tti_jitter;
uint32_t tx_data_request_jitter;
uint32_t ul_tti_jitter;
uint32_t ul_dci_jitter;
int32_t dl_tti_latest_delay;
int32_t tx_data_request_latest_delay;
int32_t ul_tti_latest_delay;
int32_t ul_dci_latest_delay;
int32_t dl_tti_earliest_arrival;
int32_t tx_data_request_earliest_arrival;
int32_t ul_tti_earliest_arrival;
int32_t ul_dci_earliest_arrival;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nr_timing_info_t;
typedef struct {
nfapi_tl_t tl;
uint32_t handle;
@@ -3653,6 +3712,50 @@ typedef struct {
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nmm_stop_response_t;
typedef struct
{
// TODO: see if this needs to be uncommented
// These TLVs are used to setup the transport connection between VNF and PNF
nfapi_ipv4_address_t p7_vnf_address_ipv4;
nfapi_ipv6_address_t p7_vnf_address_ipv6;
nfapi_uint16_tlv_t p7_vnf_port;
nfapi_ipv4_address_t p7_pnf_address_ipv4;
nfapi_ipv6_address_t p7_pnf_address_ipv6;
nfapi_uint16_tlv_t p7_pnf_port;
nfapi_uint8_tlv_t timing_window; //Value: 0 → 30,000 microseconds
nfapi_uint8_tlv_t timing_info_mode;
nfapi_uint8_tlv_t timing_info_period;
nfapi_uint32_tlv_t dl_tti_timing_offset;
nfapi_uint32_tlv_t ul_tti_timing_offset;
nfapi_uint32_tlv_t ul_dci_timing_offset;
nfapi_uint32_tlv_t tx_data_timing_offset;
// These TLVs are used to setup the transport connection between VNF and PNF
/*
nfapi_uint8_tlv_t dl_ue_per_sf;
nfapi_uint8_tlv_t ul_ue_per_sf;
// These TLVs are used by PNF to report its RF capabilities to the VNF software
nfapi_rf_bands_t rf_bands;
*/
// These TLVs are used by the VNF to configure the synchronization with the PNF.
// These TLVs are used by the VNF to configure the RF in the PNF
//nfapi_uint16_tlv_t max_transmit_power;
//nfapi_uint32_tlv_t nrarfcn;
// nfapi_nmm_frequency_bands_t nmm_gsm_frequency_bands;
// nfapi_nmm_frequency_bands_t nmm_umts_frequency_bands;
// nfapi_nmm_frequency_bands_t nmm_lte_frequency_bands;
// nfapi_uint8_tlv_t nmm_uplink_rssi_supported;
} nfapi_nr_nfapi_t;
//
// Configuration options for the encode decode functions
//
@@ -3864,6 +3967,7 @@ int nfapi_p4_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
*
*/
int nfapi_p5_message_pack(void *pMessageBuf, uint32_t messageBufLen, void *pPackedBuf, uint32_t packedBufLen, nfapi_p4_p5_codec_config_t* config);
int nfapi_nr_p5_message_pack(void *pMessageBuf, uint32_t messageBufLen, void *pPackedBuf, uint32_t packedBufLen, nfapi_p4_p5_codec_config_t* config);
/*! \brief Decodes an NFAPI P5 message header
* \param pMessageBuf A pointer to an encoded P5 message header
@@ -3887,6 +3991,7 @@ int nfapi_p5_message_header_unpack(void *pMessageBuf, uint32_t messageBufLen, vo
*
* The function will decode a byte stream pointed to by pMessageBuf into a nfapi p5 message structure pointer to by pUnpackedBuf
*/
int nfapi_nr_p5_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p4_p5_codec_config_t* config);
int nfapi_p5_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p4_p5_codec_config_t* config);
/*! \brief Encodes an NFAPI P7 message to a buffer
@@ -3900,6 +4005,7 @@ int nfapi_p5_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
*
*/
int nfapi_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t* config);
int nfapi_nr_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t* config);
/*! \brief Decodes an NFAPI P7 message header
* \param pMessageBuf A pointer to an encoded P7 message header
@@ -3925,6 +4031,7 @@ int nfapi_p7_message_header_unpack(void *pMessageBuf, uint32_t messageBufLen, vo
* The function will decode a byte stream pointed to by pMessageBuf into a nfapi p7 message structure pointer to by pUnpackedBuf
*/
int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p7_codec_config_t* config);
int nfapi_nr_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p7_codec_config_t* config);
/*! \brief Calculates the checksum of a message
*
@@ -10,7 +10,7 @@
#define _NFAPI_NR_INTERFACE_H_
#include "nfapi_interface.h"
#include <nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h>
#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h"
#define NFAPI_NR_MAX_NB_CCE_AGGREGATION_LEVELS 5
#define NFAPI_NR_MAX_NB_TCI_STATES_PDCCH 64
@@ -22,62 +22,32 @@
// nFAPI enums
//These TLVs are used exclusively by nFAPI
typedef struct
{
// These TLVs are used to setup the transport connection between VNF and PNF
// nfapi_ipv4_address_t p7_vnf_address_ipv4;
// nfapi_ipv6_address_t p7_vnf_address_ipv6;
// nfapi_uint16_tlv_t p7_vnf_port;
// nfapi_ipv4_address_t p7_pnf_address_ipv4;
// nfapi_ipv6_address_t p7_pnf_address_ipv6;
// nfapi_uint16_tlv_t p7_pnf_port;
// // These TLVs are used to setup the transport connection between VNF and PNF
// nfapi_uint8_tlv_t dl_ue_per_sf;
// nfapi_uint8_tlv_t ul_ue_per_sf;
// These TLVs are used by PNF to report its RF capabilities to the VNF software
nfapi_rf_bands_t rf_bands;
// These TLVs are used by the VNF to configure the synchronization with the PNF.
// nfapi_uint8_tlv_t timing_window;
// nfapi_uint8_tlv_t timing_info_mode;
// nfapi_uint8_tlv_t timing_info_period;
// These TLVs are used by the VNF to configure the RF in the PNF
// nfapi_uint16_tlv_t max_transmit_power;
nfapi_uint32_tlv_t nrarfcn;
// nfapi_nmm_frequency_bands_t nmm_gsm_frequency_bands;
// nfapi_nmm_frequency_bands_t nmm_umts_frequency_bands;
// nfapi_nmm_frequency_bands_t nmm_lte_frequency_bands;
// nfapi_uint8_tlv_t nmm_uplink_rssi_supported;
} nfapi_nr_nfapi_t;
#define NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG 0x5100
#define NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG 0x5101
#define NFAPI_NR_NFAPI_P7_VNF_PORT_TAG 0x5102
#define NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV4_TAG 0x5103
#define NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV6_TAG 0x5104
#define NFAPI_NR_NFAPI_P7_PNF_PORT_TAG 0x5105
#define NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG 0x0100
#define NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG 0x0101
#define NFAPI_NR_NFAPI_P7_VNF_PORT_TAG 0x0102
#define NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV4_TAG 0x0103
#define NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV6_TAG 0x0104
#define NFAPI_NR_NFAPI_P7_PNF_PORT_TAG 0x0105
#define NFAPI_NR_NFAPI_DL_TTI_TIMING_OFFSET 0x0106
#define NFAPI_NR_NFAPI_UL_TTI_TIMING_OFFSET 0x0107
#define NFAPI_NR_NFAPI_UL_DCI_TIMING_OFFSET 0x0108
#define NFAPI_NR_NFAPI_TX_DATA_TIMING_OFFSET 0x0109
#define NFAPI_NR_NFAPI_TIMING_WINDOW_TAG 0x011E
#define NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG 0x011F
#define NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG 0x0120
/*
#define NFAPI_NR_NFAPI_DOWNLINK_UES_PER_SUBFRAME_TAG 0x510A
#define NFAPI_NR_NFAPI_UPLINK_UES_PER_SUBFRAME_TAG 0x510B
#define NFAPI_NR_NFAPI_RF_BANDS_TAG 0x5114
#define NFAPI_NR_NFAPI_TIMING_WINDOW_TAG 0x511E
#define NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG 0x511F
#define NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG 0x5120
#define NFAPI_NR_NFAPI_MAXIMUM_TRANSMIT_POWER_TAG 0x5128
#define NFAPI_NR_NFAPI_NRARFCN_TAG 0x5129
#define NFAPI_NR_NFAPI_NMM_GSM_FREQUENCY_BANDS_TAG 0x5130
#define NFAPI_NR_NFAPI_NMM_UMTS_FREQUENCY_BANDS_TAG 0x5131
#define NFAPI_NR_NFAPI_NMM_LTE_FREQUENCY_BANDS_TAG 0x5132
#define NFAPI_NR_NFAPI_NMM_UPLINK_RSSI_SUPPORTED_TAG 0x5133
*/
// P5 Message Structures
typedef struct {
@@ -323,7 +293,7 @@ typedef enum {
typedef enum {
NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED=0,
NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED
NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED=1
} nfapi_nr_cce_reg_mapping_type_e;
typedef enum {
@@ -11,6 +11,7 @@
#include "stddef.h"
#include "nfapi_interface.h"
#include "nfapi_nr_interface.h"
#define NFAPI_NR_MAX_NB_CCE_AGGREGATION_LEVELS 5
#define NFAPI_NR_MAX_NB_TCI_STATES_PDCCH 64
@@ -24,25 +25,7 @@
#define NFAPI_MAX_NUM_CB 8
// Extension to the generic structures for single tlv values
typedef struct {
nfapi_tl_t tl;
int32_t value;
} nfapi_int32_tlv_t;
typedef struct {
nfapi_tl_t tl;
uint32_t value;
} nfapi_uint32_tlv_t;
typedef struct {
nfapi_tl_t tl;
int64_t value;
} nfapi_int64_tlv_t;
typedef struct {
nfapi_tl_t tl;
uint64_t value;
} nfapi_uint64_tlv_t;
typedef enum {
NFAPI_NR_DMRS_TYPE1=0,
@@ -76,35 +59,42 @@ typedef enum {
NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST= 0X05,
NFAPI_NR_PHY_MSG_TYPE_STOP_INDICATION=0X06,
NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION=0X07,
NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE=0X010D,
NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE=0X010F,
//RESERVED 0X08 ~ 0X7F
NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST= 0X80,
NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST= 0X81,
NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION=0X82,
NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST= 0X83,
NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST=0X54,
NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST=0X84, // CHANGED TO 0X84
NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION=0X85,
NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION= 0X86,
NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION= 0X87,
NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION= 0X88,
NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION= 0X89
NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION= 0X89,
//RESERVED 0X8a ~ 0xff
NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_REQUEST = 0x0100,
NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_RESPONSE = 0x0101,
NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_REQUEST= 0x0102,
NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_RESPONSE= 0x0103,
NFAPI_NR_PHY_MSG_TYPE_PNF_START_REQUEST= 0x0104,
NFAPI_NR_PHY_MSG_TYPE_PNF_START_RESPONSE= 0x0105,
NFAPI_NR_PHY_MSG_TYPE_PNF_STOP_REQUEST= 0x0106,
NFAPI_NR_PHY_MSG_TYPE_PNF_STOP_RESPONSE= 0x0107,
NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC = 0x0180,
NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC,
NFAPI_NR_PHY_MSG_TYPE_TIMING_INFO
} nfapi_nr_phy_msg_type_e;
// SCF222_5G-FAPI_PHY_SPI_Specificayion.pdf Section 3.3
//3.3.1 PARAM
//same with nfapi_param_request_t
typedef struct {
nfapi_p4_p5_message_header_t header;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nr_param_request_t;
typedef enum {
NFAPI_NR_PARAM_MSG_OK = 0,
NFAPI_NR_PARAM_MSG_INVALID_STATE
} nfapi_nr_param_errors_e;
/*typedef struct {
nfapi_nr_param_errors_e error_code;
@@ -278,12 +268,6 @@ typedef struct
//-------------------------------------------//
//3.3.2 CONFIG
typedef enum {
NFAPI_NR_CONFIG_MSG_OK = 0,
NFAPI_NR_CONFIG_MSG_INVALID_CONFIG //The configuration provided has missing mandatory TLVs, or TLVs that are invalid or unsupported in this state.
} nfapi_nr_config_errors_e;
/*typedef struct {
nfapi_nr_config_errors_e error_code;
uint8_t number_of_invalid_tlvs_that_can_only_be_configured_in_idle;
@@ -465,9 +449,108 @@ typedef struct
} nfapi_nr_measurement_config_t;
// ERROR enums
typedef enum { // Table 2-22
NFAPI_NR_PARAM_MSG_OK = 0,
NFAPI_NR_PARAM_MSG_INVALID_STATE
} nfapi_nr_param_errors_e;
typedef enum { // Table 2-25
NFAPI_NR_CONFIG_MSG_OK = 0,
NFAPI_NR_CONFIG_MSG_INVALID_STATE, //The CONFIG.request was received when the PHY was not in the IDLE state or the CONFIGURED state.
NFAPI_NR_CONFIG_MSG_INVALID_CONFIG //The configuration provided has missing mandatory TLVs, or TLVs that are invalid or unsupported in this state.
} nfapi_nr_config_errors_e;
typedef enum { // Table 2-27
NFAPI_NR_START_MSG_OK = 0,
NFAPI_NR_START_MSG_INVALID_STATE
} nfapi_nr_start_errors_e;
//PNF P5 NR
typedef struct {
nfapi_p4_p5_message_header_t header;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nr_pnf_param_request_t;
typedef struct {
uint8_t num_tlv;
nfapi_p4_p5_message_header_t header;
uint32_t error_code;
nfapi_pnf_param_general_t pnf_param_general;
nfapi_pnf_phy_t pnf_phy;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nr_pnf_param_response_t;
typedef struct {
nfapi_p4_p5_message_header_t header;
uint8_t num_tlvs;
nfapi_pnf_phy_rf_config_t pnf_phy_rf_config;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nr_pnf_config_request_t;
typedef struct {
nfapi_p4_p5_message_header_t header;
uint32_t error_code;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nr_pnf_config_response_t;
typedef struct {
nfapi_p4_p5_message_header_t header;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nr_pnf_start_request_t;
typedef struct {
nfapi_p4_p5_message_header_t header;
uint32_t error_code;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nr_pnf_start_response_t;
typedef struct {
nfapi_p4_p5_message_header_t header;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nr_pnf_stop_request_t;
typedef struct {
nfapi_p4_p5_message_header_t header;
uint32_t error_code;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nr_pnf_stop_response_t;
/* PARAM.REQUEST */
typedef struct {
nfapi_p4_p5_message_header_t header;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nr_param_request_scf_t;
/* PARAM.RESPONSE */
typedef struct {
nfapi_p4_p5_message_header_t header;
uint8_t error_code;
uint8_t num_tlv;
nfapi_vendor_extension_tlv_t vendor_extension;
nfapi_nr_cell_param_t cell_param;
nfapi_nr_carrier_param_t carrier_param;
nfapi_nr_pdcch_param_t pdcch_param;
nfapi_nr_pucch_param_t pucch_param;
nfapi_nr_pdsch_param_t pdsch_param;
nfapi_nr_pusch_param_t pusch_param;
nfapi_nr_prach_param_t prach_param;
nfapi_nr_measurement_param_t measurement_param;
nfapi_nr_nfapi_t nfapi_config;
} nfapi_nr_param_response_scf_t;
//------------------------------//
//3.3.2 CONFIG
/* CONFIG.REQUEST */
typedef struct {
nfapi_p4_p5_message_header_t header;
uint8_t num_tlv;
nfapi_vendor_extension_tlv_t vendor_extension;
nfapi_nr_carrier_config_t carrier_config;
nfapi_nr_cell_config_t cell_config;
nfapi_nr_ssb_config_t ssb_config;
@@ -475,20 +558,32 @@ typedef struct {
nfapi_nr_ssb_table_t ssb_table;
nfapi_nr_tdd_table_t tdd_table;
nfapi_nr_measurement_config_t measurement_config;
nfapi_nr_nfapi_t nfapi_config;
} nfapi_nr_config_request_scf_t;
/* CONFIG.RESPONSE */
typedef struct {
nfapi_p4_p5_message_header_t header;
uint8_t error_code;
//uint8_t num_invalid_tlvs;
// TODO: add list of invalid/unsupported TLVs (see Table 3.18)
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nr_config_response_scf_t;
//------------------------------//
//3.3.3 START
typedef struct {
nfapi_p4_p5_message_header_t header;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nr_start_request_t;
} nfapi_nr_start_request_scf_t;
typedef enum {
NFAPI_NR_START_MSG_INVALID_STATE
} nfapi_nr_start_errors_e;
typedef struct {
nfapi_p4_p5_message_header_t header;
nfapi_nr_start_errors_e error_code;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nr_start_response_scf_t;
//3.3.4 STOP
@@ -497,6 +592,7 @@ typedef struct {
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nr_stop_request_t;
typedef struct {
nfapi_p4_p5_message_header_t header;
nfapi_vendor_extension_tlv_t vendor_extension;
@@ -580,7 +676,7 @@ typedef struct {
uint16_t sfn; //0->1023
uint16_t slot;//0->319
} nfapi_nr_slot_indication_t;
} nfapi_nr_slot_indication_scf_t;
// 3.4.2
@@ -941,6 +1037,7 @@ typedef struct {
} nfapi_nr_dl_tti_request_pdu_t;
#define NFAPI_NR_MAX_DL_TTI_PDUS 32
typedef struct {
/// Number of PDUs that are included in this message. All PDUs in the message are numbered in order. Value 0 -> 255
uint8_t nPDUs;
@@ -954,11 +1051,28 @@ typedef struct {
uint8_t PduIdx[256][12];
} nfapi_nr_dl_tti_request_body_t;
typedef struct {
nfapi_p7_message_header_t header;
uint32_t t1;
int32_t delta_sfn_slot;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nr_dl_node_sync_t;
typedef struct {
nfapi_p7_message_header_t header;
uint32_t t1;
uint32_t t2;
uint32_t t3;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nr_ul_node_sync_t;
typedef struct {
nfapi_p7_message_header_t header;
/// System Frame Number (0-1023)
uint16_t SFN;
/// Slot number (0-319)
/// Slot number (0-19)
uint16_t Slot;
nfapi_nr_dl_tti_request_body_t dl_tti_request_body;
nfapi_vendor_extension_tlv_t vendor_extension;
@@ -973,7 +1087,7 @@ typedef struct
nfapi_nr_dl_tti_ssb_pdu_t* ssb_pdu;
} nfapi_nr_dl_pdu_configuration_t;
*/
/*
/*
typedef struct
{
uint16_t pdu_type;//0: PDCCH PDU 1: PDSCH PDU 2: CSI-RS PDU 3: SSB PDU,
@@ -1272,6 +1386,7 @@ typedef struct
} nfapi_nr_ul_tti_request_number_of_groups_t;
typedef struct {
nfapi_p7_message_header_t header;
uint16_t SFN; //0->1023
uint16_t Slot;//0->319
uint8_t n_pdus;//Number of PDUs that are included in this message. All PDUs in the message are numbered in order. Value 0 -> 255
@@ -1318,6 +1433,7 @@ typedef struct {
} nfapi_nr_ul_dci_request_pdus_t;
typedef struct {
nfapi_p7_message_header_t header;
uint16_t SFN;
uint16_t Slot;
uint8_t numPdus;
@@ -1363,6 +1479,7 @@ typedef struct
#define NFAPI_NR_MAX_TX_REQUEST_PDUS 16
typedef struct
{
nfapi_p7_message_header_t header;
uint16_t SFN;
uint16_t Slot;
uint16_t Number_of_PDUs;
+1 -1
View File
@@ -712,7 +712,7 @@ int unpack_tlv_list(unpack_tlv_t unpack_fns[], uint16_t size, uint8_t **ppReadPa
for(idx = 0; idx < size; ++idx)
{
if(unpack_fns[idx].tag == generic_tl.tag)
if(unpack_fns[idx].tag == generic_tl.tag) // match the extracted tag value with all the tags in unpack_fn list
{
tagMatch = 1;
nfapi_tl_t* tl = (nfapi_tl_t*)(unpack_fns[idx].tlv);
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+2
View File
@@ -38,7 +38,9 @@ typedef struct {
int pnf_connect(pnf_t *pnf);
int pnf_message_pump(pnf_t *pnf);
int pnf_nr_message_pump(pnf_t *pnf);
int pnf_nr_pack_and_send_p5_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len);
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);
+38 -2
View File
@@ -29,15 +29,37 @@
typedef struct {
uint16_t dl_conf_ontime;
uint16_t dl_tti_ontime;
uint16_t dl_conf_late;
uint16_t dl_tti_late;
uint16_t ul_conf_ontime;
uint16_t ul_tti_ontime;
uint16_t ul_conf_late;
uint16_t ul_tti_late;
uint16_t hi_dci0_ontime;
uint16_t hi_dci0_late;
uint16_t ul_dci_ontime;
uint16_t ul_dci_late;
uint16_t tx_ontime;
uint16_t tx_late;
uint16_t tx_data_ontime;
uint16_t tx_data_late;
} pnf_p7_stats_t;
typedef struct { // TODO: replace with the stats
uint16_t dl_tti_ontime;
uint16_t dl_tti_late;
uint16_t ul_tti_ontime;
uint16_t ul_tti_late;
uint16_t ul_dci_ontime;
uint16_t ul_dci_late;
uint16_t tx_data_ontime;
uint16_t tx_data_late;
} pnf_p7_nr_stats_t;
typedef struct {
uint8_t* buffer;
uint16_t length;
@@ -82,7 +104,7 @@ typedef struct {
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*/];
nfapi_pnf_p7_slot_buffer_t slot_buffer[30/*NFAPI_MAX_TIMING_WINDOW_SIZE*/];
uint32_t sequence_number;
uint16_t max_num_segments;
@@ -94,6 +116,12 @@ typedef struct {
uint16_t sfn_sf;
uint32_t sf_start_time_hr;
int32_t sfn_sf_shift;
uint16_t sfn;
uint16_t slot;
uint16_t sfn_slot;
uint32_t slot_start_time_hr;
int32_t slot_shift;
uint8_t timing_info_period_counter;
uint8_t timing_info_aperiodic_send; // 0:false 1:true
@@ -104,18 +132,26 @@ typedef struct {
uint32_t ul_config_jitter;
uint32_t hi_dci0_jitter;
uint32_t tx_jitter;
//P7 NR
uint32_t dl_tti_jitter;
uint32_t ul_tti_jitter;
uint32_t ul_dci_jitter;
uint32_t tx_data_jitter;
uint32_t tick;
pnf_p7_stats_t stats;
pnf_p7_nr_stats_t nr_stats;
} pnf_p7_t;
int pnf_p7_message_pump(pnf_p7_t* pnf_p7);
int pnf_nr_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_slot_ind(pnf_p7_t* config, uint16_t phy_id, uint16_t sfn, uint16_t slot);
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);
@@ -25,8 +25,13 @@ extern "C" {
#include "nfapi_interface.h"
#include "debug.h"
#include <openair2/PHY_INTERFACE/IF_Module.h>
#include <openair1/PHY/defs_eNB.h>
#include "nfapi_nr_interface.h"
#include "nfapi_nr_interface_scf.h"
#include <sys/types.h>
#include "openair1/PHY/defs_gNB.h"
/*! This enum is used to describe the states of the pnf
*/
@@ -121,6 +126,7 @@ typedef struct nfapi_pnf_config
* 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_nr_param_req)(nfapi_pnf_config_t* config, nfapi_nr_pnf_param_request_t* req);
int (*pnf_param_req)(nfapi_pnf_config_t* config, nfapi_pnf_param_request_t* req);
/*! A callback for the PNF_CONFIG.request
@@ -133,7 +139,8 @@ typedef struct nfapi_pnf_config
* 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);
int (*pnf_nr_config_req)(nfapi_pnf_config_t* config, nfapi_nr_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
@@ -144,7 +151,8 @@ typedef struct nfapi_pnf_config
* 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);
int (*pnf_nr_start_req)(nfapi_pnf_config_t* config, nfapi_nr_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
@@ -167,7 +175,8 @@ typedef struct nfapi_pnf_config
* 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);
int (*nr_param_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_nr_param_request_scf_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
@@ -179,6 +188,7 @@ typedef struct nfapi_pnf_config
* 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);
int (*nr_config_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_nr_config_request_scf_t* req);
/*! A callback for the START.request
* \param config A pointer to the pnf configuration
@@ -190,8 +200,8 @@ typedef struct nfapi_pnf_config
* 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);
int (*start_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_start_request_t* req);
int (*nr_start_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_nr_start_request_scf_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
@@ -203,7 +213,8 @@ typedef struct nfapi_pnf_config
* 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);
int (*nr_stop_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_nr_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
@@ -355,6 +366,7 @@ int nfapi_pnf_config_destroy(nfapi_pnf_config_t* config);
* \endcode
*/
int nfapi_pnf_start(nfapi_pnf_config_t* config);
int nfapi_nr_pnf_start(nfapi_pnf_config_t* config);
/*! Stop the PNF library.
* \param config A pointer to the pnf configuration
@@ -371,6 +383,8 @@ int nfapi_pnf_stop(nfapi_pnf_config_t* config);
*
*/
int nfapi_pnf_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_pnf_param_response_t* resp);
int nfapi_nr_pnf_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_nr_pnf_param_response_t* resp);
/*! Send the PNF_CONFIG.response
* \param config A pointer to a pnf configuraiton
@@ -379,6 +393,7 @@ int nfapi_pnf_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_pnf_param_respons
*
*/
int nfapi_pnf_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_pnf_config_response_t* resp);
int nfapi_nr_pnf_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_nr_pnf_config_response_t* resp);
/*! Send the PNF_START.response
* \param config A pointer to a pnf configuraiton
@@ -387,7 +402,7 @@ int nfapi_pnf_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_pnf_config_respo
*
*/
int nfapi_pnf_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_pnf_start_response_t* resp);
int nfapi_nr_pnf_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_nr_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
@@ -403,6 +418,7 @@ int nfapi_pnf_pnf_stop_resp(nfapi_pnf_config_t* config, nfapi_pnf_stop_response_
*
*/
int nfapi_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_param_response_t* resp);
int nfapi_nr_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_nr_param_response_scf_t* resp);
/*! Send the CONFIG.response
* \param config A pointer to a pnf configuraiton
@@ -411,7 +427,7 @@ int nfapi_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_param_response_t* res
*
*/
int nfapi_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_config_response_t* resp);
int nfapi_nr_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_nr_config_response_scf_t* resp);
/*! Send the START.response
* \param config A pointer to a pnf configuraiton
* \param resp A pointer to the message structure
@@ -419,6 +435,7 @@ int nfapi_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_config_response_t* r
*
*/
int nfapi_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_start_response_t* resp);
int nfapi_nr_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_nr_start_response_scf_t* resp);
/*! Send the STOP.response
* \param config A pointer to a pnf configuraiton
@@ -550,6 +567,22 @@ typedef struct
nfapi_ue_release_request_t* ue_release_req;
} nfapi_pnf_p7_subframe_buffer_t;
typedef struct
{
//uint16_t sfn_slot
int16_t sfn;
int16_t slot;
//TODO: Change P7 structs to NR
nfapi_nr_dl_tti_request_t* dl_tti_req;//nfapi_dl_config_request_t* dl_config_req;
nfapi_nr_ul_tti_request_t* ul_tti_req;//nfapi_ul_config_request_t* ul_config_req;
nfapi_nr_ul_dci_request_t* ul_dci_req;//nfapi_hi_dci0_request_t* hi_dci0_req;
nfapi_nr_tx_data_request_t* tx_data_req;//nfapi_tx_request_t* tx_req;
//TODO: check these two later
//nfapi_lbt_dl_config_request_t* lbt_dl_config_req;
//nfapi_ue_release_request_t* ue_release_req;
} nfapi_pnf_p7_slot_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
@@ -602,6 +635,8 @@ typedef struct nfapi_pnf_p7_config
/*! 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;
nfapi_pnf_p7_slot_buffer_t dummy_slot; // defining a slot equivalent for now
/*! Configuration options for the p7 pack unpack functions*/
nfapi_p7_codec_config_t codec_config;
@@ -611,6 +646,7 @@ typedef struct nfapi_pnf_p7_config
// tdb : if these should be public
uint16_t subframe_buffer_size;
uint16_t slot_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
@@ -620,6 +656,7 @@ typedef struct nfapi_pnf_p7_config
* \param req A pointer to the dl config request message structure
* \return not currently used
*/
int (*dl_tti_req_fn)(gNB_L1_rxtx_proc_t *proc,nfapi_pnf_p7_config_t* config, nfapi_nr_dl_tti_request_t* req);
int (*dl_config_req)(L1_rxtx_proc_t *proc,nfapi_pnf_p7_config_t* config, nfapi_dl_config_request_t* req);
/*! A callback for the UL_CONFIG.request
@@ -627,6 +664,7 @@ typedef struct nfapi_pnf_p7_config
* \param req A pointer to the ul config request message structure
* \return not currently used
*/
int (*ul_tti_req_fn)(gNB_L1_rxtx_proc_t *proc,nfapi_pnf_p7_config_t* config, nfapi_nr_ul_tti_request_t* req);
int (*ul_config_req)(L1_rxtx_proc_t *proc,nfapi_pnf_p7_config_t* config, nfapi_ul_config_request_t* req);
/*! A callback for the HI_DCI0.request
@@ -634,8 +672,9 @@ typedef struct nfapi_pnf_p7_config
* \param req A pointer to the hi dci0 request message structure
* \return not currently used
*/
int (*ul_dci_req_fn)(gNB_L1_rxtx_proc_t *proc,nfapi_pnf_p7_config_t* config, nfapi_nr_ul_dci_request_t* req);
int (*hi_dci0_req)(L1_rxtx_proc_t *proc,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
@@ -645,6 +684,7 @@ typedef struct nfapi_pnf_p7_config
* 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_data_req_fn)(nfapi_pnf_p7_config_t* config, nfapi_nr_tx_data_request_t* req);
int (*tx_req)(nfapi_pnf_p7_config_t* config, nfapi_tx_request_t* req);
/*! A callback for the LBT_DL_CONFIG.request
@@ -708,6 +748,7 @@ int nfapi_pnf_p7_config_destroy(nfapi_pnf_p7_config_t* config);
* This function will not return until nfapi_pnf_p7_stop is called.
*/
int nfapi_pnf_p7_start(nfapi_pnf_p7_config_t* config);
int nfapi_nr_pnf_p7_start(nfapi_pnf_p7_config_t* config);
/*! Stop the PNF P7 library.
* \param config A pointer to a PNF P7 config
@@ -717,6 +758,21 @@ int nfapi_pnf_p7_start(nfapi_pnf_p7_config_t* config);
*/
int nfapi_pnf_p7_stop(nfapi_pnf_p7_config_t* config);
/*! NR Slot indication
* message copied from nfapi_pnf_p7_subframe_ind
* \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_slot_ind(nfapi_pnf_p7_config_t* config, uint16_t phy_id, uint16_t sfn, uint16_t slot);
/*! Subframe indication
* \param config A pointer to a PNF P7 config
* \param phy_id The phy_id for the phy instance
+782 -2
View File
@@ -26,9 +26,29 @@
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include "nfapi_nr_interface.h"
#include "nfapi_nr_interface_scf.h"
#include "pnf.h"
# if 1 // for hard-code (remove later)
#include "COMMON/platform_types.h"
#include "COMMON/platform_constants.h"
#include "common/ran_context.h"
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "NR_BCCH-BCH-Message.h"
#include "NR_ServingCellConfigCommon.h"
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "SCHED_NR/phy_frame_config_nr.h"
#include "NR_MIB.h"
#include "openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h"
#endif
#define MAX_SCTP_STREAMS 16
void nfapi_pnf_phy_config_delete_all(nfapi_pnf_config_t* config)
@@ -63,6 +83,50 @@ nfapi_pnf_phy_config_t* nfapi_pnf_phy_config_find(nfapi_pnf_config_t* config, ui
return 0;
}
void pnf_nr_handle_pnf_param_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
// ensure it's valid
if (pRecvMsg == NULL || pnf == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
}
else
{
nfapi_nr_pnf_param_request_t req;
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF_PARAM.request received\n");
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(nfapi_nr_pnf_param_request_t), &pnf->_public.codec_config) >= 0)
{
if(pnf->_public.state == NFAPI_PNF_IDLE)
{
if(pnf->_public.pnf_nr_param_req)
{
(pnf->_public.pnf_nr_param_req)(&pnf->_public, &req);
}
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: PNF not in IDLE state\n", __FUNCTION__);
nfapi_nr_pnf_param_response_t resp;
memset(&resp, 0, sizeof(resp));
resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_RESPONSE;
resp.error_code = NFAPI_MSG_INVALID_STATE;
nfapi_nr_pnf_pnf_param_resp(&pnf->_public, &resp);
}
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
}
if(req.vendor_extension)
pnf->_public.codec_config.deallocate(req.vendor_extension);
}
}
void pnf_handle_pnf_param_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
// ensure it's valid
@@ -173,6 +237,72 @@ void pnf_handle_pnf_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
}
}
void pnf_nr_handle_pnf_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
// ensure it's valid
if (pRecvMsg == NULL || pnf == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
}
else
{
nfapi_nr_pnf_config_request_t req;
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF_CONFIG.request received\n");
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &pnf->_public.codec_config) >= 0)
{
// ensure correct state
if(pnf->_public.state != NFAPI_PNF_RUNNING)
{
// delete the phy records
nfapi_pnf_phy_config_delete_all(&pnf->_public);
// create the phy records
if (req.pnf_phy_rf_config.tl.tag == NFAPI_PNF_PHY_RF_TAG)
{
int i = 0;
for(i = 0; i < req.pnf_phy_rf_config.number_phy_rf_config_info; ++i)
{
nfapi_pnf_phy_config_t* phy = (nfapi_pnf_phy_config_t*)malloc(sizeof(nfapi_pnf_phy_config_t));
memset(phy, 0, sizeof(nfapi_pnf_phy_config_t));
phy->state = NFAPI_PNF_PHY_IDLE;
phy->phy_id = req.pnf_phy_rf_config.phy_rf_config[i].phy_id;
nfapi_pnf_phy_config_add(&(pnf->_public), phy);
}
}
if(pnf->_public.pnf_nr_config_req)
{
(pnf->_public.pnf_nr_config_req)(&(pnf->_public), &req);
}
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: PNF not in correct state: %d\n", __FUNCTION__, pnf->_public.state);
nfapi_nr_pnf_config_response_t resp;
memset(&resp, 0, sizeof(resp));
resp.header.message_id = NFAPI_PNF_CONFIG_RESPONSE;
resp.error_code = NFAPI_MSG_INVALID_STATE;
nfapi_nr_pnf_pnf_config_resp(&(pnf->_public), &resp);
}
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
}
if(req.vendor_extension)
pnf->_public.codec_config.deallocate(req.vendor_extension);
}
}
void pnf_handle_pnf_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
// ensure it's valid
@@ -215,6 +345,48 @@ void pnf_handle_pnf_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
}
}
void pnf_nr_handle_pnf_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
// ensure it's valid
if (pRecvMsg == NULL || pnf == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
}
else
{
nfapi_nr_pnf_start_request_t req;
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF_START.request Received\n");
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &pnf->_public.codec_config) >= 0)
{
if(pnf->_public.state == NFAPI_PNF_CONFIGURED)
{
if(pnf->_public.pnf_nr_start_req)
{
(pnf->_public.pnf_nr_start_req)(&(pnf->_public), &req);
}
}
else
{
nfapi_nr_pnf_start_response_t resp;
memset(&resp, 0, sizeof(resp));
resp.header.message_id = NFAPI_PNF_START_RESPONSE;
resp.error_code = NFAPI_MSG_INVALID_STATE;
nfapi_nr_pnf_pnf_start_resp(&(pnf->_public), &resp);
}
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
}
if(req.vendor_extension)
pnf->_public.codec_config.deallocate(req.vendor_extension);
}
}
void pnf_handle_pnf_stop_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
// ensure it's valid
@@ -330,6 +502,78 @@ void pnf_handle_param_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
}
}
void pnf_nr_handle_param_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
// ensure it's valid
if (pRecvMsg == NULL || pnf == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
}
else
{
nfapi_nr_param_request_scf_t req;
nfapi_pnf_config_t* config = &(pnf->_public);
NFAPI_TRACE(NFAPI_TRACE_INFO, "PARAM.request received\n");
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0)
{
if(config->state == NFAPI_PNF_RUNNING)
{
nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, req.header.phy_id);
if(phy)
{
if(phy->state == NFAPI_PNF_PHY_IDLE)
{
if(config->nr_param_req)
{
(config->nr_param_req)(config, phy, &req);
}
}
else
{
nfapi_nr_param_response_scf_t resp;
memset(&resp, 0, sizeof(resp));
resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE;
resp.header.phy_id = req.header.phy_id;
resp.error_code = NFAPI_MSG_INVALID_STATE;
nfapi_nr_pnf_param_resp(config, &resp);
}
}
else
{
nfapi_nr_param_response_scf_t resp;
memset(&resp, 0, sizeof(resp));
resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE;
resp.header.phy_id = req.header.phy_id;
resp.error_code = NFAPI_MSG_INVALID_CONFIG;
nfapi_nr_pnf_param_resp(config, &resp);
}
}
else
{
nfapi_nr_param_response_scf_t resp;
memset(&resp, 0, sizeof(resp));
resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE;
resp.header.phy_id = req.header.phy_id;
resp.error_code = NFAPI_MSG_INVALID_STATE;
nfapi_nr_pnf_param_resp(config, &resp);
}
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
}
if(req.vendor_extension)
pnf->_public.codec_config.deallocate(req.vendor_extension);
}
}
void pnf_handle_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
@@ -401,6 +645,85 @@ void pnf_handle_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
}
}
void pnf_nr_handle_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
// ensure it's valid
if (pRecvMsg == NULL || pnf == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
}
else
{
nfapi_nr_config_request_scf_t req;
NFAPI_TRACE(NFAPI_TRACE_INFO, "CONFIG.request received\n");
nfapi_pnf_config_t* config = &(pnf->_public);
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0)
{
if(config->state == NFAPI_PNF_RUNNING)
{
nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, req.header.phy_id);
#if 0 // emulate set_config TLV reception (hard-code)
int tdd_return = set_tdd_config_nr(&req, 1, 7, 6, 2, 4);
#endif
if(phy)
{
if(phy->state != NFAPI_PNF_PHY_RUNNING)
{
if(config->nr_config_req)
{
(config->nr_config_req)(config, phy, &req);
}
}
else
{
nfapi_nr_config_response_scf_t resp;
memset(&resp, 0, sizeof(resp));
resp.header.message_id = NFAPI_CONFIG_RESPONSE;
resp.header.phy_id = req.header.phy_id;
resp.error_code = NFAPI_MSG_INVALID_STATE;
nfapi_nr_pnf_config_resp(config, &resp);
}
}
else
{
nfapi_nr_config_response_scf_t resp;
memset(&resp, 0, sizeof(resp));
resp.header.message_id = NFAPI_CONFIG_RESPONSE;
resp.header.phy_id = req.header.phy_id;
resp.error_code = NFAPI_MSG_INVALID_CONFIG;
nfapi_nr_pnf_config_resp(config, &resp);
}
}
else
{
nfapi_nr_config_response_scf_t resp;
memset(&resp, 0, sizeof(resp));
resp.header.message_id = NFAPI_CONFIG_RESPONSE;
resp.header.phy_id = req.header.phy_id;
resp.error_code = NFAPI_MSG_INVALID_STATE;
nfapi_nr_pnf_config_resp(config, &resp);
}
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
}
if(req.vendor_extension)
pnf->_public.codec_config.deallocate(req.vendor_extension);
}
}
void pnf_handle_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
// ensure it's valid
@@ -472,6 +795,77 @@ void pnf_handle_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
}
}
void pnf_nr_handle_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
// ensure it's valid
if (pRecvMsg == NULL || pnf == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
}
else
{
nfapi_nr_start_request_scf_t req;
nfapi_pnf_config_t* config = &(pnf->_public);
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() START.request received state:%d\n", __FUNCTION__, config->state);
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0)
{
if(config->state == NFAPI_PNF_RUNNING)
{
nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, req.header.phy_id);
if(phy)
{
if(phy->state != NFAPI_PNF_PHY_RUNNING)
{
if(config->nr_start_req)
{
(config->nr_start_req)(config, phy, &req);
}
}
else
{
nfapi_nr_start_response_scf_t resp;
memset(&resp, 0, sizeof(resp));
resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE;
resp.header.phy_id = req.header.phy_id;
resp.error_code = NFAPI_MSG_INVALID_STATE;
nfapi_nr_pnf_start_resp(config, &resp);
}
}
else
{
nfapi_nr_start_response_scf_t resp;
memset(&resp, 0, sizeof(resp));
resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE;
resp.header.phy_id = req.header.phy_id;
resp.error_code = NFAPI_MSG_INVALID_CONFIG;
nfapi_nr_pnf_start_resp(config, &resp);
}
}
else
{
nfapi_nr_start_response_scf_t resp;
memset(&resp, 0, sizeof(resp));
resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE;
resp.header.phy_id = req.header.phy_id;
resp.error_code = NFAPI_MSG_INVALID_STATE;
nfapi_nr_pnf_start_resp(config, &resp);
}
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
}
if(req.vendor_extension)
pnf->_public.codec_config.deallocate(req.vendor_extension);
}
}
void pnf_handle_stop_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
// ensure it's valid
@@ -543,6 +937,77 @@ void pnf_handle_stop_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
}
}
void pnf_nr_handle_stop_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
// ensure it's valid
if (pRecvMsg == NULL || pnf == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
}
else
{
nfapi_nr_stop_request_t req;
NFAPI_TRACE(NFAPI_TRACE_INFO, "STOP.request received\n");
nfapi_pnf_config_t* config = &(pnf->_public);
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0)
{
if(config->state == NFAPI_PNF_RUNNING)
{
nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, req.header.phy_id);
if(phy)
{
if(phy->state != NFAPI_PNF_PHY_RUNNING)
{
if(config->nr_stop_req)
{
(config->nr_stop_req)(config, phy, &req);
}
}
else
{
nfapi_stop_response_t resp;
memset(&resp, 0, sizeof(resp));
resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE;
resp.header.phy_id = req.header.phy_id;
resp.error_code = NFAPI_MSG_INVALID_STATE;
nfapi_pnf_stop_resp(config, &resp);
}
}
else
{
nfapi_stop_response_t resp;
memset(&resp, 0, sizeof(resp));
resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE;
resp.header.phy_id = req.header.phy_id;
resp.error_code = NFAPI_MSG_INVALID_CONFIG;
nfapi_pnf_stop_resp(config, &resp);
}
}
else
{
nfapi_stop_response_t resp;
memset(&resp, 0, sizeof(resp));
resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE;
resp.header.phy_id = req.header.phy_id;
resp.error_code = NFAPI_MSG_INVALID_STATE;
nfapi_pnf_stop_resp(config, &resp);
}
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
}
if(req.vendor_extension)
pnf->_public.codec_config.deallocate(req.vendor_extension);
}
}
void pnf_handle_measurement_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
// ensure it's valid
@@ -1071,7 +1536,101 @@ void pnf_handle_vendor_extension(void* pRecvMsg, int recvMsgLen, pnf_t* pnf, uin
}
}
void pnf_nr_handle_p5_message(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
nfapi_p4_p5_message_header_t messageHeader;
// validate the input params
if(pRecvMsg == NULL || recvMsgLen < NFAPI_HEADER_LENGTH)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
return;
}
// unpack the message header
if (nfapi_p5_message_header_unpack(pRecvMsg, recvMsgLen, &messageHeader, sizeof(nfapi_p4_p5_message_header_t), &pnf->_public.codec_config) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n");
return;
}
switch (messageHeader.message_id)
{
case NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_REQUEST:
pnf_nr_handle_pnf_param_request(pnf, pRecvMsg, recvMsgLen);
break;
case NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_REQUEST:
pnf_nr_handle_pnf_config_request(pnf, pRecvMsg, recvMsgLen);
break;
case NFAPI_NR_PHY_MSG_TYPE_PNF_START_REQUEST:
pnf_nr_handle_pnf_start_request(pnf, pRecvMsg, recvMsgLen);
break;
case NFAPI_PNF_STOP_REQUEST:
pnf_handle_pnf_stop_request(pnf, pRecvMsg, recvMsgLen);
break;
case NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST:
pnf_nr_handle_param_request(pnf, pRecvMsg, recvMsgLen);
break;
case NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST:
pnf_nr_handle_config_request(pnf, pRecvMsg, recvMsgLen);
break;
case NFAPI_NR_PHY_MSG_TYPE_START_REQUEST:
pnf_nr_handle_start_request(pnf, pRecvMsg, recvMsgLen);
break;
case NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST:
pnf_nr_handle_stop_request(pnf, pRecvMsg, recvMsgLen);
break;
case NFAPI_MEASUREMENT_REQUEST:
pnf_handle_measurement_request(pnf, pRecvMsg, recvMsgLen);
break;
case NFAPI_RSSI_REQUEST:
pnf_handle_rssi_request(pnf, pRecvMsg, recvMsgLen);
break;
case NFAPI_CELL_SEARCH_REQUEST:
pnf_handle_cell_search_request(pnf, pRecvMsg, recvMsgLen);
break;
case NFAPI_BROADCAST_DETECT_REQUEST:
pnf_handle_broadcast_detect_request(pnf, pRecvMsg, recvMsgLen);
break;
case NFAPI_SYSTEM_INFORMATION_SCHEDULE_REQUEST:
pnf_handle_system_information_schedule_request(pnf, pRecvMsg, recvMsgLen);
break;
case NFAPI_SYSTEM_INFORMATION_REQUEST:
pnf_handle_system_information_request(pnf, pRecvMsg, recvMsgLen);
break;
case NFAPI_NMM_STOP_REQUEST:
pnf_handle_nmm_stop_request(pnf, pRecvMsg, recvMsgLen);
break;
default:
{
if(messageHeader.message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
messageHeader.message_id <= NFAPI_VENDOR_EXT_MSG_MAX)
{
pnf_handle_vendor_extension(pRecvMsg, recvMsgLen, pnf, messageHeader.message_id);
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s P5 Unknown message ID %d\n", __FUNCTION__, messageHeader.message_id);
}
}
break;
}
}
void pnf_handle_p5_message(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
@@ -1169,6 +1728,24 @@ void pnf_handle_p5_message(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
}
}
int pnf_nr_pack_and_send_p5_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len)
{
int packed_len = nfapi_nr_p5_message_pack(msg, msg_len,
pnf->tx_message_buffer,
sizeof(pnf->tx_message_buffer),
&pnf->_public.codec_config);
if (packed_len < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi_p5_message_pack failed (%d)\n", packed_len);
return -1;
}
return pnf_send_message(pnf, pnf->tx_message_buffer, packed_len, 0/*msg->stream_id*/);
}
int pnf_pack_and_send_p5_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len)
{
int packed_len = nfapi_p5_message_pack(msg, msg_len,
@@ -1393,8 +1970,15 @@ int pnf_connect(pnf_t* pnf)
int pnf_send_message(pnf_t* pnf, uint8_t *msg, uint32_t len, uint16_t stream)
{
if (pnf->sctp)
{
printf("\nPNF SENDS: \n");
for(int i=0; i<len; i++){
printf("%d", msg[i]);
}
printf("\n");
if (sctp_sendmsg(pnf->p5_sock, msg, len, NULL, 0, 42/*config->sctp_stream_number*/, 0, stream/*P5_STREAM_ID*/, 0, 0) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "sctp_sendmsg failed errno: %d\n", errno);
@@ -1412,7 +1996,6 @@ int pnf_send_message(pnf_t* pnf, uint8_t *msg, uint32_t len, uint16_t stream)
return 0;
}
int pnf_read_dispatch_message(pnf_t* pnf)
{
int socket_connected = 1;
@@ -1486,6 +2069,13 @@ int pnf_read_dispatch_message(pnf_t* pnf)
}
else
{
// print the received message
printf("\n MESSAGE RECEIVED: \n");
for(int i=0; i<message_size; i++){
printf("%d", read_buffer[i]);
}
printf("\n");
if (flags & MSG_NOTIFICATION)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "Notification received from %s:%u\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
@@ -1533,6 +2123,135 @@ int pnf_read_dispatch_message(pnf_t* pnf)
return socket_connected;
}
int pnf_nr_read_dispatch_message(pnf_t* pnf)
{
int socket_connected = 1;
// 1. Peek the message header
// 2. If the message is larger than the stack buffer then create a dynamic buffer
// 3. Read the buffer
// 4. Handle the p5 message
uint32_t header_buffer_size = NFAPI_HEADER_LENGTH;
uint8_t header_buffer[header_buffer_size];
uint32_t stack_buffer_size = 32; //should it be the size of then sctp_notificatoin structure
uint8_t stack_buffer[stack_buffer_size];
uint8_t* dynamic_buffer = 0;
uint8_t* read_buffer = &stack_buffer[0];
uint32_t message_size = 0;
struct sockaddr_in addr;
socklen_t addr_len = sizeof(addr);
struct sctp_sndrcvinfo sndrcvinfo;
(void)memset(&sndrcvinfo, 0, sizeof(struct sctp_sndrcvinfo));
{
int flags = MSG_PEEK;
message_size = sctp_recvmsg(pnf->p5_sock, header_buffer, header_buffer_size, /*(struct sockaddr*)&addr, &addr_len*/ 0, 0, &sndrcvinfo, &flags);
if(message_size == -1)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF Failed to peek sctp message size errno:%d\n", errno);
return 0;
}
nfapi_p4_p5_message_header_t header;
int unpack_result = nfapi_p5_message_header_unpack(header_buffer, header_buffer_size, &header, sizeof(header), 0);
if(unpack_result < 0)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF Failed to unpack p5 message header\n");
return 0;
}
message_size = header.message_length;
// now have the size of the mesage
}
if(message_size > stack_buffer_size)
{
dynamic_buffer = (uint8_t*)malloc(message_size);
if(dynamic_buffer == NULL)
{
// todo : add error mesage
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF Failed to allocate dynamic buffer for sctp_recvmsg size:%d\n", message_size);
return -1;
}
read_buffer = dynamic_buffer;
}
{
int flags = 0;
(void)memset(&sndrcvinfo, 0, sizeof(struct sctp_sndrcvinfo));
int recvmsg_result = sctp_recvmsg(pnf->p5_sock, read_buffer, message_size, (struct sockaddr*)&addr, &addr_len, &sndrcvinfo, &flags);
if(recvmsg_result == -1)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "Failed to read sctp message size errno:%d\n", errno);
}
else
{
// print the received message
printf("\n MESSAGE RECEIVED: \n");
for(int i=0; i<message_size; i++){
printf("%d", read_buffer[i]);
}
printf("\n");
if (flags & MSG_NOTIFICATION)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "Notification received from %s:%u\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
// todo - handle the events
}
else
{
/*
NFAPI_TRACE(NFAPI_TRACE_INFO, "Received message fd:%d from %s:%u assoc:%d on stream %d, PPID %d, length %d, flags 0x%x\n",
pnf->p5_sock,
inet_ntoa(addr.sin_addr),
ntohs(addr.sin_port),
sndrcvinfo.sinfo_assoc_id,
sndrcvinfo.sinfo_stream,
ntohl(sndrcvinfo.sinfo_ppid),
message_size,
flags);
*/
// handle now if complete message in one or more segments
if ((flags & 0x80) == 0x80)
{
pnf_nr_handle_p5_message(pnf, read_buffer, message_size);
}
else
{
NFAPI_TRACE(NFAPI_TRACE_WARN, "sctp_recvmsg: unhandled mode with flags 0x%x\n", flags);
// assume socket disconnected
NFAPI_TRACE(NFAPI_TRACE_WARN, "Disconnected socket\n");
socket_connected = 0;
}
}
}
}
if(dynamic_buffer)
{
free(dynamic_buffer);
}
return socket_connected;
}
@@ -1597,3 +2316,64 @@ int pnf_message_pump(pnf_t* pnf)
}
int pnf_nr_message_pump(pnf_t* pnf)
{
uint8_t socketConnected = 1;
while(socketConnected && pnf->terminate == 0)
{
fd_set rfds;
int selectRetval = 0;
// select on a timeout and then get the message
FD_ZERO(&rfds);
FD_SET(pnf->p5_sock, &rfds);
struct timeval timeout;
timeout.tv_sec = 1;
timeout.tv_usec = 0;
selectRetval = select(pnf->p5_sock+1, &rfds, NULL, NULL, &timeout);
if(selectRetval == 0)
{
// timeout
continue;
}
else if (selectRetval == -1 && (errno == EINTR))
{
// interrupted by signal
NFAPI_TRACE(NFAPI_TRACE_WARN, "P5 Signal Interrupt %d\n", errno);
continue;
}
else if (selectRetval == -1)
{
NFAPI_TRACE(NFAPI_TRACE_WARN, "P5 select() failed\n");
sleep(1);
continue;
}
if(FD_ISSET(pnf->p5_sock, &rfds))
{
socketConnected = pnf_nr_read_dispatch_message(pnf);
}
else
{
NFAPI_TRACE(NFAPI_TRACE_WARN, "Why are we here\n");
}
}
// Drop back to idle if we have lost connection
pnf->_public.state = NFAPI_PNF_PHY_IDLE;
// close the connection and socket
if (close(pnf->p5_sock) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "close(sctpSock) failed errno: %d\n", errno);
}
return 0;
}
+163 -1
View File
@@ -19,6 +19,8 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "nfapi_nr_interface.h"
#include "nfapi_nr_interface_scf.h"
nfapi_pnf_config_t* nfapi_pnf_config_create()
{
@@ -81,6 +83,40 @@ int nfapi_pnf_start(nfapi_pnf_config_t* config)
return 0;
}
int nfapi_nr_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_nr_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
@@ -96,6 +132,21 @@ int nfapi_pnf_stop(nfapi_pnf_config_t* config)
return 0;
}
int nfapi_nr_pnf_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_nr_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_nr_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_nr_pnf_param_response_t));
}
int nfapi_pnf_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_pnf_param_response_t* resp)
{
// ensure it's valid
@@ -129,6 +180,27 @@ int nfapi_pnf_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_pnf_config_respo
return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_pnf_config_response_t));
}
int nfapi_nr_pnf_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_nr_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_nr_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_nr_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
@@ -148,6 +220,26 @@ int nfapi_pnf_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_pnf_start_respons
return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_pnf_start_response_t));
}
int nfapi_nr_pnf_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_nr_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_nr_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_nr_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
@@ -166,7 +258,6 @@ int nfapi_pnf_pnf_stop_resp(nfapi_pnf_config_t* config, nfapi_pnf_stop_response_
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)
@@ -180,6 +271,20 @@ int nfapi_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_param_response_t* res
return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_param_response_t));
}
int nfapi_nr_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_nr_param_response_scf_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_nr_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_nr_param_response_scf_t));
}
int nfapi_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_config_response_t* resp)
{
if (config == NULL || resp == NULL)
@@ -208,6 +313,35 @@ int nfapi_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_config_response_t* r
return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_config_response_t));
}
int nfapi_nr_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_nr_config_response_scf_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_NR_CONFIG_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_nr_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_nr_config_response_scf_t));
}
int nfapi_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_start_response_t* resp)
{
if (config == NULL || resp == NULL)
@@ -235,6 +369,34 @@ int nfapi_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_start_response_t* res
return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_start_response_t));
}
int nfapi_nr_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_nr_start_response_scf_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_NR_START_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_nr_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_nr_start_response_scf_t));
}
int nfapi_pnf_stop_resp(nfapi_pnf_config_t* config, nfapi_stop_response_t* resp)
{
if (config == NULL || resp == NULL)
File diff suppressed because it is too large Load Diff
+31 -1
View File
@@ -31,7 +31,7 @@ nfapi_pnf_p7_config_t* nfapi_pnf_p7_config_create()
_this->_public.segment_size = 1400;
_this->max_num_segments = 8;
_this->_public.subframe_buffer_size = 8;
_this->_public.subframe_buffer_size = 8;// TODO: Initialize the slot_buffer size
_this->_public.timing_info_mode_periodic = 1;
_this->_public.timing_info_period = 32;
_this->_public.timing_info_mode_aperiodic = 1;
@@ -76,6 +76,26 @@ int nfapi_pnf_p7_start(nfapi_pnf_p7_config_t* config)
return 0;
}
int nfapi_nr_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_nr_p7_message_pump(_this);
return 0;
}
int nfapi_pnf_p7_stop(nfapi_pnf_p7_config_t* config)
{
// Verify that config is not null
@@ -88,6 +108,16 @@ int nfapi_pnf_p7_stop(nfapi_pnf_p7_config_t* config)
return 0;
}
int nfapi_pnf_p7_slot_ind(nfapi_pnf_p7_config_t* config, uint16_t phy_id, uint16_t sfn, uint16_t slot)
{
// Verify that config is not null
if(config == 0)
return -1;
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_p7_slot_ind(_this, phy_id, sfn, slot);
}
int nfapi_pnf_p7_subframe_ind(nfapi_pnf_p7_config_t* config, uint16_t phy_id, uint16_t sfn_sf)
{
@@ -48,6 +48,9 @@ typedef struct phy_info
uint8_t enabled;
uint16_t phy_id;
uint16_t sfn_sf;
uint16_t sfn;
uint16_t slot;
pthread_t thread;
@@ -1207,6 +1210,12 @@ void send_dl_subframe_msgs_interleaved(int p7Sock, int phy_id, struct sockaddr_i
//free(req.tx_request_body.tx_pdu_list);
}
void send_slot_indication(phy_info_t* phy_info)
{
// DONE: add sfn and slot as members in the phy_info
nfapi_pnf_p7_slot_ind(phy_info->config, phy_info->phy_id, phy_info->sfn, phy_info->slot);
}
void send_subframe_indication(phy_info_t* phy_info)
{
nfapi_pnf_p7_subframe_ind(phy_info->config, phy_info->phy_id, phy_info->sfn_sf);
+4
View File
@@ -35,9 +35,13 @@ typedef struct
int vnf_pack_and_send_p5_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_message_header_t* msg, uint16_t msg_len);
int vnf_nr_pack_and_send_p5_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_message_header_t* msg, uint16_t msg_len);
int vnf_pack_and_send_p4_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_message_header_t* msg, uint16_t msg_len);
int vnf_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t* pnf);
int vnf_nr_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t* pnf);
void nfapi_vnf_phy_info_list_add(nfapi_vnf_config_t* config, nfapi_vnf_phy_info_t* info);
nfapi_vnf_phy_info_t* nfapi_vnf_phy_info_list_find(nfapi_vnf_config_t* config, uint16_t phy_id);
+12 -1
View File
@@ -77,6 +77,9 @@ typedef struct nfapi_vnf_p7_connection_info {
int32_t sf_offset_filtered;
int32_t sf_offset_trend;
int32_t sf_offset;
int32_t slot_offset;
int32_t slot_offset_trend;
int32_t slot_offset_filtered;
uint16_t zero_count;
int32_t adjustment;
int32_t insync_minor_adjustment;
@@ -85,8 +88,10 @@ typedef struct nfapi_vnf_p7_connection_info {
uint32_t previous_t1;
uint32_t previous_t2;
int32_t previous_sf_offset_filtered;
int32_t previous_slot_offset_filtered;
int sfn_sf;
int sfn;
int slot;
int socket;
struct sockaddr_in local_addr;
@@ -111,6 +116,7 @@ typedef struct {
nfapi_vnf_p7_connection_info_t* p7_connections;
int socket;
uint32_t sf_start_time_hr;
uint32_t slot_start_time_hr;
uint8_t* rx_message_buffer; // would this be better put in the p7 conenction info?
uint16_t rx_message_buffer_size;
@@ -120,14 +126,19 @@ uint32_t vnf_get_current_time_hr(void);
uint16_t increment_sfn_sf(uint16_t sfn_sf);
int vnf_sync(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info);
int vnf_nr_sync(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info);
int send_mac_subframe_indications(vnf_p7_t* config);
int send_mac_slot_indications(vnf_p7_t* config);
int vnf_p7_read_dispatch_message(vnf_p7_t* vnf_p7 );
int vnf_nr_p7_read_dispatch_message(vnf_p7_t* vnf_p7 );
void vnf_p7_connection_info_list_add(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* node);
nfapi_vnf_p7_connection_info_t* vnf_p7_connection_info_list_find(vnf_p7_t* vnf_p7, uint16_t phy_id);
nfapi_vnf_p7_connection_info_t* vnf_p7_connection_info_list_delete(vnf_p7_t* vnf_p7, uint16_t phy_id);
int vnf_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* header);
int vnf_nr_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* header);
void vnf_p7_release_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* header);
void vnf_p7_release_pdu(vnf_p7_t* vnf_p7, void* pdu);
@@ -19,6 +19,7 @@
#include "nfapi_interface.h"
#include "nfapi_nr_interface_scf.h"
#include "nfapi_nr_interface.h"
#include "debug.h"
@@ -120,6 +121,7 @@ typedef struct nfapi_vnf_config
*
* \todo Do we need to send the address information of the PNF?
*/
int (*pnf_nr_connection_indication)(nfapi_vnf_config_t* config, int p5_idx);
int (*pnf_connection_indication)(nfapi_vnf_config_t* config, int p5_idx);
/*! \brief Callback indicating that a pnf has lost connection
@@ -160,6 +162,7 @@ typedef struct nfapi_vnf_config
* then the substructure pointers should be set to 0 and then the client should
* use the codec_config.deallocate function to release it at a future point
*/
int (*pnf_nr_param_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_pnf_param_response_t* resp);
int (*pnf_param_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_param_response_t* resp);
/*! A callback for the PNF_CONFIG.resp
@@ -182,7 +185,8 @@ typedef struct nfapi_vnf_config
* use the codec_config.deallocate function to release it at a future point
*/
int (*pnf_config_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_config_response_t* resp);
int (*pnf_nr_config_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_pnf_config_response_t* resp);
/*! A callback for the PNF_START.resp
* \param config A pointer to the vnf configuration
* \param p5_idx The p5 index used to indicate a particular pnf p5 connection
@@ -203,7 +207,8 @@ typedef struct nfapi_vnf_config
* use the codec_config.deallocate function to release it at a future point
*/
int (*pnf_start_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_start_response_t* resp);
int (*pnf_nr_start_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_pnf_start_response_t* resp);
/*! A callback for the PNF_STOP.resp
* \param config A pointer to the vnf configuration
* \param p5_idx The p5 index used to indicate a particular pnf p5 connection
@@ -249,6 +254,7 @@ typedef struct nfapi_vnf_config
* use the codec_config.deallocate function to release it at a future point
*/
int (*param_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_param_response_t* resp);
int (*nr_param_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_param_response_scf_t* resp);
/*! A callback for the CONFIG.response
* \param config A pointer to the vnf configuration
@@ -266,8 +272,9 @@ typedef struct nfapi_vnf_config
* then the substructure pointers should be set to 0 and then the client should
* use the codec_config.deallocate function to release it at a future point
*/
int (*nr_config_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_config_response_scf_t* resp);
int (*config_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_config_response_t* resp);
/*! A callback for the START.resp
* \param config A pointer to the vnf configuration
* \param p5_idx The p5 index used to indicate a particular pnf p5 connection
@@ -285,6 +292,7 @@ typedef struct nfapi_vnf_config
* use the codec_config.deallocate function to release it at a future point
*/
int (*start_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_start_response_t* resp);
int (*nr_start_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_start_response_scf_t* resp);
/*! A callback for the STOP.resp
* \param config A pointer to the vnf configuration
@@ -469,6 +477,8 @@ void nfapi_vnf_config_destory(nfapi_vnf_config_t* config);
*
* This function will not return untill nfapi_vnf_stop is called
*/
int nfapi_nr_vnf_start(nfapi_vnf_config_t* config);
int nfapi_vnf_start(nfapi_vnf_config_t* config);
/*! Stop the VNF library.
@@ -500,6 +510,7 @@ int nfapi_vnf_allocate_phy(nfapi_vnf_config_t* config, int p5_idx, uint16_t* phy
* \return 0 means success, -1 failure
*/
int nfapi_vnf_pnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_param_request_t* req);
int nfapi_nr_vnf_pnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_pnf_param_request_t* req);
/*! Send the PNF_CONFIG.request
* \param config A pointer to a vnf config
@@ -508,6 +519,7 @@ int nfapi_vnf_pnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_pa
* \return 0 means success, -1 failure
*/
int nfapi_vnf_pnf_config_req(nfapi_vnf_config_t* config,int p5_idx, nfapi_pnf_config_request_t* req);
int nfapi_nr_vnf_pnf_config_req(nfapi_vnf_config_t* config,int p5_idx, nfapi_nr_pnf_config_request_t* req);
/*! Send the PNF_START.request
* \param config A pointer to a vnf config
@@ -516,6 +528,7 @@ int nfapi_vnf_pnf_config_req(nfapi_vnf_config_t* config,int p5_idx, nfapi_pnf_co
* \return 0 means success, -1 failure
*/
int nfapi_vnf_pnf_start_req(nfapi_vnf_config_t* config,int p5_idx, nfapi_pnf_start_request_t* req);
int nfapi_nr_vnf_pnf_start_req(nfapi_vnf_config_t* config,int p5_idx, nfapi_nr_pnf_start_request_t* req);
/*! Send the PNF_STOP.request
* \param config A pointer to a vnf config
@@ -532,6 +545,7 @@ int nfapi_vnf_pnf_stop_req(nfapi_vnf_config_t* config,int p5_idx, nfapi_pnf_stop
* \return 0 means success, -1 failure
*/
int nfapi_vnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_param_request_t* req);
int nfapi_nr_vnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_param_request_scf_t* req);
/*! Send the CONFIG.request
* \param config A pointer to a vnf config
@@ -539,6 +553,7 @@ int nfapi_vnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_param_requ
* \param req A pointer to a CONFIG.request message structure
* \return 0 means success, -1 failure
*/
int nfapi_nr_vnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_config_request_scf_t* req);
int nfapi_vnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_config_request_t* req);
/*! Send the START.request
@@ -548,6 +563,7 @@ int nfapi_vnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_config_re
* \return 0 means success, -1 failure
*/
int nfapi_vnf_start_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_start_request_t* req);
int nfapi_nr_vnf_start_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_start_request_scf_t* req);
/*! Send the STOP.request
* \param config A pointer to a vnf config
@@ -692,6 +708,7 @@ typedef struct nfapi_vnf_p7_config
*/
int (*subframe_indication)(struct nfapi_vnf_p7_config* config, uint16_t phy_id, uint16_t sfn_sf);
int (*slot_indication)(struct nfapi_vnf_p7_config* config, uint16_t phy_id, uint16_t sfn, uint16_t slot);
/*! A callback for the HARQ.indication
* \param config A pointer to the vnf p7 configuration
@@ -885,6 +902,8 @@ void nfapi_vnf_p7_config_destory(nfapi_vnf_p7_config_t* config);
*/
int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config);
int nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t* config);
/*! Stop the VNF P7 library.
* \param config A pointer to an vnf p7 configuration structure
@@ -950,7 +969,7 @@ int nfapi_vnf_p7_nr_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_nr_dl_tti
* may be released after this function call has returned or at a later pointer
*/
int nfapi_vnf_p7_ul_config_req(nfapi_vnf_p7_config_t* config, nfapi_ul_config_request_t* req);
int nfapi_vnf_p7_ul_tti_req(nfapi_vnf_p7_config_t* config, nfapi_nr_ul_tti_request_t* req);
/*! Send the HI_DCI0.request
* \param config A pointer to the vnf p7 configuration
* \param req A data structure for the decoded HI_DCI0.request.
@@ -960,7 +979,7 @@ int nfapi_vnf_p7_ul_config_req(nfapi_vnf_p7_config_t* config, nfapi_ul_config_re
* may be released after this function call has returned or at a later pointer
*/
int nfapi_vnf_p7_hi_dci0_req(nfapi_vnf_p7_config_t* config, nfapi_hi_dci0_request_t* req);
int nfapi_vnf_p7_ul_dci_req(nfapi_vnf_p7_config_t* config, nfapi_nr_ul_dci_request_t* req);
/*! Send the TX.req
* \param config A pointer to the vnf p7 configuration
* \param req A data structure for the decoded HI_DCI0.request.
@@ -970,7 +989,7 @@ int nfapi_vnf_p7_hi_dci0_req(nfapi_vnf_p7_config_t* config, nfapi_hi_dci0_reques
* may be released after this function call has returned or at a later pointer
*/
int nfapi_vnf_p7_tx_req(nfapi_vnf_p7_config_t* config, nfapi_tx_request_t* req);
int nfapi_vnf_p7_tx_data_req(nfapi_vnf_p7_config_t* config, nfapi_nr_tx_data_request_t* req);
/*! Send the LBT_DL_CONFIG.requst
* \param config A pointer to the vnf p7 configuration
* \param req A data structure for the decoded LBT_DL_CONFIG.request.
+482 -3
View File
@@ -21,9 +21,12 @@
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include "vnf.h"
#include "nfapi_nr_interface.h"
#include "nfapi_nr_interface_scf.h"
void* vnf_malloc(nfapi_vnf_config_t* config, size_t size)
@@ -101,6 +104,39 @@ nfapi_vnf_pnf_info_t* nfapi_vnf_pnf_list_find(nfapi_vnf_config_t* config, int p5
return 0;
}
void vnf_nr_handle_pnf_param_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx)
{
// ensure it's valid
if (pRecvMsg == NULL || config == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s : NULL parameters\n", __FUNCTION__);
}
else
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "Received PNF_PARAM.reponse\n");
nfapi_nr_pnf_param_response_t msg;
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0)
{
// Invoke the call back
if(config->pnf_nr_param_resp)
{
(config->pnf_nr_param_resp)(config, p5_idx, &msg);
}
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
}
// make sure to release any dyanmic part of the message
if(msg.vendor_extension)
config->codec_config.deallocate(msg.vendor_extension);
}
}
void vnf_handle_pnf_param_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx)
{
// ensure it's valid
@@ -134,6 +170,40 @@ void vnf_handle_pnf_param_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_con
}
}
void vnf_nr_handle_pnf_config_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx)
{
// ensure it's valid
if (pRecvMsg == NULL || config == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
}
else
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "Received PNF_CONFIG_RESPONSE\n");
nfapi_nr_pnf_config_response_t msg;
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0)
{
// Invoke the call back
if(config->pnf_nr_config_resp)
{
(config->pnf_nr_config_resp)(config, p5_idx, &msg);
}
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
}
// make sure to release any dyanmic part of the message
if(msg.vendor_extension)
config->codec_config.deallocate(msg.vendor_extension);
}
}
void vnf_handle_pnf_config_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx)
{
// ensure it's valid
@@ -167,6 +237,38 @@ void vnf_handle_pnf_config_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_co
}
}
void vnf_nr_handle_pnf_start_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx)
{
// ensure it's valid
if (pRecvMsg == NULL || config == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
}
else
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "Received PNF_START_RESPONSE\n");
nfapi_nr_pnf_start_response_t msg;
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0)
{
if(config->pnf_nr_start_resp)
{
(config->pnf_nr_start_resp)(config, p5_idx, &msg);
}
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
}
// make sure to release any dyanmic part of the message
if(msg.vendor_extension)
config->codec_config.deallocate(msg.vendor_extension);
}
}
void vnf_handle_pnf_start_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx)
{
// ensure it's valid
@@ -298,8 +400,113 @@ void vnf_handle_param_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_
}
}
void vnf_nr_handle_param_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx)
{
// ensure it's valid
if (pRecvMsg == NULL || config == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
}
else
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "Received PARAM_RESPONSE\n");
nfapi_nr_param_response_scf_t msg;
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0)
{
if (msg.error_code == NFAPI_NR_PARAM_MSG_OK)
{
nfapi_vnf_phy_info_t* phy_info = nfapi_vnf_phy_info_list_find(config, msg.header.phy_id);
if(msg.nfapi_config.p7_pnf_address_ipv4.tl.tag)
{
struct sockaddr_in sockAddr;
(void)memcpy(&sockAddr.sin_addr.s_addr, msg.nfapi_config.p7_pnf_address_ipv4.address, NFAPI_IPV4_ADDRESS_LENGTH);
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 IPv4 address: %s\n", inet_ntoa(sockAddr.sin_addr));
// store address
phy_info->p7_pnf_address.sin_addr = sockAddr.sin_addr;
}
if(msg.nfapi_config.p7_pnf_address_ipv6.tl.tag)
{
struct sockaddr_in6 sockAddr6;
char addr6[64];
(void)memcpy(&sockAddr6.sin6_addr, msg.nfapi_config.p7_pnf_address_ipv6.address, NFAPI_IPV6_ADDRESS_LENGTH);
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 IPv6 address: %s\n", inet_ntop(AF_INET6, &sockAddr6.sin6_addr, addr6, sizeof(addr6)));
}
if (msg.nfapi_config.p7_pnf_port.tl.tag)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 Port: %d\n", msg.nfapi_config.p7_pnf_port.value);
// store port
phy_info->p7_pnf_address.sin_port = htons(msg.nfapi_config.p7_pnf_port.value);
}
}
if(config->nr_param_resp)
{
(config->nr_param_resp)(config, p5_idx, &msg);
}
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
}
// make sure to release any dyanmic part of the message
if(msg.vendor_extension)
config->codec_config.deallocate(msg.vendor_extension);
}
}
void vnf_nr_handle_config_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx)
{
// ensure it's valid
if (pRecvMsg == NULL || config == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
}
else
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "Received CONFIG_RESPONSE\n");
nfapi_nr_config_response_scf_t msg;
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >=0 )
{
// check the error code:
if (msg.error_code == NFAPI_NR_CONFIG_MSG_OK){
if(config->nr_config_resp)
{
(config->nr_config_resp)(config, p5_idx, &msg);
}
}
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
}
// make sure to release any dyanmic part of the message
if(msg.vendor_extension)
config->codec_config.deallocate(msg.vendor_extension);
}
}
void vnf_handle_config_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx)
{
// ensure it's valid
if (pRecvMsg == NULL || config == NULL)
{
@@ -314,9 +521,13 @@ void vnf_handle_config_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config
// unpack the message
if (nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >=0 )
{
if(config->config_resp)
{
(config->config_resp)(config, p5_idx, &msg);
// check the error code:
if (msg.error_code == NFAPI_MSG_OK){
if(config->config_resp)
{
(config->config_resp)(config, p5_idx, &msg);
}
}
}
else
@@ -362,6 +573,40 @@ void vnf_handle_start_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_
}
}
void vnf_nr_handle_start_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx)
{
// ensure it's valid
if (pRecvMsg == NULL || config == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
}
else
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "Received START_RESPONSE\n");
nfapi_nr_start_response_scf_t msg;
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0)
{ // check the error code
if (msg.error_code == NFAPI_NR_START_MSG_OK){
if(config->nr_start_resp)
{
(config->nr_start_resp)(config, p5_idx, &msg);
}
}
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
}
// make sure to release any dyanmic part of the message
if(msg.vendor_extension)
config->codec_config.deallocate(msg.vendor_extension);
}
}
void vnf_handle_stop_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx)
{
@@ -811,6 +1056,74 @@ void vnf_handle_vendor_extension(void* pRecvMsg, int recvMsgLen, nfapi_vnf_confi
}
}
void vnf_nr_handle_p4_p5_message(void *pRecvMsg, int recvMsgLen, int p5_idx, nfapi_vnf_config_t* config)
{
nfapi_p4_p5_message_header_t messageHeader;
// validate the input params
if(pRecvMsg == NULL || recvMsgLen < NFAPI_HEADER_LENGTH || config == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "vnf_handle_p4_p5_message: invalid input params\n");
return;
}
// unpack the message header
if (nfapi_p5_message_header_unpack(pRecvMsg, recvMsgLen, &messageHeader, sizeof(nfapi_p4_p5_message_header_t), &config->codec_config) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n");
return;
}
switch (messageHeader.message_id)
{
case NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_RESPONSE:
vnf_nr_handle_pnf_param_response(pRecvMsg, recvMsgLen, config, p5_idx);
break;
case NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_RESPONSE:
vnf_nr_handle_pnf_config_response(pRecvMsg, recvMsgLen, config, p5_idx);
break;
case NFAPI_NR_PHY_MSG_TYPE_PNF_START_RESPONSE:
vnf_nr_handle_pnf_start_response(pRecvMsg, recvMsgLen, config, p5_idx);
break;
case NFAPI_PNF_STOP_RESPONSE:
vnf_handle_pnf_stop_response(pRecvMsg, recvMsgLen, config, p5_idx);
break;
case NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE:
vnf_nr_handle_param_response(pRecvMsg, recvMsgLen, config, p5_idx);
break;
case NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE:
vnf_nr_handle_config_response(pRecvMsg, recvMsgLen, config, p5_idx);
break;
case NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE:
vnf_nr_handle_start_response(pRecvMsg, recvMsgLen, config, p5_idx);
break;
case NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE:
vnf_handle_stop_response(pRecvMsg, recvMsgLen, config, p5_idx);
break;
default:
{
if(messageHeader.message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
messageHeader.message_id <= NFAPI_VENDOR_EXT_MSG_MAX)
{
vnf_handle_vendor_extension(pRecvMsg, recvMsgLen, config, p5_idx, messageHeader.message_id);
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s P5 Unknown message ID %d\n", __FUNCTION__, messageHeader.message_id);
}
}
break;
}
}
void vnf_handle_p4_p5_message(void *pRecvMsg, int recvMsgLen, int p5_idx, nfapi_vnf_config_t* config)
{
nfapi_p4_p5_message_header_t messageHeader;
@@ -926,6 +1239,137 @@ void vnf_handle_p4_p5_message(void *pRecvMsg, int recvMsgLen, int p5_idx, nfapi_
break;
}
}
int vnf_nr_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t* pnf)
{
if(1)
{
int socket_connected = 1;
// 1. Peek the message header
// 2. If the message is larger than the stack buffer then create a dynamic buffer
// 3. Read the buffer
// 4. Handle the p5 message
uint32_t header_buffer_size = NFAPI_HEADER_LENGTH;
uint8_t header_buffer[header_buffer_size];
uint32_t stack_buffer_size = 32; //should it be the size of then sctp_notificatoin structure
uint8_t stack_buffer[stack_buffer_size];
uint8_t* dynamic_buffer = 0;
uint8_t* read_buffer = &stack_buffer[0];
uint32_t message_size = 0;
struct sockaddr_in addr;
socklen_t addr_len = sizeof(addr);
struct sctp_sndrcvinfo sndrcvinfo;
(void)memset(&sndrcvinfo, 0, sizeof(struct sctp_sndrcvinfo));
{
int flags = MSG_PEEK;
message_size = sctp_recvmsg(pnf->p5_sock, header_buffer, header_buffer_size, (struct sockaddr*)&addr, &addr_len, &sndrcvinfo, &flags);
if(message_size == -1)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF Failed to peek sctp message size errno:%d\n", errno);
return 0;
}
nfapi_p4_p5_message_header_t header;
int unpack_result = nfapi_p5_message_header_unpack(header_buffer, header_buffer_size, &header, sizeof(header), 0);
if(unpack_result < 0)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF Failed to decode message header %d\n", unpack_result);
return 0;
}
message_size = header.message_length;
// now have the size of the mesage
}
if(message_size > stack_buffer_size)
{
dynamic_buffer = (uint8_t*)malloc(message_size);
if(dynamic_buffer == NULL)
{
// todo : add error mesage
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF Failed to allocate dynamic buffer for sctp_recvmsg size:%d\n", message_size);
return -1;
}
read_buffer = dynamic_buffer;
}
{
int flags = 0;
(void)memset(&sndrcvinfo, 0, sizeof(struct sctp_sndrcvinfo));
int recvmsg_result = sctp_recvmsg(pnf->p5_sock, read_buffer, message_size, (struct sockaddr*)&addr, &addr_len, &sndrcvinfo, &flags);
if(recvmsg_result == -1)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "Failed to read sctp message size errno:%d\n", errno);
}
else
{
if (flags & MSG_NOTIFICATION)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "Notification received from %s:%u\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
// todo - handle the events
}
else
{
/*
NFAPI_TRACE(NFAPI_TRACE_INFO, "Received message fd:%d from %s:%u assoc:%d on stream %d, PPID %d, length %d, flags 0x%x\n",
pnf->p5_sock,
inet_ntoa(addr.sin_addr),
ntohs(addr.sin_port),
sndrcvinfo.sinfo_assoc_id,
sndrcvinfo.sinfo_stream,
ntohl(sndrcvinfo.sinfo_ppid),
message_size,
flags);
*/
// handle now if complete message in one or more segments
if ((flags & 0x80) == 0x80)
{
// printf("\nVNF RECEIVES:\n");
// for(int i=0; i<message_size; i++){
// printf("%d", read_buffer[i]);
// }
// printf("\n");
vnf_nr_handle_p4_p5_message(read_buffer, message_size, pnf->p5_idx, config);
}
else
{
NFAPI_TRACE(NFAPI_TRACE_WARN, "sctp_recvmsg: unhandled mode with flags 0x%x\n", flags);
// assume socket disconnected
NFAPI_TRACE(NFAPI_TRACE_WARN, "Disconnected socket\n");
socket_connected = 0;
}
}
}
}
if(dynamic_buffer)
{
free(dynamic_buffer);
}
return socket_connected;
}
}
int vnf_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t* pnf)
{
if(1)
@@ -1024,6 +1468,12 @@ int vnf_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t*
// handle now if complete message in one or more segments
if ((flags & 0x80) == 0x80)
{
// printf("\nVNF RECEIVES:\n");
// for(int i=0; i<message_size; i++){
// printf("%d", read_buffer[i]);
// }
// printf("\n");
vnf_handle_p4_p5_message(read_buffer, message_size, pnf->p5_idx, config);
}
else
@@ -1051,6 +1501,12 @@ int vnf_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t*
static int vnf_send_p5_msg(nfapi_vnf_pnf_info_t* pnf, const void *msg, int len, uint8_t stream)
{
// printf("\n MESSAGE SENT: \n");
// for(int i=0; i<len; i++){
// printf("%d", *(uint8_t *)(msg + i));
// }
// printf("\n");
//NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s len:%d stream:%d\n", __FUNCTION__, len, stream);
int result = sctp_sendmsg(pnf->p5_sock, msg, len, (struct sockaddr*)&pnf->p5_pnf_sockaddr, sizeof(pnf->p5_pnf_sockaddr),1, 0, stream, 0, 4);
@@ -1071,6 +1527,29 @@ static int vnf_send_p5_msg(nfapi_vnf_pnf_info_t* pnf, const void *msg, int len,
return 0;
}
int vnf_nr_pack_and_send_p5_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_message_header_t* msg, uint16_t msg_len)
{
nfapi_vnf_pnf_info_t* pnf = nfapi_vnf_pnf_list_find(&(vnf->_public), p5_idx);
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);
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;
}
}
int vnf_pack_and_send_p5_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_message_header_t* msg, uint16_t msg_len)
{
+500 -2
View File
@@ -63,6 +63,418 @@ void nfapi_vnf_config_destory(nfapi_vnf_config_t* config)
free(config);
}
int nfapi_nr_vnf_start(nfapi_vnf_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 = (nfapi_trace_fn_t)config->trace;
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s()\n", __FUNCTION__);
int p5ListenSock, p5Sock;
struct sockaddr_in addr;
socklen_t addrSize;
struct sockaddr_in6 addr6;
struct sctp_event_subscribe events;
struct sctp_initmsg initMsg;
int noDelay;
(void)memset(&addr, 0, sizeof(struct sockaddr_in));
(void)memset(&addr6, 0, sizeof(struct sockaddr_in6));
(void)memset(&events, 0, sizeof(struct sctp_event_subscribe));
(void)memset(&initMsg, 0, sizeof(struct sctp_initmsg));
vnf_t* vnf = (vnf_t*)(config);
NFAPI_TRACE(NFAPI_TRACE_INFO, "Starting P5 VNF connection on port %u\n", config->vnf_p5_port);
/*
char * host = 0;
char * port = "4242";
struct addrinfo hints;
bzero(&hints, sizeof(struct addrinfo));
//hints.ai_flags=AI_PASSIVE;
//hints.ai_flags=AI_DEFAULT;
hints.ai_family=AF_UNSPEC;
//hints.ai_family=AF_INET6;
hints.ai_socktype=SOCK_STREAM;
//hints.ai_protocol=IPPROTO_SCTP
struct addrinfo *aiHead = 0;
int result = getaddrinfo(host, port, &hints, &aiHead);
NFAPI_TRACE(NFAPI_TRACE_INFO, "getaddrinfo return %d %d\n", result, errno);
while(aiHead->ai_next != NULL)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "addr info %d (IP %d UDP %d SCTP %d)\n %d (%d)\n",
aiHead->ai_protocol, IPPROTO_IP, IPPROTO_UDP, IPPROTO_SCTP,
aiHead->ai_flags, AI_PASSIVE);
char hostBfr[ NI_MAXHOST ];
char servBfr[ NI_MAXSERV ];
getnameinfo(aiHead->ai_addr,
aiHead->ai_addrlen,
hostBfr,
sizeof( hostBfr ),
servBfr,
sizeof( servBfr ),
NI_NUMERICHOST | NI_NUMERICSERV );
switch(aiHead->ai_family)
{
case PF_INET:
{
struct sockaddr_in *pSadrIn = (struct sockaddr_in*) aiHead->ai_addr;
printf(
" ai_addr = sin_family: %d (AF_INET = %d, "
"AF_INET6 = %d)\n"
" sin_addr: %s\n"
" sin_port: %s\n",
pSadrIn->sin_family,
AF_INET,
AF_INET6,
hostBfr,
servBfr );
}
break;
case PF_INET6:
{
struct sockaddr_in6 *pSadrIn6 = (struct sockaddr_in6*) aiHead->ai_addr;
fprintf( stderr,
" ai_addr = sin6_family: %d (AF_INET = %d, "
"AF_INET6 = %d) \n"
" sin6_addr: %s\n"
" sin6_port: %s\n"
" sin6_flowinfo: %d\n"
" sin6_scope_id: %d\n",
pSadrIn6->sin6_family,
AF_INET,
AF_INET6,
hostBfr,
servBfr,
pSadrIn6->sin6_flowinfo,
pSadrIn6->sin6_scope_id);
}
break;
default:
NFAPI_TRACE(NFAPI_TRACE_INFO, "Not ment to be here\n");
break;
}
aiHead = aiHead->ai_next;
}
*/
{
int protocol;
int domain;
if (vnf->sctp)
protocol = IPPROTO_SCTP;
else
protocol = IPPROTO_IP;
if(config->vnf_ipv6)
{
domain = PF_INET6;
}
else
{
domain = AF_INET;
}
// open the SCTP socket
if ((p5ListenSock = socket(domain, SOCK_STREAM, protocol)) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After P5 socket errno: %d\n", errno);
return 0;
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "P5 socket created... %d\n", p5ListenSock);
}
if (vnf->sctp)
{
// configure for MSG_NOTIFICATION
if (setsockopt(p5ListenSock, IPPROTO_SCTP, SCTP_EVENTS, &events, sizeof(struct sctp_event_subscribe)) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt (SCTP_EVENTS) errno: %d\n", errno);
close(p5ListenSock);
return 0;
}
NFAPI_TRACE(NFAPI_TRACE_NOTE, "VNF Setting the SCTP_INITMSG\n");
// configure the SCTP socket options
initMsg.sinit_num_ostreams = 5; //MAX_SCTP_STREAMS; // number of output streams can be greater
initMsg.sinit_max_instreams = 5; //MAX_SCTP_STREAMS; // number of output streams can be greater
if (setsockopt(p5ListenSock, IPPROTO_SCTP, SCTP_INITMSG, &initMsg, sizeof(initMsg)) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt (SCTP_INITMSG) errno: %d\n", errno)
close(p5ListenSock);
return 0;
}
noDelay = 1;
if (setsockopt(p5ListenSock, IPPROTO_SCTP, SCTP_NODELAY, &noDelay, sizeof(noDelay)) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt (STCP_NODELAY) errno: %d\n", errno);
close(p5ListenSock);
return 0;
}
struct sctp_event_subscribe events;
memset( (void *)&events, 0, sizeof(events) );
events.sctp_data_io_event = 1;
if(setsockopt(p5ListenSock, SOL_SCTP, SCTP_EVENTS, (const void *)&events, sizeof(events)) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt errno: %d\n", errno);
close(p5ListenSock);
return -1;
}
}
if(config->vnf_ipv6)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "IPV6 binding to port %d %d\n", config->vnf_p5_port, p5ListenSock);
addr6.sin6_family = AF_INET6;
addr6.sin6_port = htons(config->vnf_p5_port);
addr6.sin6_addr = in6addr_any;
// bind to the configured address and port
if (bind(p5ListenSock, (struct sockaddr *)&addr6, sizeof(struct sockaddr_in6)) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After bind errno: %d\n", errno);
close(p5ListenSock);
return 0;
}
}
else if(config->vnf_ipv4)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "IPV4 binding to port %d\n", config->vnf_p5_port);
addr.sin_family = AF_INET;
addr.sin_port = htons(config->vnf_p5_port);
addr.sin_addr.s_addr = INADDR_ANY;
// bind to the configured address and port
if (bind(p5ListenSock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0)
//if (sctp_bindx(p5ListenSock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in), SCTP_BINDX_ADD_ADDR) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After bind errno: %d\n", errno);
close(p5ListenSock);
return 0;
}
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "bind succeeded..%d.\n", p5ListenSock);
// put the socket into listen mode
if (listen(p5ListenSock, 2) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After listen errno: %d\n", errno);
close(p5ListenSock);
return 0;
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "listen succeeded...\n");
struct timeval tv;
fd_set read_fd_set;
int p5_idx = 0;
while(vnf->terminate == 0)
{
FD_ZERO(&read_fd_set);
FD_SET(p5ListenSock, &read_fd_set);
int max_fd = p5ListenSock;
tv.tv_sec = 5;
tv.tv_usec = 0;
nfapi_vnf_pnf_info_t* pnf = config->pnf_list;
while(pnf != 0)
{
if(pnf->connected)
{
FD_SET(pnf->p5_sock, &read_fd_set);
if (pnf->p5_sock > max_fd)
{
max_fd = pnf->p5_sock;
}
}
pnf = pnf->next;
}
int select_result = select(max_fd + 1, &read_fd_set, 0, 0, &tv);
if(select_result == -1)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "select result %d errno %d\n", select_result, errno);
close(p5ListenSock);
return 0;
}
else if(select_result)
{
if(FD_ISSET(p5ListenSock, &read_fd_set))
{
addrSize = sizeof(struct sockaddr_in);
NFAPI_TRACE(NFAPI_TRACE_INFO, "Accepting connection from PNF...\n");
p5Sock = accept(p5ListenSock, (struct sockaddr *)&addr, &addrSize);
if (p5Sock < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to accept PNF connection reason:%d\n", errno);
}
else
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF connection (fd:%d) accepted from %s:%d \n", p5Sock, inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
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_sock = p5Sock;
pnf->p5_idx = p5_idx++;
pnf->p5_pnf_sockaddr = addr;
pnf->connected = 1;
nfapi_vnf_pnf_list_add(config, pnf);
// Inform mac that a pnf connection has been established
// todo : allow mac to 'accept' the connection. i.e. to
// reject it.
if(config->pnf_nr_connection_indication != 0)
{
(config->pnf_nr_connection_indication)(config, pnf->p5_idx);
}
// check the connection status
{
struct sctp_status status;
(void)memset(&status, 0, sizeof(struct sctp_status));
socklen_t optLen = (socklen_t) sizeof(struct sctp_status);
if (getsockopt(p5Sock, IPPROTO_SCTP, SCTP_STATUS, &status, &optLen) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After getsockopt errno: %d\n", errno);
return -1;
}
else
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF Association ID = %d\n", status.sstat_assoc_id);
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF Receiver window size = %d\n", status.sstat_rwnd);
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF In Streams = %d\n", status.sstat_instrms);
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF Out Streams = %d\n", status.sstat_outstrms);
}
}
}
}
else
{
uint8_t delete_pnfs = 0;
nfapi_vnf_pnf_info_t* pnf = config->pnf_list;
while(pnf != 0)
{
if(FD_ISSET(pnf->p5_sock, &read_fd_set))
{
if(vnf_nr_read_dispatch_message(config, pnf) == 0)
{
if(config->pnf_disconnect_indication != 0)
{
(config->pnf_disconnect_indication)(config, pnf->p5_idx);
}
close(pnf->p5_sock);
pnf->to_delete = 1;
delete_pnfs = 1;
}
}
pnf = pnf->next;
}
if(delete_pnfs)
{
nfapi_vnf_pnf_info_t* pnf = config->pnf_list;
nfapi_vnf_pnf_info_t* prev = 0;
while(pnf != 0)
{
nfapi_vnf_pnf_info_t* curr = pnf;
if(pnf->to_delete == 1)
{
if(prev == 0)
{
config->pnf_list = pnf->next;
}
else
{
prev->next = pnf->next;
}
pnf = pnf->next;
free(curr);
}
else
{
prev = pnf;
pnf = pnf->next;
}
}
}
}
continue;
}
else
{
// timeout
// Should we test for socket closure here every second?
continue;
}
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "Closing p5Sock socket's\n");
{
nfapi_vnf_pnf_info_t* curr = config->pnf_list;
while(curr != NULL)
{
if(config->pnf_disconnect_indication)
{
(config->pnf_disconnect_indication)(config, curr->p5_idx);
}
close(curr->p5_sock);
curr = curr->next;
}
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "Closing p5Listen socket\n");
close(p5ListenSock);
return 0;
}
int nfapi_vnf_start(nfapi_vnf_config_t* config)
{
// Verify that config is not null
@@ -486,6 +898,16 @@ int nfapi_vnf_stop(nfapi_vnf_config_t* config)
return 0;
}
int nfapi_nr_vnf_pnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_pnf_param_request_t* req)
{
if(config == 0 || req == 0)
return -1;
vnf_t* _this = (vnf_t*)(config);
return vnf_nr_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_nr_pnf_param_request_t));
}
int nfapi_vnf_pnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_param_request_t* req)
{
if(config == 0 || req == 0)
@@ -496,6 +918,17 @@ int nfapi_vnf_pnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_pa
return vnf_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_pnf_param_request_t));
}
int nfapi_nr_vnf_pnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_pnf_config_request_t* req)
{
if(config == 0 || req == 0)
return -1;
vnf_t* _this = (vnf_t*)(config);
return vnf_nr_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_nr_pnf_config_request_t));
}
int nfapi_vnf_pnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_config_request_t* req)
{
if(config == 0 || req == 0)
@@ -516,6 +949,16 @@ int nfapi_vnf_pnf_start_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_st
return vnf_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_pnf_start_request_t));
}
int nfapi_nr_vnf_pnf_start_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_pnf_start_request_t* req)
{
if(config == 0 || req == 0)
return -1;
vnf_t* _this = (vnf_t*)(config);
return vnf_nr_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_nr_pnf_start_request_t));
}
int nfapi_vnf_pnf_stop_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_stop_request_t* req)
{
if(config == 0 || req == 0)
@@ -526,6 +969,16 @@ int nfapi_vnf_pnf_stop_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_sto
return vnf_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_pnf_stop_request_t));
}
int nfapi_nr_vnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_param_request_scf_t* req)
{
if(config == 0 || req == 0)
return -1;
vnf_t* _this = (vnf_t*)(config);
return vnf_nr_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_nr_param_request_scf_t));
}
int nfapi_vnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_param_request_t* req)
{
if(config == 0 || req == 0)
@@ -535,6 +988,38 @@ int nfapi_vnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_param_requ
return vnf_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_param_request_t));
}
int nfapi_nr_vnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_config_request_scf_t* req)
{
if(config == 0 || req == 0)
return -1;
vnf_t* _this = (vnf_t*)(config);
nfapi_vnf_phy_info_t* phy = nfapi_vnf_phy_info_list_find(config, req->header.phy_id);
if(phy == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_WARN, "%s failed to find phy information phy_id:%d\n", __FUNCTION__, req->header.phy_id);
return -1;
}
// set the timing parameters
req->nfapi_config.timing_window.tl.tag = NFAPI_NR_NFAPI_TIMING_WINDOW_TAG;
req->nfapi_config.timing_window.value = phy->timing_window;
req->num_tlv++;
req->nfapi_config.timing_info_mode.tl.tag = NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG;
req->nfapi_config.timing_info_mode.value = phy->timing_info_mode;
req->num_tlv++;
req->nfapi_config.timing_info_period.tl.tag = NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG;
req->nfapi_config.timing_info_period.value = phy->timing_info_period;
req->num_tlv++;
return vnf_nr_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_nr_config_request_scf_t));
}
int nfapi_vnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_config_request_t* req)
{
if(config == 0 || req == 0)
@@ -565,7 +1050,8 @@ int nfapi_vnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_config_re
return vnf_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_config_request_t));
}
int nfapi_vnf_start_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_start_request_t* req)
int nfapi_vnf_start_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_start_request_t * req)
{
if(config == 0 || req == 0)
return -1;
@@ -574,6 +1060,18 @@ int nfapi_vnf_start_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_start_requ
return vnf_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_start_request_t));
}
int nfapi_nr_vnf_start_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_start_request_scf_t * req)
{
if(config == 0 || req == 0)
return -1;
vnf_t* _this = (vnf_t*)(config);
return vnf_nr_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_nr_start_request_scf_t));
}
int nfapi_vnf_stop_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_stop_request_t* req)
{
if(config == 0 || req == 0)
@@ -664,7 +1162,7 @@ int nfapi_vnf_allocate_phy(nfapi_vnf_config_t* config, int p5_idx, uint16_t* phy
info->p5_idx = p5_idx;
info->phy_id = vnf->next_phy_id++;
info->timing_window = 30; // This seems to override what gets set by the user - why???
info->timing_window = 30; // This seems to override what gets set by the user - why??? //TODO: Change in NR in terms of microsecends,what should be the value?
info->timing_info_mode = 0x03;
info->timing_info_period = 128;
File diff suppressed because it is too large Load Diff
+395 -5
View File
@@ -28,6 +28,7 @@
#define FAPI2_IP_DSCP 0
nfapi_vnf_p7_config_t* nfapi_vnf_p7_config_create()
{
vnf_p7_t* _this = (vnf_p7_t*)calloc(1, sizeof(vnf_p7_t));
@@ -90,6 +91,368 @@ struct timespec timespec_sub(struct timespec lhs, struct timespec rhs)
// monitor the p7 endpoints and the timing loop and
// send indications to mac
int 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);
// open the UDP socket
if ((vnf_p7->socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After P7 socket errno: %d\n", errno);
return -1;
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF P7 socket created...\n");
// configure the UDP socket options
int iptos_value = FAPI2_IP_DSCP << 2;
if (setsockopt(vnf_p7->socket, IPPROTO_IP, IP_TOS, &iptos_value, sizeof(iptos_value)) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt (IP_TOS) errno: %d\n", errno);
return -1;
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF P7 setsockopt succeeded...\n");
// Create the address structure
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(config->port);
addr.sin_addr.s_addr = INADDR_ANY;
// bind to the configured port
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF P7 binding too %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
if (bind(vnf_p7->socket, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0)
//if (sctp_bindx(config->socket, (struct sockaddr *)&addr, sizeof(struct sockaddr_in), 0) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After bind errno: %d\n", errno);
return -1;
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF P7 bind succeeded...\n");
//struct timespec original_pselect_timeout;
struct timespec pselect_timeout;
pselect_timeout.tv_sec = 0;
pselect_timeout.tv_nsec = 500000; // ns in a 0.5 ms
//pselect_timeout.tv_nsec = 500000;
struct timespec pselect_start;
struct timespec pselect_stop;
//struct timespec sf_end;
long last_millisecond = -1;
// struct timespec sf_duration; //Change to slot_duration?
// sf_duration.tv_sec = 0;
// sf_duration.tv_nsec = 0.5e6; // We want 1ms pause //We want 0.5 ms pause for NR
struct timespec slot_duration;
slot_duration.tv_sec = 0;
//slot_duration.tv_nsec = 0.5e6;
slot_duration.tv_nsec = 0.5e6;
// struct timespec sf_start; //Change to slot_start?
struct timespec slot_start;
// clock_gettime(CLOCK_MONOTONIC, &sf_start);
clock_gettime(CLOCK_MONOTONIC, &slot_start);
long millisecond = slot_start.tv_nsec / 1e6; //Check if we have to change
//long millisecond = slot_start.tv_nsec / 0.5e6;
// sf_start = timespec_add(sf_start, sf_duration);
slot_start = timespec_add(slot_start, slot_duration);
NFAPI_TRACE(NFAPI_TRACE_INFO, "next slot will start at %d.%d\n", slot_start.tv_sec, slot_start.tv_nsec);
while(vnf_p7->terminate == 0)
{
fd_set rfds;
int maxSock = 0;
FD_ZERO(&rfds);
int selectRetval = 0;
// Add the p7 socket
FD_SET(vnf_p7->socket, &rfds);
maxSock = vnf_p7->socket;
clock_gettime(CLOCK_MONOTONIC, &pselect_start);
//long millisecond = pselect_start.tv_nsec / 1e6;
if((last_millisecond == -1) || (millisecond == last_millisecond) || (millisecond == (last_millisecond + 1) % 1000) )
{
//NFAPI_TRACE(NFAPI_TRACE_INFO, "pselect_start:%d.%d sf_start:%d.%d\n", pselect_start.tv_sec, pselect_start.tv_nsec, sf_start.tv_sec, sf_start.tv_nsec);
//if((pselect_start.tv_sec > sf_start.tv_sec) ||
// ((pselect_start.tv_sec == sf_start.tv_sec) && (pselect_start.tv_nsec > sf_start.tv_nsec)))
if((pselect_start.tv_sec > slot_start.tv_sec) || ((pselect_start.tv_sec == slot_start.tv_sec) && (pselect_start.tv_nsec > slot_start.tv_nsec)))
{
// overran the end of the subframe we do not want to wait
pselect_timeout.tv_sec = 0;
pselect_timeout.tv_nsec = 0;
//struct timespec overrun = timespec_sub(pselect_start, sf_start);
//NFAPI_TRACE(NFAPI_TRACE_INFO, "Subframe overrun detected of %d.%d running to catchup\n", overrun.tv_sec, overrun.tv_nsec);
}
else
{
// still time before the end of the subframe wait
//pselect_timeout = timespec_sub(sf_start, pselect_start);
pselect_timeout = timespec_sub(slot_start, pselect_start);
}
//original_pselect_timeout = pselect_timeout;
// detemine how long to sleep in ns before the start of the next 1ms
//pselect_timeout.tv_nsec = 1e6 - (pselect_start.tv_nsec % 1000000);
//uint8_t underrun_possible =0;
// if we are not sleeping until the next milisecond due to the
// insycn minor adjment flag it so we don't consider it an error
//uint8_t underrun_possible =0;
/*
{
nfapi_vnf_p7_connection_info_t* phy = vnf_p7->p7_connections;
if(phy && phy->in_sync && phy->insync_minor_adjustment != 0 && phy->insync_minor_adjustment_duration > 0 && pselect_start.tv_nsec != 0)
{
NFAPI_TRACE(NFAPI_TRACE_NOTE, "[VNF] Subframe minor adjustment %d (%d->%d)\n", phy->insync_minor_adjustment,
pselect_timeout.tv_nsec, pselect_timeout.tv_nsec - (phy->insync_minor_adjustment * 1000))
if(phy->insync_minor_adjustment > 0)
{
// todo check we don't go below 0
if((phy->insync_minor_adjustment * 1000) > pselect_timeout.tv_nsec)
pselect_timeout.tv_nsec = 0;
else
pselect_timeout.tv_nsec = pselect_timeout.tv_nsec - (phy->insync_minor_adjustment * 1000);
//underrun_possible = 1;
}
else if(phy->insync_minor_adjustment < 0)
{
// todo check we don't go below 0
pselect_timeout.tv_nsec = pselect_timeout.tv_nsec - (phy->insync_minor_adjustment * 1000);
//phy->insync_minor_adjustment = 0;
phy->insync_minor_adjustment_duration--;
}
}
*/
//long wraps = pselect_timeout.tv_nsec % 1e9;
selectRetval = pselect(maxSock+1, &rfds, NULL, NULL, &pselect_timeout, NULL);
// selectRetval = pselect(120, &rfds, NULL, NULL, &pselect_timeout, NULL);
clock_gettime(CLOCK_MONOTONIC, &pselect_stop);
nfapi_vnf_p7_connection_info_t* phy = vnf_p7->p7_connections;
if (selectRetval==-1 && errno == 22)
{
// NFAPI_TRACE(NFAPI_TRACE_ERROR, "INVAL: pselect_timeout:%d.%ld adj[dur:%d adj:%d], sf_dur:%d.%ld\n",
// pselect_timeout.tv_sec, pselect_timeout.tv_nsec,
// phy->insync_minor_adjustment_duration, phy->insync_minor_adjustment,
// sf_duration.tv_sec, sf_duration.tv_nsec);
NFAPI_TRACE(NFAPI_TRACE_ERROR, "INVAL: pselect_timeout:%d.%ld adj[dur:%d adj:%d], sf_dur:%d.%ld\n",
pselect_timeout.tv_sec, pselect_timeout.tv_nsec,
phy->insync_minor_adjustment_duration, phy->insync_minor_adjustment,
slot_duration.tv_sec, slot_duration.tv_nsec);
}
if(selectRetval == 0)
{
// calculate the start of the next slot
//sf_start = timespec_add(sf_start, sf_duration);
slot_start = timespec_add(slot_start, slot_duration);
//NFAPI_TRACE(NFAPI_TRACE_INFO, "next subframe will start at %d.%d\n", sf_start.tv_sec, sf_start.tv_nsec);
if(phy && phy->in_sync && phy->insync_minor_adjustment != 0 && phy->insync_minor_adjustment_duration > 0)
{
long insync_minor_adjustment_ns = (phy->insync_minor_adjustment * 1000);
//sf_start.tv_nsec -= insync_minor_adjustment_ns;
slot_start.tv_nsec -= insync_minor_adjustment_ns;
#if 1
/* if (sf_start.tv_nsec > 1e9) //Change to 0.5e6?
{
sf_start.tv_sec++;
sf_start.tv_nsec-=1e9;
}
else if (sf_start.tv_nsec < 0)
{
sf_start.tv_sec--;
sf_start.tv_nsec+=1e9;
}*/
if (slot_start.tv_nsec > 1e9)
{
slot_start.tv_sec++;
slot_start.tv_nsec-=1e9;
}
else if (slot_start.tv_nsec < 0)
{
slot_start.tv_sec--;
slot_start.tv_nsec+=1e9;
}
#else
//NFAPI_TRACE(NFAPI_TRACE_NOTE, "[VNF] BEFORE adjustment - Subframe minor adjustment %dus sf_start.tv_nsec:%d\n", phy->insync_minor_adjustment, sf_start.tv_nsec);
if(phy->insync_minor_adjustment > 0)
{
// decrease the subframe duration a little
if (sf_start.tv_nsec > insync_minor_adjustment_ns)
sf_start.tv_nsec -= insync_minor_adjustment_ns;
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "[VNF] Adjustment would make it negative sf:%d.%ld adjust:%ld\n\n\n", sf_start.tv_sec, sf_start.tv_nsec, insync_minor_adjustment_ns);
sf_start.tv_sec--;
sf_start.tv_nsec += 1e9 - insync_minor_adjustment_ns;
}
}
else if(phy->insync_minor_adjustment < 0)
{
// todo check we don't go below 0
// increase the subframe duration a little
sf_start.tv_nsec += insync_minor_adjustment_ns;
if (sf_start.tv_nsec < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "[VNF] OVERFLOW %d.%ld\n\n\n\n", sf_start.tv_sec, sf_start.tv_nsec);
sf_start.tv_sec++;
sf_start.tv_nsec += 1e9;
}
}
#endif
//phy->insync_minor_adjustment = 0;
phy->insync_minor_adjustment_duration--;
// NFAPI_TRACE(NFAPI_TRACE_NOTE, "[VNF] AFTER adjustment - Subframe minor adjustment %dus sf_start.tv_nsec:%d duration:%u\n",
// phy->insync_minor_adjustment, sf_start.tv_nsec, phy->insync_minor_adjustment_duration);
// NFAPI_TRACE(NFAPI_TRACE_NOTE, "[VNF] AFTER adjustment - Slot minor adjustment %dus slot_start.tv_nsec:%d duration:%u\n",
// phy->insync_minor_adjustment, slot_start.tv_nsec, phy->insync_minor_adjustment_duration);
if (phy->insync_minor_adjustment_duration==0)
{
phy->insync_minor_adjustment = 0;
}
}
/*
long pselect_stop_millisecond = pselect_stop.tv_nsec / 1e6;
if(millisecond == pselect_stop_millisecond)
{
// we have woke up in the same subframe
if(underrun_possible == 0)
NFAPI_TRACE(NFAPI_TRACE_WARN, "subframe pselect underrun %ld (%d.%d)\n", millisecond, pselect_stop.tv_sec, pselect_stop.tv_nsec);
}
else if(((millisecond + 1) % 1000) != pselect_stop_millisecond)
{
// we have overrun the subframe
NFAPI_TRACE(NFAPI_TRACE_WARN, "subframe pselect overrun %ld %ld\n", millisecond, pselect_stop_millisecond);
NFAPI_TRACE(NFAPI_TRACE_WARN, "subframe underrun %ld\n", millisecond);
}
last_millisecond = millisecond;
*/
//millisecond ++;
millisecond = millisecond + 1;
}
}
else
{
// we have overrun the subframe advance to go and collect $200
if((millisecond - last_millisecond) > 3)
NFAPI_TRACE(NFAPI_TRACE_WARN, "subframe overrun %ld %ld (%ld)\n", millisecond, last_millisecond, millisecond - last_millisecond + 1);
last_millisecond = ( last_millisecond + 1 ) % 1000;
selectRetval = 0;
}
if(selectRetval == 0)
{
//vnf_p7->sf_start_time_hr = vnf_get_current_time_hr();
vnf_p7->slot_start_time_hr = vnf_get_current_time_hr();
struct timespec current_time;
clock_gettime(CLOCK_MONOTONIC, &current_time);
// pselect timed out
nfapi_vnf_p7_connection_info_t* curr = vnf_p7->p7_connections;
while(curr != 0)
{
if (curr->slot == 19)
{ //curr->slot = 0;
if(curr->sfn == 1023)
curr->sfn=0;
else
curr->sfn++;
curr->slot=0;
}
else
{
curr->slot++;
}
vnf_nr_sync(vnf_p7, curr);
curr = curr->next;
}
send_mac_slot_indications(vnf_p7);
}
else if(selectRetval > 0)
{
// have a p7 message
if(FD_ISSET(vnf_p7->socket, &rfds))
{
vnf_nr_p7_read_dispatch_message(vnf_p7);
}
}
else
{
// pselect error
if(selectRetval == -1 && errno == EINTR)
{
// a sigal was received.
}
else
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "P7 select failed result %d errno %d timeout:%d.%d orginal:%d.%d last_ms:%ld ms:%ld\n", selectRetval, errno, pselect_timeout.tv_sec, pselect_timeout.tv_nsec, pselect_timeout.tv_sec, pselect_timeout.tv_nsec, last_millisecond, millisecond);
// should we exit now?
if (selectRetval == -1 && errno == 22) // invalid argument??? not sure about timeout duration
{
usleep(100000);
}
}
}
}
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 nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config)
{
if(config == 0)
@@ -408,6 +771,7 @@ if (selectRetval==-1 && errno == 22)
return 0;
}
int nfapi_vnf_p7_stop(nfapi_vnf_p7_config_t* config)
{
if(config == 0)
@@ -434,17 +798,18 @@ int nfapi_vnf_p7_add_pnf(nfapi_vnf_p7_config_t* config, const char* pnf_p7_addr,
memset(node, 0, sizeof(nfapi_vnf_p7_connection_info_t));
node->phy_id = phy_id;
node->in_sync = 0;
node->dl_out_sync_offset = 30;
node->dl_out_sync_offset = 30;//TODO: Values need to be changed for NR,How to set the values
node->dl_out_sync_period = 10;
node->dl_in_sync_offset = 30;
node->dl_in_sync_period = 512;
node->sfn_sf = 0;
//node->sfn_sf = 0;
node->sfn = 0;
node->slot = 0;
node->min_sync_cycle_count = 8;
// save the remote endpoint information
node->remote_addr.sin_family = AF_INET;
node->remote_addr.sin_port = htons(pnf_p7_port);
node->remote_addr.sin_port = pnf_p7_port;//htons(pnf_p7_port);
node->remote_addr.sin_addr.s_addr = inet_addr(pnf_p7_addr);
vnf_p7_connection_info_list_add(vnf_p7, node);
@@ -490,7 +855,16 @@ int nfapi_vnf_p7_nr_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_nr_dl_tti
return -1;
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
return vnf_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
return vnf_nr_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
}
int nfapi_vnf_p7_ul_tti_req(nfapi_vnf_p7_config_t* config, nfapi_nr_ul_tti_request_t* req)
{
if(config == 0 || req == 0)
return -1;
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
return vnf_nr_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
}
int nfapi_vnf_p7_ul_config_req(nfapi_vnf_p7_config_t* config, nfapi_ul_config_request_t* req)
@@ -501,6 +875,14 @@ int nfapi_vnf_p7_ul_config_req(nfapi_vnf_p7_config_t* config, nfapi_ul_config_re
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
return vnf_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
}
int nfapi_vnf_p7_ul_dci_req(nfapi_vnf_p7_config_t* config, nfapi_nr_ul_dci_request_t* req)
{
if(config == 0 || req == 0)
return -1;
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
return vnf_nr_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
}
int nfapi_vnf_p7_hi_dci0_req(nfapi_vnf_p7_config_t* config, nfapi_hi_dci0_request_t* req)
{
if(config == 0 || req == 0)
@@ -509,6 +891,14 @@ int nfapi_vnf_p7_hi_dci0_req(nfapi_vnf_p7_config_t* config, nfapi_hi_dci0_reques
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
return vnf_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
}
int nfapi_vnf_p7_tx_data_req(nfapi_vnf_p7_config_t* config, nfapi_nr_tx_data_request_t* req)
{
if(config == 0 || req == 0)
return -1;
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
return vnf_nr_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
}
int nfapi_vnf_p7_tx_req(nfapi_vnf_p7_config_t* config, nfapi_tx_request_t* req)
{
if(config == 0 || req == 0)