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 "OCTET_STRING.h"
23 #include "cu_stub_sctp.h"
24 #include "cu_f1ap_msg_hdl.h"
25 #include "cu_stub_egtp.h"
33 /**************************************************************************
34 * @brief Task Initiation callback function.
38 * Function : egtpActvInit
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.
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
49 * @param[in] Reason reason.
50 * @return ROK - success
52 ***************************************************************************/
55 DU_LOG("\n\nDEBUG --> EGTP : Initializing");
56 memset (&egtpCb, 0, sizeof(EgtpGlobalCb));
58 //Initializing with INVALID value
59 memset(egtpCb.gCntPdu, 0xFF , sizeof(uint8_t)*(MAX_TEID+1));
60 protType = CM_INET_PROTO_UDP;
65 /**************************************************************************
66 * @brief Task Activation callback function.
70 * Function : egtpActvTsk
73 * This function handles all EGTP messages received
74 * This API is registered with SSI during the
75 * Task Registration of DU APP.
77 * @param[in] Pst *pst, Post structure of the primitive.
78 * @param[in] Buffer *mBuf, Packed primitive parameters in the
80 * @return ROK - success
83 ***************************************************************************/
88 egtpCb.egtpCfg = cuCb.cuCfgParams.egtpParams;
92 DU_LOG("\nERROR --> EGTP : Configuration failed");
96 ret = cuEgtpSrvOpenReq();
99 DU_LOG("\nERROR --> EGTP : Transport server open request failed");
106 /**************************************************************************
107 * @brief EGTP server configuration
111 * Function : egtpCfgReq
114 * This function handles EGTP configuration request.
116 * @return ROK - success
119 * ***********************************************************************/
122 uint8_t ret, destIdx =0;
124 memcpy(&egtpCb.egtpCfg, &cuCb.cuCfgParams.egtpParams, sizeof(CuEgtpParams));
126 for(destIdx=0; destIdx < egtpCb.egtpCfg.numDu; destIdx++)
128 egtpCb.recvTptSrvr.addr.address = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.egtpAssoc[destIdx].localIp.ipV4Addr);
129 egtpCb.recvTptSrvr.addr.port = EGTP_RECVR_PORT;
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;
138 ret = cmHashListInit(&(egtpCb.dstCb[destIdx].teIdLst), 1024, sizeof(EgtpTeIdCb), FALSE, CM_HASH_KEYTYPE_UINT32_MOD, CU_APP_MEM_REG, CU_POOL);
142 DU_LOG("\nERROR --> EGTP : TeId hash list initialization failed");
147 DU_LOG("\nINFO --> EGTP : Configuration successful");
150 egtpCb.numDu = egtpCb.egtpCfg.numDu;
155 /**************************************************************************
156 * @brief EGTP server open request
160 * Function : egtpSrvOpenReq
163 * This function handles EGTP open server request.
164 * It opens udp socket to receive/send msgs.
166 * @param[in] Pst *pst, post structure
167 * @return ROK - success
170 ***************************************************************************/
172 S16 cuEgtpSrvOpenReq(Pst *pst)
175 uint8_t ret, destIdx;
177 DU_LOG("\nINFO --> EGTP : Received open server request");
179 sockType = CM_INET_DGRAM;
180 if((ret = (cmInetSocket(sockType, &(egtpCb.recvTptSrvr.sockFd), protType))) != ROK)
182 DU_LOG("\nERROR --> EGTP : Failed to open UDP socket");
186 ret = cmInetBind(&(egtpCb.recvTptSrvr.sockFd), &(egtpCb.recvTptSrvr.addr));
189 DU_LOG("\nERROR --> EGTP : Failed to bind socket");
193 for(destIdx=0; destIdx < egtpCb.egtpCfg.numDu; destIdx++)
195 if(ret = (cmInetSocket(sockType, &(egtpCb.dstCb[destIdx].sendTptSrvr.sockFd), protType)) != ROK)
197 DU_LOG("\nERROR --> EGTP : Failed to open UDP socket");
201 ret = cmInetBind(&(egtpCb.dstCb[destIdx].sendTptSrvr.sockFd), &(egtpCb.dstCb[destIdx].sendTptSrvr.addr));
204 DU_LOG("\nERROR --> EGTP : Failed to bind socket");
208 /* TODO: set socket options */
210 DU_LOG("\nINFO --> EGTP : Receiver socket[%d] and Sender socket[%d] open", egtpCb.recvTptSrvr.sockFd.fd,\
211 egtpCb.dstCb[destIdx].sendTptSrvr.sockFd.fd);
214 } /* cuEgtpSrvOpenReq */
217 /**************************************************************************
218 * @brief EGTP tunnel management request
222 * Function : cuEgtpTnlMgmtReq
225 * This function handles EGTP tunnel managament request
227 * @param[in] Pst *pst, post structure
228 * Tunnel Eveny structure
229 * @return ROK - success
233 * ***************************************************************************/
234 S16 cuEgtpTnlMgmtReq(uint32_t duId, EgtpTnlEvt tnlEvt)
238 DU_LOG("\nINFO --> EGTP : Received tunnel management request");
239 switch(tnlEvt.action)
241 case EGTP_TNL_MGMT_ADD:
243 ret = cuEgtpTnlAdd(duId, tnlEvt);
246 case EGTP_TNL_MGMT_MOD:
248 ret = cuEgtpTnlMod(duId, tnlEvt);
251 case EGTP_TNL_MGMT_DEL:
253 ret = cuEgtpTnlDel(duId, tnlEvt);
258 DU_LOG("\nERROR --> EGTP : Invalid tunnel management action[%d]", tnlEvt.action);
266 /**************************************************************************
267 * @brief EGTP tunnel addition
271 * Function : cuEgtpTnlAdd
274 * This function handles EGTP tunnel addition
276 * @param[in] Tunnel Event structure
277 * @return ROK - success
280 * ***************************************************************************/
281 S16 cuEgtpTnlAdd(uint32_t duId, EgtpTnlEvt tnlEvt)
285 EgtpMsgHdr preDefHdr; /* pre-define header for this tunnel */
288 DU_LOG("\nINFO --> EGTP : Tunnel addition : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
290 CU_ALLOC(teidCb, (Size)sizeof(EgtpTeIdCb));
294 DU_LOG("\nERROR --> EGTP : Memory allocation failed");
299 memset(teidCb, 0, sizeof(EgtpTeIdCb));
300 teidCb->teId = tnlEvt.lclTeid;
301 teidCb->remTeId = tnlEvt.remTeid;
303 ret = cmHashListInsert(&(egtpCb.dstCb[duId-1].teIdLst), (PTR)teidCb, (uint8_t *)&(teidCb->teId), sizeof(uint32_t));
306 DU_LOG("\nERROR --> EGTP : Failed to insert in hash list");
307 CU_FREE(teidCb, (Size)sizeof(EgtpTeIdCb));
310 egtpCb.dstCb[duId-1].numTunn++;
312 /* Encoding pre-defined header */
313 memset(&preDefHdr, 0, sizeof(EgtpMsgHdr));
314 preDefHdr.msgType = EGTPU_MSG_GPDU;
315 preDefHdr.teId = teidCb->remTeId;
316 preDefHdr.extHdr.pdcpNmb.pres = FALSE;
317 preDefHdr.extHdr.udpPort.pres = FALSE;
318 preDefHdr.nPdu.pres = TRUE; //Including nPdu when sending data
319 preDefHdr.nPdu.val = 0;
321 cuEgtpEncodeHdr((uint8_t *)teidCb->preEncodedHdr.hdr, &preDefHdr, &(teidCb->preEncodedHdr.cnt));
322 egtpCb.gCntPdu[teidCb->remTeId] = 0;//Resetting the Cnt Value for this DRB which indicates its creation
324 /* SPutSBuf(CU_APP_MEM_REG, CU_POOL, (Data *)teidCb, (Size)sizeof(EgtpTeIdCb));*/
329 /**************************************************************************
330 * @brief EGTP tunnel modification
334 * Function : cuEgtpTnlMod
337 * This function handles EGTP tunnel modification
339 * @param[in] Tunnel Event structure
340 * @return ROK - success
343 * ***************************************************************************/
344 S16 cuEgtpTnlMod(uint32_t duId, EgtpTnlEvt tnlEvt)
348 EgtpTeIdCb *teidCb = NULLP;
350 DU_LOG("\nDEBUG --> CU_STUB : Tunnel modification : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
352 cmHashListFind(&(egtpCb.dstCb[duId-1].teIdLst), (uint8_t *)&(tnlEvt.teId), sizeof(uint32_t), 0, (PTR *)&teidCb);
355 DU_LOG("\nDEBUG --> CU_STUBTunnel id not found");
359 teidCb->teId = tnlEvt.lclTeid;
360 teidCb->remTeId = tnlEvt.remTeid;
365 /**************************************************************************
366 * @brief EGTP tunnel deletion
370 * Function : cuEgtpTnlDel
373 * This function handles EGTP tunnel deletion
375 * @param[in] Tunnel Event structure
376 * @return ROK - success
379 * ***************************************************************************/
380 S16 cuEgtpTnlDel(uint32_t duId, EgtpTnlEvt tnlEvt)
382 EgtpTeIdCb *teidCb = NULLP;
384 DU_LOG("\nDEBUG --> EGTP : Tunnel deletion : Local Teid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
386 cmHashListFind(&(egtpCb.dstCb[duId-1].teIdLst), (uint8_t *)&(tnlEvt.lclTeid), sizeof(uint32_t), 0, (PTR *)&teidCb);
389 DU_LOG("\nERROR --> EGTP : Tunnel id[%d] not configured", tnlEvt.lclTeid);
393 cmHashListDelete(&(egtpCb.dstCb[duId-1].teIdLst), (PTR)teidCb);
394 CU_FREE(teidCb, (Size)sizeof(EgtpTeIdCb));
395 egtpCb.dstCb[duId-1].numTunn--;
400 /*******************************************************************
402 * @brief Encodes message header
406 * Function : cuEgtpEncodeHdr
409 * Encodes EGTP message haeder
411 * @params[in] EGTP message
413 * @return ROK - success
416 * ****************************************************************/
417 S16 cuEgtpEncodeHdr(uint8_t *preEncodedHdr, EgtpMsgHdr *preDefHdr, uint8_t *hdrIdx)
419 uint8_t tmpByte = 0; /* Stores one byte of data for enc */
420 uint8_t cnt = EGTP_MAX_HDR_LEN; /* Stores the position */
421 Bool extPres = FALSE; /* Flag for indication of S, E or P presense flag */
424 /* Encoding header */
425 tmpByte |= EGTP_MASK_BIT6; /* Setting 6th LSB of 1st byte as version */
426 tmpByte |= EGTP_MASK_BIT5; /* Setting 5th LSB of 1st byte as protocol type */
428 if(preDefHdr->extHdr.udpPort.pres || preDefHdr->extHdr.pdcpNmb.pres)
430 tmpByte |= EGTP_MASK_BIT3; /* Setting 3rd LSB of 1st byte if Extension heaeder is present */
433 if(preDefHdr->seqNum.pres)
435 tmpByte |= EGTP_MASK_BIT2;
438 if(preDefHdr->nPdu.pres)
440 tmpByte |= EGTP_MASK_BIT1;
443 if((tmpByte & EGTP_MASK_BIT1) || (tmpByte & EGTP_MASK_BIT2)||(tmpByte & EGTP_MASK_BIT3))
447 preEncodedHdr[--cnt] = tmpByte;
448 preEncodedHdr[--cnt] = preDefHdr->msgType;
450 /* Encode Tunnel endpoint */
451 preEncodedHdr[--cnt] = 0;
452 preEncodedHdr[--cnt] = 0;
453 nwWord = (uint16_t)(GetHiWord(preDefHdr->teId));
454 preEncodedHdr[--cnt] = (uint8_t)(GetHiByte(nwWord));
455 preEncodedHdr[--cnt] = (uint8_t)(GetLoByte(nwWord));
456 nwWord = (uint16_t)(GetLoWord(preDefHdr->teId));
457 preEncodedHdr[--cnt] = (uint8_t)(GetHiByte(nwWord));
458 preEncodedHdr[--cnt] = (uint8_t)(GetLoByte(nwWord));
460 /* Encode sequence number */
461 if(preDefHdr->seqNum.pres)
463 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->seqNum.val);
464 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->seqNum.val);
468 preEncodedHdr[--cnt] = 0;
469 preEncodedHdr[--cnt] = 0;
472 if(preDefHdr->nPdu.pres)
474 preEncodedHdr[--cnt] = preDefHdr->nPdu.val;
478 preEncodedHdr[--cnt] = 0;
481 if(preDefHdr->extHdr.udpPort.pres)
483 preEncodedHdr[--cnt] = EGTP_EXT_HDR_UDP_TYPE;
484 preEncodedHdr[--cnt] = 1;
485 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->extHdr.udpPort.val);
486 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->extHdr.udpPort.val);
489 if(preDefHdr->extHdr.pdcpNmb.pres)
491 preEncodedHdr[--cnt] = EGTP_EXT_HDR_PDCP_TYPE;
492 preEncodedHdr[--cnt] = 1;
493 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->extHdr.pdcpNmb.val);
494 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->extHdr.pdcpNmb.val);
497 if(tmpByte & EGTP_MASK_BIT3)
499 preEncodedHdr[--cnt] = 0;
503 preEncodedHdr[--cnt] = 0;
509 } /* egtpEncodeHdr */
511 /*******************************************************************
513 * @brief This handles the any EGTP received message
517 * Function : cuEgtpHdlRecvMsg
520 * This handles the any EGTP received message
522 * @params[in] Message Buffer
523 * @return ROK - success
526 * ****************************************************************/
527 S16 cuEgtpHdlRecvMsg(Buffer *mBuf)
529 /*Decoding of EGTP message header */
531 cuEgtpDecodeHdr(mBuf);
533 /* Start Pumping data from CU to DU */
534 //return (cuEgtpDatReq());
538 /*******************************************************************
540 * @brief Decodes message header
544 * Function : cuEgtpDecodeHdr
547 * Decodes EGTP message haeder
549 * @params[in] Message Buffer
550 * @return ROK - success
553 * ****************************************************************/
554 S16 cuEgtpDecodeHdr(Buffer *mBuf)
557 uint8_t tmpByte[5]; /* Holds one byte of data after Dec */
558 uint8_t version = 0; /* Holds the version type, decoded */
559 MsgLen msgLen = 0; /* Holds the msgLen from the Hdr */
560 MsgLen bufLen = 0; /* Holds the total buffer length */
561 uint8_t extHdrType = 0; /* Holds the Extension hdr type */
562 uint8_t extHdrLen = 0; /* Extension hdr length */
563 Bool extPres = FALSE; /* Flag for indication of S, E or P presense flag */
565 ODU_GET_MSG_LEN(mBuf, &bufLen);
568 ODU_REM_PRE_MSG(&tmpByte[0], mBuf);
569 version = tmpByte[0] >> 5;
571 /* Decode message type */
572 ODU_REM_PRE_MSG((Data*)&(egtpMsg.msgHdr.msgType), mBuf);
574 /* Decode message length */
575 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
576 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
577 msgLen = (tmpByte[1] << 8) | tmpByte[2];
579 /* Decode tunnel id */
580 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
581 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
582 ODU_REM_PRE_MSG(&tmpByte[3], mBuf);
583 ODU_REM_PRE_MSG(&tmpByte[4], mBuf);
584 egtpMsg.msgHdr.teId = (tmpByte[1] << 24) | (tmpByte[2] << 16) | (tmpByte[3] << 8) | tmpByte[4];
586 if((tmpByte[0] & EGTP_MASK_BIT1) || (tmpByte[0] & EGTP_MASK_BIT2)||(tmpByte[0] & EGTP_MASK_BIT3))
591 /* Decode sequence number */
592 if ( tmpByte[0] & EGTP_MASK_BIT2 )
594 egtpMsg.msgHdr.seqNum.pres = TRUE;
595 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
596 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
597 egtpMsg.msgHdr.seqNum.val = (tmpByte[1] << 8) | tmpByte[2];
601 egtpMsg.msgHdr.seqNum.pres = 0;
602 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
603 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
604 egtpMsg.msgHdr.seqNum.val = (tmpByte[1] << 8) | tmpByte[2];
607 /* Decode N-PDU number */
608 if ( tmpByte[0] & EGTP_MASK_BIT1 )
610 egtpMsg.msgHdr.nPdu.pres = TRUE;
611 ODU_REM_PRE_MSG(&(egtpMsg.msgHdr.nPdu.val), mBuf);
615 egtpMsg.msgHdr.nPdu.pres = TRUE;
616 ODU_REM_PRE_MSG(&(egtpMsg.msgHdr.nPdu.val), mBuf);
619 if(extPres & EGTP_MASK_BIT1)
621 ODU_REM_PRE_MSG(&extHdrType, mBuf);
622 while( 0 != extHdrType)
626 case EGTP_EXT_HDR_UDP_TYPE:
628 ODU_REM_PRE_MSG(&extHdrLen, mBuf);
629 if(extHdrLen == 0x01)
631 egtpMsg.msgHdr.extHdr.udpPort.pres = TRUE;
632 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
633 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
634 egtpMsg.msgHdr.extHdr.udpPort.val = (tmpByte[1] << 8) | tmpByte[2];
639 case EGTP_EXT_HDR_PDCP_TYPE:
641 ODU_REM_PRE_MSG(&extHdrLen, mBuf);
642 if(extHdrLen == 0x01)
644 egtpMsg.msgHdr.extHdr.pdcpNmb.pres = TRUE;
645 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
646 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
647 egtpMsg.msgHdr.extHdr.pdcpNmb.val = (tmpByte[1] << 8) | tmpByte[2];
651 } /* End of switch */
653 ODU_REM_PRE_MSG(&extHdrType, mBuf);
656 } /* End of if(extPres & EGTP_MASK_BIT1) */
659 ODU_REM_PRE_MSG(&extHdrType, mBuf);
662 DU_LOG("\nDEBUG --> EGTP : Message Buffer after decoding header [TEID:%d]",egtpMsg.msgHdr.teId);
663 ODU_PRINT_MSG(mBuf, 0, 0);
669 } /* End of cuEgtpDecodeHdr */
671 /*******************************************************************
673 * @brief This function is responsible to build application message, encode EGTP
674 * header to it and send to DU over tunnel (teId)
678 * Function : cuEgtpDatReq
681 * function is responsible to build application message, encode EGTP
682 * header to it and send to DU over tunnel (teId)
684 * @params[in] uint8_t teId
686 * @return ROK - success
689 * ****************************************************************/
690 uint16_t cuEgtpDatReq(uint8_t teId)
692 uint8_t ret = ROK, cnt = 0, duId =0;
695 egtpMsg.msgHdr.teId = teId;
697 if(egtpCb.gCntPdu[teId] == 0xFF) //DRB not created
699 DU_LOG("\nERROR --> EGTP : DRB not created");
702 for(duId = 1; duId<=egtpCb.numDu; duId++)
704 /* Build Application message that is supposed to come from app to egtp */
705 ret = BuildAppMsg(duId, &egtpMsg);
708 DU_LOG("\nERROR --> EGTP : Failed to build App Msg");
712 /* Encode EGTP header to build final EGTP message */
713 ret = BuildEgtpMsg(duId, &egtpMsg);
716 DU_LOG("\nERROR --> EGTP : Failed to build EGTP Msg");
719 cuEgtpSendMsg(duId, egtpMsg.msg);
720 ODU_PUT_MSG_BUF(egtpMsg.msg);
726 /*******************************************************************
728 * @brief Builds application message to be sent to DU in DL path
732 * Function : BuildAppMsg
735 * Builds application message to be sent to DU in DL path
737 * @params[in] uint32_t duId,EGTP message
739 * @return ROK - success
742 * ****************************************************************/
743 S16 BuildAppMsg(uint32_t duId, EgtpMsg *egtpMsg)
745 char data[1215] = "In telecommunications, 5G is the fifth generation technology standard for broadband cellular"
746 " networks, which cellular phone companies began deploying worldwide in 2019, and is the planned successor to the 4G "
747 " networks which provide connectivity to most current cellphones. 5G networks are predicted to have more than 1.7"
748 " billion subscribers worldwide by 2025, according to the GSM Association.Like its predecessors, 5G networks are"
749 " cellular networks,in which the service area is divided into small geographical areas called cells.All 5G wireless"
750 " devices in a cell are connected to the Internet and telephone network by radio waves through local antenna in the"
751 " cell. The main advantage of the new networks is that they will have greater bandwidth, giving higher download"
752 " speeds, eventually up to 10 gigabits per second(Gbit/s). Due to the increased bandwidth, it is expected the"
753 " networks will not exclusively serve cellphones like existing cellular networks, but also be used as general"
754 " internet service providers for laptops and desktop computers, competing with existing ISPs such as cable"
755 " internet, and also will make possible new applications in internet of things (IoT) and machine to machine areas.";
761 if(ODU_GET_MSG_BUF(CU_APP_MEM_REG, CU_POOL, &mBuf) == ROK)
763 if(ODU_ADD_POST_MSG_MULT((Data *)data, datSize, mBuf) != ROK)
765 DU_LOG("\nERROR --> EGTP : ODU_ADD_POST_MSG_MULT failed");
766 ODU_PUT_MSG_BUF(mBuf);
772 DU_LOG("\nERROR --> EGTP : Failed to allocate memory");
776 /* filling IPv4 header */
781 ODU_GET_MSG_LEN(mBuf, &mLen);
783 memset(&ipv4Hdr, 0, sizeof(CmIpv4Hdr));
784 ipv4Hdr.length = CM_IPV4_HDRLEN + mLen;
785 ipv4Hdr.hdrVer = 0x45;
787 ipv4Hdr.srcAddr = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.egtpAssoc[duId-1].localIp.ipV4Addr);
788 ipv4Hdr.destAddr = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.egtpAssoc[duId-1].destIp.ipV4Addr);
790 /* Packing IPv4 header into buffer */
792 Data revPkArray[CM_IPV4_HDRLEN];
793 Data pkArray[CM_IPV4_HDRLEN];
795 /* initialize locals */
797 memset(revPkArray, 0, CM_IPV4_HDRLEN);
798 memset(pkArray, 0, CM_IPV4_HDRLEN);
800 /* Pack Header Version */
801 pkArray[cnt++] = ipv4Hdr.hdrVer;
804 pkArray[cnt++] = ipv4Hdr.tos;
806 pkArray[cnt++] = (Data)GetHiByte(ipv4Hdr.length);
807 pkArray[cnt++] = (Data)GetLoByte(ipv4Hdr.length);
810 pkArray[cnt++] = (Data) GetHiByte(ipv4Hdr.id);
811 pkArray[cnt++] = (Data) GetLoByte(ipv4Hdr.id);
814 pkArray[cnt++] = (Data)GetHiByte(ipv4Hdr.off);
815 pkArray[cnt++] = (Data)GetLoByte(ipv4Hdr.off);
818 pkArray[cnt++] = ipv4Hdr.ttl;
821 pkArray[cnt++] = ipv4Hdr.proto;
824 pkArray[cnt++] = (Data)GetHiByte(ipv4Hdr.chkSum);
825 pkArray[cnt++] = (Data)GetLoByte(ipv4Hdr.chkSum);
827 /* Pack Source Address */
828 pkArray[cnt++] = (Data)GetHiByte(GetHiWord(ipv4Hdr.srcAddr));
829 pkArray[cnt++] = (Data)GetLoByte(GetHiWord(ipv4Hdr.srcAddr));
830 pkArray[cnt++] = (Data)GetHiByte(GetLoWord(ipv4Hdr.srcAddr));
831 pkArray[cnt++] = (Data)GetLoByte(GetLoWord(ipv4Hdr.srcAddr));
833 /* Pack Destination Address */
834 pkArray[cnt++] = (Data)GetHiByte(GetHiWord(ipv4Hdr.destAddr));
835 pkArray[cnt++] = (Data)GetLoByte(GetHiWord(ipv4Hdr.destAddr));
836 pkArray[cnt++] = (Data)GetHiByte(GetLoWord(ipv4Hdr.destAddr));
837 pkArray[cnt++] = (Data)GetLoByte(GetLoWord(ipv4Hdr.destAddr));
839 for (idx = 0; idx < CM_IPV4_HDRLEN; idx++)
840 revPkArray[idx] = pkArray[CM_IPV4_HDRLEN - idx -1];
842 /* this function automatically reverses revPkArray */
843 ret = ODU_ADD_PRE_MSG_MULT(revPkArray, (MsgLen)cnt, mBuf);
845 egtpMsg->msgHdr.msgType = EGTPU_MSG_GPDU;
846 egtpMsg->msgHdr.nPdu.pres = TRUE;
848 if(egtpCb.gCntPdu[egtpMsg->msgHdr.teId] != NUM_DL_PACKETS)
849 egtpCb.gCntPdu[egtpMsg->msgHdr.teId]++;
851 egtpCb.gCntPdu[egtpMsg->msgHdr.teId] = 1;
853 egtpMsg->msgHdr.nPdu.val = egtpCb.gCntPdu[egtpMsg->msgHdr.teId];
854 egtpMsg->msgHdr.seqNum.pres = FALSE;
855 egtpMsg->msgHdr.extHdr.udpPort.pres = FALSE;
856 egtpMsg->msgHdr.extHdr.pdcpNmb.pres = FALSE;
862 /*******************************************************************
864 * @brief Encodes EGTP header to application message to send to DU
868 * Function : BuildEgtpMsg
871 * Encodes EGTP header to application message to send to DU
873 * @params[in] uint32_t duId,EGTP message
875 * @return ROK - success
878 * ****************************************************************/
879 S16 BuildEgtpMsg(uint32_t duId, EgtpMsg *egtpMsg)
881 EgtpTeIdCb *teidCb = NULLP;
887 cmHashListFind(&(egtpCb.dstCb[duId-1].teIdLst), (uint8_t *)&(egtpMsg->msgHdr.teId), sizeof(uint32_t), 0, (PTR *)&teidCb);
890 DU_LOG("\nERROR --> EGTP : Tunnel id[%d] not configured", egtpMsg->msgHdr.teId);
891 return (LCM_REASON_INVALID_PAR_VAL);
894 msgHdr = &(egtpMsg->msgHdr);
896 hdrLen = teidCb->preEncodedHdr.cnt;
898 if(msgHdr->extHdr.pdcpNmb.pres)
900 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= EGTP_MASK_BIT3;
901 teidCb->preEncodedHdr.hdr[hdrLen] = EGTP_EXT_HDR_PDCP_TYPE;
902 teidCb->preEncodedHdr.hdr[--hdrLen] = 1;
903 teidCb->preEncodedHdr.hdr[--hdrLen] = GetHiByte(msgHdr->extHdr.pdcpNmb.val);
904 teidCb->preEncodedHdr.hdr[--hdrLen] = GetLoByte(msgHdr->extHdr.pdcpNmb.val);
905 teidCb->preEncodedHdr.hdr[--hdrLen] = 0;
909 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT3);
912 ODU_GET_MSG_LEN(egtpMsg->msg, &tPduSize);
914 /*Adjust the header to fill the correct length*/
915 msgLen = tPduSize + (EGTP_MAX_HDR_LEN - hdrLen) - 0x08;
917 /***********************************************
918 * Fill the length field of the message header *
919 ***********************************************/
920 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 3] = (uint8_t)GetHiByte(msgLen);
921 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 4] = (uint8_t)GetLoByte(msgLen);
923 /*Update the sequence number*/
924 if(egtpMsg->msgHdr.seqNum.pres)
926 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= (EGTP_MASK_BIT2);
927 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 9] = (uint8_t)GetHiByte(egtpMsg->msgHdr.seqNum.val);
928 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 10] = (uint8_t)GetLoByte(egtpMsg->msgHdr.seqNum.val);
932 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT2);
935 /*Update the nPdU number*/
936 if(egtpMsg->msgHdr.nPdu.pres)
938 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= (EGTP_MASK_BIT1);
939 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 11] = egtpMsg->msgHdr.nPdu.val;
943 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT1);
946 ODU_ADD_PRE_MSG_MULT(&teidCb->preEncodedHdr.hdr[hdrLen], (EGTP_MAX_HDR_LEN - hdrLen), egtpMsg->msg);
950 /*******************************************************************
952 * @brief Send the egtp message to the destination DU
956 * Function : cuEgtpSendMsg
959 * Send the egtp message to the destination DU
961 * @params[in] uint32_t duId
963 * @return ROK - success
966 * ****************************************************************/
967 S16 cuEgtpSendMsg(uint32_t duId, Buffer *mBuf)
974 info.region = CU_APP_MEM_REG;
977 dstAddr.port = EGTP_RECVR_PORT;
978 dstAddr.address = egtpCb.dstCb[duId-1].dstIp;
980 ret = cmInetSendMsg(&(egtpCb.dstCb[duId-1].sendTptSrvr.sockFd), &dstAddr, &info, mBuf, &txLen, CM_INET_NO_FLAG);
981 if(ret != ROK && ret != RWOULDBLOCK)
983 DU_LOG("\nERROR --> EGTP : Message send failure");
987 DU_LOG("\nDEBUG --> EGTP : Message Sent");