Merge branch 'episys-merge' into episys/trial-merge-to-master
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
/*
|
||||
* Copyright 2017 Cisco Systems, Inc.
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -50,31 +50,17 @@ void nfapi_trace_dbg(nfapi_trace_level_t level, const char *format, ...)
|
||||
if (level < nfapi_trace_level_g)
|
||||
return;
|
||||
char trace_buff[MAX_MSG_LENGTH + TRACE_HEADER_LENGTH];
|
||||
uint32_t num_chars;
|
||||
va_list p_args;
|
||||
struct timeval tv;
|
||||
pthread_t tid = pthread_self();
|
||||
|
||||
(void)gettimeofday(&tv, NULL);
|
||||
|
||||
num_chars = (uint32_t)snprintf(trace_buff, TRACE_HEADER_LENGTH, "%04u.%06u: 0x%02x: %10u: ", ((uint32_t)tv.tv_sec) & 0x1FFF, (uint32_t)tv.tv_usec, (uint32_t)level, (uint32_t)tid);
|
||||
|
||||
if (num_chars > TRACE_HEADER_LENGTH)
|
||||
{
|
||||
printf("trace_dbg: Error, num_chars is too large: %d\n", num_chars);
|
||||
fflush(stdout);
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(trace_buff, sizeof(trace_buff), "%04u.%06u: 0x%02x: %10u: ", ((uint32_t)tv.tv_sec) & 0x1FFF, (uint32_t)tv.tv_usec, (uint32_t)level, (uint32_t)tid);
|
||||
int n = strlen(trace_buff);
|
||||
va_start(p_args, format);
|
||||
if ((num_chars = (uint32_t)vsnprintf(&trace_buff[num_chars], MAX_MSG_LENGTH, format, p_args)))
|
||||
{
|
||||
if (level <= NFAPI_TRACE_WARN)
|
||||
{
|
||||
printf("%s", trace_buff);
|
||||
}
|
||||
printf("%s", trace_buff);
|
||||
}
|
||||
vsnprintf(trace_buff + n, sizeof(trace_buff) - n, format, p_args);
|
||||
va_end(p_args);
|
||||
fputs(trace_buff, stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#define FAPI_NR_RX_PDU_TYPE_SIB 0x02
|
||||
#define FAPI_NR_RX_PDU_TYPE_DLSCH 0x03
|
||||
#define FAPI_NR_DCI_IND 0x04
|
||||
#define FAPI_NR_RX_PDU_TYPE_RAR 0x05
|
||||
|
||||
#define FAPI_NR_SIBS_MASK_SIB1 0x1
|
||||
|
||||
@@ -42,7 +43,8 @@
|
||||
|
||||
#define FAPI_NR_DL_CONFIG_TYPE_DCI 0x01
|
||||
#define FAPI_NR_DL_CONFIG_TYPE_DLSCH 0x02
|
||||
|
||||
#define FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH 0x03
|
||||
#define FAPI_NR_DL_CONFIG_TYPE_SI_DLSCH 0x04
|
||||
|
||||
#define FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED 0x01
|
||||
#define FAPI_NR_CCE_REG_MAPPING_TYPE_NON_INTERLEAVED 0x02
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "PHY/impl_defs_nr.h"
|
||||
|
||||
#define NFAPI_UE_MAX_NUM_CB 8
|
||||
#define NFAPI_MAX_NUM_UL_PDU 8
|
||||
|
||||
/*
|
||||
typedef unsigned int uint32_t;
|
||||
@@ -62,7 +63,7 @@ typedef struct {
|
||||
uint8_t CoreSetType;
|
||||
uint8_t precoder_granularity;
|
||||
uint16_t pdcch_dmrs_scrambling_id;
|
||||
|
||||
uint16_t scrambling_rnti;
|
||||
uint8_t tci_state_pdcch;
|
||||
uint8_t tci_present_in_dci;
|
||||
} fapi_nr_coreset_t;
|
||||
@@ -155,25 +156,35 @@ typedef struct {
|
||||
uint16_t slot;
|
||||
fapi_nr_tx_config_t tx_config;
|
||||
uint16_t number_of_pdus;
|
||||
fapi_nr_tx_request_body_t *tx_request_body;
|
||||
fapi_nr_tx_request_body_t tx_request_body[NFAPI_MAX_NUM_UL_PDU];
|
||||
} fapi_nr_tx_request_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t preamble_index;
|
||||
uint8_t prach_configuration_index;
|
||||
uint16_t preamble_length;
|
||||
uint8_t power_ramping_step;
|
||||
uint16_t preamble_received_target_power;
|
||||
uint8_t msg1_fdm;
|
||||
uint8_t msg1_frequency_start;
|
||||
uint8_t zero_correlation_zone_config;
|
||||
uint8_t subcarrier_spacing;
|
||||
uint8_t restrictedset_config;
|
||||
uint16_t root_sequence_index;
|
||||
uint16_t rsrp_threshold_ssb;
|
||||
uint16_t rsrp_threshold_sul;
|
||||
uint16_t prach_freq_offset;
|
||||
} fapi_nr_ul_config_prach_pdu;
|
||||
/// This struct replaces:
|
||||
/// PRACH-ConfigInfo from 38.331 RRC spec
|
||||
/// PRACH-ConfigSIB or PRACH-Config
|
||||
typedef struct {
|
||||
/// PHY cell ID
|
||||
uint16_t phys_cell_id;
|
||||
/// Num PRACH occasions
|
||||
uint8_t num_prach_ocas;
|
||||
/// PRACH format
|
||||
uint8_t prach_format;
|
||||
/// Num RA
|
||||
uint8_t num_ra;
|
||||
uint8_t prach_slot;
|
||||
uint8_t prach_start_symbol;
|
||||
/// 38.211 (NCS 38.211 6.3.3.1).
|
||||
uint16_t num_cs;
|
||||
/// Parameter: prach-rootSequenceIndex, see TS 38.211 (6.3.3.2).
|
||||
uint16_t root_seq_id;
|
||||
/// Parameter: High-speed-flag, see TS 38.211 (6.3.3.1). 1 corresponds to Restricted set and 0 to Unrestricted set.
|
||||
uint8_t restricted_set;
|
||||
/// see TS 38.211 (6.3.3.2).
|
||||
uint16_t freq_msg1;
|
||||
// When multiple SSBs per RO is configured, this indicates which one is selected in this RO -> this is used to properly compute the PRACH preamble
|
||||
uint8_t ssb_nb_in_ro;
|
||||
// nfapi_nr_ul_beamforming_t beamforming;
|
||||
} fapi_nr_ul_config_prach_pdu;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -408,8 +419,14 @@ typedef struct {
|
||||
uint8_t number_of_candidates;
|
||||
uint16_t CCE[64];
|
||||
uint8_t L[64];
|
||||
uint8_t dci_length;
|
||||
uint8_t dci_format;
|
||||
// 3GPP TS 38.212 Sec. 7.3.1.0, 3GPP TS 138.131 sec. 6.3.2 (SearchSpace)
|
||||
// The maximum number of DCI lengths allowed by the spec are 4, with max 3 for C-RNTI.
|
||||
// But a given search space may only support a maximum of 2 DCI formats at a time
|
||||
// depending on its search space type configured by RRC. Hence for blind decoding, UE
|
||||
// needs to monitor only upto 2 DCI lengths for a given search space.
|
||||
uint8_t num_dci_options; // Num DCIs the UE actually needs to decode (1 or 2)
|
||||
uint8_t dci_length_options[2];
|
||||
uint8_t dci_format_options[2];
|
||||
} fapi_nr_dl_config_dci_dl_pdu_rel15_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -455,6 +472,21 @@ typedef struct {
|
||||
uint8_t cbgti;
|
||||
uint8_t codeBlockGroupFlushIndicator;
|
||||
// to be check the fields needed to L1 with NR_DL_UE_HARQ_t and NR_UE_DLSCH_t
|
||||
// PTRS [TS38.214, sec 5.1.6.3]
|
||||
/// PT-RS antenna ports [TS38.214, sec 5.1.6.3] [TS38.211, table 7.4.1.2.2-1] Bitmap occupying the 6 LSBs with: bit 0: antenna port 1000 bit 5: antenna port 1005 and for each bit 0: PTRS port not used 1: PTRS port used
|
||||
uint8_t PTRSPortIndex ;
|
||||
/// PT-RS time density [TS38.214, table 5.1.6.3-1] 0: 1 1: 2 2: 4
|
||||
uint8_t PTRSTimeDensity;
|
||||
/// PT-RS frequency density [TS38.214, table 5.1.6.3-2] 0: 2 1: 4
|
||||
uint8_t PTRSFreqDensity;
|
||||
/// PT-RS resource element offset [TS38.211, table 7.4.1.2.2-1] Value: 0->3
|
||||
uint8_t PTRSReOffset;
|
||||
/// PT-RS-to-PDSCH EPRE ratio [TS38.214, table 4.1-2] Value :0->3
|
||||
uint8_t nEpreRatioOfPDSCHToPTRS;
|
||||
/// MCS table for this DLSCH
|
||||
uint8_t mcs_table;
|
||||
|
||||
uint16_t pduBitmap;
|
||||
} fapi_nr_dl_config_dlsch_pdu_rel15_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -766,7 +798,7 @@ typedef struct {
|
||||
} fapi_nr_pusch_power_control_t;
|
||||
|
||||
typedef enum {tx_config_codebook = 1, tx_config_nonCodebook = 2} tx_config_t;
|
||||
typedef enum {transform_precoder_disabled = 0, transform_precoder_enabled = 1} transform_precoder_t;
|
||||
typedef enum {transform_precoder_enabled = 0, transform_precoder_disabled = 1} transform_precoder_t;
|
||||
typedef enum {
|
||||
codebook_subset_fullyAndPartialAndNonCoherent = 1,
|
||||
codebook_subset_partialAndNonCoherent = 2,
|
||||
@@ -987,6 +1019,7 @@ typedef struct
|
||||
typedef struct
|
||||
{
|
||||
uint8_t tdd_period;//DL UL Transmission Periodicity. Value:0: ms0p5 1: ms0p625 2: ms1 3: ms1p25 4: ms2 5: ms2p5 6: ms5 7: ms10 8: ms3 9: ms4
|
||||
uint8_t tdd_period_in_slots;
|
||||
fapi_nr_max_tdd_periodicity_t* max_tdd_periodicity_list;
|
||||
|
||||
} fapi_nr_tdd_table_t;
|
||||
|
||||
@@ -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;
|
||||
@@ -2220,20 +2251,20 @@ typedef struct {
|
||||
nfapi_ul_config_ulsch_cqi_ri_pdu ulsch_cqi_ri_pdu;
|
||||
nfapi_ul_config_ulsch_harq_pdu ulsch_harq_pdu;
|
||||
nfapi_ul_config_ulsch_cqi_harq_ri_pdu ulsch_cqi_harq_ri_pdu;
|
||||
nfapi_ul_config_uci_cqi_pdu uci_cqi_pdu; // should never see
|
||||
nfapi_ul_config_uci_cqi_pdu uci_cqi_pdu;
|
||||
nfapi_ul_config_uci_sr_pdu uci_sr_pdu;
|
||||
nfapi_ul_config_uci_harq_pdu uci_harq_pdu;
|
||||
nfapi_ul_config_uci_sr_harq_pdu uci_sr_harq_pdu;// should only see once in a while
|
||||
nfapi_ul_config_uci_cqi_harq_pdu uci_cqi_harq_pdu;// should never see
|
||||
nfapi_ul_config_uci_cqi_sr_pdu uci_cqi_sr_pdu;// should never see
|
||||
nfapi_ul_config_uci_cqi_sr_harq_pdu uci_cqi_sr_harq_pdu;// should never see
|
||||
nfapi_ul_config_srs_pdu srs_pdu;// should never see
|
||||
nfapi_ul_config_harq_buffer_pdu harq_buffer_pdu;// should never see
|
||||
nfapi_ul_config_ulsch_uci_csi_pdu ulsch_uci_csi_pdu;// should never see
|
||||
nfapi_ul_config_ulsch_uci_harq_pdu ulsch_uci_harq_pdu;// should never see
|
||||
nfapi_ul_config_ulsch_csi_uci_harq_pdu ulsch_csi_uci_harq_pdu;// should never see
|
||||
nfapi_ul_config_nulsch_pdu nulsch_pdu;// should never see
|
||||
nfapi_ul_config_nrach_pdu nrach_pdu;// should never see
|
||||
nfapi_ul_config_uci_sr_harq_pdu uci_sr_harq_pdu;
|
||||
nfapi_ul_config_uci_cqi_harq_pdu uci_cqi_harq_pdu;
|
||||
nfapi_ul_config_uci_cqi_sr_pdu uci_cqi_sr_pdu;
|
||||
nfapi_ul_config_uci_cqi_sr_harq_pdu uci_cqi_sr_harq_pdu;
|
||||
nfapi_ul_config_srs_pdu srs_pdu;
|
||||
nfapi_ul_config_harq_buffer_pdu harq_buffer_pdu;
|
||||
nfapi_ul_config_ulsch_uci_csi_pdu ulsch_uci_csi_pdu;
|
||||
nfapi_ul_config_ulsch_uci_harq_pdu ulsch_uci_harq_pdu;
|
||||
nfapi_ul_config_ulsch_csi_uci_harq_pdu ulsch_csi_uci_harq_pdu;
|
||||
nfapi_ul_config_nulsch_pdu nulsch_pdu;
|
||||
nfapi_ul_config_nrach_pdu nrach_pdu;
|
||||
};
|
||||
} nfapi_ul_config_request_pdu_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_PACH_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;
|
||||
@@ -321,6 +305,7 @@ typedef enum {
|
||||
#define NFAPI_NR_CONFIG_PRACH_SUB_C_SPACING_TAG 0x1012
|
||||
#define NFAPI_NR_CONFIG_RESTRICTED_SET_CONFIG_TAG 0x1013
|
||||
#define NFAPI_NR_CONFIG_NUM_PRACH_FD_OCCASIONS_TAG 0x1014
|
||||
#define NFAPI_NR_CONFIG_PRACH_CONFIG_INDEX_TAG 0x1029
|
||||
#define NFAPI_NR_CONFIG_PRACH_ROOT_SEQUENCE_INDEX_TAG 0x1015
|
||||
#define NFAPI_NR_CONFIG_NUM_ROOT_SEQUENCES_TAG 0x1016
|
||||
#define NFAPI_NR_CONFIG_K1_TAG 0x1017
|
||||
@@ -364,7 +349,7 @@ typedef struct
|
||||
//table 3-22
|
||||
typedef struct
|
||||
{
|
||||
nfapi_uint8_tlv_t phy_cell_id;//Physical Cell ID, 𝑁_{𝐼𝐷}^{𝑐𝑒𝑙𝑙} [38.211, sec 7.4.2.1] Value: 0 ->1007
|
||||
nfapi_uint16_tlv_t phy_cell_id;//Physical Cell ID, 𝑁_{𝐼𝐷}^{𝑐𝑒𝑙𝑙} [38.211, sec 7.4.2.1] Value: 0 ->1007
|
||||
nfapi_uint8_tlv_t frame_duplex_type;//Frame duplex type Value: 0 = FDD 1 = TDD
|
||||
|
||||
} nfapi_nr_cell_config_t;
|
||||
@@ -385,7 +370,6 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t num_prach_fd_occasions;
|
||||
nfapi_uint16_tlv_t prach_root_sequence_index;//Starting logical root sequence index, 𝑖, equivalent to higher layer parameter prach-RootSequenceIndex [38.211, sec 6.3.3.1] Value: 0 -> 837
|
||||
nfapi_uint8_tlv_t num_root_sequences;//Number of root sequences for a particular FD occasion that are required to generate the necessary number of preambles
|
||||
nfapi_uint16_tlv_t k1;//Frequency offset (from UL bandwidth part) for each FD. [38.211, sec 6.3.3.2] Value: from 0 to 272
|
||||
@@ -401,7 +385,9 @@ typedef struct
|
||||
nfapi_uint8_tlv_t prach_sub_c_spacing;//Subcarrier spacing of PRACH. [38.211 sec 4.2] Value:0->4
|
||||
nfapi_uint8_tlv_t restricted_set_config;//PRACH restricted set config Value: 0: unrestricted 1: restricted set type A 2: restricted set type B
|
||||
nfapi_uint8_tlv_t num_prach_fd_occasions;//Corresponds to the parameter 𝑀 in [38.211, sec 6.3.3.2] which equals the higher layer parameter msg1FDM Value: 1,2,4,8
|
||||
nfapi_uint8_tlv_t prach_ConfigurationIndex;//PRACH configuration index. Value:0->255
|
||||
nfapi_nr_num_prach_fd_occasions_t* num_prach_fd_occasions_list;
|
||||
|
||||
nfapi_uint8_tlv_t ssb_per_rach;//SSB-per-RACH-occasion Value: 0: 1/8 1:1/4, 2:1/2 3:1 4:2 5:4, 6:8 7:16
|
||||
nfapi_uint8_tlv_t prach_multiple_carriers_in_a_band;//0 = disabled 1 = enabled
|
||||
|
||||
@@ -463,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;
|
||||
@@ -473,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
|
||||
|
||||
@@ -495,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;
|
||||
@@ -578,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
|
||||
|
||||
@@ -617,28 +715,43 @@ typedef struct {
|
||||
uint16_t prgSize;
|
||||
/// Number of STD ant ports (parallel streams) feeding into the digBF Value: 0->255
|
||||
uint8_t digBFInterfaces;
|
||||
// Depends on numPRGs
|
||||
uint16_t PMIdx[275];
|
||||
uint16_t *beamIdx[275];
|
||||
// Depends on digBFInterfaces
|
||||
uint16_t beamIdx[256];
|
||||
} nfapi_nr_tx_precoding_and_beamforming_t;
|
||||
|
||||
//table 3-37
|
||||
|
||||
#define DCI_PAYLOAD_BTYE_LEN 12 //? TS38.212 sec 7.3.1
|
||||
#define DCI_PAYLOAD_BYTE_LEN 8 // 12 ? TS38.212 sec 7.3.1
|
||||
#define MAX_DCI_CORESET 8
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t rnti;//
|
||||
uint16_t scrambling_id;//
|
||||
uint16_t scrambling_rnti;/* */
|
||||
uint8_t cce_index;//
|
||||
uint8_t aggregation_level;//
|
||||
nfapi_nr_tx_precoding_and_beamforming_t* precoding_and_beamforming_list;
|
||||
//tx power info
|
||||
uint8_t beta_pdcch_1_0;/*PDCCH power value used for PDCCH Format 1_0 with CRC scrambled by SI-RNTI, PI-RNTI or RA-RNTI. This is ratio of
|
||||
SSB/PBCH EPRE to PDCCH and PDCCH DMRS EPRE [TS38.213, sec 4.1] Value :0->17 */
|
||||
uint8_t power_control_offset_ss;//PDCCH power value used for all other PDCCH Formats. This is ratio of SSB/PBCH block EPRE to PDCCH and PDCCH DMRS EPRE [TS38.214, sec 4.1] Values: 0: -3dB, 1: 0dB, 2: 3dB, 3: 6dB
|
||||
uint16_t payload_size_bits;//The total DCI length (in bits) including padding bits [TS38.212 sec 7.3.1] Range 0-> DCI_PAYLOAD_BTYE_LEN*8
|
||||
uint8_t payload[DCI_PAYLOAD_BTYE_LEN];//DCI payload, where the actual size is defined by PayloadSizeBits. The bit order is as following bit0-bit7 are mapped to first byte of MSB - LSB
|
||||
typedef struct {
|
||||
// The RNTI used for identifying the UE when receiving the PDU Value: 1 -> 65535.
|
||||
uint16_t RNTI;
|
||||
// For a UE-specific search space it equals the higher-layer parameter PDCCH-DMRSScrambling-ID if configured,
|
||||
// otherwise it should be set to the phy cell ID. [TS38.211, sec 7.3.2.3] Value: 0->65535
|
||||
uint16_t ScramblingId;
|
||||
// For a UE-specific search space where PDCCH-DMRSScrambling- ID is configured This param equals the CRNTI.
|
||||
// Otherwise, it should be set to 0. [TS38.211, sec 7.3.2.3] Value: 0 -> 65535
|
||||
uint16_t ScramblingRNTI;
|
||||
// CCE start Index used to send the DCI Value: 0->135
|
||||
uint8_t CceIndex;
|
||||
// Aggregation level used [TS38.211, sec 7.3.2.1] Value: 1,2,4,8,16
|
||||
uint8_t AggregationLevel;
|
||||
// Precoding and Beamforming structure See Table 3-43
|
||||
nfapi_nr_tx_precoding_and_beamforming_t precodingAndBeamforming;
|
||||
// PDCCH power value used for PDCCH Format 1_0 with CRC scrambled by SI-RNTI, PI-RNTI or RA-RNTI.
|
||||
// This is ratio of SSB/PBCH EPRE to PDCCH and PDCCH DMRS EPRE [TS38.213, sec 4.1]
|
||||
// Value :0->17 Report title: 5G FAPI: PHY API Specification Issue date: 29 June 2019 Version: 222.10.17 68 Field Type Description representing -8 to 8 dB in 1dB steps
|
||||
uint8_t beta_PDCCH_1_0;
|
||||
// PDCCH power value used for all other PDCCH Formats.
|
||||
// This is ratio of SSB/PBCH block EPRE to PDCCH and PDCCH DMRS EPRE [TS38.214, sec 4.1] Values: 0: -3dB,1: 0dB,2: 3dB,3: 6dB
|
||||
uint8_t powerControlOffsetSS;
|
||||
// The total DCI length (in bits) including padding bits [TS38.212 sec 7.3.1] Range 0->DCI_PAYLOAD_BYTE_LEN*8
|
||||
uint16_t PayloadSizeBits;
|
||||
// DCI payload, where the actual size is defined by PayloadSizeBits. The bit order is as following bit0-bit7 are mapped to first byte of MSB - LSB
|
||||
uint8_t Payload[DCI_PAYLOAD_BYTE_LEN];
|
||||
|
||||
} nfapi_nr_dl_dci_pdu_t;
|
||||
|
||||
@@ -653,9 +766,6 @@ typedef struct {
|
||||
uint16_t *beamIdx[275];
|
||||
} nr_beamforming_t;
|
||||
|
||||
#define MAX_DCI_CORESET 8
|
||||
#define DCI_PAYLOAD_BYTE_LEN 8
|
||||
|
||||
typedef struct {
|
||||
///Bandwidth part size [TS38.213 sec12]. Number of contiguous PRBs allocated to the BWP,Value: 1->275
|
||||
uint16_t BWPSize;
|
||||
@@ -685,26 +795,8 @@ typedef struct {
|
||||
uint8_t precoderGranularity;
|
||||
///Number of DCIs in this CORESET.Value: 0->MaxDciPerSlot
|
||||
uint16_t numDlDci;
|
||||
///The RNTI used for identifying the UE when receiving the PDU Value: 1 -> 65535.
|
||||
uint16_t RNTI[MAX_DCI_CORESET];
|
||||
///For a UE-specific search space it equals the higher-layer parameter PDCCH-DMRSScrambling-ID if configured, otherwise it should be set to the phy cell ID. [TS38.211, sec 7.3.2.3] Value: 0->65535
|
||||
uint16_t ScramblingId[MAX_DCI_CORESET];
|
||||
///For a UE-specific search space where PDCCH-DMRSScrambling- ID is configured This param equals the CRNTI. Otherwise, it should be set to 0. [TS38.211, sec 7.3.2.3] Value: 0 -> 65535
|
||||
uint16_t ScramblingRNTI[MAX_DCI_CORESET];
|
||||
///CCE start Index used to send the DCI Value: 0->135
|
||||
uint8_t CceIndex[MAX_DCI_CORESET];
|
||||
///Aggregation level used [TS38.211, sec 7.3.2.1] Value: 1,2,4,8,16
|
||||
uint8_t AggregationLevel[MAX_DCI_CORESET];
|
||||
///Precoding and Beamforming structure See Table 3-43
|
||||
nfapi_nr_tx_precoding_and_beamforming_t precodingAndBeamforming[MAX_DCI_CORESET];
|
||||
///PDCCH power value used for PDCCH Format 1_0 with CRC scrambled by SI-RNTI, PI-RNTI or RA-RNTI. This is ratio of SSB/PBCH EPRE to PDCCH and PDCCH DMRS EPRE [TS38.213, sec 4.1] Value :0->17 Report title: 5G FAPI: PHY API Specification Issue date: 29 June 2019 Version: 222.10.17 68 Field Type Description representing -8 to 8 dB in 1dB steps
|
||||
uint8_t beta_PDCCH_1_0[MAX_DCI_CORESET];
|
||||
///PDCCH power value used for all other PDCCH Formats. This is ratio of SSB/PBCH block EPRE to PDCCH and PDCCH DMRS EPRE [TS38.214, sec 4.1] Values: 0: -3dB,1: 0dB,2: 3dB,3: 6dB
|
||||
uint8_t powerControlOffsetSS[MAX_DCI_CORESET];
|
||||
///The total DCI length (in bits) including padding bits [TS38.212 sec 7.3.1] Range 0->DCI_PAYLOAD_BTYE_LEN*8
|
||||
uint16_t PayloadSizeBits[MAX_DCI_CORESET];
|
||||
///DCI payload, where the actual size is defined by PayloadSizeBits. The bit order is as following bit0-bit7 are mapped to first byte of MSB - LSB
|
||||
uint8_t Payload[MAX_DCI_CORESET][DCI_PAYLOAD_BYTE_LEN];
|
||||
///DL DCI PDU
|
||||
nfapi_nr_dl_dci_pdu_t dci_pdu[MAX_DCI_CORESET];
|
||||
} nfapi_nr_dl_tti_pdcch_pdu_rel15_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -947,6 +1039,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;
|
||||
@@ -960,11 +1053,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;
|
||||
@@ -979,7 +1089,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,
|
||||
@@ -1037,10 +1147,12 @@ typedef struct
|
||||
{
|
||||
uint16_t phys_cell_id;
|
||||
uint8_t num_prach_ocas;
|
||||
// SCF PRACH PDU format field does not consider A1/B1 etc. possibilities
|
||||
// We added 9 = A1/B1 10 = A2/B2 11 A3/B3
|
||||
uint8_t prach_format;
|
||||
uint8_t num_ra;
|
||||
uint8_t prach_start_symbol;
|
||||
uint16_t num_cs;//
|
||||
uint16_t num_cs;
|
||||
nfapi_nr_ul_beamforming_t beamforming;
|
||||
|
||||
} nfapi_nr_prach_pdu_t;
|
||||
@@ -1126,6 +1238,7 @@ typedef struct
|
||||
uint16_t ul_dmrs_symb_pos;
|
||||
uint8_t dmrs_config_type;
|
||||
uint16_t ul_dmrs_scrambling_id;
|
||||
uint16_t pusch_identity;
|
||||
uint8_t scid;
|
||||
uint8_t num_dmrs_cdm_grps_no_data;
|
||||
uint16_t dmrs_ports;//DMRS ports. [TS38.212 7.3.1.1.2] provides description between DCI 0-1 content and DMRS ports. Bitmap occupying the 11 LSBs with: bit 0: antenna port 1000 bit 11: antenna port 1011 and for each bit 0: DMRS port not used 1: DMRS port used
|
||||
@@ -1263,7 +1376,7 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t pdu_idx;//This value is an index for number of PDU identified by nPDU in this message Value: 0 -> 65535
|
||||
uint8_t pdu_idx;//This value is an index for number of PDU identified by nPDU in this message Value: 0 -> 255
|
||||
|
||||
} nfapi_nr_ul_tti_request_number_of_ue_t;
|
||||
|
||||
@@ -1275,6 +1388,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
|
||||
@@ -1321,6 +1435,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;
|
||||
@@ -1366,6 +1481,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;
|
||||
@@ -1498,7 +1614,7 @@ typedef struct
|
||||
//for dci_pusch_pdu
|
||||
typedef struct
|
||||
{
|
||||
uint8_t pdu_bit_map;
|
||||
uint8_t pduBitmap;
|
||||
uint32_t handle;
|
||||
uint16_t rnti;
|
||||
uint8_t ul_cqi;
|
||||
@@ -1513,7 +1629,7 @@ typedef struct
|
||||
//for PUCCH PDU Format 0/1
|
||||
typedef struct
|
||||
{
|
||||
uint8_t pdu_bit_map;
|
||||
uint8_t pduBitmap;
|
||||
uint32_t handle;
|
||||
uint16_t rnti;
|
||||
uint8_t pucch_format;//PUCCH format Value: 0 -> 1 0: PUCCH Format0 1: PUCCH Format1
|
||||
@@ -1529,7 +1645,7 @@ typedef struct
|
||||
//PUCCH PDU Format 2/3/4
|
||||
typedef struct
|
||||
{
|
||||
uint8_t pdu_bit_map;
|
||||
uint8_t pduBitmap;
|
||||
uint32_t handle;
|
||||
uint16_t rnti;
|
||||
uint8_t pucch_format;//PUCCH format Value: 0 -> 2 0: PUCCH Format2 1: PUCCH Format3 2: PUCCH Format4
|
||||
@@ -1544,7 +1660,7 @@ typedef struct
|
||||
}nfapi_nr_uci_pucch_pdu_format_2_3_4_t;
|
||||
|
||||
typedef enum {
|
||||
NFAPI_NR_UCI_PDCCH_PDU_TYPE = 0,
|
||||
NFAPI_NR_UCI_PUSCH_PDU_TYPE = 0,
|
||||
NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE = 1,
|
||||
NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE = 2,
|
||||
} nfapi_nr_uci_pdu_type_e;
|
||||
@@ -1566,7 +1682,7 @@ typedef struct
|
||||
uint16_t sfn;
|
||||
uint16_t slot;
|
||||
uint16_t num_ucis;
|
||||
nfapi_nr_uci_t uci_list[NFAPI_MAX_NUM_UCI_INDICATION];
|
||||
nfapi_nr_uci_t *uci_list;
|
||||
|
||||
} nfapi_nr_uci_indication_t;
|
||||
|
||||
|
||||
@@ -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
@@ -37,7 +37,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);
|
||||
|
||||
@@ -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,14 @@ extern "C" {
|
||||
#include "nfapi_interface.h"
|
||||
#include "debug.h"
|
||||
#include <openair2/PHY_INTERFACE/IF_Module.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 +127,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 +140,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 +152,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 +176,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 +189,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 +201,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 +214,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 +367,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 +384,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 +394,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 +403,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 +419,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 +428,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 +436,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 +568,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 +636,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 +647,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 +657,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 +665,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 +673,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 +685,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 +749,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 +759,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
|
||||
|
||||
+860
-82
File diff suppressed because it is too large
Load Diff
@@ -1,12 +1,12 @@
|
||||
/*
|
||||
* Copyright 2017 Cisco Systems, Inc.
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -19,7 +19,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "nfapi/open-nFAPI/pnf/inc/pnf_p7.h"
|
||||
#include "nfapi_nr_interface.h"
|
||||
#include "nfapi_nr_interface_scf.h"
|
||||
|
||||
nfapi_pnf_config_t* nfapi_pnf_config_create()
|
||||
{
|
||||
@@ -31,11 +32,11 @@ nfapi_pnf_config_t* nfapi_pnf_config_create()
|
||||
memset(_this, 0, sizeof(pnf_t));
|
||||
|
||||
_this->sctp = 1; // enable sctp
|
||||
|
||||
|
||||
_this->_public.vnf_p5_port = NFAPI_P5_SCTP_PORT;
|
||||
|
||||
|
||||
_this->_public.malloc = &malloc;
|
||||
_this->_public.free = &free;
|
||||
_this->_public.free = &free;
|
||||
|
||||
_this->_public.codec_config.allocate = &malloc;
|
||||
_this->_public.codec_config.deallocate = &free;
|
||||
@@ -82,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
|
||||
@@ -97,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
|
||||
@@ -130,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
|
||||
@@ -149,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
|
||||
@@ -167,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)
|
||||
@@ -175,12 +265,26 @@ int nfapi_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_param_response_t* res
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
pnf_t* _this = (pnf_t*)(config);
|
||||
|
||||
return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_param_response_t));
|
||||
}
|
||||
|
||||
|
||||
int nfapi_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)
|
||||
@@ -209,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)
|
||||
@@ -236,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)
|
||||
@@ -430,4 +591,3 @@ int nfapi_pnf_vendor_extension(nfapi_pnf_config_t* config, nfapi_p4_p5_message_h
|
||||
|
||||
return pnf_pack_and_send_p5_message(_this, msg, msg_len);
|
||||
}
|
||||
|
||||
|
||||
+1466
-10
File diff suppressed because it is too large
Load Diff
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/*
|
||||
* Copyright 2017 Cisco Systems, Inc.
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -19,7 +19,8 @@
|
||||
|
||||
#include "nfapi_interface.h"
|
||||
#include "nfapi_nr_interface_scf.h"
|
||||
#include "nfapi/open-nFAPI/pnf/inc/pnf_p7.h"
|
||||
#include "nfapi_nr_interface.h"
|
||||
|
||||
#include "debug.h"
|
||||
#include "netinet/in.h"
|
||||
|
||||
@@ -105,336 +106,343 @@ typedef struct nfapi_vnf_config
|
||||
|
||||
/*! Configuration options for the p4 p5 pack unpack functions */
|
||||
nfapi_p4_p5_codec_config_t codec_config;
|
||||
|
||||
|
||||
/*! Optional user defined data that will be avaliable in the callbacks*/
|
||||
void* user_data;
|
||||
|
||||
/*! \brief Callback indicating that a pnf has established connection
|
||||
/*! \brief Callback indicating that a pnf has established connection
|
||||
* \param config A pointer to the vnf configuration
|
||||
* \param p5_idx The p5 used to indicate this pnf p5 connection
|
||||
*
|
||||
* The client is expected to send the PNF_PARAM.request in response to
|
||||
*
|
||||
* The client is expected to send the PNF_PARAM.request in response to
|
||||
* the connection indication
|
||||
*
|
||||
*
|
||||
* \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
|
||||
|
||||
/*! \brief Callback indicating that a pnf has lost connection
|
||||
* \param config A pointer to the vnf configuration
|
||||
* \param p5_idx The p5 used to indicate this pnf p5 connection
|
||||
*
|
||||
* The p5_idx may be used for future new p5 connections
|
||||
*
|
||||
* The client is responsiable for communicating to the p7 instance(s) that
|
||||
* may be associated with this p5 that they should be deleted using the
|
||||
* may be associated with this p5 that they should be deleted using the
|
||||
* nfapi_vnf_p7_del_pnf functon
|
||||
*
|
||||
*
|
||||
*/
|
||||
int (*pnf_disconnect_indication)(nfapi_vnf_config_t* config, int p5_idx);
|
||||
|
||||
// p5 interface functions
|
||||
|
||||
|
||||
/*! \brief A callback to handle the PNF_PARAM.resp
|
||||
* \param config A pointer to the vnf configuration
|
||||
* \param p5_idx The p5 index used to indicate a particular pnf p5 connection
|
||||
* \param resp A data structure for the decoded PNF_PARAM.response. This will
|
||||
* have been allocated on the stack.
|
||||
* \param resp A data structure for the decoded PNF_PARAM.response. This will
|
||||
* have been allocated on the stack.
|
||||
* \return not currently used.
|
||||
*
|
||||
*
|
||||
* The PNF_PARAM.resp contains the capability of the PNF identified by the
|
||||
* p5_idx.
|
||||
*
|
||||
* p5_idx.
|
||||
*
|
||||
* The client is expected to send the PNF_CONFIG.request after receiving the
|
||||
* PNF_PARAM.resp. This can be done in the call back.
|
||||
* PNF_PARAM.resp. This can be done in the call back.
|
||||
*
|
||||
* It is expected that the client when building the PNF_CONFIG.request will
|
||||
* used the nfapi_vnf_allocate_phy() to allocate unique phy id for each FAPI
|
||||
* instance the client wishes to create.
|
||||
*
|
||||
* The resp may contain pointers to dyanmically allocated sub structures
|
||||
* such as the vendor_extention. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
*
|
||||
* The resp may contain pointers to dyanmically allocated sub structures
|
||||
* such as the vendor_extention. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
* 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
|
||||
|
||||
/*! A callback for the PNF_CONFIG.resp
|
||||
* \param config A pointer to the vnf configuration
|
||||
* \param p5_idx The p5 index used to indicate a particular pnf p5 connection
|
||||
* \param resp A data structure for the decoded PNF_CONFIG.response. This will
|
||||
* have been allocated on the stack.
|
||||
* \param resp A data structure for the decoded PNF_CONFIG.response. This will
|
||||
* have been allocated on the stack.
|
||||
* \return not currently used.
|
||||
*
|
||||
* The PNF_CONFIG.resp contains the result of the PNF_CONFIG.request for the
|
||||
* PNF identified by the p5_idx.
|
||||
*
|
||||
*
|
||||
* The PNF_CONFIG.resp contains the result of the PNF_CONFIG.request for the
|
||||
* PNF identified by the p5_idx.
|
||||
*
|
||||
* The client is expected to send the PNF_START.request after receiving the
|
||||
* PNF_PARAM.resp. This can be done in the call back.
|
||||
*
|
||||
* The resp may contain pointers to dyanmically allocated sub structures
|
||||
* such as the vendor_extention. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
* PNF_PARAM.resp. This can be done in the call back.
|
||||
*
|
||||
* The resp may contain pointers to dyanmically allocated sub structures
|
||||
* such as the vendor_extention. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
* 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_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
|
||||
* \param resp A data structure for the decoded PNF_START.response. This will
|
||||
* have been allocated on the stack.
|
||||
* \param resp A data structure for the decoded PNF_START.response. This will
|
||||
* have been allocated on the stack.
|
||||
* \return not currently used.
|
||||
*
|
||||
* The PNF_START.resp contains the result of the PNF_START.request for the
|
||||
* PNF identified by the p5_idx.
|
||||
*
|
||||
* The client is expected to send the PARAM.request for each FAPI instance
|
||||
* that has been created in the PNF.
|
||||
*
|
||||
* The resp may contain pointers to dyanmically allocated sub structures
|
||||
* such as the vendor_extention. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
*
|
||||
* The PNF_START.resp contains the result of the PNF_START.request for the
|
||||
* PNF identified by the p5_idx.
|
||||
*
|
||||
* The client is expected to send the PARAM.request for each FAPI instance
|
||||
* that has been created in the PNF.
|
||||
*
|
||||
* The resp may contain pointers to dyanmically allocated sub structures
|
||||
* such as the vendor_extention. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
* 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_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
|
||||
* \param resp A data structure for the decoded PNF_STOP.response. This will
|
||||
* have been allocated on the stack.
|
||||
* \param resp A data structure for the decoded PNF_STOP.response. This will
|
||||
* have been allocated on the stack.
|
||||
* \return not currently used.
|
||||
*
|
||||
* The PNF_STOP.response contains the result of the PNF_STOP.request for the
|
||||
* PNF identified by the p5_idx.
|
||||
*
|
||||
* The resp may contain pointers to dyanmically allocated sub structures
|
||||
* such as the vendor_extention. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
*
|
||||
* The PNF_STOP.response contains the result of the PNF_STOP.request for the
|
||||
* PNF identified by the p5_idx.
|
||||
*
|
||||
* The resp may contain pointers to dyanmically allocated sub structures
|
||||
* such as the vendor_extention. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
* 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_stop_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_stop_response_t* resp);
|
||||
|
||||
|
||||
/*! A callback for the PARAM.resp
|
||||
* \param config A pointer to the vnf configuration
|
||||
* \param p5_idx The p5 index used to indicate a particular pnf p5 connection
|
||||
* \param resp A data structure for the decoded PARAM.resposne. This will
|
||||
* have been allocated on the stack.
|
||||
* \param resp A data structure for the decoded PARAM.resposne. This will
|
||||
* have been allocated on the stack.
|
||||
* \return not currently used.
|
||||
*
|
||||
*
|
||||
* The PARAM.request contains the capabilities of the FAPI instance identified
|
||||
* by the phy_id
|
||||
*
|
||||
* The client is expected to send the CONFIG.request after receiving the
|
||||
* PARAM.response. This can be done in the call back. The PARAM.response
|
||||
* contains the PNF P7 address (ipv4 or ipv6) and port. This information
|
||||
* PARAM.response. This can be done in the call back. The PARAM.response
|
||||
* contains the PNF P7 address (ipv4 or ipv6) and port. This information
|
||||
* is used when calling the nfapi_vnf_p7_add_pnf()
|
||||
*
|
||||
* The client is responsible for identifing the VNF P7 ip address
|
||||
*
|
||||
* The client is responsible for identifing the VNF P7 ip address
|
||||
* (ipv4 or ipv6) and port for the VNF P7 entity which will be sent to the
|
||||
* PNF P7 entity. That endpoint should be valid before send the
|
||||
* PNF P7 entity. That endpoint should be valid before send the
|
||||
* CONFIG.request.
|
||||
*
|
||||
* The resp may contain pointers to dyanmically allocated sub structures
|
||||
* such as the vendor_extention. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
*
|
||||
* The resp may contain pointers to dyanmically allocated sub structures
|
||||
* such as the vendor_extention. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
* 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 (*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
|
||||
* \param p5_idx The p5 index used to indicate a particular pnf p5 connection
|
||||
* \param resp A data structure for the decoded CONFIG.response This will
|
||||
* have been allocated on the stack.
|
||||
* \param resp A data structure for the decoded CONFIG.response This will
|
||||
* have been allocated on the stack.
|
||||
* \return not currently used.
|
||||
*
|
||||
*
|
||||
* The CONFIG.response contains the result of the CONFIG.request
|
||||
*
|
||||
*
|
||||
* The resp may contain pointers to dyanmically allocated sub structures
|
||||
* such as the vendor_extention. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
*
|
||||
* The resp may contain pointers to dyanmically allocated sub structures
|
||||
* such as the vendor_extention. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
* 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
|
||||
* \param resp A data structure for the decoded START.response This will
|
||||
* have been allocated on the stack.
|
||||
* \param resp A data structure for the decoded START.response This will
|
||||
* have been allocated on the stack.
|
||||
* \return not currently used.
|
||||
*
|
||||
*
|
||||
* The START.response contains the result of the START.request
|
||||
*
|
||||
*
|
||||
* The resp may contain pointers to dyanmically allocated sub structures
|
||||
* such as the vendor_extention. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
*
|
||||
* The resp may contain pointers to dyanmically allocated sub structures
|
||||
* such as the vendor_extention. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
* 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 (*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
|
||||
* \param p5_idx The p5 index used to indicate a particular pnf p5 connection
|
||||
* \param resp A data structure for the decoded STOP.response This will
|
||||
* have been allocated on the stack.
|
||||
* \param resp A data structure for the decoded STOP.response This will
|
||||
* have been allocated on the stack.
|
||||
* \return not currently used.
|
||||
*
|
||||
*
|
||||
* The STOP.response contains the result of the STOP.request
|
||||
*
|
||||
*
|
||||
* The resp may contain pointers to dyanmically allocated sub structures
|
||||
* such as the vendor_extention. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
*
|
||||
* The resp may contain pointers to dyanmically allocated sub structures
|
||||
* such as the vendor_extention. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
* 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 (*stop_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_stop_response_t* resp);
|
||||
|
||||
/*! A callback for the MEASUREMENT.resp
|
||||
|
||||
/*! A callback for the MEASUREMENT.resp
|
||||
* \param config A pointer to the vnf configuration
|
||||
* \param p5_idx The p5 index used to indicate a particular pnf p5 connection
|
||||
* \param resp A data structure for the decoded MEASUREMENT.response This will
|
||||
* have been allocated on the stack.
|
||||
* \param resp A data structure for the decoded MEASUREMENT.response This will
|
||||
* have been allocated on the stack.
|
||||
* \return not currently used.
|
||||
*
|
||||
*
|
||||
* The MEASUREMENT.response contains the result of the MEASUREMENT.request
|
||||
*
|
||||
* The resp may contain pointers to dyanmically allocated sub structures
|
||||
* such as the vendor_extention. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
*
|
||||
* The resp may contain pointers to dyanmically allocated sub structures
|
||||
* such as the vendor_extention. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
* 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 (*measurement_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_measurement_response_t* resp);
|
||||
|
||||
// p4 interface functions
|
||||
/*! A callback for the RSSI.resp
|
||||
/*! A callback for the RSSI.resp
|
||||
* \param config A pointer to the vnf configuration
|
||||
* \param p5_idx The p5 index used to indicate a particular pnf p5 connection
|
||||
* \param resp A data structure for the decoded RSSI.response This will
|
||||
* have been allocated on the stack.
|
||||
* \param resp A data structure for the decoded RSSI.response This will
|
||||
* have been allocated on the stack.
|
||||
* \return not currently used.
|
||||
*/
|
||||
int (*rssi_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_rssi_response_t* resp);
|
||||
|
||||
|
||||
/*! A callback for the RSSI.indication
|
||||
* \param config A pointer to the vnf configuration
|
||||
* \param p5_idx The p5 index used to indicate a particular pnf p5 connection
|
||||
* \param resp A data structure for the decoded RSSI.indication This will
|
||||
* have been allocated on the stack.
|
||||
* \param resp A data structure for the decoded RSSI.indication This will
|
||||
* have been allocated on the stack.
|
||||
* \return not currently used.
|
||||
*/
|
||||
int (*rssi_ind)(nfapi_vnf_config_t* config, int p5_idx, nfapi_rssi_indication_t* ind);
|
||||
|
||||
|
||||
/*! A callback for the CELL_SEARCH.response
|
||||
* \param config A pointer to the vnf configuration
|
||||
* \param p5_idx The p5 index used to indicate a particular pnf p5 connection
|
||||
* \param resp A data structure for the decoded CELL_SEARCH.response This will
|
||||
* have been allocated on the stack.
|
||||
* \param resp A data structure for the decoded CELL_SEARCH.response This will
|
||||
* have been allocated on the stack.
|
||||
* \return not currently used.
|
||||
*/
|
||||
int (*cell_search_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_cell_search_response_t* resp);
|
||||
|
||||
|
||||
/*! A callback for the CELL_SEARCH.indication
|
||||
* \param config A pointer to the vnf configuration
|
||||
* \param p5_idx The p5 index used to indicate a particular pnf p5 connection
|
||||
* \param resp A data structure for the decoded CELL_SEARCH.indication This will
|
||||
* have been allocated on the stack.
|
||||
* \param resp A data structure for the decoded CELL_SEARCH.indication This will
|
||||
* have been allocated on the stack.
|
||||
* \return not currently used.
|
||||
*/
|
||||
int (*cell_search_ind)(nfapi_vnf_config_t* config, int p5_idx, nfapi_cell_search_indication_t* ind);
|
||||
|
||||
|
||||
/*! A callback for the BROADCAST_DETECT.response
|
||||
* \param config A pointer to the vnf configuration
|
||||
* \param p5_idx The p5 index used to indicate a particular pnf p5 connection
|
||||
* \param resp A data structure for the decoded BROADCAST_DETECT.response This will
|
||||
* have been allocated on the stack.
|
||||
* \param resp A data structure for the decoded BROADCAST_DETECT.response This will
|
||||
* have been allocated on the stack.
|
||||
* \return not currently used. */
|
||||
int (*broadcast_detect_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_broadcast_detect_response_t* resp);
|
||||
|
||||
|
||||
/*! A callback for the BROADCAST_DETECT.indication
|
||||
* \param config A pointer to the vnf configuration
|
||||
* \param p5_idx The p5 index used to indicate a particular pnf p5 connection
|
||||
* \param resp A data structure for the decoded BROADCAST_DETECT.indication This will
|
||||
* have been allocated on the stack.
|
||||
* \return not currently used.
|
||||
* \param resp A data structure for the decoded BROADCAST_DETECT.indication This will
|
||||
* have been allocated on the stack.
|
||||
* \return not currently used.
|
||||
*/
|
||||
int (*broadcast_detect_ind)(nfapi_vnf_config_t* config, int p5_idx, nfapi_broadcast_detect_indication_t* ind);
|
||||
|
||||
|
||||
/*! A callback for the SYSTEM_INFORMATION_SCHEUDLE.response
|
||||
* \param config A pointer to the vnf configuration
|
||||
* \param p5_idx The p5 index used to indicate a particular pnf p5 connection
|
||||
* \param resp A data structure for the decoded SYSTEM_INFORMATION_SCHEUDLE.response This will
|
||||
* have been allocated on the stack.
|
||||
* \return not currently used.
|
||||
* \param resp A data structure for the decoded SYSTEM_INFORMATION_SCHEUDLE.response This will
|
||||
* have been allocated on the stack.
|
||||
* \return not currently used.
|
||||
*/
|
||||
int (*system_information_schedule_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_system_information_schedule_response_t* resp);
|
||||
|
||||
|
||||
/*! A callback for the SYSTEM_INFORMATION_SCHEUDLE.indication
|
||||
* \param config A pointer to the vnf configuration
|
||||
* \param p5_idx The p5 index used to indicate a particular pnf p5 connection
|
||||
* \param resp A data structure for the decoded SYSTEM_INFORMATION_SCHEUDLE.indication This will
|
||||
* have been allocated on the stack.
|
||||
* \return not currently used.
|
||||
* \param resp A data structure for the decoded SYSTEM_INFORMATION_SCHEUDLE.indication This will
|
||||
* have been allocated on the stack.
|
||||
* \return not currently used.
|
||||
*/
|
||||
int (*system_information_schedule_ind)(nfapi_vnf_config_t* config, int p5_idx, nfapi_system_information_schedule_indication_t* ind);
|
||||
|
||||
|
||||
/*! A callback for the SYSTEM_INFORMATION.response
|
||||
* \param config A pointer to the vnf configuration
|
||||
* \param p5_idx The p5 index used to indicate a particular pnf p5 connection
|
||||
* \param resp A data structure for the decoded SYSTEM_INFORMATION.response This will
|
||||
* have been allocated on the stack.
|
||||
* \return not currently used.
|
||||
* \param resp A data structure for the decoded SYSTEM_INFORMATION.response This will
|
||||
* have been allocated on the stack.
|
||||
* \return not currently used.
|
||||
*/
|
||||
int (*system_information_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_system_information_response_t* resp);
|
||||
|
||||
|
||||
/*! A callback for the SYSTEM_INFORMATION.indication
|
||||
* \param config A pointer to the vnf configuration
|
||||
* \param p5_idx The p5 index used to indicate a particular pnf p5 connection
|
||||
* \param resp A data structure for the decoded SYSTEM_INFORMATION.indication This will
|
||||
* have been allocated on the stack.
|
||||
* \return not currently used.
|
||||
* \param resp A data structure for the decoded SYSTEM_INFORMATION.indication This will
|
||||
* have been allocated on the stack.
|
||||
* \return not currently used.
|
||||
*/
|
||||
int (*system_information_ind)(nfapi_vnf_config_t* config, int p5_idx, nfapi_system_information_indication_t* ind);
|
||||
|
||||
|
||||
/*! A callback for the NMM_STOP.response
|
||||
* \param config A pointer to the vnf configuration
|
||||
* \param p5_idx The p5 index used to indicate a particular pnf p5 connection
|
||||
* \param resp A data structure for the decoded NMM_STOP.response This will
|
||||
* have been allocated on the stack.
|
||||
* \return not currently used.
|
||||
* \param resp A data structure for the decoded NMM_STOP.response This will
|
||||
* have been allocated on the stack.
|
||||
* \return not currently used.
|
||||
*/
|
||||
int (*nmm_stop_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_nmm_stop_response_t* resp);
|
||||
|
||||
|
||||
|
||||
/*! A callback for any vendor extension message received
|
||||
* \param config A pointer to the vnf configuration
|
||||
* \param p5_idx The p5 index used to indicate a particular pnf p5 connection
|
||||
* \param resp A data structure for the decoded vendor extention message
|
||||
* \return not currently used.
|
||||
* \param resp A data structure for the decoded vendor extention message
|
||||
* \return not currently used.
|
||||
*/
|
||||
int (*vendor_ext)(nfapi_vnf_config_t* config, int p5_idx, nfapi_p4_p5_message_header_t* msg);
|
||||
|
||||
/*! A callback to allocate vendor extension messages
|
||||
* \param message_id The message is taken from the message header
|
||||
* \param msg_size The is the vendor extention message that has been allocated.
|
||||
* \param msg_size The is the vendor extention message that has been allocated.
|
||||
* The callee must set this value
|
||||
* \return A pointer to an allocated vendor extention message
|
||||
*/
|
||||
nfapi_p4_p5_message_header_t* (*allocate_p4_p5_vendor_ext)(uint16_t message_id, uint16_t* msg_size);
|
||||
|
||||
|
||||
/*! A callback to deallocate vendor extension messages
|
||||
* \param header A pointer to an allocated vendor extention message
|
||||
*/
|
||||
@@ -443,8 +451,8 @@ typedef struct nfapi_vnf_config
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} nfapi_vnf_config_t;
|
||||
|
||||
/*! Creates and initialise the vnf config structure before use
|
||||
@@ -457,22 +465,24 @@ nfapi_vnf_config_t* nfapi_vnf_config_create(void);
|
||||
void nfapi_vnf_config_destory(nfapi_vnf_config_t* config);
|
||||
|
||||
|
||||
/*! Start the VNF library.
|
||||
/*! Start the VNF library.
|
||||
* \param config A pointer to a vnf config
|
||||
* \return 0 means success, -1 failure
|
||||
*
|
||||
* The config should be initailize with port the vnf should listen on and
|
||||
* the callback set to functions that will be called when a nFAPI message is
|
||||
* the callback set to functions that will be called when a nFAPI message is
|
||||
* recevied before calling nfapi_vnf_start.
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
/*! Stop the VNF library.
|
||||
* \param config A pointer to a vnf config
|
||||
* \return 0 means success, -1 failure
|
||||
*
|
||||
*
|
||||
* This function will cause the nfapi_vnf_start function to return
|
||||
*/
|
||||
int nfapi_vnf_stop(nfapi_vnf_config_t* config);
|
||||
@@ -482,7 +492,7 @@ int nfapi_vnf_stop(nfapi_vnf_config_t* config);
|
||||
* \param p5_idx The P5 index return by the callbacks
|
||||
* \param phy_id A pointer to a phy_id that will be set by this function
|
||||
* \return 0 means success, -1 failure
|
||||
*
|
||||
*
|
||||
* Called before nfapi_vnf_config_req to allocate a vnf phy instance. This
|
||||
* function will return unqiue phy_id to be used for this identify the phy
|
||||
*
|
||||
@@ -498,6 +508,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
|
||||
@@ -506,6 +517,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
|
||||
@@ -514,6 +526,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
|
||||
@@ -530,6 +543,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
|
||||
@@ -537,6 +551,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
|
||||
@@ -546,6 +561,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
|
||||
@@ -637,16 +653,16 @@ typedef struct nfapi_vnf_p7_config
|
||||
* If not set the vnf p7 library will use malloc
|
||||
*/
|
||||
void* (*malloc)(size_t size);
|
||||
|
||||
|
||||
/*! A user define callback to override the default memory deallocation
|
||||
* \param ptr Pointer to a memory block to deallocate
|
||||
*
|
||||
* If not set the vnf p7 library will use free
|
||||
*/
|
||||
void (*free)(void*);
|
||||
|
||||
|
||||
/*! A user define callback to handle trace from the pnf
|
||||
* \param level The trace level
|
||||
* \param level The trace level
|
||||
* \param message The trace string
|
||||
*/
|
||||
void (*trace)(nfapi_trace_level_t level, const char* message, ...);
|
||||
@@ -688,171 +704,172 @@ typedef struct nfapi_vnf_p7_config
|
||||
*
|
||||
* \todo Need some way the tell the VNF how long it has
|
||||
*/
|
||||
|
||||
|
||||
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
|
||||
* \param ind A data structure for the decoded HARQ.indication This will
|
||||
* have been allocated on the stack.
|
||||
* \param ind A data structure for the decoded HARQ.indication This will
|
||||
* have been allocated on the stack.
|
||||
* \return not currently used.
|
||||
*
|
||||
* The ind may contain pointers to dyanmically allocated sub structures
|
||||
* such as the pdu. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
*
|
||||
* The ind may contain pointers to dyanmically allocated sub structures
|
||||
* such as the pdu. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
* 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 (*harq_indication)(struct nfapi_vnf_p7_config* config, nfapi_harq_indication_t* ind);
|
||||
|
||||
|
||||
/*! A callback for the CRC.ind
|
||||
* \param config A pointer to the vnf p7 configuration
|
||||
* \param ind A data structure for the decoded CRC.indication This will
|
||||
* have been allocated on the stack.
|
||||
* \param ind A data structure for the decoded CRC.indication This will
|
||||
* have been allocated on the stack.
|
||||
* \return not currently used.
|
||||
*
|
||||
* The ind may contain pointers to dyanmically allocated sub structures
|
||||
* such as the pdu. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
*
|
||||
* The ind may contain pointers to dyanmically allocated sub structures
|
||||
* such as the pdu. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
* 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 (*crc_indication)(struct nfapi_vnf_p7_config* config, nfapi_crc_indication_t* ind);
|
||||
|
||||
|
||||
/*! A callback for the RX_ULSCH.indication
|
||||
* \param config A pointer to the vnf p7 configuration
|
||||
* \param ind A data structure for the decoded RX_ULSCH.indication This will
|
||||
* have been allocated on the stack.
|
||||
* \param ind A data structure for the decoded RX_ULSCH.indication This will
|
||||
* have been allocated on the stack.
|
||||
* \return not currently used.
|
||||
*
|
||||
* The ind may contain pointers to dyanmically allocated sub structures
|
||||
* such as the pdu. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
*
|
||||
* The ind may contain pointers to dyanmically allocated sub structures
|
||||
* such as the pdu. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
* 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
|
||||
*
|
||||
* Note that the rx_indication may hold one or many uplink pdus in the
|
||||
* Note that the rx_indication may hold one or many uplink pdus in the
|
||||
* ind.rx_indication_body.rx_pdu_list
|
||||
*/
|
||||
*/
|
||||
int (*rx_indication)(struct nfapi_vnf_p7_config* config, nfapi_rx_indication_t* ind);
|
||||
|
||||
|
||||
/*! A callback for the RACH.indication
|
||||
* \param config A pointer to the vnf p7 configuration
|
||||
* \param ind A data structure for the decoded RACH.indication This will
|
||||
* have been allocated on the stack.
|
||||
* \param ind A data structure for the decoded RACH.indication This will
|
||||
* have been allocated on the stack.
|
||||
* \return not currently used.
|
||||
*
|
||||
* The ind may contain pointers to dyanmically allocated sub structures
|
||||
* such as the pdu. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
*
|
||||
* The ind may contain pointers to dyanmically allocated sub structures
|
||||
* such as the pdu. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
* 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 (*rach_indication)(struct nfapi_vnf_p7_config* config, nfapi_rach_indication_t* ind);
|
||||
|
||||
|
||||
/*! A callback for the SRS.indication
|
||||
* \param config A pointer to the vnf p7 configuration
|
||||
* \param ind A data structure for the decoded SRS.indication This will
|
||||
* have been allocated on the stack.
|
||||
* \param ind A data structure for the decoded SRS.indication This will
|
||||
* have been allocated on the stack.
|
||||
* \return not currently used.
|
||||
*
|
||||
* The ind may contain pointers to dyanmically allocated sub structures
|
||||
* such as the pdu. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
*
|
||||
* The ind may contain pointers to dyanmically allocated sub structures
|
||||
* such as the pdu. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
* 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 (*srs_indication)(struct nfapi_vnf_p7_config* config, nfapi_srs_indication_t* ind);
|
||||
|
||||
|
||||
/*! A callback for the RX_SR.indication
|
||||
* \param config A pointer to the vnf p7 configuration
|
||||
* \param ind A data structure for the decoded RX_SR.indication This will
|
||||
* have been allocated on the stack.
|
||||
* \param ind A data structure for the decoded RX_SR.indication This will
|
||||
* have been allocated on the stack.
|
||||
* \return not currently used.
|
||||
*
|
||||
* The ind may contain pointers to dyanmically allocated sub structures
|
||||
* such as the pdu. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
*
|
||||
* The ind may contain pointers to dyanmically allocated sub structures
|
||||
* such as the pdu. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
* 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 (*sr_indication)(struct nfapi_vnf_p7_config* config, nfapi_sr_indication_t* ind);
|
||||
|
||||
|
||||
/*! A callback for the RX_CQI.indication
|
||||
* \param config A pointer to the vnf p7 configuration
|
||||
* \param ind A data structure for the decoded RX_CQI.indication This will
|
||||
* have been allocated on the stack.
|
||||
* \param ind A data structure for the decoded RX_CQI.indication This will
|
||||
* have been allocated on the stack.
|
||||
* \return not currently used.
|
||||
*
|
||||
* The ind may contain pointers to dyanmically allocated sub structures
|
||||
* such as the pdu. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
*
|
||||
* The ind may contain pointers to dyanmically allocated sub structures
|
||||
* such as the pdu. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
* 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 (*cqi_indication)(struct nfapi_vnf_p7_config* config, nfapi_cqi_indication_t* ind);
|
||||
|
||||
|
||||
/*! A callback for the LBT_DL.indication
|
||||
* \param config A pointer to the vnf p7 configuration
|
||||
* \param ind A data structure for the decoded LBT_DL.indication This will
|
||||
* have been allocated on the stack.
|
||||
* \param ind A data structure for the decoded LBT_DL.indication This will
|
||||
* have been allocated on the stack.
|
||||
* \return not currently used.
|
||||
*
|
||||
* The ind may contain pointers to dyanmically allocated sub structures
|
||||
* such as the pdu. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
*
|
||||
* The ind may contain pointers to dyanmically allocated sub structures
|
||||
* such as the pdu. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
* 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 (*lbt_dl_indication)(struct nfapi_vnf_p7_config* config, nfapi_lbt_dl_indication_t* ind);
|
||||
|
||||
|
||||
/*! A callback for the NB_HARQ.indication
|
||||
* \param config A pointer to the vnf p7 configuration
|
||||
* \param ind A data structure for the decoded LBT_DL.indication This will
|
||||
* have been allocated on the stack.
|
||||
* \param ind A data structure for the decoded LBT_DL.indication This will
|
||||
* have been allocated on the stack.
|
||||
* \return not currently used.
|
||||
*
|
||||
* The ind may contain pointers to dyanmically allocated sub structures
|
||||
* such as the pdu. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
*
|
||||
* The ind may contain pointers to dyanmically allocated sub structures
|
||||
* such as the pdu. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
* 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 (*nb_harq_indication)(struct nfapi_vnf_p7_config* config, nfapi_nb_harq_indication_t* ind);
|
||||
|
||||
*/
|
||||
int (*nb_harq_indication)(struct nfapi_vnf_p7_config* config, nfapi_nb_harq_indication_t* ind);
|
||||
|
||||
/*! A callback for the NRACH.indication
|
||||
* \param config A pointer to the vnf p7 configuration
|
||||
* \param ind A data structure for the decoded LBT_DL.indication This will
|
||||
* have been allocated on the stack.
|
||||
* \param ind A data structure for the decoded LBT_DL.indication This will
|
||||
* have been allocated on the stack.
|
||||
* \return not currently used.
|
||||
*
|
||||
* The ind may contain pointers to dyanmically allocated sub structures
|
||||
* such as the pdu. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
*
|
||||
* The ind may contain pointers to dyanmically allocated sub structures
|
||||
* such as the pdu. The dyanmically allocated structure will
|
||||
* be deallocated on return. If the client wishes to 'keep' the structures
|
||||
* 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 (*nrach_indication)(struct nfapi_vnf_p7_config* config, nfapi_nrach_indication_t* ind);
|
||||
|
||||
*/
|
||||
int (*nrach_indication)(struct nfapi_vnf_p7_config* config, nfapi_nrach_indication_t* ind);
|
||||
|
||||
/*! A callback for any vendor extension messages
|
||||
* \param config A pointer to the vnf p7 configuration
|
||||
* \param msg A data structure for the decoded vendor extention message allocated
|
||||
* using the allocate_p7_vendor_ext callback
|
||||
* \return not currently used.
|
||||
*/
|
||||
*/
|
||||
int (*vendor_ext)(struct nfapi_vnf_p7_config* config, nfapi_p7_message_header_t* msg);
|
||||
|
||||
/*! Optional userdata that will be passed back in the callbacks*/
|
||||
void* user_data;
|
||||
|
||||
|
||||
/*! A callback to allocate a memory for a vendor extension message
|
||||
* \param message_id The message is taken from the p7 message header
|
||||
* \param msg_size The is the vendor extention message that has been allocated.
|
||||
* \param msg_size The is the vendor extention message that has been allocated.
|
||||
* The callee must set this value
|
||||
* \return A pointer to an allocated vendor extention message
|
||||
*/
|
||||
nfapi_p7_message_header_t* (*allocate_p7_vendor_ext)(uint16_t message_id, uint16_t* msg_size);
|
||||
|
||||
|
||||
/*! A callback to deallocate a vendor extension message
|
||||
* \param header A pointer to an allocated vendor extention message
|
||||
*/
|
||||
@@ -871,7 +888,7 @@ nfapi_vnf_p7_config_t* nfapi_vnf_p7_config_create(void);
|
||||
*
|
||||
* The pointer to the config will not long be valid after this call
|
||||
*/
|
||||
|
||||
|
||||
void nfapi_vnf_p7_config_destory(nfapi_vnf_p7_config_t* config);
|
||||
|
||||
/*! Start the VNF P7 library.
|
||||
@@ -879,15 +896,17 @@ void nfapi_vnf_p7_config_destory(nfapi_vnf_p7_config_t* config);
|
||||
* \return A status value. 0 equal success, -1 indicates failure
|
||||
*
|
||||
* This function is blocking and will not return until the nfapi_vnf_p7_stop
|
||||
* function is called.
|
||||
* function is called.
|
||||
*/
|
||||
|
||||
int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config);
|
||||
|
||||
/*! Stop the VNF P7 library.
|
||||
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
|
||||
* \return A status value. 0 equal success, -1 indicates failure
|
||||
*
|
||||
*
|
||||
* This function will cause the nfapi_vnf_p7_start function to return
|
||||
*/
|
||||
int nfapi_vnf_p7_stop(nfapi_vnf_p7_config_t* config);
|
||||
@@ -908,7 +927,7 @@ int nfapi_vnf_p7_release_pdu(nfapi_vnf_p7_config_t* config, void*);
|
||||
|
||||
/*! Add a vnf p7 instance to the vnf p7 module
|
||||
* \param config A pointer to the vnf p7 configuration
|
||||
* \param pnf_p7_addr The udp address the pnf p7 entity has chosen
|
||||
* \param pnf_p7_addr The udp address the pnf p7 entity has chosen
|
||||
* \param pnf_p7_port The udp port the pnf p7 entity has chosen
|
||||
* \param phy_id The unique phy id for the pnf p7 entity
|
||||
* \return A status value. 0 equal success, -1 indicates failure
|
||||
@@ -932,7 +951,7 @@ int nfapi_vnf_p7_del_pnf(nfapi_vnf_p7_config_t* config, int phy_id);
|
||||
* \param config A pointer to the vnf p7 configuration
|
||||
* \param req A data structure for the decoded DL_CONFIG.request.
|
||||
* \return A status value. 0 equal success, -1 indicates failure
|
||||
*
|
||||
*
|
||||
* The caller is responsiable for memory management of any pointers set in the req, which
|
||||
* may be released after this function call has returned or at a later pointer
|
||||
*/
|
||||
@@ -943,37 +962,37 @@ int nfapi_vnf_p7_nr_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_nr_dl_tti
|
||||
* \param config A pointer to the vnf p7 configuration
|
||||
* \param req A data structure for the decoded UL_CONFIG.request.
|
||||
* \return A status value. 0 equal success, -1 indicates failure
|
||||
*
|
||||
*
|
||||
* The caller is responsiable for memory management of any pointers set in the req, which
|
||||
* 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.
|
||||
* \return A status value. 0 equal success, -1 indicates failure
|
||||
*
|
||||
*
|
||||
* The caller is responsiable for memory management of any pointers set in the req, which
|
||||
* 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.
|
||||
* \return A status value. 0 equal success, -1 indicates failure
|
||||
*
|
||||
*
|
||||
* The caller is responsiable for memory management of any pointers set in the req, which
|
||||
* 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.
|
||||
* \return A status value. 0 equal success, -1 indicates failure
|
||||
*
|
||||
*
|
||||
* The caller is responsiable for memory management of any pointers set in the req, which
|
||||
* may be released after this function call has returned or at a later pointer
|
||||
*/
|
||||
@@ -983,7 +1002,7 @@ int nfapi_vnf_p7_lbt_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_lbt_dl_c
|
||||
* \param config A pointer to the vnf p7 configuration
|
||||
* \param msg A data structure for the decoded vendor extention message
|
||||
* \return A status value. 0 equal success, -1 indicates failure
|
||||
*
|
||||
*
|
||||
* The caller is responsiable for memory management of any pointers set in the req, which
|
||||
* may be released after this function call has returned or at a later pointer
|
||||
*/
|
||||
|
||||
@@ -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)
|
||||
@@ -1026,6 +1470,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
|
||||
@@ -1053,6 +1503,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);
|
||||
@@ -1073,6 +1529,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)
|
||||
{
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -63,7 +64,7 @@ void nfapi_vnf_config_destory(nfapi_vnf_config_t* config)
|
||||
free(config);
|
||||
}
|
||||
|
||||
int nfapi_vnf_start(nfapi_vnf_config_t* config)
|
||||
int nfapi_nr_vnf_start(nfapi_vnf_config_t* config)
|
||||
{
|
||||
// Verify that config is not null
|
||||
if(config == 0)
|
||||
@@ -291,6 +292,411 @@ int nfapi_vnf_start(nfapi_vnf_config_t* config)
|
||||
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)
|
||||
{
|
||||
assert(config != 0);
|
||||
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)
|
||||
{
|
||||
@@ -486,6 +892,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 +912,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 +943,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 +963,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 +982,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 +1044,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 +1054,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 +1156,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
@@ -23,12 +23,12 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "vnf_p7.h"
|
||||
|
||||
#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));
|
||||
@@ -91,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, ¤t_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)
|
||||
@@ -181,7 +543,7 @@ int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config)
|
||||
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))
|
||||
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);
|
||||
|
||||
@@ -256,8 +618,8 @@ int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config)
|
||||
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,
|
||||
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);
|
||||
}
|
||||
if(selectRetval == 0)
|
||||
@@ -407,6 +769,7 @@ if (selectRetval==-1 && errno == 22)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int nfapi_vnf_p7_stop(nfapi_vnf_p7_config_t* config)
|
||||
{
|
||||
if(config == 0)
|
||||
@@ -433,17 +796,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 = 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);
|
||||
@@ -489,7 +853,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)
|
||||
@@ -500,6 +873,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)
|
||||
@@ -508,6 +889,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)
|
||||
|
||||
Reference in New Issue
Block a user