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

This commit is contained in:
Raymond Knopp
2021-02-23 11:51:29 +01:00
73 changed files with 10416 additions and 444 deletions
+1 -1
View File
@@ -25,4 +25,4 @@
]
}
]
}
}
+21 -3
View File
@@ -2153,7 +2153,23 @@ set (MCE_APP_SRC
${OPENAIR2_DIR}/MCE_APP/mce_app.c
${OPENAIR2_DIR}/MCE_APP/mce_config.c
)
set (MISC_NFAPI_LTE
${OPENAIR1_DIR}/SCHED/nfapi_lte_dummy.c
)
add_library(MISC_NFAPI_LTE_LIB
${MISC_NFAPI_LTE}
)
set (MISC_NFAPI_NR
${OPENAIR1_DIR}/SCHED/nfapi_nr_dummy.c
)
add_library(MISC_NFAPI_NR_LIB
${MISC_NFAPI_NR}
)
add_library(L2
${L2_SRC}
${MAC_SRC}
@@ -2908,7 +2924,7 @@ add_dependencies(lte-softmodem rrc_flag s1ap_flag x2_flag oai_iqplayer)
target_link_libraries (lte-softmodem
-Wl,--start-group
RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB
PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7
PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB MISC_NFAPI_LTE_LIB LFDS7
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB}
-Wl,--end-group z dl)
@@ -2951,7 +2967,7 @@ add_dependencies(ocp-enb rrc_flag s1ap_flag x2_flag oai_iqplayer coding params_l
target_link_libraries (ocp-enb
-Wl,--start-group
RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB
PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7 SIMU_COMMON
PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB MISC_NFAPI_LTE_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7 SIMU_COMMON
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB}
-Wl,--end-group z dl)
target_link_libraries (ocp-enb ${LIBXML2_LIBRARIES} pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${LIB_LMS_LIBRARIES} ${T_LIB})
@@ -3047,7 +3063,7 @@ target_link_libraries (lte-uesoftmodem
-Wl,--start-group
RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB F1AP F1AP_LIB
GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON
PHY_UE PHY_RU LFDS L2_UE L2_LTE LFDS7 SIMU_COMMON SIMU NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
PHY_UE PHY_RU LFDS L2_UE L2_LTE LFDS7 SIMU_COMMON SIMU NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB MISC_NFAPI_LTE_LIB
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${ATLAS_LIBRARIES}
-Wl,--end-group z dl)
@@ -3176,6 +3192,8 @@ target_link_libraries (nr-uesoftmodem
-Wl,--start-group
RRC_LIB NR_RRC_LIB NGAP_LIB NGAP_GNB SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB
PHY_COMMON PHY_NR_COMMON PHY_UE PHY_NR_UE PHY_RU LFDS NR_L2_UE L2_UE_LTE_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB
NFAPI_USER_LIB MISC_NFAPI_NR_LIB S1AP_LIB S1AP_ENB
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES}
NFAPI_USER_LIB S1AP_LIB S1AP_ENB
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES} LIB_5GNAS_GNB
-Wl,--end-group z dl)
+1 -1
View File
@@ -43,7 +43,7 @@
#include "config_userapi.h"
#include "../utils/LOG/log.h"
#define CONFIG_SHAREDLIBFORMAT "libparams_%s.so"
#include "nfapi/oai_integration/vendor_ext.h"
int load_config_sharedlib(configmodule_interface_t *cfgptr) {
void *lib_handle;
+1
View File
@@ -74,6 +74,7 @@ int config_sync_var=-1;
volatile int oai_exit = 0;
double cpuf;
uint16_t sf_ahead=4;
//uint16_t slot_ahead=6;
int otg_enabled;
uint64_t downlink_frequency[MAX_NUM_CCs][4];
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
+5 -3
View File
@@ -84,7 +84,7 @@
#include "T.h"
#include "nfapi/oai_integration/vendor_ext.h"
//#define DEBUG_THREADS 1
//#define USRP_DEBUG 1
@@ -137,6 +137,7 @@ void wakeup_prach_gNB(PHY_VARS_gNB *gNB, RU_t *ru, int frame, int subframe);
extern uint8_t nfapi_mode;
extern void oai_subframe_ind(uint16_t sfn, uint16_t sf);
extern void oai_slot_ind(uint16_t sfn, uint16_t slot);
extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset);
//#define TICK_TO_US(ts) (ts.diff)
@@ -151,13 +152,14 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t
// *******************************************************************
// NFAPI not yet supported for NR - this code has to be revised
if (nfapi_mode == 1) {
if (NFAPI_MODE == NFAPI_MODE_PNF) {
// I am a PNF and I need to let nFAPI know that we have a (sub)frame tick
//add_subframe(&frame, &subframe, 4);
//oai_subframe_ind(proc->frame_tx, proc->subframe_tx);
//LOG_D(PHY, "oai_subframe_ind(frame:%u, subframe:%d) - NOT CALLED ********\n", frame, subframe);
start_meas(&nfapi_meas);
oai_subframe_ind(frame_rx, slot_rx);
// oai_subframe_ind(frame_rx, slot_rx);
oai_slot_ind(frame_rx, slot_rx);
stop_meas(&nfapi_meas);
/*if (gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus||
+1
View File
@@ -114,6 +114,7 @@ int attach_rru(RU_t *ru);
int connect_rau(RU_t *ru);
uint16_t sf_ahead;
uint16_t slot_ahead;
uint16_t sl_ahead;
extern int emulate_rf;
+8 -7
View File
@@ -85,12 +85,13 @@ unsigned short config_frames[4] = {2,9,11,13};
#include "x2ap_eNB.h"
#include "ngap_gNB.h"
#include "gnb_paramdef.h"
#include "nfapi/oai_integration/vendor_ext.h"
pthread_cond_t nfapi_sync_cond;
pthread_mutex_t nfapi_sync_mutex;
int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex
uint8_t nfapi_mode = 0; // Default to monolithic mode
extern uint8_t nfapi_mode; // Default to monolithic mode
pthread_cond_t sync_cond;
pthread_mutex_t sync_mutex;
@@ -816,7 +817,7 @@ if(!IS_SOFTMODEM_NOS1)
AssertFatal(create_gNB_tasks(1) == 0,"cannot create ITTI tasks\n");
} else {
printf("No ITTI, Initializing L1\n");
RCconfig_L1();
RCconfig_NR_L1();
}
/* Start the agent. If it is turned off in the configuration, it won't start */
@@ -837,7 +838,7 @@ if(!IS_SOFTMODEM_NOS1)
usleep(1000);
if (nfapi_mode) {
if (NFAPI_MODE) {
printf("NFAPI*** - mutex and cond created - will block shortly for completion of PNF connection\n");
pthread_cond_init(&sync_cond,NULL);
pthread_mutex_init(&sync_mutex, NULL);
@@ -845,7 +846,7 @@ if(!IS_SOFTMODEM_NOS1)
const char *nfapi_mode_str = "<UNKNOWN>";
switch(nfapi_mode) {
switch(NFAPI_MODE) {
case 0:
nfapi_mode_str = "MONOLITHIC";
break;
@@ -865,7 +866,7 @@ if(!IS_SOFTMODEM_NOS1)
printf("NFAPI MODE:%s\n", nfapi_mode_str);
if (nfapi_mode==2) // VNF
if (NFAPI_MODE==NFAPI_MODE_VNF)
wait_nfapi_init("main?");
printf("START MAIN THREADS\n");
@@ -894,7 +895,7 @@ if(!IS_SOFTMODEM_NOS1)
config_sync_var=0;
if (nfapi_mode==1) { // PNF
if (NFAPI_MODE==NFAPI_MODE_PNF) {
wait_nfapi_init("main?");
}
@@ -914,7 +915,7 @@ if(!IS_SOFTMODEM_NOS1)
load_softscope("nr",&p);
}
if (nfapi_mode != 1 && nfapi_mode != 2) {
if (NFAPI_MODE != NFAPI_MODE_PNF && NFAPI_MODE != NFAPI_MODE_VNF) {
printf("Not NFAPI mode - call init_eNB_afterRU()\n");
init_eNB_afterRU();
} else {
+4
View File
@@ -39,11 +39,14 @@
#include "executables/thread-common.h"
#include "common/utils/LOG/log.h"
#include "softmodem-common.h"
#include "nfapi/oai_integration/vendor_ext.h"
static softmodem_params_t softmodem_params;
char *parallel_config=NULL;
char *worker_config=NULL;
uint8_t nfapi_mode=0;
static mapping softmodem_funcs[] = MAPPING_SOFTMODEM_FUNCTIONS;
static struct timespec start;
@@ -143,6 +146,7 @@ void get_common_options(uint32_t execmask) {
if(parallel_config != NULL) set_parallel_conf(parallel_config);
if(worker_config != NULL) set_worker_conf(worker_config);
nfapi_setmode(nfapi_mode);
}
void softmodem_printresources(int sig, telnet_printfunc_t pf) {
struct rusage usage;
+5
View File
@@ -93,6 +93,7 @@ extern "C"
#define CONFIG_HLP_RFSIM "Run in rf simulator mode (also known as basic simulator)\n"
#define CONFIG_HLP_NOKRNMOD "(noS1 only): Use tun instead of namesh module \n"
#define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n"
#define CONFIG_HLP_NFAPI "Change the nFAPI mode for NR\n"
/*-----------------------------------------------------------------------------------------------------------------------------------------------------*/
/* command line parameters common to eNodeB and UE */
@@ -114,6 +115,7 @@ extern "C"
#define SEND_DMRSSYNC softmodem_params.send_dmrs_sync
#define USIM_TEST softmodem_params.usim_test
#define USE_256QAM_TABLE softmodem_params.use_256qam_table
#define NFAPI softmodem_params.nfapi
#define DEFAULT_RFCONFIG_FILE "/usr/local/etc/syriq/ue.band7.tm1.PRB100.NR40.dat";
@@ -145,6 +147,7 @@ extern "C"
{"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, uptr:&nonbiot, defuintval:0, TYPE_INT, 0}, \
{"use-256qam-table", CONFIG_HLP_256QAM, PARAMFLAG_BOOL, iptr:&USE_256QAM_TABLE, defintval:0, TYPE_INT, 0}, \
{"usrp-tx-thread-config", CONFIG_HLP_USRP_THREAD, 0, iptr:&usrp_tx_thread, defstrval:0, TYPE_INT, 0}, \
{"nfapi", CONFIG_HLP_NFAPI, 0, u8ptr:&nfapi_mode, defintval:0, TYPE_UINT8, 0}, \
}
@@ -232,6 +235,7 @@ typedef struct {
int hw_timing_advance;
uint32_t send_dmrs_sync;
int use_256qam_table;
uint8_t nfapi;
} softmodem_params_t;
extern uint64_t get_softmodem_optmask(void);
@@ -244,6 +248,7 @@ extern void set_softmodem_sighandler(void);
extern uint64_t downlink_frequency[MAX_NUM_CCs][4];
extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
extern int usrp_tx_thread;
extern uint8_t nfapi_mode;
#ifdef __cplusplus
}
#endif
+2
View File
@@ -0,0 +1,2 @@
# Changelog
+35
View File
@@ -0,0 +1,35 @@
# Procedure to run nFAPI in 5G NR
## Conributed by 5G Testbed IISC
### Developers: Sudhakar B,Mahesh K,Gokul S,Aniq U.R
## Procedure to Build gNB and UE
The regular commands to build gNB and UE can be used
```
sudo ./build_oai --gNB --UE
```
## Procedure to run NR nFAPI using RF-Simulator
### VNF command
```
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf --nfapi 2 --noS1 --phy-test
```
### PNF command
```
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpx300.conf --nfapi 1 --rfsim --phy-test --rfsimulator.serveraddr server
```
### UE command
```
sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem --rfsim --phy-test --rrc_config_path . -d
```
## Procedure to run NR nFAPI using Hardware
Will be updated as we have not yet currently tested on hardware
## Notes
* In order to acheive the synchronization between VNF and PNF and receive the P7 messages within the timing window the order in which we should run the modules on different terminals is UE->VNF->PNF
* Currently only downlink is functional and working as we are still working on uplink functionality
File diff suppressed because it is too large Load Diff
+3
View File
@@ -23,5 +23,8 @@
#define NFAPI_PNF_H__
int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind);
void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port);
void configure_nr_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port);
void oai_subframe_ind(uint16_t sfn, uint16_t sf);
void oai_slot_ind(uint16_t sfn, uint16_t slot);
#endif
+480 -13
View File
@@ -39,8 +39,12 @@
#include "nfapi_vnf.h"
#include "PHY/defs_eNB.h"
#include "PHY/LTE_TRANSPORT/transport_proto.h"
#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
#include "common/ran_context.h"
#define TEST
extern RAN_CONTEXT_t RC;
extern UL_RCC_IND_t UL_RCC_INFO;
@@ -189,11 +193,12 @@ int vnf_pack_vendor_extension_tlv(void *ve, uint8_t **ppWritePackedMsg, uint8_t
int vnf_unpack_vendor_extension_tlv(nfapi_tl_t *tl, uint8_t **ppReadPackedMessage, uint8_t *end, void **ve, nfapi_p4_p5_codec_config_t *codec) {
return -1;
}
void install_nr_schedule_handlers(NR_IF_Module_t *if_inst);
void install_schedule_handlers(IF_Module_t *if_inst);
extern int single_thread_flag;
extern void init_eNB_afterRU(void);
extern uint16_t sf_ahead;
extern uint16_t slot_ahead;
void oai_create_enb(void) {
int bodge_counter=0;
@@ -231,6 +236,39 @@ void oai_enb_init(void) {
init_eNB_afterRU();
}
void oai_create_gnb(void) {
int bodge_counter=0;
PHY_VARS_gNB *gNB = RC.gNB[0];
RC.nb_nr_CC = (int *)malloc(sizeof(int)); // TODO: find a better function to place this in
gNB->Mod_id = bodge_counter;
gNB->CC_id = bodge_counter;
gNB->abstraction_flag = 0;
gNB->single_thread_flag = 0;//single_thread_flag;
RC.nb_nr_CC[bodge_counter] = 1;
if (gNB->if_inst==0) {
gNB->if_inst = NR_IF_Module_init(bodge_counter);
}
// This will cause phy_config_request to be installed. That will result in RRC configuring the PHY
// that will result in gNB->configured being set to TRUE.
// See we need to wait for that to happen otherwise the NFAPI message exchanges won't contain the right parameter values
if (RC.gNB[0]->if_inst==0 || RC.gNB[0]->if_inst->NR_PHY_config_req==0 || RC.gNB[0]->if_inst->NR_Schedule_response==0) {
printf("RC.gNB[0][0]->if_inst->NR_PHY_config_req is not installed - install it\n");
install_nr_schedule_handlers(RC.gNB[0]->if_inst);
}
do {
printf("%s() Waiting for gNB to become configured (by RRC/PHY) - need to wait otherwise NFAPI messages won't contain correct values\n", __FUNCTION__);
usleep(50000);
} while(gNB->configured != 1);
printf("%s() gNB is now configured\n", __FUNCTION__);
}
int pnf_connection_indication_cb(nfapi_vnf_config_t *config, int p5_idx) {
printf("[VNF] pnf connection indication idx:%d\n", p5_idx);
oai_create_enb();
@@ -241,6 +279,16 @@ int pnf_connection_indication_cb(nfapi_vnf_config_t *config, int p5_idx) {
return 0;
}
int pnf_nr_connection_indication_cb(nfapi_vnf_config_t *config, int p5_idx) {
printf("[VNF] pnf connection indication idx:%d\n", p5_idx);
oai_create_gnb();
nfapi_nr_pnf_param_request_t req;
memset(&req, 0, sizeof(req));
req.header.message_id = NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_REQUEST;
nfapi_nr_vnf_pnf_param_req(config, p5_idx, &req);
return 0;
}
int pnf_disconnection_indication_cb(nfapi_vnf_config_t *config, int p5_idx) {
printf("[VNF] pnf disconnection indication idx:%d\n", p5_idx);
vnf_info *vnf = (vnf_info *)(config->user_data);
@@ -251,6 +299,42 @@ int pnf_disconnection_indication_cb(nfapi_vnf_config_t *config, int p5_idx) {
return 0;
}
int pnf_nr_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_pnf_param_response_t *resp) {
printf("[VNF] pnf param response idx:%d error:%d\n", p5_idx, resp->error_code);
vnf_info *vnf = (vnf_info *)(config->user_data);
pnf_info *pnf = vnf->pnfs;
for(int i = 0; i < resp->pnf_phy.number_of_phys; ++i) {
phy_info phy;
memset(&phy,0,sizeof(phy));
phy.index = resp->pnf_phy.phy[i].phy_config_index;
printf("[VNF] (PHY:%d) phy_config_idx:%d\n", i, resp->pnf_phy.phy[i].phy_config_index);
nfapi_vnf_allocate_phy(config, p5_idx, &(phy.id));
for(int j = 0; j < resp->pnf_phy.phy[i].number_of_rfs; ++j) {
printf("[VNF] (PHY:%d) (RF%d) %d\n", i, j, resp->pnf_phy.phy[i].rf_config[j].rf_config_index);
phy.rfs[0] = resp->pnf_phy.phy[i].rf_config[j].rf_config_index;
}
pnf->phys[0] = phy;
}
nfapi_nr_pnf_config_request_t req;
memset(&req, 0, sizeof(req));
req.header.message_id = NFAPI_PNF_CONFIG_REQUEST;
req.pnf_phy_rf_config.tl.tag = NFAPI_PNF_PHY_RF_TAG;
req.pnf_phy_rf_config.number_phy_rf_config_info = 2; // DJP pnf.phys.size();
printf("DJP:Hard coded num phy rf to 2\n");
for(unsigned i = 0; i < 2; ++i) {
req.pnf_phy_rf_config.phy_rf_config[i].phy_id = pnf->phys[i].id;
req.pnf_phy_rf_config.phy_rf_config[i].phy_config_index = pnf->phys[i].index;
req.pnf_phy_rf_config.phy_rf_config[i].rf_config_index = pnf->phys[i].rfs[0];
}
nfapi_nr_vnf_pnf_config_req(config, p5_idx, &req);
return 0;
}
int pnf_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_param_response_t *resp) {
printf("[VNF] pnf param response idx:%d error:%d\n", p5_idx, resp->error_code);
vnf_info *vnf = (vnf_info *)(config->user_data);
@@ -270,7 +354,6 @@ int pnf_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_param_re
pnf->phys[0] = phy;
}
for(int i = 0; i < resp->pnf_rf.number_of_rfs; ++i) {
rf_info rf;
memset(&rf,0,sizeof(rf));
@@ -278,7 +361,6 @@ int pnf_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_param_re
printf("[VNF] (RF:%d) rf_config_idx:%d\n", i, resp->pnf_rf.rf[i].rf_config_index);
pnf->rfs[0] = rf;
}
nfapi_pnf_config_request_t req;
memset(&req, 0, sizeof(req));
req.header.message_id = NFAPI_PNF_CONFIG_REQUEST;
@@ -296,6 +378,31 @@ int pnf_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_param_re
return 0;
}
int pnf_nr_config_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_pnf_config_response_t *resp) {
printf("[VNF] pnf config response idx:%d resp[header[phy_id:%u message_id:%02x message_length:%u]]\n", p5_idx, resp->header.phy_id, resp->header.message_id, resp->header.message_length);
if(1) {
nfapi_nr_pnf_start_request_t req;
memset(&req, 0, sizeof(req));
req.header.phy_id = resp->header.phy_id;
req.header.message_id = NFAPI_PNF_START_REQUEST;
nfapi_nr_vnf_pnf_start_req(config, p5_idx, &req);
} else {
// Rather than send the pnf_start_request we will demonstrate
// sending a vendor extention message. The start request will be
// send when the vendor extension response is received
//vnf_info* vnf = (vnf_info*)(config->user_data);
vendor_ext_p5_req req;
memset(&req, 0, sizeof(req));
req.header.message_id = P5_VENDOR_EXT_REQ;
req.dummy1 = 45;
req.dummy2 = 1977;
nfapi_vnf_vendor_extension(config, p5_idx, &req.header);
}
return 0;
}
int pnf_config_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_config_response_t *resp) {
printf("[VNF] pnf config response idx:%d resp[header[phy_id:%u message_id:%02x message_length:%u]]\n", p5_idx, resp->header.phy_id, resp->header.message_id, resp->header.message_length);
@@ -321,6 +428,70 @@ int pnf_config_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_config_
return 0;
}
int wake_gNB_rxtx(PHY_VARS_gNB *gNB, uint16_t sfn, uint16_t slot) {
struct timespec curr_t;
clock_gettime(CLOCK_MONOTONIC,&curr_t);
//printf("\n wake_gNB_rxtx before assignment sfn:%d slot:%d TIME %d.%d",sfn,slot,curr_t.tv_sec,curr_t.tv_nsec);
gNB_L1_proc_t *proc=&gNB->proc;
gNB_L1_rxtx_proc_t *L1_proc= (slot&1)? &proc->L1_proc : &proc->L1_proc_tx;
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
//printf("%s(eNB:%p, sfn:%d, sf:%d)\n", __FUNCTION__, eNB, sfn, sf);
//int i;
struct timespec wait;
clock_gettime(CLOCK_REALTIME, &wait);
wait.tv_sec = 0;
wait.tv_nsec +=5000L;
//wait.tv_nsec = 0;
// wake up TX for subframe n+sf_ahead
// lock the TX mutex and make sure the thread is ready
if (pthread_mutex_timedlock(&L1_proc->mutex,&wait) != 0) {
LOG_E( PHY, "[gNB] ERROR pthread_mutex_lock for gNB RXTX thread %d (IC %d)\n", L1_proc->slot_rx&1,L1_proc->instance_cnt );
exit_fun( "error locking mutex_rxtx" );
return(-1);
}
{
static uint16_t old_slot = 0;
static uint16_t old_sfn = 0;
proc->slot_rx = old_slot;
proc->frame_rx = old_sfn;
// Try to be 1 frame back
old_slot = slot;
old_sfn = sfn;
//printf("\n wake_gNB_rxtx after assignment sfn:%d slot:%d",proc->frame_rx,proc->slot_rx);
if (old_slot == 0 && old_sfn % 100 == 0) LOG_W( PHY,"[gNB] sfn/slot:%d%d old_sfn/slot:%d%d proc[rx:%d%d]\n", sfn, slot, old_sfn, old_slot, proc->frame_rx, proc->slot_rx);
}
++L1_proc->instance_cnt;
//LOG_D( PHY,"[VNF-subframe_ind] sfn/sf:%d:%d proc[frame_rx:%d subframe_rx:%d] L1_proc->instance_cnt_rxtx:%d \n", sfn, sf, proc->frame_rx, proc->subframe_rx, L1_proc->instance_cnt_rxtx);
// We have just received and processed the common part of a subframe, say n.
// TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired
// transmitted timestamp of the next TX slot (first).
// The last (TS_rx mod samples_per_frame) was n*samples_per_tti,
// we want to generate subframe (n+N), so TS_tx = TX_rx+N*samples_per_tti,
// and proc->subframe_tx = proc->subframe_rx+sf_ahead
L1_proc->timestamp_tx = proc->timestamp_rx + (slot_ahead *fp->samples_per_subframe);
L1_proc->frame_rx = proc->frame_rx;
L1_proc->slot_rx = proc->slot_rx;
L1_proc->frame_tx = (L1_proc->slot_rx > (19-slot_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx;
L1_proc->slot_tx = (L1_proc->slot_rx + slot_ahead)%20;
//LOG_I(PHY, "sfn/sf:%d%d proc[rx:%d%d] rx:%d%d] About to wake rxtx thread\n\n", sfn, slot, proc->frame_rx, proc->slot_rx, L1_proc->frame_rx, L1_proc->slot_rx);
//printf("\nEntering wake_gNB_rxtx sfn %d slot %d\n",L1_proc->frame_rx,L1_proc->slot_rx);
// the thread can now be woken up
if (pthread_cond_signal(&L1_proc->cond) != 0) {
LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB RXn-TXnp4 thread\n");
exit_fun( "ERROR pthread_clond_signal" );
return(-1);
}
//LOG_D(PHY,"%s() About to attempt pthread_mutex_unlock\n", __FUNCTION__);
pthread_mutex_unlock( &L1_proc->mutex );
//LOG_D(PHY,"%s() UNLOCKED pthread_mutex_unlock\n", __FUNCTION__);
return(0);
}
int wake_eNB_rxtx(PHY_VARS_eNB *eNB, uint16_t sfn, uint16_t sf) {
L1_proc_t *proc=&eNB->proc;
L1_rxtx_proc_t *L1_proc= (sf&1)? &proc->L1_proc : &proc->L1_proc_tx;
@@ -416,6 +587,7 @@ int phy_sync_indication(struct nfapi_vnf_p7_config *config, uint8_t sync) {
printf("[VNF] SYNC %s\n", sync==1 ? "ACHIEVED" : "LOST");
if (sync==1 && nfapi_sync_var!=0) {
printf("[VNF] Signal to OAI main code that it can go\n");
pthread_mutex_lock(&nfapi_sync_mutex);
nfapi_sync_var=0;
@@ -426,6 +598,29 @@ int phy_sync_indication(struct nfapi_vnf_p7_config *config, uint8_t sync) {
return(0);
}
int phy_slot_indication(struct nfapi_vnf_p7_config *config, uint16_t phy_id, uint16_t sfn, uint16_t slot) {
static uint8_t first_time = 1;
if (first_time) {
printf("[VNF] slot indication %d\n", NFAPI_SFNSLOT2DEC(sfn, slot));
first_time = 0;
}
if (RC.gNB && RC.gNB[0]->configured) {
// uint16_t sfn = NFAPI_SFNSF2SFN(sfn_sf);
// uint16_t sf = NFAPI_SFNSF2SF(sfn_sf);
LOG_D(PHY,"[VNF] slot indication sfn:%d sf:%d\n", sfn, slot);
wake_gNB_rxtx(RC.gNB[0], sfn, slot); // DONE: find NR equivalent
} else {
printf("[VNF] %s() RC.gNB:%p\n", __FUNCTION__, RC.gNB);
if (RC.gNB) printf("RC.gNB[0]->configured:%d\n", RC.gNB[0]->configured);
}
return 0;
}
int phy_subframe_indication(struct nfapi_vnf_p7_config *config, uint16_t phy_id, uint16_t sfn_sf) {
static uint8_t first_time = 1;
@@ -937,6 +1132,14 @@ int vnf_pack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t *header, uint8_
static pthread_t vnf_start_pthread;
static pthread_t vnf_p7_start_pthread;
void *vnf_nr_p7_start_thread(void *ptr) {
printf("%s()\n", __FUNCTION__);
pthread_setname_np(pthread_self(), "VNF_P7");
nfapi_vnf_p7_config_t *config = (nfapi_vnf_p7_config_t *)ptr;
nfapi_nr_vnf_p7_start(config);
return config;
}
void *vnf_p7_start_thread(void *ptr) {
printf("%s()\n", __FUNCTION__);
pthread_setname_np(pthread_self(), "VNF_P7");
@@ -947,12 +1150,13 @@ void *vnf_p7_start_thread(void *ptr) {
void set_thread_priority(int priority);
void *vnf_p7_thread_start(void *ptr) {
void *vnf_nr_p7_thread_start(void *ptr) {
set_thread_priority(79);
vnf_p7_info *p7_vnf = (vnf_p7_info *)ptr;
p7_vnf->config->port = p7_vnf->local_port;
p7_vnf->config->sync_indication = &phy_sync_indication;
p7_vnf->config->subframe_indication = &phy_subframe_indication;
p7_vnf->config->slot_indication = &phy_slot_indication;
p7_vnf->config->harq_indication = &phy_harq_indication;
p7_vnf->config->crc_indication = &phy_crc_indication;
p7_vnf->config->rx_indication = &phy_rx_indication;
@@ -977,11 +1181,72 @@ void *vnf_p7_thread_start(void *ptr) {
p7_vnf->config->codec_config.deallocate = &vnf_deallocate;
p7_vnf->config->allocate_p7_vendor_ext = &phy_allocate_p7_vendor_ext;
p7_vnf->config->deallocate_p7_vendor_ext = &phy_deallocate_p7_vendor_ext;
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Creating VNF NFAPI start thread %s\n", __FUNCTION__);
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Creating VNF NFAPI P7 start thread %s\n", __FUNCTION__);
pthread_create(&vnf_p7_start_pthread, NULL, &vnf_nr_p7_start_thread, p7_vnf->config);
return 0;
}
void *vnf_p7_thread_start(void *ptr) {
set_thread_priority(79);
vnf_p7_info *p7_vnf = (vnf_p7_info *)ptr;
p7_vnf->config->port = p7_vnf->local_port;
p7_vnf->config->sync_indication = &phy_sync_indication;
p7_vnf->config->subframe_indication = &phy_subframe_indication;
p7_vnf->config->slot_indication = &phy_slot_indication;
p7_vnf->config->harq_indication = &phy_harq_indication;
p7_vnf->config->crc_indication = &phy_crc_indication;
p7_vnf->config->rx_indication = &phy_rx_indication;
p7_vnf->config->rach_indication = &phy_rach_indication;
p7_vnf->config->srs_indication = &phy_srs_indication;
p7_vnf->config->sr_indication = &phy_sr_indication;
p7_vnf->config->cqi_indication = &phy_cqi_indication;
p7_vnf->config->lbt_dl_indication = &phy_lbt_dl_indication;
p7_vnf->config->nb_harq_indication = &phy_nb_harq_indication;
p7_vnf->config->nrach_indication = &phy_nrach_indication;
p7_vnf->config->malloc = &vnf_allocate;
p7_vnf->config->free = &vnf_deallocate;
p7_vnf->config->trace = &vnf_trace;
p7_vnf->config->vendor_ext = &phy_vendor_ext;
p7_vnf->config->user_data = p7_vnf;
p7_vnf->mac->user_data = p7_vnf;
p7_vnf->config->codec_config.unpack_p7_vendor_extension = &phy_unpack_p7_vendor_extension;
p7_vnf->config->codec_config.pack_p7_vendor_extension = &phy_pack_p7_vendor_extension;
p7_vnf->config->codec_config.unpack_vendor_extension_tlv = &phy_unpack_vendor_extension_tlv;
p7_vnf->config->codec_config.pack_vendor_extension_tlv = &phy_pack_vendor_extension_tlv;
p7_vnf->config->codec_config.allocate = &vnf_allocate;
p7_vnf->config->codec_config.deallocate = &vnf_deallocate;
p7_vnf->config->allocate_p7_vendor_ext = &phy_allocate_p7_vendor_ext;
p7_vnf->config->deallocate_p7_vendor_ext = &phy_deallocate_p7_vendor_ext;
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Creating VNF NFAPI P7 start thread %s\n", __FUNCTION__);
pthread_create(&vnf_p7_start_pthread, NULL, &vnf_p7_start_thread, p7_vnf->config);
return 0;
}
int pnf_nr_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_pnf_start_response_t *resp) {
vnf_info *vnf = (vnf_info *)(config->user_data);
vnf_p7_info *p7_vnf = vnf->p7_vnfs;
pnf_info *pnf = vnf->pnfs;
nfapi_nr_param_request_scf_t req;
printf("[VNF] pnf start response idx:%d config:%p user_data:%p p7_vnf[config:%p thread_started:%d]\n", p5_idx, config, config->user_data, vnf->p7_vnfs[0].config, vnf->p7_vnfs[0].thread_started);
if(p7_vnf->thread_started == 0) {
pthread_t vnf_p7_thread;
pthread_create(&vnf_p7_thread, NULL, &vnf_nr_p7_thread_start, p7_vnf);
p7_vnf->thread_started = 1;
} else {
// P7 thread already running.
}
// start all the phys in the pnf.
printf("[VNF] Sending NFAPI_VNF_PARAM_REQUEST phy_id:%d\n", pnf->phys[0].id);
memset(&req, 0, sizeof(req));
req.header.message_id = NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST;
req.header.phy_id = pnf->phys[0].id;
nfapi_nr_vnf_param_req(config, p5_idx, &req);
return 0;
}
int pnf_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_start_response_t *resp) {
vnf_info *vnf = (vnf_info *)(config->user_data);
vnf_p7_info *p7_vnf = vnf->p7_vnfs;
@@ -998,7 +1263,7 @@ int pnf_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_start_re
}
// start all the phys in the pnf.
printf("[VNF] Sending NFAPI_PARAM_REQUEST phy_id:%d\n", pnf->phys[0].id);
printf("[VNF] Sending NFAPI_VNF_PARAM_REQUEST phy_id:%d\n", pnf->phys[0].id);
memset(&req, 0, sizeof(req));
req.header.message_id = NFAPI_PARAM_REQUEST;
req.header.phy_id = pnf->phys[0].id;
@@ -1008,6 +1273,69 @@ int pnf_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_start_re
extern uint32_t to_earfcn(int eutra_bandP,uint32_t dl_CarrierFreq,uint32_t bw);
int nr_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_param_response_scf_t *resp) {
printf("[VNF] Received NFAPI_PARAM_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id);
vnf_info *vnf = (vnf_info *)(config->user_data);
vnf_p7_info *p7_vnf = vnf->p7_vnfs;
pnf_info *pnf = vnf->pnfs;
phy_info *phy = pnf->phys;
struct sockaddr_in pnf_p7_sockaddr;
nfapi_nr_config_request_scf_t *req = &RC.nrmac[0]->config[0]; // check
phy->remote_port = 32123;//resp->nfapi_config.p7_pnf_port.value;
memcpy(&pnf_p7_sockaddr.sin_addr.s_addr, &(resp->nfapi_config.p7_pnf_address_ipv4.address[0]), 4);
phy->remote_addr = inet_ntoa(pnf_p7_sockaddr.sin_addr);
// for now just 1
printf("[VNF] %d.%d pnf p7 %s:%d timing %u %u %u %u\n", p5_idx, phy->id, phy->remote_addr, phy->remote_port, p7_vnf->timing_window, p7_vnf->periodic_timing_period, p7_vnf->aperiodic_timing_enabled,
p7_vnf->periodic_timing_period);
req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST;
req->header.phy_id = phy->id;
printf("[VNF] Send NFAPI_CONFIG_REQUEST\n");
//printf("\n NR bandP =%d\n",req->nfapi_config.rf_bands.rf_band[0]);
req->nfapi_config.p7_vnf_port.tl.tag = NFAPI_NR_NFAPI_P7_VNF_PORT_TAG;
req->nfapi_config.p7_vnf_port.value = p7_vnf->local_port;
req->num_tlv++;
printf("[VNF] DJP local_port:%d\n", p7_vnf->local_port);
req->nfapi_config.p7_vnf_address_ipv4.tl.tag = NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG;
struct sockaddr_in vnf_p7_sockaddr;
vnf_p7_sockaddr.sin_addr.s_addr = inet_addr(p7_vnf->local_addr);
memcpy(&(req->nfapi_config.p7_vnf_address_ipv4.address[0]), &vnf_p7_sockaddr.sin_addr.s_addr, 4);
req->num_tlv++;
printf("[VNF] DJP local_addr:%s\n", p7_vnf->local_addr);
req->nfapi_config.timing_window.tl.tag = NFAPI_NR_NFAPI_TIMING_WINDOW_TAG;
req->nfapi_config.timing_window.value = p7_vnf->timing_window;
printf("\n[VNF]Timing window tag : %d Timing window:%u\n",NFAPI_NR_NFAPI_TIMING_WINDOW_TAG, p7_vnf->timing_window);
req->num_tlv++;
if(p7_vnf->periodic_timing_enabled || p7_vnf->aperiodic_timing_enabled) {
req->nfapi_config.timing_info_mode.tl.tag = NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG;
req->nfapi_config.timing_info_mode.value = (p7_vnf->aperiodic_timing_enabled << 1) | (p7_vnf->periodic_timing_enabled);
req->num_tlv++;
if(p7_vnf->periodic_timing_enabled) {
req->nfapi_config.timing_info_period.tl.tag = NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG;
req->nfapi_config.timing_info_period.value = p7_vnf->periodic_timing_period;
req->num_tlv++;
}
}
//TODO: Assign tag and value for P7 message offsets
req->nfapi_config.dl_tti_timing_offset.tl.tag = NFAPI_NR_NFAPI_DL_TTI_TIMING_OFFSET;
req->nfapi_config.ul_tti_timing_offset.tl.tag = NFAPI_NR_NFAPI_UL_TTI_TIMING_OFFSET;
req->nfapi_config.ul_dci_timing_offset.tl.tag = NFAPI_NR_NFAPI_UL_DCI_TIMING_OFFSET;
req->nfapi_config.tx_data_timing_offset.tl.tag = NFAPI_NR_NFAPI_TX_DATA_TIMING_OFFSET;
vendor_ext_tlv_2 ve2;
memset(&ve2, 0, sizeof(ve2));
ve2.tl.tag = VENDOR_EXT_TLV_2_TAG;
ve2.dummy = 2016;
req->vendor_extension = &ve2.tl;
nfapi_nr_vnf_config_req(config, p5_idx, req);
printf("[VNF] Sent NFAPI_VNF_CONFIG_REQ num_tlv:%u\n",req->num_tlv);
return 0;
}
int param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_param_response_t *resp) {
printf("[VNF] Received NFAPI_PARAM_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id);
vnf_info *vnf = (vnf_info *)(config->user_data);
@@ -1016,7 +1344,7 @@ int param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_param_response_t
phy_info *phy = pnf->phys;
struct sockaddr_in pnf_p7_sockaddr;
nfapi_config_request_t *req = &RC.mac[0]->config[0];
phy->remote_port = resp->nfapi_config.p7_pnf_port.value;
phy->remote_port = 32123;//resp->nfapi_config.p7_pnf_port.value;
memcpy(&pnf_p7_sockaddr.sin_addr.s_addr, &(resp->nfapi_config.p7_pnf_address_ipv4.address[0]), 4);
phy->remote_addr = inet_ntoa(pnf_p7_sockaddr.sin_addr);
// for now just 1
@@ -1062,6 +1390,19 @@ int param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_param_response_t
return 0;
}
int nr_config_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_config_response_scf_t *resp) {
nfapi_nr_start_request_scf_t req;
printf("[VNF] Received NFAPI_CONFIG_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id);
printf("[VNF] Calling oai_enb_init()\n");
oai_enb_init(); // TODO: change to gnb
memset(&req, 0, sizeof(req));
req.header.message_id = NFAPI_NR_PHY_MSG_TYPE_START_REQUEST;
req.header.phy_id = resp->header.phy_id;
nfapi_nr_vnf_start_req(config, p5_idx, &req);
printf("[VNF] Send NFAPI_VNF_START_REQUEST idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id);
return 0;
}
int config_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_config_response_t *resp) {
nfapi_start_request_t req;
printf("[VNF] Received NFAPI_CONFIG_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id);
@@ -1085,6 +1426,17 @@ int start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_start_response_t
return 0;
}
int nr_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_start_response_scf_t *resp) {
printf("[VNF] Received NFAPI_START_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id);
vnf_info *vnf = (vnf_info *)(config->user_data);
pnf_info *pnf = vnf->pnfs;
phy_info *phy = pnf->phys;
vnf_p7_info *p7_vnf = vnf->p7_vnfs;
nfapi_vnf_p7_add_pnf((p7_vnf->config), phy->remote_addr, phy->remote_port, phy->id);
return 0;
}
int vendor_ext_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_p4_p5_message_header_t *msg) {
printf("[VNF] %s\n", __FUNCTION__);
@@ -1129,6 +1481,13 @@ void vnf_deallocate_p4_p5_vendor_ext(nfapi_p4_p5_message_header_t *header) {
nfapi_vnf_config_t *config = 0;
void vnf_nr_start_thread(void *ptr) {
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] VNF NFAPI thread - nfapi_vnf_start()%s\n", __FUNCTION__);
pthread_setname_np(pthread_self(), "VNF");
config = (nfapi_vnf_config_t *)ptr;
nfapi_nr_vnf_start(config);
}
void vnf_start_thread(void *ptr) {
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] VNF NFAPI thread - nfapi_vnf_start()%s\n", __FUNCTION__);
pthread_setname_np(pthread_self(), "VNF");
@@ -1138,7 +1497,57 @@ void vnf_start_thread(void *ptr) {
static vnf_info vnf;
/*------------------------------------------------------------------------------*/
void configure_nr_nfapi_vnf(char *vnf_addr, int vnf_p5_port) {
nfapi_setmode(NFAPI_MODE_VNF);
memset(&vnf, 0, sizeof(vnf));
memset(vnf.p7_vnfs, 0, sizeof(vnf.p7_vnfs));
vnf.p7_vnfs[0].timing_window = 32;
vnf.p7_vnfs[0].periodic_timing_enabled = 1;
vnf.p7_vnfs[0].aperiodic_timing_enabled = 0;
vnf.p7_vnfs[0].periodic_timing_period = 10;
vnf.p7_vnfs[0].config = nfapi_vnf_p7_config_create();
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] %s() vnf.p7_vnfs[0].config:%p VNF ADDRESS:%s:%d\n", __FUNCTION__, vnf.p7_vnfs[0].config, vnf_addr, vnf_p5_port);
strcpy(vnf.p7_vnfs[0].local_addr, vnf_addr);
//vnf.p7_vnfs[0].local_port = vnf.p7_vnfs[0].local_port; // 50001; // TODO: remove hardcode
vnf.p7_vnfs[0].local_port = 50011;
vnf.p7_vnfs[0].mac = (mac_t *)malloc(sizeof(mac_t));
nfapi_vnf_config_t *config = nfapi_vnf_config_create();
config->malloc = malloc;
config->free = free;
config->trace = &vnf_trace;
config->vnf_p5_port = vnf_p5_port;
config->vnf_ipv4 = 1;
config->vnf_ipv6 = 0;
config->pnf_list = 0;
config->phy_list = 0;
config->pnf_nr_connection_indication = &pnf_nr_connection_indication_cb;
config->pnf_disconnect_indication = &pnf_disconnection_indication_cb;
config->pnf_nr_param_resp = &pnf_nr_param_resp_cb;
config->pnf_nr_config_resp = &pnf_nr_config_resp_cb;
config->pnf_nr_start_resp = &pnf_nr_start_resp_cb;
config->nr_param_resp = &nr_param_resp_cb;
config->nr_config_resp = &nr_config_resp_cb;
config->nr_start_resp = &nr_start_resp_cb;
config->vendor_ext = &vendor_ext_cb;
config->user_data = &vnf;
// To allow custom vendor extentions to be added to nfapi
config->codec_config.unpack_vendor_extension_tlv = &vnf_unpack_vendor_extension_tlv;
config->codec_config.pack_vendor_extension_tlv = &vnf_pack_vendor_extension_tlv;
config->codec_config.unpack_p4_p5_vendor_extension = &vnf_unpack_p4_p5_vendor_extension;
config->codec_config.pack_p4_p5_vendor_extension = &vnf_pack_p4_p5_vendor_extension;
config->allocate_p4_p5_vendor_ext = &vnf_allocate_p4_p5_vendor_ext;
config->deallocate_p4_p5_vendor_ext = &vnf_deallocate_p4_p5_vendor_ext;
config->codec_config.allocate = &vnf_allocate;
config->codec_config.deallocate = &vnf_deallocate;
memset(&UL_RCC_INFO,0,sizeof(UL_RCC_IND_t));
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Creating VNF NFAPI start thread %s\n", __FUNCTION__);
pthread_create(&vnf_start_pthread, NULL, (void *)&vnf_nr_start_thread, config);
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Created VNF NFAPI start thread %s\n", __FUNCTION__);
}
void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port) {
nfapi_setmode(NFAPI_MODE_VNF);
memset(&vnf, 0, sizeof(vnf));
@@ -1150,7 +1559,8 @@ void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port) {
vnf.p7_vnfs[0].config = nfapi_vnf_p7_config_create();
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] %s() vnf.p7_vnfs[0].config:%p VNF ADDRESS:%s:%d\n", __FUNCTION__, vnf.p7_vnfs[0].config, vnf_addr, vnf_p5_port);
strcpy(vnf.p7_vnfs[0].local_addr, vnf_addr);
vnf.p7_vnfs[0].local_port = 50001;
//vnf.p7_vnfs[0].local_port = vnf.p7_vnfs[0].local_port; // 50001; // TODO: remove hardcode
vnf.p7_vnfs[0].local_port = 50011;
vnf.p7_vnfs[0].mac = (mac_t *)malloc(sizeof(mac_t));
nfapi_vnf_config_t *config = nfapi_vnf_config_create();
config->malloc = malloc;
@@ -1161,8 +1571,10 @@ void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port) {
config->vnf_ipv6 = 0;
config->pnf_list = 0;
config->phy_list = 0;
config->pnf_connection_indication = &pnf_connection_indication_cb;
config->pnf_disconnect_indication = &pnf_disconnection_indication_cb;
config->pnf_param_resp = &pnf_param_resp_cb;
config->pnf_config_resp = &pnf_config_resp_cb;
config->pnf_start_resp = &pnf_start_resp_cb;
@@ -1203,15 +1615,17 @@ int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) {
return retval;
}
int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_tti_request_t *dl_config_req)
int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req)
{
//LOG_I(PHY, "sfn:%d,slot:%d\n",dl_config_req->SFN,dl_config_req->Slot);
//printf("\nEntering oai_nfapi_nr_dl_config_req sfn:%d,slot:%d\n",dl_config_req->SFN,dl_config_req->Slot);
nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config;
dl_config_req->header.message_id= NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST;
dl_config_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
int retval = nfapi_vnf_p7_nr_dl_config_req(p7_config, dl_config_req);
dl_config_req->dl_tti_request_body.nPDUs = 0;
dl_config_req->dl_tti_request_body.nPDUs = 0;
dl_config_req->dl_tti_request_body.nGroup = 0;
@@ -1221,6 +1635,23 @@ int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_tti_request_t *dl_config_req)
return retval;
}
int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req)
{
nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config;
tx_data_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
tx_data_req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST;
//LOG_D(PHY, "[VNF] %s() TX_REQ sfn_sf:%d number_of_pdus:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(tx_req->sfn_sf), tx_req->tx_request_body.number_of_pdus);
int retval = nfapi_vnf_p7_tx_data_req(p7_config, tx_data_req);
if (retval!=0) {
LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval);
} else {
tx_data_req->Number_of_PDUs = 0;
}
return retval;
}
int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req)
{
nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config;
@@ -1238,6 +1669,22 @@ int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req)
return retval;
}
int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req) {
nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config;
ul_dci_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
ul_dci_req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST;
//LOG_D(PHY, "[VNF] %s() HI_DCI0_REQ sfn_sf:%d dci:%d hi:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(hi_dci0_req->sfn_sf), hi_dci0_req->hi_dci0_request_body.number_of_dci, hi_dci0_req->hi_dci0_request_body.number_of_hi);
int retval = nfapi_vnf_p7_ul_dci_req(p7_config, ul_dci_req);
if (retval!=0) {
LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval);
} else {
ul_dci_req->numPdus = 0;
}
return retval;
}
int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) {
nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config;
hi_dci0_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
@@ -1255,6 +1702,26 @@ int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) {
return retval;
}
int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req) {
nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config;
ul_tti_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
ul_tti_req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST;
int retval = nfapi_vnf_p7_ul_tti_req(p7_config, ul_tti_req);
if (retval!=0) {
LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval);
} else {
// Reset number of PDUs so that it is not resent
ul_tti_req->n_pdus = 0;
ul_tti_req->n_group = 0;
ul_tti_req->n_ulcch = 0;
ul_tti_req->n_ulsch = 0;
}
return retval;
}
int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) {
nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config;
ul_config_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
+1 -1
View File
@@ -23,5 +23,5 @@
#define NFAPI_VNF_H__
void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port);
void configure_nr_nfapi_vnf(char *vnf_addr, int vnf_p5_port);
#endif
@@ -120,6 +120,17 @@ typedef struct {
} nfapi_tl_t;
#define NFAPI_TAG_LENGTH_PACKED_LEN 4
// Convenience methods to convert between SFN/SLOT formats
#define NFAPI_SFNSLOT2DEC(_sfn,_slot) ( _sfn*20 + _slot ) // total count of slots
#define NFAPI_SFNSLOTDEC2SFNSLOT(_sfnslot_dec) ((((_sfnslot_dec) / 20) << 4) | (((_sfnslot_dec) - (((_sfnslot_dec) / 20) * 10)) & 0x3F))
#define NFAPI_SFNSLOT2SFN(_sfnslot) ((_sfnslot) >> 6)
#define NFAPI_SFNSLOT2SLOT(_sfnslot) ((_sfnslot) & 0x3F)
#define NFAPI_SFNSLOTDEC2SFN(_sfnslot_dec) ((_sfnslot_dec) / 20)
#define NFAPI_SFNSLOTDEC2SLOT(_sfnslot_dec) ((_sfnslot_dec) % 20)
#define NFAPI_MAX_SFNSLOTDEC 1024*20 // 20 is for numerology 1
// Convenience methods to convert between SFN/SFN formats
#define NFAPI_SFNSF2DEC(_sfnsf) ((((_sfnsf) >> 4) * 10) + ((_sfnsf) & 0xF))
#define NFAPI_SFNSFDEC2SFNSF(_sfnsf_dec) ((((_sfnsf_dec) / 10) << 4) | (((_sfnsf_dec) - (((_sfnsf_dec) / 10) * 10)) & 0xF))
@@ -176,7 +187,6 @@ typedef enum {
NFAPI_DL_NODE_SYNC,
NFAPI_TIMING_INFO,
NFAPI_RSSI_REQUEST = 0x0200,
NFAPI_RSSI_RESPONSE,
NFAPI_RSSI_INDICATION,
@@ -587,6 +597,26 @@ typedef struct {
#define NFAPI_PNF_PHY_RF_TAG 0x1003
// Generic strucutre for single tlv value.
typedef struct {
nfapi_tl_t tl;
int32_t value;
} nfapi_int32_tlv_t;
typedef struct {
nfapi_tl_t tl;
uint32_t value;
} nfapi_uint32_tlv_t;
typedef struct {
nfapi_tl_t tl;
int64_t value;
} nfapi_int64_tlv_t;
typedef struct {
nfapi_tl_t tl;
uint64_t value;
} nfapi_uint64_tlv_t;
typedef struct {
nfapi_tl_t tl;
uint16_t value;
@@ -1106,6 +1136,7 @@ typedef struct {
typedef struct {
nfapi_p4_p5_message_header_t header;
uint8_t num_tlvs;
nfapi_pnf_phy_rf_config_t pnf_phy_rf_config;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_pnf_config_request_t;
@@ -2466,7 +2497,7 @@ typedef struct {
typedef struct {
nfapi_p7_message_header_t header;
uint32_t t1;
int32_t delta_sfn_sf;
int32_t delta_sfn_sf;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_dl_node_sync_t;
@@ -2481,22 +2512,50 @@ typedef struct {
typedef struct {
nfapi_p7_message_header_t header;
uint32_t last_sfn_sf;
uint32_t time_since_last_timing_info;
uint32_t dl_config_jitter;
uint32_t tx_request_jitter;
uint32_t ul_config_jitter;
uint32_t hi_dci0_jitter;
int32_t dl_config_latest_delay;
int32_t tx_request_latest_delay;
int32_t ul_config_latest_delay;
int32_t hi_dci0_latest_delay;
int32_t dl_config_earliest_arrival;
int32_t tx_request_earliest_arrival;
int32_t ul_config_earliest_arrival;
int32_t hi_dci0_earliest_arrival;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_timing_info_t;
typedef struct {
nfapi_p7_message_header_t header;
uint32_t last_sfn;
uint32_t last_slot;
uint32_t time_since_last_timing_info;
uint32_t dl_tti_jitter;
uint32_t tx_data_request_jitter;
uint32_t ul_tti_jitter;
uint32_t ul_dci_jitter;
int32_t dl_tti_latest_delay;
int32_t tx_data_request_latest_delay;
int32_t ul_tti_latest_delay;
int32_t ul_dci_latest_delay;
int32_t dl_tti_earliest_arrival;
int32_t tx_data_request_earliest_arrival;
int32_t ul_tti_earliest_arrival;
int32_t ul_dci_earliest_arrival;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nr_timing_info_t;
typedef struct {
nfapi_tl_t tl;
uint32_t handle;
@@ -3653,6 +3712,50 @@ typedef struct {
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nmm_stop_response_t;
typedef struct
{
// TODO: see if this needs to be uncommented
// These TLVs are used to setup the transport connection between VNF and PNF
nfapi_ipv4_address_t p7_vnf_address_ipv4;
nfapi_ipv6_address_t p7_vnf_address_ipv6;
nfapi_uint16_tlv_t p7_vnf_port;
nfapi_ipv4_address_t p7_pnf_address_ipv4;
nfapi_ipv6_address_t p7_pnf_address_ipv6;
nfapi_uint16_tlv_t p7_pnf_port;
nfapi_uint8_tlv_t timing_window; //Value: 0 → 30,000 microseconds
nfapi_uint8_tlv_t timing_info_mode;
nfapi_uint8_tlv_t timing_info_period;
nfapi_uint32_tlv_t dl_tti_timing_offset;
nfapi_uint32_tlv_t ul_tti_timing_offset;
nfapi_uint32_tlv_t ul_dci_timing_offset;
nfapi_uint32_tlv_t tx_data_timing_offset;
// These TLVs are used to setup the transport connection between VNF and PNF
/*
nfapi_uint8_tlv_t dl_ue_per_sf;
nfapi_uint8_tlv_t ul_ue_per_sf;
// These TLVs are used by PNF to report its RF capabilities to the VNF software
nfapi_rf_bands_t rf_bands;
*/
// These TLVs are used by the VNF to configure the synchronization with the PNF.
// These TLVs are used by the VNF to configure the RF in the PNF
//nfapi_uint16_tlv_t max_transmit_power;
//nfapi_uint32_tlv_t nrarfcn;
// nfapi_nmm_frequency_bands_t nmm_gsm_frequency_bands;
// nfapi_nmm_frequency_bands_t nmm_umts_frequency_bands;
// nfapi_nmm_frequency_bands_t nmm_lte_frequency_bands;
// nfapi_uint8_tlv_t nmm_uplink_rssi_supported;
} nfapi_nr_nfapi_t;
//
// Configuration options for the encode decode functions
//
@@ -3864,6 +3967,7 @@ int nfapi_p4_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
*
*/
int nfapi_p5_message_pack(void *pMessageBuf, uint32_t messageBufLen, void *pPackedBuf, uint32_t packedBufLen, nfapi_p4_p5_codec_config_t* config);
int nfapi_nr_p5_message_pack(void *pMessageBuf, uint32_t messageBufLen, void *pPackedBuf, uint32_t packedBufLen, nfapi_p4_p5_codec_config_t* config);
/*! \brief Decodes an NFAPI P5 message header
* \param pMessageBuf A pointer to an encoded P5 message header
@@ -3887,6 +3991,7 @@ int nfapi_p5_message_header_unpack(void *pMessageBuf, uint32_t messageBufLen, vo
*
* The function will decode a byte stream pointed to by pMessageBuf into a nfapi p5 message structure pointer to by pUnpackedBuf
*/
int nfapi_nr_p5_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p4_p5_codec_config_t* config);
int nfapi_p5_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p4_p5_codec_config_t* config);
/*! \brief Encodes an NFAPI P7 message to a buffer
@@ -3900,6 +4005,7 @@ int nfapi_p5_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
*
*/
int nfapi_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t* config);
int nfapi_nr_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t* config);
/*! \brief Decodes an NFAPI P7 message header
* \param pMessageBuf A pointer to an encoded P7 message header
@@ -3925,6 +4031,7 @@ int nfapi_p7_message_header_unpack(void *pMessageBuf, uint32_t messageBufLen, vo
* The function will decode a byte stream pointed to by pMessageBuf into a nfapi p7 message structure pointer to by pUnpackedBuf
*/
int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p7_codec_config_t* config);
int nfapi_nr_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p7_codec_config_t* config);
/*! \brief Calculates the checksum of a message
*
@@ -10,7 +10,7 @@
#define _NFAPI_NR_INTERFACE_H_
#include "nfapi_interface.h"
#include <nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h>
#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h"
#define NFAPI_NR_MAX_NB_CCE_AGGREGATION_LEVELS 5
#define NFAPI_NR_MAX_NB_TCI_STATES_PDCCH 64
@@ -22,62 +22,32 @@
// nFAPI enums
//These TLVs are used exclusively by nFAPI
typedef struct
{
// These TLVs are used to setup the transport connection between VNF and PNF
// nfapi_ipv4_address_t p7_vnf_address_ipv4;
// nfapi_ipv6_address_t p7_vnf_address_ipv6;
// nfapi_uint16_tlv_t p7_vnf_port;
// nfapi_ipv4_address_t p7_pnf_address_ipv4;
// nfapi_ipv6_address_t p7_pnf_address_ipv6;
// nfapi_uint16_tlv_t p7_pnf_port;
// // These TLVs are used to setup the transport connection between VNF and PNF
// nfapi_uint8_tlv_t dl_ue_per_sf;
// nfapi_uint8_tlv_t ul_ue_per_sf;
// These TLVs are used by PNF to report its RF capabilities to the VNF software
nfapi_rf_bands_t rf_bands;
// These TLVs are used by the VNF to configure the synchronization with the PNF.
// nfapi_uint8_tlv_t timing_window;
// nfapi_uint8_tlv_t timing_info_mode;
// nfapi_uint8_tlv_t timing_info_period;
// These TLVs are used by the VNF to configure the RF in the PNF
// nfapi_uint16_tlv_t max_transmit_power;
nfapi_uint32_tlv_t nrarfcn;
// nfapi_nmm_frequency_bands_t nmm_gsm_frequency_bands;
// nfapi_nmm_frequency_bands_t nmm_umts_frequency_bands;
// nfapi_nmm_frequency_bands_t nmm_lte_frequency_bands;
// nfapi_uint8_tlv_t nmm_uplink_rssi_supported;
} nfapi_nr_nfapi_t;
#define NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG 0x5100
#define NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG 0x5101
#define NFAPI_NR_NFAPI_P7_VNF_PORT_TAG 0x5102
#define NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV4_TAG 0x5103
#define NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV6_TAG 0x5104
#define NFAPI_NR_NFAPI_P7_PNF_PORT_TAG 0x5105
#define NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG 0x0100
#define NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG 0x0101
#define NFAPI_NR_NFAPI_P7_VNF_PORT_TAG 0x0102
#define NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV4_TAG 0x0103
#define NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV6_TAG 0x0104
#define NFAPI_NR_NFAPI_P7_PNF_PORT_TAG 0x0105
#define NFAPI_NR_NFAPI_DL_TTI_TIMING_OFFSET 0x0106
#define NFAPI_NR_NFAPI_UL_TTI_TIMING_OFFSET 0x0107
#define NFAPI_NR_NFAPI_UL_DCI_TIMING_OFFSET 0x0108
#define NFAPI_NR_NFAPI_TX_DATA_TIMING_OFFSET 0x0109
#define NFAPI_NR_NFAPI_TIMING_WINDOW_TAG 0x011E
#define NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG 0x011F
#define NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG 0x0120
/*
#define NFAPI_NR_NFAPI_DOWNLINK_UES_PER_SUBFRAME_TAG 0x510A
#define NFAPI_NR_NFAPI_UPLINK_UES_PER_SUBFRAME_TAG 0x510B
#define NFAPI_NR_NFAPI_RF_BANDS_TAG 0x5114
#define NFAPI_NR_NFAPI_TIMING_WINDOW_TAG 0x511E
#define NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG 0x511F
#define NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG 0x5120
#define NFAPI_NR_NFAPI_MAXIMUM_TRANSMIT_POWER_TAG 0x5128
#define NFAPI_NR_NFAPI_NRARFCN_TAG 0x5129
#define NFAPI_NR_NFAPI_NMM_GSM_FREQUENCY_BANDS_TAG 0x5130
#define NFAPI_NR_NFAPI_NMM_UMTS_FREQUENCY_BANDS_TAG 0x5131
#define NFAPI_NR_NFAPI_NMM_LTE_FREQUENCY_BANDS_TAG 0x5132
#define NFAPI_NR_NFAPI_NMM_UPLINK_RSSI_SUPPORTED_TAG 0x5133
*/
// P5 Message Structures
typedef struct {
@@ -323,7 +293,7 @@ typedef enum {
typedef enum {
NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED=0,
NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED
NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED=1
} nfapi_nr_cce_reg_mapping_type_e;
typedef enum {
@@ -11,6 +11,7 @@
#include "stddef.h"
#include "nfapi_interface.h"
#include "nfapi_nr_interface.h"
#define NFAPI_NR_MAX_NB_CCE_AGGREGATION_LEVELS 5
#define NFAPI_NR_MAX_NB_TCI_STATES_PDCCH 64
@@ -24,25 +25,7 @@
#define NFAPI_MAX_NUM_CB 8
// Extension to the generic structures for single tlv values
typedef struct {
nfapi_tl_t tl;
int32_t value;
} nfapi_int32_tlv_t;
typedef struct {
nfapi_tl_t tl;
uint32_t value;
} nfapi_uint32_tlv_t;
typedef struct {
nfapi_tl_t tl;
int64_t value;
} nfapi_int64_tlv_t;
typedef struct {
nfapi_tl_t tl;
uint64_t value;
} nfapi_uint64_tlv_t;
typedef enum {
NFAPI_NR_DMRS_TYPE1=0,
@@ -76,35 +59,42 @@ typedef enum {
NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST= 0X05,
NFAPI_NR_PHY_MSG_TYPE_STOP_INDICATION=0X06,
NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION=0X07,
NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE=0X010D,
NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE=0X010F,
//RESERVED 0X08 ~ 0X7F
NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST= 0X80,
NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST= 0X81,
NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION=0X82,
NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST= 0X83,
NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST=0X54,
NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST=0X84, // CHANGED TO 0X84
NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION=0X85,
NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION= 0X86,
NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION= 0X87,
NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION= 0X88,
NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION= 0X89
NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION= 0X89,
//RESERVED 0X8a ~ 0xff
NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_REQUEST = 0x0100,
NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_RESPONSE = 0x0101,
NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_REQUEST= 0x0102,
NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_RESPONSE= 0x0103,
NFAPI_NR_PHY_MSG_TYPE_PNF_START_REQUEST= 0x0104,
NFAPI_NR_PHY_MSG_TYPE_PNF_START_RESPONSE= 0x0105,
NFAPI_NR_PHY_MSG_TYPE_PNF_STOP_REQUEST= 0x0106,
NFAPI_NR_PHY_MSG_TYPE_PNF_STOP_RESPONSE= 0x0107,
NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC = 0x0180,
NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC,
NFAPI_NR_PHY_MSG_TYPE_TIMING_INFO
} nfapi_nr_phy_msg_type_e;
// SCF222_5G-FAPI_PHY_SPI_Specificayion.pdf Section 3.3
//3.3.1 PARAM
//same with nfapi_param_request_t
typedef struct {
nfapi_p4_p5_message_header_t header;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nr_param_request_t;
typedef enum {
NFAPI_NR_PARAM_MSG_OK = 0,
NFAPI_NR_PARAM_MSG_INVALID_STATE
} nfapi_nr_param_errors_e;
/*typedef struct {
nfapi_nr_param_errors_e error_code;
@@ -278,12 +268,6 @@ typedef struct
//-------------------------------------------//
//3.3.2 CONFIG
typedef enum {
NFAPI_NR_CONFIG_MSG_OK = 0,
NFAPI_NR_CONFIG_MSG_INVALID_CONFIG //The configuration provided has missing mandatory TLVs, or TLVs that are invalid or unsupported in this state.
} nfapi_nr_config_errors_e;
/*typedef struct {
nfapi_nr_config_errors_e error_code;
uint8_t number_of_invalid_tlvs_that_can_only_be_configured_in_idle;
@@ -465,9 +449,108 @@ typedef struct
} nfapi_nr_measurement_config_t;
// ERROR enums
typedef enum { // Table 2-22
NFAPI_NR_PARAM_MSG_OK = 0,
NFAPI_NR_PARAM_MSG_INVALID_STATE
} nfapi_nr_param_errors_e;
typedef enum { // Table 2-25
NFAPI_NR_CONFIG_MSG_OK = 0,
NFAPI_NR_CONFIG_MSG_INVALID_STATE, //The CONFIG.request was received when the PHY was not in the IDLE state or the CONFIGURED state.
NFAPI_NR_CONFIG_MSG_INVALID_CONFIG //The configuration provided has missing mandatory TLVs, or TLVs that are invalid or unsupported in this state.
} nfapi_nr_config_errors_e;
typedef enum { // Table 2-27
NFAPI_NR_START_MSG_OK = 0,
NFAPI_NR_START_MSG_INVALID_STATE
} nfapi_nr_start_errors_e;
//PNF P5 NR
typedef struct {
nfapi_p4_p5_message_header_t header;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nr_pnf_param_request_t;
typedef struct {
uint8_t num_tlv;
nfapi_p4_p5_message_header_t header;
uint32_t error_code;
nfapi_pnf_param_general_t pnf_param_general;
nfapi_pnf_phy_t pnf_phy;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nr_pnf_param_response_t;
typedef struct {
nfapi_p4_p5_message_header_t header;
uint8_t num_tlvs;
nfapi_pnf_phy_rf_config_t pnf_phy_rf_config;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nr_pnf_config_request_t;
typedef struct {
nfapi_p4_p5_message_header_t header;
uint32_t error_code;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nr_pnf_config_response_t;
typedef struct {
nfapi_p4_p5_message_header_t header;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nr_pnf_start_request_t;
typedef struct {
nfapi_p4_p5_message_header_t header;
uint32_t error_code;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nr_pnf_start_response_t;
typedef struct {
nfapi_p4_p5_message_header_t header;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nr_pnf_stop_request_t;
typedef struct {
nfapi_p4_p5_message_header_t header;
uint32_t error_code;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nr_pnf_stop_response_t;
/* PARAM.REQUEST */
typedef struct {
nfapi_p4_p5_message_header_t header;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nr_param_request_scf_t;
/* PARAM.RESPONSE */
typedef struct {
nfapi_p4_p5_message_header_t header;
uint8_t error_code;
uint8_t num_tlv;
nfapi_vendor_extension_tlv_t vendor_extension;
nfapi_nr_cell_param_t cell_param;
nfapi_nr_carrier_param_t carrier_param;
nfapi_nr_pdcch_param_t pdcch_param;
nfapi_nr_pucch_param_t pucch_param;
nfapi_nr_pdsch_param_t pdsch_param;
nfapi_nr_pusch_param_t pusch_param;
nfapi_nr_prach_param_t prach_param;
nfapi_nr_measurement_param_t measurement_param;
nfapi_nr_nfapi_t nfapi_config;
} nfapi_nr_param_response_scf_t;
//------------------------------//
//3.3.2 CONFIG
/* CONFIG.REQUEST */
typedef struct {
nfapi_p4_p5_message_header_t header;
uint8_t num_tlv;
nfapi_vendor_extension_tlv_t vendor_extension;
nfapi_nr_carrier_config_t carrier_config;
nfapi_nr_cell_config_t cell_config;
nfapi_nr_ssb_config_t ssb_config;
@@ -475,20 +558,32 @@ typedef struct {
nfapi_nr_ssb_table_t ssb_table;
nfapi_nr_tdd_table_t tdd_table;
nfapi_nr_measurement_config_t measurement_config;
nfapi_nr_nfapi_t nfapi_config;
} nfapi_nr_config_request_scf_t;
/* CONFIG.RESPONSE */
typedef struct {
nfapi_p4_p5_message_header_t header;
uint8_t error_code;
//uint8_t num_invalid_tlvs;
// TODO: add list of invalid/unsupported TLVs (see Table 3.18)
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nr_config_response_scf_t;
//------------------------------//
//3.3.3 START
typedef struct {
nfapi_p4_p5_message_header_t header;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nr_start_request_t;
} nfapi_nr_start_request_scf_t;
typedef enum {
NFAPI_NR_START_MSG_INVALID_STATE
} nfapi_nr_start_errors_e;
typedef struct {
nfapi_p4_p5_message_header_t header;
nfapi_nr_start_errors_e error_code;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nr_start_response_scf_t;
//3.3.4 STOP
@@ -497,6 +592,7 @@ typedef struct {
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nr_stop_request_t;
typedef struct {
nfapi_p4_p5_message_header_t header;
nfapi_vendor_extension_tlv_t vendor_extension;
@@ -580,7 +676,7 @@ typedef struct {
uint16_t sfn; //0->1023
uint16_t slot;//0->319
} nfapi_nr_slot_indication_t;
} nfapi_nr_slot_indication_scf_t;
// 3.4.2
@@ -941,6 +1037,7 @@ typedef struct {
} nfapi_nr_dl_tti_request_pdu_t;
#define NFAPI_NR_MAX_DL_TTI_PDUS 32
typedef struct {
/// Number of PDUs that are included in this message. All PDUs in the message are numbered in order. Value 0 -> 255
uint8_t nPDUs;
@@ -954,11 +1051,28 @@ typedef struct {
uint8_t PduIdx[256][12];
} nfapi_nr_dl_tti_request_body_t;
typedef struct {
nfapi_p7_message_header_t header;
uint32_t t1;
int32_t delta_sfn_slot;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nr_dl_node_sync_t;
typedef struct {
nfapi_p7_message_header_t header;
uint32_t t1;
uint32_t t2;
uint32_t t3;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nr_ul_node_sync_t;
typedef struct {
nfapi_p7_message_header_t header;
/// System Frame Number (0-1023)
uint16_t SFN;
/// Slot number (0-319)
/// Slot number (0-19)
uint16_t Slot;
nfapi_nr_dl_tti_request_body_t dl_tti_request_body;
nfapi_vendor_extension_tlv_t vendor_extension;
@@ -973,7 +1087,7 @@ typedef struct
nfapi_nr_dl_tti_ssb_pdu_t* ssb_pdu;
} nfapi_nr_dl_pdu_configuration_t;
*/
/*
/*
typedef struct
{
uint16_t pdu_type;//0: PDCCH PDU 1: PDSCH PDU 2: CSI-RS PDU 3: SSB PDU,
@@ -1272,6 +1386,7 @@ typedef struct
} nfapi_nr_ul_tti_request_number_of_groups_t;
typedef struct {
nfapi_p7_message_header_t header;
uint16_t SFN; //0->1023
uint16_t Slot;//0->319
uint8_t n_pdus;//Number of PDUs that are included in this message. All PDUs in the message are numbered in order. Value 0 -> 255
@@ -1318,6 +1433,7 @@ typedef struct {
} nfapi_nr_ul_dci_request_pdus_t;
typedef struct {
nfapi_p7_message_header_t header;
uint16_t SFN;
uint16_t Slot;
uint8_t numPdus;
@@ -1363,6 +1479,7 @@ typedef struct
#define NFAPI_NR_MAX_TX_REQUEST_PDUS 16
typedef struct
{
nfapi_p7_message_header_t header;
uint16_t SFN;
uint16_t Slot;
uint16_t Number_of_PDUs;
+1 -1
View File
@@ -712,7 +712,7 @@ int unpack_tlv_list(unpack_tlv_t unpack_fns[], uint16_t size, uint8_t **ppReadPa
for(idx = 0; idx < size; ++idx)
{
if(unpack_fns[idx].tag == generic_tl.tag)
if(unpack_fns[idx].tag == generic_tl.tag) // match the extracted tag value with all the tags in unpack_fn list
{
tagMatch = 1;
nfapi_tl_t* tl = (nfapi_tl_t*)(unpack_fns[idx].tlv);
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+2
View File
@@ -38,7 +38,9 @@ typedef struct {
int pnf_connect(pnf_t *pnf);
int pnf_message_pump(pnf_t *pnf);
int pnf_nr_message_pump(pnf_t *pnf);
int pnf_nr_pack_and_send_p5_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len);
int pnf_pack_and_send_p5_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len);
int pnf_pack_and_send_p4_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len);
int pnf_send_message(pnf_t* pnf, uint8_t* msg, uint32_t msg_len, uint16_t stream_id);
+38 -2
View File
@@ -29,15 +29,37 @@
typedef struct {
uint16_t dl_conf_ontime;
uint16_t dl_tti_ontime;
uint16_t dl_conf_late;
uint16_t dl_tti_late;
uint16_t ul_conf_ontime;
uint16_t ul_tti_ontime;
uint16_t ul_conf_late;
uint16_t ul_tti_late;
uint16_t hi_dci0_ontime;
uint16_t hi_dci0_late;
uint16_t ul_dci_ontime;
uint16_t ul_dci_late;
uint16_t tx_ontime;
uint16_t tx_late;
uint16_t tx_data_ontime;
uint16_t tx_data_late;
} pnf_p7_stats_t;
typedef struct { // TODO: replace with the stats
uint16_t dl_tti_ontime;
uint16_t dl_tti_late;
uint16_t ul_tti_ontime;
uint16_t ul_tti_late;
uint16_t ul_dci_ontime;
uint16_t ul_dci_late;
uint16_t tx_data_ontime;
uint16_t tx_data_late;
} pnf_p7_nr_stats_t;
typedef struct {
uint8_t* buffer;
uint16_t length;
@@ -82,7 +104,7 @@ typedef struct {
pthread_mutex_t pack_mutex; // should we allow the client to specifiy
nfapi_pnf_p7_subframe_buffer_t subframe_buffer[30/*NFAPI_MAX_TIMING_WINDOW_SIZE*/];
nfapi_pnf_p7_slot_buffer_t slot_buffer[30/*NFAPI_MAX_TIMING_WINDOW_SIZE*/];
uint32_t sequence_number;
uint16_t max_num_segments;
@@ -94,6 +116,12 @@ typedef struct {
uint16_t sfn_sf;
uint32_t sf_start_time_hr;
int32_t sfn_sf_shift;
uint16_t sfn;
uint16_t slot;
uint16_t sfn_slot;
uint32_t slot_start_time_hr;
int32_t slot_shift;
uint8_t timing_info_period_counter;
uint8_t timing_info_aperiodic_send; // 0:false 1:true
@@ -104,18 +132,26 @@ typedef struct {
uint32_t ul_config_jitter;
uint32_t hi_dci0_jitter;
uint32_t tx_jitter;
//P7 NR
uint32_t dl_tti_jitter;
uint32_t ul_tti_jitter;
uint32_t ul_dci_jitter;
uint32_t tx_data_jitter;
uint32_t tick;
pnf_p7_stats_t stats;
pnf_p7_nr_stats_t nr_stats;
} pnf_p7_t;
int pnf_p7_message_pump(pnf_p7_t* pnf_p7);
int pnf_nr_p7_message_pump(pnf_p7_t* pnf_p7);
int pnf_p7_pack_and_send_p7_message(pnf_p7_t* pnf_p7, nfapi_p7_message_header_t* msg, uint32_t msg_len);
int pnf_p7_send_message(pnf_p7_t* pnf_p7, uint8_t* msg, uint32_t msg_len);
int pnf_p7_slot_ind(pnf_p7_t* config, uint16_t phy_id, uint16_t sfn, uint16_t slot);
int pnf_p7_subframe_ind(pnf_p7_t* config, uint16_t phy_id, uint16_t sfn_sf);
pnf_p7_rx_message_t* pnf_p7_rx_reassembly_queue_add_segment(pnf_p7_t* pnf_p7, pnf_p7_rx_reassembly_queue_t* queue, uint32_t rx_hr_time, uint16_t sequence_number, uint16_t segment_number, uint8_t m, uint8_t* data, uint16_t data_len);
@@ -25,8 +25,13 @@ extern "C" {
#include "nfapi_interface.h"
#include "debug.h"
#include <openair2/PHY_INTERFACE/IF_Module.h>
#include <openair1/PHY/defs_eNB.h>
#include "nfapi_nr_interface.h"
#include "nfapi_nr_interface_scf.h"
#include <sys/types.h>
#include "openair1/PHY/defs_gNB.h"
/*! This enum is used to describe the states of the pnf
*/
@@ -121,6 +126,7 @@ typedef struct nfapi_pnf_config
* The client is expected to send the PNF_PARAM.response after receiving the
* PNF_PARAM.request. This can be done in the call back.
*/
int (*pnf_nr_param_req)(nfapi_pnf_config_t* config, nfapi_nr_pnf_param_request_t* req);
int (*pnf_param_req)(nfapi_pnf_config_t* config, nfapi_pnf_param_request_t* req);
/*! A callback for the PNF_CONFIG.request
@@ -133,7 +139,8 @@ typedef struct nfapi_pnf_config
* PNF_CONFIG.request. This can be done in the call back.
*/
int (*pnf_config_req)(nfapi_pnf_config_t* config, nfapi_pnf_config_request_t* req);
int (*pnf_nr_config_req)(nfapi_pnf_config_t* config, nfapi_nr_pnf_config_request_t* req);
/*! A callback for the PNF_START.request
* \param config A pointer to the pnf configuration
* \param req A data structure for the decoded PNF_CONFIG.request. This will have
@@ -144,7 +151,8 @@ typedef struct nfapi_pnf_config
* PNF_START.request. This can be done in the call back.
*/
int (*pnf_start_req)(nfapi_pnf_config_t* config, nfapi_pnf_start_request_t* req);
int (*pnf_nr_start_req)(nfapi_pnf_config_t* config, nfapi_nr_pnf_start_request_t* req);
/*! A callback for the PNF_STOP.request
* \param config A pointer to the pnf configuration
* \param req A data structure for the decoded PNF_STOP.request. This will have
@@ -167,7 +175,8 @@ typedef struct nfapi_pnf_config
* PARAM.request. This can be done in the call back.
*/
int (*param_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_param_request_t* req);
int (*nr_param_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_nr_param_request_scf_t* req);
/*! A callback for the CONFIG.request
* \param config A pointer to the pnf configuration
* \param phy A pointer to the pnf phy configuration
@@ -179,6 +188,7 @@ typedef struct nfapi_pnf_config
* CONFIG.request. This can be done in the call back.
*/
int (*config_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_config_request_t* req);
int (*nr_config_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_nr_config_request_scf_t* req);
/*! A callback for the START.request
* \param config A pointer to the pnf configuration
@@ -190,8 +200,8 @@ typedef struct nfapi_pnf_config
* The client is expected to send the START.response after the client has received the
* first subframe indication from FAPI.
*/
int (*start_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_start_request_t* req);
int (*start_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_start_request_t* req);
int (*nr_start_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_nr_start_request_scf_t* req);
/*! A callback for the STOP.request
* \param config A pointer to the pnf configuration
* \param phy A pointer to the pnf phy configuration
@@ -203,7 +213,8 @@ typedef struct nfapi_pnf_config
* STOP.request. This can be done in the call back.
*/
int (*stop_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_stop_request_t* req);
int (*nr_stop_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_nr_stop_request_t* req);
/*! A callback for the MEASUREMENT.request
* \param config A pointer to the pnf configuration
* \param phy A pointer to the pnf phy configuration
@@ -355,6 +366,7 @@ int nfapi_pnf_config_destroy(nfapi_pnf_config_t* config);
* \endcode
*/
int nfapi_pnf_start(nfapi_pnf_config_t* config);
int nfapi_nr_pnf_start(nfapi_pnf_config_t* config);
/*! Stop the PNF library.
* \param config A pointer to the pnf configuration
@@ -371,6 +383,8 @@ int nfapi_pnf_stop(nfapi_pnf_config_t* config);
*
*/
int nfapi_pnf_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_pnf_param_response_t* resp);
int nfapi_nr_pnf_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_nr_pnf_param_response_t* resp);
/*! Send the PNF_CONFIG.response
* \param config A pointer to a pnf configuraiton
@@ -379,6 +393,7 @@ int nfapi_pnf_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_pnf_param_respons
*
*/
int nfapi_pnf_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_pnf_config_response_t* resp);
int nfapi_nr_pnf_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_nr_pnf_config_response_t* resp);
/*! Send the PNF_START.response
* \param config A pointer to a pnf configuraiton
@@ -387,7 +402,7 @@ int nfapi_pnf_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_pnf_config_respo
*
*/
int nfapi_pnf_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_pnf_start_response_t* resp);
int nfapi_nr_pnf_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_nr_pnf_start_response_t* resp);
/*! Send the PNF_STOP.response
* \param config A pointer to a pnf configuraiton
* \param resp A pointer to the message structure
@@ -403,6 +418,7 @@ int nfapi_pnf_pnf_stop_resp(nfapi_pnf_config_t* config, nfapi_pnf_stop_response_
*
*/
int nfapi_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_param_response_t* resp);
int nfapi_nr_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_nr_param_response_scf_t* resp);
/*! Send the CONFIG.response
* \param config A pointer to a pnf configuraiton
@@ -411,7 +427,7 @@ int nfapi_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_param_response_t* res
*
*/
int nfapi_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_config_response_t* resp);
int nfapi_nr_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_nr_config_response_scf_t* resp);
/*! Send the START.response
* \param config A pointer to a pnf configuraiton
* \param resp A pointer to the message structure
@@ -419,6 +435,7 @@ int nfapi_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_config_response_t* r
*
*/
int nfapi_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_start_response_t* resp);
int nfapi_nr_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_nr_start_response_scf_t* resp);
/*! Send the STOP.response
* \param config A pointer to a pnf configuraiton
@@ -550,6 +567,22 @@ typedef struct
nfapi_ue_release_request_t* ue_release_req;
} nfapi_pnf_p7_subframe_buffer_t;
typedef struct
{
//uint16_t sfn_slot
int16_t sfn;
int16_t slot;
//TODO: Change P7 structs to NR
nfapi_nr_dl_tti_request_t* dl_tti_req;//nfapi_dl_config_request_t* dl_config_req;
nfapi_nr_ul_tti_request_t* ul_tti_req;//nfapi_ul_config_request_t* ul_config_req;
nfapi_nr_ul_dci_request_t* ul_dci_req;//nfapi_hi_dci0_request_t* hi_dci0_req;
nfapi_nr_tx_data_request_t* tx_data_req;//nfapi_tx_request_t* tx_req;
//TODO: check these two later
//nfapi_lbt_dl_config_request_t* lbt_dl_config_req;
//nfapi_ue_release_request_t* ue_release_req;
} nfapi_pnf_p7_slot_buffer_t;
typedef struct nfapi_pnf_p7_config nfapi_pnf_p7_config_t;
/*! The nfapi PNF PHY P7 configuration information created using the nfapi_pnf_p7_create function
@@ -602,6 +635,8 @@ typedef struct nfapi_pnf_p7_config
/*! The dummy subframe buffer structure that should be used in case there
* are no 'valid' subframe messages */
nfapi_pnf_p7_subframe_buffer_t dummy_subframe;
nfapi_pnf_p7_slot_buffer_t dummy_slot; // defining a slot equivalent for now
/*! Configuration options for the p7 pack unpack functions*/
nfapi_p7_codec_config_t codec_config;
@@ -611,6 +646,7 @@ typedef struct nfapi_pnf_p7_config
// tdb : if these should be public
uint16_t subframe_buffer_size;
uint16_t slot_buffer_size;
uint8_t timing_info_mode_periodic; // 0:false 1:true
uint8_t timing_info_mode_aperiodic; // 0:false 1:true
uint8_t timing_info_period; // 1..225 in subframes
@@ -620,6 +656,7 @@ typedef struct nfapi_pnf_p7_config
* \param req A pointer to the dl config request message structure
* \return not currently used
*/
int (*dl_tti_req_fn)(gNB_L1_rxtx_proc_t *proc,nfapi_pnf_p7_config_t* config, nfapi_nr_dl_tti_request_t* req);
int (*dl_config_req)(L1_rxtx_proc_t *proc,nfapi_pnf_p7_config_t* config, nfapi_dl_config_request_t* req);
/*! A callback for the UL_CONFIG.request
@@ -627,6 +664,7 @@ typedef struct nfapi_pnf_p7_config
* \param req A pointer to the ul config request message structure
* \return not currently used
*/
int (*ul_tti_req_fn)(gNB_L1_rxtx_proc_t *proc,nfapi_pnf_p7_config_t* config, nfapi_nr_ul_tti_request_t* req);
int (*ul_config_req)(L1_rxtx_proc_t *proc,nfapi_pnf_p7_config_t* config, nfapi_ul_config_request_t* req);
/*! A callback for the HI_DCI0.request
@@ -634,8 +672,9 @@ typedef struct nfapi_pnf_p7_config
* \param req A pointer to the hi dci0 request message structure
* \return not currently used
*/
int (*ul_dci_req_fn)(gNB_L1_rxtx_proc_t *proc,nfapi_pnf_p7_config_t* config, nfapi_nr_ul_dci_request_t* req);
int (*hi_dci0_req)(L1_rxtx_proc_t *proc,nfapi_pnf_p7_config_t* config, nfapi_hi_dci0_request_t* req);
/*! A callback for the TX_REQ.request
* \param config A poiner to the PNF P7 config
* \param req A pointer to the tx request message structure
@@ -645,6 +684,7 @@ typedef struct nfapi_pnf_p7_config
* will 'keep' the pointers until they are transmitted the callee should set the pointers in the req to 0
* and then use the p7 codec config free function to release the pdu's when appropriate.
*/
int (*tx_data_req_fn)(nfapi_pnf_p7_config_t* config, nfapi_nr_tx_data_request_t* req);
int (*tx_req)(nfapi_pnf_p7_config_t* config, nfapi_tx_request_t* req);
/*! A callback for the LBT_DL_CONFIG.request
@@ -708,6 +748,7 @@ int nfapi_pnf_p7_config_destroy(nfapi_pnf_p7_config_t* config);
* This function will not return until nfapi_pnf_p7_stop is called.
*/
int nfapi_pnf_p7_start(nfapi_pnf_p7_config_t* config);
int nfapi_nr_pnf_p7_start(nfapi_pnf_p7_config_t* config);
/*! Stop the PNF P7 library.
* \param config A pointer to a PNF P7 config
@@ -717,6 +758,21 @@ int nfapi_pnf_p7_start(nfapi_pnf_p7_config_t* config);
*/
int nfapi_pnf_p7_stop(nfapi_pnf_p7_config_t* config);
/*! NR Slot indication
* message copied from nfapi_pnf_p7_subframe_ind
* \param config A pointer to a PNF P7 config
* \param phy_id The phy_id for the phy instance
* \param sfn_sf The SFN and SF in the format of FAPI
* \return 0 means success, -1 means failure
*
* The client should call the subframe indication every 1ms. The PNF will
* respond by invoking the pnf p7 subframe callbacks with the messages from the subframe buffer
*
* If messages are not in the subframe buffer, they dummy subframe messages will be sent
*/
int nfapi_pnf_p7_slot_ind(nfapi_pnf_p7_config_t* config, uint16_t phy_id, uint16_t sfn, uint16_t slot);
/*! Subframe indication
* \param config A pointer to a PNF P7 config
* \param phy_id The phy_id for the phy instance
+782 -2
View File
@@ -26,9 +26,29 @@
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include "nfapi_nr_interface.h"
#include "nfapi_nr_interface_scf.h"
#include "pnf.h"
# if 1 // for hard-code (remove later)
#include "COMMON/platform_types.h"
#include "COMMON/platform_constants.h"
#include "common/ran_context.h"
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "NR_BCCH-BCH-Message.h"
#include "NR_ServingCellConfigCommon.h"
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "SCHED_NR/phy_frame_config_nr.h"
#include "NR_MIB.h"
#include "openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h"
#endif
#define MAX_SCTP_STREAMS 16
void nfapi_pnf_phy_config_delete_all(nfapi_pnf_config_t* config)
@@ -63,6 +83,50 @@ nfapi_pnf_phy_config_t* nfapi_pnf_phy_config_find(nfapi_pnf_config_t* config, ui
return 0;
}
void pnf_nr_handle_pnf_param_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
// ensure it's valid
if (pRecvMsg == NULL || pnf == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
}
else
{
nfapi_nr_pnf_param_request_t req;
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF_PARAM.request received\n");
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(nfapi_nr_pnf_param_request_t), &pnf->_public.codec_config) >= 0)
{
if(pnf->_public.state == NFAPI_PNF_IDLE)
{
if(pnf->_public.pnf_nr_param_req)
{
(pnf->_public.pnf_nr_param_req)(&pnf->_public, &req);
}
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: PNF not in IDLE state\n", __FUNCTION__);
nfapi_nr_pnf_param_response_t resp;
memset(&resp, 0, sizeof(resp));
resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_RESPONSE;
resp.error_code = NFAPI_MSG_INVALID_STATE;
nfapi_nr_pnf_pnf_param_resp(&pnf->_public, &resp);
}
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
}
if(req.vendor_extension)
pnf->_public.codec_config.deallocate(req.vendor_extension);
}
}
void pnf_handle_pnf_param_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
// ensure it's valid
@@ -173,6 +237,72 @@ void pnf_handle_pnf_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
}
}
void pnf_nr_handle_pnf_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
// ensure it's valid
if (pRecvMsg == NULL || pnf == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
}
else
{
nfapi_nr_pnf_config_request_t req;
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF_CONFIG.request received\n");
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &pnf->_public.codec_config) >= 0)
{
// ensure correct state
if(pnf->_public.state != NFAPI_PNF_RUNNING)
{
// delete the phy records
nfapi_pnf_phy_config_delete_all(&pnf->_public);
// create the phy records
if (req.pnf_phy_rf_config.tl.tag == NFAPI_PNF_PHY_RF_TAG)
{
int i = 0;
for(i = 0; i < req.pnf_phy_rf_config.number_phy_rf_config_info; ++i)
{
nfapi_pnf_phy_config_t* phy = (nfapi_pnf_phy_config_t*)malloc(sizeof(nfapi_pnf_phy_config_t));
memset(phy, 0, sizeof(nfapi_pnf_phy_config_t));
phy->state = NFAPI_PNF_PHY_IDLE;
phy->phy_id = req.pnf_phy_rf_config.phy_rf_config[i].phy_id;
nfapi_pnf_phy_config_add(&(pnf->_public), phy);
}
}
if(pnf->_public.pnf_nr_config_req)
{
(pnf->_public.pnf_nr_config_req)(&(pnf->_public), &req);
}
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: PNF not in correct state: %d\n", __FUNCTION__, pnf->_public.state);
nfapi_nr_pnf_config_response_t resp;
memset(&resp, 0, sizeof(resp));
resp.header.message_id = NFAPI_PNF_CONFIG_RESPONSE;
resp.error_code = NFAPI_MSG_INVALID_STATE;
nfapi_nr_pnf_pnf_config_resp(&(pnf->_public), &resp);
}
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
}
if(req.vendor_extension)
pnf->_public.codec_config.deallocate(req.vendor_extension);
}
}
void pnf_handle_pnf_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
// ensure it's valid
@@ -215,6 +345,48 @@ void pnf_handle_pnf_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
}
}
void pnf_nr_handle_pnf_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
// ensure it's valid
if (pRecvMsg == NULL || pnf == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
}
else
{
nfapi_nr_pnf_start_request_t req;
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF_START.request Received\n");
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &pnf->_public.codec_config) >= 0)
{
if(pnf->_public.state == NFAPI_PNF_CONFIGURED)
{
if(pnf->_public.pnf_nr_start_req)
{
(pnf->_public.pnf_nr_start_req)(&(pnf->_public), &req);
}
}
else
{
nfapi_nr_pnf_start_response_t resp;
memset(&resp, 0, sizeof(resp));
resp.header.message_id = NFAPI_PNF_START_RESPONSE;
resp.error_code = NFAPI_MSG_INVALID_STATE;
nfapi_nr_pnf_pnf_start_resp(&(pnf->_public), &resp);
}
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
}
if(req.vendor_extension)
pnf->_public.codec_config.deallocate(req.vendor_extension);
}
}
void pnf_handle_pnf_stop_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
// ensure it's valid
@@ -330,6 +502,78 @@ void pnf_handle_param_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
}
}
void pnf_nr_handle_param_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
// ensure it's valid
if (pRecvMsg == NULL || pnf == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
}
else
{
nfapi_nr_param_request_scf_t req;
nfapi_pnf_config_t* config = &(pnf->_public);
NFAPI_TRACE(NFAPI_TRACE_INFO, "PARAM.request received\n");
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0)
{
if(config->state == NFAPI_PNF_RUNNING)
{
nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, req.header.phy_id);
if(phy)
{
if(phy->state == NFAPI_PNF_PHY_IDLE)
{
if(config->nr_param_req)
{
(config->nr_param_req)(config, phy, &req);
}
}
else
{
nfapi_nr_param_response_scf_t resp;
memset(&resp, 0, sizeof(resp));
resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE;
resp.header.phy_id = req.header.phy_id;
resp.error_code = NFAPI_MSG_INVALID_STATE;
nfapi_nr_pnf_param_resp(config, &resp);
}
}
else
{
nfapi_nr_param_response_scf_t resp;
memset(&resp, 0, sizeof(resp));
resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE;
resp.header.phy_id = req.header.phy_id;
resp.error_code = NFAPI_MSG_INVALID_CONFIG;
nfapi_nr_pnf_param_resp(config, &resp);
}
}
else
{
nfapi_nr_param_response_scf_t resp;
memset(&resp, 0, sizeof(resp));
resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE;
resp.header.phy_id = req.header.phy_id;
resp.error_code = NFAPI_MSG_INVALID_STATE;
nfapi_nr_pnf_param_resp(config, &resp);
}
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
}
if(req.vendor_extension)
pnf->_public.codec_config.deallocate(req.vendor_extension);
}
}
void pnf_handle_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
@@ -401,6 +645,85 @@ void pnf_handle_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
}
}
void pnf_nr_handle_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
// ensure it's valid
if (pRecvMsg == NULL || pnf == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
}
else
{
nfapi_nr_config_request_scf_t req;
NFAPI_TRACE(NFAPI_TRACE_INFO, "CONFIG.request received\n");
nfapi_pnf_config_t* config = &(pnf->_public);
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0)
{
if(config->state == NFAPI_PNF_RUNNING)
{
nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, req.header.phy_id);
#if 0 // emulate set_config TLV reception (hard-code)
int tdd_return = set_tdd_config_nr(&req, 1, 7, 6, 2, 4);
#endif
if(phy)
{
if(phy->state != NFAPI_PNF_PHY_RUNNING)
{
if(config->nr_config_req)
{
(config->nr_config_req)(config, phy, &req);
}
}
else
{
nfapi_nr_config_response_scf_t resp;
memset(&resp, 0, sizeof(resp));
resp.header.message_id = NFAPI_CONFIG_RESPONSE;
resp.header.phy_id = req.header.phy_id;
resp.error_code = NFAPI_MSG_INVALID_STATE;
nfapi_nr_pnf_config_resp(config, &resp);
}
}
else
{
nfapi_nr_config_response_scf_t resp;
memset(&resp, 0, sizeof(resp));
resp.header.message_id = NFAPI_CONFIG_RESPONSE;
resp.header.phy_id = req.header.phy_id;
resp.error_code = NFAPI_MSG_INVALID_CONFIG;
nfapi_nr_pnf_config_resp(config, &resp);
}
}
else
{
nfapi_nr_config_response_scf_t resp;
memset(&resp, 0, sizeof(resp));
resp.header.message_id = NFAPI_CONFIG_RESPONSE;
resp.header.phy_id = req.header.phy_id;
resp.error_code = NFAPI_MSG_INVALID_STATE;
nfapi_nr_pnf_config_resp(config, &resp);
}
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
}
if(req.vendor_extension)
pnf->_public.codec_config.deallocate(req.vendor_extension);
}
}
void pnf_handle_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
// ensure it's valid
@@ -472,6 +795,77 @@ void pnf_handle_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
}
}
void pnf_nr_handle_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
// ensure it's valid
if (pRecvMsg == NULL || pnf == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
}
else
{
nfapi_nr_start_request_scf_t req;
nfapi_pnf_config_t* config = &(pnf->_public);
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() START.request received state:%d\n", __FUNCTION__, config->state);
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0)
{
if(config->state == NFAPI_PNF_RUNNING)
{
nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, req.header.phy_id);
if(phy)
{
if(phy->state != NFAPI_PNF_PHY_RUNNING)
{
if(config->nr_start_req)
{
(config->nr_start_req)(config, phy, &req);
}
}
else
{
nfapi_nr_start_response_scf_t resp;
memset(&resp, 0, sizeof(resp));
resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE;
resp.header.phy_id = req.header.phy_id;
resp.error_code = NFAPI_MSG_INVALID_STATE;
nfapi_nr_pnf_start_resp(config, &resp);
}
}
else
{
nfapi_nr_start_response_scf_t resp;
memset(&resp, 0, sizeof(resp));
resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE;
resp.header.phy_id = req.header.phy_id;
resp.error_code = NFAPI_MSG_INVALID_CONFIG;
nfapi_nr_pnf_start_resp(config, &resp);
}
}
else
{
nfapi_nr_start_response_scf_t resp;
memset(&resp, 0, sizeof(resp));
resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE;
resp.header.phy_id = req.header.phy_id;
resp.error_code = NFAPI_MSG_INVALID_STATE;
nfapi_nr_pnf_start_resp(config, &resp);
}
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
}
if(req.vendor_extension)
pnf->_public.codec_config.deallocate(req.vendor_extension);
}
}
void pnf_handle_stop_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
// ensure it's valid
@@ -543,6 +937,77 @@ void pnf_handle_stop_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
}
}
void pnf_nr_handle_stop_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
// ensure it's valid
if (pRecvMsg == NULL || pnf == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
}
else
{
nfapi_nr_stop_request_t req;
NFAPI_TRACE(NFAPI_TRACE_INFO, "STOP.request received\n");
nfapi_pnf_config_t* config = &(pnf->_public);
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0)
{
if(config->state == NFAPI_PNF_RUNNING)
{
nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, req.header.phy_id);
if(phy)
{
if(phy->state != NFAPI_PNF_PHY_RUNNING)
{
if(config->nr_stop_req)
{
(config->nr_stop_req)(config, phy, &req);
}
}
else
{
nfapi_stop_response_t resp;
memset(&resp, 0, sizeof(resp));
resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE;
resp.header.phy_id = req.header.phy_id;
resp.error_code = NFAPI_MSG_INVALID_STATE;
nfapi_pnf_stop_resp(config, &resp);
}
}
else
{
nfapi_stop_response_t resp;
memset(&resp, 0, sizeof(resp));
resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE;
resp.header.phy_id = req.header.phy_id;
resp.error_code = NFAPI_MSG_INVALID_CONFIG;
nfapi_pnf_stop_resp(config, &resp);
}
}
else
{
nfapi_stop_response_t resp;
memset(&resp, 0, sizeof(resp));
resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE;
resp.header.phy_id = req.header.phy_id;
resp.error_code = NFAPI_MSG_INVALID_STATE;
nfapi_pnf_stop_resp(config, &resp);
}
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
}
if(req.vendor_extension)
pnf->_public.codec_config.deallocate(req.vendor_extension);
}
}
void pnf_handle_measurement_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
// ensure it's valid
@@ -1071,7 +1536,101 @@ void pnf_handle_vendor_extension(void* pRecvMsg, int recvMsgLen, pnf_t* pnf, uin
}
}
void pnf_nr_handle_p5_message(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
nfapi_p4_p5_message_header_t messageHeader;
// validate the input params
if(pRecvMsg == NULL || recvMsgLen < NFAPI_HEADER_LENGTH)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
return;
}
// unpack the message header
if (nfapi_p5_message_header_unpack(pRecvMsg, recvMsgLen, &messageHeader, sizeof(nfapi_p4_p5_message_header_t), &pnf->_public.codec_config) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n");
return;
}
switch (messageHeader.message_id)
{
case NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_REQUEST:
pnf_nr_handle_pnf_param_request(pnf, pRecvMsg, recvMsgLen);
break;
case NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_REQUEST:
pnf_nr_handle_pnf_config_request(pnf, pRecvMsg, recvMsgLen);
break;
case NFAPI_NR_PHY_MSG_TYPE_PNF_START_REQUEST:
pnf_nr_handle_pnf_start_request(pnf, pRecvMsg, recvMsgLen);
break;
case NFAPI_PNF_STOP_REQUEST:
pnf_handle_pnf_stop_request(pnf, pRecvMsg, recvMsgLen);
break;
case NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST:
pnf_nr_handle_param_request(pnf, pRecvMsg, recvMsgLen);
break;
case NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST:
pnf_nr_handle_config_request(pnf, pRecvMsg, recvMsgLen);
break;
case NFAPI_NR_PHY_MSG_TYPE_START_REQUEST:
pnf_nr_handle_start_request(pnf, pRecvMsg, recvMsgLen);
break;
case NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST:
pnf_nr_handle_stop_request(pnf, pRecvMsg, recvMsgLen);
break;
case NFAPI_MEASUREMENT_REQUEST:
pnf_handle_measurement_request(pnf, pRecvMsg, recvMsgLen);
break;
case NFAPI_RSSI_REQUEST:
pnf_handle_rssi_request(pnf, pRecvMsg, recvMsgLen);
break;
case NFAPI_CELL_SEARCH_REQUEST:
pnf_handle_cell_search_request(pnf, pRecvMsg, recvMsgLen);
break;
case NFAPI_BROADCAST_DETECT_REQUEST:
pnf_handle_broadcast_detect_request(pnf, pRecvMsg, recvMsgLen);
break;
case NFAPI_SYSTEM_INFORMATION_SCHEDULE_REQUEST:
pnf_handle_system_information_schedule_request(pnf, pRecvMsg, recvMsgLen);
break;
case NFAPI_SYSTEM_INFORMATION_REQUEST:
pnf_handle_system_information_request(pnf, pRecvMsg, recvMsgLen);
break;
case NFAPI_NMM_STOP_REQUEST:
pnf_handle_nmm_stop_request(pnf, pRecvMsg, recvMsgLen);
break;
default:
{
if(messageHeader.message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
messageHeader.message_id <= NFAPI_VENDOR_EXT_MSG_MAX)
{
pnf_handle_vendor_extension(pRecvMsg, recvMsgLen, pnf, messageHeader.message_id);
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s P5 Unknown message ID %d\n", __FUNCTION__, messageHeader.message_id);
}
}
break;
}
}
void pnf_handle_p5_message(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
@@ -1169,6 +1728,24 @@ void pnf_handle_p5_message(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
}
}
int pnf_nr_pack_and_send_p5_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len)
{
int packed_len = nfapi_nr_p5_message_pack(msg, msg_len,
pnf->tx_message_buffer,
sizeof(pnf->tx_message_buffer),
&pnf->_public.codec_config);
if (packed_len < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi_p5_message_pack failed (%d)\n", packed_len);
return -1;
}
return pnf_send_message(pnf, pnf->tx_message_buffer, packed_len, 0/*msg->stream_id*/);
}
int pnf_pack_and_send_p5_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len)
{
int packed_len = nfapi_p5_message_pack(msg, msg_len,
@@ -1393,8 +1970,15 @@ int pnf_connect(pnf_t* pnf)
int pnf_send_message(pnf_t* pnf, uint8_t *msg, uint32_t len, uint16_t stream)
{
if (pnf->sctp)
{
printf("\nPNF SENDS: \n");
for(int i=0; i<len; i++){
printf("%d", msg[i]);
}
printf("\n");
if (sctp_sendmsg(pnf->p5_sock, msg, len, NULL, 0, 42/*config->sctp_stream_number*/, 0, stream/*P5_STREAM_ID*/, 0, 0) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "sctp_sendmsg failed errno: %d\n", errno);
@@ -1412,7 +1996,6 @@ int pnf_send_message(pnf_t* pnf, uint8_t *msg, uint32_t len, uint16_t stream)
return 0;
}
int pnf_read_dispatch_message(pnf_t* pnf)
{
int socket_connected = 1;
@@ -1486,6 +2069,13 @@ int pnf_read_dispatch_message(pnf_t* pnf)
}
else
{
// print the received message
printf("\n MESSAGE RECEIVED: \n");
for(int i=0; i<message_size; i++){
printf("%d", read_buffer[i]);
}
printf("\n");
if (flags & MSG_NOTIFICATION)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "Notification received from %s:%u\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
@@ -1533,6 +2123,135 @@ int pnf_read_dispatch_message(pnf_t* pnf)
return socket_connected;
}
int pnf_nr_read_dispatch_message(pnf_t* pnf)
{
int socket_connected = 1;
// 1. Peek the message header
// 2. If the message is larger than the stack buffer then create a dynamic buffer
// 3. Read the buffer
// 4. Handle the p5 message
uint32_t header_buffer_size = NFAPI_HEADER_LENGTH;
uint8_t header_buffer[header_buffer_size];
uint32_t stack_buffer_size = 32; //should it be the size of then sctp_notificatoin structure
uint8_t stack_buffer[stack_buffer_size];
uint8_t* dynamic_buffer = 0;
uint8_t* read_buffer = &stack_buffer[0];
uint32_t message_size = 0;
struct sockaddr_in addr;
socklen_t addr_len = sizeof(addr);
struct sctp_sndrcvinfo sndrcvinfo;
(void)memset(&sndrcvinfo, 0, sizeof(struct sctp_sndrcvinfo));
{
int flags = MSG_PEEK;
message_size = sctp_recvmsg(pnf->p5_sock, header_buffer, header_buffer_size, /*(struct sockaddr*)&addr, &addr_len*/ 0, 0, &sndrcvinfo, &flags);
if(message_size == -1)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF Failed to peek sctp message size errno:%d\n", errno);
return 0;
}
nfapi_p4_p5_message_header_t header;
int unpack_result = nfapi_p5_message_header_unpack(header_buffer, header_buffer_size, &header, sizeof(header), 0);
if(unpack_result < 0)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF Failed to unpack p5 message header\n");
return 0;
}
message_size = header.message_length;
// now have the size of the mesage
}
if(message_size > stack_buffer_size)
{
dynamic_buffer = (uint8_t*)malloc(message_size);
if(dynamic_buffer == NULL)
{
// todo : add error mesage
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF Failed to allocate dynamic buffer for sctp_recvmsg size:%d\n", message_size);
return -1;
}
read_buffer = dynamic_buffer;
}
{
int flags = 0;
(void)memset(&sndrcvinfo, 0, sizeof(struct sctp_sndrcvinfo));
int recvmsg_result = sctp_recvmsg(pnf->p5_sock, read_buffer, message_size, (struct sockaddr*)&addr, &addr_len, &sndrcvinfo, &flags);
if(recvmsg_result == -1)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "Failed to read sctp message size errno:%d\n", errno);
}
else
{
// print the received message
printf("\n MESSAGE RECEIVED: \n");
for(int i=0; i<message_size; i++){
printf("%d", read_buffer[i]);
}
printf("\n");
if (flags & MSG_NOTIFICATION)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "Notification received from %s:%u\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
// todo - handle the events
}
else
{
/*
NFAPI_TRACE(NFAPI_TRACE_INFO, "Received message fd:%d from %s:%u assoc:%d on stream %d, PPID %d, length %d, flags 0x%x\n",
pnf->p5_sock,
inet_ntoa(addr.sin_addr),
ntohs(addr.sin_port),
sndrcvinfo.sinfo_assoc_id,
sndrcvinfo.sinfo_stream,
ntohl(sndrcvinfo.sinfo_ppid),
message_size,
flags);
*/
// handle now if complete message in one or more segments
if ((flags & 0x80) == 0x80)
{
pnf_nr_handle_p5_message(pnf, read_buffer, message_size);
}
else
{
NFAPI_TRACE(NFAPI_TRACE_WARN, "sctp_recvmsg: unhandled mode with flags 0x%x\n", flags);
// assume socket disconnected
NFAPI_TRACE(NFAPI_TRACE_WARN, "Disconnected socket\n");
socket_connected = 0;
}
}
}
}
if(dynamic_buffer)
{
free(dynamic_buffer);
}
return socket_connected;
}
@@ -1597,3 +2316,64 @@ int pnf_message_pump(pnf_t* pnf)
}
int pnf_nr_message_pump(pnf_t* pnf)
{
uint8_t socketConnected = 1;
while(socketConnected && pnf->terminate == 0)
{
fd_set rfds;
int selectRetval = 0;
// select on a timeout and then get the message
FD_ZERO(&rfds);
FD_SET(pnf->p5_sock, &rfds);
struct timeval timeout;
timeout.tv_sec = 1;
timeout.tv_usec = 0;
selectRetval = select(pnf->p5_sock+1, &rfds, NULL, NULL, &timeout);
if(selectRetval == 0)
{
// timeout
continue;
}
else if (selectRetval == -1 && (errno == EINTR))
{
// interrupted by signal
NFAPI_TRACE(NFAPI_TRACE_WARN, "P5 Signal Interrupt %d\n", errno);
continue;
}
else if (selectRetval == -1)
{
NFAPI_TRACE(NFAPI_TRACE_WARN, "P5 select() failed\n");
sleep(1);
continue;
}
if(FD_ISSET(pnf->p5_sock, &rfds))
{
socketConnected = pnf_nr_read_dispatch_message(pnf);
}
else
{
NFAPI_TRACE(NFAPI_TRACE_WARN, "Why are we here\n");
}
}
// Drop back to idle if we have lost connection
pnf->_public.state = NFAPI_PNF_PHY_IDLE;
// close the connection and socket
if (close(pnf->p5_sock) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "close(sctpSock) failed errno: %d\n", errno);
}
return 0;
}
+163 -1
View File
@@ -19,6 +19,8 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "nfapi_nr_interface.h"
#include "nfapi_nr_interface_scf.h"
nfapi_pnf_config_t* nfapi_pnf_config_create()
{
@@ -81,6 +83,40 @@ int nfapi_pnf_start(nfapi_pnf_config_t* config)
return 0;
}
int nfapi_nr_pnf_start(nfapi_pnf_config_t* config)
{
// Verify that config is not null
if(config == 0)
return -1;
// Make sure to set the defined trace function before using NFAPI_TRACE
if(config->trace)
nfapi_trace_g = config->trace;
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
pnf_t* _this = (pnf_t*)(config);
while (_this->terminate == 0)
{
int connect_result = pnf_connect(_this);
if(connect_result > 0)
{
pnf_nr_message_pump(_this);
}
else if(connect_result < 0)
{
return connect_result;
}
sleep(1);
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() terminate=1 - EXITTING............\n", __FUNCTION__);
return 0;
}
int nfapi_pnf_stop(nfapi_pnf_config_t* config)
{
// Verify that config is not null
@@ -96,6 +132,21 @@ int nfapi_pnf_stop(nfapi_pnf_config_t* config)
return 0;
}
int nfapi_nr_pnf_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_nr_pnf_param_response_t* resp)
{
// ensure it's valid
if (config == NULL || resp == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
return -1;
}
pnf_t* _this = (pnf_t*)(config);
return pnf_nr_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_nr_pnf_param_response_t));
}
int nfapi_pnf_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_pnf_param_response_t* resp)
{
// ensure it's valid
@@ -129,6 +180,27 @@ int nfapi_pnf_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_pnf_config_respo
return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_pnf_config_response_t));
}
int nfapi_nr_pnf_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_nr_pnf_config_response_t* resp)
{
// ensure it's valid
if (config == NULL || resp == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
return -1;
}
if(resp->error_code == NFAPI_MSG_OK)
{
config->state = NFAPI_PNF_CONFIGURED;
}
pnf_t* _this = (pnf_t*)(config);
return pnf_nr_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_nr_pnf_config_response_t));
}
int nfapi_pnf_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_pnf_start_response_t* resp)
{
// ensure it's valid
@@ -148,6 +220,26 @@ int nfapi_pnf_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_pnf_start_respons
return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_pnf_start_response_t));
}
int nfapi_nr_pnf_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_nr_pnf_start_response_t* resp)
{
// ensure it's valid
if (config == NULL || resp == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
return -1;
}
if(resp->error_code == NFAPI_MSG_OK)
{
config->state = NFAPI_PNF_RUNNING;
}
pnf_t* _this = (pnf_t*)(config);
return pnf_nr_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_nr_pnf_start_response_t));
}
int nfapi_pnf_pnf_stop_resp(nfapi_pnf_config_t* config, nfapi_pnf_stop_response_t* resp)
{
// ensure it's valid
@@ -166,7 +258,6 @@ int nfapi_pnf_pnf_stop_resp(nfapi_pnf_config_t* config, nfapi_pnf_stop_response_
return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_pnf_stop_response_t));
}
int nfapi_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_param_response_t* resp)
{
if (config == NULL || resp == NULL)
@@ -180,6 +271,20 @@ int nfapi_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_param_response_t* res
return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_param_response_t));
}
int nfapi_nr_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_nr_param_response_scf_t* resp)
{
if (config == NULL || resp == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
return -1;
}
pnf_t* _this = (pnf_t*)(config);
return pnf_nr_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_nr_param_response_scf_t));
}
int nfapi_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_config_response_t* resp)
{
if (config == NULL || resp == NULL)
@@ -208,6 +313,35 @@ int nfapi_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_config_response_t* r
return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_config_response_t));
}
int nfapi_nr_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_nr_config_response_scf_t* resp)
{
if (config == NULL || resp == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
return -1;
}
pnf_t* _this = (pnf_t*)(config);
nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, resp->header.phy_id);
if(phy)
{
if(resp->error_code == NFAPI_NR_CONFIG_MSG_OK)
{
phy->state = NFAPI_PNF_PHY_CONFIGURED;
}
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: unknow phy id %d\n", __FUNCTION__, resp->header.phy_id);
return -1;
}
return pnf_nr_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_nr_config_response_scf_t));
}
int nfapi_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_start_response_t* resp)
{
if (config == NULL || resp == NULL)
@@ -235,6 +369,34 @@ int nfapi_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_start_response_t* res
return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_start_response_t));
}
int nfapi_nr_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_nr_start_response_scf_t* resp)
{
if (config == NULL || resp == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
return -1;
}
pnf_t* _this = (pnf_t*)(config);
nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, resp->header.phy_id);
if(phy)
{
if(resp->error_code == NFAPI_NR_START_MSG_OK)
{
phy->state = NFAPI_PNF_PHY_RUNNING;
}
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: unknown phy id %d\n", __FUNCTION__, resp->header.phy_id);
return -1;
}
return pnf_nr_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_nr_start_response_scf_t));
}
int nfapi_pnf_stop_resp(nfapi_pnf_config_t* config, nfapi_stop_response_t* resp)
{
if (config == NULL || resp == NULL)
File diff suppressed because it is too large Load Diff
+31 -1
View File
@@ -31,7 +31,7 @@ nfapi_pnf_p7_config_t* nfapi_pnf_p7_config_create()
_this->_public.segment_size = 1400;
_this->max_num_segments = 8;
_this->_public.subframe_buffer_size = 8;
_this->_public.subframe_buffer_size = 8;// TODO: Initialize the slot_buffer size
_this->_public.timing_info_mode_periodic = 1;
_this->_public.timing_info_period = 32;
_this->_public.timing_info_mode_aperiodic = 1;
@@ -76,6 +76,26 @@ int nfapi_pnf_p7_start(nfapi_pnf_p7_config_t* config)
return 0;
}
int nfapi_nr_pnf_p7_start(nfapi_pnf_p7_config_t* config)
{
// Verify that config is not null
if(config == 0)
return -1;
// Make sure to set the defined trace function before using NFAPI_TRACE
if(config->trace)
nfapi_trace_g = config->trace;
pnf_p7_t* _this = (pnf_p7_t*)(config);
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
pnf_nr_p7_message_pump(_this);
return 0;
}
int nfapi_pnf_p7_stop(nfapi_pnf_p7_config_t* config)
{
// Verify that config is not null
@@ -88,6 +108,16 @@ int nfapi_pnf_p7_stop(nfapi_pnf_p7_config_t* config)
return 0;
}
int nfapi_pnf_p7_slot_ind(nfapi_pnf_p7_config_t* config, uint16_t phy_id, uint16_t sfn, uint16_t slot)
{
// Verify that config is not null
if(config == 0)
return -1;
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_p7_slot_ind(_this, phy_id, sfn, slot);
}
int nfapi_pnf_p7_subframe_ind(nfapi_pnf_p7_config_t* config, uint16_t phy_id, uint16_t sfn_sf)
{
@@ -48,6 +48,9 @@ typedef struct phy_info
uint8_t enabled;
uint16_t phy_id;
uint16_t sfn_sf;
uint16_t sfn;
uint16_t slot;
pthread_t thread;
@@ -1207,6 +1210,12 @@ void send_dl_subframe_msgs_interleaved(int p7Sock, int phy_id, struct sockaddr_i
//free(req.tx_request_body.tx_pdu_list);
}
void send_slot_indication(phy_info_t* phy_info)
{
// DONE: add sfn and slot as members in the phy_info
nfapi_pnf_p7_slot_ind(phy_info->config, phy_info->phy_id, phy_info->sfn, phy_info->slot);
}
void send_subframe_indication(phy_info_t* phy_info)
{
nfapi_pnf_p7_subframe_ind(phy_info->config, phy_info->phy_id, phy_info->sfn_sf);
+4
View File
@@ -35,9 +35,13 @@ typedef struct
int vnf_pack_and_send_p5_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_message_header_t* msg, uint16_t msg_len);
int vnf_nr_pack_and_send_p5_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_message_header_t* msg, uint16_t msg_len);
int vnf_pack_and_send_p4_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_message_header_t* msg, uint16_t msg_len);
int vnf_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t* pnf);
int vnf_nr_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t* pnf);
void nfapi_vnf_phy_info_list_add(nfapi_vnf_config_t* config, nfapi_vnf_phy_info_t* info);
nfapi_vnf_phy_info_t* nfapi_vnf_phy_info_list_find(nfapi_vnf_config_t* config, uint16_t phy_id);
+12 -1
View File
@@ -77,6 +77,9 @@ typedef struct nfapi_vnf_p7_connection_info {
int32_t sf_offset_filtered;
int32_t sf_offset_trend;
int32_t sf_offset;
int32_t slot_offset;
int32_t slot_offset_trend;
int32_t slot_offset_filtered;
uint16_t zero_count;
int32_t adjustment;
int32_t insync_minor_adjustment;
@@ -85,8 +88,10 @@ typedef struct nfapi_vnf_p7_connection_info {
uint32_t previous_t1;
uint32_t previous_t2;
int32_t previous_sf_offset_filtered;
int32_t previous_slot_offset_filtered;
int sfn_sf;
int sfn;
int slot;
int socket;
struct sockaddr_in local_addr;
@@ -111,6 +116,7 @@ typedef struct {
nfapi_vnf_p7_connection_info_t* p7_connections;
int socket;
uint32_t sf_start_time_hr;
uint32_t slot_start_time_hr;
uint8_t* rx_message_buffer; // would this be better put in the p7 conenction info?
uint16_t rx_message_buffer_size;
@@ -120,14 +126,19 @@ uint32_t vnf_get_current_time_hr(void);
uint16_t increment_sfn_sf(uint16_t sfn_sf);
int vnf_sync(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info);
int vnf_nr_sync(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info);
int send_mac_subframe_indications(vnf_p7_t* config);
int send_mac_slot_indications(vnf_p7_t* config);
int vnf_p7_read_dispatch_message(vnf_p7_t* vnf_p7 );
int vnf_nr_p7_read_dispatch_message(vnf_p7_t* vnf_p7 );
void vnf_p7_connection_info_list_add(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* node);
nfapi_vnf_p7_connection_info_t* vnf_p7_connection_info_list_find(vnf_p7_t* vnf_p7, uint16_t phy_id);
nfapi_vnf_p7_connection_info_t* vnf_p7_connection_info_list_delete(vnf_p7_t* vnf_p7, uint16_t phy_id);
int vnf_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* header);
int vnf_nr_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* header);
void vnf_p7_release_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* header);
void vnf_p7_release_pdu(vnf_p7_t* vnf_p7, void* pdu);
@@ -19,6 +19,7 @@
#include "nfapi_interface.h"
#include "nfapi_nr_interface_scf.h"
#include "nfapi_nr_interface.h"
#include "debug.h"
@@ -120,6 +121,7 @@ typedef struct nfapi_vnf_config
*
* \todo Do we need to send the address information of the PNF?
*/
int (*pnf_nr_connection_indication)(nfapi_vnf_config_t* config, int p5_idx);
int (*pnf_connection_indication)(nfapi_vnf_config_t* config, int p5_idx);
/*! \brief Callback indicating that a pnf has lost connection
@@ -160,6 +162,7 @@ typedef struct nfapi_vnf_config
* then the substructure pointers should be set to 0 and then the client should
* use the codec_config.deallocate function to release it at a future point
*/
int (*pnf_nr_param_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_pnf_param_response_t* resp);
int (*pnf_param_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_param_response_t* resp);
/*! A callback for the PNF_CONFIG.resp
@@ -182,7 +185,8 @@ typedef struct nfapi_vnf_config
* use the codec_config.deallocate function to release it at a future point
*/
int (*pnf_config_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_config_response_t* resp);
int (*pnf_nr_config_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_pnf_config_response_t* resp);
/*! A callback for the PNF_START.resp
* \param config A pointer to the vnf configuration
* \param p5_idx The p5 index used to indicate a particular pnf p5 connection
@@ -203,7 +207,8 @@ typedef struct nfapi_vnf_config
* use the codec_config.deallocate function to release it at a future point
*/
int (*pnf_start_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_start_response_t* resp);
int (*pnf_nr_start_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_pnf_start_response_t* resp);
/*! A callback for the PNF_STOP.resp
* \param config A pointer to the vnf configuration
* \param p5_idx The p5 index used to indicate a particular pnf p5 connection
@@ -249,6 +254,7 @@ typedef struct nfapi_vnf_config
* use the codec_config.deallocate function to release it at a future point
*/
int (*param_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_param_response_t* resp);
int (*nr_param_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_param_response_scf_t* resp);
/*! A callback for the CONFIG.response
* \param config A pointer to the vnf configuration
@@ -266,8 +272,9 @@ typedef struct nfapi_vnf_config
* then the substructure pointers should be set to 0 and then the client should
* use the codec_config.deallocate function to release it at a future point
*/
int (*nr_config_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_config_response_scf_t* resp);
int (*config_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_config_response_t* resp);
/*! A callback for the START.resp
* \param config A pointer to the vnf configuration
* \param p5_idx The p5 index used to indicate a particular pnf p5 connection
@@ -285,6 +292,7 @@ typedef struct nfapi_vnf_config
* use the codec_config.deallocate function to release it at a future point
*/
int (*start_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_start_response_t* resp);
int (*nr_start_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_start_response_scf_t* resp);
/*! A callback for the STOP.resp
* \param config A pointer to the vnf configuration
@@ -469,6 +477,8 @@ void nfapi_vnf_config_destory(nfapi_vnf_config_t* config);
*
* This function will not return untill nfapi_vnf_stop is called
*/
int nfapi_nr_vnf_start(nfapi_vnf_config_t* config);
int nfapi_vnf_start(nfapi_vnf_config_t* config);
/*! Stop the VNF library.
@@ -500,6 +510,7 @@ int nfapi_vnf_allocate_phy(nfapi_vnf_config_t* config, int p5_idx, uint16_t* phy
* \return 0 means success, -1 failure
*/
int nfapi_vnf_pnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_param_request_t* req);
int nfapi_nr_vnf_pnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_pnf_param_request_t* req);
/*! Send the PNF_CONFIG.request
* \param config A pointer to a vnf config
@@ -508,6 +519,7 @@ int nfapi_vnf_pnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_pa
* \return 0 means success, -1 failure
*/
int nfapi_vnf_pnf_config_req(nfapi_vnf_config_t* config,int p5_idx, nfapi_pnf_config_request_t* req);
int nfapi_nr_vnf_pnf_config_req(nfapi_vnf_config_t* config,int p5_idx, nfapi_nr_pnf_config_request_t* req);
/*! Send the PNF_START.request
* \param config A pointer to a vnf config
@@ -516,6 +528,7 @@ int nfapi_vnf_pnf_config_req(nfapi_vnf_config_t* config,int p5_idx, nfapi_pnf_co
* \return 0 means success, -1 failure
*/
int nfapi_vnf_pnf_start_req(nfapi_vnf_config_t* config,int p5_idx, nfapi_pnf_start_request_t* req);
int nfapi_nr_vnf_pnf_start_req(nfapi_vnf_config_t* config,int p5_idx, nfapi_nr_pnf_start_request_t* req);
/*! Send the PNF_STOP.request
* \param config A pointer to a vnf config
@@ -532,6 +545,7 @@ int nfapi_vnf_pnf_stop_req(nfapi_vnf_config_t* config,int p5_idx, nfapi_pnf_stop
* \return 0 means success, -1 failure
*/
int nfapi_vnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_param_request_t* req);
int nfapi_nr_vnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_param_request_scf_t* req);
/*! Send the CONFIG.request
* \param config A pointer to a vnf config
@@ -539,6 +553,7 @@ int nfapi_vnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_param_requ
* \param req A pointer to a CONFIG.request message structure
* \return 0 means success, -1 failure
*/
int nfapi_nr_vnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_config_request_scf_t* req);
int nfapi_vnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_config_request_t* req);
/*! Send the START.request
@@ -548,6 +563,7 @@ int nfapi_vnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_config_re
* \return 0 means success, -1 failure
*/
int nfapi_vnf_start_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_start_request_t* req);
int nfapi_nr_vnf_start_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_start_request_scf_t* req);
/*! Send the STOP.request
* \param config A pointer to a vnf config
@@ -692,6 +708,7 @@ typedef struct nfapi_vnf_p7_config
*/
int (*subframe_indication)(struct nfapi_vnf_p7_config* config, uint16_t phy_id, uint16_t sfn_sf);
int (*slot_indication)(struct nfapi_vnf_p7_config* config, uint16_t phy_id, uint16_t sfn, uint16_t slot);
/*! A callback for the HARQ.indication
* \param config A pointer to the vnf p7 configuration
@@ -885,6 +902,8 @@ void nfapi_vnf_p7_config_destory(nfapi_vnf_p7_config_t* config);
*/
int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config);
int nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t* config);
/*! Stop the VNF P7 library.
* \param config A pointer to an vnf p7 configuration structure
@@ -950,7 +969,7 @@ int nfapi_vnf_p7_nr_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_nr_dl_tti
* may be released after this function call has returned or at a later pointer
*/
int nfapi_vnf_p7_ul_config_req(nfapi_vnf_p7_config_t* config, nfapi_ul_config_request_t* req);
int nfapi_vnf_p7_ul_tti_req(nfapi_vnf_p7_config_t* config, nfapi_nr_ul_tti_request_t* req);
/*! Send the HI_DCI0.request
* \param config A pointer to the vnf p7 configuration
* \param req A data structure for the decoded HI_DCI0.request.
@@ -960,7 +979,7 @@ int nfapi_vnf_p7_ul_config_req(nfapi_vnf_p7_config_t* config, nfapi_ul_config_re
* may be released after this function call has returned or at a later pointer
*/
int nfapi_vnf_p7_hi_dci0_req(nfapi_vnf_p7_config_t* config, nfapi_hi_dci0_request_t* req);
int nfapi_vnf_p7_ul_dci_req(nfapi_vnf_p7_config_t* config, nfapi_nr_ul_dci_request_t* req);
/*! Send the TX.req
* \param config A pointer to the vnf p7 configuration
* \param req A data structure for the decoded HI_DCI0.request.
@@ -970,7 +989,7 @@ int nfapi_vnf_p7_hi_dci0_req(nfapi_vnf_p7_config_t* config, nfapi_hi_dci0_reques
* may be released after this function call has returned or at a later pointer
*/
int nfapi_vnf_p7_tx_req(nfapi_vnf_p7_config_t* config, nfapi_tx_request_t* req);
int nfapi_vnf_p7_tx_data_req(nfapi_vnf_p7_config_t* config, nfapi_nr_tx_data_request_t* req);
/*! Send the LBT_DL_CONFIG.requst
* \param config A pointer to the vnf p7 configuration
* \param req A data structure for the decoded LBT_DL_CONFIG.request.
+482 -3
View File
@@ -21,9 +21,12 @@
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include "vnf.h"
#include "nfapi_nr_interface.h"
#include "nfapi_nr_interface_scf.h"
void* vnf_malloc(nfapi_vnf_config_t* config, size_t size)
@@ -101,6 +104,39 @@ nfapi_vnf_pnf_info_t* nfapi_vnf_pnf_list_find(nfapi_vnf_config_t* config, int p5
return 0;
}
void vnf_nr_handle_pnf_param_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx)
{
// ensure it's valid
if (pRecvMsg == NULL || config == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s : NULL parameters\n", __FUNCTION__);
}
else
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "Received PNF_PARAM.reponse\n");
nfapi_nr_pnf_param_response_t msg;
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0)
{
// Invoke the call back
if(config->pnf_nr_param_resp)
{
(config->pnf_nr_param_resp)(config, p5_idx, &msg);
}
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
}
// make sure to release any dyanmic part of the message
if(msg.vendor_extension)
config->codec_config.deallocate(msg.vendor_extension);
}
}
void vnf_handle_pnf_param_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx)
{
// ensure it's valid
@@ -134,6 +170,40 @@ void vnf_handle_pnf_param_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_con
}
}
void vnf_nr_handle_pnf_config_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx)
{
// ensure it's valid
if (pRecvMsg == NULL || config == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
}
else
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "Received PNF_CONFIG_RESPONSE\n");
nfapi_nr_pnf_config_response_t msg;
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0)
{
// Invoke the call back
if(config->pnf_nr_config_resp)
{
(config->pnf_nr_config_resp)(config, p5_idx, &msg);
}
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
}
// make sure to release any dyanmic part of the message
if(msg.vendor_extension)
config->codec_config.deallocate(msg.vendor_extension);
}
}
void vnf_handle_pnf_config_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx)
{
// ensure it's valid
@@ -167,6 +237,38 @@ void vnf_handle_pnf_config_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_co
}
}
void vnf_nr_handle_pnf_start_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx)
{
// ensure it's valid
if (pRecvMsg == NULL || config == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
}
else
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "Received PNF_START_RESPONSE\n");
nfapi_nr_pnf_start_response_t msg;
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0)
{
if(config->pnf_nr_start_resp)
{
(config->pnf_nr_start_resp)(config, p5_idx, &msg);
}
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
}
// make sure to release any dyanmic part of the message
if(msg.vendor_extension)
config->codec_config.deallocate(msg.vendor_extension);
}
}
void vnf_handle_pnf_start_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx)
{
// ensure it's valid
@@ -298,8 +400,113 @@ void vnf_handle_param_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_
}
}
void vnf_nr_handle_param_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx)
{
// ensure it's valid
if (pRecvMsg == NULL || config == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
}
else
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "Received PARAM_RESPONSE\n");
nfapi_nr_param_response_scf_t msg;
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0)
{
if (msg.error_code == NFAPI_NR_PARAM_MSG_OK)
{
nfapi_vnf_phy_info_t* phy_info = nfapi_vnf_phy_info_list_find(config, msg.header.phy_id);
if(msg.nfapi_config.p7_pnf_address_ipv4.tl.tag)
{
struct sockaddr_in sockAddr;
(void)memcpy(&sockAddr.sin_addr.s_addr, msg.nfapi_config.p7_pnf_address_ipv4.address, NFAPI_IPV4_ADDRESS_LENGTH);
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 IPv4 address: %s\n", inet_ntoa(sockAddr.sin_addr));
// store address
phy_info->p7_pnf_address.sin_addr = sockAddr.sin_addr;
}
if(msg.nfapi_config.p7_pnf_address_ipv6.tl.tag)
{
struct sockaddr_in6 sockAddr6;
char addr6[64];
(void)memcpy(&sockAddr6.sin6_addr, msg.nfapi_config.p7_pnf_address_ipv6.address, NFAPI_IPV6_ADDRESS_LENGTH);
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 IPv6 address: %s\n", inet_ntop(AF_INET6, &sockAddr6.sin6_addr, addr6, sizeof(addr6)));
}
if (msg.nfapi_config.p7_pnf_port.tl.tag)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 Port: %d\n", msg.nfapi_config.p7_pnf_port.value);
// store port
phy_info->p7_pnf_address.sin_port = htons(msg.nfapi_config.p7_pnf_port.value);
}
}
if(config->nr_param_resp)
{
(config->nr_param_resp)(config, p5_idx, &msg);
}
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
}
// make sure to release any dyanmic part of the message
if(msg.vendor_extension)
config->codec_config.deallocate(msg.vendor_extension);
}
}
void vnf_nr_handle_config_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx)
{
// ensure it's valid
if (pRecvMsg == NULL || config == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
}
else
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "Received CONFIG_RESPONSE\n");
nfapi_nr_config_response_scf_t msg;
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >=0 )
{
// check the error code:
if (msg.error_code == NFAPI_NR_CONFIG_MSG_OK){
if(config->nr_config_resp)
{
(config->nr_config_resp)(config, p5_idx, &msg);
}
}
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
}
// make sure to release any dyanmic part of the message
if(msg.vendor_extension)
config->codec_config.deallocate(msg.vendor_extension);
}
}
void vnf_handle_config_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx)
{
// ensure it's valid
if (pRecvMsg == NULL || config == NULL)
{
@@ -314,9 +521,13 @@ void vnf_handle_config_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config
// unpack the message
if (nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >=0 )
{
if(config->config_resp)
{
(config->config_resp)(config, p5_idx, &msg);
// check the error code:
if (msg.error_code == NFAPI_MSG_OK){
if(config->config_resp)
{
(config->config_resp)(config, p5_idx, &msg);
}
}
}
else
@@ -362,6 +573,40 @@ void vnf_handle_start_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_
}
}
void vnf_nr_handle_start_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx)
{
// ensure it's valid
if (pRecvMsg == NULL || config == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
}
else
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "Received START_RESPONSE\n");
nfapi_nr_start_response_scf_t msg;
// unpack the message
if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0)
{ // check the error code
if (msg.error_code == NFAPI_NR_START_MSG_OK){
if(config->nr_start_resp)
{
(config->nr_start_resp)(config, p5_idx, &msg);
}
}
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
}
// make sure to release any dyanmic part of the message
if(msg.vendor_extension)
config->codec_config.deallocate(msg.vendor_extension);
}
}
void vnf_handle_stop_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx)
{
@@ -811,6 +1056,74 @@ void vnf_handle_vendor_extension(void* pRecvMsg, int recvMsgLen, nfapi_vnf_confi
}
}
void vnf_nr_handle_p4_p5_message(void *pRecvMsg, int recvMsgLen, int p5_idx, nfapi_vnf_config_t* config)
{
nfapi_p4_p5_message_header_t messageHeader;
// validate the input params
if(pRecvMsg == NULL || recvMsgLen < NFAPI_HEADER_LENGTH || config == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "vnf_handle_p4_p5_message: invalid input params\n");
return;
}
// unpack the message header
if (nfapi_p5_message_header_unpack(pRecvMsg, recvMsgLen, &messageHeader, sizeof(nfapi_p4_p5_message_header_t), &config->codec_config) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n");
return;
}
switch (messageHeader.message_id)
{
case NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_RESPONSE:
vnf_nr_handle_pnf_param_response(pRecvMsg, recvMsgLen, config, p5_idx);
break;
case NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_RESPONSE:
vnf_nr_handle_pnf_config_response(pRecvMsg, recvMsgLen, config, p5_idx);
break;
case NFAPI_NR_PHY_MSG_TYPE_PNF_START_RESPONSE:
vnf_nr_handle_pnf_start_response(pRecvMsg, recvMsgLen, config, p5_idx);
break;
case NFAPI_PNF_STOP_RESPONSE:
vnf_handle_pnf_stop_response(pRecvMsg, recvMsgLen, config, p5_idx);
break;
case NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE:
vnf_nr_handle_param_response(pRecvMsg, recvMsgLen, config, p5_idx);
break;
case NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE:
vnf_nr_handle_config_response(pRecvMsg, recvMsgLen, config, p5_idx);
break;
case NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE:
vnf_nr_handle_start_response(pRecvMsg, recvMsgLen, config, p5_idx);
break;
case NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE:
vnf_handle_stop_response(pRecvMsg, recvMsgLen, config, p5_idx);
break;
default:
{
if(messageHeader.message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
messageHeader.message_id <= NFAPI_VENDOR_EXT_MSG_MAX)
{
vnf_handle_vendor_extension(pRecvMsg, recvMsgLen, config, p5_idx, messageHeader.message_id);
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s P5 Unknown message ID %d\n", __FUNCTION__, messageHeader.message_id);
}
}
break;
}
}
void vnf_handle_p4_p5_message(void *pRecvMsg, int recvMsgLen, int p5_idx, nfapi_vnf_config_t* config)
{
nfapi_p4_p5_message_header_t messageHeader;
@@ -926,6 +1239,137 @@ void vnf_handle_p4_p5_message(void *pRecvMsg, int recvMsgLen, int p5_idx, nfapi_
break;
}
}
int vnf_nr_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t* pnf)
{
if(1)
{
int socket_connected = 1;
// 1. Peek the message header
// 2. If the message is larger than the stack buffer then create a dynamic buffer
// 3. Read the buffer
// 4. Handle the p5 message
uint32_t header_buffer_size = NFAPI_HEADER_LENGTH;
uint8_t header_buffer[header_buffer_size];
uint32_t stack_buffer_size = 32; //should it be the size of then sctp_notificatoin structure
uint8_t stack_buffer[stack_buffer_size];
uint8_t* dynamic_buffer = 0;
uint8_t* read_buffer = &stack_buffer[0];
uint32_t message_size = 0;
struct sockaddr_in addr;
socklen_t addr_len = sizeof(addr);
struct sctp_sndrcvinfo sndrcvinfo;
(void)memset(&sndrcvinfo, 0, sizeof(struct sctp_sndrcvinfo));
{
int flags = MSG_PEEK;
message_size = sctp_recvmsg(pnf->p5_sock, header_buffer, header_buffer_size, (struct sockaddr*)&addr, &addr_len, &sndrcvinfo, &flags);
if(message_size == -1)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF Failed to peek sctp message size errno:%d\n", errno);
return 0;
}
nfapi_p4_p5_message_header_t header;
int unpack_result = nfapi_p5_message_header_unpack(header_buffer, header_buffer_size, &header, sizeof(header), 0);
if(unpack_result < 0)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF Failed to decode message header %d\n", unpack_result);
return 0;
}
message_size = header.message_length;
// now have the size of the mesage
}
if(message_size > stack_buffer_size)
{
dynamic_buffer = (uint8_t*)malloc(message_size);
if(dynamic_buffer == NULL)
{
// todo : add error mesage
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF Failed to allocate dynamic buffer for sctp_recvmsg size:%d\n", message_size);
return -1;
}
read_buffer = dynamic_buffer;
}
{
int flags = 0;
(void)memset(&sndrcvinfo, 0, sizeof(struct sctp_sndrcvinfo));
int recvmsg_result = sctp_recvmsg(pnf->p5_sock, read_buffer, message_size, (struct sockaddr*)&addr, &addr_len, &sndrcvinfo, &flags);
if(recvmsg_result == -1)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "Failed to read sctp message size errno:%d\n", errno);
}
else
{
if (flags & MSG_NOTIFICATION)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "Notification received from %s:%u\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
// todo - handle the events
}
else
{
/*
NFAPI_TRACE(NFAPI_TRACE_INFO, "Received message fd:%d from %s:%u assoc:%d on stream %d, PPID %d, length %d, flags 0x%x\n",
pnf->p5_sock,
inet_ntoa(addr.sin_addr),
ntohs(addr.sin_port),
sndrcvinfo.sinfo_assoc_id,
sndrcvinfo.sinfo_stream,
ntohl(sndrcvinfo.sinfo_ppid),
message_size,
flags);
*/
// handle now if complete message in one or more segments
if ((flags & 0x80) == 0x80)
{
// printf("\nVNF RECEIVES:\n");
// for(int i=0; i<message_size; i++){
// printf("%d", read_buffer[i]);
// }
// printf("\n");
vnf_nr_handle_p4_p5_message(read_buffer, message_size, pnf->p5_idx, config);
}
else
{
NFAPI_TRACE(NFAPI_TRACE_WARN, "sctp_recvmsg: unhandled mode with flags 0x%x\n", flags);
// assume socket disconnected
NFAPI_TRACE(NFAPI_TRACE_WARN, "Disconnected socket\n");
socket_connected = 0;
}
}
}
}
if(dynamic_buffer)
{
free(dynamic_buffer);
}
return socket_connected;
}
}
int vnf_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t* pnf)
{
if(1)
@@ -1024,6 +1468,12 @@ int vnf_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t*
// handle now if complete message in one or more segments
if ((flags & 0x80) == 0x80)
{
// printf("\nVNF RECEIVES:\n");
// for(int i=0; i<message_size; i++){
// printf("%d", read_buffer[i]);
// }
// printf("\n");
vnf_handle_p4_p5_message(read_buffer, message_size, pnf->p5_idx, config);
}
else
@@ -1051,6 +1501,12 @@ int vnf_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t*
static int vnf_send_p5_msg(nfapi_vnf_pnf_info_t* pnf, const void *msg, int len, uint8_t stream)
{
// printf("\n MESSAGE SENT: \n");
// for(int i=0; i<len; i++){
// printf("%d", *(uint8_t *)(msg + i));
// }
// printf("\n");
//NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s len:%d stream:%d\n", __FUNCTION__, len, stream);
int result = sctp_sendmsg(pnf->p5_sock, msg, len, (struct sockaddr*)&pnf->p5_pnf_sockaddr, sizeof(pnf->p5_pnf_sockaddr),1, 0, stream, 0, 4);
@@ -1071,6 +1527,29 @@ static int vnf_send_p5_msg(nfapi_vnf_pnf_info_t* pnf, const void *msg, int len,
return 0;
}
int vnf_nr_pack_and_send_p5_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_message_header_t* msg, uint16_t msg_len)
{
nfapi_vnf_pnf_info_t* pnf = nfapi_vnf_pnf_list_find(&(vnf->_public), p5_idx);
if(pnf)
{
// pack the message for transmission
int packedMessageLength = nfapi_nr_p5_message_pack(msg, msg_len, vnf->tx_message_buffer, sizeof(vnf->tx_message_buffer), &vnf->_public.codec_config);
if (packedMessageLength < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi_p5_message_pack failed with return %d\n", packedMessageLength);
return -1;
}
return vnf_send_p5_msg(pnf, vnf->tx_message_buffer, packedMessageLength, 0);
}
else
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() cannot find pnf info for p5_idx:%d\n", __FUNCTION__, p5_idx);
return -1;
}
}
int vnf_pack_and_send_p5_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_message_header_t* msg, uint16_t msg_len)
{
+500 -2
View File
@@ -63,6 +63,418 @@ void nfapi_vnf_config_destory(nfapi_vnf_config_t* config)
free(config);
}
int nfapi_nr_vnf_start(nfapi_vnf_config_t* config)
{
// Verify that config is not null
if(config == 0)
return -1;
// Make sure to set the defined trace function before using NFAPI_TRACE
if(config->trace)
nfapi_trace_g = (nfapi_trace_fn_t)config->trace;
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s()\n", __FUNCTION__);
int p5ListenSock, p5Sock;
struct sockaddr_in addr;
socklen_t addrSize;
struct sockaddr_in6 addr6;
struct sctp_event_subscribe events;
struct sctp_initmsg initMsg;
int noDelay;
(void)memset(&addr, 0, sizeof(struct sockaddr_in));
(void)memset(&addr6, 0, sizeof(struct sockaddr_in6));
(void)memset(&events, 0, sizeof(struct sctp_event_subscribe));
(void)memset(&initMsg, 0, sizeof(struct sctp_initmsg));
vnf_t* vnf = (vnf_t*)(config);
NFAPI_TRACE(NFAPI_TRACE_INFO, "Starting P5 VNF connection on port %u\n", config->vnf_p5_port);
/*
char * host = 0;
char * port = "4242";
struct addrinfo hints;
bzero(&hints, sizeof(struct addrinfo));
//hints.ai_flags=AI_PASSIVE;
//hints.ai_flags=AI_DEFAULT;
hints.ai_family=AF_UNSPEC;
//hints.ai_family=AF_INET6;
hints.ai_socktype=SOCK_STREAM;
//hints.ai_protocol=IPPROTO_SCTP
struct addrinfo *aiHead = 0;
int result = getaddrinfo(host, port, &hints, &aiHead);
NFAPI_TRACE(NFAPI_TRACE_INFO, "getaddrinfo return %d %d\n", result, errno);
while(aiHead->ai_next != NULL)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "addr info %d (IP %d UDP %d SCTP %d)\n %d (%d)\n",
aiHead->ai_protocol, IPPROTO_IP, IPPROTO_UDP, IPPROTO_SCTP,
aiHead->ai_flags, AI_PASSIVE);
char hostBfr[ NI_MAXHOST ];
char servBfr[ NI_MAXSERV ];
getnameinfo(aiHead->ai_addr,
aiHead->ai_addrlen,
hostBfr,
sizeof( hostBfr ),
servBfr,
sizeof( servBfr ),
NI_NUMERICHOST | NI_NUMERICSERV );
switch(aiHead->ai_family)
{
case PF_INET:
{
struct sockaddr_in *pSadrIn = (struct sockaddr_in*) aiHead->ai_addr;
printf(
" ai_addr = sin_family: %d (AF_INET = %d, "
"AF_INET6 = %d)\n"
" sin_addr: %s\n"
" sin_port: %s\n",
pSadrIn->sin_family,
AF_INET,
AF_INET6,
hostBfr,
servBfr );
}
break;
case PF_INET6:
{
struct sockaddr_in6 *pSadrIn6 = (struct sockaddr_in6*) aiHead->ai_addr;
fprintf( stderr,
" ai_addr = sin6_family: %d (AF_INET = %d, "
"AF_INET6 = %d) \n"
" sin6_addr: %s\n"
" sin6_port: %s\n"
" sin6_flowinfo: %d\n"
" sin6_scope_id: %d\n",
pSadrIn6->sin6_family,
AF_INET,
AF_INET6,
hostBfr,
servBfr,
pSadrIn6->sin6_flowinfo,
pSadrIn6->sin6_scope_id);
}
break;
default:
NFAPI_TRACE(NFAPI_TRACE_INFO, "Not ment to be here\n");
break;
}
aiHead = aiHead->ai_next;
}
*/
{
int protocol;
int domain;
if (vnf->sctp)
protocol = IPPROTO_SCTP;
else
protocol = IPPROTO_IP;
if(config->vnf_ipv6)
{
domain = PF_INET6;
}
else
{
domain = AF_INET;
}
// open the SCTP socket
if ((p5ListenSock = socket(domain, SOCK_STREAM, protocol)) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After P5 socket errno: %d\n", errno);
return 0;
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "P5 socket created... %d\n", p5ListenSock);
}
if (vnf->sctp)
{
// configure for MSG_NOTIFICATION
if (setsockopt(p5ListenSock, IPPROTO_SCTP, SCTP_EVENTS, &events, sizeof(struct sctp_event_subscribe)) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt (SCTP_EVENTS) errno: %d\n", errno);
close(p5ListenSock);
return 0;
}
NFAPI_TRACE(NFAPI_TRACE_NOTE, "VNF Setting the SCTP_INITMSG\n");
// configure the SCTP socket options
initMsg.sinit_num_ostreams = 5; //MAX_SCTP_STREAMS; // number of output streams can be greater
initMsg.sinit_max_instreams = 5; //MAX_SCTP_STREAMS; // number of output streams can be greater
if (setsockopt(p5ListenSock, IPPROTO_SCTP, SCTP_INITMSG, &initMsg, sizeof(initMsg)) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt (SCTP_INITMSG) errno: %d\n", errno)
close(p5ListenSock);
return 0;
}
noDelay = 1;
if (setsockopt(p5ListenSock, IPPROTO_SCTP, SCTP_NODELAY, &noDelay, sizeof(noDelay)) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt (STCP_NODELAY) errno: %d\n", errno);
close(p5ListenSock);
return 0;
}
struct sctp_event_subscribe events;
memset( (void *)&events, 0, sizeof(events) );
events.sctp_data_io_event = 1;
if(setsockopt(p5ListenSock, SOL_SCTP, SCTP_EVENTS, (const void *)&events, sizeof(events)) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt errno: %d\n", errno);
close(p5ListenSock);
return -1;
}
}
if(config->vnf_ipv6)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "IPV6 binding to port %d %d\n", config->vnf_p5_port, p5ListenSock);
addr6.sin6_family = AF_INET6;
addr6.sin6_port = htons(config->vnf_p5_port);
addr6.sin6_addr = in6addr_any;
// bind to the configured address and port
if (bind(p5ListenSock, (struct sockaddr *)&addr6, sizeof(struct sockaddr_in6)) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After bind errno: %d\n", errno);
close(p5ListenSock);
return 0;
}
}
else if(config->vnf_ipv4)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "IPV4 binding to port %d\n", config->vnf_p5_port);
addr.sin_family = AF_INET;
addr.sin_port = htons(config->vnf_p5_port);
addr.sin_addr.s_addr = INADDR_ANY;
// bind to the configured address and port
if (bind(p5ListenSock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0)
//if (sctp_bindx(p5ListenSock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in), SCTP_BINDX_ADD_ADDR) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After bind errno: %d\n", errno);
close(p5ListenSock);
return 0;
}
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "bind succeeded..%d.\n", p5ListenSock);
// put the socket into listen mode
if (listen(p5ListenSock, 2) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After listen errno: %d\n", errno);
close(p5ListenSock);
return 0;
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "listen succeeded...\n");
struct timeval tv;
fd_set read_fd_set;
int p5_idx = 0;
while(vnf->terminate == 0)
{
FD_ZERO(&read_fd_set);
FD_SET(p5ListenSock, &read_fd_set);
int max_fd = p5ListenSock;
tv.tv_sec = 5;
tv.tv_usec = 0;
nfapi_vnf_pnf_info_t* pnf = config->pnf_list;
while(pnf != 0)
{
if(pnf->connected)
{
FD_SET(pnf->p5_sock, &read_fd_set);
if (pnf->p5_sock > max_fd)
{
max_fd = pnf->p5_sock;
}
}
pnf = pnf->next;
}
int select_result = select(max_fd + 1, &read_fd_set, 0, 0, &tv);
if(select_result == -1)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "select result %d errno %d\n", select_result, errno);
close(p5ListenSock);
return 0;
}
else if(select_result)
{
if(FD_ISSET(p5ListenSock, &read_fd_set))
{
addrSize = sizeof(struct sockaddr_in);
NFAPI_TRACE(NFAPI_TRACE_INFO, "Accepting connection from PNF...\n");
p5Sock = accept(p5ListenSock, (struct sockaddr *)&addr, &addrSize);
if (p5Sock < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to accept PNF connection reason:%d\n", errno);
}
else
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF connection (fd:%d) accepted from %s:%d \n", p5Sock, inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
nfapi_vnf_pnf_info_t* pnf = (nfapi_vnf_pnf_info_t*)malloc(sizeof(nfapi_vnf_pnf_info_t));
NFAPI_TRACE(NFAPI_TRACE_INFO, "MALLOC nfapi_vnf_pnf_info_t for pnf_list pnf:%p\n", pnf);
memset(pnf, 0, sizeof(nfapi_vnf_pnf_info_t));
pnf->p5_sock = p5Sock;
pnf->p5_idx = p5_idx++;
pnf->p5_pnf_sockaddr = addr;
pnf->connected = 1;
nfapi_vnf_pnf_list_add(config, pnf);
// Inform mac that a pnf connection has been established
// todo : allow mac to 'accept' the connection. i.e. to
// reject it.
if(config->pnf_nr_connection_indication != 0)
{
(config->pnf_nr_connection_indication)(config, pnf->p5_idx);
}
// check the connection status
{
struct sctp_status status;
(void)memset(&status, 0, sizeof(struct sctp_status));
socklen_t optLen = (socklen_t) sizeof(struct sctp_status);
if (getsockopt(p5Sock, IPPROTO_SCTP, SCTP_STATUS, &status, &optLen) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After getsockopt errno: %d\n", errno);
return -1;
}
else
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF Association ID = %d\n", status.sstat_assoc_id);
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF Receiver window size = %d\n", status.sstat_rwnd);
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF In Streams = %d\n", status.sstat_instrms);
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF Out Streams = %d\n", status.sstat_outstrms);
}
}
}
}
else
{
uint8_t delete_pnfs = 0;
nfapi_vnf_pnf_info_t* pnf = config->pnf_list;
while(pnf != 0)
{
if(FD_ISSET(pnf->p5_sock, &read_fd_set))
{
if(vnf_nr_read_dispatch_message(config, pnf) == 0)
{
if(config->pnf_disconnect_indication != 0)
{
(config->pnf_disconnect_indication)(config, pnf->p5_idx);
}
close(pnf->p5_sock);
pnf->to_delete = 1;
delete_pnfs = 1;
}
}
pnf = pnf->next;
}
if(delete_pnfs)
{
nfapi_vnf_pnf_info_t* pnf = config->pnf_list;
nfapi_vnf_pnf_info_t* prev = 0;
while(pnf != 0)
{
nfapi_vnf_pnf_info_t* curr = pnf;
if(pnf->to_delete == 1)
{
if(prev == 0)
{
config->pnf_list = pnf->next;
}
else
{
prev->next = pnf->next;
}
pnf = pnf->next;
free(curr);
}
else
{
prev = pnf;
pnf = pnf->next;
}
}
}
}
continue;
}
else
{
// timeout
// Should we test for socket closure here every second?
continue;
}
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "Closing p5Sock socket's\n");
{
nfapi_vnf_pnf_info_t* curr = config->pnf_list;
while(curr != NULL)
{
if(config->pnf_disconnect_indication)
{
(config->pnf_disconnect_indication)(config, curr->p5_idx);
}
close(curr->p5_sock);
curr = curr->next;
}
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "Closing p5Listen socket\n");
close(p5ListenSock);
return 0;
}
int nfapi_vnf_start(nfapi_vnf_config_t* config)
{
// Verify that config is not null
@@ -486,6 +898,16 @@ int nfapi_vnf_stop(nfapi_vnf_config_t* config)
return 0;
}
int nfapi_nr_vnf_pnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_pnf_param_request_t* req)
{
if(config == 0 || req == 0)
return -1;
vnf_t* _this = (vnf_t*)(config);
return vnf_nr_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_nr_pnf_param_request_t));
}
int nfapi_vnf_pnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_param_request_t* req)
{
if(config == 0 || req == 0)
@@ -496,6 +918,17 @@ int nfapi_vnf_pnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_pa
return vnf_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_pnf_param_request_t));
}
int nfapi_nr_vnf_pnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_pnf_config_request_t* req)
{
if(config == 0 || req == 0)
return -1;
vnf_t* _this = (vnf_t*)(config);
return vnf_nr_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_nr_pnf_config_request_t));
}
int nfapi_vnf_pnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_config_request_t* req)
{
if(config == 0 || req == 0)
@@ -516,6 +949,16 @@ int nfapi_vnf_pnf_start_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_st
return vnf_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_pnf_start_request_t));
}
int nfapi_nr_vnf_pnf_start_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_pnf_start_request_t* req)
{
if(config == 0 || req == 0)
return -1;
vnf_t* _this = (vnf_t*)(config);
return vnf_nr_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_nr_pnf_start_request_t));
}
int nfapi_vnf_pnf_stop_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_stop_request_t* req)
{
if(config == 0 || req == 0)
@@ -526,6 +969,16 @@ int nfapi_vnf_pnf_stop_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_sto
return vnf_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_pnf_stop_request_t));
}
int nfapi_nr_vnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_param_request_scf_t* req)
{
if(config == 0 || req == 0)
return -1;
vnf_t* _this = (vnf_t*)(config);
return vnf_nr_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_nr_param_request_scf_t));
}
int nfapi_vnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_param_request_t* req)
{
if(config == 0 || req == 0)
@@ -535,6 +988,38 @@ int nfapi_vnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_param_requ
return vnf_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_param_request_t));
}
int nfapi_nr_vnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_config_request_scf_t* req)
{
if(config == 0 || req == 0)
return -1;
vnf_t* _this = (vnf_t*)(config);
nfapi_vnf_phy_info_t* phy = nfapi_vnf_phy_info_list_find(config, req->header.phy_id);
if(phy == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_WARN, "%s failed to find phy information phy_id:%d\n", __FUNCTION__, req->header.phy_id);
return -1;
}
// set the timing parameters
req->nfapi_config.timing_window.tl.tag = NFAPI_NR_NFAPI_TIMING_WINDOW_TAG;
req->nfapi_config.timing_window.value = phy->timing_window;
req->num_tlv++;
req->nfapi_config.timing_info_mode.tl.tag = NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG;
req->nfapi_config.timing_info_mode.value = phy->timing_info_mode;
req->num_tlv++;
req->nfapi_config.timing_info_period.tl.tag = NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG;
req->nfapi_config.timing_info_period.value = phy->timing_info_period;
req->num_tlv++;
return vnf_nr_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_nr_config_request_scf_t));
}
int nfapi_vnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_config_request_t* req)
{
if(config == 0 || req == 0)
@@ -565,7 +1050,8 @@ int nfapi_vnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_config_re
return vnf_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_config_request_t));
}
int nfapi_vnf_start_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_start_request_t* req)
int nfapi_vnf_start_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_start_request_t * req)
{
if(config == 0 || req == 0)
return -1;
@@ -574,6 +1060,18 @@ int nfapi_vnf_start_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_start_requ
return vnf_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_start_request_t));
}
int nfapi_nr_vnf_start_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_start_request_scf_t * req)
{
if(config == 0 || req == 0)
return -1;
vnf_t* _this = (vnf_t*)(config);
return vnf_nr_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_nr_start_request_scf_t));
}
int nfapi_vnf_stop_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_stop_request_t* req)
{
if(config == 0 || req == 0)
@@ -664,7 +1162,7 @@ int nfapi_vnf_allocate_phy(nfapi_vnf_config_t* config, int p5_idx, uint16_t* phy
info->p5_idx = p5_idx;
info->phy_id = vnf->next_phy_id++;
info->timing_window = 30; // This seems to override what gets set by the user - why???
info->timing_window = 30; // This seems to override what gets set by the user - why??? //TODO: Change in NR in terms of microsecends,what should be the value?
info->timing_info_mode = 0x03;
info->timing_info_period = 128;
File diff suppressed because it is too large Load Diff
+395 -5
View File
@@ -28,6 +28,7 @@
#define FAPI2_IP_DSCP 0
nfapi_vnf_p7_config_t* nfapi_vnf_p7_config_create()
{
vnf_p7_t* _this = (vnf_p7_t*)calloc(1, sizeof(vnf_p7_t));
@@ -90,6 +91,368 @@ struct timespec timespec_sub(struct timespec lhs, struct timespec rhs)
// monitor the p7 endpoints and the timing loop and
// send indications to mac
int nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t* config)
{
if(config == 0)
return -1;
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s()\n", __FUNCTION__);
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
// Create p7 receive udp port
// todo : this needs updating for Ipv6
NFAPI_TRACE(NFAPI_TRACE_INFO, "Initialising VNF P7 port:%u\n", config->port);
// open the UDP socket
if ((vnf_p7->socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After P7 socket errno: %d\n", errno);
return -1;
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF P7 socket created...\n");
// configure the UDP socket options
int iptos_value = FAPI2_IP_DSCP << 2;
if (setsockopt(vnf_p7->socket, IPPROTO_IP, IP_TOS, &iptos_value, sizeof(iptos_value)) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt (IP_TOS) errno: %d\n", errno);
return -1;
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF P7 setsockopt succeeded...\n");
// Create the address structure
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(config->port);
addr.sin_addr.s_addr = INADDR_ANY;
// bind to the configured port
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF P7 binding too %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
if (bind(vnf_p7->socket, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0)
//if (sctp_bindx(config->socket, (struct sockaddr *)&addr, sizeof(struct sockaddr_in), 0) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After bind errno: %d\n", errno);
return -1;
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF P7 bind succeeded...\n");
//struct timespec original_pselect_timeout;
struct timespec pselect_timeout;
pselect_timeout.tv_sec = 0;
pselect_timeout.tv_nsec = 500000; // ns in a 0.5 ms
//pselect_timeout.tv_nsec = 500000;
struct timespec pselect_start;
struct timespec pselect_stop;
//struct timespec sf_end;
long last_millisecond = -1;
// struct timespec sf_duration; //Change to slot_duration?
// sf_duration.tv_sec = 0;
// sf_duration.tv_nsec = 0.5e6; // We want 1ms pause //We want 0.5 ms pause for NR
struct timespec slot_duration;
slot_duration.tv_sec = 0;
//slot_duration.tv_nsec = 0.5e6;
slot_duration.tv_nsec = 0.5e6;
// struct timespec sf_start; //Change to slot_start?
struct timespec slot_start;
// clock_gettime(CLOCK_MONOTONIC, &sf_start);
clock_gettime(CLOCK_MONOTONIC, &slot_start);
long millisecond = slot_start.tv_nsec / 1e6; //Check if we have to change
//long millisecond = slot_start.tv_nsec / 0.5e6;
// sf_start = timespec_add(sf_start, sf_duration);
slot_start = timespec_add(slot_start, slot_duration);
NFAPI_TRACE(NFAPI_TRACE_INFO, "next slot will start at %d.%d\n", slot_start.tv_sec, slot_start.tv_nsec);
while(vnf_p7->terminate == 0)
{
fd_set rfds;
int maxSock = 0;
FD_ZERO(&rfds);
int selectRetval = 0;
// Add the p7 socket
FD_SET(vnf_p7->socket, &rfds);
maxSock = vnf_p7->socket;
clock_gettime(CLOCK_MONOTONIC, &pselect_start);
//long millisecond = pselect_start.tv_nsec / 1e6;
if((last_millisecond == -1) || (millisecond == last_millisecond) || (millisecond == (last_millisecond + 1) % 1000) )
{
//NFAPI_TRACE(NFAPI_TRACE_INFO, "pselect_start:%d.%d sf_start:%d.%d\n", pselect_start.tv_sec, pselect_start.tv_nsec, sf_start.tv_sec, sf_start.tv_nsec);
//if((pselect_start.tv_sec > sf_start.tv_sec) ||
// ((pselect_start.tv_sec == sf_start.tv_sec) && (pselect_start.tv_nsec > sf_start.tv_nsec)))
if((pselect_start.tv_sec > slot_start.tv_sec) || ((pselect_start.tv_sec == slot_start.tv_sec) && (pselect_start.tv_nsec > slot_start.tv_nsec)))
{
// overran the end of the subframe we do not want to wait
pselect_timeout.tv_sec = 0;
pselect_timeout.tv_nsec = 0;
//struct timespec overrun = timespec_sub(pselect_start, sf_start);
//NFAPI_TRACE(NFAPI_TRACE_INFO, "Subframe overrun detected of %d.%d running to catchup\n", overrun.tv_sec, overrun.tv_nsec);
}
else
{
// still time before the end of the subframe wait
//pselect_timeout = timespec_sub(sf_start, pselect_start);
pselect_timeout = timespec_sub(slot_start, pselect_start);
}
//original_pselect_timeout = pselect_timeout;
// detemine how long to sleep in ns before the start of the next 1ms
//pselect_timeout.tv_nsec = 1e6 - (pselect_start.tv_nsec % 1000000);
//uint8_t underrun_possible =0;
// if we are not sleeping until the next milisecond due to the
// insycn minor adjment flag it so we don't consider it an error
//uint8_t underrun_possible =0;
/*
{
nfapi_vnf_p7_connection_info_t* phy = vnf_p7->p7_connections;
if(phy && phy->in_sync && phy->insync_minor_adjustment != 0 && phy->insync_minor_adjustment_duration > 0 && pselect_start.tv_nsec != 0)
{
NFAPI_TRACE(NFAPI_TRACE_NOTE, "[VNF] Subframe minor adjustment %d (%d->%d)\n", phy->insync_minor_adjustment,
pselect_timeout.tv_nsec, pselect_timeout.tv_nsec - (phy->insync_minor_adjustment * 1000))
if(phy->insync_minor_adjustment > 0)
{
// todo check we don't go below 0
if((phy->insync_minor_adjustment * 1000) > pselect_timeout.tv_nsec)
pselect_timeout.tv_nsec = 0;
else
pselect_timeout.tv_nsec = pselect_timeout.tv_nsec - (phy->insync_minor_adjustment * 1000);
//underrun_possible = 1;
}
else if(phy->insync_minor_adjustment < 0)
{
// todo check we don't go below 0
pselect_timeout.tv_nsec = pselect_timeout.tv_nsec - (phy->insync_minor_adjustment * 1000);
//phy->insync_minor_adjustment = 0;
phy->insync_minor_adjustment_duration--;
}
}
*/
//long wraps = pselect_timeout.tv_nsec % 1e9;
selectRetval = pselect(maxSock+1, &rfds, NULL, NULL, &pselect_timeout, NULL);
// selectRetval = pselect(120, &rfds, NULL, NULL, &pselect_timeout, NULL);
clock_gettime(CLOCK_MONOTONIC, &pselect_stop);
nfapi_vnf_p7_connection_info_t* phy = vnf_p7->p7_connections;
if (selectRetval==-1 && errno == 22)
{
// NFAPI_TRACE(NFAPI_TRACE_ERROR, "INVAL: pselect_timeout:%d.%ld adj[dur:%d adj:%d], sf_dur:%d.%ld\n",
// pselect_timeout.tv_sec, pselect_timeout.tv_nsec,
// phy->insync_minor_adjustment_duration, phy->insync_minor_adjustment,
// sf_duration.tv_sec, sf_duration.tv_nsec);
NFAPI_TRACE(NFAPI_TRACE_ERROR, "INVAL: pselect_timeout:%d.%ld adj[dur:%d adj:%d], sf_dur:%d.%ld\n",
pselect_timeout.tv_sec, pselect_timeout.tv_nsec,
phy->insync_minor_adjustment_duration, phy->insync_minor_adjustment,
slot_duration.tv_sec, slot_duration.tv_nsec);
}
if(selectRetval == 0)
{
// calculate the start of the next slot
//sf_start = timespec_add(sf_start, sf_duration);
slot_start = timespec_add(slot_start, slot_duration);
//NFAPI_TRACE(NFAPI_TRACE_INFO, "next subframe will start at %d.%d\n", sf_start.tv_sec, sf_start.tv_nsec);
if(phy && phy->in_sync && phy->insync_minor_adjustment != 0 && phy->insync_minor_adjustment_duration > 0)
{
long insync_minor_adjustment_ns = (phy->insync_minor_adjustment * 1000);
//sf_start.tv_nsec -= insync_minor_adjustment_ns;
slot_start.tv_nsec -= insync_minor_adjustment_ns;
#if 1
/* if (sf_start.tv_nsec > 1e9) //Change to 0.5e6?
{
sf_start.tv_sec++;
sf_start.tv_nsec-=1e9;
}
else if (sf_start.tv_nsec < 0)
{
sf_start.tv_sec--;
sf_start.tv_nsec+=1e9;
}*/
if (slot_start.tv_nsec > 1e9)
{
slot_start.tv_sec++;
slot_start.tv_nsec-=1e9;
}
else if (slot_start.tv_nsec < 0)
{
slot_start.tv_sec--;
slot_start.tv_nsec+=1e9;
}
#else
//NFAPI_TRACE(NFAPI_TRACE_NOTE, "[VNF] BEFORE adjustment - Subframe minor adjustment %dus sf_start.tv_nsec:%d\n", phy->insync_minor_adjustment, sf_start.tv_nsec);
if(phy->insync_minor_adjustment > 0)
{
// decrease the subframe duration a little
if (sf_start.tv_nsec > insync_minor_adjustment_ns)
sf_start.tv_nsec -= insync_minor_adjustment_ns;
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "[VNF] Adjustment would make it negative sf:%d.%ld adjust:%ld\n\n\n", sf_start.tv_sec, sf_start.tv_nsec, insync_minor_adjustment_ns);
sf_start.tv_sec--;
sf_start.tv_nsec += 1e9 - insync_minor_adjustment_ns;
}
}
else if(phy->insync_minor_adjustment < 0)
{
// todo check we don't go below 0
// increase the subframe duration a little
sf_start.tv_nsec += insync_minor_adjustment_ns;
if (sf_start.tv_nsec < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "[VNF] OVERFLOW %d.%ld\n\n\n\n", sf_start.tv_sec, sf_start.tv_nsec);
sf_start.tv_sec++;
sf_start.tv_nsec += 1e9;
}
}
#endif
//phy->insync_minor_adjustment = 0;
phy->insync_minor_adjustment_duration--;
// NFAPI_TRACE(NFAPI_TRACE_NOTE, "[VNF] AFTER adjustment - Subframe minor adjustment %dus sf_start.tv_nsec:%d duration:%u\n",
// phy->insync_minor_adjustment, sf_start.tv_nsec, phy->insync_minor_adjustment_duration);
// NFAPI_TRACE(NFAPI_TRACE_NOTE, "[VNF] AFTER adjustment - Slot minor adjustment %dus slot_start.tv_nsec:%d duration:%u\n",
// phy->insync_minor_adjustment, slot_start.tv_nsec, phy->insync_minor_adjustment_duration);
if (phy->insync_minor_adjustment_duration==0)
{
phy->insync_minor_adjustment = 0;
}
}
/*
long pselect_stop_millisecond = pselect_stop.tv_nsec / 1e6;
if(millisecond == pselect_stop_millisecond)
{
// we have woke up in the same subframe
if(underrun_possible == 0)
NFAPI_TRACE(NFAPI_TRACE_WARN, "subframe pselect underrun %ld (%d.%d)\n", millisecond, pselect_stop.tv_sec, pselect_stop.tv_nsec);
}
else if(((millisecond + 1) % 1000) != pselect_stop_millisecond)
{
// we have overrun the subframe
NFAPI_TRACE(NFAPI_TRACE_WARN, "subframe pselect overrun %ld %ld\n", millisecond, pselect_stop_millisecond);
NFAPI_TRACE(NFAPI_TRACE_WARN, "subframe underrun %ld\n", millisecond);
}
last_millisecond = millisecond;
*/
//millisecond ++;
millisecond = millisecond + 1;
}
}
else
{
// we have overrun the subframe advance to go and collect $200
if((millisecond - last_millisecond) > 3)
NFAPI_TRACE(NFAPI_TRACE_WARN, "subframe overrun %ld %ld (%ld)\n", millisecond, last_millisecond, millisecond - last_millisecond + 1);
last_millisecond = ( last_millisecond + 1 ) % 1000;
selectRetval = 0;
}
if(selectRetval == 0)
{
//vnf_p7->sf_start_time_hr = vnf_get_current_time_hr();
vnf_p7->slot_start_time_hr = vnf_get_current_time_hr();
struct timespec current_time;
clock_gettime(CLOCK_MONOTONIC, &current_time);
// pselect timed out
nfapi_vnf_p7_connection_info_t* curr = vnf_p7->p7_connections;
while(curr != 0)
{
if (curr->slot == 19)
{ //curr->slot = 0;
if(curr->sfn == 1023)
curr->sfn=0;
else
curr->sfn++;
curr->slot=0;
}
else
{
curr->slot++;
}
vnf_nr_sync(vnf_p7, curr);
curr = curr->next;
}
send_mac_slot_indications(vnf_p7);
}
else if(selectRetval > 0)
{
// have a p7 message
if(FD_ISSET(vnf_p7->socket, &rfds))
{
vnf_nr_p7_read_dispatch_message(vnf_p7);
}
}
else
{
// pselect error
if(selectRetval == -1 && errno == EINTR)
{
// a sigal was received.
}
else
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "P7 select failed result %d errno %d timeout:%d.%d orginal:%d.%d last_ms:%ld ms:%ld\n", selectRetval, errno, pselect_timeout.tv_sec, pselect_timeout.tv_nsec, pselect_timeout.tv_sec, pselect_timeout.tv_nsec, last_millisecond, millisecond);
// should we exit now?
if (selectRetval == -1 && errno == 22) // invalid argument??? not sure about timeout duration
{
usleep(100000);
}
}
}
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "Closing p7 socket\n");
close(vnf_p7->socket);
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() returning\n", __FUNCTION__);
return 0;
}
int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config)
{
if(config == 0)
@@ -408,6 +771,7 @@ if (selectRetval==-1 && errno == 22)
return 0;
}
int nfapi_vnf_p7_stop(nfapi_vnf_p7_config_t* config)
{
if(config == 0)
@@ -434,17 +798,18 @@ int nfapi_vnf_p7_add_pnf(nfapi_vnf_p7_config_t* config, const char* pnf_p7_addr,
memset(node, 0, sizeof(nfapi_vnf_p7_connection_info_t));
node->phy_id = phy_id;
node->in_sync = 0;
node->dl_out_sync_offset = 30;
node->dl_out_sync_offset = 30;//TODO: Values need to be changed for NR,How to set the values
node->dl_out_sync_period = 10;
node->dl_in_sync_offset = 30;
node->dl_in_sync_period = 512;
node->sfn_sf = 0;
//node->sfn_sf = 0;
node->sfn = 0;
node->slot = 0;
node->min_sync_cycle_count = 8;
// save the remote endpoint information
node->remote_addr.sin_family = AF_INET;
node->remote_addr.sin_port = htons(pnf_p7_port);
node->remote_addr.sin_port = pnf_p7_port;//htons(pnf_p7_port);
node->remote_addr.sin_addr.s_addr = inet_addr(pnf_p7_addr);
vnf_p7_connection_info_list_add(vnf_p7, node);
@@ -490,7 +855,16 @@ int nfapi_vnf_p7_nr_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_nr_dl_tti
return -1;
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
return vnf_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
return vnf_nr_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
}
int nfapi_vnf_p7_ul_tti_req(nfapi_vnf_p7_config_t* config, nfapi_nr_ul_tti_request_t* req)
{
if(config == 0 || req == 0)
return -1;
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
return vnf_nr_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
}
int nfapi_vnf_p7_ul_config_req(nfapi_vnf_p7_config_t* config, nfapi_ul_config_request_t* req)
@@ -501,6 +875,14 @@ int nfapi_vnf_p7_ul_config_req(nfapi_vnf_p7_config_t* config, nfapi_ul_config_re
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
return vnf_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
}
int nfapi_vnf_p7_ul_dci_req(nfapi_vnf_p7_config_t* config, nfapi_nr_ul_dci_request_t* req)
{
if(config == 0 || req == 0)
return -1;
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
return vnf_nr_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
}
int nfapi_vnf_p7_hi_dci0_req(nfapi_vnf_p7_config_t* config, nfapi_hi_dci0_request_t* req)
{
if(config == 0 || req == 0)
@@ -509,6 +891,14 @@ int nfapi_vnf_p7_hi_dci0_req(nfapi_vnf_p7_config_t* config, nfapi_hi_dci0_reques
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
return vnf_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
}
int nfapi_vnf_p7_tx_data_req(nfapi_vnf_p7_config_t* config, nfapi_nr_tx_data_request_t* req)
{
if(config == 0 || req == 0)
return -1;
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
return vnf_nr_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
}
int nfapi_vnf_p7_tx_req(nfapi_vnf_p7_config_t* config, nfapi_tx_request_t* req)
{
if(config == 0 || req == 0)
+12 -1
View File
@@ -381,6 +381,13 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
}
//Adding nr_schedule_handler
void install_nr_schedule_handlers(NR_IF_Module_t *if_inst)
{
if_inst->NR_PHY_config_req = nr_phy_config_request;
if_inst->NR_Schedule_response = nr_schedule_response;
}
/*
void install_schedule_handlers(IF_Module_t *if_inst)
{
@@ -459,7 +466,10 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) {
uint64_t ul_bw_khz = (12*gNB_config->carrier_config.ul_grid_size[gNB_config->ssb_config.scs_common.value].value)*(15<<gNB_config->ssb_config.scs_common.value);
fp->ul_CarrierFreq = ((ul_bw_khz>>1) + gNB_config->carrier_config.uplink_frequency.value)*1000 ;
fp->nr_band = *RC.nrmac[Mod_id]->common_channels[0].ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
//fp->nr_band = *RC.nrmac[Mod_id]->common_channels[0].ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
lte_frame_type_t frame_type = 0; // FDD
get_band(fp->dl_CarrierFreq,&fp->nr_band,&dlul_offset,&frame_type); //RC.nrmac[Mod_id] cannot be accessed in NFAPI
get_delta_duplex(fp->nr_band, gNB_config->ssb_config.scs_common.value, &dlul_offset);
dlul_offset *= 1000;
@@ -499,6 +509,7 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) {
LOG_I(PHY,"gNB %d configured\n",Mod_id);
}
void init_nr_transport(PHY_VARS_gNB *gNB) {
int i;
int j;
+1 -1
View File
@@ -51,7 +51,7 @@ void init_byte2m64(void) {
((int16_t*)&byte2m64_re[s])[0],((int16_t*)&byte2m64_im[s])[0],
((int16_t*)&byte2m64_re[s])[1],((int16_t*)&byte2m64_im[s])[1],
((int16_t*)&byte2m64_re[s])[2],((int16_t*)&byte2m64_im[s])[2],
((int16_t*)&byte2m64_re[s])[3],((int16_t*)&byte2m64_im[s])[3]);
((int16_t*)&byte2m64_re[s])[3],((int16_t*)&byte2m64_im[s])[3]);
}
}
+50
View File
@@ -0,0 +1,50 @@
//Dummy NR defs to avoid linking errors
#include "PHY/defs_gNB.h"
#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h"
#include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h"
#include "openair1/PHY/LTE_TRANSPORT/transport_common.h"
void handle_nfapi_nr_pdcch_pdu(PHY_VARS_gNB *gNB,
int frame, int slot,
nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu){}
void handle_nr_nfapi_ssb_pdu(PHY_VARS_gNB *gNB,int frame,int slot,
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu){}
int16_t find_nr_dlsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type){return 0;}
void handle_nr_nfapi_pdsch_pdu(PHY_VARS_gNB *gNB,int frame,int slot,
nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
uint8_t *sdu){
}
int l1_north_init_gNB(void){return 0;}
uint8_t slot_ahead=6;
//uint8_t nfapi_mode=0;
NR_IF_Module_t *NR_IF_Module_init(int Mod_id) {return NULL;}
void handle_nfapi_nr_ul_dci_pdu(PHY_VARS_gNB *gNB,
int frame, int slot,
nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu){}
void nr_fill_ulsch(PHY_VARS_gNB *gNB,
int frame,
int slot,
nfapi_nr_pusch_pdu_t *ulsch_pdu){}
void nr_fill_pucch(PHY_VARS_gNB *gNB,
int frame,
int slot,
nfapi_nr_pucch_pdu_t *pucch_pdu){}
void nr_fill_prach(PHY_VARS_gNB *gNB,
int SFN,
int Slot,
nfapi_nr_prach_pdu_t *prach_pdu){}
void nr_fill_prach_ru(RU_t *ru,
int SFN,
int Slot,
nfapi_nr_prach_pdu_t *prach_pdu){}
void nr_phy_config_request(NR_PHY_Config_t *gNB){}
void install_nr_schedule_handlers(NR_IF_Module_t *if_inst){}
void nr_dump_frame_parms(NR_DL_FRAME_PARMS *fp){}
+52
View File
@@ -0,0 +1,52 @@
//Dummy NR defs to avoid linking errors
#include "PHY/defs_gNB.h"
#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h"
#include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h"
#include "openair1/PHY/LTE_TRANSPORT/transport_common.h"
void handle_nfapi_nr_pdcch_pdu(PHY_VARS_gNB *gNB,
int frame, int slot,
nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu){}
void handle_nr_nfapi_ssb_pdu(PHY_VARS_gNB *gNB,int frame,int slot,
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu){}
int16_t find_nr_dlsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type){return 0;}
void handle_nr_nfapi_pdsch_pdu(PHY_VARS_gNB *gNB,int frame,int slot,
nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
uint8_t *sdu){
}
int l1_north_init_gNB(void){return 0;}
uint8_t slot_ahead=6;
//uint8_t nfapi_mode=0;
NR_IF_Module_t *NR_IF_Module_init(int Mod_id) {return NULL;}
void handle_nfapi_nr_ul_dci_pdu(PHY_VARS_gNB *gNB,
int frame, int slot,
nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu){}
void nr_fill_ulsch(PHY_VARS_gNB *gNB,
int frame,
int slot,
nfapi_nr_pusch_pdu_t *ulsch_pdu){}
void nr_fill_pucch(PHY_VARS_gNB *gNB,
int frame,
int slot,
nfapi_nr_pucch_pdu_t *pucch_pdu){}
void nr_fill_prach(PHY_VARS_gNB *gNB,
int SFN,
int Slot,
nfapi_nr_prach_pdu_t *prach_pdu){}
void nr_fill_prach_ru(RU_t *ru,
int SFN,
int Slot,
nfapi_nr_prach_pdu_t *prach_pdu){}
void nr_phy_config_request(NR_PHY_Config_t *gNB){}
void install_nr_schedule_handlers(NR_IF_Module_t *if_inst){}
//void nr_dump_frame_parms(NR_DL_FRAME_PARMS *fp){}
+58 -23
View File
@@ -33,6 +33,12 @@
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
#include "PHY/NR_TRANSPORT/nr_dci.h"
#include "nfapi/oai_integration/vendor_ext.h"
extern int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req);
extern int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req);
extern int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req);
extern int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req);
extern uint8_t nfapi_mode;
@@ -126,7 +132,7 @@ void handle_nr_nfapi_pdsch_pdu(PHY_VARS_gNB *gNB,int frame,int slot,
}
void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
PHY_VARS_gNB *gNB;
// copy data from L2 interface into L1 structures
module_id_t Mod_id = Sched_INFO->module_id;
@@ -169,6 +175,7 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
case NFAPI_NR_DL_TTI_SSB_PDU_TYPE:
gNB->pbch_configured=1;
if(NFAPI_MODE != NFAPI_MODE_VNF)
handle_nr_nfapi_ssb_pdu(gNB,frame,slot,
dl_tti_pdu);
@@ -176,7 +183,7 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE:
AssertFatal(pdcch_received == 0, "pdcch_received is not 0, we can only handle one PDCCH PDU per slot\n");
LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE for %d.%d\n",frame,slot,DL_req->SFN,DL_req->Slot);
if(NFAPI_MODE != NFAPI_MODE_VNF)
handle_nfapi_nr_pdcch_pdu(gNB,
frame, slot,
&dl_tti_pdu->pdcch_pdu);
@@ -193,33 +200,61 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
AssertFatal(TX_req->pdu_list[pduIndex].num_TLV == 1, "TX_req->pdu_list[%d].num_TLV %d != 1\n",
pduIndex,TX_req->pdu_list[pduIndex].num_TLV);
uint8_t *sdu = (uint8_t *)TX_req->pdu_list[pduIndex].TLVs[0].value.direct;
if(NFAPI_MODE != NFAPI_MODE_VNF)
handle_nr_nfapi_pdsch_pdu(gNB,frame,slot,&dl_tti_pdu->pdsch_pdu, sdu);
}
}
}
// if (UL_tti_req!=NULL) memcpy(&gNB->UL_tti_req,UL_tti_req,sizeof(nfapi_nr_ul_tti_request_t));
if(NFAPI_MODE != NFAPI_MODE_VNF)
for (int i=0;i<number_ul_dci_pdu;i++) {
handle_nfapi_nr_ul_dci_pdu(gNB, frame, slot, &UL_dci_req->ul_dci_pdu_list[i]);
}
if(NFAPI_MODE != NFAPI_MODE_VNF)
for (int i = 0; i < number_ul_tti_pdu; i++) {
switch (UL_tti_req->pdus_list[i].pdu_type) {
case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE:
LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PUSCH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot);
nr_fill_ulsch(gNB,UL_tti_req->SFN, UL_tti_req->Slot, &UL_tti_req->pdus_list[i].pusch_pdu);
break;
case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE:
LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PUCCH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot);
nr_fill_pucch(gNB,UL_tti_req->SFN, UL_tti_req->Slot, &UL_tti_req->pdus_list[i].pucch_pdu);
break;
case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE:
LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PRACH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot);
nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[i].prach_pdu;
nr_fill_prach(gNB, UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu);
if (gNB->RU_list[0]->if_south == LOCAL_RF) nr_fill_prach_ru(gNB->RU_list[0], UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu);
break;
}
}
if(NFAPI_MODE != NFAPI_MONOLITHIC && number_ul_tti_pdu>0)
{
oai_nfapi_ul_tti_req(UL_tti_req);
}
for (int i=0;i<number_ul_dci_pdu;i++) {
handle_nfapi_nr_ul_dci_pdu(gNB, frame, slot, &UL_dci_req->ul_dci_pdu_list[i]);
if (NFAPI_MODE != NFAPI_MONOLITHIC && Sched_INFO->UL_dci_req->numPdus!=0)
{
oai_nfapi_ul_dci_req(Sched_INFO->UL_dci_req);
}
if (NFAPI_MODE != NFAPI_MONOLITHIC)
{
if(Sched_INFO->DL_req->dl_tti_request_body.nPDUs>0)
{
Sched_INFO->DL_req->SFN = frame;
Sched_INFO->DL_req->Slot = slot;
oai_nfapi_dl_tti_req(Sched_INFO->DL_req);
}
if (Sched_INFO->TX_req->Number_of_PDUs > 0)
{
oai_nfapi_tx_data_req(Sched_INFO->TX_req);
}
}
for (int i = 0; i < number_ul_tti_pdu; i++) {
switch (UL_tti_req->pdus_list[i].pdu_type) {
case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE:
LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PUSCH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot);
nr_fill_ulsch(gNB,UL_tti_req->SFN, UL_tti_req->Slot, &UL_tti_req->pdus_list[i].pusch_pdu);
break;
case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE:
LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PUCCH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot);
nr_fill_pucch(gNB,UL_tti_req->SFN, UL_tti_req->Slot, &UL_tti_req->pdus_list[i].pucch_pdu);
break;
case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE:
LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PRACH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot);
nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[i].prach_pdu;
nr_fill_prach(gNB, UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu);
if (gNB->RU_list[0]->if_south == LOCAL_RF) nr_fill_prach_ru(gNB->RU_list[0], UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu);
break;
}
}
}
}
+10
View File
@@ -36,6 +36,11 @@
#include "nfapi_nr_interface.h"
#include "nfapi_nr_interface_scf.h"
// added
void handle_nr_nfapi_ssb_pdu(PHY_VARS_gNB *gNB,
int frame,int slot,
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu);
void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO);
void handle_nfapi_nr_pdcch_pdu(PHY_VARS_gNB *gNB,
@@ -48,3 +53,8 @@ void handle_nr_nfapi_pdsch_pdu(PHY_VARS_gNB *gNB,int frame,int slot,
void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int UE_id, uint8_t harq_pid, uint8_t crc_flag);
//added
void handle_nfapi_nr_ul_dci_pdu(PHY_VARS_gNB *gNB,
int frame, int slot,
nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu);
+1 -1
View File
@@ -161,7 +161,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_COMMON_TX,1);
if (nfapi_mode == 0 || nfapi_mode == 1) {
if (NFAPI_MODE == NFAPI_MONOLITHIC || NFAPI_MODE == NFAPI_MODE_PNF) {
if ((!(frame%ssb_frame_periodicity))) // generate SSB only for given frames according to SSB periodicity
nr_common_signal_procedures(gNB,frame, slot);
}
+1 -1
View File
@@ -295,7 +295,7 @@ harq_result_t uplink_harq_process(NR_UE_ULSCH_t *ulsch, int harq_pid, int ndi, u
/* 38.321 5.4.2.1 2> if the uplink grant was received on PDCCH for the C-RNTI and the HARQ buffer of the identified process is empty */
if ((ulsch->harq_processes[harq_pid]->first_tx == 1) && (rnti_type == _C_RNTI_)) { /* no transmission yet on this process so consider its harq buffer as empty */
ulsch->harq_processes[harq_pid]->first_tx = 0;
ulsch->harq_processes[harq_pid]->first_tx = 0;
ulsch->harq_processes[harq_pid]->pusch_pdu.pusch_data.new_data_indicator = ndi; /* store first value of ndi */
ulsch->harq_processes[harq_pid]->round = 0;
ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
+1 -1
View File
@@ -56,7 +56,7 @@ UE_nr_rxtx_proc_t proc;
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
double cpuf;
uint8_t nfapi_mode = 0;
//uint8_t nfapi_mode = 0;
uint16_t NB_UE_INST = 1;
uint8_t const nr_rv_round_map[4] = {0, 2, 1, 3};
+8 -1
View File
@@ -83,7 +83,7 @@ double cpuf;
int sf_ahead=4 ;
int sl_ahead=0;
uint8_t nfapi_mode = 0;
//uint8_t nfapi_mode = 0;
uint64_t downlink_frequency[MAX_NUM_CCs][4];
int usrp_tx_thread = 0;
@@ -175,6 +175,13 @@ int is_x2ap_enabled(void)
return 0;
}
//nFAPI P7 dummy functions
int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req) { return(0); }
int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req){ return(0); }
int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req){ return(0); }
int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req){ return(0); }
int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len) {
return 0;
}
@@ -2,9 +2,16 @@ int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { re
int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) { return(0); }
int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { return(0); }
//int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); }
//int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_config_request_t *dl_config_req) { return(0); }
int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req) { return(0); }
int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req){ return(0); }
int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req){ return(0); }
int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req){ return(0); }
int32_t get_uldl_offset(int nr_bandP) { return(0); }
NR_IF_Module_t *NR_IF_Module_init(int Mod_id) {return(NULL);}
nfapi_mode_t nfapi_mod;
nfapi_mode_t nfapi_getmode(void) {
return nfapi_mod;
}
int dummy_nr_ue_dl_indication(nr_downlink_indication_t *dl_info) { return(0); }
int dummy_nr_ue_ul_indication(nr_uplink_indication_t *ul_info) { return(0); }
void nr_fill_dl_indication(nr_downlink_indication_t *dl_ind,
@@ -2,7 +2,10 @@ int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { re
int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) { return(0); }
int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { return(0); }
int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); }
//int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_config_request_t *dl_config_req) { return(0); }
int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req) { return(0); }
int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req){ return(0); }
int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req){ return(0); }
int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req){ return(0); }
int32_t get_uldl_offset(int nr_bandP) { return(0); }
NR_IF_Module_t *NR_IF_Module_init(int Mod_id) {return(NULL);}
int dummy_nr_ue_dl_indication(nr_downlink_indication_t *dl_info) { return(0); }
+2 -1
View File
@@ -239,6 +239,7 @@ ngap_gNB_config_t ngap_config;
uint32_t ngap_generate_gNB_id(void) {return 0;}
void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port) { return;}
void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port) { return;}
void configure_nr_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port) { return;}
void configure_nr_nfapi_vnf(char *vnf_addr, int vnf_p5_port) { return;}
#endif
+1 -1
View File
@@ -56,7 +56,7 @@ RAN_CONTEXT_t RC;
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
double cpuf;
uint8_t nfapi_mode = 0;
//uint8_t nfapi_mode = 0;
uint16_t NB_UE_INST = 1;
// needed for some functions
+5 -1
View File
@@ -62,7 +62,7 @@ RU_t *ru;
double cpuf;
extern uint16_t prach_root_sequence_map0_3[838];
openair0_config_t openair0_cfg[MAX_CARDS];
uint8_t nfapi_mode=0;
//uint8_t nfapi_mode=0;
int sl_ahead = 0;
//void dump_nr_prach_config(NR_DL_FRAME_PARMS *frame_parms,uint8_t subframe);
@@ -70,6 +70,10 @@ int sl_ahead = 0;
/* temporary dummy implem of get_softmodem_optmask, till basic simulators implemented as device */
uint64_t get_softmodem_optmask(void) {return 0;}
softmodem_params_t *get_softmodem_params(void) {return 0;}
int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req) { return(0); }
int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req){ return(0); }
int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req){ return(0); }
int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req){ return(0); }
void
rrc_data_ind(
+1 -1
View File
@@ -54,7 +54,7 @@ openair0_config_t openair0_cfg[MAX_CARDS];
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
double cpuf;
uint8_t nfapi_mode = 0;
//uint8_t nfapi_mode = 0;
uint16_t NB_UE_INST = 1;
uint8_t const nr_rv_round_map[4] = {0, 2, 1, 3};
uint8_t const nr_rv_round_map_ue[4] = {0, 2, 1, 3};
+1 -1
View File
@@ -60,7 +60,7 @@ uint8_t const nr_rv_round_map[4] = {0, 2, 1, 3};
uint8_t const nr_rv_round_map_ue[4] = {0, 2, 1, 3};
double cpuf;
uint8_t nfapi_mode = 0;
//uint8_t nfapi_mode = 0;
uint16_t NB_UE_INST = 1;
// needed for some functions
+8 -1
View File
@@ -76,9 +76,10 @@ RAN_CONTEXT_t RC;
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
int sf_ahead=4 ;
int slot_ahead=6 ;
int sl_ahead=0;
double cpuf;
uint8_t nfapi_mode = 0;
//uint8_t nfapi_mode = 0;
uint64_t downlink_frequency[MAX_NUM_CCs][4];
@@ -154,6 +155,12 @@ int is_x2ap_enabled(void)
return 0;
}
//nFAPI P7 dummy functions
int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req) { return(0); }
int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req){ return(0); }
int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req){ return(0); }
int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req){ return(0); }
int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len) {
return 0;
}
@@ -142,6 +142,10 @@ void thread_top_init(char *thread_name,
int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { return(0);}
int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) { return(0); }
int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req) { return(0); }
int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req){ return(0); }
int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req){ return(0); }
int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req){ return(0); }
int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { return(0); }
+3 -3
View File
@@ -431,7 +431,7 @@ void RCconfig_NR_L1(void) {
mac_top_init_gNB();
configure_nfapi_pnf(RC.gNB[j]->eth_params_n.remote_addr, RC.gNB[j]->eth_params_n.remote_portc, RC.gNB[j]->eth_params_n.my_addr, RC.gNB[j]->eth_params_n.my_portd, RC.gNB[j]->eth_params_n .remote_portd);
configure_nr_nfapi_pnf(RC.gNB[j]->eth_params_n.remote_addr, RC.gNB[j]->eth_params_n.remote_portc, RC.gNB[j]->eth_params_n.my_addr, RC.gNB[j]->eth_params_n.my_portd, RC.gNB[j]->eth_params_n .remote_portd);
}else { // other midhaul
}
}// for (j = 0; j < RC.nb_nr_L1_inst; j++)
@@ -501,8 +501,8 @@ void RCconfig_nr_macrlc() {
//sf_ahead = 2; // Cannot cope with 4 subframes between RX and TX - set it to 2
printf("**************** vnf_port:%d\n", RC.mac[j]->eth_params_s.my_portc);
configure_nfapi_vnf(RC.nrmac[j]->eth_params_s.my_addr, RC.nrmac[j]->eth_params_s.my_portc);
printf("**************** vnf_port:%d\n", RC.nrmac[j]->eth_params_s.my_portc);
configure_nr_nfapi_vnf(RC.nrmac[j]->eth_params_s.my_addr, RC.nrmac[j]->eth_params_s.my_portc);
printf("**************** RETURNED FROM configure_nfapi_vnf() vnf_port:%d\n", RC.nrmac[j]->eth_params_s.my_portc);
}else { // other midhaul
AssertFatal(1==0,"MACRLC %d: %s unknown southbound midhaul\n",j,*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr));
@@ -3067,6 +3067,49 @@ bool set_dl_ptrs_values(NR_PTRS_DownlinkConfig_t *ptrs_config,
//printf("[MAC] PTRS is set K= %u L= %u\n", *K_ptrs,1<<*L_ptrs);
return valid;
}
void get_band(uint64_t downlink_frequency,
uint16_t *current_band,
int32_t *current_offset,
lte_frame_type_t *current_type)
{
int ind;
uint64_t center_frequency_khz;
uint64_t center_freq_diff_khz;
uint64_t dl_freq_khz = downlink_frequency/1000;
center_freq_diff_khz = 999999999999999999; // 2^64
*current_band = 0;
for ( ind=0;
ind < sizeof(nr_bandtable) / sizeof(nr_bandtable[0]);
ind++) {
LOG_I(PHY, "Scanning band %d, dl_min %"PRIu64", ul_min %"PRIu64"\n", nr_bandtable[ind].band, nr_bandtable[ind].dl_min,nr_bandtable[ind].ul_min);
if ( nr_bandtable[ind].dl_min <= dl_freq_khz && nr_bandtable[ind].dl_max >= dl_freq_khz ) {
center_frequency_khz = (nr_bandtable[ind].dl_max + nr_bandtable[ind].dl_min)/2;
if (abs(dl_freq_khz - center_frequency_khz) < center_freq_diff_khz){
*current_band = nr_bandtable[ind].band;
*current_offset = (nr_bandtable[ind].ul_min - nr_bandtable[ind].dl_min)*1000;
center_freq_diff_khz = abs(dl_freq_khz - center_frequency_khz);
if (*current_offset == 0)
*current_type = TDD;
else
*current_type = FDD;
}
}
}
LOG_I( PHY, "DL frequency %"PRIu64": band %d, frame_type %d, UL frequency %"PRIu64"\n",
downlink_frequency, *current_band, *current_type, downlink_frequency+*current_offset);
AssertFatal(*current_band != 0,
"Can't find EUTRA band for frequency %lu\n", downlink_frequency);
}
uint32_t get_ssb_slot(uint32_t ssb_index){
// this function now only support f <= 3GHz
return ssb_index & 0x3 ;
@@ -140,6 +140,7 @@ bool set_dl_ptrs_values(NR_PTRS_DownlinkConfig_t *ptrs_config,
uint8_t *K_ptrs, uint8_t *L_ptrs,uint8_t *portIndex,
uint8_t *nERatio,uint8_t *reOffset,
uint8_t NrOfSymbols);
void get_band(uint64_t downlink_frequency, uint16_t *current_band, int32_t *current_offset, lte_frame_type_t *current_type);
uint8_t get_num_dmrs_symbols(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,int NrOfSymbols);
+7 -6
View File
@@ -45,7 +45,7 @@
#include "NR_MIB.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
#include "../../../../nfapi/oai_integration/vendor_ext.h"
/* Softmodem params */
#include "executables/softmodem-common.h"
@@ -264,6 +264,7 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
}
cfg->ssb_table.ssb_mask_list[0].ssb_mask.tl.tag = NFAPI_NR_CONFIG_SSB_MASK_TAG;
cfg->ssb_table.ssb_mask_list[1].ssb_mask.tl.tag = NFAPI_NR_CONFIG_SSB_MASK_TAG;
cfg->num_tlv++;
cfg->carrier_config.num_tx_ant.value = pdsch_AntennaPorts;
@@ -305,7 +306,7 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
if (return_tdd != 0)
LOG_E(MAC,"TDD configuration can not be done\n");
else
LOG_I(MAC,"TDD has been properly configurated\n");
LOG_I(MAC,"TDD has been properly configurated\n");
}
}
@@ -366,11 +367,11 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
LOG_E(MAC, "%s() %s:%d RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req:%p\n", __FUNCTION__, __FILE__, __LINE__, RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req);
// if in nFAPI mode
if ( (nfapi_mode == 1 || nfapi_mode == 2) && (RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req == NULL) ){
if ( (NFAPI_MODE == NFAPI_MODE_PNF || NFAPI_MODE == NFAPI_MODE_VNF) && (RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req == NULL) ){
while(RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req == NULL) {
// DJP AssertFatal(RC.nrmac[Mod_idP]->if_inst->PHY_config_req != NULL,"if_inst->phy_config_request is null\n");
usleep(100 * 1000);
printf("Waiting for PHY_config_req\n");
// DJP AssertFatal(RC.nrmac[Mod_idP]->if_inst->PHY_config_req != NULL,"if_inst->phy_config_request is null\n");
usleep(100 * 1000);
printf("Waiting for PHY_config_req\n");
}
}
+2 -1
View File
@@ -52,6 +52,7 @@
#include "intertask_interface.h"
#include "executables/softmodem-common.h"
#include "nfapi/oai_integration/vendor_ext.h"
uint16_t nr_pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 };
@@ -104,7 +105,7 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
gNB->pdu_index[CC_idP] = 0;
if (nfapi_mode==0 || nfapi_mode == 1) { // monolithic or PNF
if (NFAPI_MODE == NFAPI_MONOLITHIC || NFAPI_MODE == NFAPI_MODE_PNF) { // monolithic or PNF
DL_req[CC_idP].SFN = frameP;
DL_req[CC_idP].Slot = slotP;
@@ -103,7 +103,7 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
dl_tti_pdcch_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE;
dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs+1];
dl_tti_pdsch_pdu = &nr_mac->DL_req[CC_id].dl_tti_request_body.dl_tti_pdu_list[nr_mac->DL_req[CC_id].dl_tti_request_body.nPDUs+1];
memset((void *)dl_tti_pdsch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
dl_tti_pdsch_pdu->PDUType = NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE;
dl_tti_pdsch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdsch_pdu));
@@ -238,7 +238,7 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
pdsch_pdu_rel15->mcsIndex[0]);
*/
dl_req->nPDUs+=2;
nr_mac->DL_req[CC_id].dl_tti_request_body.nPDUs+=2;
TX_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs];
TX_req->PDU_length = 6;
@@ -31,6 +31,7 @@
#include "NR_MAC_COMMON/nr_mac_extern.h"
#include "NR_MAC_gNB/mac_proto.h"
#include "common/ran_context.h"
#include "nfapi/oai_integration/vendor_ext.h"
extern RAN_CONTEXT_t RC;
@@ -1130,4 +1130,4 @@ void nr_schedule_ulsch(module_id_t module_id,
memset(sched_pusch, 0, sizeof(*sched_pusch));
}
}
}
+1 -2
View File
@@ -2135,8 +2135,7 @@ pdcp_config_set_security(
}
//-----------------------------------------------------------------------------
void
rrc_pdcp_config_req (
void rrc_pdcp_config_req (
const protocol_ctxt_t *const ctxt_pP,
const srb_flag_t srb_flagP,
const uint32_t actionP,
+4 -2
View File
@@ -36,6 +36,7 @@
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "common/ran_context.h"
#include "executables/softmodem-common.h"
#include "nfapi/oai_integration/vendor_ext.h"
#define MAX_IF_MODULES 100
//#define UL_HARQ_PRINT
@@ -104,6 +105,7 @@ void handle_nr_uci(NR_UL_IND_t *UL_info)
}
UL_info->uci_ind.num_ucis = 0;
// mark corresponding PUCCH resources as free
// NOTE: we just assume it is BWP ID 1, to be revised for multiple BWPs
RC.nrmac[mod_id]->pucch_index_used[1][slot] = 0;
@@ -184,7 +186,7 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
module_id,CC_id, UL_info->rach_ind.number_of_pdus,
UL_info->rx_ind.number_of_pdus, UL_info->crc_ind.number_crcs);
if (nfapi_mode != 1) {
if (NFAPI_MODE != NFAPI_MODE_PNF) {
if (ifi->CC_mask==0) {
ifi->current_frame = UL_info->frame;
ifi->current_slot = UL_info->slot;
@@ -203,7 +205,7 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
mac->UL_dci_req[CC_id].numPdus = 0;
handle_nr_ulsch(UL_info);
if (nfapi_mode != 1) {
if (NFAPI_MODE != NFAPI_MODE_PNF) {
if (ifi->CC_mask == ((1<<MAX_NUM_CCs)-1)) {
/*
eNB_dlsch_ulsch_scheduler(module_id,
+4
View File
@@ -30,6 +30,10 @@
#include "targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h"
#include "common/config/config_load_configmodule.h"
#include "common/config/config_userapi.h"
#include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h"
#include "openair1/PHY/defs_gNB.h"
#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h"
#include "openair1/PHY/LTE_TRANSPORT/transport_common.h"
extern int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind);
void configure_nfapi_pnf(char *vnf_ip_addr,
+1 -1
View File
@@ -303,4 +303,4 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP,
return(0);
}
}
@@ -0,0 +1,46 @@
log_config = {
global_log_level ="debug";
global_log_verbosity ="medium";
hw_log_level ="info";
hw_log_verbosity ="medium";
phy_log_level ="info";
phy_log_verbosity ="medium";
mac_log_level ="debug";
mac_log_verbosity ="medium";
rlc_log_level ="info";
rlc_log_verbosity ="medium";
pdcp_log_level ="info";
pdcp_log_verbosity ="medium";
rrc_log_level ="debug";
rrc_log_verbosity ="full";
};
L1s = (
{
num_cc = 1;
tr_n_preference = "nfapi";
local_n_if_name = "lo";
remote_n_address = "127.0.0.2"; // vnf addr
local_n_address = "127.0.0.1"; // pnf addr
local_n_portc = 50000; // pnf p5 port [!]
remote_n_portc = 50001; // vnf p5 port
local_n_portd = 50010; // pnf p7 port
remote_n_portd = 50011; // vnf p7 port
}
);
RUs = (
{
local_rf = "yes"
nb_tx = 1
nb_rx = 1
att_tx = 0
att_rx = 0;
bands = [7];
max_pdschReferenceSignalPower = -27;
max_rxgain = 114;
sdr_addrs = "type=x300"; // USRP type
}
);
@@ -0,0 +1,290 @@
Active_gNBs = ( "gNB-Eurecom-5GNRBox");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
gNBs =
(
{
////////// Identification parameters:
gNB_ID = 0xe00;
cell_type = "CELL_MACRO_GNB";
gNB_name = "gNB-Eurecom-5GNRBox";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ({mcc = 208; mnc = 93; mnc_length = 2;});
tr_s_preference = "local_mac"
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
servingCellConfigCommon = (
{
#spCellConfigCommon
physCellId = 0;
# downlinkConfigCommon
#frequencyInfoDL
# this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
absoluteFrequencySSB = 641032;
dl_frequencyBand = 78;
# this is 3600 MHz
dl_absoluteFrequencyPointA = 640000;
#scs-SpecificCarrierList
dl_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
dl_subcarrierSpacing = 1;
dl_carrierBandwidth = 106;
#initialDownlinkBWP
#genericParameters
# this is RBstart=41,L=24 (275*(L-1))+RBstart
initialDLBWPlocationAndBandwidth = 6366;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialDLBWPsubcarrierSpacing = 1;
#pdcch-ConfigCommon
initialDLBWPcontrolResourceSetZero = 12;
initialDLBWPsearchSpaceZero = 0;
#pdsch-ConfigCommon
#pdschTimeDomainAllocationList (up to 16 entries)
initialDLBWPk0_0 = 0;
#initialULBWPmappingType
#0=typeA,1=typeB
initialDLBWPmappingType_0 = 0;
#this is SS=1,L=13
initialDLBWPstartSymbolAndLength_0 = 40;
initialDLBWPk0_1 = 0;
initialDLBWPmappingType_1 = 0;
#this is SS=2,L=12
initialDLBWPstartSymbolAndLength_1 = 53;
initialDLBWPk0_2 = 0;
initialDLBWPmappingType_2 = 0;
#this is SS=1,L=12
initialDLBWPstartSymbolAndLength_2 = 54;
initialDLBWPk0_3 = 0;
initialDLBWPmappingType_3 = 0;
#this is SS=1,L=5
initialDLBWPstartSymbolAndLength_3 = 57;
#uplinkConfigCommon
#frequencyInfoUL
ul_frequencyBand = 78;
#scs-SpecificCarrierList
ul_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
ul_subcarrierSpacing = 1;
ul_carrierBandwidth = 106;
pMax = 20;
#initialUplinkBWP
#genericParameters
initialULBWPlocationAndBandwidth = 6366;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialULBWPsubcarrierSpacing = 1;
#rach-ConfigCommon
#rach-ConfigGeneric
prach_ConfigurationIndex = 98;
#prach_msg1_FDM
#0 = one, 1=two, 2=four, 3=eight
prach_msg1_FDM = 0;
prach_msg1_FrequencyStart = 0;
zeroCorrelationZoneConfig = 13;
preambleReceivedTargetPower = -118;
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
preambleTransMax = 6;
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
#oneHalf (0..15) 4,8,12,16,...60,64
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15;
#ra_ContentionResolutionTimer
#(0..7) 8,16,24,32,40,48,56,64
ra_ContentionResolutionTimer = 7;
rsrp_ThresholdSSB = 19;
#prach-RootSequenceIndex_PR
#1 = 839, 2 = 139
prach_RootSequenceIndex_PR = 2;
prach_RootSequenceIndex = 1;
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
#
msg1_SubcarrierSpacing = 1,
# restrictedSetConfig
# 0=unrestricted, 1=restricted type A, 2=restricted type B
restrictedSetConfig = 0,
# pusch-ConfigCommon (up to 16 elements)
initialULBWPk2_0 = 6;
initialULBWPmappingType_0 = 1
# this is SS=0 L=11
initialULBWPstartSymbolAndLength_0 = 55;
initialULBWPk2_1 = 6;
initialULBWPmappingType_1 = 1;
# this is SS=0 L=12
initialULBWPstartSymbolAndLength_1 = 69;
initialULBWPk2_2 = 7;
initialULBWPmappingType_2 = 1;
# this is SS=10 L=4
initialULBWPstartSymbolAndLength_2 = 52;
msg3_DeltaPreamble = 1;
p0_NominalWithGrant =-90;
# pucch-ConfigCommon setup :
# pucchGroupHopping
# 0 = neither, 1= group hopping, 2=sequence hopping
pucchGroupHopping = 0;
hoppingId = 40;
p0_nominal = -90;
# ssb_PositionsInBurs_BitmapPR
# 1=short, 2=medium, 3=long
ssb_PositionsInBurst_PR = 2;
ssb_PositionsInBurst_Bitmap = 1;
# ssb_periodicityServingCell
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
ssb_periodicityServingCell = 2;
# dmrs_TypeA_position
# 0 = pos2, 1 = pos3
dmrs_TypeA_Position = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
subcarrierSpacing = 1;
#tdd-UL-DL-ConfigurationCommon
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
referenceSubcarrierSpacing = 1;
# pattern1
# dl_UL_TransmissionPeriodicity
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
dl_UL_TransmissionPeriodicity = 6;
nrofDownlinkSlots = 7;
nrofDownlinkSymbols = 6;
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
ssPBCH_BlockPower = 10;
}
);
srb1_parameters :
{
# timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
timer_poll_retransmit = 80;
# timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
timer_reordering = 35;
# timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
timer_status_prohibit = 0;
# poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
poll_pdu = 4;
# poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
poll_byte = 99999;
# max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
max_retx_threshold = 4;
}
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// MME parameters:
mme_ip_address = ( { ipv4 = "192.168.12.26";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
NETWORK_INTERFACES :
{
GNB_INTERFACE_NAME_FOR_S1_MME = "eth0";
GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24";
GNB_INTERFACE_NAME_FOR_S1U = "eth0";
GNB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24";
GNB_PORT_FOR_S1U = 2152; # Spec 2152
};
}
);
MACRLCs = (
{
num_cc = 1;
local_s_if_name = "lo:";
remote_s_address = "127.0.0.1"; // pnf addr [!]
local_s_address = "127.0.0.2"; // vnf addr
local_s_portc = 50001; // vnf p5 port
remote_s_portc = 50000; // pnf p5 port [!]
local_s_portd = 50011; // vnf p7 port [!]
remote_s_portd = 50010; // pnf p7 port [!]
tr_s_preference = "nfapi";
tr_n_preference = "local_RRC";
}
)
THREAD_STRUCT = (
{
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
parallel_config = "PARALLEL_RU_L1_TRX_SPLIT";
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
worker_config = "WORKER_ENABLE";
}
);
log_config =
{
global_log_level ="info";
global_log_verbosity ="medium";
hw_log_level ="info";
hw_log_verbosity ="medium";
phy_log_level ="info";
phy_log_verbosity ="medium";
mac_log_level ="info";
mac_log_verbosity ="high";
rlc_log_level ="info";
rlc_log_verbosity ="medium";
pdcp_log_level ="info";
pdcp_log_verbosity ="medium";
rrc_log_level ="info";
rrc_log_verbosity ="medium";
};
+4 -4
View File
@@ -1690,10 +1690,10 @@ static void *ru_thread( void *param ) {
// wait to be woken up
if (ru->function!=eNodeB_3GPP && ru->has_ctrl_prt == 1) {
LOG_I(PHY,"Waiting for control thread to say go\n");
LOG_D(PHY,"RU %d: Waiting for control thread to say go\n",ru->idx);
if (wait_on_condition(&ru->proc.mutex_ru,&ru->proc.cond_ru_thread,&ru->proc.instance_cnt_ru,"ru_thread")<0) break;
} else wait_sync("ru_thread");
LOG_I(PHY,"Got start from control thread\n");
LOG_D(PHY,"RU %d: Got start from control thread\n",ru->idx);
if(!(ru->emulate_rf)) {
if (ru->is_slave == 0) AssertFatal(ru->state == RU_RUN,"ru-%d state = %s != RU_RUN\n",ru->idx,ru_states[ru->state]);
@@ -1721,7 +1721,7 @@ static void *ru_thread( void *param ) {
// if this is a slave RRU, try to synchronize on the DL frequency
if ((ru->is_slave == 1) && (ru->if_south == LOCAL_RF)) do_ru_synch(ru);
LOG_I(PHY,"Starting steady-state operation\n");
LOG_D(PHY,"RU %d Starting steady-state operation\n",ru->idx);
// This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices
while (ru->state == RU_RUN || ru->state == RU_CHECK_SYNC) {
@@ -1898,7 +1898,7 @@ static void *ru_thread( void *param ) {
#endif
} // else wait_cnt == 0
} // ru->state = RU_RUN
} // ru->state = RU_RUN || RU_CHECK_SYNC
} // while !oai_exit
LOG_I(PHY, "Exiting ru_thread \n");
+1
View File
@@ -594,6 +594,7 @@ int main ( int argc, char **argv )
if (RC.nb_inst > 0) {
/* Start the agent. If it is turned off in the configuration, it won't start */
for (i = 0; i < RC.nb_inst; i++) {
if(NFAPI_MODE != NFAPI_MODE_PNF)
flexran_agent_start(i);
}
+1 -1
View File
@@ -720,7 +720,7 @@ void* ru_thread_control( void* param )
break;
case RRU_sync_ok: //RAU
if (ru->if_south == LOCAL_RF) LOG_E(PHY,"Received RRU_config_ok msg...Ignoring\n");
if (ru->if_south == LOCAL_RF) LOG_E(PHY,"Received RRU_sync_ok msg...Ignoring\n");
else{
if (ru->is_slave == 1){
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Received RRU_sync_ok from RRU %d\n",ru->idx);