diff --git a/nfapi/oai_integration/nfapi_pnf.c b/nfapi/oai_integration/nfapi_pnf.c index 7ff235a0a4b7c79948e5391931ebb5258fe651df..f07fb1ad23f13aadeeabfe0b2178655bb4c2722e 100644 --- a/nfapi/oai_integration/nfapi_pnf.c +++ b/nfapi/oai_integration/nfapi_pnf.c @@ -83,7 +83,7 @@ nfapi_tx_request_pdu_t *tx_request_pdu[1023][10][10]; // [frame][subframe][max_n uint8_t tx_pdus[32][8][4096]; - +nfapi_ue_release_request_body_t release_rntis; uint16_t phy_antenna_capability_values[] = { 1, 2, 4, 8, 16 }; nfapi_pnf_param_response_t g_pnf_param_resp; @@ -895,6 +895,15 @@ int pnf_phy_lbt_dl_config_req(nfapi_pnf_p7_config_t *config, nfapi_lbt_dl_config return 0; } +int pnf_phy_ue_release_req(nfapi_pnf_p7_config_t* config, nfapi_ue_release_request_t* req) { + if (req->ue_release_request_body.number_of_TLVs==0) + return -1; + + release_rntis.number_of_TLVs = req->ue_release_request_body.number_of_TLVs; + memcpy(&release_rntis.ue_release_request_TLVs_list, req->ue_release_request_body.ue_release_request_TLVs_list, sizeof(nfapi_ue_release_request_TLVs_t)*req->ue_release_request_body.number_of_TLVs); + return 0; +} + int pnf_phy_vendor_ext(nfapi_pnf_p7_config_t *config, nfapi_p7_message_header_t *msg) { if(msg->message_id == P7_VENDOR_EXT_REQ) { //vendor_ext_p7_req* req = (vendor_ext_p7_req*)msg; @@ -1023,7 +1032,7 @@ int start_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi p7_config->hi_dci0_req = &pnf_phy_hi_dci0_req; p7_config->tx_req = &pnf_phy_tx_req; p7_config->lbt_dl_config_req = &pnf_phy_lbt_dl_config_req; - + p7_config->ue_release_req = &pnf_phy_ue_release_req; if (NFAPI_MODE==NFAPI_UE_STUB_PNF) { p7_config->dl_config_req = &memcpy_dl_config_req; p7_config->ul_config_req = &memcpy_ul_config_req; diff --git a/nfapi/oai_integration/nfapi_vnf.c b/nfapi/oai_integration/nfapi_vnf.c index 40226dfe4ee976e9d724dd39e99631e199197b88..3a8d22b531b63b4cae7d7d261fd70f2577f7b21e 100644 --- a/nfapi/oai_integration/nfapi_vnf.c +++ b/nfapi/oai_integration/nfapi_vnf.c @@ -1209,3 +1209,21 @@ int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return retval; } + +int oai_nfapi_ue_release_req(nfapi_ue_release_request_t *release_req){ + if(release_req->ue_release_request_body.number_of_TLVs <= 0) + return 0; + nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config; + + release_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! + release_req->header.message_id = NFAPI_UE_RELEASE_REQUEST; + release_req->ue_release_request_body.tl.tag = NFAPI_UE_RELEASE_BODY_TAG; + + int retval = nfapi_vnf_p7_ue_release_req(p7_config, release_req); + if (retval!=0) { + LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval); + } else { + release_req->ue_release_request_body.number_of_TLVs = 0; + } + return retval; +} diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h index 282739e31597782fd46a1e5e50f154d01c801708..82e6893309977b98e2829bcdefb39d386a151520 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h @@ -146,6 +146,8 @@ typedef enum { NFAPI_LBT_DL_INDICATION, NFAPI_NB_HARQ_INDICATION, NFAPI_NRACH_INDICATION, + NFAPI_UE_RELEASE_REQUEST, + NFAPI_UE_RELEASE_RESPONSE, NFAPI_PNF_PARAM_REQUEST = 0x0100, NFAPI_PNF_PARAM_RESPONSE, @@ -2378,6 +2380,19 @@ typedef struct { } nfapi_tx_request_body_t; #define NFAPI_TX_REQUEST_BODY_TAG 0x2022 +#define NFAPI_RELEASE_MAX_RNTI 256 +typedef struct { + uint32_t handle; + uint16_t rnti; +} nfapi_ue_release_request_TLVs_t; + +typedef struct { + nfapi_tl_t tl; + uint16_t number_of_TLVs; + nfapi_ue_release_request_TLVs_t ue_release_request_TLVs_list[NFAPI_RELEASE_MAX_RNTI]; +} nfapi_ue_release_request_body_t; +#define NFAPI_UE_RELEASE_BODY_TAG 0x2068 + // P7 Message Structures typedef struct { nfapi_p7_message_header_t header; @@ -3404,6 +3419,19 @@ typedef struct { nfapi_vendor_extension_tlv_t vendor_extension; } nfapi_error_indication_t; +typedef struct { + nfapi_p7_message_header_t header; + uint16_t sfn_sf; + nfapi_ue_release_request_body_t ue_release_request_body; + nfapi_vendor_extension_tlv_t vendor_extension; +} nfapi_ue_release_request_t; + +typedef struct { + nfapi_p7_message_header_t header; + uint32_t error_code; + nfapi_vendor_extension_tlv_t vendor_extension; +} nfapi_ue_release_response_t; + // // P4 Messages // diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c index 90b9ec26678df1e85167e8ee86c06fd4ccdc6e8b..c5d84034fed9968e127c75f8a1b02a91fec3e736 100644 --- a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c +++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c @@ -1586,7 +1586,43 @@ static uint8_t pack_tx_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *e return x && y && z; } - + +static uint8_t pack_release_request_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ue_release_request_body_t* value = (nfapi_ue_release_request_body_t*)tlv; + if(push16(value->number_of_TLVs, ppWritePackedMsg, end) == 0){ + return 0; + } + + uint8_t j; + uint16_t num = value->number_of_TLVs; + for(j = 0; j < num; ++j){ + if(push16(value->ue_release_request_TLVs_list[j].rnti, ppWritePackedMsg, end) == 0){ + return 0; + } + } + return 1; +} + +static uint8_t pack_ue_release_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_ue_release_request_t *pNfapiMsg = (nfapi_ue_release_request_t*)msg; + int x = push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end); + int y = pack_tlv(NFAPI_UE_RELEASE_BODY_TAG, &pNfapiMsg->ue_release_request_body, ppWritePackedMsg, end, &pack_release_request_body_value); + int z = pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config); + return x && y && z; +} + +static uint8_t pack_ue_release_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + + nfapi_ue_release_response_t *pNfapiMsg = (nfapi_ue_release_response_t*)msg; + + int x = push32(pNfapiMsg->error_code, ppWritePackedMsg, end); + int z = pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config); + return x && z; +} + static uint8_t pack_rx_ue_information_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) { nfapi_rx_ue_information* value = (nfapi_rx_ue_information*)tlv; @@ -2674,7 +2710,15 @@ int nfapi_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBu //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() NFAPI_TX_REQUEST\n", __FUNCTION__); result = pack_tx_request(pMessageHeader, &pWritePackedMessage, end, config); break; - + + case NFAPI_UE_RELEASE_REQUEST: + result =pack_ue_release_request(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_UE_RELEASE_RESPONSE: + result =pack_ue_release_response(pMessageHeader, &pWritePackedMessage, end, config); + break; + case NFAPI_HARQ_INDICATION: result = pack_harq_indication(pMessageHeader, &pWritePackedMessage, end, config); break; @@ -4488,7 +4532,55 @@ static uint8_t unpack_tx_request(uint8_t **ppReadPackedMsg, uint8_t *end, void * return 1; } - + +static uint8_t unpack_ue_release_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + uint8_t proceed = 1; + nfapi_ue_release_request_t *pNfapiMsg = (nfapi_ue_release_request_t*)msg; + + if(pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) == 0) + return 0; + + while (((uint8_t*)(*ppReadPackedMsg) < end) && proceed) + { + nfapi_tl_t generic_tl; + if(unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0) + return 0; + + switch(generic_tl.tag) + { + case NFAPI_UE_RELEASE_BODY_TAG: + { + pNfapiMsg->ue_release_request_body.tl = generic_tl; + if( pull16(ppReadPackedMsg, &pNfapiMsg->ue_release_request_body.number_of_TLVs, end) == 0) + return 0; + + if(pNfapiMsg->ue_release_request_body.number_of_TLVs > NFAPI_RELEASE_MAX_RNTI) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of relese rnti's exceed maxium (count:%d max:%d)\n", __FUNCTION__, pNfapiMsg->ue_release_request_body.number_of_TLVs, NFAPI_RELEASE_MAX_RNTI); + return 0; + } else { + uint8_t j; + uint16_t num = pNfapiMsg->ue_release_request_body.number_of_TLVs; + for(j = 0; j < num; ++j){ + if(pull16(ppReadPackedMsg, &pNfapiMsg->ue_release_request_body.ue_release_request_TLVs_list[j].rnti, end) == 0){ + return 0; + } + } + } + } + break; + default: + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "unpack_ue_release_request FIXME : Invalid type %d \n", generic_tl.tag ); + } + break; + }; + } + + return 1; +} + static uint8_t unpack_harq_indication_tdd_harq_data_bundling(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) { nfapi_harq_indication_tdd_harq_data_bundling_t* value = (nfapi_harq_indication_tdd_harq_data_bundling_t*)tlv; @@ -5736,7 +5828,18 @@ static uint8_t unpack_nrach_indication_rel13_value(void *tlv, uint8_t **ppReadPa pull8(ppReadPackedMsg, &value->nrach_ce_level, end)); } - +static uint8_t unpack_ue_release_resp(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_ue_release_response_t *pNfapiMsg = (nfapi_ue_release_response_t*)msg; + if(pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) == 0){ + return 0; + } + else{ + NFAPI_TRACE(NFAPI_TRACE_ERROR, "ue_release_response:error_code = %d\n", pNfapiMsg->error_code); + } + return 1; +} + static uint8_t unpack_nrach_indication_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) { nfapi_nrach_indication_body_t* value = (nfapi_nrach_indication_body_t*)tlv; @@ -5949,7 +6052,17 @@ static int check_unpack_length(nfapi_message_id_e msgId, uint32_t unpackedBufLen if (unpackedBufLen >= sizeof(nfapi_timing_info_t)) retLen = sizeof(nfapi_timing_info_t); break; - + + case NFAPI_UE_RELEASE_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_ue_release_request_t)) + retLen = sizeof(nfapi_ue_release_request_t); + break; + + case NFAPI_UE_RELEASE_RESPONSE: + if (unpackedBufLen >= sizeof(nfapi_ue_release_response_t)) + retLen = sizeof(nfapi_ue_release_response_t); + break; + default: NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown message ID %d\n", msgId); break; @@ -6069,7 +6182,14 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn else return -1; break; - + + case NFAPI_UE_RELEASE_REQUEST: + if (check_unpack_length(NFAPI_UE_RELEASE_REQUEST, unpackedBufLen)) + result = unpack_ue_release_request(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + case NFAPI_HARQ_INDICATION: if (check_unpack_length(NFAPI_HARQ_INDICATION, unpackedBufLen)) result = unpack_harq_indication(&pReadPackedMessage, end, pMessageHeader, config); @@ -6167,7 +6287,14 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn else return -1; break; - + + case NFAPI_UE_RELEASE_RESPONSE: + if (check_unpack_length(NFAPI_UE_RELEASE_RESPONSE, unpackedBufLen)) + result = unpack_ue_release_resp(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + default: if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && 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 b25caf28760ff6e06ef4607b2d49f7e1a46e1de5..8d17416a418a98a822494726b1f1261aa1f66e54 100644 --- a/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h +++ b/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h @@ -546,7 +546,7 @@ typedef struct nfapi_hi_dci0_request_t* hi_dci0_req; nfapi_tx_request_t* tx_req; nfapi_lbt_dl_config_request_t* lbt_dl_config_req; - + nfapi_ue_release_request_t* ue_release_req; } nfapi_pnf_p7_subframe_buffer_t; typedef struct nfapi_pnf_p7_config nfapi_pnf_p7_config_t; @@ -652,6 +652,17 @@ typedef struct nfapi_pnf_p7_config * \return not currently used */ int (*lbt_dl_config_req)(nfapi_pnf_p7_config_t* config, nfapi_lbt_dl_config_request_t* req); + + /*! A callback for the UE_RELEASE_REQ.request + * \param config A poiner to the PNF P7 config + * \param req A pointer to the release rnti request message structure + * \return not currently used + * + * The release request contains pointers to the release rnti to be sent. In the case that the FAPI interface + * will 'keep' the pointers until they are transmitted the callee should set the pointers in the req to 0 + * and then use the p7 codec config free function to release the rnti when appropriate. + */ + int (*ue_release_req)(nfapi_pnf_p7_config_t* config, nfapi_ue_release_request_t* req); /*! A callback for vendor extension messages * \param config A poiner to the PNF P7 config @@ -796,6 +807,7 @@ int nfapi_pnf_p7_nrach_ind(nfapi_pnf_p7_config_t* config, nfapi_nrach_indication */ int nfapi_pnf_p7_vendor_extension(nfapi_pnf_p7_config_t* config, nfapi_p7_message_header_t* msg); +int nfapi_pnf_ue_release_resp(nfapi_pnf_p7_config_t* config, nfapi_ue_release_response_t* resp); #if defined(__cplusplus) } #endif diff --git a/nfapi/open-nFAPI/pnf/src/pnf_p7.c b/nfapi/open-nFAPI/pnf/src/pnf_p7.c index 5efcf9d7cc73631b2998eb9c548c798ac97d9a07..944673037500c6f8478b3352f0998f28e840cc07 100644 --- a/nfapi/open-nFAPI/pnf/src/pnf_p7.c +++ b/nfapi/open-nFAPI/pnf/src/pnf_p7.c @@ -241,6 +241,16 @@ void deallocate_nfapi_lbt_dl_config_request(nfapi_lbt_dl_config_request_t* req, pnf_p7_free(pnf_p7, req); } +nfapi_ue_release_request_t* allocate_nfapi_ue_release_request(pnf_p7_t* pnf_p7) +{ + return pnf_p7_malloc(pnf_p7, sizeof(nfapi_ue_release_request_t)); +} + +void deallocate_nfapi_ue_release_request(nfapi_ue_release_request_t* req, pnf_p7_t* pnf_p7) +{ + pnf_p7_free(pnf_p7, req); +} + 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) { pnf_p7_rx_message_t* msg = 0; @@ -720,6 +730,21 @@ int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf) } } + 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); @@ -735,6 +760,10 @@ int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf) 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 { @@ -799,7 +828,7 @@ int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf) } } // 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) + 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; @@ -1310,6 +1339,80 @@ void pnf_handle_p7_vendor_extension(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pn } +void pnf_handle_ue_release_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7) +{ + nfapi_ue_release_request_t* req = allocate_nfapi_ue_release_request(pnf_p7); + if(req == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to alloced nfapi_ue_release_request structure\n"); + return; + } + + int unpack_result = nfapi_p7_message_unpack(pRecvMsg, recvMsgLen, req, sizeof(nfapi_ue_release_request_t), &pnf_p7->_public.codec_config); + if(unpack_result == 0) + { + if(pthread_mutex_lock(&(pnf_p7->mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "failed to lock mutex\n"); + return; + } + + if(is_p7_request_in_window(req->sfn_sf, "ue_release_request", pnf_p7)) + { + uint32_t sfn_sf_dec = NFAPI_SFNSF2DEC(req->sfn_sf); + uint8_t buffer_index = sfn_sf_dec % pnf_p7->_public.subframe_buffer_size; + + struct timespec t; + clock_gettime(CLOCK_MONOTONIC, &t); + + NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() %ld.%09ld POPULATE UE_RELEASE_REQ sfn_sf:%d buffer_index:%d\n", __FUNCTION__, t.tv_sec, t.tv_nsec, sfn_sf_dec, buffer_index); + + if (0 && NFAPI_SFNSF2DEC(req->sfn_sf)%100==0) NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() UE_RELEASE_REQ.req sfn_sf:%d rntis:%d - UE_RELEASE_REQ is within window\n", + __FUNCTION__, + NFAPI_SFNSF2DEC(req->sfn_sf), + req->ue_release_request_body.number_of_TLVs); + + if(pnf_p7->subframe_buffer[buffer_index].ue_release_req != 0) + { + deallocate_nfapi_ue_release_request(pnf_p7->subframe_buffer[buffer_index].ue_release_req, pnf_p7); + } + + pnf_p7->subframe_buffer[buffer_index].sfn_sf = req->sfn_sf; + pnf_p7->subframe_buffer[buffer_index].ue_release_req = req; + + pnf_p7->stats.tx_ontime++; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() UE_RELEASE_REQUEST Request is outside of window REQ:SFN_SF:%d CURR:SFN_SF:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), NFAPI_SFNSF2DEC(pnf_p7->sfn_sf)); + + deallocate_nfapi_ue_release_request(req, pnf_p7); + if(pnf_p7->_public.timing_info_mode_aperiodic) + { + pnf_p7->timing_info_aperiodic_send = 1; + } + + pnf_p7->stats.tx_late++; + } + nfapi_ue_release_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_UE_RELEASE_RESPONSE; + resp.header.phy_id = req->header.phy_id; + resp.error_code = NFAPI_MSG_OK; + nfapi_pnf_ue_release_resp(&(pnf_p7->_public), &resp); + NFAPI_TRACE(NFAPI_TRACE_INFO, "do ue_release_response\n"); + + if(pthread_mutex_unlock(&(pnf_p7->mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "failed to unlock mutex\n"); + return; + } + } + else + { + deallocate_nfapi_ue_release_request(req, pnf_p7); + } +} uint32_t calculate_t2(uint32_t now_time_hr, uint16_t sfn_sf, uint32_t sf_start_time_hr) { @@ -1445,7 +1548,11 @@ void pnf_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, case NFAPI_LBT_DL_CONFIG_REQUEST: pnf_handle_lbt_dl_config_request(pRecvMsg, recvMsgLen, pnf_p7); break; - + + case NFAPI_UE_RELEASE_REQUEST: + pnf_handle_ue_release_request(pRecvMsg, recvMsgLen, pnf_p7); + break; + default: { if(header.message_id >= NFAPI_VENDOR_EXT_MSG_MIN && diff --git a/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c b/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c index 74de5e5d785e5d251dfcc65133fd2154219b7641..24e73ae9b3c6fb54efd362b6ed855a941b6cb932 100644 --- a/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c +++ b/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c @@ -223,3 +223,15 @@ int nfapi_pnf_p7_vendor_extension(nfapi_pnf_p7_config_t* config, nfapi_p7_messag return pnf_p7_pack_and_send_p7_message(_this, msg, 0); } +int nfapi_pnf_ue_release_resp(nfapi_pnf_p7_config_t* config, nfapi_ue_release_response_t* resp) +{ + if (config == NULL || resp == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + return -1; + } + + pnf_p7_t* _this = (pnf_p7_t*)(config); + + return pnf_p7_pack_and_send_p7_message(_this, &(resp->header), sizeof(nfapi_ue_release_response_t)); +} diff --git a/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h b/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h index 462901391a8cd63bfc9b25a239f8600870fdad52..ed8f6ba9688939bf953fc0f52729ba7877a86659 100644 --- a/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h +++ b/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h @@ -988,6 +988,15 @@ int nfapi_vnf_p7_lbt_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_lbt_dl_c */ int nfapi_vnf_p7_vendor_extension(nfapi_vnf_p7_config_t* config, nfapi_p7_message_header_t* msg); +/*! Send the RELEASE_RNTI.request + * \param config A pointer to the vnf p7 configuration + * \param req A data structure for the decoded RELEASE_RNTI.request. + * \return A status value. 0 equal success, -1 indicates failure + * + * The caller is responsiable for memory management of any pointers set in the req, which + * may be released after this function call has returned or at a later pointer + */ +int nfapi_vnf_p7_ue_release_req(nfapi_vnf_p7_config_t* config, nfapi_ue_release_request_t* req); #if defined(__cplusplus) } #endif diff --git a/nfapi/open-nFAPI/vnf/src/vnf_p7.c b/nfapi/open-nFAPI/vnf/src/vnf_p7.c index 3a201bda37578e7f5c2992494e8c71eb09edb10b..985a6f830a6835db67f38ff587c6e0d86f5a99b4 100644 --- a/nfapi/open-nFAPI/vnf/src/vnf_p7.c +++ b/nfapi/open-nFAPI/vnf/src/vnf_p7.c @@ -822,6 +822,28 @@ void vnf_handle_nrach_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p } } +void vnf_handle_ue_release_resp(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) +{ + + // ensure it's valid + if (pRecvMsg == NULL || vnf_p7 == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_ue_release_response_t resp; + + if(nfapi_p7_message_unpack(pRecvMsg, recvMsgLen, &resp, sizeof(resp), &vnf_p7->_public.codec_config) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Failed to unpack message\n", __FUNCTION__); + } + + + vnf_p7_codec_free(vnf_p7, resp.vendor_extension); + } +} + void vnf_handle_p7_vendor_extension(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7, uint16_t message_id) { if (pRecvMsg == NULL || vnf_p7 == NULL) @@ -1334,6 +1356,10 @@ void vnf_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) vnf_handle_nrach_indication(pRecvMsg, recvMsgLen, vnf_p7); break; + case NFAPI_UE_RELEASE_RESPONSE: + vnf_handle_ue_release_resp(pRecvMsg, recvMsgLen, vnf_p7); + break; + default: { if(header.message_id >= NFAPI_VENDOR_EXT_MSG_MIN && diff --git a/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c b/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c index 4a85f7e4b3b9b245f5f5660e6c1a3a0dc8ce80eb..0444dca71d0f7d2d5973a123458be8b22df60a20 100644 --- a/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c +++ b/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c @@ -523,6 +523,14 @@ int nfapi_vnf_p7_vendor_extension(nfapi_vnf_p7_config_t* config, nfapi_p7_messag return vnf_p7_pack_and_send_p7_msg(vnf_p7, header); } +int nfapi_vnf_p7_ue_release_req(nfapi_vnf_p7_config_t* config, nfapi_ue_release_request_t* req) +{ + if(config == 0 || req == 0) + return -1; + + vnf_p7_t* vnf_p7 = (vnf_p7_t*)config; + return vnf_p7_pack_and_send_p7_msg(vnf_p7, &req->header); +} int nfapi_vnf_p7_release_msg(nfapi_vnf_p7_config_t* config, nfapi_p7_message_header_t* header) { diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c index b44a04eb742488b2dc599ba83997619987630d41..a4acfee0f1479973ca13bbcbf74e18512895c6d7 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c @@ -569,7 +569,12 @@ int dlsch_encoding_all(PHY_VARS_eNB *eNB, time_stats_t *i_stats) { int encoding_return = 0; unsigned int L,C,B; - B = dlsch->harq_processes[dlsch->harq_ids[frame%2][subframe]]->B; + uint8_t harq_pid = dlsch->harq_ids[frame%2][subframe]; + if(harq_pid >= dlsch->Mdlharq) { + LOG_E(PHY,"dlsch_encoding_all illegal harq_pid %d\n", harq_pid); + return(-1); + } + B = dlsch->harq_processes[harq_pid]->B; LOG_D(PHY,"B %d, harq_pid %d\n",B,dlsch->harq_ids[frame%2][subframe]); diff --git a/openair1/SCHED/fapi_l1.c b/openair1/SCHED/fapi_l1.c index f39c5b4f1388fe5dc410d6ce29e9acb8bf83532a..e95405e6d3c534fe4fad743e14f97d417461750e 100644 --- a/openair1/SCHED/fapi_l1.c +++ b/openair1/SCHED/fapi_l1.c @@ -42,7 +42,7 @@ int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req); int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req); int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req); - +int oai_nfapi_ue_release_req(nfapi_ue_release_request_t *release_req); void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB, int frame, int subframe, L1_rxtx_proc_t *proc, @@ -933,6 +933,8 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) { } Sched_INFO->DL_req->sfn_sf = frame << 4 | subframe; oai_nfapi_dl_config_req(Sched_INFO->DL_req); // DJP - .dl_config_request_body.dl_config_pdu_list[0]); // DJP - FIXME TODO - yuk - only copes with 1 pdu + Sched_INFO->UE_release_req->sfn_sf = frame << 4 | subframe; + oai_nfapi_ue_release_req(Sched_INFO->UE_release_req); } if ((NFAPI_MODE!=NFAPI_MONOLITHIC) && number_hi_dci0_pdu!=0) { diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 18b917430cbbaaaa387943e59b38d8b262355054..9bf1e6ec3155fdf39d669339eb4bece06a6e35a3 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -47,8 +47,7 @@ #include "intertask_interface.h" - - +nfapi_ue_release_request_body_t release_rntis; int16_t get_hundred_times_delta_IF_eNB(PHY_VARS_eNB *eNB,uint16_t UE_id,uint8_t harq_pid, uint8_t bw_factor) { uint32_t Nre,sumKr,MPR_x100,Kr,r; @@ -1522,8 +1521,10 @@ static void do_release_harq(PHY_VARS_eNB *eNB, harq_pid = dlsch0->harq_ids[frame_tx%2][subframe_tx]; - AssertFatal((harq_pid >= 0) && (harq_pid < 8),"harq_pid %d not in 0...7\n", harq_pid); - + if(harq_pid >= dlsch0->Mdlharq) { + LOG_E(PHY,"frame %d subframe %d harq_pid %d not in 0...7\n", frame_tx, subframe_tx, harq_pid); + return; + } dlsch0_harq = dlsch0->harq_processes[harq_pid]; dlsch1_harq = dlsch1->harq_processes[harq_pid]; @@ -2003,3 +2004,44 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_UESPEC, 0 ); } + +void release_rnti_of_phy(module_id_t mod_id){ + int i,j; + int CC_id; + rnti_t rnti; + PHY_VARS_eNB *eNB_PHY = NULL; + LTE_eNB_ULSCH_t *ulsch = NULL; + LTE_eNB_DLSCH_t *dlsch = NULL; + for(i = 0; i< release_rntis.number_of_TLVs;i++){ + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + eNB_PHY = RC.eNB[mod_id][CC_id]; + rnti = release_rntis.ue_release_request_TLVs_list[i].rnti; + for (j=0; j<NUMBER_OF_UE_MAX; j++) { + ulsch = eNB_PHY->ulsch[j]; + if((ulsch != NULL) && (ulsch->rnti == rnti)){ + LOG_I(PHY, "clean_eNb_ulsch ulsch[%d] UE %x\n", j, rnti); + clean_eNb_ulsch(ulsch); + } + + dlsch = eNB_PHY->dlsch[j][0]; + if((dlsch != NULL) && (dlsch->rnti == rnti)){ + LOG_I(PHY, "clean_eNb_dlsch dlsch[%d] UE %x \n", j, rnti); + clean_eNb_dlsch(dlsch); + } + } + ulsch = eNB_PHY->ulsch[j]; + if((ulsch != NULL) && (ulsch->rnti == rnti)){ + LOG_I(PHY, "clean_eNb_ulsch ulsch[%d] UE %x\n", j, rnti); + clean_eNb_ulsch(ulsch); + } + for(j=0; j<NUMBER_OF_UCI_VARS_MAX; j++) { + if(eNB_PHY->uci_vars[j].rnti == rnti){ + LOG_I(PHY, "clean eNb uci_vars[%d] UE %x \n",j, rnti); + memset(&eNB_PHY->uci_vars[i],0,sizeof(LTE_eNB_UCI)); + } + + } + } + } + memset(&release_rntis, 0, sizeof(nfapi_ue_release_request_body_t)); +} diff --git a/openair1/SCHED/sched_eNB.h b/openair1/SCHED/sched_eNB.h index dccfbf7c388ac204771e391eaa1044cffea9e4cd..7fcabdc5ddf8163b063edc655cdca442a0f0617c 100644 --- a/openair1/SCHED/sched_eNB.h +++ b/openair1/SCHED/sched_eNB.h @@ -219,6 +219,7 @@ int is_srs_occasion_common(LTE_DL_FRAME_PARMS *frame_parms,int frame_tx,int subf void compute_srs_pos(lte_frame_type_t frameType,uint16_t isrs,uint16_t *psrsPeriodicity,uint16_t *psrsOffset); +void release_rnti_of_phy(module_id_t mod_id); /*@}*/ diff --git a/openair1/SIMULATION/LTE_PHY/dummy_functions.c b/openair1/SIMULATION/LTE_PHY/dummy_functions.c index 586193484dd968d8564ad82c9f710c6a252fc246..43ae6502701e1379a0ac4bf0b571a94136a92f82 100644 --- a/openair1/SIMULATION/LTE_PHY/dummy_functions.c +++ b/openair1/SIMULATION/LTE_PHY/dummy_functions.c @@ -88,5 +88,5 @@ int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { return(0);} int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) { return(0); } int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { return(0); } - +int oai_nfapi_ue_release_req(nfapi_ue_release_request_t *release_req){ return(0); } int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); } diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index 0ac3a32fa8b82bee1eba86369121edc97f5f6d65..723e248c7f0016d08143bd9438cd340f378ab885 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -1417,6 +1417,8 @@ typedef struct eNB_MAC_INST_s { tx_request_pdu[NFAPI_CC_MAX][MAX_NUM_TX_REQUEST_PDU]; /// NFAPI DL PDU structure nfapi_tx_request_t TX_req[NFAPI_CC_MAX]; + /// NFAPI UE_release_req structure + nfapi_ue_release_request_t UE_release_req; /// UL handle uint32_t ul_handle; UE_list_t UE_list; diff --git a/openair2/PHY_INTERFACE/IF_Module.c b/openair2/PHY_INTERFACE/IF_Module.c index b58c96cc13b31a1b053228b56b97588160bfc996..f41a733d9afd8badbae3dd226e8783dff1ba4a11 100644 --- a/openair2/PHY_INTERFACE/IF_Module.c +++ b/openair2/PHY_INTERFACE/IF_Module.c @@ -762,6 +762,9 @@ void UL_indication(UL_IND_t *UL_info) { sched_info->UL_req = NULL; sched_info->TX_req = &mac->TX_req[CC_id]; + pthread_mutex_lock(&lock_ue_freelist); + sched_info->UE_release_req = &mac->UE_release_req; + pthread_mutex_unlock(&lock_ue_freelist); #ifdef DUMP_FAPI dump_dl(sched_info); #endif diff --git a/openair2/PHY_INTERFACE/IF_Module.h b/openair2/PHY_INTERFACE/IF_Module.h index 11dea21d284e7d75e9f5ea725dd7936d2a117fdc..9226220c803d324c5f76f6de7c38ae8f2981ab3d 100644 --- a/openair2/PHY_INTERFACE/IF_Module.h +++ b/openair2/PHY_INTERFACE/IF_Module.h @@ -129,6 +129,8 @@ typedef struct{ nfapi_hi_dci0_request_t *HI_DCI0_req; /// Pointers to DL SDUs nfapi_tx_request_t *TX_req; + /// Pointers to ue_release + nfapi_ue_release_request_t *UE_release_req; }Sched_Rsp_t; typedef struct { diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 42a15037327d7385523deb14a1ff182662248f54..52f9a618df0e84544bb3a7dc85a735f2ce4c7ce0 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -979,6 +979,8 @@ void put_UE_in_freelist(module_id_t mod_id, rnti_t rnti, boolean_t removeFlag) { free_list->UE_free_ctrl[free_list->tail_freelist].rnti = rnti; free_list->UE_free_ctrl[free_list->tail_freelist].removeContextFlg = removeFlag; free_list->num_UEs++; + eNB_MAC->UE_release_req.ue_release_request_body.ue_release_request_TLVs_list[eNB_MAC->UE_release_req.ue_release_request_body.number_of_TLVs].rnti = rnti; + eNB_MAC->UE_release_req.ue_release_request_body.number_of_TLVs++; free_list->tail_freelist = (free_list->tail_freelist + 1) % (NUMBER_OF_UE_MAX+1); pthread_mutex_unlock(&lock_ue_freelist); } diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 36a9b9e46973c15b831f27800fc1ccd8a2dad2c2..bc2ff7a0811c332322b26c28d952b7cc16d00d60 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -204,8 +204,10 @@ static inline int rxtx(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, char *thread_name wakeup_prach_eNB_br(eNB,NULL,proc->frame_rx,proc->subframe_rx); #endif } - if (NFAPI_MODE==NFAPI_MODE_VNF) { - release_UE_in_freeList(eNB->Mod_id); + if (NFAPI_MODE!=NFAPI_MODE_PNF) { + release_UE_in_freeList(eNB->Mod_id); + } else { + release_rnti_of_phy(eNB->Mod_id); } // UE-specific RX processing for subframe n if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) {