[ Jira id - ODUHIGH-593 ] Pack and unpack function nomenclature correction
[o-du/l2.git] / src / cu_stub / cu_stub_egtp.c
1 /*******************************************************************************
2 ################################################################################
3 #   Copyright (c) [2017-2019] [Radisys]                                        #
4 #                                                                              #
5 #   Licensed under the Apache License, Version 2.0 (the "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 #       http://www.apache.org/licenses/LICENSE-2.0                             #
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 /* This file contains all EGTP related functionality */
20
21 #include "common_def.h"
22 #include "OCTET_STRING.h"
23 #include "cu_stub_sctp.h"
24 #include "cu_f1ap_msg_hdl.h"
25 #include "cu_stub_egtp.h"
26 #include "cu_stub.h"
27 #include "cm_inet.h"
28 #include "cm_tpt.h"
29  
30 #include "cm_inet.x"
31 #include "cm_tpt.x"
32
33 uint8_t sockType;
34 uint8_t protType;
35 EgtpGlobalCb egtpCb;
36
37 /**************************************************************************
38  * @brief Task Initiation callback function. 
39  *
40  * @details
41  *
42  *     Function : egtpActvInit 
43  *    
44  *     Functionality:
45  *             This function is supplied as one of parameters during EGTP's 
46  *             task registration. SSI will invoke this function once, after
47  *             it creates and attaches this TAPA Task to a system task.
48  *     
49  * @param[in]  Ent entity, the entity ID of this task.     
50  * @param[in]  Inst inst, the instance ID of this task.
51  * @param[in]  Region region, the region ID registered for memory 
52  *              usage of this task.
53  * @param[in]  Reason reason.
54  * @return ROK     - success
55  *         RFAILED - failure
56  ***************************************************************************/
57 S16 egtpActvInit()
58 {
59   DU_LOG("\n\nDEBUG  -->  EGTP : Initializing");
60   memset (&egtpCb, 0, sizeof(EgtpGlobalCb));
61   
62   //Initializing with INVALID value
63   memset(egtpCb.gCntPdu, 0xFF , sizeof(uint8_t)*(MAX_TEID+1)); 
64   protType = CM_INET_PROTO_UDP;
65   return ROK;
66 }
67
68
69 /**************************************************************************
70  * @brief Task Activation callback function. 
71  *
72  * @details
73  *
74  *      Function : egtpActvTsk 
75  * 
76  *      Functionality:
77  *           This function handles all EGTP messages received
78  *           This API is registered with SSI during the 
79  *           Task Registration of DU APP.
80  *     
81  * @param[in]  Pst     *pst, Post structure of the primitive.     
82  * @param[in]  Buffer *mBuf, Packed primitive parameters in the
83  *  buffer.
84  * @return ROK     - success
85  *         RFAILED - failure
86  *
87  ***************************************************************************/
88 uint8_t egtpInitReq()
89 {
90    uint8_t ret = ROK;
91    
92    egtpCb.egtpCfg = cuCb.cuCfgParams.egtpParams;
93    ret = cuEgtpCfgReq();
94    if(ret != ROK)
95    {
96       DU_LOG("\nERROR  -->  EGTP : Configuration failed");
97       return (ret);
98    }
99
100    ret = cuEgtpSrvOpenReq();
101    if(ret != ROK)
102    {
103        DU_LOG("\nERROR  -->  EGTP : Transport server open request failed");
104        return (ret);
105    }
106
107    return ret;
108 } /* egtpInitReq */
109
110 /**************************************************************************
111  * @brief EGTP server configuration 
112  *
113  * @details
114  *
115  *      Function : egtpCfgReq
116  * 
117  *      Functionality:
118  *           This function handles EGTP configuration request.
119  *     
120  * @return ROK     - success
121  *         RFAILED - failure
122  *
123  * ***********************************************************************/
124 S16 cuEgtpCfgReq()
125 {
126    uint8_t ret, destIdx =0;
127    
128    memcpy(&egtpCb.egtpCfg, &cuCb.cuCfgParams.egtpParams, sizeof(CuEgtpParams));
129    
130    egtpCb.localAddr.address = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.localIp.ipV4Addr);
131    egtpCb.localAddr.port = egtpCb.egtpCfg.localPort;
132
133    for(destIdx=0; destIdx < egtpCb.egtpCfg.numDu; destIdx++)
134    {
135       egtpCb.dstCb[destIdx].duId = destIdx+1;
136       egtpCb.dstCb[destIdx].dstAddr.address = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.dstCfg[destIdx].dstIp.ipV4Addr);
137       egtpCb.dstCb[destIdx].dstAddr.port = egtpCb.egtpCfg.dstCfg[destIdx].dstPort;
138       egtpCb.dstCb[destIdx].numTunn = 0;
139
140       ret = cmHashListInit(&(egtpCb.dstCb[destIdx].teIdLst), 1024, sizeof(EgtpTeIdCb), FALSE, CM_HASH_KEYTYPE_UINT32_MOD, CU_APP_MEM_REG, CU_POOL);
141
142       if(ret != ROK)
143       {
144          DU_LOG("\nERROR  -->  EGTP : TeId hash list initialization failed");
145          return RFAILED;
146       }
147       else
148       {
149          DU_LOG("\nINFO  -->  EGTP : Configuration successful");
150       }
151    }
152    egtpCb.numDu = egtpCb.egtpCfg.numDu; 
153
154    return ROK;
155 } /* cuEgtpCfgReq */
156
157 /**************************************************************************
158  * @brief EGTP server open request 
159  *
160  * @details
161  *
162  *      Function : egtpSrvOpenReq
163  * 
164  *      Functionality:
165  *           This function handles EGTP open server request.
166  *           It opens udp socket to receive/send msgs.
167  *     
168  * @param[in]  Pst *pst, post structure
169  * @return ROK     - success
170  *         RFAILED - failure
171  *
172  ***************************************************************************/
173
174 S16 cuEgtpSrvOpenReq(Pst *pst)
175 {
176
177    uint8_t ret, destIdx;
178
179    DU_LOG("\nINFO  -->  EGTP : Received open server request");
180
181    sockType = CM_INET_DGRAM;
182    if((ret = (cmInetSocket(sockType, &(egtpCb.sockFd), protType))) != ROK)
183    {
184       DU_LOG("\nERROR  -->  EGTP : Failed to open UDP socket");
185       return RFAILED;
186    }
187
188    ret = cmInetBind(&(egtpCb.sockFd), &(egtpCb.localAddr));
189    if(ret != ROK)
190    {
191       DU_LOG("\nERROR  -->  EGTP : Failed to bind socket");
192       return RFAILED;
193    }
194
195    DU_LOG("\nINFO  -->  EGTP : Socket[%d] is open", egtpCb.sockFd.fd);
196    return ROK;
197 } /* cuEgtpSrvOpenReq */
198
199
200 /**************************************************************************
201  * @brief EGTP tunnel management request
202  *
203  * @details
204  *
205  *      Function : cuEgtpTnlMgmtReq
206  * 
207  *      Functionality:
208  *           This function handles EGTP tunnel managament request
209  *     
210  * @param[in]  Pst *pst, post structure
211  *             Tunnel Eveny structure
212  * @return ROK     - success
213  *         RFAILED - failure
214  *
215  
216  * ***************************************************************************/
217 S16 cuEgtpTnlMgmtReq(uint32_t duId, EgtpTnlEvt tnlEvt)
218 {
219    S8 ret;
220
221    DU_LOG("\nINFO  -->  EGTP : Received tunnel management request");
222    switch(tnlEvt.action)
223    {
224       case EGTP_TNL_MGMT_ADD:
225       {
226          ret = cuEgtpTnlAdd(duId, tnlEvt);
227          break;
228       }
229       case EGTP_TNL_MGMT_MOD:
230       {
231          ret = cuEgtpTnlMod(duId, tnlEvt);
232          break;
233       }
234       case EGTP_TNL_MGMT_DEL:
235       {
236          ret = cuEgtpTnlDel(duId, tnlEvt);
237          break;
238       }
239       default:
240       {
241          DU_LOG("\nERROR  -->  EGTP : Invalid tunnel management action[%d]", tnlEvt.action);
242          ret = RFAILED;
243       }
244    }
245
246    return (ret);
247 }
248
249 /**************************************************************************
250  * @brief EGTP tunnel addition
251  *
252  * @details
253  *
254  *      Function : cuEgtpTnlAdd
255  * 
256  *      Functionality:
257  *           This function handles EGTP tunnel addition
258  *     
259  * @param[in]  Tunnel Event structure
260  * @return ROK     - success
261  *         RFAILED - failure
262  *
263  * ***************************************************************************/
264 S16 cuEgtpTnlAdd(uint32_t duId, EgtpTnlEvt tnlEvt)
265 {
266    S16   ret;
267    EgtpTeIdCb     *teidCb;
268    EgtpMsgHdr   preDefHdr; /* pre-define header for this tunnel */
269    
270
271    DU_LOG("\nINFO  -->  EGTP : Tunnel addition : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
272
273    CU_ALLOC(teidCb, (Size)sizeof(EgtpTeIdCb));
274
275    if(teidCb == NULLP)
276    {
277       DU_LOG("\nERROR  -->  EGTP : Memory allocation failed");
278       return RFAILED;
279    }
280
281    memset(teidCb, 0, sizeof(EgtpTeIdCb));
282    teidCb->teId = tnlEvt.lclTeid;
283    teidCb->remTeId = tnlEvt.remTeid;
284
285    ret = cmHashListInsert(&(egtpCb.dstCb[duId-1].teIdLst), (PTR)teidCb, (uint8_t *)&(teidCb->teId), sizeof(uint32_t));
286    if(ret != ROK)
287    {
288       DU_LOG("\nERROR  -->  EGTP : Failed to insert in hash list");
289       CU_FREE(teidCb, (Size)sizeof(EgtpTeIdCb));
290       return RFAILED;
291    }
292    egtpCb.dstCb[duId-1].numTunn++;
293
294    /* Encoding pre-defined header */
295    memset(&preDefHdr, 0, sizeof(EgtpMsgHdr));
296    preDefHdr.msgType = EGTPU_MSG_GPDU;
297    preDefHdr.teId = teidCb->remTeId;
298    preDefHdr.extHdr.pdcpNmb.pres = FALSE;
299    preDefHdr.extHdr.udpPort.pres = FALSE;
300    preDefHdr.nPdu.pres = TRUE; //Including nPdu when sending data
301    preDefHdr.nPdu.val = 0;
302
303    cuEgtpEncodeHdr((uint8_t *)teidCb->preEncodedHdr.hdr, &preDefHdr, &(teidCb->preEncodedHdr.cnt));
304    egtpCb.gCntPdu[teidCb->remTeId] = 0;//Resetting the Cnt Value for this DRB which indicates its creation
305
306 /*   SPutSBuf(CU_APP_MEM_REG, CU_POOL, (Data *)teidCb, (Size)sizeof(EgtpTeIdCb));*/
307
308    return ROK;
309 } /* cuEgtpTnlAdd */
310
311 /**************************************************************************
312  * @brief EGTP tunnel modification
313  *
314  * @details
315  *
316  *      Function : cuEgtpTnlMod
317  * 
318  *      Functionality:
319  *           This function handles EGTP tunnel modification
320  *     
321  * @param[in]  Tunnel Event structure
322  * @return ROK     - success
323  *         RFAILED - failure
324  * 
325  * ***************************************************************************/
326 S16 cuEgtpTnlMod(uint32_t duId, EgtpTnlEvt tnlEvt)
327 {
328 #if 0
329    S16   ret;
330    EgtpTeIdCb     *teidCb = NULLP;
331
332    DU_LOG("\nDEBUG  -->  CU_STUB : Tunnel modification : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
333
334    cmHashListFind(&(egtpCb.dstCb[duId-1].teIdLst), (uint8_t *)&(tnlEvt.teId), sizeof(uint32_t), 0, (PTR *)&teidCb);
335    if(teidCb == NULLP)
336    {
337       DU_LOG("\nDEBUG --> CU_STUBTunnel id not found");
338       return RFAILED;
339    }  
340    
341    teidCb->teId = tnlEvt.lclTeid;
342    teidCb->remTeId = tnlEvt.remTeid;
343 #endif
344    return ROK;
345 }
346
347 /**************************************************************************
348  * @brief EGTP tunnel deletion
349  *
350  * @details
351  *
352  *     Function : cuEgtpTnlDel
353  * 
354  *     Functionality:
355  *         This function handles EGTP tunnel deletion
356  *    
357  * @param[in]  Tunnel Event structure
358  * @return ROK     - success
359  *         RFAILED - failure
360  * 
361  * ***************************************************************************/
362 S16 cuEgtpTnlDel(uint32_t duId, EgtpTnlEvt tnlEvt)
363 {
364    EgtpTeIdCb     *teidCb = NULLP;
365
366    DU_LOG("\nDEBUG  -->  EGTP : Tunnel deletion : Local Teid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
367    
368    cmHashListFind(&(egtpCb.dstCb[duId-1].teIdLst), (uint8_t *)&(tnlEvt.lclTeid), sizeof(uint32_t), 0, (PTR *)&teidCb);
369    if(teidCb == NULLP)
370    {
371       DU_LOG("\nERROR  -->  EGTP : Tunnel id[%d] not configured", tnlEvt.lclTeid);
372       return RFAILED;
373    } 
374
375    cmHashListDelete(&(egtpCb.dstCb[duId-1].teIdLst), (PTR)teidCb);
376    CU_FREE(teidCb, (Size)sizeof(EgtpTeIdCb));
377    egtpCb.dstCb[duId-1].numTunn--;
378
379    return ROK;
380 } /* cuEgtpTnlDel */
381
382 /*******************************************************************
383  *
384  * @brief Encodes message header
385  *
386  * @details
387  *
388  *    Function : cuEgtpEncodeHdr
389  * 
390  *    Functionality:
391  *       Encodes EGTP message haeder
392  *
393  * @params[in] EGTP message
394  *             Message Buffer 
395  * @return ROK     - success
396  *         RFAILED - failure
397  *
398  * ****************************************************************/
399 S16 cuEgtpEncodeHdr(uint8_t *preEncodedHdr, EgtpMsgHdr *preDefHdr, uint8_t *hdrIdx)
400 {
401    uint8_t         tmpByte = 0;                 /* Stores one byte of data for enc */
402    uint8_t         cnt     = EGTP_MAX_HDR_LEN;  /* Stores the position */
403    Bool       extPres = FALSE;             /* Flag for indication of S, E or P presense flag */
404    uint16_t        nwWord = 0;
405
406    /* Encoding header */
407    tmpByte |= EGTP_MASK_BIT6;   /* Setting 6th LSB of 1st byte as version */
408    tmpByte |= EGTP_MASK_BIT5;   /* Setting 5th LSB of 1st byte as protocol type */
409    
410    if(preDefHdr->extHdr.udpPort.pres || preDefHdr->extHdr.pdcpNmb.pres)
411    {
412       tmpByte |= EGTP_MASK_BIT3;  /* Setting 3rd LSB of 1st byte if Extension heaeder is present */
413    }
414     
415    if(preDefHdr->seqNum.pres)
416    {
417       tmpByte |= EGTP_MASK_BIT2;
418    }
419    
420    if(preDefHdr->nPdu.pres)
421    {
422       tmpByte |= EGTP_MASK_BIT1;
423    }
424    
425    if((tmpByte & EGTP_MASK_BIT1) || (tmpByte & EGTP_MASK_BIT2)||(tmpByte & EGTP_MASK_BIT3))
426    {
427       extPres = TRUE;
428    }
429    preEncodedHdr[--cnt] = tmpByte;
430    preEncodedHdr[--cnt] = preDefHdr->msgType;
431     
432    /* Encode Tunnel endpoint */
433    preEncodedHdr[--cnt] = 0;
434    preEncodedHdr[--cnt] = 0;
435    nwWord = (uint16_t)(GetHiWord(preDefHdr->teId));
436    preEncodedHdr[--cnt] = (uint8_t)(GetHiByte(nwWord));
437    preEncodedHdr[--cnt] = (uint8_t)(GetLoByte(nwWord));
438    nwWord = (uint16_t)(GetLoWord(preDefHdr->teId));
439    preEncodedHdr[--cnt] = (uint8_t)(GetHiByte(nwWord));
440    preEncodedHdr[--cnt] = (uint8_t)(GetLoByte(nwWord));
441     
442    /* Encode sequence number */
443    if(preDefHdr->seqNum.pres)
444    {
445       preEncodedHdr[--cnt] = GetHiByte(preDefHdr->seqNum.val);
446       preEncodedHdr[--cnt] = GetLoByte(preDefHdr->seqNum.val);
447    }
448    else if(extPres)
449    {
450       preEncodedHdr[--cnt] = 0;
451       preEncodedHdr[--cnt] = 0;
452    }
453
454    if(preDefHdr->nPdu.pres)
455    {
456       preEncodedHdr[--cnt] = preDefHdr->nPdu.val;
457    }
458    else if(extPres)
459    {
460       preEncodedHdr[--cnt] = 0;
461    }
462     
463    if(preDefHdr->extHdr.udpPort.pres)
464    {
465       preEncodedHdr[--cnt] = EGTP_EXT_HDR_UDP_TYPE;
466       preEncodedHdr[--cnt] = 1;
467       preEncodedHdr[--cnt] = GetHiByte(preDefHdr->extHdr.udpPort.val);
468       preEncodedHdr[--cnt] = GetLoByte(preDefHdr->extHdr.udpPort.val);
469    }
470    
471    if(preDefHdr->extHdr.pdcpNmb.pres)
472    {
473       preEncodedHdr[--cnt] = EGTP_EXT_HDR_PDCP_TYPE;
474       preEncodedHdr[--cnt] = 1;
475       preEncodedHdr[--cnt] = GetHiByte(preDefHdr->extHdr.pdcpNmb.val);
476       preEncodedHdr[--cnt] = GetLoByte(preDefHdr->extHdr.pdcpNmb.val);
477    }
478     
479    if(tmpByte & EGTP_MASK_BIT3)
480    {
481       preEncodedHdr[--cnt] = 0;
482    }
483    else if(extPres)
484    {
485       preEncodedHdr[--cnt] = 0;
486    } 
487    
488    *hdrIdx = cnt;
489    return ROK;
490
491 } /* egtpEncodeHdr */
492
493 /*******************************************************************
494  *
495  * @brief This handles the any EGTP received message 
496  *
497  * @details
498  *
499  *    Function : cuEgtpHdlRecvMsg 
500  * 
501  *    Functionality:
502  *       This handles the any EGTP received message
503  *
504  * @params[in]  Message Buffer 
505  * @return ROK     - success
506  *         RFAILED - failure
507  *
508  * ****************************************************************/
509 S16 cuEgtpHdlRecvMsg(Buffer *mBuf)
510 {
511    /*Decoding of EGTP message header */
512    
513    cuEgtpDecodeHdr(mBuf);
514    
515    /* Start Pumping data from CU to DU */
516    //return (cuEgtpDatReq());
517
518 }
519
520 /*******************************************************************
521  *
522  * @brief Decodes message header
523  *
524  * @details
525  *
526  *    Function : cuEgtpDecodeHdr 
527  * 
528  *    Functionality:
529  *       Decodes EGTP message haeder
530  *
531  * @params[in]  Message Buffer 
532  * @return ROK     - success
533  *         RFAILED - failure
534  *
535  * ****************************************************************/
536 S16 cuEgtpDecodeHdr(Buffer *mBuf)
537 {
538    EgtpMsg  egtpMsg;
539    uint8_t       tmpByte[5];         /* Holds one byte of data after Dec */
540    uint8_t       version = 0;         /* Holds the version type, decoded */
541    MsgLen   msgLen  = 0;         /* Holds the msgLen from the Hdr */
542    MsgLen   bufLen  = 0;         /* Holds the total buffer length */
543    uint8_t       extHdrType = 0;       /* Holds the Extension hdr type */
544    uint8_t       extHdrLen = 0;        /* Extension hdr length */
545    Bool     extPres = FALSE;      /* Flag for indication of S, E or P presense flag */
546
547    ODU_GET_MSG_LEN(mBuf, &bufLen);
548
549    /* Decode version */
550    ODU_REM_PRE_MSG(&tmpByte[0], mBuf);
551    version = tmpByte[0] >> 5;
552
553    /* Decode message type */
554    ODU_REM_PRE_MSG((Data*)&(egtpMsg.msgHdr.msgType), mBuf);
555
556    /* Decode message length */
557    ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
558    ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
559    msgLen = (tmpByte[1] << 8) | tmpByte[2];
560
561    /* Decode tunnel id */
562    ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
563    ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
564    ODU_REM_PRE_MSG(&tmpByte[3], mBuf);
565    ODU_REM_PRE_MSG(&tmpByte[4], mBuf);
566    egtpMsg.msgHdr.teId = (tmpByte[1] << 24) | (tmpByte[2] << 16) | (tmpByte[3] << 8) | tmpByte[4];
567
568    if((tmpByte[0] & EGTP_MASK_BIT1) || (tmpByte[0] & EGTP_MASK_BIT2)||(tmpByte[0] & EGTP_MASK_BIT3))
569    {
570       extPres = TRUE;
571    }
572
573    /* Decode sequence number */
574    if ( tmpByte[0] & EGTP_MASK_BIT2 )
575    {
576       egtpMsg.msgHdr.seqNum.pres = TRUE;
577       ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
578       ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
579       egtpMsg.msgHdr.seqNum.val = (tmpByte[1] << 8) | tmpByte[2];
580    }
581    else  if(extPres)
582    {
583       egtpMsg.msgHdr.seqNum.pres = 0;
584       ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
585       ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
586       egtpMsg.msgHdr.seqNum.val = (tmpByte[1] << 8) | tmpByte[2];
587    }
588
589    /* Decode N-PDU number */
590    if ( tmpByte[0] & EGTP_MASK_BIT1 )
591    {
592       egtpMsg.msgHdr.nPdu.pres = TRUE;
593       ODU_REM_PRE_MSG(&(egtpMsg.msgHdr.nPdu.val), mBuf);
594    }
595    else if(extPres)
596    {
597       egtpMsg.msgHdr.nPdu.pres = TRUE;
598       ODU_REM_PRE_MSG(&(egtpMsg.msgHdr.nPdu.val), mBuf);
599    }
600
601    if(extPres & EGTP_MASK_BIT1)
602    {
603       ODU_REM_PRE_MSG(&extHdrType, mBuf);
604       while( 0 != extHdrType)
605       {
606          switch (extHdrType)
607          {
608             case EGTP_EXT_HDR_UDP_TYPE:
609             {
610                ODU_REM_PRE_MSG(&extHdrLen, mBuf);
611                if(extHdrLen == 0x01)
612                {
613                   egtpMsg.msgHdr.extHdr.udpPort.pres = TRUE;
614                   ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
615                   ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
616                   egtpMsg.msgHdr.extHdr.udpPort.val = (tmpByte[1] << 8) | tmpByte[2];
617                }
618                break;
619             }
620
621             case EGTP_EXT_HDR_PDCP_TYPE:
622             {
623                ODU_REM_PRE_MSG(&extHdrLen, mBuf);
624                if(extHdrLen == 0x01)
625                {
626                   egtpMsg.msgHdr.extHdr.pdcpNmb.pres = TRUE;
627                   ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
628                   ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
629                   egtpMsg.msgHdr.extHdr.pdcpNmb.val = (tmpByte[1] << 8) | tmpByte[2];
630                }
631                break;
632             }
633          } /* End of switch */
634
635          ODU_REM_PRE_MSG(&extHdrType, mBuf);
636
637       } /* End of while */
638    } /* End of if(extPres & EGTP_MASK_BIT1) */
639    else if(extPres)
640    {
641       ODU_REM_PRE_MSG(&extHdrType, mBuf);
642    }
643
644    DU_LOG("\nDEBUG  -->  EGTP : Message Buffer after decoding header [TEID:%d]",egtpMsg.msgHdr.teId);
645    ODU_PRINT_MSG(mBuf, 0, 0);
646
647    SPutMsg(mBuf);
648
649    return ROK;
650      
651 } /* End of cuEgtpDecodeHdr */
652
653 /*******************************************************************
654  *
655  * @brief This function is responsible to build application message, encode EGTP
656  * header to it and send to DU over tunnel (teId)
657  *
658  * @details
659  *
660  *    Function : cuEgtpDatReq
661  * 
662  *    Functionality:
663  *       function is responsible to build application message, encode EGTP
664  *       header to it and send to DU over tunnel (teId) 
665  *
666  * @params[in]  uint8_t teId
667  *
668  * @return ROK     - success
669  *         RFAILED - failure
670  *
671  * ****************************************************************/
672 uint16_t cuEgtpDatReq(uint32_t duId, uint8_t teId)
673 {
674    uint8_t ret = ROK, cnt = 0;
675    EgtpMsg  egtpMsg;
676
677    egtpMsg.msgHdr.teId = teId;
678    
679    if(egtpCb.gCntPdu[teId] == 0xFF) //DRB not created
680    {
681       DU_LOG("\nERROR  -->  EGTP : DRB  not created");
682       return RFAILED ;
683    }
684    /* Build Application message that is supposed to come from app to egtp */
685    ret = BuildAppMsg(duId, &egtpMsg);
686    if(ret != ROK)
687    {
688       DU_LOG("\nERROR  -->  EGTP : Failed to build App Msg");
689       return RFAILED;
690    }
691
692    /* Encode EGTP header to build final EGTP message */
693    ret = BuildEgtpMsg(duId, &egtpMsg);
694    if(ret != ROK)
695    {
696       DU_LOG("\nERROR  -->  EGTP : Failed to build EGTP Msg");
697       return RFAILED;
698    }
699    cuEgtpSendMsg(duId, egtpMsg.msg);
700    ODU_PUT_MSG_BUF(egtpMsg.msg);
701    return ROK;
702 }
703
704
705 /*******************************************************************
706  *
707  * @brief Builds application message to be sent to DU in DL path
708  *
709  * @details
710  *
711  *    Function : BuildAppMsg
712  * 
713  *    Functionality:
714  *      Builds application message to be sent to DU in DL path
715  *
716  * @params[in] uint32_t duId,EGTP message
717  *             
718  * @return ROK     - success
719  *         RFAILED - failure
720  *
721  * ****************************************************************/
722 S16 BuildAppMsg(uint32_t duId, EgtpMsg  *egtpMsg)
723 {
724    char data[1215] = "In telecommunications, 5G is the fifth generation technology standard for broadband cellular"
725    " networks, which cellular phone companies began deploying worldwide in 2019, and is the planned successor to the 4G "
726    " networks which provide connectivity to most current cellphones. 5G networks are predicted to have more than 1.7"
727    " billion subscribers worldwide by 2025, according to the GSM Association.Like its predecessors, 5G networks are"
728    " cellular networks,in which the service area is divided into small geographical areas called cells.All 5G wireless"
729    " devices in a cell are connected to the Internet and telephone network by radio waves through local antenna in the"
730    " cell. The main advantage of the new networks is that they will have greater bandwidth, giving higher download"
731    " speeds, eventually up to 10 gigabits per second(Gbit/s). Due to the increased bandwidth, it is expected the"
732    " networks will not exclusively serve cellphones like existing cellular networks, but also be used as general"
733    " internet service providers for laptops and desktop computers, competing with existing ISPs such as cable"
734    " internet, and also will make possible new applications in internet of things (IoT) and machine to machine areas.";
735
736    int datSize = 1215;
737  
738    Buffer   *mBuf;
739  
740    if(ODU_GET_MSG_BUF(CU_APP_MEM_REG, CU_POOL, &mBuf) == ROK)
741    {
742       if(ODU_ADD_POST_MSG_MULT((Data *)data, datSize, mBuf) != ROK)
743       {
744          DU_LOG("\nERROR  -->  EGTP : ODU_ADD_POST_MSG_MULT failed");
745          ODU_PUT_MSG_BUF(mBuf);
746          return RFAILED;
747       }
748    }
749    else
750    {
751        DU_LOG("\nERROR  -->  EGTP : Failed to allocate memory");
752        return RFAILED;
753    }
754  
755    /* filling IPv4 header */
756    CmIpv4Hdr ipv4Hdr;
757    MsgLen    mLen;
758  
759    mLen = 0;
760    ODU_GET_MSG_LEN(mBuf, &mLen);
761
762    memset(&ipv4Hdr, 0, sizeof(CmIpv4Hdr));
763    ipv4Hdr.length = CM_IPV4_HDRLEN + mLen;
764    ipv4Hdr.hdrVer = 0x45;
765    ipv4Hdr.proto = 1;
766    ipv4Hdr.srcAddr = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.localIp.ipV4Addr);
767    ipv4Hdr.destAddr = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.dstCfg[duId-1].dstIp.ipV4Addr);
768  
769    /* Packing IPv4 header into buffer */
770    S16          ret, cnt, idx;
771    Data         revPkArray[CM_IPV4_HDRLEN];
772    Data         pkArray[CM_IPV4_HDRLEN];
773  
774    /* initialize locals */
775    cnt = 0;
776    memset(revPkArray, 0, CM_IPV4_HDRLEN);
777    memset(pkArray, 0, CM_IPV4_HDRLEN);
778
779    /* Pack Header Version */
780    pkArray[cnt++] = ipv4Hdr.hdrVer;
781  
782    /* Pack TOS */
783    pkArray[cnt++] = ipv4Hdr.tos;
784  
785    pkArray[cnt++] = (Data)GetHiByte(ipv4Hdr.length);
786    pkArray[cnt++] = (Data)GetLoByte(ipv4Hdr.length);
787  
788    /* Pack Id */
789    pkArray[cnt++] = (Data) GetHiByte(ipv4Hdr.id);
790    pkArray[cnt++] = (Data) GetLoByte(ipv4Hdr.id);
791  
792    /* Pack Offset */
793    pkArray[cnt++] = (Data)GetHiByte(ipv4Hdr.off);
794    pkArray[cnt++] = (Data)GetLoByte(ipv4Hdr.off);
795  
796    /* Pack TTL */
797    pkArray[cnt++] = ipv4Hdr.ttl;
798  
799    /* Pack Protocol */
800    pkArray[cnt++] = ipv4Hdr.proto;
801  
802    /* Pack Checksum */
803    pkArray[cnt++] = (Data)GetHiByte(ipv4Hdr.chkSum);
804    pkArray[cnt++] = (Data)GetLoByte(ipv4Hdr.chkSum);
805                                                         
806    /* Pack Source Address */
807    pkArray[cnt++] = (Data)GetHiByte(GetHiWord(ipv4Hdr.srcAddr));
808    pkArray[cnt++] = (Data)GetLoByte(GetHiWord(ipv4Hdr.srcAddr));
809    pkArray[cnt++] = (Data)GetHiByte(GetLoWord(ipv4Hdr.srcAddr));
810    pkArray[cnt++] = (Data)GetLoByte(GetLoWord(ipv4Hdr.srcAddr));
811  
812    /* Pack Destination Address */
813    pkArray[cnt++] = (Data)GetHiByte(GetHiWord(ipv4Hdr.destAddr));
814    pkArray[cnt++] = (Data)GetLoByte(GetHiWord(ipv4Hdr.destAddr));
815    pkArray[cnt++] = (Data)GetHiByte(GetLoWord(ipv4Hdr.destAddr));
816    pkArray[cnt++] = (Data)GetLoByte(GetLoWord(ipv4Hdr.destAddr));
817  
818    for (idx = 0;  idx < CM_IPV4_HDRLEN;  idx++)
819       revPkArray[idx] = pkArray[CM_IPV4_HDRLEN - idx -1];
820  
821    /* this function automatically reverses revPkArray */
822    ret = ODU_ADD_PRE_MSG_MULT(revPkArray, (MsgLen)cnt, mBuf);
823  
824    egtpMsg->msgHdr.msgType = EGTPU_MSG_GPDU;
825    egtpMsg->msgHdr.nPdu.pres = TRUE;
826
827    if(egtpCb.gCntPdu[egtpMsg->msgHdr.teId] != NUM_DL_PACKETS)
828      egtpCb.gCntPdu[egtpMsg->msgHdr.teId]++;
829    else
830      egtpCb.gCntPdu[egtpMsg->msgHdr.teId] = 1;
831
832    egtpMsg->msgHdr.nPdu.val = egtpCb.gCntPdu[egtpMsg->msgHdr.teId];
833    egtpMsg->msgHdr.seqNum.pres = FALSE;
834    egtpMsg->msgHdr.extHdr.udpPort.pres = FALSE;
835    egtpMsg->msgHdr.extHdr.pdcpNmb.pres = FALSE;
836    egtpMsg->msg = mBuf;
837
838    return ret;
839 }
840
841 /*******************************************************************
842  *
843  * @brief Encodes EGTP header to application message to send to DU
844  *
845  * @details
846  *
847  *    Function : BuildEgtpMsg
848  * 
849  *    Functionality:
850  *        Encodes EGTP header to application message to send to DU
851  *
852  * @params[in] uint32_t duId,EGTP message
853  *             
854  * @return ROK     - success
855  *         RFAILED - failure
856  *
857  * ****************************************************************/
858 S16 BuildEgtpMsg(uint32_t duId, EgtpMsg *egtpMsg)
859 {
860    EgtpTeIdCb   *teidCb = NULLP;
861    MsgLen tPduSize;
862    uint8_t     hdrLen;
863    uint32_t    msgLen;
864    EgtpMsgHdr   *msgHdr;
865  
866    cmHashListFind(&(egtpCb.dstCb[duId-1].teIdLst), (uint8_t *)&(egtpMsg->msgHdr.teId), sizeof(uint32_t), 0, (PTR *)&teidCb);
867    if(teidCb == NULLP)
868    {
869       DU_LOG("\nERROR  -->  EGTP : Tunnel id[%d] not configured", egtpMsg->msgHdr.teId);
870       return (LCM_REASON_INVALID_PAR_VAL);
871    }
872
873    msgHdr = &(egtpMsg->msgHdr);
874
875    hdrLen = teidCb->preEncodedHdr.cnt;
876
877    if(msgHdr->extHdr.pdcpNmb.pres)
878    {
879       teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= EGTP_MASK_BIT3;
880       teidCb->preEncodedHdr.hdr[hdrLen] = EGTP_EXT_HDR_PDCP_TYPE;
881       teidCb->preEncodedHdr.hdr[--hdrLen] = 1;
882       teidCb->preEncodedHdr.hdr[--hdrLen] = GetHiByte(msgHdr->extHdr.pdcpNmb.val);
883       teidCb->preEncodedHdr.hdr[--hdrLen] = GetLoByte(msgHdr->extHdr.pdcpNmb.val);
884       teidCb->preEncodedHdr.hdr[--hdrLen] = 0;
885    }
886    else
887    {
888       teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT3);
889    }
890  
891    ODU_GET_MSG_LEN(egtpMsg->msg, &tPduSize);
892
893    /*Adjust the header to fill the correct length*/
894    msgLen = tPduSize +  (EGTP_MAX_HDR_LEN - hdrLen) - 0x08;
895
896    /***********************************************
897     * Fill the length field of the message header *
898     ***********************************************/
899    teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 3] = (uint8_t)GetHiByte(msgLen);
900    teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 4] = (uint8_t)GetLoByte(msgLen);
901
902    /*Update the sequence number*/
903    if(egtpMsg->msgHdr.seqNum.pres)
904    {
905       teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= (EGTP_MASK_BIT2);
906       teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 9] = (uint8_t)GetHiByte(egtpMsg->msgHdr.seqNum.val);
907       teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 10] = (uint8_t)GetLoByte(egtpMsg->msgHdr.seqNum.val);
908    }
909    else
910    {
911       teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT2);
912    }
913
914    /*Update the nPdU number*/
915    if(egtpMsg->msgHdr.nPdu.pres)
916    {
917       teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= (EGTP_MASK_BIT1);
918       teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 11] = egtpMsg->msgHdr.nPdu.val;
919    }
920    else
921    {
922       teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT1);
923    }
924
925    ODU_ADD_PRE_MSG_MULT(&teidCb->preEncodedHdr.hdr[hdrLen], (EGTP_MAX_HDR_LEN - hdrLen), egtpMsg->msg);
926    return ROK;
927 }
928
929 /*******************************************************************
930  *
931  * @brief Send the egtp message to the destination DU
932  *
933  * @details
934  *
935  *    Function : cuEgtpSendMsg 
936  * 
937  *    Functionality:
938  *       Send the egtp message to the destination DU
939  *
940  * @params[in] uint32_t duId 
941  *             Message Buffer 
942  * @return ROK     - success
943  *         RFAILED - failure
944  *
945  * ****************************************************************/
946 S16 cuEgtpSendMsg(uint32_t duId, Buffer *mBuf)
947 {
948    S16            ret;
949    MsgLen         txLen;
950    CmInetMemInfo  info;
951
952    info.region = CU_APP_MEM_REG;
953    info.pool = CU_POOL;
954  
955    ret = cmInetSendMsg(&(egtpCb.sockFd), &egtpCb.dstCb[duId-1].dstAddr, &info, mBuf, &txLen, CM_INET_NO_FLAG);
956    if(ret != ROK && ret != RWOULDBLOCK)
957    {
958       DU_LOG("\nERROR  -->  EGTP : Message send failure");
959       return RFAILED;
960    }
961    
962    DU_LOG("\nDEBUG  -->  EGTP : Message Sent");
963  
964    return ROK;
965 }