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