X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=src%2Fcu_stub%2Fcu_xnap_msg_hdl.c;h=4f5cd3b8060f3d10c58c8ae8d4d2dd69864de150;hb=49856df248fd976b4a9882ca4e650fc0bc3e4ee3;hp=26d7329bd2b34aeee76efb76f6d8606583e2c73f;hpb=ec8c7f10edacea2db18e2c0726e66169cd788d4a;p=o-du%2Fl2.git diff --git a/src/cu_stub/cu_xnap_msg_hdl.c b/src/cu_stub/cu_xnap_msg_hdl.c index 26d7329bd..4f5cd3b80 100644 --- a/src/cu_stub/cu_xnap_msg_hdl.c +++ b/src/cu_stub/cu_xnap_msg_hdl.c @@ -21,6 +21,7 @@ #include "cu_stub_sctp.h" #include "cu_stub_egtp.h" #include "OCTET_STRING.h" +#include "F1AP-PDU.h" #include "cu_f1ap_msg_hdl.h" #include "cu_stub.h" @@ -52,8 +53,8 @@ void BuildAndSendXnSetupReq() { if(ODU_GET_MSG_BUF(1, 1, &mBuf) == ROK) { - CMCHKPK(oduUnpackUInt8,(Data *)CU_ID, mBuf); - CMCHKPK(oduUnpackUInt8,XN_SETUP_REQ, mBuf); + CMCHKPK(oduPackUInt8,(Data *)CU_ID, mBuf); + CMCHKPK(oduPackUInt8,XN_SETUP_REQ, mBuf); ODU_PRINT_MSG(mBuf, 0,0); if(sendOnSctpAssoc(assocCb, mBuf) != ROK) { @@ -86,7 +87,7 @@ void XNAPProcXnSetupReq(uint32_t *destId, Buffer *mBuf) uint8_t cuId; DU_LOG("\nINFO --> CU STUB : Received XN Setup Request"); - CMCHKUNPK(oduPackUInt8, &(cuId), mBuf) + CMCHKUNPK(oduUnpackUInt8, &(cuId), mBuf) *destId = cuId; BuildAndSendXnSetupRsp(*destId); @@ -113,8 +114,8 @@ void BuildAndSendXnSetupRsp(uint32_t destId) if(ODU_GET_MSG_BUF(1, 1, &mBuf) == ROK) { - CMCHKPK(oduUnpackUInt8, CU_ID, mBuf); - CMCHKPK(oduUnpackUInt8, XN_SETUP_RSP, mBuf); + CMCHKPK(oduPackUInt8, CU_ID, mBuf); + CMCHKPK(oduPackUInt8, XN_SETUP_RSP, mBuf); if(sctpSend(XN_INTERFACE, destId, mBuf)) { DU_LOG("\nERROR --> CU_STUB: Failed to send XN setup response to peer CU"); @@ -143,7 +144,7 @@ void XNAPProcXnSetupRsp(uint32_t *destId, Buffer *mBuf) uint8_t cuId; DU_LOG("\nINFO --> CU STUB : Received XN Setup Response"); - CMCHKUNPK(oduPackUInt8, &(cuId), mBuf) + CMCHKUNPK(oduUnpackUInt8, &(cuId), mBuf) *destId = cuId; } @@ -165,16 +166,18 @@ void XNAPProcXnSetupRsp(uint32_t *destId, Buffer *mBuf) * @return void * ******************************************************************/ -void BuildAndSendHOReq(CuUeCb *ueCb, XnEventType event, char *xnMsg, MsgLen xnMsgLen) +void BuildAndSendHOReq(CuUeCb *ueCb, 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) + { + CMCHKPK(oduPackUInt8, ueCb->hoInfo.cuUeF1apIdSrc, mBuf); + CMCHKPK(oduPackUInt32, ueCb->hoInfo.tgtCellId, mBuf); + CMCHKPK(oduPackUInt8, HO_REQ, mBuf); + if(sctpSend(XN_INTERFACE, ueCb->hoInfo.tgtNodeId, mBuf) != ROK) { DU_LOG("\nERROR --> CU_STUB: Failed to send handover request to peer CU"); ueCb->state = UE_ACTIVE; @@ -184,6 +187,303 @@ void BuildAndSendHOReq(CuUeCb *ueCb, XnEventType event, char *xnMsg, MsgLen xnMs } } +/******************************************************************* + * + * @brief Process received Handover Request + * + * @details + * + * Function : XNAPProcHandoverReq + * + * Functionality: + * 1. Unpack Cell Id from msg and find DU to which it belongs + * 2. Create UE context for UE in handover and store in DU DB + * 3. Decode the F1AP UE context modification msg received in + * XNAP message buffer and extract UE configurations + * 4. Send UE context setup request to DU with these configs + * + * @params[in] Pointer to destination Id + * Pointer to message buffer + * @return void + * + ******************************************************************/ +void XNAPProcHandoverReq(uint32_t destId, Buffer *mBuf) +{ + uint8_t duIdx, cellIdx; + uint8_t cuUeF1apIdSrc; + uint32_t cellId; + DuDb *duDb; + CuCellCb *cellCb; + + DU_LOG("\nINFO --> CU STUB : Received Handover Request"); + + /* Find DU Db and Cell Cb from cellId */ + CMCHKUNPK(oduUnpackUInt32, &(cellId), mBuf); + for(duIdx = 0; duIdx < cuCb.numDu; duIdx++) + { + duDb = &cuCb.duInfo[duIdx]; + SEARCH_CELL_DB(cellIdx, duDb, cellId, cellCb) + if(cellCb) + break; + } + if(!cellCb) + { + DU_LOG("\nERROR --> CU_STUB: Failed to find Cell Id [%d] received in HO Request", cellId); + return; + } + + /* Fetch CU UE F1AP ID of UE in handover assigned by source CU */ + CMCHKUNPK(oduUnpackUInt8, &(cuUeF1apIdSrc), mBuf); + + /* Filling temporary UE context which will be used to create actual UE context at + * CU later */ + CU_ALLOC(duDb->tempUeCtxtInHo, sizeof(CuUeCb)); + if(!duDb->tempUeCtxtInHo) + { + DU_LOG("\nERROR --> XNAP : Failed to allocate memory to temporary UE context for UE in handover"); + return; + } + memset(duDb->tempUeCtxtInHo, 0, sizeof(CuUeCb)); + duDb->tempUeCtxtInHo->cellCb = cellCb; + duDb->tempUeCtxtInHo->gnbCuUeF1apId = ++cuCb.gnbCuUeF1apIdGenerator; + duDb->tempUeCtxtInHo->state = UE_HANDOVER_IN_PROGRESS; + duDb->tempUeCtxtInHo->hoInfo.HOType = Xn_Based_Inter_CU_HO; + duDb->tempUeCtxtInHo->hoInfo.srcNodeId = destId; + duDb->tempUeCtxtInHo->hoInfo.tgtNodeId = cuCb.cuCfgParams.cuId; + duDb->tempUeCtxtInHo->hoInfo.tgtCellId = cellId; + duDb->tempUeCtxtInHo->hoInfo.cuUeF1apIdSrc = cuUeF1apIdSrc; + duDb->tempUeCtxtInHo->hoInfo.cuUeF1apIdTgt = duDb->tempUeCtxtInHo->gnbCuUeF1apId; + + /* Decode UE context modification response msg received in Xn Msg */ + char *recvBuf; + MsgLen recvBufLen, copyLen; + F1AP_PDU_t *f1apMsg = NULLP; + F1AP_PDU_t f1apasnmsg ; + + f1apMsg = &f1apasnmsg; + memset(f1apMsg, 0, sizeof(F1AP_PDU_t)); + if(F1APDecodeMsg(f1apMsg, mBuf, &recvBuf, &recvBufLen) != ROK) + { + DU_LOG("\nERROR --> F1AP : F1AP PDU decode failed"); + return; + } + CU_FREE(recvBuf, recvBufLen); + procUeContextModificationResponse(duDb->duId, f1apMsg, NULL, 0); +} + +/******************************************************************* + * + * @brief Build And send dummy Handover request ack to Peer CU + * + * @details + * + * Function : BuildAndSendHOReqAck + * + * Functionality: + * Build And send dummy Handover request ack to Peer CU + * + * @params[in] Pointer to UE Cb + * Message to be sent + * Message Length + * @return void + * + ******************************************************************/ +void BuildAndSendHOReqAck(CuUeCb *ueCb, 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(oduPackUInt8, ueCb->gnbCuUeF1apId, mBuf); + CMCHKPK(oduPackUInt8, ueCb->hoInfo.cuUeF1apIdSrc, mBuf); + CMCHKPK(oduPackUInt8, HO_REQ_ACK, mBuf); + if(sctpSend(XN_INTERFACE, ueCb->hoInfo.srcNodeId, mBuf) != ROK) + { + DU_LOG("\nERROR --> CU_STUB: Failed to send handover request ack to peer CU"); + } + } + } +} + +/******************************************************************* + * + * @brief Process received Handover Request Ack + * + * @details + * + * Function : XNAPProcHandoverReqAck + * + * Functionality: + * 1. Unpack CU UE F1AP ID (by SCU) and fetch UE CB and + * the corresponding DU DB (SDU) + * 2. Unpack CU UE F1AP ID (by TCU) and fill in UEcb->hoInfo + * 3. Decode DU to CU RRC Container received in XNAP message + * buffer and extract UE configurations. + * 4. Send UE Context modification response to SDU conatining + * RRC Reconfig Message and command to stop transmission + * to UE in handover. + * + * @params[in] Destination Id + * Pointer to message buffer + * @return void + * + ******************************************************************/ +void XNAPProcHandoverReqAck(uint32_t destId, Buffer *mBuf) +{ + uint8_t duIdx, duId, ueIdx; + uint8_t cuUeF1apIdSrc; + uint8_t cuUeF1apIdTgt; + DuDb *duDb; + CuUeCb *ueCb; + + DU_LOG("\nINFO --> CU STUB : Received Handover Request Acknowledgement"); + + /* Fetch UE CB and DU DB in Source CU for UE under Inter-CU Handover */ + CMCHKUNPK(oduUnpackUInt8, &(cuUeF1apIdSrc), mBuf); + for(duIdx = 0; duIdx < cuCb.numDu; duIdx++) + { + for(ueIdx = 0; ueIdx < MAX_NUM_CELL * MAX_NUM_UE; ueIdx++) + { + if(cuCb.duInfo[duIdx].ueCb[ueIdx].gnbCuUeF1apId == cuUeF1apIdSrc) + { + duDb = &cuCb.duInfo[duIdx]; + ueCb = &cuCb.duInfo[duIdx].ueCb[ueIdx]; + break; + } + } + if(duDb && ueCb) + break; + } + if(!duDb || !ueCb) + { + DU_LOG("\nERROR --> CU STUB : UE CB not found for CU UE F1AP ID [%d]", cuUeF1apIdSrc); + return; + } + + /* Decode CU UE F1AP ID assigned by Target CU to UE in handover and store + * this in hoInfo block for use during future message exchange between the + * two CUs */ + CMCHKUNPK(oduUnpackUInt8, &(cuUeF1apIdTgt), mBuf); + ueCb->hoInfo.cuUeF1apIdTgt = cuUeF1apIdTgt; + + /* Decode DU to CU RRC Container received in Xn Msg */ + OCTET_STRING_t rrcCont; + MsgLen copyCnt; + + /* Copy mBuf into char array to decode it */ + memset(&rrcCont, 0, sizeof(OCTET_STRING_t)); + ODU_GET_MSG_LEN(mBuf, &rrcCont.size); + CU_ALLOC(rrcCont.buf, rrcCont.size); + if(rrcCont.buf == NULLP) + { + DU_LOG("\nERROR --> XNAP : Memory allocation failed"); + return; + } + if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, rrcCont.size, (Data *)rrcCont.buf, ©Cnt) != ROK) + { + DU_LOG("\nERROR --> F1AP : Failed while copying %d", copyCnt); + return; + } + + /* Extract DU to CU RRC container information and store in UE CB */ + extractDuToCuRrcCont(ueCb, rrcCont); + + CU_FREE(rrcCont.buf, rrcCont.size); + + /* Send UE Context Modification request after filling it using the information received in + * Xn Handover Request Ack */ + if(BuildAndSendUeContextModificationReq(duDb->duId, ueCb, STOP_DATA_TX) != ROK) + { + DU_LOG("\nERROR -> F1AP : Failed at BuildAndSendUeContextModificationReq()"); + return; + } +} + +/******************************************************************* + * + * @brief Build And send dummy UE Context Release to Peer CU + * + * @details + * + * Function : BuildAndSendUeContextRelease + * + * Functionality: + * Build And send dummy UE Context Release to Peer CU + * + * @params[in] Pointer to UE Cb + * @return void + * + ******************************************************************/ +void BuildAndSendUeContextRelease(CuUeCb *ueCb) +{ + Buffer *mBuf = NULLP; + + if(ODU_GET_MSG_BUF(1, 1, &mBuf) == ROK) + { + CMCHKPK(oduPackUInt8, ueCb->hoInfo.cuUeF1apIdSrc, mBuf); + CMCHKPK(oduPackUInt8, UE_CTXT_REL, mBuf); + if(sctpSend(XN_INTERFACE, ueCb->hoInfo.srcNodeId, mBuf) != ROK) + { + DU_LOG("\nERROR --> CU_STUB: Failed to send UE context release to peer CU"); + } + } + + return; +} + +/******************************************************************* + * @brief Process received UE Context Release + * + * @details + * + * Function : XNAPProcUeContextRel + * + * Functionality: + * 1. Unpack CU UE F1AP ID (by SCU) and fetch UE CB and + * the corresponding DU DB (SDU) + * 2. Send UE Context release command to SDU + * + * @params[in] Destination Id + * Pointer to message buffer + * @return void + * + ******************************************************************/ +void XNAPProcUeContextRel(uint32_t destId, Buffer *mBuf) +{ + uint8_t duIdx, duId, ueIdx; + uint8_t cuUeF1apIdSrc; + DuDb *duDb; + CuUeCb *ueCb; + + DU_LOG("\nINFO --> CU STUB : Received UE Context Release"); + + /* Fetch UE CB and DU DB in Source CU for UE under Inter-CU Handover */ + CMCHKUNPK(oduUnpackUInt8, &(cuUeF1apIdSrc), mBuf); + for(duIdx = 0; duIdx < cuCb.numDu; duIdx++) + { + for(ueIdx = 0; ueIdx < MAX_NUM_CELL * MAX_NUM_UE; ueIdx++) + { + if(cuCb.duInfo[duIdx].ueCb[ueIdx].gnbCuUeF1apId == cuUeF1apIdSrc) + { + duDb = &cuCb.duInfo[duIdx]; + ueCb = &duDb->ueCb[ueIdx]; + break; + } + } + if(duDb && ueCb) + break; + } + if(!duDb || !ueCb) + { + DU_LOG("\nERROR --> CU STUB : UE CB not found for CU UE F1AP ID [%d]", cuUeF1apIdSrc); + return; + } + + BuildAndSendUeContextReleaseCommand(duDb->duId, ueCb->gnbCuUeF1apId, ueCb->gnbDuUeF1apId); +} + /******************************************************************* * * @brief Handle incoming messages at Xn interface @@ -205,7 +505,7 @@ void XNAPMsgHdlr(uint32_t *destId, Buffer *mBuf) { XnEventType event; - CMCHKUNPK(oduPackUInt8, &event, mBuf); + CMCHKUNPK(oduUnpackUInt8, &event, mBuf); switch(event) { @@ -223,56 +523,18 @@ void XNAPMsgHdlr(uint32_t *destId, Buffer *mBuf) 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 + XNAPProcHandoverReq(*destId, mBuf); + break; + } + + case HO_REQ_ACK: + { + XNAPProcHandoverReqAck(*destId, mBuf); + break; + } + case UE_CTXT_REL: + { + XNAPProcUeContextRel(*destId, mBuf); break; } default: