Merge "Classification of CM logs [JIRA ID - ODUHIGH-275]"
[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 "cu_stub_egtp.h"
23 #include "du_log.h"
24
25 /* Global variable declaration */
26 EgtpGlobalCb egtpCb;
27
28 /**************************************************************************
29  * @brief Task Initiation callback function. 
30  *
31  * @details
32  *
33  *     Function : egtpActvInit 
34  *    
35  *     Functionality:
36  *             This function is supplied as one of parameters during EGTP's 
37  *             task registration. SSI will invoke this function once, after
38  *             it creates and attaches this TAPA Task to a system task.
39  *     
40  * @param[in]  Ent entity, the entity ID of this task.     
41  * @param[in]  Inst inst, the instance ID of this task.
42  * @param[in]  Region region, the region ID registered for memory 
43  *              usage of this task.
44  * @param[in]  Reason reason.
45  * @return ROK     - success
46  *         RFAILED - failure
47  ***************************************************************************/
48 S16 egtpActvInit()
49 {
50   DU_LOG("\n\nDEBUG  -->  EGTP : Initializing");
51   memset (&egtpCb, 0, sizeof(EgtpGlobalCb));
52   protType = CM_INET_PROTO_UDP;
53   return ROK;
54 }
55
56
57 /**************************************************************************
58  * @brief Task Activation callback function. 
59  *
60  * @details
61  *
62  *      Function : egtpActvTsk 
63  * 
64  *      Functionality:
65  *           This function handles all EGTP messages received
66  *           This API is registered with SSI during the 
67  *           Task Registration of DU APP.
68  *     
69  * @param[in]  Pst     *pst, Post structure of the primitive.     
70  * @param[in]  Buffer *mBuf, Packed primitive parameters in the
71  *  buffer.
72  * @return ROK     - success
73  *         RFAILED - failure
74  *
75  ***************************************************************************/
76 uint8_t egtpInitReq()
77 {
78    uint8_t ret = ROK;
79    EgtpTnlEvt tnlEvt;
80
81    ret = cuEgtpCfgReq();
82    if(ret != ROK)
83    {
84       DU_LOG("\nERROR  -->  EGTP : Configuration failed");
85       return (ret);
86    }
87
88    ret = cuEgtpSrvOpenReq();
89    if(ret != ROK)
90    {
91        DU_LOG("\nERROR  -->  EGTP : Transport server open request failed");
92        return (ret);
93    }
94
95    tnlEvt.action = EGTP_TNL_MGMT_ADD;
96    tnlEvt.lclTeid = 10;
97    tnlEvt.remTeid = 1;
98    ret = cuEgtpTnlMgmtReq(tnlEvt);
99    if(ret != ROK)
100    {
101       DU_LOG("\nERROR  -->  EGTP : Tunnel management request failed");
102       return RFAILED;
103    }
104
105    return ret;
106 } /* egtpInitReq */
107
108 /**************************************************************************
109  * @brief EGTP server configuration 
110  *
111  * @details
112  *
113  *      Function : egtpCfgReq
114  * 
115  *      Functionality:
116  *           This function handles EGTP configuration request.
117  *     
118  * @return ROK     - success
119  *         RFAILED - failure
120  *
121  * ***********************************************************************/
122 S16 cuEgtpCfgReq()
123 {
124    uint8_t ret;
125
126    memcpy(&egtpCb.egtpCfg, &cuCfgParams.egtpParams, sizeof(EgtpParams));
127
128    egtpCb.recvTptSrvr.addr.address = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.localIp.ipV4Addr);
129    egtpCb.recvTptSrvr.addr.port = EGTP_DFLT_PORT;
130
131    egtpCb.dstCb.dstIp = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.destIp.ipV4Addr);
132    egtpCb.dstCb.dstPort = egtpCb.egtpCfg.destPort;
133    egtpCb.dstCb.sendTptSrvr.addr.address = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.localIp.ipV4Addr);
134    egtpCb.dstCb.sendTptSrvr.addr.port = egtpCb.egtpCfg.localPort;
135    egtpCb.dstCb.numTunn = 0;
136
137    ret = cmHashListInit(&(egtpCb.dstCb.teIdLst), 1024, sizeof(EgtpTeIdCb), FALSE, CM_HASH_KEYTYPE_UINT32_MOD, CU_APP_MEM_REG, CU_POOL);
138
139    if(ret != ROK)
140    {
141       DU_LOG("\nERROR  -->  EGTP : TeId hash list initialization failed");
142       return RFAILED;
143    }
144    else
145    {
146       DU_LOG("\nINFO  -->  EGTP : Configuration successful");
147    }
148
149    return ROK;
150 } /* cuEgtpCfgReq */
151
152 /**************************************************************************
153  * @brief EGTP server open request 
154  *
155  * @details
156  *
157  *      Function : egtpSrvOpenReq
158  * 
159  *      Functionality:
160  *           This function handles EGTP open server request.
161  *           It opens udp socket to receive/send msgs.
162  *     
163  * @param[in]  Pst *pst, post structure
164  * @return ROK     - success
165  *         RFAILED - failure
166  *
167  ***************************************************************************/
168
169 S16 cuEgtpSrvOpenReq(Pst *pst)
170 {
171
172    uint8_t ret;
173
174    DU_LOG("\nINFO  -->  EGTP : Received open server request");
175  
176    sockType = CM_INET_DGRAM;
177    if((ret = (cmInetSocket(sockType, &(egtpCb.recvTptSrvr.sockFd), protType))) != ROK)
178    {
179       DU_LOG("\nERROR  -->  EGTP : Failed to open UDP socket");
180       return RFAILED;
181    }
182
183    ret = cmInetBind(&(egtpCb.recvTptSrvr.sockFd), &(egtpCb.recvTptSrvr.addr));
184    if(ret != ROK)
185    {
186       DU_LOG("\nERROR  -->  EGTP : Failed to bind socket");
187       return RFAILED;
188    }
189
190    if(ret = (cmInetSocket(sockType, &(egtpCb.dstCb.sendTptSrvr.sockFd), protType)) != ROK)
191    {  
192       DU_LOG("\nERROR  -->  EGTP : Failed to open UDP socket");
193       return RFAILED;
194    }
195       
196    ret = cmInetBind(&(egtpCb.dstCb.sendTptSrvr.sockFd), &(egtpCb.dstCb.sendTptSrvr.addr));
197    if(ret != ROK)
198    {  
199       DU_LOG("\nERROR  -->  EGTP : Failed to bind socket");
200       return RFAILED;
201    }
202        
203    /* TODO: set socket options */
204
205    DU_LOG("\nINFO  -->  EGTP : Receiver socket[%d] and Sender socket[%d] open", egtpCb.recvTptSrvr.sockFd.fd,\
206    egtpCb.dstCb.sendTptSrvr.sockFd.fd);
207    return ROK;
208 } /* cuEgtpSrvOpenReq */
209
210
211 /**************************************************************************
212  * @brief EGTP tunnel management request
213  *
214  * @details
215  *
216  *      Function : cuEgtpTnlMgmtReq
217  * 
218  *      Functionality:
219  *           This function handles EGTP tunnel managament request
220  *     
221  * @param[in]  Pst *pst, post structure
222  *             Tunnel Eveny structure
223  * @return ROK     - success
224  *         RFAILED - failure
225  *
226  
227  * ***************************************************************************/
228 S16 cuEgtpTnlMgmtReq(EgtpTnlEvt tnlEvt)
229 {
230    S8 ret;
231
232    DU_LOG("\nINFO  -->  EGTP : Received tunnel management request");
233    switch(tnlEvt.action)
234    {
235       case EGTP_TNL_MGMT_ADD:
236       {
237          ret = cuEgtpTnlAdd(tnlEvt);
238          break;
239       }
240       case EGTP_TNL_MGMT_MOD:
241       {
242          ret = cuEgtpTnlMod(tnlEvt);
243          break;
244       }
245       case EGTP_TNL_MGMT_DEL:
246       {
247          ret = cuEgtpTnlDel(tnlEvt);
248          break;
249       }
250       default:
251       {
252          DU_LOG("\nERROR  -->  EGTP : Invalid tunnel management action[%d]", tnlEvt.action);
253          ret = RFAILED;
254       }
255    }
256
257    return (ret);
258 }
259
260 /**************************************************************************
261  * @brief EGTP tunnel addition
262  *
263  * @details
264  *
265  *      Function : cuEgtpTnlAdd
266  * 
267  *      Functionality:
268  *           This function handles EGTP tunnel addition
269  *     
270  * @param[in]  Tunnel Event structure
271  * @return ROK     - success
272  *         RFAILED - failure
273  *
274  * ***************************************************************************/
275 S16 cuEgtpTnlAdd(EgtpTnlEvt tnlEvt)
276 {
277    S16   ret;
278    EgtpTeIdCb     *teidCb;
279    EgtpMsgHdr   preDefHdr; /* pre-define header for this tunnel */
280    
281
282    DU_LOG("\nINFO  -->  EGTP : Tunnel addition : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
283
284    CU_ALLOC(teidCb, (Size)sizeof(EgtpTeIdCb));
285
286    if(teidCb == NULLP)
287    {
288       DU_LOG("\nERROR  -->  EGTP : Memory allocation failed");
289       return RFAILED;
290    }
291
292
293    memset(teidCb, 0, sizeof(EgtpTeIdCb));
294    teidCb->teId = tnlEvt.lclTeid;
295    teidCb->remTeId = tnlEvt.remTeid;
296
297    ret = cmHashListInsert(&(egtpCb.dstCb.teIdLst), (PTR)teidCb, (uint8_t *)&(teidCb->teId), sizeof(uint32_t));
298    if(ret != ROK)
299    {
300       DU_LOG("\nERROR  -->  EGTP : Failed to insert in hash list");
301       CU_FREE(teidCb, (Size)sizeof(EgtpTeIdCb));
302       return RFAILED;
303    }
304    egtpCb.dstCb.numTunn++;
305
306    /* Encoding pre-defined header */
307    memset(&preDefHdr, 0, sizeof(EgtpMsgHdr));
308    preDefHdr.msgType = EGTPU_MSG_GPDU;
309    preDefHdr.teId = teidCb->remTeId;
310    preDefHdr.extHdr.pdcpNmb.pres = FALSE;
311    preDefHdr.extHdr.udpPort.pres = FALSE;
312    preDefHdr.nPdu.pres = FALSE;
313    
314    cuEgtpEncodeHdr((uint8_t *)teidCb->preEncodedHdr.hdr, &preDefHdr, &(teidCb->preEncodedHdr.cnt));
315
316 /*   SPutSBuf(CU_APP_MEM_REG, CU_POOL, (Data *)teidCb, (Size)sizeof(EgtpTeIdCb));*/
317
318    return ROK;
319 } /* cuEgtpTnlAdd */
320
321 /**************************************************************************
322  * @brief EGTP tunnel modification
323  *
324  * @details
325  *
326  *      Function : cuEgtpTnlMod
327  * 
328  *      Functionality:
329  *           This function handles EGTP tunnel modification
330  *     
331  * @param[in]  Tunnel Event structure
332  * @return ROK     - success
333  *         RFAILED - failure
334  * 
335  * ***************************************************************************/
336 S16 cuEgtpTnlMod(EgtpTnlEvt tnlEvt)
337 {
338 #if 0
339    S16   ret;
340    EgtpTeIdCb     *teidCb = NULLP;
341
342    DU_LOG("\nDEBUG  -->  CU_STUB : Tunnel modification : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
343
344    cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(tnlEvt.teId), sizeof(uint32_t), 0, (PTR *)&teidCb);
345    if(teidCb == NULLP)
346    {
347       DU_LOG("\nDEBUG --> CU_STUBTunnel id not found");
348       return RFAILED;
349    }  
350    
351    teidCb->teId = tnlEvt.lclTeid;
352    teidCb->remTeId = tnlEvt.remTeid;
353 #endif
354    return ROK;
355 }
356
357 /**************************************************************************
358  * @brief EGTP tunnel deletion
359  *
360  * @details
361  *
362  *     Function : cuEgtpTnlDel
363  * 
364  *     Functionality:
365  *         This function handles EGTP tunnel deletion
366  *    
367  * @param[in]  Tunnel Event structure
368  * @return ROK     - success
369  *         RFAILED - failure
370  * 
371  * ***************************************************************************/
372 S16 cuEgtpTnlDel(EgtpTnlEvt tnlEvt)
373 {
374    EgtpTeIdCb     *teidCb = NULLP;
375
376    DU_LOG("\nDEBUG  -->  EGTP : Tunnel deletion : Local Teid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
377    
378    cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(tnlEvt.lclTeid), sizeof(uint32_t), 0, (PTR *)&teidCb);
379    if(teidCb == NULLP)
380    {
381       DU_LOG("\nERROR  -->  EGTP : Tunnel id[%d] not configured", tnlEvt.lclTeid);
382       return RFAILED;
383    } 
384
385    cmHashListDelete(&(egtpCb.dstCb.teIdLst), (PTR)teidCb);
386    CU_FREE(teidCb, (Size)sizeof(EgtpTeIdCb));
387    egtpCb.dstCb.numTunn--;
388
389    return ROK;
390 } /* cuEgtpTnlDel */
391
392 /*******************************************************************
393  *
394  * @brief Encodes message header
395  *
396  * @details
397  *
398  *    Function : cuEgtpEncodeHdr
399  * 
400  *    Functionality:
401  *       Encodes EGTP message haeder
402  *
403  * @params[in] EGTP message
404  *             Message Buffer 
405  * @return ROK     - success
406  *         RFAILED - failure
407  *
408  * ****************************************************************/
409 S16 cuEgtpEncodeHdr(uint8_t *preEncodedHdr, EgtpMsgHdr *preDefHdr, uint8_t *hdrIdx)
410 {
411    uint8_t         tmpByte = 0;                 /* Stores one byte of data for enc */
412    uint8_t         cnt     = EGTP_MAX_HDR_LEN;  /* Stores the position */
413    Bool       extPres = FALSE;             /* Flag for indication of S, E or P presense flag */
414    uint16_t        nwWord = 0;
415
416    /* Encoding header */
417    tmpByte |= EGTP_MASK_BIT6;   /* Setting 6th LSB of 1st byte as version */
418    tmpByte |= EGTP_MASK_BIT5;   /* Setting 5th LSB of 1st byte as protocol type */
419    
420    if(preDefHdr->extHdr.udpPort.pres || preDefHdr->extHdr.pdcpNmb.pres)
421    {
422       tmpByte |= EGTP_MASK_BIT3;  /* Setting 3rd LSB of 1st byte if Extension heaeder is present */
423    }
424     
425    if(preDefHdr->seqNum.pres)
426    {
427       tmpByte |= EGTP_MASK_BIT2;
428    }
429    
430    if(preDefHdr->nPdu.pres)
431    {
432       tmpByte |= EGTP_MASK_BIT1;
433    }
434    
435    if((tmpByte & EGTP_MASK_BIT1) || (tmpByte & EGTP_MASK_BIT2)||(tmpByte & EGTP_MASK_BIT3))
436    {
437       extPres = TRUE;
438    }
439    preEncodedHdr[--cnt] = tmpByte;
440    preEncodedHdr[--cnt] = preDefHdr->msgType;
441     
442    /* Encode Tunnel endpoint */
443    preEncodedHdr[--cnt] = 0;
444    preEncodedHdr[--cnt] = 0;
445    nwWord = (uint16_t)(GetHiWord(preDefHdr->teId));
446    preEncodedHdr[--cnt] = (uint8_t)(GetHiByte(nwWord));
447    preEncodedHdr[--cnt] = (uint8_t)(GetLoByte(nwWord));
448    nwWord = (uint16_t)(GetLoWord(preDefHdr->teId));
449    preEncodedHdr[--cnt] = (uint8_t)(GetHiByte(nwWord));
450    preEncodedHdr[--cnt] = (uint8_t)(GetLoByte(nwWord));
451     
452    /* Encode sequence number */
453    if(preDefHdr->seqNum.pres)
454    {
455       preEncodedHdr[--cnt] = GetHiByte(preDefHdr->seqNum.val);
456       preEncodedHdr[--cnt] = GetLoByte(preDefHdr->seqNum.val);
457    }
458    else if(extPres)
459    {
460       preEncodedHdr[--cnt] = 0;
461       preEncodedHdr[--cnt] = 0;
462    }
463
464    if(preDefHdr->nPdu.pres)
465    {
466       preEncodedHdr[--cnt] = preDefHdr->nPdu.val;
467    }
468    else if(extPres)
469    {
470       preEncodedHdr[--cnt] = 0;
471    }
472     
473    if(preDefHdr->extHdr.udpPort.pres)
474    {
475       preEncodedHdr[--cnt] = EGTP_EXT_HDR_UDP_TYPE;
476       preEncodedHdr[--cnt] = 1;
477       preEncodedHdr[--cnt] = GetHiByte(preDefHdr->extHdr.udpPort.val);
478       preEncodedHdr[--cnt] = GetLoByte(preDefHdr->extHdr.udpPort.val);
479    }
480    
481    if(preDefHdr->extHdr.pdcpNmb.pres)
482    {
483       preEncodedHdr[--cnt] = EGTP_EXT_HDR_PDCP_TYPE;
484       preEncodedHdr[--cnt] = 1;
485       preEncodedHdr[--cnt] = GetHiByte(preDefHdr->extHdr.pdcpNmb.val);
486       preEncodedHdr[--cnt] = GetLoByte(preDefHdr->extHdr.pdcpNmb.val);
487    }
488     
489    if(tmpByte & EGTP_MASK_BIT3)
490    {
491       preEncodedHdr[--cnt] = 0;
492    }
493    else if(extPres)
494    {
495       preEncodedHdr[--cnt] = 0;
496    } 
497    
498    *hdrIdx = cnt;
499    return ROK;
500
501 } /* egtpEncodeHdr */
502
503 S16 cuEgtpHdlRecvMsg(Buffer *mBuf)
504 {
505    /*Decoding of EGTP message header */
506    cuEgtpDecodeHdr(mBuf);
507
508    /* Start Pumping data from CU to DU */
509    //return (cuEgtpDatReq());
510
511 }
512
513 S16 cuEgtpDecodeHdr(Buffer *mBuf)
514 {
515    EgtpMsg  egtpMsg;
516    uint8_t       tmpByte[5];         /* Holds one byte of data after Dec */
517    uint8_t       version = 0;         /* Holds the version type, decoded */
518    MsgLen   msgLen  = 0;         /* Holds the msgLen from the Hdr */
519    MsgLen   bufLen  = 0;         /* Holds the total buffer length */
520    uint8_t       extHdrType = 0;       /* Holds the Extension hdr type */
521    uint8_t       extHdrLen = 0;        /* Extension hdr length */
522    Bool     extPres = FALSE;      /* Flag for indication of S, E or P presense flag */
523
524    ODU_GET_MSG_LEN(mBuf, &bufLen);
525
526    /* Decode version */
527    ODU_REM_PRE_MSG(&tmpByte[0], mBuf);
528    version = tmpByte[0] >> 5;
529
530    /* Decode message type */
531    ODU_REM_PRE_MSG((Data*)&(egtpMsg.msgHdr.msgType), mBuf);
532
533    /* Decode message length */
534    ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
535    ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
536    msgLen = (tmpByte[1] << 8) | tmpByte[2];
537
538    /* Decode tunnel id */
539    ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
540    ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
541    ODU_REM_PRE_MSG(&tmpByte[3], mBuf);
542    ODU_REM_PRE_MSG(&tmpByte[4], mBuf);
543    egtpMsg.msgHdr.teId = (tmpByte[1] << 24) | (tmpByte[2] << 16) | (tmpByte[3] << 8) | tmpByte[4];
544
545    if((tmpByte[0] & EGTP_MASK_BIT1) || (tmpByte[0] & EGTP_MASK_BIT2)||(tmpByte[0] & EGTP_MASK_BIT3))
546    {
547       extPres = TRUE;
548    }
549
550    /* Decode sequence number */
551    if ( tmpByte[0] & EGTP_MASK_BIT2 )
552    {
553       egtpMsg.msgHdr.seqNum.pres = TRUE;
554       ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
555       ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
556       egtpMsg.msgHdr.seqNum.val = (tmpByte[1] << 8) | tmpByte[2];
557    }
558    else  if(extPres)
559    {
560       egtpMsg.msgHdr.seqNum.pres = 0;
561       ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
562       ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
563       egtpMsg.msgHdr.seqNum.val = (tmpByte[1] << 8) | tmpByte[2];
564    }
565
566    /* Decode N-PDU number */
567    if ( tmpByte[0] & EGTP_MASK_BIT1 )
568    {
569       egtpMsg.msgHdr.nPdu.pres = TRUE;
570       ODU_REM_PRE_MSG(&(egtpMsg.msgHdr.nPdu.val), mBuf);
571    }
572    else if(extPres)
573    {
574       egtpMsg.msgHdr.nPdu.pres = TRUE;
575       ODU_REM_PRE_MSG(&(egtpMsg.msgHdr.nPdu.val), mBuf);
576    }
577
578    if(extPres & EGTP_MASK_BIT1)
579    {
580       ODU_REM_PRE_MSG(&extHdrType, mBuf);
581       while( 0 != extHdrType)
582       {
583          switch (extHdrType)
584          {
585             case EGTP_EXT_HDR_UDP_TYPE:
586             {
587                ODU_REM_PRE_MSG(&extHdrLen, mBuf);
588                if(extHdrLen == 0x01)
589                {
590                   egtpMsg.msgHdr.extHdr.udpPort.pres = TRUE;
591                   ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
592                   ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
593                   egtpMsg.msgHdr.extHdr.udpPort.val = (tmpByte[1] << 8) | tmpByte[2];
594                }
595                break;
596             }
597
598             case EGTP_EXT_HDR_PDCP_TYPE:
599             {
600                ODU_REM_PRE_MSG(&extHdrLen, mBuf);
601                if(extHdrLen == 0x01)
602                {
603                   egtpMsg.msgHdr.extHdr.pdcpNmb.pres = TRUE;
604                   ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
605                   ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
606                   egtpMsg.msgHdr.extHdr.pdcpNmb.val = (tmpByte[1] << 8) | tmpByte[2];
607                }
608                break;
609             }
610          } /* End of switch */
611
612          ODU_REM_PRE_MSG(&extHdrType, mBuf);
613
614       } /* End of while */
615    } /* End of if(extPres & EGTP_MASK_BIT1) */
616    else if(extPres)
617    {
618       ODU_REM_PRE_MSG(&extHdrType, mBuf);
619    }
620
621    DU_LOG("\nDEBUG  -->  EGTP : Message Buffer after decoding header ");
622    ODU_PRINT_MSG(mBuf, 0, 0);
623
624    return ROK;
625      
626 } /* End of cuEgtpDecodeHdr */
627
628 S16 cuEgtpDatReq()
629 {
630    uint8_t cnt = 0;
631    EgtpMsg  egtpMsg;
632
633    /* Build Application message that is supposed to come from app to egtp */
634    BuildAppMsg(&egtpMsg);
635
636    /* Encode EGTP header to build final EGTP message */
637    BuildEgtpMsg(&egtpMsg);
638
639    /* Send Message to peer */
640    while(cnt < 200)
641    {
642       DU_LOG("\nDEBUG  -->  EGTP : Sending message[%d]", cnt+1);
643       cuEgtpSendMsg(egtpMsg.msg);
644       cnt++;
645    }
646
647    ODU_PUT_MSG_BUF(egtpMsg.msg);
648
649    return ROK;
650 }
651
652
653 S16 BuildAppMsg(EgtpMsg  *egtpMsg)
654 {
655    char data[30] = "This is EGTP data from CU";
656    int datSize = 30;
657  
658    Buffer   *mBuf;
659  
660    if(ODU_GET_MSG_BUF(CU_APP_MEM_REG, CU_POOL, &mBuf) == ROK)
661    {
662       if(ODU_ADD_POST_MSG_MULT((Data *)data, datSize, mBuf) != ROK)
663       {
664          DU_LOG("\nERROR  -->  EGTP : ODU_ADD_POST_MSG_MULT failed");
665          ODU_PUT_MSG_BUF(mBuf);
666          return RFAILED;
667       }
668    }
669    else
670    {
671        DU_LOG("\nERROR  -->  EGTP : Failed to allocate memory");
672        return RFAILED;
673    }
674  
675    /* filling IPv4 header */
676    CmIpv4Hdr ipv4Hdr;
677    MsgLen    mLen;
678  
679    mLen = 0;
680    ODU_GET_MSG_LEN(mBuf, &mLen);
681
682    memset(&ipv4Hdr, 0, sizeof(CmIpv4Hdr));
683    ipv4Hdr.length = CM_IPV4_HDRLEN + mLen;
684    ipv4Hdr.hdrVer = 0x45;
685    ipv4Hdr.proto = 1;
686    ipv4Hdr.srcAddr = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.localIp.ipV4Addr);
687    ipv4Hdr.destAddr = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.destIp.ipV4Addr);
688  
689    /* Packing IPv4 header into buffer */
690    S16          ret, cnt, idx;
691    Data         revPkArray[CM_IPV4_HDRLEN];
692    Data         pkArray[CM_IPV4_HDRLEN];
693  
694    /* initialize locals */
695    cnt = 0;
696    memset(revPkArray, 0, CM_IPV4_HDRLEN);
697    memset(pkArray, 0, CM_IPV4_HDRLEN);
698
699    /* Pack Header Version */
700    pkArray[cnt++] = ipv4Hdr.hdrVer;
701  
702    /* Pack TOS */
703    pkArray[cnt++] = ipv4Hdr.tos;
704  
705    pkArray[cnt++] = (Data)GetHiByte(ipv4Hdr.length);
706    pkArray[cnt++] = (Data)GetLoByte(ipv4Hdr.length);
707  
708    /* Pack Id */
709    pkArray[cnt++] = (Data) GetHiByte(ipv4Hdr.id);
710    pkArray[cnt++] = (Data) GetLoByte(ipv4Hdr.id);
711  
712    /* Pack Offset */
713    pkArray[cnt++] = (Data)GetHiByte(ipv4Hdr.off);
714    pkArray[cnt++] = (Data)GetLoByte(ipv4Hdr.off);
715  
716    /* Pack TTL */
717    pkArray[cnt++] = ipv4Hdr.ttl;
718  
719    /* Pack Protocol */
720    pkArray[cnt++] = ipv4Hdr.proto;
721  
722    /* Pack Checksum */
723    pkArray[cnt++] = (Data)GetHiByte(ipv4Hdr.chkSum);
724    pkArray[cnt++] = (Data)GetLoByte(ipv4Hdr.chkSum);
725                                                         
726    /* Pack Source Address */
727    pkArray[cnt++] = (Data)GetHiByte(GetHiWord(ipv4Hdr.srcAddr));
728    pkArray[cnt++] = (Data)GetLoByte(GetHiWord(ipv4Hdr.srcAddr));
729    pkArray[cnt++] = (Data)GetHiByte(GetLoWord(ipv4Hdr.srcAddr));
730    pkArray[cnt++] = (Data)GetLoByte(GetLoWord(ipv4Hdr.srcAddr));
731  
732    /* Pack Destination Address */
733    pkArray[cnt++] = (Data)GetHiByte(GetHiWord(ipv4Hdr.destAddr));
734    pkArray[cnt++] = (Data)GetLoByte(GetHiWord(ipv4Hdr.destAddr));
735    pkArray[cnt++] = (Data)GetHiByte(GetLoWord(ipv4Hdr.destAddr));
736    pkArray[cnt++] = (Data)GetLoByte(GetLoWord(ipv4Hdr.destAddr));
737  
738    for (idx = 0;  idx < CM_IPV4_HDRLEN;  idx++)
739       revPkArray[idx] = pkArray[CM_IPV4_HDRLEN - idx -1];
740  
741    /* this function automatically reverses revPkArray */
742    ret = ODU_ADD_PRE_MSG_MULT(revPkArray, (MsgLen)cnt, mBuf);
743  
744    egtpMsg->msgHdr.msgType = EGTPU_MSG_GPDU;
745    egtpMsg->msgHdr.nPdu.pres = FALSE;
746    egtpMsg->msgHdr.seqNum.pres = FALSE;
747    egtpMsg->msgHdr.extHdr.udpPort.pres = FALSE;
748    egtpMsg->msgHdr.extHdr.pdcpNmb.pres = FALSE;
749    egtpMsg->msgHdr.teId = 10;
750    egtpMsg->msg = mBuf;
751
752    return ret;
753 }
754
755
756 S16 BuildEgtpMsg(EgtpMsg *egtpMsg)
757 {
758    EgtpTeIdCb   *teidCb = NULLP;
759    MsgLen tPduSize;
760    uint8_t     hdrLen;
761    uint32_t    msgLen;
762    EgtpMsgHdr   *msgHdr;
763  
764    cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(egtpMsg->msgHdr.teId), sizeof(uint32_t), 0, (PTR *)&teidCb);
765    if(teidCb == NULLP)
766    {
767       DU_LOG("\nERROR  -->  EGTP : Tunnel id[%d] not configured", egtpMsg->msgHdr.teId);
768       return (LCM_REASON_INVALID_PAR_VAL);
769    }
770
771    msgHdr = &(egtpMsg->msgHdr);
772
773    hdrLen = teidCb->preEncodedHdr.cnt;
774
775    if(msgHdr->extHdr.pdcpNmb.pres)
776    {
777       teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= EGTP_MASK_BIT3;
778       teidCb->preEncodedHdr.hdr[hdrLen] = EGTP_EXT_HDR_PDCP_TYPE;
779       teidCb->preEncodedHdr.hdr[--hdrLen] = 1;
780       teidCb->preEncodedHdr.hdr[--hdrLen] = GetHiByte(msgHdr->extHdr.pdcpNmb.val);
781       teidCb->preEncodedHdr.hdr[--hdrLen] = GetLoByte(msgHdr->extHdr.pdcpNmb.val);
782       teidCb->preEncodedHdr.hdr[--hdrLen] = 0;
783    }
784    else
785    {
786       teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT3);
787    }
788  
789    ODU_GET_MSG_LEN(egtpMsg->msg, &tPduSize);
790
791    /*Adjust the header to fill the correct length*/
792    msgLen = tPduSize +  (EGTP_MAX_HDR_LEN - hdrLen) - 0x08;
793
794    /***********************************************
795     * Fill the length field of the message header *
796     ***********************************************/
797    teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 3] = (uint8_t)GetHiByte(msgLen);
798    teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 4] = (uint8_t)GetLoByte(msgLen);
799
800    /*Update the sequence number*/
801    if(egtpMsg->msgHdr.seqNum.pres)
802    {
803       teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= (EGTP_MASK_BIT2);
804       teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 9] = (uint8_t)GetHiByte(egtpMsg->msgHdr.seqNum.val);
805       teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 10] = (uint8_t)GetLoByte(egtpMsg->msgHdr.seqNum.val);
806    }
807    else
808    {
809       teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT2);
810    }
811
812    ODU_ADD_PRE_MSG_MULT(&teidCb->preEncodedHdr.hdr[hdrLen], (EGTP_MAX_HDR_LEN - hdrLen), egtpMsg->msg);
813
814    DU_LOG("\nDEBUG  -->  EGTP : Sending message buffer");
815    ODU_PRINT_MSG(egtpMsg->msg, 0, 0);
816
817    return ROK;
818 }
819
820 S16 cuEgtpSendMsg(Buffer *mBuf)
821 {
822    S16            ret;
823    MsgLen         txLen;
824    CmInetMemInfo  info;
825    CmInetAddr     dstAddr;
826
827    info.region = CU_APP_MEM_REG;
828    info.pool = CU_POOL;
829  
830    dstAddr.port = EGTP_DFLT_PORT;
831    dstAddr.address = egtpCb.dstCb.dstIp;
832  
833    ret = cmInetSendMsg(&(egtpCb.dstCb.sendTptSrvr.sockFd), &dstAddr, &info, mBuf, &txLen, CM_INET_NO_FLAG);
834    if(ret != ROK && ret != RWOULDBLOCK)
835    {
836       DU_LOG("\nERROR  -->  EGTP : Message send failure");
837       return RFAILED;
838    }
839    
840    DU_LOG("\nDEBUG  -->  EGTP : Message Sent");
841  
842    return ROK;
843 }