+/*******************************************************************
+ *
+ * @brief
+ * Handler for storing all DL PDU Info into RLC-MAC interface
+ * struct and sending to lower interface
+ *
+ * @details
+ * This function stores DL PDU info for all logical channels
+ * of per UE grant per TTI and sends to MAC
+ *
+ * Function : rlcSendDedLcDlData
+ *
+ * @params[in]
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ * ****************************************************************/
+uint8_t rlcSendDedLcDlData(Pst *post, SpId spId, RguDDatReqInfo *datReqInfo)
+{
+ uint8_t ueIdx; /* UE info list iterator */
+ uint8_t tbIdx; /* TB info list iterator */
+ uint8_t lchIdx; /* Lch info list iterator */
+ uint8_t pduIdx; /* RLC PDU list iterator */
+ RguDDatReqPerUe datPerUe; /* DL data info per UE */
+ RguDatReqTb datPerTb; /* DL data info per TB */
+ RguLchDatReq datPerLch; /* DL data info per Lch */
+ RlcData *dlData; /* DL data to be sent to MAC */
+ RlcDlRrcMsgRsp *dlRrcMsgRsp;/* DL Data Msg Rsp sent to DU */
+ Pst pst; /* Post structure */
+ uint16_t pduLen; /* PDU length */
+ uint16_t copyLen; /* Number of bytes copied */
+
+ dlData = NULLP;
+ dlRrcMsgRsp = NULLP;
+ RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL,
+ dlData, sizeof(RlcData));
+ if ( dlData == NULLP )
+ {
+ DU_LOG("\nERROR --> RLC_DL : rlcSendDedLcDlData: Memory allocation failed for dl data");
+ RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL,
+ datReqInfo, sizeof(RguDDatReqInfo));
+ return RFAILED;
+ }
+
+ for(ueIdx = 0; ueIdx < datReqInfo->nmbOfUeGrantPerTti; ueIdx++)
+ {
+ datPerUe = datReqInfo->datReq[ueIdx];
+
+ memset(dlData, 0, sizeof(RlcData));
+
+ dlData->cellId = datReqInfo->cellId;
+ dlData->rnti = datPerUe.rnti;
+
+ /* Retrieving sfn/slot from transId. It was filled in RlcProcSchedResultRpt */
+ dlData->slotInfo.sfn = datPerUe.transId >> 16;
+ dlData->slotInfo.slot = datPerUe.transId & 0xffff;
+ dlData->numPdu = 0;
+
+ for(tbIdx = 0; tbIdx < datPerUe.nmbOfTbs; tbIdx++)
+ {
+ datPerTb = datPerUe.datReqTb[tbIdx];
+ for(lchIdx = 0; lchIdx < datPerTb.nmbLch; lchIdx++)
+ {
+ datPerLch = datPerTb.lchData[lchIdx];
+ for(pduIdx = 0; pduIdx < datPerLch.pdu.numPdu; pduIdx++)
+ {
+ dlData->pduInfo[dlData->numPdu].commCh = FALSE;
+ dlData->pduInfo[dlData->numPdu].lcId = datPerLch.lcId;
+
+ /* Copy Message to fixed buffer to send */
+ ODU_GET_MSG_LEN(datPerLch.pdu.mBuf[pduIdx], (MsgLen *)&pduLen);
+ RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL,
+ dlData->pduInfo[dlData->numPdu].pduBuf, pduLen);
+
+ if (dlData->pduInfo[dlData->numPdu].pduBuf == NULLP )
+ {
+ DU_LOG("\nERROR --> RLC_DL : rlcSendDedLcDlData: Memory allocation failed");
+ for(pduIdx = 0; pduIdx < dlData->numPdu; pduIdx++)
+ {
+ RLC_FREE_SHRABL_BUF(pst.region, pst.pool, dlData->pduInfo[pduIdx].pduBuf,\
+ dlData->pduInfo[pduIdx].pduLen);
+ }
+ RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL,
+ dlData, sizeof(RlcData));
+ RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL,
+ datReqInfo, sizeof(RguDDatReqInfo));
+ return RFAILED;
+ }
+
+ ODU_COPY_MSG_TO_FIX_BUF(datPerLch.pdu.mBuf[pduIdx], 0, pduLen, \
+ dlData->pduInfo[dlData->numPdu].pduBuf, (MsgLen *)©Len);
+ dlData->pduInfo[dlData->numPdu].pduLen = pduLen;
+
+ /* Free message */
+ ODU_PUT_MSG_BUF(datPerLch.pdu.mBuf[pduIdx]);
+
+ dlData->numPdu++;
+ }/* For per PDU */
+ }/* For Data per Lch */
+ }/* For Data per Tb */
+
+ RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL,
+ dlRrcMsgRsp, sizeof(RlcDlRrcMsgRsp));
+ if( dlRrcMsgRsp == NULLP )
+ {
+ DU_LOG("\nERROR --> RLC_DL : rlcSendDedLcDlData: Memory allocation failed for dlRrcMsgRsp");
+ for(pduIdx = 0; pduIdx < dlData->numPdu; pduIdx++)
+ {
+ RLC_FREE_SHRABL_BUF(pst.region, pst.pool, dlData->pduInfo[pduIdx].pduBuf,\
+ dlData->pduInfo[pduIdx].pduLen);
+ }
+ RLC_FREE_SHRABL_BUF(pst.region, pst.pool, dlData, sizeof(RlcData));
+ RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL,
+ datReqInfo, sizeof(RguDDatReqInfo));
+ return RFAILED;
+ }
+
+ dlRrcMsgRsp->cellId = dlData->cellId;
+ dlRrcMsgRsp->crnti = dlData->rnti;
+
+ /* Sending DL Data per UE to MAC */
+ memset(&pst, 0, sizeof(Pst));
+ FILL_PST_RLC_TO_MAC(pst, RLC_DL_INST, EVENT_DL_DATA_TO_MAC);
+ if(RlcSendDlDataToMac(&pst, dlData) != ROK)
+ {
+ for(pduIdx = 0; pduIdx < dlData->numPdu; pduIdx++)
+ {
+ RLC_FREE_SHRABL_BUF(pst.region, pst.pool, dlData->pduInfo[pduIdx].pduBuf,\
+ dlData->pduInfo[pduIdx].pduLen);
+ }
+ RLC_FREE_SHRABL_BUF(pst.region, pst.pool, dlData, sizeof(RlcData));
+ /* Update DL RRC MSG Rsp State */
+ dlRrcMsgRsp->state = TRANSMISSION_FAILED;
+ }
+ else
+ dlRrcMsgRsp->state = TRANSMISSION_COMPLETE;
+
+ /* Send Dl RRC Msg Rsp to DU APP */
+ FILL_PST_RLC_TO_DUAPP(pst, RLC_DL_INST, EVENT_DL_RRC_MSG_RSP_TO_DU);
+ if(rlcSendDlRrcMsgRspToDu(&pst, dlRrcMsgRsp) != ROK)
+ {
+ RLC_FREE_SHRABL_BUF(pst.region, pst.pool, dlRrcMsgRsp, sizeof(RlcDlRrcMsgRsp));
+ }
+ } /* For Data per UE */
+
+ RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL,
+ datReqInfo, sizeof(RguDDatReqInfo));
+
+ return ROK;
+}/* End of rlcSendDedLcDlData */
+