Modify licenses
[scp/ocu/5gnr.git] / Cu / CuUp / Pdcp / PdcpUp / Src / pdcpuUlDataProc.c
1 /******************************************************************************
2 *
3 *   Copyright (c) 2020 ICT/CAS.
4 *
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
8 *
9 *       https://www.o-ran.org/software
10 *
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.
16 *
17 *******************************************************************************/
18
19 #include "vos_types.h"
20 #include "vos_linklist.h"
21 #include "vos_module.h"
22 #include "vos_sem.h"
23 #include "cuupCommon.h"
24 #include "msgb.h"
25 #include "bitsPack.h"
26 #include "pdcpu.h"
27 #include "gnbCommon.h"
28 #include "pdcpCommon.h"
29 #include "pdcpuCore.h"
30 #include "cuupUeIdTransf.h"
31
32 #include "cuupTest.h"
33
34 extern PdcpuUeInfo_t *gPdcpuUeInfo[MAX_UE_NUM];
35 extern CuupUeIdxTable_t gPdcpuUeIdxTable;
36 extern ULONG gPdcpuModuleId;
37 ULONG gPdcpuUlModuleId;
38
39 extern INT32 sdapUlDataProc(UINT64 upE1apId, UINT64 sessId, UINT64 drbId, MsgbBuff_t *pMsgBuff);
40 INT32 pdcpuUlInit(ULONG userModuleId)
41 {
42         gPdcpuUlModuleId = userModuleId;
43
44         return VOS_OK;
45 }
46
47 INT32 pdcpuUnpackPduHead(MsgbBuff_t *pMsgBuff, PdcpSnSize_e snSize,
48                                                         UINT8 *pPdutype, UINT32 *pSn)
49 {
50         BitOpt_t bit;
51         UINT8 *pMsgHead = msgbData(pMsgBuff);
52         UINT16 pduLen = msgbDataUsedLen(pMsgBuff);
53
54         initBits(&bit, pMsgHead, pduLen, 0);
55         *pPdutype = unpackBits(&bit, 1);
56         if(PDCP_CTRL_PDU == *pPdutype)
57         {
58                 //*pCtrlPduType = unpackBits(&bit, 3);
59
60                 return 0;
61
62         }else if(PDCP_DATA_PDU == *pPdutype)
63         {
64                 if(LEN12BITS == snSize)
65                 {
66                         /*************D/C + 3R + PDCP SN = 16bits*************/
67                         skipBits(&bit, 3, BIT_UNPACKED);
68                         *pSn = unpackBits(&bit, LEN12BITS);
69
70                         return PDCP_SN_12_HEAD_LEN;
71
72                 }else if(LEN18BITS == snSize)
73                 {
74                         /*************D/C + 5R + PDCP SN =24bits*************/
75                         skipBits(&bit, 5, BIT_UNPACKED);
76                         *pSn = unpackBits(&bit, LEN18BITS);
77
78                         return PDCP_SN_18_HEAD_LEN;
79
80                 }else
81                 {
82                         pdcpuLog(LOG_ERR,"[PDCPU] sn size is wrong!\n");
83                         return VOS_ERROR;
84                 }
85         }
86
87         return VOS_OK;
88 }
89
90
91 INT32 pdcpuDecideCountAndHFN(PdcpStateVar_t *pStateVar, INT32 rcvdSn, PdcpSnSize_e snSize)
92 {
93         UINT32 rcvdHFN = 0;
94         UINT32 rxDeliv = pStateVar->rxDelivery;
95         INT32  tmp = 0;
96
97         if(LEN12BITS == snSize)
98         {
99                 tmp = GET_SN_12_SN(rxDeliv) - SN_12_WINDOW_SIZE;
100                 if(rcvdSn < tmp)
101                 {
102                         rcvdHFN = GET_HFN_12_SN(rxDeliv) + 1;
103                 }else if(rcvdSn >= GET_SN_12_SN(rxDeliv) + SN_12_WINDOW_SIZE)
104                 {
105                         rcvdHFN = GET_HFN_12_SN(rxDeliv) - 1;
106                 }else
107                 {
108                         rcvdHFN = GET_HFN_12_SN(rxDeliv);
109                 }
110                 pStateVar->rxCount = GET_COUNT_12_SN(rcvdHFN, rcvdSn);
111
112         }else if(LEN18BITS == snSize)
113         {
114                 tmp = GET_SN_18_SN(rxDeliv) - SN_18_WINDOW_SIZE;
115                 if(rcvdSn < tmp)
116                 {
117                         rcvdHFN = GET_HFN_18_SN(rxDeliv) + 1;
118
119                 }else if(rcvdSn >= GET_SN_18_SN(rxDeliv) + SN_18_WINDOW_SIZE)
120                 {
121                         rcvdHFN = GET_HFN_18_SN(rxDeliv) - 1;
122                 }else
123                 {
124                         rcvdHFN = GET_HFN_18_SN(rxDeliv);
125                 }
126                 pStateVar->rxCount = GET_COUNT_18_SN(rcvdHFN, rcvdSn);
127         }else
128         {
129                 pdcpuLog(LOG_ERR,"[PDCPU] sn size is wrong!\n");
130                 return VOS_ERROR;
131         }
132
133         return VOS_OK;
134 }
135
136
137 INT32 pdcpuCtrlPduProc(MsgbBuff_t *pMsgBuff, PdcpCtrlPduType_e ctrlPduType, PdcpDrbEntity_t *pPdcpDrbEntity)
138 {
139         pdcpuMsgbFree(pMsgBuff);
140
141         return VOS_OK;
142 }
143
144
145 INT32 pdcpuDelivUldata(PdcpDrbEntity_t *pDrbEntity)
146 {
147         /* traverse list and send data to SDAP */
148         struct cl_lib_listnode *pNode = NULL;
149         PdcpuDataBuffNode_t *pDataInBuff1 = NULL;
150         PdcpuDataBuffNode_t *pDataInBuff2 = NULL;
151
152         UINT32 count = 0;
153
154         pNode = cl_lib_listhead(pDrbEntity->pRxSduList);
155         if(NULL == pNode)
156         {
157                 /* There is no data in buffer */
158                 VOS_Printf("there is no data in buffer\n");
159                 return VOS_OK;
160         }
161         pDataInBuff1 = (PdcpuDataBuffNode_t *)cl_lib_getdata(pNode);
162
163         if(pDataInBuff1->count == pDrbEntity->stateVar.rxDelivery)
164         {
165                 while(pNode)
166                 {
167                         cl_lib_nextnode (pNode);
168                         count = pDataInBuff1->count;
169
170                         /*+++++++++++++++++++++++++++test+++++++++++++++++++++++++++*/
171                         //VOS_Printf("\n[pdcp ul data] pdcpuDelivUldata ueIdx:%d ueE1apId:%d drbId:%d count:%d \n",
172                         //                      pDrbEntity->ueIdx,pDrbEntity->ueE1apId,pDrbEntity->drbId,count);
173                         //printfMsgbBuff(pDataInBuff1->pData);
174                         /*---------------------------test----------------------------*/
175
176                         /* delivery to sdap,if sdapUlDataProc return VOS_OK,free the data
177                            else, also free the data */
178                         sdapUlDataProc(pDrbEntity->ueE1apId,pDrbEntity->pduSessionId,pDrbEntity->drbId,pDataInBuff1->pData);
179
180                         /* update stateVar */
181                         pDrbEntity->stateVar.rxDelivery = count + 1;
182
183                         /* delete rx buffer */
184                         cl_lib_listnode_delete(pDrbEntity->pRxSduList, pDataInBuff1);
185                         pdcpuFreeDataBuffNode(pDataInBuff1);
186
187                         if(NULL == pNode)
188                         {
189                                 /* There is no more data in buffer */
190                                 return VOS_OK;
191                         }
192                         pDataInBuff2 = (PdcpuDataBuffNode_t *)cl_lib_getdata(pNode);
193                         if(NULL == pDataInBuff2)
194                         {
195                                 /* There is no more data in buffer */
196                                 pdcpuLog(LOG_ERR,"[PDCPU] data is null\n");
197                                 return VOS_ERROR;
198                         }
199
200                         if(pDataInBuff2->count == count + 1)
201                         {
202                                 /* The data is continuously */
203                                 pDataInBuff1 = pDataInBuff2;
204
205                         }else if(pDataInBuff2->count > count + 1)
206                         {
207                                 /* The data is not continuously */
208                                 return VOS_OK;
209                         }else
210                         {
211                                 pdcpuLog(LOG_ERR,"[PDCPU] out of order in receiving buffer!\n");
212                                 return VOS_ERROR;
213                         }
214
215
216                 }
217
218                 return VOS_OK;
219         }else if(pDataInBuff1->count > pDrbEntity->stateVar.rxDelivery)
220         {
221                 /* the data whose count value is equal to rxDelivery,is still waited for */
222                 return VOS_OK;
223         }else
224         {
225                 pdcpuLog(LOG_ERR,"[PDCPU] rxbuff is wrong!\n");
226                 return VOS_ERROR;
227         }
228
229         return VOS_OK;
230 }
231
232
233 /*******************************************************************************
234  * pdcp-u ul data process
235  * INPUT:
236  *       ueE1apId: E1AP ID of the UE
237  *       drbId: ID of data radio bearer
238  *       pMsgBuff: SDAP PDU
239  * OUTPUT:
240  *       0: success
241  *       -1:failed
242 *******************************************************************************/
243 INT32 pdcpuUlDataProc(UINT64 ueE1apId, UINT8 drbId, MsgbBuff_t *pMsgBuff)
244 {
245         UINT8  pduType     = 0;
246         UINT32 rcvdSn      = 0;
247         UINT32 count       = 0;
248         INT8   pduHeadLen  = 0;
249         UINT16 ueIdx       = 0xffff;
250         INT32  ret         = -1;
251         PdcpSnSize_e            snSize;
252         PdcpDrbEntity_t         *pPdcpDrbEntity = NULL;
253         PdcpStateVar_t          *pStateVar              = NULL;
254
255         pdcpuNullCheck(pMsgBuff);
256         UINT8 *pMsgHead = msgbData(pMsgBuff);
257         UINT16 pduLen   = msgbDataUsedLen(pMsgBuff);
258         if(pduLen<1)
259         {
260                 pdcpuMsgbFree(pMsgBuff);
261                 pdcpuLog(LOG_ERR,"[PDCPU] data len is too small!\n");
262                 return VOS_ERROR;
263         }
264
265         if(VOS_ERROR == cuupGetUeIdx(ueE1apId, &ueIdx, &gPdcpuUeIdxTable))
266         {
267                 pdcpuLog(LOG_ERR,"[PDCPU] add ueE1apId failed\n");
268                 pdcpuMsgbFree(pMsgBuff);
269                 return VOS_ERROR;
270         }
271         pdcpuGetEntity(ueIdx, drbId, pPdcpDrbEntity);
272         pdcpuNullCheck(pPdcpDrbEntity);
273         snSize    = pPdcpDrbEntity->pdcpSnSizeUl;
274         pStateVar = &pPdcpDrbEntity->stateVar;
275
276         /* get pdcp pdu type */
277         BitOpt_t bit;
278         initBits(&bit, pMsgHead, pduLen, 0);
279         pduType = unpackBits(&bit, 1);
280
281     if(PDCP_DATA_PDU == pduType)
282         {
283                 //1.analysis pdcp header: shall not move the data start pointer
284                 pduHeadLen = pdcpuUnpackPduHead(pMsgBuff, snSize, &pduType, &rcvdSn);
285                 if(VOS_ERROR == pduHeadLen)
286                 {
287                         pdcpuLog(LOG_ERR,"[PDCPU] unpack pdu head wrong!\n");
288                         pdcpuMsgbFree(pMsgBuff);
289                         return VOS_ERROR;
290                 }
291
292                 //make sure received HFN and received Count
293                 if(VOS_ERROR == pdcpuDecideCountAndHFN(pStateVar, rcvdSn, snSize))
294                 {
295                         pdcpuLog(LOG_ERR,"[PDCPU] get count wrong!\n");
296                         pdcpuMsgbFree(pMsgBuff);
297                         return VOS_ERROR;
298                 }
299
300                 count = pStateVar->rxCount;
301
302                 //2.deciphering : except pdcp pdu head, the SDAP header and the SDAP Control PDU
303                 //get sdap pdu type
304                 BitOpt_t SdapHeadbit;
305                 UINT8 *pSdapPduHead = msgbData(pMsgBuff) + pduHeadLen;
306                 initBits(&SdapHeadbit, pSdapPduHead, 1, 0);
307                 //5.remove pdcp pdu head
308                 msgbHeadPull(pMsgBuff, pduHeadLen);
309                 ret = sdapUlDataProc(ueE1apId,pPdcpDrbEntity->pduSessionId,drbId,pMsgBuff);
310                 pPdcpDrbEntity->stateVar.rxDelivery = count + 1;
311                 if(VOS_OK == ret)
312                 {
313                         pdcpuMsgbFree(pMsgBuff);
314                         return VOS_OK;
315                 }else
316                 {
317                         pdcpuMsgbFree(pMsgBuff);
318                         pdcpuLog(LOG_ERR,"[PDCPU] ul proc failed\n");
319                         return VOS_ERROR;
320                 }
321
322
323         }
324
325         return VOS_OK;
326 }