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:
+2
-2
@@ -242,10 +242,10 @@ To see the (any) periodical output at the PNF, define `NFAPI_TRACE_LEVEL=info`.
|
|||||||
This output shows:
|
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
|
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
|
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.
|
last window (since the last print), 489 messages arrived at the PNF in total.
|
||||||
|
|||||||
@@ -199,8 +199,6 @@ void nr_schedule_ul_dci_req() {};
|
|||||||
void nr_schedule_tx_req() {};
|
void nr_schedule_tx_req() {};
|
||||||
void nr_schedule_ul_tti_req() {};
|
void nr_schedule_ul_tti_req() {};
|
||||||
void nr_slot_select() {};
|
void nr_slot_select() {};
|
||||||
void NR_UL_indication(NR_UL_IND_t *UL_INFO) {};
|
|
||||||
void gNB_dlsch_ulsch_scheduler() {};
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|||||||
@@ -2314,7 +2314,7 @@ static void maybe_slow_down_pnf(int mu)
|
|||||||
last_execution = current_execution;
|
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;
|
nfapi_pnf_p7_config_t *config = p7_config_g;
|
||||||
pnf_p7_t *_this = (pnf_p7_t *)(config);
|
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);
|
oai_nfapi_nr_slot_indication(&ind);
|
||||||
|
|
||||||
// copy data from appropriate p7 slot buffers into channel structures for PHY processing
|
// 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 configure_nr_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port);
|
||||||
|
|
||||||
void oai_subframe_ind(uint16_t sfn, uint16_t sf);
|
void oai_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);
|
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_slot_indication(nfapi_nr_slot_indication_scf_t *ind);
|
||||||
|
|||||||
@@ -971,65 +971,63 @@ int phy_cqi_indication(struct nfapi_vnf_p7_config *config, nfapi_cqi_indication_
|
|||||||
//NR phy 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_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_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_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 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)
|
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);
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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_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_send_message(pnf_p7_t* pnf_p7, uint8_t* msg, uint32_t msg_len);
|
||||||
|
|
||||||
|
int nr_pnf_p7_get_msgs(pnf_p7_t* pnf_p7,
|
||||||
int pnf_p7_slot_ind(pnf_p7_t* config, uint16_t phy_id, uint16_t sfn, uint16_t slot);
|
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 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_slot_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_slot_indication_scf_t* ind);
|
||||||
int nfapi_pnf_p7_nr_rx_data_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_rx_data_indication_t* ind);
|
int nfapi_pnf_p7_nr_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);
|
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
|
* message copied from nfapi_pnf_p7_subframe_ind
|
||||||
* \param config A pointer to a PNF P7 config
|
* \param config A pointer to a PNF P7 config
|
||||||
* \param phy_id The phy_id for the phy instance
|
* \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
|
* 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
|
/*! Subframe indication
|
||||||
* \param config A pointer to a PNF P7 config
|
* \param config A pointer to a PNF P7 config
|
||||||
|
|||||||
@@ -672,52 +672,48 @@ void send_dummy_subframe(pnf_p7_t* pnf_p7, uint16_t sfn_sf)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int nr_pnf_p7_get_msgs(pnf_p7_t* pnf_p7,
|
||||||
int pnf_p7_slot_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn, uint16_t slot)
|
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) {
|
||||||
|
|
||||||
// We could either send an event to the p7 thread have have it run the
|
|
||||||
// subframe or we could handle it here and lock access to the subframe
|
|
||||||
// buffers. If we do it on the p7 thread then we run the risk of blocking
|
|
||||||
// on the udp send.
|
|
||||||
|
|
||||||
// todo : consider a more efficent lock mechasium
|
|
||||||
//uint16_t NUM_SLOTS = 20;//10* 2^mu
|
|
||||||
|
|
||||||
if(pthread_mutex_lock(&(pnf_p7->mutex)) != 0)
|
|
||||||
{
|
|
||||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n");
|
NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// save the curren time, sfn and slot
|
// save the curren time, sfn and slot
|
||||||
|
// TODO useful?
|
||||||
pnf_p7->slot_start_time_hr = pnf_get_current_time_hr();
|
pnf_p7->slot_start_time_hr = pnf_get_current_time_hr();
|
||||||
|
|
||||||
//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.
|
// 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->sfn = sfn;
|
||||||
pnf_p7->slot = slot;
|
pnf_p7->slot = slot;
|
||||||
|
|
||||||
uint32_t tx_slot_dec = NFAPI_SFNSLOT2DEC(pnf_p7->mu, sfn,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);
|
uint8_t buffer_index_tx = tx_slot_dec % NFAPI_SLOTNUM(pnf_p7->mu);
|
||||||
|
|
||||||
// If the subframe_buffer has been configured
|
// If the subframe_buffer has been configured
|
||||||
if(pnf_p7->_public.slot_buffer_size!= 0) // for now value is same as sf_buffer_size
|
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
|
// apply the shift to the incoming sfn_sf
|
||||||
if(pnf_p7->slot_shift != 0) // see in vnf_build_send_dl_node_sync
|
if (pnf_p7->slot_shift != 0) // see in vnf_build_send_dl_node_sync
|
||||||
{
|
{
|
||||||
uint16_t shifted_slot = slot + pnf_p7->slot_shift;
|
uint16_t shifted_slot = slot + pnf_p7->slot_shift;
|
||||||
|
|
||||||
// adjust for wrap-around
|
// adjust for wrap-around
|
||||||
if(shifted_slot < 0)
|
if (shifted_slot < 0)
|
||||||
shifted_slot += NFAPI_MAX_SFNSLOTDEC(pnf_p7->mu);
|
shifted_slot += NFAPI_MAX_SFNSLOTDEC(pnf_p7->mu);
|
||||||
else if(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);
|
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);
|
//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;
|
slot = shifted_slot;
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -729,64 +725,77 @@ int pnf_p7_slot_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn, uint16_t sl
|
|||||||
|
|
||||||
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_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;
|
nfapi_nr_tx_data_request_t* txd = &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) {
|
if (dl_tti_req->SFN == sfn && dl_tti_req->Slot == slot && txd->SFN == sfn && txd->Slot == slot) {
|
||||||
DevAssert(pnf_p7->_public.dl_tti_req_fn != NULL);
|
nfapi_nr_dl_tti_request_body_t* p_tti = &dl_tti_req->dl_tti_request_body;
|
||||||
DevAssert(pnf_p7->_public.tx_data_req_fn != NULL);
|
int ret_idx = 0;
|
||||||
if (tx_data_req->Number_of_PDUs > 0 && tx_data_req->SFN == sfn && tx_data_req->Slot == slot) {
|
for (int i = 0; i < p_tti->nPDUs; ++i) {
|
||||||
(pnf_p7->_public.dl_tti_req_fn)(NULL, &(pnf_p7->_public), dl_tti_req);
|
int tx_index = p_tti->dl_tti_pdu_list[i].pdsch_pdu.pdsch_pdu_rel15.pduIndex - 1;
|
||||||
(pnf_p7->_public.tx_data_req_fn)(&(pnf_p7->_public), tx_data_req);
|
if (tx_index >= txd->Number_of_PDUs) {
|
||||||
} else {
|
NFAPI_TRACE(NFAPI_TRACE_ERROR,
|
||||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%4d.%2d no corresponding tx_data.request for dl_tti.request, dropping\n", sfn, slot);
|
"%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.SFN = -1;
|
||||||
tx_slot_buffer->dl_tti_req.Slot = -1;
|
tx_slot_buffer->dl_tti_req.Slot = -1;
|
||||||
tx_slot_buffer->tx_data_req.SFN = -1;
|
tx_slot_buffer->tx_data_req.SFN = -1;
|
||||||
tx_slot_buffer->tx_data_req.Slot = -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)
|
ret_ul_tti->SFN = sfn;
|
||||||
{
|
ret_ul_tti->Slot = slot;
|
||||||
DevAssert(pnf_p7->_public.ul_tti_req_fn != NULL);
|
ret_ul_tti->n_pdus = 0;
|
||||||
(pnf_p7->_public.ul_tti_req_fn)(NULL, &(pnf_p7->_public), &tx_slot_buffer->ul_tti_req);
|
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.SFN = -1;
|
||||||
tx_slot_buffer->ul_tti_req.Slot = -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)
|
ret_ul_dci->SFN = sfn;
|
||||||
{
|
ret_ul_dci->Slot = slot;
|
||||||
DevAssert(pnf_p7->_public.ul_dci_req_fn != NULL);
|
ret_ul_dci->numPdus = 0;
|
||||||
(pnf_p7->_public.ul_dci_req_fn)(NULL, &(pnf_p7->_public), &tx_slot_buffer->ul_dci_req);
|
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.SFN = -1;
|
||||||
tx_slot_buffer->ul_dci_req.Slot = -1;
|
tx_slot_buffer->ul_dci_req.Slot = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//send the periodic timing info if configured
|
// send the periodic timing info if configured
|
||||||
if(pnf_p7->_public.timing_info_mode_periodic && (pnf_p7->timing_info_period_counter++) == pnf_p7->_public.timing_info_period)
|
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_nr_pack_and_send_timing_info(pnf_p7);
|
||||||
|
|
||||||
pnf_p7->timing_info_period_counter = 0;
|
pnf_p7->timing_info_period_counter = 0;
|
||||||
}
|
} else if (pnf_p7->_public.timing_info_mode_aperiodic && pnf_p7->timing_info_aperiodic_send) {
|
||||||
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_nr_pack_and_send_timing_info(pnf_p7);
|
||||||
|
|
||||||
pnf_p7->timing_info_aperiodic_send = 0;
|
pnf_p7->timing_info_aperiodic_send = 0;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
pnf_p7->timing_info_ms_counter++;
|
pnf_p7->timing_info_ms_counter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sfn % 128 == 0 && slot == 0) {
|
if (sfn % 128 == 0 && slot == 0) {
|
||||||
@@ -794,14 +803,19 @@ int pnf_p7_slot_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn, uint16_t sl
|
|||||||
int ontime = s->dl_tti.ontime + s->ul_tti.ontime + s->ul_dci.ontime + s->tx_data.ontime;
|
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;
|
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 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;
|
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);
|
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));
|
memset(s, 0, sizeof(*s));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pthread_mutex_unlock(&(pnf_p7->mutex)) != 0)
|
if (pthread_mutex_unlock(&(pnf_p7->mutex)) != 0) {
|
||||||
{
|
|
||||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n");
|
NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -809,8 +823,6 @@ int pnf_p7_slot_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn, uint16_t sl
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf)
|
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
|
// We could either send an event to the p7 thread have have it run the
|
||||||
|
|||||||
@@ -89,15 +89,22 @@ int nfapi_pnf_p7_stop(nfapi_pnf_p7_config_t* config)
|
|||||||
return 0;
|
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
|
// Verify that config is not null
|
||||||
if(config == 0)
|
if (config == 0)
|
||||||
return -1;
|
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)
|
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);
|
//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)
|
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);
|
nfapi_pnf_p7_subframe_ind(phy_info->config, phy_info->phy_id, phy_info->sfn_sf);
|
||||||
|
|||||||
@@ -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)
|
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;
|
module_id_t module_id = 0;
|
||||||
int CC_id = 0;
|
int CC_id = 0;
|
||||||
reset_sched_response(rsp, ind->sfn, ind->slot, module_id, CC_id);
|
reset_sched_response(rsp, ind->sfn, ind->slot, module_id, CC_id);
|
||||||
handle_nr_slot_ind(ind->sfn, ind->slot);
|
handle_nr_slot_ind(ind->sfn, ind->slot, rsp);
|
||||||
|
|
||||||
// TODO copy messages from FAPI buffers
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void run_scheduler_monolithic(const nfapi_nr_slot_indication_scf_t *ind, NR_Sched_Rsp_t *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);
|
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");
|
AssertFatal(UL_info!=NULL,"UL_info is null\n");
|
||||||
module_id_t module_id = UL_info->module_id;
|
module_id_t module_id = UL_info->module_id;
|
||||||
int CC_id = UL_info->CC_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]->CC_mask=0;
|
||||||
nr_if_inst[Mod_id]->NR_UL_indication = NR_UL_indication;
|
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;
|
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;
|
nr_if_inst[Mod_id]->NR_slot_indication = pnf_send_slot_ind;
|
||||||
else // NFAPI_MODE_VNF
|
} else { // NFAPI_MODE_VNF
|
||||||
NULL;
|
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,
|
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);
|
"allocation of nr_if_inst[%d]->if_mutex fails\n",Mod_id);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ typedef struct {
|
|||||||
// Downlink slot P7
|
// Downlink slot P7
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct NR_Sched_Rsp {
|
||||||
/// the ID of this sched_response - used by sched_reponse memory management
|
/// the ID of this sched_response - used by sched_reponse memory management
|
||||||
int sched_response_id;
|
int sched_response_id;
|
||||||
/// Module 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_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*/
|
/*Interface for Downlink, transmitting the DLSCH SDU, DCI SDU*/
|
||||||
void NR_Schedule_Response(NR_Sched_Rsp_t *Sched_INFO);
|
void NR_Schedule_Response(NR_Sched_Rsp_t *Sched_INFO);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user