From 91e620505c094c9e194453e2865a6e414930446c Mon Sep 17 00:00:00 2001 From: "lal.harshita" Date: Wed, 1 Mar 2023 17:39:02 +0530 Subject: [PATCH] [Epic-ID: ODUHIGH-463][Task-ID: ODUHIGH-496] Dummy Xn Setup Request/Response Signed-off-by: lal.harshita Change-Id: I147ea03ccfa38bc0ee1c326cae24c27638bb0005 Signed-off-by: lal.harshita --- src/cu_stub/cu_f1ap_msg_hdl.c | 60 +++++---- src/cu_stub/cu_stub.h | 7 ++ src/cu_stub/cu_stub_sctp.c | 61 ++++++--- src/cu_stub/cu_xnap_msg_hdl.c | 286 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 372 insertions(+), 42 deletions(-) create mode 100644 src/cu_stub/cu_xnap_msg_hdl.c diff --git a/src/cu_stub/cu_f1ap_msg_hdl.c b/src/cu_stub/cu_f1ap_msg_hdl.c index 14f7a2827..601637b33 100644 --- a/src/cu_stub/cu_f1ap_msg_hdl.c +++ b/src/cu_stub/cu_f1ap_msg_hdl.c @@ -11898,7 +11898,7 @@ uint8_t procServedCellPlmnList(ServedPLMNs_List_t *srvPlmn) * RFAILED - failure * * ****************************************************************/ -uint8_t procUeContextModificationResponse(uint32_t duId, F1AP_PDU_t *f1apMsg) +uint8_t procUeContextModificationResponse(uint32_t duId, F1AP_PDU_t *f1apMsg, char *recvBuf, MsgLen recvBufLen) { uint8_t idx=0, duIdx=0; uint8_t duUeF1apId = 0, cuUeF1apId = 0; @@ -11922,6 +11922,11 @@ uint8_t procUeContextModificationResponse(uint32_t duId, F1AP_PDU_t *f1apMsg) { duUeF1apId = ueCtxtModRsp->protocolIEs.list.array[idx]->value.choice.GNB_DU_UE_F1AP_ID; ueCb = &duDb->ueCb[duUeF1apId-1]; + + if((ueCb->state == UE_HANDOVER_IN_PROGRESS) && (ueCb->hoInfo.HOType == Xn_Based_Inter_CU_HO)) + { + BuildAndSendHOReq(ueCb, HO_REQ, recvBuf, recvBufLen); + } break; } case ProtocolIE_ID_id_DRBs_SetupMod_List: @@ -11958,35 +11963,38 @@ uint8_t procUeContextModificationResponse(uint32_t duId, F1AP_PDU_t *f1apMsg) /* If UE is in handover and UE context is not yet created at target DU, then send * UE context setup request to target DU */ - if(ueCb->state == UE_HANDOVER_IN_PROGRESS && ueCb->hoInfo.HOType == Inter_DU_HO) + if(ueCb->state == UE_HANDOVER_IN_PROGRESS) { - uint8_t ueIdx = 0; - DuDb *tgtDuDb = NULLP; - CuUeCb *ueCbInTgtDu = NULLP; - - SEARCH_DU_DB(duIdx, ueCb->hoInfo.targetId, tgtDuDb); - if(tgtDuDb) + if(ueCb->hoInfo.HOType == Inter_DU_HO) { - /* Since DU UE F1AP ID assigned by target DU to this UE in handover is - * not known here, using CU UE F1AP ID to search for UE Cb in target DU - * DB */ - for(ueIdx = 0; ueIdx < MAX_NUM_UE; ueIdx++) + uint8_t ueIdx = 0; + DuDb *tgtDuDb = NULLP; + CuUeCb *ueCbInTgtDu = NULLP; + + SEARCH_DU_DB(duIdx, ueCb->hoInfo.targetId, tgtDuDb); + if(tgtDuDb) { - if(tgtDuDb->ueCb[ueIdx].gnbCuUeF1apId == cuUeF1apId) + /* Since DU UE F1AP ID assigned by target DU to this UE in handover is + * not known here, using CU UE F1AP ID to search for UE Cb in target DU + * DB */ + for(ueIdx = 0; ueIdx < MAX_NUM_UE; ueIdx++) { - ueCbInTgtDu = &tgtDuDb->ueCb[ueIdx]; - break; + if(tgtDuDb->ueCb[ueIdx].gnbCuUeF1apId == cuUeF1apId) + { + ueCbInTgtDu = &tgtDuDb->ueCb[ueIdx]; + break; + } } - } - /* If UE context is not found in Target DU DU, send UE context setup - * request */ - if(ueCbInTgtDu == NULLP) - { - if((BuildAndSendUeContextSetupReq(ueCb->hoInfo.targetId, ueCb)) != ROK) + /* If UE context is not found in Target DU DU, send UE context setup + * request */ + if(ueCbInTgtDu == NULLP) { - DU_LOG("\nERROR -> F1AP : Failed at BuildAndSendUeContextSetupReq"); - return RFAILED; + if((BuildAndSendUeContextSetupReq(ueCb->hoInfo.targetId, ueCb)) != ROK) + { + DU_LOG("\nERROR -> F1AP : Failed at BuildAndSendUeContextSetupReq"); + return RFAILED; + } } } } @@ -12027,6 +12035,10 @@ void procF1SetupReq(uint32_t *destDuId, F1AP_PDU_t *f1apMsg) GNB_DU_Served_Cells_Item_t *srvCellItem = NULLP; GNB_DU_Served_Cells_List_t *duServedCell = NULLP; + /* Triggering XN setup request before F1 setup establishment */ + if(LOCAL_NODE_TYPE == CLIENT) + BuildAndSendXnSetupReq(); + f1SetupReq = &f1apMsg->choice.initiatingMessage->value.choice.F1SetupRequest; for(ieIdx=0; ieIdx < f1SetupReq->protocolIEs.list.count; ieIdx++) { @@ -12676,7 +12688,7 @@ void F1APMsgHdlr(uint32_t *duId, Buffer *mBuf) case SuccessfulOutcome__value_PR_UEContextModificationResponse: { DU_LOG("\nINFO --> F1AP : UE Context Modification Response received"); - procUeContextModificationResponse(*duId, f1apMsg); + procUeContextModificationResponse(*duId, f1apMsg, recvBuf, recvBufLen); break; } case SuccessfulOutcome__value_PR_UEContextReleaseComplete: diff --git a/src/cu_stub/cu_stub.h b/src/cu_stub/cu_stub.h index 180116f4a..08cb36b0f 100644 --- a/src/cu_stub/cu_stub.h +++ b/src/cu_stub/cu_stub.h @@ -112,6 +112,13 @@ typedef enum Inter_DU_HO }HandoverType; +typedef enum +{ + XN_SETUP_REQ, + XN_SETUP_RSP, + HO_REQ +}XnEventType; + typedef enum { CELL_INACTIVE, diff --git a/src/cu_stub/cu_stub_sctp.c b/src/cu_stub/cu_stub_sctp.c index e9bd0d64d..0a03f0d54 100644 --- a/src/cu_stub/cu_stub_sctp.c +++ b/src/cu_stub/cu_stub_sctp.c @@ -121,7 +121,6 @@ uint8_t sctpCfgReq() for(destIdx=0; destIdx < sctpCb.sctpCfg.xnSctpInfo.numDestNode; destIdx++) { sctpCb.assocCb[assocIdx].intf = XN_INTERFACE; - sctpCb.assocCb[assocIdx].destId = CU_ID + destIdx +1; sctpCb.assocCb[assocIdx].destPort = sctpCb.sctpCfg.xnSctpInfo.destCb[destIdx].destPort; sctpCb.assocCb[assocIdx].bReadFdSet = ROK; memset(&sctpCb.assocCb[assocIdx].sockFd, -1, sizeof(CmInetFd)); @@ -617,9 +616,9 @@ uint8_t processPolling(sctpSockPollParams *pollParams, CuSctpAssocCb *assocCb, u } else if(assocCb->connUp && assocCb->intf == XN_INTERFACE) { - //TODO : Handler for messages on XN interface to be added in future commits DU_LOG("\nDEBUG --> SCTP : Received message at XN interface"); ODU_PRINT_MSG(pollParams->mBuf, 0,0); + XNAPMsgHdlr(&assocCb->destId, pollParams->mBuf); ODU_PUT_MSG_BUF(pollParams->mBuf); } else @@ -631,6 +630,43 @@ uint8_t processPolling(sctpSockPollParams *pollParams, CuSctpAssocCb *assocCb, u return ROK; }/* End of sctpSockPoll() */ +/******************************************************************* + * + * @brief Send message on an SCTP Association + * + * @details + * + * Function : sendOnSctpAssoc + * + * Functionality: + * Send message on SCTP association + * + * @params[in] + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +uint8_t sendOnSctpAssoc(CuSctpAssocCb *assocCb, Buffer *mBuf) +{ + uint8_t ret = ROK; + MsgLen len = 0; /* number of actually sent octets */ + CmInetMemInfo memInfo; + + memset(&memInfo , 0, sizeof(CmInetMemInfo)); + memInfo.region = CU_APP_MEM_REG; + memInfo.pool = CU_POOL; + + ret = cmInetSctpSendMsg(&assocCb->sockFd, &assocCb->destIpNetAddr, assocCb->destPort, &memInfo, mBuf, &len, 0, \ + FALSE, 0, 0/*SCT_PROTID_NONE*/, RWOULDBLOCK); + + if(ret != ROK && ret != RWOULDBLOCK) + { + DU_LOG("\nERROR --> SCTP : Send message failed"); + return RFAILED; + } + return ROK; +} + /******************************************************************* * * @brief Send message on SCTP socket @@ -649,27 +685,16 @@ uint8_t processPolling(sctpSockPollParams *pollParams, CuSctpAssocCb *assocCb, u * ****************************************************************/ uint8_t sctpSend(InterfaceType intf, uint32_t destId, Buffer *mBuf) { - uint8_t ret = ROK, assocIdx = 0; - MsgLen len = 0; /* number of actually sent octets */ - CmInetMemInfo memInfo; - - memset(&memInfo , 0, sizeof(CmInetMemInfo)); - memInfo.region = CU_APP_MEM_REG; - memInfo.pool = CU_POOL; + uint8_t assocIdx = 0; for(assocIdx=0; assocIdx < sctpCb.numAssoc; assocIdx++) { if((sctpCb.assocCb[assocIdx].intf == intf) && (sctpCb.assocCb[assocIdx].destId == destId)) { - ret = cmInetSctpSendMsg(&sctpCb.assocCb[assocIdx].sockFd, &sctpCb.assocCb[assocIdx].destIpNetAddr, \ - sctpCb.assocCb[assocIdx].destPort, &memInfo, mBuf, &len, 0, FALSE, 0, 0/*SCT_PROTID_NONE*/, RWOULDBLOCK); - - if(ret != ROK && ret != RWOULDBLOCK) - { - DU_LOG("\nERROR --> SCTP : Send message failed"); - return RFAILED; - } - return ROK; + if(sendOnSctpAssoc(&sctpCb.assocCb[assocIdx], mBuf) == ROK) + return ROK; + else + break; } } DU_LOG("\nERROR --> SCTP : Dest ID [%d] at Interface [%d] not found in SCTP DestCb list. Failed to send message", destId, intf); diff --git a/src/cu_stub/cu_xnap_msg_hdl.c b/src/cu_stub/cu_xnap_msg_hdl.c new file mode 100644 index 000000000..26d7329bd --- /dev/null +++ b/src/cu_stub/cu_xnap_msg_hdl.c @@ -0,0 +1,286 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +################################################################################ +*******************************************************************************/ + +/* This file contains F1AP message handler functions */ +#include "common_def.h" +#include "cu_stub_sctp.h" +#include "cu_stub_egtp.h" +#include "OCTET_STRING.h" +#include "cu_f1ap_msg_hdl.h" +#include "cu_stub.h" + +/******************************************************************* + * + * @brief Build And send dummy Xn Setup request + * + * @details + * + * Function : BuildAndSendXnSetupReq + * + * Functionality: + * Build And send dummy Xn Setup request + * + * @params[in] + * @return void + * + ******************************************************************/ +void BuildAndSendXnSetupReq() +{ + uint8_t assocIdx = 0; + Buffer *mBuf = NULLP; + CuSctpAssocCb *assocCb = NULLP; + + for(assocIdx = 0; assocIdx < sctpCb.numAssoc; assocIdx++) + { + assocCb = &sctpCb.assocCb[assocIdx]; + if(assocCb->connUp && assocCb->intf == XN_INTERFACE && assocCb->destId == 0) + { + if(ODU_GET_MSG_BUF(1, 1, &mBuf) == ROK) + { + CMCHKPK(oduUnpackUInt8,(Data *)CU_ID, mBuf); + CMCHKPK(oduUnpackUInt8,XN_SETUP_REQ, mBuf); + ODU_PRINT_MSG(mBuf, 0,0); + if(sendOnSctpAssoc(assocCb, mBuf) != ROK) + { + DU_LOG("\nERROR --> CU_STUB: Failed to send XN setup request to peer CU"); + } + } + break; + } + } +} + +/******************************************************************* + * + * @brief Process received Xn Setup request + * + * @details + * + * Function : XNAPProcXnSetupReq + * + * Functionality: + * Fetch peer CU ID and store in assocCb + * + * @params[in] Pointer to destination Id + * Pointer to message buffer + * @return void + * + ******************************************************************/ +void XNAPProcXnSetupReq(uint32_t *destId, Buffer *mBuf) +{ + uint8_t cuId; + + DU_LOG("\nINFO --> CU STUB : Received XN Setup Request"); + CMCHKUNPK(oduPackUInt8, &(cuId), mBuf) + *destId = cuId; + + BuildAndSendXnSetupRsp(*destId); +} + +/******************************************************************* + * + * @brief Build And send dummy Xn Setup response + * + * @details + * + * Function : BuildAndSendXnSetupRsp + * + * Functionality: + * Build And send dummy Xn Setup response + * + * @params[in] + * @return void + * + ******************************************************************/ +void BuildAndSendXnSetupRsp(uint32_t destId) +{ + Buffer *mBuf = NULLP; + + if(ODU_GET_MSG_BUF(1, 1, &mBuf) == ROK) + { + CMCHKPK(oduUnpackUInt8, CU_ID, mBuf); + CMCHKPK(oduUnpackUInt8, XN_SETUP_RSP, mBuf); + if(sctpSend(XN_INTERFACE, destId, mBuf)) + { + DU_LOG("\nERROR --> CU_STUB: Failed to send XN setup response to peer CU"); + } + } +} + +/******************************************************************* + * + * @brief Process received Xn Setup response + * + * @details + * + * Function : XNAPProcXnSetupRsp + * + * Functionality: + * Fetch peer CU ID and store in assocCb + * + * @params[in] Pointer to destination Id + * Pointer to message buffer + * @return void + * + ******************************************************************/ +void XNAPProcXnSetupRsp(uint32_t *destId, Buffer *mBuf) +{ + uint8_t cuId; + + DU_LOG("\nINFO --> CU STUB : Received XN Setup Response"); + CMCHKUNPK(oduPackUInt8, &(cuId), mBuf) + *destId = cuId; +} + +/******************************************************************* + * + * @brief Build And send dummy Handover request to Peer CU + * + * @details + * + * Function : BuildAndSendHOReq + * + * Functionality: + * Build And send dummy Handover request to Peer CU + * + * @params[in] Pointer to UE Cb + * Event type + * Message to be sent + * Message Length + * @return void + * + ******************************************************************/ +void BuildAndSendHOReq(CuUeCb *ueCb, XnEventType event, char *xnMsg, MsgLen xnMsgLen) +{ + Buffer *mBuf = NULLP; + + if(ODU_GET_MSG_BUF(1, 1, &mBuf) == ROK) + { + if(ODU_ADD_POST_MSG_MULT((Data *)xnMsg, xnMsgLen, mBuf) == ROK) + { + CMCHKPK(oduUnpackUInt8, event, mBuf); + if(sctpSend(XN_INTERFACE, ueCb->hoInfo.targetId, mBuf) != ROK) + { + DU_LOG("\nERROR --> CU_STUB: Failed to send handover request to peer CU"); + ueCb->state = UE_ACTIVE; + memset(&ueCb->hoInfo, 0, sizeof(HandoverInfo)); + } + } + } +} + +/******************************************************************* + * + * @brief Handle incoming messages at Xn interface + * + * @details + * + * Function : XNAPMsgHdlr + * + * Functionality: + * Fetch event type from message buffer and call appropriate + * handler + * + * @params[in] Pointer to destination Id + * Pointer to message buffer + * @return void + * + ******************************************************************/ +void XNAPMsgHdlr(uint32_t *destId, Buffer *mBuf) +{ + XnEventType event; + + CMCHKUNPK(oduPackUInt8, &event, mBuf); + + switch(event) + { + case XN_SETUP_REQ: + { + XNAPProcXnSetupReq(destId, mBuf); + break; + } + + case XN_SETUP_RSP: + { + XNAPProcXnSetupRsp(destId, mBuf); + break; + } + + case HO_REQ: + { + DU_LOG("\nINFO --> CU STUB : Received Handover Request at XNAP"); + +//Handling of HO Request to be added in next gerrit +#if 0 + char *recvBuf; + MsgLen copyCnt; + MsgLen recvBufLen; + F1AP_PDU_t *f1apMsg = NULLP; + asn_dec_rval_t rval; /* Decoder return value */ + F1AP_PDU_t f1apasnmsg ; + + ODU_PRINT_MSG(mBuf, 0,0); + + /* Copy mBuf into char array to decode it */ + ODU_GET_MSG_LEN(mBuf, &recvBufLen); + CU_ALLOC(recvBuf, (Size)recvBufLen); + + if(recvBuf == NULLP) + { + DU_LOG("\nERROR --> F1AP : Memory allocation failed"); + return; + } + if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, ©Cnt) != ROK) + { + DU_LOG("\nERROR --> F1AP : Failed while copying %d", copyCnt); + return; + } + + DU_LOG("\nDEBUG --> F1AP : Received flat buffer to be decoded : "); + for(i=0; i< recvBufLen; i++) + { + DU_LOG("%x",recvBuf[i]); + } + + /* Decoding flat buffer into F1AP messsage */ + f1apMsg = &f1apasnmsg; + memset(f1apMsg, 0, sizeof(F1AP_PDU_t)); + rval = aper_decode(0, &asn_DEF_F1AP_PDU, (void **)&f1apMsg, recvBuf, recvBufLen, 0, 0); + CU_FREE(recvBuf, (Size)recvBufLen); + + if(rval.code == RC_FAIL || rval.code == RC_WMORE) + { + DU_LOG("\nERROR --> F1AP : ASN decode failed"); + return; + } + DU_LOG("\n"); + xer_fprint(stdout, &asn_DEF_F1AP_PDU, f1apMsg); + + procUeContextModificationResponse(0, f1apMsg, recvBuf, recvBufLen); +#endif + break; + } + default: + DU_LOG("\nERROR --> CU_STUB : Invalid event [%d] received at XN interface", event); + break; + } +} + +/********************************************************************** + End of file + **********************************************************************/ -- 2.16.6