+
+/*******************************************************************
+ *
+ * @brief Process UL data from UE
+ *
+ * @details
+ *
+ * Function : RlcProcUlData
+ *
+ * Functionality:
+ * This function receives the PDU from MAC.
+ * seggregates common and dedicated logical channel
+ * PDU and call respective handler.
+ *
+ * @params[in]
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ * ****************************************************************/
+uint8_t RlcProcUlData(Pst *pst, RlcData *ulData)
+{
+ uint8_t ret = ROK;
+ uint8_t idx, pduIdx;
+ uint8_t lcId; /* Logical Channel */
+ uint8_t numDLch = 0; /* Number of dedicated logical channel */
+ bool dLchPduPres; /* PDU received on dedicated logical channel */
+ RguLchDatInd dLchData[MAX_NUM_LC]; /* PDU info on dedicated logical channel */
+ RguDDatIndInfo *dLchUlDat; /* UL data on dedicated logical channel */
+ RguCDatIndInfo *cLchUlDat; /* UL data on common logical channel */
+
+ /* Initializing dedicated logical channel Database */
+ DU_LOG("\nRLC: Received UL Data request from MAC");
+ for(idx = 0; idx < MAX_NUM_LC; idx++)
+ {
+ dLchData[idx].lcId = idx;
+ dLchData[idx].pdu.numPdu = 0;
+ }
+ dLchPduPres = FALSE;
+
+ /* Seggregate PDUs received on common and dedicated channels
+ * and call common channel's handler */
+ for(idx = 0; idx< ulData->numPdu; idx++)
+ {
+ if(ulData->pduInfo[idx].commCh)
+ {
+ RLC_SHRABL_STATIC_BUF_ALLOC(RLC_MEM_REGION_UL, RLC_POOL, cLchUlDat, \
+ sizeof(RguCDatIndInfo));
+ if(!cLchUlDat)
+ {
+ DU_LOG("\nRLC : Memory allocation failed at RlcProcUlData");
+ ret = RFAILED;
+ break;
+ }
+ memset(cLchUlDat, 0, sizeof(RguCDatIndInfo));
+
+ cLchUlDat->cellId = ulData->cellId;
+ GET_UE_IDX(ulData->rnti, cLchUlDat->rnti);
+ cLchUlDat->lcId = ulData->pduInfo[idx].lcId;
+
+ /* Copy fixed buffer to message */
+ if(ODU_GET_MSG_BUF(RLC_MEM_REGION_UL, RLC_POOL, &cLchUlDat->pdu) != ROK)
+ {
+ DU_LOG("\nRLC : Memory allocation failed at RlcProcUlData");
+ RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_UL, RLC_POOL, cLchUlDat, \
+ sizeof(RguCDatIndInfo));
+ ret = RFAILED;
+ break;
+ }
+ oduCpyFixBufToMsg(ulData->pduInfo[idx].pduBuf, cLchUlDat->pdu, \
+ ulData->pduInfo[idx].pduLen);
+
+ rlcProcCommLcUlData(pst, 0, cLchUlDat);
+ }
+ else
+ {
+ if(!dLchPduPres)
+ {
+ RLC_SHRABL_STATIC_BUF_ALLOC(RLC_MEM_REGION_UL, RLC_POOL, dLchUlDat, \
+ sizeof(RguDDatIndInfo));
+ if(!dLchUlDat)
+ {
+ DU_LOG("\nRLC : Memory allocation failed at RlcMacProcUlData");
+ ret = RFAILED;
+ break;
+ }
+ dLchPduPres = TRUE;
+ }
+
+ /* Copy fixed buffer to message */
+ lcId = ulData->pduInfo[idx].lcId;
+ if(ODU_GET_MSG_BUF(RLC_MEM_REGION_UL, RLC_POOL, \
+ &dLchData[lcId].pdu.mBuf[dLchData[lcId].pdu.numPdu]) != ROK)
+ {
+ DU_LOG("\nRLC : Memory allocation failed at RlcMacProcUlData");
+ for(pduIdx=0; pduIdx < dLchData[lcId].pdu.numPdu; pduIdx++)
+ {
+ ODU_PUT_MSG_BUF(dLchData[lcId].pdu.mBuf[dLchData[lcId].pdu.numPdu]);
+ }
+ RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_UL, RLC_POOL, dLchUlDat, \
+ sizeof(RguDDatIndInfo));
+ ret = RFAILED;
+ break;
+ }
+ oduCpyFixBufToMsg(ulData->pduInfo[idx].pduBuf, \
+ dLchData[lcId].pdu.mBuf[dLchData[lcId].pdu.numPdu],\
+ ulData->pduInfo[idx].pduLen);
+
+ dLchData[lcId].pdu.numPdu++;
+ }
+ }
+
+ /* If any PDU received on dedicated logical channel, copy into RguDDatIndInfo
+ * and call its handler */
+ if(ret == ROK)
+ {
+ if(dLchPduPres)
+ {
+ dLchUlDat->cellId = ulData->cellId;
+ dLchUlDat->rnti = ulData->rnti;
+
+ for(idx = 0; idx < MAX_NUM_LC; idx++)
+ {
+ if(dLchData[idx].pdu.numPdu)
+ {
+ memcpy(&dLchUlDat->lchData[numDLch], &dLchData[idx], sizeof(RguLchDatInd));
+ numDLch++;
+ }
+ }
+ dLchUlDat->numLch = numDLch;
+ rlcProcDedLcUlData(pst, 0, dLchUlDat);
+ }
+ }
+
+ for(pduIdx = 0; pduIdx < ulData->numPdu; pduIdx++)
+ {
+ RLC_FREE_SHRABL_BUF(pst->region, pst->pool, ulData->pduInfo[pduIdx].pduBuf, \
+ ulData->pduInfo[pduIdx].pduLen);
+ }
+ RLC_FREE_SHRABL_BUF(pst->region, pst->pool, ulData, sizeof(RlcData));
+ return ROK;
+
+}/* End of RlcProcUlData */
+
+/*******************************************************************
+ *
+ * @brief Handler for extracting common and dedicated channel
+ * Scheduling result report.
+ *
+ * @details
+ *
+ * Function : RlcProcSchedResultRpt
+ *
+ * Functionality:
+ * Handler for extracting common and dedicated channel
+ * Scheduling result report
+ *
+ * @params[in]
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ * ****************************************************************/
+uint8_t RlcProcSchedResultRpt(Pst *pst, RlcSchedResultRpt *schRep)
+{
+ uint8_t ret = ROK;
+ uint8_t idx; /* Iterator */
+ uint8_t nmbDLch = 0; /* Number of dedicated logical channles */
+ RguCStaIndInfo *cLchSchInfo; /* Common logical channel scheduling result */
+ RguDStaIndInfo *dLchSchInfo; /* Dedicated logical channel scheduling result */
+
+ DU_LOG("\nRLC : Received scheduling report from MAC");
+ for(idx=0; idx < schRep->numLc; idx++)
+ {
+ /* If it is common channel, fill status indication information
+ * and trigger the handler for each common lch separately */
+ if(schRep->lcSch[idx].commCh)
+ {
+ RLC_SHRABL_STATIC_BUF_ALLOC(RLC_MEM_REGION_DL, RLC_POOL, cLchSchInfo, \
+ sizeof(RguCStaIndInfo));
+ if(!cLchSchInfo)
+ {
+ DU_LOG("\nRLC: RlcProcSchedResultRpt: Memory allocation failed for cLchSchInfo");
+ ret = RFAILED;
+ break;
+ }
+ memset(cLchSchInfo, 0, sizeof(RguCStaIndInfo));
+
+ cLchSchInfo->cellId = schRep->cellId;
+ cLchSchInfo->lcId = schRep->lcSch[idx].lcId;
+ cLchSchInfo->transId = schRep->slotInfo.sfn;
+ cLchSchInfo->transId = (cLchSchInfo->transId << 16) | schRep->slotInfo.slot;
+ cLchSchInfo->rnti = schRep->rnti;
+ rlcProcCommLcSchedRpt(pst, 0, cLchSchInfo);
+
+ }
+ else
+ {
+ /* Fill status info structure if at least one dedicated channel
+ * scheduling report is received */
+ if(nmbDLch == 0)
+ {
+ RLC_SHRABL_STATIC_BUF_ALLOC(RLC_MEM_REGION_DL, RLC_POOL, dLchSchInfo, \
+ sizeof(RguDStaIndInfo));
+ if(!dLchSchInfo)
+ {
+ DU_LOG("\nRLC: RlcProcSchedResultRpt: Memory allocation failed for dLchSchInfo");
+ ret = RFAILED;
+ break;
+ }
+
+ dLchSchInfo->cellId = schRep->cellId;
+ dLchSchInfo->nmbOfUeGrantPerTti = 1;
+ /* MAC sends Scheduling report for one UE at a time. Hence filling
+ only the 0th index of staInd */
+ dLchSchInfo->staInd[0].rnti = schRep->rnti;
+
+ /* Storing sfn/slot into a single 32-bit variable to be used later*/
+ dLchSchInfo->staInd[0].transId = schRep->slotInfo.sfn;
+ dLchSchInfo->staInd[0].transId = \
+ (dLchSchInfo->staInd[0].transId << 16) | schRep->slotInfo.slot;
+ dLchSchInfo->staInd[0].nmbOfTbs = 1;
+ dLchSchInfo->staInd[0].fillCtrlPdu = true;
+ }
+
+ /* Fill logical channel scheduling info */
+ dLchSchInfo->staInd[0].staIndTb[0].lchStaInd[nmbDLch].lcId = \
+ schRep->lcSch[idx].lcId;
+ dLchSchInfo->staInd[0].staIndTb[0].lchStaInd[nmbDLch].totBufSize = \
+ schRep->lcSch[idx].bufSize;
+ nmbDLch++;
+ }
+ }
+
+ /* Calling handler for all dedicated channels scheduling*/
+ if(ret == ROK)
+ {
+ if(nmbDLch)
+ {
+ dLchSchInfo->staInd[0].staIndTb[0].nmbLch = nmbDLch;
+ rlcProcDedLcSchedRpt(pst, 0, dLchSchInfo);
+ }
+ }
+
+ RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, schRep, sizeof(RlcSchedResultRpt));
+ return ret;
+}
+