ac6dc9877b5e2b879ea24eab14400f029a3f01c6
[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 "rlc_utils.h"
64 #include "du_app_rlc_inf.h"
65 #include "rlc_mgr.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 EXTERN 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 #ifdef ANSI
100 S16 rlcUlUdxBndCfm
101 (
102 Pst    *pst,  
103 SuId   suId, 
104 U8     status 
105 )
106 #else
107 S16 rlcUlUdxBndCfm (pst, suId, status)
108 Pst    *pst; 
109 SuId   suId;   
110 U8     status; 
111 #endif
112 {
113    U16            event;        
114    U16            cause;       
115    RlcUdxUlSapCb   *udxSap;   /* RGU SAP Control Block */
116    RlcCb           *tRlcCb;
117
118    TRC3(rlcUlUdxBndCfm)
119
120 #if (ERRCLASS & ERRCLS_INT_PAR)
121    if (pst->dstInst >= MAX_RLC_INSTANCES)
122    {
123       return  (RFAILED);
124    }
125 #endif
126    tRlcCb = RLC_GET_RLCCB(pst->dstInst);
127
128    RLCDBGP_BRIEF(tRlcCb, "rlcUlUdxBndCfm(post, suId(%d), status(%d)\n", 
129                 suId, status);
130
131 #if (ERRCLASS & ERRCLS_INT_PAR)
132    if (tRlcCb->init.cfgDone != TRUE)
133    {
134       RLOG0(L_FATAL, "General configuration not done");
135       RLC_SEND_SAPID_ALARM(tRlcCb,suId, 
136                           LKW_EVENT_LI_BND_CFM, LCM_CAUSE_INV_STATE);
137
138       return RFAILED;
139    }
140
141    if (suId < 0)
142    {
143       RLOG0(L_ERROR, "Invalid suId");
144       RLC_SEND_SAPID_ALARM(tRlcCb,suId, 
145                            LKW_EVENT_LI_BND_CFM, LCM_CAUSE_INV_SUID);
146
147       return RFAILED;
148    }
149 #endif /* ERRCLASS & ERRCLS_INT_PAR */
150
151    udxSap = tRlcCb->u.ulCb->udxUlSap + suId;
152
153    RLCDBGP_DETAIL(tRlcCb, "RlcLiRguBndCfm: For RGU SAP state=%d\n", 
154                  udxSap->state);
155
156    /* Check rguSap state */
157    switch (udxSap->state)
158    {
159       case RLC_SAP_BINDING:
160       {
161          if(TRUE == rlcChkTmr(tRlcCb,(PTR)udxSap,RLC_EVT_WAIT_BNDCFM))
162          {
163              rlcStopTmr (tRlcCb,(PTR)udxSap, RLC_EVT_WAIT_BNDCFM);
164          }
165          udxSap->retryCnt = 0;
166           
167          if (status == CM_BND_OK)
168          {
169             udxSap->state = RLC_SAP_BND;
170             event = LCM_EVENT_BND_OK;
171             cause = LKW_CAUSE_SAP_BNDENB;
172          }
173          else
174          {
175             udxSap->state = RLC_SAP_CFG;
176             event = LCM_EVENT_BND_FAIL;
177             cause = LKW_CAUSE_UNKNOWN;
178          }
179       }
180       break;
181
182      default:
183         event = LKW_EVENT_RGU_BND_CFM;
184         cause = LCM_CAUSE_INV_STATE;
185         break;
186    }
187    /* Send an alarm with proper event and cause */
188    RLC_SEND_SAPID_ALARM(tRlcCb,suId, event, cause);
189
190    return ROK;
191
192
193 /**
194  * @brief 
195  *    Handles UDX Configuration Confirm 
196  *
197  * @details
198  *    This function handles the UDX configuration Confirm from DL Instance
199  *
200  * @param[in] pst     Post structure  
201  * @param[in] suId    Service User ID
202  * @param[in] cfmInfo Confirm Information 
203  * 
204  * @return  S16
205  *    -# ROK 
206  *    -# RFAILED
207  */
208 #ifdef ANSI
209 S16 rlcUlUdxCfgCfm
210 (
211 Pst             *pst,  
212 SuId            suId, 
213 RlcCfgCfmInfo   *cfmInfo  
214 )
215 #else
216 S16 rlcUlUdxCfgCfm (pst, suId, cfmInfo)
217 Pst             *pst;   
218 SuId            suId;  
219 RlcCfgCfmInfo   *cfmInfo;  
220 #endif
221 {
222    RlcCb             *tRlcCb;
223    RlcCfgCfmInfo    *cfgCfm;
224    RlcUlCfgTmpData   *cfgTmpData;
225    Pst rspPst;
226    memset(&rspPst, 0, sizeof(Pst));
227
228    TRC3(rlcUlUdxCfgCfm)
229
230 #if (ERRCLASS & ERRCLS_INT_PAR)
231    if (pst->dstInst >= MAX_RLC_INSTANCES)
232    {
233       RLC_FREE_SHRABL_BUF(pst->region,
234                          pst->pool,
235                          cfmInfo,
236                          sizeof(RlcCfgCfmInfo));
237       return  (RFAILED);
238    }
239 #endif
240    tRlcCb = RLC_GET_RLCCB(pst->dstInst);
241    RLCDBGP_BRIEF(tRlcCb, " suId(%d)\n", suId);
242
243 #if (ERRCLASS & ERRCLS_INT_PAR)
244    if (suId < 0)
245    {
246       RLOG0(L_ERROR, "Invalid suId");
247       RLC_SEND_SAPID_ALARM(tRlcCb,suId, 
248                            LKW_EVENT_LI_BND_CFM, LCM_CAUSE_INV_SUID);
249       RLC_FREE_SHRABL_BUF(pst->region,
250                          pst->pool,
251                          cfmInfo,
252                          sizeof(RlcCfgCfmInfo));
253       return RFAILED;
254    }
255 #endif /* ERRCLASS & ERRCLS_INT_PAR */
256
257    if(ROK != rlcDbmFindUlTransaction(tRlcCb,cfmInfo->transId, &cfgTmpData))
258    {
259       RLOG0(L_ERROR, "Invalid transId");
260       RLC_FREE_SHRABL_BUF(pst->region,
261                          pst->pool,
262                          cfmInfo,
263                          sizeof(RlcCfgCfmInfo));
264       return  (RFAILED);
265    }
266
267    if(ROK != rlcDbmDelUlTransaction(tRlcCb, cfgTmpData))
268    {
269       RLC_FREE_SHRABL_BUF(pst->region,
270                          pst->pool,
271                          cfmInfo,
272                          sizeof(RlcCfgCfmInfo));
273        return RFAILED;
274    }
275       /* Allocate memory and memset to 0 for cfmInfo */
276    RLC_ALLOC(tRlcCb,cfgCfm, sizeof(RlcCfgCfmInfo));
277 #if (ERRCLASS & ERRCLS_ADD_RES)
278    if (cfgCfm == NULLP)
279    {
280       RLOG0(L_FATAL, "Memory Allocation failed.");
281       RLC_FREE_SHRABL_BUF(pst->region,
282                          pst->pool,
283                          cfmInfo,
284                          sizeof(RlcCfgCfmInfo));
285        return RFAILED;
286    }
287 #endif /* ERRCLASS & ERRCLS_ADD_RES */
288    rlcHdlCrlcUlCfgReq(tRlcCb,cfgTmpData, cfmInfo, cfgCfm);
289    FILL_PST_RLC_TO_DUAPP(rspPst, tRlcCb->genCfg.lmPst.dstProcId, RLC_UL_INST, EVENT_RLC_UL_UE_CREATE_RSP);
290    SendRlcUlUeCreateRspToDu(&rspPst, cfgCfm);
291
292    /* free the memory from DL */
293    RLC_FREE_SHRABL_BUF(pst->region,
294                       pst->pool,
295                       cfmInfo,
296                       sizeof(RlcCfgCfmInfo));
297
298    /* free the cfgInfo that came from LM */
299    RLC_PST_FREE(pst->region, pst->pool, cfgTmpData->cfgInfo, sizeof(RlcCfgInfo));
300    RLC_FREE(tRlcCb,cfgTmpData,sizeof(RlcUlCfgTmpData));
301    
302    return ROK;
303
304
305 /**
306  * @brief 
307  *    Handler for UeId change confirm 
308  *
309  * @details
310  *    This function handles the UeId Change Confirm from DL Instance 
311  *
312  *  @param[in] pst     Post structure  
313  *  @param[in] suId    Service User ID
314  *  @param[in] transId Transaction Id 
315  *  @param[in] status  Status of confirmation 
316  *  @return  S16
317  *      -# ROK 
318  *      -# RFAILED
319  */
320
321 #ifdef ANSI
322 S16 rlcUlUdxUeIdChgCfm
323 (
324 Pst        *pst,          
325 SuId       suId,           
326 U32        transId,
327 CmStatus   status
328 )
329 #else
330 S16 rlcUlUdxUeIdChgCfm (pst, suId, cfmInfo)
331 Pst        *pst;         
332 SuId       suId;        
333 U32        transId;
334 CmStatus   status;
335 #endif
336 {
337    RlcCb             *tRlcCb;
338    RlcUlCfgTmpData   *cfgTmpData;
339
340    TRC3(rlcUlUdxUeIdChgCfm)
341
342 #if (ERRCLASS & ERRCLS_INT_PAR)
343    if (pst->dstInst >= MAX_RLC_INSTANCES)
344    {
345       return  (RFAILED);
346    }
347 #endif
348    tRlcCb = RLC_GET_RLCCB(pst->dstInst);
349
350    RLCDBGP_BRIEF(tRlcCb, " suId(%d) \n", suId);
351
352 #if (ERRCLASS & ERRCLS_INT_PAR)
353    if (suId < 0)
354    {
355       RLOG0(L_ERROR, "Invalid suId");
356       return RFAILED;
357    }
358 #endif /* ERRCLASS & ERRCLS_INT_PAR */
359
360    if(ROK != rlcDbmFindUlTransaction(tRlcCb, transId, &cfgTmpData))
361    {
362       RLOG0(L_ERROR, "Invalid transId");
363       return  (RFAILED);
364    }
365
366    if(ROK != rlcDbmDelUlTransaction(tRlcCb, cfgTmpData))
367    {
368       return RFAILED;
369    }
370
371    if(status.status == CKW_CFG_CFM_OK)
372    {
373        if(cfgTmpData->ueCb != NULLP) 
374        {
375       rlcCfgApplyUlUeIdChng(tRlcCb, cfgTmpData->ueInfo, cfgTmpData->newUeInfo, cfgTmpData);
376    }
377    }
378    RlcUiCkwUeIdChgCfm(&(tRlcCb->u.ulCb->ckwSap.pst),
379                      tRlcCb->u.ulCb->ckwSap.suId,
380                      transId,cfgTmpData->ueInfo,status);
381    /* only newUeInfo needs to be freed here, ueInfo would be freed at the 
382       interface or by he receipient in case of tight coupling */
383    RLC_PST_FREE(pst->region, pst->pool, cfgTmpData->newUeInfo, sizeof(CkwUeInfo));
384    RLC_FREE_WC(tRlcCb, cfgTmpData, sizeof (RlcUlCfgTmpData));
385    return ROK;
386
387
388 /**
389  * @brief 
390  *    Udx Status Prohibit Timer Start
391  *
392  *  @param[in] pst     Post structure  
393  *  @param[in] suId    Service User ID
394  *  @param[in] rlcId   rlc Id 
395  *  @return  S16
396  *      -# ROK 
397  *      -# RFAILED
398  */
399 S16  rlcUlUdxStaProhTmrStart
400 (
401 Pst*         pst,
402 SuId         suId,
403 CmLteRlcId   *rlcId
404 )
405 {
406    RlcCb       *tRlcCb= NULLP;
407    RlcUlRbCb   *rbCb;        
408
409 #if (ERRCLASS & ERRCLS_INT_PAR)
410    if (pst->dstInst >= MAX_RLC_INSTANCES)
411    {
412       return  (RFAILED);
413    }
414 #endif
415    tRlcCb = RLC_GET_RLCCB(pst->dstInst);
416
417    rlcDbmFetchUlRbCbByRbId(tRlcCb, rlcId, &rbCb);
418    if (rbCb == NULLP)
419    {    
420       RLOG_ARG2(L_ERROR, DBG_UEID,rlcId->ueId, "CellId [%u]:RbId[%d] not found",
421             rlcId->cellId,rlcId->rbId);
422       return RFAILED;
423    }
424
425    /* Start staProhTmr */
426    rlcStartTmr(tRlcCb,(PTR)rbCb, RLC_EVT_AMUL_STA_PROH_TMR);
427
428    return  (ROK);
429
430
431 /**
432  * @brief 
433  *    Handler for configuration confirm from DL.
434  *
435  * @param[in] gCb        - RLC Instance Control Block
436  * @param[in] cfgTmpData - Configuration Temporary Data 
437  * @param[in] cfmInfo    - DL Configuration Confirm Info
438  * @param[out] cfgCfm    - Configuration Confirm to be sent to RRC
439  *
440  * @return  S16
441  *    -# ROK 
442  *    -# RFAILED
443  */
444 #ifdef ANSI
445 S16 rlcHdlCrlcUlCfgReq
446 (
447 RlcCb             *gCb,
448 RlcUlCfgTmpData   *cfgTmpData,
449 RlcCfgCfmInfo    *cfmInfo,
450 RlcCfgCfmInfo    *cfgCfm
451 )
452 #else
453 S16 rlcHdlCrlcUlCfgReq(gCb,cfgTmpData,cfmInfo,cfmInfo)
454 RlcCb             *gCb;
455 RlcUlCfgTmpData   *cfgTmpData;
456 RlcCfgCfmInfo    *cfmInfo;
457 RlcCfgCfmInfo    *cfgCfm;
458 #endif
459 {
460    RlcCfgInfo   *cfg;
461    U32          idx;
462    U32          maxEnt;
463    
464    cfg = cfgTmpData->cfgInfo;
465    maxEnt = (cfg->numEnt < CKW_MAX_ENT_CFG)? cfg->numEnt:CKW_MAX_ENT_CFG;
466
467    for (idx = 0; idx < maxEnt; idx++)
468    {
469       RlcEntCfgCfmInfo   *entCfgCfm;
470       RlcEntCfgCfmInfo   *entDlCfgCfm;
471       RlcEntCfgInfo      *entCfg;
472
473       entCfg  = &(cfg->entCfg[idx]);
474       entCfgCfm   = &(cfgCfm->entCfgCfm[idx]);
475       entDlCfgCfm = &(cfmInfo->entCfgCfm[idx]);
476       switch (entCfg->cfgType)
477       {
478          case CKW_CFG_ADD:
479          case CKW_CFG_MODIFY:
480          case CKW_CFG_DELETE:
481             {
482                if (entCfg->dir == RLC_DIR_UL)
483                {
484                   RLC_MEM_CPY(entCfgCfm, 
485                              &cfgTmpData->cfgEntData[idx].entUlCfgCfm, 
486                              sizeof(RlcEntCfgCfmInfo)); 
487                }
488                else if (entCfg->dir == RLC_DIR_DL)
489                {
490                   RLC_MEM_CPY(entCfgCfm, entDlCfgCfm, sizeof(RlcEntCfgCfmInfo)); 
491                }
492                else if(entCfg->dir == RLC_DIR_BOTH)
493                {
494                   if (entDlCfgCfm->status.status != CKW_CFG_CFM_OK)
495                   {
496                      rlcCfgRollBackUlRb(gCb,
497                                        cfg->ueId,
498                                        &cfg->entCfg[idx], 
499                                        &cfgTmpData->cfgEntData[idx]);
500                   }
501                   else
502                   {
503                      rlcCfgApplyUlRb(gCb,  
504                                     &cfg->entCfg[idx], 
505                                     &cfgTmpData->cfgEntData[idx],
506                                     cfgTmpData);
507                   }
508                   RLC_MEM_CPY(entCfgCfm, entDlCfgCfm, sizeof(RlcEntCfgCfmInfo)); 
509                }
510                else
511                {
512                             RLC_CFG_FILL_CFG_CFM(entCfgCfm, entCfg->rbId, entCfg->rbType,
513                                            CKW_CFG_CFM_NOK, CKW_CFG_REAS_INVALID_DIR);
514                   RLOG_ARG2(L_ERROR,DBG_UEID,cfg->ueId,"RBID[%d] direction[%d] is invalid",
515                          entCfg->rbId,entCfg->dir);
516                }
517                break;
518             }
519
520          case CKW_CFG_REESTABLISH:
521             {
522                if (entCfg->dir == RLC_DIR_UL)
523                {
524                   RLC_MEM_CPY(entCfgCfm, 
525                              &cfgTmpData->cfgEntData[idx].entUlCfgCfm, 
526                              sizeof(RlcEntCfgCfmInfo)); 
527                }
528                else if (entCfg->dir == RLC_DIR_DL)
529                {
530                   RLC_MEM_CPY(entCfgCfm, entDlCfgCfm, sizeof(RlcEntCfgCfmInfo)); 
531                }
532                else
533                {
534                   if (entCfg->dir & RLC_DIR_UL)
535                   {
536                      /* Reestablish indication is sent from UL Instance only*/
537                      if (entDlCfgCfm->status.status == CKW_CFG_CFM_OK)
538                      {
539                         rlcCfgApplyReEstUlRb (gCb, cfg->ueId, 
540                                              cfg->cellId, TRUE, 
541                                              &cfgTmpData->cfgEntData[idx]);
542                      }
543                      RLC_MEM_CPY(entCfgCfm, entDlCfgCfm, sizeof(RlcEntCfgCfmInfo)); 
544                   }
545                }
546                break;
547             }
548          case CKW_CFG_DELETE_UE:
549             {
550                if (cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status == CKW_CFG_CFM_OK)
551                {
552                   rlcCfgApplyDelUlUe(gCb, cfgTmpData);
553                   RLC_MEM_CPY(entCfgCfm, 
554                              &cfgTmpData->cfgEntData[idx].entUlCfgCfm, 
555                              sizeof(RlcEntCfgCfmInfo)); 
556                }
557                else
558                {
559                    RLC_MEM_CPY(entCfgCfm, entDlCfgCfm,
560                               sizeof(RlcEntCfgCfmInfo)); 
561                }
562                break;
563             }
564          case CKW_CFG_DELETE_CELL:
565             {
566                if (cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status == CKW_CFG_CFM_OK)
567                {
568                   rlcCfgApplyDelUlCell(gCb, cfgTmpData);
569                   RLC_MEM_CPY(entCfgCfm, 
570                              &cfgTmpData->cfgEntData[idx].entUlCfgCfm, 
571                              sizeof(RlcEntCfgCfmInfo)); 
572                }
573                else
574                {
575                    RLC_MEM_CPY(entCfgCfm, entDlCfgCfm,
576                               sizeof(RlcEntCfgCfmInfo)); 
577                }
578                break;
579             }
580          default:
581             {
582                RLC_CFG_FILL_CFG_CFM(entCfgCfm, entCfg->rbId, entCfg->rbType,
583                                    CKW_CFG_CFM_NOK, CKW_CFG_REAS_INVALID_CFG);
584
585                RLOG0(L_ERROR,"Invalid configuration type");
586             }
587       }
588    }
589
590    /* Assign number of entity configurations and suId */
591    cfgCfm->transId = cfgTmpData->uprLyrTransId;
592    cfgCfm->ueId = cfg->ueId;
593    cfgCfm->cellId = cfg->cellId;
594    cfgCfm->numEnt = cfg->numEnt;
595
596    return ROK;
597 }
598 #ifdef __cplusplus
599 }
600 #endif /* __cplusplus */
601
602 \f
603 /**********************************************************************
604          End of file
605 **********************************************************************/