1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
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 #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
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 *******************************************************************************/
19 /* This file contains all EGTP related functionality */
21 #include "common_def.h"
22 #include "cu_f1ap_msg_hdl.h"
23 #include "cu_stub_egtp.h"
26 /* Global variable declaration */
28 /**************************************************************************
29 * @brief Task Initiation callback function.
33 * Function : egtpActvInit
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.
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
44 * @param[in] Reason reason.
45 * @return ROK - success
47 ***************************************************************************/
50 DU_LOG("\n\nDEBUG --> EGTP : Initializing");
51 memset (&egtpCb, 0, sizeof(EgtpGlobalCb));
53 //Initializing with INVALID value
54 memset(egtpCb.gCntPdu, 0xFF , sizeof(uint8_t)*(MAX_TEID+1));
55 protType = CM_INET_PROTO_UDP;
60 /**************************************************************************
61 * @brief Task Activation callback function.
65 * Function : egtpActvTsk
68 * This function handles all EGTP messages received
69 * This API is registered with SSI during the
70 * Task Registration of DU APP.
72 * @param[in] Pst *pst, Post structure of the primitive.
73 * @param[in] Buffer *mBuf, Packed primitive parameters in the
75 * @return ROK - success
78 ***************************************************************************/
86 DU_LOG("\nERROR --> EGTP : Configuration failed");
90 ret = cuEgtpSrvOpenReq();
93 DU_LOG("\nERROR --> EGTP : Transport server open request failed");
100 /**************************************************************************
101 * @brief EGTP server configuration
105 * Function : egtpCfgReq
108 * This function handles EGTP configuration request.
110 * @return ROK - success
113 * ***********************************************************************/
118 memcpy(&egtpCb.egtpCfg, &cuCfgParams.egtpParams, sizeof(EgtpParams));
120 egtpCb.recvTptSrvr.addr.address = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.localIp.ipV4Addr);
121 egtpCb.recvTptSrvr.addr.port = EGTP_DFLT_PORT;
123 egtpCb.dstCb.dstIp = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.destIp.ipV4Addr);
124 egtpCb.dstCb.dstPort = egtpCb.egtpCfg.destPort;
125 egtpCb.dstCb.sendTptSrvr.addr.address = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.localIp.ipV4Addr);
126 egtpCb.dstCb.sendTptSrvr.addr.port = egtpCb.egtpCfg.localPort;
127 egtpCb.dstCb.numTunn = 0;
129 ret = cmHashListInit(&(egtpCb.dstCb.teIdLst), 1024, sizeof(EgtpTeIdCb), FALSE, CM_HASH_KEYTYPE_UINT32_MOD, CU_APP_MEM_REG, CU_POOL);
133 DU_LOG("\nERROR --> EGTP : TeId hash list initialization failed");
138 DU_LOG("\nINFO --> EGTP : Configuration successful");
144 /**************************************************************************
145 * @brief EGTP server open request
149 * Function : egtpSrvOpenReq
152 * This function handles EGTP open server request.
153 * It opens udp socket to receive/send msgs.
155 * @param[in] Pst *pst, post structure
156 * @return ROK - success
159 ***************************************************************************/
161 S16 cuEgtpSrvOpenReq(Pst *pst)
166 DU_LOG("\nINFO --> EGTP : Received open server request");
168 sockType = CM_INET_DGRAM;
169 if((ret = (cmInetSocket(sockType, &(egtpCb.recvTptSrvr.sockFd), protType))) != ROK)
171 DU_LOG("\nERROR --> EGTP : Failed to open UDP socket");
175 ret = cmInetBind(&(egtpCb.recvTptSrvr.sockFd), &(egtpCb.recvTptSrvr.addr));
178 DU_LOG("\nERROR --> EGTP : Failed to bind socket");
182 if(ret = (cmInetSocket(sockType, &(egtpCb.dstCb.sendTptSrvr.sockFd), protType)) != ROK)
184 DU_LOG("\nERROR --> EGTP : Failed to open UDP socket");
188 ret = cmInetBind(&(egtpCb.dstCb.sendTptSrvr.sockFd), &(egtpCb.dstCb.sendTptSrvr.addr));
191 DU_LOG("\nERROR --> EGTP : Failed to bind socket");
195 /* TODO: set socket options */
197 DU_LOG("\nINFO --> EGTP : Receiver socket[%d] and Sender socket[%d] open", egtpCb.recvTptSrvr.sockFd.fd,\
198 egtpCb.dstCb.sendTptSrvr.sockFd.fd);
200 } /* cuEgtpSrvOpenReq */
203 /**************************************************************************
204 * @brief EGTP tunnel management request
208 * Function : cuEgtpTnlMgmtReq
211 * This function handles EGTP tunnel managament request
213 * @param[in] Pst *pst, post structure
214 * Tunnel Eveny structure
215 * @return ROK - success
219 * ***************************************************************************/
220 S16 cuEgtpTnlMgmtReq(EgtpTnlEvt tnlEvt)
224 DU_LOG("\nINFO --> EGTP : Received tunnel management request");
225 switch(tnlEvt.action)
227 case EGTP_TNL_MGMT_ADD:
229 ret = cuEgtpTnlAdd(tnlEvt);
232 case EGTP_TNL_MGMT_MOD:
234 ret = cuEgtpTnlMod(tnlEvt);
237 case EGTP_TNL_MGMT_DEL:
239 ret = cuEgtpTnlDel(tnlEvt);
244 DU_LOG("\nERROR --> EGTP : Invalid tunnel management action[%d]", tnlEvt.action);
252 /**************************************************************************
253 * @brief EGTP tunnel addition
257 * Function : cuEgtpTnlAdd
260 * This function handles EGTP tunnel addition
262 * @param[in] Tunnel Event structure
263 * @return ROK - success
266 * ***************************************************************************/
267 S16 cuEgtpTnlAdd(EgtpTnlEvt tnlEvt)
271 EgtpMsgHdr preDefHdr; /* pre-define header for this tunnel */
274 DU_LOG("\nINFO --> EGTP : Tunnel addition : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
276 CU_ALLOC(teidCb, (Size)sizeof(EgtpTeIdCb));
280 DU_LOG("\nERROR --> EGTP : Memory allocation failed");
285 memset(teidCb, 0, sizeof(EgtpTeIdCb));
286 teidCb->teId = tnlEvt.lclTeid;
287 teidCb->remTeId = tnlEvt.remTeid;
289 ret = cmHashListInsert(&(egtpCb.dstCb.teIdLst), (PTR)teidCb, (uint8_t *)&(teidCb->teId), sizeof(uint32_t));
292 DU_LOG("\nERROR --> EGTP : Failed to insert in hash list");
293 CU_FREE(teidCb, (Size)sizeof(EgtpTeIdCb));
296 egtpCb.dstCb.numTunn++;
298 /* Encoding pre-defined header */
299 memset(&preDefHdr, 0, sizeof(EgtpMsgHdr));
300 preDefHdr.msgType = EGTPU_MSG_GPDU;
301 preDefHdr.teId = teidCb->remTeId;
302 preDefHdr.extHdr.pdcpNmb.pres = FALSE;
303 preDefHdr.extHdr.udpPort.pres = FALSE;
304 preDefHdr.nPdu.pres = TRUE; //Including nPdu when sending data
305 preDefHdr.nPdu.val = 0;
307 cuEgtpEncodeHdr((uint8_t *)teidCb->preEncodedHdr.hdr, &preDefHdr, &(teidCb->preEncodedHdr.cnt));
308 egtpCb.gCntPdu[teidCb->remTeId] = 0;//Resetting the Cnt Value for this DRB which indicates its creation
310 /* SPutSBuf(CU_APP_MEM_REG, CU_POOL, (Data *)teidCb, (Size)sizeof(EgtpTeIdCb));*/
315 /**************************************************************************
316 * @brief EGTP tunnel modification
320 * Function : cuEgtpTnlMod
323 * This function handles EGTP tunnel modification
325 * @param[in] Tunnel Event structure
326 * @return ROK - success
329 * ***************************************************************************/
330 S16 cuEgtpTnlMod(EgtpTnlEvt tnlEvt)
334 EgtpTeIdCb *teidCb = NULLP;
336 DU_LOG("\nDEBUG --> CU_STUB : Tunnel modification : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
338 cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(tnlEvt.teId), sizeof(uint32_t), 0, (PTR *)&teidCb);
341 DU_LOG("\nDEBUG --> CU_STUBTunnel id not found");
345 teidCb->teId = tnlEvt.lclTeid;
346 teidCb->remTeId = tnlEvt.remTeid;
351 /**************************************************************************
352 * @brief EGTP tunnel deletion
356 * Function : cuEgtpTnlDel
359 * This function handles EGTP tunnel deletion
361 * @param[in] Tunnel Event structure
362 * @return ROK - success
365 * ***************************************************************************/
366 S16 cuEgtpTnlDel(EgtpTnlEvt tnlEvt)
368 EgtpTeIdCb *teidCb = NULLP;
370 DU_LOG("\nDEBUG --> EGTP : Tunnel deletion : Local Teid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
372 cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(tnlEvt.lclTeid), sizeof(uint32_t), 0, (PTR *)&teidCb);
375 DU_LOG("\nERROR --> EGTP : Tunnel id[%d] not configured", tnlEvt.lclTeid);
379 cmHashListDelete(&(egtpCb.dstCb.teIdLst), (PTR)teidCb);
380 CU_FREE(teidCb, (Size)sizeof(EgtpTeIdCb));
381 egtpCb.dstCb.numTunn--;
386 /*******************************************************************
388 * @brief Encodes message header
392 * Function : cuEgtpEncodeHdr
395 * Encodes EGTP message haeder
397 * @params[in] EGTP message
399 * @return ROK - success
402 * ****************************************************************/
403 S16 cuEgtpEncodeHdr(uint8_t *preEncodedHdr, EgtpMsgHdr *preDefHdr, uint8_t *hdrIdx)
405 uint8_t tmpByte = 0; /* Stores one byte of data for enc */
406 uint8_t cnt = EGTP_MAX_HDR_LEN; /* Stores the position */
407 Bool extPres = FALSE; /* Flag for indication of S, E or P presense flag */
410 /* Encoding header */
411 tmpByte |= EGTP_MASK_BIT6; /* Setting 6th LSB of 1st byte as version */
412 tmpByte |= EGTP_MASK_BIT5; /* Setting 5th LSB of 1st byte as protocol type */
414 if(preDefHdr->extHdr.udpPort.pres || preDefHdr->extHdr.pdcpNmb.pres)
416 tmpByte |= EGTP_MASK_BIT3; /* Setting 3rd LSB of 1st byte if Extension heaeder is present */
419 if(preDefHdr->seqNum.pres)
421 tmpByte |= EGTP_MASK_BIT2;
424 if(preDefHdr->nPdu.pres)
426 tmpByte |= EGTP_MASK_BIT1;
429 if((tmpByte & EGTP_MASK_BIT1) || (tmpByte & EGTP_MASK_BIT2)||(tmpByte & EGTP_MASK_BIT3))
433 preEncodedHdr[--cnt] = tmpByte;
434 preEncodedHdr[--cnt] = preDefHdr->msgType;
436 /* Encode Tunnel endpoint */
437 preEncodedHdr[--cnt] = 0;
438 preEncodedHdr[--cnt] = 0;
439 nwWord = (uint16_t)(GetHiWord(preDefHdr->teId));
440 preEncodedHdr[--cnt] = (uint8_t)(GetHiByte(nwWord));
441 preEncodedHdr[--cnt] = (uint8_t)(GetLoByte(nwWord));
442 nwWord = (uint16_t)(GetLoWord(preDefHdr->teId));
443 preEncodedHdr[--cnt] = (uint8_t)(GetHiByte(nwWord));
444 preEncodedHdr[--cnt] = (uint8_t)(GetLoByte(nwWord));
446 /* Encode sequence number */
447 if(preDefHdr->seqNum.pres)
449 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->seqNum.val);
450 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->seqNum.val);
454 preEncodedHdr[--cnt] = 0;
455 preEncodedHdr[--cnt] = 0;
458 if(preDefHdr->nPdu.pres)
460 preEncodedHdr[--cnt] = preDefHdr->nPdu.val;
464 preEncodedHdr[--cnt] = 0;
467 if(preDefHdr->extHdr.udpPort.pres)
469 preEncodedHdr[--cnt] = EGTP_EXT_HDR_UDP_TYPE;
470 preEncodedHdr[--cnt] = 1;
471 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->extHdr.udpPort.val);
472 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->extHdr.udpPort.val);
475 if(preDefHdr->extHdr.pdcpNmb.pres)
477 preEncodedHdr[--cnt] = EGTP_EXT_HDR_PDCP_TYPE;
478 preEncodedHdr[--cnt] = 1;
479 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->extHdr.pdcpNmb.val);
480 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->extHdr.pdcpNmb.val);
483 if(tmpByte & EGTP_MASK_BIT3)
485 preEncodedHdr[--cnt] = 0;
489 preEncodedHdr[--cnt] = 0;
495 } /* egtpEncodeHdr */
497 S16 cuEgtpHdlRecvMsg(Buffer *mBuf)
499 /*Decoding of EGTP message header */
500 cuEgtpDecodeHdr(mBuf);
502 /* Start Pumping data from CU to DU */
503 //return (cuEgtpDatReq());
507 S16 cuEgtpDecodeHdr(Buffer *mBuf)
510 uint8_t tmpByte[5]; /* Holds one byte of data after Dec */
511 uint8_t version = 0; /* Holds the version type, decoded */
512 MsgLen msgLen = 0; /* Holds the msgLen from the Hdr */
513 MsgLen bufLen = 0; /* Holds the total buffer length */
514 uint8_t extHdrType = 0; /* Holds the Extension hdr type */
515 uint8_t extHdrLen = 0; /* Extension hdr length */
516 Bool extPres = FALSE; /* Flag for indication of S, E or P presense flag */
518 ODU_GET_MSG_LEN(mBuf, &bufLen);
521 ODU_REM_PRE_MSG(&tmpByte[0], mBuf);
522 version = tmpByte[0] >> 5;
524 /* Decode message type */
525 ODU_REM_PRE_MSG((Data*)&(egtpMsg.msgHdr.msgType), mBuf);
527 /* Decode message length */
528 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
529 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
530 msgLen = (tmpByte[1] << 8) | tmpByte[2];
532 /* Decode tunnel id */
533 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
534 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
535 ODU_REM_PRE_MSG(&tmpByte[3], mBuf);
536 ODU_REM_PRE_MSG(&tmpByte[4], mBuf);
537 egtpMsg.msgHdr.teId = (tmpByte[1] << 24) | (tmpByte[2] << 16) | (tmpByte[3] << 8) | tmpByte[4];
539 if((tmpByte[0] & EGTP_MASK_BIT1) || (tmpByte[0] & EGTP_MASK_BIT2)||(tmpByte[0] & EGTP_MASK_BIT3))
544 /* Decode sequence number */
545 if ( tmpByte[0] & EGTP_MASK_BIT2 )
547 egtpMsg.msgHdr.seqNum.pres = TRUE;
548 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
549 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
550 egtpMsg.msgHdr.seqNum.val = (tmpByte[1] << 8) | tmpByte[2];
554 egtpMsg.msgHdr.seqNum.pres = 0;
555 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
556 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
557 egtpMsg.msgHdr.seqNum.val = (tmpByte[1] << 8) | tmpByte[2];
560 /* Decode N-PDU number */
561 if ( tmpByte[0] & EGTP_MASK_BIT1 )
563 egtpMsg.msgHdr.nPdu.pres = TRUE;
564 ODU_REM_PRE_MSG(&(egtpMsg.msgHdr.nPdu.val), mBuf);
568 egtpMsg.msgHdr.nPdu.pres = TRUE;
569 ODU_REM_PRE_MSG(&(egtpMsg.msgHdr.nPdu.val), mBuf);
572 if(extPres & EGTP_MASK_BIT1)
574 ODU_REM_PRE_MSG(&extHdrType, mBuf);
575 while( 0 != extHdrType)
579 case EGTP_EXT_HDR_UDP_TYPE:
581 ODU_REM_PRE_MSG(&extHdrLen, mBuf);
582 if(extHdrLen == 0x01)
584 egtpMsg.msgHdr.extHdr.udpPort.pres = TRUE;
585 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
586 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
587 egtpMsg.msgHdr.extHdr.udpPort.val = (tmpByte[1] << 8) | tmpByte[2];
592 case EGTP_EXT_HDR_PDCP_TYPE:
594 ODU_REM_PRE_MSG(&extHdrLen, mBuf);
595 if(extHdrLen == 0x01)
597 egtpMsg.msgHdr.extHdr.pdcpNmb.pres = TRUE;
598 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
599 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
600 egtpMsg.msgHdr.extHdr.pdcpNmb.val = (tmpByte[1] << 8) | tmpByte[2];
604 } /* End of switch */
606 ODU_REM_PRE_MSG(&extHdrType, mBuf);
609 } /* End of if(extPres & EGTP_MASK_BIT1) */
612 ODU_REM_PRE_MSG(&extHdrType, mBuf);
615 DU_LOG("\nDEBUG --> EGTP : Message Buffer after decoding header [TEID:%d]",egtpMsg.msgHdr.teId);
616 ODU_PRINT_MSG(mBuf, 0, 0);
620 } /* End of cuEgtpDecodeHdr */
622 uint16_t cuEgtpDatReq(uint8_t teId)
624 uint8_t ret = ROK, cnt = 0;
627 egtpMsg.msgHdr.teId = teId;
629 if(egtpCb.gCntPdu[teId] == 0xFF) //DRB not created
631 DU_LOG("\nERROR --> EGTP : DRB not created");
634 /* Build Application message that is supposed to come from app to egtp */
635 ret = BuildAppMsg(&egtpMsg);
638 DU_LOG("\nERROR --> EGTP : Failed to build App Msg");
642 /* Encode EGTP header to build final EGTP message */
643 ret = BuildEgtpMsg(&egtpMsg);
646 DU_LOG("\nERROR --> EGTP : Failed to build EGTP Msg");
649 cuEgtpSendMsg(egtpMsg.msg);
650 ODU_PUT_MSG_BUF(egtpMsg.msg);
656 S16 BuildAppMsg(EgtpMsg *egtpMsg)
658 char data[1215] = "In telecommunications, 5G is the fifth generation technology standard for broadband cellular"
659 " networks, which cellular phone companies began deploying worldwide in 2019, and is the planned successor to the 4G "
660 " networks which provide connectivity to most current cellphones. 5G networks are predicted to have more than 1.7"
661 " billion subscribers worldwide by 2025, according to the GSM Association.Like its predecessors, 5G networks are"
662 " cellular networks,in which the service area is divided into small geographical areas called cells.All 5G wireless"
663 " devices in a cell are connected to the Internet and telephone network by radio waves through local antenna in the"
664 " cell. The main advantage of the new networks is that they will have greater bandwidth, giving higher download"
665 " speeds, eventually up to 10 gigabits per second(Gbit/s). Due to the increased bandwidth, it is expected the"
666 " networks will not exclusively serve cellphones like existing cellular networks, but also be used as general"
667 " internet service providers for laptops and desktop computers, competing with existing ISPs such as cable"
668 " internet, and also will make possible new applications in internet of things (IoT) and machine to machine areas.";
674 if(ODU_GET_MSG_BUF(CU_APP_MEM_REG, CU_POOL, &mBuf) == ROK)
676 if(ODU_ADD_POST_MSG_MULT((Data *)data, datSize, mBuf) != ROK)
678 DU_LOG("\nERROR --> EGTP : ODU_ADD_POST_MSG_MULT failed");
679 ODU_PUT_MSG_BUF(mBuf);
685 DU_LOG("\nERROR --> EGTP : Failed to allocate memory");
689 /* filling IPv4 header */
694 ODU_GET_MSG_LEN(mBuf, &mLen);
696 memset(&ipv4Hdr, 0, sizeof(CmIpv4Hdr));
697 ipv4Hdr.length = CM_IPV4_HDRLEN + mLen;
698 ipv4Hdr.hdrVer = 0x45;
700 ipv4Hdr.srcAddr = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.localIp.ipV4Addr);
701 ipv4Hdr.destAddr = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.destIp.ipV4Addr);
703 /* Packing IPv4 header into buffer */
705 Data revPkArray[CM_IPV4_HDRLEN];
706 Data pkArray[CM_IPV4_HDRLEN];
708 /* initialize locals */
710 memset(revPkArray, 0, CM_IPV4_HDRLEN);
711 memset(pkArray, 0, CM_IPV4_HDRLEN);
713 /* Pack Header Version */
714 pkArray[cnt++] = ipv4Hdr.hdrVer;
717 pkArray[cnt++] = ipv4Hdr.tos;
719 pkArray[cnt++] = (Data)GetHiByte(ipv4Hdr.length);
720 pkArray[cnt++] = (Data)GetLoByte(ipv4Hdr.length);
723 pkArray[cnt++] = (Data) GetHiByte(ipv4Hdr.id);
724 pkArray[cnt++] = (Data) GetLoByte(ipv4Hdr.id);
727 pkArray[cnt++] = (Data)GetHiByte(ipv4Hdr.off);
728 pkArray[cnt++] = (Data)GetLoByte(ipv4Hdr.off);
731 pkArray[cnt++] = ipv4Hdr.ttl;
734 pkArray[cnt++] = ipv4Hdr.proto;
737 pkArray[cnt++] = (Data)GetHiByte(ipv4Hdr.chkSum);
738 pkArray[cnt++] = (Data)GetLoByte(ipv4Hdr.chkSum);
740 /* Pack Source Address */
741 pkArray[cnt++] = (Data)GetHiByte(GetHiWord(ipv4Hdr.srcAddr));
742 pkArray[cnt++] = (Data)GetLoByte(GetHiWord(ipv4Hdr.srcAddr));
743 pkArray[cnt++] = (Data)GetHiByte(GetLoWord(ipv4Hdr.srcAddr));
744 pkArray[cnt++] = (Data)GetLoByte(GetLoWord(ipv4Hdr.srcAddr));
746 /* Pack Destination Address */
747 pkArray[cnt++] = (Data)GetHiByte(GetHiWord(ipv4Hdr.destAddr));
748 pkArray[cnt++] = (Data)GetLoByte(GetHiWord(ipv4Hdr.destAddr));
749 pkArray[cnt++] = (Data)GetHiByte(GetLoWord(ipv4Hdr.destAddr));
750 pkArray[cnt++] = (Data)GetLoByte(GetLoWord(ipv4Hdr.destAddr));
752 for (idx = 0; idx < CM_IPV4_HDRLEN; idx++)
753 revPkArray[idx] = pkArray[CM_IPV4_HDRLEN - idx -1];
755 /* this function automatically reverses revPkArray */
756 ret = ODU_ADD_PRE_MSG_MULT(revPkArray, (MsgLen)cnt, mBuf);
758 egtpMsg->msgHdr.msgType = EGTPU_MSG_GPDU;
759 egtpMsg->msgHdr.nPdu.pres = TRUE;
761 if(egtpCb.gCntPdu[egtpMsg->msgHdr.teId] != NUM_DL_PACKETS)
762 egtpCb.gCntPdu[egtpMsg->msgHdr.teId]++;
764 egtpCb.gCntPdu[egtpMsg->msgHdr.teId] = 1;
766 egtpMsg->msgHdr.nPdu.val = egtpCb.gCntPdu[egtpMsg->msgHdr.teId];
767 egtpMsg->msgHdr.seqNum.pres = FALSE;
768 egtpMsg->msgHdr.extHdr.udpPort.pres = FALSE;
769 egtpMsg->msgHdr.extHdr.pdcpNmb.pres = FALSE;
775 S16 BuildEgtpMsg(EgtpMsg *egtpMsg)
777 EgtpTeIdCb *teidCb = NULLP;
783 cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(egtpMsg->msgHdr.teId), sizeof(uint32_t), 0, (PTR *)&teidCb);
786 DU_LOG("\nERROR --> EGTP : Tunnel id[%d] not configured", egtpMsg->msgHdr.teId);
787 return (LCM_REASON_INVALID_PAR_VAL);
790 msgHdr = &(egtpMsg->msgHdr);
792 hdrLen = teidCb->preEncodedHdr.cnt;
794 if(msgHdr->extHdr.pdcpNmb.pres)
796 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= EGTP_MASK_BIT3;
797 teidCb->preEncodedHdr.hdr[hdrLen] = EGTP_EXT_HDR_PDCP_TYPE;
798 teidCb->preEncodedHdr.hdr[--hdrLen] = 1;
799 teidCb->preEncodedHdr.hdr[--hdrLen] = GetHiByte(msgHdr->extHdr.pdcpNmb.val);
800 teidCb->preEncodedHdr.hdr[--hdrLen] = GetLoByte(msgHdr->extHdr.pdcpNmb.val);
801 teidCb->preEncodedHdr.hdr[--hdrLen] = 0;
805 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT3);
808 ODU_GET_MSG_LEN(egtpMsg->msg, &tPduSize);
810 /*Adjust the header to fill the correct length*/
811 msgLen = tPduSize + (EGTP_MAX_HDR_LEN - hdrLen) - 0x08;
813 /***********************************************
814 * Fill the length field of the message header *
815 ***********************************************/
816 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 3] = (uint8_t)GetHiByte(msgLen);
817 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 4] = (uint8_t)GetLoByte(msgLen);
819 /*Update the sequence number*/
820 if(egtpMsg->msgHdr.seqNum.pres)
822 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= (EGTP_MASK_BIT2);
823 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 9] = (uint8_t)GetHiByte(egtpMsg->msgHdr.seqNum.val);
824 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 10] = (uint8_t)GetLoByte(egtpMsg->msgHdr.seqNum.val);
828 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT2);
831 /*Update the nPdU number*/
832 if(egtpMsg->msgHdr.nPdu.pres)
834 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= (EGTP_MASK_BIT1);
835 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 11] = egtpMsg->msgHdr.nPdu.val;
839 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT1);
842 ODU_ADD_PRE_MSG_MULT(&teidCb->preEncodedHdr.hdr[hdrLen], (EGTP_MAX_HDR_LEN - hdrLen), egtpMsg->msg);
846 S16 cuEgtpSendMsg(Buffer *mBuf)
853 info.region = CU_APP_MEM_REG;
856 dstAddr.port = EGTP_DFLT_PORT;
857 dstAddr.address = egtpCb.dstCb.dstIp;
859 ret = cmInetSendMsg(&(egtpCb.dstCb.sendTptSrvr.sockFd), &dstAddr, &info, mBuf, &txLen, CM_INET_NO_FLAG);
860 if(ret != ROK && ret != RWOULDBLOCK)
862 DU_LOG("\nERROR --> EGTP : Message send failure");
866 DU_LOG("\nDEBUG --> EGTP : Message Sent");