X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=src%2F5gnrpdcp%2Fpj_dl_utl.c;fp=src%2F5gnrpdcp%2Fpj_dl_utl.c;h=b236af701e25ade3b5b9e1c05eba5268e3c7f2fe;hb=9ffd4692faec97b8457ef0428549b7bfa7a6bb82;hp=0000000000000000000000000000000000000000;hpb=5625a52ad68f6ad93684e68bbbdbaef0d462cf9a;p=o-du%2Fl2.git diff --git a/src/5gnrpdcp/pj_dl_utl.c b/src/5gnrpdcp/pj_dl_utl.c new file mode 100755 index 000000000..b236af701 --- /dev/null +++ b/src/5gnrpdcp/pj_dl_utl.c @@ -0,0 +1,2710 @@ +/******************************************************************************* +################################################################################ +# 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_dl_utl.c + +**********************************************************************/ + static const char* RLOG_MODULE_NAME="PDCP"; +static int RLOG_MODULE_ID=1024; +static int RLOG_FILE_ID=218; + +/** @file pj_dl_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_dl.h" +#include "pj_err.h" /* Error defines */ +#include "pj_udx.h" +#include "pj_ptsec.h" + +/* 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" +#include "pj_udx.x" +#include "pj_dl.x" +#include "pj_lib.x" /* LIB */ + + +EXTERN CmLListCp pjMsCiphQ; +EXTERN CmLListCp pjMsDeCiphQ; +#ifndef XEON_SPECIFIC_CHANGES +EXTERN U32 dbgPdcpMemCount,pdcpdrop, dbgSpaccThreshHoldDropCnt; +EXTERN U32 dbgPdcpQSizeThreshHoldDropCnt; +U32 spaccDropCount = 0; +EXTERN U32 pjMsDlSpaccQCnt; +EXTERN U32 pjMsUlSpaccQCnt; +#endif +#ifdef __cplusplus +EXTERN "C" { +#endif /* __cplusplus */ + +#ifdef INTEL_SW_SEC +EXTERN S16 PjLibObdSwCipherReq(PjLibTrans *libTrans, Buffer *mBuf, PjCb *gCb, Buffer **opSdu); + +EXTERN S16 pjSendToSwCipherFB ARGS((PjLibTrans *libTrans, FlatBuffer *mBuf, + PjCb *gCb, Buffer **opSdu)); +#endif + +PUBLIC S16 pjUtlReEstDl +( +PjCb *gCb, +PjDlUeCb *ueCb /* UE Control Block */ +); + +PRIVATE S16 pjUtlDlHdlSecInitCfm ARGS((PjCb *gCb,PjDlUeCb *ueCb, + U16 txIdx,PjAsyncCfm *asyncCfm, UdxSecCfgCfmInfo *secCfgCfm,UdxReEstCfmInfo *reEstCfm)); +PRIVATE S16 pjUtlDlHdlCmpInitCfm ARGS((PjCb *gCb,PjDlUeCb *ueCb, + U16 txIdx,PjAsyncCfm *asyncCfm, UdxCfgCfmInfo *cfgCfm)); + +/** + * + * @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 pjUtlDlUpdUpSecKeys +( +PjCb *gCb, +PjDlUeCb *ueCb /* UE Control Block */ +) +#else +PUBLIC S16 pjUtlDlUpdUpSecKeys(gCb,ueCb) +PjCb *gCb; +PjDlUeCb *ueCb; /* UE Control Block */ +#endif +{ + Void *tmpUpCxt; + + TRC2(pjUtlDlUpdUpSecKeys); + + RLOG2(L_DEBUG, "pjUtlReEstReconfig(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 + + pjUtlDlUpInit(gCb,ueCb); + pjUtlDlCipherClose(gCb,tmpUpCxt); + } + + RETVALUE(ROK); +} /* pjUtlDlUpdUpSecKeys */ + +/** + * + * @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 pjUtlDlUpdCpSecKeys +( +PjCb *gCb, +PjDlUeCb *ueCb /* UE Control Block */ +) +#else +PUBLIC S16 pjUtlDlUpdCpSecKeys(gCb,ueCb) +PjCb *gCb; +PjDlUeCb *ueCb; /* UE Control Block */ +#endif +{ + Void *tmpIntCxt; + Void *tmpCpCxt; + + TRC2(pjUtlDlUpdCpSecKeys); + + RLOG2(L_DEBUG, "pjUtlReEstReconfig(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 + + pjUtlDlCpInit(gCb,ueCb); + pjUtlDlIntInit(gCb,ueCb); + + pjUtlDlIntClose(gCb,tmpIntCxt); + pjUtlDlCipherClose(gCb,tmpCpCxt); + + } + + RETVALUE(ROK); + +} /* pjUtlDlUpdCpSecKeys */ + +/******************************************************************** + * Utility Handler for Sending to Offboarding unit * + *******************************************************************/ + +/** + * + * @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 pjUtlDlCmpInit +( +PjCb *gCb, +PjDlRbCb *pjRbCb /* PDCP RbCb */ +) +#else +PUBLIC S16 pjUtlDlCmpInit(pjRbCb) +PjCb *gCb; +PjDlRbCb *pjRbCb; /* PDCP RbCb */ +#endif +{ + TRC3(pjUtlDlCmpInit) + + RLOG2(L_DEBUG, "pjUtlDlCmpInit(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 */ + + + +/** + * + * @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 pjUtlDlIntInit +( +PjCb *gCb, +PjDlUeCb *ueCb /* UE CB Ptr */ +) +#else +PUBLIC S16 pjUtlDlIntInit(*gCb, *ueCb) +PjCb *gCb; +PjDlUeCb *ueCb; /* UE CB Ptr */ +#endif +{ + + S16 ret=ROK; + Void *ctxId = NULLP; +#ifdef PJ_SEC_ASYNC + U8 txIdx; + U32 *libInitBitMask = NULLP; +#endif + + TRC3(pjUtlDlIntInit) + + RLOG2(L_DEBUG, "pjUtlDlIntInit(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_INSTANCE + pjLibIntInitReq(gCb->u.dlCb->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 /* INTEL_QAT_DP */ +#endif /* PJ_SEC_ASYNC */ + + RETVALUE(ret); + +} /* end of pjUtlIntInit */ + +/** + * + * @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 pjUtlDlCpInit +( +PjCb *gCb, +PjDlUeCb *ueCb /* UE CB Ptr */ +) +#else +PUBLIC S16 pjUtlDlCpInit(*gCb, *ueCb) +PjCb *gCb; +PjDlUeCb *ueCb; /* UE CB Ptr */ +#endif +{ + Void *ctxId = NULLP; +#ifdef PJ_SEC_ASYNC + U8 txIdx; + U32 *libInitBitMask = NULLP; +#endif + S16 ret = ROK; + + TRC3(pjUtlDlCpInit) + + 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.dlCb->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 pjUtlDlUpInit +( +PjCb *gCb, +PjDlUeCb *ueCb /* UE CB Ptr */ +) +#else +PUBLIC S16 pjUtlDlUpInit(*gCb,*ueCb) +PjCb *gCb; +PjDlUeCb *ueCb; /* UE CB Ptr */ +#endif +{ + + Void *ctxId = NULLP; +#ifdef PJ_SEC_ASYNC + U8 txIdx; + U32 *libInitBitMask = NULLP; +#endif + S16 ret = ROK; + + TRC3(pjUtlDlUpInit) + + 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.dlCb->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(ret); +} /* end of pjUtlUpInit */ + + + +/** + * + * @brief + * + * Handler for redirecing ciphering request to either synchronous + * or asynchronous module. + * + * @b Description: + * + * This function sends ciphering protection 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 + * + */ +//#ifdef TENB_AS_SECURITY +#ifdef ANSI +PUBLIC S16 pjUtlCipherReq +( +PjCb *gCb, +PjDlRbCb *pjRbCb, /* PDCP RbCb */ +U32 count, /* Input parameters for deciphering */ +Buffer *mBuf, /* Data to be deciphered */ +Buffer **opSdu /* Deciphered SDU */ +) +#else +PUBLIC S16 pjUtlCipherReq(gCb, pjRbCb, count, mBuf, opSdu) +PjCb *gCb, +PjDlRbCb *pjRbCb; /* PDCP RbCb */ +U32 count; /* Input parameters for deciphering */ +Buffer *mBuf; /* Data to be deciphered */ +Buffer **opSdu; /* Deciphered SDU */ +#endif +{ + S16 ret = ROK; + PjDlUeCb *dlUeCb; + PjLibTrans libTrans; /* Transaction Id for deciphering */ + +#if PJ_SEC_ASYNC + Void *cxtId; /* Context Identifier */ +#endif + + TRC3(pjUtlCipherReq) + + dlUeCb = pjRbCb->ueCb; + libTrans.pdcpInstance = gCb->init.inst; + libTrans.count = count; + + libTrans.rbId = pjRbCb->rbId - 1; + libTrans.dir = PJ_SEC_DIR_DL; + libTrans.rbType = pjRbCb->rbType; + libTrans.snLen = pjRbCb->snLen; + libTrans.ciphAlgoType = dlUeCb->secInfo.cipherInfo.algoType; + libTrans.ueCb = (PTR)dlUeCb; + libTrans.ueId = dlUeCb->key.ueId; + libTrans.cellId = dlUeCb->key.cellId; + if(PJ_SRB == pjRbCb->rbType) + { + libTrans.key = dlUeCb->secInfo.cipherInfo.cpKey; +#ifdef INTEL_QAT_DP + libTrans.sessCxtId = dlUeCb->secInfo.cpCiphSessCxtId; +#ifdef QAT_TWO_INSTANCE + libTrans.instHndl = gCb->u.dlCb->instHndl; +#else + libTrans.instHndl = gCb->instHndl; +#endif +#endif + } + else + { + libTrans.key = dlUeCb->secInfo.cipherInfo.upKey; +#ifdef INTEL_QAT_DP + libTrans.sessCxtId = dlUeCb->secInfo.upCiphSessCxtId; +#ifdef QAT_TWO_INSTANCE + libTrans.instHndl = gCb->u.dlCb->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_DL_OBD_TMR)) == FALSE) + { + pjStartTmr(gCb, (PTR)pjRbCb, PJ_EVT_DL_OBD_TMR); + } + + if (pjRbCb->rbType == PJ_SRB) + { + cxtId = pjRbCb->ueCb->secInfo.cpCxtId; + } + else + { + cxtId = pjRbCb->ueCb->secInfo.upCxtId; + } + + ret = PjLibObdCipherReq(&(gCb->pjGenCfg.obdPst.secPst), cxtId, + secInp, libTrans, mBuf); + +#else +#ifdef INTEL_SW_SEC + ret = PjLibObdSwCipherReq(&libTrans, mBuf, gCb,opSdu); +#else + ret = PjLibObdCipherReq(&libTrans, mBuf, opSdu); +#endif /* INTEL_SW_SEC */ +#endif + + RETVALUE(ret); + +} + + +#ifdef FLAT_BUFFER_OPT +/** + * + * @brief + * + * Handler for redirecing ciphering request to either synchronous + * or asynchronous module. + * + * @b Description: + * + * This function sends ciphering protection 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 Flat Buffer to be deciphered + * @param[in] opSdu Deciphered SDU + * + * @return S16 + * -# ROK + * + */ + +#ifdef ANSI +PUBLIC S16 pjUtlCipherReqFB +( +PjCb *gCb, +PjDlRbCb *pjRbCb, /* PDCP RbCb */ +U32 count, /* Input parameters for deciphering */ +FlatBuffer *mBuf, /* Data to be deciphered */ +Buffer **opSdu /* Deciphered SDU */ +) +#else +PUBLIC S16 pjUtlCipherReqFB(gCb, pjRbCb, count, mBuf, opSdu) +PjCb *gCb, +PjDlRbCb *pjRbCb; /* PDCP RbCb */ +U32 count; /* Input parameters for deciphering */ +FlatBuffer *mBuf; /* Data to be deciphered */ +Buffer **opSdu; /* Deciphered SDU */ +#endif +{ + S16 ret = ROK; +#ifdef PJ_SEC_ASYNC + Void *cxtId; /* Context Identifier */ +#endif + PjDlUeCb *dlUeCb; + PjLibTrans libTrans; + + TRC3(pjUtlCipherReqFB) + +#ifdef PJ_SEC_ASYNC + cxtId = pjRbCb->ueCb->secInfo.upCxtId; +#endif + + dlUeCb = pjRbCb->ueCb; + libTrans.pdcpInstance = gCb->init.inst; + libTrans.count = count; + + libTrans.rbId = pjRbCb->rbId - 1; + libTrans.dir = PJ_SEC_DIR_DL; + libTrans.rbType = pjRbCb->rbType; + libTrans.snLen = pjRbCb->snLen; + libTrans.ciphAlgoType = dlUeCb->secInfo.cipherInfo.algoType; + libTrans.ueCb = (PTR)dlUeCb; + libTrans.ueId = dlUeCb->key.ueId; + libTrans.cellId = dlUeCb->key.cellId; + if(PJ_SRB == pjRbCb->rbType) + { + libTrans.key = dlUeCb->secInfo.cipherInfo.cpKey; +#ifdef INTEL_QAT_DP + libTrans.sessCxtId = dlUeCb->secInfo.cpCiphSessCxtId; +#ifdef QAT_TWO_INSTANCE + libTrans.instHndl = gCb->u.dlCb->instHndl; +#else + libTrans.instHndl = gCb->instHndl; +#endif +#endif + } + else + { + libTrans.key = dlUeCb->secInfo.cipherInfo.upKey; +#ifdef INTEL_QAT_DP + libTrans.sessCxtId = dlUeCb->secInfo.upCiphSessCxtId; +#ifdef QAT_TWO_INSTANCE + libTrans.instHndl = gCb->u.dlCb->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_DL_OBD_TMR)) == FALSE) + { + pjStartTmr(gCb, (PTR)pjRbCb, PJ_EVT_DL_OBD_TMR); + } + + ret = PjLibObdCipherReq(&(gCb->pjGenCfg.obdPst.secPst), cxtId, + secInp, libTrans, mBuf); + +#else +#ifndef INTEL_SW_SEC + ret = PjLibObdCipherReqFB(&libTrans, mBuf, opSdu); +#else + ret = pjSendToSwCipherFB(&libTrans, mBuf,gCb,opSdu); +#endif +#endif + + RETVALUE(ret); + +} +#endif + + +/** + * + * @brief + * + * Handler for redirecing Integration request to either synchronous + * or asynchronous module. + * + * @b Description: + * + * This function sends Intergrity protection 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] macI Message authentication code for the SDU + * + * @return S16 + * -# ROK + * + */ +#ifdef ANSI +PUBLIC S16 pjUtlIntProtReq +( +PjCb *gCb, +PjDlRbCb *pjRbCb, /* PDCP RbCb */ +PjSecInp secInp, /* Input parameters for integrity */ +Buffer **mBuf /* SDU to be compressed */ +) +#else +PUBLIC S16 pjUtlIntProtReq(gCb, pjRbCb, secInp, mBuf) +PjCb *gCb; +PjDlRbCb *pjRbCb; /* PDCP RbCb */ +PjSecInp secInp; /* Input parameters for integrity */ +Buffer **mBuf; /* SDU to be compressed */ +#endif +{ + S16 ret = ROK; + PjDlUeCb *dlUeCb; + PjLibTrans libTrans; +#if PJ_SEC_ASYNC + Void *cxtId; /* Context Identifier */ +#endif + + TRC3(pjUtlIntProtReq) + +#if PJ_SEC_ASYNC + cxtId = pjRbCb->ueCb->secInfo.intCxtId; +#endif + + dlUeCb = pjRbCb->ueCb; + libTrans.pdcpInstance = gCb->init.inst; + libTrans.count = secInp.count; + libTrans.rbId = pjRbCb->rbId - 1; + libTrans.dir = secInp.dir; + libTrans.rbType = pjRbCb->rbType; + /*pSecInfo.snLen = pjRbCb->snLen;*/ + libTrans.intAlgoType = dlUeCb->secInfo.intInfo.algoType; + libTrans.ueCb = (PTR)dlUeCb; + libTrans.ueId = dlUeCb->key.ueId; + libTrans.cellId = dlUeCb->key.cellId; + libTrans.key = &(dlUeCb->secInfo.intInfo.intKey[0]); + PJ_SEC_FILL_FRESH(libTrans.fresh, libTrans.rbId); + +#ifdef INTEL_QAT_DP + libTrans.sessCxtId = dlUeCb->secInfo.cpIntSessCxtId; +#ifdef QAT_TWO_INSTNACES + libTrans.instHndl = gCb->u.dlCb->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_DL_OBD_TMR)) == FALSE) + { + pjStartTmr(gCb, (PTR)pjRbCb, PJ_EVT_DL_OBD_TMR); + } + + ret = PjLibObdIntProtReq(&(gCb->pjGenCfg.obdPst.secPst), cxtId, + secInp, libTrans, mBuf); + +#else +#ifdef INTEL_SW_INTEG + ret = PjLibObdIntProtReq(gCb, &libTrans, mBuf); +#else + ret = PjLibObdIntProtReq(&libTrans, mBuf); +#endif /* INTEL_SW_INTEG */ +#endif + + RETVALUE(ret); + +} /* end of pjUtlIntProtReq */ + +//#endif + + +/** + * + * @brief + * + * Handler for closing the DL context with the Ciphering unit (either + * synchronous or asynchronous) for SRBs of an UE. + * + * @b Description: + * + * This function closes an existing DL 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 pjUtlDlCipherClose +( +PjCb *gCb, +Void *cpCxtId /* Context Id for Ciphering to be closed */ +) +#else +PUBLIC S16 pjUtlDlCipherClose(gCb, cpCxtId) +PjCb *gCb; +Void *cpCxtId; /* Context Id for Ciphering to be closed */ +#endif +{ +#ifdef INTEL_QAT_DP + S16 ret; +#endif + TRC3(pjUtlDlCipherClose) + + RLOG0(L_DEBUG, "pjUtlDlCipherClose"); + +#ifndef PJ_SEC_ASYNC +#ifdef INTEL_QAT_DP +#ifdef QAT_TWO_INSTANCE + ret = PjLibObdCipherCloseReq(gCb->u.dlCb->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.dlCb->instHndl, cpCxtId); +#else + ret = PjLibObdCipherCloseReq(gCb->instHndl, cpCxtId); +#endif +#else + PjLibObdCipherCloseReq(&gCb->pjGenCfg.obdPst.secPst, cpCxtId); +#endif +#endif + +#ifdef INTEL_QAT_DP + RETVALUE(ret); +#else + RETVALUE(ROK); +#endif + +} /* end of pjUtlCipherClose */ + + +/** + * + * @brief + * + * Handler for closing the DL context with the Integration unit (either + * synchronous or asynchronous) for all RBs of an UE. + * + * @b Description: + * + * This function closes an existing DL 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 pjUtlDlIntClose +( +PjCb *gCb, +Void *intCxtId /* Integration CxtId to be closed */ +) +#else +PUBLIC S16 pjUtlDlIntClose(gCb, intCxtId) +PjCb *gCb; +Void *intCxtId; /* Integration CxtId to be closed */ +#endif +{ +#ifdef INTEL_QAT_DP + S16 ret = ROK; +#endif + TRC3(pjUtlDlIntClose) + + RLOG0(L_DEBUG, "pjUtlDlIntClose"); + +#ifdef PJ_SEC_ASYNC + PjLibObdIntCloseReq(&gCb->pjGenCfg.obdPst.secPst,intCxtId); +#else +#ifdef INTEL_QAT_DP +#ifdef QAT_TWO_INSTANCE + ret = PjLibObdIntCloseReq(gCb->u.dlCb->instHndl,intCxtId); +#else + ret = PjLibObdIntCloseReq(gCb->instHndl,intCxtId); +#endif +#else + PjLibObdIntCloseReq(intCxtId); +#endif /* INTEL_QAT_DP */ +#endif /* PJ_SEC_ASYNC */ + +#ifdef INTEL_QAT_DP + RETVALUE(ret); +#else + RETVALUE(ROK); +#endif + +} /* end of pjUtlIntClose */ + + +/** + * + * @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 pjUtlDlCmpReset +( +PjCb *gCb, +PjDlRbCb *pjRbCb /* Context to be reset for compression */ +) +#else +PUBLIC S16 pjUtlDlCmpReset(pjRbCb) +PjCb *gCb; +PjDlRbCb *pjRbCb; /* Context to be reset for compression */ +#endif +{ + TRC3(pjUtlDlCmpReset) + + RLOG2(L_DEBUG, "pjUtlCmpReset(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 + * Handle re-establishment on SRB1. + * + * @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] gCb PDCP Instance control block + * @param[in] pjRbCb Downlink Rb control block + * + * @return S16 + * -# ROK + * -# RFAILED + * + */ +#ifdef ANSI +PUBLIC S16 pjUtlDlReEstSrb1 +( +PjCb *gCb, +PjDlRbCb *pjRbCb /* PDCP Control Block Pointer */ +) +#else +PUBLIC S16 pjUtlDlReEstSrb1(gCb, pjRbCb) +PjCb *gCb; +PjDlRbCb *pjRbCb; /* PDCP Control Block Pointer */ +#endif +{ + PjDlUeCb *ueCb; + + TRC2(pjUtlDlReEstSrb1) + + 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 */ + + pjUtlDlUpdCpSecKeys(gCb,ueCb); + + /* Perform downlink reestablishment of SRB1 */ + pjDlmReEstSrb(gCb,pjRbCb); + + /* If Only SRB1 configured then we can update userplane + keys also */ + if ((ueCb->numSrbs == 1) && (ueCb->numDrbs == 0)) + { + pjUtlDlUpdUpSecKeys(gCb,ueCb); + } + + RETVALUE(ROK); +} /* pjUtlReEstSrb1 */ + + +/** + * + * @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 pjUtlDlReEstHO +( +PjCb *gCb, +PjDlUeCb *ueCb /* Number of RBs undergoing reestablishment*/ +) +#else +PUBLIC S16 pjUtlDlReEstHO(gCb,ueCb) +PjCb *gCb; +PjDlUeCb *ueCb; /* Number of RBs undergoing reestablishment*/ +#endif +{ + U8 rbCnt; + PjDlRbCb **rbCbLst; + PjDlRbCb * pjRbCb; + + TRC2 (pjUtlDlReEstHO); + +#ifdef ALIGN_64BIT + RLOG2(L_DEBUG, "pjUtlReEstHO(ueCb(%d,%d))",ueCb->key.ueId, ueCb->key.cellId); +#else + RLOG2(L_DEBUG, "pjUtlReEstHO(ueCb(%d,%d))",ueCb->key.ueId, ueCb->key.cellId); +#endif + + /* Initialisations */ + ueCb->libInfo.numReEstDrb = 0; + ueCb->libInfo.state = PJ_STATE_REEST_HO; + + /* Perform initialisations on the HO Info structure */ + PJ_ALLOC(gCb,ueCb->hoInfo, sizeof(PjDlHoInfo)); +#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(PjDlHoCfmInfo) * PJ_MAX_DRB_PER_UE ); +#if (ERRCLASS & ERRCLS_ADD_RES) + if (ueCb->hoInfo->hoCfmInfo == NULLP ) + { + /*ccpu00136858 */ + PJ_PST_FREE(gCb->u.dlCb->udxDlSap[0].pst.region, + gCb->u.dlCb->udxDlSap[0].pst.pool, + ueCb->hoInfo, sizeof(PjDlHoInfo)); + RLOG0(L_FATAL, "Memory Allocation failed."); + 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; + + if(pjRbCb->mode == PJ_DRB_AM) + { + pjDlmReEstHoDrbAm(gCb, pjRbCb); + } + + }/* for(rbCnt .. */ + + RETVALUE(ROK); +} /* pjUtlReEstHO */ + + +/** + * + * @brief + * + * Called after the new security algorithms have been applied + * and header compression/decompression reset. It starts + * reestablishment procedures for downlink DRBs. + * + * @b Description: + * + * This function + * 1. Creates new contexts for Ciphering and Integrity. + * 2. Closes the old contexts for Ciphering and Integrity. + * 3. Resets the ROHC unit. + * + * @param[in] ueCb UE Control Block + * + * @return S16 + * -# ROK + * -# RFAILED + * + */ +#ifdef ANSI +PUBLIC S16 pjUtlReEstDl +( +PjCb *gCb, +PjDlUeCb *ueCb /* UE Control Block */ +) +#else +PUBLIC S16 pjUtlReEstDl(gCb, ueCb) +PjCb *gCb; +PjDlUeCb *ueCb; /* UE Control Block */ +#endif +{ + TRC2(pjUtlReEstDl); + + RLOG2(L_DEBUG, "pjUtlReEstDl(ueCb(%d,%d))",ueCb->key.ueId, ueCb->key.cellId); + + + /* Send Cfms and update the state only + when there is some cfgreq cfm is present for other RBs*/ + if(ueCb->libInfo.state == PJ_STATE_REEST) + { + pjUtlDlSndReEstCfgCfm(gCb, ueCb); + } + else if(ueCb->libInfo.state == PJ_STATE_REEST_HO) + { + pjUtlDlSndSduStaCfm(gCb, ueCb); + } + ueCb->libInfo.state = PJ_STATE_NORMAL; + + RETVALUE(ROK); + +} /* pjUtlReEstDl */ + + + + +/** + * + * @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 pjUtlDlSndReEstCfgCfm +( +PjCb *gCb, +PjDlUeCb *ueCb /* UE Control Block */ +) +#else +PUBLIC S16 pjUtlDlSndReEstCfgCfm(ueCb) +PjCb *gCb; +PjDlUeCb *ueCb; /* UE Control Block */ +#endif +{ + U8 rbCnt; + PjDlRbCb *tRbCb; + CpjCfgCfmInfo *cfgCfmInfo; + U8 txIdx; + PjAsyncCfm *asyncCfm = NULLP; + PjUdxDlSapCb *udxSap; + S16 ret = ROK; + + TRC2(pjUtlDlSndReEstCfgCfm); + + RLOG2(L_DEBUG, "pjUtlSndReEstCfgCfm(ueCb(%d,%d))",ueCb->key.ueId, ueCb->key.cellId); + + ueCb->libInfo.state = PJ_STATE_NORMAL; + + /* 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); + } + + for(rbCnt = 0; rbCnt < PJ_MAX_SRB_PER_UE; rbCnt ++) + { + if( ((tRbCb = ueCb->srbCb[rbCnt]) == NULLP) || + (tRbCb->state == PJ_STATE_NORMAL)) + { + continue; + } + + /* Fetch the rbCb and intialise the states */ + tRbCb->state = PJ_STATE_NORMAL; + } + + /* Memory leak fix ccpu00135359 */ + udxSap = &(gCb->u.dlCb->udxDlSap[0]); + PJ_ALLOC_BUF_SHRABL(udxSap->pst, cfgCfmInfo, + sizeof (CpjCfgCfmInfo), ret); + if(ret != 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); + + PjDlUdxCfgCfm(&gCb->u.dlCb->udxDlSap[0].pst, + gCb->u.dlCb->udxDlSap[0].suId, + (UdxCfgCfmInfo *)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 pjUtlDlSaveCfmInfo +( +PjCb *gCb, +PjDlUeCb *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 pjUtlDlSaveCfmInfo(ueCb, cfmType, startTmr, entity, cfmPtr, cfgPtr) +PjCb *gCb; +PjDlUeCb *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(pjUtlDlSaveCfmInfo) + + 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 */ + +/** + * + * @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 pjUtlDlHdlObdInitCfm +( +PjCb *gCb, +PjDlUeCb *ueCb, /* Pointer to UeCb */ +U16 txIdx, /* Transaction Index for UeCb */ +U8 cfmType, /* Confirm type */ +U8 maskVal /* mask value */ +) +#else +PUBLIC S16 pjUtlDlHdlObdInitCfm(ueCb, txIdx, cfmType, maskVal) +PjCb *gCb; +PjDlUeCb *ueCb; /* Pointer to UeCb */ +U16 txIdx; /* Transaction Index for UeCb */ +U8 cfmType; /* Confirm type */ +U8 maskVal; /* mask value */ +#endif +{ + UdxSecCfgCfmInfo *secCfgCfm; /* Security config confirm */ + UdxReEstCfmInfo *reEstCfm; /* Reest config confirm */ + PjAsyncCfm *asyncCfm; + UdxCfgCfmInfo *cfgCfm; + U8 idx; + S16 ret; + + TRC3(pjUtlDlHdlObdInitCfm) + + RLOG_ARG4(L_DEBUG,DBG_UEID,ueCb->key.ueId, + "pjUtlHdlDlObdInitCfm cellId(%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 = pjUtlDlHdlSecInitCfm(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; + } + } + + /* Check if we can send confirm */ + if(asyncCfm->cmpInitBitMask == 0) + { + ret = pjUtlDlHdlCmpInitCfm(gCb,ueCb,txIdx,asyncCfm,cfgCfm); + } + } + RETVALUE(ret); +}/* pjUtlHdlDlObdInitCfm */ + +/** + * + * @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 pjUtlDlHdlInitObdTmrExp +( +PjCb *gCb, +PjDlUeCb *ueCb +) +#else +PUBLIC S16 pjUtlDlHdlInitObdTmrExp(ueCb) +PjCb *gCb; +PjDlUeCb *ueCb; +#endif +{ + S16 ret; /* Return Value */ + UdxSecCfgCfmInfo *secCfgCfm; /* Security Cfg Confirm Info */ + UdxCfgCfmInfo *cfgCfm; /* Config Confirm Info */ + UdxReEstCfmInfo *reEstCfm; /* Reest config confirm */ + UdxCfgCfmInfo *pjCfgCfm; + PjLibInfo *libInfo; /* Off-board Info */ + PjAsyncCfm *asyncCfm; /* Async Cfm Info */ + PjUdxDlSapCb *udxSap; + U16 txIdx; /* Tx Idx */ + U16 idx; /* Index for looping */ + U16 cfgIdx; + + TRC3(pjUtlDlHdlInitObdTmrExp) + + RLOG2(L_DEBUG, "pjUtlDlHdlInitObdTmrExp(ueCb(%d,%d))", + ueCb->key.ueId, ueCb->key.cellId); + + ret = ROK; + udxSap = &(gCb->u.dlCb->udxDlSap[0]); + 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_BUF_SHRABL(udxSap->pst,secCfgCfm, + sizeof (UdxSecCfgCfmInfo), ret); + if(ret != ROK) + { + RLOG0(L_FATAL, "Memory Allocation failed."); + RETVALUE(RFAILED); + } + 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); + + PjDlUdxSecCfgCfm((&udxSap->pst), udxSap->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); + + PjDlUdxCfgCfm(&(gCb->u.dlCb->udxDlSap[0].pst), + gCb->u.dlCb->udxDlSap[0].suId, + cfgCfm); + } + else if (asyncCfm->cfmType & PJ_REEST_ASYNC_CFM) + { + /* Send ReEstCfm */ + /* Memory leak fix ccpu00135359 */ + PJ_ALLOC_BUF_SHRABL(udxSap->pst,reEstCfm, + sizeof (UdxReEstCfmInfo), ret); + if(ret != ROK) + { + RLOG0(L_FATAL, "Memory Allocation failed."); + RETVALUE(RFAILED); + } + PJ_FILL_REEST_CFM_INFO(reEstCfm, asyncCfm, LCM_PRIM_NOK); + + PJ_CLEAN_AND_UPD_ASYNCINFO(gCb,ueCb, txIdx); + + PjDlUdxReEstCfm(&udxSap->pst, + udxSap->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); + + PjDlUdxCfgCfm(&gCb->u.dlCb->udxDlSap[0].pst, + gCb->u.dlCb->udxDlSap[0].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_ERROR, DBG_UEID,ueCb->key.ueId, + "Hash List Delete Failed for DL ueCb"); +#endif + } + + if ( asyncCfm->entity == ENTPJ ) + { + PJ_ALLOC_BUF_SHRABL(udxSap->pst,cfgCfm, + sizeof (UdxCfgCfmInfo), ret); + if(ret != ROK) + { + RLOG0(L_FATAL, "Memory Allocation failed."); + RETVALUE(RFAILED); + } + + 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(PjDlUeCb)); + PjDlUdxCfgCfm(&(udxSap->pst), udxSap->suId, cfgCfm); + } + else if ( asyncCfm->entity == ENTPJ ) + { + /* Memory leak fix ccpu00135359 */ + PJ_ALLOC_BUF_SHRABL(udxSap->pst,pjCfgCfm, + sizeof (UdxCfgCfmInfo), ret); + if(ret != ROK) + { + RLOG0(L_FATAL, "Memory Allocation failed."); + RETVALUE(RFAILED); + } + 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(PjDlUeCb)); + PjDlUdxCfgCfm(&(udxSap->pst), udxSap->suId, pjCfgCfm); + } + } + + RETVALUE(ret); +} /* pjHdlUeDelWaitTmrExp */ + + +/** + * + * @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 pjUtlDlSndSduStaCfm +( +PjCb *gCb, +PjDlUeCb *ueCb /* UE Control Block */ +) +#else +PUBLIC S16 pjUtlDlSndSduStaCfm(gCb, ueCb) +PjCb *gCb; +PjDlUeCb *ueCb; /* UE Control Block */ +#endif +{ + UdxSduStaCfmInfo *cfmInfo; + PjUdxDlSapCb *udxSap; + S16 ret = ROK; + + TRC2(pjUtlDlSndSduStaCfm); + + RLOG2(L_DEBUG, "pjUtlSndSduStaCfm(ueCb(%d,%d))",ueCb->key.ueId, ueCb->key.cellId); + + /* Perform processing for filling up cfm structures */ + /* Memory leak fix ccpu00135359 */ + udxSap = &(gCb->u.dlCb->udxDlSap[0]); + PJ_ALLOC_BUF_SHRABL(udxSap->pst, cfmInfo, + sizeof (UdxSduStaCfmInfo), ret); + if( ret != ROK) + { + RLOG0(L_FATAL, "Memory Allocation failed."); + RETVALUE(RFAILED); + } + PJ_FILL_DL_SDU_CFM_INFO(gCb,cfmInfo, ueCb); + + PjDlUdxSduStaCfm(&gCb->u.dlCb->udxDlSap[0].pst, + gCb->u.dlCb->udxDlSap[0].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 pjUtlDlShutdown +( +PjCb *gCb +) +#else +PUBLIC S16 pjUtlDlShutdown() +PjCb *gCb; +#endif +{ + S16 ret; /* Return Value */ + PjDlUeCb *ueCb; /* UE Control Block */ + PjDlUeCb *prevUeCb; /* Previos UE Control Block */ + PjDlRbCb *rbCb; /* RB Control Block */ + PjDlRbCb **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(pjUtlDlShutdown) + + 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.dlCb->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 */ + pjUtlDlFreeRb(gCb,rbCb); + } + } + rbCbLst = ueCb->drbCb; + for (idx = 0; idx < PJ_MAX_DRB_PER_UE; idx++) + { + rbCb = rbCbLst[idx]; + if (rbCb != NULLP) + { + pjUtlDlFreeRb(gCb,rbCb); + } + } + /* Close all the context info for offboarding */ + secInfo = ueCb->secInfo; +#ifdef INTEL_QAT_DP + pjUtlDlIntClose(gCb,ueCb->secInfo.cpIntSessCxtId); + pjUtlDlCipherClose(gCb,ueCb->secInfo.cpCiphSessCxtId); + pjUtlDlCipherClose(gCb,ueCb->secInfo.upCiphSessCxtId); +#else + pjUtlDlCipherClose(gCb,secInfo.cpCxtId); + pjUtlDlCipherClose(gCb,secInfo.upCxtId); + pjUtlDlIntClose(gCb,secInfo.intCxtId); +#endif + + /* Delete hoInfo if present */ + if (ueCb->hoInfo != NULLP) + { + PJ_FREE(gCb,ueCb->hoInfo->hoCfmInfo, + (PJ_MAX_DRB_PER_UE * sizeof(PjDlHoCfmInfo))); + PJ_FREE(gCb,ueCb->hoInfo, sizeof(PjDlHoInfo)); + } + } + prevUeCb = ueCb; + } +#ifdef LTE_L2_MEAS_COMMENT + for(idx = 0; idx < PJ_MAX_L2MEAS_EVT; idx++) + { + if(gCb->u.dlCb->pjL2Cb.pjMeasEvtCb[idx] != NULLP) + { + measEvtCb = gCb->u.dlCb->pjL2Cb.pjMeasEvtCb[idx]; + pjStopTmr((PTR)measEvtCb, PJ_EVT_L2_TMR); + gCb->u.dlCb->pjL2Cb.pjNumMeas--; + PJ_FREE(gCb,measEvtCb, sizeof(PjL2MeasEvtCb)); + gCb->u.dlCb->pjL2Cb.pjMeasEvtCb[idx] = NULLP; + } + } +#endif + ret = pjDbmDlDeInit(gCb); +#if (ERRCLASS & ERRCLS_DEBUG) + if (ret != ROK) + { + RLOG0(L_FATAL, "PDCP DL DeInitialization Failed."); + } +#endif /* ERRCLASS & ERRCLS_DEBUG */ + + + /* commented this to use in deregister timer and kwusap */ + /* gCb->init.cfgDone &= ~PJ_LMM_GENCFG_DONE; */ + 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 pjUtlDlFreeRb +( +PjCb *gCb, +PjDlRbCb *pjRbCb +) +#else +PUBLIC Void pjUtlDlFreeRb(pjRbCb) +PjCb *gCb; +PjDlRbCb *pjRbCb; +#endif +{ + TRC3(pjUtlDlFreeRb) + RLOG0(L_DEBUG, "pjUtlFreeRb()"); + + +#if (defined(PJ_SEC_ASYNC) || defined (PJ_CMP_ASYNC)) + if (pjRbCb->dlCb.obdTmr.tmrEvnt == PJ_EVT_DL_OBD_TMR) + { + pjStopTmr(gCb,(PTR)pjRbCb, PJ_EVT_DL_OBD_TMR); + } +#endif + + 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 pjUtlDlSndDatFwdInd +( +PjCb *gCb, +PjDlRbCb *pjRbCb, +PjuDatFwdIndInfo *datFwdInd +) +#else +PUBLIC S16 pjUtlDlSndDatFwdInd(pjRbCb, datFwdInd) +PjCb *gCb; +PjDlRbCb *pjRbCb; +PjuDatFwdIndInfo *datFwdInd; +#endif +{ + CmLtePdcpId *pdcpId; + PjPjuSapCb *pjuSap; + + TRC3(pjUtlDlSndDatFwdInd) + + RLOG0(L_DEBUG, "pjUtlSndDatFwdInd()"); + + pjuSap = &(gCb->u.dlCb->pjuSap[PJ_DRB_SAP]); + CmLtePdcpId pdcpIdTmp; + 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 */ + +/* 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 pjUtlL2MeasDlInit(PjCb *gCb) +{ + U16 cntr; + + gCb->u.dlCb->pjL2Cb.pjNumMeas=0; + for(cntr = 0; cntr < LPJ_MAX_L2MEAS; cntr++) + { + cmMemset((U8 *)&(gCb->u.dlCb->pjL2Cb.pjL2EvtCb[cntr]), 0, sizeof(PjL2MeasEvtCb)); + } + gCb->u.dlCb->pjL2Cb.pjL2EvtCb[0].measCb.measType = LPJ_L2MEAS_DL_DISC; + + RETVALUE(ROK); +} + +/** + * + * @brief Handler for sending L2 Measurement report + * + * @b Description + * + * @param[in] gCb PDCP Instance Control Block. + * @param[in] measEvtCb Measurement Event Control Block. + * + * + * @return S16 + * -# ROK + */ + +#ifdef ANSI +PUBLIC S16 pjUtlSndDlL2MeasCfm +( +PjCb *gCb, +PjL2MeasEvtCb *measEvtCb +) +#else +PUBLIC S16 pjUtlSndDlL2MeasCfm(measEvtCb) +PjCb *gCb; +PjL2MeasEvtCb *measEvtCb; +#endif +{ + PjL2MeasCb *measCb; + PjL2MeasCfmEvt measCfmEvt; + U8 qciIdx; + + TRC3(pjUtlSndDlL2MeasCfm) + + measCb = &measEvtCb->measCb; + cmMemset((U8*)&measCfmEvt, 0, sizeof(PjL2MeasCfmEvt)); + + measCfmEvt.measType = measCb->measType; + measCfmEvt.status.status = LCM_PRIM_OK; + measCfmEvt.status.reason = LCM_REASON_NOT_APPL; + for(qciIdx = 0; qciIdx < (LPJ_MAX_QCI-1); qciIdx++) + { + measCfmEvt.measCfm[measCfmEvt.numQciCfm].qci = measCb->qci[qciIdx]; + if(measCfmEvt.measCfm[measCfmEvt.numQciCfm].qci > 0) + { + if((measCb->measType & LPJ_L2MEAS_DL_DISC) && + (measCb->measData[measCb->qci[qciIdx]].dlDisc.numPkts > 0)) + { + /* dlDisc = num of Pkts Discarded * 10^6 / total no of pkts. */ + measCfmEvt.measCfm[measCfmEvt.numQciCfm].dlDisc = + measCb->measData[measCb->qci[qciIdx]].dlDisc.val * (1000000) / + measCb->measData[measCb->qci[qciIdx]].dlDisc.numPkts; + /* Reset the counters */ + measCb->measData[measCb->qci[qciIdx]].dlDisc.val = 0; + measCb->measData[measCb->qci[qciIdx]].dlDisc.numPkts =0; + } + measCfmEvt.numQciCfm++; + } + } + + /* Send Measurement confirmation to layer manager */ + PjMiLpjL2MeasCfm(&gCb->pjGenCfg.lmPst,&measCfmEvt); + + RETVALUE(ROK); +} + + +/** + * @brief Validates the measurement request parameters. + * + * @details + * + * Function :pjUtlValidateL2Meas + * + * @param[in] PjL2MeasReqEvt measReqEvt + * @param[out] PjL2MeasCfmEvt measCfmEvt + **/ +/** + * + * @brief Handler for resetting the DL measurement counters + * + * Function :pjUtlResetDlL2MeasCntr + * + * @b Description + * + * @param[in] measCb Measurement Control Block. + * + * + * @return Void + */ +#ifdef ANSI + +PUBLIC Void pjUtlResetDlL2MeasCntr +( +PjCb *gCb, +PjL2MeasCb *measCb, +U8 measType +) +#else +PUBLIC Void pjUtlResetDlL2MeasCntr(gCb, measCb, measType) +PjCb *gCb; +PjL2MeasCb *measCb; +U8 measType; +#endif +{ + /* for now the only meas should be DL discard in this case */ + if (measCb->measType & LPJ_L2MEAS_DL_DISC) + { + U32 i; + for(i = 0; i < (LPJ_MAX_QCI - 1); i++) + { + U8 qciVal = measCb->qci[i]; + + measCb->measData[qciVal].dlDisc.val = 0; + measCb->measData[qciVal].dlDisc.numPkts = 0; + gCb->u.dlCb->pjL2Cb.measOn[qciVal] &= ~LPJ_L2MEAS_DL_DISC; + } + + measCb->numQci = 0; + } +} + +/** + * + * @brief Handler for storing address of MeasData in rbCb at right index + * + * + * @b Description + * This function is called when LM sends measReq message to RLC. + * + * @param[in] + * @param[out] + * @param[in] + * + * + * @return S16 + * -# ROK + */ +#ifdef ANSI +PUBLIC Void pjUtlPlcMeasDatInDlL2Sts +( +PjL2Cntr *measData, +PjL2MeasRbCb *rbL2Cb, +U8 measType +) +#else +PUBLIC Void pjUtlPlcMeasDatInDlL2Sts(measData, rbL2Cb, measType) +PjL2Cntr *measData; +PjL2MeasRbCb *rbL2Cb; +U8 measType; +#endif +{ + TRC3(pjUtlPlcMeasDatInDlL2Sts) + + /* 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_DL_DISC) + { + rbL2Cb->l2Sts[PJ_L2MEAS_DL_DISC] = measData; + } + +}/* End of pjUtlPlcMeasDatInDlL2Sts */ +#endif /* LTE_L2_MEAS */ + +void dumpPDCPDlRbInformation(PjDlRbCb* dlRbCb, U16 ueId) +{ + PjDlCb* dlCb = &dlRbCb->dlCb; + RLOG_ARG1(L_INFO,DBG_UEID,ueId, "PDCP DL RB numEntries = %lu", + dlCb->txBuf.numEntries); +#ifndef ALIGN_64BIT + RTLIN_DUMP_DEBUG("UE [%u] PDCP DL RB numEntries = %lu", + ueId, dlCb->txBuf.numEntries); +#else + RTLIN_DUMP_DEBUG("UE [%u] PDCP DL RB numEntries = %u", + ueId, dlCb->txBuf.numEntries); +#endif +} + +void DumpPDCPDlDebugInformation(void) +{ +#ifndef RGL_SPECIFIC_CHANGES +#ifdef TENB_T2K3K_SPECIFIC_CHANGES + void *iccHdl = NULLP; + U32 poolZeroFreeCnt; + U32 poolOneFreeCnt; + U32 poolTwoFreeCnt; + U32 poolThreeFreeCnt; +#endif + + PjCb* dlInst = pjCb[1]; /* TODO: check whether DL is 0 or 1 */ + PjDlgCb* dlgCb = dlInst->u.dlCb; + + PjDlUeCb *ueCb = NULLP; + RLOG0(L_INFO,"PDCP DL Information"); + RLOG0(L_INFO,"==================="); + RTLIN_DUMP_DEBUG("PDCP DL Information\n"); + RTLIN_DUMP_DEBUG("===================\n"); + /* Until no more ueCb is ueLstCp hash list get and delete ueCb */ + while (ROK == cmHashListGetNext(&dlgCb->ueLstCp, + (PTR) ueCb, + (PTR *)&ueCb)) + { + U32 i; + for(i = 0; i < PJ_MAX_SRB_PER_UE; i++) + { + PjDlRbCb* rbCb = ueCb->srbCb[i]; + if(rbCb != NULLP) + { + dumpPDCPDlRbInformation(rbCb, ueCb->key.ueId); + } + } + for(i = 0; i < PJ_MAX_DRB_PER_UE; i++) + { + PjDlRbCb* rbCb = ueCb->drbCb[i]; + if(rbCb != NULLP) + { + dumpPDCPDlRbInformation(rbCb, ueCb->key.ueId); + } + } + }/* end while */ + /*printing ICC memory statistics*/ +#ifdef TENB_T2K3K_SPECIFIC_CHANGES + iccHdl = ssGetIccHdl(dlInst->init.region); + if(NULLP != iccHdl) + { + poolZeroFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ZERO_SIZE); + poolOneFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_ONE_SIZE); + poolTwoFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_TWO_SIZE); + poolThreeFreeCnt = TL_GetFreeBlocks(iccHdl, ICC_POOL_THREE_SIZE); + RLOG1(L_ALWAYS,"ICC pool zero free count = %lu", poolZeroFreeCnt); + RLOG1(L_ALWAYS,"ICC pool one free count = %lu", poolOneFreeCnt); + RLOG1(L_ALWAYS,"ICC pool two free count = %lu", poolTwoFreeCnt); + RLOG1(L_ALWAYS,"ICC pool three free count = %lu", poolThreeFreeCnt); + RTLIN_DUMP_DEBUG("ICC pool zero free count = %lu\n", poolZeroFreeCnt); + RTLIN_DUMP_DEBUG("ICC pool one free count = %lu\n", poolOneFreeCnt); + RTLIN_DUMP_DEBUG("ICC pool two free count = %lu\n", poolTwoFreeCnt); + RTLIN_DUMP_DEBUG("ICC pool three free count = %lu\n", poolThreeFreeCnt); + } + /*ccpu00136858 */ + RLOG1(L_ALWAYS,"SPACC cipher Q num of entry = %lu ", pjMsCiphQ.count); + RLOG1(L_ALWAYS,"SPACC decipher Q num of entry = %lu ", pjMsDeCiphQ.count); + RTLIN_DUMP_DEBUG("SPACC cipher Q num of entry = %lu \n", pjMsCiphQ.count); + RTLIN_DUMP_DEBUG("SPACC decipher Q num of entry = %lu \n", pjMsDeCiphQ.count); +#endif +#endif +} + +PUBLIC Void pjUtlEmptyDlPktList(PjCb *gCb, PjDlRbCb *pjRbCb) +{ + PjDlPkt *ulPkt; + CmLListCp *ulPktLst = &pjRbCb->dlCb.dlPktQ; + while(ulPktLst->first) + { + ulPkt = (PjDlPkt *)(ulPktLst->first->node); + cmLListDelFrm(ulPktLst, ulPktLst->first); + PJ_FREE_BUF(ulPkt->pdu); +#ifdef FLAT_BUFFER_OPT + PJ_FREE_FLAT_BUF(gCb, &(ulPkt->fb)) +#endif + PJ_FREE(gCb, ulPkt, sizeof(PjDlPkt)); + } + RETVOID; +} + +void ResetPDCPStats(void) +{ + cmMemset((U8*)&gPdcpStats, 0, sizeof(PDCPStats)); +} + +#ifndef ALIGN_64BIT +void PrintPDCPStats(void) +{ +#ifdef TENB_T2K3K_SPECIFIC_CHANGES + /* UDAY */ +#ifdef XEON_SPECIFIC_CHANGES + RLOG3(L_INFO,"PDCP Stats: SDUs Dropped = (%ld),SDUs Queued for SPAcc Cipher = (%ld)," + "Decipher = (%ld)", + gPdcpStats.numPdcpSdusDiscarded, pjMsCiphQ.count, pjMsDeCiphQ.count); +#else + RLOG3(L_INFO,"PDCP Stats: SDUs Dropped = (%ld),SDUs Queued for SPAcc Cipher = (%ld)," + "Decipher = (%ld)", + gPdcpStats.numPdcpSdusDiscarded, pjMsDlSpaccQCnt, pjMsUlSpaccQCnt); +#endif +#ifdef XEON_SPECIFIC_CHANGES + if((gPdcpStats.numPdcpSdusDiscarded > 0) || (pjMsCiphQ.count > 0) || (pjMsDeCiphQ.count > 0) ) + { + RTLIN_DUMP_DEBUG("PDCP Stats: SDUs Dropped = (%d)," + "SDUs Queued for SPAcc Cipher = (%d), Decipher = (%d) \n", + gPdcpStats.numPdcpSdusDiscarded, pjMsCiphQ.count, pjMsDeCiphQ.count); /* UDAY */ + } +#else + RTLIN_DUMP_DEBUG("PDCP Stats: SDUs Dropped = (%ld)," + "SDUs Queued for SPAcc Cipher = (%ld), Decipher = (%ld) Rb Overload DROP = (%ld) dbgPdcpQSizeThreshHoldDropCnt is (%ld) MmThredHldDrp (%ld) spaccQDropCnt (%ld) dlSpaccPktDrop %ld\n", + gPdcpStats.numPdcpSdusDiscarded, pjMsDlSpaccQCnt, pjMsUlSpaccQCnt,dbgPdcpMemCount,dbgPdcpQSizeThreshHoldDropCnt,pdcpdrop, dbgSpaccThreshHoldDropCnt,spaccDropCount); /* UDAY */ + dbgPdcpMemCount =0; + dbgPdcpQSizeThreshHoldDropCnt=0; + pdcpdrop = 0; + + spaccDropCount = 0; + //pdcpDropMemTh=0; +#endif +#endif +} +#else +void PrintPDCPStats(void) +{ + printf ("\n============================== PDCP STATS ===========================\n"); + RTLIN_DUMP_DEBUG("SDUs Dropped = (%u) No of Reodering Tmr Exp (%u)", + gPdcpStats.numPdcpSdusDiscarded, gPdcpStats.numPdcpCellReorderTmrExp); +} +#endif + +#ifdef ANSI +PRIVATE S16 pjUtlDlHdlSecInitCfm +( +PjCb *gCb, /* Pointer to PJ DL Control Block */ +PjDlUeCb *ueCb, /* Pointer to UeCb */ +U16 txIdx, /* Transaction Index for UeCb */ +PjAsyncCfm *asyncCfm, +UdxSecCfgCfmInfo *secCfgCfm, /* Security config confirm */ +UdxReEstCfmInfo *reEstCfm /* Reest config confirm */ +) +#else +PRIVATE S16 pjUtlDlHdlSecInitCfm(gCb,ueCb,txIdx,secCfgCfm,reEstCfm) +( +PjCb *gCb; /* Pointer to PJ DL Control Block */ +PjDlUeCb *ueCb; /* Pointer to UeCb */ +U16 txIdx; /* Transaction Index for UeCb */ +PjAsyncCfm *asyncCfm; +UdxSecCfgCfmInfo *secCfgCfm; /* Security config confirm */ +UdxReEstCfmInfo *reEstCfm; /* Reest config confirm */ +) +#endif +{ + PjUdxDlSapCb *udxSap; + S16 ret = ROK; + + TRC3(pjUtlDlHdlSecInitCfm) + + if(asyncCfm->libInitBitMask == 0) + { + PJ_CHK_RESTART_OBD_TIMER(gCb,ueCb, txIdx); + if(ueCb->libInfo.state == PJ_STATE_NORMAL) + { + /* Send security config confirm */ + /* Memory leak fix ccpu00135359 */ + udxSap = &(gCb->u.dlCb->udxDlSap[0]); + PJ_ALLOC_BUF_SHRABL(udxSap->pst,secCfgCfm, + sizeof (UdxSecCfgCfmInfo), ret); + if(ret != ROK) + { + RLOG0(L_FATAL, "Memory Allocation failed."); + RETVALUE(RFAILED); + } + PJ_FILL_SEC_CFM_INFO(secCfgCfm, asyncCfm); + + PJ_CLEAN_AND_UPD_ASYNCINFO(gCb,ueCb, txIdx); + + PjDlUdxSecCfgCfm(&gCb->u.dlCb->udxDlSap[0].pst, + gCb->u.dlCb->udxDlSap[0].suId, + (UdxSecCfgCfmInfo *) secCfgCfm); + } + else if(ueCb->libInfo.state == PJ_STATE_REEST) + { + /* Send ReEstCfm */ + /* Memory leak fix ccpu00135359 */ + udxSap = &(gCb->u.dlCb->udxDlSap[0]); + PJ_ALLOC_BUF_SHRABL(udxSap->pst,reEstCfm, + sizeof (UdxReEstCfmInfo), ret); + if(ret != ROK) + { + RLOG0(L_FATAL, "Memory Allocation failed."); + RETVALUE(RFAILED); + } + PJ_FILL_REEST_CFM_INFO(reEstCfm, asyncCfm, LCM_PRIM_OK); + + /* Some house keeping work */ + PJ_CLEAN_AND_UPD_ASYNCINFO(gCb,ueCb, txIdx); + + PjDlUdxReEstCfm(&gCb->u.dlCb->udxDlSap[0].pst, + gCb->u.dlCb->udxDlSap[0].suId, reEstCfm); + + pjUtlReEstDl(gCb, ueCb); + } + } + RETVALUE(ROK); +} + + +#ifdef ANSI +PRIVATE S16 pjUtlDlHdlCmpInitCfm +( +PjCb *gCb, /* Pointer to PJ DL Control Block */ +PjDlUeCb *ueCb, /* Pointer to UeCb */ +U16 txIdx, /* Transaction Index for UeCb */ +PjAsyncCfm *asyncCfm, /* Async Confirm */ +UdxCfgCfmInfo *cfgCfm /* UDX Config Confirm */ +) +#else +PRIVATE S16 pjUtlDlHdlCmpInitCfm(gCb,ueCb,txIdx,asyncCfm,cfgCfm) +( +PjCb *gCb; /* Pointer to PJ DL Control Block */ +PjDlUeCb *ueCb; /* Pointer to UeCb */ +U16 txIdx; /* Transaction Index for UeCb */ +PjAsyncCfm *asyncCfm; /* Async Confirm */ +UdxCfgCfmInfo *cfgCfm; /* UDX Config Confirm */ +) +#endif +{ + PjUdxDlSapCb *udxSap; + U32 idx; + S16 ret = ROK; + TRC3(pjUtlDlHdlCmpInitCfm) + + asyncCfm->libInitBitMask ^= (PJ_LIB_COMP_BIT_MASK); + + if((asyncCfm->libInitBitMask == 0) && + !(asyncCfm->cfmType & PJ_CFG_REEST_ASYNC_CFM)) + { + + /* Send config confirm */ + /* Memory leak fix ccpu00135359 */ + udxSap = &(gCb->u.dlCb->udxDlSap[0]); + PJ_ALLOC_BUF_SHRABL(udxSap->pst,cfgCfm, + sizeof (UdxCfgCfmInfo), ret); + if(ret != ROK) + { + RLOG0(L_FATAL, "Memory Allocation failed."); + RETVALUE(RFAILED); + } + 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 */ + PjDlUdxCfgCfm(&(gCb->u.dlCb->udxDlSap[0].pst), + gCb->u.dlCb->udxDlSap[0].suId, + (UdxCfgCfmInfo *)cfgCfm); + } + + RETVALUE(ROK); +} + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +/********************************************************************30** + End of file +**********************************************************************/