From edf809241b22901ebf97d741f08cd4d5a8f0f81d Mon Sep 17 00:00:00 2001 From: "lal.harshita" Date: Thu, 20 Apr 2023 19:37:56 +0530 Subject: [PATCH] Epic-ID: ODUHIGH-463][Task-ID: ODUHIGH-504]Dummy Handover Request/Response and UE context setup at target GNB Change-Id: I4813a36690fe4a9895074f3821f2533f36f87a57 Signed-off-by: lal.harshita --- src/cm/common_def.c | 2 +- src/cm/common_def.h | 1 + src/cu_stub/cu_f1ap_msg_hdl.c | 367 +++++++++++++++++++++++++----------------- src/cu_stub/cu_stub.c | 33 ++-- src/cu_stub/cu_stub.h | 11 +- src/cu_stub/cu_xnap_msg_hdl.c | 216 ++++++++++++++++++------- 6 files changed, 413 insertions(+), 217 deletions(-) diff --git a/src/cm/common_def.c b/src/cm/common_def.c index 11d80b2d7..4b974c3b5 100644 --- a/src/cm/common_def.c +++ b/src/cm/common_def.c @@ -484,7 +484,7 @@ uint32_t convertFreqToArfcn(uint32_t freq) for(indexTable = 0; indexTable < 3; indexTable++) { - if(freq < arfcnFreqTable[indexTable][0]) + if(freq < (arfcnFreqTable[indexTable][0] * 1000)) { arfcn = arfcnFreqTable[indexTable][3] + ((freq - (arfcnFreqTable[indexTable][2] * 1000)) / (arfcnFreqTable[indexTable][1])); return (arfcn); diff --git a/src/cm/common_def.h b/src/cm/common_def.h index 1bdb4a118..c58d28afb 100644 --- a/src/cm/common_def.h +++ b/src/cm/common_def.h @@ -145,6 +145,7 @@ #define ODU_PRINT_MSG SPrntMsg #define ODU_REM_PRE_MSG SRemPreMsg #define ODU_REM_PRE_MSG_MULT SRemPreMsgMult +#define ODU_REM_POST_MSG_MULT SRemPstMsgMult #define ODU_REG_TMR_MT SRegTmrMt #define ODU_SEGMENT_MSG SSegMsg #define ODU_CAT_MSG SCatMsg diff --git a/src/cu_stub/cu_f1ap_msg_hdl.c b/src/cu_stub/cu_f1ap_msg_hdl.c index 601637b33..a40b86535 100644 --- a/src/cu_stub/cu_f1ap_msg_hdl.c +++ b/src/cu_stub/cu_f1ap_msg_hdl.c @@ -2566,9 +2566,9 @@ uint8_t BuildQOSInfo(QosInfo *qosInfo, QoSFlowLevelQoSParameters_t *drbQos, uint return RFAILED; } - if(hoInProgress) + if(hoInProgress == Inter_DU_HO) drbQos->qoS_Characteristics.choice.non_Dynamic_5QI->fiveQI = qosInfo->nonDynFiveQI ; - else + else if(hoInProgress == false || hoInProgress == Xn_Based_Inter_CU_HO) { /*FiveQI*/ if(actionType == ProtocolIE_ID_id_DRBs_ToBeModified_Item) @@ -2607,7 +2607,7 @@ uint8_t BuildQOSInfo(QosInfo *qosInfo, QoSFlowLevelQoSParameters_t *drbQos, uint drbQos->nGRANallocationRetentionPriority.pre_emptionCapability = qosInfo->preemptionCapability; drbQos->nGRANallocationRetentionPriority.pre_emptionVulnerability = qosInfo->preemptionVulnerability; } - else + else if((hoInProgress == false) || (hoInProgress == Xn_Based_Inter_CU_HO)) { drbQos->nGRANallocationRetentionPriority.priorityLevel = PriorityLevel_lowest; drbQos->nGRANallocationRetentionPriority.pre_emptionCapability = Pre_emptionCapability_may_trigger_pre_emption; @@ -2693,6 +2693,12 @@ uint8_t BuildQOSInfo(QosInfo *qosInfo, QoSFlowLevelQoSParameters_t *drbQos, uint uint8_t BuildSNSSAI(DrbInfo *drbInfo, SNSSAI_t *snssai, Snssai *snssaiToCopy, bool hoInProgress) { /*SNSSAI*/ + /* In case of non-HO UE context creation and Xn Based HO, DRB's SNSSAI + * configuration is not known beforehand. In these 2 case, the following + * condition will hit */ + if(!hoInProgress || (hoInProgress == Xn_Based_Inter_CU_HO)) + drbInfo->snssai = snssaiToCopy; + /*ssT*/ snssai->sST.size = sizeof(uint8_t); CU_ALLOC(snssai->sST.buf, snssai->sST.size); @@ -2700,10 +2706,7 @@ uint8_t BuildSNSSAI(DrbInfo *drbInfo, SNSSAI_t *snssai, Snssai *snssaiToCopy, bo { return RFAILED; } - if(!hoInProgress) - memcpy(snssai->sST.buf, &snssaiToCopy->sst, snssai->sST.size); - else - memcpy(snssai->sST.buf, &drbInfo->snssai->sst, snssai->sST.size); + memcpy(snssai->sST.buf, &drbInfo->snssai->sst, snssai->sST.size); /*sD*/ CU_ALLOC(snssai->sD, sizeof(OCTET_STRING_t)); @@ -2717,13 +2720,8 @@ uint8_t BuildSNSSAI(DrbInfo *drbInfo, SNSSAI_t *snssai, Snssai *snssaiToCopy, bo { return RFAILED; } - if(!hoInProgress) - memcpy(snssai->sD->buf, snssaiToCopy->sd, snssai->sD->size); - else - memcpy(snssai->sD->buf, drbInfo->snssai->sd, snssai->sD->size); + memcpy(snssai->sD->buf, drbInfo->snssai->sd, snssai->sD->size); - if(!hoInProgress) - drbInfo->snssai = snssaiToCopy; return ROK; }/*End of BuildSNSSAI*/ @@ -2748,10 +2746,14 @@ uint8_t BuildFlowsMap(DrbInfo *drbInfo, Flows_Mapped_To_DRB_List_t *flowMap , ui uint8_t ret = ROK, idx = 0, flowCnt = 0, flowIdx = 0; FlowsMapped *qosFlow; - if(!hoInProgress) + /* In case of non-HO UE context creation and Xn Based HO, DRB's SNSSAI + * configuration is not known beforehand. In these 2 case, the following + * condition will hit */ + if(!hoInProgress || (hoInProgress == Xn_Based_Inter_CU_HO)) flowCnt = 1; else flowCnt = drbInfo->numFlowMap; + flowMap->list.count = flowCnt; flowMap->list.size = flowCnt * sizeof(Flows_Mapped_To_DRB_Item_t *); CU_ALLOC(flowMap->list.array,flowMap->list.size); @@ -2769,7 +2771,7 @@ uint8_t BuildFlowsMap(DrbInfo *drbInfo, Flows_Mapped_To_DRB_List_t *flowMap , ui return RFAILED; } - if(!hoInProgress) + if(!hoInProgress || (hoInProgress == Xn_Based_Inter_CU_HO)) { flowMap->list.array[idx]->qoSFlowIdentifier = 0; if(actionType == ProtocolIE_ID_id_DRBs_ToBeModified_Item) @@ -2803,7 +2805,7 @@ uint8_t BuildFlowsMap(DrbInfo *drbInfo, Flows_Mapped_To_DRB_List_t *flowMap , ui return RFAILED; } - if((!hoInProgress) && (actionType != ProtocolIE_ID_id_DRBs_ToBeModified_Item)) + if(((!hoInProgress) && (actionType != ProtocolIE_ID_id_DRBs_ToBeModified_Item)) || (hoInProgress == Xn_Based_Inter_CU_HO)) drbInfo->numFlowMap++; } return ROK; @@ -2866,7 +2868,7 @@ uint8_t BuildULTnlInfo(uint8_t duId, TnlInfo *ulUpTnlInfo, ULUPTNLInformation_To return RFAILED; } - if(!hoInProgress) + if((!hoInProgress) || (hoInProgress == Xn_Based_Inter_CU_HO)) { /* NOTE: Below IP address must be changed if running on different IP configuration */ ulInfo->list.array[idx]->uLUPTNLInformation.choice.gTPTunnel->transportLayerAddress.buf[0] = 192; @@ -2899,7 +2901,7 @@ uint8_t BuildULTnlInfo(uint8_t duId, TnlInfo *ulUpTnlInfo, ULUPTNLInformation_To return RFAILED; } - if(!hoInProgress) + if((!hoInProgress) || (hoInProgress == Xn_Based_Inter_CU_HO)) { ulInfo->list.array[idx]->uLUPTNLInformation.choice.gTPTunnel->gTP_TEID.buf[0] = 0; ulInfo->list.array[idx]->uLUPTNLInformation.choice.gTPTunnel->gTP_TEID.buf[1] = 0; @@ -3000,7 +3002,7 @@ uint8_t BuildDRBSetup(uint32_t duId, CuUeCb *ueCb, DRBs_ToBeSetup_List_t *drbSet choice_extension->value.choice.DRB_Information.dRB_QoS, ProtocolIE_ID_id_DRBs_ToBeSetup_Item, PDU_SESSION_ID_1, FALSE); else BuildQOSInforet = BuildQOSInfo(&ueCb->drbList[idx].qos, &drbSetItem->qoSInformation.choice.\ - choice_extension->value.choice.DRB_Information.dRB_QoS, ProtocolIE_ID_id_DRBs_ToBeSetup_Item, PDU_SESSION_ID_1, TRUE); + choice_extension->value.choice.DRB_Information.dRB_QoS, ProtocolIE_ID_id_DRBs_ToBeSetup_Item, PDU_SESSION_ID_1, ueCb->hoInfo.HOType); if(BuildQOSInforet != ROK) { DU_LOG("\nERROR --> F1AP : Failed to build QOS Info in BuildDRBSetup"); @@ -3014,7 +3016,7 @@ uint8_t BuildDRBSetup(uint32_t duId, CuUeCb *ueCb, DRBs_ToBeSetup_List_t *drbSet 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, NULLP, TRUE); + choice_extension->value.choice.DRB_Information.sNSSAI, cuCb.snssaiList[snssaiIdx], ueCb->hoInfo.HOType); if(BuildSNSSAIret != ROK) { DU_LOG("\nERROR --> F1AP : Failed to build SNSSAI Info in BuildDRBSetup"); @@ -3027,7 +3029,7 @@ uint8_t BuildDRBSetup(uint32_t duId, CuUeCb *ueCb, DRBs_ToBeSetup_List_t *drbSet value.choice.DRB_Information.flows_Mapped_To_DRB_List, ProtocolIE_ID_id_DRBs_ToBeSetup_Item, FALSE); else BuildFlowsMapret = BuildFlowsMap(&ueCb->drbList[idx], &drbSetItem->qoSInformation.choice.choice_extension->\ - value.choice.DRB_Information.flows_Mapped_To_DRB_List, ProtocolIE_ID_id_DRBs_ToBeSetup_Item, TRUE); + value.choice.DRB_Information.flows_Mapped_To_DRB_List, ProtocolIE_ID_id_DRBs_ToBeSetup_Item, ueCb->hoInfo.HOType); if(BuildFlowsMapret != ROK) { DU_LOG("\nERROR --> F1AP : Failed to build Flow Map Info in BuildDRBSetup"); @@ -3040,7 +3042,7 @@ uint8_t BuildDRBSetup(uint32_t duId, CuUeCb *ueCb, DRBs_ToBeSetup_List_t *drbSet FALSE); else BuildULTnlInforet = BuildULTnlInfo(duId, &ueCb->drbList[idx].ulUpTnlInfo, &drbSetItem->uLUPTNLInformation_ToBeSetup_List,\ - TRUE); + ueCb->hoInfo.HOType); if(BuildULTnlInforet != ROK) { DU_LOG("\nERROR --> F1AP : Failed to build tunnel Info in BuildDRBSetup"); @@ -3048,7 +3050,7 @@ uint8_t BuildDRBSetup(uint32_t duId, CuUeCb *ueCb, DRBs_ToBeSetup_List_t *drbSet } /*RLCMode*/ - if(ueCb->state != UE_HANDOVER_IN_PROGRESS) + if((ueCb->state != UE_HANDOVER_IN_PROGRESS) || (ueCb->hoInfo.HOType == Xn_Based_Inter_CU_HO)) { drbSetItem->rLCMode = RLCMode_rlc_um_bidirectional; ueCb->drbList[ueCb->numDrb].rlcMode = drbSetItem->rLCMode; @@ -9228,6 +9230,7 @@ uint8_t BuildAndSendUeContextSetupReq(uint32_t duId, CuUeCb *ueCb) uint8_t elementCnt; uint8_t idx, idx1, bufLen, duIdx; uint32_t spCellId; + uint32_t targetDuId; DuDb *targetDuDb = NULLP; F1AP_PDU_t *f1apMsg = NULLP; UEContextSetupRequest_t *ueSetReq = NULLP; @@ -9313,16 +9316,23 @@ uint8_t BuildAndSendUeContextSetupReq(uint32_t duId, CuUeCb *ueCb) ueSetReq->protocolIEs.list.array[idx]->id = ProtocolIE_ID_id_SpCell_ID; ueSetReq->protocolIEs.list.array[idx]->criticality = Criticality_reject; ueSetReq->protocolIEs.list.array[idx]->value.present = UEContextSetupRequestIEs__value_PR_NRCGI; + + /* Spec 38.473 Sec 9.2.2.1 : For handover case, this IE shall be considered as target cell. */ if(ueCb->state == UE_HANDOVER_IN_PROGRESS) { - /* Spec 38.473 Sec 9.2.2.1 : For handover case, this IE shall be considered as target cell. */ - SEARCH_DU_DB(duIdx, ueCb->hoInfo.targetId, targetDuDb); + if(ueCb->hoInfo.HOType == Inter_DU_HO) + targetDuId = ueCb->hoInfo.tgtNodeId; + else + targetDuId = duId; + + SEARCH_DU_DB(duIdx, targetDuId, targetDuDb); /* Since we are supporting only one cell per DU, accessing 0th index to * get target cell info */ spCellId = targetDuDb->cellCb[0].nrCellId; } else spCellId = ueCb->cellCb->nrCellId; + Nrcgiret = BuildNrcgi(&ueSetReq->protocolIEs.list.array[idx]->value.choice.NRCGI, spCellId); if(Nrcgiret != ROK) { @@ -9618,7 +9628,7 @@ uint8_t procDrbSetupList(uint32_t duId, CuUeCb *ueCb, DRBs_Setup_List_t *drbSetu * RFAILED - failure * * ****************************************************************/ -uint8_t procUeContextSetupResponse(uint32_t duId, F1AP_PDU_t *f1apMsg) +uint8_t procUeContextSetupResponse(uint32_t duId, F1AP_PDU_t *f1apMsg, char *recvBuf, MsgLen recvBufLen) { uint8_t duIdx = 0, idx = 0, ueIdx = 0, rrcMsgType=0; uint8_t duUeF1apId = 0, cuUeF1apId = 0; @@ -9650,11 +9660,24 @@ uint8_t procUeContextSetupResponse(uint32_t duId, F1AP_PDU_t *f1apMsg) { /* Creating UE context in target DU */ memset(ueCb, 0, sizeof(CuUeCb)); - ueCb->cellCb = &duDb->cellCb[0]; - ueCb->gnbDuUeF1apId = duUeF1apId; - ueCb->gnbCuUeF1apId = cuUeF1apId; - ueCb->state = UE_HANDOVER_IN_PROGRESS; - ueCb->hoInfo.targetId = duId; + + /* Check if UE is under Inter-CU handover */ + if(duDb->tempUeCtxtInHo && (duDb->tempUeCtxtInHo->gnbCuUeF1apId == cuUeF1apId)) + { + memcpy(ueCb, duDb->tempUeCtxtInHo, sizeof(CuUeCb)); + ueCb->gnbDuUeF1apId = duUeF1apId; + CU_FREE(duDb->tempUeCtxtInHo, sizeof(CuUeCb)); + } + else + { + /* In case of Inter DU Handover */ + ueCb->cellCb = &duDb->cellCb[0]; + ueCb->gnbDuUeF1apId = duUeF1apId; + ueCb->gnbCuUeF1apId = cuUeF1apId; + ueCb->state = UE_HANDOVER_IN_PROGRESS; + ueCb->hoInfo.HOType = Inter_DU_HO; + ueCb->hoInfo.tgtNodeId = duId; + } (duDb->numUe)++; ueCb->cellCb->ueCb[ueCb->cellCb->numUe] = ueCb; @@ -9689,65 +9712,73 @@ uint8_t procUeContextSetupResponse(uint32_t duId, F1AP_PDU_t *f1apMsg) } } - /* If the UE is in handover, UE context modification request is to be sent to - * source DU once UE context setup response is received from target DU */ - if(ueCb->state == UE_HANDOVER_IN_PROGRESS) + if(ueCb->state != UE_HANDOVER_IN_PROGRESS) { - DuDb *srcDuDb = NULLP; - CuUeCb *ueCbInSrcDu = NULLP; + ueCb->f1apMsgDb.dlRrcMsgCount++; + rrcMsgType = setDlRRCMsgType(ueCb); - /* Since Source DU Id and DU UE F1AP ID assigned to UE by source DU is not known here, we - * need to find Source DU and UE CB in source DU using CU UE F1AP ID */ - for(duIdx=0; duIdx < cuCb.numDu; duIdx++) + DU_LOG("\nINFO --> F1AP: Sending DL RRC MSG for RRC reconfiguration"); + if(BuildAndSendDLRRCMessageTransfer(duId, ueCb, SRB1, rrcMsgType) != ROK) + { + DU_LOG("\nINFO --> F1AP: Failed to build and send DL RRC MSG for RRC reconfiguration"); + return RFAILED; + } + } + else if(ueCb->state == UE_HANDOVER_IN_PROGRESS) + { + if(ueCb->hoInfo.HOType == Inter_DU_HO) { - /* UE context setup response is received from target DU. Search all - * DUs to find source DU except this target DU Id.*/ - if(cuCb.duInfo[duIdx].duId != duId) + /* If the UE is in Inter-DU handover, UE context modification request is to be sent to + * source DU once UE context setup response is received from target DU */ + + DuDb *srcDuDb = NULLP; + CuUeCb *ueCbInSrcDu = NULLP; + + /* Since Source DU Id and DU UE F1AP ID assigned to UE by source DU is not known here, we + * need to find Source DU and UE CB in source DU using CU UE F1AP ID */ + for(duIdx=0; duIdx < cuCb.numDu; duIdx++) { - for(ueIdx = 0; ueIdx < MAX_NUM_UE; ueIdx++) + /* UE context setup response is received from target DU. Search all + * DUs to find source DU except this target DU Id.*/ + if(cuCb.duInfo[duIdx].duId != duId) { - /* Check following: - * 1. CU UE F1AP ID in srcDU->ueCb should be same as cuUeF1apId - * received in UE context setup response since CU UE F1AP ID does not - * change for UE in handover. - * 2. srcDU->UeCb->uestate should be UE_HANDOVER_IN_PROGRESS - */ - if((cuCb.duInfo[duIdx].ueCb[ueIdx].gnbCuUeF1apId == cuUeF1apId) && - (cuCb.duInfo[duIdx].ueCb[ueIdx].state == UE_HANDOVER_IN_PROGRESS)) + for(ueIdx = 0; ueIdx < MAX_NUM_UE; ueIdx++) { - srcDuDb = &cuCb.duInfo[duIdx]; - ueCbInSrcDu = &cuCb.duInfo[duIdx].ueCb[ueIdx]; + /* Check following: + * 1. CU UE F1AP ID in srcDU->ueCb should be same as cuUeF1apId + * received in UE context setup response since CU UE F1AP ID does not + * change for UE in handover. + * 2. srcDU->UeCb->uestate should be UE_HANDOVER_IN_PROGRESS + */ + if((cuCb.duInfo[duIdx].ueCb[ueIdx].gnbCuUeF1apId == cuUeF1apId) && + (cuCb.duInfo[duIdx].ueCb[ueIdx].state == UE_HANDOVER_IN_PROGRESS)) + { + srcDuDb = &cuCb.duInfo[duIdx]; + ueCbInSrcDu = &cuCb.duInfo[duIdx].ueCb[ueIdx]; - /* Store source DU info in the new UE context created in - * tareget DU */ - ueCb->hoInfo.sourceId = srcDuDb->duId; + /* Store source DU info in the new UE context created in + * tareget DU */ + ueCb->hoInfo.srcNodeId = srcDuDb->duId; - /* Copy the received container to UeCb */ - memcpy(&ueCbInSrcDu->f1apMsgDb.duToCuContainer, duToCuRrcContainer, sizeof(OCTET_STRING_t)); + /* Copy the received container to UeCb */ + memcpy(&ueCbInSrcDu->f1apMsgDb.duToCuContainer, duToCuRrcContainer, sizeof(OCTET_STRING_t)); - if(BuildAndSendUeContextModificationReq(srcDuDb->duId, ueCbInSrcDu, STOP_DATA_TX) != ROK) - { - DU_LOG("\nERROR -> F1AP : Failed at BuildAndSendUeContextModificationReq()"); - return RFAILED; + if(BuildAndSendUeContextModificationReq(srcDuDb->duId, ueCbInSrcDu, STOP_DATA_TX) != ROK) + { + DU_LOG("\nERROR -> F1AP : Failed at BuildAndSendUeContextModificationReq()"); + return RFAILED; + } + break; } - break; } } + if(srcDuDb && ueCbInSrcDu) + break; } - if(srcDuDb && ueCbInSrcDu) - break; } - } - else - { - ueCb->f1apMsgDb.dlRrcMsgCount++; - rrcMsgType = setDlRRCMsgType(ueCb); - - DU_LOG("\nINFO --> F1AP: Sending DL RRC MSG for RRC reconfiguration"); - if(BuildAndSendDLRRCMessageTransfer(duId, ueCb, SRB1, rrcMsgType) != ROK) + else if(ueCb->hoInfo.HOType == Xn_Based_Inter_CU_HO) { - DU_LOG("\nINFO --> F1AP: Failed to build and send DL RRC MSG for RRC reconfiguration"); - return RFAILED; + BuildAndSendHOReqAck(ueCb, recvBuf, recvBufLen); } } @@ -9816,7 +9847,7 @@ uint8_t procUlRrcMsg(uint32_t duId, F1AP_PDU_t *f1apMsg) if(duDb->ueCb[duUeF1apId-1].state == UE_HANDOVER_IN_PROGRESS) { uint8_t ueIdx = 0; - uint8_t srcDuId = duDb->ueCb[duUeF1apId-1].hoInfo.sourceId; + uint8_t srcDuId = duDb->ueCb[duUeF1apId-1].hoInfo.srcNodeId; DuDb *srcDuDb = NULLP; /* In target DU DB, mark UE as active and delete HO info */ @@ -11806,17 +11837,17 @@ uint8_t procDrbSetupModList(uint32_t duId, CuUeCb *ueCb, DRBs_SetupMod_List_t *d if(ueCb->state != UE_HANDOVER_IN_PROGRESS) { - /* extracting teId */ - teId = extractTeId(&drbItemIe->value.choice.DRBs_SetupMod_Item.dLUPTNLInformation_ToBeSetup_List); - if(teId > 0) - { - if(addDrbTunnels(duId, teId)== ROK) - { - DU_LOG("\nDEBUG --> EGTP: Tunnel Added for TeId %d", teId); - } - } - else - return RFAILED; + /* extracting teId */ + teId = extractTeId(&drbItemIe->value.choice.DRBs_SetupMod_Item.dLUPTNLInformation_ToBeSetup_List); + if(teId > 0) + { + if(addDrbTunnels(duId, teId)== ROK) + { + DU_LOG("\nDEBUG --> EGTP: Tunnel Added for TeId %d", teId); + } + } + else + return RFAILED; } } } @@ -11908,6 +11939,10 @@ uint8_t procUeContextModificationResponse(uint32_t duId, F1AP_PDU_t *f1apMsg, ch SEARCH_DU_DB(duIdx, duId, duDb); ueCtxtModRsp = &f1apMsg->choice.successfulOutcome->value.choice.UEContextModificationResponse; + + /* In case of Inter-CU Handover request received from peer CU */ + if(duDb->tempUeCtxtInHo) + ueCb = duDb->tempUeCtxtInHo; for(idx=0; idx < ueCtxtModRsp->protocolIEs.list.count; idx++) { @@ -11915,17 +11950,28 @@ uint8_t procUeContextModificationResponse(uint32_t duId, F1AP_PDU_t *f1apMsg, ch { case ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID: { - cuUeF1apId = ueCtxtModRsp->protocolIEs.list.array[idx]->value.choice.GNB_CU_UE_F1AP_ID; + if(ueCb == NULLP) + { + cuUeF1apId = ueCtxtModRsp->protocolIEs.list.array[idx]->value.choice.GNB_CU_UE_F1AP_ID; + } + else + { + /* In case of Inter-CU Handover request received from peer CU */ + cuUeF1apId = ueCb->gnbCuUeF1apId; + } break; } case ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID: { - 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)) + if(!ueCb) { - BuildAndSendHOReq(ueCb, HO_REQ, recvBuf, recvBufLen); + 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, recvBuf, recvBufLen); + } } break; } @@ -11965,41 +12011,48 @@ uint8_t procUeContextModificationResponse(uint32_t duId, F1AP_PDU_t *f1apMsg, ch * UE context setup request to target DU */ if(ueCb->state == UE_HANDOVER_IN_PROGRESS) { + uint8_t ueIdx = 0; + uint8_t tgtDuId = 0; + DuDb *tgtDuDb = NULLP; + CuUeCb *ueCbInTgtDu = NULLP; + if(ueCb->hoInfo.HOType == Inter_DU_HO) { - uint8_t ueIdx = 0; - DuDb *tgtDuDb = NULLP; - CuUeCb *ueCbInTgtDu = NULLP; + tgtDuId = ueCb->hoInfo.tgtNodeId; + } + else if (ueCb->hoInfo.HOType == Xn_Based_Inter_CU_HO) + { + tgtDuId = duId; + } - SEARCH_DU_DB(duIdx, ueCb->hoInfo.targetId, tgtDuDb); - if(tgtDuDb) + SEARCH_DU_DB(duIdx, tgtDuId, tgtDuDb); + if(tgtDuDb) + { + /* 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++) { - /* 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++) + if(tgtDuDb->ueCb[ueIdx].gnbCuUeF1apId == cuUeF1apId) { - if(tgtDuDb->ueCb[ueIdx].gnbCuUeF1apId == cuUeF1apId) - { - ueCbInTgtDu = &tgtDuDb->ueCb[ueIdx]; - break; - } + ueCbInTgtDu = &tgtDuDb->ueCb[ueIdx]; + break; } + } - /* If UE context is not found in Target DU DU, send UE context setup - * request */ - if(ueCbInTgtDu == NULLP) + /* If UE context is not found in Target DU, send UE context setup + * request */ + if(ueCbInTgtDu == NULLP) + { + if((BuildAndSendUeContextSetupReq(tgtDuId, ueCb)) != ROK) { - if((BuildAndSendUeContextSetupReq(ueCb->hoInfo.targetId, ueCb)) != ROK) - { - DU_LOG("\nERROR -> F1AP : Failed at BuildAndSendUeContextSetupReq"); - return RFAILED; - } + DU_LOG("\nERROR -> F1AP : Failed at BuildAndSendUeContextSetupReq"); + return RFAILED; } } } } - + #ifdef START_DL_UL_DATA startDlData(); #endif @@ -12546,7 +12599,7 @@ uint8_t BuildAndSendPagingMsg(uint64_t gsTmsi, uint8_t duId) /******************************************************************* * - * @brief Handles received F1AP message and sends back response + * @brief Decode received character string into F1AP message * * @details * @@ -12554,61 +12607,86 @@ uint8_t BuildAndSendPagingMsg(uint64_t gsTmsi, uint8_t duId) * * Functionality: * - Decodes received F1AP control message - * - Prepares response message, encodes and sends to SCTP * * @params[in] * @return ROK - success * RFAILED - failure * * ****************************************************************/ -void F1APMsgHdlr(uint32_t *duId, Buffer *mBuf) +uint8_t F1APDecodeMsg(F1AP_PDU_t *f1apMsg, Buffer *mBuf, char **recvBuf, MsgLen *recvBufLen) { int i; - char *recvBuf; MsgLen copyCnt; - MsgLen recvBufLen; - F1AP_PDU_t *f1apMsg = NULLP; asn_dec_rval_t rval; /* Decoder return value */ - F1AP_PDU_t f1apasnmsg ; - - DU_LOG("\nINFO --> F1AP : Received F1AP message buffer"); - 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) + ODU_GET_MSG_LEN(mBuf, recvBufLen); + CU_ALLOC(*recvBuf, (Size)(*recvBufLen)); + if(*recvBuf == NULLP) { DU_LOG("\nERROR --> F1AP : Memory allocation failed"); - return; + return RFAILED; } - if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, ©Cnt) != ROK) + if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, *recvBufLen, (Data *)*recvBuf, ©Cnt) != ROK) { DU_LOG("\nERROR --> F1AP : Failed while copying %d", copyCnt); - return; + return RFAILED; } - DU_LOG("\nDEBUG --> F1AP : Received flat buffer to be decoded : "); - for(i=0; i< recvBufLen; i++) + DU_LOG("\nDEBUG --> F1AP : Received flat buffer to be decoded : \n"); + for(i=0; i< *recvBufLen; i++) { - DU_LOG("%x",recvBuf[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); - + rval = aper_decode(0, &asn_DEF_F1AP_PDU, (void **)&f1apMsg, *recvBuf, *recvBufLen, 0, 0); if(rval.code == RC_FAIL || rval.code == RC_WMORE) { DU_LOG("\nERROR --> F1AP : ASN decode failed"); - return; + return RFAILED; } + + /* Printing the decoded F1AP PDU */ DU_LOG("\n"); xer_fprint(stdout, &asn_DEF_F1AP_PDU, f1apMsg); + return ROK; +} + +/******************************************************************* + * + * @brief Handles received F1AP message and sends back response + * + * @details + * + * Function : F1APMsgHdlr + * + * Functionality: + * - Decodes received F1AP control message + * - Prepares response message, encodes and sends to SCTP + * + * @params[in] + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +void F1APMsgHdlr(uint32_t *duId, Buffer *mBuf) +{ + char *recvBuf; + MsgLen recvBufLen; + F1AP_PDU_t *f1apMsg = NULLP; + F1AP_PDU_t f1apasnmsg ; + + DU_LOG("\nINFO --> F1AP : Received F1AP message buffer"); + ODU_PRINT_MSG(mBuf, 0,0); + + 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; + } switch(f1apMsg->present) { @@ -12682,7 +12760,7 @@ void F1APMsgHdlr(uint32_t *duId, Buffer *mBuf) case SuccessfulOutcome__value_PR_UEContextSetupResponse: { DU_LOG("\nINFO --> F1AP : UE ContextSetupResponse received"); - procUeContextSetupResponse(*duId, f1apMsg); + procUeContextSetupResponse(*duId, f1apMsg, recvBuf, recvBufLen); break; } case SuccessfulOutcome__value_PR_UEContextModificationResponse: @@ -12713,6 +12791,7 @@ void F1APMsgHdlr(uint32_t *duId, Buffer *mBuf) } }/* End of switch(f1apMsg->present) */ + CU_FREE(recvBuf, (Size)(recvBufLen)); } /* End of F1APMsgHdlr */ /********************************************************************** diff --git a/src/cu_stub/cu_stub.c b/src/cu_stub/cu_stub.c index b817edfc7..6a9c7ddd5 100644 --- a/src/cu_stub/cu_stub.c +++ b/src/cu_stub/cu_stub.c @@ -286,8 +286,8 @@ void initiateInterDuHandover(uint32_t sourceDuId, uint32_t targetDuId, uint32_t { ueCb->state = UE_HANDOVER_IN_PROGRESS; ueCb->hoInfo.HOType = Inter_DU_HO; - ueCb->hoInfo.sourceId = sourceDuId; - ueCb->hoInfo.targetId = targetDuId; + ueCb->hoInfo.srcNodeId = sourceDuId; + ueCb->hoInfo.tgtNodeId = targetDuId; BuildAndSendUeContextModificationReq(sourceDuId, ueCb, QUERY_CONFIG); } @@ -316,13 +316,13 @@ void initiateInterDuHandover(uint32_t sourceDuId, uint32_t targetDuId, uint32_t * RFAILED - failure * * ****************************************************************/ -void initiateInterCuHandover(uint32_t sourceCuId, uint32_t targetCuId, uint32_t cuUeF1apId) +void initiateInterCuHandover(uint32_t targetCuId, uint32_t cellId, uint32_t cuUeF1apId) { uint8_t duIdx, ueIdx; CuUeCb *ueCb = NULLP; - DU_LOG("\nINFO --> CU_STUB: Inter-CU Handover Started for ueId [%d] from CU ID [%d] to CU ID [%d]", \ - cuUeF1apId, sourceCuId, targetCuId); + DU_LOG("\nINFO --> CU_STUB: Inter-CU Handover Started for ueId [%d] to CU ID [%d]", \ + cuUeF1apId, targetCuId); for(duIdx = 0; duIdx < cuCb.numDu; duIdx++) { @@ -343,8 +343,11 @@ void initiateInterCuHandover(uint32_t sourceCuId, uint32_t targetCuId, uint32_t { ueCb->state = UE_HANDOVER_IN_PROGRESS; ueCb->hoInfo.HOType = Xn_Based_Inter_CU_HO; - ueCb->hoInfo.sourceId = sourceCuId; - ueCb->hoInfo.targetId = targetCuId; + ueCb->hoInfo.srcNodeId = cuCb.cuCfgParams.cuId; + ueCb->hoInfo.tgtNodeId = targetCuId; + ueCb->hoInfo.tgtCellId = cellId; + ueCb->hoInfo.cuUeF1apIdSrc = ueCb->gnbCuUeF1apId; + BuildAndSendUeContextModificationReq(cuCb.duInfo[duIdx].duId, ueCb, QUERY_CONFIG); } else @@ -485,32 +488,32 @@ void *cuConsoleHandler(void *args) else if(ch == 'h') { HandoverType hoType; - uint32_t sourceId, targetId, ueId; + uint32_t srcNodeId, tgtNodeId, targetCellId, ueId; DU_LOG("\n\nChoose the type of handover to initiate : \nEnter 1 for Inter-CU Handover over Xn interface\nEnter 2 for Inter-DU Handover\n"); scanf("%d", &hoType); if(hoType == Xn_Based_Inter_CU_HO) { - DU_LOG("\nEnter Source CU ID for Inter-CU Handover : "); - scanf("%d", &sourceId); DU_LOG("\nEnter Target CU ID for Inter-CU Handover : "); - scanf("%d", &targetId); + scanf("%d", &tgtNodeId); + DU_LOG("\nEnter Target Physical Cell ID for Inter-CU Handover : "); + scanf("%d", &targetCellId); DU_LOG("\nEnter CU UE F1AP ID to be handed over : "); scanf("%d", &ueId); - initiateInterCuHandover(sourceId, targetId, ueId); + initiateInterCuHandover(tgtNodeId, targetCellId, ueId); } else if(hoType == Inter_DU_HO) { DU_LOG("\nEnter Source DU ID for Inter-DU Handover : "); - scanf("%d", &sourceId); + scanf("%d", &srcNodeId); DU_LOG("\nEnter Target DU ID for Inter-DU Handover : "); - scanf("%d", &targetId); + scanf("%d", &tgtNodeId); DU_LOG("\nEnter DU UE F1AP ID to be handed over : "); scanf("%d", &ueId); - initiateInterDuHandover(sourceId, targetId, ueId); + initiateInterDuHandover(srcNodeId, tgtNodeId, ueId); } } /* Start Idle mode paging when 'p' is received from console input */ diff --git a/src/cu_stub/cu_stub.h b/src/cu_stub/cu_stub.h index 08cb36b0f..b80998137 100644 --- a/src/cu_stub/cu_stub.h +++ b/src/cu_stub/cu_stub.h @@ -116,7 +116,8 @@ typedef enum { XN_SETUP_REQ, XN_SETUP_RSP, - HO_REQ + HO_REQ, + HO_REQ_ACK }XnEventType; typedef enum @@ -153,8 +154,11 @@ typedef struct cuCfgParams typedef struct handoverInfo { HandoverType HOType; - uint32_t sourceId; /* If Inter_DU HO, this is Source DU ID. In case of Inter CU HO, this is Source CU ID */ - uint32_t targetId; /* If Inter_DU HO, this is Taregt DU ID. In case of Inter CU HO, this is Target CU ID */ + uint32_t srcNodeId; /* If Inter_DU HO, this is Source DU ID. In case of Inter CU HO, this is Source CU ID */ + uint32_t tgtNodeId; /* If Inter_DU HO, this is Taregt DU ID. In case of Inter CU HO, this is Target CU ID */ + uint32_t tgtCellId; /* Cell Id in target node to which UE is to be handed over */ + uint8_t cuUeF1apIdSrc; /* Used for Inter-CU HO. CU UE F1AP ID of UE in source CU */ + uint8_t cuUeF1apIdTgt; /* Used for Inter-CU HO. CU UE F1AP ID of UE in target CU */ }HandoverInfo; typedef struct dlAmCfg @@ -352,6 +356,7 @@ typedef struct duDb CuCellCb cellCb[MAX_NUM_CELL]; uint8_t numUe; CuUeCb ueCb[MAX_NUM_CELL * MAX_NUM_UE]; + CuUeCb *tempUeCtxtInHo; }DuDb; typedef struct cuGlobalCb diff --git a/src/cu_stub/cu_xnap_msg_hdl.c b/src/cu_stub/cu_xnap_msg_hdl.c index 26d7329bd..436809a51 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" @@ -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(oduUnpackUInt8, ueCb->hoInfo.cuUeF1apIdSrc, mBuf); + CMCHKPK(oduUnpackUInt32, ueCb->hoInfo.tgtCellId, mBuf); + CMCHKPK(oduUnpackUInt8, 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,154 @@ 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(oduPackUInt32, &(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(oduPackUInt8, &(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(oduUnpackUInt8, ueCb->gnbCuUeF1apId, mBuf); + CMCHKPK(oduUnpackUInt8, ueCb->hoInfo.cuUeF1apIdSrc, mBuf); + CMCHKPK(oduUnpackUInt8, 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 search for UE CB and + * the corresponding DU DB (SDU) + * 2. Unpack CU UE F1AP ID (by TCU) and fill in UEcb->hoInfo + * 3. Decode the F1AP UE context setup response msg received in + * XNAP message buffer and extract UE configurations + * 4. Create RRC reconfig msg with these configurations + * 5. Send RRC Reconfig msg and Transmission Action = DO NOT TRANSMIT + * in UE context modification request to S DU + * + * @params[in] Pointer to destination Id + * Pointer to message buffer + * @return void + * + ******************************************************************/ +void XNAPProcHandoverReqAck(uint32_t destId, Buffer *mBuf) +{ + DU_LOG("\nINFO --> CU STUB : Received Handover Request Acknowledgement"); +} + /******************************************************************* * * @brief Handle incoming messages at Xn interface @@ -223,56 +374,13 @@ 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; } default: -- 2.16.6