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"
37 /**************************************************************************
38 * @brief Task Initiation callback function.
42 * Function : egtpActvInit
45 * This function is supplied as one of parameters during EGTP's
46 * task registration. SSI will invoke this function once, after
47 * it creates and attaches this TAPA Task to a system task.
49 * @param[in] Ent entity, the entity ID of this task.
50 * @param[in] Inst inst, the instance ID of this task.
51 * @param[in] Region region, the region ID registered for memory
53 * @param[in] Reason reason.
54 * @return ROK - success
56 ***************************************************************************/
59 DU_LOG("\n\nDEBUG --> EGTP : Initializing");
60 memset (&egtpCb, 0, sizeof(EgtpGlobalCb));
62 //Initializing with INVALID value
63 memset(egtpCb.gCntPdu, 0xFF , sizeof(uint8_t)*(MAX_TEID+1));
64 protType = CM_INET_PROTO_UDP;
69 /**************************************************************************
70 * @brief Task Activation callback function.
74 * Function : egtpActvTsk
77 * This function handles all EGTP messages received
78 * This API is registered with SSI during the
79 * Task Registration of DU APP.
81 * @param[in] Pst *pst, Post structure of the primitive.
82 * @param[in] Buffer *mBuf, Packed primitive parameters in the
84 * @return ROK - success
87 ***************************************************************************/
92 egtpCb.egtpCfg = cuCb.cuCfgParams.egtpParams;
96 DU_LOG("\nERROR --> EGTP : Configuration failed");
100 ret = cuEgtpSrvOpenReq();
103 DU_LOG("\nERROR --> EGTP : Transport server open request failed");
110 /**************************************************************************
111 * @brief EGTP server configuration
115 * Function : egtpCfgReq
118 * This function handles EGTP configuration request.
120 * @return ROK - success
123 * ***********************************************************************/
126 uint8_t ret, destIdx =0;
128 memcpy(&egtpCb.egtpCfg, &cuCb.cuCfgParams.egtpParams, sizeof(CuEgtpParams));
130 egtpCb.localAddr.address = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.localIp.ipV4Addr);
131 egtpCb.localAddr.port = egtpCb.egtpCfg.localPort;
133 for(destIdx=0; destIdx < egtpCb.egtpCfg.numDu; destIdx++)
135 egtpCb.dstCb[destIdx].duId = destIdx+1;
136 egtpCb.dstCb[destIdx].dstAddr.address = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.dstCfg[destIdx].dstIp.ipV4Addr);
137 egtpCb.dstCb[destIdx].dstAddr.port = egtpCb.egtpCfg.dstCfg[destIdx].dstPort;
138 egtpCb.dstCb[destIdx].numTunn = 0;
140 ret = cmHashListInit(&(egtpCb.dstCb[destIdx].teIdLst), 1024, sizeof(EgtpTeIdCb), FALSE, CM_HASH_KEYTYPE_UINT32_MOD, CU_APP_MEM_REG, CU_POOL);
144 DU_LOG("\nERROR --> EGTP : TeId hash list initialization failed");
149 DU_LOG("\nINFO --> EGTP : Configuration successful");
152 egtpCb.numDu = egtpCb.egtpCfg.numDu;
157 /**************************************************************************
158 * @brief EGTP server open request
162 * Function : egtpSrvOpenReq
165 * This function handles EGTP open server request.
166 * It opens udp socket to receive/send msgs.
168 * @param[in] Pst *pst, post structure
169 * @return ROK - success
172 ***************************************************************************/
174 S16 cuEgtpSrvOpenReq(Pst *pst)
177 uint8_t ret, destIdx;
179 DU_LOG("\nINFO --> EGTP : Received open server request");
181 sockType = CM_INET_DGRAM;
182 if((ret = (cmInetSocket(sockType, &(egtpCb.sockFd), protType))) != ROK)
184 DU_LOG("\nERROR --> EGTP : Failed to open UDP socket");
188 ret = cmInetBind(&(egtpCb.sockFd), &(egtpCb.localAddr));
191 DU_LOG("\nERROR --> EGTP : Failed to bind socket");
195 DU_LOG("\nINFO --> EGTP : Socket[%d] is open", egtpCb.sockFd.fd);
197 } /* cuEgtpSrvOpenReq */
200 /**************************************************************************
201 * @brief EGTP tunnel management request
205 * Function : cuEgtpTnlMgmtReq
208 * This function handles EGTP tunnel managament request
210 * @param[in] Pst *pst, post structure
211 * Tunnel Eveny structure
212 * @return ROK - success
216 * ***************************************************************************/
217 S16 cuEgtpTnlMgmtReq(uint32_t duId, EgtpTnlEvt tnlEvt)
221 DU_LOG("\nINFO --> EGTP : Received tunnel management request");
222 switch(tnlEvt.action)
224 case EGTP_TNL_MGMT_ADD:
226 ret = cuEgtpTnlAdd(duId, tnlEvt);
229 case EGTP_TNL_MGMT_MOD:
231 ret = cuEgtpTnlMod(duId, tnlEvt);
234 case EGTP_TNL_MGMT_DEL:
236 ret = cuEgtpTnlDel(duId, tnlEvt);
241 DU_LOG("\nERROR --> EGTP : Invalid tunnel management action[%d]", tnlEvt.action);
249 /**************************************************************************
250 * @brief EGTP tunnel addition
254 * Function : cuEgtpTnlAdd
257 * This function handles EGTP tunnel addition
259 * @param[in] Tunnel Event structure
260 * @return ROK - success
263 * ***************************************************************************/
264 S16 cuEgtpTnlAdd(uint32_t duId, EgtpTnlEvt tnlEvt)
268 EgtpMsgHdr preDefHdr; /* pre-define header for this tunnel */
271 DU_LOG("\nINFO --> EGTP : Tunnel addition : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
273 CU_ALLOC(teidCb, (Size)sizeof(EgtpTeIdCb));
277 DU_LOG("\nERROR --> EGTP : Memory allocation failed");
281 memset(teidCb, 0, sizeof(EgtpTeIdCb));
282 teidCb->teId = tnlEvt.lclTeid;
283 teidCb->remTeId = tnlEvt.remTeid;
285 ret = cmHashListInsert(&(egtpCb.dstCb[duId-1].teIdLst), (PTR)teidCb, (uint8_t *)&(teidCb->teId), sizeof(uint32_t));
288 DU_LOG("\nERROR --> EGTP : Failed to insert in hash list");
289 CU_FREE(teidCb, (Size)sizeof(EgtpTeIdCb));
292 egtpCb.dstCb[duId-1].numTunn++;
294 /* Encoding pre-defined header */
295 memset(&preDefHdr, 0, sizeof(EgtpMsgHdr));
296 preDefHdr.msgType = EGTPU_MSG_GPDU;
297 preDefHdr.teId = teidCb->remTeId;
298 preDefHdr.extHdr.pdcpNmb.pres = FALSE;
299 preDefHdr.extHdr.udpPort.pres = FALSE;
300 preDefHdr.nPdu.pres = TRUE; //Including nPdu when sending data
301 preDefHdr.nPdu.val = 0;
303 cuEgtpEncodeHdr((uint8_t *)teidCb->preEncodedHdr.hdr, &preDefHdr, &(teidCb->preEncodedHdr.cnt));
304 egtpCb.gCntPdu[teidCb->remTeId] = 0;//Resetting the Cnt Value for this DRB which indicates its creation
306 /* SPutSBuf(CU_APP_MEM_REG, CU_POOL, (Data *)teidCb, (Size)sizeof(EgtpTeIdCb));*/
311 /**************************************************************************
312 * @brief EGTP tunnel modification
316 * Function : cuEgtpTnlMod
319 * This function handles EGTP tunnel modification
321 * @param[in] Tunnel Event structure
322 * @return ROK - success
325 * ***************************************************************************/
326 S16 cuEgtpTnlMod(uint32_t duId, EgtpTnlEvt tnlEvt)
330 EgtpTeIdCb *teidCb = NULLP;
332 DU_LOG("\nDEBUG --> CU_STUB : Tunnel modification : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
334 cmHashListFind(&(egtpCb.dstCb[duId-1].teIdLst), (uint8_t *)&(tnlEvt.teId), sizeof(uint32_t), 0, (PTR *)&teidCb);
337 DU_LOG("\nDEBUG --> CU_STUBTunnel id not found");
341 teidCb->teId = tnlEvt.lclTeid;
342 teidCb->remTeId = tnlEvt.remTeid;
347 /**************************************************************************
348 * @brief EGTP tunnel deletion
352 * Function : cuEgtpTnlDel
355 * This function handles EGTP tunnel deletion
357 * @param[in] Tunnel Event structure
358 * @return ROK - success
361 * ***************************************************************************/
362 S16 cuEgtpTnlDel(uint32_t duId, EgtpTnlEvt tnlEvt)
364 EgtpTeIdCb *teidCb = NULLP;
366 DU_LOG("\nDEBUG --> EGTP : Tunnel deletion : Local Teid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid);
368 cmHashListFind(&(egtpCb.dstCb[duId-1].teIdLst), (uint8_t *)&(tnlEvt.lclTeid), sizeof(uint32_t), 0, (PTR *)&teidCb);
371 DU_LOG("\nERROR --> EGTP : Tunnel id[%d] not configured", tnlEvt.lclTeid);
375 cmHashListDelete(&(egtpCb.dstCb[duId-1].teIdLst), (PTR)teidCb);
376 CU_FREE(teidCb, (Size)sizeof(EgtpTeIdCb));
377 egtpCb.dstCb[duId-1].numTunn--;
382 /*******************************************************************
384 * @brief Encodes message header
388 * Function : cuEgtpEncodeHdr
391 * Encodes EGTP message haeder
393 * @params[in] EGTP message
395 * @return ROK - success
398 * ****************************************************************/
399 S16 cuEgtpEncodeHdr(uint8_t *preEncodedHdr, EgtpMsgHdr *preDefHdr, uint8_t *hdrIdx)
401 uint8_t tmpByte = 0; /* Stores one byte of data for enc */
402 uint8_t cnt = EGTP_MAX_HDR_LEN; /* Stores the position */
403 Bool extPres = FALSE; /* Flag for indication of S, E or P presense flag */
406 /* Encoding header */
407 tmpByte |= EGTP_MASK_BIT6; /* Setting 6th LSB of 1st byte as version */
408 tmpByte |= EGTP_MASK_BIT5; /* Setting 5th LSB of 1st byte as protocol type */
410 if(preDefHdr->extHdr.udpPort.pres || preDefHdr->extHdr.pdcpNmb.pres)
412 tmpByte |= EGTP_MASK_BIT3; /* Setting 3rd LSB of 1st byte if Extension heaeder is present */
415 if(preDefHdr->seqNum.pres)
417 tmpByte |= EGTP_MASK_BIT2;
420 if(preDefHdr->nPdu.pres)
422 tmpByte |= EGTP_MASK_BIT1;
425 if((tmpByte & EGTP_MASK_BIT1) || (tmpByte & EGTP_MASK_BIT2)||(tmpByte & EGTP_MASK_BIT3))
429 preEncodedHdr[--cnt] = tmpByte;
430 preEncodedHdr[--cnt] = preDefHdr->msgType;
432 /* Encode Tunnel endpoint */
433 preEncodedHdr[--cnt] = 0;
434 preEncodedHdr[--cnt] = 0;
435 nwWord = (uint16_t)(GetHiWord(preDefHdr->teId));
436 preEncodedHdr[--cnt] = (uint8_t)(GetHiByte(nwWord));
437 preEncodedHdr[--cnt] = (uint8_t)(GetLoByte(nwWord));
438 nwWord = (uint16_t)(GetLoWord(preDefHdr->teId));
439 preEncodedHdr[--cnt] = (uint8_t)(GetHiByte(nwWord));
440 preEncodedHdr[--cnt] = (uint8_t)(GetLoByte(nwWord));
442 /* Encode sequence number */
443 if(preDefHdr->seqNum.pres)
445 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->seqNum.val);
446 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->seqNum.val);
450 preEncodedHdr[--cnt] = 0;
451 preEncodedHdr[--cnt] = 0;
454 if(preDefHdr->nPdu.pres)
456 preEncodedHdr[--cnt] = preDefHdr->nPdu.val;
460 preEncodedHdr[--cnt] = 0;
463 if(preDefHdr->extHdr.udpPort.pres)
465 preEncodedHdr[--cnt] = EGTP_EXT_HDR_UDP_TYPE;
466 preEncodedHdr[--cnt] = 1;
467 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->extHdr.udpPort.val);
468 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->extHdr.udpPort.val);
471 if(preDefHdr->extHdr.pdcpNmb.pres)
473 preEncodedHdr[--cnt] = EGTP_EXT_HDR_PDCP_TYPE;
474 preEncodedHdr[--cnt] = 1;
475 preEncodedHdr[--cnt] = GetHiByte(preDefHdr->extHdr.pdcpNmb.val);
476 preEncodedHdr[--cnt] = GetLoByte(preDefHdr->extHdr.pdcpNmb.val);
479 if(tmpByte & EGTP_MASK_BIT3)
481 preEncodedHdr[--cnt] = 0;
485 preEncodedHdr[--cnt] = 0;
491 } /* egtpEncodeHdr */
493 /*******************************************************************
495 * @brief This handles the any EGTP received message
499 * Function : cuEgtpHdlRecvMsg
502 * This handles the any EGTP received message
504 * @params[in] Message Buffer
505 * @return ROK - success
508 * ****************************************************************/
509 S16 cuEgtpHdlRecvMsg(Buffer *mBuf)
511 /*Decoding of EGTP message header */
513 cuEgtpDecodeHdr(mBuf);
515 /* Start Pumping data from CU to DU */
516 //return (cuEgtpDatReq());
520 /*******************************************************************
522 * @brief Decodes message header
526 * Function : cuEgtpDecodeHdr
529 * Decodes EGTP message haeder
531 * @params[in] Message Buffer
532 * @return ROK - success
535 * ****************************************************************/
536 S16 cuEgtpDecodeHdr(Buffer *mBuf)
539 uint8_t tmpByte[5]; /* Holds one byte of data after Dec */
540 uint8_t version = 0; /* Holds the version type, decoded */
541 MsgLen msgLen = 0; /* Holds the msgLen from the Hdr */
542 MsgLen bufLen = 0; /* Holds the total buffer length */
543 uint8_t extHdrType = 0; /* Holds the Extension hdr type */
544 uint8_t extHdrLen = 0; /* Extension hdr length */
545 Bool extPres = FALSE; /* Flag for indication of S, E or P presense flag */
547 ODU_GET_MSG_LEN(mBuf, &bufLen);
550 ODU_REM_PRE_MSG(&tmpByte[0], mBuf);
551 version = tmpByte[0] >> 5;
553 /* Decode message type */
554 ODU_REM_PRE_MSG((Data*)&(egtpMsg.msgHdr.msgType), mBuf);
556 /* Decode message length */
557 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
558 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
559 msgLen = (tmpByte[1] << 8) | tmpByte[2];
561 /* Decode tunnel id */
562 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
563 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
564 ODU_REM_PRE_MSG(&tmpByte[3], mBuf);
565 ODU_REM_PRE_MSG(&tmpByte[4], mBuf);
566 egtpMsg.msgHdr.teId = (tmpByte[1] << 24) | (tmpByte[2] << 16) | (tmpByte[3] << 8) | tmpByte[4];
568 if((tmpByte[0] & EGTP_MASK_BIT1) || (tmpByte[0] & EGTP_MASK_BIT2)||(tmpByte[0] & EGTP_MASK_BIT3))
573 /* Decode sequence number */
574 if ( tmpByte[0] & EGTP_MASK_BIT2 )
576 egtpMsg.msgHdr.seqNum.pres = TRUE;
577 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
578 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
579 egtpMsg.msgHdr.seqNum.val = (tmpByte[1] << 8) | tmpByte[2];
583 egtpMsg.msgHdr.seqNum.pres = 0;
584 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
585 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
586 egtpMsg.msgHdr.seqNum.val = (tmpByte[1] << 8) | tmpByte[2];
589 /* Decode N-PDU number */
590 if ( tmpByte[0] & EGTP_MASK_BIT1 )
592 egtpMsg.msgHdr.nPdu.pres = TRUE;
593 ODU_REM_PRE_MSG(&(egtpMsg.msgHdr.nPdu.val), mBuf);
597 egtpMsg.msgHdr.nPdu.pres = TRUE;
598 ODU_REM_PRE_MSG(&(egtpMsg.msgHdr.nPdu.val), mBuf);
601 if(extPres & EGTP_MASK_BIT1)
603 ODU_REM_PRE_MSG(&extHdrType, mBuf);
604 while( 0 != extHdrType)
608 case EGTP_EXT_HDR_UDP_TYPE:
610 ODU_REM_PRE_MSG(&extHdrLen, mBuf);
611 if(extHdrLen == 0x01)
613 egtpMsg.msgHdr.extHdr.udpPort.pres = TRUE;
614 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
615 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
616 egtpMsg.msgHdr.extHdr.udpPort.val = (tmpByte[1] << 8) | tmpByte[2];
621 case EGTP_EXT_HDR_PDCP_TYPE:
623 ODU_REM_PRE_MSG(&extHdrLen, mBuf);
624 if(extHdrLen == 0x01)
626 egtpMsg.msgHdr.extHdr.pdcpNmb.pres = TRUE;
627 ODU_REM_PRE_MSG(&tmpByte[1], mBuf);
628 ODU_REM_PRE_MSG(&tmpByte[2], mBuf);
629 egtpMsg.msgHdr.extHdr.pdcpNmb.val = (tmpByte[1] << 8) | tmpByte[2];
633 } /* End of switch */
635 ODU_REM_PRE_MSG(&extHdrType, mBuf);
638 } /* End of if(extPres & EGTP_MASK_BIT1) */
641 ODU_REM_PRE_MSG(&extHdrType, mBuf);
644 DU_LOG("\nDEBUG --> EGTP : Message Buffer after decoding header [TEID:%d]",egtpMsg.msgHdr.teId);
645 ODU_PRINT_MSG(mBuf, 0, 0);
651 } /* End of cuEgtpDecodeHdr */
653 /*******************************************************************
655 * @brief This function is responsible to build application message, encode EGTP
656 * header to it and send to DU over tunnel (teId)
660 * Function : cuEgtpDatReq
663 * function is responsible to build application message, encode EGTP
664 * header to it and send to DU over tunnel (teId)
666 * @params[in] uint8_t teId
668 * @return ROK - success
671 * ****************************************************************/
672 uint16_t cuEgtpDatReq(uint32_t duId, uint8_t teId)
674 uint8_t ret = ROK, cnt = 0;
677 egtpMsg.msgHdr.teId = teId;
679 if(egtpCb.gCntPdu[teId] == 0xFF) //DRB not created
681 DU_LOG("\nERROR --> EGTP : DRB not created");
684 /* Build Application message that is supposed to come from app to egtp */
685 ret = BuildAppMsg(duId, &egtpMsg);
688 DU_LOG("\nERROR --> EGTP : Failed to build App Msg");
692 /* Encode EGTP header to build final EGTP message */
693 ret = BuildEgtpMsg(duId, &egtpMsg);
696 DU_LOG("\nERROR --> EGTP : Failed to build EGTP Msg");
699 cuEgtpSendMsg(duId, egtpMsg.msg);
700 ODU_PUT_MSG_BUF(egtpMsg.msg);
705 /*******************************************************************
707 * @brief Builds application message to be sent to DU in DL path
711 * Function : BuildAppMsg
714 * Builds application message to be sent to DU in DL path
716 * @params[in] uint32_t duId,EGTP message
718 * @return ROK - success
721 * ****************************************************************/
722 S16 BuildAppMsg(uint32_t duId, EgtpMsg *egtpMsg)
724 char data[1215] = "In telecommunications, 5G is the fifth generation technology standard for broadband cellular"
725 " networks, which cellular phone companies began deploying worldwide in 2019, and is the planned successor to the 4G "
726 " networks which provide connectivity to most current cellphones. 5G networks are predicted to have more than 1.7"
727 " billion subscribers worldwide by 2025, according to the GSM Association.Like its predecessors, 5G networks are"
728 " cellular networks,in which the service area is divided into small geographical areas called cells.All 5G wireless"
729 " devices in a cell are connected to the Internet and telephone network by radio waves through local antenna in the"
730 " cell. The main advantage of the new networks is that they will have greater bandwidth, giving higher download"
731 " speeds, eventually up to 10 gigabits per second(Gbit/s). Due to the increased bandwidth, it is expected the"
732 " networks will not exclusively serve cellphones like existing cellular networks, but also be used as general"
733 " internet service providers for laptops and desktop computers, competing with existing ISPs such as cable"
734 " internet, and also will make possible new applications in internet of things (IoT) and machine to machine areas.";
740 if(ODU_GET_MSG_BUF(CU_APP_MEM_REG, CU_POOL, &mBuf) == ROK)
742 if(ODU_ADD_POST_MSG_MULT((Data *)data, datSize, mBuf) != ROK)
744 DU_LOG("\nERROR --> EGTP : ODU_ADD_POST_MSG_MULT failed");
745 ODU_PUT_MSG_BUF(mBuf);
751 DU_LOG("\nERROR --> EGTP : Failed to allocate memory");
755 /* filling IPv4 header */
760 ODU_GET_MSG_LEN(mBuf, &mLen);
762 memset(&ipv4Hdr, 0, sizeof(CmIpv4Hdr));
763 ipv4Hdr.length = CM_IPV4_HDRLEN + mLen;
764 ipv4Hdr.hdrVer = 0x45;
766 ipv4Hdr.srcAddr = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.localIp.ipV4Addr);
767 ipv4Hdr.destAddr = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.dstCfg[duId-1].dstIp.ipV4Addr);
769 /* Packing IPv4 header into buffer */
771 Data revPkArray[CM_IPV4_HDRLEN];
772 Data pkArray[CM_IPV4_HDRLEN];
774 /* initialize locals */
776 memset(revPkArray, 0, CM_IPV4_HDRLEN);
777 memset(pkArray, 0, CM_IPV4_HDRLEN);
779 /* Pack Header Version */
780 pkArray[cnt++] = ipv4Hdr.hdrVer;
783 pkArray[cnt++] = ipv4Hdr.tos;
785 pkArray[cnt++] = (Data)GetHiByte(ipv4Hdr.length);
786 pkArray[cnt++] = (Data)GetLoByte(ipv4Hdr.length);
789 pkArray[cnt++] = (Data) GetHiByte(ipv4Hdr.id);
790 pkArray[cnt++] = (Data) GetLoByte(ipv4Hdr.id);
793 pkArray[cnt++] = (Data)GetHiByte(ipv4Hdr.off);
794 pkArray[cnt++] = (Data)GetLoByte(ipv4Hdr.off);
797 pkArray[cnt++] = ipv4Hdr.ttl;
800 pkArray[cnt++] = ipv4Hdr.proto;
803 pkArray[cnt++] = (Data)GetHiByte(ipv4Hdr.chkSum);
804 pkArray[cnt++] = (Data)GetLoByte(ipv4Hdr.chkSum);
806 /* Pack Source Address */
807 pkArray[cnt++] = (Data)GetHiByte(GetHiWord(ipv4Hdr.srcAddr));
808 pkArray[cnt++] = (Data)GetLoByte(GetHiWord(ipv4Hdr.srcAddr));
809 pkArray[cnt++] = (Data)GetHiByte(GetLoWord(ipv4Hdr.srcAddr));
810 pkArray[cnt++] = (Data)GetLoByte(GetLoWord(ipv4Hdr.srcAddr));
812 /* Pack Destination Address */
813 pkArray[cnt++] = (Data)GetHiByte(GetHiWord(ipv4Hdr.destAddr));
814 pkArray[cnt++] = (Data)GetLoByte(GetHiWord(ipv4Hdr.destAddr));
815 pkArray[cnt++] = (Data)GetHiByte(GetLoWord(ipv4Hdr.destAddr));
816 pkArray[cnt++] = (Data)GetLoByte(GetLoWord(ipv4Hdr.destAddr));
818 for (idx = 0; idx < CM_IPV4_HDRLEN; idx++)
819 revPkArray[idx] = pkArray[CM_IPV4_HDRLEN - idx -1];
821 /* this function automatically reverses revPkArray */
822 ret = ODU_ADD_PRE_MSG_MULT(revPkArray, (MsgLen)cnt, mBuf);
824 egtpMsg->msgHdr.msgType = EGTPU_MSG_GPDU;
825 egtpMsg->msgHdr.nPdu.pres = TRUE;
827 if(egtpCb.gCntPdu[egtpMsg->msgHdr.teId] != NUM_DL_PACKETS)
828 egtpCb.gCntPdu[egtpMsg->msgHdr.teId]++;
830 egtpCb.gCntPdu[egtpMsg->msgHdr.teId] = 1;
832 egtpMsg->msgHdr.nPdu.val = egtpCb.gCntPdu[egtpMsg->msgHdr.teId];
833 egtpMsg->msgHdr.seqNum.pres = FALSE;
834 egtpMsg->msgHdr.extHdr.udpPort.pres = FALSE;
835 egtpMsg->msgHdr.extHdr.pdcpNmb.pres = FALSE;
841 /*******************************************************************
843 * @brief Encodes EGTP header to application message to send to DU
847 * Function : BuildEgtpMsg
850 * Encodes EGTP header to application message to send to DU
852 * @params[in] uint32_t duId,EGTP message
854 * @return ROK - success
857 * ****************************************************************/
858 S16 BuildEgtpMsg(uint32_t duId, EgtpMsg *egtpMsg)
860 EgtpTeIdCb *teidCb = NULLP;
866 cmHashListFind(&(egtpCb.dstCb[duId-1].teIdLst), (uint8_t *)&(egtpMsg->msgHdr.teId), sizeof(uint32_t), 0, (PTR *)&teidCb);
869 DU_LOG("\nERROR --> EGTP : Tunnel id[%d] not configured", egtpMsg->msgHdr.teId);
870 return (LCM_REASON_INVALID_PAR_VAL);
873 msgHdr = &(egtpMsg->msgHdr);
875 hdrLen = teidCb->preEncodedHdr.cnt;
877 if(msgHdr->extHdr.pdcpNmb.pres)
879 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= EGTP_MASK_BIT3;
880 teidCb->preEncodedHdr.hdr[hdrLen] = EGTP_EXT_HDR_PDCP_TYPE;
881 teidCb->preEncodedHdr.hdr[--hdrLen] = 1;
882 teidCb->preEncodedHdr.hdr[--hdrLen] = GetHiByte(msgHdr->extHdr.pdcpNmb.val);
883 teidCb->preEncodedHdr.hdr[--hdrLen] = GetLoByte(msgHdr->extHdr.pdcpNmb.val);
884 teidCb->preEncodedHdr.hdr[--hdrLen] = 0;
888 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT3);
891 ODU_GET_MSG_LEN(egtpMsg->msg, &tPduSize);
893 /*Adjust the header to fill the correct length*/
894 msgLen = tPduSize + (EGTP_MAX_HDR_LEN - hdrLen) - 0x08;
896 /***********************************************
897 * Fill the length field of the message header *
898 ***********************************************/
899 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 3] = (uint8_t)GetHiByte(msgLen);
900 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 4] = (uint8_t)GetLoByte(msgLen);
902 /*Update the sequence number*/
903 if(egtpMsg->msgHdr.seqNum.pres)
905 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= (EGTP_MASK_BIT2);
906 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 9] = (uint8_t)GetHiByte(egtpMsg->msgHdr.seqNum.val);
907 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 10] = (uint8_t)GetLoByte(egtpMsg->msgHdr.seqNum.val);
911 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT2);
914 /*Update the nPdU number*/
915 if(egtpMsg->msgHdr.nPdu.pres)
917 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= (EGTP_MASK_BIT1);
918 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 11] = egtpMsg->msgHdr.nPdu.val;
922 teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT1);
925 ODU_ADD_PRE_MSG_MULT(&teidCb->preEncodedHdr.hdr[hdrLen], (EGTP_MAX_HDR_LEN - hdrLen), egtpMsg->msg);
929 /*******************************************************************
931 * @brief Send the egtp message to the destination DU
935 * Function : cuEgtpSendMsg
938 * Send the egtp message to the destination DU
940 * @params[in] uint32_t duId
942 * @return ROK - success
945 * ****************************************************************/
946 S16 cuEgtpSendMsg(uint32_t duId, Buffer *mBuf)
952 info.region = CU_APP_MEM_REG;
955 ret = cmInetSendMsg(&(egtpCb.sockFd), &egtpCb.dstCb[duId-1].dstAddr, &info, mBuf, &txLen, CM_INET_NO_FLAG);
956 if(ret != ROK && ret != RWOULDBLOCK)
958 DU_LOG("\nERROR --> EGTP : Message send failure");
962 DU_LOG("\nDEBUG --> EGTP : Message Sent");