X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=src%2Fcu_stub%2Fcu_stub_egtp.c;h=c53bc6d925212d6880db75a4a200292b64c6c402;hb=0ba7b600f85b2975e1d60e5b8ad1523349b5f396;hp=f2b6da60c74704e7e81ac88a3464e843ff65b420;hpb=13d69430713cd381772de495739acff114be7e2a;p=o-du%2Fl2.git diff --git a/src/cu_stub/cu_stub_egtp.c b/src/cu_stub/cu_stub_egtp.c index f2b6da60c..c53bc6d92 100644 --- a/src/cu_stub/cu_stub_egtp.c +++ b/src/cu_stub/cu_stub_egtp.c @@ -19,11 +19,16 @@ /* This file contains all EGTP related functionality */ #include "common_def.h" +#include "OCTET_STRING.h" +#include "cu_stub_sctp.h" +#include "cu_f1ap_msg_hdl.h" #include "cu_stub_egtp.h" -#include "du_log.h" - -/* Global variable declaration */ -EgtpGlobalCb egtpCb; +#include "cu_stub.h" +#include "cm_inet.h" +#include "cm_tpt.h" + +#include "cm_inet.x" +#include "cm_tpt.x" /************************************************************************** * @brief Task Initiation callback function. @@ -49,6 +54,9 @@ S16 egtpActvInit() { DU_LOG("\n\nDEBUG --> EGTP : Initializing"); memset (&egtpCb, 0, sizeof(EgtpGlobalCb)); + + //Initializing with INVALID value + memset(egtpCb.gCntPdu, 0xFF , sizeof(uint8_t)*(MAX_TEID+1)); protType = CM_INET_PROTO_UDP; return ROK; } @@ -76,8 +84,8 @@ S16 egtpActvInit() uint8_t egtpInitReq() { uint8_t ret = ROK; - EgtpTnlEvt tnlEvt; - + + egtpCb.egtpCfg = cuCb.cuCfgParams.egtpParams; ret = cuEgtpCfgReq(); if(ret != ROK) { @@ -92,16 +100,6 @@ uint8_t egtpInitReq() return (ret); } - tnlEvt.action = EGTP_TNL_MGMT_ADD; - tnlEvt.lclTeid = 1; - tnlEvt.remTeid = 1; - ret = cuEgtpTnlMgmtReq(tnlEvt); - if(ret != ROK) - { - DU_LOG("\nERROR --> EGTP : Tunnel management request failed"); - return RFAILED; - } - return ret; } /* egtpInitReq */ @@ -121,30 +119,35 @@ uint8_t egtpInitReq() * ***********************************************************************/ S16 cuEgtpCfgReq() { - uint8_t ret; - - memcpy(&egtpCb.egtpCfg, &cuCfgParams.egtpParams, sizeof(EgtpParams)); - - egtpCb.recvTptSrvr.addr.address = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.localIp.ipV4Addr); - egtpCb.recvTptSrvr.addr.port = EGTP_DFLT_PORT; + uint8_t ret, destIdx =0; + + memcpy(&egtpCb.egtpCfg, &cuCb.cuCfgParams.egtpParams, sizeof(CuEgtpParams)); + + for(destIdx=0; destIdx < egtpCb.egtpCfg.numDu; destIdx++) + { + egtpCb.recvTptSrvr.addr.address = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.egtpAssoc[destIdx].localIp.ipV4Addr); + egtpCb.recvTptSrvr.addr.port = EGTP_RECVR_PORT; - egtpCb.dstCb.dstIp = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.destIp.ipV4Addr); - egtpCb.dstCb.dstPort = egtpCb.egtpCfg.destPort; - egtpCb.dstCb.sendTptSrvr.addr.address = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.localIp.ipV4Addr); - egtpCb.dstCb.sendTptSrvr.addr.port = egtpCb.egtpCfg.localPort; - egtpCb.dstCb.numTunn = 0; + egtpCb.dstCb[destIdx].duId = destIdx+1; + egtpCb.dstCb[destIdx].dstIp = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.egtpAssoc[destIdx].destIp.ipV4Addr); + egtpCb.dstCb[destIdx].dstPort = egtpCb.egtpCfg.egtpAssoc[destIdx].destPort; + egtpCb.dstCb[destIdx].sendTptSrvr.addr.address = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.egtpAssoc[destIdx].localIp.ipV4Addr); + egtpCb.dstCb[destIdx].sendTptSrvr.addr.port = egtpCb.egtpCfg.egtpAssoc[destIdx].localPort; + egtpCb.dstCb[destIdx].numTunn = 0; - ret = cmHashListInit(&(egtpCb.dstCb.teIdLst), 1024, sizeof(EgtpTeIdCb), FALSE, CM_HASH_KEYTYPE_UINT32_MOD, CU_APP_MEM_REG, CU_POOL); + ret = cmHashListInit(&(egtpCb.dstCb[destIdx].teIdLst), 1024, sizeof(EgtpTeIdCb), FALSE, CM_HASH_KEYTYPE_UINT32_MOD, CU_APP_MEM_REG, CU_POOL); - if(ret != ROK) - { - DU_LOG("\nERROR --> EGTP : TeId hash list initialization failed"); - return RFAILED; - } - else - { - DU_LOG("\nINFO --> EGTP : Configuration successful"); + if(ret != ROK) + { + DU_LOG("\nERROR --> EGTP : TeId hash list initialization failed"); + return RFAILED; + } + else + { + DU_LOG("\nINFO --> EGTP : Configuration successful"); + } } + egtpCb.numDu = egtpCb.egtpCfg.numDu; return ROK; } /* cuEgtpCfgReq */ @@ -169,10 +172,10 @@ S16 cuEgtpCfgReq() S16 cuEgtpSrvOpenReq(Pst *pst) { - uint8_t ret; + uint8_t ret, destIdx; DU_LOG("\nINFO --> EGTP : Received open server request"); - + sockType = CM_INET_DGRAM; if((ret = (cmInetSocket(sockType, &(egtpCb.recvTptSrvr.sockFd), protType))) != ROK) { @@ -186,24 +189,27 @@ S16 cuEgtpSrvOpenReq(Pst *pst) DU_LOG("\nERROR --> EGTP : Failed to bind socket"); return RFAILED; } + + for(destIdx=0; destIdx < egtpCb.egtpCfg.numDu; destIdx++) + { + if(ret = (cmInetSocket(sockType, &(egtpCb.dstCb[destIdx].sendTptSrvr.sockFd), protType)) != ROK) + { + DU_LOG("\nERROR --> EGTP : Failed to open UDP socket"); + return RFAILED; + } - if(ret = (cmInetSocket(sockType, &(egtpCb.dstCb.sendTptSrvr.sockFd), protType)) != ROK) - { - DU_LOG("\nERROR --> EGTP : Failed to open UDP socket"); - return RFAILED; - } - - ret = cmInetBind(&(egtpCb.dstCb.sendTptSrvr.sockFd), &(egtpCb.dstCb.sendTptSrvr.addr)); - if(ret != ROK) - { - DU_LOG("\nERROR --> EGTP : Failed to bind socket"); - return RFAILED; - } - - /* TODO: set socket options */ + ret = cmInetBind(&(egtpCb.dstCb[destIdx].sendTptSrvr.sockFd), &(egtpCb.dstCb[destIdx].sendTptSrvr.addr)); + if(ret != ROK) + { + DU_LOG("\nERROR --> EGTP : Failed to bind socket"); + return RFAILED; + } + + /* TODO: set socket options */ - DU_LOG("\nINFO --> EGTP : Receiver socket[%d] and Sender socket[%d] open", egtpCb.recvTptSrvr.sockFd.fd,\ - egtpCb.dstCb.sendTptSrvr.sockFd.fd); + DU_LOG("\nINFO --> EGTP : Receiver socket[%d] and Sender socket[%d] open", egtpCb.recvTptSrvr.sockFd.fd,\ + egtpCb.dstCb[destIdx].sendTptSrvr.sockFd.fd); + } return ROK; } /* cuEgtpSrvOpenReq */ @@ -225,7 +231,7 @@ S16 cuEgtpSrvOpenReq(Pst *pst) * * ***************************************************************************/ -S16 cuEgtpTnlMgmtReq(EgtpTnlEvt tnlEvt) +S16 cuEgtpTnlMgmtReq(uint32_t duId, EgtpTnlEvt tnlEvt) { S8 ret; @@ -234,17 +240,17 @@ S16 cuEgtpTnlMgmtReq(EgtpTnlEvt tnlEvt) { case EGTP_TNL_MGMT_ADD: { - ret = cuEgtpTnlAdd(tnlEvt); + ret = cuEgtpTnlAdd(duId, tnlEvt); break; } case EGTP_TNL_MGMT_MOD: { - ret = cuEgtpTnlMod(tnlEvt); + ret = cuEgtpTnlMod(duId, tnlEvt); break; } case EGTP_TNL_MGMT_DEL: { - ret = cuEgtpTnlDel(tnlEvt); + ret = cuEgtpTnlDel(duId, tnlEvt); break; } default: @@ -272,7 +278,7 @@ S16 cuEgtpTnlMgmtReq(EgtpTnlEvt tnlEvt) * RFAILED - failure * * ***************************************************************************/ -S16 cuEgtpTnlAdd(EgtpTnlEvt tnlEvt) +S16 cuEgtpTnlAdd(uint32_t duId, EgtpTnlEvt tnlEvt) { S16 ret; EgtpTeIdCb *teidCb; @@ -289,19 +295,18 @@ S16 cuEgtpTnlAdd(EgtpTnlEvt tnlEvt) return RFAILED; } - memset(teidCb, 0, sizeof(EgtpTeIdCb)); teidCb->teId = tnlEvt.lclTeid; teidCb->remTeId = tnlEvt.remTeid; - ret = cmHashListInsert(&(egtpCb.dstCb.teIdLst), (PTR)teidCb, (uint8_t *)&(teidCb->teId), sizeof(uint32_t)); + ret = cmHashListInsert(&(egtpCb.dstCb[duId-1].teIdLst), (PTR)teidCb, (uint8_t *)&(teidCb->teId), sizeof(uint32_t)); if(ret != ROK) { DU_LOG("\nERROR --> EGTP : Failed to insert in hash list"); CU_FREE(teidCb, (Size)sizeof(EgtpTeIdCb)); return RFAILED; } - egtpCb.dstCb.numTunn++; + egtpCb.dstCb[duId-1].numTunn++; /* Encoding pre-defined header */ memset(&preDefHdr, 0, sizeof(EgtpMsgHdr)); @@ -309,9 +314,11 @@ S16 cuEgtpTnlAdd(EgtpTnlEvt tnlEvt) preDefHdr.teId = teidCb->remTeId; preDefHdr.extHdr.pdcpNmb.pres = FALSE; preDefHdr.extHdr.udpPort.pres = FALSE; - preDefHdr.nPdu.pres = FALSE; - + preDefHdr.nPdu.pres = TRUE; //Including nPdu when sending data + preDefHdr.nPdu.val = 0; + cuEgtpEncodeHdr((uint8_t *)teidCb->preEncodedHdr.hdr, &preDefHdr, &(teidCb->preEncodedHdr.cnt)); + egtpCb.gCntPdu[teidCb->remTeId] = 0;//Resetting the Cnt Value for this DRB which indicates its creation /* SPutSBuf(CU_APP_MEM_REG, CU_POOL, (Data *)teidCb, (Size)sizeof(EgtpTeIdCb));*/ @@ -333,7 +340,7 @@ S16 cuEgtpTnlAdd(EgtpTnlEvt tnlEvt) * RFAILED - failure * * ***************************************************************************/ -S16 cuEgtpTnlMod(EgtpTnlEvt tnlEvt) +S16 cuEgtpTnlMod(uint32_t duId, EgtpTnlEvt tnlEvt) { #if 0 S16 ret; @@ -341,7 +348,7 @@ S16 cuEgtpTnlMod(EgtpTnlEvt tnlEvt) DU_LOG("\nDEBUG --> CU_STUB : Tunnel modification : LocalTeid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid); - cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(tnlEvt.teId), sizeof(uint32_t), 0, (PTR *)&teidCb); + cmHashListFind(&(egtpCb.dstCb[duId-1].teIdLst), (uint8_t *)&(tnlEvt.teId), sizeof(uint32_t), 0, (PTR *)&teidCb); if(teidCb == NULLP) { DU_LOG("\nDEBUG --> CU_STUBTunnel id not found"); @@ -369,22 +376,22 @@ S16 cuEgtpTnlMod(EgtpTnlEvt tnlEvt) * RFAILED - failure * * ***************************************************************************/ -S16 cuEgtpTnlDel(EgtpTnlEvt tnlEvt) +S16 cuEgtpTnlDel(uint32_t duId, EgtpTnlEvt tnlEvt) { EgtpTeIdCb *teidCb = NULLP; DU_LOG("\nDEBUG --> EGTP : Tunnel deletion : Local Teid[%d] Remote Teid[%d]", tnlEvt.lclTeid, tnlEvt.remTeid); - cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(tnlEvt.lclTeid), sizeof(uint32_t), 0, (PTR *)&teidCb); + cmHashListFind(&(egtpCb.dstCb[duId-1].teIdLst), (uint8_t *)&(tnlEvt.lclTeid), sizeof(uint32_t), 0, (PTR *)&teidCb); if(teidCb == NULLP) { DU_LOG("\nERROR --> EGTP : Tunnel id[%d] not configured", tnlEvt.lclTeid); return RFAILED; } - cmHashListDelete(&(egtpCb.dstCb.teIdLst), (PTR)teidCb); + cmHashListDelete(&(egtpCb.dstCb[duId-1].teIdLst), (PTR)teidCb); CU_FREE(teidCb, (Size)sizeof(EgtpTeIdCb)); - egtpCb.dstCb.numTunn--; + egtpCb.dstCb[duId-1].numTunn--; return ROK; } /* cuEgtpTnlDel */ @@ -500,16 +507,49 @@ S16 cuEgtpEncodeHdr(uint8_t *preEncodedHdr, EgtpMsgHdr *preDefHdr, uint8_t *hdrI } /* egtpEncodeHdr */ +/******************************************************************* + * + * @brief This handles the any EGTP received message + * + * @details + * + * Function : cuEgtpHdlRecvMsg + * + * Functionality: + * This handles the any EGTP received message + * + * @params[in] Message Buffer + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ S16 cuEgtpHdlRecvMsg(Buffer *mBuf) { /*Decoding of EGTP message header */ + cuEgtpDecodeHdr(mBuf); - + /* Start Pumping data from CU to DU */ //return (cuEgtpDatReq()); } +/******************************************************************* + * + * @brief Decodes message header + * + * @details + * + * Function : cuEgtpDecodeHdr + * + * Functionality: + * Decodes EGTP message haeder + * + * @params[in] Message Buffer + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ S16 cuEgtpDecodeHdr(Buffer *mBuf) { EgtpMsg egtpMsg; @@ -618,20 +658,48 @@ S16 cuEgtpDecodeHdr(Buffer *mBuf) ODU_REM_PRE_MSG(&extHdrType, mBuf); } - DU_LOG("\nDEBUG --> EGTP : Message Buffer after decoding header "); + DU_LOG("\nDEBUG --> EGTP : Message Buffer after decoding header [TEID:%d]",egtpMsg.msgHdr.teId); ODU_PRINT_MSG(mBuf, 0, 0); + SPutMsg(mBuf); + return ROK; } /* End of cuEgtpDecodeHdr */ -S16 cuEgtpDatReq() +/******************************************************************* + * + * @brief This function is responsible to build application message, encode EGTP + * header to it and send to DU over tunnel (teId) + * + * @details + * + * Function : cuEgtpDatReq + * + * Functionality: + * function is responsible to build application message, encode EGTP + * header to it and send to DU over tunnel (teId) + * + * @params[in] uint8_t teId + * + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +uint16_t cuEgtpDatReq(uint32_t duId, uint8_t teId) { uint8_t ret = ROK, cnt = 0; EgtpMsg egtpMsg; + egtpMsg.msgHdr.teId = teId; + + if(egtpCb.gCntPdu[teId] == 0xFF) //DRB not created + { + DU_LOG("\nERROR --> EGTP : DRB not created"); + return RFAILED ; + } /* Build Application message that is supposed to come from app to egtp */ - ret = BuildAppMsg(&egtpMsg); + ret = BuildAppMsg(duId, &egtpMsg); if(ret != ROK) { DU_LOG("\nERROR --> EGTP : Failed to build App Msg"); @@ -639,28 +707,36 @@ S16 cuEgtpDatReq() } /* Encode EGTP header to build final EGTP message */ - ret = BuildEgtpMsg(&egtpMsg); + ret = BuildEgtpMsg(duId, &egtpMsg); if(ret != ROK) { DU_LOG("\nERROR --> EGTP : Failed to build EGTP Msg"); return RFAILED; } - /* Send Message to peer */ - while(cnt < 200) - { - DU_LOG("\nDEBUG --> EGTP : Sending message[%d]", cnt+1); - cuEgtpSendMsg(egtpMsg.msg); - cnt++; - //sleep(1); - } - + cuEgtpSendMsg(duId, egtpMsg.msg); ODU_PUT_MSG_BUF(egtpMsg.msg); - return ROK; } -S16 BuildAppMsg(EgtpMsg *egtpMsg) +/******************************************************************* + * + * @brief Builds application message to be sent to DU in DL path + * + * @details + * + * Function : BuildAppMsg + * + * Functionality: + * Builds application message to be sent to DU in DL path + * + * @params[in] uint32_t duId,EGTP message + * + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +S16 BuildAppMsg(uint32_t duId, EgtpMsg *egtpMsg) { char data[1215] = "In telecommunications, 5G is the fifth generation technology standard for broadband cellular" " networks, which cellular phone companies began deploying worldwide in 2019, and is the planned successor to the 4G " @@ -704,8 +780,8 @@ S16 BuildAppMsg(EgtpMsg *egtpMsg) ipv4Hdr.length = CM_IPV4_HDRLEN + mLen; ipv4Hdr.hdrVer = 0x45; ipv4Hdr.proto = 1; - ipv4Hdr.srcAddr = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.localIp.ipV4Addr); - ipv4Hdr.destAddr = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.destIp.ipV4Addr); + ipv4Hdr.srcAddr = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.egtpAssoc[duId-1].localIp.ipV4Addr); + ipv4Hdr.destAddr = CM_INET_NTOH_UINT32(egtpCb.egtpCfg.egtpAssoc[duId-1].destIp.ipV4Addr); /* Packing IPv4 header into buffer */ S16 ret, cnt, idx; @@ -763,18 +839,40 @@ S16 BuildAppMsg(EgtpMsg *egtpMsg) ret = ODU_ADD_PRE_MSG_MULT(revPkArray, (MsgLen)cnt, mBuf); egtpMsg->msgHdr.msgType = EGTPU_MSG_GPDU; - egtpMsg->msgHdr.nPdu.pres = FALSE; + egtpMsg->msgHdr.nPdu.pres = TRUE; + + if(egtpCb.gCntPdu[egtpMsg->msgHdr.teId] != NUM_DL_PACKETS) + egtpCb.gCntPdu[egtpMsg->msgHdr.teId]++; + else + egtpCb.gCntPdu[egtpMsg->msgHdr.teId] = 1; + + egtpMsg->msgHdr.nPdu.val = egtpCb.gCntPdu[egtpMsg->msgHdr.teId]; egtpMsg->msgHdr.seqNum.pres = FALSE; egtpMsg->msgHdr.extHdr.udpPort.pres = FALSE; egtpMsg->msgHdr.extHdr.pdcpNmb.pres = FALSE; - egtpMsg->msgHdr.teId = 1; egtpMsg->msg = mBuf; return ret; } - -S16 BuildEgtpMsg(EgtpMsg *egtpMsg) +/******************************************************************* + * + * @brief Encodes EGTP header to application message to send to DU + * + * @details + * + * Function : BuildEgtpMsg + * + * Functionality: + * Encodes EGTP header to application message to send to DU + * + * @params[in] uint32_t duId,EGTP message + * + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +S16 BuildEgtpMsg(uint32_t duId, EgtpMsg *egtpMsg) { EgtpTeIdCb *teidCb = NULLP; MsgLen tPduSize; @@ -782,7 +880,7 @@ S16 BuildEgtpMsg(EgtpMsg *egtpMsg) uint32_t msgLen; EgtpMsgHdr *msgHdr; - cmHashListFind(&(egtpCb.dstCb.teIdLst), (uint8_t *)&(egtpMsg->msgHdr.teId), sizeof(uint32_t), 0, (PTR *)&teidCb); + cmHashListFind(&(egtpCb.dstCb[duId-1].teIdLst), (uint8_t *)&(egtpMsg->msgHdr.teId), sizeof(uint32_t), 0, (PTR *)&teidCb); if(teidCb == NULLP) { DU_LOG("\nERROR --> EGTP : Tunnel id[%d] not configured", egtpMsg->msgHdr.teId); @@ -830,15 +928,39 @@ S16 BuildEgtpMsg(EgtpMsg *egtpMsg) teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT2); } - ODU_ADD_PRE_MSG_MULT(&teidCb->preEncodedHdr.hdr[hdrLen], (EGTP_MAX_HDR_LEN - hdrLen), egtpMsg->msg); - - DU_LOG("\nDEBUG --> EGTP : Sending message buffer"); - ODU_PRINT_MSG(egtpMsg->msg, 0, 0); + /*Update the nPdU number*/ + if(egtpMsg->msgHdr.nPdu.pres) + { + teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] |= (EGTP_MASK_BIT1); + teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 11] = egtpMsg->msgHdr.nPdu.val; + } + else + { + teidCb->preEncodedHdr.hdr[EGTP_MAX_HDR_LEN - 1] &= ~(EGTP_MASK_BIT1); + } + ODU_ADD_PRE_MSG_MULT(&teidCb->preEncodedHdr.hdr[hdrLen], (EGTP_MAX_HDR_LEN - hdrLen), egtpMsg->msg); return ROK; } -S16 cuEgtpSendMsg(Buffer *mBuf) +/******************************************************************* + * + * @brief Send the egtp message to the destination DU + * + * @details + * + * Function : cuEgtpSendMsg + * + * Functionality: + * Send the egtp message to the destination DU + * + * @params[in] uint32_t duId + * Message Buffer + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +S16 cuEgtpSendMsg(uint32_t duId, Buffer *mBuf) { S16 ret; MsgLen txLen; @@ -848,10 +970,10 @@ S16 cuEgtpSendMsg(Buffer *mBuf) info.region = CU_APP_MEM_REG; info.pool = CU_POOL; - dstAddr.port = EGTP_DFLT_PORT; - dstAddr.address = egtpCb.dstCb.dstIp; + dstAddr.port = EGTP_RECVR_PORT; + dstAddr.address = egtpCb.dstCb[duId-1].dstIp; - ret = cmInetSendMsg(&(egtpCb.dstCb.sendTptSrvr.sockFd), &dstAddr, &info, mBuf, &txLen, CM_INET_NO_FLAG); + ret = cmInetSendMsg(&(egtpCb.dstCb[duId-1].sendTptSrvr.sockFd), &dstAddr, &info, mBuf, &txLen, CM_INET_NO_FLAG); if(ret != ROK && ret != RWOULDBLOCK) { DU_LOG("\nERROR --> EGTP : Message send failure");