Commit 05dd7b2f authored by Raphael Defosseux's avatar Raphael Defosseux

Merge remote-tracking branch 'origin/nfapi_nr_arch_mod' into integration_2021_w33

parents 25b449e3 2bc9e50d
# global
xnf is pnf or vnf
The xnf starting functions are configure_nfapi_xnf()
The OAI code that read the configuration parameters call these functions that will create autonomous thread for xnf control part
These control threads create a SCTP socket by Linux API call (no use of OpenAir internal architecture with SCTP itti thread).
The main() function of softmodem has to create and start the other threads+loop on event for appropriate work: RF Rx in pnf, NGAP, GTP-U, X2, RLC, PDCP for vnf
NFAPI has it's own code directly on Linux+Posix, it doesn't reuse any piece of the OpenAir framework: SCTP thread, thread creation and management, ...
## signaling (P5) xnf main loop
nfapi_vnf_start() create the SCTP socket, then do event waiting in a infinite loop while(vnf->terminate == 0). It accepts the pnf connections, then process the messages on reception
nfapi_pnf_start() initiate connection to vnf until it has a link. Then it enter a similar infinite loop in pnf_message_pump()
After some checks, when a message is obtained, it calls pnf_handle_p5_message() or vnf_handle_p4_p5_message() that have a switch on each p5 message types: the enum nfapi_message_id_e
Each message type has it's own processing function in the switch, like
```
case NFAPI_START_RESPONSE:
vnf_handle_start_response(pRecvMsg, recvMsgLen, config, p5_idx);
break;
```
These loops are autonomous in their thread waiting incoming message.
## P7 xnf main loop
When the p5 interface receives appropriate message, it starts the p7 interface by launching a thread (see the calls to pthread_create() in nfapi/oai_integration/nfapi_xnf.c)
The p7 main loops starting is a bit simpler, thanks to UDP non connected protocol. The xnf_dispatch_p7_message() do p7 fragments re-assembly, then
calls xnf_dispatch_p7_message() that have the big switch on message type (as in p5 above description)
So, we have the logic for UL reception in vnf, and DL reception in pnf
## P7 UL transmission by PNF
RF samples are received, and decoding is done by the PNF using control data transmitted by the VNF to the PNF through downlink p7 messages (UL_TTI_req and UL_DCI_req).
After decoding, results are accumulated into the xNB->UL_INFO structure at the PNF.
The data in the UL_INFO struct is transmitted through a socket in the form of 'uplink indication functions' from the PNF to the VNF. Each uplink indication message is transmitted from their respective handle functions in NR_UL_indication(). For example,
```
void handle_nr_rach(NR_UL_IND_t *UL_info) {
if(NFAPI_MODE == NFAPI_MODE_PNF) {
if (UL_info->rach_ind.number_of_pdus>0) {
oai_nfapi_nr_rach_indication(&UL_info->rach_ind); //This function calls the routines required for packing + transmission through socket
UL_info->rach_ind.number_of_pdus = 0;
}
}
```
## P7 UL reception at VNF
Through the infinite loop [while(vnf_p7->terminate == 0)] running in nfapi_nr_vnf_p7_start(), the VNF receives and unpacks the uplink indication message received on its socket. Based on the unpacked messages, UL_INFO struct on the VNF side gets populated.
```
// have a p7 message
if(FD_ISSET(vnf_p7->socket, &rfds))
{
vnf_nr_p7_read_dispatch_message(vnf_p7);
}
```
vnf_nr_dispatch_p7_message() is the function that contains the switch on various message headers so that the appropriate unpack function is called.
## P7 DL Transmission by VNF
DL messages are scheduled at the VNF, through NR_UL_indication(). NR_UL_indication() is called when the SFN/slot in the UL_info structure changes (this acts as a trigger for next slot processing, instead of running a separate clock at the VNF). The SFN/slot at the VNF in UL_info is updated using the slot_indication uplink p7 message, which is sent at the beginning of every slot by the PNF. The slot_indication message contains SFN/slot of the TX_thread, so that the scheduler operates slot_ahead slots ahead of the RX thread. This ensures that UL_tti_req is received before RX slot processing at the PNF.
The function NR_schedule_response calls oai_nfapi_[DL P7 msg]_req(), which contains the routines for packing + transmission of scheduled messages through the socket to the PNF. For example, to send the 'TX_data_req' p7 message
```
if (Sched_INFO->TX_req->Number_of_PDUs > 0)
{
oai_nfapi_tx_data_req(Sched_INFO->TX_req);
}
```
```mermaid
graph TD
pselect[VNF socket pselect] -- timed out : end of slot --> call_sched[Call Scheduler NR_UL_indication] -- oai_nfapi_***_req sends the DL p7 msg--> slot_inc[Increment sfn/slot];
pselect[VNF socket pselect] -- UL p7 xyz msg recvd --> msg_recvd[Read message vnf_nr_p7_read_dispatch_message] --> header_unpack[Unpack Header] -- switch cases on header --> unpack_msg[Handle Message vnf_handle_nr_xyz] --> fill_ul_info[Fill UL info struct with fn pointer vnf_p7->_public.nr_rx_xyz];
fill_ul_info -- update pselect_timeout: next_slot_start - time_xyz_msg_recvd-->pselect;
slot_inc -- next slot --> pselect
```
Note that since DL P7 message reception and TX/RX processing are done on separate threads, there is the issue of the L1 processing threads trying to do their job before the required P7 message is received. In the case of RX processing, since the scheduler operates slot_ahead slots ahead of the RX thread, the required messages conveniently arrive earlier than they are required. However, in the case of TX processing, this cannot be ensured if the scheduler is exactly in sync with the TX thread.
Therefore, we operate the VNF vnf_slot_ahead (which is currently 2) slots ahead of the PNF. This is to ensure that the DL fapi structures for a particular TX slot are all received before TX processing for that slot.
## P7 DL Reception at PNF
Through the infinite loop [while(pnf_p7->terminate == 0)] running in pnf_nr_p7_message_pump(), the PNF receives and unpacks the downlink P7 message received on its socket. Based on the unpacked message, the appropriate message structures are filled in the PNF, and these are used further down the pipeline for processing.
While receiving the DL P7 message, we check whether the message was received within a timing window from which it was sent. The duration of the window can be set by the user (set as a parameter for xnf in the p5 messages). Note that the DL information must be received by the PNF within a timing window at least lesser than the duration of slot_ahead variable (timing_window <= slot_ahead * slot_duration).
```mermaid
graph TB
pselect[PNF socket pselect] -- timed out : end of slot --> slot_inc[Increment sfn/slot];
pselect[PNF socket pselect] -- DL p7 xyz msg recvd --> msg_recvd[Read message pnf_nr_nfapi_p7_read_dispatch_message] --> header_unpack[Unpack Header] -- switch cases on header --> unpack_msg[Unpack Message pnf_handle_nr_xyz] --> fill_pnf_p7[Fill pnf_p7 global structure pnf_handle_nr_xyz] --Data from pnf_p7 struct copied to fapi structures using pnf_phy_***_req. Called every slot from handle_nr_slot_ind-->pselect;
slot_inc -- next slot --> pselect
```
Once the messages are received, they are filled into slot buffers, and are stored until the processing of the slot that they were meant for.
# Procedure to run nFAPI in 5G NR
## Conributed by 5G Testbed IISC
### Developers: Sudhakar B,Mahesh K,Gokul S,Aniq U.R
## Contributed by 5G Testbed IISc
### Developers: Gokul S, Mahesh A, 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
sudo ./build_oai --gNB --nrUE
```
## Procedure to run NR nFAPI using RF-Simulator
### Bring up another loopback interface
If running for the first time on your computer, or you have restarted your computer, bring up another loopback interface with this command:
sudo ifconfig lo: 127.0.0.2 netmask 255.0.0.0 up
### VNF command
```
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf --nfapi 2 --noS1 --phy-test
......@@ -27,9 +34,21 @@ sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfap
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
## Procedure to run NR nFAPI using Hardware (tested with USRP x310)
### 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 --phy-test
```
### UE command
```
sudo ./nr-uesoftmodem --usrp-args "addr=*USRP_ADDRESS*,clock_source=external,time_source=external" --phy-test --rrc_config_path ../../../ci-scripts/rrc-files
```
## 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
......@@ -146,15 +146,12 @@ void rx_func(void *param) {
start_meas(&softmodem_stats_rxtx_sf);
// *******************************************************************
// NFAPI not yet supported for NR - this code has to be revised
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);
//LOG_D(PHY, "oai_nfapi_slot_ind(frame:%u, slot:%d) ********\n", frame_rx, slot_rx);
start_meas(&nfapi_meas);
// oai_subframe_ind(frame_rx, slot_rx);
oai_slot_ind(frame_rx, slot_rx);
handle_nr_slot_ind(frame_rx, slot_rx);
stop_meas(&nfapi_meas);
/*if (gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus||
......@@ -451,6 +448,8 @@ void init_eNB_afterRU(void) {
PHY_VARS_gNB *gNB;
LOG_I(PHY,"%s() RC.nb_nr_inst:%d\n", __FUNCTION__, RC.nb_nr_inst);
if(NFAPI_MODE == NFAPI_MODE_PNF)
RC.nb_nr_inst = 1;
for (inst=0; inst<RC.nb_nr_inst; inst++) {
LOG_I(PHY,"RC.nb_nr_CC[inst:%d]:%p\n", inst, RC.gNB[inst]);
gNB = RC.gNB[inst];
......
......@@ -37,8 +37,6 @@
#include "nfapi_pnf.h"
#include "common/ran_context.h"
#include "openair2/PHY_INTERFACE/phy_stub_UE.h"
//#include "openair1/PHY/vars.h"
extern RAN_CONTEXT_t RC;
#include <sys/socket.h>
#include <sys/time.h>
......@@ -50,7 +48,7 @@ extern RAN_CONTEXT_t RC;
#include <vendor_ext.h>
#include "fapi_stub.h"
//#include "fapi_l1.h"
#include "common/utils/LOG/log.h"
#include "PHY/INIT/phy_init.h"
......@@ -62,7 +60,7 @@ extern RAN_CONTEXT_t RC;
#include <openair1/SCHED/fapi_l1.h>
#include <openair1/PHY/NR_TRANSPORT/nr_transport_proto.h>
#include <targets/RT/USER/lte-softmodem.h>
#include "nfapi/open-nFAPI/pnf/inc/pnf_p7.h"
#define NUM_P5_PHY 2
......@@ -70,6 +68,7 @@ extern RAN_CONTEXT_t RC;
extern void phy_init_RU(RU_t *);
extern int config_sync_var;
extern RAN_CONTEXT_t RC;
extern pthread_cond_t nfapi_sync_cond;
extern pthread_mutex_t nfapi_sync_mutex;
......@@ -1110,18 +1109,14 @@ int pnf_phy_ul_dci_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7,
// LOG_D(PHY,"[PNF] HI_DCI0_REQUEST SFN/SF:%05d dci:%d hi:%d\n", NFAPI_SFNSF2DEC(req->sfn_sf), req->hi_dci0_request_body.number_of_dci, req->hi_dci0_request_body.number_of_hi);
//phy_info* phy = (phy_info*)(pnf_p7->user_data);
struct PHY_VARS_gNB_s *gNB = RC.gNB[0];
if (proc ==NULL)
proc = &gNB->proc.L1_proc;
for (int i=0; i<req->numPdus; i++) {
//LOG_D(PHY,"[PNF] HI_DCI0_REQ sfn_sf:%d PDU[%d]\n", NFAPI_SFNSF2DEC(req->sfn_sf), i);
if (req->ul_dci_pdu_list[i].PDUType == 0) {
//LOG_D(PHY,"[PNF] HI_DCI0_REQ sfn_sf:%d PDU[%d] - NFAPI_HI_DCI0_DCI_PDU_TYPE\n", NFAPI_SFNSF2DEC(req->sfn_sf), i);
nfapi_nr_ul_dci_request_pdus_t *ul_dci_req_pdu = &req->ul_dci_pdu_list[i];
int SFN=req->SFN+2;
handle_nfapi_nr_ul_dci_pdu(gNB, SFN, req->Slot, ul_dci_req_pdu);
nfapi_nr_ul_dci_request_pdus_t *ul_dci_req_pdu = &req->ul_dci_pdu_list[i];
handle_nfapi_nr_ul_dci_pdu(gNB, req->SFN, req->Slot, ul_dci_req_pdu);
}
else {
LOG_E(PHY,"[PNF] UL_DCI_REQ sfn_slot:%d PDU[%d] - unknown pdu type:%d\n", NFAPI_SFNSLOT2DEC(req->SFN, req->Slot), i, req->ul_dci_pdu_list[i].PDUType);
......@@ -1181,45 +1176,37 @@ int pnf_phy_dl_tti_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7,
int sfn = req->SFN;
int slot = req->Slot;
struct PHY_VARS_gNB_s *gNB = RC.gNB[0];
if (proc==NULL)
proc = &gNB->proc.L1_proc;
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu_list = req->dl_tti_request_body.dl_tti_pdu_list;
if (req->dl_tti_request_body.nPDUs)
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() TX:%d/%d RX:%d/%d; sfn:%d, slot:%d, nGroup:%u, nPDUs: %u, nUE: %u, PduIdx: %u,\n",
__FUNCTION__, proc->frame_tx, proc->slot_tx, proc->frame_rx, proc->slot_rx, // TODO: change subframes to slot
req->SFN,
req->Slot,
req->dl_tti_request_body.nGroup,
req->dl_tti_request_body.nPDUs,
req->dl_tti_request_body.nUe,
req->dl_tti_request_body.PduIdx);
//if (req->dl_tti_request_body.nPDUs)
// NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() TX:%d/%d RX:%d/%d; sfn:%d, slot:%d, nGroup:%u, nPDUs: %u, nUE: %u, PduIdx: %u,\n",
// __FUNCTION__, proc->frame_tx, proc->slot_tx, proc->frame_rx, proc->slot_rx, // TODO: change subframes to slot
// req->SFN,
// req->Slot,
// req->dl_tti_request_body.nGroup,
// req->dl_tti_request_body.nPDUs,
// req->dl_tti_request_body.nUe,
// req->dl_tti_request_body.PduIdx);
for (int i=0; i<req->dl_tti_request_body.nPDUs; i++) {
// TODO: enable after adding gNB PDCCH:
// NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() sfn/sf:%d PDU[%d] size:%d pdcch_vars->num_dci:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), i, dl_config_pdu_list[i].pdu_size,pdcch_vars->num_dci);
if (dl_tti_pdu_list[i].PDUType == NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE) {
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu=&dl_tti_pdu_list[i];
memcpy(dl_tti_pdu,&dl_tti_pdu_list[i],sizeof(nfapi_nr_dl_tti_request_pdu_t));
int SFN=sfn+2;
handle_nfapi_nr_pdcch_pdu(gNB, SFN, slot, &dl_tti_pdu->pdcch_pdu);
//dl_tti_pdu_list[i].pdcch_pdu.pdcch_pdu_rel15.numDlDci++; // ?
// NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() pdcch_vars->num_dci:%d\n", __FUNCTION__, pdcch_vars->num_dci);
} else if (dl_tti_pdu_list[i].PDUType == NFAPI_NR_DL_TTI_SSB_PDU_TYPE) {
//NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() PDU:%d BCH: pdu_index:%u pdu_length:%d sdu_length:%d BCH_SDU:%x,%x,%x\n", __FUNCTION__, i, pdu_index, bch_pdu->bch_pdu_rel8.length, tx_request_pdu[sfn][sf][pdu_index]->segments[0].segment_length, sdu[0], sdu[1], sdu[2]);
handle_nr_nfapi_ssb_pdu(gNB, sfn, slot, &dl_tti_pdu_list[i]);
gNB->pbch_configured=1;
//} else {
// NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() BCH NULL TX PDU SFN/SF:%d PDU_INDEX:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), pdu_index);
//}
} else if (dl_tti_pdu_list[i].PDUType == NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE) {
handle_nfapi_nr_pdcch_pdu(gNB, sfn, slot, &dl_tti_pdu->pdcch_pdu);
}
else if (dl_tti_pdu_list[i].PDUType == NFAPI_NR_DL_TTI_SSB_PDU_TYPE) {
//NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() PDU:%d BCH: pdu_index:%u pdu_length:%d sdu_length:%d BCH_SDU:%x,%x,%x\n", __FUNCTION__, i, pdu_index, bch_pdu->bch_pdu_rel8.length, tx_request_pdu[sfn][sf][pdu_index]->segments[0].segment_length, sdu[0], sdu[1], sdu[2]);
handle_nr_nfapi_ssb_pdu(gNB, sfn, slot, &dl_tti_pdu_list[i]);
gNB->pbch_configured=1;
}
else if (dl_tti_pdu_list[i].PDUType == NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE) {
nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu = &dl_tti_pdu_list[i].pdsch_pdu;
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15_pdu = &pdsch_pdu->pdsch_pdu_rel15;
//nfapi_nr_tx_data_request_t *tx_data = tx_data_request[sfn][slot][rel15_pdu->pduIndex];
nfapi_nr_pdu_t *tx_data = tx_data_request[sfn][slot][0];
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15_pdu = &pdsch_pdu->pdsch_pdu_rel15;
nfapi_nr_pdu_t *tx_data = tx_data_request[sfn][slot][rel15_pdu->pduIndex];
if (tx_data != NULL) {
int UE_id = find_nr_dlsch(rel15_pdu->rnti,gNB,SEARCH_EXIST_OR_FREE);
......@@ -1232,14 +1219,21 @@ int pnf_phy_dl_tti_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7,
LOG_E(PHY,"pnf_phy_dl_config_req illegal harq_pid %d\n", harq_pid);
return(-1);
}
//uint8_t *dlsch_sdu = (uint8_t *)tx_data->TLVs[0].value.direct;
uint8_t *dlsch_sdu = nr_tx_pdus[UE_id][harq_pid];
memcpy(dlsch_sdu, tx_data->TLVs[0].value.direct,tx_data->PDU_length);//TODO: Check if required
memcpy(dlsch_sdu, tx_data->TLVs[0].value.direct,tx_data->PDU_length);
//NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() DLSCH:pdu_index:%d handle_nfapi_dlsch_pdu(eNB, proc_rxtx, dlsch_pdu, transport_blocks:%d sdu:%p) eNB->pdcch_vars[proc->subframe_tx & 1].num_pdcch_symbols:%d\n", __FUNCTION__, rel8_pdu->pdu_index, rel8_pdu->transport_blocks, dlsch_sdu, eNB->pdcch_vars[proc->subframe_tx & 1].num_pdcch_symbols);
handle_nr_nfapi_pdsch_pdu(gNB, sfn, slot,pdsch_pdu, dlsch_sdu);
} else {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() DLSCH NULL TX PDU SFN/SF:%d PDU_INDEX:%d\n", __FUNCTION__, NFAPI_SFNSLOT2DEC(sfn,slot), rel15_pdu->pduIndex); }
} else {
}
else {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() DLSCH NULL TX PDU SFN/SF:%d PDU_INDEX:%d\n", __FUNCTION__, NFAPI_SFNSLOT2DEC(sfn,slot), rel15_pdu->pduIndex);
}
}
else if (dl_tti_pdu_list[i].PDUType == NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE) {
nfapi_nr_dl_tti_csi_rs_pdu *csi_rs_pdu = &dl_tti_pdu_list[i].csi_rs_pdu;
handle_nfapi_nr_csirs_pdu(gNB, sfn, slot, csi_rs_pdu);
}
else {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() UNKNOWN:%d\n", __FUNCTION__, dl_tti_pdu_list[i].PDUType);
}
}
......@@ -1399,13 +1393,10 @@ int pnf_phy_tx_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_tx_request_t *req) {
int pnf_phy_ul_tti_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_nr_ul_tti_request_t *req) {
// if (0)LOG_D(PHY,"[PNF] UL_CONFIG_REQ %s() sfn_sf:%d pdu:%d rach_prach_frequency_resources:%d srs_present:%u\n",
// __FUNCTION__,
// NFAPI_SFNSF2DEC(req->sfn_sf),
// req->ul_config_request_body.number_of_pdus,
// req->ul_config_request_body.rach_prach_frequency_resources,
// req->ul_config_request_body.srs_present
// );
LOG_D(PHY,"[PNF] UL_TTI_REQ recvd, writing into structs, SFN/slot:%d.%d pdu:%d \n",
req->SFN,req->Slot,
req->n_pdus
);
if (RC.ru == 0) {
return -1;
......@@ -2162,7 +2153,7 @@ void configure_nr_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_add
pnf.phys[0].udp.tx_port = vnf_p7_port;
strcpy(pnf.phys[0].udp.tx_addr, vnf_ip_addr);
strcpy(pnf.phys[0].local_addr, pnf_ip_addr);
printf("%s() VNF:%s:%d PNF_PHY[addr:%s UDP:tx_addr:%s:%u rx:%u]\n",
printf("%s() VNF:%s:%d PNF_PHY[addr:%s UDP:tx_addr:%s:%d rx:%d]\n",
__FUNCTION__,config->vnf_ip_addr, config->vnf_p5_port,
pnf.phys[0].local_addr,
pnf.phys[0].udp.tx_addr, pnf.phys[0].udp.tx_port,
......@@ -2213,7 +2204,7 @@ void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr,
pnf.phys[0].udp.tx_port = vnf_p7_port;
strcpy(pnf.phys[0].udp.tx_addr, vnf_ip_addr);
strcpy(pnf.phys[0].local_addr, pnf_ip_addr);
printf("%s() VNF:%s:%d PNF_PHY[addr:%s UDP:tx_addr:%s:%u rx:%u]\n",
printf("%s() VNF:%s:%d PNF_PHY[addr:%s UDP:tx_addr:%s:%d rx:%d]\n",
__FUNCTION__,
config->vnf_ip_addr, config->vnf_p5_port,
pnf.phys[0].local_addr,
......@@ -2272,50 +2263,24 @@ void oai_subframe_ind(uint16_t sfn, uint16_t sf) {
}
}
void handle_nr_slot_ind(uint16_t sfn, uint16_t slot) {
long shift_ns,prev_ts_nsec,shift_us;
void oai_slot_ind(uint16_t sfn, uint16_t slot) {
//slow down PNF
LOG_D(PHY,"%s(sfn:%d, slot:%d)\n", __FUNCTION__, sfn, slot);
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
// if (!(sfn == 0 && slot == 0) && ts.tv_nsec > prev_ts_nsec){
// shift_ns = ts.tv_nsec - prev_ts_nsec;
// shift_us = shift_ns/1000;
// printf("previous: %d, current: %d, shift: %d", prev_ts_nsec, ts.tv_nsec, shift_us);
// if(500-shift_us > 0)
// usleep(500-shift_us);
// // usleep(50);
// }
prev_ts_nsec = ts.tv_nsec;
//NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] %s %d.%d (sfn:%u slot:%u) SFN/SLOT(TX):%u\n", __FUNCTION__, ts.tv_sec, ts.tv_nsec, sfn, slot, NFAPI_SFNSLOT2DEC(sfn, slot));
//TODO FIXME - HACK - DJP - using a global to bodge it in
if (p7_config_g != NULL && sync_var==0) {
// DONE: changed for NR x x x x x x x x x x x x x x - - - - - - : x (Frame), - (Slot) (max_numer =2)
uint16_t sfn_slot_tx = sfn<<6 | slot;
// if ((sfn % 100 == 0) && slot==0) { // DOUBT: Why 100?
// struct timespec ts;
// clock_gettime(CLOCK_MONOTONIC, &ts);
// NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] %s %d.%d (sfn:%u slot:%u) SFN/SLOT(TX):%u\n", __FUNCTION__, ts.tv_sec, ts.tv_nsec, sfn, slot, NFAPI_SFNSLOT2DEC(sfn, slot));
// }
//TODO: send p7_config instead of p7_config_g
int slot_ret = nfapi_pnf_p7_slot_ind(p7_config_g, p7_config_g->phy_id, sfn, slot);
//send VNF slot indication, which is aligned with TX thread, so that it can call the scheduler
nfapi_nr_slot_indication_scf_t *ind;
ind = (nfapi_nr_slot_indication_scf_t *) malloc(sizeof(nfapi_nr_slot_indication_scf_t));
uint8_t slot_ahead = 6;
uint32_t sfn_slot_tx = sfnslot_add_slot(sfn, slot, slot_ahead);
uint16_t sfn_tx = NFAPI_SFNSLOT2SFN(sfn_slot_tx);
uint8_t slot_tx = NFAPI_SFNSLOT2SLOT(sfn_slot_tx);
// if (subframe_ret) {
if (slot_ret) {
NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] %s(frame:%u slot:%u) SFN/SLOT(TX):%u - PROBLEM with pnf_p7_slot_ind()\n", __FUNCTION__, sfn, slot, sfn_slot_tx, NFAPI_SFNSLOT2DEC(sfn, slot));
// printing anything causes error: probably because there isn't enough time to accomodate a print statement
} else {
//NFAPI_TRACE(NFAPI_TRACE_INFO, "***NFAPI subframe handler finished *** \n");
}
} else {
}
ind->sfn = sfn_tx;
ind->slot = slot_tx;
oai_nfapi_nr_slot_indication(ind);
//copy data from appropriate p7 slot buffers into channel structures for PHY processing
nfapi_pnf_p7_slot_ind(p7_config_g, p7_config_g->phy_id, sfn, slot);
return;
}
int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind) {
......@@ -2366,3 +2331,42 @@ int oai_nfapi_sr_indication(nfapi_sr_indication_t *ind) {
//free(ind.rx_indication_body.rx_pdu_list);
return retval;
}
//NR UPLINK INDICATION
int oai_nfapi_nr_slot_indication(nfapi_nr_slot_indication_scf_t *ind) {
ind->header.phy_id = 1;
ind->header.message_id = NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION;
return nfapi_pnf_p7_nr_slot_ind(p7_config_g, ind);
}
int oai_nfapi_nr_rx_data_indication(nfapi_nr_rx_data_indication_t *ind) {
ind->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
ind->header.message_id = NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION;
return nfapi_pnf_p7_nr_rx_data_ind(p7_config_g, ind);
}
int oai_nfapi_nr_crc_indication(nfapi_nr_crc_indication_t *ind) {
ind->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
ind->header.message_id = NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION;
return nfapi_pnf_p7_nr_crc_ind(p7_config_g, ind);
}
int oai_nfapi_nr_srs_indication(nfapi_nr_srs_indication_t *ind) {
ind->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
ind->header.message_id = NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION;
return nfapi_pnf_p7_nr_srs_ind(p7_config_g, ind);
}
int oai_nfapi_nr_uci_indication(nfapi_nr_uci_indication_t *ind) {
ind->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
ind->header.message_id = NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION;
return nfapi_pnf_p7_nr_uci_ind(p7_config_g, ind);
}
int oai_nfapi_nr_rach_indication(nfapi_nr_rach_indication_t *ind) {
ind->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
ind->header.message_id = NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION;
return nfapi_pnf_p7_nr_rach_ind(p7_config_g, ind);
}
......@@ -19,13 +19,20 @@
* contact@openairinterface.org
*/
#if !defined(NFAPI_PNF_H__)
#define NFAPI_PNF_H__
extern nfapi_ue_release_request_body_t release_rntis;
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
void handle_nr_slot_ind(uint16_t sfn, uint16_t slot);
uint32_t sfnslot_add_slot(uint16_t sfn, uint16_t slot, int offset);
int oai_nfapi_nr_slot_indication(nfapi_nr_slot_indication_scf_t *ind);
int oai_nfapi_nr_rx_data_indication(nfapi_nr_rx_data_indication_t *ind);
int oai_nfapi_nr_crc_indication(nfapi_nr_crc_indication_t *ind);
int oai_nfapi_nr_srs_indication(nfapi_nr_srs_indication_t *ind);
int oai_nfapi_nr_uci_indication(nfapi_nr_uci_indication_t *ind);
int oai_nfapi_nr_rach_indication(nfapi_nr_rach_indication_t *ind);
......@@ -33,10 +33,10 @@
#include "nfapi_nr_interface_scf.h"
#include "nfapi_vnf_interface.h"
#include "nfapi_vnf.h"
#include "nfapi.h"
#include "vendor_ext.h"
#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"
......@@ -239,6 +239,18 @@ void oai_enb_init(void) {
void oai_create_gnb(void) {
int bodge_counter=0;
if (RC.gNB == NULL) {
RC.gNB = (PHY_VARS_gNB **) calloc(1, sizeof(PHY_VARS_gNB *));
LOG_I(PHY,"gNB L1 structure RC.gNB allocated @ %p\n",RC.gNB);
}
if (RC.gNB[0] == NULL) {
RC.gNB[0] = (PHY_VARS_gNB *) calloc(1, sizeof(PHY_VARS_gNB));
LOG_I(PHY,"[nr-gnb.c] gNB structure RC.gNB[%d] allocated @ %p\n",0,RC.gNB[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
......@@ -584,7 +596,7 @@ extern pthread_mutex_t nfapi_sync_mutex;
extern int nfapi_sync_var;
int phy_sync_indication(struct nfapi_vnf_p7_config *config, uint8_t sync) {
printf("[VNF] SYNC %s\n", sync==1 ? "ACHIEVED" : "LOST");
//printf("[VNF] SYNC %s\n", sync==1 ? "ACHIEVED" : "LOST");
if (sync==1 && nfapi_sync_var!=0) {
......@@ -1002,6 +1014,124 @@ int phy_cqi_indication(struct nfapi_vnf_p7_config *config, nfapi_cqi_indication_
return 1;
}
//NR phy indication
int phy_nr_slot_indication(nfapi_nr_slot_indication_scf_t *ind) {
uint8_t vnf_slot_ahead = 2;
uint32_t vnf_sfn_slot = sfnslot_add_slot(ind->sfn, ind->slot, vnf_slot_ahead);
uint16_t vnf_sfn = NFAPI_SFNSLOT2SFN(vnf_sfn_slot);
uint8_t vnf_slot = NFAPI_SFNSLOT2SLOT(vnf_sfn_slot); //offsetting the vnf from pnf by vnf_slot_head slots
struct PHY_VARS_gNB_s *gNB = RC.gNB[0];
pthread_mutex_lock(&gNB->UL_INFO_mutex);
gNB->UL_INFO.frame = vnf_sfn;
gNB->UL_INFO.slot = vnf_slot;
pthread_mutex_unlock(&gNB->UL_INFO_mutex);
LOG_D(MAC, "VNF SFN/Slot %d.%d \n", gNB->UL_INFO.frame, gNB->UL_INFO.slot);
return 1;
}
int phy_nr_crc_indication(nfapi_nr_crc_indication_t *ind) {
struct PHY_VARS_gNB_s *gNB = RC.gNB[0];
pthread_mutex_lock(&gNB->UL_INFO_mutex);
gNB->UL_INFO.crc_ind = *ind;
if (ind->number_crcs > 0)
gNB->UL_INFO.crc_ind.crc_list = malloc(sizeof(nfapi_nr_crc_t)*ind->number_crcs);
for (int i=0; i<ind->number_crcs; i++)
memcpy(&gNB->UL_INFO.crc_ind.crc_list[i], &ind->crc_list[i], sizeof(ind->crc_list[0]));
pthread_mutex_unlock(&gNB->UL_INFO_mutex);
return 1;
}
int phy_nr_rx_data_indication(nfapi_nr_rx_data_indication_t *ind) {
struct PHY_VARS_gNB_s *gNB = RC.gNB[0];
pthread_mutex_lock(&gNB->UL_INFO_mutex);
gNB->UL_INFO.rx_ind = *ind;
if (ind->number_of_pdus > 0)
gNB->UL_INFO.rx_ind.pdu_list = malloc(sizeof(nfapi_nr_rx_data_pdu_t)*ind->number_of_pdus);
for (int i=0; i<ind->number_of_pdus; i++)
memcpy(&gNB->UL_INFO.rx_ind.pdu_list[i], &ind->pdu_list[i], sizeof(ind->pdu_list[0]));
pthread_mutex_unlock(&gNB->UL_INFO_mutex);
return 1;
}
int phy_nr_uci_indication(nfapi_nr_uci_indication_t *ind) {
struct PHY_VARS_gNB_s *gNB = RC.gNB[0];
pthread_mutex_lock(&gNB->UL_INFO_mutex);
gNB->UL_INFO.uci_ind = *ind;
if (ind->num_ucis > 0)
gNB->UL_INFO.uci_ind.uci_list = malloc(sizeof(nfapi_nr_uci_t)*ind->num_ucis);
for (int i=0; i<ind->num_ucis; i++)
memcpy(&gNB->UL_INFO.uci_ind.uci_list[i], &ind->uci_list[i], sizeof(ind->uci_list[0]));
//printf("UCI ind written to UL_info: num_ucis: %d, PDU_type : %d. \n", ind->num_ucis, ind->uci_list[0].pdu_type);
pthread_mutex_unlock(&gNB->UL_INFO_mutex);
return 1;
}
int phy_nr_srs_indication(nfapi_nr_srs_indication_t *ind) {
struct PHY_VARS_gNB_s *gNB = RC.gNB[0];
pthread_mutex_lock(&gNB->UL_INFO_mutex);
gNB->UL_INFO.srs_ind = *ind;
if (ind->number_of_pdus > 0)
gNB->UL_INFO.srs_ind.pdu_list = malloc(sizeof(nfapi_nr_srs_indication_pdu_t)*ind->number_of_pdus);
for (int i=0; i<ind->number_of_pdus; i++) {
memcpy(&gNB->UL_INFO.srs_ind.pdu_list[i], &ind->pdu_list[i], sizeof(ind->pdu_list[0]));
LOG_D(MAC, "%s() NFAPI SFN/Slot:%d.%d SRS_IND:number_of_pdus:%d UL_INFO:pdus:%d\n",
__FUNCTION__,
ind->sfn,ind->slot, ind->number_of_pdus, gNB->UL_INFO.srs_ind.number_of_pdus
);
}
pthread_mutex_unlock(&gNB->UL_INFO_mutex);
return 1;
}
int phy_nr_rach_indication(nfapi_nr_rach_indication_t *ind) {
struct PHY_VARS_gNB_s *gNB = RC.gNB[0];
pthread_mutex_lock(&gNB->UL_INFO_mutex);
gNB->UL_INFO.rach_ind = *ind;
if (ind->number_of_pdus > 0)
gNB->UL_INFO.rach_ind.pdu_list = malloc(sizeof(nfapi_nr_prach_indication_pdu_t)*ind->number_of_pdus);
for (int i=0; i<ind->number_of_pdus; i++) {
memcpy(&gNB->UL_INFO.rach_ind.pdu_list[i], &ind->pdu_list[i], sizeof(ind->pdu_list[0]));
LOG_D(MAC, "%s() NFAPI SFN/Slot:%d.%d RACH_IND:number_of_pdus:%d UL_INFO:pdus:%d\n",
__FUNCTION__,
ind->sfn,ind->slot, ind->number_of_pdus, gNB->UL_INFO.rach_ind.number_of_pdus
);
}
pthread_mutex_unlock(&gNB->UL_INFO_mutex);
return 1;
}
//end NR phy indication
int phy_lbt_dl_indication(struct nfapi_vnf_p7_config *config, nfapi_lbt_dl_indication_t *ind) {
// vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data);
//mac_lbt_dl_ind(p7_vnf->mac, ind);
......@@ -1167,6 +1297,12 @@ void *vnf_nr_p7_thread_start(void *ptr) {
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->nr_crc_indication = &phy_nr_crc_indication;
p7_vnf->config->nr_slot_indication = &phy_nr_slot_indication;
p7_vnf->config->nr_rx_data_indication = &phy_nr_rx_data_indication;
p7_vnf->config->nr_uci_indication = &phy_nr_uci_indication;
p7_vnf->config->nr_rach_indication = &phy_nr_rach_indication;
p7_vnf->config->nr_srs_indication = &phy_nr_srs_indication;
p7_vnf->config->malloc = &vnf_allocate;
p7_vnf->config->free = &vnf_deallocate;
p7_vnf->config->trace = &vnf_trace;
......@@ -1501,8 +1637,8 @@ 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].timing_window = 30;
vnf.p7_vnfs[0].periodic_timing_enabled = 0;
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();
......@@ -1620,7 +1756,7 @@ 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.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);
......
......@@ -19,9 +19,9 @@
* contact@openairinterface.org
*/
#if !defined(NFAPI_VNF_H__)
#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
uint32_t sfnslot_add_slot(uint16_t sfn, uint16_t slot, int offset);
/*
* Copyright 2017 Cisco Systems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/types.h>
#include <pthread.h>
#include <syslog.h>
#include <debug.h>
#define MAX_MSG_LENGTH 2096
#define TRACE_HEADER_LENGTH 44
void nfapi_trace_dbg(nfapi_trace_level_t level, const char *format, ...);
// initialize the trace function to 0
void (*nfapi_trace_g)(nfapi_trace_level_t level, const char* format, ...) = &nfapi_trace_dbg;
nfapi_trace_level_t nfapi_trace_level_g = NFAPI_TRACE_INFO;
//nfapi_trace_level_t nfapi_trace_level_g = NFAPI_TRACE_WARN;
void nfapi_set_trace_level(nfapi_trace_level_t new_level)
{
nfapi_trace_level_g = new_level;
}
void nfapi_trace_dbg(nfapi_trace_level_t level, const char *format, ...)
{
char trace_buff[MAX_MSG_LENGTH + TRACE_HEADER_LENGTH];
uint32_t num_chars;
va_list p_args;
struct timeval tv;
pthread_t tid = pthread_self();
(void)gettimeofday(&tv, NULL);
num_chars = (uint32_t)snprintf(trace_buff, TRACE_HEADER_LENGTH, "%04u.%06u: 0x%02x: %10u: ", ((uint32_t)tv.tv_sec) & 0x1FFF, (uint32_t)tv.tv_usec, (uint32_t)level, (uint32_t)tid);
if (num_chars > TRACE_HEADER_LENGTH)
{
printf("trace_dbg: Error, num_chars is too large: %u", num_chars);
return;
}
va_start(p_args, format);
if ((num_chars = (uint32_t)vsnprintf(&trace_buff[num_chars], MAX_MSG_LENGTH, format, p_args)))
{
if (level <= NFAPI_TRACE_WARN)
{
printf("%s", trace_buff);
}
printf("%s", trace_buff);
}
va_end(p_args);
}
/*
* Copyright 2017 Cisco Systems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/types.h>
#include <pthread.h>
#include <syslog.h>
#include <debug.h>
#define MAX_MSG_LENGTH 2096
#define TRACE_HEADER_LENGTH 44
void nfapi_trace_dbg(nfapi_trace_level_t level, const char *format, ...);
// initialize the trace function to 0
void (*nfapi_trace_g)(nfapi_trace_level_t level, const char* format, ...) = &nfapi_trace_dbg;
nfapi_trace_level_t nfapi_trace_level_g = NFAPI_TRACE_INFO;
//nfapi_trace_level_t nfapi_trace_level_g = NFAPI_TRACE_WARN;
void nfapi_set_trace_level(nfapi_trace_level_t new_level)
{
nfapi_trace_level_g = new_level;
}
void nfapi_trace_dbg(nfapi_trace_level_t level, const char *format, ...)
{
char trace_buff[MAX_MSG_LENGTH + TRACE_HEADER_LENGTH];
uint32_t num_chars;
va_list p_args;
struct timeval tv;
pthread_t tid = pthread_self();
(void)gettimeofday(&tv, NULL);
num_chars = (uint32_t)snprintf(trace_buff, TRACE_HEADER_LENGTH, "%04u.%06u: 0x%02x: %10u: ", ((uint32_t)tv.tv_sec) & 0x1FFF, (uint32_t)tv.tv_usec, (uint32_t)level, (uint32_t)tid);
if (num_chars > TRACE_HEADER_LENGTH)
{
printf("trace_dbg: Error, num_chars is too large: %d", num_chars);
return;
}
va_start(p_args, format);
if ((num_chars = (uint32_t)vsnprintf(&trace_buff[num_chars], MAX_MSG_LENGTH, format, p_args)))
{
if (level <= NFAPI_TRACE_WARN)
{
printf("%s", trace_buff);
}
printf("%s", trace_buff);
}
va_end(p_args);
}
......@@ -673,6 +673,7 @@ typedef struct {
#define NFAPI_NR_SLOT_INDICATION_PERIOD_NUMEROLOGY_3 125 //us
typedef struct {
nfapi_p7_message_header_t header;
uint16_t sfn; //0->1023
uint16_t slot;//0->319
......@@ -1492,10 +1493,11 @@ typedef struct
typedef struct
{
nfapi_p7_message_header_t header;
uint16_t sfn;
uint16_t slot;
uint16_t number_of_pdus;
nfapi_nr_rx_data_pdu_t* pdu_list;
nfapi_nr_rx_data_pdu_t *pdu_list;
} nfapi_nr_rx_data_indication_t;
......@@ -1518,6 +1520,7 @@ typedef struct
typedef struct
{
nfapi_p7_message_header_t header;
uint16_t sfn;
uint16_t slot;
uint16_t number_crcs;
......@@ -1653,6 +1656,7 @@ typedef struct
typedef struct
{
nfapi_p7_message_header_t header;
uint16_t sfn;
uint16_t slot;
uint16_t num_ucis;
......@@ -1689,6 +1693,7 @@ typedef struct
typedef struct
{
nfapi_p7_message_header_t header;
uint16_t sfn;
uint16_t slot;
uint8_t number_of_pdus;
......@@ -1721,6 +1726,7 @@ typedef struct{
typedef struct
{
nfapi_p7_message_header_t header;
uint16_t sfn;
uint16_t slot;
uint8_t number_of_pdus;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -153,10 +153,17 @@ 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);
int nfapi_pnf_p7_nr_slot_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_slot_indication_scf_t* ind);
int nfapi_pnf_p7_nr_rx_data_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_rx_data_indication_t* ind);
int nfapi_pnf_p7_nr_crc_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_crc_indication_t* ind);
int nfapi_pnf_p7_nr_srs_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_srs_indication_t* ind);
int nfapi_pnf_p7_nr_uci_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_uci_indication_t* ind);
int nfapi_pnf_p7_nr_rach_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_rach_indication_t* ind);
pnf_p7_rx_message_t* pnf_p7_rx_reassembly_queue_add_segment(pnf_p7_t* pnf_p7, pnf_p7_rx_reassembly_queue_t* queue, uint32_t rx_hr_time, uint16_t sequence_number, uint16_t segment_number, uint8_t m, uint8_t* data, uint16_t data_len);
void pnf_p7_rx_reassembly_queue_remove_msg(pnf_p7_t* pnf_p7, pnf_p7_rx_reassembly_queue_t* queue, pnf_p7_rx_message_t* msg);
void pnf_p7_rx_reassembly_queue_remove_old_msgs(pnf_p7_t* pnf_p7, pnf_p7_rx_reassembly_queue_t* queue, uint32_t rx_hr_time, uint32_t delta);
int pnf_nr_p7_pack_and_send_p7_message(pnf_p7_t* pnf_p7, nfapi_p7_message_header_t* header, uint32_t msg_len);
#endif /* _PNF_P7_H_ */
......@@ -27,6 +27,7 @@ extern "C" {
#include <openair2/PHY_INTERFACE/IF_Module.h>
#include "nfapi_nr_interface.h"
#include "nfapi_nr_interface_scf.h"
#include <sys/types.h>
#include "openair1/PHY/defs_gNB.h"
......
......@@ -156,17 +156,16 @@ nfapi_dl_config_request_t* allocate_nfapi_dl_config_request(pnf_p7_t* pnf_p7)
void deallocate_nfapi_dl_tti_request(nfapi_nr_dl_tti_request_t* req, pnf_p7_t* pnf_p7)
{
//printf("%s() SFN/SF:%d %s req:%p pdu_list:%p\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), pnf_p7->_public.codec_config.deallocate ? "DEALLOCATE" : "FREE", req, req->dl_config_request_body.dl_config_pdu_list);
/*
if(pnf_p7->_public.codec_config.deallocate)
{
//nfapi_nr_dl_tti_request_pdu_t *temp = &req->dl_tti_pdu_list;
(pnf_p7->_public.codec_config.deallocate)(req);
}
else
{
free(req);
}
*/
// if(pnf_p7->_public.codec_config.deallocate)
// {
// (pnf_p7->_public.codec_config.deallocate)(req);
// }
// else
// {
// free(req);
// }
pnf_p7_free(pnf_p7, req);
}
......@@ -915,14 +914,13 @@ void send_dummy_subframe(pnf_p7_t* pnf_p7, uint16_t sfn_sf)
int pnf_p7_slot_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn, uint16_t slot)
{
{
//This function is aligned with rx sfn/slot
// We could either send an event to the p7 thread have have it run the
// subframe or we could handle it here and lock access to the subframe
// buffers. If we do it on the p7 thread then we run the risk of blocking
// on the udp send.
//
// todo : start a timer to give us more of the 1 ms tick before send back
// the frame
// todo : consider a more efficent lock mechasium
//uint16_t NUM_SLOTS = 20;//10* 2^mu
......@@ -935,21 +933,21 @@ int pnf_p7_slot_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn, uint16_t sl
// save the curren time, sfn and slot
pnf_p7->slot_start_time_hr = pnf_get_current_time_hr();
pnf_p7->sfn = sfn;
pnf_p7->slot = slot;
slot_ahead = 6;
uint32_t sfn_slot_tx = sfnslot_add_slot(sfn, slot, slot_ahead);
uint16_t sfn_tx = sfn_slot_tx>>6;
uint16_t slot_tx = sfn_slot_tx & 0X3F;
uint16_t sfn_tx = NFAPI_SFNSLOT2SFN(sfn_slot_tx);
uint8_t slot_tx = NFAPI_SFNSLOT2SLOT(sfn_slot_tx);
// uint32_t tx_sfn_slot_dec = NFAPI_SFNSLOT2DEC(sfn,slot);
uint32_t tx_slot_dec = NFAPI_SFNSLOT2DEC(sfn,slot);
//We align the pnf_p7 sfn/slot with tx sfn/slot, and vnf is synced with pnf_p7 sfn/slot. This is so that the scheduler runs slot_ahead from rx thread.
pnf_p7->sfn = sfn_tx;
pnf_p7->slot = slot_tx;
//uint32_t tx_sfn_slot_dec = NFAPI_SFNSLOT2DEC(sfn_slot_tx);
uint32_t rx_slot_dec = NFAPI_SFNSLOT2DEC(sfn, slot);
uint8_t buffer_index_rx = rx_slot_dec % 20;
uint32_t tx_slot_dec = NFAPI_SFNSLOT2DEC(sfn_tx,slot_tx);
uint8_t buffer_index_tx = tx_slot_dec % 20;
// If the subframe_buffer has been configured
if(pnf_p7->_public.slot_buffer_size!= 0) // for now value is same as sf_buffer_size
......@@ -976,28 +974,20 @@ int pnf_p7_slot_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn, uint16_t sl
pnf_p7->slot_shift = 0;
}
uint32_t slot_dec = NFAPI_SFNSLOT2DEC(sfn, slot);
uint8_t buffer_index = slot_dec % pnf_p7->_public.slot_buffer_size;
nfapi_pnf_p7_slot_buffer_t* slot_buffer = &(pnf_p7->slot_buffer[buffer_index]);
// see where the PNF_P7 slot buffer its getting filled
nfapi_pnf_p7_slot_buffer_t* rx_slot_buffer = &(pnf_p7->slot_buffer[buffer_index_rx]);
uint8_t tx_buffer_index = tx_slot_dec % pnf_p7->_public.slot_buffer_size;
nfapi_pnf_p7_slot_buffer_t* tx_slot_buffer = &(pnf_p7->slot_buffer[tx_buffer_index]);
nfapi_pnf_p7_slot_buffer_t* tx_slot_buffer = &(pnf_p7->slot_buffer[buffer_index_tx]);
if (0) NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() shift:%d slot_buffer->sfn_sf:%d tx_slot_buffer->sfn_slot:%d sfn_sf:%d subframe_buffer[buffer_index:%u dl_config_req:%p tx_req:%p] "
"TX:sfn_sf:%d:tx_buffer_index:%d[dl_config_req:%p tx_req:%p]\n",
__FUNCTION__,
pnf_p7->slot_shift,
NFAPI_SFNSLOT2DEC(slot_buffer->sfn, slot_buffer->slot),
NFAPI_SFNSLOT2DEC(tx_slot_buffer->sfn, tx_slot_buffer->slot),
slot_dec, buffer_index, slot_buffer->dl_tti_req, slot_buffer->tx_data_req,
tx_slot_dec, tx_buffer_index, tx_slot_buffer->dl_tti_req, tx_slot_buffer->tx_data_req);
// if (0) NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() shift:%d slot_buffer->sfn_sf:%d tx_slot_buffer->sfn_slot:%d sfn_sf:%d subframe_buffer[buffer_index:%u dl_config_req:%p tx_req:%p] "
// "TX:sfn_sf:%d:tx_buffer_index:%d[dl_config_req:%p tx_req:%p]\n",
// __FUNCTION__,
// pnf_p7->slot_shift,
// NFAPI_SFNSLOT2DEC(rx_slot_buffer->sfn, rx_slot_buffer->slot),
// NFAPI_SFNSLOT2DEC(tx_slot_buffer->sfn, tx_slot_buffer->slot),
// slot_dec, buffer_index_rx, rx_slot_buffer->dl_tti_req, rx_slot_buffer->tx_data_req,
// tx_slot_dec, buffer_index_tx, tx_slot_buffer->dl_tti_req, tx_slot_buffer->tx_data_req);
//TODO: Change later if required
// if the subframe buffer sfn sf is set then we have atlease 1 message
// from the vnf.
// todo : how to handle the messages we don't have, send dummies for
// now
......@@ -1006,37 +996,39 @@ int pnf_p7_slot_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn, uint16_t sl
//printf("tx_slot_buff_sfn - %d, tx_slot_buf_slot - %d, sfn_tx = %d, sllot_tx - %d \n",tx_slot_buffer->sfn,tx_slot_buffer->slot,sfn_tx,slot_tx);
// if(tx_slot_buffer->slot == slot_tx && tx_slot_buffer->sfn == sfn_tx)
// {
if(tx_slot_buffer->tx_data_req != 0)
{
//checking in the tx slot buffers to see if a p7 msg is present. todo: what if it's a mixed slot?
if(tx_slot_buffer->tx_data_req != 0 && tx_slot_buffer->tx_data_req->SFN == sfn_tx && tx_slot_buffer->tx_data_req->Slot == slot_tx)
{
if(pnf_p7->_public.tx_data_req_fn)
{
(pnf_p7->_public.tx_data_req_fn)(&(pnf_p7->_public), tx_slot_buffer->tx_data_req);
}
if(pnf_p7->_public.tx_data_req_fn)
{
//NFAPI_TRACE(NFAPI_TRACE_INFO, "Calling tx_data_req_fn in SFN/slot %d.%d \n",sfn,slot);
LOG_D(PHY, "Process tx_data SFN/slot %d.%d buffer index: %d \n",sfn_tx,slot_tx,buffer_index_tx);
(pnf_p7->_public.tx_data_req_fn)(&(pnf_p7->_public), tx_slot_buffer->tx_data_req);
}
else
}
else
{
// send dummy
if(pnf_p7->_public.tx_data_req_fn && pnf_p7->_public.dummy_slot.tx_data_req)
{
// send dummy
if(pnf_p7->_public.tx_data_req_fn && pnf_p7->_public.dummy_slot.tx_data_req)
{
pnf_p7->_public.dummy_slot.tx_data_req->SFN = sfn_tx;
pnf_p7->_public.dummy_slot.tx_data_req->Slot = slot_tx;
pnf_p7->_public.dummy_slot.tx_data_req->SFN = sfn_tx;
pnf_p7->_public.dummy_slot.tx_data_req->Slot = slot_tx;
(pnf_p7->_public.tx_data_req_fn)(&(pnf_p7->_public), pnf_p7->_public.dummy_slot.tx_data_req);
}
(pnf_p7->_public.tx_data_req_fn)(&(pnf_p7->_public), pnf_p7->_public.dummy_slot.tx_data_req);
}
//}
if( tx_slot_buffer->dl_tti_req != 0) // ADDED & TO BYPASS ERROR
}
if(tx_slot_buffer->dl_tti_req != 0 && tx_slot_buffer->dl_tti_req->SFN == sfn_tx && tx_slot_buffer->dl_tti_req->Slot == slot_tx)
{
if(pnf_p7->_public.dl_tti_req_fn)
{
LOG_D(PHY, "Process dl_tti SFN/slot %d.%d buffer index: %d \n",sfn_tx,slot_tx,buffer_index_tx);
(pnf_p7->_public.dl_tti_req_fn)(NULL, &(pnf_p7->_public), tx_slot_buffer->dl_tti_req);
}
}
else
{
// send dummy
......@@ -1048,10 +1040,13 @@ int pnf_p7_slot_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn, uint16_t sl
}
}
if(tx_slot_buffer->ul_dci_req!= 0)
if(tx_slot_buffer->ul_dci_req!= 0 && tx_slot_buffer->ul_dci_req->SFN == sfn_tx && tx_slot_buffer->ul_dci_req->Slot == slot_tx)
{
if(pnf_p7->_public.ul_dci_req_fn)
{
//NFAPI_TRACE(NFAPI_TRACE_INFO, "Calling UL_dci_req_fn in SFN/slot %d.%d \n",sfn,slot);
LOG_D(PHY, "Process ul_dci SFN/slot %d.%d buffer index: %d \n",sfn_tx,slot_tx,buffer_index_tx);
(pnf_p7->_public.ul_dci_req_fn)(NULL, &(pnf_p7->_public), tx_slot_buffer->ul_dci_req);
}
}
......@@ -1065,10 +1060,14 @@ int pnf_p7_slot_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn, uint16_t sl
(pnf_p7->_public.ul_dci_req_fn)(NULL, &(pnf_p7->_public), pnf_p7->_public.dummy_slot.ul_dci_req);
}
}
//deallocate slot buffers after passing down the PDUs to PHY processing
if(tx_slot_buffer->dl_tti_req != 0)
{
deallocate_nfapi_dl_tti_request(tx_slot_buffer->dl_tti_req, pnf_p7);
tx_slot_buffer->dl_tti_req = 0;
LOG_D(PHY,"SFN/slot %d.%d Buffer index : %d freed \n",sfn_tx,slot_tx,buffer_index_tx);
}
if(tx_slot_buffer->tx_data_req != 0)
......@@ -1082,73 +1081,52 @@ int pnf_p7_slot_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn, uint16_t sl
deallocate_nfapi_ul_dci_request(tx_slot_buffer->ul_dci_req, pnf_p7);
tx_slot_buffer->ul_dci_req = 0;
}
else
{
// If we ever need to "send" a dummy ul_config this won't work!!!
// send_dummy_subframe(pnf_p7, sfn_sf_tx);
// send_dummy_slot(pnf_p7, sfn_tx, slot_tx);
}
//checking in the rx slot buffers to see if a p7 msg is present.
if(slot_buffer->sfn == sfn && slot_buffer->slot == slot )
if(rx_slot_buffer->ul_tti_req != 0 && rx_slot_buffer->ul_tti_req->SFN == sfn && rx_slot_buffer->ul_tti_req->Slot == slot)
{
if(slot_buffer->ul_tti_req != 0)
{
if(pnf_p7->_public.ul_tti_req_fn)
{
(pnf_p7->_public.ul_tti_req_fn)(NULL, &(pnf_p7->_public), slot_buffer->ul_tti_req);
}
//deallocate_nfapi_ul_config_request(subframe_buffer->ul_config_req, pnf_p7);
if(pnf_p7->_public.ul_tti_req_fn)
{
//NFAPI_TRACE(NFAPI_TRACE_INFO, "Calling UL_tti_req_fn in SFN/slot %d.%d \n",sfn,slot);
(pnf_p7->_public.ul_tti_req_fn)(NULL, &(pnf_p7->_public), rx_slot_buffer->ul_tti_req);
}
else
}
else
{
// send dummy
if(pnf_p7->_public.ul_tti_req_fn && pnf_p7->_public.dummy_slot.ul_tti_req)
{
// send dummy
if(pnf_p7->_public.ul_tti_req_fn && pnf_p7->_public.dummy_slot.ul_tti_req)
{
pnf_p7->_public.dummy_slot.ul_tti_req->SFN = sfn;
pnf_p7->_public.dummy_slot.ul_tti_req->Slot = slot;
(pnf_p7->_public.ul_tti_req_fn)(NULL, &(pnf_p7->_public), pnf_p7->_public.dummy_slot.ul_tti_req);
}
pnf_p7->_public.dummy_slot.ul_tti_req->SFN = sfn;
pnf_p7->_public.dummy_slot.ul_tti_req->Slot = slot;
LOG_D(PHY, "Process ul_tti SFN/slot %d.%d buffer index: %d \n",sfn,slot,buffer_index_rx);
(pnf_p7->_public.ul_tti_req_fn)(NULL, &(pnf_p7->_public), pnf_p7->_public.dummy_slot.ul_tti_req);
}
//if(subframe_buffer->dl_config_req != 0)
//deallocate_nfapi_dl_config_request(subframe_buffer->dl_config_req, pnf_p7);
//if(subframe_buffer->tx_req != 0)
//deallocate_nfapi_tx_request(subframe_buffer->tx_req, pnf_p7);
if(slot_buffer->ul_tti_req != 0)
{
deallocate_nfapi_ul_tti_request(slot_buffer->ul_tti_req, pnf_p7);
slot_buffer->ul_tti_req = 0;
}
if(rx_slot_buffer->ul_tti_req != 0)
{
deallocate_nfapi_ul_tti_request(rx_slot_buffer->ul_tti_req, pnf_p7);
rx_slot_buffer->ul_tti_req = 0;
}
#if 0
if(slot_buffer->lbt_dl_config_req != 0)
{
deallocate_nfapi_lbt_dl_config_request(slot_buffer->lbt_dl_config_req, pnf_p7);
slot_buffer->lbt_dl_config_req = 0;
}
#endif
} // sfn_slot match
}
//reset slot buffer
if ( slot_buffer->dl_tti_req == 0 &&
slot_buffer->tx_data_req == 0 &&
slot_buffer->ul_tti_req == 0)
//slot_buffer->lbt_dl_config_req == 0 &&
//slot_buffer->ue_release_req == 0)
if ( rx_slot_buffer->dl_tti_req == 0 &&
rx_slot_buffer->tx_data_req == 0 &&
rx_slot_buffer->ul_tti_req == 0)
{
memset(&(pnf_p7->slot_buffer[buffer_index]), 0, sizeof(nfapi_pnf_p7_slot_buffer_t));
pnf_p7->slot_buffer[buffer_index].sfn = -1;
pnf_p7->slot_buffer[buffer_index].slot = -1;
memset(&(pnf_p7->slot_buffer[buffer_index_rx]), 0, sizeof(nfapi_pnf_p7_slot_buffer_t));
pnf_p7->slot_buffer[buffer_index_rx].sfn = -1;
pnf_p7->slot_buffer[buffer_index_rx].slot = -1;
}
//printf("pnf_p7->_public.timing_info_mode_periodic:%d pnf_p7->timing_info_period_counter:%d pnf_p7->_public.timing_info_period:%d\n", pnf_p7->_public.timing_info_mode_periodic, pnf_p7->timing_info_period_counter, pnf_p7->_public.timing_info_period);
//printf("pnf_p7->_public.timing_info_mode_aperiodic:%d pnf_p7->timing_info_aperiodic_send:%d\n", pnf_p7->_public.timing_info_mode_aperiodic, pnf_p7->timing_info_aperiodic_send);
//printf("pnf_p7->timing_info_ms_counter:%d\n", pnf_p7->timing_info_ms_counter);
// send the periodic timing info if configured
//send the periodic timing info if configured
if(pnf_p7->_public.timing_info_mode_periodic && (pnf_p7->timing_info_period_counter++) == pnf_p7->_public.timing_info_period)
{
pnf_nr_pack_and_send_timing_info(pnf_p7);
......@@ -1167,26 +1145,6 @@ int pnf_p7_slot_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn, uint16_t sl
}
}
else
{
//send_dummy_subframe(pnf_p7, sfn_sf_tx);
}
//printf("pnf_p7->tick:%d\n", pnf_p7->tick);
// if(pnf_p7->tick == 1000) // why?
// {
// // TODO: change stats to nr_stats
// NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF P7:%d] (ONTIME/LATE) DL:(%d/%d) UL:(%d/%d) HI:(%d/%d) TX:(%d/%d)\n", pnf_p7->_public.phy_id,
// pnf_p7->stats.dl_conf_ontime, pnf_p7->stats.dl_conf_late,
// pnf_p7->stats.ul_conf_ontime, pnf_p7->stats.ul_conf_late,
// pnf_p7->stats.hi_dci0_ontime, pnf_p7->stats.hi_dci0_late,
// pnf_p7->stats.tx_ontime, pnf_p7->stats.tx_late);
// pnf_p7->tick = 0;
// memset(&pnf_p7->stats, 0, sizeof(pnf_p7->stats));
// }
// pnf_p7->tick++;
if(pthread_mutex_unlock(&(pnf_p7->mutex)) != 0)
{
......@@ -1495,7 +1453,7 @@ uint8_t is_nr_p7_request_in_window(uint16_t sfn,uint16_t slot, const char* name,
{
uint32_t recv_sfn_slot_dec = NFAPI_SFNSLOT2DEC(sfn,slot);
uint32_t current_sfn_slot_dec = NFAPI_SFNSLOT2DEC(phy->sfn,phy->slot);
printf("p7_msg_sfn: %d, p7_msg_slot: %d, phy_sfn:%d , phy_slot:%d \n",sfn,slot,phy->sfn,phy->slot);
//printf("p7_msg_sfn: %d, p7_msg_slot: %d, phy_sfn:%d , phy_slot:%d \n",sfn,slot,phy->sfn,phy->slot);
uint8_t in_window = 0;
uint8_t timing_window = phy->_public.slot_buffer_size;
......@@ -1546,11 +1504,11 @@ uint8_t is_nr_p7_request_in_window(uint16_t sfn,uint16_t slot, const char* name,
// }
if(current_sfn_slot_dec <= recv_sfn_slot_dec + timing_window){
in_window = 1;
NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] %s is in window %d\n", current_sfn_slot_dec, name, recv_sfn_slot_dec);
//NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] %s is in window %d\n", current_sfn_slot_dec, name, recv_sfn_slot_dec);
}
else if(current_sfn_slot_dec + NFAPI_MAX_SFNSLOTDEC <= recv_sfn_slot_dec + timing_window){ //checking for wrap
in_window = 1;
NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] %s is in window %d\n", current_sfn_slot_dec, name, recv_sfn_slot_dec);
//NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] %s is in window %d\n", current_sfn_slot_dec, name, recv_sfn_slot_dec);
}
else
......@@ -1630,7 +1588,6 @@ void pnf_handle_dl_tti_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7)
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to alloced nfapi_dl_tti_request structure\n");
return;
}
int unpack_result = nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, req, sizeof(nfapi_nr_dl_tti_request_t), &(pnf_p7->_public.codec_config));
if(unpack_result == 0)
......@@ -1640,34 +1597,18 @@ void pnf_handle_dl_tti_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7)
NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n");
return;
}
#if 0
if (
0 &&
(NFAPI_SFNSF2DEC(req->sfn_sf) % 100 ==0 ||
NFAPI_SFNSF2DEC(req->sfn_sf) % 105 ==0
)
)
NFAPI_TRACE(NFAPI_TRACE_INFO, "DL_CONFIG.req sfn_sf:%d pdcch:%u dci:%u pdu:%u pdsch_rnti:%u pcfich:%u\n",
NFAPI_SFNSF2DEC(req->sfn_sf),
req->dl_config_request_body.number_pdcch_ofdm_symbols,
req->dl_config_request_body.number_dci,
req->dl_config_request_body.number_pdu,
req->dl_config_request_body.number_pdsch_rnti,
req->dl_config_request_body.transmission_power_pcfich
);
#endif
if(is_nr_p7_request_in_window(req->SFN,req->Slot, "dl_tti_request", pnf_p7))
{
uint32_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(req->SFN,req->Slot);
uint8_t buffer_index = sfn_slot_dec % pnf_p7->_public.slot_buffer_size;
if(is_nr_p7_request_in_window(req->SFN,req->Slot, "dl_tti_request", pnf_p7))
{
uint32_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(req->SFN,req->Slot);
uint8_t buffer_index = sfn_slot_dec % 20;
struct timespec t;
clock_gettime(CLOCK_MONOTONIC, &t);
struct timespec t;
clock_gettime(CLOCK_MONOTONIC, &t);
//NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() %ld.%09ld POPULATE DL_TTI_REQ sfn_slot:%d buffer_index:%d\n", __FUNCTION__, t.tv_sec, t.tv_nsec, sfn_slot_dec, buffer_index);
NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() %ld.%09ld POPULATE DL_TTI_REQ current tx sfn/slot:%d.%d p7 msg sfn/slot: %d.%d buffer_index:%d\n", __FUNCTION__, t.tv_sec, t.tv_nsec, pnf_p7->sfn,pnf_p7->slot, req->SFN, req->Slot, buffer_index);
// if there is already an dl_config_req make sure we free it.
// if there is already an dl_tti_req make sure we free it.
if(pnf_p7->slot_buffer[buffer_index].dl_tti_req != 0)
{
NFAPI_TRACE(NFAPI_TRACE_NOTE, "%s() is_nr_p7_request_in_window()=TRUE buffer_index occupied - free it first sfn_slot:%d buffer_index:%d\n", __FUNCTION__, NFAPI_SFNSLOT2DEC(req->SFN,req->Slot), buffer_index);
......@@ -1677,7 +1618,7 @@ void pnf_handle_dl_tti_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7)
deallocate_nfapi_dl_tti_request(pnf_p7->slot_buffer[buffer_index].dl_tti_req, pnf_p7);
}
// saving dl_config_request in subframe buffer
// filling dl_tti_request in slot buffer
pnf_p7->slot_buffer[buffer_index].sfn = req->SFN;
pnf_p7->slot_buffer[buffer_index].slot = req->Slot;
pnf_p7->slot_buffer[buffer_index].dl_tti_req = req;
......@@ -1826,12 +1767,12 @@ void pnf_handle_ul_tti_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7)
if(is_nr_p7_request_in_window(req->SFN,req->Slot, "ul_tti_request", pnf_p7))
{
uint32_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(req->SFN,req->Slot);
uint8_t buffer_index = sfn_slot_dec % pnf_p7->_public.slot_buffer_size;
uint8_t buffer_index = (sfn_slot_dec % 20);
struct timespec t;
clock_gettime(CLOCK_MONOTONIC, &t);
NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() %ld.%09ld POPULATE UL_TTI_REQ sfn_slot:%d buffer_index:%d\n", __FUNCTION__, t.tv_sec, t.tv_nsec, sfn_slot_dec, buffer_index);
NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() %ld.%09ld POPULATE UL_TTI_REQ current tx sfn/slot:%d.%d p7 msg sfn/slot: %d.%d buffer_index:%d\n", __FUNCTION__, t.tv_sec, t.tv_nsec, pnf_p7->sfn,pnf_p7->slot, req->SFN, req->Slot, buffer_index);
if(pnf_p7->slot_buffer[buffer_index].ul_tti_req != 0)
{
......@@ -1841,6 +1782,8 @@ void pnf_handle_ul_tti_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7)
deallocate_nfapi_ul_tti_request(pnf_p7->slot_buffer[buffer_index].ul_tti_req, pnf_p7);
}
//filling slot buffer
pnf_p7->slot_buffer[buffer_index].sfn = req->SFN;
pnf_p7->slot_buffer[buffer_index].slot = req->Slot;
......@@ -1972,7 +1915,7 @@ void pnf_handle_ul_dci_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7)
if(is_nr_p7_request_in_window(req->SFN,req->Slot,"ul_dci_request", pnf_p7))
{
uint32_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(req->SFN,req->Slot);
uint8_t buffer_index = sfn_slot_dec % pnf_p7->_public.slot_buffer_size;
uint8_t buffer_index = sfn_slot_dec % 20;
if(pnf_p7->slot_buffer[buffer_index].ul_dci_req!= 0)
{
......@@ -2010,7 +1953,7 @@ void pnf_handle_ul_dci_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7)
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to unpack hi_dci0_req\n");
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to unpack UL DCI req\n");
deallocate_nfapi_ul_dci_request(req, pnf_p7);
}
}
......@@ -2111,12 +2054,12 @@ void pnf_handle_tx_data_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7
if(is_nr_p7_request_in_window(req->SFN, req->Slot,"tx_request", pnf_p7))
{
uint32_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(req->SFN,req->Slot);
uint8_t buffer_index = sfn_slot_dec % pnf_p7->_public.slot_buffer_size;
uint8_t buffer_index = sfn_slot_dec % 20;
struct timespec t;
clock_gettime(CLOCK_MONOTONIC, &t);
NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() %ld.%09ld POPULATE TX_DATA_REQ sfn_sf:%d buffer_index:%d\n", __FUNCTION__, t.tv_sec, t.tv_nsec, sfn_slot_dec, buffer_index);
//NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() %ld.%09ld POPULATE TX_DATA_REQ sfn_sf:%d buffer_index:%d\n", __FUNCTION__, t.tv_sec, t.tv_nsec, sfn_slot_dec, buffer_index);
#if 0
if (0 && NFAPI_SFNSF2DEC(req->sfn_sf)%100==0) NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() TX_REQ.req sfn_sf:%d pdus:%d - TX_REQ is within window\n",
__FUNCTION__,
......@@ -2678,9 +2621,7 @@ void pnf_nr_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7
case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC:
pnf_nr_handle_dl_node_sync(pRecvMsg, recvMsgLen, pnf_p7, rx_hr_time);
break;
case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
//printf("\nEntering pnf_handle_dl_tti_request sfn=%d,slot=%d \n",pnf_p7->sfn,pnf_p7->slot);
pnf_handle_dl_tti_request(pRecvMsg, recvMsgLen, pnf_p7);
break;
case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
......@@ -2989,13 +2930,11 @@ void pnf_nr_nfapi_p7_read_dispatch_message(pnf_p7_t* pnf_p7, uint32_t now_hr_tim
struct sockaddr_in remote_addr;
socklen_t remote_addr_size = sizeof(remote_addr);
remote_addr.sin_family = 2; //hardcoded
do
{
// peek the header
uint8_t header_buffer[NFAPI_P7_HEADER_LENGTH];
recvfrom_result = recvfrom(pnf_p7->p7_sock, header_buffer, NFAPI_P7_HEADER_LENGTH, MSG_DONTWAIT | MSG_PEEK, (struct sockaddr*)&remote_addr, &remote_addr_size);
if(recvfrom_result > 0)
{
// get the segment size
......@@ -3272,7 +3211,7 @@ int pnf_nr_p7_message_pump(pnf_p7_t* pnf_p7)
FD_SET(pnf_p7->p7_sock, &rfds);
struct timeval timeout;
timeout.tv_sec = 1;
timeout.tv_sec = 100;
timeout.tv_usec = 0;
selectRetval = select(pnf_p7->p7_sock+1, &rfds, NULL, NULL, &timeout);
......
......@@ -265,3 +265,77 @@ int nfapi_pnf_ue_release_resp(nfapi_pnf_p7_config_t* config, nfapi_ue_release_re
return pnf_p7_pack_and_send_p7_message(_this, &(resp->header), sizeof(nfapi_ue_release_response_t));
}
//NR UPLINK INDICATION
int nfapi_pnf_p7_nr_slot_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_slot_indication_scf_t* ind)
{
if(config == NULL || ind == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
return -1;
}
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_nr_rx_data_indication_t));
}
int nfapi_pnf_p7_nr_rx_data_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_rx_data_indication_t* ind)
{
if(config == NULL || ind == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
return -1;
}
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_nr_rx_data_indication_t));
}
int nfapi_pnf_p7_nr_crc_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_crc_indication_t* ind)
{
if(config == NULL || ind == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
return -1;
}
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_nr_crc_indication_t));
}
int nfapi_pnf_p7_nr_srs_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_srs_indication_t* ind)
{
if(config == NULL || ind == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
return -1;
}
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_nr_srs_indication_t));
}
int nfapi_pnf_p7_nr_uci_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_uci_indication_t* ind)
{
if(config == NULL || ind == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
return -1;
}
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_nr_uci_indication_t));
}
int nfapi_pnf_p7_nr_rach_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_rach_indication_t* ind)
{
if(config == NULL || ind == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
return -1;
}
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_nr_rach_indication_t));
}
......@@ -278,7 +278,7 @@ void *fapi_thread_start(void *ptr) {
if(instance->tick == 1000) {
if(instance->tx_byte_count > 0) {
printf("[FAPI] Tx rate %u bytes/sec\n", instance->tx_byte_count);
printf("[FAPI] Tx rate %d bytes/sec\n", instance->tx_byte_count);
instance->tx_byte_count = 0;
}
......@@ -319,7 +319,7 @@ void *fapi_thread_start(void *ptr) {
millisec = now_ts.tv_nsec / 1e6;
if(last_millisec != -1 && ((last_millisec + 1 ) % 1000) != millisec) {
printf("*** missing millisec %u %u\n", last_millisec, millisec);
printf("*** missing millisec %d %d\n", last_millisec, millisec);
catchup = millisec - last_millisec - 1;
}
......
......@@ -25,7 +25,6 @@
#define TIME2TIMEHR(_time) (((uint32_t)(_time.tv_sec) & 0xFFF) << 20 | ((uint32_t)(_time.tv_usec) & 0xFFFFF))
typedef struct {
uint8_t* buffer;
uint16_t length;
......
......@@ -852,7 +852,15 @@ typedef struct nfapi_vnf_p7_config
* use the codec_config.deallocate function to release it at a future point
*/
int (*nrach_indication)(struct nfapi_vnf_p7_config* config, nfapi_nrach_indication_t* ind);
//The NR indication functions below copy uplink information received at the VNF into the UL info struct
int (*nr_slot_indication)(nfapi_nr_slot_indication_scf_t* ind);
int (*nr_crc_indication)(nfapi_nr_crc_indication_t* ind);
int (*nr_rx_data_indication)(nfapi_nr_rx_data_indication_t* ind);
int (*nr_uci_indication)(nfapi_nr_uci_indication_t* ind);
int (*nr_rach_indication)(nfapi_nr_rach_indication_t* ind);
int (*nr_srs_indication)(nfapi_nr_srs_indication_t* ind);
/*! A callback for any vendor extension messages
* \param config A pointer to the vnf p7 configuration
* \param msg A data structure for the decoded vendor extention message allocated
......
......@@ -22,7 +22,7 @@
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include "vnf_p7.h"
#define SYNC_CYCLE_COUNT 2
......@@ -456,7 +456,7 @@ int send_mac_subframe_indications(vnf_p7_t* vnf_p7)
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)
{
int sendto_result = sendto(vnf_p7->socket, msg, len, 0, (struct sockaddr*)&(p7_info->remote_addr), sizeof(p7_info->remote_addr));
//printf("\nSending p7 message sfn=%d,slot=%d\n",vnf_p7->p7_connections->sfn,vnf_p7->p7_connections->slot);
//printf("P7 msg sent \n");
if(sendto_result != len)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() sendto_result %d %d\n", __FUNCTION__, sendto_result, errno);
......@@ -533,6 +533,7 @@ int vnf_nr_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t*
nfapi_p7_update_transmit_timestamp(buffer, calculate_transmit_timestamp(p7_connection->sfn, p7_connection->slot, vnf_p7->slot_start_time_hr));
send_result = vnf_send_p7_msg(vnf_p7, p7_connection, &tx_buffer[0], segment_size);
}
}
else
......@@ -549,7 +550,6 @@ int vnf_nr_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t*
}
p7_connection->sequence_number++;
return send_result;
}
else
......@@ -667,7 +667,6 @@ int vnf_build_send_dl_node_sync(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t
int vnf_nr_build_send_dl_node_sync(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info)
{
nfapi_nr_dl_node_sync_t dl_node_sync;
memset(&dl_node_sync, 0, sizeof(dl_node_sync));
......@@ -1290,7 +1289,7 @@ void vnf_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
{
if(phy->in_sync == 0)
{
NFAPI_TRACE(NFAPI_TRACE_NOTE, "VNF P7 In Sync with phy (phy_id:%d)\n", phy->phy_id);
//NFAPI_TRACE(NFAPI_TRACE_NOTE, "VNF P7 In Sync with phy (phy_id:%d)\n", phy->phy_id);
if(vnf_p7->_public.sync_indication)
(vnf_p7->_public.sync_indication)(&(vnf_p7->_public), 1);
......@@ -1454,6 +1453,161 @@ void vnf_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
}
}
//NR HANDLES FOR UPLINK MESSAGES
void vnf_handle_nr_slot_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
{
// ensure it's valid
if (pRecvMsg == NULL || vnf_p7 == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
}
else
{
nfapi_nr_slot_indication_scf_t ind;
if(nfapi_nr_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__);
}
else
{
if(vnf_p7->_public.nr_slot_indication)
{
(vnf_p7->_public.nr_slot_indication)(&ind);
}
}
}
}
void vnf_handle_nr_rx_data_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
{
// ensure it's valid
if (pRecvMsg == NULL || vnf_p7 == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
}
else
{
nfapi_nr_rx_data_indication_t ind;
if(nfapi_nr_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__);
}
else
{
if(vnf_p7->_public.nr_rx_data_indication)
{
(vnf_p7->_public.nr_rx_data_indication)(&ind);
}
}
}
}
void vnf_handle_nr_crc_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
{
// ensure it's valid
if (pRecvMsg == NULL || vnf_p7 == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
}
else
{
nfapi_nr_crc_indication_t ind;
if(nfapi_nr_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__);
}
else
{
if(vnf_p7->_public.nr_crc_indication)
{
(vnf_p7->_public.nr_crc_indication)(&ind);
}
}
}
}
void vnf_handle_nr_srs_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
{
// ensure it's valid
if (pRecvMsg == NULL || vnf_p7 == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
}
else
{
nfapi_nr_srs_indication_t ind;
if(nfapi_nr_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__);
}
else
{
if(vnf_p7->_public.nr_srs_indication)
{
(vnf_p7->_public.nr_srs_indication)(&ind);
}
}
}
}
void vnf_handle_nr_uci_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
{
// ensure it's valid
if (pRecvMsg == NULL || vnf_p7 == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
}
else
{
nfapi_nr_uci_indication_t ind;
if(nfapi_nr_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__);
}
else
{
if(vnf_p7->_public.nr_uci_indication)
{
(vnf_p7->_public.nr_uci_indication)(&ind);
}
}
}
}
void vnf_handle_nr_rach_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
{
// ensure it's valid
if (pRecvMsg == NULL || vnf_p7 == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
}
else
{
nfapi_nr_rach_indication_t ind;
if(nfapi_nr_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__);
}
else
{
if(vnf_p7->_public.nr_rach_indication)
{
(vnf_p7->_public.nr_rach_indication)(&ind);
}
}
}
}
void vnf_nr_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
{
//printf("received UL Node sync");
......@@ -1484,6 +1638,8 @@ void vnf_nr_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7
// divide by 2 using shift operator
uint32_t latency = (tx_2_rx - pnf_proc_time) >> 1;
//phy->in_sync = 1;
if(!(phy->filtered_adjust))
{
phy->latency[phy->min_sync_cycle_count] = latency;
......@@ -1533,17 +1689,24 @@ void vnf_nr_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
//NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%4d/%1d) %d.%d PNF to VNF phy_id:%2d (t1/2/3/4:%8u, %8u, %8u, %8u) txrx:%4u procT:%3u latency(us):%4d(avg:%4d) offset(us):%8d filtered(us):%8d wrap[t1:%u t2:%u]\n",
// phy->sfn, phy->slot, ts.tv_sec, ts.tv_nsec, ind.header.phy_id,
// ind.t1, ind.t2, ind.t3, t4,
// tx_2_rx, pnf_proc_time, latency, phy->average_latency, phy->slot_offset, phy->slot_offset_filtered,
// (ind.t1<phy->previous_t1), (ind.t2<phy->previous_t2));
// NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%4d/%1d) %d.%d PNF to VNF phy_id:%2d (t1/2/3/4:%8u, %8u, %8u, %8u) txrx:%4u procT:%3u latency(us):%4d(avg:%4d) offset(us):%8d filtered(us):%8d wrap[t1:%u t2:%u]\n",
// phy->sfn, phy->slot, ts.tv_sec, ts.tv_nsec, ind.header.phy_id,
// ind.t1, ind.t2, ind.t3, t4,
// tx_2_rx, pnf_proc_time, latency, phy->average_latency, phy->slot_offset, phy->slot_offset_filtered,
// (ind.t1<phy->previous_t1), (ind.t2<phy->previous_t2));
}
}
if (phy->filtered_adjust && (phy->slot_offset_filtered > 1e6 || phy->slot_offset_filtered < -1e6))
{
{ struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%4d/%1d) %d.%d PNF to VNF phy_id:%2d (t1/2/3/4:%8u, %8u, %8u, %8u) txrx:%4u procT:%3u latency(us):%4d(avg:%4d) offset(us):%8d filtered(us):%8d wrap[t1:%u t2:%u]\n",
phy->sfn, phy->slot, ts.tv_sec, ts.tv_nsec, ind.header.phy_id,
ind.t1, ind.t2, ind.t3, t4,
tx_2_rx, pnf_proc_time, latency, phy->average_latency, phy->slot_offset, phy->slot_offset_filtered,
(ind.t1<phy->previous_t1), (ind.t2<phy->previous_t2));
phy->filtered_adjust = 0;
phy->zero_count=0;
phy->min_sync_cycle_count = 2;
......@@ -1575,7 +1738,7 @@ void vnf_nr_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7
sfn_slot_dec += (phy->slot_offset / 500);
NFAPI_TRACE(NFAPI_TRACE_NOTE, "PNF to VNF slot offset:%d sfn :%d slot:%d \n",phy->slot_offset,NFAPI_SFNSLOTDEC2SFN(sfn_slot_dec),NFAPI_SFNSLOTDEC2SLOT(sfn_slot_dec) );
//NFAPI_TRACE(NFAPI_TRACE_NOTE, "PNF to VNF slot offset:%d sfn :%d slot:%d \n",phy->slot_offset,NFAPI_SFNSLOTDEC2SFN(sfn_slot_dec),NFAPI_SFNSLOTDEC2SLOT(sfn_slot_dec) );
}
......@@ -2033,46 +2196,30 @@ void vnf_nr_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7
case NFAPI_TIMING_INFO:
vnf_nr_handle_timing_info(pRecvMsg, recvMsgLen, vnf_p7);
break;
case NFAPI_HARQ_INDICATION:
vnf_handle_harq_indication(pRecvMsg, recvMsgLen, vnf_p7);
case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION:
vnf_handle_nr_slot_indication(pRecvMsg, recvMsgLen, vnf_p7);
break;
case NFAPI_CRC_INDICATION:
vnf_handle_crc_indication(pRecvMsg, recvMsgLen, vnf_p7);
case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION:
vnf_handle_nr_rx_data_indication(pRecvMsg, recvMsgLen, vnf_p7);
break;
case NFAPI_RX_ULSCH_INDICATION:
vnf_handle_rx_ulsch_indication(pRecvMsg, recvMsgLen, vnf_p7);
case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION:
vnf_handle_nr_crc_indication(pRecvMsg, recvMsgLen, vnf_p7);
break;
case NFAPI_RACH_INDICATION:
vnf_handle_rach_indication(pRecvMsg, recvMsgLen, vnf_p7);
case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION:
vnf_handle_nr_uci_indication(pRecvMsg, recvMsgLen, vnf_p7);
break;
case NFAPI_SRS_INDICATION:
vnf_handle_srs_indication(pRecvMsg, recvMsgLen, vnf_p7);
case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION:
vnf_handle_nr_srs_indication(pRecvMsg, recvMsgLen, vnf_p7);
break;
case NFAPI_RX_SR_INDICATION:
vnf_handle_rx_sr_indication(pRecvMsg, recvMsgLen, vnf_p7);
break;
case NFAPI_RX_CQI_INDICATION:
vnf_handle_rx_cqi_indication(pRecvMsg, recvMsgLen, vnf_p7);
break;
case NFAPI_LBT_DL_INDICATION:
vnf_handle_lbt_dl_indication(pRecvMsg, recvMsgLen, vnf_p7);
break;
case NFAPI_NB_HARQ_INDICATION:
vnf_handle_nb_harq_indication(pRecvMsg, recvMsgLen, vnf_p7);
case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION:
vnf_handle_nr_rach_indication(pRecvMsg, recvMsgLen, vnf_p7);
break;
case NFAPI_NRACH_INDICATION:
vnf_handle_nrach_indication(pRecvMsg, recvMsgLen, vnf_p7);
break;
case NFAPI_UE_RELEASE_RESPONSE:
vnf_handle_ue_release_resp(pRecvMsg, recvMsgLen, vnf_p7);
......
......@@ -25,9 +25,14 @@
#include <errno.h>
#include "vnf_p7.h"
#include "nfapi_vnf.h"
#include "common/ran_context.h"
#include "openair1/PHY/defs_gNB.h"
#define FAPI2_IP_DSCP 0
extern RAN_CONTEXT_t RC;
nfapi_vnf_p7_config_t* nfapi_vnf_p7_config_create()
{
......@@ -92,7 +97,9 @@ 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)
{
{
struct PHY_VARS_gNB_s *gNB = RC.gNB[0];
uint8_t prev_slot = 0;
if(config == 0)
return -1;
......@@ -145,40 +152,14 @@ int nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t* config)
//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;
pselect_timeout.tv_sec = 100;
pselect_timeout.tv_nsec = 0;
// 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);
struct timespec ref_time;
clock_gettime(CLOCK_MONOTONIC, &ref_time);
uint8_t setup_time;
while(vnf_p7->terminate == 0)
{
{
fd_set rfds;
int maxSock = 0;
FD_ZERO(&rfds);
......@@ -188,239 +169,33 @@ int nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t* config)
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;
}
struct timespec curr_time;
clock_gettime(CLOCK_MONOTONIC, &curr_time);
setup_time = curr_time.tv_sec - ref_time.tv_sec;
if(setup_time > 10 && prev_slot != gNB->UL_INFO.slot){ //Give the VNF sufficient time to setup before starting scheduling
//Call the scheduler
pthread_mutex_lock(&gNB->UL_INFO_mutex);
gNB->UL_INFO.module_id = gNB->Mod_id;
gNB->UL_INFO.CC_id = gNB->CC_id;
gNB->if_inst->NR_UL_indication(&gNB->UL_INFO);
pthread_mutex_unlock(&gNB->UL_INFO_mutex);
prev_slot = gNB->UL_INFO.slot;
}
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;
}
selectRetval = pselect(maxSock+1, &rfds, NULL, NULL, &pselect_timeout, NULL);
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);
// pselect timed out, continue
}
else if(selectRetval > 0)
{
// have a p7 message
if(FD_ISSET(vnf_p7->socket, &rfds))
{
vnf_nr_p7_read_dispatch_message(vnf_p7);
{
vnf_nr_p7_read_dispatch_message(vnf_p7);
}
}
else
......@@ -432,7 +207,7 @@ struct timespec current_time;
}
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);
//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
{
......@@ -440,10 +215,7 @@ struct timespec current_time;
}
}
}
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "Closing p7 socket\n");
close(vnf_p7->socket);
......@@ -862,7 +634,6 @@ int nfapi_vnf_p7_ul_tti_req(nfapi_vnf_p7_config_t* config, nfapi_nr_ul_tti_reque
{
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);
}
......
......@@ -48,6 +48,8 @@
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "nfapi/oai_integration/vendor_ext.h"
#include "T.h"
//#define DEBUG_NR_PUCCH_RX 1
......
......@@ -17,6 +17,10 @@ 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){
}
void handle_nfapi_nr_csirs_pdu(PHY_VARS_gNB *gNB,
int frame, int slot,
nfapi_nr_dl_tti_csi_rs_pdu *csirs_pdu){
}
int l1_north_init_gNB(void){return 0;}
uint8_t slot_ahead=6;
......
......@@ -17,6 +17,10 @@ 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){
}
void handle_nfapi_nr_csirs_pdu(PHY_VARS_gNB *gNB,
int frame, int slot,
nfapi_nr_dl_tti_csi_rs_pdu *csirs_pdu){
}
int l1_north_init_gNB(void){return 0;}
uint8_t slot_ahead=6;
......
......@@ -181,71 +181,64 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
uint8_t number_dl_pdu = (DL_req==NULL) ? 0 : DL_req->dl_tti_request_body.nPDUs;
uint8_t number_ul_dci_pdu = (UL_dci_req==NULL) ? 0 : UL_dci_req->numPdus;
uint8_t number_ul_tti_pdu = (UL_tti_req==NULL) ? 0 : UL_tti_req->n_pdus;
uint8_t number_tx_data_pdu = (TX_req == NULL) ? 0 : TX_req->Number_of_PDUs;
if (NFAPI_MODE == NFAPI_MONOLITHIC){
if (DL_req != NULL && TX_req!=NULL)
LOG_D(PHY,"NFAPI: Sched_INFO:SFN/SLOT:%04d/%d DL_req:SFN/SLO:%04d/%d:dl_pdu:%d tx_req:SFN/SLOT:%04d/%d:pdus:%d;ul_dci %d ul_tti %d\n",
frame,slot,
DL_req->SFN,DL_req->Slot,number_dl_pdu,
TX_req->SFN,TX_req->Slot,TX_req->Number_of_PDUs,
number_ul_dci_pdu,number_ul_tti_pdu);
int pdcch_received=0;
gNB->num_pdsch_rnti[slot]=0;
for (int i=0; i<gNB->number_of_nr_dlsch_max; i++) {
gNB->dlsch[i][0]->rnti=0;
gNB->dlsch[i][0]->harq_mask=0;
}
if (DL_req != NULL && TX_req!=NULL)
LOG_D(PHY,"NFAPI: Sched_INFO:SFN/SLOT:%04d/%d DL_req:SFN/SLO:%04d/%d:dl_pdu:%d tx_req:SFN/SLOT:%04d/%d:pdus:%d;ul_dci %d ul_tti %d\n",
frame,slot,
DL_req->SFN,DL_req->Slot,number_dl_pdu,
TX_req->SFN,TX_req->Slot,TX_req->Number_of_PDUs,
number_ul_dci_pdu,number_ul_tti_pdu);
int pdcch_received=0;
gNB->num_pdsch_rnti[slot]=0;
for (int i=0; i<gNB->number_of_nr_dlsch_max; i++) {
gNB->dlsch[i][0]->rnti=0;
gNB->dlsch[i][0]->harq_mask=0;
}
for (int i=0;i<number_dl_pdu;i++) {
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu = &DL_req->dl_tti_request_body.dl_tti_pdu_list[i];
LOG_D(PHY,"NFAPI: dl_pdu %d : type %d\n",i,dl_tti_pdu->PDUType);
switch (dl_tti_pdu->PDUType) {
case NFAPI_NR_DL_TTI_SSB_PDU_TYPE:
if(NFAPI_MODE != NFAPI_MODE_VNF)
handle_nr_nfapi_ssb_pdu(gNB,frame,slot,
dl_tti_pdu);
for (int i=0;i<number_dl_pdu;i++) {
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu = &DL_req->dl_tti_request_body.dl_tti_pdu_list[i];
LOG_D(PHY,"NFAPI: dl_pdu %d : type %d\n",i,dl_tti_pdu->PDUType);
switch (dl_tti_pdu->PDUType) {
case NFAPI_NR_DL_TTI_SSB_PDU_TYPE:
handle_nr_nfapi_ssb_pdu(gNB,frame,slot,
dl_tti_pdu);
break;
break;
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");
handle_nfapi_nr_pdcch_pdu(gNB,
frame, slot,
&dl_tti_pdu->pdcch_pdu);
pdcch_received = 1;
break;
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");
if(NFAPI_MODE != NFAPI_MODE_VNF)
handle_nfapi_nr_pdcch_pdu(gNB,
frame, slot,
&dl_tti_pdu->pdcch_pdu);
pdcch_received = 1;
case NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE:
LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE for %d.%d\n",frame,slot,DL_req->SFN,DL_req->Slot);
handle_nfapi_nr_csirs_pdu(gNB,
frame, slot,
&dl_tti_pdu->csi_rs_pdu);
break;
break;
case NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE:
LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE for %d.%d\n",frame,slot,DL_req->SFN,DL_req->Slot);
handle_nfapi_nr_csirs_pdu(gNB,
frame, slot,
&dl_tti_pdu->csi_rs_pdu);
break;
case NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE:
{
LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE for %d.%d\n",frame,slot,DL_req->SFN,DL_req->Slot);
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdu->pdsch_pdu.pdsch_pdu_rel15;
uint16_t pduIndex = pdsch_pdu_rel15->pduIndex;
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);
case NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE:
LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE for %d.%d\n",frame,slot,DL_req->SFN,DL_req->Slot);
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdu->pdsch_pdu.pdsch_pdu_rel15;
uint16_t pduIndex = pdsch_pdu_rel15->pduIndex;
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;
handle_nr_nfapi_pdsch_pdu(gNB,frame,slot,&dl_tti_pdu->pdsch_pdu, sdu);
break;
}
}
}
// 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:
......@@ -264,30 +257,22 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
break;
}
}
if(NFAPI_MODE != NFAPI_MONOLITHIC && number_ul_tti_pdu>0)
{
oai_nfapi_ul_tti_req(UL_tti_req);
}
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);
}
if (NFAPI_MODE == NFAPI_MODE_VNF) { //If VNF, oai_nfapi functions send respective p7 msgs to PNF for which nPDUs is greater than 0
if(number_ul_tti_pdu>0)
oai_nfapi_ul_tti_req(UL_tti_req);
if (number_ul_dci_pdu>0)
oai_nfapi_ul_dci_req(UL_dci_req);
}
if (number_dl_pdu>0)
oai_nfapi_dl_tti_req(DL_req);
if (number_tx_data_pdu>0)
oai_nfapi_tx_data_req(TX_req);
}
}
......@@ -147,14 +147,14 @@ 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 == NFAPI_MONOLITHIC || NFAPI_MODE == NFAPI_MODE_PNF) {
for (int i=0; i<fp->Lmax; i++) {
if (gNB->ssb[i].active) {
nr_common_signal_procedures(gNB,frame,slot,gNB->ssb[i].ssb_pdu);
gNB->ssb[i].active = false;
}
for (int i=0; i<fp->Lmax; i++) {
if (gNB->ssb[i].active) {
nr_common_signal_procedures(gNB,frame,slot,gNB->ssb[i].ssb_pdu);
gNB->ssb[i].active = false;
}
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_COMMON_TX,0);
int pdcch_pdu_id=find_nr_pdcch(frame,slot,gNB,SEARCH_EXIST);
......
......@@ -226,12 +226,17 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(module_id_t module_idP,
void processSlotTX(void *arg) {}
//nFAPI P7 dummy functions
//nFAPI P7 dummy functions to avoid linking errors
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_nr_rx_data_indication(nfapi_nr_rx_data_indication_t *ind) { return(0); }
int oai_nfapi_nr_crc_indication(nfapi_nr_crc_indication_t *ind) { return(0); }
int oai_nfapi_nr_srs_indication(nfapi_nr_srs_indication_t *ind) { return(0); }
int oai_nfapi_nr_uci_indication(nfapi_nr_uci_indication_t *ind) { return(0); }
int oai_nfapi_nr_rach_indication(nfapi_nr_rach_indication_t *ind) { return(0); }
// needed for some functions
openair0_config_t openair0_cfg[MAX_CARDS];
......
......@@ -8,6 +8,12 @@ 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_nr_rx_data_indication(nfapi_nr_rx_data_indication_t *ind) { return(0); }
int oai_nfapi_nr_crc_indication(nfapi_nr_crc_indication_t *ind) { return(0); }
int oai_nfapi_nr_srs_indication(nfapi_nr_srs_indication_t *ind) { return(0); }
int oai_nfapi_nr_uci_indication(nfapi_nr_uci_indication_t *ind) { return(0); }
int oai_nfapi_nr_rach_indication(nfapi_nr_rach_indication_t *ind) { 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;
......
......@@ -3,9 +3,15 @@ int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) { re
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_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_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_nr_rx_data_indication(nfapi_nr_rx_data_indication_t *ind) { return(0); }
int oai_nfapi_nr_crc_indication(nfapi_nr_crc_indication_t *ind) { return(0); }
int oai_nfapi_nr_srs_indication(nfapi_nr_srs_indication_t *ind) { return(0); }
int oai_nfapi_nr_uci_indication(nfapi_nr_uci_indication_t *ind) { return(0); }
int oai_nfapi_nr_rach_indication(nfapi_nr_rach_indication_t *ind) { 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); }
......
......@@ -81,6 +81,11 @@ 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_nr_rx_data_indication(nfapi_nr_rx_data_indication_t *ind) { return(0); }
int oai_nfapi_nr_crc_indication(nfapi_nr_crc_indication_t *ind) { return(0); }
int oai_nfapi_nr_srs_indication(nfapi_nr_srs_indication_t *ind) { return(0); }
int oai_nfapi_nr_uci_indication(nfapi_nr_uci_indication_t *ind) { return(0); }
int oai_nfapi_nr_rach_indication(nfapi_nr_rach_indication_t *ind) { return(0); }
void
rrc_data_ind(
......
......@@ -212,6 +212,11 @@ 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_nr_rx_data_indication(nfapi_nr_rx_data_indication_t *ind) { return(0); }
int oai_nfapi_nr_crc_indication(nfapi_nr_crc_indication_t *ind) { return(0); }
int oai_nfapi_nr_srs_indication(nfapi_nr_srs_indication_t *ind) { return(0); }
int oai_nfapi_nr_uci_indication(nfapi_nr_uci_indication_t *ind) { return(0); }
int oai_nfapi_nr_rach_indication(nfapi_nr_rach_indication_t *ind) { return(0); }
int nr_derive_key(int alg_type, uint8_t alg_id,
const uint8_t key[32], uint8_t **out)
......
......@@ -146,6 +146,11 @@ 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_nr_rx_data_indication(nfapi_nr_rx_data_indication_t *ind) { return(0); }
int oai_nfapi_nr_crc_indication(nfapi_nr_crc_indication_t *ind) { return(0); }
int oai_nfapi_nr_srs_indication(nfapi_nr_srs_indication_t *ind) { return(0); }
int oai_nfapi_nr_uci_indication(nfapi_nr_uci_indication_t *ind) { return(0); }
int oai_nfapi_nr_rach_indication(nfapi_nr_rach_indication_t *ind) { return(0); }
int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { return(0); }
......
......@@ -219,29 +219,30 @@ void *gNB_app_task(void *args_p)
//registered_gnb = 0;
__attribute__((unused)) uint32_t register_gnb_pending = gNB_app_register (gnb_id_start, gnb_id_end);
}
if (RC.nb_nr_inst > 0) {
if (NODE_IS_CU(RC.nrrrc[0]->node_type)) {
if (NODE_IS_CU(RC.nrrrc[0]->node_type)) {
if (itti_create_task(TASK_CU_F1, F1AP_CU_task, NULL) < 0) {
LOG_E(F1AP, "Create task for F1AP CU failed\n");
AssertFatal(1==0,"exiting");
}
}
if (itti_create_task(TASK_CU_F1, F1AP_CU_task, NULL) < 0) {
LOG_E(F1AP, "Create task for F1AP CU failed\n");
AssertFatal(1==0,"exiting");
}
}
if (NODE_IS_DU(RC.nrrrc[0]->node_type)) {
if (NODE_IS_DU(RC.nrrrc[0]->node_type)) {
if (itti_create_task(TASK_DU_F1, F1AP_DU_task, NULL) < 0) {
LOG_E(F1AP, "Create task for F1AP DU failed\n");
AssertFatal(1==0,"exiting");
if (itti_create_task(TASK_DU_F1, F1AP_DU_task, NULL) < 0) {
LOG_E(F1AP, "Create task for F1AP DU failed\n");
AssertFatal(1==0,"exiting");
}
// configure F1AP here for F1C
LOG_I(GNB_APP,"ngran_gNB_DU: Allocating ITTI message for F1AP_SETUP_REQ\n");
msg_p = itti_alloc_new_message (TASK_GNB_APP, 0, F1AP_SETUP_REQ);
RCconfig_NR_DU_F1(msg_p, 0);
itti_send_msg_to_task (TASK_DU_F1, GNB_MODULE_ID_TO_INSTANCE(0), msg_p);
}
// configure F1AP here for F1C
LOG_I(GNB_APP,"ngran_gNB_DU: Allocating ITTI message for F1AP_SETUP_REQ\n");
msg_p = itti_alloc_new_message (TASK_GNB_APP, 0, F1AP_SETUP_REQ);
RCconfig_NR_DU_F1(msg_p, 0);
itti_send_msg_to_task (TASK_DU_F1, GNB_MODULE_ID_TO_INSTANCE(0), msg_p);
}
do {
// Wait for a message
itti_receive_msg (TASK_GNB_APP, &msg_p);
......
......@@ -1383,7 +1383,6 @@ void NRRCConfig(void) {
config_get( GNBSParams,sizeof(GNBSParams)/sizeof(paramdef_t),NULL);
RC.nb_nr_inst = GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt;
// Get num MACRLC instances
config_getlist( &MACRLCParamList,NULL,0, NULL);
......
......@@ -60,6 +60,8 @@
uint16_t nr_pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 };
uint8_t vnf_first_sched_entry = 1;
void clear_mac_stats(gNB_MAC_INST *gNB) {
memset((void*)gNB->UE_info.mac_stats,0,MAX_MOBILES_PER_GNB*sizeof(NR_mac_stats_t));
}
......@@ -150,34 +152,32 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
gNB->pdu_index[CC_idP] = 0;
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;
DL_req[CC_idP].dl_tti_request_body.nPDUs = 0;
DL_req[CC_idP].dl_tti_request_body.nGroup = 0;
//DL_req[CC_idP].dl_tti_request_body.transmission_power_pcfich = 6000;
memset(pdcch, 0, sizeof(**pdcch) * MAX_NUM_BWP * MAX_NUM_CORESET);
DL_req[CC_idP].SFN = frameP;
DL_req[CC_idP].Slot = slotP;
DL_req[CC_idP].dl_tti_request_body.nPDUs = 0;
DL_req[CC_idP].dl_tti_request_body.nGroup = 0;
//DL_req[CC_idP].dl_tti_request_body.transmission_power_pcfich = 6000;
memset(pdcch, 0, sizeof(**pdcch) * MAX_NUM_BWP * MAX_NUM_CORESET);
UL_dci_req[CC_idP].SFN = frameP;
UL_dci_req[CC_idP].Slot = slotP;
UL_dci_req[CC_idP].numPdus = 0;
UL_dci_req[CC_idP].SFN = frameP;
UL_dci_req[CC_idP].Slot = slotP;
UL_dci_req[CC_idP].numPdus = 0;
/* advance last round's future UL_tti_req to be ahead of current frame/slot */
future_ul_tti_req->SFN = (slotP == 0 ? frameP : frameP + 1) % 1024;
/* future_ul_tti_req->Slot is fixed! */
future_ul_tti_req->n_pdus = 0;
future_ul_tti_req->n_ulsch = 0;
future_ul_tti_req->n_ulcch = 0;
future_ul_tti_req->n_group = 0;
/* advance last round's future UL_tti_req to be ahead of current frame/slot */
future_ul_tti_req->SFN = (slotP == 0 ? frameP : frameP + 1) % 1024;
LOG_D(MAC,"Future_ul_tti SFN = %d for slot %d \n", future_ul_tti_req->SFN, (slotP + num_slots - 1) % num_slots);
/* future_ul_tti_req->Slot is fixed! */
future_ul_tti_req->n_pdus = 0;
future_ul_tti_req->n_ulsch = 0;
future_ul_tti_req->n_ulcch = 0;
future_ul_tti_req->n_group = 0;
/* UL_tti_req is a simple pointer into the current UL_tti_req_ahead, i.e.,
* it walks over UL_tti_req_ahead in a circular fashion */
gNB->UL_tti_req[CC_idP] = &gNB->UL_tti_req_ahead[CC_idP][slotP];
/* UL_tti_req is a simple pointer into the current UL_tti_req_ahead, i.e.,
* it walks over UL_tti_req_ahead in a circular fashion */
gNB->UL_tti_req[CC_idP] = &gNB->UL_tti_req_ahead[CC_idP][slotP];
TX_req[CC_idP].Number_of_PDUs = 0;
TX_req[CC_idP].Number_of_PDUs = 0;
}
}
/*
void check_nr_ul_failure(module_id_t module_idP,
......@@ -401,6 +401,22 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
memset(&vrb_map_UL[last_slot * MAX_BWP_SIZE], 0, sizeof(uint16_t) * MAX_BWP_SIZE);
clear_nr_nfapi_information(RC.nrmac[module_idP], CC_id, frame, slot);
/*VNF first entry into scheduler. Since frame numbers for future_ul_tti_req of some future slots
will not be set before we encounter them, set them here */
if (NFAPI_MODE == NFAPI_MODE_VNF){
if(vnf_first_sched_entry == 1)
{
for (int i = 0; i<num_slots; i++){
if(i < slot)
gNB->UL_tti_req_ahead[CC_id][i].SFN = (frame + 1) % 1024;
else
gNB->UL_tti_req_ahead[CC_id][i].SFN = frame;
}
vnf_first_sched_entry = 0;
}
}
}
......@@ -429,7 +445,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
schedule_nr_prach(module_idP, f, s);
}
// This schedule SR
// This schedule SR
nr_sr_reporting(module_idP, frame, slot);
// Schedule CSI-RS transmission
......
......@@ -47,6 +47,7 @@
/*Softmodem params*/
#include "executables/softmodem-common.h"
#include "../../../nfapi/oai_integration/vendor_ext.h"
////////////////////////////////////////////////////////
/////* DLSCH MAC PDU generation (6.1.2 TS 38.321) */////
......
......@@ -48,59 +48,83 @@ extern int oai_nfapi_crc_indication(nfapi_crc_indication_t *crc_ind);
extern int oai_nfapi_cqi_indication(nfapi_cqi_indication_t *cqi_ind);
extern int oai_nfapi_sr_indication(nfapi_sr_indication_t *ind);
extern int oai_nfapi_rx_ind(nfapi_rx_indication_t *ind);
extern int oai_nfapi_nr_slot_indication(nfapi_nr_slot_indication_scf_t *ind);
extern int oai_nfapi_nr_rx_data_indication(nfapi_nr_rx_data_indication_t *ind);
extern int oai_nfapi_nr_crc_indication(nfapi_nr_crc_indication_t *ind);
extern int oai_nfapi_nr_srs_indication(nfapi_nr_srs_indication_t *ind);
extern int oai_nfapi_nr_uci_indication(nfapi_nr_uci_indication_t *ind);
extern int oai_nfapi_nr_rach_indication(nfapi_nr_rach_indication_t *ind);
extern uint8_t nfapi_mode;
extern uint16_t sf_ahead;
extern uint16_t sl_ahead;
void handle_nr_rach(NR_UL_IND_t *UL_info) {
if (UL_info->rach_ind.number_of_pdus>0) {
LOG_D(MAC,"UL_info[Frame %d, Slot %d] Calling initiate_ra_proc RACH:SFN/SLOT:%d/%d\n",UL_info->frame,UL_info->slot, UL_info->rach_ind.sfn,UL_info->rach_ind.slot);
int npdus = UL_info->rach_ind.number_of_pdus;
for(int i = 0; i < npdus; i++) {
UL_info->rach_ind.number_of_pdus--;
if (UL_info->rach_ind.pdu_list[i].num_preamble>0)
AssertFatal(UL_info->rach_ind.pdu_list[i].num_preamble==1,
"More than 1 preamble not supported\n");
nr_initiate_ra_proc(UL_info->module_id,
UL_info->CC_id,
UL_info->rach_ind.sfn,
UL_info->rach_ind.slot,
UL_info->rach_ind.pdu_list[i].preamble_list[0].preamble_index,
UL_info->rach_ind.pdu_list[i].freq_index,
UL_info->rach_ind.pdu_list[i].symbol_index,
UL_info->rach_ind.pdu_list[i].preamble_list[0].timing_advance);
if(NFAPI_MODE == NFAPI_MODE_PNF) {
if (UL_info->rach_ind.number_of_pdus>0) {
LOG_D(PHY,"UL_info->UL_info->rach_ind.number_of_pdus:%d SFN/Slot:%d.%d \n", UL_info->rach_ind.number_of_pdus, UL_info->rach_ind.sfn,UL_info->rach_ind.slot);
oai_nfapi_nr_rach_indication(&UL_info->rach_ind);
UL_info->rach_ind.number_of_pdus = 0;
}
}
else{
if (UL_info->rach_ind.number_of_pdus>0) {
LOG_D(MAC,"UL_info[Frame %d, Slot %d] Calling initiate_ra_proc RACH:SFN/SLOT:%d/%d\n",UL_info->frame,UL_info->slot, UL_info->rach_ind.sfn,UL_info->rach_ind.slot);
int npdus = UL_info->rach_ind.number_of_pdus;
for(int i = 0; i < npdus; i++) {
UL_info->rach_ind.number_of_pdus--;
if (UL_info->rach_ind.pdu_list[i].num_preamble>0)
AssertFatal(UL_info->rach_ind.pdu_list[i].num_preamble==1,
"More than 1 preamble not supported\n");
nr_initiate_ra_proc(UL_info->module_id,
UL_info->CC_id,
UL_info->rach_ind.sfn,
UL_info->rach_ind.slot,
UL_info->rach_ind.pdu_list[i].preamble_list[0].preamble_index,
UL_info->rach_ind.pdu_list[i].freq_index,
UL_info->rach_ind.pdu_list[i].symbol_index,
UL_info->rach_ind.pdu_list[i].preamble_list[0].timing_advance);
}
}
}
}
void handle_nr_uci(NR_UL_IND_t *UL_info)
{
const module_id_t mod_id = UL_info->module_id;
const frame_t frame = UL_info->frame;
const sub_frame_t slot = UL_info->slot;
int num_ucis = UL_info->uci_ind.num_ucis;
nfapi_nr_uci_t *uci_list = UL_info->uci_ind.uci_list;
for (int i = 0; i < num_ucis; i++) {
switch (uci_list[i].pdu_type) {
case NFAPI_NR_UCI_PUSCH_PDU_TYPE:
LOG_E(MAC, "%s(): unhandled NFAPI_NR_UCI_PUSCH_PDU_TYPE\n", __func__);
break;
{
if(NFAPI_MODE == NFAPI_MODE_PNF) {
if (UL_info->uci_ind.num_ucis>0) {
LOG_D(PHY,"PNF Sending UL_info->num_ucis:%d PDU_type: %d, SFN/SF:%d.%d \n", UL_info->uci_ind.num_ucis, UL_info->uci_ind.uci_list[0].pdu_type ,UL_info->frame, UL_info->slot);
oai_nfapi_nr_uci_indication(&UL_info->uci_ind);
UL_info->uci_ind.num_ucis = 0;
}
}
else{
const module_id_t mod_id = UL_info->module_id;
const frame_t frame = UL_info->frame;
const sub_frame_t slot = UL_info->slot;
int num_ucis = UL_info->uci_ind.num_ucis;
nfapi_nr_uci_t *uci_list = UL_info->uci_ind.uci_list;
LOG_D(MAC,"handling UCI SFN/slot: %d.%d, num_ucis: %d \n", frame,slot, num_ucis);
for (int i = 0; i < num_ucis; i++) {
switch (uci_list[i].pdu_type) {
case NFAPI_NR_UCI_PUSCH_PDU_TYPE:
LOG_E(MAC, "%s(): unhandled NFAPI_NR_UCI_PUSCH_PDU_TYPE\n", __func__);
break;
case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: {
const nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu = &uci_list[i].pucch_pdu_format_0_1;
handle_nr_uci_pucch_0_1(mod_id, frame, slot, uci_pdu);
break;
}
case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: {
const nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu = &uci_list[i].pucch_pdu_format_0_1;
handle_nr_uci_pucch_0_1(mod_id, frame, slot, uci_pdu);
break;
}
case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: {
const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu = &uci_list[i].pucch_pdu_format_2_3_4;
handle_nr_uci_pucch_2_3_4(mod_id, frame, slot, uci_pdu);
break;
case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: {
const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu = &uci_list[i].pucch_pdu_format_2_3_4;
handle_nr_uci_pucch_2_3_4(mod_id, frame, slot, uci_pdu);
break;
}
}
LOG_D(MAC, "UCI handled \n");
}
}
......@@ -109,60 +133,75 @@ void handle_nr_uci(NR_UL_IND_t *UL_info)
void handle_nr_ulsch(NR_UL_IND_t *UL_info)
{
if (UL_info->rx_ind.number_of_pdus > 0 && UL_info->crc_ind.number_crcs > 0) {
for (int i = 0; i < UL_info->rx_ind.number_of_pdus; i++) {
for (int j = 0; j < UL_info->crc_ind.number_crcs; j++) {
// find crc_indication j corresponding rx_indication i
const nfapi_nr_rx_data_pdu_t *rx = &UL_info->rx_ind.pdu_list[i];
const nfapi_nr_crc_t *crc = &UL_info->crc_ind.crc_list[j];
LOG_D(PHY,
"UL_info->crc_ind.pdu_list[%d].rnti:%04x "
"UL_info->rx_ind.pdu_list[%d].rnti:%04x\n",
j,
crc->rnti,
i,
rx->rnti);
if(NFAPI_MODE == NFAPI_MODE_PNF) {
if (UL_info->crc_ind.number_crcs>0) {
LOG_D(PHY,"UL_info->UL_info->crc_ind.number_crcs:%d CRC_IND:SFN/Slot:%d.%d\n", UL_info->crc_ind.number_crcs, UL_info->crc_ind.sfn, UL_info->crc_ind.slot);
oai_nfapi_nr_crc_indication(&UL_info->crc_ind);
UL_info->crc_ind.number_crcs = 0;
}
if (crc->rnti != rx->rnti)
continue;
if (UL_info->rx_ind.number_of_pdus>0) {
LOG_D(PHY,"UL_info->rx_ind.number_of_pdus:%d RX_IND:SFN/Slot:%d.%d \n", UL_info->rx_ind.number_of_pdus, UL_info->rx_ind.sfn, UL_info->rx_ind.slot);
oai_nfapi_nr_rx_data_indication(&UL_info->rx_ind);
UL_info->rx_ind.number_of_pdus = 0;
}
}
else{
if (UL_info->rx_ind.number_of_pdus > 0 && UL_info->crc_ind.number_crcs > 0) {
for (int i = 0; i < UL_info->rx_ind.number_of_pdus; i++) {
for (int j = 0; j < UL_info->crc_ind.number_crcs; j++) {
// find crc_indication j corresponding rx_indication i
const nfapi_nr_rx_data_pdu_t *rx = &UL_info->rx_ind.pdu_list[i];
const nfapi_nr_crc_t *crc = &UL_info->crc_ind.crc_list[j];
LOG_D(PHY,
"UL_info->crc_ind.pdu_list[%d].rnti:%04x "
"UL_info->rx_ind.pdu_list[%d].rnti:%04x\n",
j,
crc->rnti,
i,
rx->rnti);
if (crc->rnti != rx->rnti)
continue;
LOG_D(MAC,
"%4d.%2d Calling rx_sdu (CRC %s/tb_crc_status %d)\n",
UL_info->frame,
UL_info->slot,
crc->tb_crc_status ? "error" : "ok",
crc->tb_crc_status);
LOG_D(MAC,
"%4d.%2d Calling rx_sdu (CRC %s/tb_crc_status %d)\n",
UL_info->frame,
UL_info->slot,
crc->tb_crc_status ? "error" : "ok",
crc->tb_crc_status);
/* if CRC passes, pass PDU, otherwise pass NULL as error indication */
nr_rx_sdu(UL_info->module_id,
UL_info->CC_id,
UL_info->rx_ind.sfn,
UL_info->rx_ind.slot,
rx->rnti,
crc->tb_crc_status ? NULL : rx->pdu,
rx->pdu_length,
rx->timing_advance,
rx->ul_cqi,
rx->rssi);
handle_nr_ul_harq(UL_info->module_id, UL_info->frame, UL_info->slot, crc);
break;
} // for (j=0;j<UL_info->crc_ind.number_crcs;j++)
} // for (i=0;i<UL_info->rx_ind.number_of_pdus;i++)
/* if CRC passes, pass PDU, otherwise pass NULL as error indication */
nr_rx_sdu(UL_info->module_id,
UL_info->CC_id,
UL_info->rx_ind.sfn,
UL_info->rx_ind.slot,
rx->rnti,
crc->tb_crc_status ? NULL : rx->pdu,
rx->pdu_length,
rx->timing_advance,
rx->ul_cqi,
rx->rssi);
handle_nr_ul_harq(UL_info->module_id, UL_info->frame, UL_info->slot, crc);
break;
} // for (j=0;j<UL_info->crc_ind.number_crcs;j++)
} // for (i=0;i<UL_info->rx_ind.number_of_pdus;i++)
UL_info->crc_ind.number_crcs = 0;
UL_info->rx_ind.number_of_pdus = 0;
} else if (UL_info->rx_ind.number_of_pdus != 0
|| UL_info->crc_ind.number_crcs != 0) {
LOG_E(PHY,
"hoping not to have mis-match between CRC ind and RX ind - "
"hopefully the missing message is coming shortly "
"rx_ind:%d(SFN/SL:%d/%d) crc_ind:%d(SFN/SL:%d/%d) \n",
UL_info->rx_ind.number_of_pdus,
UL_info->rx_ind.sfn,
UL_info->rx_ind.slot,
UL_info->crc_ind.number_crcs,
UL_info->rx_ind.sfn,
UL_info->rx_ind.slot);
UL_info->crc_ind.number_crcs = 0;
UL_info->rx_ind.number_of_pdus = 0;
} else if (UL_info->rx_ind.number_of_pdus != 0
|| UL_info->crc_ind.number_crcs != 0) {
LOG_E(PHY,
"hoping not to have mis-match between CRC ind and RX ind - "
"hopefully the missing message is coming shortly "
"rx_ind:%d(SFN/SL:%d/%d) crc_ind:%d(SFN/SL:%d/%d) \n",
UL_info->rx_ind.number_of_pdus,
UL_info->rx_ind.sfn,
UL_info->rx_ind.slot,
UL_info->crc_ind.number_crcs,
UL_info->rx_ind.sfn,
UL_info->rx_ind.slot);
}
}
}
......@@ -181,7 +220,15 @@ 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);
handle_nr_rach(UL_info);
handle_nr_uci(UL_info);
// clear UL DCI prior to handling ULSCH
mac->UL_dci_req[CC_id].numPdus = 0;
handle_nr_ulsch(UL_info);
if (NFAPI_MODE != NFAPI_MODE_PNF) {
if (ifi->CC_mask==0) {
ifi->current_frame = UL_info->frame;
ifi->current_slot = UL_info->slot;
......@@ -191,16 +238,7 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
}
ifi->CC_mask |= (1<<CC_id);
}
handle_nr_rach(UL_info);
handle_nr_uci(UL_info);
// clear HI prior to handling ULSCH
mac->UL_dci_req[CC_id].numPdus = 0;
handle_nr_ulsch(UL_info);
if (NFAPI_MODE != NFAPI_MODE_PNF) {
if (ifi->CC_mask == ((1<<MAX_NUM_CCs)-1)) {
/*
eNB_dlsch_ulsch_scheduler(module_id,
......
......@@ -28,6 +28,7 @@ L1s = (
remote_n_portc = 50001; // vnf p5 port
local_n_portd = 50010; // pnf p7 port
remote_n_portd = 50011; // vnf p7 port
pusch_proc_threads = 8;
}
);
......@@ -42,5 +43,7 @@ RUs = (
max_pdschReferenceSignalPower = -27;
max_rxgain = 114;
sdr_addrs = "type=x300"; // USRP type
clock_src = "external";
time_src = "external";
}
);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment