Merge remote-tracking branch 'origin/nfapi-fixes' into integration_2025_w04 (!2999)
Repair nFAPI in 5G Add 5G nFAPI in OAI/Make it it work. Many commits in this branch are basically bug fixes of things that don't work properly, such as - check for correct conditions (e.g. instance numbers in the RAN context) - remove artificial limitation (e.g. only one PUCCH per TDD period in the PNF) - improve performance (reduce big mallocs, make some static buffers such as a global ring buffer for nFAPI messages in the PNF) - fix bugs in nFAPI (e.g., increase maximum message size to ~64kB instead of 1500 bytes, because the latter is way too small for many TX_data.requests in 5G, and it will delay message arrival unduly) - fix bugs in message enc/dec (e.g., handle FDD in config.request) - adjust the L1 such that the condition "we run monolithic" is not necessery (e.g., some message numbers in nFAPI struct where reset in MAC, instead of L1, and this breaks when running the PNF) There are instructions that explain how to set it up. Two CI tests have been added, one with COTS UE and MIMO in DL+UL in TDD numerology 1 (30kHz), and a second test with FDD mu=0 (15kHZ) in RFsimulator. These were some old to-dos that have been addressed. - test with COTS UE - 4x4 pipeline works good in DL, UL now also work - test in RFsim - make PNF status message - make FDD in u0 work
This commit is contained in:
@@ -49,7 +49,6 @@ void *aerial_vnf_nr_p7_config_init(void *ptr)
|
||||
init_queue(&gnb_rx_ind_queue);
|
||||
init_queue(&gnb_crc_ind_queue);
|
||||
init_queue(&gnb_uci_ind_queue);
|
||||
init_queue(&gnb_slot_ind_queue);
|
||||
|
||||
p7_vnf->config->port = p7_vnf->local_port;
|
||||
p7_vnf->config->sync_indication = NULL;
|
||||
@@ -335,12 +334,6 @@ int aerial_nr_config_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_co
|
||||
int aerial_nr_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_start_response_scf_t *resp)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Received NFAPI_START_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id);
|
||||
vnf_info *vnf = (vnf_info *)(config->user_data);
|
||||
pnf_info *pnf = vnf->pnfs;
|
||||
phy_info *phy = pnf->phys;
|
||||
vnf_p7_info *p7_vnf = vnf->p7_vnfs;
|
||||
|
||||
nfapi_vnf_p7_add_pnf((p7_vnf->config), phy->remote_addr, phy->remote_port, phy->id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -93,56 +93,17 @@ int aerial_phy_nr_uci_indication(nfapi_nr_uci_indication_t *ind)
|
||||
return 1;
|
||||
}
|
||||
|
||||
NR_Sched_Rsp_t g_sched_resp;
|
||||
void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, sub_frame_t slot, NR_Sched_Rsp_t* sched_info);
|
||||
int oai_fapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req);
|
||||
int oai_fapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req);
|
||||
int oai_fapi_tx_data_req(nfapi_nr_tx_data_request_t* tx_data_req);
|
||||
int oai_fapi_ul_dci_req(nfapi_nr_ul_dci_request_t* ul_dci_req);
|
||||
int oai_fapi_send_end_request(int cell, uint32_t frame, uint32_t slot);
|
||||
|
||||
int trigger_scheduler(nfapi_nr_slot_indication_scf_t *slot_ind)
|
||||
{
|
||||
|
||||
NR_UL_IND_t ind = {.frame = slot_ind->sfn, .slot = slot_ind->slot, };
|
||||
NR_UL_indication(&ind);
|
||||
// Call into the scheduler (this is hardcoded and should be init properly!)
|
||||
// memset(sched_resp, 0, sizeof(*sched_resp));
|
||||
gNB_dlsch_ulsch_scheduler(0, slot_ind->sfn, slot_ind->slot, &g_sched_resp);
|
||||
|
||||
bool send_slt_resp = false;
|
||||
if (g_sched_resp.DL_req.dl_tti_request_body.nPDUs> 0) {
|
||||
oai_fapi_dl_tti_req(&g_sched_resp.DL_req);
|
||||
send_slt_resp = true;
|
||||
}
|
||||
if (g_sched_resp.UL_tti_req.n_pdus > 0) {
|
||||
oai_fapi_ul_tti_req(&g_sched_resp.UL_tti_req);
|
||||
send_slt_resp = true;
|
||||
}
|
||||
if (g_sched_resp.TX_req.Number_of_PDUs > 0) {
|
||||
oai_fapi_tx_data_req(&g_sched_resp.TX_req);
|
||||
send_slt_resp = true;
|
||||
}
|
||||
if (g_sched_resp.UL_dci_req.numPdus > 0) {
|
||||
oai_fapi_ul_dci_req(&g_sched_resp.UL_dci_req);
|
||||
send_slt_resp = true;
|
||||
}
|
||||
if (send_slt_resp) {
|
||||
oai_fapi_send_end_request(0,slot_ind->sfn, slot_ind->slot);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
extern int trigger_scheduler(nfapi_nr_slot_indication_scf_t *slot_ind);
|
||||
|
||||
int aerial_phy_nr_slot_indication(nfapi_nr_slot_indication_scf_t *ind)
|
||||
{
|
||||
uint8_t vnf_slot_ahead = 0;
|
||||
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);
|
||||
LOG_D(MAC, "VNF SFN/Slot %d.%d \n", vnf_sfn, vnf_slot);
|
||||
// printf( "VNF SFN/Slot %d.%d \n", vnf_sfn, vnf_slot);
|
||||
LOG_D(MAC, "VNF SFN/Slot %d.%d \n", ind->sfn, ind->slot);
|
||||
trigger_scheduler(ind);
|
||||
|
||||
return 1;
|
||||
|
||||
@@ -25,4 +25,3 @@ queue_t gnb_rach_ind_queue;
|
||||
queue_t gnb_rx_ind_queue;
|
||||
queue_t gnb_crc_ind_queue;
|
||||
queue_t gnb_uci_ind_queue;
|
||||
queue_t gnb_slot_ind_queue;
|
||||
|
||||
@@ -6,4 +6,3 @@ extern queue_t gnb_rach_ind_queue;
|
||||
extern queue_t gnb_rx_ind_queue;
|
||||
extern queue_t gnb_crc_ind_queue;
|
||||
extern queue_t gnb_uci_ind_queue;
|
||||
extern queue_t gnb_slot_ind_queue;
|
||||
|
||||
@@ -544,7 +544,6 @@ int param_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi
|
||||
nfapi_resp.num_tlv++;
|
||||
nfapi_pnf_param_resp(config, &nfapi_resp);
|
||||
printf("[PNF] Sent NFAPI_PARAM_RESPONSE phy_id:%d number_of_tlvs:%u\n", req->header.phy_id, nfapi_resp.num_tlv);
|
||||
printf("[PNF] param request .. exit\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -763,7 +762,6 @@ int nr_param_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nf
|
||||
nfapi_nr_pnf_param_resp(config, &nfapi_resp);
|
||||
|
||||
printf("[PNF] Sent NFAPI_PNF_PARAM_RESPONSE phy_id:%d number_of_tlvs:%u\n", req->header.phy_id, nfapi_resp.num_tlv);
|
||||
printf("[PNF] param request .. exit\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1102,38 +1100,13 @@ void pnf_nr_phy_deallocate_p7_vendor_ext(void *header)
|
||||
free(header);
|
||||
}
|
||||
|
||||
notifiedFIFO_elt_t *l1tx_message_extract(PHY_VARS_gNB *gNB, int frame, int slot) {
|
||||
notifiedFIFO_elt_t *res;
|
||||
|
||||
//TODO: This needs to be reworked for nfapi to work
|
||||
res = pullNotifiedFIFO(&gNB->L1_tx_free);
|
||||
return res;
|
||||
}
|
||||
|
||||
int pnf_phy_ul_dci_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_nr_ul_dci_request_t *req) {
|
||||
extern void nr_schedule_ul_dci_req(PHY_VARS_gNB *gNB, nfapi_nr_ul_dci_request_t *UL_dci_req);
|
||||
int pnf_phy_ul_dci_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_nr_ul_dci_request_t *req)
|
||||
{
|
||||
DevAssert(RC.gNB != NULL && RC.gNB[0] != NULL);
|
||||
PHY_VARS_gNB *gNB = RC.gNB[0]; // phy_inst?
|
||||
|
||||
// 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);
|
||||
|
||||
struct PHY_VARS_gNB_s *gNB = RC.gNB[0];
|
||||
|
||||
// extract the next available thread message (priority to message with current slot, then free message)
|
||||
notifiedFIFO_elt_t *res;
|
||||
res = l1tx_message_extract(gNB, req->SFN, req->Slot);
|
||||
processingData_L1tx_t *msgTx = (processingData_L1tx_t *)NotifiedFifoData(res);
|
||||
|
||||
if (proc ==NULL)
|
||||
proc = &gNB->proc.L1_proc;
|
||||
|
||||
if (req->numPdus > 0) {
|
||||
for (int i=0; i<req->numPdus; i++) {
|
||||
if (req->ul_dci_pdu_list[i].PDUType == NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE) // only possible value 0: PDCCH PDU
|
||||
msgTx->ul_pdcch_pdu[i] = req->ul_dci_pdu_list[i];
|
||||
else
|
||||
LOG_E(PHY,"[PNF] UL_DCI_REQ sfn_slot:%d PDU[%d] - unknown pdu type:%d\n", NFAPI_SFNSLOT2DEC(req->SFN, req->Slot), req->numPdus-1, req->ul_dci_pdu_list[req->numPdus-1].PDUType);
|
||||
}
|
||||
}
|
||||
|
||||
pushNotifiedFIFO(&gNB->L1_tx_filled, res);
|
||||
nr_schedule_ul_dci_req(gNB, req);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1168,84 +1141,16 @@ int pnf_phy_hi_dci0_req(L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfa
|
||||
}
|
||||
|
||||
|
||||
int pnf_phy_dl_tti_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_nr_dl_tti_request_t *req) {
|
||||
if (RC.ru == 0) {
|
||||
return -1;
|
||||
}
|
||||
// from dl_tti_req_fn fptr
|
||||
extern void nr_schedule_dl_tti_req(PHY_VARS_gNB *gNB, nfapi_nr_dl_tti_request_t *DL_req);
|
||||
int pnf_phy_dl_tti_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_nr_dl_tti_request_t *DL_req)
|
||||
{
|
||||
DevAssert(proc == NULL);
|
||||
DevAssert(sync_var == 0);
|
||||
DevAssert(RC.gNB != NULL && RC.gNB[0] != NULL);
|
||||
PHY_VARS_gNB *gNB = RC.gNB[0]; // phy_inst?
|
||||
|
||||
if (RC.gNB == 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (RC.gNB[0] == 0) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
if (sync_var != 0) {
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() Main system not up - is this a dummy subframe?\n", __FUNCTION__);
|
||||
return -4;
|
||||
}
|
||||
|
||||
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: %p, PduIdx: %p,\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++) {
|
||||
// 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);
|
||||
notifiedFIFO_elt_t *res;
|
||||
res = l1tx_message_extract(gNB, sfn, slot);
|
||||
processingData_L1tx_t *msgTx = (processingData_L1tx_t *)NotifiedFifoData(res);
|
||||
|
||||
if (dl_tti_pdu_list[i].PDUType == NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE) {
|
||||
msgTx->pdcch_pdu[i] = dl_tti_pdu_list[i].pdcch_pdu; // copies all the received PDCCH PDUs
|
||||
}
|
||||
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(msgTx, sfn, slot, &dl_tti_pdu_list[i]);
|
||||
}
|
||||
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_pdu_t *tx_data = tx_data_request[sfn][slot][rel15_pdu->pduIndex];
|
||||
|
||||
if (tx_data != NULL) {
|
||||
uint8_t *dlsch_sdu = (uint8_t *)tx_data->TLVs[0].value.direct;
|
||||
//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);
|
||||
AssertFatal(msgTx->num_pdsch_slot < gNB->max_nb_pdsch,
|
||||
"Number of PDSCH PDUs %d exceeded the limit %d\n",
|
||||
msgTx->num_pdsch_slot,
|
||||
gNB->max_nb_pdsch);
|
||||
handle_nr_nfapi_pdsch_pdu(msgTx, 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 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(msgTx, sfn, slot, csi_rs_pdu);
|
||||
}
|
||||
else {
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() UNKNOWN:%d\n", __FUNCTION__, dl_tti_pdu_list[i].PDUType);
|
||||
}
|
||||
pushNotifiedFIFO(&gNB->L1_tx_filled, res);
|
||||
}
|
||||
|
||||
if(req->vendor_extension)
|
||||
free(req->vendor_extension);
|
||||
nr_schedule_dl_tti_req(gNB, DL_req);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1343,29 +1248,13 @@ int pnf_phy_dl_config_req(L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, n
|
||||
}
|
||||
|
||||
|
||||
extern void nr_schedule_tx_req(PHY_VARS_gNB *gNB, nfapi_nr_tx_data_request_t *TX_req);
|
||||
int pnf_phy_tx_data_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_nr_tx_data_request_t *req)
|
||||
{
|
||||
DevAssert(RC.gNB != NULL && RC.gNB[0] != NULL);
|
||||
PHY_VARS_gNB *gNB = RC.gNB[0]; // phy_inst?
|
||||
|
||||
int pnf_phy_tx_data_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_nr_tx_data_request_t *req) {
|
||||
uint16_t sfn = req->SFN;
|
||||
uint16_t slot = req->Slot;
|
||||
|
||||
if (req->Number_of_PDUs == 0)
|
||||
LOG_D(PHY,"%s() SFN/SLOT:%d%d PDUs:%d\n", __FUNCTION__, sfn, slot, req->Number_of_PDUs);
|
||||
|
||||
//if (req->pdu_list[0].TLVs->tag == NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST) {
|
||||
for (int i=0; i<req->Number_of_PDUs; i++) {
|
||||
// LOG_D(PHY,"%s() SFN/SF:%d%d number_of_pdus:%d [PDU:%d] pdu_length:%d pdu_index:%d num_segments:%d\n",
|
||||
// __FUNCTION__,
|
||||
// sfn, sf,
|
||||
// req->tx_request_body.number_of_pdus,
|
||||
// i,
|
||||
// req->tx_request_body.tx_pdu_list[i].pdu_length,
|
||||
// req->tx_request_body.tx_pdu_list[i].pdu_index,
|
||||
// req->tx_request_body.tx_pdu_list[i].num_segments
|
||||
// );
|
||||
// tx_request_pdu[sfn][sf][i] = &req->tx_request_body.tx_pdu_list[i];
|
||||
tx_data_request[sfn][slot][i] = &req->pdu_list[i];
|
||||
}
|
||||
//}
|
||||
nr_schedule_tx_req(gNB, req);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1396,77 +1285,13 @@ int pnf_phy_tx_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_tx_request_t *req) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern void nr_schedule_ul_tti_req(PHY_VARS_gNB *gNB, nfapi_nr_ul_tti_request_t *UL_tti_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)
|
||||
{
|
||||
DevAssert(RC.gNB != NULL && RC.gNB[0] != NULL);
|
||||
PHY_VARS_gNB *gNB = RC.gNB[0]; // phy_inst?
|
||||
|
||||
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
if (RC.gNB == 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (RC.gNB[0] == 0) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
if (sync_var != 0) {
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() Main system not up - is this a dummy slot?\n", __FUNCTION__);
|
||||
return -4;
|
||||
}
|
||||
uint16_t curr_sfn = req->SFN;
|
||||
uint16_t curr_slot = req->Slot;
|
||||
struct PHY_VARS_gNB_s *gNB = RC.gNB[0];
|
||||
|
||||
if (proc==NULL)
|
||||
proc = &gNB->proc.L1_proc;
|
||||
|
||||
nfapi_nr_ul_tti_request_number_of_pdus_t *ul_tti_pdu_list = req->pdus_list;
|
||||
|
||||
for (int i=0; i< req->n_pdus; i++) {
|
||||
switch (ul_tti_pdu_list[i].pdu_type) {
|
||||
case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE:
|
||||
//LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PUSCH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot);
|
||||
//curr_sfn = curr_sfn + 3; //Gokul
|
||||
nr_fill_ulsch(gNB,curr_sfn, curr_slot, &ul_tti_pdu_list[i].pusch_pdu);
|
||||
break;
|
||||
case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE:
|
||||
//LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PUCCH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot);
|
||||
nr_fill_pucch(gNB,curr_sfn, curr_slot, &ul_tti_pdu_list[i].pucch_pdu);
|
||||
break;
|
||||
case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE:
|
||||
//LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PRACH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot);
|
||||
nr_fill_prach(gNB, curr_sfn, curr_slot, &ul_tti_pdu_list[i].prach_pdu);
|
||||
if (gNB->RU_list[0]->if_south == LOCAL_RF) nr_fill_prach_ru(gNB->RU_list[0], curr_sfn, curr_slot, &ul_tti_pdu_list[i].prach_pdu);
|
||||
break;
|
||||
default:
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() PDU:%i UNKNOWN type :%d\n", __FUNCTION__, i, ul_tti_pdu_list[i].pdu_type);
|
||||
break;
|
||||
|
||||
}
|
||||
// //LOG_D(PHY, "%s() sfn/sf:%d PDU[%d] size:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), i, ul_config_pdu_list[i].pdu_size);
|
||||
// if (
|
||||
// ul_tti_pdu_list[i].pdu_type == NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE ||
|
||||
// ul_tti_pdu_list[i].pdu_type == NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE ||
|
||||
// ul_tti_pdu_list[i].pdu_type == NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE ||
|
||||
// ul_tti_pdu_list[i].pdu_type == NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE
|
||||
// ) {
|
||||
// //LOG_D(PHY, "%s() handle_nfapi_ul_pdu() for PDU:%d\n", __FUNCTION__, i);
|
||||
// // handle_nfapi_ul_pdu(eNB,proc,&ul_config_pdu_list[i],curr_sfn,curr_sf,req->ul_config_request_body.srs_present);
|
||||
|
||||
// // TODO: dont have an NR function for this, also srs_present flag not there
|
||||
|
||||
// } else {
|
||||
// NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() PDU:%i UNKNOWN type :%d\n", __FUNCTION__, i, ul_tti_pdu_list[i].pdu_type);
|
||||
// }
|
||||
}
|
||||
|
||||
nr_schedule_ul_tti_req(gNB, req);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1931,6 +1756,18 @@ int nr_start_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nf
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] HACK - Set p7_config global ready for subframe ind%s\n", __FUNCTION__);
|
||||
p7_config_g = p7_config;
|
||||
|
||||
// Hack? in the config request (which comes before the start request here),
|
||||
// we receive the SCS/mu. The PNF needs that for calculating frame/slot
|
||||
// offsets. However, the memory for the structure which actually keeps track
|
||||
// of the time, is only allocated here, so "pick" the SCS from memory.
|
||||
PHY_VARS_gNB *gNB = RC.gNB[0];
|
||||
DevAssert(gNB != NULL);
|
||||
// check that SCS has actually been received
|
||||
const nfapi_uint8_tlv_t *scs = &gNB->gNB_config.ssb_config.scs_common;
|
||||
DevAssert(scs->tl.tag == NFAPI_NR_CONFIG_SCS_COMMON_TAG);
|
||||
pnf_p7_t* pnf_p7 = (pnf_p7_t*)(p7_config);
|
||||
pnf_p7->mu = scs->value;
|
||||
|
||||
// Need to wait for main thread to create RU structures
|
||||
while (config_sync_var < 0) {
|
||||
usleep(5000000);
|
||||
@@ -1955,7 +1792,7 @@ int nr_start_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nf
|
||||
}
|
||||
|
||||
while(sync_var<0) {
|
||||
usleep(5000000);
|
||||
usleep(50000);
|
||||
printf("[PNF] waiting for OAI to be started\n");
|
||||
}
|
||||
|
||||
@@ -2430,24 +2267,53 @@ void oai_subframe_ind(uint16_t sfn, uint16_t sf) {
|
||||
}
|
||||
}
|
||||
|
||||
void handle_nr_slot_ind(uint16_t sfn, uint16_t slot) {
|
||||
#define SLOT_DURATION 800 // in microseconds
|
||||
static void maybe_slow_down_pnf(int mu)
|
||||
{
|
||||
/* uses a usleep to wait for approximately the same time period (300 us) */
|
||||
static struct timespec last_execution = {0};
|
||||
struct timespec current_execution;
|
||||
clock_gettime(CLOCK_REALTIME, ¤t_execution);
|
||||
// Calculate elapsed time since last execution
|
||||
long elapsed_time = (current_execution.tv_sec - last_execution.tv_sec) * 1000000; // Convert seconds to microseconds
|
||||
elapsed_time += (current_execution.tv_nsec - last_execution.tv_nsec) / 1000; // Convert nanoseconds to microseconds
|
||||
int duration = SLOT_DURATION >> mu;
|
||||
if (elapsed_time < duration)
|
||||
usleep(duration - elapsed_time);
|
||||
// Update last_execution time
|
||||
last_execution = current_execution;
|
||||
}
|
||||
|
||||
void handle_nr_slot_ind(uint16_t sfn, uint16_t slot)
|
||||
{
|
||||
nfapi_pnf_p7_config_t *config = p7_config_g;
|
||||
pnf_p7_t *_this = (pnf_p7_t *)(config);
|
||||
int mu = _this->mu;
|
||||
|
||||
if (IS_SOFTMODEM_RFSIM) {
|
||||
// RFsim can run faster than realtime. However, we need to give the VNF
|
||||
// some time to send an answer, so the PNF can run faster than realtime,
|
||||
// but it should not too much. This function will "maybe" slow down, up to
|
||||
// a slot length
|
||||
maybe_slow_down_pnf(mu);
|
||||
}
|
||||
|
||||
//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));
|
||||
int 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);
|
||||
//we give four additional slots (2ms) which should be enough time for the VNF to
|
||||
//answer
|
||||
int slot_ahead = 2 << mu;
|
||||
uint16_t sfn_tx = sfn;
|
||||
uint16_t slot_tx = slot;
|
||||
sfnslot_add_slot(mu, &sfn_tx, &slot_tx, slot_ahead); // modify: do in place
|
||||
|
||||
ind->sfn = sfn_tx;
|
||||
ind->slot = slot_tx;
|
||||
oai_nfapi_nr_slot_indication(ind);
|
||||
// printf("send slot indication for sfn/slot:%4d.%2d current:%4d.%2d\n", sfn_tx, slot_tx, sfn, slot);
|
||||
nfapi_nr_slot_indication_scf_t ind = {.sfn = sfn_tx, .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);
|
||||
// copy data from appropriate p7 slot buffers into channel structures for PHY processing
|
||||
nfapi_pnf_p7_slot_ind(config, config->phy_id, sfn, slot);
|
||||
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind) {
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef 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);
|
||||
@@ -27,7 +29,7 @@ void configure_nr_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_add
|
||||
|
||||
void oai_subframe_ind(uint16_t sfn, uint16_t sf);
|
||||
void handle_nr_slot_ind(uint16_t sfn, uint16_t slot);
|
||||
uint32_t sfnslot_add_slot(uint16_t sfn, uint16_t slot, int offset);
|
||||
void sfnslot_add_slot(int mu, 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);
|
||||
@@ -36,3 +38,4 @@ 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);
|
||||
|
||||
#endif /* NFAPI_PNF_H_ */
|
||||
|
||||
@@ -50,6 +50,9 @@
|
||||
#include "nr_fapi_p7_utils.h"
|
||||
#include <NR_MAC_gNB/mac_proto.h>
|
||||
|
||||
#ifdef ENABLE_AERIAL
|
||||
#include "aerial/fapi_vnf_p5.h"
|
||||
#endif
|
||||
|
||||
#define TEST
|
||||
|
||||
@@ -272,49 +275,6 @@ void oai_enb_init(void) {
|
||||
init_eNB_afterRU();
|
||||
}
|
||||
|
||||
|
||||
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_D(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_D(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
|
||||
|
||||
gNB->Mod_id = bodge_counter;
|
||||
gNB->CC_id = bodge_counter;
|
||||
RC.nb_nr_CC[bodge_counter] = 1;
|
||||
|
||||
if (gNB->if_inst==0) {
|
||||
gNB->if_inst = NR_IF_Module_init(bodge_counter);
|
||||
}
|
||||
|
||||
|
||||
// This will cause phy_config_request to be installed. That will result in RRC configuring the PHY
|
||||
// that will result in gNB->configured being set to true.
|
||||
// See we need to wait for that to happen otherwise the NFAPI message exchanges won't contain the right parameter values
|
||||
if (RC.gNB[0]->if_inst==0 || RC.gNB[0]->if_inst->NR_PHY_config_req==0 || RC.gNB[0]->if_inst->NR_Schedule_response==0) {
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "RC.gNB[0][0]->if_inst->NR_PHY_config_req is not installed - install it\n");
|
||||
install_nr_schedule_handlers(RC.gNB[0]->if_inst);
|
||||
}
|
||||
|
||||
do {
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() Waiting for gNB to become configured (by RRC/PHY) - need to wait otherwise NFAPI messages won't contain correct values\n", __FUNCTION__);
|
||||
usleep(50000);
|
||||
} while(gNB->configured != 1);
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() gNB is now configured\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
int pnf_connection_indication_cb(nfapi_vnf_config_t *config, int p5_idx) {
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] pnf connection indication idx:%d\n", p5_idx);
|
||||
oai_create_enb();
|
||||
@@ -327,7 +287,6 @@ int pnf_connection_indication_cb(nfapi_vnf_config_t *config, int p5_idx) {
|
||||
|
||||
int pnf_nr_connection_indication_cb(nfapi_vnf_config_t *config, int p5_idx) {
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] pnf connection indication idx:%d\n", p5_idx);
|
||||
oai_create_gnb();
|
||||
nfapi_nr_pnf_param_request_t req;
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.header.message_id = NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_REQUEST;
|
||||
@@ -650,7 +609,7 @@ int phy_slot_indication(struct nfapi_vnf_p7_config *config, uint16_t phy_id, uin
|
||||
static uint8_t first_time = 1;
|
||||
|
||||
if (first_time) {
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] slot indication %d\n", NFAPI_SFNSLOT2DEC(sfn, slot));
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] slot indication %d.%d\n", sfn, slot);
|
||||
first_time = 0;
|
||||
}
|
||||
|
||||
@@ -1118,24 +1077,66 @@ int phy_cqi_indication(struct nfapi_vnf_p7_config *config, nfapi_cqi_indication_
|
||||
|
||||
//NR phy indication
|
||||
|
||||
int phy_nr_slot_indication(nfapi_nr_slot_indication_scf_t *ind) {
|
||||
|
||||
uint8_t vnf_slot_ahead = 0;
|
||||
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);
|
||||
LOG_D(MAC, "VNF SFN/Slot %d.%d \n", vnf_sfn, vnf_slot);
|
||||
NR_Sched_Rsp_t g_sched_resp;
|
||||
void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, sub_frame_t slot, NR_Sched_Rsp_t* sched_info);
|
||||
int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req);
|
||||
int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req);
|
||||
int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t* tx_data_req);
|
||||
int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t* ul_dci_req);
|
||||
|
||||
nfapi_nr_slot_indication_scf_t *nr_slot_ind = CALLOC(1, sizeof(*nr_slot_ind));
|
||||
nr_slot_ind->header = ind->header;
|
||||
nr_slot_ind->sfn = vnf_sfn;
|
||||
nr_slot_ind->slot = vnf_slot;
|
||||
if (!put_queue(&gnb_slot_ind_queue, nr_slot_ind))
|
||||
{
|
||||
LOG_E(NR_MAC, "Put_queue failed for slot_ind\n");
|
||||
free(nr_slot_ind);
|
||||
nr_slot_ind = NULL;
|
||||
}
|
||||
int trigger_scheduler(nfapi_nr_slot_indication_scf_t *slot_ind)
|
||||
{
|
||||
// Call into the scheduler (this is hardcoded and should be init properly!)
|
||||
// memset(sched_resp, 0, sizeof(*sched_resp));
|
||||
gNB_dlsch_ulsch_scheduler(0, slot_ind->sfn, slot_ind->slot, &g_sched_resp);
|
||||
|
||||
#ifdef ENABLE_AERIAL
|
||||
bool send_slt_resp = false;
|
||||
if (g_sched_resp.DL_req.dl_tti_request_body.nPDUs> 0) {
|
||||
oai_fapi_dl_tti_req(&g_sched_resp.DL_req);
|
||||
send_slt_resp = true;
|
||||
}
|
||||
if (g_sched_resp.UL_tti_req.n_pdus > 0) {
|
||||
oai_fapi_ul_tti_req(&g_sched_resp.UL_tti_req);
|
||||
send_slt_resp = true;
|
||||
}
|
||||
if (g_sched_resp.TX_req.Number_of_PDUs > 0) {
|
||||
oai_fapi_tx_data_req(&g_sched_resp.TX_req);
|
||||
send_slt_resp = true;
|
||||
}
|
||||
if (g_sched_resp.UL_dci_req.numPdus > 0) {
|
||||
oai_fapi_ul_dci_req(&g_sched_resp.UL_dci_req);
|
||||
send_slt_resp = true;
|
||||
}
|
||||
if (send_slt_resp) {
|
||||
oai_fapi_send_end_request(0,slot_ind->sfn, slot_ind->slot);
|
||||
}
|
||||
#else
|
||||
if (g_sched_resp.DL_req.dl_tti_request_body.nPDUs > 0)
|
||||
oai_nfapi_dl_tti_req(&g_sched_resp.DL_req);
|
||||
|
||||
if (g_sched_resp.UL_tti_req.n_pdus > 0)
|
||||
oai_nfapi_ul_tti_req(&g_sched_resp.UL_tti_req);
|
||||
|
||||
if (g_sched_resp.TX_req.Number_of_PDUs > 0)
|
||||
oai_nfapi_tx_data_req(&g_sched_resp.TX_req);
|
||||
|
||||
if (g_sched_resp.UL_dci_req.numPdus > 0)
|
||||
oai_nfapi_ul_dci_req(&g_sched_resp.UL_dci_req);
|
||||
#endif
|
||||
|
||||
NR_UL_IND_t ind = {.frame = slot_ind->sfn, .slot = slot_ind->slot, };
|
||||
NR_UL_indication(&ind);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int phy_nr_slot_indication(nfapi_nr_slot_indication_scf_t *ind)
|
||||
{
|
||||
LOG_D(MAC, "VNF SFN/Slot %d.%d \n", ind->sfn, ind->slot);
|
||||
|
||||
trigger_scheduler(ind);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -1413,7 +1414,6 @@ void *vnf_nr_p7_thread_start(void *ptr)
|
||||
init_queue(&gnb_rx_ind_queue);
|
||||
init_queue(&gnb_crc_ind_queue);
|
||||
init_queue(&gnb_uci_ind_queue);
|
||||
init_queue(&gnb_slot_ind_queue);
|
||||
|
||||
vnf_p7_info *p7_vnf = (vnf_p7_info *)ptr;
|
||||
p7_vnf->config->port = p7_vnf->local_port;
|
||||
@@ -1551,6 +1551,17 @@ int nr_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_param_resp
|
||||
// for now just 1
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] %d.%d pnf p7 %s:%d timing %u %u %u %u\n", p5_idx, phy->id, phy->remote_addr, phy->remote_port, p7_vnf->timing_window, p7_vnf->periodic_timing_period, p7_vnf->aperiodic_timing_enabled,
|
||||
p7_vnf->periodic_timing_period);
|
||||
// Hack? the VNF might need the subcarrier spacing for some calculations
|
||||
// (that we actually don't use as of now...). We therefore need to save the
|
||||
// mu, for the current PNF connection (together with where we have frame/slot
|
||||
// info). nfapi_vnf_p7_add_pnf() prepends the current P7 connection to the
|
||||
// beginning of the list. Pick it from there, and save the mu.
|
||||
// check that SCS has actually been set
|
||||
const nfapi_uint8_tlv_t *scs = &req->ssb_config.scs_common;
|
||||
DevAssert(scs->tl.tag == NFAPI_NR_CONFIG_SCS_COMMON_TAG);
|
||||
int mu = scs->value;
|
||||
nfapi_vnf_p7_add_pnf((p7_vnf->config), phy->remote_addr, phy->remote_port, phy->id, mu);
|
||||
|
||||
req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST;
|
||||
req->header.phy_id = phy->id;
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Send NFAPI_CONFIG_REQUEST\n");
|
||||
@@ -1683,18 +1694,12 @@ int start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_start_response_t
|
||||
pnf_info *pnf = vnf->pnfs;
|
||||
phy_info *phy = pnf->phys;
|
||||
vnf_p7_info *p7_vnf = vnf->p7_vnfs;
|
||||
nfapi_vnf_p7_add_pnf((p7_vnf->config), phy->remote_addr, htons(phy->remote_port), phy->id);
|
||||
nfapi_vnf_p7_add_pnf((p7_vnf->config), phy->remote_addr, htons(phy->remote_port), phy->id, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nr_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_start_response_scf_t *resp) {
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Received NFAPI_START_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id);
|
||||
vnf_info *vnf = (vnf_info *)(config->user_data);
|
||||
pnf_info *pnf = vnf->pnfs;
|
||||
phy_info *phy = pnf->phys;
|
||||
vnf_p7_info *p7_vnf = vnf->p7_vnfs;
|
||||
|
||||
nfapi_vnf_p7_add_pnf((p7_vnf->config), phy->remote_addr, phy->remote_port, phy->id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1816,7 +1821,7 @@ void configure_nr_nfapi_vnf(char *vnf_addr, int vnf_p5_port, char *pnf_ip_addr,
|
||||
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].periodic_timing_period = 1;
|
||||
vnf.p7_vnfs[0].config = nfapi_vnf_p7_config_create();
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO,
|
||||
"[VNF] %s() vnf.p7_vnfs[0].config:%p VNF ADDRESS:%s:%d\n",
|
||||
|
||||
@@ -19,9 +19,10 @@
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef NFAPI_VNF_H_
|
||||
#define NFAPI_VNF_H_
|
||||
|
||||
void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port);
|
||||
void configure_nr_nfapi_vnf(char *vnf_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port);
|
||||
|
||||
uint32_t sfnslot_add_slot(uint16_t sfn, uint16_t slot, int offset);
|
||||
|
||||
#endif /* NFAPI_VNF_H_ */
|
||||
|
||||
@@ -66,7 +66,7 @@ void nfapi_trace(nfapi_trace_level_t level,
|
||||
{
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
printf("%ld%06ld [%c] %10u: %s: ",
|
||||
printf("%ld.%06ld [%c] %10u: %s: ",
|
||||
ts.tv_sec,
|
||||
ts.tv_nsec / 1000,
|
||||
"XEWNID"[level], // NFAPI_TRACE_NONE, NFAPI_TRACE_ERROR, ...
|
||||
|
||||
@@ -714,16 +714,7 @@ uint8_t unpack_nr_param_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *
|
||||
{NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG, &pNfapiMsg->nfapi_config.timing_info_mode, &unpack_uint8_tlv_value},
|
||||
{NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG, &pNfapiMsg->nfapi_config.timing_info_period, &unpack_uint8_tlv_value},
|
||||
};
|
||||
// print ppReadPackedMsg
|
||||
uint8_t *ptr = *ppReadPackedMsg;
|
||||
printf("\n Read message unpack_param_response: ");
|
||||
|
||||
while (ptr < end) {
|
||||
printf(" 0x%02x", *ptr);
|
||||
ptr++;
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
return (pull8(ppReadPackedMsg, &pNfapiMsg->error_code, end) && pull8(ppReadPackedMsg, &pNfapiMsg->num_tlv, end)
|
||||
&& unpack_nr_tlv_list(unpack_fns,
|
||||
sizeof(unpack_fns) / sizeof(unpack_tlv_t),
|
||||
@@ -1017,22 +1008,24 @@ uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *e
|
||||
|
||||
// END SSB Table
|
||||
// START TDD Table
|
||||
retval &=
|
||||
pack_nr_tlv(NFAPI_NR_CONFIG_TDD_PERIOD_TAG, &(pNfapiMsg->tdd_table.tdd_period), ppWritePackedMsg, end, &pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
const uint8_t slotsperframe[5] = {10, 20, 40, 80, 160};
|
||||
// Assuming always CP_Normal, because Cyclic prefix is not included in CONFIG.request 10.02, but is present in 10.04
|
||||
uint8_t cyclicprefix = 1;
|
||||
// 3GPP 38.211 Table 4.3.2.1 & Table 4.3.2.2
|
||||
uint8_t number_of_symbols_per_slot = cyclicprefix ? 14 : 12;
|
||||
for (int i = 0; i < slotsperframe[pNfapiMsg->ssb_config.scs_common.value]; i++) { // TODO check right number of slots
|
||||
for (int k = 0; k < number_of_symbols_per_slot; k++) { // TODO can change?
|
||||
retval &= pack_nr_tlv(NFAPI_NR_CONFIG_SLOT_CONFIG_TAG,
|
||||
&pNfapiMsg->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[k].slot_config,
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
if (pNfapiMsg->cell_config.frame_duplex_type.value == 1 /* TDD */) {
|
||||
retval &=
|
||||
pack_nr_tlv(NFAPI_NR_CONFIG_TDD_PERIOD_TAG, &(pNfapiMsg->tdd_table.tdd_period), ppWritePackedMsg, end, &pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
const uint8_t slotsperframe[5] = {10, 20, 40, 80, 160};
|
||||
// Assuming always CP_Normal, because Cyclic prefix is not included in CONFIG.request 10.02, but is present in 10.04
|
||||
uint8_t cyclicprefix = 1;
|
||||
// 3GPP 38.211 Table 4.3.2.1 & Table 4.3.2.2
|
||||
uint8_t number_of_symbols_per_slot = cyclicprefix ? 14 : 12;
|
||||
for (int i = 0; i < slotsperframe[pNfapiMsg->ssb_config.scs_common.value]; i++) { // TODO check right number of slots
|
||||
for (int k = 0; k < number_of_symbols_per_slot; k++) { // TODO can change?
|
||||
retval &= pack_nr_tlv(NFAPI_NR_CONFIG_SLOT_CONFIG_TAG,
|
||||
&pNfapiMsg->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[k].slot_config,
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint8_tlv_value);
|
||||
numTLVs++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1232,27 +1225,28 @@ uint8_t unpack_nr_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *
|
||||
pNfapiMsg->prach_config.num_prach_fd_occasions.tl.tag = generic_tl.tag;
|
||||
pNfapiMsg->prach_config.num_prach_fd_occasions.tl.length = generic_tl.length;
|
||||
result = (*unpack_fns[idx].unpack_func)(&pNfapiMsg->prach_config.num_prach_fd_occasions, ppReadPackedMsg, end);
|
||||
pNfapiMsg->prach_config.num_prach_fd_occasions_list = (nfapi_nr_num_prach_fd_occasions_t *)malloc(
|
||||
pNfapiMsg->prach_config.num_prach_fd_occasions.value * sizeof(nfapi_nr_num_prach_fd_occasions_t));
|
||||
pNfapiMsg->prach_config.num_prach_fd_occasions_list = calloc(pNfapiMsg->prach_config.num_prach_fd_occasions.value, sizeof(nfapi_nr_num_prach_fd_occasions_t));
|
||||
prach_root_seq_idx = 0;
|
||||
break;
|
||||
case NFAPI_NR_CONFIG_SCS_COMMON_TAG:
|
||||
pNfapiMsg->ssb_config.scs_common.tl.tag = generic_tl.tag;
|
||||
pNfapiMsg->ssb_config.scs_common.tl.length = generic_tl.length;
|
||||
result = (*unpack_fns[idx].unpack_func)(&pNfapiMsg->ssb_config.scs_common, ppReadPackedMsg, end);
|
||||
const uint8_t slotsperframe[5] = {10, 20, 40, 80, 160};
|
||||
|
||||
// Assuming always CP_Normal, because Cyclic prefix is not included in CONFIG.request 10.02, but is present in 10.04
|
||||
uint8_t cyclicprefix = 1;
|
||||
// 3GPP 38.211 Table 4.3.2.1 & Table 4.3.2.2
|
||||
uint8_t number_of_symbols_per_slot = cyclicprefix ? 14 : 12;
|
||||
|
||||
pNfapiMsg->tdd_table.max_tdd_periodicity_list = (nfapi_nr_max_tdd_periodicity_t *)malloc(
|
||||
slotsperframe[pNfapiMsg->ssb_config.scs_common.value] * sizeof(nfapi_nr_max_tdd_periodicity_t));
|
||||
if (pNfapiMsg->cell_config.frame_duplex_type.value == 1 /* TDD */) {
|
||||
const uint8_t slotsperframe[5] = {10, 20, 40, 80, 160};
|
||||
int n = slotsperframe[pNfapiMsg->ssb_config.scs_common.value];
|
||||
pNfapiMsg->tdd_table.max_tdd_periodicity_list = calloc(n, sizeof(nfapi_nr_max_tdd_periodicity_t));
|
||||
|
||||
for (int i = 0; i < slotsperframe[pNfapiMsg->ssb_config.scs_common.value]; i++) {
|
||||
pNfapiMsg->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list =
|
||||
(nfapi_nr_max_num_of_symbol_per_slot_t *)malloc(number_of_symbols_per_slot
|
||||
* sizeof(nfapi_nr_max_num_of_symbol_per_slot_t));
|
||||
for (int i = 0; i < n; i++) {
|
||||
pNfapiMsg->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list =
|
||||
calloc(number_of_symbols_per_slot, sizeof(nfapi_nr_max_num_of_symbol_per_slot_t));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NFAPI_NR_CONFIG_PRACH_ROOT_SEQUENCE_INDEX_TAG:
|
||||
|
||||
@@ -240,18 +240,20 @@ bool eq_config_request(const nfapi_nr_config_request_scf_t *unpacked_req, const
|
||||
EQ_TLV(unpacked_req->ssb_table.ssb_beam_id_list[i].beam_id, req->ssb_table.ssb_beam_id_list[i].beam_id);
|
||||
}
|
||||
|
||||
EQ_TLV(unpacked_req->tdd_table.tdd_period, req->tdd_table.tdd_period);
|
||||
if (req->cell_config.frame_duplex_type.value == 1 /* TDD */) {
|
||||
EQ_TLV(unpacked_req->tdd_table.tdd_period, req->tdd_table.tdd_period);
|
||||
|
||||
const uint8_t slotsperframe[5] = {10, 20, 40, 80, 160};
|
||||
// Assuming always CP_Normal, because Cyclic prefix is not included in CONFIG.request 10.02, but is present in 10.04
|
||||
uint8_t cyclicprefix = 1;
|
||||
// 3GPP 38.211 Table 4.3.2.1 & Table 4.3.2.2
|
||||
uint8_t number_of_symbols_per_slot = cyclicprefix ? 14 : 12;
|
||||
const uint8_t slotsperframe[5] = {10, 20, 40, 80, 160};
|
||||
// Assuming always CP_Normal, because Cyclic prefix is not included in CONFIG.request 10.02, but is present in 10.04
|
||||
uint8_t cyclicprefix = 1;
|
||||
// 3GPP 38.211 Table 4.3.2.1 & Table 4.3.2.2
|
||||
uint8_t number_of_symbols_per_slot = cyclicprefix ? 14 : 12;
|
||||
|
||||
for (int i = 0; i < slotsperframe[unpacked_req->ssb_config.scs_common.value]; i++) {
|
||||
for (int k = 0; k < number_of_symbols_per_slot; k++) {
|
||||
EQ_TLV(unpacked_req->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[k].slot_config,
|
||||
req->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[k].slot_config);
|
||||
for (int i = 0; i < slotsperframe[unpacked_req->ssb_config.scs_common.value]; i++) {
|
||||
for (int k = 0; k < number_of_symbols_per_slot; k++) {
|
||||
EQ_TLV(unpacked_req->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[k].slot_config,
|
||||
req->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[k].slot_config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -768,24 +770,26 @@ void copy_config_request(const nfapi_nr_config_request_scf_t *src, nfapi_nr_conf
|
||||
COPY_TLV(dst->ssb_table.ssb_beam_id_list[i].beam_id, src->ssb_table.ssb_beam_id_list[i].beam_id);
|
||||
}
|
||||
|
||||
COPY_TLV(dst->tdd_table.tdd_period, src->tdd_table.tdd_period);
|
||||
if (src->cell_config.frame_duplex_type.value == 1 /* TDD */) {
|
||||
COPY_TLV(dst->tdd_table.tdd_period, src->tdd_table.tdd_period);
|
||||
|
||||
const uint8_t slotsperframe[5] = {10, 20, 40, 80, 160};
|
||||
// Assuming always CP_Normal, because Cyclic prefix is not included in CONFIG.request 10.02, but is present in 10.04
|
||||
uint8_t cyclicprefix = 1;
|
||||
// 3GPP 38.211 Table 4.3.2.1 & Table 4.3.2.2
|
||||
uint8_t number_of_symbols_per_slot = cyclicprefix ? 14 : 12;
|
||||
dst->tdd_table.max_tdd_periodicity_list = (nfapi_nr_max_tdd_periodicity_t *)malloc(slotsperframe[dst->ssb_config.scs_common.value]
|
||||
* sizeof(nfapi_nr_max_tdd_periodicity_t));
|
||||
const uint8_t slotsperframe[5] = {10, 20, 40, 80, 160};
|
||||
// Assuming always CP_Normal, because Cyclic prefix is not included in CONFIG.request 10.02, but is present in 10.04
|
||||
uint8_t cyclicprefix = 1;
|
||||
// 3GPP 38.211 Table 4.3.2.1 & Table 4.3.2.2
|
||||
uint8_t number_of_symbols_per_slot = cyclicprefix ? 14 : 12;
|
||||
dst->tdd_table.max_tdd_periodicity_list = (nfapi_nr_max_tdd_periodicity_t *)malloc(slotsperframe[dst->ssb_config.scs_common.value]
|
||||
* sizeof(nfapi_nr_max_tdd_periodicity_t));
|
||||
|
||||
for (int i = 0; i < slotsperframe[dst->ssb_config.scs_common.value]; i++) {
|
||||
dst->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list =
|
||||
(nfapi_nr_max_num_of_symbol_per_slot_t *)malloc(number_of_symbols_per_slot * sizeof(nfapi_nr_max_num_of_symbol_per_slot_t));
|
||||
}
|
||||
for (int i = 0; i < slotsperframe[dst->ssb_config.scs_common.value]; i++) { // TODO check right number of slots
|
||||
for (int k = 0; k < number_of_symbols_per_slot; k++) { // TODO can change?
|
||||
COPY_TLV(dst->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[k].slot_config,
|
||||
src->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[k].slot_config);
|
||||
for (int i = 0; i < slotsperframe[dst->ssb_config.scs_common.value]; i++) {
|
||||
dst->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list =
|
||||
(nfapi_nr_max_num_of_symbol_per_slot_t *)malloc(number_of_symbols_per_slot * sizeof(nfapi_nr_max_num_of_symbol_per_slot_t));
|
||||
}
|
||||
for (int i = 0; i < slotsperframe[dst->ssb_config.scs_common.value]; i++) { // TODO check right number of slots
|
||||
for (int k = 0; k < number_of_symbols_per_slot; k++) { // TODO can change?
|
||||
COPY_TLV(dst->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[k].slot_config,
|
||||
src->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[k].slot_config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -120,16 +120,14 @@ typedef struct {
|
||||
#define NFAPI_TAG_LENGTH_PACKED_LEN 4
|
||||
|
||||
// Convenience methods to convert between SFN/SLOT formats
|
||||
#define NFAPI_SFNSLOT2DEC(_sfn,_slot) ( _sfn*20 + _slot ) // total count of slots
|
||||
#define NFAPI_SFNSLOTDEC2SFNSLOT(_sfnslot_dec) ((((_sfnslot_dec) / 20) << 6) | (((_sfnslot_dec) - (((_sfnslot_dec) / 20) * 20)) & 0x3F))
|
||||
#define NFAPI_SLOTNUM(_mu) (10 << (_mu))
|
||||
#define NFAPI_SLOTLEN(_mu) (1000.f / (1 << _mu))
|
||||
|
||||
#define NFAPI_SFNSLOT2SFN(_sfnslot) ((_sfnslot) >> 6)
|
||||
#define NFAPI_SFNSLOT2SLOT(_sfnslot) ((_sfnslot) & 0x3F)
|
||||
#define NFAPI_SFNSLOTDEC2SFN(_sfnslot_dec) ((_sfnslot_dec) / 20)
|
||||
#define NFAPI_SFNSLOTDEC2SLOT(_sfnslot_dec) ((_sfnslot_dec) % 20)
|
||||
#define NFAPI_SFNSLOT2HEX(_sfn,_slot) ((_sfn << 6) | (_slot & 0x3F))
|
||||
#define NFAPI_SFNSLOT2DEC(_mu, _sfn, _slot) ((_sfn) * NFAPI_SLOTNUM(_mu) + (_slot))
|
||||
#define NFAPI_SFNSLOTDEC2SFN(_mu, _sfnslot_dec) ((_sfnslot_dec) / NFAPI_SLOTNUM(_mu))
|
||||
#define NFAPI_SFNSLOTDEC2SLOT(_mu, _sfnslot_dec) ((_sfnslot_dec) % NFAPI_SLOTNUM(_mu))
|
||||
|
||||
#define NFAPI_MAX_SFNSLOTDEC 1024*20 // 20 is for numerology 1
|
||||
#define NFAPI_MAX_SFNSLOTDEC(_mu) (1024 * NFAPI_SLOTNUM(_mu))
|
||||
|
||||
// Convenience methods to convert between SFN/SFN formats
|
||||
#define NFAPI_SFNSF2DEC(_sfnsf) ((((_sfnsf) >> 4) * 10) + ((_sfnsf) & 0xF))
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#define _NFAPI_NR_INTERFACE_H_
|
||||
#include "nfapi_common_interface.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#define NFAPI_NR_P5_HEADER_LENGTH 10
|
||||
#define NFAPI_NR_P7_HEADER_LENGTH 18
|
||||
|
||||
@@ -177,6 +179,18 @@ int nfapi_nr_p7_message_unpack(void *pMessageBuf,
|
||||
uint32_t unpackedBufLen,
|
||||
nfapi_p7_codec_config_t *config);
|
||||
|
||||
/*! \brief Peeks the SFN and Slot of an (n)FAPI P7 message
|
||||
* \param pMessageBuf A pointer to an encoded P7 message header
|
||||
* \param messageBufLen The size of the encoded P7 message header
|
||||
* \param SFN A pointer to store the peeked SFN
|
||||
* \param Slot A pointer to store the peeked Slot
|
||||
* \return true on success, false, otherwise.
|
||||
*
|
||||
* The function will decode the encoded SFN and Slot from an encoded P7 (n)FAPI message
|
||||
|
||||
*/
|
||||
bool peek_nr_nfapi_p7_sfn_slot(void *pMessageBuf, uint32_t messageBufLen, uint16_t *SFN, uint16_t *Slot);
|
||||
|
||||
/*! \brief Calculates the checksum of a message
|
||||
*
|
||||
* \param buffer Pointer to the packed message
|
||||
|
||||
@@ -6202,6 +6202,18 @@ int nfapi_p7_message_unpack(void *pMessageBuf,
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool peek_nr_nfapi_p7_sfn_slot(void *pMessageBuf, uint32_t messageBufLen, uint16_t *SFN, uint16_t *Slot)
|
||||
{
|
||||
uint8_t *pReadPackedMessage = &((uint8_t *)pMessageBuf)[NFAPI_NR_P7_HEADER_LENGTH];
|
||||
uint8_t *end = (uint8_t*)pMessageBuf + messageBufLen;
|
||||
if(!(pull16(&pReadPackedMessage, SFN, end) && pull16(&pReadPackedMessage, Slot, end))) {
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to peek SFN.Slot\n");
|
||||
return false;
|
||||
}
|
||||
NFAPI_TRACE(NFAPI_TRACE_DEBUG, "Peeked SFN.Slot is (%d.%d)\n", *SFN, *Slot);
|
||||
return true;
|
||||
}
|
||||
|
||||
int nfapi_nr_p7_message_unpack(void *pMessageBuf,
|
||||
uint32_t messageBufLen,
|
||||
void *pUnpackedBuf,
|
||||
|
||||
@@ -29,37 +29,32 @@
|
||||
|
||||
typedef struct {
|
||||
uint16_t dl_conf_ontime;
|
||||
uint16_t dl_tti_ontime;
|
||||
uint16_t dl_conf_late;
|
||||
uint16_t dl_tti_late;
|
||||
uint16_t ul_conf_ontime;
|
||||
uint16_t ul_tti_ontime;
|
||||
uint16_t ul_conf_late;
|
||||
uint16_t ul_tti_late;
|
||||
uint16_t hi_dci0_ontime;
|
||||
uint16_t hi_dci0_late;
|
||||
uint16_t ul_dci_ontime;
|
||||
uint16_t ul_dci_late;
|
||||
uint16_t tx_ontime;
|
||||
uint16_t tx_late;
|
||||
uint16_t tx_data_ontime;
|
||||
uint16_t tx_data_late;
|
||||
} pnf_p7_stats_t;
|
||||
|
||||
|
||||
typedef struct { // TODO: replace with the stats
|
||||
uint16_t dl_tti_ontime;
|
||||
uint16_t dl_tti_late;
|
||||
uint16_t ul_tti_ontime;
|
||||
uint16_t ul_tti_late;
|
||||
uint16_t ul_dci_ontime;
|
||||
uint16_t ul_dci_late;
|
||||
uint16_t tx_data_ontime;
|
||||
uint16_t tx_data_late;
|
||||
typedef struct pnf_p7_arr_time {
|
||||
uint16_t ontime;
|
||||
uint16_t late;
|
||||
} pnf_p7_arr_time_t;
|
||||
typedef struct pnf_p7_dir {
|
||||
uint32_t bytes;
|
||||
} pnf_p7_dir_t;
|
||||
typedef struct {
|
||||
pnf_p7_arr_time_t dl_tti;
|
||||
pnf_p7_arr_time_t ul_tti;
|
||||
pnf_p7_arr_time_t ul_dci;
|
||||
pnf_p7_arr_time_t tx_data;
|
||||
pnf_p7_dir_t dl;
|
||||
pnf_p7_dir_t ul;
|
||||
} pnf_p7_nr_stats_t;
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t* buffer;
|
||||
uint16_t length;
|
||||
@@ -119,6 +114,7 @@ typedef struct {
|
||||
|
||||
uint16_t sfn;
|
||||
uint16_t slot;
|
||||
int mu;
|
||||
uint16_t sfn_slot;
|
||||
uint32_t slot_start_time_hr;
|
||||
int32_t slot_shift;
|
||||
|
||||
@@ -573,11 +573,10 @@ typedef struct
|
||||
//uint16_t sfn_slot
|
||||
uint16_t sfn;
|
||||
uint16_t slot;
|
||||
//TODO: Change P7 structs to NR
|
||||
nfapi_nr_dl_tti_request_t* dl_tti_req;//nfapi_dl_config_request_t* dl_config_req;
|
||||
nfapi_nr_ul_tti_request_t* ul_tti_req;//nfapi_ul_config_request_t* ul_config_req;
|
||||
nfapi_nr_ul_dci_request_t* ul_dci_req;//nfapi_hi_dci0_request_t* hi_dci0_req;
|
||||
nfapi_nr_tx_data_request_t* tx_data_req;//nfapi_tx_request_t* tx_req;
|
||||
nfapi_nr_dl_tti_request_t dl_tti_req;
|
||||
nfapi_nr_ul_tti_request_t ul_tti_req;
|
||||
nfapi_nr_ul_dci_request_t ul_dci_req;
|
||||
nfapi_nr_tx_data_request_t tx_data_req;
|
||||
|
||||
//TODO: check these two later
|
||||
//nfapi_lbt_dl_config_request_t* lbt_dl_config_req;
|
||||
|
||||
+271
-689
File diff suppressed because it is too large
Load Diff
@@ -21,14 +21,15 @@
|
||||
|
||||
nfapi_pnf_p7_config_t* nfapi_pnf_p7_config_create()
|
||||
{
|
||||
pnf_p7_t* _this = (pnf_p7_t*)calloc(1, sizeof(pnf_p7_t));
|
||||
pnf_p7_t* _this = NULL;
|
||||
int rc = posix_memalign((void**)&_this, 32, sizeof(pnf_p7_t));
|
||||
|
||||
if(_this == 0)
|
||||
return 0;
|
||||
if (_this == NULL || rc != 0)
|
||||
return 0;
|
||||
|
||||
|
||||
// set the default parameters
|
||||
_this->_public.segment_size = 1400;
|
||||
_this->_public.segment_size = 65000; // UDP max packet size is 65535
|
||||
_this->max_num_segments = 8;
|
||||
|
||||
_this->_public.subframe_buffer_size = 8;// TODO: Initialize the slot_buffer size
|
||||
@@ -271,7 +272,13 @@ int nfapi_pnf_p7_nr_rx_data_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_rx_data_
|
||||
}
|
||||
|
||||
pnf_p7_t* _this = (pnf_p7_t*)(config);
|
||||
return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_nr_p7_message_header_t*)ind, sizeof(nfapi_nr_rx_data_indication_t));
|
||||
|
||||
int ret = pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_nr_p7_message_header_t*)ind, sizeof(nfapi_nr_rx_data_indication_t));
|
||||
if (ret == 0) {
|
||||
for (int i = 0; i < ind->number_of_pdus; ++i)
|
||||
_this->nr_stats.ul.bytes += ind->pdu_list[i].pdu_length;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int nfapi_pnf_p7_nr_crc_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_crc_indication_t* ind)
|
||||
|
||||
@@ -91,6 +91,8 @@ typedef struct nfapi_vnf_p7_connection_info {
|
||||
int sfn_sf;
|
||||
int sfn;
|
||||
int slot;
|
||||
int mu; // some 5G slot calculations need the numerology to know the number
|
||||
// of slots
|
||||
|
||||
int socket;
|
||||
struct sockaddr_in local_addr;
|
||||
|
||||
@@ -901,7 +901,6 @@ void nfapi_vnf_p7_config_destory(nfapi_vnf_p7_config_t* config);
|
||||
* This function is blocking and will not return until the nfapi_vnf_p7_stop
|
||||
* function is called.
|
||||
*/
|
||||
extern queue_t gnb_slot_ind_queue;
|
||||
int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config);
|
||||
int nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t* config);
|
||||
|
||||
@@ -933,13 +932,14 @@ int nfapi_vnf_p7_release_pdu(nfapi_vnf_p7_config_t* config, void*);
|
||||
* \param pnf_p7_addr The udp address the pnf p7 entity has chosen
|
||||
* \param pnf_p7_port The udp port the pnf p7 entity has chosen
|
||||
* \param phy_id The unique phy id for the pnf p7 entity
|
||||
* \param mu The subcarrier spacing the PNF is operating with.
|
||||
* \return A status value. 0 equal success, -1 indicates failure
|
||||
*
|
||||
* This function should be used to each pnf p7 entity that is to be added to this
|
||||
* vnf p7 entity. Once added the vnf p7 entity will start establish sync with the
|
||||
* pnf p7 entity and that has been sucessfull will generate subframe indications for it
|
||||
*/
|
||||
int nfapi_vnf_p7_add_pnf(nfapi_vnf_p7_config_t* config, const char* pnf_p7_addr, int pnf_p7_port, int phy_id);
|
||||
int nfapi_vnf_p7_add_pnf(nfapi_vnf_p7_config_t* config, const char* pnf_p7_addr, int pnf_p7_port, int phy_id, int mu);
|
||||
|
||||
/*! Delete a vnf p7 instance to the vnf p7 module
|
||||
* \param config A pointer to the vnf p7 configuration
|
||||
|
||||
@@ -93,20 +93,14 @@ nfapi_vnf_pnf_info_t* nfapi_vnf_pnf_list_find(nfapi_vnf_config_t* config, int p5
|
||||
NFAPI_TRACE(NFAPI_TRACE_DEBUG, "config->pnf_list:%p\n", config->pnf_list);
|
||||
|
||||
nfapi_vnf_pnf_info_t* curr = config->pnf_list;
|
||||
while(curr != 0)
|
||||
{
|
||||
if(curr->p5_idx == p5_idx)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s : curr->p5_idx:%d p5_idx:%d\n", __FUNCTION__, curr->p5_idx, p5_idx);
|
||||
return curr;
|
||||
}
|
||||
while (curr != 0) {
|
||||
if (curr->p5_idx == p5_idx)
|
||||
return curr;
|
||||
curr = curr->next;
|
||||
}
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s(): could not find P5 connection for p5_idx %d\n", __func__, p5_idx);
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s : curr->next:%p\n", __FUNCTION__, curr->next);
|
||||
|
||||
curr = curr->next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void vnf_nr_handle_pnf_param_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx)
|
||||
@@ -129,7 +123,9 @@ void vnf_nr_handle_pnf_param_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_
|
||||
if(config->pnf_nr_param_resp)
|
||||
{
|
||||
(config->pnf_nr_param_resp)(config, p5_idx, &msg);
|
||||
}
|
||||
} else {
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s(): no pnf_nr_param_resp cb installed\n", __func__);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -162,7 +158,9 @@ void vnf_handle_pnf_param_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_con
|
||||
if(config->pnf_param_resp)
|
||||
{
|
||||
(config->pnf_param_resp)(config, p5_idx, &msg);
|
||||
}
|
||||
} else {
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s(): no pnf_params_resp cb installed\n", __func__);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -196,7 +194,9 @@ void vnf_nr_handle_pnf_config_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf
|
||||
if(config->pnf_nr_config_resp)
|
||||
{
|
||||
(config->pnf_nr_config_resp)(config, p5_idx, &msg);
|
||||
}
|
||||
} else {
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s(): no pnf_nr_config_resp cb installed\n", __func__);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -229,7 +229,9 @@ void vnf_handle_pnf_config_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_co
|
||||
if(config->pnf_config_resp)
|
||||
{
|
||||
(config->pnf_config_resp)(config, p5_idx, &msg);
|
||||
}
|
||||
} else {
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s(): no pnf_config_resp cb installed\n", __func__);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -261,7 +263,9 @@ void vnf_nr_handle_pnf_start_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_
|
||||
if(config->pnf_nr_start_resp)
|
||||
{
|
||||
(config->pnf_nr_start_resp)(config, p5_idx, &msg);
|
||||
}
|
||||
} else {
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s(): no pnf_nr_start_resp cb installed\n", __func__);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -293,7 +297,9 @@ void vnf_handle_pnf_start_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_con
|
||||
if(config->pnf_start_resp)
|
||||
{
|
||||
(config->pnf_start_resp)(config, p5_idx, &msg);
|
||||
}
|
||||
} else {
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s(): no pnf_start_resp cb installed\n", __func__);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -325,7 +331,9 @@ void vnf_handle_pnf_stop_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_conf
|
||||
if(config->pnf_stop_resp)
|
||||
{
|
||||
(config->pnf_stop_resp)(config, p5_idx, &msg);
|
||||
}
|
||||
} else {
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s(): no pnf_stop_resp cb installed\n", __func__);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -565,7 +573,9 @@ void vnf_handle_start_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_
|
||||
if(config->start_resp)
|
||||
{
|
||||
(config->start_resp)(config, p5_idx, &msg);
|
||||
}
|
||||
} else {
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s(): no start_resp cb installed\n", __func__);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -598,7 +608,9 @@ void vnf_nr_handle_start_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_conf
|
||||
if(config->nr_start_resp)
|
||||
{
|
||||
(config->nr_start_resp)(config, p5_idx, &msg);
|
||||
}
|
||||
} else {
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s(): no nr_start_resp cb installed\n", __func__);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -89,16 +89,14 @@ void vnf_p7_connection_info_list_add(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_i
|
||||
nfapi_vnf_p7_connection_info_t* vnf_p7_connection_info_list_find(vnf_p7_t* vnf_p7, uint16_t phy_id)
|
||||
{
|
||||
nfapi_vnf_p7_connection_info_t* curr = vnf_p7->p7_connections;
|
||||
while(curr != 0)
|
||||
{
|
||||
if(curr->phy_id == phy_id)
|
||||
{
|
||||
return curr;
|
||||
}
|
||||
curr = curr->next;
|
||||
}
|
||||
while (curr != 0) {
|
||||
if (curr->phy_id == phy_id)
|
||||
return curr;
|
||||
curr = curr->next;
|
||||
}
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s(): could not find P7 connection for phy_id %d\n", __func__, phy_id);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
nfapi_vnf_p7_connection_info_t* vnf_p7_connection_info_list_delete(vnf_p7_t* vnf_p7, uint16_t phy_id)
|
||||
@@ -243,7 +241,7 @@ void vnf_p7_rx_reassembly_queue_remove_old_msgs(vnf_p7_t* vnf_p7, vnf_p7_rx_reas
|
||||
previous->next = iterator->next;
|
||||
}
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "Deleting stale reassembly message (%u %u %d)\n", iterator->rx_hr_time, rx_hr_time, delta);
|
||||
NFAPI_TRACE(NFAPI_TRACE_WARN, "Deleting stale reassembly message (packet rx_hr_time %u current rx_hr_time %u delta %d us)\n", iterator->rx_hr_time, rx_hr_time, delta);
|
||||
|
||||
vnf_p7_rx_message_t* to_delete = iterator;
|
||||
iterator = iterator->next;
|
||||
@@ -364,13 +362,13 @@ uint32_t calculate_t1(uint16_t sfn_sf, uint32_t sf_start_time_hr)
|
||||
return t1;
|
||||
}
|
||||
|
||||
uint32_t calculate_nr_t1(uint16_t sfn, uint16_t slot, uint32_t slot_start_time_hr)
|
||||
uint32_t calculate_nr_t1(int mu, uint16_t sfn, uint16_t slot, uint32_t slot_start_time_hr)
|
||||
{
|
||||
uint32_t now_time_hr = vnf_get_current_time_hr();
|
||||
|
||||
uint32_t slot_time_us = get_slot_time(now_time_hr, slot_start_time_hr);
|
||||
|
||||
uint32_t t1 = (NFAPI_SFNSLOT2DEC(sfn,slot) * 500) + slot_time_us;
|
||||
uint32_t t1 = NFAPI_SFNSLOT2DEC(mu, sfn,slot) * NFAPI_SLOTLEN(mu) + slot_time_us;
|
||||
|
||||
return t1;
|
||||
}
|
||||
@@ -386,24 +384,24 @@ uint32_t calculate_t4(uint32_t now_time_hr, uint16_t sfn_sf, uint32_t sf_start_t
|
||||
|
||||
}
|
||||
|
||||
uint32_t calculate_nr_t4(uint32_t now_time_hr, uint16_t sfn, uint16_t slot, uint32_t slot_start_time_hr)
|
||||
uint32_t calculate_nr_t4(uint32_t now_time_hr, int mu, uint16_t sfn, uint16_t slot, uint32_t slot_start_time_hr)
|
||||
{
|
||||
uint32_t slot_time_us = get_slot_time(now_time_hr, slot_start_time_hr);
|
||||
|
||||
uint32_t t4 = (NFAPI_SFNSLOT2DEC(sfn,slot) * 500) + slot_time_us;
|
||||
uint32_t t4 = NFAPI_SFNSLOT2DEC(mu, sfn,slot) * NFAPI_SLOTLEN(mu) + slot_time_us;
|
||||
|
||||
return t4;
|
||||
|
||||
}
|
||||
|
||||
|
||||
uint32_t calculate_transmit_timestamp(uint16_t sfn, uint16_t slot, uint32_t slot_start_time_hr)
|
||||
uint32_t calculate_transmit_timestamp(int mu, uint16_t sfn, uint16_t slot, uint32_t slot_start_time_hr)
|
||||
{
|
||||
uint32_t now_time_hr = vnf_get_current_time_hr();
|
||||
|
||||
uint32_t slot_time_us = get_slot_time(now_time_hr, slot_start_time_hr);
|
||||
|
||||
uint32_t tt = (NFAPI_SFNSLOT2DEC(sfn, slot) * 500) + slot_time_us;
|
||||
uint32_t tt = NFAPI_SFNSLOT2DEC(mu, sfn, slot) * NFAPI_SLOTLEN(mu) + slot_time_us;
|
||||
|
||||
return tt;
|
||||
}
|
||||
@@ -509,7 +507,7 @@ int vnf_nr_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_nr_p7_message_header_
|
||||
int segment = 0;
|
||||
int offset = NFAPI_NR_P7_HEADER_LENGTH;
|
||||
uint8_t tx_buffer[vnf_p7->_public.segment_size];
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() MORE THAN ONE SEGMENT phy_id:%d nfapi_p7_message_pack()=len=%d vnf_p7->_public.segment_size:%u\n", __FUNCTION__, header->phy_id, len, vnf_p7->_public.segment_size);
|
||||
NFAPI_TRACE(NFAPI_TRACE_DEBUG, "%s() MORE THAN ONE SEGMENT phy_id:%d nfapi_p7_message_pack()=len=%d vnf_p7->_public.segment_size:%u\n", __FUNCTION__, header->phy_id, len, vnf_p7->_public.segment_size);
|
||||
for(segment = 0; segment < segment_count; ++segment)
|
||||
{
|
||||
uint8_t last = 0;
|
||||
@@ -540,7 +538,7 @@ int vnf_nr_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_nr_p7_message_header_
|
||||
nfapi_nr_p7_update_checksum(tx_buffer, segment_size);
|
||||
}
|
||||
|
||||
nfapi_nr_p7_update_transmit_timestamp(buffer, calculate_transmit_timestamp(p7_connection->sfn, p7_connection->slot, vnf_p7->slot_start_time_hr));
|
||||
nfapi_nr_p7_update_transmit_timestamp(buffer, calculate_transmit_timestamp(p7_connection->mu, 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);
|
||||
|
||||
@@ -553,7 +551,7 @@ int vnf_nr_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_nr_p7_message_header_
|
||||
nfapi_nr_p7_update_checksum(buffer, len);
|
||||
}
|
||||
|
||||
nfapi_nr_p7_update_transmit_timestamp(buffer, calculate_transmit_timestamp(p7_connection->sfn, p7_connection->slot, vnf_p7->slot_start_time_hr));
|
||||
nfapi_nr_p7_update_transmit_timestamp(buffer, calculate_transmit_timestamp(p7_connection->mu, p7_connection->sfn, p7_connection->slot, vnf_p7->slot_start_time_hr));
|
||||
|
||||
// simple case that the message fits in a single segement
|
||||
send_result = vnf_send_p7_msg(vnf_p7, p7_connection, &buffer[0], len);
|
||||
@@ -634,7 +632,7 @@ int vnf_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* hea
|
||||
nfapi_p7_update_checksum(tx_buffer, segment_size);
|
||||
}
|
||||
|
||||
nfapi_p7_update_transmit_timestamp(buffer, calculate_transmit_timestamp(p7_connection->sfn, p7_connection->slot, vnf_p7->slot_start_time_hr));
|
||||
nfapi_p7_update_transmit_timestamp(buffer, calculate_transmit_timestamp(p7_connection->mu, 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);
|
||||
}
|
||||
@@ -646,7 +644,7 @@ int vnf_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* hea
|
||||
nfapi_p7_update_checksum(buffer, len);
|
||||
}
|
||||
|
||||
nfapi_p7_update_transmit_timestamp(buffer, calculate_transmit_timestamp(p7_connection->sfn, p7_connection->slot, vnf_p7->slot_start_time_hr));
|
||||
nfapi_p7_update_transmit_timestamp(buffer, calculate_transmit_timestamp(p7_connection->mu, p7_connection->sfn, p7_connection->slot, vnf_p7->slot_start_time_hr));
|
||||
|
||||
// simple case that the message fits in a single segement
|
||||
send_result = vnf_send_p7_msg(vnf_p7, p7_connection, &buffer[0], len);
|
||||
@@ -683,7 +681,7 @@ int vnf_nr_build_send_dl_node_sync(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_inf
|
||||
dl_node_sync.header.phy_id = p7_info->phy_id;
|
||||
dl_node_sync.header.message_id = NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC;
|
||||
//dl_node_sync.t1 = calculate_t1(p7_info->sfn_sf, vnf_p7->sf_start_time_hr);
|
||||
dl_node_sync.t1 = calculate_nr_t1(p7_info->sfn,p7_info->slot, vnf_p7->slot_start_time_hr);
|
||||
dl_node_sync.t1 = calculate_nr_t1(p7_info->mu, p7_info->sfn,p7_info->slot, vnf_p7->slot_start_time_hr);
|
||||
dl_node_sync.delta_sfn_slot = 0;
|
||||
|
||||
return vnf_nr_p7_pack_and_send_p7_msg(vnf_p7, &dl_node_sync.header);
|
||||
@@ -695,11 +693,9 @@ int vnf_nr_sync(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info)
|
||||
if(p7_info->in_sync == 1)
|
||||
{
|
||||
uint16_t dl_sync_period_mask = p7_info->dl_in_sync_period-1;
|
||||
// uint16_t sfn_sf_dec = NFAPI_SFNSF2DEC(p7_info->sfn_sf);
|
||||
uint16_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(p7_info->sfn,p7_info->slot);
|
||||
uint16_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(p7_info->mu, p7_info->sfn,p7_info->slot);
|
||||
|
||||
//if ((((sfn_sf_dec + p7_info->dl_in_sync_offset) % NFAPI_MAX_SFNSFDEC) & dl_sync_period_mask) == 0)
|
||||
if ((((sfn_slot_dec + p7_info->dl_in_sync_offset) % NFAPI_MAX_SFNSLOTDEC) & dl_sync_period_mask) == 0)
|
||||
if ((((sfn_slot_dec + p7_info->dl_in_sync_offset) % NFAPI_MAX_SFNSLOTDEC(p7_info->mu)) & dl_sync_period_mask) == 0)
|
||||
{
|
||||
vnf_nr_build_send_dl_node_sync(vnf_p7, p7_info);
|
||||
}
|
||||
@@ -708,10 +704,9 @@ int vnf_nr_sync(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info)
|
||||
{
|
||||
uint16_t dl_sync_period_mask = p7_info->dl_out_sync_period-1;
|
||||
//uint16_t sfn_sf_dec = NFAPI_SFNSF2DEC(p7_info->sfn_sf);
|
||||
uint16_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(p7_info->sfn, p7_info->slot);
|
||||
uint16_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(p7_info->mu, p7_info->sfn, p7_info->slot);
|
||||
|
||||
//if ((((sfn_sf_dec + p7_info->dl_out_sync_offset) % NFAPI_MAX_SFNSFDEC) & dl_sync_period_mask) == 0)
|
||||
if ((((sfn_slot_dec + p7_info->dl_out_sync_offset) % NFAPI_MAX_SFNSLOTDEC) & dl_sync_period_mask) == 0)
|
||||
if ((((sfn_slot_dec + p7_info->dl_out_sync_offset) % NFAPI_MAX_SFNSLOTDEC(p7_info->mu)) & dl_sync_period_mask) == 0)
|
||||
{
|
||||
vnf_nr_build_send_dl_node_sync(vnf_p7, p7_info);
|
||||
}
|
||||
@@ -1499,7 +1494,7 @@ void vnf_handle_nr_slot_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf
|
||||
}
|
||||
else
|
||||
{
|
||||
nfapi_nr_slot_indication_scf_t ind;
|
||||
nfapi_nr_slot_indication_scf_t ind = {0};
|
||||
|
||||
if(nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, &ind, sizeof(ind), &vnf_p7->_public.codec_config) < 0)
|
||||
{
|
||||
@@ -1534,7 +1529,7 @@ void vnf_handle_nr_rx_data_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t*
|
||||
}
|
||||
else
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s: Handling RX Indication\n", __FUNCTION__);
|
||||
NFAPI_TRACE(NFAPI_TRACE_DEBUG, "%s: Handling RX Indication\n", __FUNCTION__);
|
||||
if(vnf_p7->_public.nr_rx_data_indication)
|
||||
{
|
||||
(vnf_p7->_public.nr_rx_data_indication)(&ind);
|
||||
@@ -1561,7 +1556,7 @@ void vnf_handle_nr_crc_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_
|
||||
}
|
||||
else
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s: Handling CRC Indication\n", __FUNCTION__);
|
||||
NFAPI_TRACE(NFAPI_TRACE_DEBUG, "%s: Handling CRC Indication\n", __FUNCTION__);
|
||||
if(vnf_p7->_public.nr_crc_indication)
|
||||
{
|
||||
(vnf_p7->_public.nr_crc_indication)(&ind);
|
||||
@@ -1614,7 +1609,7 @@ void vnf_handle_nr_uci_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_
|
||||
}
|
||||
else
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s: Handling UCI Indication\n", __FUNCTION__);
|
||||
NFAPI_TRACE(NFAPI_TRACE_DEBUG, "%s: Handling UCI Indication\n", __FUNCTION__);
|
||||
if(vnf_p7->_public.nr_uci_indication)
|
||||
{
|
||||
(vnf_p7->_public.nr_uci_indication)(&ind);
|
||||
@@ -1673,9 +1668,9 @@ void vnf_nr_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7
|
||||
//NFAPI_TRACE(NFAPI_TRACE_INFO, "Received UL_NODE_SYNC phy_id:%d t1:%d t2:%d t3:%d\n", ind.header.phy_id, ind.t1, ind.t2, ind.t3);
|
||||
|
||||
nfapi_vnf_p7_connection_info_t* phy = vnf_p7_connection_info_list_find(vnf_p7, ind.header.phy_id);
|
||||
uint32_t t4 = calculate_nr_t4(now_time_hr, phy->sfn, phy->slot, vnf_p7->slot_start_time_hr);
|
||||
uint32_t t4 = calculate_nr_t4(now_time_hr, phy->mu, phy->sfn, phy->slot, vnf_p7->slot_start_time_hr);
|
||||
|
||||
uint32_t tx_2_rx = t4>ind.t1 ? t4 - ind.t1 : t4 + NFAPI_MAX_SFNSLOTDEC - ind.t1 ; //time taken to receive ul node sync - time taken to send dl node sync
|
||||
uint32_t tx_2_rx = t4>ind.t1 ? t4 - ind.t1 : t4 + NFAPI_MAX_SFNSLOTDEC(phy->mu) - ind.t1 ; //time taken to receive ul node sync - time taken to send dl node sync
|
||||
uint32_t pnf_proc_time = ind.t3 - ind.t2;
|
||||
|
||||
// divide by 2 using shift operator
|
||||
@@ -1700,12 +1695,12 @@ void vnf_nr_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7
|
||||
if (ind.t2 < phy->previous_t2 && ind.t1 > phy->previous_t1)
|
||||
{
|
||||
// Only t2 wrap has occurred!!!
|
||||
phy->slot_offset = (NFAPI_MAX_SFNSLOTDEC + ind.t2) - ind.t1 - latency;
|
||||
phy->slot_offset = (NFAPI_MAX_SFNSLOTDEC(phy->mu) + ind.t2) - ind.t1 - latency;
|
||||
}
|
||||
else if (ind.t2 > phy->previous_t2 && ind.t1 < phy->previous_t1)
|
||||
{
|
||||
// Only t1 wrap has occurred
|
||||
phy->slot_offset = ind.t2 - ( ind.t1 + NFAPI_MAX_SFNSLOTDEC) - latency;
|
||||
phy->slot_offset = ind.t2 - ( ind.t1 + NFAPI_MAX_SFNSLOTDEC(phy->mu)) - latency;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1757,7 +1752,7 @@ void vnf_nr_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7
|
||||
{
|
||||
uint32_t curr_sfn = phy->sfn;
|
||||
uint32_t curr_slot = phy->slot;
|
||||
int32_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(phy->sfn,phy->slot);
|
||||
int32_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(phy->mu, phy->sfn,phy->slot);
|
||||
|
||||
if(!phy->filtered_adjust)
|
||||
{
|
||||
@@ -1774,7 +1769,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(phy->mu, sfn_slot_dec),NFAPI_SFNSLOTDEC2SLOT(phy->mu, sfn_slot_dec) );
|
||||
|
||||
|
||||
}
|
||||
@@ -1786,19 +1781,19 @@ void vnf_nr_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7
|
||||
|
||||
if(sfn_slot_dec < 0)
|
||||
{
|
||||
sfn_slot_dec += NFAPI_MAX_SFNSLOTDEC;
|
||||
sfn_slot_dec += NFAPI_MAX_SFNSLOTDEC(phy->mu);
|
||||
}
|
||||
else if( sfn_slot_dec >= NFAPI_MAX_SFNSLOTDEC)
|
||||
else if( sfn_slot_dec >= NFAPI_MAX_SFNSLOTDEC(phy->mu))
|
||||
{
|
||||
sfn_slot_dec -= NFAPI_MAX_SFNSLOTDEC;
|
||||
sfn_slot_dec -= NFAPI_MAX_SFNSLOTDEC(phy->mu);
|
||||
}
|
||||
|
||||
|
||||
uint16_t new_sfn = NFAPI_SFNSLOTDEC2SFN(sfn_slot_dec);
|
||||
uint16_t new_slot = NFAPI_SFNSLOTDEC2SLOT(sfn_slot_dec);
|
||||
uint16_t new_sfn = NFAPI_SFNSLOTDEC2SFN(phy->mu, sfn_slot_dec);
|
||||
uint16_t new_slot = NFAPI_SFNSLOTDEC2SLOT(phy->mu, sfn_slot_dec);
|
||||
|
||||
{
|
||||
phy->adjustment = NFAPI_SFNSLOT2DEC(new_sfn, new_slot) - NFAPI_SFNSLOT2DEC(curr_sfn, curr_slot);
|
||||
phy->adjustment = NFAPI_SFNSLOT2DEC(phy->mu, new_sfn, new_slot) - NFAPI_SFNSLOT2DEC(phy->mu, curr_sfn, curr_slot);
|
||||
|
||||
//NFAPI_TRACE(NFAPI_TRACE_NOTE, "PNF to VNF phy_id:%d adjustment%d phy->previous_slot_offset_filtered:%d phy->previous_slot_offset_filtered:%d phy->slot_offset_trend:%d\n", ind.header.phy_id, phy->adjustment, phy->previous_slot_offset_filtered, phy->previous_slot_offset_filtered, phy->slot_offset_trend);
|
||||
|
||||
@@ -1906,15 +1901,24 @@ void vnf_nr_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7
|
||||
|
||||
if(phy->insync_minor_adjustment != 0)
|
||||
{
|
||||
// NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%4d/%d) VNF phy_id:%d Apply minor insync adjustment %dus for %d slots (slot_offset_filtered:%d) %d %d %d NEW:%d CURR:%d adjustment:%d\n",
|
||||
// phy->sfn, phy->slot, ind.header.phy_id,
|
||||
// phy->insync_minor_adjustment, phy->insync_minor_adjustment_duration,
|
||||
// phy->slot_offset_filtered,
|
||||
// insync_minor_adjustment_1, insync_minor_adjustment_2, phy->slot_offset_trend,
|
||||
// NFAPI_SFNSLOT2DEC(new_sfn, new_slot),
|
||||
// NFAPI_SFNSLOT2DEC(curr_sfn, curr_slot),
|
||||
// phy->adjustment);
|
||||
}
|
||||
NFAPI_TRACE(NFAPI_TRACE_DEBUG,
|
||||
"(%4d/%d) VNF phy_id:%d Apply minor insync adjustment %dus for %d slots (slot_offset_filtered:%d) %d %d "
|
||||
"%d NEW:%d.%d CURR:%d.%d adjustment:%d\n",
|
||||
phy->sfn,
|
||||
phy->slot,
|
||||
ind.header.phy_id,
|
||||
phy->insync_minor_adjustment,
|
||||
phy->insync_minor_adjustment_duration,
|
||||
phy->slot_offset_filtered,
|
||||
insync_minor_adjustment_1,
|
||||
insync_minor_adjustment_2,
|
||||
phy->slot_offset_trend,
|
||||
new_sfn,
|
||||
new_slot,
|
||||
curr_sfn,
|
||||
curr_slot,
|
||||
phy->adjustment);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1948,16 +1952,27 @@ void vnf_nr_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7
|
||||
{
|
||||
// out of sync?
|
||||
}
|
||||
|
||||
// NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%4d/%d) VNF phy_id:%d Apply minor insync adjustment %dus for %d slots (adjustment:%d slot_offset_filtered:%d) %d %d %d NEW:%d CURR:%d adj:%d\n",
|
||||
// phy->sfn, phy->slot, ind.header.phy_id,
|
||||
// phy->insync_minor_adjustment, phy->insync_minor_adjustment_duration, phy->adjustment, phy->slot_offset_filtered,
|
||||
// insync_minor_adjustment_1, insync_minor_adjustment_2, phy->slot_offset_trend,
|
||||
// NFAPI_SFNSLOT2DEC(new_sfn, new_slot),
|
||||
// NFAPI_SFNSLOT2DEC(curr_sfn, curr_slot),
|
||||
// phy->adjustment);
|
||||
|
||||
}
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_DEBUG,
|
||||
"(%4d/%d) VNF phy_id:%d Apply minor insync adjustment %dus for %d slots (adjustment:%d "
|
||||
"slot_offset_filtered:%d) %d %d %d NEW:%d.%d CURR:%d.%d adj:%d\n",
|
||||
phy->sfn,
|
||||
phy->slot,
|
||||
ind.header.phy_id,
|
||||
phy->insync_minor_adjustment,
|
||||
phy->insync_minor_adjustment_duration,
|
||||
phy->adjustment,
|
||||
phy->slot_offset_filtered,
|
||||
insync_minor_adjustment_1,
|
||||
insync_minor_adjustment_2,
|
||||
phy->slot_offset_trend,
|
||||
new_sfn,
|
||||
new_slot,
|
||||
curr_sfn,
|
||||
curr_slot,
|
||||
phy->adjustment);
|
||||
|
||||
}
|
||||
else if(phy->adjustment < 0)
|
||||
{
|
||||
// VNF is fast
|
||||
@@ -2088,15 +2103,16 @@ void vnf_nr_handle_timing_info(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
|
||||
if (vnf_p7 && vnf_p7->p7_connections)
|
||||
{
|
||||
//int16_t vnf_pnf_sfnsf_delta = NFAPI_SFNSF2DEC(vnf_p7->p7_connections[0].sfn_sf) - NFAPI_SFNSF2DEC(ind.last_sfn_sf);
|
||||
vnf_pnf_sfnslot_delta = NFAPI_SFNSLOT2DEC(vnf_p7->p7_connections[0].sfn,vnf_p7->p7_connections[0].slot) - NFAPI_SFNSLOT2DEC(ind.last_sfn,ind.last_slot);
|
||||
nfapi_vnf_p7_connection_info_t *p7_con = &vnf_p7->p7_connections[0];
|
||||
vnf_pnf_sfnslot_delta = NFAPI_SFNSLOT2DEC(p7_con->mu, p7_con->sfn,p7_con->slot) - NFAPI_SFNSLOT2DEC(p7_con->mu, ind.last_sfn,ind.last_slot);
|
||||
//NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() PNF:SFN/SF:%d VNF:SFN/SF:%d deltaSFNSF:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind.last_sfn_sf), NFAPI_SFNSF2DEC(vnf_p7->p7_connections[0].sfn_sf), vnf_pnf_sfnsf_delta);
|
||||
|
||||
// Panos: Careful here!!! Modification of the original nfapi-code
|
||||
//if (vnf_pnf_sfnsf_delta>1 || vnf_pnf_sfnsf_delta < -1)
|
||||
//printf("VNF-PNF delta - %d", vnf_pnf_sfnslot_delta);
|
||||
if (vnf_pnf_sfnslot_delta != 0)
|
||||
if (vnf_pnf_sfnslot_delta > 1) // we need to have a small delta, otherwise it would mean we don't advance
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() LARGE SFN/SLOT DELTA between PNF and VNF. Delta %d. PNF:%d.%d VNF:%d.%d\n\n\n\n\n\n\n\n\n",
|
||||
NFAPI_TRACE(NFAPI_TRACE_WARN, "%s() LARGE SFN/SLOT DELTA between PNF and VNF. Delta %d slots. PNF:%d.%d VNF:%d.%d\n",
|
||||
__FUNCTION__, vnf_pnf_sfnslot_delta,
|
||||
ind.last_sfn, ind.last_slot,
|
||||
vnf_p7->p7_connections[0].sfn, vnf_p7->p7_connections[0].slot);
|
||||
@@ -2507,7 +2523,8 @@ void vnf_nr_handle_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
|
||||
vnf_p7_rx_reassembly_queue_remove_msg(vnf_p7, &(phy->reassembly_queue), rx_msg);
|
||||
}
|
||||
|
||||
vnf_p7_rx_reassembly_queue_remove_old_msgs(vnf_p7, &(phy->reassembly_queue), 1000);
|
||||
// see corresponding comment in pnf_nr_handle_p7_message() [same commit]
|
||||
vnf_p7_rx_reassembly_queue_remove_old_msgs(vnf_p7, &(phy->reassembly_queue), 10000);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -42,7 +42,7 @@ nfapi_vnf_p7_config_t* nfapi_vnf_p7_config_create()
|
||||
return 0;
|
||||
|
||||
// todo : initialize
|
||||
_this->_public.segment_size = 1400;
|
||||
_this->_public.segment_size = 65000; // UDP max packet size is 65535
|
||||
_this->_public.max_num_segments = 8;
|
||||
_this->_public.checksum_enabled = 1;
|
||||
|
||||
@@ -98,8 +98,6 @@ struct timespec timespec_sub(struct timespec lhs, struct timespec rhs)
|
||||
// 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;
|
||||
|
||||
@@ -157,7 +155,6 @@ int nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t* config)
|
||||
|
||||
struct timespec ref_time;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ref_time);
|
||||
uint8_t setup_done;
|
||||
while(vnf_p7->terminate == 0)
|
||||
{
|
||||
fd_set rfds;
|
||||
@@ -169,39 +166,6 @@ int nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t* config)
|
||||
FD_SET(vnf_p7->socket, &rfds);
|
||||
maxSock = vnf_p7->socket;
|
||||
|
||||
if (setup_done == 0) {
|
||||
struct timespec curr_time;
|
||||
clock_gettime(CLOCK_MONOTONIC, &curr_time);
|
||||
uint8_t setup_time = curr_time.tv_sec - ref_time.tv_sec;
|
||||
if (setup_time > 3) {
|
||||
setup_done = 1;
|
||||
}
|
||||
}
|
||||
|
||||
nfapi_nr_slot_indication_scf_t *slot_ind = get_queue(&gnb_slot_ind_queue);
|
||||
NFAPI_TRACE(NFAPI_TRACE_DEBUG, "This is the slot_ind queue size %ld in %s():%d\n",
|
||||
gnb_slot_ind_queue.num_items, __FUNCTION__, __LINE__);
|
||||
if (slot_ind) {
|
||||
NR_UL_IND_t UL_INFO = {.frame = slot_ind->sfn, .slot = slot_ind->slot};
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_DEBUG, "UL_INFO.frame = %d and slot %d, prev_slot = %d\n", UL_INFO.frame, UL_INFO.slot, prev_slot);
|
||||
if (setup_done && prev_slot != UL_INFO.slot) { // Give the VNF sufficient time to setup before starting scheduling &&
|
||||
// prev_slot != UL_INFO.slot
|
||||
|
||||
// Call the scheduler
|
||||
UL_INFO.module_id = gNB->Mod_id;
|
||||
UL_INFO.CC_id = gNB->CC_id;
|
||||
NFAPI_TRACE(NFAPI_TRACE_DEBUG,
|
||||
"Calling NR_UL_indication for UL_INFO.frame = %d and slot %d\n",
|
||||
UL_INFO.frame,
|
||||
UL_INFO.slot);
|
||||
gNB->if_inst->NR_UL_indication(&UL_INFO);
|
||||
prev_slot = UL_INFO.slot;
|
||||
}
|
||||
free(slot_ind);
|
||||
slot_ind = NULL;
|
||||
}
|
||||
|
||||
selectRetval = pselect(maxSock+1, &rfds, NULL, NULL, &pselect_timeout, NULL);
|
||||
|
||||
if(selectRetval == 0)
|
||||
@@ -570,7 +534,7 @@ int nfapi_vnf_p7_stop(nfapi_vnf_p7_config_t* config)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nfapi_vnf_p7_add_pnf(nfapi_vnf_p7_config_t* config, const char* pnf_p7_addr, int pnf_p7_port, int phy_id)
|
||||
int nfapi_vnf_p7_add_pnf(nfapi_vnf_p7_config_t* config, const char* pnf_p7_addr, int pnf_p7_port, int phy_id, int mu)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s(config:%p phy_id:%d pnf_addr:%s pnf_p7_port:%d)\n", __FUNCTION__, config, phy_id, pnf_p7_addr, pnf_p7_port);
|
||||
|
||||
@@ -594,6 +558,7 @@ int nfapi_vnf_p7_add_pnf(nfapi_vnf_p7_config_t* config, const char* pnf_p7_addr,
|
||||
node->sfn = 0;
|
||||
node->slot = 0;
|
||||
node->min_sync_cycle_count = 8;
|
||||
node->mu = mu;
|
||||
|
||||
// save the remote endpoint information
|
||||
node->remote_addr.sin_family = AF_INET;
|
||||
|
||||
@@ -769,7 +769,7 @@ int start_response(nfapi_vnf_config_t* config, int p5_idx, nfapi_start_response_
|
||||
|
||||
vnf_test_config_vnf_t* vnf = &(vnf_test_config[0].vnfs[phy->vnf_idx]);
|
||||
|
||||
nfapi_vnf_p7_add_pnf(vnf->config, addr, port, response->header.phy_id);
|
||||
nfapi_vnf_p7_add_pnf(vnf->config, addr, port, response->header.phy_id, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -22,7 +22,7 @@
|
||||
#include "nr_fapi_p5.h"
|
||||
#include "nr_fapi_p5_utils.h"
|
||||
|
||||
void fill_config_request_tlv(nfapi_nr_config_request_scf_t *nfapi_resp)
|
||||
static void fill_config_request_tlv_tdd_rand(nfapi_nr_config_request_scf_t *nfapi_resp)
|
||||
{
|
||||
FILL_TLV(nfapi_resp->carrier_config.dl_bandwidth, NFAPI_NR_CONFIG_DL_BANDWIDTH_TAG, rand16());
|
||||
nfapi_resp->num_tlv++;
|
||||
@@ -70,7 +70,8 @@ void fill_config_request_tlv(nfapi_nr_config_request_scf_t *nfapi_resp)
|
||||
FILL_TLV(nfapi_resp->cell_config.phy_cell_id, NFAPI_NR_CONFIG_PHY_CELL_ID_TAG, rand16());
|
||||
nfapi_resp->num_tlv++;
|
||||
|
||||
FILL_TLV(nfapi_resp->cell_config.frame_duplex_type, NFAPI_NR_CONFIG_FRAME_DUPLEX_TYPE_TAG, rand8());
|
||||
// TDD because below we pack the TDD table
|
||||
FILL_TLV(nfapi_resp->cell_config.frame_duplex_type, NFAPI_NR_CONFIG_FRAME_DUPLEX_TYPE_TAG, 1 /* TDD */);
|
||||
nfapi_resp->num_tlv++;
|
||||
|
||||
FILL_TLV(nfapi_resp->ssb_config.ss_pbch_power, NFAPI_NR_CONFIG_SS_PBCH_POWER_TAG, (int32_t)rand32());
|
||||
@@ -230,7 +231,7 @@ void fill_config_request_tlv(nfapi_nr_config_request_scf_t *nfapi_resp)
|
||||
nfapi_resp->num_tlv++;
|
||||
}
|
||||
|
||||
void test_pack_unpack(nfapi_nr_config_request_scf_t *req)
|
||||
static void test_pack_unpack(nfapi_nr_config_request_scf_t *req)
|
||||
{
|
||||
uint8_t msg_buf[65535];
|
||||
uint16_t msg_len = sizeof(*req);
|
||||
@@ -263,7 +264,7 @@ void test_pack_unpack(nfapi_nr_config_request_scf_t *req)
|
||||
free_config_request(&unpacked_req);
|
||||
}
|
||||
|
||||
void test_copy(const nfapi_nr_config_request_scf_t *msg)
|
||||
static void test_copy(const nfapi_nr_config_request_scf_t *msg)
|
||||
{
|
||||
// Test copy function
|
||||
nfapi_nr_config_request_scf_t copy = {0};
|
||||
@@ -272,16 +273,173 @@ void test_copy(const nfapi_nr_config_request_scf_t *msg)
|
||||
free_config_request(©);
|
||||
}
|
||||
|
||||
int main(int n, char *v[])
|
||||
static void test_config_req_rand(void)
|
||||
{
|
||||
fapi_test_init();
|
||||
nfapi_nr_config_request_scf_t req = {.header.message_id = NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST};
|
||||
// Fill CONFIG.request TVLs
|
||||
fill_config_request_tlv(&req);
|
||||
fill_config_request_tlv_tdd_rand(&req);
|
||||
// Perform tests
|
||||
test_pack_unpack(&req);
|
||||
test_copy(&req);
|
||||
// All tests successful!
|
||||
free_config_request(&req);
|
||||
}
|
||||
|
||||
static void fill_config_request_tlv_fdd(nfapi_nr_config_request_scf_t *req)
|
||||
{
|
||||
/* carrier config */
|
||||
FILL_TLV(req->carrier_config.dl_bandwidth, NFAPI_NR_CONFIG_DL_BANDWIDTH_TAG, 5);
|
||||
req->num_tlv++;
|
||||
FILL_TLV(req->carrier_config.dl_frequency, NFAPI_NR_CONFIG_DL_FREQUENCY_TAG, 2150430);
|
||||
req->num_tlv++;
|
||||
for (int i = 0; i < 5; ++i)
|
||||
FILL_TLV(req->carrier_config.dl_k0[i], NFAPI_NR_CONFIG_DL_K0_TAG, 0);
|
||||
// these 5 are 1 tlv
|
||||
req->num_tlv++;
|
||||
FILL_TLV(req->carrier_config.dl_grid_size[0], NFAPI_NR_CONFIG_DL_GRID_SIZE_TAG, 25);
|
||||
for (int i = 1; i < 5; ++i)
|
||||
FILL_TLV(req->carrier_config.dl_grid_size[i], NFAPI_NR_CONFIG_DL_GRID_SIZE_TAG, 0);
|
||||
// these 5 are 1 tlv
|
||||
req->num_tlv++;
|
||||
FILL_TLV(req->carrier_config.num_tx_ant, NFAPI_NR_CONFIG_NUM_TX_ANT_TAG, 1);
|
||||
req->num_tlv++;
|
||||
FILL_TLV(req->carrier_config.uplink_bandwidth, NFAPI_NR_CONFIG_UPLINK_BANDWIDTH_TAG, 5);
|
||||
req->num_tlv++;
|
||||
FILL_TLV(req->carrier_config.uplink_frequency, NFAPI_NR_CONFIG_UPLINK_FREQUENCY_TAG, 1750430);
|
||||
req->num_tlv++;
|
||||
for (int i = 0; i < 5; ++i)
|
||||
FILL_TLV(req->carrier_config.ul_k0[i], NFAPI_NR_CONFIG_UL_K0_TAG, 0);
|
||||
// these 5 are 1 tlv
|
||||
req->num_tlv++;
|
||||
FILL_TLV(req->carrier_config.ul_grid_size[0], NFAPI_NR_CONFIG_UL_GRID_SIZE_TAG, 25);
|
||||
for (int i = 0; i < 5; ++i)
|
||||
FILL_TLV(req->carrier_config.ul_grid_size[i], NFAPI_NR_CONFIG_UL_GRID_SIZE_TAG, 0);
|
||||
// these 5 are 1 tlv
|
||||
req->num_tlv++;
|
||||
FILL_TLV(req->carrier_config.num_rx_ant, NFAPI_NR_CONFIG_NUM_RX_ANT_TAG, 1);
|
||||
req->num_tlv++;
|
||||
FILL_TLV(req->carrier_config.frequency_shift_7p5khz, NFAPI_NR_CONFIG_FREQUENCY_SHIFT_7P5KHZ_TAG, 0);
|
||||
req->num_tlv++;
|
||||
|
||||
/* cell config */
|
||||
FILL_TLV(req->cell_config.phy_cell_id, NFAPI_NR_CONFIG_PHY_CELL_ID_TAG, 0);
|
||||
req->num_tlv++;
|
||||
FILL_TLV(req->cell_config.frame_duplex_type, NFAPI_NR_CONFIG_FRAME_DUPLEX_TYPE_TAG, 0 /* FDD */);
|
||||
req->num_tlv++;
|
||||
|
||||
/* SSB config */
|
||||
FILL_TLV(req->ssb_config.ss_pbch_power, NFAPI_NR_CONFIG_SS_PBCH_POWER_TAG, -25);
|
||||
req->num_tlv++;
|
||||
FILL_TLV(req->ssb_config.bch_payload, NFAPI_NR_CONFIG_BCH_PAYLOAD_TAG, 1 /* PHY generates timing bits */);
|
||||
req->num_tlv++;
|
||||
FILL_TLV(req->ssb_config.scs_common, NFAPI_NR_CONFIG_SCS_COMMON_TAG, 0 /* 15 kHz */);
|
||||
req->num_tlv++;
|
||||
|
||||
/* PRACH config */
|
||||
FILL_TLV(req->prach_config.prach_sequence_length, NFAPI_NR_CONFIG_PRACH_SEQUENCE_LENGTH_TAG, 1);
|
||||
req->num_tlv++;
|
||||
FILL_TLV(req->prach_config.prach_sub_c_spacing, NFAPI_NR_CONFIG_PRACH_SUB_C_SPACING_TAG, 0);
|
||||
req->num_tlv++;
|
||||
FILL_TLV(req->prach_config.restricted_set_config, NFAPI_NR_CONFIG_RESTRICTED_SET_CONFIG_TAG, 0);
|
||||
req->num_tlv++;
|
||||
FILL_TLV(req->prach_config.prach_ConfigurationIndex, NFAPI_NR_CONFIG_PRACH_CONFIG_INDEX_TAG, 98);
|
||||
req->num_tlv++;
|
||||
int num_prach = 1;
|
||||
FILL_TLV(req->prach_config.num_prach_fd_occasions, NFAPI_NR_CONFIG_NUM_PRACH_FD_OCCASIONS_TAG, num_prach);
|
||||
req->num_tlv++;
|
||||
nfapi_nr_num_prach_fd_occasions_t *l = calloc(num_prach, sizeof(*l));
|
||||
req->prach_config.num_prach_fd_occasions_list = l;
|
||||
FILL_TLV(l->prach_root_sequence_index, NFAPI_NR_CONFIG_PRACH_ROOT_SEQUENCE_INDEX_TAG, 1);
|
||||
req->num_tlv++;
|
||||
FILL_TLV(l->num_root_sequences, NFAPI_NR_CONFIG_NUM_ROOT_SEQUENCES_TAG, 16);
|
||||
req->num_tlv++;
|
||||
FILL_TLV(l->k1, NFAPI_NR_CONFIG_K1_TAG, 0);
|
||||
req->num_tlv++;
|
||||
FILL_TLV(l->prach_zero_corr_conf, NFAPI_NR_CONFIG_PRACH_ZERO_CORR_CONF_TAG, 13);
|
||||
req->num_tlv++;
|
||||
/* should be at least according to spec */
|
||||
FILL_TLV(l->num_unused_root_sequences, NFAPI_NR_CONFIG_NUM_UNUSED_ROOT_SEQUENCES_TAG, 0);
|
||||
req->num_tlv++;
|
||||
l->unused_root_sequences_list = NULL;
|
||||
FILL_TLV(req->prach_config.ssb_per_rach, NFAPI_NR_CONFIG_SSB_PER_RACH_TAG, 3);
|
||||
req->num_tlv++;
|
||||
FILL_TLV(req->prach_config.prach_multiple_carriers_in_a_band, NFAPI_NR_CONFIG_PRACH_MULTIPLE_CARRIERS_IN_A_BAND_TAG, 0);
|
||||
req->num_tlv++;
|
||||
|
||||
/* SSB table */
|
||||
FILL_TLV(req->ssb_table.ssb_offset_point_a, NFAPI_NR_CONFIG_SSB_OFFSET_POINT_A_TAG, 4);
|
||||
req->num_tlv++;
|
||||
FILL_TLV(req->ssb_table.ssb_period, NFAPI_NR_CONFIG_SSB_PERIOD_TAG, 2);
|
||||
req->num_tlv++;
|
||||
FILL_TLV(req->ssb_table.ssb_subcarrier_offset, NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG, 0);
|
||||
req->num_tlv++;
|
||||
FILL_TLV(req->ssb_table.MIB, NFAPI_NR_CONFIG_MIB_TAG, 0);
|
||||
req->num_tlv++;
|
||||
|
||||
FILL_TLV(req->ssb_table.ssb_mask_list[0].ssb_mask, NFAPI_NR_CONFIG_SSB_MASK_TAG, 2147483648);
|
||||
req->num_tlv++;
|
||||
FILL_TLV(req->ssb_table.ssb_mask_list[1].ssb_mask, NFAPI_NR_CONFIG_SSB_MASK_TAG, 0);
|
||||
req->num_tlv++;
|
||||
for (int i = 0; i < 64; i++) {
|
||||
FILL_TLV(req->ssb_table.ssb_beam_id_list[i].beam_id, NFAPI_NR_CONFIG_BEAM_ID_TAG, 0);
|
||||
req->num_tlv++;
|
||||
}
|
||||
|
||||
/* NOTE: no TDD table! */
|
||||
|
||||
/* Measurement config rssi_measurement NULL -> not present */
|
||||
|
||||
/* nFAPI config */
|
||||
/* IPv4 address is 127.0.0.1 */
|
||||
req->nfapi_config.p7_vnf_address_ipv4.tl.tag = NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG;
|
||||
req->nfapi_config.p7_vnf_address_ipv4.address[0] = 127;
|
||||
req->nfapi_config.p7_vnf_address_ipv4.address[1] = 0;
|
||||
req->nfapi_config.p7_vnf_address_ipv4.address[2] = 0;
|
||||
req->nfapi_config.p7_vnf_address_ipv4.address[3] = 1;
|
||||
req->num_tlv++;
|
||||
/* no IPv6 address */
|
||||
FILL_TLV(req->nfapi_config.p7_vnf_port, NFAPI_NR_NFAPI_P7_VNF_PORT_TAG, 50011);
|
||||
req->num_tlv++;
|
||||
FILL_TLV(req->nfapi_config.timing_window, NFAPI_NR_NFAPI_TIMING_WINDOW_TAG, 30);
|
||||
req->num_tlv++;
|
||||
FILL_TLV(req->nfapi_config.timing_info_mode, NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG, 3);
|
||||
req->num_tlv++;
|
||||
FILL_TLV(req->nfapi_config.timing_info_period, NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG, 10);
|
||||
req->num_tlv++;
|
||||
FILL_TLV(req->nfapi_config.dl_tti_timing_offset, NFAPI_NR_NFAPI_DL_TTI_TIMING_OFFSET, 0);
|
||||
req->num_tlv++;
|
||||
FILL_TLV(req->nfapi_config.dl_tti_timing_offset, NFAPI_NR_NFAPI_UL_TTI_TIMING_OFFSET, 0);
|
||||
req->num_tlv++;
|
||||
FILL_TLV(req->nfapi_config.dl_tti_timing_offset, NFAPI_NR_NFAPI_UL_DCI_TIMING_OFFSET, 0);
|
||||
req->num_tlv++;
|
||||
FILL_TLV(req->nfapi_config.dl_tti_timing_offset, NFAPI_NR_NFAPI_TX_DATA_TIMING_OFFSET, 0);
|
||||
req->num_tlv++;
|
||||
|
||||
/* PMI list NULL */
|
||||
|
||||
/* Digital beamforming NULL */
|
||||
|
||||
/* Analog beamforming NULL */
|
||||
|
||||
//DevAssert(req->num_tlv == 103);
|
||||
}
|
||||
|
||||
static void test_config_req_fdd(void)
|
||||
{
|
||||
nfapi_nr_config_request_scf_t req = {.header.phy_id = 1, .header.message_id = NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST};
|
||||
// Fill CONFIG.request TVLs
|
||||
fill_config_request_tlv_fdd(&req);
|
||||
// Perform tests
|
||||
test_pack_unpack(&req);
|
||||
test_copy(&req);
|
||||
// All tests successful!
|
||||
free_config_request(&req);
|
||||
}
|
||||
|
||||
int main(int n, char *v[])
|
||||
{
|
||||
fapi_test_init();
|
||||
test_config_req_rand();
|
||||
test_config_req_fdd();
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user