b7eb803adec5e0a81998cfd613258d4461ec28e3
[o-du/l2.git] / src / 5gnrrlc / rlc_dl_ul_inf_ul.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 /**********************************************************************
20  
21     Name:   NR RLC layer
22  
23     Type:   C include file
24  
25     Desc:   Defines required by LTE MAC
26  
27     File:   rlc_dl_ul_inf_ul.c
28  
29 **********************************************************************/
30
31 /** @file rlc_dl_ul_inf_ul.c
32 @brief  UDX Uplink Module 
33 */
34  
35 /* header include files (.h) */
36 #include "common_def.h"
37 #include "lkw.h"           /* LKW defines */
38 #include "ckw.h"           /* CKW defines */
39 #include "kwu.h"           /* KWU defines */
40 #include "rgu.h"           /* RGU defines */
41 #include "rlc_err.h"        /* Err defines */
42 #include "rlc_env.h"        /* RLC environment options */
43
44 /* extern (.x) include files */
45 #include "lkw.x"           /* LKW */
46 #include "ckw.x"           /* CKW */
47 #include "kwu.x"           /* KWU */
48 #include "rgu.x"           /* RGU */
49
50 #include "rlc_utils.h"            /* RLC defines */
51 #include "rlc_dl_ul_inf.h"
52 #include "rlc_dl.h"
53 #include "rlc_ul.h"
54 #include "du_app_rlc_inf.h"
55 #include "rlc_mgr.h"
56
57 #define RLC_MODULE RLC_DBGMASK_UDX
58 /* local defines */
59
60 /* local externs */
61
62 /* forward references */
63
64 /* public variable declarations */
65 S16 rlcHdlCrlcUlCfgReq ARGS((RlcCb  *gCb,RlcUlCfgTmpData *cfgTmpData,
66                                   RlcCfgCfmInfo *cfmInfo, RlcCfgCfmInfo *cfgCfm));
67
68 /**
69   * @brief
70   * UDX APIs
71   */
72 /**
73  * @brief 
74  *    Handler for bind confirmation from DL.
75  *
76  * @details
77  *    This function handles the bind confirmation received
78  *    from DL. 
79  *
80  * @param[in] pst     Post structure  
81  * @param[in] suId    Service User ID
82  * @param[in] status  Status of confirmation 
83  * 
84  * @return  S16
85  *    -# ROK 
86  *    -# RFAILED
87  */
88
89 S16 rlcUlUdxBndCfm
90 (
91 Pst    *pst,  
92 SuId   suId, 
93 uint8_t status 
94 )
95 {
96    uint16_t        event;        
97    uint16_t        cause;       
98    RlcUdxUlSapCb   *udxSap;   /* RGU SAP Control Block */
99    RlcCb           *tRlcCb;
100
101 #if (ERRCLASS & ERRCLS_INT_PAR)
102    if (pst->dstInst >= MAX_RLC_INSTANCES)
103    {
104       return  (RFAILED);
105    }
106 #endif
107    tRlcCb = RLC_GET_RLCCB(pst->dstInst);
108
109    RLCDBGP_BRIEF(tRlcCb, "rlcUlUdxBndCfm(post, suId(%d), status(%d)\n", 
110                 suId, status);
111
112 #if (ERRCLASS & ERRCLS_INT_PAR)
113    if (tRlcCb->init.cfgDone != TRUE)
114    {
115       DU_LOG("\nERROR  -->  RLC_UL : General configuration not done");
116       RLC_SEND_SAPID_ALARM(tRlcCb,suId, 
117                           LKW_EVENT_LI_BND_CFM, LCM_CAUSE_INV_STATE);
118
119       return RFAILED;
120    }
121
122    if (suId < 0)
123    {
124       DU_LOG("\nERROR  -->  RLC_UL : Invalid suId");
125       RLC_SEND_SAPID_ALARM(tRlcCb,suId, 
126                            LKW_EVENT_LI_BND_CFM, LCM_CAUSE_INV_SUID);
127
128       return RFAILED;
129    }
130 #endif /* ERRCLASS & ERRCLS_INT_PAR */
131
132    udxSap = tRlcCb->u.ulCb->udxUlSap + suId;
133
134    RLCDBGP_DETAIL(tRlcCb, "RlcLiRguBndCfm: For RGU SAP state=%d\n", 
135                  udxSap->state);
136
137    /* Check rguSap state */
138    switch (udxSap->state)
139    {
140       case RLC_SAP_BINDING:
141       {
142          if(TRUE == rlcChkTmr(tRlcCb,(PTR)udxSap,EVENT_RLC_WAIT_BNDCFM))
143          {
144              rlcStopTmr (tRlcCb,(PTR)udxSap, EVENT_RLC_WAIT_BNDCFM);
145          }
146          udxSap->retryCnt = 0;
147           
148          if (status == CM_BND_OK)
149          {
150             udxSap->state = RLC_SAP_BND;
151             event = LCM_EVENT_BND_OK;
152             cause = LKW_CAUSE_SAP_BNDENB;
153          }
154          else
155          {
156             udxSap->state = RLC_SAP_CFG;
157             event = LCM_EVENT_BND_FAIL;
158             cause = LKW_CAUSE_UNKNOWN;
159          }
160       }
161       break;
162
163      default:
164         event = LKW_EVENT_RGU_BND_CFM;
165         cause = LCM_CAUSE_INV_STATE;
166         break;
167    }
168    /* Send an alarm with proper event and cause */
169    RLC_SEND_SAPID_ALARM(tRlcCb,suId, event, cause);
170
171    return ROK;
172
173
174 /**
175  * @brief 
176  *    Handles UDX Configuration Confirm 
177  *
178  * @details
179  *    This function handles the UDX configuration Confirm from DL Instance
180  *
181  * @param[in] pst     Post structure  
182  * @param[in] suId    Service User ID
183  * @param[in] cfmInfo Confirm Information 
184  * 
185  * @return  S16
186  *    -# ROK 
187  *    -# RFAILED
188  */
189 S16 rlcUlUdxCfgCfm
190 (
191 Pst             *pst,  
192 SuId            suId, 
193 RlcCfgCfmInfo   *cfmInfo  
194 )
195 {
196    uint8_t cfgIdx=0;
197    RlcCb             *tRlcCb;
198    RlcCfgCfmInfo    *cfgCfm;
199    RlcUlCfgTmpData   *cfgTmpData;
200    Pst rspPst;
201    memset(&rspPst, 0, sizeof(Pst));
202
203 #if (ERRCLASS & ERRCLS_INT_PAR)
204    if (pst->dstInst >= MAX_RLC_INSTANCES)
205    {
206       RLC_FREE_SHRABL_BUF(pst->region,
207                          pst->pool,
208                          cfmInfo,
209                          sizeof(RlcCfgCfmInfo));
210       return  (RFAILED);
211    }
212 #endif
213    tRlcCb = RLC_GET_RLCCB(pst->dstInst);
214    RLCDBGP_BRIEF(tRlcCb, " suId(%d)\n", suId);
215
216 #if (ERRCLASS & ERRCLS_INT_PAR)
217    if (suId < 0)
218    {
219       DU_LOG("\nERROR  -->  RLC_UL : Invalid suId");
220       RLC_SEND_SAPID_ALARM(tRlcCb,suId, 
221                            LKW_EVENT_LI_BND_CFM, LCM_CAUSE_INV_SUID);
222       RLC_FREE_SHRABL_BUF(pst->region,
223                          pst->pool,
224                          cfmInfo,
225                          sizeof(RlcCfgCfmInfo));
226       return RFAILED;
227    }
228 #endif /* ERRCLASS & ERRCLS_INT_PAR */
229
230    if(ROK != rlcDbmFindUlTransaction(tRlcCb,cfmInfo->transId, &cfgTmpData))
231    {
232       DU_LOG("\nERROR  -->  RLC_UL : Invalid transId");
233       RLC_FREE_SHRABL_BUF(pst->region,
234                          pst->pool,
235                          cfmInfo,
236                          sizeof(RlcCfgCfmInfo));
237       return  (RFAILED);
238    }
239
240    if(ROK != rlcDbmDelUlTransaction(tRlcCb, cfgTmpData))
241    {
242       RLC_FREE_SHRABL_BUF(pst->region,
243                          pst->pool,
244                          cfmInfo,
245                          sizeof(RlcCfgCfmInfo));
246        return RFAILED;
247    }
248       /* Allocate memory and memset to 0 for cfmInfo */
249    RLC_ALLOC(tRlcCb,cfgCfm, sizeof(RlcCfgCfmInfo));
250 #if (ERRCLASS & ERRCLS_ADD_RES)
251    if (cfgCfm == NULLP)
252    {
253       DU_LOG("\nERROR  -->  RLC_UL : Memory Allocation failed.");
254       RLC_FREE_SHRABL_BUF(pst->region,
255                          pst->pool,
256                          cfmInfo,
257                          sizeof(RlcCfgCfmInfo));
258        return RFAILED;
259    }
260 #endif /* ERRCLASS & ERRCLS_ADD_RES */
261    rlcHdlCrlcUlCfgReq(tRlcCb,cfgTmpData, cfmInfo, cfgCfm);
262    if(tRlcCb->u.ulCb->rlcUlUdxEventType == EVENT_RLC_UE_CREATE_REQ)
263    {
264       FILL_PST_RLC_TO_DUAPP(rspPst, RLC_UL_INST, EVENT_RLC_UE_CREATE_RSP);
265       SendRlcUeCfgRspToDu(&rspPst, cfgCfm);
266    }
267    else if(tRlcCb->u.ulCb->rlcUlUdxEventType == EVENT_RLC_UE_RECONFIG_REQ)
268    {
269       FILL_PST_RLC_TO_DUAPP(rspPst, RLC_UL_INST, EVENT_RLC_UE_RECONFIG_RSP);
270       SendRlcUeCfgRspToDu(&rspPst, cfgCfm);
271    }
272    else if (tRlcCb->u.ulCb->rlcUlUdxEventType == EVENT_RLC_UE_DELETE_REQ)
273    {
274       FILL_PST_RLC_TO_DUAPP(rspPst, RLC_UL_INST, EVENT_RLC_UE_DELETE_RSP);
275       if(sendRlcUeDeleteRspToDu(cfgCfm->cellId, cfgCfm->ueId, SUCCESSFUL) != ROK)
276       {
277          DU_LOG("ERROR  --> RLC_UL: rlcUlUdxCfgCfm(): Failed to send UE delete response ");
278          RLC_FREE(tRlcCb, cfgCfm, sizeof(RlcCfgCfmInfo));
279          return RFAILED;
280       }
281       RLC_FREE(tRlcCb, cfgCfm, sizeof(RlcCfgCfmInfo));
282    }
283    else if  (tRlcCb->u.ulCb->rlcUlUdxEventType == EVENT_RLC_UE_REESTABLISH_REQ)
284    {
285       if(sendRlcUeReestablishRspToDu(cfgCfm->cellId, cfgCfm->ueId, SUCCESSFUL) != ROK)
286       {
287          DU_LOG("ERROR  --> RLC_UL: rlcUlUdxCfgCfm(): Failed to send UE Reestablishment response to DU ");
288          RLC_FREE(tRlcCb, cfgCfm, sizeof(RlcCfgCfmInfo));
289          return RFAILED;
290       }
291       RLC_FREE(tRlcCb, cfgCfm, sizeof(RlcCfgCfmInfo));
292    }
293
294    /* free the memory from DL */
295    RLC_FREE_SHRABL_BUF(pst->region, pst->pool, cfmInfo, sizeof(RlcCfgCfmInfo));
296
297    /* free the cfgInfo that came from LM */
298    for(cfgIdx=0; cfgIdx<cfgTmpData->cfgInfo->numEnt; cfgIdx++)
299    {
300       RLC_FREE(tRlcCb, cfgTmpData->cfgInfo->entCfg[cfgIdx].snssai, sizeof(Snssai)); 
301    }
302    RLC_FREE(tRlcCb, cfgTmpData->cfgInfo, sizeof(RlcCfgInfo));
303    RLC_FREE(tRlcCb,cfgTmpData,sizeof(RlcUlCfgTmpData));
304    
305    return ROK;
306
307
308 /**
309  * @brief 
310  *    Handler for UeId change confirm 
311  *
312  * @details
313  *    This function handles the UeId Change Confirm from DL Instance 
314  *
315  *  @param[in] pst     Post structure  
316  *  @param[in] suId    Service User ID
317  *  @param[in] transId Transaction Id 
318  *  @param[in] status  Status of confirmation 
319  *  @return  S16
320  *      -# ROK 
321  *      -# RFAILED
322  */
323
324 S16 rlcUlUdxUeIdChgCfm
325 (
326 Pst        *pst,          
327 SuId       suId,           
328 uint32_t        transId,
329 CmStatus   status
330 )
331 {
332    RlcCb             *tRlcCb;
333    RlcUlCfgTmpData   *cfgTmpData;
334
335 #if (ERRCLASS & ERRCLS_INT_PAR)
336    if (pst->dstInst >= MAX_RLC_INSTANCES)
337    {
338       return  (RFAILED);
339    }
340 #endif
341    tRlcCb = RLC_GET_RLCCB(pst->dstInst);
342
343    RLCDBGP_BRIEF(tRlcCb, " suId(%d) \n", suId);
344
345 #if (ERRCLASS & ERRCLS_INT_PAR)
346    if (suId < 0)
347    {
348       DU_LOG("\nERROR  -->  RLC_UL : Invalid suId");
349       return RFAILED;
350    }
351 #endif /* ERRCLASS & ERRCLS_INT_PAR */
352
353    if(ROK != rlcDbmFindUlTransaction(tRlcCb, transId, &cfgTmpData))
354    {
355       DU_LOG("\nERROR  -->  RLC_UL : Invalid transId");
356       return  (RFAILED);
357    }
358
359    if(ROK != rlcDbmDelUlTransaction(tRlcCb, cfgTmpData))
360    {
361       return RFAILED;
362    }
363
364    if(status.status == CKW_CFG_CFM_OK)
365    {
366        if(cfgTmpData->ueCb != NULLP) 
367        {
368       rlcCfgApplyUlUeIdChng(tRlcCb, cfgTmpData->ueInfo, cfgTmpData->newUeInfo, cfgTmpData);
369    }
370    }
371    RlcUiCkwUeIdChgCfm(&(tRlcCb->u.ulCb->ckwSap.pst),
372                      tRlcCb->u.ulCb->ckwSap.suId,
373                      transId,cfgTmpData->ueInfo,status);
374    /* only newUeInfo needs to be freed here, ueInfo would be freed at the 
375       interface or by he receipient in case of tight coupling */
376    RLC_PST_FREE(pst->region, pst->pool, cfgTmpData->newUeInfo, sizeof(CkwUeInfo));
377    RLC_FREE(tRlcCb, cfgTmpData, sizeof (RlcUlCfgTmpData));
378    return ROK;
379
380
381 /**
382  * @brief 
383  *    Udx Status Prohibit Timer Start
384  *
385  *  @param[in] pst     Post structure  
386  *  @param[in] suId    Service User ID
387  *  @param[in] rlcId   rlc Id 
388  *  @return  S16
389  *      -# ROK 
390  *      -# RFAILED
391  */
392 S16  rlcUlUdxStaProhTmrStart
393 (
394 Pst*         pst,
395 SuId         suId,
396 CmLteRlcId   *rlcId
397 )
398 {
399    RlcCb       *tRlcCb= NULLP;
400    RlcUlRbCb   *rbCb;        
401
402 #if (ERRCLASS & ERRCLS_INT_PAR)
403    if (pst->dstInst >= MAX_RLC_INSTANCES)
404    {
405       return  (RFAILED);
406    }
407 #endif
408    tRlcCb = RLC_GET_RLCCB(pst->dstInst);
409
410    rlcDbmFetchUlRbCbByRbId(tRlcCb, rlcId, &rbCb);
411    if (rbCb == NULLP)
412    {    
413       DU_LOG("\nERROR  -->  RLC_UL : CellId [%u]:RbId[%d] not found",
414             rlcId->cellId,rlcId->rbId);
415       return RFAILED;
416    }
417
418    /* Start staProhTmr */
419    rlcStartTmr(tRlcCb,(PTR)rbCb, EVENT_RLC_AMUL_STA_PROH_TMR);
420
421    return  (ROK);
422
423
424 /**
425  * @brief 
426  *    Handler for configuration confirm from DL.
427  *
428  * @param[in] gCb        - RLC Instance Control Block
429  * @param[in] cfgTmpData - Configuration Temporary Data 
430  * @param[in] cfmInfo    - DL Configuration Confirm Info
431  * @param[out] cfgCfm    - Configuration Confirm to be sent to RRC
432  *
433  * @return  S16
434  *    -# ROK 
435  *    -# RFAILED
436  */
437 S16 rlcHdlCrlcUlCfgReq
438 (
439 RlcCb             *gCb,
440 RlcUlCfgTmpData   *cfgTmpData,
441 RlcCfgCfmInfo    *cfmInfo,
442 RlcCfgCfmInfo    *cfgCfm
443 )
444 {
445    RlcCfgInfo   *cfg;
446    uint32_t     idx;
447    uint32_t     maxEnt;
448    
449    cfg = cfgTmpData->cfgInfo;
450    maxEnt = (cfg->numEnt < CKW_MAX_ENT_CFG)? cfg->numEnt:CKW_MAX_ENT_CFG;
451
452    for (idx = 0; idx < maxEnt; idx++)
453    {
454       RlcEntCfgCfmInfo   *entCfgCfm;
455       RlcEntCfgCfmInfo   *entDlCfgCfm;
456       RlcEntCfgInfo      *entCfg;
457
458       entCfg  = &(cfg->entCfg[idx]);
459       entCfgCfm   = &(cfgCfm->entCfgCfm[idx]);
460       entDlCfgCfm = &(cfmInfo->entCfgCfm[idx]);
461       switch (entCfg->cfgType)
462       {
463          case CKW_CFG_ADD:
464          case CKW_CFG_MODIFY:
465          case CKW_CFG_DELETE:
466             {
467                if (entCfg->dir == RLC_DIR_UL)
468                {
469                   RLC_MEM_CPY(entCfgCfm, 
470                              &cfgTmpData->cfgEntData[idx].entUlCfgCfm, 
471                              sizeof(RlcEntCfgCfmInfo)); 
472                }
473                else if (entCfg->dir == RLC_DIR_DL)
474                {
475                   RLC_MEM_CPY(entCfgCfm, entDlCfgCfm, sizeof(RlcEntCfgCfmInfo)); 
476                }
477                else if(entCfg->dir == RLC_DIR_BOTH)
478                {
479                   if (entDlCfgCfm->status.status != CKW_CFG_CFM_OK)
480                   {
481                      rlcCfgRollBackUlRb(gCb,
482                                        cfg->ueId,
483                                        &cfg->entCfg[idx], 
484                                        &cfgTmpData->cfgEntData[idx]);
485                   }
486                   else
487                   {
488                      rlcCfgApplyUlRb(gCb,  
489                                     &cfg->entCfg[idx], 
490                                     &cfgTmpData->cfgEntData[idx],
491                                     cfgTmpData);
492                   }
493                   RLC_MEM_CPY(entCfgCfm, entDlCfgCfm, sizeof(RlcEntCfgCfmInfo)); 
494                }
495                else
496                {
497                             RLC_CFG_FILL_CFG_CFM(entCfgCfm, entCfg->rbId, entCfg->rbType,
498                                            CKW_CFG_CFM_NOK, CKW_CFG_REAS_INVALID_DIR);
499                   DU_LOG("\nDEBUG  -->  RLC_UL : RBID[%d] direction[%d] is invalid",
500                          entCfg->rbId,entCfg->dir);
501                }
502                break;
503             }
504
505          case CKW_CFG_REESTABLISH:
506             {
507                if (entCfg->dir == RLC_DIR_UL)
508                {
509                   RLC_MEM_CPY(entCfgCfm, 
510                              &cfgTmpData->cfgEntData[idx].entUlCfgCfm, 
511                              sizeof(RlcEntCfgCfmInfo)); 
512                }
513                else if (entCfg->dir == RLC_DIR_DL)
514                {
515                   RLC_MEM_CPY(entCfgCfm, entDlCfgCfm, sizeof(RlcEntCfgCfmInfo)); 
516                }
517                else
518                {
519                   if (entCfg->dir & RLC_DIR_UL)
520                   {
521                      /* Reestablish indication is sent from UL Instance only*/
522                      if (entDlCfgCfm->status.status == CKW_CFG_CFM_OK)
523                      {
524                         rlcCfgApplyReEstUlRb (gCb, cfg->ueId, 
525                                              cfg->cellId, TRUE, 
526                                              &cfgTmpData->cfgEntData[idx]);
527                      }
528                      RLC_MEM_CPY(entCfgCfm, entDlCfgCfm, sizeof(RlcEntCfgCfmInfo)); 
529                   }
530                }
531                break;
532             }
533          case CKW_CFG_DELETE_UE:
534             {
535                if (cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status == CKW_CFG_CFM_OK)
536                {
537                   rlcCfgApplyDelUlUe(gCb, cfgTmpData);
538                   RLC_MEM_CPY(entCfgCfm, 
539                              &cfgTmpData->cfgEntData[idx].entUlCfgCfm, 
540                              sizeof(RlcEntCfgCfmInfo));
541                }
542                else
543                {
544                    RLC_MEM_CPY(entCfgCfm, entDlCfgCfm,
545                               sizeof(RlcEntCfgCfmInfo)); 
546                }
547                break;
548             }
549          case CKW_CFG_DELETE_CELL:
550             {
551                if (cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status == CKW_CFG_CFM_OK)
552                {
553                   rlcCfgApplyDelUlCell(gCb, cfgTmpData);
554                   RLC_MEM_CPY(entCfgCfm, 
555                              &cfgTmpData->cfgEntData[idx].entUlCfgCfm, 
556                              sizeof(RlcEntCfgCfmInfo)); 
557                }
558                else
559                {
560                    RLC_MEM_CPY(entCfgCfm, entDlCfgCfm,
561                               sizeof(RlcEntCfgCfmInfo)); 
562                }
563                break;
564             }
565          default:
566             {
567                RLC_CFG_FILL_CFG_CFM(entCfgCfm, entCfg->rbId, entCfg->rbType,
568                                    CKW_CFG_CFM_NOK, CKW_CFG_REAS_INVALID_CFG);
569
570                DU_LOG("\nERROR  -->  RLC_UL : Invalid configuration type");
571             }
572       }
573    }
574
575    /* Assign number of entity configurations and suId */
576    cfgCfm->transId = cfgTmpData->uprLyrTransId;
577    cfgCfm->ueId = cfg->ueId;
578    cfgCfm->cellId = cfg->cellId;
579    cfgCfm->numEnt = cfg->numEnt;
580
581    return ROK;
582 }
583 #ifdef __cplusplus
584 }
585 #endif /* __cplusplus */
586
587 \f
588 /**********************************************************************
589          End of file
590 **********************************************************************/