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