c6e9cbc93aa41fef916e8ac414c5ced5e2ce06b7
[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 "envopt.h"        /* environment options */
40 #include "envdep.h"        /* environment dependent */
41 #include "envind.h"        /* environment independent */
42
43 #include "gen.h"           /* general */
44 #include "ssi.h"           /* system services */
45 #include "cm5.h"           /* common timer defines */
46 #include "cm_tkns.h"       /* common tokens defines */
47 #include "cm_mblk.h"       /* common memory allocation library defines */
48 #include "cm_llist.h"      /* common link list  defines  */
49 #include "cm_hash.h"       /* common hash list  defines */
50 #include "cm_lte.h"        /* common LTE defines */
51 #include "lkw.h"           /* LKW defines */
52 #include "ckw.h"           /* CKW defines */
53 #include "kwu.h"           /* KWU defines */
54 #include "rgu.h"           /* RGU defines */
55 #include "kw_err.h"        /* Err defines */
56 #include "kw_env.h"        /* RLC environment options */
57
58 #include "kw.h"            /* RLC defines */
59 #include "kw_udx.h"
60 #include "kw_ul.h"
61 #include "kw_dl.h"
62
63 /* extern (.x) include files */
64 #include "gen.x"           /* general */
65 #include "ssi.x"           /* system services */
66
67 #include "cm5.x"           /* common timer library */
68 #include "cm_tkns.x"       /* common tokens */
69 #include "cm_mblk.x"       /* common memory allocation */
70 #include "cm_llist.x"      /* common link list */
71 #include "cm_hash.x"       /* common hash list */
72 #include "cm_lte.x"        /* common LTE includes */
73 #include "cm_lib.x"        /* common memory allocation library */
74 #include "lkw.x"           /* LKW */
75 #include "ckw.x"           /* CKW */
76 #include "kwu.x"           /* KWU */
77 #include "rgu.x"           /* RGU */
78
79 #include "kw.x"
80 #include "kw_udx.x"
81 #include "kw_dl.x"
82 #include "kw_ul.x"
83
84
85 #define KW_MODULE KW_DBGMASK_UDX
86 /* local defines */
87
88 /* local externs */
89
90 /* forward references */
91
92 /* public variable declarations */
93 EXTERN S16 kwHdlCkwUlCfgReq ARGS((KwCb  *gCb,KwUlCfgTmpData *cfgTmpData,
94                                   CkwCfgCfmInfo *cfmInfo, CkwCfgCfmInfo *cfgCfm));
95
96 /**
97   * @brief
98   * UDX APIs
99   */
100 /**
101  * @brief 
102  *    Handler for bind confirmation from DL.
103  *
104  * @details
105  *    This function handles the bind confirmation received
106  *    from DL. 
107  *
108  * @param[in] pst     Post structure  
109  * @param[in] suId    Service User ID
110  * @param[in] status  Status of confirmation 
111  * 
112  * @return  S16
113  *    -# ROK 
114  *    -# RFAILED
115  */
116
117 #ifdef ANSI
118 PUBLIC S16 KwUlUdxBndCfm
119 (
120 Pst    *pst,  
121 SuId   suId, 
122 U8     status 
123 )
124 #else
125 PUBLIC S16 KwUlUdxBndCfm (pst, suId, status)
126 Pst    *pst; 
127 SuId   suId;   
128 U8     status; 
129 #endif
130 {
131    U16            event;        
132    U16            cause;       
133    KwUdxUlSapCb   *udxSap;   /* RGU SAP Control Block */
134    KwCb           *tKwCb;
135
136    TRC3(KwUlUdxBndCfm)
137
138 #if (ERRCLASS & ERRCLS_INT_PAR)
139    if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
140    {
141       RETVALUE (RFAILED);
142    }
143 #endif
144    tKwCb = KW_GET_KWCB(pst->dstInst);
145
146    KWDBGP_BRIEF(tKwCb, "KwUlUdxBndCfm(post, suId(%d), status(%d)\n", 
147                 suId, status);
148
149 #if (ERRCLASS & ERRCLS_INT_PAR)
150    if (tKwCb->init.cfgDone != TRUE)
151    {
152       RLOG0(L_FATAL, "General configuration not done");
153       KW_SEND_SAPID_ALARM(tKwCb,suId, 
154                           LKW_EVENT_LI_BND_CFM, LCM_CAUSE_INV_STATE);
155
156       RETVALUE(RFAILED);
157    }
158
159    if (suId < 0)
160    {
161       RLOG0(L_ERROR, "Invalid suId");
162       KW_SEND_SAPID_ALARM(tKwCb,suId, 
163                            LKW_EVENT_LI_BND_CFM, LCM_CAUSE_INV_SUID);
164
165       RETVALUE(RFAILED);
166    }
167 #endif /* ERRCLASS & ERRCLS_INT_PAR */
168
169    udxSap = tKwCb->u.ulCb->udxUlSap + suId;
170
171    KWDBGP_DETAIL(tKwCb, "KwLiRguBndCfm: For RGU SAP state=%d\n", 
172                  udxSap->state);
173
174    /* Check rguSap state */
175    switch (udxSap->state)
176    {
177       case KW_SAP_BINDING:
178       {
179          if(TRUE == kwChkTmr(tKwCb,(PTR)udxSap,KW_EVT_WAIT_BNDCFM))
180          {
181              kwStopTmr (tKwCb,(PTR)udxSap, KW_EVT_WAIT_BNDCFM);
182          }
183          udxSap->retryCnt = 0;
184           
185          if (status == CM_BND_OK)
186          {
187             udxSap->state = KW_SAP_BND;
188             event = LCM_EVENT_BND_OK;
189             cause = LKW_CAUSE_SAP_BNDENB;
190          }
191          else
192          {
193             udxSap->state = KW_SAP_CFG;
194             event = LCM_EVENT_BND_FAIL;
195             cause = LKW_CAUSE_UNKNOWN;
196          }
197       }
198       break;
199
200      default:
201         event = LKW_EVENT_RGU_BND_CFM;
202         cause = LCM_CAUSE_INV_STATE;
203         break;
204    }
205    /* Send an alarm with proper event and cause */
206    KW_SEND_SAPID_ALARM(tKwCb,suId, event, cause);
207
208    RETVALUE(ROK);
209
210
211 /**
212  * @brief 
213  *    Handles UDX Configuration Confirm 
214  *
215  * @details
216  *    This function handles the UDX configuration Confirm from DL Instance
217  *
218  * @param[in] pst     Post structure  
219  * @param[in] suId    Service User ID
220  * @param[in] cfmInfo Confirm Information 
221  * 
222  * @return  S16
223  *    -# ROK 
224  *    -# RFAILED
225  */
226 #ifdef ANSI
227 PUBLIC S16 KwUlUdxCfgCfm
228 (
229 Pst             *pst,  
230 SuId            suId, 
231 CkwCfgCfmInfo   *cfmInfo  
232 )
233 #else
234 PUBLIC S16 KwUlUdxCfgCfm (pst, suId, cfmInfo)
235 Pst             *pst;   
236 SuId            suId;  
237 CkwCfgCfmInfo   *cfmInfo;  
238 #endif
239 {
240    KwCb             *tKwCb;
241    CkwCfgCfmInfo    *cfgCfm;
242    KwUlCfgTmpData   *cfgTmpData;
243
244    TRC3(KwUlUdxCfgCfm)
245
246 #if (ERRCLASS & ERRCLS_INT_PAR)
247    if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
248    {
249       KW_FREE_SHRABL_BUF(pst->region,
250                          pst->pool,
251                          cfmInfo,
252                          sizeof(CkwCfgCfmInfo));
253       RETVALUE (RFAILED);
254    }
255 #endif
256    tKwCb = KW_GET_KWCB(pst->dstInst);
257    KWDBGP_BRIEF(tKwCb, " suId(%d)\n", suId);
258
259 #if (ERRCLASS & ERRCLS_INT_PAR)
260    if (suId < 0)
261    {
262       RLOG0(L_ERROR, "Invalid suId");
263       KW_SEND_SAPID_ALARM(tKwCb,suId, 
264                            LKW_EVENT_LI_BND_CFM, LCM_CAUSE_INV_SUID);
265       KW_FREE_SHRABL_BUF(pst->region,
266                          pst->pool,
267                          cfmInfo,
268                          sizeof(CkwCfgCfmInfo));
269       RETVALUE(RFAILED);
270    }
271 #endif /* ERRCLASS & ERRCLS_INT_PAR */
272
273    if(ROK != kwDbmFindUlTransaction(tKwCb,cfmInfo->transId, &cfgTmpData))
274    {
275       RLOG0(L_ERROR, "Invalid transId");
276       KW_FREE_SHRABL_BUF(pst->region,
277                          pst->pool,
278                          cfmInfo,
279                          sizeof(CkwCfgCfmInfo));
280       RETVALUE (RFAILED);
281    }
282
283    if(ROK != kwDbmDelUlTransaction(tKwCb, cfgTmpData))
284    {
285       KW_FREE_SHRABL_BUF(pst->region,
286                          pst->pool,
287                          cfmInfo,
288                          sizeof(CkwCfgCfmInfo));
289        RETVALUE(RFAILED);
290    }
291       /* Allocate memory and memset to 0 for cfmInfo */
292    KW_ALLOC(tKwCb,cfgCfm, sizeof(CkwCfgCfmInfo));
293 #if (ERRCLASS & ERRCLS_ADD_RES)
294    if (cfgCfm == NULLP)
295    {
296       RLOG0(L_FATAL, "Memory Allocation failed.");
297       KW_FREE_SHRABL_BUF(pst->region,
298                          pst->pool,
299                          cfmInfo,
300                          sizeof(CkwCfgCfmInfo));
301        RETVALUE(RFAILED);
302    }
303 #endif /* ERRCLASS & ERRCLS_ADD_RES */
304    kwHdlCkwUlCfgReq(tKwCb,cfgTmpData, cfmInfo, cfgCfm);
305    KwUiCkwCfgCfm(&(tKwCb->u.ulCb->ckwSap.pst), 
306                  tKwCb->u.ulCb->ckwSap.suId , cfgCfm);
307
308    /* free the memory from DL */
309    KW_FREE_SHRABL_BUF(pst->region,
310                       pst->pool,
311                       cfmInfo,
312                       sizeof(CkwCfgCfmInfo));
313
314    /* free the cfgInfo that came from LM */
315    KW_PST_FREE(pst->region, pst->pool, cfgTmpData->cfgInfo, sizeof(CkwCfgInfo));
316    KW_FREE(tKwCb,cfgTmpData,sizeof(KwUlCfgTmpData));
317    
318    RETVALUE(ROK);
319
320
321 /**
322  * @brief 
323  *    Handler for UeId change confirm 
324  *
325  * @details
326  *    This function handles the UeId Change Confirm from DL Instance 
327  *
328  *  @param[in] pst     Post structure  
329  *  @param[in] suId    Service User ID
330  *  @param[in] transId Transaction Id 
331  *  @param[in] status  Status of confirmation 
332  *  @return  S16
333  *      -# ROK 
334  *      -# RFAILED
335  */
336
337 #ifdef ANSI
338 PUBLIC S16 KwUlUdxUeIdChgCfm
339 (
340 Pst        *pst,          
341 SuId       suId,           
342 U32        transId,
343 CmStatus   status
344 )
345 #else
346 PUBLIC S16 KwUlUdxUeIdChgCfm (pst, suId, cfmInfo)
347 Pst        *pst;         
348 SuId       suId;        
349 U32        transId;
350 CmStatus   status;
351 #endif
352 {
353    KwCb             *tKwCb;
354    KwUlCfgTmpData   *cfgTmpData;
355
356    TRC3(KwUlUdxUeIdChgCfm)
357
358 #if (ERRCLASS & ERRCLS_INT_PAR)
359    if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
360    {
361       RETVALUE (RFAILED);
362    }
363 #endif
364    tKwCb = KW_GET_KWCB(pst->dstInst);
365
366    KWDBGP_BRIEF(tKwCb, " suId(%d) \n", suId);
367
368 #if (ERRCLASS & ERRCLS_INT_PAR)
369    if (suId < 0)
370    {
371       RLOG0(L_ERROR, "Invalid suId");
372       RETVALUE(RFAILED);
373    }
374 #endif /* ERRCLASS & ERRCLS_INT_PAR */
375
376    if(ROK != kwDbmFindUlTransaction(tKwCb, transId, &cfgTmpData))
377    {
378       RLOG0(L_ERROR, "Invalid transId");
379       RETVALUE (RFAILED);
380    }
381
382    if(ROK != kwDbmDelUlTransaction(tKwCb, cfgTmpData))
383    {
384       RETVALUE(RFAILED);
385    }
386
387    if(status.status == CKW_CFG_CFM_OK)
388    {
389        if(cfgTmpData->ueCb != NULLP) 
390        {
391       kwCfgApplyUlUeIdChng(tKwCb, cfgTmpData->ueInfo, cfgTmpData->newUeInfo, cfgTmpData);
392    }
393    }
394    KwUiCkwUeIdChgCfm(&(tKwCb->u.ulCb->ckwSap.pst),
395                      tKwCb->u.ulCb->ckwSap.suId,
396                      transId,cfgTmpData->ueInfo,status);
397    /* only newUeInfo needs to be freed here, ueInfo would be freed at the 
398       interface or by he receipient in case of tight coupling */
399    KW_PST_FREE(pst->region, pst->pool, cfgTmpData->newUeInfo, sizeof(CkwUeInfo));
400    KW_FREE_WC(tKwCb, cfgTmpData, sizeof (KwUlCfgTmpData));
401    RETVALUE(ROK);
402
403
404 /**
405  * @brief 
406  *    Udx Status Prohibit Timer Start
407  *
408  *  @param[in] pst     Post structure  
409  *  @param[in] suId    Service User ID
410  *  @param[in] rlcId   rlc Id 
411  *  @return  S16
412  *      -# ROK 
413  *      -# RFAILED
414  */
415 PUBLIC S16  KwUlUdxStaProhTmrStart
416 (
417 Pst*         pst,
418 SuId         suId,
419 CmLteRlcId   *rlcId
420 )
421 {
422    KwCb       *tKwCb= NULLP;
423    KwUlRbCb   *rbCb;        
424
425 #if (ERRCLASS & ERRCLS_INT_PAR)
426    if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
427    {
428       RETVALUE (RFAILED);
429    }
430 #endif
431    tKwCb = KW_GET_KWCB(pst->dstInst);
432
433    kwDbmFetchUlRbCbByRbId(tKwCb, rlcId, &rbCb);
434    if (rbCb == NULLP)
435    {    
436       RLOG_ARG2(L_ERROR, DBG_UEID,rlcId->ueId, "CellId [%u]:RbId[%d] not found",
437             rlcId->cellId,rlcId->rbId);
438       RETVALUE(RFAILED);
439    }
440
441    /* Start staProhTmr */
442    kwStartTmr(tKwCb,(PTR)rbCb, KW_EVT_AMUL_STA_PROH_TMR);
443
444    RETVALUE (ROK);
445
446
447 /**
448  * @brief 
449  *    Handler for configuration confirm from DL.
450  *
451  * @param[in] gCb        - RLC Instance Control Block
452  * @param[in] cfgTmpData - Configuration Temporary Data 
453  * @param[in] cfmInfo    - DL Configuration Confirm Info
454  * @param[out] cfgCfm    - Configuration Confirm to be sent to RRC
455  *
456  * @return  S16
457  *    -# ROK 
458  *    -# RFAILED
459  */
460 #ifdef ANSI
461 PUBLIC S16 kwHdlCkwUlCfgReq
462 (
463 KwCb             *gCb,
464 KwUlCfgTmpData   *cfgTmpData,
465 CkwCfgCfmInfo    *cfmInfo,
466 CkwCfgCfmInfo    *cfgCfm
467 )
468 #else
469 PUBLIC S16 kwHdlCkwUlCfgReq(gCb,cfgTmpData,cfmInfo,cfmInfo)
470 KwCb             *gCb;
471 KwUlCfgTmpData   *cfgTmpData;
472 CkwCfgCfmInfo    *cfmInfo;
473 CkwCfgCfmInfo    *cfgCfm;
474 #endif
475 {
476    CkwCfgInfo   *cfg;
477    U32          idx;
478    U32          maxEnt;
479    
480    cfg = cfgTmpData->cfgInfo;
481    maxEnt = (cfg->numEnt < CKW_MAX_ENT_CFG)? cfg->numEnt:CKW_MAX_ENT_CFG;
482
483    for (idx = 0; idx < maxEnt; idx++)
484    {
485       CkwEntCfgCfmInfo   *entCfgCfm;
486       CkwEntCfgCfmInfo   *entDlCfgCfm;
487       CkwEntCfgInfo      *entCfg;
488
489       entCfg  = &(cfg->entCfg[idx]);
490       entCfgCfm   = &(cfgCfm->entCfgCfm[idx]);
491       entDlCfgCfm = &(cfmInfo->entCfgCfm[idx]);
492       switch (entCfg->cfgType)
493       {
494          case CKW_CFG_ADD:
495          case CKW_CFG_MODIFY:
496          case CKW_CFG_DELETE:
497             {
498                if (entCfg->dir == KW_DIR_UL)
499                {
500                   KW_MEM_CPY(entCfgCfm, 
501                              &cfgTmpData->cfgEntData[idx].entUlCfgCfm, 
502                              sizeof(CkwEntCfgCfmInfo)); 
503                }
504                else if (entCfg->dir == KW_DIR_DL)
505                {
506                   KW_MEM_CPY(entCfgCfm, entDlCfgCfm, sizeof(CkwEntCfgCfmInfo)); 
507                }
508                else if(entCfg->dir == KW_DIR_BOTH)
509                {
510                   if (entDlCfgCfm->status.status != CKW_CFG_CFM_OK)
511                   {
512                      kwCfgRollBackUlRb(gCb,
513                                        cfg->ueId,
514                                        &cfg->entCfg[idx], 
515                                        &cfgTmpData->cfgEntData[idx]);
516                   }
517                   else
518                   {
519                      kwCfgApplyUlRb(gCb,  
520                                     &cfg->entCfg[idx], 
521                                     &cfgTmpData->cfgEntData[idx],
522                                     cfgTmpData);
523                   }
524                   KW_MEM_CPY(entCfgCfm, entDlCfgCfm, sizeof(CkwEntCfgCfmInfo)); 
525                }
526                else
527                {
528                             KW_CFG_FILL_CFG_CFM(entCfgCfm, entCfg->rbId, entCfg->rbType,
529                                            CKW_CFG_CFM_NOK, CKW_CFG_REAS_INVALID_DIR);
530                   RLOG_ARG2(L_ERROR,DBG_UEID,cfg->ueId,"RBID[%d] direction[%d] is invalid",
531                          entCfg->rbId,entCfg->dir);
532                }
533                break;
534             }
535
536          case CKW_CFG_REESTABLISH:
537             {
538                if (entCfg->dir == KW_DIR_UL)
539                {
540                   KW_MEM_CPY(entCfgCfm, 
541                              &cfgTmpData->cfgEntData[idx].entUlCfgCfm, 
542                              sizeof(CkwEntCfgCfmInfo)); 
543                }
544                else if (entCfg->dir == KW_DIR_DL)
545                {
546                   KW_MEM_CPY(entCfgCfm, entDlCfgCfm, sizeof(CkwEntCfgCfmInfo)); 
547                }
548                else
549                {
550                   if (entCfg->dir & KW_DIR_UL)
551                   {
552                      /* Reestablish indication is sent from UL Instance only*/
553                      if (entDlCfgCfm->status.status == CKW_CFG_CFM_OK)
554                      {
555                         kwCfgApplyReEstUlRb (gCb, cfg->ueId, 
556                                              cfg->cellId, TRUE, 
557                                              &cfgTmpData->cfgEntData[idx]);
558                      }
559                      KW_MEM_CPY(entCfgCfm, entDlCfgCfm, sizeof(CkwEntCfgCfmInfo)); 
560                   }
561                }
562                break;
563             }
564          case CKW_CFG_DELETE_UE:
565             {
566                if (cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status == CKW_CFG_CFM_OK)
567                {
568                   kwCfgApplyDelUlUe(gCb, cfgTmpData);
569                   KW_MEM_CPY(entCfgCfm, 
570                              &cfgTmpData->cfgEntData[idx].entUlCfgCfm, 
571                              sizeof(CkwEntCfgCfmInfo)); 
572                }
573                else
574                {
575                    KW_MEM_CPY(entCfgCfm, entDlCfgCfm,
576                               sizeof(CkwEntCfgCfmInfo)); 
577                }
578                break;
579             }
580          case CKW_CFG_DELETE_CELL:
581             {
582                if (cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status == CKW_CFG_CFM_OK)
583                {
584                   kwCfgApplyDelUlCell(gCb, cfgTmpData);
585                   KW_MEM_CPY(entCfgCfm, 
586                              &cfgTmpData->cfgEntData[idx].entUlCfgCfm, 
587                              sizeof(CkwEntCfgCfmInfo)); 
588                }
589                else
590                {
591                    KW_MEM_CPY(entCfgCfm, entDlCfgCfm,
592                               sizeof(CkwEntCfgCfmInfo)); 
593                }
594                break;
595             }
596          default:
597             {
598                KW_CFG_FILL_CFG_CFM(entCfgCfm, entCfg->rbId, entCfg->rbType,
599                                    CKW_CFG_CFM_NOK, CKW_CFG_REAS_INVALID_CFG);
600
601                RLOG0(L_ERROR,"Invalid configuration type");
602             }
603       }
604    }
605
606    /* Assign number of entity configurations and suId */
607    cfgCfm->transId = cfgTmpData->uprLyrTransId;
608    cfgCfm->ueId = cfg->ueId;
609    cfgCfm->cellId = cfg->cellId;
610    cfgCfm->numEnt = cfg->numEnt;
611
612    RETVALUE(ROK);
613 }
614 #ifdef __cplusplus
615 }
616 #endif /* __cplusplus */
617
618 \f
619 /**********************************************************************
620          End of file
621 **********************************************************************/