X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=Cu%2FCuUp%2FPdcp%2FPdcpUp%2FSrc%2FpdcpuUpc.c;fp=Cu%2FCuUp%2FPdcp%2FPdcpUp%2FSrc%2FpdcpuUpc.c;h=36ba83b35071e40d969dd5f721cf1b83a790dcbf;hb=1f71b9a76eacf92b39c1ce6f782f8404a34f60a9;hp=0000000000000000000000000000000000000000;hpb=254694245736881ecfff4eb0d1503bf3f49a21be;p=scp%2Focu%2F5gnr.git diff --git a/Cu/CuUp/Pdcp/PdcpUp/Src/pdcpuUpc.c b/Cu/CuUp/Pdcp/PdcpUp/Src/pdcpuUpc.c new file mode 100644 index 0000000..36ba83b --- /dev/null +++ b/Cu/CuUp/Pdcp/PdcpUp/Src/pdcpuUpc.c @@ -0,0 +1,434 @@ +/****************************************************************************** +############################################################################### +# Copyright (c) [2017-2020] [ICT/CAS] # +# Licensed under the ORAN Software License v1.0 (License) # +############################################################################### +******************************************************************************/ +#include "vos_types.h" +#include "vos_string.h" +#include "vos_lib.h" +#include "pdcpu.h" +#include "pdcpuCore.h" +#include "pdcpCommon.h" +#include "cuupCommon.h" +#include "cuModuleInterface.h" +#include "pdcpComprohc.h" +#include "cuupTest.h" +#include "cuupUeIdTransf.h" +#include "upcContext.h" + +extern PdcpuUeInfo_t *gPdcpuUeInfo[MAX_UE_NUM]; +ULONG gPdcpuModuleId; +CuupUeIdxTable_t gPdcpuUeIdxTable; + + +/******************************************************************************* +* To +* INPUT: +* : +* OUTPUT: +* 0:success +* -1:fail +*******************************************************************************/ +INT32 pdcpuInit(ULONG userModuleId) +{ + /* get pdcpu moduleId */ + gPdcpuModuleId = userModuleId; + + /* init ueIdx table */ + UINT8 i = 0; + for(i=0; isecInfo; + if(NULL != pDrbSecInfo) + { + VOS_Free(pDrbSecInfo); + gPdcpuUeInfo[ueIdx]->secInfo = NULL; + } + + return VOS_OK; +} + +/******************************************************************************* +* To deal with security indication +* Security Result indicates whether the security policy indicated as "preferred" +* in the Security Indication IE is performed or not. +* INPUT: +* ueE1apId : UE E1AP ID +* pduSessionId : pdu session id +* pSecInd : security indication +* pSecResult : security result +* OUTPUT: +* 0:success +* -1:fail +*******************************************************************************/ +INT32 pdcpuDealSecurityInd(PdcpuSecInfo_t *pSec, PdcpuSecEnableInfo_t *pEnableInfo, SecuInd_t *pSecInd, PdcpuCfgResult_t *pResult) +{ + /* get security enable information global variable */ + pdcpuNullCheck(pSec); + pdcpuNullCheck(pEnableInfo); + pdcpuNullCheck(pSecInd); + + /* for integrity protection */ + if(ACTIVE_INT_STATE == pSec->intActiveFlag) + { + /* integrity protection is active for the UE, apply the indication */ + if(IP_REQUIRED == pSecInd->IPIndication) + { + pEnableInfo->integrityEnableFlag = TRUE; + pEnableInfo->maxIPDataRate = pSecInd->maxIPdataRate; + pResult->secResPresent = FALSE; + + }else if(IP_PREFERRED == pSecInd->IPIndication) + { + pEnableInfo->integrityEnableFlag = TRUE; + pEnableInfo->maxIPDataRate = pSecInd->maxIPdataRate; + pResult->secResPresent = TRUE; + pResult->secuResult.integrityProtectionResult= IP_RESULT_PERFORMED; + + }else + { + pEnableInfo->integrityEnableFlag = FALSE; + pResult->secResPresent = FALSE; + + } + + }else + { + /* integrity protection is inactive for the UE */ + pEnableInfo->integrityEnableFlag = FALSE; + if(IP_PREFERRED == pSecInd->IPIndication) + { + pResult->secResPresent = TRUE; + pResult->secuResult.integrityProtectionResult= IP_RESULT_NOT_PERFORMED; + } + } + + /* for ciphering */ + if(ACTIVE_ENC_STATE == pSec->encActiveFlag) + { + /* ciphering is active for the UE, apply the indication */ + if(CP_REQUIRED == pSecInd->CPIndication) + { + pEnableInfo->cipherEnableFlag = TRUE; + pResult->secResPresent = FALSE; + + }else if(CP_PREFERRED == pSecInd->CPIndication) + { + pEnableInfo->cipherEnableFlag = TRUE; + pResult->secResPresent = TRUE; + pResult->secuResult.confidentialityProtectionResult = CP_RESULT_PERFORMED; + + }else + { + pEnableInfo->cipherEnableFlag = FALSE; + pResult->secResPresent = FALSE; + + } + + }else + { + /* ciphering is inactive for the UE */ + pEnableInfo->cipherEnableFlag = FALSE; + if(CP_PREFERRED == pSecInd->CPIndication) + { + pResult->secResPresent = TRUE; + pResult->secuResult.confidentialityProtectionResult= CP_RESULT_NOT_PERFORMED; + } + } + + return VOS_OK; +} + +INT32 pdcpuRetFailResult(UpcCfgType_e cfgType, upcTempSessInfo_t *pCfgInfo, PdcpuCfgResult_t *pResult) +{ + pdcpuLog(LOG_ERR,"[PDCPU] pdu session config failed\n"); + + UINT8 i = 0; + if(PDU_SESSION_ADD == cfgType) + { + /* drb to setup list */ + for(i=0; idrbSetupNum; i++) + { + pResult->drbSetupFailedArray[i].drbId = pCfgInfo->pTempDrbSetupList[i].drbId; + pResult->drbSetupFailedArray[i].cause = RNL_UNSPECIFIED; + } + pResult->drbSetupFailNum = pCfgInfo->drbSetupNum; + pResult->pduSessionCause = RNL_UNSPECIFIED; + + } + + + return VOS_ERROR; +} + +/******************************************************************************* +* To deal with PDU session to setup config +* INPUT: +* ueE1apId : UE E1AP ID +* pPduSessionCfg : PDU session to setup config +* pResult : PDU session to setup result +* OUTPUT: +* none +*******************************************************************************/ +INT32 pdcpuSessionAddProc(UINT64 ueE1apId, VOID *pCfgInfo, PdcpuCfgResult_t *pResult) +{ + upcTempSessInfo_t *pSetupInfo = (upcTempSessInfo_t *)pCfgInfo; + upcTempDrbInfo_t *pDrbTemp = NULL; + PdcpuSecInfo_t *pSec = NULL; + PdcpuSecEnableInfo_t *pEnableInfo = NULL; + + UINT16 pduSessionId = pSetupInfo->pduSessId; + pResult->pduSessionId = pduSessionId; + + /* get ueIdx */ + UINT16 ueIdx; + if(VOS_ERROR == cuupAddUeE1apid(ueE1apId, &ueIdx, &gPdcpuUeIdxTable)) + { + pdcpuLog(LOG_ERR,"[PDCPU] add ueE1apId failed\n"); + return pdcpuRetFailResult(PDU_SESSION_ADD,pCfgInfo,pResult); + } + + /* check ue and security context block */ + if((NULL == gPdcpuUeInfo[ueIdx]) || (NULL == gPdcpuUeInfo[ueIdx]->secInfo)) + { + pdcpuLog(LOG_ERR,"[PDCPU] ue and security context block not exist\n"); + return pdcpuRetFailResult(PDU_SESSION_ADD,pCfgInfo,pResult); + } + pSec = gPdcpuUeInfo[ueIdx]->secInfo; + + /* alloc pdu session information */ + pEnableInfo = gPdcpuUeInfo[ueIdx]->secEnableInfo[pduSessionId]; + if(NULL == pEnableInfo) + { + pEnableInfo = VOS_Malloc(sizeof(PdcpuSecEnableInfo_t), gPdcpuModuleId); + if(NULL == pEnableInfo) + { + pdcpuLog(LOG_ERR,"[PDCPU] vos_malloc failed\n"); + return pdcpuRetFailResult(PDU_SESSION_ADD,pCfgInfo,pResult); + } + VOS_MemZero(pEnableInfo, sizeof(PdcpuSecEnableInfo_t)); + gPdcpuUeInfo[ueIdx]->secEnableInfo[pduSessionId] = pEnableInfo; + } + pEnableInfo->pduSessionId = pduSessionId; + + /* deal with security indication */ + if(VOS_ERROR == pdcpuDealSecurityInd(pSec, pEnableInfo, &pSetupInfo->secuIndi, pResult)) + { + pdcpuLog(LOG_ERR,"[PDCPU] deal security indication failed\n"); + return pdcpuRetFailResult(PDU_SESSION_ADD,pCfgInfo,pResult); + } + + /* create pdcp entity */ + UINT8 i = 0; + for(i = 0; i < pSetupInfo->drbSetupNum; i++) + { + pDrbTemp = &pSetupInfo->pTempDrbSetupList[i]; + + if((NULL == pDrbTemp) || (FALSE == pDrbTemp->drbSetupAllowed)) + { + continue; + } + + if(VOS_OK == pdcpuCreateEntity(ueE1apId, ueIdx, pduSessionId, pDrbTemp)) + { + pResult->drbSetupSuccessArray[pResult->drbSetupSuccessNum] = pDrbTemp->drbId; + pResult->drbSetupSuccessNum += 1; + }else + { + pResult->drbSetupFailedArray[pResult->drbSetupFailNum].drbId = pDrbTemp->drbId; + pResult->drbSetupFailedArray[pResult->drbSetupFailNum].cause = RNL_PDCP_CONFIG_NOT_SUPPORT; + pResult->drbSetupFailNum += 1; + + } + } + + /* return */ + if(0 != pResult->drbSetupSuccessNum) + { + return VOS_OK; + }else + { + pResult->pduSessionCause = RNL_UNSPECIFIED; + pdcpuLog(LOG_ERR,"[PDCPU] all drbs setup failed\n"); + return VOS_ERROR; + } +} + +/******************************************************************************* + * To manage pdcp-u entity + * INPUT: + * ueE1apId : UE E1AP ID + * pPduSessionCfg : PDU Session Resource to setup item + * cfgType : configuration type + * pResult : result which will return to upc + * OUTPUT: + * result: PDCP config result + *******************************************************************************/ +INT32 pdcpuConfig(UINT64 ueE1apId, VOID *pCfgInfo, UpcCfgType_e cfgType, PdcpuCfgResult_t *pResult) +{ + switch(cfgType) + { + case PDU_SESSION_ADD: + { + pdcpuNullCheck(pCfgInfo); + pdcpuNullCheck(pResult); + VOS_MemZero(pResult, sizeof(PdcpuCfgResult_t)); + pResult->cfgType = cfgType; + return pdcpuSessionAddProc(ueE1apId, pCfgInfo, pResult); + } + default: + { + pdcpuLog(LOG_ERR,"[PDCPU] cfgType error\n"); + return VOS_ERROR; + } + } + +} + + +/******************************************************************************* + * To get ue security information pointer + * INPUT: + * ueIdx: UE index + * OUTPUT: + * pDrbSecInfo: ue security information pointer + *******************************************************************************/ +PdcpuSecInfo_t *pdcpuAllocUeSecInfo(UINT16 ueIdx) +{ + PdcpuSecInfo_t *pSecInfo = NULL; + PdcpuUeInfo_t *pPdcpUeInfo = NULL; + + //check ue + if(NULL == gPdcpuUeInfo[ueIdx]) + { + pPdcpUeInfo = VOS_Malloc(sizeof(PdcpuUeInfo_t), gPdcpuModuleId); + pdcpuNullCheckRp(pPdcpUeInfo); + VOS_MemZero(pPdcpUeInfo, sizeof(PdcpuUeInfo_t)); + gPdcpuUeInfo[ueIdx] = pPdcpUeInfo; + }else + { + pPdcpUeInfo = gPdcpuUeInfo[ueIdx]; + } + //check secInfo + if(NULL == pPdcpUeInfo->secInfo) + { + pSecInfo = VOS_Malloc(sizeof(PdcpuSecInfo_t), gPdcpuModuleId); + pdcpuNullCheckRp(pSecInfo); + VOS_MemZero(pSecInfo, sizeof(PdcpuSecInfo_t)); + pPdcpUeInfo->secInfo = pSecInfo; + }else + { + pSecInfo = pPdcpUeInfo->secInfo; + } + + VOS_MemZero(pSecInfo, sizeof(PdcpuSecInfo_t)); + + return pSecInfo; +} + + +/******************************************************************************* + * To set ue security parameters. When receiving security information, + * pdcp-u shall save AS keys, AS algorithm and active integrity and ciphering. + * INPUT: + * ueE1apId: UE E1AP ID + * secInfo: security information + * OUTPUT: + * 0: success + * -1:failed + *******************************************************************************/ +INT32 pdcpuSetSecParam(UINT64 ueE1apId, SecuInfo_t *secInfo) +{ + pdcpuNullCheck(secInfo); + + UINT16 ueIdx; + if(VOS_ERROR == cuupAddUeE1apid(ueE1apId, &ueIdx, &gPdcpuUeIdxTable)) + { + pdcpuLog(LOG_ERR,"[PDCPU] add ueE1apId failed\n"); + return VOS_ERROR; + } + + /* find ue security struct */ + PdcpuSecInfo_t *pDrbSecInfo = pdcpuAllocUeSecInfo(ueIdx); + pdcpuNullCheck(pDrbSecInfo); + + /* activate integrity */ + if(secInfo->secuAlgorithm.bitMask & SECURITY_ALGORITHM_INTERGRITY_PROTECTION_ALGORITHM) + { + UINT8 intAlgorithm = secInfo->secuAlgorithm.integrityProtectionAlgorithm; + UINT8 *pIntKey = secInfo->upSecukey.integrityProtectionKey.buffer; + UINT8 intKeyLen = secInfo->upSecukey.integrityProtectionKey.size; /* 128 bits */ + + if(intKeyLen < AS_KEY_LEN) + { + pdcpuLog(LOG_ERR,"[PDCPU] integrity parameter is wrong!\n"); + pdcpuFreeSecInfo(ueIdx); + return VOS_ERROR; + } + + pDrbSecInfo->intActiveFlag = ACTIVE_INT_STATE; /* 0-inactive, 1-active */ + if(intAlgorithm == NIA0 || intAlgorithm == NIA1 || intAlgorithm == NIA2) + { + pDrbSecInfo->intAlgorithm = intAlgorithm; + VOS_MemCpy(pDrbSecInfo->kUpInt, pIntKey, AS_KEY_LEN); /* 128 bits */ + }else + { + pDrbSecInfo->intActiveFlag = INACTIVE_INT_STATE; + pdcpuLog(LOG_ERR,"[PDCPU] integrity algorithm is %d, not supported!\n",intAlgorithm); + pdcpuFreeSecInfo(ueIdx); + return VOS_ERROR; + } + }else + { + pDrbSecInfo->intActiveFlag = INACTIVE_INT_STATE; + pdcpuLog(LOG_INFO,"[PDCPU] integrity is not config\n"); + } + + /* activate encryption */ + UINT8 encAlgorithm = secInfo->secuAlgorithm.cipheringAlgorithm; + UINT8 *pEncKey = secInfo->upSecukey.encryptionKey.buffer; + UINT8 encKeyLen = secInfo->upSecukey.encryptionKey.size; /* 128 bits */ + + if(encKeyLen < AS_KEY_LEN) + { + pdcpuLog(LOG_ERR,"[PDCPU] encryption parameter is wrong!\n"); + pdcpuFreeSecInfo(ueIdx); + return VOS_ERROR; + } + + pDrbSecInfo->encActiveFlag = ACTIVE_ENC_STATE; /* 0-inactive, 1-active */ + if(encAlgorithm == NEA0 || encAlgorithm == NEA1 || encAlgorithm == NEA2) + { + pDrbSecInfo->encAlgorithm = encAlgorithm; + VOS_MemCpy(pDrbSecInfo->kUpEnc, pEncKey, AS_KEY_LEN); /* 128 bits */ + }else + { + pDrbSecInfo->encActiveFlag = INACTIVE_ENC_STATE; + pdcpuLog(LOG_ERR,"[PDCPU] encryption algorithm:%d, is not supported!\n", encAlgorithm); + pdcpuFreeSecInfo(ueIdx); + return VOS_ERROR; + } + + pDrbSecInfo->ueE1apId = ueE1apId; + pDrbSecInfo->ueIdx = ueIdx; + pDrbSecInfo->nhInd = FALSE; + + return VOS_OK; +} +