X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=src%2Fcu_stub%2Fcu_f1ap_msg_hdl.c;h=39b0c1fa48ef91a694d5aa18b4083be7c956ac80;hb=2ba58cd78e409ae234aac627914f954e6aa8b1ff;hp=fc098257138c8de0e67c382048ebfd1d89cf4eae;hpb=b7a8e8fc6abc7fba2f580684da44413d481be825;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 fc0982571..39b0c1fa4 100644 --- a/src/cu_stub/cu_f1ap_msg_hdl.c +++ b/src/cu_stub/cu_f1ap_msg_hdl.c @@ -177,7 +177,7 @@ S16 SendF1APMsg(Region region, Pool pool, uint32_t duId) { ODU_PRINT_MSG(mBuf, 0,0); - if(sctpSend(duId, mBuf) != ROK) + if(sctpSend(F1_INTERFACE, duId, mBuf) != ROK) { DU_LOG("\nERROR --> F1AP : SCTP Send failed"); ODU_PUT_MSG_BUF(mBuf); @@ -224,10 +224,10 @@ uint8_t BuildAndSendF1SetupRsp(uint32_t duId, BIT_STRING_t *nrcellId) uint8_t idx,ieIdx; uint8_t elementCnt,cellCnt; F1AP_PDU_t *f1apMsg = NULL; - F1SetupResponse_t *f1SetupRsp; - GNB_CU_Name_t *cuName; + F1SetupResponse_t *f1SetupRsp = NULL; + GNB_CU_Name_t *cuName = NULL; Cells_to_be_Activated_List_t *cellToActivate; - RRC_Version_t *rrcVer; + RRC_Version_t *rrcVer = NULL; asn_enc_rval_t encRetVal; DU_LOG("\nINFO --> F1AP : Building F1 Setup Response\n"); @@ -254,7 +254,7 @@ uint8_t BuildAndSendF1SetupRsp(uint32_t duId, BIT_STRING_t *nrcellId) SuccessfulOutcome__value_PR_F1SetupResponse; f1SetupRsp = &f1apMsg->choice.successfulOutcome->value.choice.F1SetupResponse; - elementCnt = 4; + elementCnt = 3; f1SetupRsp->protocolIEs.list.count = elementCnt; f1SetupRsp->protocolIEs.list.size = elementCnt*sizeof(F1SetupResponseIEs_t *); @@ -291,58 +291,54 @@ uint8_t BuildAndSendF1SetupRsp(uint32_t duId, BIT_STRING_t *nrcellId) F1SetupResponseIEs__value_PR_TransactionID; f1SetupRsp->protocolIEs.list.array[idx]->value.choice.TransactionID =\ TRANS_ID; - +#if 0 + /* CU name IE is of type printableString_t which wireshark is unable to decode. + * However this string is decoded successfully on online decoders. + * Since this is an optional IE and the value received in it are not + * used as of now, eliminating this IE for now to avoid wireshark error. + */ /*CU Name*/ idx++; f1SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_ID_id_gNB_CU_Name; f1SetupRsp->protocolIEs.list.array[idx]->criticality = Criticality_ignore; - f1SetupRsp->protocolIEs.list.array[idx]->value.present = \ - F1SetupResponseIEs__value_PR_GNB_CU_Name; + f1SetupRsp->protocolIEs.list.array[idx]->value.present = F1SetupResponseIEs__value_PR_GNB_CU_Name; cuName = &f1SetupRsp->protocolIEs.list.array[idx]->value.choice.GNB_CU_Name; - cuName->size = sizeof(cuCb.cuCfgParams.cuName); + cuName->size = strlen((char *)cuCb.cuCfgParams.cuName); - CU_ALLOC(cuName->buf, sizeof(cuName->size)); + CU_ALLOC(cuName->buf, cuName->size); if(cuName->buf == NULLP) { for(ieIdx=0; ieIdxprotocolIEs.list.array[ieIdx],\ - sizeof(F1SetupResponseIEs_t)); + CU_FREE(f1SetupRsp->protocolIEs.list.array[ieIdx], sizeof(F1SetupResponseIEs_t)); } - CU_FREE(f1SetupRsp->protocolIEs.list.array,\ - elementCnt * sizeof(F1SetupResponseIEs_t *)); - CU_FREE(f1apMsg->choice.successfulOutcome,\ - sizeof(SuccessfulOutcome_t)); + CU_FREE(f1SetupRsp->protocolIEs.list.array, elementCnt * sizeof(F1SetupResponseIEs_t *)); + CU_FREE(f1apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcome_t)); CU_FREE(f1apMsg, sizeof(F1AP_PDU_t)); return RFAILED; } strcpy((char*)cuName->buf, (char*)cuCb.cuCfgParams.cuName); +#endif /*Cells to be activated list*/ idx++; - f1SetupRsp->protocolIEs.list.array[idx]->id = \ - ProtocolIE_ID_id_Cells_to_be_Activated_List ; + f1SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_ID_id_Cells_to_be_Activated_List ; f1SetupRsp->protocolIEs.list.array[idx]->criticality = Criticality_reject; - f1SetupRsp->protocolIEs.list.array[idx]->value.present = \ - F1SetupResponseIEs__value_PR_Cells_to_be_Activated_List; - cellToActivate = &f1SetupRsp->protocolIEs.list.array[idx]->value.choice.\ - Cells_to_be_Activated_List; + f1SetupRsp->protocolIEs.list.array[idx]->value.present = F1SetupResponseIEs__value_PR_Cells_to_be_Activated_List; + cellToActivate = &f1SetupRsp->protocolIEs.list.array[idx]->value.choice.Cells_to_be_Activated_List; + cellCnt=1; cellToActivate->list.count = cellCnt; - cellToActivate->list.size = \ - cellCnt*sizeof(struct Cells_to_be_Activated_List_ItemIEs *); - CU_ALLOC(cellToActivate->list.array,\ - sizeof(struct Cells_to_be_Activated_List_ItemIEs *)); + cellToActivate->list.size = cellCnt * sizeof(struct Cells_to_be_Activated_List_ItemIEs *); + CU_ALLOC(cellToActivate->list.array, sizeof(struct Cells_to_be_Activated_List_ItemIEs *)); if(cellToActivate->list.array == NULLP) { CU_FREE(cuName->buf, sizeof(cuName->size)); for(ieIdx=0; ieIdxprotocolIEs.list.array[ieIdx],\ - sizeof(F1SetupResponseIEs_t)); + CU_FREE(f1SetupRsp->protocolIEs.list.array[ieIdx], sizeof(F1SetupResponseIEs_t)); } - CU_FREE(f1SetupRsp->protocolIEs.list.array,\ - elementCnt * sizeof(F1SetupResponseIEs_t *)); + CU_FREE(f1SetupRsp->protocolIEs.list.array, elementCnt * sizeof(F1SetupResponseIEs_t *)); CU_FREE(f1apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcome_t)); CU_FREE(f1apMsg, sizeof(F1AP_PDU_t)); return RFAILED; @@ -352,18 +348,14 @@ uint8_t BuildAndSendF1SetupRsp(uint32_t duId, BIT_STRING_t *nrcellId) CU_ALLOC(cellToActivate->list.array[ieIdx],sizeof(struct Cells_to_be_Activated_List_ItemIEs )); if(cellToActivate->list.array[ieIdx] == NULLP) { - CU_FREE(cellToActivate->list.array,\ - sizeof(struct Cells_to_be_Activated_List_ItemIEs *)); + CU_FREE(cellToActivate->list.array, sizeof(struct Cells_to_be_Activated_List_ItemIEs *)); CU_FREE(cuName->buf, sizeof(cuName->size)); for(ieIdx=0; ieIdxprotocolIEs.list.array[ieIdx], \ - sizeof(F1SetupResponseIEs_t)); + CU_FREE(f1SetupRsp->protocolIEs.list.array[ieIdx], sizeof(F1SetupResponseIEs_t)); } - CU_FREE(f1SetupRsp->protocolIEs.list.array, \ - elementCnt * sizeof(F1SetupResponseIEs_t *)); - CU_FREE(f1apMsg->choice.successfulOutcome, \ - sizeof(SuccessfulOutcome_t)); + CU_FREE(f1SetupRsp->protocolIEs.list.array, elementCnt * sizeof(F1SetupResponseIEs_t *)); + CU_FREE(f1apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcome_t)); CU_FREE(f1apMsg, sizeof(F1AP_PDU_t)); return RFAILED; } @@ -439,6 +431,7 @@ uint8_t BuildAndSendF1SetupRsp(uint32_t duId, BIT_STRING_t *nrcellId) return RFAILED; } memcpy(&cellToActivate->list.array[0]->value.choice.Cells_to_be_Activated_List_Item.nRCGI.nRCellIdentity, nrcellId, sizeof(BIT_STRING_t)); + /* RRC Version */ idx++; f1SetupRsp->protocolIEs.list.array[idx]->id = \ @@ -573,8 +566,10 @@ uint8_t BuildAndSendF1SetupRsp(uint32_t duId, BIT_STRING_t *nrcellId) encRetVal = aper_encode(&asn_DEF_F1AP_PDU, 0, f1apMsg, PrepFinalEncBuf, encBuf); /* Clean up */ - CU_FREE(rrcVer->latest_RRC_Version.buf, sizeof(uint8_t)); - CU_FREE(cuName->buf, sizeof(cuName->size)); + if(rrcVer) + CU_FREE(rrcVer->latest_RRC_Version.buf, sizeof(uint8_t)); + if(cuName) + CU_FREE(cuName->buf, cuName->size); for(idx=0; idxprotocolIEs.list.array[idx], sizeof(F1SetupResponseIEs_t)); @@ -1113,7 +1108,7 @@ uint8_t fillDlCcchRrcMsg(CuUeCb *ueCb, RRCContainer_t *rrcContainer) xer_fprint(stdout, &asn_DEF_DL_CCCH_MessageType, &dl_CCCH_Msg); memset(encBuf, 0, ENC_BUF_MAX_LEN); encBufSize = 0; - encRetVal = aper_encode(&asn_DEF_DL_CCCH_MessageType, 0, &dl_CCCH_Msg, PrepFinalEncBuf, encBuf); + encRetVal = uper_encode(&asn_DEF_DL_CCCH_MessageType, 0, &dl_CCCH_Msg, PrepFinalEncBuf, encBuf); /* Encode results */ if(encRetVal.encoded == ENCODE_FAIL) { @@ -1406,7 +1401,7 @@ uint8_t fillRrcReconfigIE(RRCReconfiguration_IEs_t *rrcReconfigMsg) * * ****************************************************************/ -uint8_t fillDlDcchRrcMsg(CuUeCb *ueCb, RRCContainer_t *rrcContainer) +uint8_t fillDlDcchRrcMsg(CuUeCb *ueCb, RRCContainer_t *rrcContainer, bool updateAllRbCfg) { uint8_t ret = ROK; uint16_t idx2 = 0, drbIdx = 0, srbIdx = 0; @@ -1426,7 +1421,7 @@ uint8_t fillDlDcchRrcMsg(CuUeCb *ueCb, RRCContainer_t *rrcContainer) if(dl_DCCH_Msg.message.choice.c1->choice.rrcReconfiguration != NULLP) { DU_LOG("\nDEBUG --> F1AP : Filling DL DCCH RRC Reconfiguration Message "); - fillRrcReconfig(ueCb, dl_DCCH_Msg.message.choice.c1->choice.rrcReconfiguration, false); + fillRrcReconfig(ueCb, dl_DCCH_Msg.message.choice.c1->choice.rrcReconfiguration, updateAllRbCfg); if(ret == ROK) { /* If RB configuration are filled successfully in RRC Reconfiguration, mark these @@ -1446,7 +1441,7 @@ uint8_t fillDlDcchRrcMsg(CuUeCb *ueCb, RRCContainer_t *rrcContainer) xer_fprint(stdout, &asn_DEF_DL_DCCH_MessageType, &dl_DCCH_Msg); memset(encBuf, 0, ENC_BUF_MAX_LEN); encBufSize = 0; - encRetVal = aper_encode(&asn_DEF_DL_DCCH_MessageType, 0, &dl_DCCH_Msg, PrepFinalEncBuf, encBuf); + encRetVal = uper_encode(&asn_DEF_DL_DCCH_MessageType, 0, &dl_DCCH_Msg, PrepFinalEncBuf, encBuf); /* Encode results */ if(encRetVal.encoded == ENCODE_FAIL) { @@ -1524,9 +1519,31 @@ uint8_t BuildDLRRCContainer(CuUeCb *ueCb, uint8_t rrcMsgType, RRCContainer_t *rr DU_LOG("\nERROR --> F1AP: Failed to fill DL-CCCH Msg at RRC SETUP"); } else if(rrcMsgType == RRC_SETUP_COMPLETE) + { + DU_LOG("\nINFO --> F1AP : Sending NAS Authentication Request"); + char authReqBuf[51] = {0x00, ueCb->pdcpSn++, 0x2a, 0x85, 0x4f, 0xc0, 0x0a, 0xc0, 0x40, 0x40, 0x00, 0x04, 0x2f, 0x58, 0x39, 0x12,\ + 0x37, 0x15, 0x74, 0x16, 0x4c, 0x8d, 0xd3, 0x95, 0xa6, 0x9e, 0x94, 0x03, 0x24, 0x02, 0x00, 0x6f,\ + 0x0b, 0x39, 0x5e, 0xbc, 0xb0, 0x00, 0x1a, 0xb1, 0xc1, 0x3f, 0x84, 0x4f, 0x77, 0xe3, 0x20, 0x00,\ + 0x00, 0x00, 0x00}; + bufLen = 51; + rrcContainer->size = bufLen; + CU_ALLOC(rrcContainer->buf, rrcContainer->size); + if(rrcContainer->buf != NULLP) + { + memset(rrcContainer->buf, 0, bufLen); + memcpy(rrcContainer->buf, authReqBuf, bufLen); + } + else + { + DU_LOG("\nERROR --> F1AP : Memory allocation failure for RRC Container buffer"); + ret = RFAILED; + + } + } + else if(rrcMsgType == NAS_AUTHENTICATION_RSP) { 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, + char secModeBuf[30]={0x00, ueCb->pdcpSn++, 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; @@ -1545,7 +1562,7 @@ uint8_t BuildDLRRCContainer(CuUeCb *ueCb, uint8_t rrcMsgType, RRCContainer_t *rr 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}; + char secModeBuf[9]={0x00, ueCb->pdcpSn++, 0x22, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00}; bufLen =9; rrcContainer->size = bufLen; CU_ALLOC(rrcContainer->buf, rrcContainer->size); @@ -1564,7 +1581,7 @@ uint8_t BuildDLRRCContainer(CuUeCb *ueCb, uint8_t rrcMsgType, RRCContainer_t *rr { /*Hardcoded RRC Container from reference logs*/ DU_LOG("\nINFO --> F1AP : Sending Registration accept"); - char buf[14] ={0x00, 0x04, 0x2a, 0x80, 0xaf, 0xc0, 0x08, 0x40, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00}; + char buf[14] ={0x00, ueCb->pdcpSn++, 0x2a, 0x80, 0xaf, 0xc0, 0x08, 0x40, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00}; bufLen =14; rrcContainer->size = bufLen; CU_ALLOC(rrcContainer->buf, rrcContainer->size); @@ -1581,8 +1598,22 @@ uint8_t BuildDLRRCContainer(CuUeCb *ueCb, uint8_t rrcMsgType, RRCContainer_t *rr } else if(rrcMsgType == UE_CONTEXT_SETUP_RSP) { + uint16_t tmpBufIdx = 0, bufIdx = 0; + RRCContainer_t rrcContainerTmp; DU_LOG("\nINFO --> F1AP : Filling DL DCCH RRC Message for RRC Reconfiguration "); - ret = fillDlDcchRrcMsg(ueCb, rrcContainer); + ret = fillDlDcchRrcMsg(ueCb, &rrcContainerTmp, false); + rrcContainer->size = rrcContainerTmp.size + 2; + CU_ALLOC(rrcContainer->buf, rrcContainer->size); + if(rrcContainer->buf != NULLP) + { + memset(rrcContainer->buf, 0, rrcContainer->size); + rrcContainer->buf[0] = 0x00; + rrcContainer->buf[1] = ueCb->pdcpSn++; //PDCP SN + for(bufIdx = 2, tmpBufIdx = 0; bufIdx < rrcContainer->size; bufIdx++, tmpBufIdx++) + { + rrcContainer->buf[bufIdx] = rrcContainerTmp.buf[tmpBufIdx]; + } + } if(ret == RFAILED) DU_LOG("\nERROR --> F1AP: Failed to fill DL-DCCH Msg for RRC Reconfiguration"); } @@ -1798,6 +1829,9 @@ uint8_t setDlRRCMsgType(CuUeCb *ueCb) case RRC_SETUP_COMPLETE: rrcMsgType = RRC_SETUP_COMPLETE; break; + case NAS_AUTHENTICATION_RSP: + rrcMsgType = NAS_AUTHENTICATION_RSP; + break; case NAS_SECURITY_MODE_COMPLETE: rrcMsgType = NAS_SECURITY_MODE_COMPLETE; break; @@ -2205,7 +2239,7 @@ uint8_t extractDuToCuRrcCont(CuUeCb *ueCb, OCTET_STRING_t rrcCont) cellGrpCfgMsg = &cellGrpCfg; memset(cellGrpCfgMsg, 0, sizeof(CellGroupConfigRrc_t)); - rval = aper_decode(0, &asn_DEF_CellGroupConfigRrc, (void **)&cellGrpCfgMsg, rrcCont.buf, rrcCont.size, 0, 0); + rval = uper_decode(0, &asn_DEF_CellGroupConfigRrc, (void **)&cellGrpCfgMsg, rrcCont.buf, rrcCont.size, 0, 0); if(rval.code == RC_FAIL || rval.code == RC_WMORE) { @@ -2532,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) @@ -2573,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; @@ -2659,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); @@ -2666,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)); @@ -2683,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*/ @@ -2714,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); @@ -2735,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) @@ -2769,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; @@ -2832,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; @@ -2865,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; @@ -2966,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"); @@ -2980,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"); @@ -2993,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"); @@ -3006,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"); @@ -3014,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; @@ -6738,7 +6774,7 @@ uint8_t fillCellGrpCfg(CuUeCb *ueCb, OCTET_STRING_t *cellGrp, bool updateAllRbCf xer_fprint(stdout, &asn_DEF_CellGroupConfigRrc, &cellGrpCfg); cmMemset((uint8_t *)encBuf, 0, ENC_BUF_MAX_LEN); encBufSize = 0; - encRetVal = aper_encode(&asn_DEF_CellGroupConfigRrc, 0, &cellGrpCfg, PrepFinalEncBuf, encBuf); + encRetVal = uper_encode(&asn_DEF_CellGroupConfigRrc, 0, &cellGrpCfg, PrepFinalEncBuf, encBuf); /* Encode results */ if(encRetVal.encoded == ENCODE_FAIL) { @@ -7126,7 +7162,7 @@ uint8_t fillUeCapRatCont(OCTET_STRING_t *ueCapRatContBuf) xer_fprint(stdout, &asn_DEF_UE_NR_Capability, &ueNrCap); cmMemset((uint8_t *)encBuf, 0, ENC_BUF_MAX_LEN); encBufSize = 0; - encRetVal = aper_encode(&asn_DEF_UE_NR_Capability, 0, &ueNrCap, PrepFinalEncBuf, encBuf); + encRetVal = uper_encode(&asn_DEF_UE_NR_Capability, 0, &ueNrCap, PrepFinalEncBuf, encBuf); /* Encode results */ if(encRetVal.encoded == ENCODE_FAIL) @@ -7254,7 +7290,7 @@ uint8_t fillUeCapRatContListBuf(UE_CapabilityRAT_ContainerList_t *ueCapablityLis xer_fprint(stdout, &asn_DEF_UE_CapabilityRAT_ContainerListRRC, &ueCapablityList); cmMemset((uint8_t *)encBuf, 0, ENC_BUF_MAX_LEN); encBufSize = 0; - encRetVal = aper_encode(&asn_DEF_UE_CapabilityRAT_ContainerListRRC, 0, \ + encRetVal = uper_encode(&asn_DEF_UE_CapabilityRAT_ContainerListRRC, 0, \ &ueCapablityList, PrepFinalEncBuf, encBuf); /* Encode results */ @@ -7452,7 +7488,7 @@ uint8_t fillMeasTimingConfigBuf(MeasConfig_t *measTimingConfigBuf) xer_fprint(stdout, &asn_DEF_MeasurementTimingConfigurationRrc, &measTimingConfig); cmMemset((uint8_t *)encBuf, 0, ENC_BUF_MAX_LEN); encBufSize = 0; - encRetVal = aper_encode(&asn_DEF_MeasurementTimingConfigurationRrc, 0, &measTimingConfig, PrepFinalEncBuf, encBuf); + encRetVal = uper_encode(&asn_DEF_MeasurementTimingConfigurationRrc, 0, &measTimingConfig, PrepFinalEncBuf, encBuf); /* Encode results */ if(encRetVal.encoded == ENCODE_FAIL) @@ -8265,7 +8301,7 @@ uint8_t fillMeasObjToAddModList(MeasObjectToAddModList_t *measObjList) /* RSRQ offset for SSB */ CU_ALLOC(measObject->offsetMO.rsrqOffsetSSB, sizeof(Q_OffsetRange_t)); - if(!measObject->offsetMO.rsrpOffsetSSB) + if(!measObject->offsetMO.rsrqOffsetSSB) { DU_LOG("\nERROR --> F1AP: Memory allocation failed for SSB RSRQ offset in fillMeasObjToAddModList"); return RFAILED; @@ -8820,7 +8856,7 @@ uint8_t fillRrcReconfigBuf(CuUeCb *ueCb, OCTET_STRING_t *rrcReconfigBuf, bool u xer_fprint(stdout, &asn_DEF_RRCReconfiguration, rrcReconfig); cmMemset((uint8_t *)encBuf, 0, ENC_BUF_MAX_LEN); encBufSize = 0; - encRetVal = aper_encode(&asn_DEF_RRCReconfiguration, 0, rrcReconfig, PrepFinalEncBuf, encBuf); + encRetVal = uper_encode(&asn_DEF_RRCReconfiguration, 0, rrcReconfig, PrepFinalEncBuf, encBuf); /* Encode results */ if(encRetVal.encoded == ENCODE_FAIL) @@ -8931,7 +8967,7 @@ uint8_t fillHOPreparationInfoBuf(CuUeCb *ueCb, HandoverPreparationInformation_t xer_fprint(stdout, &asn_DEF_HandoverPreparationInformationRrc, &hoPrepInfo); cmMemset((uint8_t *)encBuf, 0, ENC_BUF_MAX_LEN); encBufSize = 0; - encRetVal = aper_encode(&asn_DEF_HandoverPreparationInformationRrc, 0, \ + encRetVal = uper_encode(&asn_DEF_HandoverPreparationInformationRrc, 0, \ &hoPrepInfo, PrepFinalEncBuf, encBuf); /* Encode results */ @@ -8988,14 +9024,32 @@ uint8_t fillCuToDuContainer(CuUeCb *ueCb, CUtoDURRCInformation_t *rrcMsg) uint8_t ret = ROK; uint8_t idx; - /* UE Capabulity RAT Container List */ - CU_ALLOC(rrcMsg->uE_CapabilityRAT_ContainerList, sizeof(UE_CapabilityRAT_ContainerList_t)); - if(!rrcMsg->uE_CapabilityRAT_ContainerList) + if((ueCb->state != UE_HANDOVER_IN_PROGRESS) || ((ueCb->state == UE_HANDOVER_IN_PROGRESS) && (ueCb->hoInfo.HOType == Inter_DU_HO))) { - DU_LOG("\nERROR --> F1AP : Memory allocation for UE capability RAT container list failed"); - return RFAILED; + /* UE Capabulity RAT Container List */ + CU_ALLOC(rrcMsg->uE_CapabilityRAT_ContainerList, sizeof(UE_CapabilityRAT_ContainerList_t)); + if(!rrcMsg->uE_CapabilityRAT_ContainerList) + { + DU_LOG("\nERROR --> F1AP : Memory allocation for UE capability RAT container list failed"); + return RFAILED; + } + ret = fillUeCapRatContListBuf(rrcMsg->uE_CapabilityRAT_ContainerList); } - ret = fillUeCapRatContListBuf(rrcMsg->uE_CapabilityRAT_ContainerList); + +#if 0 + + /* Commenting this because: + * CUToDURRCInformation->MeasConfig contains measurement gap configurations. + * Howeever measurement gap is not supported in our code. Measurement Gap will + * be required if we want to support inter-RAT handover or handover to + * neighbouring cells operating on a different frequency than serving cell. + * + * In case we plan to use this IE in future, following fixes are required: + * As of now, we are filling MeasurementTimingConfigurationRrc_t into rrcMsg->measConfig. + * This is incorrect. We must fill MeasConfigRrc_t in rrcMsg->measConfig. + * MeasurementTimingConfigurationRrc_t should be filled in + * rrcMsg->iE_Extensions->MeasurementTimingConfiguration, if required. + */ CU_ALLOC(rrcMsg->measConfig, sizeof(MeasConfig_t)); if(!rrcMsg->measConfig) @@ -9004,6 +9058,7 @@ uint8_t fillCuToDuContainer(CuUeCb *ueCb, CUtoDURRCInformation_t *rrcMsg) return RFAILED; } ret = fillMeasTimingConfigBuf(rrcMsg->measConfig); +#endif if(ueCb->state == UE_HANDOVER_IN_PROGRESS) { @@ -9072,7 +9127,7 @@ uint8_t fillCuToDuContainer(CuUeCb *ueCb, CUtoDURRCInformation_t *rrcMsg) ******************************************************************/ uint8_t BuildDrxCycle(DRXCycle_t *drxCycle) { - drxCycle->longDRXCycleLength = LongDRXCycleLength_ms40; + drxCycle->longDRXCycleLength = LongDRXCycleLength_ms80; CU_ALLOC(drxCycle->shortDRXCycleLength, sizeof(ShortDRXCycleLength_t)); if(!drxCycle->shortDRXCycleLength) { @@ -9178,6 +9233,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; @@ -9263,16 +9319,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.targetDuId, 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) { @@ -9568,7 +9631,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; @@ -9600,11 +9663,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.targetDuId = 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; @@ -9639,65 +9715,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->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.sourceDuId = 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, duToCuRrcContainer->buf, duToCuRrcContainer->size); } } @@ -9765,29 +9849,36 @@ 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.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(duDb->ueCb[duUeF1apId-1].hoInfo.HOType == Inter_DU_HO) { - if(srcDuDb->ueCb[ueIdx].gnbCuUeF1apId == cuUeF1apId) + uint8_t ueIdx = 0; + uint8_t srcDuId = duDb->ueCb[duUeF1apId-1].hoInfo.srcNodeId; + DuDb *srcDuDb = NULLP; + + /* 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++) { - ret = BuildAndSendUeContextReleaseCommand(srcDuId, srcDuDb->ueCb[ueIdx].gnbCuUeF1apId, srcDuDb->ueCb[ueIdx].gnbDuUeF1apId); - if(ret != ROK) + if(srcDuDb->ueCb[ueIdx].gnbCuUeF1apId == cuUeF1apId) { - DU_LOG("\nINFO --> F1AP: Failed to build and send UE context release command to source DU Id [%d]", srcDuId); + 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; } - break; } } + else + { + BuildAndSendUeContextRelease(&duDb->ueCb[duUeF1apId-1]); + } + + /* 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)); return ret; } break; @@ -9804,22 +9895,7 @@ uint8_t procUlRrcMsg(uint32_t duId, F1AP_PDU_t *f1apMsg) ueCb = &duDb->ueCb[duUeF1apId-1]; ueCb->f1apMsgDb.dlRrcMsgCount++; rrcMsgType = setDlRRCMsgType(ueCb); - if(rrcMsgType == RRC_SETUP_COMPLETE) - { - 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 == RRC_SECURITY_MODE_COMPLETE) - { - DU_LOG("\nINFO --> F1AP: Sending DL RRC MSG for RRC Registration Accept"); - BuildAndSendDLRRCMessageTransfer(duId, ueCb, srbId, rrcMsgType); - } - else if(rrcMsgType == REGISTRATION_COMPLETE) + if(rrcMsgType == REGISTRATION_COMPLETE) { DU_LOG("\nINFO --> F1AP: Sending Ue Context Setup Request"); ret = BuildAndSendUeContextSetupReq(duId, ueCb); @@ -9829,6 +9905,11 @@ uint8_t procUlRrcMsg(uint32_t duId, F1AP_PDU_t *f1apMsg) DU_LOG("\nINFO --> F1AP: Sending UE Context Modification Request"); BuildAndSendUeContextModificationReq(duId, ueCb, RRC_RECONFIG_COMPLETE_IND); } + else + { + /* In case rrcMsgType is RRC_SETUP_COMPLETE / NAS_AUTHENTICATION_RSP / NAS_SECURITY_MODE_COMPLETE / RRC_SECURITY_MODE_COMPLETE */ + BuildAndSendDLRRCMessageTransfer(duId, ueCb, srbId, rrcMsgType); + } } return ret; } @@ -10707,6 +10788,95 @@ uint8_t BuildDrbToBeModifiedList(uint32_t duId, CuUeCb *ueCb, DRBs_ToBeModified_ return ret; } +/******************************************************************* +* +* @brief Builds the DRB to be released Item IE +* +* @details +* +* Function : FillDrbToBeRelItemList +* +* Functionality: Constructs the DRB to be modified Mod Item Ies +* +* @params[in] struct DRBs_ToBeReleased_ItemIEs *drbItemIe +* +* @return ROK - success +* RFAILED - failure +* +* ****************************************************************/ + +uint8_t FillDrbToBeRelItemList(uint32_t duId, CuUeCb *ueCb, uint8_t arrIdx, struct DRBs_ToBeReleased_ItemIEs *drbItemIe) +{ + uint8_t drbIdx; + + drbItemIe->id = ProtocolIE_ID_id_DRBs_ToBeReleased_Item; + drbItemIe->criticality = Criticality_reject; + drbItemIe->value.present = DRBs_ToBeReleased_ItemIEs__value_PR_DRBs_ToBeReleased_Item; + drbItemIe->value.choice.DRBs_ToBeReleased_Item.dRBID = DRB1 + arrIdx; + + for(drbIdx = 0; drbIdx < ueCb->numDrb; drbIdx++) + { + if(ueCb->drbList[drbIdx].drbId == drbItemIe->value.choice.DRBs_ToBeReleased_Item.dRBID) + { + deleteEgtpTunnel(duId, ueCb->drbList[drbIdx].dlUpTnlInfo.teId); + CU_FREE(ueCb->drbList[drbIdx].snssai, sizeof(Snssai)); + break; + } + } + return ROK; +} + +/******************************************************************* +* +* @brief Builds the DRB to be released list +* +* @details +* +* Function : BuildDrbToBeReleasedList +* +* Functionality: Constructs the DRB to be released list +* +* @params[in] DRBs_ToBeReleased_List_t *drbSet +* +* @return ROK - success +* RFAILED - failure +* +* ****************************************************************/ + +uint8_t BuildDrbToBeReleasedList(uint32_t duId, CuUeCb *ueCb, DRBs_ToBeReleased_List_t *drbSet) +{ + uint8_t ret = ROK; + uint8_t arrIdx =0; + uint8_t drbCnt =0; + + drbCnt = MAX_DRB_MODIFIED_UE_MOD_REQ; + drbSet->list.count = drbCnt; + drbSet->list.size = drbCnt * sizeof(DRBs_ToBeReleased_ItemIEs_t *); + CU_ALLOC(drbSet->list.array, drbSet->list.size); + if(drbSet->list.array == NULLP) + { + DU_LOG("\nERROR --> F1AP : Memory allocation failed in BuildDrbToBeReleasedList"); + return RFAILED; + } + for(arrIdx=0; arrIdxlist.array[arrIdx], sizeof(DRBs_ToBeReleased_ItemIEs_t)); + if(drbSet->list.array[arrIdx] == NULLP) + { + DU_LOG("\nERROR --> F1AP : Memory allocation failed in BuildDrbToBeReleasedList"); + return RFAILED; + } + + ret = FillDrbToBeRelItemList(duId, ueCb, arrIdx, (DRBs_ToBeReleased_ItemIEs_t *)drbSet->list.array[arrIdx]); + if(ret != ROK) + { + DU_LOG("\nERROR --> F1AP : FillDrbToBeRelItemList failed"); + } + } + + return ret; +} + /******************************************************************* * * @brief freeing the DRB item @@ -10828,6 +10998,40 @@ void FreeDrbToBeModifiedList(DRBs_ToBeModified_List_t *drbSet) } +/******************************************************************* +* +* @brief free the DRB to be modfified list +* +* @details +* +* Function : FreeDrbToBeReleasedList +* +* Functionality: free the DRB to be Release list +* +* @params[in] FreeDrbToBeReleasedList_t *drbSet +* +* @return ROK - success +* RFAILED - failure +* +* ****************************************************************/ +void FreeDrbToBeReleasedList(DRBs_ToBeReleased_List_t *drbSet) +{ + uint8_t arrIdx =0; + struct DRBs_ToBeReleased_ItemIEs *drbItemIe; + + if(drbSet->list.array) + { + for(arrIdx=0; arrIdxlist.count ; arrIdx++) + { + if(drbSet->list.array[arrIdx] != NULLP) + { + CU_FREE(drbSet->list.array[arrIdx], sizeof(DRBs_ToBeReleased_ItemIEs_t)); + } + } + CU_FREE(drbSet->list.array, drbSet->list.size); + } +} + /******************************************************************* * * @brief free the UeContextModification Request @@ -10879,6 +11083,12 @@ void FreeUeContextModicationRequest(F1AP_PDU_t *f1apMsg) choice.DRBs_ToBeModified_List); break; } + case ProtocolIE_ID_id_DRBs_ToBeReleased_List: + { + FreeDrbToBeReleasedList(&ueContextModifyReq->protocolIEs.list.array[arrIdx]->value.\ + choice.DRBs_ToBeReleased_List); + break; + } case ProtocolIE_ID_id_TransmissionActionIndicator: break; case ProtocolIE_ID_id_RRCContainer: @@ -10920,9 +11130,11 @@ uint8_t BuildAndSendUeContextModificationReq(uint32_t duId, void *cuUeCb, UeCtxt uint8_t ieIdx = 0; uint8_t elementCnt = 0; uint8_t ret = RFAILED; + uint16_t tmpBufIdx = 0, bufIdx = 0; CuUeCb *ueCb = (CuUeCb *)cuUeCb; F1AP_PDU_t *f1apMsg = NULLP; UEContextModificationRequest_t *ueContextModifyReq = NULLP; + RRCContainer_t rrcContainerTmp, *rrcContainer = NULLP; asn_enc_rval_t encRetVal; DU_LOG("\nINFO --> F1AP : Building Ue context modification request\n"); while(1) @@ -10949,13 +11161,18 @@ uint8_t BuildAndSendUeContextModificationReq(uint32_t duId, void *cuUeCb, UeCtxt ueContextModifyReq =&f1apMsg->choice.initiatingMessage->value.choice.UEContextModificationRequest; if(action == MODIFY_UE) - elementCnt = 4; + elementCnt = 5; else if(action == QUERY_CONFIG) elementCnt = 3; else if(action == RRC_RECONFIG_COMPLETE_IND) elementCnt = 3; else if((action == STOP_DATA_TX) || (action == RESTART_DATA_TX)) - elementCnt = 5; + { + if(ueCb->state != UE_HANDOVER_IN_PROGRESS) + elementCnt = 5; + else + elementCnt = 4; + } #ifdef NR_DRX if(DRX_TO_BE_RELEASE && ueCb->drxCfgPresent) @@ -11016,15 +11233,26 @@ uint8_t BuildAndSendUeContextModificationReq(uint32_t duId, void *cuUeCb, UeCtxt ret = BuildDrbToBeModifiedList(duId, ueCb, &(ueContextModifyReq->protocolIEs.list.array[ieIdx]->\ value.choice.DRBs_ToBeModified_List)); - /* TODO: DRB to be release list */ - if(ret != ROK) { DU_LOG("\nERROR --> F1AP : BuildAndSendUeContextModificationReq(): Failed to build drb to be modified list"); break; } - /* TODO: fill the RRC reconfiguration information in RRC Contaiiner ie in case of MODIFY_UE */ + /* DRB to be released list */ + ieIdx++; + ueContextModifyReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_ID_id_DRBs_ToBeReleased_List; + ueContextModifyReq->protocolIEs.list.array[ieIdx]->criticality = Criticality_reject; + ueContextModifyReq->protocolIEs.list.array[ieIdx]->value.present =\ + UEContextModificationRequestIEs__value_PR_DRBs_ToBeReleased_List; + ret = BuildDrbToBeReleasedList(duId, ueCb, &(ueContextModifyReq->protocolIEs.list.array[ieIdx]->\ + value.choice.DRBs_ToBeReleased_List)); + + if(ret != ROK) + { + DU_LOG("\nERROR --> F1AP : BuildAndSendUeContextModificationReq(): Failed to build drb to be deleted list"); + break; + } } else if(action == QUERY_CONFIG) { @@ -11070,20 +11298,33 @@ uint8_t BuildAndSendUeContextModificationReq(uint32_t duId, void *cuUeCb, UeCtxt ieIdx++; ueContextModifyReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_ID_id_RRCContainer; ueContextModifyReq->protocolIEs.list.array[ieIdx]->criticality = Criticality_reject; - ueContextModifyReq->protocolIEs.list.array[ieIdx]->value.present = \ - UEContextModificationRequestIEs__value_PR_RRCContainer; - if(fillRrcReconfigBuf(ueCb, &ueContextModifyReq->protocolIEs.list.array[ieIdx]->value.choice.RRCContainer, true) != ROK) + ueContextModifyReq->protocolIEs.list.array[ieIdx]->value.present = UEContextModificationRequestIEs__value_PR_RRCContainer; + if(fillDlDcchRrcMsg(ueCb, &rrcContainerTmp, true) != ROK) { DU_LOG( "\nERROR --> F1AP : Failed to fill Rrc reconfiguration buffer"); return RFAILED; } + rrcContainer = &ueContextModifyReq->protocolIEs.list.array[ieIdx]->value.choice.RRCContainer; + rrcContainer->size = rrcContainerTmp.size + 2; /* 2 bytes of PDCP SN */ + CU_ALLOC(rrcContainer->buf, rrcContainer->size); + memset(rrcContainer->buf, 0, rrcContainer->size); + rrcContainer->buf[0] = 0x00; + rrcContainer->buf[1] = ueCb->pdcpSn; //PDCP SN + for(bufIdx = 2, tmpBufIdx = 0; bufIdx < rrcContainer->size; bufIdx++, tmpBufIdx++) + { + rrcContainer->buf[bufIdx] = rrcContainerTmp.buf[tmpBufIdx]; + } + /* RRC delivery status request */ - ieIdx++; - ueContextModifyReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_ID_id_RRCDeliveryStatusRequest; - ueContextModifyReq->protocolIEs.list.array[ieIdx]->criticality = Criticality_ignore; - ueContextModifyReq->protocolIEs.list.array[ieIdx]->value.present = UEContextModificationRequestIEs__value_PR_RRCDeliveryStatusRequest; - ueContextModifyReq->protocolIEs.list.array[ieIdx]->value.choice.RRCDeliveryStatusRequest = RRCDeliveryStatusRequest_true; + if(ueCb->state != UE_HANDOVER_IN_PROGRESS) + { + ieIdx++; + ueContextModifyReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_ID_id_RRCDeliveryStatusRequest; + ueContextModifyReq->protocolIEs.list.array[ieIdx]->criticality = Criticality_ignore; + ueContextModifyReq->protocolIEs.list.array[ieIdx]->value.present = UEContextModificationRequestIEs__value_PR_RRCDeliveryStatusRequest; + ueContextModifyReq->protocolIEs.list.array[ieIdx]->value.choice.RRCDeliveryStatusRequest = RRCDeliveryStatusRequest_true; + } } #ifdef NR_DRX @@ -11614,17 +11855,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; } } } @@ -11706,7 +11947,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; @@ -11716,6 +11957,10 @@ uint8_t procUeContextModificationResponse(uint32_t duId, F1AP_PDU_t *f1apMsg) 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++) { @@ -11723,13 +11968,35 @@ uint8_t procUeContextModificationResponse(uint32_t duId, F1AP_PDU_t *f1apMsg) { 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) + { + duUeF1apId = ueCtxtModRsp->protocolIEs.list.array[idx]->value.choice.GNB_DU_UE_F1AP_ID; + ueCb = &duDb->ueCb[duUeF1apId-1]; + + /* In case UE context modification response is received at source GNB CU from source GNB DU + * for a UE in handover, send HO request to target GNB only if not sent already. + * If HO Req is already sent to target GNB, and an HO Req Ack is received, then + * ueCb->hoInfo.cuUeF1apIdTgt will be non-zero + */ + if((ueCb->state == UE_HANDOVER_IN_PROGRESS) && (ueCb->hoInfo.HOType == Xn_Based_Inter_CU_HO) && \ + (ueCb->hoInfo.cuUeF1apIdTgt == 0)) + { + BuildAndSendHOReq(ueCb, recvBuf, recvBufLen); + } + } break; } case ProtocolIE_ID_id_DRBs_SetupMod_List: @@ -11739,6 +12006,11 @@ uint8_t procUeContextModificationResponse(uint32_t duId, F1AP_PDU_t *f1apMsg) break; } + case ProtocolIE_ID_id_DRBs_Modified_List: + { + DU_LOG("\nINFO --> Received DRBs Modified List"); + break; + } case ProtocolIE_ID_id_SRBs_SetupMod_List: { procSrbSetupModList(ueCb, &ueCtxtModRsp->protocolIEs.list.array[idx]->value.choice.SRBs_SetupMod_List); @@ -11764,10 +12036,20 @@ uint8_t procUeContextModificationResponse(uint32_t duId, F1AP_PDU_t *f1apMsg) if(ueCb->state == UE_HANDOVER_IN_PROGRESS) { uint8_t ueIdx = 0; + uint8_t tgtDuId = 0; DuDb *tgtDuDb = NULLP; CuUeCb *ueCbInTgtDu = NULLP; - SEARCH_DU_DB(duIdx, ueCb->hoInfo.targetDuId, tgtDuDb); + if(ueCb->hoInfo.HOType == Inter_DU_HO) + { + tgtDuId = ueCb->hoInfo.tgtNodeId; + } + else if (ueCb->hoInfo.HOType == Xn_Based_Inter_CU_HO) + { + tgtDuId = duId; + } + + SEARCH_DU_DB(duIdx, tgtDuId, tgtDuDb); if(tgtDuDb) { /* Since DU UE F1AP ID assigned by target DU to this UE in handover is @@ -11782,11 +12064,11 @@ uint8_t procUeContextModificationResponse(uint32_t duId, F1AP_PDU_t *f1apMsg) } } - /* If UE context is not found in Target DU DU, send UE context setup + /* If UE context is not found in Target DU, send UE context setup * request */ if(ueCbInTgtDu == NULLP) { - if((BuildAndSendUeContextSetupReq(ueCb->hoInfo.targetDuId, ueCb)) != ROK) + if((BuildAndSendUeContextSetupReq(tgtDuId, ueCb)) != ROK) { DU_LOG("\nERROR -> F1AP : Failed at BuildAndSendUeContextSetupReq"); return RFAILED; @@ -11794,7 +12076,11 @@ uint8_t procUeContextModificationResponse(uint32_t duId, F1AP_PDU_t *f1apMsg) } } } - + +#ifdef START_DL_UL_DATA + startDlData(); +#endif + return ROK; } @@ -11826,6 +12112,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++) { @@ -12161,6 +12451,11 @@ uint8_t BuildAndSendPagingMsg(uint64_t gsTmsi, uint8_t duId) DU_LOG("\nERROR --> F1AP : BuildAndSendPagingMsg(): DuDb is empty"); return ret; } + if(duDb->numCells == 0) + { + DU_LOG("\nERROR --> F1AP : BuildAndSendPagingMsg(): No CELL is UP!"); + return ret; + } while(true) { @@ -12328,7 +12623,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 * @@ -12336,61 +12631,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) { @@ -12464,13 +12784,13 @@ 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: { DU_LOG("\nINFO --> F1AP : UE Context Modification Response received"); - procUeContextModificationResponse(*duId, f1apMsg); + procUeContextModificationResponse(*duId, f1apMsg, recvBuf, recvBufLen); break; } case SuccessfulOutcome__value_PR_UEContextReleaseComplete: @@ -12495,6 +12815,7 @@ void F1APMsgHdlr(uint32_t *duId, Buffer *mBuf) } }/* End of switch(f1apMsg->present) */ + CU_FREE(recvBuf, (Size)(recvBufLen)); } /* End of F1APMsgHdlr */ /**********************************************************************