diff --git a/.vscode/launch.json b/.vscode/launch.json index a40fdcba9b4857df499cee42e5bca50311e50719..2b0f71f6a35f5a15f1e18502a4f743fc28fc343d 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -124,6 +124,30 @@ } ] } + { + "name": "(rfsim) Launch GNB", + "type": "cppdbg", + "request": "launch", + "program": " /home/glab/NR_nfapi/openairinterface5g/cmake_targets/ran_build/build/nr-softmodem", + "args":["-O", + "/home/glab/NR_nfapi/openairinterface5g/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf", + "--rfsim", + "--rfsimulator.serveraddr", + "server"], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "miDebuggerPath": "/usr/bin/gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + } ] } diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index aa16c771ae2940789467ac3f868bc9922fa85977..2fc8c8688f937932043d4228a016f0ae7623b6ce 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -135,6 +135,7 @@ void wakeup_prach_gNB(PHY_VARS_gNB *gNB, RU_t *ru, int frame, int subframe); extern uint8_t nfapi_mode; extern void oai_subframe_ind(uint16_t sfn, uint16_t sf); +extern void oai_slot_ind(uint16_t sfn, uint16_t slot); extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset); //#define TICK_TO_US(ts) (ts.diff) @@ -156,7 +157,8 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t //oai_subframe_ind(proc->frame_tx, proc->subframe_tx); //LOG_D(PHY, "oai_subframe_ind(frame:%u, subframe:%d) - NOT CALLED ********\n", frame, subframe); start_meas(&nfapi_meas); - oai_subframe_ind(frame_rx, slot_rx); + // oai_subframe_ind(frame_rx, slot_rx); + oai_slot_ind(frame_rx, slot_rx); stop_meas(&nfapi_meas); /*if (gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus|| diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 873adc03039198c802b6aae700be6138be20289c..bafa007bdf19d97414c63bb1dbea408af984e442 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -1502,7 +1502,7 @@ void *ru_thread( void *param ) { proc->frame_rx,proc->tti_rx, proc->frame_tx,proc->tti_tx, RC.gNB[0]->proc.frame_rx,RC.gNB[0]->proc.slot_rx, - RC.gNB[0]->proc.frame_tx); + RC.gNB[0]->proc.frame_tx); /* LOG_D(PHY,"RU thread (do_prach %d, is_prach_subframe %d), received frame %d, subframe %d\n", ru->do_prach, diff --git a/nfapi/oai_integration/nfapi_pnf.c b/nfapi/oai_integration/nfapi_pnf.c index f5ff8936b2e9aab46b7e17683d29b9047fcc258e..fd7ef89f4a773572632e5a93a0b28248c90bb66b 100644 --- a/nfapi/oai_integration/nfapi_pnf.c +++ b/nfapi/oai_integration/nfapi_pnf.c @@ -1214,6 +1214,7 @@ int start_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfap p7_config->phy_id = phy->phy_id; p7_config->remote_p7_port = phy_info->remote_port; p7_config->remote_p7_addr = phy_info->remote_addr; + // TODO: remove this hardcoded port p7_config->local_p7_port = 32123; // DJP - good grief cannot seem to get the right answer phy_info->local_port; //DJP p7_config->local_p7_addr = (char*)phy_info->local_addr.c_str(); p7_config->local_p7_addr = phy_info->local_addr; @@ -1319,10 +1320,17 @@ int start_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfap printf("[PNF] Sending PNF_START_RESP\n"); nfapi_send_pnf_start_resp(config, p7_config->phy_id); - printf("[PNF] Sending first P7 subframe ind\n"); - nfapi_pnf_p7_subframe_ind(p7_config, p7_config->phy_id, 0); // DJP - SFN_SF set to zero - correct??? + printf("[PNF] Sending first P7 slot indication\n"); +#if 1 //TODO: Change to nfapi_pnf_p7_slot_ind + nfapi_pnf_p7_slot_ind(p7_config, p7_config->phy_id, 0, 0); + printf("[PNF] Sent first P7 slot ind\n"); +#else + nfapi_pnf_p7_subframe_ind(p7_config, p7_config->phy_id, 0); // DJP - SFN_SF set to zero - correct??? printf("[PNF] Sent first P7 subframe ind\n"); +#endif + + return 0; } @@ -1635,6 +1643,59 @@ void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, void oai_subframe_ind(uint16_t sfn, uint16_t sf) { //LOG_D(PHY,"%s(sfn:%d, sf:%d)\n", __FUNCTION__, sfn, sf); + //TODO FIXME - HACK - DJP - using a global to bodge it in + if (p7_config_g != NULL && sync_var==0) { + uint16_t sfn_sf_tx = sfn<<4 | sf; + + if ((sfn % 100 == 0) && sf==0) { + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] %s %d.%d (sfn:%u sf:%u) SFN/SF(TX):%u\n", __FUNCTION__, ts.tv_sec, ts.tv_nsec, sfn, sf, NFAPI_SFNSF2DEC(sfn_sf_tx)); + } + + int subframe_ret = nfapi_pnf_p7_subframe_ind(p7_config_g, p7_config_g->phy_id, sfn_sf_tx); + + if (subframe_ret) { + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] %s(frame:%u subframe:%u) SFN/SF(TX):%u - PROBLEM with pnf_p7_subframe_ind()\n", __FUNCTION__, sfn, sf, sfn_sf_tx, NFAPI_SFNSF2DEC(sfn_sf_tx)); + } else { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "***NFAPI subframe handler finished *** \n"); + } + } else { + } +} + + + +void oai_slot_ind(uint16_t sfn, uint16_t slot) { + +#if 1 // Put the NR code here + //LOG_D(PHY,"%s(sfn:%d, sf:%d)\n", __FUNCTION__, sfn, sf); + + //TODO FIXME - HACK - DJP - using a global to bodge it in + if (p7_config_g != NULL && sync_var==0) { + // DONE: changed for NR x x x x x x x x x x x x x x - - - - - - : x (Frame), - (Slot) (max_numer =2) + uint16_t sfn_slot_tx = sfn<<6 | slot; + if ((sfn % 100 == 0) && slot==0) { // DOUBT: Why 100? + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] %s %d.%d (sfn:%u slot:%u) SFN/SLOT(TX):%u\n", __FUNCTION__, ts.tv_sec, ts.tv_nsec, sfn, slot, NFAPI_SFNSLOT2DEC(sfn_slot_tx)); + } + + // int subframe_ret = nfapi_pnf_p7_slot_ind(p7_config_g, p7_config_g->phy_id, 0, 0); + int slot_ret = nfapi_pnf_p7_slot_ind(p7_config_g, p7_config_g->phy_id, sfn, slot); + + // if (subframe_ret) { + if (slot_ret) { + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] %s(frame:%u slot:%u) SFN/SLOT(TX):%u - PROBLEM with pnf_p7_slot_ind()\n", __FUNCTION__, sfn, slot, sfn_slot_tx, NFAPI_SFNSLOT2DEC(sfn_slot_tx)); + // printing anything causes error: probably because there isn't enough time to accomodate a print statement + } else { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "***NFAPI subframe handler finished *** \n"); + } + } else { + } +#else + //LOG_D(PHY,"%s(sfn:%d, sf:%d)\n", __FUNCTION__, sfn, sf); + //TODO FIXME - HACK - DJP - using a global to bodge it in if (p7_config_g != NULL && sync_var==0) { uint16_t sfn_sf_tx = sfn<<4 | sf; @@ -1654,6 +1715,7 @@ void oai_subframe_ind(uint16_t sfn, uint16_t sf) { } } else { } +#endif } int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind) { diff --git a/nfapi/oai_integration/nfapi_pnf.h b/nfapi/oai_integration/nfapi_pnf.h index 2c8201737c8642a9b25bf9238c70465b1d4fdb7e..8c3cf9c4c03d7135392cdc8f994fe5e7e6fe0ba3 100644 --- a/nfapi/oai_integration/nfapi_pnf.h +++ b/nfapi/oai_integration/nfapi_pnf.h @@ -24,4 +24,5 @@ int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind); void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port); void oai_subframe_ind(uint16_t sfn, uint16_t sf); +void oai_slot_ind(uint16_t sfn, uint16_t slot); #endif diff --git a/nfapi/oai_integration/nfapi_vnf.c b/nfapi/oai_integration/nfapi_vnf.c index cf7597b59a5a3dc69b3869c0325b93504eff4f86..42da901a276021e3a8c0bc18708121db46d6f570 100644 --- a/nfapi/oai_integration/nfapi_vnf.c +++ b/nfapi/oai_integration/nfapi_vnf.c @@ -1091,7 +1091,10 @@ int start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_start_respons 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); + + nfapi_vnf_p7_add_pnf((p7_vnf->config), phy->remote_addr, 32123, phy->id); + + // nfapi_vnf_p7_add_pnf((p7_vnf->config), phy->remote_addr, phy->remote_port, phy->id); return 0; } diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h index 8b13cd03b0ea1567dd453fa41a6a308208f4b325..fa9a8d3aabf0a5e9e451586e94f6e236eb2bab2c 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h @@ -120,6 +120,9 @@ typedef struct { } nfapi_tl_t; #define NFAPI_TAG_LENGTH_PACKED_LEN 4 +// Convenience methods to convert between SFN/SLOT formats +#define NFAPI_SFNSLOT2DEC(_sfnslot) ((((_sfnslot) >> 6) * 10) + ((_sfnslot) & 0xF)) + // Convenience methods to convert between SFN/SFN formats #define NFAPI_SFNSF2DEC(_sfnsf) ((((_sfnsf) >> 4) * 10) + ((_sfnsf) & 0xF)) #define NFAPI_SFNSFDEC2SFNSF(_sfnsf_dec) ((((_sfnsf_dec) / 10) << 4) | (((_sfnsf_dec) - (((_sfnsf_dec) / 10) * 10)) & 0xF)) diff --git a/nfapi/open-nFAPI/pnf/inc/pnf_p7.h b/nfapi/open-nFAPI/pnf/inc/pnf_p7.h index 3f08d85e6b678aff5c15c733b3361c65ab81961c..882a25cd0b0982e5cc1a333d201318091e0d2e92 100644 --- a/nfapi/open-nFAPI/pnf/inc/pnf_p7.h +++ b/nfapi/open-nFAPI/pnf/inc/pnf_p7.h @@ -116,6 +116,7 @@ int pnf_p7_pack_and_send_p7_message(pnf_p7_t* pnf_p7, nfapi_p7_message_header_t* int pnf_p7_send_message(pnf_p7_t* pnf_p7, uint8_t* msg, uint32_t msg_len); +int pnf_p7_slot_ind(pnf_p7_t* config, uint16_t phy_id, uint16_t sfn, uint16_t slot); int pnf_p7_subframe_ind(pnf_p7_t* config, uint16_t phy_id, uint16_t sfn_sf); pnf_p7_rx_message_t* pnf_p7_rx_reassembly_queue_add_segment(pnf_p7_t* pnf_p7, pnf_p7_rx_reassembly_queue_t* queue, uint32_t rx_hr_time, uint16_t sequence_number, uint16_t segment_number, uint8_t m, uint8_t* data, uint16_t data_len); diff --git a/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h b/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h index cb98ad29054b20f0de462dd65bc155a2e57cfaac..5f32005a60cee1fd0a11e2d6945cc4d2b7021c7b 100644 --- a/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h +++ b/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h @@ -720,6 +720,21 @@ 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 + * 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 + * \param sfn_sf The SFN and SF in the format of FAPI + * \return 0 means success, -1 means failure + * + * The client should call the subframe indication every 1ms. The PNF will + * respond by invoking the pnf p7 subframe callbacks with the messages from the subframe buffer + * + * 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); + + /*! Subframe indication * \param config A pointer to a PNF P7 config * \param phy_id The phy_id for the phy instance diff --git a/nfapi/open-nFAPI/pnf/src/pnf_p7.c b/nfapi/open-nFAPI/pnf/src/pnf_p7.c index 5ba912e059f73b5c15b3d8e5a4e490ddc2000cd6..97e0c213a195137eb5348669917657e9d9d24402 100644 --- a/nfapi/open-nFAPI/pnf/src/pnf_p7.c +++ b/nfapi/open-nFAPI/pnf/src/pnf_p7.c @@ -413,8 +413,10 @@ int pnf_p7_send_message(pnf_p7_t* pnf_p7, uint8_t* msg, uint32_t len) struct sockaddr_in remote_addr; memset((char*)&remote_addr, 0, sizeof(struct sockaddr_in)); remote_addr.sin_family = AF_INET; - remote_addr.sin_port = htons(pnf_p7->_public.remote_p7_port); + remote_addr.sin_port = 32123;//htons(pnf_p7->_public.remote_p7_port); //hardcoding for now //remote_addr.sin_addr.s_addr = inet_addr(pnf_p7->_public.remote_p7_addr); + + if(inet_aton(pnf_p7->_public.remote_p7_addr, &remote_addr.sin_addr) == -1) { NFAPI_TRACE(NFAPI_TRACE_ERROR, "inet_aton failed %d\n", errno); @@ -599,6 +601,297 @@ 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) +{ + // We could either send an event to the p7 thread have have it run the + // subframe or we could handle it here and lock access to the subframe + // buffers. If we do it on the p7 thread then we run the risk of blocking + // on the udp send. + // + // todo : start a timer to give us more of the 1 ms tick before send back + // the frame + + // todo : consider a more efficent lock mechasium + +#if 0 + if(pthread_mutex_lock(&(pnf_p7->mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n"); + return -1; + } + + // save the curren time and sfn_sf + pnf_p7->sf_start_time_hr = pnf_get_current_time_hr(); + pnf_p7->sfn_sf = sfn_sf; + + uint32_t sfn_sf_tx = sfnsf_add_sf(sfn_sf, sf_ahead); + uint32_t tx_sfn_sf_dec = NFAPI_SFNSF2DEC(sfn_sf_tx); + + // If the subframe_buffer has been configured + if(pnf_p7->_public.subframe_buffer_size != 0) + { + + // apply the shift to the incoming sfn_sf + if(pnf_p7->sfn_sf_shift != 0) + { + int32_t sfn_sf_dec = NFAPI_SFNSF2DEC(sfn_sf); + + int32_t shifted_sfn_sf = sfn_sf_dec += pnf_p7->sfn_sf_shift; + + // adjust for wrap-around + if(shifted_sfn_sf < 0) + shifted_sfn_sf += NFAPI_MAX_SFNSFDEC; + else if(shifted_sfn_sf > NFAPI_MAX_SFNSFDEC) + shifted_sfn_sf -= NFAPI_MAX_SFNSFDEC; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "Applying shift %d to sfn/sf (%d -> %d)\n", pnf_p7->sfn_sf_shift, NFAPI_SFNSF2DEC(sfn_sf), shifted_sfn_sf); + sfn_sf = shifted_sfn_sf; + + // + // DJP - why does the shift not apply to pnf_p7->sfn_sf??? + // + + pnf_p7->sfn_sf_shift = 0; + } + + uint32_t sfn_sf_dec = NFAPI_SFNSF2DEC(sfn_sf); + uint8_t buffer_index = sfn_sf_dec % pnf_p7->_public.subframe_buffer_size; + + nfapi_pnf_p7_subframe_buffer_t* subframe_buffer = &(pnf_p7->subframe_buffer[buffer_index]); + + uint8_t tx_buffer_index = tx_sfn_sf_dec % pnf_p7->_public.subframe_buffer_size; + nfapi_pnf_p7_subframe_buffer_t* tx_subframe_buffer = &(pnf_p7->subframe_buffer[tx_buffer_index]); + + //printf("sfn_sf_dec:%d tx_sfn_sf_dec:%d\n", sfn_sf_dec, tx_sfn_sf_dec); + + if (0) NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() shift:%d subframe_buffer->sfn_sf:%d tx_subframe_buffer->sfn_sf:%d sfn_sf:%d subframe_buffer[buffer_index:%u dl_config_req:%p tx_req:%p] " + "TX:sfn_sf:%d:tx_buffer_index:%d[dl_config_req:%p tx_req:%p]\n", + __FUNCTION__, + pnf_p7->sfn_sf_shift, + NFAPI_SFNSF2DEC(subframe_buffer->sfn_sf), + NFAPI_SFNSF2DEC(tx_subframe_buffer->sfn_sf), + sfn_sf_dec, buffer_index, subframe_buffer->dl_config_req, subframe_buffer->tx_req, + tx_sfn_sf_dec, tx_buffer_index, tx_subframe_buffer->dl_config_req, tx_subframe_buffer->tx_req); + + // if the subframe buffer sfn sf is set then we have atlease 1 message + // from the vnf. + // todo : how to handle the messages we don't have, send dummies for + // now + + //printf("tx_subframe_buffer->sfn_sf:%d sfn_sf_tx:%d\n", tx_subframe_buffer->sfn_sf, sfn_sf_tx); + //printf("subframe_buffer->sfn_sf:%d sfn_sf:%d\n", subframe_buffer->sfn_sf, sfn_sf); + if(tx_subframe_buffer->sfn_sf == sfn_sf_tx) + { + if(tx_subframe_buffer->tx_req != 0) + { + if(pnf_p7->_public.tx_req) + (pnf_p7->_public.tx_req)(&(pnf_p7->_public), tx_subframe_buffer->tx_req); + + //deallocate_nfapi_tx_request(subframe_buffer->tx_req, pnf_p7); + } + else + { + // send dummy + if(pnf_p7->_public.tx_req && pnf_p7->_public.dummy_subframe.tx_req) + { + pnf_p7->_public.dummy_subframe.tx_req->sfn_sf = sfn_sf_tx; + (pnf_p7->_public.tx_req)(&(pnf_p7->_public), pnf_p7->_public.dummy_subframe.tx_req); + } + } + + if(tx_subframe_buffer->dl_config_req != 0) + { + if(pnf_p7->_public.dl_config_req) + (pnf_p7->_public.dl_config_req)(NULL, &(pnf_p7->_public), tx_subframe_buffer->dl_config_req); + + //deallocate_nfapi_dl_config_request(subframe_buffer->dl_config_req, pnf_p7); + } + else + { + // send dummy + if(pnf_p7->_public.dl_config_req && pnf_p7->_public.dummy_subframe.dl_config_req) + { + pnf_p7->_public.dummy_subframe.dl_config_req->sfn_sf = sfn_sf_tx; + (pnf_p7->_public.dl_config_req)(NULL, &(pnf_p7->_public), pnf_p7->_public.dummy_subframe.dl_config_req); + } + } + + if(tx_subframe_buffer->hi_dci0_req != 0) + { + if(pnf_p7->_public.hi_dci0_req) + (pnf_p7->_public.hi_dci0_req)(NULL, &(pnf_p7->_public), tx_subframe_buffer->hi_dci0_req); + + //deallocate_nfapi_hi_dci0_request(subframe_buffer->hi_dci0_req, pnf_p7); + } + else + { + //send dummy + if(pnf_p7->_public.hi_dci0_req && pnf_p7->_public.dummy_subframe.hi_dci0_req) + { + pnf_p7->_public.dummy_subframe.hi_dci0_req->sfn_sf = sfn_sf_tx; + (pnf_p7->_public.hi_dci0_req)(NULL, &(pnf_p7->_public), pnf_p7->_public.dummy_subframe.hi_dci0_req); + } + } + + if(tx_subframe_buffer->ue_release_req != 0) + { + if(pnf_p7->_public.ue_release_req) + (pnf_p7->_public.ue_release_req)(&(pnf_p7->_public), tx_subframe_buffer->ue_release_req); + } + else + { + //send dummy + if(pnf_p7->_public.ue_release_req && pnf_p7->_public.dummy_subframe.ue_release_req) + { + pnf_p7->_public.dummy_subframe.ue_release_req->sfn_sf = sfn_sf_tx; + (pnf_p7->_public.ue_release_req)(&(pnf_p7->_public), pnf_p7->_public.dummy_subframe.ue_release_req); + } + } + + if(tx_subframe_buffer->dl_config_req != 0) + { + deallocate_nfapi_dl_config_request(tx_subframe_buffer->dl_config_req, pnf_p7); + tx_subframe_buffer->dl_config_req = 0; + } + if(tx_subframe_buffer->tx_req != 0) + { + deallocate_nfapi_tx_request(tx_subframe_buffer->tx_req, pnf_p7); + tx_subframe_buffer->tx_req = 0; + } + if(tx_subframe_buffer->hi_dci0_req != 0) + { + deallocate_nfapi_hi_dci0_request(tx_subframe_buffer->hi_dci0_req, pnf_p7); + tx_subframe_buffer->hi_dci0_req = 0; + } + if(tx_subframe_buffer->ue_release_req != 0){ + deallocate_nfapi_ue_release_request(tx_subframe_buffer->ue_release_req, pnf_p7); + tx_subframe_buffer->ue_release_req = 0; + } + } + else + { + // If we ever need to "send" a dummy ul_config this won't work!!! + send_dummy_subframe(pnf_p7, sfn_sf_tx); + } + + if(subframe_buffer->sfn_sf == sfn_sf) + { + + if(subframe_buffer->ul_config_req != 0) + { + if(pnf_p7->_public.ul_config_req) + (pnf_p7->_public.ul_config_req)(NULL, &(pnf_p7->_public), subframe_buffer->ul_config_req); + + //deallocate_nfapi_ul_config_request(subframe_buffer->ul_config_req, pnf_p7); + } + else + { + // send dummy + if(pnf_p7->_public.ul_config_req && pnf_p7->_public.dummy_subframe.ul_config_req) + { + pnf_p7->_public.dummy_subframe.ul_config_req->sfn_sf = sfn_sf; + (pnf_p7->_public.ul_config_req)(NULL, &(pnf_p7->_public), pnf_p7->_public.dummy_subframe.ul_config_req); + } + } + + if(subframe_buffer->lbt_dl_config_req != 0) + { + if(pnf_p7->_public.lbt_dl_config_req) + (pnf_p7->_public.lbt_dl_config_req)(&(pnf_p7->_public), subframe_buffer->lbt_dl_config_req); + + //deallocate_nfapi_lbt_dl_config_request(subframe_buffer->lbt_dl_config_req, pnf_p7); + } + else + { + // send dummy + if(pnf_p7->_public.lbt_dl_config_req && pnf_p7->_public.dummy_subframe.lbt_dl_config_req) + { + pnf_p7->_public.dummy_subframe.lbt_dl_config_req->sfn_sf = sfn_sf; + (pnf_p7->_public.lbt_dl_config_req)(&(pnf_p7->_public), pnf_p7->_public.dummy_subframe.lbt_dl_config_req); + } + + } + + //if(subframe_buffer->dl_config_req != 0) + //deallocate_nfapi_dl_config_request(subframe_buffer->dl_config_req, pnf_p7); + //if(subframe_buffer->tx_req != 0) + //deallocate_nfapi_tx_request(subframe_buffer->tx_req, pnf_p7); + if(subframe_buffer->ul_config_req != 0) + { + deallocate_nfapi_ul_config_request(subframe_buffer->ul_config_req, pnf_p7); + subframe_buffer->ul_config_req = 0; + + } + //if(subframe_buffer->hi_dci0_req != 0) + //deallocate_nfapi_hi_dci0_request(subframe_buffer->hi_dci0_req, pnf_p7); + if(subframe_buffer->lbt_dl_config_req != 0) + { + deallocate_nfapi_lbt_dl_config_request(subframe_buffer->lbt_dl_config_req, pnf_p7); + subframe_buffer->lbt_dl_config_req = 0; + } + } // sfn_sf match + + if (subframe_buffer->dl_config_req == 0 && subframe_buffer->tx_req == 0 && subframe_buffer->ul_config_req == 0 && subframe_buffer->lbt_dl_config_req == 0 && subframe_buffer->ue_release_req == 0) + { + memset(&(pnf_p7->subframe_buffer[buffer_index]), 0, sizeof(nfapi_pnf_p7_subframe_buffer_t)); + pnf_p7->subframe_buffer[buffer_index].sfn_sf = -1; + } + + //printf("pnf_p7->_public.timing_info_mode_periodic:%d pnf_p7->timing_info_period_counter:%d pnf_p7->_public.timing_info_period:%d\n", pnf_p7->_public.timing_info_mode_periodic, pnf_p7->timing_info_period_counter, pnf_p7->_public.timing_info_period); + //printf("pnf_p7->_public.timing_info_mode_aperiodic:%d pnf_p7->timing_info_aperiodic_send:%d\n", pnf_p7->_public.timing_info_mode_aperiodic, pnf_p7->timing_info_aperiodic_send); + //printf("pnf_p7->timing_info_ms_counter:%d\n", pnf_p7->timing_info_ms_counter); + + // send the periodic timing info if configured + if(pnf_p7->_public.timing_info_mode_periodic && (pnf_p7->timing_info_period_counter++) == pnf_p7->_public.timing_info_period) + { + pnf_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_pack_and_send_timing_info(pnf_p7); + + pnf_p7->timing_info_aperiodic_send = 0; + } + else + { + pnf_p7->timing_info_ms_counter++; + } + } + else + { + //send_dummy_subframe(pnf_p7, sfn_sf_tx); + } + + + //printf("pnf_p7->tick:%d\n", pnf_p7->tick); + if(pnf_p7->tick == 1000) + { + + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF P7:%d] (ONTIME/LATE) DL:(%d/%d) UL:(%d/%d) HI:(%d/%d) TX:(%d/%d)\n", pnf_p7->_public.phy_id, + pnf_p7->stats.dl_conf_ontime, pnf_p7->stats.dl_conf_late, + pnf_p7->stats.ul_conf_ontime, pnf_p7->stats.ul_conf_late, + pnf_p7->stats.hi_dci0_ontime, pnf_p7->stats.hi_dci0_late, + pnf_p7->stats.tx_ontime, pnf_p7->stats.tx_late); + pnf_p7->tick = 0; + memset(&pnf_p7->stats, 0, sizeof(pnf_p7->stats)); + } + pnf_p7->tick++; + + + if(pthread_mutex_unlock(&(pnf_p7->mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n"); + return -1; + } +#endif + 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 @@ -621,8 +914,8 @@ int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf) pnf_p7->sf_start_time_hr = pnf_get_current_time_hr(); pnf_p7->sfn_sf = sfn_sf; - uint32_t sfn_sf_tx = sfnsf_add_sf(sfn_sf, sf_ahead); - uint32_t tx_sfn_sf_dec = NFAPI_SFNSF2DEC(sfn_sf_tx); + uint32_t sfn_sf_tx = sfnsf_add_sf(sfn_sf, sf_ahead); + uint32_t tx_sfn_sf_dec = NFAPI_SFNSF2DEC(sfn_sf_tx); // If the subframe_buffer has been configured if(pnf_p7->_public.subframe_buffer_size != 0) diff --git a/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c b/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c index 24e73ae9b3c6fb54efd362b6ed855a941b6cb932..0b77754a2f43ea00aa1a7b91133e8c91c4201a0c 100644 --- a/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c +++ b/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c @@ -88,6 +88,16 @@ 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) +{ + // Verify that config is not null + if(config == 0) + return -1; + + pnf_p7_t* _this = (pnf_p7_t*)(config); + + return pnf_p7_slot_ind(_this, phy_id, sfn, slot); +} int nfapi_pnf_p7_subframe_ind(nfapi_pnf_p7_config_t* config, uint16_t phy_id, uint16_t sfn_sf) { diff --git a/nfapi/open-nFAPI/pnf/tests/pnf_cunit_main.c b/nfapi/open-nFAPI/pnf/tests/pnf_cunit_main.c index d2ab031ad4708000942e490df8a0cd0b64276bb8..bd6bedbea546c67e9e8a133b7b26b586f13a23fe 100644 --- a/nfapi/open-nFAPI/pnf/tests/pnf_cunit_main.c +++ b/nfapi/open-nFAPI/pnf/tests/pnf_cunit_main.c @@ -48,6 +48,9 @@ typedef struct phy_info uint8_t enabled; uint16_t phy_id; uint16_t sfn_sf; + uint16_t sfn; + uint16_t slot; + pthread_t thread; @@ -1207,6 +1210,12 @@ 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); diff --git a/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c b/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c index a0efeeb5f4dbff9f123c5715bd02266efcccfecb..70153d06499fa4221388f13d7969e24086335b42 100644 --- a/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c +++ b/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c @@ -444,7 +444,7 @@ int nfapi_vnf_p7_add_pnf(nfapi_vnf_p7_config_t* config, const char* pnf_p7_addr, // save the remote endpoint information node->remote_addr.sin_family = AF_INET; - node->remote_addr.sin_port = htons(pnf_p7_port); + node->remote_addr.sin_port = pnf_p7_port;//htons(pnf_p7_port); node->remote_addr.sin_addr.s_addr = inet_addr(pnf_p7_addr); vnf_p7_connection_info_list_add(vnf_p7, node);