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