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