RLC-MAC Interface APIs and Memory configuration Changes
[o-du/l2.git] / src / 5gnrrlc / kw_uim.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**
20   
21      Name:    LTE-RLC Layer - Upper Interface Functions
22     
23      Type:    C file
24   
25      Desc:     Source code for RLC Upper Interface Module
26                This file contains following functions
27       
28         --KwUiCkwBndReq
29         --KwUiCkwUbndReq
30         --KwUiCkwCfgReq
31
32         --KwUiKwuBndReq
33         --KwUiKwuUbndReq
34         --KwUiKwuDatReq
35         --KwUiKwuDiscSduReq 
36
37      File:     kw_uim.c
38
39 **********************************************************************/
40 static const char* RLOG_MODULE_NAME="UIM";
41 static int RLOG_MODULE_ID=2048;
42 static int RLOG_FILE_ID=205;
43
44 /** 
45  * @file kw_uim.c
46  * @brief RLC Upper Interface Module
47 */
48
49 #define KW_MODULE KW_DBGMASK_INF
50
51 \f
52 /* header (.h) include files */
53 #include "envopt.h"        /* environment options */
54 #include "envdep.h"        /* environment dependent */
55 #include "envind.h"        /* environment independent */
56
57 #include "gen.h"           /* general */
58 #include "ssi.h"           /* system services */
59 #include "cm5.h"           /* common timer defines */
60 #include "cm_tkns.h"       /* common tokens defines */
61 #include "cm_mblk.h"       /* common memory allocation library defines */
62 #include "cm_llist.h"      /* common link list  defines  */
63 #include "cm_hash.h"       /* common hash list  defines */
64 #include "cm_lte.h"        /* common LTE defines */
65 #include "lkw.h"           /* LKW defines */
66 #include "ckw.h"           /* CKW defines */
67 #include "kwu.h"           /* KWU defines */
68 #include "rgu.h"           /* RGU defines */
69 #include "kw_env.h"        /* RLC environment options */
70 #include "kw.h"            /* RLC defines */
71 #include "kw_dl.h"
72 #include "kw_ul.h"
73 #include "kw_udx.h"
74
75 /* extern (.x) include files */
76 #include "gen.x"           /* general */
77 #include "ssi.x"           /* system services */
78
79 #include "cm5.x"           /* common timer library */
80 #include "cm_tkns.x"       /* common tokens */
81 #include "cm_mblk.x"       /* common memory allocation */
82 #include "cm_llist.x"      /* common link list */
83 #include "cm_hash.x"       /* common hash list */
84 #include "cm_lte.x"        /* common LTE includes */
85 #include "cm_lib.x"        /* common memory allocation library */
86 #include "lkw.x"           /* LKW */
87 #include "ckw.x"           /* CKW */
88 #include "kwu.x"           /* KWU */
89 #include "rgu.x"           /* RGU */
90 #include "kw_err.h"
91 #include "kw.x"
92 #include "kw_udx.x"
93 #include "kw_dl.x"
94 #include "kw_ul.x"
95
96
97 /*****************************************************************************
98  *                          CKW INTERFACE
99  ****************************************************************************/
100
101 /**
102  * @brief 
103  *    Handler for binding the RLC upper layer service user with 
104  *    the RLC layer.
105  *
106  * @details
107  *    This function is used by RLC user to request for binding to 
108  *    RLC. This function is called by the CKW interface to bind 
109  *    RLC's SAP (identified by spId) with the service user's
110  *    SAP (identified by suId). 
111  *
112  * @param[in] pst     Post structure
113  * @param[in] suId    Service User ID
114  * @param[in] spId    Service provider ID
115  *
116  * @return  S16
117  *    -# ROK 
118  *    -# RFAILED
119  *
120 */
121 #ifdef ANSI
122 PUBLIC S16 KwUiCkwBndReq 
123 (
124 Pst    *pst,
125 SuId   suId,
126 SpId   spId 
127 )
128 #else
129 PUBLIC S16 KwUiCkwBndReq (pst, suId, spId)
130 Pst    *pst; 
131 SuId   suId;
132 SpId   spId;
133 #endif
134 {
135    KwCkwSapCb   *ckwSap;  
136    KwCb         *tKwCb;
137
138    TRC3(KwUiCkwBndReq);
139
140 #if (ERRCLASS & ERRCLS_INT_PAR)
141    if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
142    {
143       RETVALUE(RFAILED);
144    }
145 #endif
146
147    tKwCb = KW_GET_KWCB(pst->dstInst);
148
149    RLOG2(L_DEBUG, "spId(%d), suId(%d)", spId, suId);
150    ckwSap = &(tKwCb->u.ulCb->ckwSap);
151    /* Take action based on the current state of the SAP */
152    switch(ckwSap->state)
153    {
154       /* SAP is configured but not bound */
155       case KW_SAP_CFG:
156       case KW_SAP_UBND:
157       {
158          /* copy bind configuration parameters in SSAP sap */
159          ckwSap->suId = suId;
160          ckwSap->pst.dstProcId = pst->srcProcId;
161          ckwSap->pst.dstEnt = pst->srcEnt;
162          ckwSap->pst.dstInst = pst->srcInst;
163
164          /* Update the State */
165          ckwSap->state = KW_SAP_BND;
166
167          RLOG1(L_DEBUG, "KwUiCkwBndReq: state (%d)", ckwSap->state);
168          break;
169       }
170       case KW_SAP_BND:
171       {
172          /* Sap is already bound check source, destination Entity and  
173           * Proc Id  */
174          if (ckwSap->pst.dstProcId != pst->srcProcId ||
175              ckwSap->pst.dstEnt != pst->srcEnt ||
176              ckwSap->pst.dstInst != pst->srcInst ||
177              ckwSap->suId != suId)
178          {
179             KW_SEND_SAPID_ALARM(tKwCb,
180                                 spId, 
181                                 LKW_EVENT_CKW_BND_REQ, 
182                                 LCM_CAUSE_INV_PAR_VAL);
183
184             RLOG0(L_ERROR, "CKW SAP already Bound");
185             KwUiCkwBndCfm(&(ckwSap->pst), ckwSap->suId, CM_BND_NOK);
186             RETVALUE(RFAILED);
187          }
188          break;
189       }
190       default:
191       {
192 #if (ERRCLASS & ERRCLS_INT_PAR)
193          RLOG0(L_ERROR, "Invalid CKW SAP State in Bind Req");
194          KW_SEND_SAPID_ALARM(tKwCb,
195                              spId, 
196                              LKW_EVENT_CKW_BND_REQ, 
197                              LCM_CAUSE_INV_STATE);
198 #endif /* ERRCLASS & ERRCLS_INT_PAR */
199          KwUiCkwBndCfm(&(ckwSap->pst), ckwSap->suId, CM_BND_NOK);
200          RETVALUE(RFAILED);
201          break;
202       }
203    }
204
205    KwUiCkwBndCfm(&(ckwSap->pst), ckwSap->suId, CM_BND_OK);
206    RETVALUE(ROK);
207
208
209 \f
210 /**
211  * @brief 
212  *    Handler for unbinding the RLC upper layer service user CKW with 
213  *    the RLC layer.
214  *
215  * @details
216  *    This function is used by RLC user to request for unbinding  
217  *    with RLC.This function is called by the CKW interface to 
218  *    unbind with RLC.  
219  *
220  * @param[in] pst     Post structure
221  * @param[in] spId    Service provider SAP ID
222  * @param[in] reason  Reason for Unbinding 
223  *
224  * @return  S16
225  *    -# ROK 
226  *    -# RFAILED
227 */ 
228 #ifdef ANSI
229 PUBLIC S16 KwUiCkwUbndReq
230 (
231 Pst      *pst,   
232 SpId     spId,  
233 Reason   reason 
234 )
235 #else
236 PUBLIC S16 KwUiCkwUbndReq(pst, spId, reason)
237 Pst      *pst; 
238 SpId     spId; 
239 Reason   reason;
240 #endif
241 {
242    KwCb *tKwCb;
243
244    TRC3(KwUiCkwUbndReq)
245
246 #if (ERRCLASS & ERRCLS_INT_PAR)
247    if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
248    {
249       RETVALUE(RFAILED);
250    }
251 #endif /* ERRCLASS & ERRCLS_INT_PAR */
252    tKwCb = KW_GET_KWCB(pst->dstInst);
253
254    RLOG2(L_DEBUG,"spId(%d), reason(%d)", 
255                 spId, 
256                 reason);
257
258    UNUSED(reason);
259
260 #if (ERRCLASS & ERRCLS_INT_PAR)
261    KW_GET_AND_VALIDATE_CKWSAP(tKwCb, 
262                               (&(tKwCb->u.ulCb->ckwSap)), 
263                               EKW208, 
264                               "KwUiCkwUbndReq");
265 #endif /* ERRCLASS & ERRCLS_INT_PAR */
266
267    /* disable upper sap (CKW) */
268    tKwCb->u.ulCb->ckwSap.state = KW_SAP_CFG;
269    RETVALUE(ROK);
270
271
272 /*******************************************************************
273  *
274  * @brief Handler for UE create request
275  *
276  * @details
277  *
278  *    Function : RlcDuappProcUeCreateReq 
279  *
280  *    Functionality:
281  *       Handler for UE create request
282  *
283  * @params[in] pst - Post Structure
284  *             cfg - Configuration information for one or more RLC entities
285  * @return ROK     - success
286  *         RFAILED - failure
287  *
288  * ****************************************************************/
289 PUBLIC S16 RlcDuappProcUeCreateReq(Pst *pst, CkwCfgInfo *ueCfg)
290 {
291    U8 idx;
292
293    ueCfg->transId = 1;
294
295    for(idx = 0; idx < ueCfg->numEnt; idx++)
296    {
297       ueCfg->entCfg[idx].cfgType = CKW_CFG_ADD; 
298    }
299    
300    KwUiCkwCfgReq(pst, ueCfg);
301 } /* RlcDuappUeCreateReq */ 
302
303 \f
304 /**
305  * @brief  
306  *    Handler for configuring RLC entities.
307  *
308  * @details
309  *    This function is used by RRC to configure(add/delete/modify)
310  *    one or more RLC entities. 
311  *
312  * @param[in] pst   -  Post structure  
313  * @param[in] spId  -  Serive Provider ID 
314  * @param[in] cfg   -  Configuration information for one or more RLC entities. 
315  *
316  * @return  S16
317  *      -# ROK 
318  *      -# RFAILED
319  */
320 #ifdef ANSI
321 PUBLIC S16 KwUiCkwCfgReq
322 (
323 Pst          *pst,
324 //SpId         spId,
325 CkwCfgInfo   *cfg
326 )
327 #else
328 //PUBLIC S16 KwUiCkwCfgReq(pst, spId, cfg)
329 PUBLIC S16 KwUiCkwCfgReq(pst, cfg)
330 Pst          *pst;
331 //SpId         spId;
332 CkwCfgInfo   *cfg;
333 #endif
334 {
335    S16         ret = ROK;
336    KwCb        *tKwCb;
337    KwUlCfgTmpData   *cfgTmpData;
338
339    static U32  transCount;
340
341
342    TRC3(KwUiCkwCfgReq)
343       
344 #if (ERRCLASS & ERRCLS_INT_PAR)
345    if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
346    {
347       KW_PST_FREE(pst->region, pst->pool, cfg, sizeof(CkwCfgInfo));
348       RETVALUE(RFAILED);
349    }
350 #endif
351    tKwCb = KW_GET_KWCB(pst->dstInst);
352
353 /* HLAL */
354 #if 0
355    RLOG1(L_DEBUG, "spId(%d)", spId);
356
357    /* Validate SAP ID under ERRORCLS */
358    KW_VALDATE_SAP(tKwCb, spId, (&(tKwCb->u.ulCb->ckwSap)), ret);
359    if (ret != ROK)
360    {
361       KW_PST_FREE(pst->region, pst->pool, cfg, sizeof(CkwCfgInfo));
362       RETVALUE(RFAILED);
363    }
364 #endif
365
366    KW_ALLOC(tKwCb, cfgTmpData, sizeof (KwUlCfgTmpData));
367
368    if (cfgTmpData == NULLP)
369    {
370       KW_PST_FREE(pst->region, pst->pool, cfg, sizeof(CkwCfgInfo));
371       RETVALUE(RFAILED);
372    }
373
374
375    cfgTmpData->uprLyrTransId = cfg->transId; /*Save User TransId*/
376    cfgTmpData->transId = ++transCount;       /*Generate new TransId*/
377    cfg->transId = cfgTmpData->transId;
378    cfgTmpData->cfgInfo  = cfg;
379  
380    if (kwDbmAddUlTransaction(tKwCb, cfgTmpData) != ROK)
381    {
382       RLOG0(L_ERROR, "Addition to UL transId Lst Failed");
383       KW_PST_FREE(pst->region, pst->pool, cfg, sizeof(CkwCfgInfo));
384       
385       RETVALUE(RFAILED);
386    }
387    
388    kwHdlUiCkwUlCfgReq(tKwCb, cfgTmpData, cfg);
389    
390    KwUlUdxCfgReq(&(KW_GET_UDX_SAP(tKwCb)->pst),KW_GET_UDX_SAP(tKwCb)->spId,cfg); 
391
392    RETVALUE(ROK);
393
394
395 /**
396  * @brief 
397  *    Handler to change the UeId
398  *
399  * @details 
400  *    This primitive is used by RRC to change the UeId for the existing UE
401  *    context.
402  *     
403  * @param[in] pst     -  Point to the pst structure
404  * @param[in] spId    -  The ID of the service provider SAP in the RLC layer 
405  * @param[in] transId -  Transaction ID. This field uniquily identifies
406  *                       transaction between RRC and RLC
407  * @param[in] ueInfo    -  Old UE Id Info for which the change request has come 
408  * @param[in] newUeInfo -  New UE Id Info for existing UE context 
409  * 
410  * @return S16
411  *    -# ROK
412  *    -# RFAILED
413  */
414 #ifdef ANSI
415 PUBLIC S16 KwUiCkwUeIdChgReq
416 (
417 Pst         *pst, 
418 SpId        spId, 
419 U32         transId, 
420 CkwUeInfo   *ueInfo,
421 CkwUeInfo   *newUeInfo
422 )
423 #else
424 PUBLIC S16 KwUiCkwUeIdChgReq(pst, spId, transId, ueInfo, newUeInfo)
425 Pst         *pst;
426 SpId        spId;
427 U32         transId;
428 CkwUeInfo   *ueInfo;
429 CkwUeInfo   *newUeInfo;
430 #endif
431 {
432    S16              ret = ROK;
433    KwCb             *tKwCb;
434    KwUlCfgTmpData   *cfgTmpData = NULLP;
435
436    TRC3(KwUiCkwUeIdChgReq)
437
438    do
439    {
440 #if (ERRCLASS & ERRCLS_INT_PAR)
441       if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
442       {
443          ret = RFAILED;
444          break;
445       }
446 #endif
447
448       tKwCb = KW_GET_KWCB(pst->dstInst);
449 #ifndef ALIGN_64BIT
450       RLOG_ARG2(L_DEBUG,DBG_CELLID,newUeInfo->cellId,
451                    "KwUiCkwUeIdChgReq(pst, spId(%d), transId(%ld))", 
452                    spId, 
453                    transId);
454 #else
455       RLOG_ARG2(L_DEBUG,DBG_CELLID,newUeInfo->cellId, 
456                    "KwUiCkwUeIdChgReq(pst, spId(%d), transId(%d))\n", 
457                    spId, 
458                    transId);
459 #endif
460
461       KW_ALLOC(tKwCb, cfgTmpData, sizeof (KwUlCfgTmpData));
462       if (!cfgTmpData)
463       {
464          ret = RFAILED;
465          break;
466       }
467
468       cfgTmpData->transId = transId;
469       cfgTmpData->ueInfo  = ueInfo;
470       cfgTmpData->newUeInfo  = newUeInfo; 
471
472       if (kwDbmAddUlTransaction(tKwCb, cfgTmpData))
473       {
474          RLOG0(L_ERROR, "Addition to UL transId Lst Failed");
475          ret = RFAILED;
476          break;
477       }
478    }while(0);
479
480    if(ret)
481    {
482       /* there was an error in the processing, free up all the memory
483        * that was passed and could have been allocated in this function
484        */
485       /* Freeing from proper region */
486       KW_PST_FREE(pst->region, pst->pool, newUeInfo, sizeof(CkwUeInfo));
487       KW_PST_FREE(pst->region, pst->pool, ueInfo, sizeof(CkwUeInfo));
488
489       if(cfgTmpData)
490       {
491          KW_FREE(tKwCb, cfgTmpData, sizeof (KwUlCfgTmpData));
492       }
493       RETVALUE(RFAILED);
494    }
495
496    if(ROK != kwCfgValidateUeIdChng(tKwCb,ueInfo,newUeInfo,cfgTmpData))
497    {
498       RLOG_ARG0(L_ERROR,DBG_CELLID,cfgTmpData->ueInfo->cellId, 
499             "Validation Failure for UeId change");
500    }
501
502    KwUlUdxUeIdChgReq(&(KW_GET_UDX_SAP(tKwCb)->pst),
503                      KW_GET_UDX_SAP(tKwCb)->spId,
504                      transId, 
505                      ueInfo,
506                      newUeInfo);
507
508    RETVALUE(ROK);
509
510
511 \f
512 /**
513  * @brief 
514  *    Handler for Configuration Request 
515  *
516  * @param[in] gCb      RLC Instance Control Block  
517  * @param[in] cfgTmpData  Configuration stored in Transaction Block  
518  * @param[in] cfg      Configuration block
519  *
520  * @return  S16
521  *    -# ROK 
522  *    -# RFAILED
523  */
524 #ifdef ANSI
525 PUBLIC Void kwHdlUiCkwUlCfgReq
526 (
527 KwCb             *gCb,
528 KwUlCfgTmpData   *cfgTmpData,
529 CkwCfgInfo       *cfg
530 )
531 #else
532 PUBLIC Void kwHdlUiCkwUlCfgReq(gCb, cfgTmpData, cfg)
533 KwCb             *gCb;
534 KwUlCfgTmpData   *cfgTmpData;
535 CkwCfgInfo       *cfg;
536 #endif
537 {
538    U8   idx;  
539
540    TRC3(kwHdlUiCkwUlCfgReq)
541
542    cfgTmpData->ueId = cfg->ueId;
543    cfgTmpData->cellId = cfg->cellId;
544    for (idx = 0; idx < cfg->numEnt; idx++)
545    {
546       cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status = CKW_CFG_CFM_OK;
547       cfgTmpData->cfgEntData[idx].entUlCfgCfm.rbId = cfg->entCfg[idx].rbId; 
548       cfgTmpData->cfgEntData[idx].entUlCfgCfm.rbType = cfg->entCfg[idx].rbType;
549       switch(cfg->entCfg[idx].cfgType)
550       {
551          case CKW_CFG_ADD:
552          case CKW_CFG_MODIFY:
553          case CKW_CFG_DELETE:
554          {
555          
556             if(cfg->entCfg[idx].dir & KW_DIR_UL)
557             {
558                /* Configuration is for UL , thus validating */
559                if(ROK != kwCfgValidateUlRb(gCb,
560                                            &cfg->entCfg[idx], 
561                                            &cfgTmpData->cfgEntData[idx],
562                                            cfgTmpData))
563                {
564                   RLOG_ARG2(L_ERROR,DBG_UEID, cfgTmpData->ueId,
565                         "CELLID [%u]:Validation Failure for UL RB [%d]",
566                          cfg->cellId,cfg->entCfg[idx].rbId);
567                   cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status = CKW_CFG_CFM_NOK;
568                   /*Validation is getting failed so no need to do configuration at DL.
569                    *Set dir as UL, so that no configuration is done at DL */
570                   cfg->entCfg[idx].dir = KW_DIR_UL;
571                }
572             }
573             if(cfg->entCfg[idx].dir == KW_DIR_UL)
574             {
575                /*If the configuration is for UL only then apply it */   
576                if (cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status == CKW_CFG_CFM_OK)
577                {
578                   kwCfgApplyUlRb(gCb, 
579                                  &cfg->entCfg[idx], 
580                                  &cfgTmpData->cfgEntData[idx],
581                                  cfgTmpData);
582                }
583             }
584             break;
585          }
586          case CKW_CFG_REESTABLISH:   
587          {
588             if(cfg->entCfg[idx].dir & KW_DIR_UL)
589             {
590                if(ROK != kwCfgValidateReEstRb(gCb,
591                                               cfg->ueId, 
592                                               cfg->cellId, 
593                                               &cfg->entCfg[idx], 
594                                               &cfgTmpData->cfgEntData[idx]))
595                {
596                   RLOG_ARG2(L_ERROR,DBG_UEID,cfg->ueId,
597                         "CellID [%u]:Validation Failure for Reest UL RB [%d]",
598                         cfg->cellId,cfg->entCfg[idx].rbId);
599                   cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status = CKW_CFG_CFM_NOK;
600                   /* Setting dir as UL, so that no configuration is done at DL */
601                   cfg->entCfg[idx].dir = KW_DIR_UL;
602                   break;
603                }
604             }
605             if(cfg->entCfg[idx].dir == KW_DIR_UL)
606             {
607                /*If the configuration is for UL only then apply it */   
608                if (cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status == CKW_CFG_CFM_OK)
609                {
610                   kwCfgApplyReEstUlRb(gCb,  
611                                       cfg->ueId, 
612                                       cfg->cellId,
613                                       TRUE,
614                                       &cfgTmpData->cfgEntData[idx]);
615                }
616             }
617             break;
618          }
619          case CKW_CFG_DELETE_UE :   
620          {
621             if(ROK != kwCfgValidateDelUlUe(gCb,  
622                                            &cfg->entCfg[idx], 
623                                            &cfgTmpData->cfgEntData[idx],
624                                            cfgTmpData))
625             {
626                RLOG_ARG1(L_ERROR,DBG_CELLID,cfg->cellId,
627                      "UL UEID [%d]:Validation Failure",
628                      cfgTmpData->ueId);
629                cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status = CKW_CFG_CFM_NOK;
630                /* Setting dir as UL, so that no configuration is done at DL */
631                cfg->entCfg[idx].dir = KW_DIR_UL;
632             }
633             break;
634          }
635          case CKW_CFG_DELETE_CELL :   
636          {
637             if(ROK != kwCfgValidateDelUlCell(gCb,
638                                              cfg->cellId, 
639                                              &cfg->entCfg[idx], 
640                                              &cfgTmpData->cfgEntData[idx],
641                                              cfgTmpData))
642             {
643                RLOG_ARG0(L_ERROR,DBG_CELLID,cfg->cellId,
644                      "Del UL Cell Validation Failure");
645                cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status = CKW_CFG_CFM_NOK;
646                /* Setting dir as UL, so that no configuration is done at DL */
647                cfg->entCfg[idx].dir = KW_DIR_UL;
648             }
649             break;
650          }
651       }/* switch end */
652    }/* for end */
653    RETVOID;
654 }
655
656 \f
657 /*****************************************************************************
658  *                          KWU INTERFACE
659  ****************************************************************************/
660 /**
661  * @brief  
662  *    Handler for binding the RLC upper layer service user with 
663  *    the RLC layer.
664  *
665  * @details
666  *    This function is used by RLC user to request for binding to 
667  *    RLC.This function is called by the KWU interface to bind 
668  *    RLC's SAP (identified by spId) with the service user's
669  *    SAP (identified by suId). 
670  *
671  * @param[in] pst   Post structure  
672  * @param[in] suId  Service user SAP ID 
673  * @param[in] spId  Service provider ID
674  *
675  * @return  S16
676  *    -# ROK
677  *    -# RFAILED
678  *
679  */
680 #ifdef ANSI
681 PUBLIC S16 KwUiKwuBndReq 
682 (
683 Pst    *pst,  
684 SuId   suId, 
685 SpId   spId 
686 )
687 #else
688 PUBLIC S16 KwUiKwuBndReq (pst, suId, spId)
689 Pst    *pst;  
690 SuId   suId; 
691 SpId   spId; 
692 #endif
693 {
694    KwKwuSapCb   *kwuSap;     /* SAP Config Block */
695    KwCb         *tKwCb;
696    
697    TRC3(KwUiKwuBndReq)
698
699 #if (ERRCLASS & ERRCLS_INT_PAR)
700    if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
701    {
702       RETVALUE(RFAILED);
703    }
704 #endif
705    tKwCb = KW_GET_KWCB(pst->dstInst);
706    RLOG2(L_DEBUG, "KwUiKwuBndReq(pst, spId(%d), suId(%d))", spId, suId);
707
708     /* Validation of input parameters */
709 #if (ERRCLASS & ERRCLS_INT_PAR)
710    if(!((spId < (S16) tKwCb->genCfg.maxKwuSaps) && (spId >=0))) 
711    {
712       RLOG0(L_ERROR,"Invalid spId");
713       KW_SEND_SAPID_ALARM(tKwCb,spId, LKW_EVENT_KWU_BND_REQ, LCM_CAUSE_INV_SAP);
714       RETVALUE(RFAILED); 
715    }
716 #endif
717
718    /* Get Sap control block */
719    kwuSap = (tKwCb->genCfg.rlcMode == LKW_RLC_MODE_DL) ?
720             (tKwCb->u.dlCb->kwuDlSap + spId):
721             (tKwCb->u.ulCb->kwuUlSap + spId);
722
723    /* Take action based on the current state of the SAP */
724    switch(kwuSap->state)
725    {
726       /* SAP is configured but not bound */
727       case KW_SAP_CFG:
728       case KW_SAP_UBND:
729       {
730          /* copy bind configuration parameters in sap */
731          kwuSap->suId          = suId;
732          kwuSap->pst.dstProcId = pst->srcProcId;
733          kwuSap->pst.dstEnt    = pst->srcEnt;
734          kwuSap->pst.dstInst   = pst->srcInst;
735
736          /* Update the State */
737          kwuSap->state = KW_SAP_BND;
738
739          RLOG1(L_DEBUG, "KwUiKwuBndReq: state (%d)", kwuSap->state);
740          break;
741       }
742       case KW_SAP_BND:
743       {
744          /* Sap is already bound check source, destination Entity and Proc Id */
745          if (kwuSap->pst.dstProcId != pst->srcProcId ||
746              kwuSap->pst.dstEnt != pst->srcEnt ||
747              kwuSap->pst.dstInst != pst->srcInst ||
748              kwuSap->suId != suId)
749          {
750             KW_SEND_SAPID_ALARM(tKwCb,
751                                 spId, 
752                                 LKW_EVENT_KWU_BND_REQ, 
753                                 LCM_CAUSE_INV_PAR_VAL);
754             RLOG1(L_ERROR,"RLC Mode [%d] : KWU SAP already Bound",
755                   tKwCb->genCfg.rlcMode);
756             KwUiKwuBndCfm(&(kwuSap->pst), kwuSap->suId, CM_BND_NOK);
757             RETVALUE(RFAILED);
758          }
759          break;
760       }
761
762      default:
763       {
764 #if (ERRCLASS & ERRCLS_INT_PAR)
765          RLOG1(L_ERROR,"RLC Mode [%d]:Invalid KWU SAP State in Bind Req",
766                tKwCb->genCfg.rlcMode);
767          KW_SEND_SAPID_ALARM(tKwCb,
768                              spId,
769                              LKW_EVENT_KWU_BND_REQ, 
770                              LCM_CAUSE_INV_STATE);
771 #endif /* ERRCLASS & ERRCLS_INT_PAR */
772          KwUiKwuBndCfm(&(kwuSap->pst), kwuSap->suId, CM_BND_NOK);
773          RETVALUE(RFAILED);
774       }
775    }
776    KwUiKwuBndCfm(&(kwuSap->pst), kwuSap->suId, CM_BND_OK);
777    RETVALUE(ROK);
778
779
780 \f
781 /**
782  * @brief 
783  *    Handler for unbinding the RLC upper layer service user with 
784  *    the RLC layer.
785  *
786  * @details
787  *    This function is used by RLC user to request for unbinding  
788  *    with RLC.This function is called by the KWU interface to 
789  *    unbind with RLC. 
790  *
791  * @param[in] pst     Post structure  
792  * @param[in] spId    Service provider SAP ID 
793  * @param[in] reason  Reason for Unbinding 
794  *
795  * @return  S16
796  *     -# ROK 
797  *     -# RFAILED
798  */
799 #ifdef ANSI
800 PUBLIC S16 KwUiKwuUbndReq
801 (
802 Pst      *pst,  
803 SpId     spId, 
804 Reason   reason 
805 )
806 #else
807 PUBLIC S16 KwUiKwuUbndReq(pst, spId, reason)
808 Pst      *pst; 
809 SpId     spId; 
810 Reason   reason; 
811 #endif
812 {
813    KwKwuSapCb   *kwuSap;   /* KWU SAP control block */
814    KwCb         *tKwCb;
815
816    TRC3(KwUiKwuUbndReq)
817
818 #if (ERRCLASS & ERRCLS_INT_PAR)
819    if ((pst->dstInst >= KW_MAX_RLC_INSTANCES) ||
820        (spId >= (S16) kwCb[pst->dstInst]->genCfg.maxKwuSaps) ||
821        (spId < 0))
822    {
823       RETVALUE (RFAILED);
824    }
825 #endif
826
827    tKwCb = KW_GET_KWCB(pst->dstInst);
828
829    RLOG2(L_DEBUG, "spId(%d), reason(%d)", 
830                 spId, 
831                 reason);
832
833    /* Get Sap control block */
834    kwuSap = (tKwCb->genCfg.rlcMode == LKW_RLC_MODE_DL) ?
835             (tKwCb->u.dlCb->kwuDlSap + spId):
836             (tKwCb->u.ulCb->kwuUlSap + spId);
837
838    kwuSap->state = KW_SAP_CFG;
839
840    RETVALUE(ROK);
841
842
843 /**
844  * @brief Handler for receiving the data(SDU) from upper layer. 
845  *
846  * @details
847  *    This function is used by RLC service user (PDCP) to 
848  *    transfer data (SDU) to RLC.
849  *
850  * @param[in] pst         Post structure  
851  * @param[in] spId        Service Provider SAP ID 
852  * @param[in] datreq  Data Request Information
853  * @param[in] mBuf        Data Buffer (SDU) 
854  *
855  * @return  S16
856  *    -# ROK 
857  *    -# RFAILED
858  */
859 #ifdef ANSI
860 PUBLIC S16 KwUiKwuDatReq
861 (
862 Pst             *pst,   
863 SpId            spId,  
864 KwuDatReqInfo   *datReq, 
865 Buffer          *mBuf   
866 )
867 #else
868 PUBLIC S16 KwUiKwuDatReq(pst, spId, datReq, mBuf)
869 Pst             *pst;  
870 SpId            spId; 
871 KwuDatReqInfo   *datReq; 
872 Buffer          *mBuf;  
873 #endif
874 {
875    S16          ret = ROK;   /* Return Value */
876    KwDlRbCb     *rbCb;       /* RB Control Block */
877    KwKwuSapCb   *kwuSap;     /* SAP Config Block */
878    KwCb         *tKwCb;
879
880    TRC3(KwUiKwuDatReq)
881
882 #if (ERRCLASS & ERRCLS_INT_PAR)
883    if ((pst->dstInst >= KW_MAX_RLC_INSTANCES) ||
884        (spId >= (S16) kwCb[pst->dstInst]->genCfg.maxKwuSaps) ||
885        (spId < 0))
886    {
887       SPutMsg(mBuf);
888       RETVALUE(RFAILED);
889    }
890 #endif
891
892    tKwCb = KW_GET_KWCB(pst->dstInst);
893
894    /* Get Sap control block */
895    kwuSap = tKwCb->u.dlCb->kwuDlSap + spId;
896
897    /* Validate SAP ID under ERRORCLS */
898    KW_VALDATE_SAP(tKwCb,spId, kwuSap, ret);
899    if (ret != ROK)
900    {
901       KW_FREE_BUF(mBuf);
902       RETVALUE(RFAILED);
903    }
904
905    /* Fetch the RbCb */
906    kwDbmFetchDlRbCbByRbId(tKwCb, &datReq->rlcId, &rbCb);
907    if(!rbCb)
908    {
909       RLOG_ARG2(L_WARNING, DBG_UEID,datReq->rlcId.ueId, "CellId[%u]:DL RbId [%d] not found",
910             datReq->rlcId.cellId,datReq->rlcId.rbId);
911       KW_FREE_BUF(mBuf);
912
913       RETVALUE(RFAILED);
914    }
915
916    /* kw005.201 update the spId received in datReq to update statistics */
917    rbCb->kwuSapId = spId;
918    /* Dispatch according to mode of the rbCb */
919    switch (rbCb->mode)
920    {
921       case CM_LTE_MODE_TM:
922       {
923          /* Verify the user */
924          if (pst->srcEnt != ENTNH)
925          {
926             /* kw002.201 Freeing from proper region */
927             KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datReq, 
928                         sizeof(KwuDatReqInfo));
929             KW_FREE_BUF(mBuf);
930              
931             RETVALUE(RFAILED);
932          }
933
934          kwTmmQSdu(tKwCb,rbCb, datReq, mBuf);
935          /* kw005.201 ccpu00117318, updated statistics */
936          kwuSap->sts.sduRx++;
937          break;
938       }
939       case CM_LTE_MODE_UM:
940       {
941          kwUmmQSdu(tKwCb,rbCb, datReq, mBuf);
942
943          /* kw005.201 ccpu00117318, updated statistics */
944          kwuSap->sts.sduRx++;
945          break;
946       }
947       case CM_LTE_MODE_AM:
948       {
949          kwAmmQSdu(tKwCb,rbCb, mBuf, datReq);
950          /* kw005.201 ccpu00117318, updated statistics */
951          kwuSap->sts.sduRx++;
952          break;
953       }
954       default:
955       {
956          RLOG0(L_ERROR, "Invalid RB Mode");
957          break;
958       }
959    }
960    RETVALUE(ret);
961
962
963 \f
964 /**
965  * @brief 
966  *    Handler for discarding a SDU. 
967  *
968  * @details
969  *    This function is used by RLC AM  and RLC UM entities. 
970  *    This function is called by the service user to discard a particular
971  *    RLC SDU if it is present in the SDU queue of the RB control block 
972  *    and if it is not mapped to any PDU. 
973  *
974  * @param[in] pst            Post structure  
975  * @param[in] spId           Service Provider SAP ID 
976  * @param[in] discSdu        SDU discard Information 
977  *
978  * @return  S16
979  *    -# ROK 
980  *    -# RFAILED
981  */
982 #ifdef ANSI
983 PUBLIC S16 KwUiKwuDiscSduReq 
984 (
985 Pst              *pst,   
986 SpId             spId,  
987 KwuDiscSduInfo   *discSdu 
988 )
989 #else
990 PUBLIC S16 KwUiKwuDiscSduReq(pst, spId, discSdu)
991 Pst              *pst;   
992 SpId             spId;  
993 KwuDiscSduInfo   *discSdu; 
994 #endif
995 {
996    KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, discSdu, sizeof(KwuDiscSduInfo));
997    RETVALUE(ROK);
998
999
1000 /********************************************************************30**
1001          End of file
1002 **********************************************************************/