Compare commits

...

1 Commits

Author SHA1 Message Date
Anurag Asokan
61aaaddc1b Virtual Time Support for OAI 4G L2 Sim
Virtual Time mode enables the communication between the base station
and UE which operates in L2-Simulator mode to communicate in a
non real time mode i.e it doesnt need to obey the sub frame boundary for
synchronization.

Removed vt code for 5G NR
2023-04-21 09:09:03 +00:00
21 changed files with 442 additions and 338 deletions

View File

@@ -483,6 +483,10 @@ int main ( int argc, char **argv )
#endif
LOG_I(HW, "Version: %s\n", PACKAGE_VERSION);
if (get_softmodem_params()->virtual_time) {
LOG_A(ENB_APP, "Running eNB in VIRTUAL TIME mode\n");
}
/* Read configuration */
if (RC.nb_inst > 0) {
read_config_and_init();

View File

@@ -83,7 +83,6 @@
/*-------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* command line parameters specific to UE */
/* optname helpstr paramflags XXXptr defXXXval type numelt */

View File

@@ -1158,6 +1158,11 @@ static void *UE_phy_stub_standalone_pnf_task(void *arg) {
NFAPI_SFNSF2SFN(ul_config_req->sfn_sf), NFAPI_SFNSF2SF(ul_config_req->sfn_sf));
}
}
if (UE->virtual_time) {
fill_ue_sf_indication_UE_MAC(ue_Mod_id, NFAPI_SFNSF2SFN(sfn_sf), NFAPI_SFNSF2SF(sfn_sf), sfn_sf, UL_INFO);
}
} //for (Mod_id=0; Mod_id<NB_UE_INST; Mod_id++)
if (UL_INFO->crc_ind.crc_indication_body.number_of_crcs > 0) {
@@ -1200,6 +1205,18 @@ static void *UE_phy_stub_standalone_pnf_task(void *arg) {
UL_INFO->sr_ind.sr_indication_body.number_of_srs = 0;
}
if (UE->virtual_time && UL_INFO->vt_ue_sf_ind.sfn_sf != 0x4000) {
LOG_D(MAC,
"Sending UE_SLOT.indication at SFN: %d SF: %d for Ack'ing sfn: %d sf: %d \n",
NFAPI_SFNSF2SFN(sfn_sf),
NFAPI_SFNSF2SF(sfn_sf),
NFAPI_SFNSF2SFN(UL_INFO->vt_ue_sf_ind.sfn_sf),
NFAPI_SFNSF2SF(UL_INFO->vt_ue_sf_ind.sfn_sf));
send_standalone_msg(UL_INFO, UL_INFO->vt_ue_sf_ind.header.message_id);
sent_any = true;
UL_INFO->vt_ue_sf_ind.sfn_sf = 0x4000; /** An ivalid value */
}
// De-allocate memory of nfapi requests copies before next subframe round
if (dl_config_req_tx_req != NULL) {
if (dl_config_req_tx_req->dl_config_req->vendor_extension != NULL) {

View File

@@ -88,7 +88,6 @@ uint16_t sf_ahead=4;
int tddflag;
char *emul_iface;
pthread_cond_t sync_cond;
pthread_mutex_t sync_mutex;
int sync_var=-1; //!< protected by mutex \ref sync_mutex.
@@ -607,6 +606,10 @@ int main( int argc, char **argv ) {
PHY_vars_UE_g[i][CC_id]->mac_enabled = 0;
else
PHY_vars_UE_g[i][CC_id]->mac_enabled = 1;
PHY_vars_UE_g[i][CC_id]->virtual_time = get_softmodem_params()->virtual_time;
if (get_softmodem_params()->virtual_time)
LOG_I(NFAPI_VNF, "UE Id: %d running in VIRTUAL TIME mode.\n", i);
}
}
} else init_openair0(frame_parms[0],(int)rx_gain[0][0]);

View File

@@ -631,6 +631,10 @@ int main( int argc, char **argv ) {
#endif
LOG_I(HW, "Version: %s\n", PACKAGE_VERSION);
if (get_softmodem_params()->virtual_time) {
LOG_A(ENB_APP, "Running gNB in VIRTUAL TIME mode\n");
}
if (RC.nb_nr_L1_inst > 0)
RCconfig_NR_L1();

View File

@@ -103,6 +103,7 @@ extern "C"
#define CONFIG_L1_EMULATOR "Run in L1 emulated mode (disable PHY layer)\n"
#define CONFIG_HLP_CONTINUOUS_TX "perform continuous transmission, even in TDD mode (to work around USRP issues)\n"
#define CONFIG_HLP_STATS_DISABLE "disable globally the stats generation and persistence"
#define CONFIG_HLP_VIRT_TIME "Enable virtual time mode (Flexible TTI duration). Works with L1 emulator only.\n"
/*-----------------------------------------------------------------------------------------------------------------------------------------------------*/
/* command line parameters common to eNodeB and UE */
@@ -132,50 +133,53 @@ extern "C"
#define NON_STOP softmodem_params.non_stop
#define EMULATE_L1 softmodem_params.emulate_l1
#define CONTINUOUS_TX softmodem_params.continuous_tx
#define VIRTUAL_TIME softmodem_params.virtual_time
#define DEFAULT_RFCONFIG_FILE "/usr/local/etc/syriq/ue.band7.tm1.PRB100.NR40.dat";
extern int usrp_tx_thread;
// clang-format off
#define CMDLINE_PARAMS_DESC { \
{"rf-config-file", CONFIG_HLP_RFCFGF, 0, .strptr=&RF_CONFIG_FILE, .defstrval=NULL, TYPE_STRING, 0}, \
{"thread-pool", CONFIG_HLP_TPOOL, 0, .strptr=&TP_CONFIG, .defstrval="-1,-1,-1,-1,-1,-1,-1,-1", TYPE_STRING, 0}, \
{"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, .iptr=&PHY_TEST, .defintval=0, TYPE_INT, 0}, \
{"do-ra", CONFIG_HLP_DORA, PARAMFLAG_BOOL, .iptr=&DO_RA, .defintval=0, TYPE_INT, 0}, \
{"sa", CONFIG_HLP_SA, PARAMFLAG_BOOL, .iptr=&SA, .defintval=0, TYPE_INT, 0}, \
{"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, .u8ptr=&USIM_TEST, .defintval=0, TYPE_UINT8, 0}, \
{"clock-source", CONFIG_HLP_CLK, 0, .uptr=&CLOCK_SOURCE, .defintval=0, TYPE_UINT, 0}, \
{"time-source", CONFIG_HLP_TME, 0, .uptr=&TIMING_SOURCE, .defintval=0, TYPE_UINT, 0}, \
{"tune-offset", CONFIG_HLP_TUNE_OFFSET, 0, .dblptr=&TUNE_OFFSET, .defintval=0, TYPE_DOUBLE, 0}, \
{"wait-for-sync", NULL, PARAMFLAG_BOOL, .iptr=&WAIT_FOR_SYNC, .defintval=0, TYPE_INT, 0}, \
{"single-thread-enable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, .iptr=&SINGLE_THREAD_FLAG, .defintval=0, TYPE_INT, 0}, \
{"C" , CONFIG_HLP_DLF, 0, .u64ptr=&(downlink_frequency[0][0]), .defuintval=0, TYPE_UINT64, 0}, \
{"CO" , CONFIG_HLP_ULF, 0, .iptr=&(uplink_frequency_offset[0][0]), .defintval=0, TYPE_INT, 0}, \
{"a" , CONFIG_HLP_CHOFF, 0, .iptr=&CHAIN_OFFSET, .defintval=0, TYPE_INT, 0}, \
{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, .uptr=&do_forms, .defintval=0, TYPE_UINT, 0}, \
{"dqt" , CONFIG_HLP_SOFTS_QT, PARAMFLAG_BOOL, .uptr=&do_forms_qt, .defintval=0, TYPE_UINT, 0}, \
{"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, .iptr=&opp_enabled, .defintval=0, TYPE_INT, 0}, \
{"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, .iptr=&NUMEROLOGY, .defintval=1, TYPE_INT, 0}, \
{"band" , CONFIG_HLP_BAND, PARAMFLAG_BOOL, .iptr=&BAND, .defintval=78, TYPE_INT, 0}, \
{"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, .iptr=&EMULATE_RF, .defintval=0, TYPE_INT, 0}, \
{"parallel-config", CONFIG_HLP_PARALLEL_CMD, 0, .strptr=&parallel_config, .defstrval=NULL, TYPE_STRING, 0}, \
{"worker-config", CONFIG_HLP_WORKER_CMD, 0, .strptr=&worker_config, .defstrval=NULL, TYPE_STRING, 0}, \
{"noS1", CONFIG_HLP_NOS1, PARAMFLAG_BOOL, .uptr=&noS1, .defintval=0, TYPE_UINT, 0}, \
{"rfsim", CONFIG_HLP_RFSIM, PARAMFLAG_BOOL, .uptr=&rfsim, .defintval=0, TYPE_UINT, 0}, \
{"nokrnmod", CONFIG_HLP_NOKRNMOD, PARAMFLAG_BOOL, .uptr=&nokrnmod, .defintval=1, TYPE_UINT, 0}, \
{"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, .uptr=&nonbiot, .defuintval=0, TYPE_UINT, 0}, \
{"chest-freq", CONFIG_HLP_CHESTFREQ, 0, .iptr=&CHEST_FREQ, .defintval=0, TYPE_INT, 0}, \
{"chest-time", CONFIG_HLP_CHESTTIME, 0, .iptr=&CHEST_TIME, .defintval=0, TYPE_INT, 0}, \
{"nsa", CONFIG_HLP_NSA, PARAMFLAG_BOOL, .iptr=&NSA, .defintval=0, TYPE_INT, 0}, \
{"node-number", NULL, 0, .u16ptr=&NODE_NUMBER, .defuintval=0, TYPE_UINT16, 0}, \
{"usrp-tx-thread-config", CONFIG_HLP_USRP_THREAD, 0, .iptr=&usrp_tx_thread, .defstrval=0, TYPE_INT, 0}, \
{"nfapi", CONFIG_HLP_NFAPI, 0, .strptr=NULL, .defstrval="MONOLITHIC", TYPE_STRING, 0}, \
{"non-stop", CONFIG_HLP_NONSTOP, PARAMFLAG_BOOL, .iptr=&NON_STOP, .defintval=0, TYPE_INT, 0}, \
{"emulate-l1", CONFIG_L1_EMULATOR, PARAMFLAG_BOOL, .iptr=&EMULATE_L1, .defintval=0, TYPE_INT, 0}, \
{"continuous-tx", CONFIG_HLP_CONTINUOUS_TX, PARAMFLAG_BOOL, .iptr=&CONTINUOUS_TX, .defintval=0, TYPE_INT, 0}, \
{"disable-stats", CONFIG_HLP_STATS_DISABLE, PARAMFLAG_BOOL, .iptr=&stats_disabled, .defintval=0, TYPE_INT, 0}, \
}
// clang-format on
{"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:&RF_CONFIG_FILE, defstrval:NULL, TYPE_STRING, 0},\
{"thread-pool", CONFIG_HLP_TPOOL, 0, strptr:&TP_CONFIG, defstrval:"-1,-1,-1,-1,-1,-1,-1,-1", TYPE_STRING, 0}, \
{"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&PHY_TEST, defintval:0, TYPE_INT, 0}, \
{"do-ra", CONFIG_HLP_DORA, PARAMFLAG_BOOL, iptr:&DO_RA, defintval:0, TYPE_INT, 0}, \
{"sa", CONFIG_HLP_SA, PARAMFLAG_BOOL, iptr:&SA, defintval:0, TYPE_INT, 0}, \
{"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&USIM_TEST, defintval:0, TYPE_UINT8, 0}, \
{"clock-source", CONFIG_HLP_CLK, 0, uptr:&CLOCK_SOURCE, defintval:0, TYPE_UINT, 0}, \
{"time-source", CONFIG_HLP_TME, 0, uptr:&TIMING_SOURCE, defintval:0, TYPE_UINT, 0}, \
{"tune-offset", CONFIG_HLP_TUNE_OFFSET, 0, dblptr:&TUNE_OFFSET, defintval:0, TYPE_DOUBLE, 0}, \
{"wait-for-sync", NULL, PARAMFLAG_BOOL, iptr:&WAIT_FOR_SYNC, defintval:0, TYPE_INT, 0}, \
{"single-thread-enable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&SINGLE_THREAD_FLAG, defintval:0, TYPE_INT, 0}, \
{"C" , CONFIG_HLP_DLF, 0, u64ptr:&(downlink_frequency[0][0]), defuintval:0, TYPE_UINT64, 0}, \
{"CO" , CONFIG_HLP_ULF, 0, iptr:&(uplink_frequency_offset[0][0]), defintval:0, TYPE_INT, 0}, \
{"a" , CONFIG_HLP_CHOFF, 0, iptr:&CHAIN_OFFSET, defintval:0, TYPE_INT, 0}, \
{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:&do_forms, defintval:0, TYPE_UINT, 0}, \
{"dqt" , CONFIG_HLP_SOFTS_QT, PARAMFLAG_BOOL, uptr:&do_forms_qt, defintval:0, TYPE_UINT, 0}, \
{"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \
{"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&NUMEROLOGY, defintval:1, TYPE_INT, 0}, \
{"band" , CONFIG_HLP_BAND, PARAMFLAG_BOOL, iptr:&BAND, defintval:78, TYPE_INT, 0}, \
{"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&EMULATE_RF, defintval:0, TYPE_INT, 0}, \
{"parallel-config", CONFIG_HLP_PARALLEL_CMD, 0, strptr:&parallel_config, defstrval:NULL, TYPE_STRING, 0}, \
{"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:&worker_config, defstrval:NULL, TYPE_STRING, 0}, \
{"noS1", CONFIG_HLP_NOS1, PARAMFLAG_BOOL, uptr:&noS1, defintval:0, TYPE_UINT, 0}, \
{"rfsim", CONFIG_HLP_RFSIM, PARAMFLAG_BOOL, uptr:&rfsim, defintval:0, TYPE_UINT, 0}, \
{"nokrnmod", CONFIG_HLP_NOKRNMOD, PARAMFLAG_BOOL, uptr:&nokrnmod, defintval:0, TYPE_UINT, 0}, \
{"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, uptr:&nonbiot, defuintval:0, TYPE_UINT, 0}, \
{"chest-freq", CONFIG_HLP_CHESTFREQ, 0, iptr:&CHEST_FREQ, defintval:0, TYPE_INT, 0}, \
{"chest-time", CONFIG_HLP_CHESTTIME, 0, iptr:&CHEST_TIME, defintval:0, TYPE_INT, 0}, \
{"nsa", CONFIG_HLP_NSA, PARAMFLAG_BOOL, iptr:&NSA, defintval:0, TYPE_INT, 0}, \
{"node-number", NULL, 0, u16ptr:&NODE_NUMBER, defuintval:0, TYPE_UINT16, 0}, \
{"usrp-tx-thread-config", CONFIG_HLP_USRP_THREAD, 0, iptr:&usrp_tx_thread, defstrval:0, TYPE_INT, 0}, \
{"nfapi", CONFIG_HLP_NFAPI, 0, strptr:NULL, defstrval:"MONOLITHIC", TYPE_STRING, 0}, \
{"non-stop", CONFIG_HLP_NONSTOP, PARAMFLAG_BOOL, iptr:&NON_STOP, defintval:0, TYPE_INT, 0}, \
{"emulate-l1", CONFIG_L1_EMULATOR, PARAMFLAG_BOOL, iptr:&EMULATE_L1, defintval:0, TYPE_INT, 0}, \
{"continuous-tx", CONFIG_HLP_CONTINUOUS_TX,PARAMFLAG_BOOL, iptr:&CONTINUOUS_TX, defintval:0, TYPE_INT, 0}, \
{"disable-stats", CONFIG_HLP_STATS_DISABLE, PARAMFLAG_BOOL, iptr:&stats_disabled, defintval:0, TYPE_INT, 0}, \
{"virtual-time", CONFIG_HLP_VIRT_TIME, PARAMFLAG_BOOL, iptr:&VIRTUAL_TIME, defintval:0, TYPE_INT, 0}, \
}
// clang-format off
#define CMDLINE_PARAMS_CHECK_DESC { \
@@ -218,6 +222,7 @@ extern int usrp_tx_thread;
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
}
// clang-format on
@@ -324,6 +329,7 @@ typedef struct {
int non_stop;
int emulate_l1;
int continuous_tx;
int virtual_time;
} softmodem_params_t;
extern uint64_t get_softmodem_optmask(void);

View File

@@ -32,7 +32,6 @@
#include <arpa/inet.h>
#include "nfapi_nr_interface_scf.h"
#include "nfapi_vnf_interface.h"
#include "nfapi_vnf.h"
#include "nfapi.h"
#include "vendor_ext.h"
@@ -1633,6 +1632,8 @@ req->nfapi_config.tx_data_timing_offset.tl.tag = NFAPI_NR_NFAPI_TX_DATA_TIMING_O
int param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_param_response_t *resp) {
NFAPI_TRACE(NFAPI_TRACE_INFO, "[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);
if (get_softmodem_params()->virtual_time)
printf("[VNF] Virtual time enabled\n");
vnf_p7_info *p7_vnf = vnf->p7_vnfs;
pnf_info *pnf = vnf->pnfs;
phy_info *phy = pnf->phys;

View File

@@ -18,7 +18,7 @@
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "nfapi_vnf_interface.h"
void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port);
void configure_nr_nfapi_vnf(char *vnf_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port);

View File

@@ -3465,6 +3465,9 @@ typedef struct {
uint16_t sfn_sf;
} nfapi_subframe_indication_t;
/** VTUESF.indication sent from UE as an ACK in the virtual time scenario */
typedef nfapi_subframe_indication_t nfapi_ue_sf_indication_vt_t;
typedef struct {
nfapi_p7_message_header_t header;
uint16_t sfn_sf;

View File

@@ -3384,6 +3384,12 @@ static uint8_t pack_nr_uci_pucch_2_3_4(void* tlv, uint8_t **ppWritePackedMsg, ui
return 1;
}
static uint8_t pack_subframe_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
{
nfapi_subframe_indication_t *pNfapiMsg = (nfapi_subframe_indication_t *)msg;
return (push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end));
}
static uint8_t pack_nr_uci_indication_body(nfapi_nr_uci_t* value, uint8_t **ppWritePackedMsg, uint8_t *end)
{
if (!push16(value->pdu_type, ppWritePackedMsg, end))
@@ -3696,6 +3702,10 @@ int nfapi_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBu
result = pack_timing_info(pMessageHeader, &pWritePackedMessage, end, config);
break;
case NFAPI_SUBFRAME_INDICATION:
result = pack_subframe_indication(pMessageHeader, &pWritePackedMessage, end, config);
break;
default: {
if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
@@ -5335,6 +5345,16 @@ static uint8_t unpack_ul_config_request(uint8_t **ppReadPackedMsg, uint8_t *end,
unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
}
static uint8_t unpack_subframe_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config)
{
nfapi_subframe_indication_t *pNfapiMsg = (nfapi_subframe_indication_t *)msg;
if (!(pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end)))
return 0;
return 1;
}
static uint8_t unpack_hi_dci0_hi_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
nfapi_hi_dci0_hi_pdu_rel8_t *hi_pdu_rel8 = (nfapi_hi_dci0_hi_pdu_rel8_t *)tlv;
return( pull8(ppReadPackedMsg, &hi_pdu_rel8->resource_block_start, end) &&
@@ -7875,6 +7895,15 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
// look for the specific message
switch (pMessageHeader->message_id) {
case NFAPI_SUBFRAME_INDICATION:
if (check_unpack_length(NFAPI_SUBFRAME_INDICATION, unpackedBufLen)) {
nfapi_subframe_indication_t *msg = (nfapi_subframe_indication_t *)pMessageHeader;
result = unpack_subframe_indication(&pReadPackedMessage, end, msg, config);
} else
return -1;
break;
case NFAPI_DL_CONFIG_REQUEST:
if (check_unpack_length(NFAPI_DL_CONFIG_REQUEST, unpackedBufLen))
result = unpack_dl_config_request(&pReadPackedMessage, end, pMessageHeader, config);
@@ -8233,12 +8262,15 @@ int nfapi_nr_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *
{
if(config && config->unpack_p7_vendor_extension)
{
result = (config->unpack_p7_vendor_extension)(pMessageHeader, &pReadPackedMessage, end, config);
}
result = (config->unpack_p7_vendor_extension)(pMessageHeader, &pReadPackedMessage, end, config);
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve decoder provided\n", __FUNCTION__, pMessageHeader->message_id);
}
NFAPI_TRACE(NFAPI_TRACE_ERROR,
"%s VE NFAPI message ID %d. No ve decoder provided\n",
__FUNCTION__,
pMessageHeader->message_id);
}
}
else
{

View File

@@ -127,8 +127,8 @@ 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 send_mac_subframe_indications(vnf_p7_t* config, uint16_t sfn_sf);
int send_mac_slot_indications(vnf_p7_t* config, uint16_t sfn, uint16_t slot);
int vnf_p7_read_dispatch_message(vnf_p7_t* vnf_p7 );
int vnf_nr_p7_read_dispatch_message(vnf_p7_t* vnf_p7 );

View File

@@ -25,7 +25,9 @@
#include <errno.h>
#include <stdio.h>
#include <assert.h>
#include "softmodem-common.h"
#include "nfapi_vnf.h"
#include "vnf_p7.h"
#ifdef NDEBUG
@@ -417,47 +419,70 @@ uint16_t increment_sfn_sf_by(uint16_t sfn_sf, uint8_t increment)
return sfn_sf;
}
int send_mac_slot_indications(vnf_p7_t* vnf_p7)
void vnf_handle_subframe_indication(void* pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
{
if (pRecvMsg == NULL || vnf_p7 == NULL) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
return;
}
nfapi_subframe_indication_t ind;
if (nfapi_p7_message_unpack(pRecvMsg, recvMsgLen, &ind, sizeof(ind), &vnf_p7->_public.codec_config) < 0) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Failed to unpack message\n", __FUNCTION__);
return;
}
uint8_t* p = (uint8_t*)pRecvMsg;
uint16_t sfnsf = p[16] << 8 | p[17];
vnf_p7->sf_start_time_hr = vnf_get_current_time_hr();
if (vnf_p7->_public.subframe_indication) {
send_mac_subframe_indications(vnf_p7, sfnsf);
}
}
int send_mac_slot_indications(vnf_p7_t* vnf_p7, uint16_t sfn, uint16_t slot)
{
nfapi_vnf_p7_connection_info_t* curr = vnf_p7->p7_connections;
while(curr != 0)
{
if(curr->in_sync == 1)
{
// ask for subframes in the future
while (curr != 0) {
if (curr->in_sync == 1 && get_softmodem_params()->virtual_time) {
// ask for subframes in the future
//uint16_t sfn_sf_adv = increment_sfn_sf_by(curr->sfn_sf, 2);
//vnf_p7->_public.subframe_indication(&(vnf_p7->_public), curr->phy_id, sfn_sf_adv);
// suggestion fix by Haruki NAOI
//printf("\nsfn:%d, slot:%d\n",curr->sfn,curr->slot);
vnf_p7->_public.slot_indication(&(vnf_p7->_public), curr->phy_id, curr->sfn,curr->slot);
}
vnf_p7->_public.slot_indication(&(vnf_p7->_public), curr->phy_id, curr->sfn, curr->slot);
} else if (get_softmodem_params()->virtual_time) {
vnf_p7->_public.slot_indication(&(vnf_p7->_public), curr->phy_id, sfn, slot);
}
curr = curr->next;
}
curr = curr->next;
}
return 0;
return 0;
}
int send_mac_subframe_indications(vnf_p7_t* vnf_p7)
int send_mac_subframe_indications(vnf_p7_t* vnf_p7, uint16_t sfn_sf)
{
nfapi_vnf_p7_connection_info_t* curr = vnf_p7->p7_connections;
while(curr != 0)
{
if(curr->in_sync == 1)
{
// ask for subframes in the future
while (curr != 0) {
if (curr->in_sync == 1 && !get_softmodem_params()->virtual_time) {
// ask for subframes in the future
//uint16_t sfn_sf_adv = increment_sfn_sf_by(curr->sfn_sf, 2);
//vnf_p7->_public.subframe_indication(&(vnf_p7->_public), curr->phy_id, sfn_sf_adv);
// suggestion fix by Haruki NAOI
vnf_p7->_public.subframe_indication(&(vnf_p7->_public), curr->phy_id, curr->sfn_sf);
}
vnf_p7->_public.subframe_indication(&(vnf_p7->_public), curr->phy_id, curr->sfn_sf);
} else if (get_softmodem_params()->virtual_time) {
vnf_p7->_public.subframe_indication(&(vnf_p7->_public), curr->phy_id, sfn_sf);
}
curr = curr->next;
}
curr = curr->next;
}
return 0;
return 0;
}
int vnf_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info, uint8_t* msg, const uint32_t len)
@@ -2146,7 +2171,11 @@ void vnf_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
vnf_handle_ue_release_resp(pRecvMsg, recvMsgLen, vnf_p7);
break;
default:
case NFAPI_SUBFRAME_INDICATION:
vnf_handle_subframe_indication(pRecvMsg, recvMsgLen, vnf_p7);
break;
default:
{
if(header.message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
header.message_id <= NFAPI_VENDOR_EXT_MSG_MAX)

View File

@@ -30,6 +30,8 @@
#include "common/ran_context.h"
#include "openair1/PHY/defs_gNB.h"
#include "executables/softmodem-common.h"
#define FAPI2_IP_DSCP 0
extern RAN_CONTEXT_t RC;
@@ -246,318 +248,285 @@ int nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t* config)
int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config)
{
if(config == 0)
return -1;
if (config == 0)
return -1;
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s()\n", __FUNCTION__);
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s()\n", __FUNCTION__);
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
// Create p7 receive udp port
// todo : this needs updating for Ipv6
// Create p7 receive udp port
// todo : this needs updating for Ipv6
NFAPI_TRACE(NFAPI_TRACE_INFO, "Initialising VNF P7 port:%u\n", config->port);
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;
}
// 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");
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;
}
// 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");
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;
// 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;
}
// 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");
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 = 1000000; // ns in a 1 us
//struct timespec original_pselect_timeout;
struct timespec pselect_timeout;
pselect_timeout.tv_sec = 0;
pselect_timeout.tv_nsec = 1000000; // ns in a 1 us
struct timespec pselect_start;
struct timespec pselect_stop;
// struct timespec sf_end;
struct timespec pselect_start;
struct timespec pselect_stop;
long last_millisecond = -1;
//struct timespec sf_end;
struct timespec sf_duration;
sf_duration.tv_sec = 0;
sf_duration.tv_nsec = 1e6; // We want 1ms pause
long last_millisecond = -1;
struct timespec sf_start;
clock_gettime(CLOCK_MONOTONIC, &sf_start);
long millisecond = sf_start.tv_nsec / 1e6;
sf_start = timespec_add(sf_start, sf_duration);
NFAPI_TRACE(NFAPI_TRACE_INFO, "next subframe will start at %ld.%ld\n", sf_start.tv_sec, sf_start.tv_nsec);
uint8_t vt = get_softmodem_params()->virtual_time;
struct timespec sf_duration;
sf_duration.tv_sec = 0;
sf_duration.tv_nsec = 1e6; // We want 1ms pause
while (vnf_p7->terminate == 0) {
fd_set rfds;
int maxSock = 0;
FD_ZERO(&rfds);
int selectRetval = 0;
struct timespec sf_start;
clock_gettime(CLOCK_MONOTONIC, &sf_start);
long millisecond = sf_start.tv_nsec / 1e6;
sf_start = timespec_add(sf_start, sf_duration);
NFAPI_TRACE(NFAPI_TRACE_INFO, "next subframe will start at %ld.%ld\n", sf_start.tv_sec, sf_start.tv_nsec);
// Add the p7 socket
FD_SET(vnf_p7->socket, &rfds);
maxSock = vnf_p7->socket;
while(vnf_p7->terminate == 0)
{
fd_set rfds;
int maxSock = 0;
FD_ZERO(&rfds);
int selectRetval = 0;
clock_gettime(CLOCK_MONOTONIC, &pselect_start);
// long millisecond = pselect_start.tv_nsec / 1e6;
// Add the p7 socket
FD_SET(vnf_p7->socket, &rfds);
maxSock = vnf_p7->socket;
if (!vt) {
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);
clock_gettime(CLOCK_MONOTONIC, &pselect_start);
//long millisecond = pselect_start.tv_nsec / 1e6;
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))) {
// overran the end of the subframe we do not want to wait
pselect_timeout.tv_sec = 0;
pselect_timeout.tv_nsec = 0;
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);
// 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);
}
selectRetval = pselect(maxSock + 1, &rfds, NULL, NULL, &pselect_timeout, NULL);
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)))
{
// overran the end of the subframe we do not want to wait
pselect_timeout.tv_sec = 0;
pselect_timeout.tv_nsec = 0;
clock_gettime(CLOCK_MONOTONIC, &pselect_stop);
//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);
nfapi_vnf_p7_connection_info_t* phy = vnf_p7->p7_connections;
}
if (selectRetval == -1 && errno == 22) {
NFAPI_TRACE(NFAPI_TRACE_ERROR,
"INVAL: pselect_timeout:%ld.%ld adj[dur:%d adj:%d], sf_dur:%ld.%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);
}
if (selectRetval == 0) {
// calculate the start of the next subframe
sf_start = timespec_add(sf_start, sf_duration);
// NFAPI_TRACE(NFAPI_TRACE_INFO, "next subframe will start at %d.%d\n", sf_start.tv_sec, sf_start.tv_nsec);
//original_pselect_timeout = pselect_timeout;
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);
// 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);
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:%ld.%ld adj[dur:%d adj:%d], sf_dur:%ld.%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);
}
if(selectRetval == 0)
{
// calculate the start of the next subframe
sf_start = timespec_add(sf_start, sf_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;
sf_start.tv_nsec -= insync_minor_adjustment_ns;
#if 1
if (sf_start.tv_nsec > 1e9)
{
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 (sf_start.tv_nsec > 1e9) {
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;
}
#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;
// 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;
}
}
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--;
// 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:%ld duration:%u\n",
phy->insync_minor_adjustment, sf_start.tv_nsec, phy->insync_minor_adjustment_duration);
NFAPI_TRACE(NFAPI_TRACE_NOTE,
"[VNF] AFTER adjustment - Subframe minor adjustment %dus sf_start.tv_nsec:%ld duration:%u\n",
phy->insync_minor_adjustment,
sf_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;
*/
if (phy->insync_minor_adjustment_duration == 0) {
phy->insync_minor_adjustment = 0;
}
}
millisecond++;
}
} else {
if ((millisecond - last_millisecond) > 3)
NFAPI_TRACE(NFAPI_TRACE_WARN,
"subframe overrun %ld %ld (%ld)\n",
millisecond,
last_millisecond,
millisecond - last_millisecond + 1);
millisecond ++;
}
}
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;
}
last_millisecond = ( last_millisecond + 1 ) % 1000;
selectRetval = 0;
}
if (selectRetval == 0) {
vnf_p7->sf_start_time_hr = vnf_get_current_time_hr();
if(selectRetval == 0)
{
vnf_p7->sf_start_time_hr = vnf_get_current_time_hr();
// pselect timed out
nfapi_vnf_p7_connection_info_t* curr = vnf_p7->p7_connections;
// pselect timed out
nfapi_vnf_p7_connection_info_t* curr = vnf_p7->p7_connections;
while (curr != 0) {
curr->sfn_sf = increment_sfn_sf(curr->sfn_sf);
vnf_sync(vnf_p7, curr);
curr = curr->next;
}
while(curr != 0)
{
curr->sfn_sf = increment_sfn_sf(curr->sfn_sf);
vnf_sync(vnf_p7, curr);
curr = curr->next;
}
/** NOTE: The second argument (sfn_sf) has no significance */
send_mac_subframe_indications(vnf_p7, 0);
send_mac_subframe_indications(vnf_p7);
} else if (selectRetval > 0) {
// have a p7 message
if (FD_ISSET(vnf_p7->socket, &rfds)) {
vnf_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:%ld.%ld orginal:%ld.%ld 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 == EINVAL) // invalid argument??? not sure about timeout duration
{
usleep(100000);
}
}
}
}
else if(selectRetval > 0)
{
// have a p7 message
if(FD_ISSET(vnf_p7->socket, &rfds))
{
vnf_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:%ld.%ld orginal:%ld.%ld 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);
}
}
}
} else {
/* System running in System Simulator mode with Virtual time
* no need of synching the SFN and over-run of SFN time for
* the processing the P7 handling is kept simple
*/
selectRetval = pselect(maxSock + 1, &rfds, NULL, NULL, &pselect_timeout, NULL);
if (selectRetval == -1 && errno == EINVAL) {
NFAPI_TRACE(NFAPI_TRACE_ERROR,
"INVAL: pselect_timeout:%ld.%ld sf_dur:%ld.%ld\n",
pselect_timeout.tv_sec,
pselect_timeout.tv_nsec,
sf_duration.tv_sec,
sf_duration.tv_nsec);
} else if (selectRetval > 0) {
NFAPI_TRACE(NFAPI_TRACE_INFO, "\n\nGot a message\n\n");
// have a p7 message
if (FD_ISSET(vnf_p7->socket, &rfds)) {
vnf_p7_read_dispatch_message(vnf_p7);
}
} else if (selectRetval == 0) {
NFAPI_TRACE(NFAPI_TRACE_INFO,
"No message received pselect_timeout:%ld.%ld sf_dur:%ld.%ld\n",
pselect_timeout.tv_sec,
pselect_timeout.tv_nsec,
sf_duration.tv_sec,
sf_duration.tv_nsec);
}
sf_start = timespec_add(sf_start, sf_duration);
pselect_timeout = timespec_sub(sf_start, pselect_start);
}
if (pselect_timeout.tv_sec < 0 || pselect_timeout.tv_nsec < 0) {
pselect_timeout.tv_sec = sf_duration.tv_sec;
pselect_timeout.tv_nsec = sf_duration.tv_nsec;
}
}
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "Closing p7 socket\n");
close(vnf_p7->socket);
NFAPI_TRACE(NFAPI_TRACE_INFO, "Closing p7 socket\n");
close(vnf_p7->socket);
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() returning\n", __FUNCTION__);
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() returning\n", __FUNCTION__);
return 0;
return 0;
}

View File

@@ -845,6 +845,8 @@ typedef struct {
openair0_device rfdevice;
void *scopeData;
/// Flag to tell if UE is in Virtual time mode
uint8_t virtual_time;
} PHY_VARS_UE;
/* this structure is used to pass both UE phy vars and

View File

@@ -102,6 +102,7 @@ typedef struct ru_config_s {
extern void RCconfig_L1(void);
extern void RCconfig_macrlc(void);
extern void RCconfig_ssparam(void);
extern void UE_config_stub_pnf(void);
extern int RCconfig_gtpu(void );
extern void RCConfig(void);

View File

@@ -240,7 +240,7 @@ typedef enum {
#define ENB_ASN1_VERBOSITY_IDX 0
#define ENB_ACTIVE_ENBS_IDX 1
#define ENB_NOS1_IDX 2
#define ENB_VT_IDX 3
/*------------------------------------------------------------------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------------------------------------------------------------------*/

View File

@@ -83,9 +83,12 @@ typedef enum {
/* global parameters, not under a specific section */
#define GNB_CONFIG_STRING_ASN1_VERBOSITY "Asn1_verbosity"
#define GNB_CONFIG_STRING_ACTIVE_GNBS "Active_gNBs"
/** global parameter for virtual time */
#define GNB_CONFIG_STRING_VIRTUAL_TIME "virtual_time"
/*--------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* global configuration parameters */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/* global configuration parameters */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*--------------------------------------------------------------------------------------------------------------------------------------------------------------*/
#define GNBSPARAMS_DESC { \
{GNB_CONFIG_STRING_ASN1_VERBOSITY, NULL, 0, .uptr=NULL, .defstrval=GNB_CONFIG_STRING_ASN1_VERBOSITY_NONE, TYPE_STRING, 0}, \

View File

@@ -218,6 +218,7 @@ void send_nsa_standalone_msg(NR_UL_IND_t *UL_INFO, uint16_t msg_id)
}
case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION:
break;
default:
break;
}
@@ -676,6 +677,7 @@ static void fill_dci_from_dl_config(nr_downlink_indication_t*dl_ind, fapi_nr_dl_
}
}
void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request,
nfapi_nr_tx_data_request_t *tx_data_request,
nfapi_nr_ul_dci_request_t *ul_dci_request,

View File

@@ -85,6 +85,9 @@ typedef struct {
/// RX indication
nfapi_rx_indication_t rx_ind;
/// UE Subframe indication for VT
nfapi_ue_sf_indication_vt_t vt_ue_sf_ind;
} UL_IND_t;
// Downlink subframe P7
@@ -160,6 +163,8 @@ typedef struct {
pthread_mutex_t harq_mutex;
pthread_mutex_t cqi_mutex;
pthread_mutex_t rach_mutex;
pthread_mutex_t vt_ue_sf_mutex;
pthread_mutex_t vt_ue_slot_mutex;
} FILL_UL_INFO_MUTEX_t;
/*Initial */

View File

@@ -1451,7 +1451,11 @@ void *ue_standalone_pnf_task(void *context)
break;
}
default:
LOG_E(MAC, "Case Statement has no corresponding nfapi message\n");
if (header.message_id >= NFAPI_VENDOR_EXT_MSG_MIN && header.message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
LOG_I(MAC, "Unsupported vendor extension received\n");
} else {
LOG_E(MAC, "Case Statement has no corresponding nfapi message\n");
}
break;
}
}
@@ -1684,6 +1688,11 @@ static void print_rx_ind(nfapi_rx_indication_t *p)
encoded_size = nfapi_p7_message_pack(&UL->sr_ind, buffer, sizeof(buffer), NULL);
LOG_I(MAC, "SR_IND sent to Proxy, Size: %d\n", encoded_size);
break;
case NFAPI_SUBFRAME_INDICATION:
encoded_size = nfapi_p7_message_pack(&UL->vt_ue_sf_ind, buffer, sizeof(buffer), NULL);
LOG_D(MAC, "UE_SF_IND sent to Proxy, Size: %d\n", encoded_size);
break;
default:
LOG_I(MAC, "%s Unknown Message msg_type :: %u\n", __func__, msg_type);
return;
@@ -1834,6 +1843,18 @@ char *nfapi_ul_config_req_to_string(nfapi_ul_config_request_t *req)
return result;
}
void fill_ue_sf_indication_UE_MAC(int Mod_id, int frame, int subframe, uint16_t ack_sfn_sf, UL_IND_t *UL_INFO)
{
pthread_mutex_lock(&fill_ul_mutex.vt_ue_sf_mutex);
nfapi_ue_sf_indication_vt_t *ue_sf_ind = &UL_INFO->vt_ue_sf_ind;
ue_sf_ind->sfn_sf = frame << 4 | subframe;
ue_sf_ind->header.message_id = NFAPI_SUBFRAME_INDICATION;
pthread_mutex_unlock(&fill_ul_mutex.vt_ue_sf_mutex);
}
/* Dummy functions*/
void handle_nfapi_hi_dci0_dci_pdu(

View File

@@ -171,6 +171,9 @@ void hi_dci0_req_UE_MAC(int sfn,
nfapi_hi_dci0_request_pdu_t* bch,
int num_ue);
// To send UE_SF.indication in virtual time.
void fill_ue_sf_indication_UE_MAC(int Mod_id, int frame, int subframe, uint16_t ack_sfn_sf, UL_IND_t *UL_INFO);
// The following set of memcpy functions should be getting called as callback functions from
// pnf_p7_subframe_ind.