119ac12f1ed6e3a5bac84b23f9311dad1835dade
[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 = RB_TYPE_SRB;
405    datReqInfo->rlcId.rbId = dlRrcMsgInfo->lcId;
406    datReqInfo->rlcId.ueId = dlRrcMsgInfo->ueId;
407    datReqInfo->rlcId.cellId = dlRrcMsgInfo->cellId;
408    datReqInfo->lcType = LCH_DCCH;
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, RlcUlData *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(!dLchPduPres)
483       {
484          RLC_SHRABL_STATIC_BUF_ALLOC(RLC_MEM_REGION_UL, RLC_POOL, dLchUlDat, \
485                sizeof(RguDDatIndInfo));
486          if(!dLchUlDat)
487          {
488             DU_LOG("\nERROR  -->  RLC : Memory allocation failed at RlcMacProcUlData");
489             ret = RFAILED;
490             break;
491          }
492          dLchPduPres = TRUE;
493       }
494
495       /* Copy fixed buffer to message */
496       lcId = ulData->pduInfo[idx].lcId;
497       if(ODU_GET_MSG_BUF(RLC_MEM_REGION_UL, RLC_POOL, \
498                &dLchData[lcId].pdu.mBuf[dLchData[lcId].pdu.numPdu]) != ROK)
499       {
500          DU_LOG("\nERROR  -->  RLC : Memory allocation failed at RlcMacProcUlData");
501          for(pduIdx=0; pduIdx < dLchData[lcId].pdu.numPdu; pduIdx++)
502          {
503             ODU_PUT_MSG_BUF(dLchData[lcId].pdu.mBuf[dLchData[lcId].pdu.numPdu]);
504          }
505          RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_UL, RLC_POOL, dLchUlDat, \
506                sizeof(RguDDatIndInfo));
507          ret = RFAILED;
508          break;
509       }
510       oduCpyFixBufToMsg(ulData->pduInfo[idx].pduBuf, \
511             dLchData[lcId].pdu.mBuf[dLchData[lcId].pdu.numPdu],\
512             ulData->pduInfo[idx].pduLen);
513
514       dLchData[lcId].pdu.numPdu++;
515    }
516
517    /* If any PDU received on dedicated logical channel, copy into RguDDatIndInfo
518     * and call its handler */
519    if(ret == ROK)
520    {
521       if(dLchPduPres)
522       {
523          dLchUlDat->cellId = ulData->cellId;
524          GET_UE_ID(ulData->rnti, dLchUlDat->rnti);
525
526          for(idx = 0; idx < MAX_NUM_LC; idx++)
527          {
528             if(dLchData[idx].pdu.numPdu)
529             {
530                memcpy(&dLchUlDat->lchData[numDLch], &dLchData[idx], sizeof(RguLchDatInd));
531                numDLch++;
532             }
533          }
534          dLchUlDat->numLch = numDLch;
535          rlcProcDedLcUlData(pst, 0, dLchUlDat);
536       }
537    }
538
539    for(pduIdx = 0; pduIdx < ulData->numPdu; pduIdx++)
540    {
541       RLC_FREE_SHRABL_BUF(pst->region, pst->pool, ulData->pduInfo[pduIdx].pduBuf, \
542             ulData->pduInfo[pduIdx].pduLen);
543    }
544    RLC_FREE_SHRABL_BUF(pst->region, pst->pool, ulData, sizeof(RlcUlData));
545    return ROK;
546
547 }/* End of RlcProcUlData */
548
549 /*******************************************************************
550  *
551  * @brief Handler for extracting common and dedicated channel
552  *      Scheduling result report.
553  *
554  * @details
555  *
556  *    Function : RlcProcSchedResultRpt
557  *
558  *    Functionality:
559  *     Handler for extracting common and dedicated channel
560  *      Scheduling result report
561  *
562  * @params[in]
563  * @return ROK     - success
564  *         RFAILED - failure
565  *
566  * ****************************************************************/
567 uint8_t RlcProcSchedResultRpt(Pst *pst, RlcSchedResultRpt *schRep)
568 {
569    uint8_t ret = ROK;
570    uint8_t idx;                     /* Iterator */
571    uint8_t nmbDLch = 0;                 /* Number of dedicated logical channles */
572    RguCStaIndInfo   *cLchSchInfo;    /* Common logical channel scheduling result */
573    RguDStaIndInfo   *dLchSchInfo;  /* Dedicated logical channel scheduling result */
574
575    DU_LOG("\nDEBUG  -->  RLC : Received scheduling report from MAC");
576    for(idx=0; idx < schRep->numLc; idx++)
577    {
578       /* Fill status info structure if at least one channel's scheduling report is received */
579       if(nmbDLch == 0)
580       {
581          RLC_SHRABL_STATIC_BUF_ALLOC(RLC_MEM_REGION_DL, RLC_POOL, dLchSchInfo, \
582                sizeof(RguDStaIndInfo));
583          if(!dLchSchInfo)
584          {
585             DU_LOG("\nERROR  -->  RLC: RlcProcSchedResultRpt: Memory allocation failed for dLchSchInfo");
586             ret = RFAILED;
587             break;
588          }
589
590          dLchSchInfo->cellId = schRep->cellId;
591          dLchSchInfo->nmbOfUeGrantPerTti = 1;
592          /* MAC sends Scheduling report for one UE at a time. Hence filling
593             only the 0th index of staInd */
594          dLchSchInfo->staInd[0].rnti = schRep->rnti;
595
596          /* Storing sfn/slot into a single 32-bit variable to be used later*/
597          dLchSchInfo->staInd[0].transId = schRep->slotInfo.sfn;
598          dLchSchInfo->staInd[0].transId = \
599                                           (dLchSchInfo->staInd[0].transId << 16) | schRep->slotInfo.slot; 
600          dLchSchInfo->staInd[0].nmbOfTbs = 1;
601          dLchSchInfo->staInd[0].fillCtrlPdu = true; 
602       }
603
604       /* Fill logical channel scheduling info */
605       dLchSchInfo->staInd[0].staIndTb[0].lchStaInd[nmbDLch].lcId = \
606                                                                    schRep->lcSch[idx].lcId;
607       dLchSchInfo->staInd[0].staIndTb[0].lchStaInd[nmbDLch].totBufSize = \
608                                                                          schRep->lcSch[idx].bufSize;
609       nmbDLch++;
610    }
611
612    /* Calling handler for all dedicated channels scheduling*/
613    if(ret == ROK)
614    {
615       if(nmbDLch)
616       {
617          dLchSchInfo->staInd[0].staIndTb[0].nmbLch = nmbDLch;
618          rlcProcDedLcSchedRpt(pst, 0, dLchSchInfo);
619       }
620    }
621
622    RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, schRep, sizeof(RlcSchedResultRpt));
623    return ret;
624 }
625
626
627 /*******************************************************************
628  *
629  * @brief Handles Ue Reconfig Request from DU APP
630  *
631  * @details
632  *
633  *    Function : RlcProcUeReconfigReq
634  *
635  *    Functionality:
636  *      Handles Ue Reconfig Request from DU APP
637  *
638  * @params[in] Post structure pointer
639  *             RlcUeCfg pointer 
640  * @return ROK     - success
641  *         RFAILED - failure
642  *
643  * ****************************************************************/
644 uint8_t RlcProcUeReconfigReq(Pst *pst, RlcUeCfg *ueCfg)
645 {
646    uint8_t ret = ROK;
647    RlcCfgInfo *rlcUeCfg = NULLP; //Seed code Rlc cfg struct
648    RlcCb *rlcUeCb = NULLP;
649    RlcCfgCfmInfo cfgRsp; 
650    Pst rspPst;
651
652    DU_LOG("\nDEBUG  -->  RLC: UE reconfig request received. CellID[%d] UEID[%d]",ueCfg->cellId, ueCfg->ueId);
653
654    rlcUeCb = RLC_GET_RLCCB(pst->dstInst);
655    RLC_ALLOC(rlcUeCb, rlcUeCfg, sizeof(RlcCfgInfo));
656    if(rlcUeCfg == NULLP)
657    {
658       DU_LOG("\nERROR  -->  RLC: Failed to allocate memory at RlcProcUeReconfigReq()");
659       ret = RFAILED;
660    }
661    else
662    {
663       memset(rlcUeCfg, 0, sizeof(RlcCfgInfo));
664       ret = fillRlcCfg(rlcUeCb, rlcUeCfg, ueCfg);
665       if(ret != ROK)
666       {
667          DU_LOG("\nERROR  -->  RLC: Failed to fill configuration at RlcProcUeReconfigReq()");
668          FILL_PST_RLC_TO_DUAPP(rspPst, RLC_UL_INST, EVENT_RLC_UE_RECONFIG_RSP);
669          fillRlcCfgFailureRsp(&cfgRsp, ueCfg);
670          SendRlcUeCfgRspToDu(&rspPst, &cfgRsp);
671       }
672       else
673       {
674          ret = RlcProcCfgReq(pst, rlcUeCfg);
675          if(ret != ROK)
676             DU_LOG("\nERROR  -->  RLC: Failed to configure Add/Mod/Del entities at RlcProcUeReconfigReq()");
677       }
678    }
679    
680    RLC_FREE_SHRABL_BUF(pst->region, pst->pool, ueCfg, sizeof(RlcUeCfg));
681    return ret;
682 }
683
684 /* ****************************************************************
685  *
686  * @brief Process the DL Data transfer from DU APP
687  *
688  * @details
689  *
690  *    Function : RlcProcDlUserDataTransfer
691  *
692  *    Functionality: Process the DL transfer from DU APP
693  *
694  * @params[in] Post structure
695  *             DL RRC Message info
696  * @return ROK     - success
697  *         RFAILED - failure
698  *
699  * ****************************************************************/
700 uint8_t RlcProcDlUserDataTransfer(Pst *pst, RlcDlUserDataInfo *dlDataMsgInfo)
701 {
702    Buffer        *mBuf = NULLP;
703    RlcDatReqInfo *datReqInfo = NULLP;
704
705    if(dlDataMsgInfo->dlMsg == NULLP)
706    {
707       DU_LOG("\nERROR  -->  RLC_DL : Received DL message is NULLP in RlcProcDlUserDataTransfer()");
708       return RFAILED;
709    }
710    RLC_SHRABL_STATIC_BUF_ALLOC(RLC_MEM_REGION_DL, RLC_POOL, datReqInfo, sizeof(RlcDatReqInfo));
711    if(!datReqInfo)
712    {
713       DU_LOG("\nERROR  -->  RLC_DL : Memory allocation failed for DatReq in RlcProcDlUserDataTransfer()");
714       ODU_PUT_MSG_BUF(dlDataMsgInfo->dlMsg);
715       RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, dlDataMsgInfo, sizeof(RlcDlUserDataInfo));
716       return RFAILED;
717    }
718
719    datReqInfo->rlcId.rbType = RB_TYPE_DRB;
720    datReqInfo->rlcId.rbId   = dlDataMsgInfo->rbId;
721    datReqInfo->rlcId.ueId   = dlDataMsgInfo->ueId;
722    datReqInfo->rlcId.cellId = dlDataMsgInfo->cellId;
723    datReqInfo->lcType       = LCH_DTCH;
724    datReqInfo->sduId        = ++(rlcCb[pst->dstInst]->dlSduId);
725    mBuf = dlDataMsgInfo->dlMsg;
726    if(rlcProcDlData(pst, datReqInfo, mBuf) != ROK)
727    {
728       return RFAILED;
729    }
730     
731    /* Free memory allocated by du app */
732    RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_DL, RLC_POOL, datReqInfo, sizeof(RlcDatReqInfo));
733    RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, dlDataMsgInfo, sizeof(RlcDlUserDataInfo));
734    return ROK;
735 }
736
737 /*******************************************************************
738  *
739  * @brief sending UE delete response to DU 
740  *
741  * @details
742  *
743  *    Function : sendRlcUeDeleteRspToDu 
744  *
745  *    Functionality:
746  *      sending UE delete response to DU 
747  *
748  * @params[in] uint8_t cellId, uint8_t ueId, UeDeleteResult result 
749  *
750  * @return ROK     - success
751  *         RFAILED - failure
752  *
753  * ****************************************************************/
754 uint8_t sendRlcUeDeleteRspToDu(uint16_t cellId,uint8_t ueId, UeDeleteResult result)
755 {
756    Pst pst;  
757    RlcUeDeleteRsp *ueDeleteRsp = NULLP;
758    
759    FILL_PST_RLC_TO_DUAPP(pst, RLC_UL_INST, EVENT_RLC_UE_DELETE_RSP);
760
761    RLC_ALLOC_SHRABL_BUF(pst.region, pst.pool, ueDeleteRsp, sizeof(RlcUeDeleteRsp));
762    if(!ueDeleteRsp)
763    {
764       DU_LOG("\nERROR  -->  RLC: sendRlcUeDeleteRspToDu(): Memory allocation failed ");
765       return RFAILED;
766    }
767    else
768    {
769       ueDeleteRsp->cellId = cellId;
770       ueDeleteRsp->ueId = ueId;
771       ueDeleteRsp->result = result;
772   
773       if(rlcSendUeDeleteRspToDu(&pst, ueDeleteRsp) == ROK)
774       {
775          DU_LOG("\nDEBUG  -->  RLC: UE Delete response send successfully");
776       }
777       else
778       {
779          DU_LOG("\nERROR  -->  RLC: SendRlcUeDeleteRspToDu():Failed to send UE Delete response to DU");
780          RLC_FREE_SHRABL_BUF(pst.region, pst.pool, ueDeleteRsp, sizeof(RlcUeDeleteRsp));
781          return RFAILED;
782       }
783    }
784    return ROK;
785 }
786
787 /*******************************************************************
788 *
789 * @brief Handles Ue delete Request from DU APP
790 *
791 * @details
792 *
793 *    Function : RlcProcUeDeleteReq
794 *
795 *    Functionality:
796 *      Handles Ue delete Request from DU APP
797 *
798 * @params[in] Post structure pointer
799 *             RlcUeDelete pointer
800 * @return ROK     - success
801 *         RFAILED - failure
802 *
803 * ****************************************************************/
804
805 uint8_t RlcProcUeDeleteReq(Pst *pst, RlcUeDelete *ueDelete)
806 {
807    uint8_t ret = ROK;
808    RlcCb *gRlcCb = NULLP;
809    RlcUlUeCb *ueCb = NULLP;
810    UeDeleteResult result=SUCCESSFUL;
811
812    DU_LOG("\nDEBUG  -->  RLC: UE Delete request received. CellID[%d] UEID[%d]",ueDelete->cellId, ueDelete->ueId);
813
814    if(ueDelete != NULLP)
815    {
816       gRlcCb = RLC_GET_RLCCB(pst->dstInst);
817       rlcDbmFetchUlUeCb(gRlcCb,ueDelete->ueId, ueDelete->cellId, &ueCb);
818       if(ueCb != NULLP)
819       {
820          if(ueDelete->cellId == ueCb->cellId)
821          {
822             memcpy(&ueCb->ueDeleteInfo.pst, pst, sizeof(Pst));
823             if((rlcChkTmr(gRlcCb, (PTR)ueCb, EVENT_RLC_UE_DELETE_TMR)) == FALSE)
824             {
825                rlcStartTmr(gRlcCb,(PTR)ueCb, EVENT_RLC_UE_DELETE_TMR);
826             }
827          }
828          else
829          {
830             result = INVALID_CELLID;
831          }
832       }
833       else
834       {
835          result = INVALID_UEID;
836       }
837
838       if(result != SUCCESSFUL)
839       {
840          ret = sendRlcUeDeleteRspToDu(ueDelete->cellId, ueDelete->ueId, result);
841          if(ret != ROK)
842          {
843             DU_LOG("\nERROR  -->  RLC: RlcProcUeDeleteReq():Failed to send UE Delete response to DU");
844          }
845       }
846       RLC_FREE_SHRABL_BUF(pst->region, pst->pool, ueDelete, sizeof(RlcUeDelete));
847    }
848    else
849    {
850       DU_LOG("\nERROR  -->  RLC: RlcProcUeDeleteReq(): Recieved NULL pointer UE Delete ");
851       ret = RFAILED;
852    }
853    return ret;
854 }
855
856 /*******************************************************************
857 *
858 * @brief Send the Slice Metrics to  DU APP
859 *
860 * @details
861 *
862 *    Function : sendSlicePmToDu
863 *
864 *    Functionality:
865 *      Handles the sending of Slice Metrics to  DU APP
866 *
867 * @params[in] Post structure pointer
868 *             SlicePmList *sliceStats pointer
869 *
870 * @return ROK     - success
871 *         RFAILED - failure
872 *
873 * ****************************************************************/
874 uint8_t sendSlicePmToDu(SlicePmList *sliceStats)
875 {
876    Pst pst;  
877    
878    FILL_PST_RLC_TO_DUAPP(pst, RLC_UL_INST, EVENT_RLC_SLICE_PM_TO_DU);
879
880    if(!sliceStats)
881    {
882       DU_LOG("\nERROR  -->  RLC: sendSlicePmToDu(): Memory allocation failed ");
883       return RFAILED;
884    }
885    else
886    {
887       if(rlcSendSlicePmToDu(&pst, sliceStats) == ROK)
888       {
889          DU_LOG("\nDEBUG  -->  RLC: Slice PM send successfully");
890       }
891       else
892       {
893          DU_LOG("\nERROR  -->  RLC: sendSlicePmToDu():Failed to send Slice PM to DU");
894          RLC_FREE_SHRABL_BUF(pst.region, pst.pool, sliceStats, sizeof(SlicePmList));
895          return RFAILED;
896       }
897    }
898    return ROK;
899 }
900
901 /**
902  * @brief 
903  *    Handler for searching the Slice Entry in Slice Metrics structure
904  *
905  * @details
906  *    This func finds the slice entry in the SliceMetric record structure and
907  *    return the index of the slice sot hat Tput entries can be done
908  *
909  * @param[in] snssaiVal : Snssai Val to be searched
910  *            *snssaiIdx : O/P : Index of the Slice in Slice Metrics record
911  *            sliceStats : Pointer of Slice metrics record list
912  *
913  * @return bool: True: If slice found in the record
914  *               False: If Slice not found; thus parent function will create the
915  *               recpord of this snssai
916  *   
917  */
918 bool rlcFindSliceEntry(SliceIdentifier snssaiVal, uint8_t *snssaiIdx, SlicePmList *sliceStats)
919 {
920    uint8_t cntSlices = sliceStats->numSlice;
921
922    for(*snssaiIdx = 0;(*snssaiIdx) < cntSlices; (*snssaiIdx)++)
923    {
924       if((snssaiVal.sst == sliceStats->sliceRecord[*snssaiIdx].networkSliceIdentifier.sst)&&
925             (snssaiVal.sd == sliceStats->sliceRecord[*snssaiIdx].networkSliceIdentifier.sd))
926       {
927          return TRUE;
928       }
929    }
930    return FALSE;
931 }
932
933
934 /*******************************************************************
935 *
936 * @brief Builds the Slice Performance Metrics structure to be sent to DU
937 *
938 * @details
939 *
940 *    Function : BuildSliceReportToDu
941 *
942 *    Functionality:
943 *      Builds the Slice Performance Metrics structure to be sent to DU
944 *
945 * @params[in] uint8_t snssaiCnt
946 *             
947 * @return ROK     - success
948 *         RFAILED - failure
949 *
950 * ****************************************************************/
951 uint8_t BuildSliceReportToDu(uint8_t snssaiCnt)
952 {
953    CmLList  *node = NULLP;
954    RlcTptPerSnssai *snssaiNode = NULLP;
955    Direction dir = DIR_UL;
956    SlicePmList *sliceStats = NULLP;   /*Slice metric */
957    SliceIdentifier snssaiVal ;
958    uint8_t snssaiIdx = 0;
959
960    if(snssaiCnt == 0)
961    {
962       DU_LOG("\nERROR  -->  RLC: No SNSSAI to send the SLice PM");
963       return RFAILED;
964    }
965
966    RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_UL, RLC_POOL, sliceStats, sizeof(SlicePmList));
967    if(sliceStats == NULLP)
968    {
969       DU_LOG("\nERROR  -->  RLC: Memory Allocation Failed");
970       return RFAILED;
971    }
972    RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_UL, RLC_POOL, sliceStats->sliceRecord, snssaiCnt * (sizeof(SlicePm)));
973
974    if(sliceStats->sliceRecord == NULLP)
975    {
976       DU_LOG("\nERROR  -->  RLC: Memory Allocation Failed");
977       RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_UL, RLC_POOL, sliceStats, sizeof(SlicePmList));
978       return RFAILED;
979    }
980    while(dir < DIR_BOTH)
981    {
982       node = arrTputPerSnssai[dir]->first;
983       if(node == NULLP)
984       {
985          DU_LOG("\nERROR  -->  RLC: No SNSSAI in list");
986          RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_UL, RLC_POOL, sliceStats, sizeof(SlicePmList));
987          RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_UL, RLC_POOL, sliceStats->sliceRecord, (snssaiCnt * (sizeof(SlicePm))));
988          return RFAILED;
989       }
990
991       while(node)
992       {
993          snssaiIdx = 0;
994          snssaiNode = (RlcTptPerSnssai *)node->node;
995
996          snssaiVal.sst = snssaiNode->snssai->sst;
997          snssaiVal.sd = snssaiNode->snssai->sd[2]+snssaiNode->snssai->sd[1]*10+snssaiNode->snssai->sd[0]*100;
998          if(rlcFindSliceEntry(snssaiVal, &snssaiIdx, sliceStats) == FALSE)
999          {
1000             sliceStats->sliceRecord[snssaiIdx].networkSliceIdentifier = snssaiVal;
1001             sliceStats->numSlice++;
1002          }
1003          if(dir == DIR_UL)
1004          {
1005             sliceStats->sliceRecord[snssaiIdx].ThpUl = snssaiNode->tpt;
1006          }
1007          else
1008          {
1009             sliceStats->sliceRecord[snssaiIdx].ThpDl = snssaiNode->tpt;
1010          }
1011          node = node->next;
1012       }
1013       dir++;
1014    }
1015
1016    sendSlicePmToDu(sliceStats);
1017    return ROK;
1018 }
1019 /**********************************************************************
1020          End of file
1021 **********************************************************************/