/****************************************************************************** * * Copyright (c) 2020 ICT/CAS. * * Licensed under the O-RAN Software License, Version 1.0 (the "Software License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.o-ran.org/software * * 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. * *******************************************************************************/ #include #include "vos_types.h" #include "vos_linklist.h" #include "vos_sem.h" #include "cuupCommon.h" #include "msgb.h" #include "bitsPack.h" #include "pdcpu.h" #include "gnbCommon.h" #include "cuupUeIdTransf.h" #include "cuupTest.h" //for test extern PdcpuUeInfo_t *gPdcpuUeInfo[MAX_UE_NUM]; extern CuupUeIdxTable_t gPdcpuUeIdxTable; extern ULONG gPdcpuModuleId; ULONG gPdcpuDlModuleId; INT32 pdcpuDlInit(ULONG userModuleId) { gPdcpuDlModuleId = userModuleId; return VOS_OK; } INT32 pdcpuPackPduHead(PdcpRlcMode_e rlc_mode,PdcpSnSize_e snSize, UINT32 sn, MsgbBuff_t *msgb) { BitOpt_t bit; UINT8 *p = NULL; UINT8 *pPduHead = NULL; UINT8 pduHeadLen = 0; if(LEN12BITS == snSize) { pduHeadLen = PDCP_SN_12_HEAD_LEN; }else if(LEN18BITS == snSize) { pduHeadLen = PDCP_SN_18_HEAD_LEN; }else { pdcpuLog(LOG_ERR,"[PDCPU] sn size is wrong!\n"); return VOS_ERROR; } pPduHead = VOS_Malloc(pduHeadLen,gPdcpuDlModuleId); pdcpuNullCheck(pPduHead); VOS_MemZero(pPduHead, pduHeadLen); if(snSize == LEN12BITS) { if(sn >= MAX_PDCP_SN_12) { pdcpuLog(LOG_ERR,"[PDCPU] sn too big\n"); return VOS_ERROR; } initBits(&bit, pPduHead, 16, 0); packBits(&bit, 1, 1); skipBits(&bit, 3, BIT_PACKED); packBits(&bit, 4, ((sn & 0xf00)>>8)); packBits(&bit, 8, sn & 0x0ff); }else if(snSize == LEN18BITS) { if(sn >= MAX_PDCP_SN_18) { pdcpuLog(LOG_ERR,"[PDCPU] sn too big\n"); return VOS_ERROR; } initBits(&bit, pPduHead, 24, 0); packBits(&bit, 1, 1); skipBits(&bit, 5, BIT_PACKED); packBits(&bit, 2, ((sn & 0x00030000)>>16)); packBits(&bit, 8, ((sn & 0x0000ff00)>>8)); packBits(&bit, 8, sn & 0x000000ff); }else { pdcpuLog(LOG_ERR,"[PDCPU] sn size error\n"); return VOS_ERROR; } p = msgbHeadPush(msgb, pduHeadLen); if(NULL != p) { VOS_MemCpy(p, pPduHead, pduHeadLen); }else { pdcpuLog(LOG_ERR,"[PDCPU] msgbHeadPush failed!\n"); return VOS_ERROR; } if(NULL != pPduHead) { VOS_Free(pPduHead); pPduHead= NULL; } return pduHeadLen; } /******************************************************************************* * pdcp-u dl data process * INPUT: * ueE1apId: E1AP ID of the UE * drbId: ID of data radio bearer * pMsgBuff: PDCP PDU * OUTPUT: * 0: success * -1:failed *******************************************************************************/ INT32 pdcpuDlDataProc(UINT64 ueE1apId, UINT8 drbId, MsgbBuff_t *pMsgBuff, UINT8 sdapPduType) { UINT32 sn = 0; INT8 pduHeadLen = 0; PdcpSnSize_e snSize; PdcpRlcMode_e rlcMode; PdcpDrbEntity_t *pPdcpDrbEntity = NULL; UINT16 ueIdx; if(VOS_ERROR == cuupGetUeIdx(ueE1apId, &ueIdx, &gPdcpuUeIdxTable)) { pdcpuLog(LOG_ERR,"[PDCPU] get ueIdx failed,ueE1apId:%d\n",ueE1apId); return VOS_ERROR; } pdcpuCheckUeIdx(ueIdx); pdcpuCheckDrbId(drbId); pdcpuGetEntity(ueIdx, drbId, pPdcpDrbEntity); pdcpuNullCheck(pPdcpDrbEntity); rlcMode = pPdcpDrbEntity->rlcMode; //1.check data pdcpuNullCheck(pMsgBuff); //2.assign the sn UINT32 count = pPdcpDrbEntity->stateVar.txNext++; // check out count wrapping around whether or not if(0xffffffff == count) { pdcpuLog(LOG_ERR,"[PDCPU] count value is going to wrap around!\n"); return VOS_ERROR; } snSize = pPdcpDrbEntity->pdcpSnSizeDl; if(snSize == LEN12BITS) { sn = GET_SN_12_SN(count); }else if(snSize == LEN18BITS) { sn = GET_SN_18_SN(count); }else { pdcpuLog(LOG_ERR,"[PDCPU] sn size is wrong!\n"); return VOS_ERROR; } //4.add pdu head pduHeadLen = pdcpuPackPduHead(rlcMode, snSize, sn, pMsgBuff); if(VOS_ERROR == pduHeadLen) { pdcpuLog(LOG_ERR,"[PDCPU] pack pdcp pdu head failed!\n"); return VOS_ERROR; } //8. 否则:cuf1u将数据发送成功后,释放 if(VOS_OK == cuf1uDlDataProc(ueE1apId, drbId, pMsgBuff, NULL)) { //vos_info_print("there is no buffer\n"); msgbFree(pMsgBuff); pMsgBuff = NULL; return VOS_OK; }else { pdcpuLog(LOG_ERR,"[PDCPU] cuf1u send failed\n"); return VOS_ERROR; } }