Committing in PDCP code
[o-du/l2.git] / src / 5gnrpdcp / pj_ul_utl.c
diff --git a/src/5gnrpdcp/pj_ul_utl.c b/src/5gnrpdcp/pj_ul_utl.c
new file mode 100755 (executable)
index 0000000..6c60117
--- /dev/null
@@ -0,0 +1,2844 @@
+/*******************************************************************************
+################################################################################
+#   Copyright (c) [2017-2019] [Radisys]                                        #
+#                                                                              #
+#   Licensed under the Apache License, Version 2.0 (the "License");            #
+#   you may not use this file except in compliance with the License.           #
+#   You may obtain a copy of the License at                                    #
+#                                                                              #
+#       http://www.apache.org/licenses/LICENSE-2.0                             #
+#                                                                              #
+#   Unless required by applicable law or agreed to in writing, software        #
+#   distributed under the License is distributed on an "AS IS" BASIS,          #
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
+#   See the License for the specific language governing permissions and        #
+#   limitations under the License.                                             #
+################################################################################
+*******************************************************************************/
+
+/**********************************************************************
+
+     Name:     LTE-PDCP Layer 
+  
+     Type:     C file
+  
+     Desc:     Source code for PDCP Utility Module
+
+               This file contains following functions:
+
+                  --PjLibObdCmpCfm
+                  --PjLibObdIntProtCfm
+                  --PjLibObdCipherCfm
+                  --PjLibObdDecipherCfm
+                  --PjLibObdIntVerCfm
+                  --PjLibObdDecmpCfm
+                  -- pjUtlCmpReq
+                  -- pjUtlCipherReq
+                  -- pjUtlIntProtReq
+  
+     File:     pj_ul_utl.c
+
+**********************************************************************/
+static const char* RLOG_MODULE_NAME="PDCP";
+static int RLOG_FILE_ID=251;
+static int RLOG_MODULE_ID=1024;
+
+/** @file gp_pj_utl.c
+@brief PDCP Utility Module 
+*/
+
+/* header (.h) include files */
+#include "envopt.h"        /* environment options */
+#include "envdep.h"        /* environment dependent */
+#include "envind.h"        /* environment independent */
+
+#include "gen.h"           /* general */
+#include "ssi.h"           /* system services */
+#include "cm5.h"           /* common timer defines */
+#include "cm_tkns.h"       /* common tokens defines */
+#include "cm_mblk.h"       /* common memory allocation library defines */
+#include "cm_llist.h"      /* common link list  defines  */
+#include "cm_hash.h"       /* common hash list  defines */
+#include "cm_lte.h"        /* common LTE defines */
+#include "cpj.h"                /* CPJ defines */
+#include "pju.h"                /* PJU defines */
+#include "lpj.h"                /* LPJ defines */
+
+#include "pj_env.h"        /* RLC environment options */
+#include "pj.h"            /* RLC defines */
+#include "pj_ul.h"
+#include "pj_dl.h"
+#include "pj_err.h"        /* Error defines */
+
+/* extern (.x) include files */
+#include "gen.x"           /* general */
+#include "ssi.x"           /* system services */
+
+#include "cm5.x"           /* common timer library */
+#include "cm_tkns.x"       /* common tokens */
+#include "cm_mblk.x"       /* common memory allocation */
+#include "cm_llist.x"      /* common link list */
+#include "cm_hash.x"       /* common hash list */
+#include "cm_lte.x"        /* common LTE includes */
+#include "cm_lib.x"        /* common memory allocation library */
+#include "cpj.x"                /* CPJ */
+#include "pju.x"                /* PJU */
+#include "lpj.x"                /* LPJ */
+#include "pj.x"
+#include "pj_udx.h"          /* LIB */
+#include "pj_udx.x"          /* LIB */
+#include "pj_ul.x"
+#include "pj_dl.x"
+#include "pj_lib.x"          /* LIB */
+
+#ifdef __cplusplus
+EXTERN "C" {
+#endif /* __cplusplus */
+
+PRIVATE S16 pjUtlUlHdlSecInitCfm ARGS((PjCb *gCb,PjUlUeCb *ueCb, 
+              U16 txIdx,PjAsyncCfm *asyncCfm, CpjSecCfgCfmInfo *secCfgCfm,CpjReEstCfmInfo *reEstCfm));
+PRIVATE S16 pjUtlUlHdlCmpInitCfm ARGS((PjCb *gCb,PjUlUeCb *ueCb, 
+              U16 txIdx,PjAsyncCfm *asyncCfm, CpjCfgCfmInfo *cfgCfm));
+#ifdef INTEL_SW_SEC
+EXTERN S16 PjLibObdSwDecipherReq(PjLibTrans *libTrans, Buffer *mBuf, PjCb *gCb, Buffer **opSdu);
+#endif
+/********************************************************************
+ *    Utility Handler for Sending to Offboarding unit               *
+ *******************************************************************/
+\f
+/**
+ *
+ * @brief 
+ *
+ *        Handler for opening the context with the compression unit (either 
+ *        synchronous or asynchronous) for RB within an UE.
+ *
+ * @b Description:
+ *
+ *        This function opens the context with the compression unit per RB per
+ *        UE, by sending ROHC configuration elements using synchronous / asynchronous 
+ *        function calls with relevant input parameters.
+ *
+ *
+ *  @param[in]  pjRbCb   PDCP RbCb
+ *
+ *  @return  S16
+ *      -# ROK 
+ *
+ */
+#ifdef ANSI
+PUBLIC S16 pjUtlUlCmpInit
+(
+PjCb       *gCb,
+PjUlRbCb   *pjRbCb                  /* PDCP RbCb */
+)
+#else
+PUBLIC S16 pjUtlUlCmpInit(pjRbCb)
+PjCb       *gCb;
+PjUlRbCb   *pjRbCb;                 /* PDCP RbCb */
+#endif
+{
+   TRC3(pjUtlUlCmpInit)
+
+   RLOG2(L_DEBUG, "pjUtlUlCmpInit(pjRbCb(%d,%d))",
+                    pjRbCb->rbId, pjRbCb->rbType);
+#ifdef PJ_CMP_ASYNC
+
+   pjRbCb->ueCb->libInfo.tCmpInitBitMask |= (1 << (pjRbCb->rbId - 1));
+   pjRbCb->ueCb->libInfo.tLibInitBitMask |= PJ_LIB_COMP_BIT_MASK;
+   pjRbCb->cmpCxt.cfgTxId  =  pjRbCb->ueCb->libInfo.nxtAvlbTxId;
+
+   PjLibObdCmpInitReq(&gCb->pjGenCfg.obdPst.cmpPst, 
+                                    pjRbCb->cmpCxt, pjRbCb->rohc);
+#else
+   pjLibCmpInitReq(pjRbCb->cmpCxt, pjRbCb->rohc, &(pjRbCb->cmpCxtId));
+#endif  /* PJ_CMP_ASYNC */
+
+   RETVALUE(ROK);
+
+} /* end of pjUtlCmpInit */
+\f
+
+
+/**
+ *
+ * @brief 
+ *
+ *        Handler for opening the context with the Integration unit (either 
+ *        synchronous or asynchronous) for all SRBs of an UE.
+ *
+ * @b Description:
+ *
+ *        This function opens the context with the security algo unit per UE
+ *        for Integration protection/verification by sending the configured
+ *        Integrity Info using synchronous / asynchronous function calls with 
+ *        relevant input parameters.
+ *
+ *  @param[in]  pjRbCb     Pointer to RB control Block
+ *
+ *
+ *  @return  S16
+ *      -# ROK 
+ *
+ */
+#ifdef ANSI
+PUBLIC S16 pjUtlUlIntInit
+(
+PjCb     *gCb,
+PjUlUeCb   *ueCb                   /* UE CB Ptr */
+)
+#else
+PUBLIC S16 pjUtlUlIntInit(ueCb)
+PjCb     *gCb;
+PjUlUeCb   *ueCb;                   /* UE CB Ptr */
+#endif
+{
+
+#ifndef PJ_SEC_ASYNC
+   Void *ctxId = NULL;   /* KW_FIX */
+#else
+   U8  txIdx;
+   U32 *libInitBitMask = NULLP;
+#endif
+   S32 ret=ROK;
+
+   TRC3(pjUtlUlIntInit)
+
+   RLOG2(L_DEBUG, "pjUtlUlIntInit(ueCb(%d,%d))",
+                    ueCb->key.ueId, ueCb->key.cellId);
+
+#ifdef PJ_SEC_ASYNC
+
+   if(ueCb->libInfo.state == PJ_STATE_REEST)
+   {
+      for(txIdx = 0; txIdx < PJ_MAX_ASYNC_CFM; txIdx++)
+      {
+         if((ueCb->libInfo.asyncCfm[txIdx] != NULLP) &&
+               (ueCb->libInfo.asyncCfm[txIdx]->cfmType == PJ_REEST_ASYNC_CFM))
+         {
+            libInitBitMask =  &ueCb->libInfo.asyncCfm[txIdx]->libInitBitMask;
+            break;
+         }
+      }
+   }
+   else if(ueCb->libInfo.state == PJ_STATE_NORMAL)
+   {
+      libInitBitMask =  &ueCb->libInfo.tLibInitBitMask;
+   }
+
+   if(libInitBitMask)
+   {
+      (*libInitBitMask) = (*libInitBitMask) | PJ_LIB_INT_BIT_MASK;
+   }
+
+   ret = PjLibObdIntInitReq(&gCb->pjGenCfg.obdPst.secPst, 
+                           ueCb->secInfo.secCxt, ueCb->secInfo.intInfo);
+#else
+#ifdef INTEL_QAT_DP
+#ifdef QAT_TWO_INSTNACES
+   pjLibIntInitReq(gCb->u.ulCb->instHndl, ueCb->secInfo.intInfo,&ctxId);
+#else
+   pjLibIntInitReq(gCb, ueCb->secInfo.intInfo,&ctxId);
+#endif
+   ueCb->secInfo.cpIntSessCxtId        =  ctxId;
+#else
+   pjLibIntInitReq(ueCb->secInfo.secCxt, ueCb->secInfo.intInfo,&(ctxId));
+   ueCb->secInfo.intCxtId    =  ctxId;
+#endif   
+#endif /* PJ_SEC_ASYNC */
+
+   RETVALUE(ret);
+
+} /* end of pjUtlIntInit */
+\f
+/**
+ *
+ * @brief 
+ *
+ *        Handler for opening the context with the Ciphering unit (either 
+ *        synchronous or asynchronous) for SRBs of an UE.
+ *
+ * @b Description:
+ *
+ *        This function opens the context with the security algo unit per UE
+ *        for ciphering / deciphering by key by sending the configured
+ *        Ciphering Info with control plane key using synchronous / asynchronous 
+ *        function calls with relevant input parameters.
+ *
+ *  @param[in]  pjRbCb     Pointer to RB control Block
+ *
+ *  @return  S16
+ *      -# ROK 
+ *
+ */
+#ifdef ANSI
+PUBLIC S16 pjUtlUlCpInit
+(
+PjCb     *gCb,
+PjUlUeCb   *ueCb                    /* UE CB Ptr */
+)
+#else
+PUBLIC S16 pjUtlUlCpInit(ueCb)
+PjCb     *gCb;
+PjUlUeCb   *ueCb;                   /* UE CB Ptr */
+#endif
+{
+
+#ifndef PJ_SEC_ASYNC
+   Void *ctxId = NULL;       /* KW_FIX */
+#else
+   U8  txIdx;
+   U32 *libInitBitMask = NULLP;
+#endif
+   S16   ret = ROK;
+
+   TRC3(pjUtlUlCpInit)
+
+   RLOG2(L_DEBUG, "pjUtlCpInit(ueCb(%d,%d))",
+                    ueCb->key.ueId, ueCb->key.cellId);
+
+#ifdef PJ_SEC_ASYNC
+
+   if(ueCb->libInfo.state == PJ_STATE_REEST)
+   {
+      for(txIdx = 0; txIdx < PJ_MAX_ASYNC_CFM; txIdx++)
+      {
+         if((ueCb->libInfo.asyncCfm[txIdx] != NULLP) &&
+               (ueCb->libInfo.asyncCfm[txIdx]->cfmType == PJ_REEST_ASYNC_CFM))
+         {
+            libInitBitMask =  &ueCb->libInfo.asyncCfm[txIdx]->libInitBitMask;
+            break;
+         }
+      }
+   }
+   else if(ueCb->libInfo.state == PJ_STATE_NORMAL)
+   {
+      libInitBitMask =  &ueCb->libInfo.tLibInitBitMask;
+   }
+
+   if(libInitBitMask)
+   {
+      (*libInitBitMask) = (*libInitBitMask) | PJ_LIB_CP_CIP_BIT_MASK;
+   }
+   ret = PjLibObdCpInitReq(&gCb->pjGenCfg.obdPst.secPst, ueCb->secInfo.secCxt, 
+         ueCb->secInfo.cipherInfo.algoType, ueCb->secInfo.cipherInfo.cpKey);
+#else
+#ifdef INTEL_QAT_DP
+#ifdef QAT_TWO_INSTANCE
+   ret = pjLibCpInitReq(gCb->u.ulCb->instHndl, ueCb->secInfo.secCxt, ueCb->secInfo.cipherInfo.algoType,
+                  ueCb->secInfo.cipherInfo.cpKey, &ctxId);
+#else
+   ret = pjLibCpInitReq(gCb, ueCb->secInfo.secCxt, ueCb->secInfo.cipherInfo.algoType,
+                  ueCb->secInfo.cipherInfo.cpKey, &ctxId);
+#endif
+   ueCb->secInfo.cpCiphSessCxtId = ctxId;
+#else
+   ret = pjLibCpInitReq(ueCb->secInfo.secCxt, (U8)ueCb->secInfo.cipherInfo.algoType,
+                  ueCb->secInfo.cipherInfo.cpKey, &ctxId);  /*KW_FIX*/
+   ueCb->secInfo.cpCxtId = ctxId;
+#endif /* INTEL_QAT_DP */
+#endif /* PJ_SEC_ASYNC */
+
+   RETVALUE(ret);
+
+} /* end of pjUtlCpInit */
+
+/**
+ *
+ * @brief 
+ *
+ *        Handler for opening the context with the Ciphering unit (either 
+ *        synchronous or asynchronous) for DRBs of an UE.
+ *
+ * @b Description:
+ *
+ *        This function opens the context with the security algo unit per UE
+ *        for ciphering / deciphering by sending the configured
+ *        Ciphering Info with user plane key using synchronous / asynchronous 
+ *        function calls with relevant input parameters.
+ *
+ *  @param[in]  pjRbCb     Pointer to RB control Block
+ *
+ *  @return  S16
+ *      -# ROK 
+ *
+ */
+#ifdef ANSI
+PUBLIC S16 pjUtlUlUpInit
+(
+PjCb     *gCb,
+PjUlUeCb   *ueCb                    /* UE CB Ptr */
+)
+#else
+PUBLIC S16 pjUtlUpInit(gCb,ueCb)
+PjCb     *gCb;
+PjUlUeCb   *ueCb;                   /* UE CB Ptr */
+#endif
+{
+
+#ifndef PJ_SEC_ASYNC
+   Void* ctxId = NULL;  /* KW_FIX */
+#else
+   U8  txIdx;
+   U32 *libInitBitMask = NULLP;
+#endif
+
+   TRC3(pjUtlUlUpInit)
+
+   RLOG2(L_DEBUG, "pjUtlUpInit(ueCb(%d,%d))",
+                    ueCb->key.ueId, ueCb->key.cellId);
+
+#ifdef PJ_SEC_ASYNC
+
+   if(ueCb->libInfo.state == PJ_STATE_REEST)
+   {
+      for(txIdx = 0; txIdx < PJ_MAX_ASYNC_CFM; txIdx++)
+      {
+         if((ueCb->libInfo.asyncCfm[txIdx] != NULLP) &&
+               (ueCb->libInfo.asyncCfm[txIdx]->cfmType == PJ_REEST_ASYNC_CFM))
+         {
+            libInitBitMask =  &ueCb->libInfo.asyncCfm[txIdx]->libInitBitMask;
+            break;
+         }
+      }
+   }
+   else if(ueCb->libInfo.state == PJ_STATE_NORMAL)
+   {
+      libInitBitMask =  &ueCb->libInfo.tLibInitBitMask;
+   }
+
+   if(libInitBitMask)
+      (*libInitBitMask) = (*libInitBitMask) | PJ_LIB_UP_CIP_BIT_MASK;
+
+   ret = PjLibObdUpInitReq(&gCb->pjGenCfg.obdPst.secPst, ueCb->secInfo.secCxt, 
+         ueCb->secInfo.cipherInfo.algoType, ueCb->secInfo.cipherInfo.upKey);
+#else
+#ifdef INTEL_QAT_DP
+#ifdef QAT_TWO_INSTANCE
+   pjLibUpInitReq(gCb->u.ulCb->instHndl, ueCb->secInfo.secCxt, ueCb->secInfo.cipherInfo.algoType, 
+                              ueCb->secInfo.cipherInfo.upKey, &ctxId);
+#else
+   pjLibUpInitReq(gCb, ueCb->secInfo.secCxt, ueCb->secInfo.cipherInfo.algoType, 
+                              ueCb->secInfo.cipherInfo.upKey, &ctxId);
+#endif
+   ueCb->secInfo.upCiphSessCxtId= ctxId; 
+#else
+   pjLibUpInitReq(ueCb->secInfo.secCxt, (U8)ueCb->secInfo.cipherInfo.algoType, 
+                              ueCb->secInfo.cipherInfo.upKey, &ctxId); /*KW_FIX*/
+   ueCb->secInfo.upCxtId = ctxId;
+#endif /* INTEL_QAT_DP */
+#endif /* PJ_SEC_ASYNC */
+
+   RETVALUE(ROK);
+
+} /* end of pjUtlUpInit */
+
+
+/**
+ *
+ * @brief 
+ *
+ *        Handler for resetting the context with the compression unit (either 
+ *        synchronous or asynchronous) for RB within an UE.
+ *
+ * @b Description:
+ *
+ *        This function resets the context with the compression unit per RB per
+ *        UE by using synchronous / asynchronous function calls.
+ *
+ *
+ *  @param[in] cmpCxtId     Context to be reset for compression 
+ *
+ *  @return  S16
+ *      -# ROK 
+ *
+ */
+#ifdef ANSI
+PUBLIC S16 pjUtlUlCmpReset
+(
+PjCb        *gCb,
+PjUlRbCb      *pjRbCb                 /* Context to be reset for compression */
+)
+#else
+PUBLIC S16 pjUtlUlCmpReset(pjRbCb)
+PjCb        *gCb;
+PjUlRbCb      *pjRbCb;                 /* Context to be reset for compression */
+#endif
+{
+   TRC3(pjUtlUlCmpReset)
+
+   RLOG2(L_DEBUG, "pjUtlUlCmpReset(pjRbCb(%d,%d))",
+                    pjRbCb->rbId, pjRbCb->rbType);
+
+#ifdef PJ_CMP_ASYNC
+   PjLibObdCmpResetReq(&gCb->pjGenCfg.obdPst.cmpPst, pjRbCb->cmpCxtId);
+#else
+   pjLibCmpResetReq(pjRbCb->cmpCxtId);
+#endif
+
+   RETVALUE(ROK);
+
+} /* end of pjUtlCmpReset */
+
+
+/**
+ *
+ * @brief 
+ *
+ *        Handler for closing the UL context with the Ciphering unit (either 
+ *        synchronous or asynchronous) for SRBs of an UE.
+ *
+ * @b Description:
+ *
+ *        This function closes an existing UL context with the security algo unit per UE
+ *        for ciphering / deciphering with control plane key using synchronous / asynchronous 
+ *        function calls with relevant input parameters.
+ *
+ *
+ *  @param[in] cpCxtId          Context Id for Ciphering to be closed 
+ *
+ *  @return  S16
+ *      -# ROK 
+ *
+ */
+#ifdef ANSI      
+PUBLIC S16 pjUtlUlCipherClose
+(
+PjCb     *gCb,
+Void      *cpCxtId                  /* Context Id for Ciphering to be closed */
+)
+#else
+PUBLIC S16 pjUtlUlCipherClose(cpCxtId)
+PjCb     *gCb;
+Void     *cpCxtId;                 /* Context Id for Ciphering to be closed */
+#endif
+{
+   S16   ret = ROK;
+   TRC3(pjUtlUlCipherClose)
+   RLOG0(L_DEBUG, "pjUtlUlCipherClose");
+#ifndef PJ_SEC_ASYNC
+#ifdef INTEL_QAT_DP
+#ifdef QAT_TWO_INSTANCE
+   ret = PjLibObdCipherCloseReq(gCb->u.ulCb->instHndl, cpCxtId);
+#else
+   ret = PjLibObdCipherCloseReq(gCb->instHndl, cpCxtId); 
+#endif
+#else
+   PjLibObdCipherCloseReq(cpCxtId);
+#endif
+#else
+#ifdef INTEL_QAT_DP
+#ifdef QAT_TWO_INSTANCE
+   ret = PjLibObdCipherCloseReq(gCb->u.ulCb->instHndl, cpCxtId);
+#else
+   ret = PjLibObdCipherCloseReq(gCb->instHndl, cpCxtId); 
+#endif
+#else
+   PjLibObdCipherCloseReq(&gCb->pjGenCfg.obdPst.secPst, cpCxtId);
+#endif
+#endif
+   RETVALUE(ret);
+} /* end of pjUtlCipherClose */
+/**
+ *
+ * @brief 
+ *
+ *        Handler for closing the UL context with the Integration unit (either 
+ *        synchronous or asynchronous) for all RBs of an UE.
+ *
+ * @b Description:
+ *
+ *        This function closes an existing UL context with the security algo unit per UE
+ *        for Integration protection/verification using synchronous / asynchronous function 
+ *        calls with relevant input parameters.
+ *
+ *
+ *  @param[in] intCxtId        Integration CxtId to be closed 
+ *
+ *  @return  S16
+ *      -# ROK 
+ *
+ */
+#ifdef ANSI   
+PUBLIC S16 pjUtlUlIntClose
+(
+PjCb     *gCb,
+Void      *intCxtId                 /* Integration CxtId to be closed */
+)
+#else
+PUBLIC S16 pjUtlUlIntClose(intCxtId)
+PjCb     *gCb;
+Void     *intCxtId;                /* Integration CxtId to be closed */
+#endif
+{
+   S16   ret = ROK;
+   TRC3(pjUtlUlIntClose)
+   RLOG0(L_DEBUG, "pjUtlUlIntClose");
+   
+#ifdef TENB_AS_SECURITY
+#ifdef INTEL_QAT_DP
+#ifdef QAT_TWO_INSTANCE
+   ret = PjLibObdIntCloseReq(gCb->u.ulCb->instHndl,intCxtId);
+#else
+   ret = PjLibObdIntCloseReq(gCb->instHndl,intCxtId);
+#endif
+#endif
+#else
+#ifdef PJ_SEC_ASYNC
+   PjLibObdIntCloseReq(&gCb->pjGenCfg.obdPst.secPst,intCxtId);
+#else   
+   PjLibObdIntCloseReq(intCxtId);
+#endif
+#endif
+   RETVALUE(ret);
+} /* end of pjUtlIntClose */
+
+/**
+ *
+ * @brief 
+ *
+ *        Handler for redirecing deciphering request to either synchronous
+ *        or asynchronous module.
+ *
+ * @b Description:
+ *
+ *        This function sends deciphering request as either synchronous or
+ *        asynchronous function calls with relevant input parameters.
+ *
+ *  @param[in]   pjRbCb           PDCP RbCb 
+ *  @param[in]   secInp           Input parameters for deciphering 
+ *  @param[in]   mBuf             Data to be deciphered 
+ *  @param[in]   opSdu            Deciphered SDU 
+ *
+ *  @return  S16
+ *      -# ROK 
+ *
+ */
+/* Uday */
+#ifdef TENB_AS_SECURITY
+#ifdef ANSI
+PUBLIC S16 pjUtlDecipherReq
+(
+PjCb       *gCb,
+PjUlRbCb   *pjRbCb,                 /* PDCP RbCb */
+U32        count,
+Buffer     *mBuf,                    /* Data to be deciphered */
+Buffer   **opSdu                  /* Deciphered SDU */
+)
+#else
+PUBLIC S16 pjUtlDecipherReq(gCb, pjRbCb, count, mBuf, opSdu)
+PjCb       *gCb;
+PjUlRbCb   *pjRbCb;                 /* PDCP RbCb */
+U32        count;
+Buffer     *mBuf;                   /* Data to be deciphered */
+Buffer   **opSdu;                  /* Deciphered SDU */
+#endif
+{
+   S16 ret = ROK;
+   PjUlUeCb *ulUeCb;
+   PjLibTrans  libTrans;
+#ifdef PJ_SEC_ASYNC
+   Void      *cxtId = NULLP;    /* Context Identifier */
+#endif
+   TRC3(pjUtlDecipherReq)
+
+#ifdef PJ_SEC_ASYNC
+   if (pjRbCb->rbType == PJ_SRB)
+   {
+      cxtId = pjRbCb->ueCb->secInfo.cpCxtId;
+   }
+   else
+   {
+      cxtId = pjRbCb->ueCb->secInfo.upCxtId;
+   } 
+#endif
+   ulUeCb = pjRbCb->ueCb;
+   libTrans.pdcpInstance = gCb->init.inst;
+   libTrans.count = count;
+   libTrans.rbId = pjRbCb->rbId - 1;
+   libTrans.dir = PJ_SEC_DIR_UL;
+   libTrans.rbType = pjRbCb->rbType;
+   libTrans.snLen = pjRbCb->snLen;
+   libTrans.ciphAlgoType = ulUeCb->secInfo.cipherInfo.algoType;
+   libTrans.ueCb = (PTR)ulUeCb;
+   libTrans.ueId = ulUeCb->key.ueId;
+   libTrans.cellId = ulUeCb->key.cellId;
+   if(PJ_SRB == pjRbCb->rbType)
+   {
+      libTrans.key = ulUeCb->secInfo.cipherInfo.cpKey;
+#ifdef INTEL_QAT_DP
+      libTrans.sessCxtId = ulUeCb->secInfo.cpCiphSessCxtId;
+#ifdef QAT_TWO_INSTANCE
+      libTrans.instHndl = gCb->u.ulCb->instHndl;
+#else
+      libTrans.instHndl = gCb->instHndl;
+#endif
+#endif
+   }
+   else
+   {
+      libTrans.key = ulUeCb->secInfo.cipherInfo.upKey;
+#ifdef INTEL_QAT_DP
+      libTrans.sessCxtId = ulUeCb->secInfo.upCiphSessCxtId;
+#ifdef QAT_TWO_INSTANCE
+      libTrans.instHndl = gCb->u.ulCb->instHndl;
+#else
+      libTrans.instHndl = gCb->instHndl;
+#endif
+#endif
+   }
+   
+#ifdef PJ_SEC_ASYNC
+   /* Start the timer if it is not started already */
+   if((pjChkTmr(gCb,(PTR)pjRbCb, PJ_EVT_UL_OBD_TMR)) == FALSE)
+   {
+      pjRbCb->ulCb.obdPdu   =  secInp.count;
+      pjStartTmr(gCb,(PTR)pjRbCb, PJ_EVT_UL_OBD_TMR);
+   }
+   ret = PjLibObdDecipherReq(&(gCb->pjGenCfg.obdPst.secPst), 
+                                 cxtId, secInp, libTrans, mBuf);  
+#else
+#ifdef INTEL_QAT_DP
+    /* TODO: 3rd arg is unused can be removed */
+       ret = PjLibObdDecipherReq(&libTrans, mBuf, opSdu);
+#else
+#ifndef INTEL_SW_SEC
+   ret = PjLibObdDecipherReq(&libTrans, mBuf, opSdu);
+#else
+   ret = PjLibObdSwDecipherReq(&libTrans, mBuf, gCb,opSdu);
+#endif
+#endif
+#endif
+   RETVALUE(ret);
+} /* end of pjUtlDecipherReq */
+#else
+#ifdef ANSI
+PUBLIC S16 pjUtlDecipherReq
+(
+PjCb       *gCb,                  /* Cell Cb */
+PjUlRbCb   *pjRbCb,                 /* PDCP RbCb */
+U32        count,
+Buffer   *mBuf,                   /* Data to be deciphered */
+Buffer   **opSdu                  /* Deciphered SDU */
+)
+#else
+PUBLIC S16 pjUtlDecipherReq(gCb, pjRbCb, count, mBuf, opSdu)
+PjCb       *gCb;
+PjUlRbCb   *pjRbCb;                 /* PDCP RbCb */
+U32        count;
+Buffer   *mBuf;                   /* Data to be deciphered */
+Buffer   **opSdu;                 /* Deciphered SDU */
+#endif
+{
+   S16 ret = ROK;
+#ifdef PJ_SEC_ASYNC
+   PjLibTrans libTrans; /* Transaction Id for deciphering */
+#else
+   PjSecInp   secInp;
+#endif /* PJ_SEC_ASYNC */
+   PTR        cxtId;    /* Context Identifier */
+   TRC3(pjUtlDecipherReq)
+   if (pjRbCb->rbType == PJ_SRB)
+   {
+      cxtId = (PTR)pjRbCb->ueCb->secInfo.cpCxtId;
+   }
+   else
+   {
+      cxtId = (PTR)pjRbCb->ueCb->secInfo.upCxtId;
+   } 
+#ifdef PJ_SEC_ASYNC
+   /* Assign transId and cxtId */
+   libTrans.count  = count;
+   /* kw005.201 ccpu00114955 corrected the RB ID calculation */
+   libTrans.rbId   = pjRbCb->rbId - 1;
+   libTrans.rbType = pjRbCb->rbType;
+   libTrans.ueCb   = pjRbCb->ueCb;
+   /* Start the timer if it is not started already */
+   if((pjChkTmr(gCb,(PTR)pjRbCb, PJ_EVT_UL_OBD_TMR)) == FALSE)
+   {
+      pjRbCb->ulCb.obdPdu   =  secInp.count;
+      pjStartTmr(gCb,(PTR)pjRbCb, PJ_EVT_UL_OBD_TMR);
+   }
+   ret = PjLibObdDecipherReq(&gCb->pjGenCfg.obdPst.secPst, 
+                                 cxtId, secInp, libTrans, mBuf);  
+#else
+   secInp.count = count;
+   secInp.rbId  = pjRbCb->rbId - 1;
+   secInp.dir = 0;
+   ret = pjLibDecipherReq(cxtId, secInp, mBuf, opSdu);
+#endif
+   RETVALUE(ret);
+} /* end of pjUtlDecipherReq */
+#endif
+/**
+ *
+ * @brief 
+ *
+ *        Handler for redirecing Integration request to either synchronous
+ *        or asynchronous module.
+ *
+ * @b Description:
+ *
+ *        This function sends Intergrity verification request as either synchronous or
+ *        asynchronous function calls with relevant input parameters.
+ *
+ *  @param[in]   pjRbCb        PDCP RbCb 
+ *  @param[in]   secInp        Input parameters for integrity 
+ *  @param[in]   mBuf          SDU to be compressed 
+ *  @param[out]  status        Integrity verification status 
+ *
+ *  @return  S16
+ *      -# ROK 
+ *
+ */
+#ifdef TENB_AS_SECURITY
+#ifdef ANSI
+PUBLIC S16 pjUtlIntVerReq
+(
+PjCb     *gCb,
+PjUlRbCb   *pjRbCb,                 /* PDCP RbCb */
+PjSecInp secInp ,                 /* Input parameters for integrity */ 
+Buffer   *mBuf,                   /* SDU to be compressed */
+U32      macI,                    /* MAC-I to be verified with */
+Status   *status                  /* Integrity verification status */
+)
+#else
+PUBLIC S16 pjUtlIntVerReq(pjRbCb, secInp, mBuf, macI, status)
+PjCb     *gCb;
+PjUlRbCb   *pjRbCb;                 /* PDCP RbCb */
+PjSecInp secInp;                 /* Input parameters for integrity */ 
+Buffer   *mBuf;                   /* SDU to be compressed */
+U32      macI;                    /* MAC-I to be verified with */
+Status   *status;                 /* Integrity verification status */
+#endif
+{
+   S16 ret = ROK;
+   PjUlUeCb *ulUeCb;
+   PjLibTrans  libTrans;
+#ifdef PJ_SEC_ASYNC
+   Void       *cxtId;    /* Context Identifier */
+#endif
+   TRC3(pjUtlIntVerReq)
+
+#ifdef PJ_SEC_ASYNC
+   cxtId = pjRbCb->ueCb->secInfo.intCxtId;
+#endif
+   ulUeCb = pjRbCb->ueCb;
+   libTrans.pdcpInstance = gCb->init.inst;
+   libTrans.count = secInp.count;
+   libTrans.rbId = pjRbCb->rbId - 1;
+   libTrans.dir = secInp.dir;
+   libTrans.rbType = pjRbCb->rbType;
+   libTrans.intAlgoType = ulUeCb->secInfo.intInfo.algoType;
+   libTrans.ueCb = (PTR)ulUeCb;
+   libTrans.ueId = ulUeCb->key.ueId;
+   libTrans.cellId = ulUeCb->key.cellId;
+   libTrans.key = (U8*)&ulUeCb->secInfo.intInfo.intKey[0];
+   PJ_SEC_FILL_FRESH(libTrans.fresh, libTrans.rbId);
+
+#ifdef INTEL_QAT_DP
+   libTrans.sessCxtId = ulUeCb->secInfo.cpIntSessCxtId;
+#ifdef QAT_TWO_INSTANCE
+   libTrans.instHndl = gCb->u.ulCb->instHndl;
+#else
+   libTrans.instHndl = gCb->instHndl;
+#endif
+#endif
+#ifdef PJ_SEC_ASYNC
+   /* Start the timer if it is not started already */
+   if((pjChkTmr(gCb, (PTR)pjRbCb, PJ_EVT_UL_OBD_TMR)) == FALSE)
+   {
+      pjRbCb->ulCb.obdPdu   =  secInp.count;
+      pjStartTmr(gCb, (PTR)pjRbCb, PJ_EVT_UL_OBD_TMR);
+   }
+   ret = PjLibObdIntVerReq(&(gCb->pjGenCfg.obdPst.secPst), cxtId, 
+                                       secInp, libTrans, mBuf, macI);  
+#else
+#ifdef INTEL_SW_INTEG
+   ret = PjLibObdIntVerReq(gCb, &libTrans, mBuf, macI);
+#else
+   ret = PjLibObdIntVerReq(&libTrans, mBuf, macI);
+#endif
+#endif
+   RETVALUE(ret);
+
+} /* end of pjUtlIntVerReq */
+#else
+#ifdef ANSI
+PUBLIC S16 pjUtlIntVerReq
+(
+PjCb     *gCb,
+PjUlRbCb   *pjRbCb,                 /* PDCP RbCb */
+PjSecInp secInp ,                 /* Input parameters for integrity */ 
+Buffer   *mBuf,                   /* SDU to be compressed */
+U32      macI,                    /* MAC-I to be verified with */
+Status   *status                  /* Integrity verification status */
+)
+#else
+PUBLIC S16 pjUtlIntVerReq(gCb, pjRbCb, secInp, mBuf, macI, status)
+PjCb     *gCb;
+PjUlRbCb   *pjRbCb;                 /* PDCP RbCb */
+PjSecInp secInp;                 /* Input parameters for integrity */ 
+Buffer   *mBuf;                   /* SDU to be compressed */
+U32      macI;                    /* MAC-I to be verified with */
+Status   *status;                 /* Integrity verification status */
+#endif
+{
+   S16 ret = ROK;
+#ifdef PJ_SEC_ASYNC
+   PjLibTrans libTrans; /* Transaction Id for deciphering */
+#endif /* PJ_SEC_ASYNC */
+   PTR cxtId;    /* Context Identifier */
+
+   TRC3(pjUtlIntVerReq)
+
+   cxtId = (PTR)pjRbCb->ueCb->secInfo.intCxtId;
+
+#ifdef PJ_SEC_ASYNC
+   /* Assign transId and cxtId */
+   libTrans.count  = secInp.count;
+   libTrans.rbId   = pjRbCb->rbId - 1;
+   libTrans.rbType = pjRbCb->rbType;
+   libTrans.ueCb   = pjRbCb->ueCb;
+
+   /* Start the timer if it is not started already */
+   if((pjChkTmr(gCb,(PTR)pjRbCb, PJ_EVT_UL_OBD_TMR)) == FALSE)
+   {
+      pjRbCb->ulCb.obdPdu   =  secInp.count;
+      pjStartTmr(gCb,(PTR)pjRbCb, PJ_EVT_UL_OBD_TMR);
+   }
+
+   ret = PjLibObdIntVerReq(&gCb->pjGenCfg.obdPst.secPst, cxtId, 
+                                       secInp, libTrans, mBuf, macI);  
+#else
+   /* ccpu00142570 */
+   ret = pjLibIntVerReq(cxtId, secInp, mBuf, macI, status);
+#endif
+
+   RETVALUE(ret);
+
+} /* end of pjUtlIntVerReq */
+#endif
+
+
+
+
+/**
+ *
+ * @brief 
+ *
+ *        Utility function that processes the CfgReq with type as
+ *        REESTABLISH sent from RRC.
+ *
+ * @b Description:
+ *
+ *        This function 
+ *        1. Marks the state of the RBs as PJ_STATE_REEST.
+ *        2. Calculates the number of RBs undergoing reestablishment.
+ *
+ *  @param[in] ueCb     UE Control Block Pointer.
+ *  @param[in] numEnt   Number of entities undergoing reestablishment
+ *  @param[in] cfgEnt   List of entities configured.
+ *
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED
+ *
+ */
+#ifdef ANSI
+PUBLIC S16 pjUtlUlReEstSrb1
+(
+PjCb       *gCb,
+PjUlRbCb   *pjRbCb                    /* PDCP Control Block Pointer */
+)
+#else
+PUBLIC S16 pjUtlUlReEstSrb1(pjRbCb)
+PjCb       *gCb;
+PjUlRbCb   *pjRbCb;                   /* PDCP Control Block Pointer */
+#endif
+{
+   PjUlUeCb   *ueCb;
+
+   TRC2(pjUtlReEstSrb1)
+
+   RLOG2(L_DEBUG, "pjUtlReEstSrb1(pjRbCb(%d,%d))",
+                    pjRbCb->rbId, pjRbCb->rbType);
+
+   ueCb     = pjRbCb->ueCb;
+
+   ueCb->libInfo.state  =  PJ_STATE_REEST;
+
+   /* SRB Reconfiguration we can update the control Plane keys and
+      the Integrity Keys in the OBD module */
+
+   pjUtlUlUpdCpSecKeys(gCb,ueCb);
+
+   /* Perform  uplink reestablishment of SRB1 */
+   pjUlmReEstSrb(gCb,pjRbCb);
+
+   /* Start security reconfiguration if SRB1 is the only RB */
+   if ((ueCb->numSrbs == 1) && (ueCb->numDrbs == 0))
+   {
+     pjUtlUlUpdUpSecKeys(gCb,ueCb);
+   }
+
+   RETVALUE(ROK);
+} /* pjUtlReEstSrb1 */
+\f
+/**
+ *
+ * @brief 
+ *
+ *        Handler to start reestablishment processing
+ *
+ * @b Description:
+ *
+ *        This function 
+ *        1. Marks the state of the RBs as PJ_STATE_REEST_HO.
+ *        2. Calculates the number of RBs undergoing reestablishment.
+ *
+ *  @param[in] ueCb    Number of RBs undergoing reestablishment
+ *
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED
+ *
+ */
+#ifdef ANSI
+PUBLIC S16 pjUtlUlReEstHO
+(
+PjCb          *gCb,
+PjUlUeCb      *ueCb           /* Number of RBs undergoing reestablishment*/ 
+)
+#else
+PUBLIC S16 pjUtlUlReEstHO(gCb,ueCb) 
+PjCb          *gCb;
+PjUlUeCb      *ueCb;           /* Number of RBs undergoing reestablishment*/ 
+#endif
+{
+   U8             rbCnt;
+   PjUlRbCb     **rbCbLst;
+   PjUlRbCb      *pjRbCb;
+
+   TRC2(pjUtlUlReEstHO); 
+
+#ifdef ALIGN_64BIT
+   RLOG2(L_DEBUG, "pjUtlReEstHOStart(ueCb(%d,%d)))",
+                ueCb->key.ueId, ueCb->key.cellId);
+#else
+   RLOG2(L_DEBUG, "pjUtlReEstHOStart(ueCb(%d,%d))",
+                ueCb->key.ueId, ueCb->key.cellId);
+#endif
+
+   /* Perform initialisations on the HO Info structure */
+   PJ_ALLOC(gCb,ueCb->hoInfo, sizeof(PjUlHoInfo));
+#if (ERRCLASS & ERRCLS_ADD_RES)
+   if (ueCb->hoInfo == NULLP)
+   {
+      RLOG0(L_FATAL, "Memory Allocation failed.");
+      RETVALUE(RFAILED);
+   }
+#endif /* ERRCLASS & ERRCLS_ADD_RES */
+   PJ_ALLOC(gCb,ueCb->hoInfo->hoCfmInfo, 
+              sizeof(PjUlHoCfmInfo) *  PJ_MAX_DRB_PER_UE );
+#if (ERRCLASS & ERRCLS_ADD_RES)
+   if (ueCb->hoInfo->hoCfmInfo == NULLP )
+   {
+      RLOG0(L_FATAL, "Memory Allocation failed.");
+      /*ccpu00136858 */      
+      PJ_PST_FREE(gCb->u.ulCb->cpjSap.pst.region, gCb->u.ulCb->cpjSap.pst.pool, ueCb->hoInfo, sizeof(PjUlHoInfo));
+      RETVALUE(RFAILED);
+   }
+#endif /* ERRCLASS & ERRCLS_ADD_RES */
+   /* Initialise the reestablishment states for the RBs */
+   rbCbLst      = ueCb->drbCb;
+   for(rbCnt = 0; rbCnt < PJ_MAX_DRB_PER_UE; rbCnt ++)
+   {
+      /* Check of rbCb available */
+      if( (pjRbCb = rbCbLst[rbCnt]) == NULLP)
+      {
+         continue;
+      }
+      /* Fetch the rbCb and intialise the states */
+      pjRbCb->state  =  PJ_STATE_REEST_HO;
+      ueCb->libInfo.numReEstDrb++;
+
+#if (defined(PJ_SEC_ASYNC) || defined (PJ_CMP_ASYNC))
+       pjRbCb->ulCb.obdCnt   = 0;
+       pjRbCb->ulCb.transCmp = 0;
+       if(pjRbCb->mode == PJ_DRB_AM)
+       {
+          pjRbCb->ulCb.firstReEstCnt   =   pjRbCb->ulCb.rxDeliv;
+       }
+#endif /* (defined(PJ_SEC_ASYNC) || defined (PJ_CMP_ASYNC)) */
+
+   }/* for(rbCnt .. */ 
+
+   RETVALUE(ROK);
+
+} /* pjUtlReEstHOStart */
+
+/**
+ *
+ * @brief 
+ *
+ *        Handler to apply the new security algorithms and 
+ *        reset the compression unit.
+ *
+ * @b Description:
+ *
+ *        This function 
+ *        1. Creates new contexts for Control Plane Ciphering and Integrity.
+ *        2. Closes the old contexts for Control Plane Ciphering and Integrity.
+ *
+ *  @param[in] ueCb   UE Control Block
+ *
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED
+ *
+ */
+#ifdef ANSI
+PUBLIC S16 pjUtlUlUpdUpSecKeys
+(
+PjCb       *gCb,
+PjUlUeCb   *ueCb           /* UE Control Block */ 
+)
+#else
+PUBLIC S16 pjUtlUlUpdUpSecKeys(gCb,ueCb)
+PjCb         *gCb;
+PjUlUeCb     *ueCb;           /* UE Control Block */ 
+#endif
+{
+   Void     *tmpUpCxt;
+
+   TRC2(pjUtlUlUpdUpSecKeys);
+
+   RLOG2(L_DEBUG, "pjUtlUlUpdUpSecKeys(ueCb(%d,%d))",
+                ueCb->key.ueId, ueCb->key.cellId);
+
+   if(ueCb->secInfo.secAct == TRUE)
+   {
+      /* Initialisation is done first followed by closure since we
+       * do not want the same ctxId to be returned for the new init.
+       * In ASYNC case, we drop packets if they are returned from a
+       * different ctxId. */
+
+#ifdef INTEL_QAT_DP
+      tmpUpCxt  = ueCb->secInfo.upCiphSessCxtId; 
+#else
+      tmpUpCxt  = ueCb->secInfo.upCxtId; 
+#endif
+      pjUtlUlUpInit(gCb,ueCb);
+      pjUtlUlCipherClose(gCb,tmpUpCxt);
+   }
+
+   RETVALUE(ROK);
+} /* pjUtlUlUpdUpSecKeys */
+
+/**
+ *
+ * @brief 
+ *
+ *        Handler to apply the new security algorithms and 
+ *        reset the compression unit.
+ *
+ * @b Description:
+ *
+ *        This function 
+ *        1. Creates new contexts for Control Plane Ciphering and Integrity.
+ *        2. Closes the old contexts for Control Plane Ciphering and Integrity.
+ *
+ *  @param[in] ueCb   UE Control Block
+ *
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED
+ *
+ */
+#ifdef ANSI
+PUBLIC S16 pjUtlUlUpdCpSecKeys
+(
+PjCb       *gCb,
+PjUlUeCb   *ueCb           /* UE Control Block */ 
+)
+#else
+PUBLIC S16 pjUtlUlUpdCpSecKeys(gCb,ueCb)
+PjCb         *gCb;
+PjDlUeCb     *ueCb;           /* UE Control Block */ 
+#endif
+{
+   Void     *tmpIntCxt;
+   Void     *tmpCpCxt;
+
+   TRC2(pjUtlDlUpdCpSecKeys);
+
+   RLOG2(L_DEBUG, "pjUtlUlUpdCpSecKeys(ueCb(%d,%d))",
+                ueCb->key.ueId, ueCb->key.cellId);
+
+   if(ueCb->secInfo.secAct == TRUE)
+   {
+      /* Initialisation is done first followed by closure since we
+       * do not want the same ctxId to be returned for the new init.
+       * In ASYNC case, we drop packets if they are returned from a
+       * different ctxId. */
+#ifdef INTEL_QAT_DP
+      tmpIntCxt = ueCb->secInfo.cpIntSessCxtId;  
+      tmpCpCxt  = ueCb->secInfo.cpCiphSessCxtId;         
+
+#else
+      tmpIntCxt = ueCb->secInfo.intCxtId;  
+      tmpCpCxt  = ueCb->secInfo.cpCxtId;    
+#endif
+
+      pjUtlUlCpInit(gCb,ueCb);
+      pjUtlUlIntInit(gCb,ueCb);
+
+      pjUtlUlIntClose(gCb,tmpIntCxt);
+      pjUtlUlCipherClose(gCb,tmpCpCxt);
+   }
+
+   RETVALUE(ROK);
+} /* pjUtlDlUpdCpSecKeys */
+
+/**
+ *
+ * @brief 
+ *
+ *        Function to handle the REESTABLISHMENT COMPLETE 
+ *        for each uplink RB
+ *
+ * @b Description:
+ *
+ *        This function 
+ *
+ *  @param[in] ueCb   UE Control Block
+ *
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED
+ *
+ */
+#ifdef ANSI
+PUBLIC S16 pjUtlUlHdlRbReEstComplete
+(
+PjCb         *gCb,
+PjUlRbCb     *pjRbCb           /*RB Control Block */ 
+)
+#else
+PUBLIC S16 pjUtlUlHdlRbReEstComplete(ueCb, pjRbCb)
+PjCb         *gCb;
+PjUlRbCb     *pjRbCb;          /* RB Control Block */ 
+#endif
+{
+   PjUlUeCb      *ueCb;
+
+   TRC2(pjUtlUlHdlRbReEstComplete);
+
+   RLOG1(L_DEBUG, "pjUtlUlHdlRbReEstComplete(rbCb(%d)",
+                pjRbCb->rbId);
+
+   ueCb = pjRbCb->ueCb;
+   if (ueCb->libInfo.numReEstDrb == 0)
+   {
+      ueCb->libInfo.numReEstCmp++;
+      RETVALUE(ROK);
+   }
+   else
+   {
+      ueCb->libInfo.numReEstDrb--;  
+   }
+
+   if (ueCb->libInfo.numReEstDrb == 0)
+   {
+      if (ueCb->libInfo.state == PJ_STATE_REEST)
+      {
+         /* Since we have received all the packets in uplink
+            we can update the user keys */
+         pjUtlUlUpdUpSecKeys(gCb, ueCb);
+
+#ifdef PJ_ASYNC_CFM
+        RETVALUE(ROK);
+#endif
+        pjUtlUlSndReEstCfgCfm(gCb,ueCb);
+      }
+      else if (ueCb->libInfo.state == PJ_STATE_REEST_HO)
+      {
+         pjUtlUlSndSduStaCfm(gCb,ueCb);
+      }
+   }
+   RETVALUE(ROK);
+
+} /* pjUtlUlHdlRbReEstComplete */
+
+/**
+ *
+ * @brief 
+ *
+ *        Function to sent the REESTABLISHMENT COMPPLETE 
+ *        to the RRC.
+ *
+ * @b Description:
+ *
+ *        This function 
+ *        1. Sends a ReEstablishment Confirm for normal reestablishment.
+ *        2. Sends a SDU status confirm for handover reestablishment.
+ *
+ *  @param[in] ueCb   UE Control Block
+ *
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED
+ *
+ */
+#ifdef ANSI
+PUBLIC S16 pjUtlUlSndReEstCfgCfm
+(
+PjCb         *gCb,
+PjUlUeCb       *ueCb           /* UE Control Block */ 
+)
+#else
+PUBLIC S16 pjUtlUlSndReEstCfgCfm(ueCb)
+PjCb         *gCb;
+PjUlUeCb       *ueCb;           /* UE Control Block */ 
+#endif
+{
+   CpjCfgCfmInfo *cfgCfmInfo;
+   U8             txIdx;
+   PjAsyncCfm    *asyncCfm    = NULLP;
+   PjCpjSapCb    *cpjSap;
+
+   TRC2(pjUtlSndReEstCfgCfm);
+
+   RLOG2(L_DEBUG, "pjUtlSndReEstCfgCfm(ueCb(%d,%d))",
+                ueCb->key.ueId, ueCb->key.cellId);
+
+   /* Pick up the confirm info */
+   for(txIdx = 0; txIdx < PJ_MAX_ASYNC_CFM; txIdx++)
+   {
+      if((ueCb->libInfo.asyncCfm[txIdx] != NULLP) &&
+         (ueCb->libInfo.asyncCfm[txIdx]->cfmType & PJ_CFG_REEST_ASYNC_CFM))
+      {
+         asyncCfm =  ueCb->libInfo.asyncCfm[txIdx];
+         break;
+      }
+   }
+
+   /* its a reestablishment with only srb1 configured */
+   if(asyncCfm == NULLP)
+   {
+      RETVALUE(ROK);
+   }
+   /* Memory leak fix ccpu00135359 */
+   cpjSap = &(gCb->u.ulCb->cpjSap);
+   if(SGetSBuf(cpjSap->pst.region,cpjSap->pst.pool,(Data **)&cfgCfmInfo,
+      sizeof (CpjCfgCfmInfo)) != ROK)
+   {
+      RLOG0(L_FATAL, "Memory Allocation failed.");
+      RETVALUE(RFAILED);
+   }
+
+   PJ_FILL_REEST_CFG_CFM_INFO(cfgCfmInfo, asyncCfm);
+   PJ_CLEAN_AND_UPD_ASYNCINFO(gCb,ueCb, txIdx);
+
+   PjUiCpjCfgCfm(&gCb->u.ulCb->cpjSap.pst, gCb->u.ulCb->cpjSap.suId, cfgCfmInfo);         
+
+   RETVALUE(ROK);
+} /* pjUtlSndReEstCfgCfm */
+/**
+ *
+ * @brief Handler to store the confirms while we wait for the init
+ *        confirms from the off-board.
+ *       
+ *
+ * @b Description
+ *        This function is invoked during security config request,
+ *        reestablishment request and config request if the libraries
+ *        are off-boarded. This stores the entries in a confirm list
+ *        while waiting for the confirm from the offboard.
+ *
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED 
+ *
+*/
+
+#ifdef ANSI
+PUBLIC S16 pjUtlUlSaveCfmInfo
+(
+PjCb        *gCb,
+PjUlUeCb      *ueCb,           /* Pointer to UeCb */ 
+U8          cfmType,         /* Confirm type */
+Bool        startTmr,        /* Start Timer */
+U8          entity,          /* Confirm type */
+PTR         cfmPtr,          /* Pointer to the structure for confirm */
+PTR         cfgPtr           /* Pointer to the structure for request */
+)
+#else
+PUBLIC S16 pjUtlUlSaveCfmInfo(ueCb, cfmType, startTmr, entity, cfmPtr, cfgPtr)
+PjCb        *gCb;
+PjUlUeCb      *ueCb;           /* Pointer to UeCb */ 
+U8          cfmType;         /* Confirm type */
+Bool        startTmr;        /* Start Timer */
+U8          entity;          /* Confirm type */
+PTR         cfmPtr;          /* Pointer to the structure for confirm */
+PTR         cfgPtr;          /* Pointer to the structure for request */
+#endif
+{
+   S16               ret;        /* Return value            */
+   CpjSecCfgCfmInfo  *secCfm;    /* Security confirm        */
+   CpjReEstCfmInfo   *reEstCfm;  /* Reestablishment confirm */
+   CpjCfgCfmInfo     *cfgCfm;    /* Config confirm          */
+   U16               txId;       /* Transaction Id          */
+   PjAsyncCfm        *tAsyncCfm; /* Pointer to the async Cfm*/
+   CpjCfgReqInfo     *cfgReq;    /* Pointer to the config request */
+   U8                cfmIdx;     /* index for loopoing */
+
+
+   TRC3(pjUtlSaveCfmInfo)
+
+   RLOG_ARG4(L_DEBUG,DBG_UEID,  ueCb->key.ueId,
+         "pjUtlSaveCfmInfo cellId(%d),cfmType(%d),startTmr(%d),entity(%d))",
+         ueCb->key.cellId, cfmType, startTmr, entity);
+
+   /* Initialisations */
+   ret      = ROK;
+   secCfm   = NULLP;
+   reEstCfm = NULLP;
+   cfgCfm   = NULLP;
+   cfgReq   = NULLP;
+   txId     = ueCb->libInfo.nxtAvlbTxId;
+
+   if(txId == PJ_MAX_ASYNC_CFM)
+   {
+      /* The entire list is full, have to return negative confirms */
+      RETVALUE(RFAILED);
+   }
+
+   /* is entry already present */
+   if(ueCb->libInfo.asyncCfm[txId] != NULLP)
+   {
+      RETVALUE(RFAILED);
+   }
+
+   /* Allocate the structure */
+   PJ_ALLOC(gCb,ueCb->libInfo.asyncCfm[txId],  sizeof(PjAsyncCfm));
+   if(ueCb->libInfo.asyncCfm[txId]== NULLP)
+   {
+      RLOG0(L_FATAL, "Memory Allocation failed.");
+      RETVALUE(RFAILED);
+   }
+
+   /* Initialise the structure */
+   tAsyncCfm   =   ueCb->libInfo.asyncCfm[txId];
+   tAsyncCfm->libInitBitMask   =   ueCb->libInfo.tLibInitBitMask;
+   tAsyncCfm->cmpInitBitMask   =   ueCb->libInfo.tCmpInitBitMask;
+   tAsyncCfm->entity           =   entity;
+   tAsyncCfm->startTmr         =   startTmr;
+
+   ueCb->libInfo.tLibInitBitMask =  0; 
+   ueCb->libInfo.tCmpInitBitMask =  0; 
+   
+   /* Assign the values */
+   if(cfmType  ==   PJ_SEC_ASYNC_CFM)
+   {
+      secCfm   =  (CpjSecCfgCfmInfo *)cfmPtr;
+      tAsyncCfm->cfmType =  cfmType;
+      tAsyncCfm->ueId    = secCfm->ueId;
+      tAsyncCfm->cellId  = secCfm->cellId;
+      tAsyncCfm->transId = secCfm->transId;
+   }
+   else if(cfmType  ==   PJ_REEST_ASYNC_CFM)
+   {
+      reEstCfm   =  (CpjReEstCfmInfo *)cfmPtr;
+      tAsyncCfm->cfmType =  cfmType;
+      tAsyncCfm->ueId    = reEstCfm->ueId;
+      tAsyncCfm->cellId  = reEstCfm->cellId;
+      tAsyncCfm->transId = reEstCfm->transId;
+   }
+   else if((cfmType  & PJ_CFG_ASYNC_CFM)  ||
+           (cfmType  & PJ_CFG_REEST_ASYNC_CFM)||
+           (cfmType  & PJ_CFG_UEDEL_ASYNC_CFM))
+   {
+      if(entity   == ENTPJ)
+      {
+         cfgCfm   =  (CpjCfgCfmInfo *)cfmPtr;
+         cfgReq   =  (CpjCfgReqInfo *)cfgPtr;
+
+         tAsyncCfm->cfmType = cfmType;
+         tAsyncCfm->ueId    = cfgCfm->ueId;
+         tAsyncCfm->cellId  = cfgCfm->cellId;
+         tAsyncCfm->transId = cfgCfm->transId;
+         tAsyncCfm->numEnt  = cfgReq->numEnt;
+
+         for ( cfmIdx = 0; cfmIdx < cfgReq->numEnt; cfmIdx++ )
+         {
+            tAsyncCfm->cfmEnt[cfmIdx].status  = cfgCfm->cfmEnt[cfmIdx].status;
+            tAsyncCfm->cfmEnt[cfmIdx].reason  = cfgCfm->cfmEnt[cfmIdx].reason;
+            tAsyncCfm->cfmEnt[cfmIdx].rbId    = cfgCfm->cfmEnt[cfmIdx].rbId;
+            tAsyncCfm->cfmEnt[cfmIdx].rbType  = cfgCfm->cfmEnt[cfmIdx].rbType;
+            tAsyncCfm->cfmEnt[cfmIdx].cfgType = cfgReq->cfgEnt[cfmIdx].cfgType;
+         }
+      }
+      else if(entity == ENTPJ)
+      {
+         CpjCfgCfmInfo  *pjCfgCfm;       /* Configuraiton Confirm */
+         pjCfgCfm   =  (CpjCfgCfmInfo *)cfmPtr;
+
+         tAsyncCfm->cfmType = cfmType;
+         tAsyncCfm->transId = pjCfgCfm->transId;
+         tAsyncCfm->ueId    = pjCfgCfm->ueId;
+         tAsyncCfm->cellId  = pjCfgCfm->cellId;
+         tAsyncCfm->numEnt  = pjCfgCfm->numEnt;
+
+         for ( cfmIdx = 0; cfmIdx < pjCfgCfm->numEnt; cfmIdx++ )
+         {
+            tAsyncCfm->cfmEnt[cfmIdx].status  = 
+                                 pjCfgCfm->cfmEnt[cfmIdx].status;
+            tAsyncCfm->cfmEnt[cfmIdx].reason  = 
+                                 pjCfgCfm->cfmEnt[cfmIdx].reason;
+            tAsyncCfm->cfmEnt[cfmIdx].rbId    = 
+                                 pjCfgCfm->cfmEnt[cfmIdx].rbId;
+            tAsyncCfm->cfmEnt[cfmIdx].rbType  = 
+                                 pjCfgCfm->cfmEnt[cfmIdx].rbType;
+         }
+      }
+   }
+
+   /* Start timer */
+   /* Timer should not be started when SEC is SYNC for ReEst Req
+    * and for the subsequent config req for REEST. The config req
+    * after reest req can still start the timer in the case comp being
+    * async and sec being sync if it also adds a RB and a compInit has
+    * to be sent . 
+    * */
+
+   if(tAsyncCfm->startTmr  == TRUE)
+   {
+      if((pjChkTmr(gCb,(PTR)ueCb, PJ_EVT_OBD_WAIT_TMR)) == FALSE)
+      {
+         pjStartTmr(gCb,(PTR)ueCb, PJ_EVT_OBD_WAIT_TMR);
+         ueCb->libInfo.crntTmrTxId  =  ueCb->libInfo.nxtAvlbTxId;
+      }
+   }
+
+   /* update nxtAvlbTxId to the next empty slot */
+   for(cfmIdx = 0; cfmIdx < PJ_MAX_ASYNC_CFM; cfmIdx++)
+   {
+      ueCb->libInfo.nxtAvlbTxId = 
+        (U16)((ueCb->libInfo.nxtAvlbTxId + 1) % PJ_MAX_ASYNC_CFM); /*KW_FIX*/
+
+      if(ueCb->libInfo.asyncCfm[ueCb->libInfo.nxtAvlbTxId] == NULLP)
+      {
+         break;
+      }
+   }
+
+   /* Cant find an empty slot ? */
+   if(cfmIdx == PJ_MAX_ASYNC_CFM)
+   {
+      ueCb->libInfo.nxtAvlbTxId = PJ_MAX_ASYNC_CFM;
+   }
+
+   RETVALUE(ret);
+}/* pjUtlSaveCfmInfo */
+\f
+/**
+ *
+ * @brief Handler to store update the bitmaks and send confirms if necessary.
+ *       
+ *
+ * @b Description
+ *        This function is invoked when receiving a InitCfm from Offboard.
+ *        It updates the bit masks and checks if it is necesary to send a 
+ *        confirm.
+ *
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED 
+ *
+*/
+
+#ifdef ANSI
+PUBLIC S16 pjUtlUlHdlObdInitCfm
+(
+PjCb        *gCb,
+PjUlUeCb      *ueCb,           /* Pointer to UeCb */ 
+U16         txIdx,           /* Transaction Index for UeCb */
+U8          cfmType,         /* Confirm type */
+U8          maskVal          /* mask value */
+)
+#else
+PUBLIC S16 pjUtlUlHdlObdInitCfm(ueCb, txIdx, cfmType, maskVal)
+PjCb        *gCb;
+PjUlUeCb      *ueCb;           /* Pointer to UeCb */ 
+U16         txIdx;           /* Transaction Index for UeCb */
+U8          cfmType;         /* Confirm type */
+U8          maskVal;         /* mask value */
+#endif
+{
+   CpjSecCfgCfmInfo *secCfgCfm;   /* Security config confirm */
+   CpjReEstCfmInfo  *reEstCfm;    /* Reest config confirm */
+   PjAsyncCfm       *asyncCfm;
+   CpjCfgCfmInfo    *cfgCfm;
+   U8               idx;
+   S16              ret;
+   TRC3(pjUtlUlHdlObdInitCfm)
+
+   RLOG_ARG4(L_DEBUG,DBG_UEID,  ueCb->key.ueId, 
+         "pjUtlHdlUlObdInitCfm(ueCb(%d,%d),txIdx(%d),cfmType(%d),maskVal(%d))",
+           ueCb->key.cellId, txIdx, cfmType, maskVal);
+
+   /* Initialisations */
+   secCfgCfm   =  NULLP;
+   reEstCfm    =  NULLP;
+   cfgCfm      =  NULLP;
+   asyncCfm    =  NULLP;
+   ret         =  ROK;
+
+   if((txIdx  == PJ_MAX_ASYNC_CFM) ||
+      (ueCb->libInfo.asyncCfm[txIdx] == NULLP))
+   {
+      RETVALUE(RFAILED);
+   }
+
+   asyncCfm =  ueCb->libInfo.asyncCfm[txIdx];
+
+   if(cfmType & PJ_SEC_INIT_CFM)
+   {
+      /* Update bit mask and check if all confirms have been received */
+      asyncCfm->libInitBitMask ^= (maskVal);
+      ret = pjUtlUlHdlSecInitCfm(gCb,ueCb,txIdx,asyncCfm,secCfgCfm,reEstCfm);
+   }
+   else if(cfmType  & PJ_CMP_INIT_CFM)
+   {
+      /* Check if all confirms have been received */
+      asyncCfm->cmpInitBitMask &= ~(1 << (maskVal - 1));
+
+      /* Update the status and reason for the received CmpInitCfm */
+      for ( idx = 0; idx < asyncCfm->numEnt; idx++ )
+      {
+         if ( asyncCfm->cfmEnt[idx].rbId == maskVal)
+         {
+            asyncCfm->cfmEnt[idx].status = CPJ_CFG_CFM_OK;
+            asyncCfm->cfmEnt[idx].reason = CPJ_CFG_REAS_NONE;
+            break;
+         }
+      }
+
+      ret = pjUtlUlHdlCmpInitCfm(gCb,ueCb,txIdx,asyncCfm,cfgCfm);
+   }
+
+   RETVALUE(ret);
+}/* pjUtlHdlUlObdInitCfm */
+\f
+/**
+ *
+ * @brief Handler for init off-board timer expiry.
+ *
+ *
+ * @b Description
+ *        This function is called when the off-board timer expires for
+ *        a Init Req of a channel (either for ciphering/integrity/compression).
+ *        This function sends a confirm with failure for SecCfgReq if the
+ *        state of the RB is normal. It sends a confirm with failure
+ *        for config request(only for RBs with Re-establishment Req, a failure 
+ *        is stored in the confirm) if the state of the RB is re-establishment.
+ *
+ *  @param[in] ueCb    UE control block.
+ *
+ *
+ *  @return  S16
+ *      -# ROK
+ */
+
+#ifdef ANSI
+PUBLIC S16 pjUtlUlHdlInitObdTmrExp
+(
+PjCb     *gCb,
+PjUlUeCb *ueCb
+)
+#else
+PUBLIC S16 pjUtlUlHdlInitObdTmrExp(ueCb)
+PjCb     *gCb;
+PjUlUeCb *ueCb;
+#endif
+{
+   S16               ret;           /* Return Value */
+   CpjSecCfgCfmInfo  *secCfgCfm;    /* Security Cfg Confirm Info */
+   CpjCfgCfmInfo     *cfgCfm;       /* Config Confirm Info */
+   CpjReEstCfmInfo   *reEstCfm;     /* Reest config confirm */
+   CpjCfgCfmInfo     *pjCfgCfm;
+   PjLibInfo         *libInfo;      /* Off-board Info */
+   PjAsyncCfm        *asyncCfm;     /* Async Cfm Info */
+   PjCpjSapCb        *cpjSap;       /* CPJ SAP Control Block */
+   U16               txIdx;         /* Tx Idx */
+   U16               idx;           /* Index for looping */
+   U16               cfgIdx;
+
+   TRC3(pjUtlHdlInitObdTmrExp)
+
+   RLOG2(L_DEBUG, "pjUtlHdlInitObdTmrExp(ueCb(%d,%d))",
+                ueCb->key.ueId, ueCb->key.cellId);
+
+   ret       = ROK;
+   cpjSap    = &(gCb->u.ulCb->cpjSap);
+   secCfgCfm = NULLP;
+   libInfo   = &ueCb->libInfo;
+   txIdx     = libInfo->crntTmrTxId;
+
+   /* Restart the timer */
+   PJ_CHK_RESTART_OBD_TIMER(gCb,ueCb, txIdx);
+
+   /* Shouldnt happen, nevertheless, check */
+   if( txIdx >= PJ_MAX_ASYNC_CFM || libInfo->asyncCfm[txIdx] == NULLP)
+   {
+      RETVALUE(ROK);
+   }
+
+   asyncCfm =  libInfo->asyncCfm[txIdx];
+
+   /* Security confirm */
+   if(asyncCfm->cfmType & PJ_SEC_ASYNC_CFM)
+   {
+      PJ_ALLOC(gCb,secCfgCfm, sizeof(CpjSecCfgCfmInfo));
+#if (ERRCLASS & ERRCLS_ADD_RES)
+      if (secCfgCfm == NULLP)
+      {
+         RLOG0(L_FATAL, "Memory Allocation failed.");
+         RETVALUE(RFAILED);
+   }
+#endif /* ERRCLASS & ERRCLS_ADD_RES */
+      PJ_FILL_SEC_CFM_INFO(secCfgCfm, asyncCfm);
+      secCfgCfm->status = CPJ_CFG_CFM_NOK;
+      secCfgCfm->reason = CPJ_CFG_REAS_OBD_TIMEOUT;
+
+      PJ_CLEAN_AND_UPD_ASYNCINFO(gCb,ueCb, txIdx);
+
+      PjUiCpjSecCfgCfm(&(cpjSap->pst), cpjSap->suId, secCfgCfm);
+   }
+
+   /* Configuration confirms */
+   else if ((asyncCfm->cfmType & PJ_CFG_ASYNC_CFM) ||
+            (asyncCfm->cfmType & PJ_CFG_REEST_ASYNC_CFM))
+   {
+      PJ_FILL_TIMEOUT_CFG_CFM_INFO(gCb,cfgCfm, asyncCfm);
+
+      PJ_CLEAN_AND_UPD_ASYNCINFO(gCb,ueCb, txIdx);
+
+      PjUiCpjCfgCfm(&(cpjSap->pst), cpjSap->suId, cfgCfm);
+   }
+   else if (asyncCfm->cfmType & PJ_REEST_ASYNC_CFM)
+   {
+      /* Send ReEstCfm */
+      PJ_ALLOC(gCb,reEstCfm, sizeof(CpjReEstCfmInfo));
+#if (ERRCLASS & ERRCLS_ADD_RES)
+      if (reEstCfm == NULLP)
+      {
+         RLOG0(L_FATAL, "Memory Allocation failed.");
+         RETVALUE(RFAILED);
+      }
+#endif /* ERRCLASS & ERRCLS_ADD_RES */
+      PJ_FILL_REEST_CFM_INFO(reEstCfm, asyncCfm, LCM_PRIM_NOK);
+
+      PJ_CLEAN_AND_UPD_ASYNCINFO(gCb,ueCb, txIdx);
+
+      PjUiCpjReEstCfm(&gCb->u.ulCb->cpjSap.pst, 
+                       gCb->u.ulCb->cpjSap.suId, reEstCfm);
+
+      /* Send the config confirm also if any exists */
+      cfgIdx   =  (U16)(txIdx + 1);  /*KW_FIX*/
+
+      for(idx = 0; idx < PJ_MAX_ASYNC_CFM; idx++, cfgIdx++)
+      {
+         cfgIdx %=   PJ_MAX_ASYNC_CFM;
+         if((libInfo->asyncCfm[cfgIdx] != NULLP) &&
+            (libInfo->asyncCfm[cfgIdx]->cfmType & PJ_CFG_REEST_ASYNC_CFM))
+         {
+            break;
+         }
+      }
+
+      /* This scenario occurs when only SRB1 is configured */
+      if(idx == PJ_MAX_ASYNC_CFM)
+      {
+         RETVALUE(ROK);
+      }
+
+      PJ_CHK_RESTART_OBD_TIMER(gCb,ueCb, cfgIdx);
+      asyncCfm =  libInfo->asyncCfm[cfgIdx];
+
+      PJ_FILL_TIMEOUT_CFG_CFM_INFO(gCb,cfgCfm, asyncCfm);
+
+      PJ_CLEAN_AND_UPD_ASYNCINFO(gCb,ueCb, txIdx);
+
+      PjUiCpjCfgCfm(&(cpjSap->pst), cpjSap->suId, cfgCfm);
+   }
+   else if(asyncCfm->cfmType & PJ_CFG_UEDEL_ASYNC_CFM)
+   {
+      /* Delete ueCb entry from ueLstCp */
+      pjStopTmr(gCb,(PTR)ueCb, PJ_EVT_OBD_WAIT_TMR);
+      ret = cmHashListDelete(&(gCb->u.ulCb->ueLstCp), (PTR) ueCb);
+      if (ret != ROK)
+      {
+
+#ifdef DEBUGP
+         RLOG_ARG0(L_DEBUG,DBG_UEID,ueCb->key.ueId, 
+               "pjUtlHdlInitObdTmrExp: cmHashListDelete Failed for ueCb.");
+#endif
+      }
+
+      if ( asyncCfm->entity == ENTPJ )
+      {
+         PJ_ALLOC(gCb,cfgCfm, sizeof(CpjCfgCfmInfo));
+#if (ERRCLASS & ERRCLS_ADD_RES)
+         if (cfgCfm == NULLP)
+         {
+            RLOG0(L_FATAL, "Memory Allocation failed.");
+            RETVALUE(RFAILED);
+         }
+#endif /* ERRCLASS & ERRCLS_ADD_RES */
+
+         for ( idx = 0; idx < asyncCfm->numEnt; idx++)
+         {
+            cfgCfm->cfmEnt[idx].status = asyncCfm->cfmEnt[idx].status;
+            cfgCfm->cfmEnt[idx].reason = asyncCfm->cfmEnt[idx].reason;
+            cfgCfm->cfmEnt[idx].rbId   = asyncCfm->cfmEnt[idx].rbId;
+            cfgCfm->cfmEnt[idx].rbType = asyncCfm->cfmEnt[idx].rbType;
+         }
+         cfgCfm->ueId    = asyncCfm->ueId;
+         cfgCfm->cellId  = asyncCfm->cellId;
+         cfgCfm->transId = asyncCfm->transId;
+         cfgCfm->numEnt  = asyncCfm->numEnt;
+
+         /* delete all confirms present there */
+         for(idx = 0; idx < PJ_MAX_ASYNC_CFM; idx++)
+         {
+            if(libInfo->asyncCfm[idx] != NULLP)
+            {
+               PJ_FREE(gCb,ueCb->libInfo.asyncCfm[idx], sizeof(PjAsyncCfm)); 
+               ueCb->libInfo.asyncCfm[idx] = NULLP; 
+            }
+         }
+
+         PJ_FREE(gCb,ueCb, sizeof(PjUlUeCb));
+         PjUiCpjCfgCfm(&(cpjSap->pst), cpjSap->suId, cfgCfm);
+      }
+      else if ( asyncCfm->entity == ENTPJ )
+      {
+         PJ_ALLOC(gCb,pjCfgCfm, sizeof(CpjCfgCfmInfo));
+#if (ERRCLASS & ERRCLS_ADD_RES)
+         if (pjCfgCfm == NULLP)
+         {
+            RLOG0(L_FATAL, "Memory Allocation failed.");
+            RETVALUE(RFAILED);
+         }
+#endif /* ERRCLASS & ERRCLS_ADD_RES */
+         for ( idx = 0; idx < asyncCfm->numEnt; idx++)
+         {
+            pjCfgCfm->cfmEnt[idx].status = asyncCfm->cfmEnt[idx].status;
+            pjCfgCfm->cfmEnt[idx].reason = asyncCfm->cfmEnt[idx].reason;
+            pjCfgCfm->cfmEnt[idx].rbId          = asyncCfm->cfmEnt[idx].rbId;
+            pjCfgCfm->cfmEnt[idx].rbType        = asyncCfm->cfmEnt[idx].rbType;
+         }
+         pjCfgCfm->ueId    = asyncCfm->ueId;
+         pjCfgCfm->cellId  = asyncCfm->cellId;
+         pjCfgCfm->transId = asyncCfm->transId;
+         pjCfgCfm->numEnt  = asyncCfm->numEnt;
+
+         /* delete all confirms present there */
+         for(idx = 0; idx < PJ_MAX_ASYNC_CFM; idx++)
+         {
+            if(libInfo->asyncCfm[idx] != NULLP)
+            {
+               PJ_FREE(gCb,ueCb->libInfo.asyncCfm[idx], sizeof(PjAsyncCfm)); 
+               ueCb->libInfo.asyncCfm[idx] = NULLP; 
+            }
+         }
+
+         PJ_FREE(gCb,ueCb, sizeof(PjUlUeCb));
+         PjUiCpjCfgCfm(&(cpjSap->pst), cpjSap->suId, pjCfgCfm);
+      }
+   }
+
+   RETVALUE(ret);
+} /* pjHdlUeDelWaitTmrExp */
+
+\f
+/**
+ *
+ * @brief 
+ *
+ *        Function to sent the REESTABLISHMENT COMPPLETE 
+ *        to the RRC.
+ *
+ * @b Description:
+ *
+ *        This function 
+ *        1. Sends a ReEstablishment Confirm for normal reestablishment.
+ *        2. Sends a SDU status confirm for handover reestablishment.
+ *
+ *  @param[in] ueCb   UE Control Block
+ *
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED
+ *
+ */
+#ifdef ANSI
+PUBLIC S16 pjUtlUlSndSduStaCfm
+(
+PjCb         *gCb,
+PjUlUeCb     *ueCb           /* UE Control Block */ 
+)
+#else
+PUBLIC S16 pjUtlUlSndSduStaCfm(gCb, ueCb)  
+PjCb         *gCb;
+PjUlUeCb     *ueCb;           /* UE Control Block */ 
+#endif
+{
+   U8       rbCnt;
+   CpjSduStaCfmInfo  *cfmInfo;
+   UdxSduStaCfmInfo  *udxCfmInfo;
+   UdxSduStaInfo tempDlStaInfo[PJ_MAX_DRB_PER_UE] = {{0}};
+   U8 rbId;
+   U8 numRb = 0;
+   PjUlHoCfmInfo *hoCfmInfo;
+   CpjSduStaInfo  *staInfo;
+   Bool rbPres;
+   PjCpjSapCb     *cpjSap;
+   PjUdxUlSapCb   *udxSap;
+   
+
+   TRC2(pjUtlUlSndSduStaCfm); 
+
+   RLOG2(L_DEBUG, "pjUtlUlSndSduStaCfm(ueCb(%d,%d))",
+                ueCb->key.ueId, ueCb->key.cellId);
+
+   cpjSap = &(gCb->u.ulCb->cpjSap);
+   if(SGetSBuf(cpjSap->pst.region,cpjSap->pst.pool,(Data **)&cfmInfo,
+      sizeof (CpjSduStaCfmInfo)) != ROK)
+   {
+      RLOG0(L_FATAL, "Memory Allocation failed.");
+      RETVALUE(RFAILED);
+   }
+
+   cfmInfo->ueId = ueCb->key.ueId;
+   cfmInfo->cellId = ueCb->key.cellId;
+   cfmInfo->transId = ueCb->hoInfo->transId;
+   cfmInfo->reason = CPJ_CFG_REAS_NONE;
+   udxCfmInfo      = ueCb->hoInfo->staCfm;
+
+   for(rbCnt = 0; rbCnt < udxCfmInfo->numRb; rbCnt++)
+   {
+      /*
+      - Check for rbId and copy the info to index=(rbId)
+      */
+      rbId = udxCfmInfo->sduStaInfo[rbCnt].rbId;
+      if(udxCfmInfo->sduStaInfo[rbCnt].dlSduStaInfo.hoPres == TRUE)
+      {
+         tempDlStaInfo[rbId].rbId = udxCfmInfo->sduStaInfo[rbCnt].rbId;
+         tempDlStaInfo[rbId].dir = udxCfmInfo->sduStaInfo[rbCnt].dir;
+         tempDlStaInfo[rbId].dlSduStaInfo.count = udxCfmInfo->sduStaInfo[rbCnt].dlSduStaInfo.count;
+         tempDlStaInfo[rbId].dlSduStaInfo.hoPres = TRUE;
+      }
+   } 
+
+   for(rbCnt = 0;
+      ((rbCnt < PJ_MAX_DRB_PER_UE) && (numRb < CPJ_MAX_DRB)); rbCnt++)
+   {
+      rbPres     = FALSE;
+      hoCfmInfo   =  &ueCb->hoInfo->hoCfmInfo[rbCnt];
+      staInfo     =  &cfmInfo->sduStaInfo[numRb];
+      memset((void *)staInfo,0,sizeof(CpjSduStaInfo));
+      if(hoCfmInfo->pres == TRUE)
+      {                          
+         rbPres = TRUE;
+         staInfo->rbId  =  hoCfmInfo->rbId;
+         staInfo->dir   |= hoCfmInfo->dir;
+         staInfo->snLen = ueCb->drbCb[hoCfmInfo->rbId]->snLen;
+         staInfo->ulSduStaInfo.numBits   =  hoCfmInfo->numBits;
+         if (hoCfmInfo->numBits > 0) 
+         {
+            /* numBits is always filled as multiple's of 8 */
+            cpjSap = &(gCb->u.ulCb->cpjSap);
+            if(SGetSBuf(cpjSap->pst.region,cpjSap->pst.pool,
+                        (Data **)&staInfo->ulSduStaInfo.ulBitMap,
+                        sizeof (U8) * (hoCfmInfo->numBits / 8)) != ROK)
+            {
+               RLOG0(L_FATAL, "Memory Allocation failed.");
+               RETVALUE(RFAILED);
+            }
+            PJ_MEM_CPY(staInfo->ulSduStaInfo.ulBitMap, hoCfmInfo->ulBitMap, (hoCfmInfo->numBits / 8));
+            PJ_FREE(gCb, hoCfmInfo->ulBitMap, sizeof(U8) * (hoCfmInfo->numBits / 8));
+         }
+         staInfo->ulSduStaInfo.count     =  hoCfmInfo->count;
+      }
+      if(tempDlStaInfo[rbCnt].dlSduStaInfo.hoPres == TRUE)
+      { 
+         rbPres = TRUE;
+         staInfo->rbId  =  tempDlStaInfo[rbCnt].rbId;
+         staInfo->dir   |=  tempDlStaInfo[rbCnt].dir;
+         staInfo->snLen = ueCb->drbCb[staInfo->rbId]->snLen;
+         staInfo->dlSduStaInfo.count = tempDlStaInfo[rbCnt].dlSduStaInfo.count;
+      }
+      if(rbPres != TRUE)
+      {
+         continue;
+      }
+      else
+      {
+        numRb++;
+      }
+   }
+
+   cfmInfo->numRb = numRb; 
+   cfmInfo->status = ROK;
+   cfmInfo->reason = CPJ_CFG_REAS_NONE;
+   PJ_FREE(gCb,ueCb->hoInfo->hoCfmInfo,
+              (PJ_MAX_DRB_PER_UE * sizeof(PjUlHoCfmInfo)));
+   /* Memory leak fix ccpu00135359 */
+   udxSap = PJ_GET_UL_UDX_SAP(gCb);
+   PJ_PST_FREE(udxSap->pst.region, udxSap->pst.pool,ueCb->hoInfo->staCfm,
+                sizeof (UdxSduStaCfmInfo));
+   PJ_FREE(gCb,ueCb->hoInfo, sizeof(PjUlHoInfo));
+   
+   PjUiCpjSduStaCfm(&gCb->u.ulCb->cpjSap.pst, 
+                     gCb->u.ulCb->cpjSap.suId, cfmInfo);
+    
+   RETVALUE(ROK);
+} /* pjUtlSndSduStaCfm */
+
+/**
+ *
+ * @brief Handler to clean up all the PDCP Control Blocks.
+ *       
+ *
+ * @b Description
+ *        This function is invoked by LMM to shutdown the
+ *        layer. This cleans up recBuf and txBuf of all the
+ *        PDCP RBs in all the UEs.
+ *
+ *  @return  S16
+ *      -# ROK 
+ *      -# RFAILED 
+ *
+*/
+
+#ifdef ANSI
+PUBLIC S16 pjUtlUlShutdown
+(
+PjCb  *gCb
+)
+#else
+PUBLIC S16 pjUtlUlShutdown()
+PjCb   *gCb;
+#endif
+{
+   S16         ret;              /* Return Value */
+   PjUlUeCb      *ueCb;            /* UE Control Block */
+   PjUlUeCb      *prevUeCb;        /* Previos UE Control Block */
+   PjUlRbCb        *rbCb;            /* RB Control Block */
+   PjUlRbCb        **rbCbLst;        /* RB Control Block List */
+   PjSec       *secInfo;          /* Security info of UE */
+   U8          idx;              /* Index for RBs */
+#ifdef LTE_L2_MEAS_COMMENT
+   PjL2MeasEvtCb  *measEvtCb = NULLP;
+#endif
+   TRC3(pjUtlShutdown)
+
+   RLOG0(L_DEBUG, "pjUtlShutdown()");
+
+   ret      = ROK;
+   ueCb     = NULLP;
+   prevUeCb = NULLP;
+   rbCb     = NULLP;
+   rbCbLst  = NULLP;
+   idx      = 0;
+
+   /* Until no more ueCb is ueLstCp hash list get and delete ueCb */
+   while (cmHashListGetNext(&(gCb->u.ulCb->ueLstCp), (PTR) prevUeCb, (PTR *)&ueCb) == ROK)
+   {
+      if ( ueCb != NULLP )
+      {
+#if (defined(PJ_SEC_ASYNC) || defined (PJ_CMP_ASYNC))
+         if (ueCb->libInfo.obdTmr.tmrEvnt == PJ_EVT_OBD_TMR)
+         {
+            pjStopTmr(gCb,(PTR)ueCb, PJ_EVT_OBD_TMR);
+         }
+#endif
+         rbCbLst = ueCb->srbCb;
+         for (idx = 0; idx < PJ_MAX_SRB_PER_UE; idx++)
+         {
+             rbCb = rbCbLst[idx];
+             if (rbCb != NULLP)
+             {
+               /* Free the Buffers of RbCb */
+               pjUtlUlFreeRb(gCb,rbCb);
+             }
+         }
+         rbCbLst = ueCb->drbCb;
+         for (idx = 0; idx < PJ_MAX_DRB_PER_UE; idx++)
+         {
+             rbCb = rbCbLst[idx];
+             if (rbCb != NULLP)
+             {
+                pjUtlUlFreeRb(gCb,rbCb);
+             }
+         }
+         /* Close all the context info for offboarding */
+         secInfo = &(ueCb->secInfo);
+#ifdef INTEL_QAT_DP
+                pjUtlUlIntClose(gCb,ueCb->secInfo.cpIntSessCxtId); 
+                pjUtlUlCipherClose(gCb,ueCb->secInfo.cpCiphSessCxtId);
+                pjUtlUlCipherClose(gCb,ueCb->secInfo.upCiphSessCxtId);
+#else
+         pjUtlUlCipherClose(gCb,secInfo->cpCxtId);
+         pjUtlUlCipherClose(gCb,secInfo->upCxtId);
+         pjUtlUlIntClose(gCb,secInfo->intCxtId);
+#endif
+         /* Delete hoInfo if present */
+         if (ueCb->hoInfo != NULLP)
+         {
+            for (idx = 0; idx < PJ_MAX_DRB_PER_UE; idx++)
+            {
+               if (ueCb->hoInfo->hoCfmInfo[idx].pres == TRUE)
+               {
+                  PJ_FREE(gCb,ueCb->hoInfo->hoCfmInfo[idx].ulBitMap,
+                        (ueCb->hoInfo->hoCfmInfo[idx].numBits % 8)?
+                        ((ueCb->hoInfo->hoCfmInfo[idx].numBits / 8) + 1):
+                        (ueCb->hoInfo->hoCfmInfo[idx].numBits / 8 ));
+               }
+            }
+
+            PJ_FREE(gCb,ueCb->hoInfo->hoCfmInfo,                         \
+                           (PJ_MAX_DRB_PER_UE * sizeof(PjUlHoCfmInfo)));
+            PJ_FREE(gCb,ueCb->hoInfo, sizeof(PjUlHoInfo));                 
+         }
+      }
+      prevUeCb = ueCb;
+   }
+#ifdef LTE_L2_MEAS_COMMENT
+   for(idx = 0; idx < PJ_MAX_L2MEAS_EVT; idx++)
+   {
+      if(pjCb.pjL2Cb.pjMeasEvtCb[idx] != NULLP)
+      {
+         measEvtCb = pjCb.pjL2Cb.pjMeasEvtCb[idx];
+         pjStopTmr(gCb,(PTR)measEvtCb, PJ_EVT_L2_TMR);
+         gCb.pjL2Cb.pjNumMeas--;
+         PJ_FREE(gCb,measEvtCb, sizeof(PjL2MeasEvtCb));
+         pjCb.pjL2Cb.pjMeasEvtCb[idx] = NULLP;
+      }
+   }
+#endif
+   ret = pjDbmUlDeInit(gCb);
+#if (ERRCLASS & ERRCLS_DEBUG)
+   if (ret != ROK)
+   {
+      RLOG0(L_FATAL, "PDCP UL DeInitialization Failed.\n");
+   }
+#endif /* ERRCLASS & ERRCLS_DEBUG */
+   RETVALUE(ret);
+}
+
+/**
+ * 
+ * @brief 
+ *
+ *        Handler to free a PDCP Control Block.
+ *
+ * @b Description:
+ * 
+ *        This function frees the txBuf and rxBuf in a PDCP control block.
+ *        and closes the compression channel opened. It stops the timers 
+ *        of this control block if they are running.
+ *
+ *  @param[in]  pst        Post structure 
+ *  @param[in]  secCxt     Context for Integrity protection/verification 
+ *  @param[in]  ctxId      Integrity Context Id
+ *
+ *
+ *  @return  S16
+ *      -# ROK 
+ *
+ */
+
+#ifdef ANSI
+PUBLIC Void pjUtlUlFreeRb
+(
+PjCb     *gCb,
+PjUlRbCb *pjRbCb
+)
+#else
+PUBLIC Void pjUtlUlFreeRb(pjRbCb)
+PjCb     *gCb;
+PjUlRbCb *pjRbCb;
+#endif
+{
+   TRC3(pjUtlFreeUlRb)
+
+   RLOG0(L_DEBUG, "pjUtlFreeRb()");
+
+#if (defined(PJ_SEC_ASYNC) || defined (PJ_CMP_ASYNC))
+   if (pjRbCb->ulCb.obdTmr.tmrEvnt == PJ_EVT_UL_OBD_TMR)
+   {
+       pjStopTmr(gCb,(PTR)pjRbCb, PJ_EVT_UL_OBD_TMR);
+   }
+#endif
+   pjDbmRxDeInit(gCb,&(pjRbCb->ulCb.recBuf));
+   
+   pjUtlCmpClose(gCb,pjRbCb->cmpCxtId);
+   /*pj004.201 Adding of Missing Trace in LTE RLC PDCP*/
+   RETVOID;
+}
+
+/* pj005.201 added function to send data forward indication message */
+/**
+ * 
+ * @brief 
+ *
+ *        Handler to send Data Fwd Indication
+ *
+ * @b Description:
+ *      This function sends Data Fwd Indication message to PDCP user 
+ *
+ *  @param[in]  pjRbCb     PDCP RbCb
+ *  @param[in]  datFwdInd  Data forward indication
+ *
+ *
+ *  @return  S16
+ *      -# ROK 
+ *
+ */
+
+#ifdef ANSI
+PUBLIC S16 pjUtlUlSndDatFwdInd
+(
+PjCb             *gCb,
+PjUlRbCb           *pjRbCb,
+PjuDatFwdIndInfo *datFwdInd
+)
+#else
+PUBLIC S16 pjUtlUlSndDatFwdInd(pjRbCb, datFwdInd)
+PjCb             *gCb;
+PjUlRbCb           *pjRbCb;
+PjuDatFwdIndInfo *datFwdInd;
+#endif
+{
+   CmLtePdcpId  *pdcpId;
+   PjPjuSapCb   *pjuSap;
+   CmLtePdcpId   pdcpIdTmp;
+
+   TRC3(pjUtlUlSndDatFwdInd)
+   
+   RLOG0(L_DEBUG, "pjUtlSndDatFwdInd()");
+
+   pjuSap   = &(gCb->u.ulCb->pjuSap[PJ_DRB_SAP]);
+   pdcpId = &pdcpIdTmp;
+
+   if(pdcpId != NULLP)
+   {
+      pdcpId->ueId   =  pjRbCb->ueCb->key.ueId;
+      pdcpId->cellId =  pjRbCb->ueCb->key.cellId;
+      pdcpId->rbId   =  pjRbCb->rbId;
+      pdcpId->rbType =  pjRbCb->rbType;
+      
+      gCb->pjGenSts.numPktsFrwd += datFwdInd->numSdus;
+      /* If trace flag is enabled send the trace indication */
+      if(gCb->init.trc == TRUE)
+      {                       
+         /* Populate the trace params */
+         pjLmmSendTrc(gCb,EVTPJUDATFWDIND, NULLP);
+      }
+      PjUiPjuDatFwdInd(&(pjuSap->pst), pjuSap->suId, pdcpId, datFwdInd);
+   }
+
+  RETVALUE(ROK);
+
+}/* end of pjUtlSndDatFwdInd */
+
+/**
+ * 
+ * @brief 
+ *
+ *        Handler to send Data Fwd Indication
+ *
+ * @b Description:
+ *      This function sends Data Fwd Indication message to PDCP user 
+ *
+ *  @param[in]  pjRbCb     PDCP RbCb
+ *  @param[in]  datFwdInd  Data forward indication
+ *
+ *
+ *  @return  S16
+ *      -# ROK 
+ *
+ */
+
+#ifdef ANSI
+PUBLIC S16 pjUtlUlSndUlStaRep
+(
+PjCb             *gCb,
+PjUlRbCb         *pjRbCb,
+Buffer           *sta
+)
+#else
+PUBLIC S16 pjUtlUlSndUlStaRep(pjRbCb, sta)
+PjCb             *gCb;
+PjUlRbCb         *pjRbCb;
+Buffer           *sta;
+#endif
+{
+   PjUdxUlSapCb *udxSap;
+   UdxUlStaRepInfo   *staRep;
+   S16               ret = ROK;           /* Return Value */
+   
+   udxSap = PJ_GET_UL_UDX_SAP(gCb);
+
+   TRC3(pjUtlUlSndUlStaRep)
+   
+   RLOG0(L_DEBUG, "pjUtlUlSndUlStaRep()");
+
+   PJ_ALLOC_BUF_SHRABL(udxSap->pst, staRep,
+                     sizeof (UdxUlStaRepInfo), ret);
+                     
+   if(ret != ROK)
+   {
+     staRep = NULLP;
+   }
+
+   if(staRep != NULLP)
+   {
+      staRep->pdcpId.ueId   =  pjRbCb->ueCb->key.ueId;
+      staRep->pdcpId.cellId =  pjRbCb->ueCb->key.cellId;
+      staRep->pdcpId.rbId   =  pjRbCb->rbId;
+      staRep->pdcpId.rbType =  pjRbCb->rbType;
+      staRep->sta = sta;
+
+      PjUlUdxUlStaRep(&(udxSap->pst), udxSap->spId, staRep);
+   }
+   else
+   {
+      PJ_FREE_BUF(sta);
+   }
+
+   RETVALUE(ROK);
+}/* end of pjUtlSndDatFwdInd */
+
+
+/**
+ * 
+ * @brief 
+ *
+ *        Handler to send Feedback packet to DL-PDCP
+ *
+ * @b Description:
+ *      This function sends Feedback packet to DL-PDCP 
+ *
+ *  @param[in]  pjCb       PDCP global control block
+ *  @param[in]  pjRbCb     PDCP RbCb
+ *  @param[in]  fbPkt      Feedback packet
+ *
+ *
+ *  @return  S16
+ *      -# ROK 
+ *
+ */
+
+#ifdef ANSI
+PUBLIC S16 pjUtlUlSndUlRohcFdbk
+(
+PjCb             *gCb,
+PjUlRbCb         *pjRbCb,
+Buffer           *fbPkt
+)
+#else
+PUBLIC S16 pjUtlUlSndUlRohcFdbk(gCb, pjRbCb, fbPkt)
+PjCb             *gCb;
+PjUlRbCb         *pjRbCb;
+Buffer           *fbPkt;
+#endif
+{
+   PjUdxUlSapCb      *udxSap;
+   UdxUlFdbkPktInfo  *fdbkPktInfo;
+   S16               ret = ROK;
+   
+   udxSap = PJ_GET_UL_UDX_SAP(gCb);
+
+   TRC3(pjUtlUlSndUlRohcFdbk)
+   
+   RLOG0(L_DEBUG, "pjUtlUlSndUlRohcFdbk()");
+
+   PJ_ALLOC_BUF_SHRABL(udxSap->pst, fdbkPktInfo,
+      sizeof (UdxUlFdbkPktInfo), ret);
+   if(ret != ROK)
+   {
+      fdbkPktInfo= NULLP;
+   }
+
+   if(fdbkPktInfo != NULLP)
+   {
+      fdbkPktInfo->pdcpId.ueId   =  pjRbCb->ueCb->key.ueId;
+      fdbkPktInfo->pdcpId.cellId =  pjRbCb->ueCb->key.cellId;
+      fdbkPktInfo->pdcpId.rbId   =  pjRbCb->rbId;
+      fdbkPktInfo->pdcpId.rbType =  pjRbCb->rbType;
+      fdbkPktInfo->fbPkt = fbPkt;
+
+      PjUlUdxUlFdbkPktInfo(&(udxSap->pst), udxSap->spId, fdbkPktInfo);
+   }
+   else
+   {
+      PJ_FREE_BUF(fbPkt);
+   }
+
+   RETVALUE(ROK);
+}/* end of pjUtlUlSndUlRohcFdbk */
+
+/* pj005.201 added support for L2 Measurement */
+#ifdef LTE_L2_MEAS
+/**
+ *
+ * @brief Function to initialise measurement
+ *
+ * @b Description
+ *
+ * @param[in]  gCb     PDCP Instance Control Block
+ *
+ *  @return  Void
+ *
+ */
+S16 pjUtlL2MeasUlInit(PjCb *gCb)
+{
+   U16   cntr;
+
+   gCb->u.ulCb->pjL2Cb.pjNumMeas=0;
+   for(cntr = 0; cntr < LPJ_MAX_L2MEAS; cntr++)
+   {
+      cmMemset((U8 *)&(gCb->u.ulCb->pjL2Cb.pjL2EvtCb[cntr]), 0, sizeof(PjL2MeasEvtCb));
+   }
+   gCb->u.ulCb->pjL2Cb.pjL2EvtCb[PJ_L2MEAS_UL_LOSS].measCb.measType = LPJ_L2MEAS_UL_LOSS;
+   gCb->u.ulCb->pjL2Cb.pjL2EvtCb[PJ_L2CPU_PERCORE_STATS].measCb.measType = LPJ_L2CPU_PERCORE_STATS;
+   gCb->u.ulCb->pjL2Cb.pjL2EvtCb[PJ_L2MEM_PERPOOL_STATS].measCb.measType = LPJ_L2MEM_PERPOOL_STATS;
+   /* initialize the timer value for memory and CPU utilization */
+   gCb->u.ulCb->pjL2Cb.measTmrCfg.enb = TRUE;
+   gCb->u.ulCb->pjL2Cb.measTmrCfg.val = CM_MEM_CPU_UITL_INFO_TMR_VAL;
+   cmInitTimers(&gCb->u.ulCb->pjL2Cb.measTmr,PJ_L2_MAX_TIMERS); 
+   
+   RETVALUE(ROK);
+}
+/**
+ *
+ * @brief Handler for resetting the DL measurement counters 
+ *
+ *
+ * @b Description
+ *
+ * @param[in] measCb    Measurement Control Block.
+ *
+ *
+ * @return  Void
+ */
+#ifdef ANSI
+
+PUBLIC Void pjUtlResetUlL2MeasCntr
+(
+PjCb         *tPjCb,
+PjL2MeasCb   *measCb,
+U8           measType
+)
+#else
+PUBLIC Void pjUtlResetUlL2MeasCntr(tPjCb, measCb, measType)
+PjCb         *tPjCb;
+PjL2MeasCb   *measCb;
+U8           measType;
+#endif
+{
+   if (measCb->measType & LPJ_L2MEAS_UL_LOSS)
+   {
+      U32 qciIdx;
+      for(qciIdx = 1; qciIdx < LPJ_MAX_QCI; qciIdx++)
+      {
+         U8 qci = measCb->qci[qciIdx];
+
+         measCb->measData[qci].ulLoss.val = 0;
+         measCb->measData[qci].ulLoss.numPkts = 0;
+         tPjCb->u.ulCb->pjL2Cb.measOn[qci] &= ~LPJ_L2MEAS_UL_LOSS;
+      }
+   }
+   if (measCb->measType & LPJ_L2MEM_PERPOOL_STATS)
+   {
+     tPjCb->u.ulCb->pjL2Cb.memUtilizationMask = 0;
+     /* Clear Memory Statistics */
+     cmClearMemUtilizationCounter(&(measCb->memInfo));
+   }
+   if(measCb->measType & LPJ_L2CPU_PERCORE_STATS )
+   {
+     tPjCb->u.ulCb->pjL2Cb.cpuUtilizationMask = 0;
+   }
+
+}
+
+\f
+/**
+ *
+ * @brief Handler for Sending Negative confirm .
+ *
+ *
+ * @b Description
+ *        This function is called when the l2 measurement cannot be started
+ *        This function sends  negative confirm for all the requests
+ *
+ *  @param[in] measReqEvt    Measurement Req Structure
+ *
+ *
+ *  @return  S16
+ *      -# ROK
+ */
+
+#ifdef ANSI
+PUBLIC S16 pjUtlSndUlL2MeasNCfm
+(
+PjCb            *gCb,
+PjL2MeasCfmEvt  *measCfmEvt
+)
+#else
+PUBLIC S16 pjUtlSndUlL2MeasNCfm(gCb, measCfmEvt)
+PjCb            *gCb;
+PjL2MeasCfmEvt  *measCfmEvt;
+#endif
+{
+
+   TRC3(pjUtlSndL2MeasNCfm)
+
+   PjMiLpjL2MeasCfm(&gCb->pjGenCfg.lmPst, measCfmEvt);
+
+   RETVALUE(ROK);
+} /* pjUtlSndL2MeasNCfm */
+
+/**
+ *
+ * @brief Handler for storing address of MeasData in rbCb at right index
+ *
+ *
+ * @b Description
+ *        Handler for storing address of MeasData in rbCb at right index.
+ *
+ *  @param[in] 
+ *  @param[out] 
+ *  @param[in] 
+ *
+ *
+ *  @return  S16
+ *      -# ROK
+ */
+#ifdef ANSI
+PUBLIC Void pjUtlPlcMeasDatInUlL2Sts
+(
+PjL2Cntr       *measData, 
+PjL2MeasRbCb   *rbL2Cb,
+U8             measType
+)
+#else
+PUBLIC Void pjUtlPlcMeasDatInUlL2Sts(measData, rbL2Cb, measType)
+PjL2Cntr       *measData; 
+PjL2MeasRbCb   *rbL2Cb;
+U8             measType;
+#endif
+{
+   TRC3(pjUtlPlcMeasDatInUlL2Sts)
+   
+   /* We should check the number of measType in the request. This can be done 
+    * by looking at each bit in the measType. Also store the measData in the 
+    * correct index of l2Sts in RbCb.
+    * */
+
+    if(measType & LPJ_L2MEAS_UL_LOSS)
+    {
+         rbL2Cb->l2Sts[PJ_L2MEAS_UL_LOSS] = measData;
+    }
+
+}/* End of pjUtlPlcMeasDatInUlL2Sts */
+#endif /* LTE_L2_MEAS */
+
+
+/**
+@brief 
+This function processes Data Resume request received from the Application.
+ *  @param[in] gCb      PDCP Instance Control block 
+ *  @param[in] ueCb     Uplink UeCb 
+ *  @return S16
+ *      -# Success : ROK
+ *      -# Failure : RFAILED
+*/
+#ifdef ANSI
+PUBLIC S16 pjUtlUlPrcsDatResume
+(
+PjCb                 *gCb,
+CpjDatResumeReqInfo  *datResReq
+)
+#else
+PUBLIC S16 pjUtlUlPrcsDatResume(gCb, datResReq)
+PjCb                 *gCb;
+CpjDatResumeReqInfo  *datResReq;
+#endif
+{
+   U8 rbCnt;
+   PjUlRbCb *pjRbCb = NULLP;
+   PjUlUeCb *ueCb= NULLP;
+   
+   pjDbmFetchUlUeCb(gCb, datResReq->ueId, datResReq->cellId, &ueCb);
+   if(!ueCb)
+   {
+      RLOG_ARG1(L_ERROR, DBG_CELLID, datResReq->cellId,"UeId[%u] not found",
+            datResReq->ueId);
+      RETVALUE(RFAILED);
+   }   
+
+   for(rbCnt = 0; rbCnt < PJ_MAX_DRB_PER_UE; rbCnt ++)
+   {
+      /* Check of rbCb available */
+      if( (pjRbCb = ueCb->drbCb[rbCnt]) == NULLP)
+      {
+         continue;
+      }
+#ifdef LTE_L2_MEAS
+      pjRbCb->ulCb.nxtSubSn = (pjRbCb->ulCb.rxNext % (1 << pjRbCb->snLen));
+#endif
+
+      /* Process the packets in dlPktQ */
+      pjUlmProcessUlPktQ(gCb, pjRbCb);
+      pjRbCb->state = PJ_STATE_NORMAL;
+   }
+   ueCb->libInfo.state = PJ_STATE_NORMAL;
+   RETVALUE(ROK);
+}
+
+PUBLIC Void pjUtlEmptyUlPktList(PjCb *gCb, PjUlRbCb *pjRbCb)
+{
+   PjUlPkt *ulPkt;
+   CmLListCp *ulPktLst = &pjRbCb->ulCb.ulPktLst;
+   while(ulPktLst->first)
+   {
+      ulPkt = (PjUlPkt *)(ulPktLst->first->node);
+      cmLListDelFrm(ulPktLst, ulPktLst->first);
+      PJ_FREE_BUF(ulPkt->pdu);
+      PJ_FREE(gCb, ulPkt, sizeof(PjUlPkt));
+   }
+   RETVOID;
+}
+
+void dumpPDCPUlRbInformation(PjUlRbCb* ulRbCb, U16 ueId)
+{
+   PjUlCb* ulCb = &ulRbCb->ulCb;
+
+#ifndef ALIGN_64BIT
+   RTLIN_DUMP_DEBUG("UE [%u] PDCP UL RB numEntries = %lu\n",ueId, ulCb->recBuf.numEntries);
+#else
+   RTLIN_DUMP_DEBUG("UE [%u] PDCP UL RB numEntries = %u\n",ueId, ulCb->recBuf.numEntries);
+#endif
+}
+
+
+void DumpPDCPUlDebugInformation(void)
+{
+   PjCb* ulInst = pjCb[0]; /* TODO: check whether UL is 0 or 1 */
+
+   PjUlgCb* ulgCb = ulInst->u.ulCb;
+
+   PjUlUeCb *ueCb = NULLP; 
+   RTLIN_DUMP_DEBUG("PDCP UL Information\n");
+   RTLIN_DUMP_DEBUG("===================\n");
+   
+   /* Until no more ueCb is ueLstCp hash list get and delete ueCb */
+   while (ROK == cmHashListGetNext(&ulgCb->ueLstCp, 
+                                   (PTR) ueCb, 
+                                   (PTR *)&ueCb))
+   {
+      U32 i;
+      for(i = 0; i < PJ_MAX_SRB_PER_UE; i++)
+      {
+         PjUlRbCb* rbCb = ueCb->srbCb[i];
+         if(rbCb != NULLP)
+         {
+            dumpPDCPUlRbInformation(rbCb, ueCb->key.ueId);
+         }
+      }
+      for(i = 0; i < PJ_MAX_DRB_PER_UE; i++)
+      {
+         PjUlRbCb* rbCb = ueCb->drbCb[i];
+         if(rbCb != NULLP)
+         {
+            dumpPDCPUlRbInformation(rbCb, ueCb->key.ueId);
+         }
+      }
+   }/* end while */   
+}
+
+#ifdef TENB_DPDK_BUF
+
+#ifdef ANSI
+PUBLIC S16 pjUpdRxEntBuf
+(
+PjRxEnt    *rxEnt
+)
+#else
+PUBLIC S16 pjUpdRxEntBuf(rxEnt)
+PjRxEnt    *rxEnt;
+#endif
+{
+   MsgLen    msgLen;
+   Data      *dpdkFBuf;
+
+#define PDCP_NW_OFFSET 8
+
+   TRC2(pjUpdRxEntBuf)
+
+
+   RETVALUE(ROK);
+}
+
+#endif  /* TENB_DPDK_BUF */
+#ifdef ANSI
+PRIVATE S16 pjUtlUlHdlSecInitCfm
+(
+PjCb        *gCb,              /* Pointer to PJ DL Control Block */
+PjUlUeCb      *ueCb,           /* Pointer to UeCb */ 
+U16         txIdx,             /* Transaction Index for UeCb */
+PjAsyncCfm       *asyncCfm,    /* Async Confirm */
+CpjSecCfgCfmInfo *secCfgCfm,   /* Security config confirm */
+CpjReEstCfmInfo  *reEstCfm     /* Reest config confirm */
+)
+#else
+PRIVATE S16 pjUtlUlHdlSecInitCfm(gCb,ueCb,txIdx, asyncCfm,secCfgCfm,reEstCfm)
+(                              
+PjCb        *gCb;              /* Pointer to PJ DL Control Block */
+PjUlUeCb      *ueCb;           /* Pointer to UeCb */ 
+U16         txIdx;             /* Transaction Index for UeCb */
+PjAsyncCfm       *asyncCfm;    /* Async Confirm */
+CpjSecCfgCfmInfo *secCfgCfm;   /* Security config confirm */
+CpjReEstCfmInfo  *reEstCfm;    /* Reest config confirm */
+)
+#endif   
+{
+   TRC3(pjUtlUlHdlSecInitCfm)
+
+   if(asyncCfm->libInitBitMask == 0)
+   {
+      PJ_CHK_RESTART_OBD_TIMER(gCb,ueCb, txIdx);
+      if(ueCb->libInfo.state == PJ_STATE_NORMAL)
+      {
+         /* Send security config confirm */
+         PJ_ALLOC(gCb,secCfgCfm, sizeof(CpjSecCfgCfmInfo));
+#if (ERRCLASS & ERRCLS_DEBUG)
+         if (secCfgCfm == NULLP)
+         {
+            RLOG0(L_FATAL, "Memory Allocation failed.");
+            RETVALUE(RFAILED);
+         }
+#endif /* (ERRCLASS & ERRCLS_DEBUG) */
+         PJ_FILL_SEC_CFM_INFO(secCfgCfm, asyncCfm);
+
+         PJ_CLEAN_AND_UPD_ASYNCINFO(gCb,ueCb, txIdx);
+
+         PjUiCpjSecCfgCfm(&gCb->u.ulCb->cpjSap.pst, gCb->u.ulCb->cpjSap.suId, secCfgCfm);
+      }
+      else if(ueCb->libInfo.state == PJ_STATE_REEST)
+      {
+         /* Send ReEstCfm */
+         PJ_ALLOC(gCb,reEstCfm, sizeof(CpjReEstCfmInfo));
+#if (ERRCLASS & ERRCLS_DEBUG)
+         if (reEstCfm == NULLP)
+         {
+            RLOG0(L_FATAL, "Memory Allocation failed.");
+            RETVALUE(RFAILED);
+         }
+#endif /* (ERRCLASS & ERRCLS_DEBUG) */
+
+         PJ_FILL_REEST_CFM_INFO(reEstCfm, asyncCfm, LCM_PRIM_OK);
+
+         /* Some house keeping work */
+         PJ_CLEAN_AND_UPD_ASYNCINFO(gCb,ueCb, txIdx);
+
+#ifdef PJ_SEC_ASYNC            
+         /*Change the state from REEST to NORMAL*/
+         ueCb->libInfo.reEstCfmSent = TRUE;
+#endif
+         PjUiCpjReEstCfm(&gCb->u.ulCb->cpjSap.pst, gCb->u.ulCb->cpjSap.suId, reEstCfm);
+      }
+   }
+
+ RETVALUE(ROK);
+}
+
+
+#ifdef ANSI
+PRIVATE S16 pjUtlUlHdlCmpInitCfm
+(
+PjCb           *gCb,            /* Pointer to PJ DL Control Block */
+PjUlUeCb       *ueCb,           /* Pointer to UeCb */ 
+U16            txIdx,           /* Transaction Index for UeCb */
+PjAsyncCfm     *asyncCfm,       /* Async Confirm */
+CpjCfgCfmInfo  *cfgCfm         /* UDX Config Confirm */
+)
+#else
+PRIVATE S16 pjUtlUlHdlCmpInitCfm(gCb,ueCb,txIdx,asyncCfm,cfgCfm)
+(                              
+PjCb           *gCb;            /* Pointer to PJ DL Control Block */
+PjUlUeCb       *ueCb;           /* Pointer to UeCb */ 
+U16            txIdx;           /* Transaction Index for UeCb */
+PjAsyncCfm     *asyncCfm;       /* Async Confirm */
+CpjCfgCfmInfo  *cfgCfm;         /* UDX Config Confirm */
+)
+#endif   
+{
+   U32               idx;
+
+   TRC3(pjUtlUlHdlCmpInitCfm)
+
+      if(asyncCfm->cmpInitBitMask == 0)
+      {
+         asyncCfm->libInitBitMask ^= (PJ_LIB_COMP_BIT_MASK);
+
+         if((asyncCfm->libInitBitMask == 0) &&
+               !(asyncCfm->cfmType & PJ_CFG_REEST_ASYNC_CFM))
+         {
+
+            /* Send config confirm */
+            PJ_ALLOC(gCb,cfgCfm, sizeof(CpjCfgCfmInfo));
+#if (ERRCLASS & ERRCLS_ADD_RES)
+            if (cfgCfm == NULLP)
+            {
+               RLOG0(L_FATAL, "Memory Allocation failed.");
+               RETVALUE(RFAILED);
+            }
+#endif /* ERRCLASS & ERRCLS_ADD_RES */
+            cfgCfm->transId = asyncCfm->transId;
+            cfgCfm->ueId    = asyncCfm->ueId;
+            cfgCfm->cellId  = asyncCfm->cellId;
+            cfgCfm->numEnt  = asyncCfm->numEnt; 
+            for ( idx = 0; idx < asyncCfm->numEnt; idx++ )
+            {
+               cfgCfm->cfmEnt[idx].status = asyncCfm->cfmEnt[idx].status;  
+               cfgCfm->cfmEnt[idx].reason = asyncCfm->cfmEnt[idx].reason;  
+               cfgCfm->cfmEnt[idx].rbId   = asyncCfm->cfmEnt[idx].rbId;
+               cfgCfm->cfmEnt[idx].rbType = asyncCfm->cfmEnt[idx].rbType;
+            }
+
+            /* Some house keeping work */
+            PJ_CHK_RESTART_OBD_TIMER(gCb,ueCb, txIdx);
+            PJ_CLEAN_AND_UPD_ASYNCINFO(gCb,ueCb, txIdx);
+
+            /* Send confirmtion to the User */
+            PjUiCpjCfgCfm(&(gCb->u.ulCb->cpjSap.pst), gCb->u.ulCb->cpjSap.suId, cfgCfm);
+         }
+      }
+   RETVALUE(ROK);
+}   
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+/********************************************************************30**
+         End of file
+**********************************************************************/