+*
+* @brief free the memory allocated by decoder
+*
+* @details
+*
+* Function : freeAperDecodeULTnlInfo
+*
+* Functionality: added free part for the memory allocated by aper_decoder
+*
+* @params[in] ULUPTNLInformation_ToBeSetup_List_t *ulInfo
+* @return void
+*
+* ****************************************************************/
+
+
+void freeAperDecodeULTnlInfo(ULUPTNLInformation_ToBeSetup_List_t *ulInfo)
+{
+ uint8_t ulIdx=0;
+ if(ulInfo->list.array != NULLP)
+ {
+ for(ulIdx=0; ulIdx<ulInfo->list.count; ulIdx++)
+ {
+ if(ulIdx==0&&ulInfo->list.array[ulIdx]!=NULLP)
+ {
+ if(ulInfo->list.array[ulIdx]->uLUPTNLInformation.choice.gTPTunnel!=NULLP)
+ {
+ if(ulInfo->list.array[ulIdx]->uLUPTNLInformation.choice.gTPTunnel->\
+ transportLayerAddress.buf != NULLP)
+ {
+ if(ulInfo->list.array[ulIdx]->uLUPTNLInformation.choice.gTPTunnel->gTP_TEID.buf\
+ !=NULLP)
+ {
+ free(ulInfo->list.array[ulIdx]->uLUPTNLInformation.choice.gTPTunnel->gTP_TEID.buf);
+ }
+ free(ulInfo->list.array[ulIdx]->uLUPTNLInformation.choice.gTPTunnel->\
+ transportLayerAddress.buf);
+ }
+ free(ulInfo->list.array[ulIdx]->uLUPTNLInformation.choice.gTPTunnel);
+ }
+ }
+ if(ulInfo->list.array[ulIdx]!=NULLP)
+ {
+ free(ulInfo->list.array[ulIdx]);
+ }
+ }
+ free(ulInfo->list.array);
+ }
+}
+/*******************************************************************
+*
+* @brief free the memory allocated by decoder
+*
+* @details
+*
+* Function : freeAperDecodeDRBSetup
+*
+* Functionality: free DRBSetup which is allocated by decoder
+*
+* @params[in] DRBs_ToBeSetup_List_t *drbSet
+* @return void
+*
+* ****************************************************************/
+
+void freeAperDecodeDRBSetup(DRBs_ToBeSetup_List_t *drbSet)
+{
+ DRBs_ToBeSetup_Item_t *drbSetItem = NULLP;
+ uint8_t flowIdx =0;
+ uint8_t drbIdx =0;
+
+ if(drbSet->list.array != NULLP)
+ {
+ for(drbIdx=0; drbIdx<drbSet->list.count; drbIdx++)
+ {
+ if(drbIdx==0&&drbSet->list.array[drbIdx] != NULLP)
+ {
+ drbSetItem =&drbSet->list.array[drbIdx]->value.choice.DRBs_ToBeSetup_Item;
+ if(drbSetItem->qoSInformation.choice.choice_extension != NULLP)
+ {
+ if(drbSetItem->qoSInformation.choice.choice_extension->value.choice.DRB_Information.dRB_QoS.\
+ qoS_Characteristics.choice.non_Dynamic_5QI !=NULLP)
+ {
+ if(drbSetItem->qoSInformation.choice.choice_extension->value.choice.DRB_Information.dRB_QoS.\
+ qoS_Characteristics.choice.non_Dynamic_5QI->averagingWindow!=NULLP)
+ {
+ if(drbSetItem->qoSInformation.choice.choice_extension->value.choice.DRB_Information.dRB_QoS.\
+ qoS_Characteristics.choice.non_Dynamic_5QI->maxDataBurstVolume!=NULLP)
+ {
+
+ if(drbSetItem->qoSInformation.choice.choice_extension->value.choice.DRB_Information.sNSSAI.sST.buf!=NULLP)
+ {
+
+ if(drbSetItem->qoSInformation.choice.choice_extension->value.choice.DRB_Information.sNSSAI.sD!=NULLP)
+ {
+
+ if(drbSetItem->qoSInformation.choice.choice_extension->value.choice.DRB_Information.sNSSAI.sD->\
+ buf!=NULLP)
+ {
+
+ if(drbSetItem->qoSInformation.choice.choice_extension->value.choice.DRB_Information.\
+ flows_Mapped_To_DRB_List.list.array != NULLP)
+ {
+
+ for(flowIdx=0;flowIdx<drbSetItem->qoSInformation.choice.choice_extension->value.choice.\
+ DRB_Information.flows_Mapped_To_DRB_List.list.count; flowIdx++)
+ {
+
+ if(flowIdx==0&&drbSetItem->qoSInformation.choice.choice_extension->value.choice.\
+ DRB_Information.flows_Mapped_To_DRB_List.list.array[flowIdx]!=NULLP)
+ {
+ if(drbSetItem->qoSInformation.choice.choice_extension->value.choice.\
+ DRB_Information.flows_Mapped_To_DRB_List.list.array[flowIdx]->\
+ qoSFlowLevelQoSParameters.\
+ qoS_Characteristics.choice.non_Dynamic_5QI!=NULLP)
+ {
+ if(drbSetItem->qoSInformation.choice.choice_extension->value.choice.\
+ DRB_Information.flows_Mapped_To_DRB_List.list.array[flowIdx]->\
+ qoSFlowLevelQoSParameters.\
+ qoS_Characteristics.choice.non_Dynamic_5QI->averagingWindow!=NULLP)
+ {
+
+ if(drbSetItem->qoSInformation.choice.choice_extension->value.choice.\
+ DRB_Information.flows_Mapped_To_DRB_List.list.array[flowIdx]->\
+ qoSFlowLevelQoSParameters.\
+ qoS_Characteristics.choice.non_Dynamic_5QI->maxDataBurstVolume!=NULLP)
+ {
+
+
+ free(drbSetItem->qoSInformation.choice.choice_extension->value.choice.\
+ DRB_Information.flows_Mapped_To_DRB_List.list.array[flowIdx]->\
+ qoSFlowLevelQoSParameters.\
+ qoS_Characteristics.choice.non_Dynamic_5QI->maxDataBurstVolume);
+ }
+
+ free(drbSetItem->qoSInformation.choice.choice_extension->value.choice.\
+ DRB_Information.flows_Mapped_To_DRB_List.list.array[flowIdx]->\
+ qoSFlowLevelQoSParameters.\
+ qoS_Characteristics.choice.non_Dynamic_5QI->averagingWindow);
+ }
+
+ free(drbSetItem->qoSInformation.choice.choice_extension->value.choice.\
+
+ DRB_Information.flows_Mapped_To_DRB_List.list.array[flowIdx]->\
+ qoSFlowLevelQoSParameters.\
+ qoS_Characteristics.choice.non_Dynamic_5QI);
+ }
+ }
+ if(drbSetItem->qoSInformation.choice.choice_extension->value.choice.\
+ DRB_Information.flows_Mapped_To_DRB_List.list.array[flowIdx]!=NULLP)
+ {
+
+ free(drbSetItem->qoSInformation.choice.choice_extension->value.choice.\
+ DRB_Information.flows_Mapped_To_DRB_List.list.array[flowIdx]);
+ }
+ }
+
+ free(drbSetItem->qoSInformation.choice.choice_extension->value.choice.\
+ DRB_Information.flows_Mapped_To_DRB_List.list.array);
+ }
+
+ free(drbSetItem->qoSInformation.choice.choice_extension->value.choice.\
+ DRB_Information.sNSSAI.sD->buf);
+ }
+
+ free(drbSetItem->qoSInformation.choice.choice_extension->value.choice.DRB_Information.sNSSAI.sD);
+ }
+
+ free(drbSetItem->qoSInformation.choice.choice_extension->value.choice.DRB_Information.sNSSAI.sST.buf);
+
+ }
+
+ free(drbSetItem->qoSInformation.choice.choice_extension->value.choice.DRB_Information.dRB_QoS.\
+
+ qoS_Characteristics.choice.non_Dynamic_5QI->maxDataBurstVolume);
+ }
+
+ free(drbSetItem->qoSInformation.choice.choice_extension->value.choice.DRB_Information.dRB_QoS.\
+ qoS_Characteristics.choice.non_Dynamic_5QI->averagingWindow);
+ }
+
+ free(drbSetItem->qoSInformation.choice.choice_extension->value.choice.DRB_Information.dRB_QoS.\
+ qoS_Characteristics.choice.non_Dynamic_5QI);
+ }
+ free(drbSetItem->qoSInformation.choice.choice_extension);
+ }
+ freeAperDecodeULTnlInfo(&drbSetItem->uLUPTNLInformation_ToBeSetup_List);
+ if(drbSetItem->uLConfiguration)
+ {
+ free(drbSetItem->uLConfiguration);
+ }
+ }
+ if(drbSet->list.array[drbIdx]!=NULLP)
+ {
+ free(drbSet->list.array[drbIdx]);
+ }
+ }
+ free(drbSet->list.array);
+ }
+}
+
+
+/*******************************************************************
+ *
+ * @brief builds Mac Cell Cfg
+ *
+ * @details
+ *
+ * Function : procUeReCfgCellInfo
+ *
+ * Functionality: builds Mac Cell Cfg
+ *
+ * @params[in] MacUeCfg *macUeCfgToSend = Used to Store the information which
+ * needs to send in other layer, as well as this can be
+ * the variable which stores the information in DuCb.
+ * MacUeCfg *storedMacUeCfg = Null in case of sending the
+ * information to other layer else it will have copyOfmacUeCfg
+ * which we have stored in F1UeContextSetupDb
+ * void *cellInfo = CellGroupConfigRrc_t information which is send
+ * by CU, which we have stored in F1UeContextSetupDb
+ *
+ * @return void
+ *
+ * ****************************************************************/
+uint8_t procUeReCfgCellInfo(MacUeCfg *macUeCfgToSend,MacUeCfg *storedMacUeCfg, void *cellInfo)
+{
+ uint8_t ret = ROK;
+ CellGroupConfigRrc_t *cellGrp = NULLP;
+
+ if(cellInfo)
+ {
+ cellGrp = (CellGroupConfigRrc_t *)cellInfo;
+ ret = extractUeReCfgCellInfo(cellGrp, macUeCfgToSend, storedMacUeCfg);
+ if(ret == RFAILED)
+ DU_LOG("\nERROR --> F1AP : Failed at procUeReCfgCellInfo()");
+ }
+ if(ret == RFAILED)
+ {
+ freeUeReCfgCellGrpInfo(macUeCfgToSend);
+ }
+ return ret;
+}
+
+/*******************************************************************
+ *
+ * @brief Filling modulation info in mac ue cfg
+ *
+ * @details
+ *
+ * Function : duFillModulationDetails
+ *
+ * Functionality: Filling modulation info in mac ue cfg
+ *
+ * @params[in] MAC UE Config to be updated
+ * Current UE configuration
+ * UE NR capability from CU
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ * ****************************************************************/
+void duFillModulationDetails(MacUeCfg *ueCfg, MacUeCfg *oldUeCfg, void *ueCap)
+{
+ UE_NR_Capability_t *ueNrCap=NULLP;
+
+ if(!ueCap)
+ {
+ memcpy(&ueCfg->dlModInfo, &oldUeCfg->dlModInfo, sizeof(ModulationInfo));
+ memcpy(&ueCfg->ulModInfo, &oldUeCfg->ulModInfo, sizeof(ModulationInfo));
+ }
+ else
+ {
+ ueNrCap = (UE_NR_Capability_t *)ueCap;
+
+ /* Filling DL modulation info */
+ if(ueNrCap->featureSets && ueNrCap->featureSets->featureSetsDownlinkPerCC && \
+ ueNrCap->featureSets->featureSetsDownlinkPerCC->list.array[0] && \
+ ueNrCap->featureSets->featureSetsDownlinkPerCC->list.array[0]->supportedModulationOrderDL)
+ {
+ switch(*(ueNrCap->featureSets->featureSetsDownlinkPerCC->list.array[0]->supportedModulationOrderDL))
+ {
+ case ModulationOrder_qpsk:
+ {
+ ueCfg->dlModInfo.modOrder = MOD_ORDER_QPSK;
+ break;
+ }
+ case ModulationOrder_qam16:
+ {
+ ueCfg->dlModInfo.modOrder = MOD_ORDER_QAM16;
+ break;
+ }
+ case ModulationOrder_qam64:
+ {
+ ueCfg->dlModInfo.modOrder = MOD_ORDER_QAM64;
+ ueCfg->dlModInfo.mcsIndex = PDSCH_MCS_INDEX;
+ ueCfg->dlModInfo.mcsTable = MCS_TABLE_QAM64;
+ break;
+ }
+ case ModulationOrder_qam256:
+ {
+ ueCfg->dlModInfo.modOrder = MOD_ORDER_QAM256;
+ break;
+ }
+ default:
+ {
+ DU_LOG("\nERROR --> DU APP: Incorrect downlink modulation order received. Reatining old modulation configuration");
+ memcpy(&ueCfg->dlModInfo, &oldUeCfg->dlModInfo, sizeof(ModulationInfo));
+ break;
+ }
+ }
+ }
+ else
+ {
+ memcpy(&ueCfg->dlModInfo, &oldUeCfg->dlModInfo, sizeof(ModulationInfo));
+ }
+
+ /* Filling UL modulation info */
+ if(ueNrCap->featureSets && ueNrCap->featureSets->featureSetsUplinkPerCC && \
+ ueNrCap->featureSets->featureSetsUplinkPerCC->list.array[0] && \
+ ueNrCap->featureSets->featureSetsUplinkPerCC->list.array[0]->supportedModulationOrderUL)
+ {
+ switch(*(ueNrCap->featureSets->featureSetsUplinkPerCC->list.array[0]->supportedModulationOrderUL))
+ {
+ case ModulationOrder_qpsk:
+ {
+ ueCfg->ulModInfo.modOrder = MOD_ORDER_QPSK;
+ break;
+ }
+ case ModulationOrder_qam16:
+ {
+ ueCfg->ulModInfo.modOrder = MOD_ORDER_QAM16;
+ ueCfg->ulModInfo.mcsIndex = PUSCH_MCS_INDEX;
+ ueCfg->ulModInfo.mcsTable = MCS_TABLE_QAM64;
+ break;
+ }
+ case ModulationOrder_qam64:
+ {
+ ueCfg->ulModInfo.modOrder = MOD_ORDER_QAM64;
+ break;
+ }
+ case ModulationOrder_qam256:
+ {
+ ueCfg->ulModInfo.modOrder = MOD_ORDER_QAM256;
+ break;
+ }
+ default:
+ {
+ DU_LOG("\nERROR --> DU APP: Incorrect uplink modulation order received. Reatining old modulation configuration");
+ memcpy(&ueCfg->ulModInfo, &oldUeCfg->ulModInfo, sizeof(ModulationInfo));
+ break;
+ }
+ }
+ }
+ else
+ {
+ memcpy(&ueCfg->ulModInfo, &oldUeCfg->ulModInfo, sizeof(ModulationInfo));
+ }
+ }
+}
+
+/*******************************************************************
+ *
+ * @brief Function to extract cellGrp Info present in cutoDu cont
+ *
+ * @details
+ *
+ * Function : extractCellGrpInfo
+ *
+ * Functionality: Function to extract cellGrp Info present
+ * in cutoDu cont
+ *
+ * @params[in] ProtocolExtensionContainer_4624P16_t pointer
+ *
+ * @return CellGroupConfigRrc_t *
+ *
+ * ****************************************************************/
+
+CellGroupConfigRrc_t *extractCellGrpInfo(ProtocolExtensionContainer_4624P16_t *protocolIeExtn,\
+ DuUeCfg *ueCfgDb)
+{
+ uint8_t idx2 =0;
+ uint16_t id =0;
+ uint16_t recvBufLen =0;
+ CellGroupConfigRrc_t *cellGrpCfg = NULLP;
+ CUtoDURRCInformation_ExtIEs_t *extIeInfo = NULLP;
+ asn_dec_rval_t rval; /* Decoder return value */
+ memset(&rval, 0, sizeof(asn_dec_rval_t));
+
+ if(protocolIeExtn)
+ {
+ for(idx2 = 0; idx2 < protocolIeExtn->list.count; idx2++)
+ {
+ extIeInfo = ((CUtoDURRCInformation_ExtIEs_t *)(protocolIeExtn->list.array[idx2]));
+ id = extIeInfo->id;
+ switch(id)
+ {
+ case ProtocolIE_ID_id_CellGroupConfig:
+ {
+ recvBufLen = extIeInfo->extensionValue.choice.CellGroupConfig.size;
+ /* decoding the CellGroup Buf received */
+ DU_ALLOC(cellGrpCfg, sizeof(CellGroupConfigRrc_t));
+ if(cellGrpCfg)
+ {
+ memset(cellGrpCfg, 0, sizeof(CellGroupConfigRrc_t));
+ rval = aper_decode(0, &asn_DEF_CellGroupConfigRrc, (void **)&cellGrpCfg,
+ extIeInfo->extensionValue.choice.CellGroupConfig.buf, recvBufLen, 0, 0);
+ if(rval.code == RC_FAIL || rval.code == RC_WMORE)
+ {
+ DU_LOG("\nERROR --> F1AP : ASN decode failed at decodeCellGrpCfg()");
+ return NULLP;
+ }
+ xer_fprint(stdout, &asn_DEF_CellGroupConfigRrc, cellGrpCfg);
+ if(extractRlcCfgToAddMod(cellGrpCfg->rlc_BearerToAddModList, ueCfgDb))
+ return NULLP;
+ }
+ break;
+ }
+ default:
+ DU_LOG("\nERROR --> F1AP : Invalid IE received CUtoDURRCInformation:%d at decodeCellGrpCfg()", id);
+ break;
+ }
+ }
+ }
+ return cellGrpCfg;
+}
+
+/*******************************************************************
+ *
+ * @brief Fills Srb List received by CU
+ *
+ * @details
+ *
+ * Function : procSrbListToSetup
+ *
+ * Functionality: Fills Srb List received by CU
+ *
+ * @params[in] SRBs_ToBeSetup_Item_t *cuSrbItem
+ * LcCfg pointer
+ * RlcBearerCfg pointer
+ * @return void
+ *
+ * ****************************************************************/
+uint8_t procSrbListToSetup(SRBs_ToBeSetup_Item_t * srbItem, LcCfg *macLcToAdd, RlcBearerCfg *rlcLcToAdd)
+{
+ uint8_t ret = ROK;
+
+ /* Filling RLC INFO */
+ procRlcLcCfg(srbItem->sRBID, srbItem->sRBID, RB_TYPE_SRB, RLC_AM, CONFIG_ADD, NULL, rlcLcToAdd);
+
+ /* Filling MAC INFO */
+ ret = procMacLcCfg(srbItem->sRBID, RB_TYPE_SRB, CONFIG_ADD, NULL,NULL, NULL, macLcToAdd, NULL);
+ if(ret == RFAILED)
+ {
+ DU_LOG("\nERROR --> F1AP : Failed at MAC LC Cfg in procSrbListToSetup()");
+ return ret;
+ }
+ return ret;
+}
+
+
+
+/*******************************************************************
+ *
+ * @brief extract Srb List received by CU
+ *
+ * @details
+ *
+ * Function : extractSrbListToSetup
+ *
+ * Functionality: extract Srb List received by CU
+ * for both MAC and RLC
+ *
+ * @params[in] SRBs_ToBeSetup_Item_t pointer
+ * DuUeCfg pointer
+ * @return ROK/RFAIED
+ *
+ * ****************************************************************/
+
+uint8_t extractSrbListToSetup(SRBs_ToBeSetup_List_t *srbCfg, DuUeCfg *ueCfgDb)
+{
+ uint8_t ret, srbIdx;
+ SRBs_ToBeSetup_Item_t *srbItem = NULLP;
+
+ if(srbCfg)
+ {
+ for(srbIdx = 0; srbIdx < srbCfg->list.count; srbIdx++)
+ {
+ srbItem = &srbCfg->list.array[srbIdx]->value.choice.SRBs_ToBeSetup_Item;
+ if(ueCfgDb->numMacLcs > MAX_NUM_LC)
+ {
+ DU_LOG("\nERROR --> F1AP: MAX LC Reached in MAC");
+ ret = RFAILED;
+ break;
+ }
+ if(ueCfgDb->numRlcLcs > MAX_NUM_LC)
+ {
+ DU_LOG("\nERROR --> F1AP: MAX LC Reached in RLC");
+ ret = RFAILED;
+ break;
+ }
+ memset(&ueCfgDb->macLcCfg[ueCfgDb->numMacLcs], 0, sizeof(LcCfg));
+ memset(&ueCfgDb->rlcLcCfg[ueCfgDb->numRlcLcs], 0, sizeof(RlcBearerCfg));
+ ret = procSrbListToSetup(srbItem, &ueCfgDb->macLcCfg[ueCfgDb->numMacLcs],\
+ &ueCfgDb->rlcLcCfg[ueCfgDb->numRlcLcs]);
+ ueCfgDb->numRlcLcs++;
+ ueCfgDb->numMacLcs++;
+ DU_LOG("\nDEBUG --> DUAPP: extractSrbListToSetup: SRBID: %d [RLC,MAC,NumDrb]:[%x,%x,%x]",\
+ srbItem->sRBID, ueCfgDb->numRlcLcs, ueCfgDb->numMacLcs, ueCfgDb->numDrb);
+ if(ret == RFAILED)
+ {
+ DU_LOG("\nERROR --> F1AP: Failed at extractSrbListToSetup()");
+ break;
+ }
+ }
+ }
+ else
+ ret = RFAILED;
+
+ return ret;
+}
+
+/*******************************************************************
+ *
+ * @brief Fills Drb List received by CU
+ *
+ * @details
+ *
+ * Function : procDrbListToSetup
+ *
+ * Functionality: Fills Drb List received by CU
+ * for both MAC and RLC
+ *
+ * @params[in] SRBs_ToBeSetup_Item_t pointer
+ * LcCfg pointer,
+ * RlcBearerCfg pointer
+ * @return void
+ *
+ * ****************************************************************/
+
+uint8_t procDrbListToSetup(uint8_t lcId, DRBs_ToBeSetup_Item_t *drbItem,\
+DRBs_ToBeSetupMod_Item_t *drbSetupModItem, LcCfg *macLcToAdd, RlcBearerCfg *rlcLcToAdd, UpTnlCfg *upTnlInfo)
+{
+
+ if(drbItem != NULLP)
+ {
+ /* Filling RLC INFO */
+ procRlcLcCfg(drbItem->dRBID, lcId, RB_TYPE_DRB, drbItem->rLCMode, CONFIG_ADD, NULL, rlcLcToAdd);
+
+ /* Filling MAC INFO */
+ if(procMacLcCfg(lcId, RB_TYPE_DRB, CONFIG_ADD, drbItem, NULL, NULL, macLcToAdd, upTnlInfo) != ROK)
+ {
+ DU_LOG("\nERROR --> F1AP : Failed at RLC LC Cfg in procDrbListToSetup()");
+ return RFAILED;
+ }
+ }
+ else if(drbSetupModItem != NULLP)
+ {
+ procRlcLcCfg(drbSetupModItem->dRBID, lcId, RB_TYPE_DRB, drbSetupModItem->rLCMode, CONFIG_ADD, NULL, rlcLcToAdd);
+
+ if(procMacLcCfg(lcId, RB_TYPE_DRB, CONFIG_ADD, NULL, drbSetupModItem, NULL, macLcToAdd, upTnlInfo) != ROK)
+ {
+ DU_LOG("\nERROR --> F1AP : Failed at RLC LC Cfg in procDrbListToSetup()");
+ return RFAILED;
+ }
+ }
+ return ROK;
+}
+
+/*******************************************************************
+ *
+ * @brief extract Drb List received by CU
+ *
+ * @details
+ *
+ * Function : extractDrbListToSetup
+ *
+ * Functionality: extract Drb List received by CU
+ * for both MAC and RLC
+ *
+ * @params[in] DRBs_ToBeSetup_Item_t pointer
+ * DuUeCfg pointer
+ * @return ROK/RFAIED
+ *
+ * ****************************************************************/
+
+uint8_t extractDrbListToSetup(DRBs_ToBeSetup_List_t *drbCfg,DRBs_ToBeSetupMod_List_t *drbSetupModCfg,\
+uint8_t drbCount, DuUeCfg *ueCfgDb, uint32_t *drbBitMap)
+{
+ uint8_t ret, drbIdx, lcId = 0;
+ DRBs_ToBeSetup_Item_t *drbItem = NULLP;
+ DRBs_ToBeSetupMod_ItemIEs_t *drbSetupModItem = NULLP;
+
+ ret = ROK;
+ if(drbCount > 0)
+ {
+ for(drbIdx = 0; drbIdx < drbCount; drbIdx++)
+ {
+ if(ueCfgDb->numMacLcs > MAX_NUM_LC)
+ {
+ DU_LOG("\nERROR --> F1AP : MAX LC Reached in MAC at extractDrbListToSetup()");
+ ret = RFAILED;
+ break;
+ }
+ if(ueCfgDb->numRlcLcs > MAX_NUM_LC)
+ {
+ DU_LOG("\nERROR --> F1AP : MAX LC Reached in RLC at extractDrbListToSetup()");
+ ret = RFAILED;
+ break;
+ }
+ memset(&ueCfgDb->macLcCfg[ueCfgDb->numMacLcs], 0, sizeof(LcCfg));
+ memset(&ueCfgDb->rlcLcCfg[ueCfgDb->numRlcLcs], 0, sizeof(RlcBearerCfg));
+
+ lcId = getDrbLcId(drbBitMap);
+ if(lcId == RFAILED)
+ {
+ DU_LOG("\nERROR --> F1AP : InCorrect LCID extractDrbListToSetup()");
+ ret = RFAILED;
+ break;
+ }
+ if(drbCfg != NULL)
+ {
+ drbItem = &drbCfg->list.array[drbIdx]->value.choice.DRBs_ToBeSetup_Item;
+ ret = procDrbListToSetup(lcId, drbItem, NULL, &ueCfgDb->macLcCfg[ueCfgDb->numMacLcs],\
+ &ueCfgDb->rlcLcCfg[ueCfgDb->numRlcLcs], &ueCfgDb->upTnlInfo[ueCfgDb->numDrb]);
+ if(ret == RFAILED)
+ {
+ DU_LOG("\nERROR --> F1AP : Failed at extractDrbListToSetup()");
+ break;
+ }
+ }
+ else if(drbSetupModCfg != NULL)
+ {
+ drbSetupModItem = (DRBs_ToBeSetupMod_ItemIEs_t *) drbSetupModCfg->list.array[drbIdx];
+ ret = procDrbListToSetup(lcId, NULL, &(drbSetupModItem->value.choice.DRBs_ToBeSetupMod_Item) ,\
+ &ueCfgDb->macLcCfg[ueCfgDb->numMacLcs], &ueCfgDb->rlcLcCfg[ueCfgDb->numRlcLcs],\
+ &ueCfgDb->upTnlInfo[ueCfgDb->numDrb]);
+ if(ret == RFAILED)
+ {
+ DU_LOG("\nERROR --> F1AP : Failed at extractDrbListToSetup()");
+ break;
+ }
+ }
+ ueCfgDb->numRlcLcs++;
+ ueCfgDb->numMacLcs++;
+ ueCfgDb->numDrb++;
+
+ DU_LOG("\nDEBUG --> DUAPP: extractDrbListToSetup:lcId:%x ,BitMap:%x, [RLC,MAC,NumDrb]:[%x,%x,%x]",\
+ lcId,*drbBitMap, ueCfgDb->numRlcLcs, ueCfgDb->numMacLcs, ueCfgDb->numDrb);
+ if(ret == RFAILED)
+ {
+ DU_LOG("\nERROR --> F1AP : Failed at extractDrbListToSetup()");
+ break;
+ }
+ }
+ }
+ else
+ ret = RFAILED;
+
+ return ret;
+}
+
+/*******************************************************************
+ *
+ * @brief Function to extract Dl RRC Msg received from CU
+ *
+ * @details
+ *
+ * Function : extractDlRrcMsg
+ *
+ * Functionality: Function to extract Dl RRC Msg received from CU
+ *
+ * @params[in] F1AP message
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ * ****************************************************************/
+
+uint8_t extractDlRrcMsg(uint32_t gnbDuUeF1apId, uint32_t gnbCuUeF1apId, \
+ F1DlRrcMsg *dlRrcMsg, RRCContainer_t *rrcContainer)
+{
+ uint8_t ret = ROK;
+ dlRrcMsg->rrcMsgSize = rrcContainer->size;
+ if(dlRrcMsg->rrcMsgSize > 0)
+ {
+ DU_ALLOC_SHRABL_BUF(dlRrcMsg->rrcMsgPdu, dlRrcMsg->rrcMsgSize);
+ if(!dlRrcMsg->rrcMsgPdu)
+ {
+ DU_LOG("\nERROR --> DU APP : Memory allocation failed for RRC Msg in extractDlRrcMsg()");
+ ret = RFAILED;
+ }
+ else
+ {
+ dlRrcMsg->gnbDuUeF1apId = gnbDuUeF1apId;
+ dlRrcMsg->gnbCuUeF1apId = gnbCuUeF1apId;
+ dlRrcMsg->srbId = SRB1_LCID;
+ memcpy(dlRrcMsg->rrcMsgPdu, rrcContainer->buf, dlRrcMsg->rrcMsgSize);
+ }
+ }
+ return ret;
+}
+
+/*******************************************************************
+ *
+ * @brief Extract UE capability info
+ *
+ * @details
+ *
+ * Function : extractUeCapability
+ *
+ * Functionality: Extract UE capability info and stores in ue Cb
+ *
+ * @params[in] Octet string of UE capability RAT container list
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ * ****************************************************************/
+UE_NR_Capability_t *extractUeCapability(UE_CapabilityRAT_ContainerList_t *ueCapablityListBuf, DuUeCb *ueCb)
+{
+ uint8_t idx;
+ uint16_t recvBufLen;
+ asn_dec_rval_t rval;
+ UE_NR_Capability_t *ueNrCap = NULLP;
+ UE_CapabilityRAT_ContainerListRRC_t *ueCapRatContList = NULLP;
+
+ /* Decoding UE Capability RAT Container List */
+ recvBufLen = ueCapablityListBuf->size;
+ DU_ALLOC(ueCapRatContList, sizeof(UE_CapabilityRAT_ContainerListRRC_t));
+ if(!ueCapRatContList)
+ {
+ DU_LOG("\nERROR --> F1AP : Memory allocation failed in extractUeCapability");
+ return NULLP;
+ }
+ memset(ueCapRatContList, 0, sizeof(UE_CapabilityRAT_ContainerListRRC_t));
+ memset(&rval, 0, sizeof(asn_dec_rval_t));
+ rval = aper_decode(0, &asn_DEF_UE_CapabilityRAT_ContainerListRRC, (void **)&ueCapRatContList,
+ ueCapablityListBuf->buf, recvBufLen, 0, 0);
+ if(rval.code == RC_FAIL || rval.code == RC_WMORE)
+ {
+ DU_LOG("\nERROR --> F1AP : ASN decode failed at decodeCellGrpCfg()");
+ return NULLP;
+ }
+ xer_fprint(stdout, &asn_DEF_UE_CapabilityRAT_ContainerListRRC, ueCapRatContList);
+
+ /* Free encoded buffer after decoding */
+
+ for(idx = 0; idx < ueCapRatContList->list.count; idx++)
+ {
+ if(ueCapRatContList->list.array[idx]->rat_Type == RAT_Type_nr)
+ {
+ /* Decoding UE NR Capability */
+ recvBufLen = ueCapRatContList->list.array[idx]->ue_CapabilityRAT_Container.size;
+ DU_ALLOC(ueNrCap, sizeof(UE_NR_Capability_t));
+ if(!ueNrCap)
+ {
+ DU_LOG("\nERROR --> F1AP : Memory allocation failed in extractUeCapability");
+ DU_FREE(ueCapRatContList, sizeof(UE_CapabilityRAT_ContainerListRRC_t));
+ return NULLP;
+ }
+ memset(ueNrCap, 0, sizeof(UE_NR_Capability_t));
+ memset(&rval, 0, sizeof(asn_dec_rval_t));
+ rval = aper_decode(0, &asn_DEF_UE_NR_Capability, (void **)&ueNrCap,
+ ueCapRatContList->list.array[idx]->ue_CapabilityRAT_Container.buf, recvBufLen, 0, 0);
+ if(rval.code == RC_FAIL || rval.code == RC_WMORE)
+ {
+ DU_LOG("\nERROR --> F1AP : ASN decode failed at decodeCellGrpCfg()");
+ return NULLP;
+ }
+ xer_fprint(stdout, &asn_DEF_UE_NR_Capability, ueNrCap);
+
+ /* Free encoded buffer after decoding */
+ free(ueCapRatContList->list.array[idx]->ue_CapabilityRAT_Container.buf);
+ }
+ free(ueCapRatContList->list.array[idx]);
+ }
+
+ /* Free Memory*/
+ free(ueCapRatContList->list.array);
+ DU_FREE(ueCapRatContList, sizeof(UE_CapabilityRAT_ContainerListRRC_t));
+ return ueNrCap;
+}
+
+/*******************************************************************
+*
+* @brief free UE context setup request from CU
+*
+* @details
+*
+* Function : freeAperDecodeF1UeContextSetupReq
+*
+* Functionality: freeing part for the memory allocated by aper_decoder
+*
+* @params[in] F1AP message
+* @return ROK - success
+* RFAILED - failure
+*
+* ****************************************************************/
+void freeAperDecodeF1UeContextSetupReq(UEContextSetupRequest_t *ueSetReq)
+{
+ uint8_t ieIdx = 0;
+
+ if(ueSetReq->protocolIEs.list.array != NULLP)
+ {
+ for(ieIdx = 0; ieIdx < ueSetReq->protocolIEs.list.count; ieIdx++)
+ {
+ if(ueSetReq->protocolIEs.list.array[ieIdx])
+ {
+ switch(ueSetReq->protocolIEs.list.array[ieIdx]->id)
+ {
+ case ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID:
+ break;
+ case ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID:
+ break;
+ case ProtocolIE_ID_id_SpCell_ID:
+ freeAperDecodeNrcgi(&ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.NRCGI);
+ break;
+ case ProtocolIE_ID_id_ServCellIndex:
+ break;
+ case ProtocolIE_ID_id_SpCellULConfigured:
+ break;
+ case ProtocolIE_ID_id_CUtoDURRCInformation:
+
+ freeAperDecodeCuToDuInfo(&ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.CUtoDURRCInformation);
+ break;
+ case ProtocolIE_ID_id_SCell_ToBeSetup_List:
+
+ freeAperDecodeSplCellList(&ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.SCell_ToBeSetup_List);
+ break;
+ case ProtocolIE_ID_id_SRBs_ToBeSetup_List:
+
+ freeAperDecodeSRBSetup(&ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.SRBs_ToBeSetup_List);
+ break;
+ case ProtocolIE_ID_id_DRBs_ToBeSetup_List:
+
+ freeAperDecodeDRBSetup(&ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.DRBs_ToBeSetup_List);
+ break;
+ case ProtocolIE_ID_id_RRCContainer:
+ {
+
+ if(ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.RRCContainer.buf != NULLP)
+ {
+
+ free(ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.RRCContainer.buf);
+ }
+ break;
+ }
+ case ProtocolIE_ID_id_RRCDeliveryStatusRequest:
+ break;
+ case ProtocolIE_ID_id_GNB_DU_UE_AMBR_UL:
+ {
+ if(ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.BitRate.buf)
+ {
+ free(ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.BitRate.buf);
+ }
+ break;
+ }
+ default:
+ DU_LOG("\nERROR --> F1AP: Invalid event type %ld " ,ueSetReq->protocolIEs.list.array[ieIdx]->id);
+ }
+ free(ueSetReq->protocolIEs.list.array[ieIdx]);
+ }
+ }
+ free(ueSetReq->protocolIEs.list.array);
+ }
+}
+/*******************************************************************
+ *
+ * @brief Process UE context setup request from CU
+ *
+ * @details
+ *
+ * Function : procF1UeContextSetupReq
+ *
+ * Functionality: Process UE context setup request from CU
+ *
+ * @params[in] F1AP message
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ * ****************************************************************/
+uint8_t procF1UeContextSetupReq(F1AP_PDU_t *f1apMsg)
+{
+ uint8_t ret=0, ieIdx=0, ueIdx=0, cellIdx=0;
+ bool ueCbFound = false;
+ uint32_t gnbCuUeF1apId=0, gnbDuUeF1apId=0, bitRateSize=0;
+ DuUeCb *duUeCb = NULL;
+ UEContextSetupRequest_t *ueSetReq = NULL;
+ DRBs_ToBeSetup_List_t *drbCfg = NULL;
+
+ ret = ROK;
+
+ ueSetReq = &f1apMsg->choice.initiatingMessage->value.choice.UEContextSetupRequest;
+ for(ieIdx=0; (ieIdx < ueSetReq->protocolIEs.list.count && ret == ROK); ieIdx++)
+ {
+ switch(ueSetReq->protocolIEs.list.array[ieIdx]->id)
+ {
+ case ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID:
+ {
+ gnbCuUeF1apId = ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.GNB_CU_UE_F1AP_ID;
+ break;
+ }
+ case ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID:
+ {
+ gnbDuUeF1apId = ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.GNB_DU_UE_F1AP_ID;
+ break;
+ }
+ case ProtocolIE_ID_id_ServCellIndex:
+ {
+ cellIdx = ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.ServCellIndex;
+ for(ueIdx = 0; ueIdx < MAX_NUM_UE; ueIdx++)
+ {
+ if((duCb.actvCellLst[cellIdx]->ueCb[ueIdx].gnbDuUeF1apId == gnbDuUeF1apId)&&\
+ (duCb.actvCellLst[cellIdx]->ueCb[ueIdx].gnbCuUeF1apId == gnbCuUeF1apId))
+ {
+ ueCbFound = true;
+ duUeCb = &duCb.actvCellLst[cellIdx]->ueCb[ueIdx];
+ DU_ALLOC(duUeCb->f1UeDb, sizeof(F1UeContextSetupDb));
+ if(duUeCb->f1UeDb)
+ {
+ memset(duUeCb->f1UeDb, 0, sizeof(F1UeContextSetupDb));
+ duUeCb->f1UeDb->actionType = UE_CTXT_SETUP;
+ duUeCb->f1UeDb->cellIdx = cellIdx;
+ }
+ else
+ {
+ DU_LOG("\nERROR --> F1AP: Memory Alloc Failed at procF1UeContextSetupReq()");
+ ret = RFAILED;
+ }
+ break;
+ }
+ else
+ ueCbFound = false;
+
+ }
+ if(!ueCbFound)
+ {
+ DU_LOG("\nERROR --> F1AP: DuUeCb is not found at procF1UeContextSetupReq()");
+ ret = RFAILED;
+ }
+ break;
+ }
+ case ProtocolIE_ID_id_SpCellULConfigured:
+ /* Indicates whether the gNB-CU requests the gNB-DU to configure the uplink as no UL,
+ UL, SUL or UL+SUL for the indicated cell for the UE */
+ break;
+ case ProtocolIE_ID_id_CUtoDURRCInformation:
+ {
+ if(ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList)
+ {
+ duUeCb->f1UeDb->duUeCfg.ueNrCapability = \
+ extractUeCapability(ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.CUtoDURRCInformation.\
+ uE_CapabilityRAT_ContainerList, duUeCb);
+ }
+ if(ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.CUtoDURRCInformation.iE_Extensions)
+ {
+ duUeCb->f1UeDb->duUeCfg.cellGrpCfg = extractCellGrpInfo(ueSetReq->protocolIEs.list.array[ieIdx]->\
+ value.choice.CUtoDURRCInformation.iE_Extensions, &duUeCb->f1UeDb->duUeCfg);
+ if(!duUeCb->f1UeDb->duUeCfg.cellGrpCfg)
+ {
+ DU_LOG("\nERROR --> F1AP: Failed to extract cell Grp Info");
+ //TODO: Update the failure cause in ue context Setup Response
+ ret = RFAILED;
+ }
+ }
+ break;
+ }
+ case ProtocolIE_ID_id_SCell_ToBeSetup_List:
+ {
+ DU_LOG("\nINFO --> DU_APP: Received SCell_ToBeSetup_List but Not processing the list");
+ break;
+ }
+ case ProtocolIE_ID_id_SRBs_ToBeSetup_List:
+ {
+ if(extractSrbListToSetup(&ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.SRBs_ToBeSetup_List,\
+ &duUeCb->f1UeDb->duUeCfg))
+ {
+ DU_LOG("\nERROR --> DU APP : Failed at extractSrbListToSetup()");
+ //TODO: Update the failure cause in ue context Setup Response
+ ret = RFAILED;
+ }
+ break;
+ }
+ case ProtocolIE_ID_id_DRBs_ToBeSetup_List:
+ {
+ drbCfg = &ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.DRBs_ToBeSetup_List;
+
+ if(extractDrbListToSetup(drbCfg, NULL, drbCfg->list.count, &duUeCb->f1UeDb->duUeCfg, &duUeCb->drbBitMap))
+ {
+ DU_LOG("\nERROR --> DU APP : Failed at extractDrbListToSetup()");
+ //TODO: Update the failure cause in ue context Setup Response
+ ret = RFAILED;
+ }
+ break;
+ }
+ case ProtocolIE_ID_id_RRCContainer:
+ {
+ /* Filling Dl RRC Msg Info */
+ DU_ALLOC_SHRABL_BUF(duUeCb->f1UeDb->dlRrcMsg, sizeof(F1DlRrcMsg));
+ if(!duUeCb->f1UeDb->dlRrcMsg)
+ {
+ DU_LOG("\nERROR --> DU APP : Memory allocation failed for DL RRC Msg in procUeCtxtSetupReq()");
+ ret = RFAILED;
+ }
+ else
+ {
+ duUeCb->f1UeDb->dlRrcMsgPres = true;
+ memset(duUeCb->f1UeDb->dlRrcMsg, 0, sizeof(F1DlRrcMsg));
+ ret = extractDlRrcMsg(gnbDuUeF1apId, gnbCuUeF1apId, duUeCb->f1UeDb->dlRrcMsg,\
+ &ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.RRCContainer);
+ }
+ break;
+ }
+ case ProtocolIE_ID_id_RRCDeliveryStatusRequest:
+ {
+ if(duUeCb->f1UeDb->dlRrcMsg->rrcMsgPdu)
+ {
+ duUeCb->f1UeDb->dlRrcMsg->deliveryStatRpt = true;
+ }
+ else
+ {
+ DU_LOG("\nERROR --> Ignoring delivery report, since rrcContainer is not present");
+ }
+ break;
+ }
+ case ProtocolIE_ID_id_GNB_DU_UE_AMBR_UL:
+ {
+ /* MaximumBitRate Uplink */
+ bitRateSize = ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.BitRate.size;
+ if(bitRateSize > 0)
+ {
+ DU_ALLOC_SHRABL_BUF(duUeCb->f1UeDb->duUeCfg.ambrCfg, bitRateSize);
+ if(!duUeCb->f1UeDb->duUeCfg.ambrCfg)
+ {
+ DU_LOG("\nERROR --> DU APP : Memory allocation failed for bitRate in procUeCtxtSetupReq");
+ ret = RFAILED;
+ }
+ else
+ {
+ memset(duUeCb->f1UeDb->duUeCfg.ambrCfg, 0, sizeof(AmbrCfg));
+ memcpy(&duUeCb->f1UeDb->duUeCfg.ambrCfg->ulBr,
+ ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.BitRate.buf, bitRateSize);
+ }
+ }
+ else
+ ret = RFAILED;
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+ if(ret == RFAILED)
+ {
+ /*TODO : Negative case*/
+ // BuildAndSendUeContextSetupRsp(cellId,ueIdx);
+ DU_LOG("\nERROR --> F1AP: Failed to process UE CNTXT SETUP REQ at procF1UeContextSetupReq()");
+ }
+ else
+ ret = duProcUeContextSetupRequest(duUeCb);
+
+ freeAperDecodeF1UeContextSetupReq(ueSetReq);
+ return ret;
+
+}
+/*******************************************************************
+ * @brief Free the memory allocated for Dl Tunnel Info
+ *
+ * @details
+ *
+ * Function : freeDlTnlInfo
+ *
+ * Functionality:
+ * Free the memory allocated for Dl Tunnel Info
+ *
+ * @params[in] DLUPTNLInformation_ToBeSetup_List_t *
+ * @return void
+ *
+ * ****************************************************************/
+
+void freeDlTnlInfo(DLUPTNLInformation_ToBeSetup_List_t *tnlInfo)
+{
+ uint8_t arrIdx = 0;
+
+ if(tnlInfo)
+ {
+ for(arrIdx=0; arrIdx < tnlInfo->list.count; arrIdx++)
+ {
+ DU_FREE(tnlInfo->list.array[arrIdx]->dLUPTNLInformation.choice.gTPTunnel->transportLayerAddress.buf,\
+ tnlInfo->list.array[arrIdx]->dLUPTNLInformation.choice.gTPTunnel->transportLayerAddress.size);
+ DU_FREE(tnlInfo->list.array[arrIdx]->dLUPTNLInformation.choice.gTPTunnel->gTP_TEID.buf,\
+ tnlInfo->list.array[arrIdx]->dLUPTNLInformation.choice.gTPTunnel->gTP_TEID.size);
+ DU_FREE(tnlInfo->list.array[arrIdx]->dLUPTNLInformation.choice.gTPTunnel, sizeof(GTPTunnel_t));
+ DU_FREE(tnlInfo->list.array[arrIdx], sizeof(DLUPTNLInformation_ToBeSetup_Item_t));
+ }
+ DU_FREE(tnlInfo->list.array, tnlInfo->list.size);
+ }
+}
+
+/*******************************************************************
+ * @brief Free the memory allocated for DRB setup List
+ *
+ * @details
+ *
+ * Function : freeDrbSetupList
+ *
+ * Functionality:
+ * Free the memory allocated for DRB setup list
+ *
+ * @params[in] DRBs_Setup_List_t *
+ * @return void
+ *
+ * ****************************************************************/
+void freeDrbSetupList(DRBs_Setup_List_t *drbSetupList)
+{
+ uint8_t arrIdx = 0;
+ DRBs_Setup_ItemIEs_t *drbItemIe = NULLP;