X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=src%2Fcu_stub%2Fcu_f1ap_msg_hdl.c;h=f292045e3c8c12c5b53bb98fac2d49ca99f3e792;hb=0ba7b600f85b2975e1d60e5b8ad1523349b5f396;hp=4f2b34fe24bfc1ea8d8f96370272827e13a0f71c;hpb=f76690adc96d589ab208fbcdef906be32a5abb7d;p=o-du%2Fl2.git diff --git a/src/cu_stub/cu_f1ap_msg_hdl.c b/src/cu_stub/cu_f1ap_msg_hdl.c index 4f2b34fe2..f292045e3 100644 --- a/src/cu_stub/cu_f1ap_msg_hdl.c +++ b/src/cu_stub/cu_f1ap_msg_hdl.c @@ -130,6 +130,7 @@ #include "CNUEPagingIdentity.h" #include "PagingCell-Item.h" #include "UL-DCCH-Message.h" +#include "DRX-ConfigRrc.h" #include "cu_stub_sctp.h" #include "cu_stub_egtp.h" @@ -1513,8 +1514,27 @@ uint8_t BuildDLRRCContainer(CuUeCb *ueCb, uint8_t rrcMsgType, RRCContainer_t *rr } else if(rrcMsgType == RRC_SETUP_COMPLETE) { - DU_LOG("\nINFO --> F1AP : Sending Security mode command"); - char secModeBuf[9]={0x00, 0x02, 0x22, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00}; + DU_LOG("\nINFO --> F1AP : Sending NAS Security mode command"); + char secModeBuf[30]={0x00, 0x02, 0x2e, 0x82, 0xaf, 0xc0, 0x7d, 0x1c, 0x4e, 0xfc, 0x80, 0x0f, 0xc0, + 0x0b, 0xa0, 0x20, 0x40, 0x9e, 0x0e, 0x1e, 0x0e, 0x1c, 0x26, 0xc0, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00}; + bufLen =30; + rrcContainer->size = bufLen; + CU_ALLOC(rrcContainer->buf, rrcContainer->size); + if(rrcContainer->buf != NULLP) + { + memset(rrcContainer->buf, 0, bufLen); + memcpy(rrcContainer->buf, secModeBuf, bufLen); + } + else + { + DU_LOG("\nERROR --> F1AP : Memory allocation failure for RRC Container buffer"); + ret = RFAILED; + } + } + else if(rrcMsgType == NAS_SECURITY_MODE_COMPLETE) + { + DU_LOG("\nINFO --> F1AP : Sending RRC Security mode command"); + char secModeBuf[9]={0x00, 0x03, 0x22, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00}; bufLen =9; rrcContainer->size = bufLen; CU_ALLOC(rrcContainer->buf, rrcContainer->size); @@ -1529,11 +1549,11 @@ uint8_t BuildDLRRCContainer(CuUeCb *ueCb, uint8_t rrcMsgType, RRCContainer_t *rr ret = RFAILED; } } - else if(rrcMsgType == SECURITY_MODE_COMPLETE) + else if(rrcMsgType == RRC_SECURITY_MODE_COMPLETE) { /*Hardcoded RRC Container from reference logs*/ DU_LOG("\nINFO --> F1AP : Sending Registration accept"); - char buf[14] ={0x00, 0x03, 0x2a, 0x80, 0xaf, 0xc0, 0x08, 0x40, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00}; + char buf[14] ={0x00, 0x04, 0x2a, 0x80, 0xaf, 0xc0, 0x08, 0x40, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00}; bufLen =14; rrcContainer->size = bufLen; CU_ALLOC(rrcContainer->buf, rrcContainer->size); @@ -1767,8 +1787,11 @@ uint8_t setDlRRCMsgType(CuUeCb *ueCb) case RRC_SETUP_COMPLETE: rrcMsgType = RRC_SETUP_COMPLETE; break; - case SECURITY_MODE_COMPLETE: - rrcMsgType = SECURITY_MODE_COMPLETE; + case NAS_SECURITY_MODE_COMPLETE: + rrcMsgType = NAS_SECURITY_MODE_COMPLETE; + break; + case RRC_SECURITY_MODE_COMPLETE: + rrcMsgType = RRC_SECURITY_MODE_COMPLETE; break; case REGISTRATION_COMPLETE: rrcMsgType = REGISTRATION_COMPLETE; @@ -1785,6 +1808,190 @@ uint8_t setDlRRCMsgType(CuUeCb *ueCb) return rrcMsgType; } +#ifdef NR_DRX +/******************************************************************* + * + * @brief fill long cycle offset value of drx + * + * @details + * + * Function : fillLongCycleOffsetValue + * + * Functionality: fill long cycle offset value of drx + * + * @params[in] DrxLongCycleStartOffset drxLongCycleStartOffset, + * struct DRX_ConfigRrc__drx_LongCycleStartOffset recvedLongCycleOffsetVal + * + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +void fillLongCycleOffsetValue(DrxLongCycleStartOffset *drxLongCycleStartOffset, struct DRX_ConfigRrc__recvedLongCycleOffsetVal *recvedLongCycleOffsetVal) +{ + + drxLongCycleStartOffset->drxLongCycleStartOffsetChoice = recvedLongCycleOffsetVal->present; + switch(recvedLongCycleOffsetVal->present) + { + case DRX_ConfigRrc__recvedLongCycleOffsetVal_PR_ms10: + { + drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms10; + break; + } + case DRX_ConfigRrc__recvedLongCycleOffsetVal_PR_ms20: + { + drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms20; + break; + } + case DRX_ConfigRrc__recvedLongCycleOffsetVal_PR_ms32: + { + drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms32; + break; + } + case DRX_ConfigRrc__recvedLongCycleOffsetVal_PR_ms40: + { + drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms40; + break; + } + case DRX_ConfigRrc__recvedLongCycleOffsetVal_PR_ms60: + { + drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms60; + break; + } + case DRX_ConfigRrc__recvedLongCycleOffsetVal_PR_ms64: + { + drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms64; + break; + } + case DRX_ConfigRrc__recvedLongCycleOffsetVal_PR_ms70: + { + drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms70; + break; + } + case DRX_ConfigRrc__recvedLongCycleOffsetVal_PR_ms80: + { + drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms80; + break; + } + case DRX_ConfigRrc__recvedLongCycleOffsetVal_PR_ms128: + { + drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms128; + break; + } + case DRX_ConfigRrc__recvedLongCycleOffsetVal_PR_ms160: + { + drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms160; + break; + } + case DRX_ConfigRrc__recvedLongCycleOffsetVal_PR_ms256: + { + drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms256; + break; + } + case DRX_ConfigRrc__recvedLongCycleOffsetVal_PR_ms320: + { + drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms320; + break; + } + case DRX_ConfigRrc__recvedLongCycleOffsetVal_PR_ms512: + { + drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms512; + break; + } + case DRX_ConfigRrc__recvedLongCycleOffsetVal_PR_ms640: + { + drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms640; + break; + } + case DRX_ConfigRrc__recvedLongCycleOffsetVal_PR_ms1024: + { + drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms1024; + break; + } + case DRX_ConfigRrc__recvedLongCycleOffsetVal_PR_ms1280: + { + drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms1280; + break; + } + case DRX_ConfigRrc__recvedLongCycleOffsetVal_PR_ms2048: + { + drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms2048; + break; + } + case DRX_ConfigRrc__recvedLongCycleOffsetVal_PR_ms2560: + { + drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms2560; + break; + } + case DRX_ConfigRrc__recvedLongCycleOffsetVal_PR_ms5120: + { + drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms5120; + break; + } + case DRX_ConfigRrc__recvedLongCycleOffsetVal_PR_ms10240: + { + drxLongCycleStartOffset->drxLongCycleStartOffsetVal = recvedLongCycleOffsetVal->choice.ms10240; + break; + } + default : + break; + } +} + +/******************************************************************* + * + * @brief Extract configuration from DRX_ConfigRrc + * and store the drx configuration in UeCb + * + * @details + * + * Function : storeDrxCfgInUeCb + * + * Functionality: Store drx configuration in UeCb + * + * @params[in] (struct DRX_ConfigRrc *setup, DrxCfg *drxCfg) + * + * @return void + * ****************************************************************/ +void storeDrxCfgInUeCb(struct DRX_ConfigRrc *drxSetup, DrxCfg *drxCfg) +{ + if(drxSetup) + { + switch(drxSetup->drx_onDurationTimer.present) + { + case DRX_ConfigRrc__drx_onDurationTimer_PR_NOTHING: + break; + case DRX_ConfigRrc__drx_onDurationTimer_PR_milliSeconds: + { + drxCfg->drxOnDurationTimer.onDurationTimerValInMs = true; + drxCfg->drxOnDurationTimer.onDurationtimerValue.milliSeconds=drxSetup->drx_onDurationTimer.choice.milliSeconds; + break; + } + case DRX_ConfigRrc__drx_onDurationTimer_PR_subMilliSeconds: + { + drxCfg->drxOnDurationTimer.onDurationTimerValInMs = false; + drxCfg->drxOnDurationTimer.onDurationtimerValue.subMilliSeconds = drxSetup->drx_onDurationTimer.choice.subMilliSeconds; + break; + } + } + } + fillLongCycleOffsetValue(&drxCfg->drxLongCycleStartOffset, &drxSetup->drx_LongCycleStartOffset); + drxCfg->drxInactivityTimer = drxSetup->drx_InactivityTimer; + drxCfg->drxHarqRttTimerDl = drxSetup->drx_HARQ_RTT_TimerDL; + drxCfg->drxHarqRttTimerUl = drxSetup->drx_HARQ_RTT_TimerUL; + drxCfg->drxRetransmissionTimerDl = drxSetup->drx_RetransmissionTimerDL; + drxCfg->drxRetransmissionTimerUl = drxSetup->drx_RetransmissionTimerUL; + drxCfg->drxSlotOffset = drxSetup->drx_SlotOffset; + if(drxSetup->shortDRX) + { + drxCfg->shortDrxPres=true; + drxCfg->shortDrx.drxShortCycle = drxSetup->shortDRX->drx_ShortCycle; + drxCfg->shortDrx.drxShortCycleTimer = drxSetup->shortDRX->drx_ShortCycleTimer; + } + else + drxCfg->shortDrxPres=false; +} +#endif + /******************************************************************* * * @brief Extract configuration from CellGroupConfig @@ -1814,6 +2021,9 @@ uint8_t extractCellGroupConfig(CuUeCb *ueCb, CellGroupConfigRrc_t *cellGrpCfg) RLC_BearerConfig_t *rlcCfg = NULLP; RLC_Config_t *rlcLcCfg = NULLP; LogicalChannelConfig_t *macLcCfg = NULLP; +#ifdef NR_DRX + DrxCfg drxCfg; +#endif if(ueCb == NULLP) { @@ -1827,6 +2037,29 @@ uint8_t extractCellGroupConfig(CuUeCb *ueCb, CellGroupConfigRrc_t *cellGrpCfg) return RFAILED; } +#ifdef NR_DRX + if(cellGrpCfg->mac_CellGroupConfig) + { + if(cellGrpCfg->mac_CellGroupConfig->drx_ConfigRrc) + { + switch(cellGrpCfg->mac_CellGroupConfig->drx_ConfigRrc->present) + { + case MAC_CellGroupConfig__drx_ConfigRrc_PR_NOTHING: + break; + + case MAC_CellGroupConfig__drx_ConfigRrc_PR_setup: + { + storeDrxCfgInUeCb(cellGrpCfg->mac_CellGroupConfig->drx_ConfigRrc->choice.setup, &ueCb->drxCfg); + break; + } + + case MAC_CellGroupConfig__drx_ConfigRrc_PR_release: + break; + } + } + } +#endif + for(rbIdx = 0; rbIdx < cellGrpCfg->rlc_BearerToAddModList->list.count; rbIdx++) { srbFound = false; @@ -1964,7 +2197,7 @@ uint8_t extractDuToCuRrcCont(CuUeCb *ueCb, OCTET_STRING_t rrcCont) if(rval.code == RC_FAIL || rval.code == RC_WMORE) { - DU_LOG("\nERROR --> F1AP : ASN decode failed"); + DU_LOG("\nERROR --> F1AP : ASN decode failed in extractDuToCuRrcCont"); return RFAILED; } printf("\n"); @@ -2660,6 +2893,7 @@ uint8_t BuildULTnlInfo(uint8_t duId, TnlInfo *ulUpTnlInfo, ULUPTNLInformation_To * ****************************************************************/ uint8_t BuildDRBSetup(uint32_t duId, CuUeCb *ueCb, DRBs_ToBeSetup_List_t *drbSet) { + uint16_t snssaiIdx=0; uint8_t idx = 0, extIeIdx = 0; uint8_t elementCnt = 0, drbCnt = 0; uint8_t BuildQOSInforet = 0,BuildSNSSAIret = 0; @@ -2728,12 +2962,13 @@ uint8_t BuildDRBSetup(uint32_t duId, CuUeCb *ueCb, DRBs_ToBeSetup_List_t *drbSet } /*SNSSAI*/ + snssaiIdx = (idx% cuCb.numSnssaiSupported); if(ueCb->state != UE_HANDOVER_IN_PROGRESS) BuildSNSSAIret = BuildSNSSAI(&ueCb->drbList[ueCb->numDrb], &drbSetItem->qoSInformation.choice.\ - choice_extension->value.choice.DRB_Information.sNSSAI, cuCb.snssaiList[0], FALSE); + choice_extension->value.choice.DRB_Information.sNSSAI, cuCb.snssaiList[snssaiIdx], FALSE); else BuildSNSSAIret = BuildSNSSAI(&ueCb->drbList[idx], &drbSetItem->qoSInformation.choice.\ - choice_extension->value.choice.DRB_Information.sNSSAI, cuCb.snssaiList[0], TRUE); + choice_extension->value.choice.DRB_Information.sNSSAI, NULLP, TRUE); if(BuildSNSSAIret != ROK) { DU_LOG("\nERROR --> F1AP : Failed to build SNSSAI Info in BuildDRBSetup"); @@ -5268,7 +5503,7 @@ uint8_t BuildSchedulingReqConfig(struct SchedulingRequestConfig *schedulingReque * ****************************************************************/ uint8_t BuildMacCellGrpCfg(MAC_CellGroupConfig_t *macCellGrpCfg) { - macCellGrpCfg->drx_Config = NULLP; + macCellGrpCfg->drx_ConfigRrc = NULLP; macCellGrpCfg->schedulingRequestConfig = NULLP; CU_ALLOC(macCellGrpCfg->schedulingRequestConfig, sizeof(struct SchedulingRequestConfig)); if(!macCellGrpCfg->schedulingRequestConfig) @@ -8739,7 +8974,7 @@ uint8_t fillCuToDuContainer(CuUeCb *ueCb, CUtoDURRCInformation_t *rrcMsg) { uint8_t elementCnt = 0; uint8_t ret = ROK; - uint8_t idx, idx2, rrcBufLen; + uint8_t idx; /* UE Capabulity RAT Container List */ CU_ALLOC(rrcMsg->uE_CapabilityRAT_ContainerList, sizeof(UE_CapabilityRAT_ContainerList_t)); @@ -8807,7 +9042,42 @@ uint8_t fillCuToDuContainer(CuUeCb *ueCb, CUtoDURRCInformation_t *rrcMsg) } return ret; } - +/******************************************************************* + * + * @brief Build the drx cycle + * + * @details + * + * Function : BuildDrxCycle + * + * Functionality: Build drx cycle IE + * + * @params[in] pointer to DRXCycle_t + * + * @return ROK - success + * RFAILED - failure + * + ******************************************************************/ +uint8_t BuildDrxCycle(DRXCycle_t *drxCycle) +{ + drxCycle->longDRXCycleLength = LongDRXCycleLength_ms40; + CU_ALLOC(drxCycle->shortDRXCycleLength, sizeof(ShortDRXCycleLength_t)); + if(!drxCycle->shortDRXCycleLength) + { + DU_LOG("\nERROR --> F1AP : Memory allocation failed for shortDRXCycleLength"); + return RFAILED; + } + *(drxCycle->shortDRXCycleLength) = ShortDRXCycleLength_ms4; + + CU_ALLOC(drxCycle->shortDRXCycleTimer, sizeof(ShortDRXCycleTimer_t)); + if(!drxCycle->shortDRXCycleTimer) + { + DU_LOG("\nERROR --> F1AP : Memory allocation failed for shortDRXCycleTimer"); + return RFAILED; + } + *(drxCycle->shortDRXCycleTimer) = 4; + return ROK; +} /******************************************************************* * * @brief Free CuToDuContainer @@ -8930,7 +9200,13 @@ uint8_t BuildAndSendUeContextSetupReq(uint32_t duId, CuUeCb *ueCb) if(ueCb->state == UE_HANDOVER_IN_PROGRESS) elementCnt = 7; else + { +#ifdef NR_DRX + elementCnt = 12; +#else elementCnt = 11; +#endif + } ueSetReq->protocolIEs.list.count = elementCnt; ueSetReq->protocolIEs.list.size = elementCnt * sizeof(UEContextSetupRequestIEs_t *); @@ -9020,6 +9296,18 @@ uint8_t BuildAndSendUeContextSetupReq(uint32_t duId, CuUeCb *ueCb) if(ueCb->state != UE_HANDOVER_IN_PROGRESS) { + /*Drx cycle*/ +#ifdef NR_DRX + idx++; + ueSetReq->protocolIEs.list.array[idx]->id = ProtocolIE_ID_id_DRXCycle; + ueSetReq->protocolIEs.list.array[idx]->criticality = Criticality_ignore; + ueSetReq->protocolIEs.list.array[idx]->value.present = UEContextSetupRequestIEs__value_PR_DRXCycle; + if(BuildDrxCycle(&ueSetReq->protocolIEs.list.array[idx]->value.choice.DRXCycle) != ROK) + { + DU_LOG("\nERROR --> F1AP : Failed to build drx cycle"); + break; + } +#endif /*Special Cells to be SetupList*/ idx++; ueSetReq->protocolIEs.list.array[idx]->id = ProtocolIE_ID_id_SCell_ToBeSetup_List; @@ -9212,9 +9500,9 @@ uint8_t addDrbTunnels(uint32_t duId, uint8_t teId) * RFAILED - failure * * ****************************************************************/ -uint8_t procDrbSetupList(uint32_t duId, DRBs_Setup_List_t *drbSetupList) +uint8_t procDrbSetupList(uint32_t duId, CuUeCb *ueCb, DRBs_Setup_List_t *drbSetupList) { - uint8_t arrIdx = 0; + uint8_t arrIdx = 0, drbIdx = 0; uint32_t teId = 0; DRBs_Setup_ItemIEs_t *drbItemIe = NULLP; @@ -9229,10 +9517,21 @@ uint8_t procDrbSetupList(uint32_t duId, DRBs_Setup_List_t *drbSetupList) teId = extractTeId(&drbItemIe->value.choice.DRBs_Setup_Item.dLUPTNLInformation_ToBeSetup_List); if(teId > 0) { - if(addDrbTunnels(duId, teId)== ROK) - { - DU_LOG("\nDEBUG --> EGTP: Tunnel Added for TeId %d", teId); - } + if(addDrbTunnels(duId, teId)== ROK) + { + DU_LOG("\nDEBUG --> EGTP: Tunnel Added for TeId %d", teId); + } + /* As per Spec 38.473, in UE COntext Response, Tunnel information + * are sent to CU for setting up of Tunnels in DL direction. + * Search for DRB ID in CU databse */ + for(drbIdx = 0; drbIdx < ueCb->numDrb; drbIdx++) + { + if(ueCb->drbList[drbIdx].drbId == drbItemIe->value.choice.DRBs_Setup_Item.dRBID) + { + fillTeIdString(3, teId, ueCb->drbList[drbIdx].dlUpTnlInfo.teId); + break; + } + } } else return RFAILED; @@ -9309,7 +9608,7 @@ uint8_t procUeContextSetupResponse(uint32_t duId, F1AP_PDU_t *f1apMsg) case ProtocolIE_ID_id_DRBs_Setup_List: { /* Adding Tunnels for successful DRB */ - procDrbSetupList(duId, &ueCtxtSetupRsp->protocolIEs.list.array[idx]->value.choice.DRBs_Setup_List); + procDrbSetupList(duId, ueCb, &ueCtxtSetupRsp->protocolIEs.list.array[idx]->value.choice.DRBs_Setup_List); break; } case ProtocolIE_ID_id_DUtoCURRCInformation: @@ -9411,12 +9710,12 @@ uint8_t procUeContextSetupResponse(uint32_t duId, F1AP_PDU_t *f1apMsg) uint8_t procUlRrcMsg(uint32_t duId, F1AP_PDU_t *f1apMsg) { - uint8_t idx, ret, srbId, rrcMsgType, duIdx=0; - uint8_t cuUeF1apId, duUeF1apId; - uint8_t *rrcContainer = NULLP; - uint16_t rrcContLen; - DuDb *duDb; - CuUeCb *ueCb; + uint8_t idx = 0, ret = ROK, srbId = 0, rrcMsgType = 0, duIdx=0; + uint8_t *rrcContainer = NULLP; + uint16_t rrcContLen = 0; + uint32_t cuUeF1apId = 0, duUeF1apId = 0; + DuDb *duDb = NULLP; + CuUeCb *ueCb = NULLP; ULRRCMessageTransfer_t *ulRrcMsg = NULLP; ret = ROK; @@ -9453,8 +9752,32 @@ uint8_t procUlRrcMsg(uint32_t duId, F1AP_PDU_t *f1apMsg) memcpy(rrcContainer, ulRrcMsg->protocolIEs.list.array[idx]->value.choice.RRCContainer.buf, rrcContLen); if(duDb->ueCb[duUeF1apId-1].state == UE_HANDOVER_IN_PROGRESS) - return; - + { + uint8_t ueIdx = 0; + uint8_t srcDuId = duDb->ueCb[duUeF1apId-1].hoInfo.sourceDuId; + DuDb *srcDuDb = NULLP; + + /* In target DU DB, mark UE as active and delete HO info */ + duDb->ueCb[duUeF1apId-1].state = UE_ACTIVE; + memset(&duDb->ueCb[duUeF1apId-1].hoInfo, 0, sizeof(HandoverInfo)); + + /* Release UE context in source DU because the UE is now + * attached to target DU */ + SEARCH_DU_DB(duIdx, srcDuId, srcDuDb); + for(ueIdx = 0; ueIdx < srcDuDb->numUe; ueIdx++) + { + if(srcDuDb->ueCb[ueIdx].gnbCuUeF1apId == cuUeF1apId) + { + ret = BuildAndSendUeContextReleaseCommand(srcDuId, srcDuDb->ueCb[ueIdx].gnbCuUeF1apId, srcDuDb->ueCb[ueIdx].gnbDuUeF1apId); + if(ret != ROK) + { + DU_LOG("\nINFO --> F1AP: Failed to build and send UE context release command to source DU Id [%d]", srcDuId); + } + break; + } + } + return ret; + } break; } @@ -9471,10 +9794,15 @@ uint8_t procUlRrcMsg(uint32_t duId, F1AP_PDU_t *f1apMsg) rrcMsgType = setDlRRCMsgType(ueCb); if(rrcMsgType == RRC_SETUP_COMPLETE) { - DU_LOG("\nINFO --> F1AP: Sending DL RRC MSG for Security Mode Command"); + DU_LOG("\nINFO --> F1AP: Sending DL RRC MSG for NAS Security Mode Command"); + ret = BuildAndSendDLRRCMessageTransfer(duId, ueCb, srbId, rrcMsgType); + } + if(rrcMsgType == NAS_SECURITY_MODE_COMPLETE) + { + DU_LOG("\nINFO --> F1AP: Sending DL RRC MSG for RRC Security Mode Command"); ret = BuildAndSendDLRRCMessageTransfer(duId, ueCb, srbId, rrcMsgType); } - else if(rrcMsgType == SECURITY_MODE_COMPLETE) + else if(rrcMsgType == RRC_SECURITY_MODE_COMPLETE) { DU_LOG("\nINFO --> F1AP: Sending DL RRC MSG for RRC Registration Accept"); BuildAndSendDLRRCMessageTransfer(duId, ueCb, srbId, rrcMsgType); @@ -11480,13 +11808,11 @@ void procF1SetupReq(uint32_t *destDuId, F1AP_PDU_t *f1apMsg) if(duDb == NULLP) { duDb = &cuCb.duInfo[cuCb.numDu]; - memset(duDb, 0, sizeof(DuDb)); - duDb->duId = duId; cuCb.numDu++; - *destDuId = duId; } - else - return; + memset(duDb, 0, sizeof(DuDb)); + duDb->duId = duId; + *destDuId = duId; break; } case ProtocolIE_ID_id_gNB_DU_Name: @@ -11557,7 +11883,7 @@ void procF1SetupReq(uint32_t *destDuId, F1AP_PDU_t *f1apMsg) * ****************************************************************/ void procUeContextReleaseComplete(uint32_t duId, F1AP_PDU_t *f1apMsg) { - uint8_t duIdx = 0, ieIdx = 0, ueIdx = 0; + uint8_t duIdx = 0, ieIdx = 0, ueIdx = 0, drbIdx = 0; uint8_t gnbDuUeF1apId = 0, gnbCuUeF1apId = 0; DuDb *duDb = NULLP; CuUeCb *ueCb = NULLP; @@ -11591,6 +11917,10 @@ void procUeContextReleaseComplete(uint32_t duId, F1AP_PDU_t *f1apMsg) if((ueCb->cellCb->ueCb[ueIdx]->gnbCuUeF1apId == gnbCuUeF1apId) && (ueCb->cellCb->ueCb[ueIdx]->gnbDuUeF1apId == gnbDuUeF1apId)) { + for(drbIdx = 0; drbIdx < ueCb->numDrb; drbIdx++) + { + deleteEgtpTunnel(duId, ueCb->drbList[drbIdx].dlUpTnlInfo.teId); + } ueCb->cellCb->ueCb[ueIdx] = NULLP; ueCb->cellCb->numUe--; if((ueCb->cellCb->numUe == 0) && (ueCb->cellCb->cellStatus == CELL_DELETION_IN_PROGRESS))