Added a new Flag ODU_LWR_MAC_DEBUG in the code
[o-du/l2.git] / src / 5gnrrlc / rlc_msg_hdl.c
1 /*******************************************************************************
2 ################################################################################
3 #   Copyright (c) [2017-2019] [Radisys]                                        #
4 #                                                                              #
5 #   Licensed under the Apache License, Version 2.0 (the "License");            #
6 #   you may not use this file except in compliance with the License.           #
7 #   You may obtain a copy of the License at                                    #
8 #                                                                              #
9 #       http://www.apache.org/licenses/LICENSE-2.0                             #
10 #                                                                              #
11 #   Unless required by applicable law or agreed to in writing, software        #
12 #   distributed under the License is distributed on an "AS IS" BASIS,          #
13 #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
14 #   See the License for the specific language governing permissions and        #
15 #   limitations under the License.                                             #
16 ################################################################################
17 *******************************************************************************/
18
19 /* header include files (.h) */
20 #include "common_def.h"
21 #include "rgu.h"           /* RGU interface includes*/
22 #include "lkw.h"           /* LKW defines */
23 #include "ckw.h"           /* CKW defines */
24 #include "kwu.h"           /* KWU defines */
25 #include "kw_env.h"        /* RLC environment options */
26 #include "kw.h"            /* RLC defines */
27 #include "kw_udx.h"
28 #include "kw_ul.h"
29 #include "kw_dl.h"
30
31 /* header/extern include files (.x) */
32 #include "rgu.x"           
33 #include "lkw.x"           /* LKW */
34 #include "ckw.x"           /* CKW */
35 #include "kwu.x"           /* KWU */
36 #include "kw_err.h"
37 #include "kw.x"
38 #include "kw_udx.x"
39 #include "kw_dl.x"
40 #include "kw_ul.x"
41
42 #include "rlc_mac_inf.h"
43 #include "du_app_rlc_inf.h"
44 #include "rlc_utils.h"
45 #include "rlc_upr_inf_api.h"
46 /*******************************************************************
47  *
48  * @brief Fills RLC UL UE Cfg Rsp from RlcCRsp 
49  *
50  * @details
51  *
52  *    Function : fillRlcUlUeCfgRsp
53  *
54  *    Functionality: 
55  *     Fills RLC UL UE Cfg Rsp from RlcCRsp
56  * 
57  *  @params[in]  Pointer to RlcCfgCfm
58  *               Pointer to RlcUeCfgRsp
59  *
60  *  @return void
61  * 
62  *****************************************************************/
63
64 void fillRlcUlUeCfgRsp(RlcUeCfgRsp *rlcCfgRsp, RlcCfgCfmInfo *rlcCRsp)
65 {
66    uint8_t idx;
67  
68    rlcCfgRsp->cellId = rlcCRsp->cellId;
69    rlcCfgRsp->ueIdx  = rlcCRsp->ueId;
70    for(idx = 0; idx < rlcCRsp->numEnt; idx++)
71    {
72       if(rlcCRsp->entCfgCfm[idx].status.status == CKW_CFG_CFM_OK)
73       {
74          rlcCfgRsp->result = RLC_DU_APP_RSP_OK;
75          rlcCfgRsp->reason = rlcCRsp->entCfgCfm[idx].status.reason;
76       }
77       else
78       {
79          rlcCfgRsp->result = RLC_DU_APP_RSP_NOK;
80          rlcCfgRsp->reason = rlcCRsp->entCfgCfm[idx].status.reason;
81       }
82    }
83 }
84
85 /*******************************************************************
86  *
87  * @brief Fills the entity mode and direction compiling to seed code
88  *
89  * @details
90  *
91  *    Function : fillEntModeAndDir
92  *
93  *    Functionality:
94  *      Fills the entity mode and direction compiling to seed code
95  *
96  * @params[in] Pointer to entMode
97  *             Pointer to direction
98  *             RlcMode Param 
99  * @return void
100  * ****************************************************************/
101
102 void fillEntModeAndDir(uint8_t *entMode, uint8_t *direction, RlcMode rlcMode)
103 {
104    switch(rlcMode)
105    {
106       case RLC_AM:
107          *entMode   = CM_LTE_MODE_AM;
108          *direction = RLC_CFG_DIR_BOTH;
109          break;
110       case RLC_UM_BI_DIRECTIONAL:
111          *entMode = CM_LTE_MODE_UM;
112          *direction = RLC_CFG_DIR_BOTH;
113          break;
114       case RLC_UM_UNI_DIRECTIONAL_UL:
115          *entMode = CM_LTE_MODE_UM;
116          *direction = RLC_CFG_DIR_UL;
117          break;
118       case RLC_UM_UNI_DIRECTIONAL_DL:
119          *entMode = CM_LTE_MODE_UM;
120          *direction = RLC_CFG_DIR_DL;
121          break;
122       default : 
123          DU_LOG("\nRLC: Rlc Mode invalid %d", rlcMode);
124     break;
125    }
126 }
127 /*******************************************************************
128  *
129  * @brief Handles Ue Create Request from DU APP
130  *
131  * @details
132  *
133  *    Function : RlcUlProcUeCreateReq
134  *
135  *    Functionality:
136  *      Handles Ue create Request from DU APP
137  *
138  * @params[in] Post structure pointer
139  *             RlcUeCfg pointer 
140  * @return ROK     - success
141  *         RFAILED - failure
142  *
143  * ****************************************************************/
144 uint8_t RlcUlProcUeCreateReq(Pst *pst, RlcUeCfg *ueCfg)
145 {
146    uint8_t idx;
147    uint8_t ret = ROK;
148    uint8_t lChRbIdx;
149    RlcCfgInfo *rlcUeCfg = NULLP;
150
151    RlcCb *rlcUeCb = NULLP;
152    rlcUeCb = RLC_GET_RLCCB(pst->dstInst);
153    RLC_ALLOC(rlcUeCb, rlcUeCfg, sizeof(RlcCfgInfo));
154    if(rlcUeCfg)
155    {
156       memset(rlcUeCfg, 0, sizeof(RlcCfgInfo));
157
158       rlcUeCfg->ueId    = ueCfg->ueIdx;
159       rlcUeCfg->cellId  = ueCfg->cellId;
160       rlcUeCfg->numEnt  = ueCfg->numLcs;
161       rlcUeCfg->transId = getTransId();
162  
163       for(idx = 0; idx < ueCfg->numLcs; idx++)
164       {
165          lChRbIdx = 0;
166          rlcUeCfg->entCfg[idx].rbId           = ueCfg->rlcBearerCfg[idx].rbId;
167          rlcUeCfg->entCfg[idx].rbType         = ueCfg->rlcBearerCfg[idx].rbType;   // SRB or DRB
168          rlcUeCfg->entCfg[idx].lCh[lChRbIdx].lChId   = ueCfg->rlcBearerCfg[idx].lcId;   
169          rlcUeCfg->entCfg[idx].lCh[lChRbIdx].type    = ueCfg->rlcBearerCfg[idx].lcType;
170          fillEntModeAndDir(&rlcUeCfg->entCfg[idx].entMode, &rlcUeCfg->entCfg[idx].dir,\
171             ueCfg->rlcBearerCfg[idx].rlcMode);
172          rlcUeCfg->entCfg[idx].cfgType        = CKW_CFG_ADD;
173          switch(rlcUeCfg->entCfg[idx].entMode)
174          {
175
176             case CM_LTE_MODE_AM:
177             {
178                /* DL AM INFO */
179                rlcUeCfg->entCfg[idx].m.amInfo.dl.snLen = ueCfg->rlcBearerCfg[idx].u.amCfg.dlAmCfg.snLenDl; 
180                rlcUeCfg->entCfg[idx].m.amInfo.dl.pollRetxTmr = ueCfg->rlcBearerCfg[idx].u.amCfg.dlAmCfg.pollRetxTmr;
181                rlcUeCfg->entCfg[idx].m.amInfo.dl.pollPdu = ueCfg->rlcBearerCfg[idx].u.amCfg.dlAmCfg.pollPdu; 
182                rlcUeCfg->entCfg[idx].m.amInfo.dl.pollByte = ueCfg->rlcBearerCfg[idx].u.amCfg.dlAmCfg.pollByte; 
183                rlcUeCfg->entCfg[idx].m.amInfo.dl.maxRetx = ueCfg->rlcBearerCfg[idx].u.amCfg.dlAmCfg.maxRetxTh;
184
185                /* UL AM INFO */
186                lChRbIdx++;   //lChRbIdx = 1, indicates UL AM
187                rlcUeCfg->entCfg[idx].lCh[lChRbIdx].lChId   = ueCfg->rlcBearerCfg[idx].lcId;   
188                rlcUeCfg->entCfg[idx].lCh[lChRbIdx].type    = ueCfg->rlcBearerCfg[idx].lcType;
189                rlcUeCfg->entCfg[idx].m.amInfo.ul.snLen = ueCfg->rlcBearerCfg[idx].u.amCfg.ulAmCfg.snLenUl; 
190                rlcUeCfg->entCfg[idx].m.amInfo.ul.staProhTmr = ueCfg->rlcBearerCfg[idx].u.amCfg.ulAmCfg.statProhTmr;
191                rlcUeCfg->entCfg[idx].m.amInfo.ul.reOrdTmr = ueCfg->rlcBearerCfg[idx].u.amCfg.ulAmCfg.reAssemTmr;
192                break;
193             }
194             case CM_LTE_MODE_UM:
195             {
196                /* UL UM CONFIG */
197                rlcUeCfg->entCfg[idx].m.umInfo.ul.snLen = ueCfg->rlcBearerCfg[idx].u.umBiDirCfg.ulUmCfg.snLenUlUm; 
198                rlcUeCfg->entCfg[idx].m.umInfo.ul.reOrdTmr = ueCfg->rlcBearerCfg[idx].u.umBiDirCfg.ulUmCfg.reAssemTmr;
199
200                /* DL UM CONFIG */
201                rlcUeCfg->entCfg[idx].m.umInfo.dl.snLen = ueCfg->rlcBearerCfg[idx].u.umBiDirCfg.dlUmCfg.snLenDlUm; 
202                break;
203             }
204             default:
205                break;
206          }/* End of switch(entMode) */
207       }
208       ret = RlcProcCfgReq(pst, rlcUeCfg);
209       }
210       else
211       {
212          DU_LOG("\nRLC: Failed to allocate memory ");
213          ret = RFAILED;
214       }
215       RLC_FREE_SHRABL_BUF(pst->region, pst->pool, ueCfg, sizeof(RlcUeCfg));
216       return ret;
217 }
218 /*******************************************************************
219 *
220 * @brief filling the structure of rrc delivery msg info
221 *
222 * @details
223 *
224 *    Function : BuildAndSendRrcDeliveryReportToDu
225 *
226 *    Functionality: filling the structure of rrc delivery msg info
227 *
228 * @return ROK     - success
229 *         RFAILED - failure
230 *
231 * ****************************************************************/
232 uint8_t BuildAndSendRrcDeliveryReportToDu( RlcDlRrcMsgInfo *dlRrcMsgInfo )
233 {
234     Pst             pst;
235     RrcDeliveryReport *rrcDelivery;
236
237     DU_LOG("\nRLC : Filling the RRC Delivery Report");
238     RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_UL, RLC_POOL, rrcDelivery, sizeof(RrcDeliveryReport));
239
240     if(rrcDelivery)
241     {
242        rrcDelivery->cellId = dlRrcMsgInfo->cellId;
243        rrcDelivery->ueIdx  = dlRrcMsgInfo->ueIdx;
244        rrcDelivery->srbId  = dlRrcMsgInfo->lcId ;
245        rrcDelivery->rrcDeliveryStatus.deliveryStatus    = PDCP_SN;
246        rrcDelivery->rrcDeliveryStatus.triggeringMessage = PDCP_SN;
247
248        /* Sending UL RRC Message transfeer to DU APP */
249        memset(&pst, 0, sizeof(Pst));
250        FILL_PST_RLC_TO_DUAPP(pst, RLC_UL_INST, EVENT_RRC_DELIVERY_MSG_TRANS_TO_DU);
251        rlcSendRrcDeliveryReportToDu(&pst, rrcDelivery);
252     }
253     else
254     {
255        DU_LOG("\nRLC : Memory allocation failed");
256     }
257
258    return ROK;
259 }
260 /* ****************************************************************
261  *
262  * @brief Process the DL RRC Message from DU APP
263  *
264  * @details
265  *
266  *    Function : RlcProcDlRrcMsgTransfer
267  *
268  *    Functionality: Process the DL RRC Message from DU APP
269  *
270  * @params[in] Post structure
271  *             DL RRC Message info
272  * @return ROK     - success
273  *         RFAILED - failure
274  *
275  * ****************************************************************/
276 uint8_t RlcProcDlRrcMsgTransfer(Pst *pst, RlcDlRrcMsgInfo *dlRrcMsgInfo)
277 {
278    Buffer        *mBuf;
279    KwuDatReqInfo *datReqInfo;
280
281    RLC_SHRABL_STATIC_BUF_ALLOC(RLC_MEM_REGION_DL, RLC_POOL, datReqInfo, sizeof(KwuDatReqInfo));
282    if(!datReqInfo)
283    {
284       DU_LOG("\nRLC : Memory allocation failed in RlcProcDlRrcMsgTransfer");
285       RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, dlRrcMsgInfo->rrcMsg, dlRrcMsgInfo->msgLen);
286       RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, dlRrcMsgInfo, sizeof(RlcDlRrcMsgInfo));
287       return RFAILED;
288    }
289
290    datReqInfo->rlcId.rbType = dlRrcMsgInfo->rbType;
291    datReqInfo->rlcId.rbId = dlRrcMsgInfo->rbId;
292    datReqInfo->rlcId.ueId = dlRrcMsgInfo->ueIdx;
293    datReqInfo->rlcId.cellId = dlRrcMsgInfo->cellId;
294    datReqInfo->lcType = dlRrcMsgInfo->lcType;
295    datReqInfo->sduId = ++(rlcCb[pst->dstInst]->dlSduId);
296
297    /* Copy fixed buffer to message */
298    if(ODU_GET_MSG_BUF(RLC_MEM_REGION_UL, RLC_POOL, &mBuf) != ROK)
299    {
300       DU_LOG("\nRLC : Memory allocation failed at RlcMacProcUlData");
301       RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_DL, RLC_POOL, datReqInfo, sizeof(KwuDatReqInfo));
302       RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, dlRrcMsgInfo->rrcMsg, dlRrcMsgInfo->msgLen);
303       RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, dlRrcMsgInfo, sizeof(RlcDlRrcMsgInfo));
304       return RFAILED;
305    }
306    oduCpyFixBufToMsg(dlRrcMsgInfo->rrcMsg, mBuf, dlRrcMsgInfo->msgLen);
307
308    rlcProcDlData(pst, datReqInfo, mBuf);
309
310    /* RRC Delivery report is only send when RRC Delivery status report is true in DL RRC Message */
311    if(dlRrcMsgInfo->deliveryStaRpt)
312    {
313       BuildAndSendRrcDeliveryReportToDu(dlRrcMsgInfo);
314    }
315
316    /* Free memory allocated by du app */
317    RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_DL, RLC_POOL, datReqInfo, sizeof(KwuDatReqInfo));
318    RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, dlRrcMsgInfo->rrcMsg, dlRrcMsgInfo->msgLen);
319    RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, dlRrcMsgInfo, sizeof(RlcDlRrcMsgInfo));
320    return ROK;
321 }
322
323 /*******************************************************************
324  *
325  * @brief Process UL data from UE
326  *
327  * @details
328  *
329  *    Function : RlcProcUlData
330  *
331  *    Functionality:
332  *       This function receives the PDU from MAC.
333  *       seggregates common and dedicated logical channel
334  *       PDU and call respective handler.
335  *
336  * @params[in]
337  * @return ROK     - success
338  *         RFAILED - failure
339  *
340  * ****************************************************************/
341 uint8_t RlcProcUlData(Pst *pst, RlcData *ulData)
342 {
343    uint8_t         ret = ROK;
344    uint8_t              idx, pduIdx;
345    uint8_t              lcId;                    /* Logical Channel */
346    uint8_t              numDLch = 0;             /* Number of dedicated logical channel */
347    bool            dLchPduPres;             /* PDU received on dedicated logical channel */
348    RguLchDatInd    dLchData[MAX_NUM_LC];  /* PDU info on dedicated logical channel */
349    RguDDatIndInfo  *dLchUlDat;               /* UL data on dedicated logical channel */
350    RguCDatIndInfo  *cLchUlDat;               /* UL data on common logical channel */
351
352    /* Initializing dedicated logical channel Database */
353    DU_LOG("\nRLC: Received UL Data request from MAC");
354    for(idx = 0; idx < MAX_NUM_LC; idx++)
355    {
356       dLchData[idx].lcId = idx;
357       dLchData[idx].pdu.numPdu = 0;
358    }
359    dLchPduPres = FALSE;
360
361    /* Seggregate PDUs received on common and dedicated channels
362     * and call common channel's handler */
363    for(idx = 0; idx< ulData->numPdu; idx++)
364    {
365       if(ulData->pduInfo[idx].commCh)
366       {
367          RLC_SHRABL_STATIC_BUF_ALLOC(RLC_MEM_REGION_UL, RLC_POOL, cLchUlDat, \
368             sizeof(RguCDatIndInfo));
369          if(!cLchUlDat)
370          {
371             DU_LOG("\nRLC : Memory allocation failed at RlcProcUlData");
372             ret = RFAILED;
373             break;
374          }
375          memset(cLchUlDat, 0, sizeof(RguCDatIndInfo));
376
377          cLchUlDat->cellId = ulData->cellId;
378          GET_UE_IDX(ulData->rnti, cLchUlDat->rnti);
379          cLchUlDat->lcId   = ulData->pduInfo[idx].lcId;
380
381          /* Copy fixed buffer to message */
382          if(ODU_GET_MSG_BUF(RLC_MEM_REGION_UL, RLC_POOL, &cLchUlDat->pdu) != ROK)
383          {
384             DU_LOG("\nRLC : Memory allocation failed at RlcProcUlData");
385             RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_UL, RLC_POOL, cLchUlDat, \
386                sizeof(RguCDatIndInfo));
387             ret = RFAILED;
388             break;
389          }
390          oduCpyFixBufToMsg(ulData->pduInfo[idx].pduBuf, cLchUlDat->pdu, \
391             ulData->pduInfo[idx].pduLen);
392
393          rlcProcCommLcUlData(pst, 0, cLchUlDat);
394       }
395       else
396       {
397          if(!dLchPduPres)
398          {
399             RLC_SHRABL_STATIC_BUF_ALLOC(RLC_MEM_REGION_UL, RLC_POOL, dLchUlDat, \
400                sizeof(RguDDatIndInfo));
401             if(!dLchUlDat)
402             {
403                DU_LOG("\nRLC : Memory allocation failed at RlcMacProcUlData");
404                ret = RFAILED;
405                break;
406             }
407             dLchPduPres = TRUE;
408          }
409
410          /* Copy fixed buffer to message */
411          lcId = ulData->pduInfo[idx].lcId;
412          if(ODU_GET_MSG_BUF(RLC_MEM_REGION_UL, RLC_POOL, \
413                   &dLchData[lcId].pdu.mBuf[dLchData[lcId].pdu.numPdu]) != ROK)
414          {
415             DU_LOG("\nRLC : Memory allocation failed at RlcMacProcUlData");
416             for(pduIdx=0; pduIdx < dLchData[lcId].pdu.numPdu; pduIdx++)
417             {
418                ODU_PUT_MSG_BUF(dLchData[lcId].pdu.mBuf[dLchData[lcId].pdu.numPdu]);
419             }
420             RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_UL, RLC_POOL, dLchUlDat, \
421                sizeof(RguDDatIndInfo));
422             ret = RFAILED;
423             break;
424          }
425          oduCpyFixBufToMsg(ulData->pduInfo[idx].pduBuf, \
426                dLchData[lcId].pdu.mBuf[dLchData[lcId].pdu.numPdu],\
427                ulData->pduInfo[idx].pduLen);
428
429          dLchData[lcId].pdu.numPdu++;
430       }
431    }
432
433    /* If any PDU received on dedicated logical channel, copy into RguDDatIndInfo
434     * and call its handler */
435    if(ret == ROK)
436    {
437       if(dLchPduPres)
438       {
439          dLchUlDat->cellId = ulData->cellId;
440          dLchUlDat->rnti   = ulData->rnti;
441
442          for(idx = 0; idx < MAX_NUM_LC; idx++)
443          {
444             if(dLchData[idx].pdu.numPdu)
445             {
446                memcpy(&dLchUlDat->lchData[numDLch], &dLchData[idx], sizeof(RguLchDatInd));
447                numDLch++;
448             }
449          }
450          dLchUlDat->numLch = numDLch;
451          rlcProcDedLcUlData(pst, 0, dLchUlDat);
452       }
453    }
454
455    for(pduIdx = 0; pduIdx < ulData->numPdu; pduIdx++)
456    {
457       RLC_FREE_SHRABL_BUF(pst->region, pst->pool, ulData->pduInfo[pduIdx].pduBuf, \
458          ulData->pduInfo[pduIdx].pduLen);
459    }
460    RLC_FREE_SHRABL_BUF(pst->region, pst->pool, ulData, sizeof(RlcData));
461    return ROK;
462
463 }/* End of RlcProcUlData */
464
465 /*******************************************************************
466  *
467  * @brief Handler for extracting common and dedicated channel
468  *      Scheduling result report.
469  *
470  * @details
471  *
472  *    Function : RlcProcSchedResultRpt
473  *
474  *    Functionality:
475  *     Handler for extracting common and dedicated channel
476  *      Scheduling result report
477  *
478  * @params[in]
479  * @return ROK     - success
480  *         RFAILED - failure
481  *
482  * ****************************************************************/
483 uint8_t RlcProcSchedResultRpt(Pst *pst, RlcSchedResultRpt *schRep)
484 {
485    uint8_t ret = ROK;
486    uint8_t idx;                     /* Iterator */
487    uint8_t nmbDLch = 0;                 /* Number of dedicated logical channles */
488    RguCStaIndInfo   *cLchSchInfo;    /* Common logical channel scheduling result */
489    RguDStaIndInfo   *dLchSchInfo;  /* Dedicated logical channel scheduling result */
490
491    DU_LOG("\nRLC : Received scheduling report from MAC");
492    for(idx=0; idx < schRep->numLc; idx++)
493    {
494       /* If it is common channel, fill status indication information
495        * and trigger the handler for each common lch separately */
496       if(schRep->lcSch[idx].commCh)
497       {
498           RLC_SHRABL_STATIC_BUF_ALLOC(RLC_MEM_REGION_DL, RLC_POOL, cLchSchInfo, \
499              sizeof(RguCStaIndInfo));
500           if(!cLchSchInfo)
501           {
502              DU_LOG("\nRLC: RlcProcSchedResultRpt: Memory allocation failed for cLchSchInfo");
503              ret = RFAILED;
504              break;
505           }
506           memset(cLchSchInfo, 0, sizeof(RguCStaIndInfo));
507
508           cLchSchInfo->cellId  = schRep->cellId;
509           cLchSchInfo->lcId    = schRep->lcSch[idx].lcId;
510           cLchSchInfo->transId = schRep->slotInfo.sfn;
511           cLchSchInfo->transId = (cLchSchInfo->transId << 16) | schRep->slotInfo.slot;
512           cLchSchInfo->rnti = schRep->rnti;
513           rlcProcCommLcSchedRpt(pst, 0, cLchSchInfo);
514
515       }
516       else
517       {
518           /* Fill status info structure if at least one dedicated channel
519            * scheduling report is received */
520           if(nmbDLch == 0)
521           {
522              RLC_SHRABL_STATIC_BUF_ALLOC(RLC_MEM_REGION_DL, RLC_POOL, dLchSchInfo, \
523                 sizeof(RguDStaIndInfo));
524              if(!dLchSchInfo)
525              {
526                 DU_LOG("\nRLC: RlcProcSchedResultRpt: Memory allocation failed for dLchSchInfo");
527                 ret = RFAILED;
528                 break;
529              }
530
531              dLchSchInfo->cellId = schRep->cellId;
532              dLchSchInfo->nmbOfUeGrantPerTti = 1;
533              /* MAC sends Scheduling report for one UE at a time. Hence filling
534              only the 0th index of staInd */
535              dLchSchInfo->staInd[0].rnti = schRep->rnti;
536
537              /* Storing sfn/slot into a single 32-bit variable to be used later*/
538              dLchSchInfo->staInd[0].transId = schRep->slotInfo.sfn;
539              dLchSchInfo->staInd[0].transId = \
540                 (dLchSchInfo->staInd[0].transId << 16) | schRep->slotInfo.slot; 
541              dLchSchInfo->staInd[0].nmbOfTbs = 1;
542              dLchSchInfo->staInd[0].fillCtrlPdu = true; 
543           }
544
545           /* Fill logical channel scheduling info */
546           dLchSchInfo->staInd[0].staIndTb[0].lchStaInd[nmbDLch].lcId = \
547              schRep->lcSch[idx].lcId;
548           dLchSchInfo->staInd[0].staIndTb[0].lchStaInd[nmbDLch].totBufSize = \
549              schRep->lcSch[idx].bufSize;
550           nmbDLch++;
551       }
552    }
553
554    /* Calling handler for all dedicated channels scheduling*/
555    if(ret == ROK)
556    {
557       if(nmbDLch)
558       {
559          dLchSchInfo->staInd[0].staIndTb[0].nmbLch = nmbDLch;
560          rlcProcDedLcSchedRpt(pst, 0, dLchSchInfo);
561       }
562    }
563
564    RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, schRep, sizeof(RlcSchedResultRpt));
565    return ret;
566 }
567
568 /**********************************************************************
569          End of file
570 **********************************************************************/