[Epic-ID: ODUHIGH-488][Task-ID: ODUHIGH-501] WG8 Alignment | Ue reset req and rsp
[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    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 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->numLcsToAdd;
232    rlcUeCfg->transId = getTransId();
233    for(lcIdx = 0; lcIdx < rlcUeCfg->numEnt; lcIdx++)
234    {
235       if(fillLcCfg(gCb, &rlcUeCfg->entCfg[lcIdx], &ueCfg->rlcLcCfgAdd[lcIdx]) != ROK)
236       {
237           DU_LOG("\nERROR  --> RLC : fillRlcCfg(): Failed to fill LC configuration");
238           return RFAILED;
239       }
240       rlcUeCfg->entCfg[lcIdx].cfgType = CONFIG_ADD; 
241    }
242    return ROK;
243 }
244
245 /*******************************************************************
246  *
247  * @brief updates LC Cfgs to be Added/Mod/Rel in RLC
248  *
249  * @details
250  *
251  *    Function : updateRlcCfg
252  *
253  *    Functionality:
254  *      updates LC Cfgs to be Add/Mod/Del in RLC
255  *
256  * @params[in] 
257  *             RlcEntCfgInfo pointer
258  *             RlcBearerCfg pointer
259  * @return ROK - Success
260  *          RFAILED - Failure
261  *
262  ******************************************************************/
263
264 uint8_t updateRlcCfg(RlcCb *gCb, RlcCfgInfo *rlcUeCfg, RlcUeRecfg *ueRecfg)
265 {
266    uint8_t lcIdx = 0;
267    
268    rlcUeCfg->ueId    = ueRecfg->ueId;
269    rlcUeCfg->cellId  = ueRecfg->cellId;
270    rlcUeCfg->transId = getTransId();
271    
272    rlcUeCfg->numEnt = 0;
273    for(lcIdx = 0; lcIdx < ueRecfg->numLcsToAdd; lcIdx++)
274    {
275       if(fillLcCfg(gCb, &rlcUeCfg->entCfg[rlcUeCfg->numEnt], &ueRecfg->rlcLcCfgAdd[lcIdx]) != ROK)
276       {
277           DU_LOG("\nERROR  --> RLC : fillRlcCfg(): Failed to fill LC configuration");
278           return RFAILED;
279       }
280       rlcUeCfg->entCfg[rlcUeCfg->numEnt].cfgType = CONFIG_ADD;
281       rlcUeCfg->numEnt++;
282    }
283    for(lcIdx = 0; lcIdx < ueRecfg->numLcsToMod; lcIdx++)
284    {
285       if(fillLcCfg(gCb, &rlcUeCfg->entCfg[rlcUeCfg->numEnt], &ueRecfg->rlcLcCfgMod[lcIdx]) != ROK)
286       {
287           DU_LOG("\nERROR  --> RLC : fillRlcCfg(): Failed to fill LC configuration");
288           return RFAILED;
289       }
290       rlcUeCfg->entCfg[rlcUeCfg->numEnt].cfgType = CONFIG_MOD;
291       rlcUeCfg->numEnt++;
292    }
293    for(lcIdx = 0; lcIdx < ueRecfg->numLcsToRel; lcIdx++)
294    {
295       if(fillLcCfg(gCb, &rlcUeCfg->entCfg[rlcUeCfg->numEnt], &ueRecfg->rlcLcCfgRel[lcIdx]) != ROK)
296       {
297           DU_LOG("\nERROR  --> RLC : fillRlcCfg(): Failed to fill LC configuration");
298           return RFAILED;
299       }
300       rlcUeCfg->entCfg[rlcUeCfg->numEnt].cfgType = CONFIG_DEL;
301       rlcUeCfg->numEnt++;
302    }
303    return ROK;
304 }
305
306 /*******************************************************************
307  *
308  * @brief Fill RlcCfgCfmInfo structure for sending failure response to DU
309  *
310  * @details
311  *
312  *    Function : fillRlcCfgFailureRsp
313  *
314  *    Functionality:
315  *      Fill RlcCfgCfmInfo structure for sending failure response to DU
316  *
317  * @params[in] RlcCfgCfmInfo *cfgRsp, RlcUeCfg *ueCfg
318  *             
319  * @return void 
320  *
321  * ****************************************************************/
322 void fillRlcCfgFailureRsp(RlcCfgCfmInfo *cfgRsp, RlcUeCfg *ueCfg)
323 {
324    uint8_t cfgIdx =0;
325
326    cfgRsp->ueId = ueCfg->ueId;
327    cfgRsp->cellId = ueCfg->cellId;
328    cfgRsp->numEnt = ueCfg->numLcsToAdd;
329    for(cfgIdx =0; cfgIdx<ueCfg->numLcsToAdd; cfgIdx++)
330    {
331       cfgRsp->entCfgCfm[cfgIdx].rbId = ueCfg->rlcLcCfgAdd[cfgIdx].rbId;
332       cfgRsp->entCfgCfm[cfgIdx].rbType = ueCfg->rlcLcCfgAdd[cfgIdx].rbType;
333       cfgRsp->entCfgCfm[cfgIdx].status.status = RLC_DU_APP_RSP_NOK;
334       cfgRsp->entCfgCfm[cfgIdx].status.reason = CKW_CFG_REAS_NONE;
335    }
336 }
337
338 /*******************************************************************
339  *
340  * @brief Fill RlcCfgCfmInfo structure for sending failure response to DU
341  *
342  * @details
343  *
344  *    Function : fillRlcRecfgFailureRsp
345  *
346  *    Functionality:
347  *      Fill RlcCfgCfmInfo structure for sending failure response to DU
348  *
349  * @params[in] RlcCfgCfmInfo *cfgRsp, RlcUeCfg *ueCfg
350  *             
351  * @return void 
352  *
353  * ****************************************************************/
354 void fillRlcRecfgFailureRsp(RlcCfgCfmInfo *cfgRsp, RlcUeRecfg *ueRecfg)
355 {
356    uint8_t cfgIdx =0;
357
358    cfgRsp->ueId = ueRecfg->ueId;
359    cfgRsp->cellId = ueRecfg->cellId;
360    cfgRsp->numEnt = 0;
361    for(cfgIdx =0; cfgIdx<ueRecfg->numLcsToAdd; cfgIdx++)
362    {
363       cfgRsp->entCfgCfm[cfgRsp->numEnt].rbId = ueRecfg->rlcLcCfgAdd[cfgIdx].rbId;
364       cfgRsp->entCfgCfm[cfgRsp->numEnt].rbType = ueRecfg->rlcLcCfgAdd[cfgIdx].rbType;
365       cfgRsp->entCfgCfm[cfgRsp->numEnt].status.status = RLC_DU_APP_RSP_NOK;
366       cfgRsp->entCfgCfm[cfgRsp->numEnt].status.reason = CKW_CFG_REAS_NONE;
367       cfgRsp->numEnt++;
368    }
369    for(cfgIdx =0; cfgIdx<ueRecfg->numLcsToMod; cfgIdx++)
370    {
371       cfgRsp->entCfgCfm[cfgRsp->numEnt].rbId = ueRecfg->rlcLcCfgMod[cfgIdx].rbId;
372       cfgRsp->entCfgCfm[cfgRsp->numEnt].rbType = ueRecfg->rlcLcCfgMod[cfgIdx].rbType;
373       cfgRsp->entCfgCfm[cfgRsp->numEnt].status.status = RLC_DU_APP_RSP_NOK;
374       cfgRsp->entCfgCfm[cfgRsp->numEnt].status.reason = CKW_CFG_REAS_NONE;
375       cfgRsp->numEnt++;
376    }
377    for(cfgIdx =0; cfgIdx<ueRecfg->numLcsToRel; cfgIdx++)
378    {
379       cfgRsp->entCfgCfm[cfgRsp->numEnt].rbId = ueRecfg->rlcLcCfgRel[cfgIdx].rbId;
380       cfgRsp->entCfgCfm[cfgRsp->numEnt].rbType = ueRecfg->rlcLcCfgRel[cfgIdx].rbType;
381       cfgRsp->entCfgCfm[cfgRsp->numEnt].status.status = RLC_DU_APP_RSP_NOK;
382       cfgRsp->entCfgCfm[cfgRsp->numEnt].status.reason = CKW_CFG_REAS_NONE;
383       cfgRsp->numEnt++;
384    }
385 }
386
387 /*******************************************************************
388  *
389  * @brief Handles Ue Create Request from DU APP
390  *
391  * @details
392  *
393  *    Function : RlcProcUeCreateReq
394  *
395  *    Functionality:
396  *      Handles Ue create Request from DU APP
397  *
398  * @params[in] Post structure pointer
399  *             RlcUeCfg pointer 
400  * @return ROK     - success
401  *         RFAILED - failure
402  *
403  * ****************************************************************/
404 uint8_t RlcProcUeCreateReq(Pst *pst, RlcUeCfg *ueCfg)
405 {
406    uint8_t ret = ROK;
407    RlcCb *gCb;
408    RlcCfgInfo *rlcUeCfg = NULLP;
409    RlcCfgCfmInfo cfgRsp;
410    Pst rspPst;
411
412    gCb = RLC_GET_RLCCB(pst->dstInst);
413    RLC_ALLOC(gCb, rlcUeCfg, sizeof(RlcCfgInfo));
414    if(rlcUeCfg == NULLP)
415    {
416       DU_LOG("\nERROR  -->  RLC: Failed to allocate memory at RlcProcUeCreateReq()");
417       ret = RFAILED;
418    }
419    else
420    {
421       memset(rlcUeCfg, 0, sizeof(RlcCfgInfo));
422       ret = fillRlcCfg(gCb, rlcUeCfg, ueCfg); 
423       if(ret != ROK)
424       {
425          DU_LOG("\nERROR  -->  RLC: Failed to fill configuration at RlcProcUeCreateReq()");
426          FILL_PST_RLC_TO_DUAPP(rspPst, RLC_UL_INST, EVENT_RLC_UE_CREATE_RSP);
427          fillRlcCfgFailureRsp(&cfgRsp, ueCfg);
428          SendRlcUeCfgRspToDu(&rspPst, &cfgRsp);
429
430       }
431       else
432       {
433          ret = RlcProcCfgReq(pst, rlcUeCfg);
434          if(ret != ROK)
435             DU_LOG("\nERROR  -->  RLC: Failed to configure Add/Mod/Del entities at RlcProcUeCreateReq()");
436       }
437    }
438    RLC_FREE_SHRABL_BUF(pst->region, pst->pool, ueCfg, sizeof(RlcUeCfg));
439    return ret;
440 }
441
442 /*******************************************************************
443 *
444 * @brief filling the structure of rrc delivery msg info
445 *
446 * @details
447 *
448 *    Function : BuildAndSendRrcDeliveryReportToDu
449 *
450 *    Functionality: filling the structure of rrc delivery msg info
451 *
452 * @return ROK     - success
453 *         RFAILED - failure
454 *
455 * ****************************************************************/
456 uint8_t BuildAndSendRrcDeliveryReportToDu( RlcDlRrcMsgInfo *dlRrcMsgInfo )
457 {
458     Pst             pst;
459     RrcDeliveryReport *rrcDelivery;
460
461     DU_LOG("\nINFO  -->  RLC : Filling RRC Delivery Report");
462     RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_UL, RLC_POOL, rrcDelivery, sizeof(RrcDeliveryReport));
463
464     if(rrcDelivery)
465     {
466        rrcDelivery->cellId = dlRrcMsgInfo->cellId;
467        rrcDelivery->ueId  = dlRrcMsgInfo->ueId;
468        rrcDelivery->srbId  = dlRrcMsgInfo->lcId ;
469        rrcDelivery->rrcDeliveryStatus.deliveryStatus    = PDCP_SN;
470        rrcDelivery->rrcDeliveryStatus.triggeringMessage = PDCP_SN;
471
472        /* Sending UL RRC Message transfeer to DU APP */
473        memset(&pst, 0, sizeof(Pst));
474        FILL_PST_RLC_TO_DUAPP(pst, RLC_UL_INST, EVENT_RRC_DELIVERY_MSG_TRANS_TO_DU);
475        rlcSendRrcDeliveryReportToDu(&pst, rrcDelivery);
476     }
477     else
478     {
479        DU_LOG("\nERROR  -->  RLC : Memory allocation failed");
480     }
481
482    return ROK;
483 }
484 /* ****************************************************************
485  *
486  * @brief Process the DL RRC Message from DU APP
487  *
488  * @details
489  *
490  *    Function : RlcProcDlRrcMsgTransfer
491  *
492  *    Functionality: Process the DL RRC Message from DU APP
493  *
494  * @params[in] Post structure
495  *             DL RRC Message info
496  * @return ROK     - success
497  *         RFAILED - failure
498  *
499  * ****************************************************************/
500 uint8_t RlcProcDlRrcMsgTransfer(Pst *pst, RlcDlRrcMsgInfo *dlRrcMsgInfo)
501 {
502    Buffer        *mBuf;
503    RlcDatReqInfo *datReqInfo;
504
505    RLC_SHRABL_STATIC_BUF_ALLOC(RLC_MEM_REGION_DL, RLC_POOL, datReqInfo, sizeof(RlcDatReqInfo));
506    if(!datReqInfo)
507    {
508       DU_LOG("\nERROR  -->  RLC : Memory allocation failed in RlcProcDlRrcMsgTransfer");
509       RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, dlRrcMsgInfo->rrcMsg, dlRrcMsgInfo->msgLen);
510       RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, dlRrcMsgInfo, sizeof(RlcDlRrcMsgInfo));
511       return RFAILED;
512    }
513
514    datReqInfo->rlcId.rbType = RB_TYPE_SRB;
515    datReqInfo->rlcId.rbId = dlRrcMsgInfo->lcId;
516    datReqInfo->rlcId.ueId = dlRrcMsgInfo->ueId;
517    datReqInfo->rlcId.cellId = dlRrcMsgInfo->cellId;
518    datReqInfo->lcType = LCH_DCCH;
519    datReqInfo->sduId = ++(rlcCb[pst->dstInst]->dlSduId);
520
521    /* Copy fixed buffer to message */
522    if(ODU_GET_MSG_BUF(RLC_MEM_REGION_UL, RLC_POOL, &mBuf) != ROK)
523    {
524       DU_LOG("\nERROR  -->  RLC : Memory allocation failed at RlcMacProcUlData");
525       RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_DL, RLC_POOL, datReqInfo, sizeof(RlcDatReqInfo));
526       RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, dlRrcMsgInfo->rrcMsg, dlRrcMsgInfo->msgLen);
527       RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, dlRrcMsgInfo, sizeof(RlcDlRrcMsgInfo));
528       return RFAILED;
529    }
530    oduCpyFixBufToMsg(dlRrcMsgInfo->rrcMsg, mBuf, dlRrcMsgInfo->msgLen);
531
532    if(rlcProcDlData(pst, datReqInfo, mBuf) != ROK)
533    {
534       return RFAILED;
535    }
536
537    /* RRC Delivery report is only send when RRC Delivery status report is true in DL RRC Message */
538    if(dlRrcMsgInfo->deliveryStaRpt)
539    {
540       BuildAndSendRrcDeliveryReportToDu(dlRrcMsgInfo);
541    }
542
543    /* Free memory allocated by du app */
544    RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_DL, RLC_POOL, datReqInfo, sizeof(RlcDatReqInfo));
545    RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, dlRrcMsgInfo->rrcMsg, dlRrcMsgInfo->msgLen);
546    RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, dlRrcMsgInfo, sizeof(RlcDlRrcMsgInfo));
547    return ROK;
548 }
549
550 /*******************************************************************
551  *
552  * @brief Process UL data from UE
553  *
554  * @details
555  *
556  *    Function : RlcProcUlData
557  *
558  *    Functionality:
559  *       This function receives the PDU from MAC.
560  *       seggregates common and dedicated logical channel
561  *       PDU and call respective handler.
562  *
563  * @params[in]
564  * @return ROK     - success
565  *         RFAILED - failure
566  *
567  * ****************************************************************/
568 uint8_t RlcProcUlData(Pst *pst, RlcUlData *ulData)
569 {
570    uint8_t         ret = ROK;
571    uint8_t         idx, pduIdx;
572    uint8_t         lcId;                    /* Logical Channel */
573    uint8_t         numDLch = 0;             /* Number of dedicated logical channel */
574    bool            dLchPduPres;             /* PDU received on dedicated logical channel */
575    RguLchDatInd    dLchData[MAX_NUM_LC];    /* PDU info on dedicated logical channel */
576    RguDDatIndInfo  *dLchUlDat;              /* UL data on dedicated logical channel */
577
578    /* Initializing dedicated logical channel Database */
579    DU_LOG("\nDEBUG  -->  RLC: Received UL Data request from MAC");
580    for(idx = 0; idx < MAX_NUM_LC; idx++)
581    {
582       dLchData[idx].lcId = idx;
583       dLchData[idx].pdu.numPdu = 0;
584    }
585    dLchPduPres = FALSE;
586
587    /* Seggregate PDUs received on common and dedicated channels
588     * and call common channel's handler */
589    for(idx = 0; idx< ulData->numPdu; idx++)
590    {
591       if(!dLchPduPres)
592       {
593          RLC_SHRABL_STATIC_BUF_ALLOC(RLC_MEM_REGION_UL, RLC_POOL, dLchUlDat, \
594                sizeof(RguDDatIndInfo));
595          if(!dLchUlDat)
596          {
597             DU_LOG("\nERROR  -->  RLC : Memory allocation failed at RlcMacProcUlData");
598             ret = RFAILED;
599             break;
600          }
601          dLchPduPres = TRUE;
602       }
603
604       /* Copy fixed buffer to message */
605       lcId = ulData->pduInfo[idx].lcId;
606       if(ODU_GET_MSG_BUF(RLC_MEM_REGION_UL, RLC_POOL, \
607                &dLchData[lcId].pdu.mBuf[dLchData[lcId].pdu.numPdu]) != ROK)
608       {
609          DU_LOG("\nERROR  -->  RLC : Memory allocation failed at RlcMacProcUlData");
610          for(pduIdx=0; pduIdx < dLchData[lcId].pdu.numPdu; pduIdx++)
611          {
612             ODU_PUT_MSG_BUF(dLchData[lcId].pdu.mBuf[dLchData[lcId].pdu.numPdu]);
613          }
614          RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_UL, RLC_POOL, dLchUlDat, \
615                sizeof(RguDDatIndInfo));
616          ret = RFAILED;
617          break;
618       }
619       oduCpyFixBufToMsg(ulData->pduInfo[idx].pduBuf, \
620             dLchData[lcId].pdu.mBuf[dLchData[lcId].pdu.numPdu],\
621             ulData->pduInfo[idx].pduLen);
622
623       dLchData[lcId].pdu.numPdu++;
624    }
625
626    /* If any PDU received on dedicated logical channel, copy into RguDDatIndInfo
627     * and call its handler */
628    if(ret == ROK)
629    {
630       if(dLchPduPres)
631       {
632          dLchUlDat->cellId = ulData->cellId;
633          GET_UE_ID(ulData->rnti, dLchUlDat->rnti);
634
635          for(idx = 0; idx < MAX_NUM_LC; idx++)
636          {
637             if(dLchData[idx].pdu.numPdu)
638             {
639                memcpy(&dLchUlDat->lchData[numDLch], &dLchData[idx], sizeof(RguLchDatInd));
640                numDLch++;
641             }
642          }
643          dLchUlDat->numLch = numDLch;
644          rlcProcDedLcUlData(pst, 0, dLchUlDat);
645       }
646    }
647
648    for(pduIdx = 0; pduIdx < ulData->numPdu; pduIdx++)
649    {
650       RLC_FREE_SHRABL_BUF(pst->region, pst->pool, ulData->pduInfo[pduIdx].pduBuf, \
651             ulData->pduInfo[pduIdx].pduLen);
652    }
653    RLC_FREE_SHRABL_BUF(pst->region, pst->pool, ulData, sizeof(RlcUlData));
654    return ROK;
655
656 }/* End of RlcProcUlData */
657
658 /*******************************************************************
659  *
660  * @brief Handler for extracting common and dedicated channel
661  *      Scheduling result report.
662  *
663  * @details
664  *
665  *    Function : RlcProcSchedResultRpt
666  *
667  *    Functionality:
668  *     Handler for extracting common and dedicated channel
669  *      Scheduling result report
670  *
671  * @params[in]
672  * @return ROK     - success
673  *         RFAILED - failure
674  *
675  * ****************************************************************/
676 uint8_t RlcProcSchedResultRpt(Pst *pst, RlcSchedResultRpt *schRep)
677 {
678    uint8_t ret = ROK;
679    uint8_t idx;                     /* Iterator */
680    uint8_t nmbDLch = 0;                 /* Number of dedicated logical channles */
681    RguDStaIndInfo   *dLchSchInfo;  /* Dedicated logical channel scheduling result */
682
683    DU_LOG("\nDEBUG  -->  RLC : Received scheduling report from MAC");
684    for(idx=0; idx < schRep->numLc; idx++)
685    {
686       /* Fill status info structure if at least one channel's scheduling report is received */
687       if(nmbDLch == 0)
688       {
689          RLC_SHRABL_STATIC_BUF_ALLOC(RLC_MEM_REGION_DL, RLC_POOL, dLchSchInfo, \
690                sizeof(RguDStaIndInfo));
691          if(!dLchSchInfo)
692          {
693             DU_LOG("\nERROR  -->  RLC: RlcProcSchedResultRpt: Memory allocation failed for dLchSchInfo");
694             ret = RFAILED;
695             break;
696          }
697
698          dLchSchInfo->cellId = schRep->cellId;
699          dLchSchInfo->nmbOfUeGrantPerTti = 1;
700          /* MAC sends Scheduling report for one UE at a time. Hence filling
701             only the 0th index of staInd */
702          dLchSchInfo->staInd[0].rnti = schRep->rnti;
703
704          /* Storing sfn/slot into a single 32-bit variable to be used later*/
705          dLchSchInfo->staInd[0].transId = schRep->slotInfo.sfn;
706          dLchSchInfo->staInd[0].transId = \
707                                           (dLchSchInfo->staInd[0].transId << 16) | schRep->slotInfo.slot; 
708          dLchSchInfo->staInd[0].nmbOfTbs = 1;
709          dLchSchInfo->staInd[0].fillCtrlPdu = true; 
710       }
711
712       /* Fill logical channel scheduling info */
713       dLchSchInfo->staInd[0].staIndTb[0].lchStaInd[nmbDLch].lcId = \
714                                                                    schRep->lcSch[idx].lcId;
715       dLchSchInfo->staInd[0].staIndTb[0].lchStaInd[nmbDLch].totBufSize = \
716                                                                          schRep->lcSch[idx].bufSize;
717       nmbDLch++;
718    }
719
720    /* Calling handler for all dedicated channels scheduling*/
721    if(ret == ROK)
722    {
723       if(nmbDLch)
724       {
725          dLchSchInfo->staInd[0].staIndTb[0].nmbLch = nmbDLch;
726          rlcProcDedLcSchedRpt(pst, 0, dLchSchInfo);
727       }
728    }
729
730    RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, schRep, sizeof(RlcSchedResultRpt));
731    return ret;
732 }
733
734
735 /*******************************************************************
736  *
737  * @brief Handles Ue Reconfig Request from DU APP
738  *
739  * @details
740  *
741  *    Function : RlcProcUeReconfigReq
742  *
743  *    Functionality:
744  *      Handles Ue Reconfig Request from DU APP
745  *
746  * @params[in] Post structure pointer
747  *             RlcUeCfg pointer 
748  * @return ROK     - success
749  *         RFAILED - failure
750  *
751  * ****************************************************************/
752 uint8_t RlcProcUeReconfigReq(Pst *pst, RlcUeRecfg *ueRecfg)
753 {
754    uint8_t ret = ROK;
755    RlcCfgInfo *rlcUeCfg = NULLP; //Seed code Rlc cfg struct
756    RlcCb *rlcUeCb = NULLP;
757    RlcCfgCfmInfo cfgRsp; 
758    Pst rspPst;
759
760    DU_LOG("\nDEBUG  -->  RLC: UE reconfig request received. CellID[%d] UEID[%d]",ueRecfg->cellId, ueRecfg->ueId);
761
762    rlcUeCb = RLC_GET_RLCCB(pst->dstInst);
763    RLC_ALLOC(rlcUeCb, rlcUeCfg, sizeof(RlcCfgInfo));
764    if(rlcUeCfg == NULLP)
765    {
766       DU_LOG("\nERROR  -->  RLC: Failed to allocate memory at RlcProcUeReconfigReq()");
767       ret = RFAILED;
768    }
769    else
770    {
771       memset(rlcUeCfg, 0, sizeof(RlcCfgInfo));
772       ret = updateRlcCfg(rlcUeCb, rlcUeCfg, ueRecfg);
773       if(ret != ROK)
774       {
775          DU_LOG("\nERROR  -->  RLC: Failed to fill configuration at RlcProcUeReconfigReq()");
776          FILL_PST_RLC_TO_DUAPP(rspPst, RLC_UL_INST, EVENT_RLC_UE_RECONFIG_RSP);
777          fillRlcRecfgFailureRsp(&cfgRsp, ueRecfg);
778          SendRlcUeCfgRspToDu(&rspPst, &cfgRsp);
779       }
780       else
781       {
782          ret = RlcProcCfgReq(pst, rlcUeCfg);
783          if(ret != ROK)
784             DU_LOG("\nERROR  -->  RLC: Failed to configure Add/Mod/Del entities at RlcProcUeReconfigReq()");
785       }
786    }
787    
788    RLC_FREE_SHRABL_BUF(pst->region, pst->pool, ueRecfg, sizeof(RlcUeRecfg));
789    return ret;
790 }
791
792 /* ****************************************************************
793  *
794  * @brief Process the DL Data transfer from DU APP
795  *
796  * @details
797  *
798  *    Function : RlcProcDlUserDataTransfer
799  *
800  *    Functionality: Process the DL transfer from DU APP
801  *
802  * @params[in] Post structure
803  *             DL RRC Message info
804  * @return ROK     - success
805  *         RFAILED - failure
806  *
807  * ****************************************************************/
808 uint8_t RlcProcDlUserDataTransfer(Pst *pst, RlcDlUserDataInfo *dlDataMsgInfo)
809 {
810    Buffer        *mBuf = NULLP;
811    RlcDatReqInfo *datReqInfo = NULLP;
812
813    if(dlDataMsgInfo->dlMsg == NULLP)
814    {
815       DU_LOG("\nERROR  -->  RLC_DL : Received DL message is NULLP in RlcProcDlUserDataTransfer()");
816       return RFAILED;
817    }
818    RLC_SHRABL_STATIC_BUF_ALLOC(RLC_MEM_REGION_DL, RLC_POOL, datReqInfo, sizeof(RlcDatReqInfo));
819    if(!datReqInfo)
820    {
821       DU_LOG("\nERROR  -->  RLC_DL : Memory allocation failed for DatReq in RlcProcDlUserDataTransfer()");
822       ODU_PUT_MSG_BUF(dlDataMsgInfo->dlMsg);
823       RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, dlDataMsgInfo, sizeof(RlcDlUserDataInfo));
824       return RFAILED;
825    }
826
827    datReqInfo->rlcId.rbType = RB_TYPE_DRB;
828    datReqInfo->rlcId.rbId   = dlDataMsgInfo->rbId;
829    datReqInfo->rlcId.ueId   = dlDataMsgInfo->ueId;
830    datReqInfo->rlcId.cellId = dlDataMsgInfo->cellId;
831    datReqInfo->lcType       = LCH_DTCH;
832    datReqInfo->sduId        = ++(rlcCb[pst->dstInst]->dlSduId);
833    mBuf = dlDataMsgInfo->dlMsg;
834    if(rlcProcDlData(pst, datReqInfo, mBuf) != ROK)
835    {
836       return RFAILED;
837    }
838     
839    /* Free memory allocated by du app */
840    RLC_SHRABL_STATIC_BUF_FREE(RLC_MEM_REGION_DL, RLC_POOL, datReqInfo, sizeof(RlcDatReqInfo));
841    RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, dlDataMsgInfo, sizeof(RlcDlUserDataInfo));
842    return ROK;
843 }
844
845 /*******************************************************************
846  *
847  * @brief sending UE delete response to DU 
848  *
849  * @details
850  *
851  *    Function : sendRlcUeDeleteRspToDu 
852  *
853  *    Functionality:
854  *      sending UE delete response to DU 
855  *
856  * @params[in] uint8_t cellId, uint8_t ueId, CauseOfResult  status 
857  *
858  * @return ROK     - success
859  *         RFAILED - failure
860  *
861  * ****************************************************************/
862 uint8_t sendRlcUeDeleteRspToDu(uint16_t cellId,uint8_t ueId, CauseOfResult  status)
863 {
864    Pst pst;  
865    RlcUeDeleteRsp *ueDeleteRsp = NULLP;
866    
867    FILL_PST_RLC_TO_DUAPP(pst, RLC_UL_INST, EVENT_RLC_UE_DELETE_RSP);
868
869    RLC_ALLOC_SHRABL_BUF(pst.region, pst.pool, ueDeleteRsp, sizeof(RlcUeDeleteRsp));
870    if(!ueDeleteRsp)
871    {
872       DU_LOG("\nERROR  -->  RLC: sendRlcUeDeleteRspToDu(): Memory allocation failed ");
873       return RFAILED;
874    }
875    else
876    {
877       ueDeleteRsp->cellId = cellId;
878       ueDeleteRsp->ueId = ueId;
879       ueDeleteRsp->status = status;
880   
881       if(rlcSendUeDeleteRspToDu(&pst, ueDeleteRsp) == ROK)
882       {
883          DU_LOG("\nDEBUG  -->  RLC: UE Delete response send successfully");
884       }
885       else
886       {
887          DU_LOG("\nERROR  -->  RLC: SendRlcUeDeleteRspToDu():Failed to send UE Delete response to DU");
888          RLC_FREE_SHRABL_BUF(pst.region, pst.pool, ueDeleteRsp, sizeof(RlcUeDeleteRsp));
889          return RFAILED;
890       }
891    }
892    return ROK;
893 }
894
895 /*******************************************************************
896 *
897 * @brief Handles Ue delete Request from DU APP
898 *
899 * @details
900 *
901 *    Function : RlcProcUeDeleteReq
902 *
903 *    Functionality:
904 *      Handles Ue delete Request from DU APP
905 *
906 * @params[in] Post structure pointer
907 *             RlcUeDelete pointer
908 * @return ROK     - success
909 *         RFAILED - failure
910 *
911 * ****************************************************************/
912
913 uint8_t RlcProcUeDeleteReq(Pst *pst, RlcUeDelete *ueDelete)
914 {
915    uint8_t ret = ROK;
916    RlcCb *gRlcCb = NULLP;
917    RlcUlUeCb *ueCb = NULLP;
918    CauseOfResult  status =SUCCESSFUL;
919
920    DU_LOG("\nDEBUG  -->  RLC: UE Delete request received. CellID[%d] UEID[%d]",ueDelete->cellId, ueDelete->ueId);
921
922    if(ueDelete != NULLP)
923    {
924       gRlcCb = RLC_GET_RLCCB(pst->dstInst);
925       rlcDbmFetchUlUeCb(gRlcCb,ueDelete->ueId, ueDelete->cellId, &ueCb);
926       if(ueCb != NULLP)
927       {
928          if(ueDelete->cellId == ueCb->cellId)
929          {
930             memcpy(&ueCb->ueDeleteInfo.pst, pst, sizeof(Pst));
931             if((rlcChkTmr(gRlcCb, (PTR)ueCb, EVENT_RLC_UE_DELETE_TMR)) == FALSE)
932             {
933                rlcStartTmr(gRlcCb,(PTR)ueCb, EVENT_RLC_UE_DELETE_TMR);
934             }
935          }
936          else
937          {
938             status = CELLID_INVALID;
939          }
940       }
941       else
942       {
943          status = UEID_INVALID;
944       }
945
946       if(status != SUCCESSFUL)
947       {
948          ret = sendRlcUeDeleteRspToDu(ueDelete->cellId, ueDelete->ueId, status);
949          if(ret != ROK)
950          {
951             DU_LOG("\nERROR  -->  RLC: RlcProcUeDeleteReq():Failed to send UE Delete response to DU");
952          }
953       }
954       RLC_FREE_SHRABL_BUF(pst->region, pst->pool, ueDelete, sizeof(RlcUeDelete));
955    }
956    else
957    {
958       DU_LOG("\nERROR  -->  RLC: RlcProcUeDeleteReq(): Recieved NULL pointer UE Delete ");
959       ret = RFAILED;
960    }
961    return ret;
962 }
963
964 /*******************************************************************
965 *
966 * @brief Send the Slice Metrics to  DU APP
967 *
968 * @details
969 *
970 *    Function : sendSlicePmToDu
971 *
972 *    Functionality:
973 *      Handles the sending of Slice Metrics to  DU APP
974 *
975 * @params[in] Post structure pointer
976 *             SlicePmList *sliceStats pointer
977 *
978 * @return ROK     - success
979 *         RFAILED - failure
980 *
981 * ****************************************************************/
982 uint8_t sendSlicePmToDu(SlicePmList *sliceStats)
983 {
984    Pst pst;  
985    
986    FILL_PST_RLC_TO_DUAPP(pst, RLC_UL_INST, EVENT_RLC_SLICE_PM_TO_DU);
987
988    if(!sliceStats)
989    {
990       DU_LOG("\nERROR  -->  RLC: sendSlicePmToDu(): Memory allocation failed ");
991       return RFAILED;
992    }
993    else
994    {
995       if(rlcSendSlicePmToDu(&pst, sliceStats) == ROK)
996       {
997          DU_LOG("\nDEBUG  -->  RLC: Slice PM send successfully");
998       }
999       else
1000       {
1001          DU_LOG("\nERROR  -->  RLC: sendSlicePmToDu():Failed to send Slice PM to DU");
1002          RLC_FREE_SHRABL_BUF(pst.region, pst.pool, sliceStats, sizeof(SlicePmList));
1003          return RFAILED;
1004       }
1005    }
1006    return ROK;
1007 }
1008
1009 /**
1010  * @brief 
1011  *    Handler for searching the Slice Entry in Slice Metrics structure
1012  *
1013  * @details
1014  *    This func finds the slice entry in the SliceMetric record structure and
1015  *    return the index of the slice sot hat Tput entries can be done
1016  *
1017  * @param[in] snssaiVal : Snssai Val to be searched
1018  *            *snssaiIdx : O/P : Index of the Slice in Slice Metrics record
1019  *            sliceStats : Pointer of Slice metrics record list
1020  *
1021  * @return bool: True: If slice found in the record
1022  *               False: If Slice not found; thus parent function will create the
1023  *               recpord of this snssai
1024  *   
1025  */
1026 bool rlcFindSliceEntry(SliceIdentifier snssaiVal, uint8_t *snssaiIdx, SlicePmList *sliceStats)
1027 {
1028    uint8_t cntSlices = sliceStats->numSlice;
1029
1030    for(*snssaiIdx = 0;(*snssaiIdx) < cntSlices; (*snssaiIdx)++)
1031    {
1032       if((snssaiVal.sst == sliceStats->sliceRecord[*snssaiIdx].networkSliceIdentifier.sst)&&
1033             (snssaiVal.sd == sliceStats->sliceRecord[*snssaiIdx].networkSliceIdentifier.sd))
1034       {
1035          return TRUE;
1036       }
1037    }
1038    return FALSE;
1039 }
1040
1041
1042 /*******************************************************************
1043 *
1044 * @brief Builds the Slice Performance Metrics structure to be sent to DU
1045 *
1046 * @details
1047 *
1048 *    Function : BuildSliceReportToDu
1049 *
1050 *    Functionality:
1051 *      Builds the Slice Performance Metrics structure to be sent to DU
1052 *
1053 * @params[in] uint8_t snssaiCnt
1054 *             
1055 * @return ROK     - success
1056 *         RFAILED - failure
1057 *
1058 * ****************************************************************/
1059 uint8_t BuildSliceReportToDu(uint8_t snssaiCnt)
1060 {
1061    CmLList  *node = NULLP;
1062    RlcTptPerSnssai *snssaiNode = NULLP;
1063    Direction dir = DIR_UL;
1064    SlicePmList *sliceStats = NULLP;   /*Slice metric */
1065    SliceIdentifier snssaiVal ;
1066    uint8_t snssaiIdx = 0;
1067
1068    if(snssaiCnt == 0)
1069    {
1070       DU_LOG("\nERROR  -->  RLC: No SNSSAI to send the SLice PM");
1071       return RFAILED;
1072    }
1073
1074    RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_UL, RLC_POOL, sliceStats, sizeof(SlicePmList));
1075    if(sliceStats == NULLP)
1076    {
1077       DU_LOG("\nERROR  -->  RLC: Memory Allocation Failed");
1078       return RFAILED;
1079    }
1080    RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_UL, RLC_POOL, sliceStats->sliceRecord, snssaiCnt * (sizeof(SlicePm)));
1081
1082    if(sliceStats->sliceRecord == NULLP)
1083    {
1084       DU_LOG("\nERROR  -->  RLC: Memory Allocation Failed");
1085       RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_UL, RLC_POOL, sliceStats, sizeof(SlicePmList));
1086       return RFAILED;
1087    }
1088    while(dir < DIR_BOTH)
1089    {
1090       node = arrTputPerSnssai[dir]->first;
1091       if(node == NULLP)
1092       {
1093          DU_LOG("\nERROR  -->  RLC: No SNSSAI in list");
1094          RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_UL, RLC_POOL, sliceStats, sizeof(SlicePmList));
1095          RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_UL, RLC_POOL, sliceStats->sliceRecord, (snssaiCnt * (sizeof(SlicePm))));
1096          return RFAILED;
1097       }
1098
1099       while(node)
1100       {
1101          snssaiIdx = 0;
1102          snssaiNode = (RlcTptPerSnssai *)node->node;
1103
1104          snssaiVal.sst = snssaiNode->snssai->sst;
1105          snssaiVal.sd = snssaiNode->snssai->sd[2]+snssaiNode->snssai->sd[1]*10+snssaiNode->snssai->sd[0]*100;
1106          if(rlcFindSliceEntry(snssaiVal, &snssaiIdx, sliceStats) == FALSE)
1107          {
1108             sliceStats->sliceRecord[snssaiIdx].networkSliceIdentifier = snssaiVal;
1109             sliceStats->numSlice++;
1110          }
1111          if(dir == DIR_UL)
1112          {
1113             sliceStats->sliceRecord[snssaiIdx].ThpUl = snssaiNode->tpt;
1114          }
1115          else
1116          {
1117             sliceStats->sliceRecord[snssaiIdx].ThpDl = snssaiNode->tpt;
1118          }
1119          node = node->next;
1120       }
1121       dir++;
1122    }
1123
1124    sendSlicePmToDu(sliceStats);
1125    return ROK;
1126 }
1127 /**********************************************************************
1128          End of file
1129 **********************************************************************/