1 /******************************************************************************
3 * Copyright (c) 2020 ICT/CAS.
5 * Licensed under the O-RAN Software License, Version 1.0 (the "Software License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * https://www.o-ran.org/software
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 *******************************************************************************/
19 #include "vos_types.h"
20 #include "vos_string.h"
21 #include "vos_linklist.h"
24 #include "cuupCommon.h"
25 #include "cuModuleInterface.h"
26 #include "gnbCommon.h"
27 #include "upcContext.h"
30 PdcpuUeInfo_t *gPdcpuUeInfo[MAX_UE_NUM];
31 extern ULONG gPdcpuModuleId;
33 /* not used at the moment */
34 /*void pdcpuSetLessCountFun(const void* cpv_first, const void* cpv_second, void* pv_output)
36 assert(cpv_first != NULL && cpv_second != NULL && pv_output != NULL);
38 *(bool_t*)pv_output = (((PdcpuDataBuffNode_t *)cpv_first)->count) < (((PdcpuDataBuffNode_t *)cpv_second)->count) ? true : false;
42 /** 释放一个 PdcpuDataBuffNode_t 数据,赋值给plist->del */
43 VOID pdcpuFreeDataBuffNode(VOID *p)
45 PdcpuDataBuffNode_t *pNode = NULL;
51 pNode = (PdcpuDataBuffNode_t *)p;
52 if(NULL != pNode->pData)
54 msgbFree(pNode->pData);
63 /*******************************************************************************
64 * discard all stored PDCP PDUs in the transmitting buffer
66 * pTxPduList: transmitting buffer list
70 *******************************************************************************/
71 INT32 pdcpuDiscardTransmitBuff(plist pTxPduList)
76 /*******************************************************************************
77 * transmit or retransmit all stored PDCP PDUs in the transmitting buffer
79 * pTxPduList: transmitting buffer list
83 *******************************************************************************/
84 INT32 pdcpuDeliverTransmitBuff(PdcpDrbEntity_t *pPdcpuEntity)
89 /*******************************************************************************
90 * deliver the PDCP SDUs stored in the receiving buffer to upper layers
91 * in ascending order of associated COUNT values
93 * pTxPduList: transmitting buffer list
97 *******************************************************************************/
98 INT32 pdcpuDeliverRecvBuff(PdcpDrbEntity_t *pPdcpuEntity)
104 /*******************************************************************************
105 * To construct and send a PDCP status report
107 * pPdcpuEntity: pdcpu entity
111 *******************************************************************************/
112 INT32 pdcpuConstructStatusReport(PdcpDrbEntity_t *pPdcpuEntity)
117 /*******************************************************************************
118 * To perform PDCP data recovery
120 * ueE1apId: UE E1AP ID
125 *******************************************************************************/
126 INT32 pdcpuDataRecovery(PdcpDrbEntity_t *pPdcpuEntity)
131 INT32 pdcpuRecfgRohc(PdcpDrbEntity_t *pPdcpuEntity, upcTempDrbInfo_t *pDrbItem)
138 INT32 pdcpuSetSn(PdcpSnSize_e *pSn, PdcpSNSize_e snCfg)
140 if(PDCP_SN_SIZE_S12 == snCfg)
144 }else if(PDCP_SN_SIZE_S18 == snCfg)
150 pdcpuLog(LOG_ERR,"[PDCPU] input sn size is wrong!\n");
157 INT32 pdcpuSetRlcMode(PdcpRlcMode_e *pRlcMode, CuRlcMode_e rlcCfg)
162 pdcpuLog(LOG_ERR,"[PDCPU] input-TM MODE is wrong!\n");
169 case RLCMODE_UM_BIDIRECTIONAL:
170 case RLCMODE_UM_UNIDIRECTIONAL_UL:
171 case RLCMODE_UM_UNIDIRECTIONAL_DL:
176 pdcpuLog(LOG_ERR,"[PDCPU] input-rlc mode is wrong\n");
181 /*******************************************************************************
182 * To get SDAP DATA PDU header length configuration
188 *******************************************************************************/
189 INT32 pdcpuGetSdapHeadLen(SdapHeader_e sdapHeadInd, UINT8 *sdapHeadLen)
191 if(SDAP_HEADER_PRESENT == sdapHeadInd)
193 *sdapHeadLen = 1; /*Data PDU with SDAP header*/
195 }else if(SDAP_HEADER_ABSENT == sdapHeadInd)
197 *sdapHeadLen = 0; /*Data PDU without SDAP header*/
201 pdcpuLog(LOG_ERR,"[PDCPU] sdap head cfg is wrong\n");
209 /*******************************************************************************
210 * To create PDCP-U entity
212 * ueE1apId: UE E1AP ID
213 * pDrbItem : DRB to setup item
217 *******************************************************************************/
218 INT32 pdcpuCreateEntity(UINT64 ueE1apId, UINT16 ueIdx, UINT16 pduSessionId, upcTempDrbInfo_t *pDrbItem)
220 UINT8 drbId = pDrbItem->drbId;
221 PdcpuUeInfo_t *pPdcpUeInfo = NULL;
222 PdcpDrbEntity_t *pPdcpuEntity = NULL;
225 pdcpuCheckUeIdx(ueIdx);
226 pdcpuCheckDrbId(drbId);
228 /* examine ue info */
229 if(NULL == gPdcpuUeInfo[ueIdx])
231 pPdcpUeInfo = VOS_Malloc(sizeof(PdcpuUeInfo_t), gPdcpuModuleId);
232 pdcpuNullCheck(pPdcpUeInfo);
233 VOS_MemZero(pPdcpUeInfo, sizeof(PdcpuUeInfo_t));
234 gPdcpuUeInfo[ueIdx] = pPdcpUeInfo;
237 pPdcpUeInfo = gPdcpuUeInfo[ueIdx];
240 /* examine drb info */
241 if(NULL != pPdcpUeInfo->pdcpDrbEntity[drbId])
243 pPdcpuEntity = pPdcpUeInfo->pdcpDrbEntity[drbId];
246 pPdcpuEntity = VOS_Malloc(sizeof(PdcpDrbEntity_t), gPdcpuModuleId);
247 pdcpuNullCheck(pPdcpuEntity);
248 VOS_MemZero(pPdcpuEntity, sizeof(PdcpDrbEntity_t));
249 pPdcpUeInfo->pdcpDrbEntity[drbId] = pPdcpuEntity;
251 PDCPConfiguration_t *pPdcpCfg = &(pDrbItem->pdcpConfig);
252 pPdcpuEntity->ueE1apId = ueE1apId;
253 pPdcpuEntity->ueIdx = ueIdx;
254 pPdcpuEntity->pduSessionId = pduSessionId;
255 pPdcpuEntity->drbId = drbId;
257 if(0 != ((pPdcpCfg->bitMask)&PDCP_CONFIGURATION_OUT_OF_ORDER_DELIVERY_PRESENT))
259 pdcpuLog(LOG_INFO,"[PDCPU] 乱序递交已设置\n");
260 pPdcpuEntity->outOfOrderDelivery= TRUE;
264 ret += pdcpuSetRlcMode(&pPdcpuEntity->rlcMode, pPdcpCfg->rlcMode);
266 /* set sn size- Cond Setup2(38.331) */
267 ret += pdcpuSetSn(&pPdcpuEntity->pdcpSnSizeUl, pPdcpCfg->pdcpSNSizeUl);
268 ret += pdcpuSetSn(&pPdcpuEntity->pdcpSnSizeDl, pPdcpCfg->pdcpSNSizeDl);
271 /* set sdap head length */
272 ret += pdcpuGetSdapHeadLen(pDrbItem->sdapConfig.sdapDlHeaderInd, &pPdcpuEntity->sdapDlHeadLen);
273 ret += pdcpuGetSdapHeadLen(pDrbItem->sdapConfig.sdapUlHeaderInd, &pPdcpuEntity->sdapUlHeadLen);
275 /* check the above return results */
278 pdcpuLog(LOG_ERR,"[PDCPU] input parameter is wrong\n");
279 VOS_Free(pPdcpuEntity);
280 pPdcpUeInfo->pdcpDrbEntity[drbId] = NULL;
285 /* set security enable information */
286 PdcpuSecEnableInfo_t *pEnableInfo = gPdcpuUeInfo[ueIdx]->secEnableInfo[pduSessionId];
287 pdcpuNullCheck(pEnableInfo);
288 pPdcpuEntity->integrityProtection = pEnableInfo->integrityEnableFlag;
289 pPdcpuEntity->ciperingEnabled = pEnableInfo->cipherEnableFlag;
291 /* not support: ulDataSplitThreshold, pdcpDuplication */
293 /* set state variable */
294 VOS_MemZero(&(pPdcpuEntity->stateVar), sizeof(PdcpStateVar_t));
297 /* initial transmitting buffer */
298 pPdcpuEntity->txListLock = VOS_SemMCreate(VOS_SEM_Q_FIFO);
299 pPdcpuEntity->pTxPduList = cl_lib_list_new("pdcpuTxPduList", gPdcpuModuleId);
301 /* initial receiving buffer */
302 pPdcpuEntity->rxListLock = VOS_SemMCreate(VOS_SEM_Q_FIFO);
303 pPdcpuEntity->pRxSduList = cl_lib_list_new("pdcpuRxSduList", gPdcpuModuleId);
305 printfDrbEntity(pPdcpuEntity);