--- /dev/null
+/*******************************************************************************
+################################################################################
+# 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
+**********************************************************************/