Reimplement nFAPI message exchange after msgDataTx removal

Reimplement nFAPI message exchange between L1 and L2 following the
changes in parent commit removing msgDataTx.

Avoid direct calls and use NR_IF_module fptrs to avoid linking problems.
allowing to remove some function definitions that are not needed.
This commit is contained in:
Robert Schmidt
2025-11-14 18:16:02 +01:00
parent 2bea71a80a
commit eefb9da69a
12 changed files with 216 additions and 188 deletions
+2 -2
View File
@@ -242,10 +242,10 @@ To see the (any) periodical output at the PNF, define `NFAPI_TRACE_LEVEL=info`.
This output shows:
```
41056.739654 [I] 3556767424: pnf_p7_slot_ind: [P7:1] msgs ontime 489 thr DL 0.06 UL 0.01 msg late 0 (vtime)
41056.739654 [I] 3556767424: nr_pnf_p7_get_msgs: [P7:1] msgs ontime 489 thr DL 0.06 UL 0.01 msg late 0 (vtime)
```
The first numbers are timestamps. `pnf_p7_slot_ind` is the name of the
The first numbers are timestamps. `nr_pnf_p7_get_msgs` is the name of the
functions that prints the output. `[P7:1]` refers to the fact that these are
information on P7, of PHY ID 1. Finally, `msgs ontime 489` means that in the
last window (since the last print), 489 messages arrived at the PNF in total.
-2
View File
@@ -199,8 +199,6 @@ void nr_schedule_ul_dci_req() {};
void nr_schedule_tx_req() {};
void nr_schedule_ul_tti_req() {};
void nr_slot_select() {};
void NR_UL_indication(NR_UL_IND_t *UL_INFO) {};
void gNB_dlsch_ulsch_scheduler() {};
/*------------------------------------------------------------------------*/
+9 -2
View File
@@ -2314,7 +2314,7 @@ static void maybe_slow_down_pnf(int mu)
last_execution = current_execution;
}
void handle_nr_slot_ind(uint16_t sfn, uint16_t slot)
void handle_nr_slot_ind(uint16_t sfn, uint16_t slot, NR_Sched_Rsp_t *sched_resp)
{
nfapi_pnf_p7_config_t *config = p7_config_g;
pnf_p7_t *_this = (pnf_p7_t *)(config);
@@ -2345,7 +2345,14 @@ void handle_nr_slot_ind(uint16_t sfn, uint16_t slot)
oai_nfapi_nr_slot_indication(&ind);
// copy data from appropriate p7 slot buffers into channel structures for PHY processing
nfapi_pnf_p7_slot_ind(config, config->phy_id, sfn, slot);
nfapi_pnf_p7_get_msgs(config,
config->phy_id,
sfn,
slot,
&sched_resp->DL_req,
&sched_resp->UL_tti_req,
&sched_resp->UL_dci_req,
&sched_resp->TX_req);
return;
}
+2 -1
View File
@@ -28,7 +28,8 @@ void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr,
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 handle_nr_slot_ind(uint16_t sfn, uint16_t slot);
struct NR_Sched_Rsp;
void handle_nr_slot_ind(uint16_t sfn, uint16_t slot, struct NR_Sched_Rsp *resp);
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);
+48 -50
View File
@@ -971,65 +971,63 @@ int phy_cqi_indication(struct nfapi_vnf_p7_config *config, nfapi_cqi_indication_
//NR phy indication
NR_Sched_Rsp_t g_sched_resp;
void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, slot_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);
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);
// this variable is very big (multiple MB), so we put it into static storage
// to not overflow the stack while still having it in local (function) scope
// also, phy_nr_slot_indication() is only executed by one thread, serially
static NR_Sched_Rsp_t sched_response;
NR_IF_Module_t *ifi = RC.nrmac[0]->if_inst;
ifi->NR_slot_indication(ind, &sched_response);
#ifdef ENABLE_AERIAL
bool send_slt_resp = false;
if (sched_response.DL_req.dl_tti_request_body.nPDUs> 0) {
oai_fapi_dl_tti_req(&sched_response.DL_req);
send_slt_resp = true;
}
if (sched_response.UL_tti_req.n_pdus > 0) {
oai_fapi_ul_tti_req(&sched_response.UL_tti_req);
send_slt_resp = true;
}
if (sched_response.TX_req.Number_of_PDUs > 0) {
oai_fapi_tx_data_req(&sched_response.TX_req);
send_slt_resp = true;
}
if (sched_response.UL_dci_req.numPdus > 0) {
oai_fapi_ul_dci_req(&sched_response.UL_dci_req);
send_slt_resp = true;
}
if (send_slt_resp) {
oai_fapi_send_end_request(0, ind->sfn, ind->slot);
}
#else
if (sched_response.DL_req.dl_tti_request_body.nPDUs > 0)
oai_nfapi_dl_tti_req(&sched_response.DL_req);
if (sched_response.UL_tti_req.n_pdus > 0)
oai_nfapi_ul_tti_req(&sched_response.UL_tti_req);
if (sched_response.TX_req.Number_of_PDUs > 0)
oai_nfapi_tx_data_req(&sched_response.TX_req);
if (sched_response.UL_dci_req.numPdus > 0)
oai_nfapi_ul_dci_req(&sched_response.UL_dci_req);
#endif
/* the below works because the function behind the callback collects
* messages from queue into which messages have been copied.
* TODO we should have different callbacks for received messages and call
* into the scheduler separately for each message instead of one big one. */
NR_UL_IND_t ul_ind = {.frame = ind->sfn, .slot = ind->slot, };
ifi->NR_UL_indication(&ul_ind);
return 1;
}
+8 -2
View File
@@ -145,8 +145,14 @@ int pnf_nr_p7_message_pump(pnf_p7_t* pnf_p7);
int pnf_p7_pack_and_send_p7_message(pnf_p7_t* pnf_p7, nfapi_p7_message_header_t* msg, uint32_t msg_len);
int pnf_p7_send_message(pnf_p7_t* pnf_p7, uint8_t* msg, uint32_t msg_len);
int pnf_p7_slot_ind(pnf_p7_t* config, uint16_t phy_id, uint16_t sfn, uint16_t slot);
int nr_pnf_p7_get_msgs(pnf_p7_t* pnf_p7,
uint16_t phy_id,
uint16_t sfn,
uint16_t slot,
nfapi_nr_dl_tti_request_t* ret_dl_tti,
nfapi_nr_ul_tti_request_t* ret_ul_tti,
nfapi_nr_ul_dci_request_t* ret_ul_dci,
nfapi_nr_tx_data_request_t* ret_tx_data);
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);
@@ -856,7 +856,7 @@ int nfapi_pnf_p7_start(nfapi_pnf_p7_config_t* config);
*/
int nfapi_pnf_p7_stop(nfapi_pnf_p7_config_t* config);
/*! NR Slot indication
/*! NR get stuff
* message copied from nfapi_pnf_p7_subframe_ind
* \param config A pointer to a PNF P7 config
* \param phy_id The phy_id for the phy instance
@@ -868,8 +868,14 @@ int nfapi_pnf_p7_stop(nfapi_pnf_p7_config_t* config);
*
* If messages are not in the subframe buffer, they dummy subframe messages will be sent
*/
int nfapi_pnf_p7_slot_ind(nfapi_pnf_p7_config_t* config, uint16_t phy_id, uint16_t sfn, uint16_t slot);
int nfapi_pnf_p7_get_msgs(nfapi_pnf_p7_config_t* config,
uint16_t phy_id,
uint16_t sfn,
uint16_t slot,
nfapi_nr_dl_tti_request_t* ret_dl_tti,
nfapi_nr_ul_tti_request_t* ret_ul_tti,
nfapi_nr_ul_dci_request_t* ret_ul_dci,
nfapi_nr_tx_data_request_t* ret_tx_data);
/*! Subframe indication
* \param config A pointer to a PNF P7 config
+112 -100
View File
@@ -672,145 +672,157 @@ 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)
int nr_pnf_p7_get_msgs(pnf_p7_t* pnf_p7,
uint16_t phy_id,
uint16_t sfn,
uint16_t slot,
nfapi_nr_dl_tti_request_t* ret_dl_tti,
nfapi_nr_ul_tti_request_t* ret_ul_tti,
nfapi_nr_ul_dci_request_t* ret_ul_dci,
nfapi_nr_tx_data_request_t* ret_tx_data)
{
//This function is aligned with rx sfn/slot
if (pthread_mutex_lock(&(pnf_p7->mutex)) != 0) {
NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n");
return -1;
}
// 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.
// save the curren time, sfn and slot
// TODO useful?
pnf_p7->slot_start_time_hr = pnf_get_current_time_hr();
// todo : consider a more efficent lock mechasium
//uint16_t NUM_SLOTS = 20;//10* 2^mu
// 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;
pnf_p7->slot = slot;
if(pthread_mutex_lock(&(pnf_p7->mutex)) != 0)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n");
return -1;
}
uint32_t tx_slot_dec = NFAPI_SFNSLOT2DEC(pnf_p7->mu, sfn, slot);
uint8_t buffer_index_tx = tx_slot_dec % NFAPI_SLOTNUM(pnf_p7->mu);
// save the curren time, sfn and slot
pnf_p7->slot_start_time_hr = pnf_get_current_time_hr();
// If the subframe_buffer has been configured
if (pnf_p7->_public.slot_buffer_size != 0) // for now value is same as sf_buffer_size
{
// apply the shift to the incoming sfn_sf
if (pnf_p7->slot_shift != 0) // see in vnf_build_send_dl_node_sync
{
uint16_t shifted_slot = slot + pnf_p7->slot_shift;
//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.
// adjust for wrap-around
if (shifted_slot < 0)
shifted_slot += NFAPI_MAX_SFNSLOTDEC(pnf_p7->mu);
else if (shifted_slot > NFAPI_MAX_SFNSLOTDEC(pnf_p7->mu))
shifted_slot -= NFAPI_MAX_SFNSLOTDEC(pnf_p7->mu);
pnf_p7->sfn = sfn;
pnf_p7->slot = slot;
//NFAPI_TRACE(NFAPI_TRACE_INFO, "Applying shift %d to sfn/slot (%d -> %d)\n", pnf_p7->sfn_slot_shift,
//NFAPI_SFNSF2DEC(sfn_slot), shifted_sfn_slot);
slot = shifted_slot;
uint32_t tx_slot_dec = NFAPI_SFNSLOT2DEC(pnf_p7->mu, sfn,slot);
uint8_t buffer_index_tx = tx_slot_dec % NFAPI_SLOTNUM(pnf_p7->mu);
//
// why does the shift not apply to pnf_p7->sfn_sf???
//
// If the subframe_buffer has been configured
if(pnf_p7->_public.slot_buffer_size!= 0) // for now value is same as sf_buffer_size
{
pnf_p7->slot_shift = 0;
}
// apply the shift to the incoming sfn_sf
if(pnf_p7->slot_shift != 0) // see in vnf_build_send_dl_node_sync
{
uint16_t shifted_slot = slot + pnf_p7->slot_shift;
// adjust for wrap-around
if(shifted_slot < 0)
shifted_slot += NFAPI_MAX_SFNSLOTDEC(pnf_p7->mu);
else if(shifted_slot > NFAPI_MAX_SFNSLOTDEC(pnf_p7->mu))
shifted_slot -= NFAPI_MAX_SFNSLOTDEC(pnf_p7->mu);
// NFAPI_TRACE(NFAPI_TRACE_INFO, "Applying shift %d to sfn/slot (%d -> %d)\n", pnf_p7->sfn_slot_shift, NFAPI_SFNSF2DEC(sfn_slot), shifted_sfn_slot);
slot = shifted_slot;
//
// why does the shift not apply to pnf_p7->sfn_sf???
//
pnf_p7->slot_shift = 0;
}
nfapi_pnf_p7_slot_buffer_t* tx_slot_buffer = &(pnf_p7->slot_buffer[buffer_index_tx]);
nfapi_pnf_p7_slot_buffer_t* tx_slot_buffer = &(pnf_p7->slot_buffer[buffer_index_tx]);
ret_dl_tti->SFN = sfn;
ret_dl_tti->Slot = slot;
ret_dl_tti->dl_tti_request_body.nPDUs = 0;
ret_tx_data->SFN = sfn;
ret_tx_data->Slot = slot;
ret_tx_data->Number_of_PDUs = 0;
nfapi_nr_dl_tti_request_t* dl_tti_req = &tx_slot_buffer->dl_tti_req;
nfapi_nr_tx_data_request_t* tx_data_req = &tx_slot_buffer->tx_data_req;
if (dl_tti_req->dl_tti_request_body.nPDUs > 0 && dl_tti_req->SFN == sfn && dl_tti_req->Slot == slot) {
DevAssert(pnf_p7->_public.dl_tti_req_fn != NULL);
DevAssert(pnf_p7->_public.tx_data_req_fn != NULL);
if (tx_data_req->Number_of_PDUs > 0 && tx_data_req->SFN == sfn && tx_data_req->Slot == slot) {
(pnf_p7->_public.dl_tti_req_fn)(NULL, &(pnf_p7->_public), dl_tti_req);
(pnf_p7->_public.tx_data_req_fn)(&(pnf_p7->_public), tx_data_req);
} else {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%4d.%2d no corresponding tx_data.request for dl_tti.request, dropping\n", sfn, slot);
nfapi_nr_tx_data_request_t* txd = &tx_slot_buffer->tx_data_req;
if (dl_tti_req->SFN == sfn && dl_tti_req->Slot == slot && txd->SFN == sfn && txd->Slot == slot) {
nfapi_nr_dl_tti_request_body_t* p_tti = &dl_tti_req->dl_tti_request_body;
int ret_idx = 0;
for (int i = 0; i < p_tti->nPDUs; ++i) {
int tx_index = p_tti->dl_tti_pdu_list[i].pdsch_pdu.pdsch_pdu_rel15.pduIndex - 1;
if (tx_index >= txd->Number_of_PDUs) {
NFAPI_TRACE(NFAPI_TRACE_ERROR,
"%4d.%2d no corresponding tx_data.request for dl_tti.request index %d, dropping\n",
sfn,
slot,
tx_index);
continue;
}
ret_dl_tti->dl_tti_request_body.dl_tti_pdu_list[ret_idx] = p_tti->dl_tti_pdu_list[i];
// TODO avoid huge copy
ret_tx_data->pdu_list[ret_idx] = txd->pdu_list[i];
ret_idx++;
}
ret_dl_tti->dl_tti_request_body.nPDUs = ret_idx;
ret_tx_data->Number_of_PDUs = ret_idx;
tx_slot_buffer->dl_tti_req.SFN = -1;
tx_slot_buffer->dl_tti_req.Slot = -1;
tx_slot_buffer->tx_data_req.SFN = -1;
tx_slot_buffer->tx_data_req.Slot = -1;
}
if (tx_data_req->Number_of_PDUs > 0 && tx_data_req->SFN == sfn && tx_data_req->Slot == slot) {
// there is a tx_data.request in this slot, but no corresponding
// dl_tti.request (when they need to come pairwise)
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%4d.%2d no corresponding dl_tti.request for tx_data.request, dropping\n", sfn, slot);
tx_slot_buffer->tx_data_req.SFN = -1;
tx_slot_buffer->tx_data_req.Slot = -1;
}
if(tx_slot_buffer->ul_tti_req.n_pdus > 0 && tx_slot_buffer->ul_tti_req.SFN == sfn && tx_slot_buffer->ul_tti_req.Slot == slot)
{
DevAssert(pnf_p7->_public.ul_tti_req_fn != NULL);
(pnf_p7->_public.ul_tti_req_fn)(NULL, &(pnf_p7->_public), &tx_slot_buffer->ul_tti_req);
ret_ul_tti->SFN = sfn;
ret_ul_tti->Slot = slot;
ret_ul_tti->n_pdus = 0;
if (tx_slot_buffer->ul_tti_req.SFN == sfn && tx_slot_buffer->ul_tti_req.Slot == slot) {
nfapi_nr_ul_tti_request_t* p = &tx_slot_buffer->ul_tti_req;
ret_ul_tti->n_pdus = p->n_pdus;
for (int i = 0; i < p->n_pdus; ++i)
ret_ul_tti->pdus_list[i] = p->pdus_list[i];
tx_slot_buffer->ul_tti_req.SFN = -1;
tx_slot_buffer->ul_tti_req.Slot = -1;
}
}
if(tx_slot_buffer->ul_dci_req.numPdus > 0 && tx_slot_buffer->ul_dci_req.SFN == sfn && tx_slot_buffer->ul_dci_req.Slot == slot)
{
DevAssert(pnf_p7->_public.ul_dci_req_fn != NULL);
(pnf_p7->_public.ul_dci_req_fn)(NULL, &(pnf_p7->_public), &tx_slot_buffer->ul_dci_req);
ret_ul_dci->SFN = sfn;
ret_ul_dci->Slot = slot;
ret_ul_dci->numPdus = 0;
if (tx_slot_buffer->ul_dci_req.SFN == sfn && tx_slot_buffer->ul_dci_req.Slot == slot) {
nfapi_nr_ul_dci_request_t* p = &tx_slot_buffer->ul_dci_req;
ret_ul_dci->numPdus = p->numPdus;
for (int i = 0; i < p->numPdus; ++i)
ret_ul_dci->ul_dci_pdu_list[i] = p->ul_dci_pdu_list[i];
tx_slot_buffer->ul_dci_req.SFN = -1;
tx_slot_buffer->ul_dci_req.Slot = -1;
}
}
//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);
// 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);
pnf_p7->timing_info_period_counter = 0;
}
else if(pnf_p7->_public.timing_info_mode_aperiodic && pnf_p7->timing_info_aperiodic_send)
{
pnf_nr_pack_and_send_timing_info(pnf_p7);
pnf_p7->timing_info_period_counter = 0;
} else if (pnf_p7->_public.timing_info_mode_aperiodic && pnf_p7->timing_info_aperiodic_send) {
pnf_nr_pack_and_send_timing_info(pnf_p7);
pnf_p7->timing_info_aperiodic_send = 0;
}
else
{
pnf_p7->timing_info_ms_counter++;
}
}
pnf_p7->timing_info_aperiodic_send = 0;
} else {
pnf_p7->timing_info_ms_counter++;
}
}
if (sfn % 128 == 0 && slot == 0) {
pnf_p7_nr_stats_t* s = &pnf_p7->nr_stats;
int ontime = s->dl_tti.ontime + s->ul_tti.ontime + s->ul_dci.ontime + s->tx_data.ontime;
int late = s->dl_tti.late + s->ul_tti.late + s->ul_dci.late + s->tx_data.late;
float dl_thr = (float) s->dl.bytes * 8 / 1000 / 1000 / 1.28f; // every 128 frames = 1.28 s
float ul_thr = (float) s->ul.bytes * 8 / 1000 / 1000 / 1.28f;
NFAPI_TRACE(NFAPI_TRACE_INFO, "[P7:%d] msgs ontime %d thr DL %.2f UL %.2f msg late %d (vtime)\n", pnf_p7->_public.phy_id, ontime, dl_thr, ul_thr, late);
float dl_thr = (float)s->dl.bytes * 8 / 1000 / 1000 / 1.28f; // every 128 frames = 1.28 s
float ul_thr = (float)s->ul.bytes * 8 / 1000 / 1000 / 1.28f;
NFAPI_TRACE(NFAPI_TRACE_INFO,
"[P7:%d] msgs ontime %d thr DL %.2f UL %.2f msg late %d (vtime)\n",
pnf_p7->_public.phy_id,
ontime,
dl_thr,
ul_thr,
late);
memset(s, 0, sizeof(*s));
}
if(pthread_mutex_unlock(&(pnf_p7->mutex)) != 0)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n");
return -1;
}
if (pthread_mutex_unlock(&(pnf_p7->mutex)) != 0) {
NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n");
return -1;
}
return 0;
return 0;
}
int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf)
{
// We could either send an event to the p7 thread have have it run the
+13 -6
View File
@@ -89,15 +89,22 @@ int nfapi_pnf_p7_stop(nfapi_pnf_p7_config_t* config)
return 0;
}
int nfapi_pnf_p7_slot_ind(nfapi_pnf_p7_config_t* config, uint16_t phy_id, uint16_t sfn, uint16_t slot)
int nfapi_pnf_p7_get_msgs(nfapi_pnf_p7_config_t* config,
uint16_t phy_id,
uint16_t sfn,
uint16_t slot,
nfapi_nr_dl_tti_request_t* ret_dl_tti,
nfapi_nr_ul_tti_request_t* ret_ul_tti,
nfapi_nr_ul_dci_request_t* ret_ul_dci,
nfapi_nr_tx_data_request_t* ret_tx_data)
{
// Verify that config is not null
if(config == 0)
return -1;
// Verify that config is not null
if (config == 0)
return -1;
pnf_p7_t* _this = (pnf_p7_t*)(config);
pnf_p7_t* _this = (pnf_p7_t*)(config);
return pnf_p7_slot_ind(_this, phy_id, sfn, slot);
return nr_pnf_p7_get_msgs(_this, phy_id, sfn, slot, ret_dl_tti, ret_ul_tti, ret_ul_dci, ret_tx_data);
}
int nfapi_pnf_p7_subframe_ind(nfapi_pnf_p7_config_t* config, uint16_t phy_id, uint16_t sfn_sf)
@@ -1210,12 +1210,6 @@ void send_dl_subframe_msgs_interleaved(int p7Sock, int phy_id, struct sockaddr_i
//free(req.tx_request_body.tx_pdu_list);
}
void send_slot_indication(phy_info_t* phy_info)
{
// DONE: add sfn and slot as members in the phy_info
nfapi_pnf_p7_slot_ind(phy_info->config, phy_info->phy_id, phy_info->sfn, phy_info->slot);
}
void send_subframe_indication(phy_info_t* phy_info)
{
nfapi_pnf_p7_subframe_ind(phy_info->config, phy_info->phy_id, phy_info->sfn_sf);
+10 -9
View File
@@ -379,15 +379,13 @@ static void match_crc_rx_pdu(nfapi_nr_rx_data_indication_t *rx_ind, nfapi_nr_crc
}
}
extern void handle_nr_slot_ind(uint16_t sfn, uint16_t slot);
extern void handle_nr_slot_ind(uint16_t sfn, uint16_t slot, NR_Sched_Rsp_t *sched_response);
static void pnf_send_slot_ind(const nfapi_nr_slot_indication_scf_t *ind, NR_Sched_Rsp_t *rsp)
{
module_id_t module_id = 0;
int CC_id = 0;
reset_sched_response(rsp, ind->sfn, ind->slot, module_id, CC_id);
handle_nr_slot_ind(ind->sfn, ind->slot);
// TODO copy messages from FAPI buffers
handle_nr_slot_ind(ind->sfn, ind->slot, rsp);
}
static void run_scheduler_monolithic(const nfapi_nr_slot_indication_scf_t *ind, NR_Sched_Rsp_t *rsp)
@@ -398,7 +396,8 @@ static void run_scheduler_monolithic(const nfapi_nr_slot_indication_scf_t *ind,
gNB_dlsch_ulsch_scheduler(rsp->module_id, ind->sfn, ind->slot, rsp);
}
void NR_UL_indication(NR_UL_IND_t *UL_info) {
static void NR_UL_indication(NR_UL_IND_t *UL_info)
{
AssertFatal(UL_info!=NULL,"UL_info is null\n");
module_id_t module_id = UL_info->module_id;
int CC_id = UL_info->CC_id;
@@ -475,12 +474,14 @@ NR_IF_Module_t *NR_IF_Module_init(int Mod_id) {
nr_if_inst[Mod_id]->CC_mask=0;
nr_if_inst[Mod_id]->NR_UL_indication = NR_UL_indication;
if (NFAPI_MODE == NFAPI_MONOLITHIC)
if (NFAPI_MODE == NFAPI_MONOLITHIC) {
nr_if_inst[Mod_id]->NR_slot_indication = run_scheduler_monolithic;
else if (NFAPI_MODE == NFAPI_MODE_PNF)
} else if (NFAPI_MODE == NFAPI_MODE_PNF) {
nr_if_inst[Mod_id]->NR_slot_indication = pnf_send_slot_ind;
else // NFAPI_MODE_VNF
NULL;
} else { // NFAPI_MODE_VNF
DevAssert(NFAPI_MODE == NFAPI_MODE_VNF || NFAPI_MODE == NFAPI_MODE_AERIAL);
nr_if_inst[Mod_id]->NR_slot_indication = run_scheduler_monolithic;
}
AssertFatal(pthread_mutex_init(&nr_if_inst[Mod_id]->if_mutex,NULL)==0,
"allocation of nr_if_inst[%d]->if_mutex fails\n",Mod_id);
}
+1 -3
View File
@@ -91,7 +91,7 @@ typedef struct {
// Downlink slot P7
typedef struct {
typedef struct NR_Sched_Rsp {
/// the ID of this sched_response - used by sched_reponse memory management
int sched_response_id;
/// Module ID
@@ -137,8 +137,6 @@ NR_IF_Module_t *NR_IF_Module_init(int Mod_id);
void NR_IF_Module_kill(int Mod_id);
void NR_UL_indication(NR_UL_IND_t *UL_INFO);
/*Interface for Downlink, transmitting the DLSCH SDU, DCI SDU*/
void NR_Schedule_Response(NR_Sched_Rsp_t *Sched_INFO);