[Epic-ID: ODUHIGH-405][Task-ID: ODUHIGH-425] Changes in Ue Context Modification
[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 "rlc_env.h"        /* RLC environment options */
26 #include "rlc_err.h"
27
28
29 /* header/extern include files (.x) */
30 #include "rgu.x"           
31 #include "lkw.x"           /* LKW */
32 #include "ckw.x"           /* CKW */
33 #include "kwu.x"           /* KWU */
34
35 #include "rlc_utils.h"            /* RLC defines */
36 #include "rlc_dl_ul_inf.h"
37 #include "rlc_dl.h"
38 #include "rlc_ul.h"
39 #include "rlc_mac_inf.h"
40 #include "du_app_rlc_inf.h"
41 #include "rlc_upr_inf_api.h"
42 #include "rlc_mgr.h"
43 /*******************************************************************
44  *
45  * @brief Fills RLC UL UE Cfg Rsp from RlcCRsp 
46  *
47  * @details
48  *
49  *    Function : fillRlcUeCfgRsp
50  *
51  *    Functionality: 
52  *     Fills RLC UL UE Cfg Rsp from RlcCRsp
53  * 
54  *  @params[in]  Pointer to RlcCfgCfm
55  *               Pointer to RlcUeCfgRsp
56  *
57  *  @return ROK/RFAILED
58  * 
59  *****************************************************************/
60
61 uint8_t fillRlcUeCfgRsp(RlcUeCfgRsp *rlcCfgRsp, RlcCfgCfmInfo *rlcCRsp)
62 {
63    uint8_t idx;
64    uint8_t ret = ROK;
65  
66    rlcCfgRsp->cellId = rlcCRsp->cellId;
67    rlcCfgRsp->ueId   = rlcCRsp->ueId;
68    rlcCfgRsp->result = RLC_DU_APP_RSP_OK;
69    for(idx = 0; idx < rlcCRsp->numEnt; idx++)
70    {
71       if(rlcCRsp->entCfgCfm[idx].status.status == CKW_CFG_CFM_OK)
72       {
73          rlcCfgRsp->result = RLC_DU_APP_RSP_OK;
74          rlcCfgRsp->reason = rlcCRsp->entCfgCfm[idx].status.reason;
75          ret = ROK;
76       }
77       else
78       {
79          rlcCfgRsp->result = RLC_DU_APP_RSP_NOK;
80          rlcCfgRsp->reason = rlcCRsp->entCfgCfm[idx].status.reason;
81          ret = RFAILED;
82          break;
83       }
84    }
85    return ret;
86 }
87
88 /*******************************************************************
89  *
90  * @brief Fills the entity mode and direction compiling to seed code
91  *
92  * @details
93  *
94  *    Function : fillEntModeAndDir
95  *
96  *    Functionality:
97  *      Fills the entity mode and direction compiling to seed code
98  *
99  * @params[in] Pointer to entMode
100  *             Pointer to direction
101  *             RlcMode Param 
102  * @return void
103  * ****************************************************************/
104
105 void fillEntModeAndDir(uint8_t *entMode, uint8_t *direction, RlcMode rlcMode)
106 {
107    switch(rlcMode)
108    {
109       case RLC_AM:
110          *entMode   = RLC_MODE_AM;
111          *direction = RLC_CFG_DIR_BOTH;
112          break;
113       case RLC_UM_BI_DIRECTIONAL:
114          *entMode = RLC_MODE_UM;
115          *direction = RLC_CFG_DIR_BOTH;
116          break;
117       case RLC_UM_UNI_DIRECTIONAL_UL:
118          *entMode = RLC_MODE_UM;
119          *direction = RLC_CFG_DIR_UL;
120          break;
121       case RLC_UM_UNI_DIRECTIONAL_DL:
122          *entMode = RLC_MODE_UM;
123          *direction = RLC_CFG_DIR_DL;
124          break;
125       default : 
126          DU_LOG("\nERROR  -->  RLC: Rlc Mode invalid %d", rlcMode);
127     break;
128    }
129 }
130
131 /*******************************************************************
132  *
133  * @brief fills LC Cfgs to be Added in RLC
134  *
135  * @details
136  *
137  *    Function : fillLcCfg
138  *
139  *    Functionality:
140  *      fills LC Cfgs to be Added in RLC
141  *
142  * @params[in] 
143  *             RlcEntCfgInfo pointer
144  *             RlcBearerCfg pointer
145  *             Config Type 
146  * @return ROK -  SUCCESS
147  *         RFAILED - FAILURE
148  *
149  * ****************************************************************/
150 uint8_t fillLcCfg(RlcCb *gCb, RlcEntCfgInfo *rlcUeCfg, RlcBearerCfg *duRlcUeCfg)
151 {
152    uint8_t lChRbIdx = 0;
153
154    rlcUeCfg->rbId                  = duRlcUeCfg->rbId;
155    rlcUeCfg->rbType                = duRlcUeCfg->rbType;   // SRB or DRB
156    rlcUeCfg->lCh[lChRbIdx].lChId   = duRlcUeCfg->lcId;   
157    rlcUeCfg->lCh[lChRbIdx].type    = duRlcUeCfg->lcType;
158    if(duRlcUeCfg->snssai)
159    {
160       RLC_ALLOC(gCb, rlcUeCfg->snssai, sizeof(Snssai));
161       if(rlcUeCfg->snssai == NULLP)
162       {
163          DU_LOG("\nERROR  --> RLC : fillLcCfg(): Failed to allocate memory for snssai");
164          return RFAILED;
165       }
166       memcpy(rlcUeCfg->snssai, duRlcUeCfg->snssai, sizeof(Snssai));
167    }
168    fillEntModeAndDir(&rlcUeCfg->entMode, &rlcUeCfg->dir, duRlcUeCfg->rlcMode);
169    rlcUeCfg->cfgType               = duRlcUeCfg->configType;
170    switch(rlcUeCfg->entMode)
171    {
172
173       case RLC_MODE_AM:
174          {
175             /* DL AM INFO */
176             rlcUeCfg->m.amInfo.dl.snLen       = duRlcUeCfg->u.amCfg->dlAmCfg.snLenDl; 
177             rlcUeCfg->m.amInfo.dl.pollRetxTmr = duRlcUeCfg->u.amCfg->dlAmCfg.pollRetxTmr;
178             rlcUeCfg->m.amInfo.dl.pollPdu     = duRlcUeCfg->u.amCfg->dlAmCfg.pollPdu; 
179             rlcUeCfg->m.amInfo.dl.pollByte    = duRlcUeCfg->u.amCfg->dlAmCfg.pollByte; 
180             rlcUeCfg->m.amInfo.dl.maxRetx     = duRlcUeCfg->u.amCfg->dlAmCfg.maxRetxTh;
181
182             /* UL AM INFO */
183             lChRbIdx++;   //lChRbIdx = 1, indicates UL AM
184             rlcUeCfg->lCh[lChRbIdx].lChId    = duRlcUeCfg->lcId;   
185             rlcUeCfg->lCh[lChRbIdx].type     = duRlcUeCfg->lcType;
186             rlcUeCfg->m.amInfo.ul.snLen      = duRlcUeCfg->u.amCfg->ulAmCfg.snLenUl; 
187             rlcUeCfg->m.amInfo.ul.staProhTmr = duRlcUeCfg->u.amCfg->ulAmCfg.statProhTmr;
188             rlcUeCfg->m.amInfo.ul.reAsmblTmr   = duRlcUeCfg->u.amCfg->ulAmCfg.reAssemTmr;
189             break;
190          }
191       case RLC_MODE_UM:
192          {
193             /* UL UM CONFIG */
194             rlcUeCfg->m.umInfo.ul.snLen      = duRlcUeCfg->u.umBiDirCfg->ulUmCfg.snLenUlUm; 
195             rlcUeCfg->m.umInfo.ul.reAsmblTmr = duRlcUeCfg->u.umBiDirCfg->ulUmCfg.reAssemTmr;
196
197             /* DL UM CONFIG */
198             rlcUeCfg->m.umInfo.dl.snLen = duRlcUeCfg->u.umBiDirCfg->dlUmCfg.snLenDlUm; 
199             break;
200          }
201       default:
202          break;
203    }/* End of switch(entMode) */
204    return ROK;
205 }
206
207 /*******************************************************************
208  *
209  * @brief fills LC Cfgs to be Added in RLC
210  *
211  * @details
212  *
213  *    Function : fillRlcCfg
214  *
215  *    Functionality:
216  *      fills LC Cfgs to be Add/Mod/Del in RLC
217  *
218  * @params[in] 
219  *             RlcEntCfgInfo pointer
220  *             RlcBearerCfg pointer
221  * @return ROK - Success
222  *          RFAILED - Failure
223  *
224  ******************************************************************/
225
226 uint8_t fillRlcCfg(RlcCb *gCb, RlcCfgInfo *rlcUeCfg, RlcUeCfg *ueCfg)
227 {
228    uint8_t lcIdx;
229    
230    rlcUeCfg->ueId    = ueCfg->ueId;
231    rlcUeCfg->cellId  = ueCfg->cellId;
232    rlcUeCfg->numEnt  = ueCfg->numLcs;
233    rlcUeCfg->transId = getTransId();
234    
235    for(lcIdx = 0; lcIdx < rlcUeCfg->numEnt; lcIdx++)
236    {
237       if(fillLcCfg(gCb, &rlcUeCfg->entCfg[lcIdx], &ueCfg->rlcLcCfg[lcIdx]) != ROK)
238       {
239           DU_LOG("\nERROR  --> RLC : fillRlcCfg(): Failed to fill LC configuration");
240           return RFAILED;
241       }
242    }
243    return ROK;
244 }
245
246 /*******************************************************************
247  *
248  * @brief Fill RlcCfgCfmInfo structure for sending failure response to DU
249  *
250  * @details
251  *
252  *    Function : fillRlcCfgFailureRsp
253  *
254  *    Functionality:
255  *      Fill RlcCfgCfmInfo structure for sending failure response to DU
256  *
257  * @params[in] RlcCfgCfmInfo *cfgRsp, RlcUeCfg *ueCfg
258  *             
259  * @return void 
260  *
261  * ****************************************************************/
262 void fillRlcCfgFailureRsp(RlcCfgCfmInfo *cfgRsp, RlcUeCfg *ueCfg)
263 {
264    uint8_t cfgIdx =0;
265
266    cfgRsp->ueId = ueCfg->ueId;
267    cfgRsp->cellId = ueCfg->cellId;
268    cfgRsp->numEnt = ueCfg->numLcs;
269    for(cfgIdx =0; cfgIdx<ueCfg->numLcs; cfgIdx++)
270    {
271       cfgRsp->entCfgCfm[cfgIdx].rbId = ueCfg->rlcLcCfg[cfgIdx].rbId;
272       cfgRsp->entCfgCfm[cfgIdx].rbType = ueCfg->rlcLcCfg[cfgIdx].rbType;
273       cfgRsp->entCfgCfm[cfgIdx].status.status = RLC_DU_APP_RSP_NOK;
274       cfgRsp->entCfgCfm[cfgIdx].status.reason = CKW_CFG_REAS_NONE;
275    }
276 }
277 /*******************************************************************
278  *
279  * @brief Handles Ue Create Request from DU APP
280  *
281  * @details
282  *
283  *    Function : RlcProcUeCreateReq
284  *
285  *    Functionality:
286  *      Handles Ue create Request from DU APP
287  *
288  * @params[in] Post structure pointer
289  *             RlcUeCfg pointer 
290  * @return ROK     - success
291  *         RFAILED - failure
292  *
293  * ****************************************************************/
294 uint8_t RlcProcUeCreateReq(Pst *pst, RlcUeCfg *ueCfg)
295 {
296    uint8_t ret = ROK;
297    RlcCb *gCb;
298    RlcCfgInfo *rlcUeCfg = NULLP;
299    RlcCfgCfmInfo cfgRsp;
300    Pst rspPst;
301
302    gCb = RLC_GET_RLCCB(pst->dstInst);
303    RLC_ALLOC(gCb, rlcUeCfg, sizeof(RlcCfgInfo));
304    if(rlcUeCfg == NULLP)
305    {
306       DU_LOG("\nERROR  -->  RLC: Failed to allocate memory at RlcProcUeCreateReq()");
307       ret = RFAILED;
308    }
309    else
310    {
311       memset(rlcUeCfg, 0, sizeof(RlcCfgInfo));
312       ret = fillRlcCfg(gCb, rlcUeCfg, ueCfg); 
313       if(ret != ROK)
314       {
315          DU_LOG("\nERROR  -->  RLC: Failed to fill configuration at RlcProcUeCreateReq()");
316          FILL_PST_RLC_TO_DUAPP(rspPst, RLC_UL_INST, EVENT_RLC_UE_CREATE_RSP);
317          fillRlcCfgFailureRsp(&cfgRsp, ueCfg);
318          SendRlcUeCfgRspToDu(&rspPst, &cfgRsp);
319
320       }
321       else
322       {
323          ret = RlcProcCfgReq(pst, rlcUeCfg);
324          if(ret != ROK)
325             DU_LOG("\nERROR  -->  RLC: Failed to configure Add/Mod/Del entities at RlcProcUeCreateReq()");
326       }
327    }
328    RLC_FREE_SHRABL_BUF(pst->region, pst->pool, ueCfg, sizeof(RlcUeCfg));
329    return ret;
330 }
331
332 /*******************************************************************
333 *
334 * @brief filling the structure of rrc delivery msg info
335 *
336 * @details
337 *
338 *    Function : BuildAndSendRrcDeliveryReportToDu
339 *
340 *    Functionality: filling the structure of rrc delivery msg info
341 *
342 * @return ROK     - success
343 *         RFAILED - failure
344 *
345 * ****************************************************************/
346 uint8_t BuildAndSendRrcDeliveryReportToDu( RlcDlRrcMsgInfo *dlRrcMsgInfo )
347 {
348     Pst             pst;
349     RrcDeliveryReport *rrcDelivery;
350
351     DU_LOG("\nINFO  -->  RLC : Filling RRC Delivery Report");
352     RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_UL, RLC_POOL, rrcDelivery, sizeof(RrcDeliveryReport));
353
354     if(rrcDelivery)
355     {
356        rrcDelivery->cellId = dlRrcMsgInfo->cellId;
357        rrcDelivery->ueId  = dlRrcMsgInfo->ueId;
358        rrcDelivery->srbId  = dlRrcMsgInfo->lcId ;
359        rrcDelivery->rrcDeliveryStatus.deliveryStatus    = PDCP_SN;
360        rrcDelivery->rrcDeliveryStatus.triggeringMessage = PDCP_SN;
361
362        /* Sending UL RRC Message transfeer to DU APP */
363        memset(&pst, 0, sizeof(Pst));
364        FILL_PST_RLC_TO_DUAPP(pst, RLC_UL_INST, EVENT_RRC_DELIVERY_MSG_TRANS_TO_DU);
365        rlcSendRrcDeliveryReportToDu(&pst, rrcDelivery);
366     }
367     else
368     {
369        DU_LOG("\nERROR  -->  RLC : Memory allocation failed");
370     }
371
372    return ROK;
373 }
374 /* ****************************************************************
375  *
376  * @brief Process the DL RRC Message from DU APP
377  *
378  * @details
379  *
380  *    Function : RlcProcDlRrcMsgTransfer
381  *
382  *    Functionality: Process the DL RRC Message from DU APP
383  *
384  * @params[in] Post structure
385  *             DL RRC Message info
386  * @return ROK     - success
387  *         RFAILED - failure
388  *
389  * ****************************************************************/
390 uint8_t RlcProcDlRrcMsgTransfer(Pst *pst, RlcDlRrcMsgInfo *dlRrcMsgInfo)
391 {
392    Buffer        *mBuf;
393    RlcDatReqInfo *datReqInfo;
394
395    RLC_SHRABL_STATIC_BUF_ALLOC(RLC_MEM_REGION_DL, RLC_POOL, datReqInfo, sizeof(RlcDatReqInfo));
396    if(!datReqInfo)
397    {
398       DU_LOG("\nERROR  -->  RLC : Memory allocation failed in RlcProcDlRrcMsgTransfer");
399       RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, dlRrcMsgInfo->rrcMsg, dlRrcMsgInfo->msgLen);
400       RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, dlRrcMsgInfo, sizeof(RlcDlRrcMsgInfo));
401       return RFAILED;
402    }
403
404    datReqInfo->rlcId.rbType = dlRrcMsgInfo->rbType;
405    datReqInfo->rlcId.rbId = dlRrcMsgInfo->rbId;
406    datReqInfo->rlcId.ueId = dlRrcMsgInfo->ueId;
407    datReqInfo->rlcId.cellId = dlRrcMsgInfo->cellId;
408    datReqInfo->lcType = dlRrcMsgInfo->lcType;
409    datReqInfo->sduId = ++(rlcCb[pst->dstInst]->dlSduId);
410
411    /* Copy fixed buffer to message */
412    if(ODU_GET_MSG_BUF(RLC_MEM_REGION_UL, RLC_POOL, &mBuf) != ROK)
413    {
414       DU_LOG("\nERROR  -->  RLC : Memory allocation failed at RlcMacProcUlData");
415       RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_DL, RLC_POOL, datReqInfo, sizeof(RlcDatReqInfo));
416       RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, dlRrcMsgInfo->rrcMsg, dlRrcMsgInfo->msgLen);
417       RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, dlRrcMsgInfo, sizeof(RlcDlRrcMsgInfo));
418       return RFAILED;
419    }
420    oduCpyFixBufToMsg(dlRrcMsgInfo->rrcMsg, mBuf, dlRrcMsgInfo->msgLen);
421
422    if(rlcProcDlData(pst, datReqInfo, mBuf) != ROK)
423    {
424       return RFAILED;
425    }
426
427    /* RRC Delivery report is only send when RRC Delivery status report is true in DL RRC Message */
428    if(dlRrcMsgInfo->deliveryStaRpt)
429    {
430       BuildAndSendRrcDeliveryReportToDu(dlRrcMsgInfo);
431    }
432
433    /* Free memory allocated by du app */
434    RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_DL, RLC_POOL, datReqInfo, sizeof(RlcDatReqInfo));
435    RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, dlRrcMsgInfo->rrcMsg, dlRrcMsgInfo->msgLen);
436    RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, dlRrcMsgInfo, sizeof(RlcDlRrcMsgInfo));
437    return ROK;
438 }
439
440 /*******************************************************************
441  *
442  * @brief Process UL data from UE
443  *
444  * @details
445  *
446  *    Function : RlcProcUlData
447  *
448  *    Functionality:
449  *       This function receives the PDU from MAC.
450  *       seggregates common and dedicated logical channel
451  *       PDU and call respective handler.
452  *
453  * @params[in]
454  * @return ROK     - success
455  *         RFAILED - failure
456  *
457  * ****************************************************************/
458 uint8_t RlcProcUlData(Pst *pst, RlcData *ulData)
459 {
460    uint8_t         ret = ROK;
461    uint8_t         idx, pduIdx;
462    uint8_t         lcId;                    /* Logical Channel */
463    uint8_t         numDLch = 0;             /* Number of dedicated logical channel */
464    bool            dLchPduPres;             /* PDU received on dedicated logical channel */
465    RguLchDatInd    dLchData[MAX_NUM_LC];    /* PDU info on dedicated logical channel */
466    RguDDatIndInfo  *dLchUlDat;              /* UL data on dedicated logical channel */
467    RguCDatIndInfo  *cLchUlDat;              /* UL data on common logical channel */
468
469    /* Initializing dedicated logical channel Database */
470    DU_LOG("\nDEBUG  -->  RLC: Received UL Data request from MAC");
471    for(idx = 0; idx < MAX_NUM_LC; idx++)
472    {
473       dLchData[idx].lcId = idx;
474       dLchData[idx].pdu.numPdu = 0;
475    }
476    dLchPduPres = FALSE;
477
478    /* Seggregate PDUs received on common and dedicated channels
479     * and call common channel's handler */
480    for(idx = 0; idx< ulData->numPdu; idx++)
481    {
482       if(ulData->pduInfo[idx].commCh)
483       {
484          RLC_SHRABL_STATIC_BUF_ALLOC(RLC_MEM_REGION_UL, RLC_POOL, cLchUlDat, \
485                sizeof(RguCDatIndInfo));
486          if(!cLchUlDat)
487          {
488             DU_LOG("\nERROR  -->  RLC : Memory allocation failed at RlcProcUlData");
489             ret = RFAILED;
490             break;
491          }
492          memset(cLchUlDat, 0, sizeof(RguCDatIndInfo));
493
494          cLchUlDat->cellId = ulData->cellId;
495          GET_UE_ID(ulData->rnti, cLchUlDat->rnti);
496          cLchUlDat->lcId   = ulData->pduInfo[idx].lcId;
497
498          /* Copy fixed buffer to message */
499          if(ODU_GET_MSG_BUF(RLC_MEM_REGION_UL, RLC_POOL, &cLchUlDat->pdu) != ROK)
500          {
501             DU_LOG("\nERROR  -->  RLC : Memory allocation failed at RlcProcUlData");
502             RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_UL, RLC_POOL, cLchUlDat, \
503                   sizeof(RguCDatIndInfo));
504             ret = RFAILED;
505             break;
506          }
507          oduCpyFixBufToMsg(ulData->pduInfo[idx].pduBuf, cLchUlDat->pdu, \
508                ulData->pduInfo[idx].pduLen);
509
510          rlcProcCommLcUlData(pst, 0, cLchUlDat);
511       }
512       else
513       {
514          if(!dLchPduPres)
515          {
516             RLC_SHRABL_STATIC_BUF_ALLOC(RLC_MEM_REGION_UL, RLC_POOL, dLchUlDat, \
517                   sizeof(RguDDatIndInfo));
518             if(!dLchUlDat)
519             {
520                DU_LOG("\nERROR  -->  RLC : Memory allocation failed at RlcMacProcUlData");
521                ret = RFAILED;
522                break;
523             }
524             dLchPduPres = TRUE;
525          }
526
527          /* Copy fixed buffer to message */
528          lcId = ulData->pduInfo[idx].lcId;
529          if(ODU_GET_MSG_BUF(RLC_MEM_REGION_UL, RLC_POOL, \
530                   &dLchData[lcId].pdu.mBuf[dLchData[lcId].pdu.numPdu]) != ROK)
531          {
532             DU_LOG("\nERROR  -->  RLC : Memory allocation failed at RlcMacProcUlData");
533             for(pduIdx=0; pduIdx < dLchData[lcId].pdu.numPdu; pduIdx++)
534             {
535                ODU_PUT_MSG_BUF(dLchData[lcId].pdu.mBuf[dLchData[lcId].pdu.numPdu]);
536             }
537             RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_UL, RLC_POOL, dLchUlDat, \
538                   sizeof(RguDDatIndInfo));
539             ret = RFAILED;
540             break;
541          }
542          oduCpyFixBufToMsg(ulData->pduInfo[idx].pduBuf, \
543                dLchData[lcId].pdu.mBuf[dLchData[lcId].pdu.numPdu],\
544                ulData->pduInfo[idx].pduLen);
545
546          dLchData[lcId].pdu.numPdu++;
547       }
548    }
549
550    /* If any PDU received on dedicated logical channel, copy into RguDDatIndInfo
551     * and call its handler */
552    if(ret == ROK)
553    {
554       if(dLchPduPres)
555       {
556          dLchUlDat->cellId = ulData->cellId;
557          GET_UE_ID(ulData->rnti, dLchUlDat->rnti);
558
559          for(idx = 0; idx < MAX_NUM_LC; idx++)
560          {
561             if(dLchData[idx].pdu.numPdu)
562             {
563                memcpy(&dLchUlDat->lchData[numDLch], &dLchData[idx], sizeof(RguLchDatInd));
564                numDLch++;
565             }
566          }
567          dLchUlDat->numLch = numDLch;
568          rlcProcDedLcUlData(pst, 0, dLchUlDat);
569       }
570    }
571
572    for(pduIdx = 0; pduIdx < ulData->numPdu; pduIdx++)
573    {
574       RLC_FREE_SHRABL_BUF(pst->region, pst->pool, ulData->pduInfo[pduIdx].pduBuf, \
575             ulData->pduInfo[pduIdx].pduLen);
576    }
577    RLC_FREE_SHRABL_BUF(pst->region, pst->pool, ulData, sizeof(RlcData));
578    return ROK;
579
580 }/* End of RlcProcUlData */
581
582 /*******************************************************************
583  *
584  * @brief Handler for extracting common and dedicated channel
585  *      Scheduling result report.
586  *
587  * @details
588  *
589  *    Function : RlcProcSchedResultRpt
590  *
591  *    Functionality:
592  *     Handler for extracting common and dedicated channel
593  *      Scheduling result report
594  *
595  * @params[in]
596  * @return ROK     - success
597  *         RFAILED - failure
598  *
599  * ****************************************************************/
600 uint8_t RlcProcSchedResultRpt(Pst *pst, RlcSchedResultRpt *schRep)
601 {
602    uint8_t ret = ROK;
603    uint8_t idx;                     /* Iterator */
604    uint8_t nmbDLch = 0;                 /* Number of dedicated logical channles */
605    RguCStaIndInfo   *cLchSchInfo;    /* Common logical channel scheduling result */
606    RguDStaIndInfo   *dLchSchInfo;  /* Dedicated logical channel scheduling result */
607
608    DU_LOG("\nDEBUG  -->  RLC : Received scheduling report from MAC");
609    for(idx=0; idx < schRep->numLc; idx++)
610    {
611       /* If it is common channel, fill status indication information
612        * and trigger the handler for each common lch separately */
613       if(schRep->lcSch[idx].commCh)
614       {
615           RLC_SHRABL_STATIC_BUF_ALLOC(RLC_MEM_REGION_DL, RLC_POOL, cLchSchInfo, \
616              sizeof(RguCStaIndInfo));
617           if(!cLchSchInfo)
618           {
619              DU_LOG("\nERROR  -->  RLC: RlcProcSchedResultRpt: Memory allocation failed for cLchSchInfo");
620              ret = RFAILED;
621              break;
622           }
623           memset(cLchSchInfo, 0, sizeof(RguCStaIndInfo));
624
625           cLchSchInfo->cellId  = schRep->cellId;
626           cLchSchInfo->lcId    = schRep->lcSch[idx].lcId;
627           cLchSchInfo->transId = schRep->slotInfo.sfn;
628           cLchSchInfo->transId = (cLchSchInfo->transId << 16) | schRep->slotInfo.slot;
629           cLchSchInfo->rnti = schRep->rnti;
630           rlcProcCommLcSchedRpt(pst, 0, cLchSchInfo);
631
632       }
633       else
634       {
635           /* Fill status info structure if at least one dedicated channel
636            * scheduling report is received */
637           if(nmbDLch == 0)
638           {
639              RLC_SHRABL_STATIC_BUF_ALLOC(RLC_MEM_REGION_DL, RLC_POOL, dLchSchInfo, \
640                 sizeof(RguDStaIndInfo));
641              if(!dLchSchInfo)
642              {
643                 DU_LOG("\nERROR  -->  RLC: RlcProcSchedResultRpt: Memory allocation failed for dLchSchInfo");
644                 ret = RFAILED;
645                 break;
646              }
647
648              dLchSchInfo->cellId = schRep->cellId;
649              dLchSchInfo->nmbOfUeGrantPerTti = 1;
650              /* MAC sends Scheduling report for one UE at a time. Hence filling
651              only the 0th index of staInd */
652              dLchSchInfo->staInd[0].rnti = schRep->rnti;
653
654              /* Storing sfn/slot into a single 32-bit variable to be used later*/
655              dLchSchInfo->staInd[0].transId = schRep->slotInfo.sfn;
656              dLchSchInfo->staInd[0].transId = \
657                 (dLchSchInfo->staInd[0].transId << 16) | schRep->slotInfo.slot; 
658              dLchSchInfo->staInd[0].nmbOfTbs = 1;
659              dLchSchInfo->staInd[0].fillCtrlPdu = true; 
660           }
661
662           /* Fill logical channel scheduling info */
663           dLchSchInfo->staInd[0].staIndTb[0].lchStaInd[nmbDLch].lcId = \
664              schRep->lcSch[idx].lcId;
665           dLchSchInfo->staInd[0].staIndTb[0].lchStaInd[nmbDLch].totBufSize = \
666              schRep->lcSch[idx].bufSize;
667           nmbDLch++;
668       }
669    }
670
671    /* Calling handler for all dedicated channels scheduling*/
672    if(ret == ROK)
673    {
674       if(nmbDLch)
675       {
676          dLchSchInfo->staInd[0].staIndTb[0].nmbLch = nmbDLch;
677          rlcProcDedLcSchedRpt(pst, 0, dLchSchInfo);
678       }
679    }
680
681    RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, schRep, sizeof(RlcSchedResultRpt));
682    return ret;
683 }
684
685
686 /*******************************************************************
687  *
688  * @brief Handles Ue Reconfig Request from DU APP
689  *
690  * @details
691  *
692  *    Function : RlcProcUeReconfigReq
693  *
694  *    Functionality:
695  *      Handles Ue Reconfig Request from DU APP
696  *
697  * @params[in] Post structure pointer
698  *             RlcUeCfg pointer 
699  * @return ROK     - success
700  *         RFAILED - failure
701  *
702  * ****************************************************************/
703 uint8_t RlcProcUeReconfigReq(Pst *pst, RlcUeCfg *ueCfg)
704 {
705    uint8_t ret = ROK;
706    RlcCfgInfo *rlcUeCfg = NULLP; //Seed code Rlc cfg struct
707    RlcCb *rlcUeCb = NULLP;
708    RlcCfgCfmInfo cfgRsp; 
709    Pst rspPst;
710
711    DU_LOG("\nDEBUG  -->  RLC: UE reconfig request received. CellID[%d] UEID[%d]",ueCfg->cellId, ueCfg->ueId);
712
713    rlcUeCb = RLC_GET_RLCCB(pst->dstInst);
714    RLC_ALLOC(rlcUeCb, rlcUeCfg, sizeof(RlcCfgInfo));
715    if(rlcUeCfg == NULLP)
716    {
717       DU_LOG("\nERROR  -->  RLC: Failed to allocate memory at RlcProcUeReconfigReq()");
718       ret = RFAILED;
719    }
720    else
721    {
722       memset(rlcUeCfg, 0, sizeof(RlcCfgInfo));
723       ret = fillRlcCfg(rlcUeCb, rlcUeCfg, ueCfg);
724       if(ret != ROK)
725       {
726          DU_LOG("\nERROR  -->  RLC: Failed to fill configuration at RlcProcUeReconfigReq()");
727          FILL_PST_RLC_TO_DUAPP(rspPst, RLC_UL_INST, EVENT_RLC_UE_RECONFIG_RSP);
728          fillRlcCfgFailureRsp(&cfgRsp, ueCfg);
729          SendRlcUeCfgRspToDu(&rspPst, &cfgRsp);
730       }
731       else
732       {
733          ret = RlcProcCfgReq(pst, rlcUeCfg);
734          if(ret != ROK)
735             DU_LOG("\nERROR  -->  RLC: Failed to configure Add/Mod/Del entities at RlcProcUeReconfigReq()");
736       }
737    }
738    
739    RLC_FREE_SHRABL_BUF(pst->region, pst->pool, ueCfg, sizeof(RlcUeCfg));
740    return ret;
741 }
742
743 /* ****************************************************************
744  *
745  * @brief Process the DL Data transfer from DU APP
746  *
747  * @details
748  *
749  *    Function : RlcProcDlUserDataTransfer
750  *
751  *    Functionality: Process the DL transfer from DU APP
752  *
753  * @params[in] Post structure
754  *             DL RRC Message info
755  * @return ROK     - success
756  *         RFAILED - failure
757  *
758  * ****************************************************************/
759 uint8_t RlcProcDlUserDataTransfer(Pst *pst, RlcDlUserDataInfo *dlDataMsgInfo)
760 {
761    Buffer        *mBuf = NULLP;
762    RlcDatReqInfo *datReqInfo = NULLP;
763
764    if(dlDataMsgInfo->dlMsg == NULLP)
765    {
766       DU_LOG("\nERROR  -->  RLC_DL : Received DL message is NULLP in RlcProcDlUserDataTransfer()");
767       return RFAILED;
768    }
769    RLC_SHRABL_STATIC_BUF_ALLOC(RLC_MEM_REGION_DL, RLC_POOL, datReqInfo, sizeof(RlcDatReqInfo));
770    if(!datReqInfo)
771    {
772       DU_LOG("\nERROR  -->  RLC_DL : Memory allocation failed for DatReq in RlcProcDlUserDataTransfer()");
773       ODU_PUT_MSG_BUF(dlDataMsgInfo->dlMsg);
774       RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, dlDataMsgInfo, sizeof(RlcDlUserDataInfo));
775       return RFAILED;
776    }
777
778    datReqInfo->rlcId.rbType = RB_TYPE_DRB;
779    datReqInfo->rlcId.rbId   = dlDataMsgInfo->rbId;
780    datReqInfo->rlcId.ueId   = dlDataMsgInfo->ueId;
781    datReqInfo->rlcId.cellId = dlDataMsgInfo->cellId;
782    datReqInfo->lcType       = LCH_DTCH;
783    datReqInfo->sduId        = ++(rlcCb[pst->dstInst]->dlSduId);
784    mBuf = dlDataMsgInfo->dlMsg;
785    if(rlcProcDlData(pst, datReqInfo, mBuf) != ROK)
786    {
787       return RFAILED;
788    }
789     
790    /* Free memory allocated by du app */
791    RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_DL, RLC_POOL, datReqInfo, sizeof(RlcDatReqInfo));
792    RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, dlDataMsgInfo, sizeof(RlcDlUserDataInfo));
793    return ROK;
794 }
795
796 /*******************************************************************
797  *
798  * @brief sending UE delete response to DU 
799  *
800  * @details
801  *
802  *    Function : sendRlcUeDeleteRspToDu 
803  *
804  *    Functionality:
805  *      sending UE delete response to DU 
806  *
807  * @params[in] uint8_t cellId, uint8_t ueId, UeDeleteResult result 
808  *
809  * @return ROK     - success
810  *         RFAILED - failure
811  *
812  * ****************************************************************/
813 uint8_t sendRlcUeDeleteRspToDu(uint16_t cellId,uint8_t ueId, UeDeleteResult result)
814 {
815    Pst pst;  
816    RlcUeDeleteRsp *ueDeleteRsp = NULLP;
817    
818    FILL_PST_RLC_TO_DUAPP(pst, RLC_UL_INST, EVENT_RLC_UE_DELETE_RSP);
819
820    RLC_ALLOC_SHRABL_BUF(pst.region, pst.pool, ueDeleteRsp, sizeof(RlcUeDeleteRsp));
821    if(!ueDeleteRsp)
822    {
823       DU_LOG("\nERROR  -->  RLC: sendRlcUeDeleteRspToDu(): Memory allocation failed ");
824       return RFAILED;
825    }
826    else
827    {
828       ueDeleteRsp->cellId = cellId;
829       ueDeleteRsp->ueId = ueId;
830       ueDeleteRsp->result = result;
831   
832       if(rlcSendUeDeleteRspToDu(&pst, ueDeleteRsp) == ROK)
833       {
834          DU_LOG("\nDEBUG  -->  RLC: UE Delete response send successfully");
835       }
836       else
837       {
838          DU_LOG("\nERROR  -->  RLC: SendRlcUeDeleteRspToDu():Failed to send UE Delete response to DU");
839          RLC_FREE_SHRABL_BUF(pst.region, pst.pool, ueDeleteRsp, sizeof(RlcUeDeleteRsp));
840          return RFAILED;
841       }
842    }
843    return ROK;
844 }
845
846 /*******************************************************************
847 *
848 * @brief Handles Ue delete Request from DU APP
849 *
850 * @details
851 *
852 *    Function : RlcProcUeDeleteReq
853 *
854 *    Functionality:
855 *      Handles Ue delete Request from DU APP
856 *
857 * @params[in] Post structure pointer
858 *             RlcUeDelete pointer
859 * @return ROK     - success
860 *         RFAILED - failure
861 *
862 * ****************************************************************/
863
864 uint8_t RlcProcUeDeleteReq(Pst *pst, RlcUeDelete *ueDelete)
865 {
866    uint8_t ret = ROK;
867    RlcCb *gRlcCb = NULLP;
868    RlcUlUeCb *ueCb = NULLP;
869    UeDeleteResult result=SUCCESSFUL;
870
871    DU_LOG("\nDEBUG  -->  RLC: UE Delete request received. CellID[%d] UEID[%d]",ueDelete->cellId, ueDelete->ueId);
872
873    if(ueDelete != NULLP)
874    {
875       gRlcCb = RLC_GET_RLCCB(pst->dstInst);
876       rlcDbmFetchUlUeCb(gRlcCb,ueDelete->ueId, ueDelete->cellId, &ueCb);
877       if(ueCb != NULLP)
878       {
879          if(ueDelete->cellId == ueCb->cellId)
880          {
881             memcpy(&ueCb->ueDeleteInfo.pst, pst, sizeof(Pst));
882             if((rlcChkTmr(gRlcCb, (PTR)ueCb, EVENT_RLC_UE_DELETE_TMR)) == FALSE)
883             {
884                rlcStartTmr(gRlcCb,(PTR)ueCb, EVENT_RLC_UE_DELETE_TMR);
885             }
886          }
887          else
888          {
889             result = INVALID_CELLID;
890          }
891       }
892       else
893       {
894          result = INVALID_UEID;
895       }
896
897       if(result != SUCCESSFUL)
898       {
899          ret = sendRlcUeDeleteRspToDu(ueDelete->cellId, ueDelete->ueId, result);
900          if(ret != ROK)
901          {
902             DU_LOG("\nERROR  -->  RLC: RlcProcUeDeleteReq():Failed to send UE Delete response to DU");
903          }
904       }
905       RLC_FREE_SHRABL_BUF(pst->region, pst->pool, ueDelete, sizeof(RlcUeDelete));
906    }
907    else
908    {
909       DU_LOG("\nERROR  -->  RLC: RlcProcUeDeleteReq(): Recieved NULL pointer UE Delete ");
910       ret = RFAILED;
911    }
912    return ret;
913 }
914
915 /*******************************************************************
916 *
917 * @brief Send the Slice Metrics to  DU APP
918 *
919 * @details
920 *
921 *    Function : sendSlicePmToDu
922 *
923 *    Functionality:
924 *      Handles the sending of Slice Metrics to  DU APP
925 *
926 * @params[in] Post structure pointer
927 *             SlicePmList *sliceStats pointer
928 *
929 * @return ROK     - success
930 *         RFAILED - failure
931 *
932 * ****************************************************************/
933 uint8_t sendSlicePmToDu(SlicePmList *sliceStats)
934 {
935    Pst pst;  
936    
937    FILL_PST_RLC_TO_DUAPP(pst, RLC_UL_INST, EVENT_RLC_SLICE_PM_TO_DU);
938
939    if(!sliceStats)
940    {
941       DU_LOG("\nERROR  -->  RLC: sendSlicePmToDu(): Memory allocation failed ");
942       return RFAILED;
943    }
944    else
945    {
946       if(rlcSendSlicePmToDu(&pst, sliceStats) == ROK)
947       {
948          DU_LOG("\nDEBUG  -->  RLC: Slice PM send successfully");
949       }
950       else
951       {
952          DU_LOG("\nERROR  -->  RLC: sendSlicePmToDu():Failed to send Slice PM to DU");
953          RLC_FREE_SHRABL_BUF(pst.region, pst.pool, sliceStats, sizeof(SlicePmList));
954          return RFAILED;
955       }
956    }
957    return ROK;
958 }
959
960 /**
961  * @brief 
962  *    Handler for searching the Slice Entry in Slice Metrics structure
963  *
964  * @details
965  *    This func finds the slice entry in the SliceMetric record structure and
966  *    return the index of the slice sot hat Tput entries can be done
967  *
968  * @param[in] snssaiVal : Snssai Val to be searched
969  *            *snssaiIdx : O/P : Index of the Slice in Slice Metrics record
970  *            sliceStats : Pointer of Slice metrics record list
971  *
972  * @return bool: True: If slice found in the record
973  *               False: If Slice not found; thus parent function will create the
974  *               recpord of this snssai
975  *   
976  */
977 bool rlcFindSliceEntry(SliceIdentifier snssaiVal, uint8_t *snssaiIdx, SlicePmList *sliceStats)
978 {
979    uint8_t cntSlices = sliceStats->numSlice;
980
981    for(*snssaiIdx = 0;(*snssaiIdx) < cntSlices; (*snssaiIdx)++)
982    {
983       if((snssaiVal.sst == sliceStats->sliceRecord[*snssaiIdx].networkSliceIdentifier.sst)&&
984             (snssaiVal.sd == sliceStats->sliceRecord[*snssaiIdx].networkSliceIdentifier.sd))
985       {
986          return TRUE;
987       }
988    }
989    return FALSE;
990 }
991
992
993 /*******************************************************************
994 *
995 * @brief Builds the Slice Performance Metrics structure to be sent to DU
996 *
997 * @details
998 *
999 *    Function : BuildSliceReportToDu
1000 *
1001 *    Functionality:
1002 *      Builds the Slice Performance Metrics structure to be sent to DU
1003 *
1004 * @params[in] uint8_t snssaiCnt
1005 *             
1006 * @return ROK     - success
1007 *         RFAILED - failure
1008 *
1009 * ****************************************************************/
1010 uint8_t BuildSliceReportToDu(uint8_t snssaiCnt)
1011 {
1012    CmLList  *node = NULLP;
1013    RlcTptPerSnssai *snssaiNode = NULLP;
1014    Direction dir = DIR_UL;
1015    SlicePmList *sliceStats = NULLP;   /*Slice metric */
1016    SliceIdentifier snssaiVal ;
1017    uint8_t snssaiIdx = 0;
1018
1019    if(snssaiCnt == 0)
1020    {
1021       DU_LOG("\nERROR  -->  RLC: No SNSSAI to send the SLice PM");
1022       return RFAILED;
1023    }
1024
1025    RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_UL, RLC_POOL, sliceStats, sizeof(SlicePmList));
1026    if(sliceStats == NULLP)
1027    {
1028       DU_LOG("\nERROR  -->  RLC: Memory Allocation Failed");
1029       return RFAILED;
1030    }
1031    RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_UL, RLC_POOL, sliceStats->sliceRecord, snssaiCnt * (sizeof(SlicePm)));
1032
1033    if(sliceStats->sliceRecord == NULLP)
1034    {
1035       DU_LOG("\nERROR  -->  RLC: Memory Allocation Failed");
1036       RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_UL, RLC_POOL, sliceStats, sizeof(SlicePmList));
1037       return RFAILED;
1038    }
1039    while(dir < DIR_BOTH)
1040    {
1041       node = arrTputPerSnssai[dir]->first;
1042       if(node == NULLP)
1043       {
1044          DU_LOG("\nERROR  -->  RLC: No SNSSAI in list");
1045          RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_UL, RLC_POOL, sliceStats, sizeof(SlicePmList));
1046          RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_UL, RLC_POOL, sliceStats->sliceRecord, (snssaiCnt * (sizeof(SlicePm))));
1047          return RFAILED;
1048       }
1049
1050       while(node)
1051       {
1052          snssaiIdx = 0;
1053          snssaiNode = (RlcTptPerSnssai *)node->node;
1054
1055          snssaiVal.sst = snssaiNode->snssai->sst;
1056          snssaiVal.sd = snssaiNode->snssai->sd[2]+snssaiNode->snssai->sd[1]*10+snssaiNode->snssai->sd[0]*100;
1057          if(rlcFindSliceEntry(snssaiVal, &snssaiIdx, sliceStats) == FALSE)
1058          {
1059             sliceStats->sliceRecord[snssaiIdx].networkSliceIdentifier = snssaiVal;
1060             sliceStats->numSlice++;
1061          }
1062          if(dir == DIR_UL)
1063          {
1064             sliceStats->sliceRecord[snssaiIdx].ThpUl = snssaiNode->tpt;
1065          }
1066          else
1067          {
1068             sliceStats->sliceRecord[snssaiIdx].ThpDl = snssaiNode->tpt;
1069          }
1070          node = node->next;
1071       }
1072       dir++;
1073    }
1074
1075    sendSlicePmToDu(sliceStats);
1076    return ROK;
1077 }
1078 /**********************************************************************
1079          End of file
1080 **********************************************************************/