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:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
+113
-101
@@ -672,145 +672,157 @@ void send_dummy_subframe(pnf_p7_t* pnf_p7, uint16_t sfn_sf)
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (pthread_mutex_lock(&(pnf_p7->mutex)) != 0) {
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int pnf_p7_slot_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn, uint16_t slot)
|
||||
{
|
||||
//This function is aligned with rx sfn/slot
|
||||
// save the curren time, sfn and slot
|
||||
// TODO useful?
|
||||
pnf_p7->slot_start_time_hr = pnf_get_current_time_hr();
|
||||
|
||||
// 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");
|
||||
return -1;
|
||||
}
|
||||
// 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;
|
||||
|
||||
// save the curren time, sfn and slot
|
||||
pnf_p7->slot_start_time_hr = pnf_get_current_time_hr();
|
||||
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);
|
||||
|
||||
//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.
|
||||
// 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;
|
||||
|
||||
pnf_p7->sfn = sfn;
|
||||
pnf_p7->slot = slot;
|
||||
// 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);
|
||||
|
||||
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);
|
||||
//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;
|
||||
|
||||
// If the subframe_buffer has been configured
|
||||
if(pnf_p7->_public.slot_buffer_size!= 0) // for now value is same as sf_buffer_size
|
||||
{
|
||||
//
|
||||
// why does the shift not apply to pnf_p7->sfn_sf???
|
||||
//
|
||||
|
||||
// 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;
|
||||
pnf_p7->slot_shift = 0;
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
@@ -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;
|
||||
|
||||
pnf_p7_t* _this = (pnf_p7_t*)(config);
|
||||
// Verify that config is not null
|
||||
if (config == 0)
|
||||
return -1;
|
||||
|
||||
return pnf_p7_slot_ind(_this, phy_id, sfn, slot);
|
||||
pnf_p7_t* _this = (pnf_p7_t*)(config);
|
||||
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user