E2AP code changes
[o-du/l2.git] / src / du_app / du_sctp.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 SCTP related functionality */
20
21 #include <stdio.h> 
22 #include "du_sctp.h"
23 #include "lsctp.h"
24
25
26 /**************************************************************************
27  * @brief Task Initiation callback function. 
28  *
29  * @details
30  *
31  *     Function : sctpActvInit 
32  *    
33  *     Functionality:
34  *             This function is supplied as one of parameters during SCTP's 
35  *             task registration. SSI will invoke this function once, after
36  *             it creates and attaches this TAPA Task to a system task.
37  *     
38  * @param[in]  Ent entity, the entity ID of this task.     
39  * @param[in]  Inst inst, the instance ID of this task.
40  * @param[in]  Region region, the region ID registered for memory 
41  *              usage of this task.
42  * @param[in]  Reason reason.
43  * @return ROK     - success
44  *         RFAILED - failure
45  ***************************************************************************/
46 S16 sctpActvInit(Ent entity, Inst inst, Region region, Reason reason)
47 {
48    DU_LOG("\n\nSCTP : Initializing");
49    SSetProcId(DU_PROC);
50    connUp = FALSE;
51    f1Params.assocId = -1;
52    ricParams.assocId = -1;
53    nonblocking = FALSE;
54    return ROK;
55
56 }
57
58 /**************************************************************************
59  * @brief Task Activation callback function. 
60  *
61  * @details
62  *
63  *      Function : sctpActvTsk 
64  * 
65  *      Functionality:
66  *           This function handles all SCTP 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 sctpActvTsk(Pst *pst, Buffer *mBuf)
78 {
79    switch(pst->srcEnt)
80    {
81       case ENTDUAPP:
82          {
83             switch(pst->event)
84             {
85                case EVTSTRTPOLL:
86                {
87                   sctpSockPoll();
88                   break;
89                } 
90             }
91             break;
92          }
93    }
94    SExitTsk();
95    return ROK;
96 }
97
98 /**************************************************************************
99  * @brief Function to configure the Sctp Params during config Request
100  *
101  * @details
102  *
103  *      Function : duSctpCfgReq
104  * 
105  *      Functionality:
106  *           This function configures SCTP Params during the config Request
107  *     
108  * @param[in]  SctpParams sctpCfg, common structure which has all the configuration
109  * @param[in]  CmStatus cfm, Builds the cfm status and reason
110  *  buffer.
111  *
112  * @return ROK     - success
113  *         RFAILED - failure
114  *
115  ***************************************************************************/
116
117 S16 duSctpCfgReq(SctpParams sctpCfg, CmStatus *cfm)
118 {
119 /* Fill F1 Params */
120    f1Params.destIpAddr.ipV4Pres  = sctpCfg.cuIpAddr.ipV4Pres;
121    f1Params.destIpAddr.ipV4Addr  = sctpCfg.cuIpAddr.ipV4Addr;
122    f1Params.destPort             = sctpCfg.cuPort;
123    f1Params.itfState             = DU_SCTP_DOWN;
124    f1Params.srcPort              = sctpCfg.duPort[0];
125    f1Params.recvMsgSet          = ROK;
126    cmMemset ((U8 *)&f1Params.sockFd, -1, sizeof(CmInetFd));
127    fillDestNetAddr(&f1Params.destIpNetAddr, &f1Params.destIpAddr);
128    fillAddrLst(&f1Params.destAddrLst, &f1Params.destIpAddr);
129
130 /* Fill RIC Params */
131    ricParams.destIpAddr.ipV4Pres = sctpCfg.ricIpAddr.ipV4Pres;
132    ricParams.destIpAddr.ipV4Addr = sctpCfg.ricIpAddr.ipV4Addr;
133    ricParams.destPort            = sctpCfg.ricPort;
134    ricParams.itfState            = DU_SCTP_DOWN;
135    ricParams.srcPort             = sctpCfg.duPort[1];
136    ricParams.recvMsgSet         = ROK;
137    cmMemset ((U8 *)&ricParams.sockFd, -1, sizeof(CmInetFd));
138    fillDestNetAddr(&ricParams.destIpNetAddr, &ricParams.destIpAddr);
139    fillAddrLst(&ricParams.destAddrLst, &ricParams.destIpAddr);
140
141 /* Fill AddressList */
142    fillAddrLst(&localAddrLst, &sctpCfg.duIpAddr);
143
144 /* Set polling to FALSE */
145    pollingState = FALSE;  
146
147 /* Fill Cfm Status */
148    cfm->status = LCM_PRIM_OK;
149    cfm->reason = LCM_REASON_NOT_APPL;
150
151    RETVALUE(ROK);
152 }
153
154 /*******************************************************************
155  *
156  * @brief Fills the address List of the source Ip Address
157  *
158  * @details
159  *
160  *    Function : fillAddrLst
161  *
162  *    Functionality:
163  *       Fills the address List of source Ip Address
164  *
165  * @params[in] CmInetNetAddrLst *addrLstPtr, Address List pointer
166  * @params[in] F1IpAddr *srcIpAddr, src Ip Adrress to be filled in the Address List
167  *
168  * @return ROK     - success
169  *         RFAILED - failure
170  *
171  ******************************************************************/
172
173 S16 fillAddrLst(CmInetNetAddrLst *addrLstPtr, F1IpAddr *ipAddr)
174
175    addrLstPtr->count++;
176    addrLstPtr->addrs[(addrLstPtr->count - 1)].type = CM_INET_IPV4ADDR_TYPE;
177    addrLstPtr->addrs[(addrLstPtr->count - 1)].u.ipv4NetAddr = CM_INET_NTOH_U32(ipAddr->ipV4Addr);
178
179    RETVALUE(ROK);
180 }
181
182 /******************************************************************************
183  *
184  * @brief Fills the address List of the source Ip Address
185  *
186  * @details
187  *
188  *    Function : fillDestNetAddr
189  *
190  *    Functionality:
191  *       Fills the address List of destinatoion Ip Address
192  *
193  * @params[in] CmInetNetAddr *destAddrPtr, Address List pointer
194  * @params[in] F1IpAddr *dstIpAddr, destIp Address to be filled in the Address List
195  *
196  * @return ROK     - success
197  *         RFAILED - failure
198  *
199  *******************************************************************************/
200 S16 fillDestNetAddr(CmInetNetAddr *destAddrPtr, F1IpAddr *dstIpPtr)
201 {
202    /* Filling destination address */
203    destAddrPtr->type = CM_INET_IPV4ADDR_TYPE;
204    destAddrPtr->u.ipv4NetAddr = CM_INET_NTOH_U32(dstIpPtr->ipV4Addr);
205    RETVALUE(ROK);
206 }
207
208 /******************************************************************************
209  *
210  * @brief Establishes the Assoc Req for the received interface type
211  *
212  * @details
213  *
214  *    Function : establishAssocReq
215  *
216  *    Functionality:
217  *       Eastablishes the Assoc Req for the received interface type
218  *
219  * @params[in] DuSctpDestCb *paramPtr
220  *
221  * @return ROK     - success
222  *         RFAILED - failure
223  *
224  *******************************************************************************/
225
226 S16 establishReq(DuSctpDestCb *paramPtr)
227 {
228    Pst pst;
229    S16 ret = ROK;
230    socket_type = CM_INET_STREAM;
231
232    if((ret = cmInetSocket(socket_type, &paramPtr->sockFd, IPPROTO_SCTP)) != ROK)
233    {
234       DU_LOG("\nSCTP : Failed while opening a socket in ODU");
235    } 
236    else if((ret = cmInetSctpBindx(&paramPtr->sockFd, &localAddrLst, paramPtr->srcPort)) != ROK)
237    {
238       DU_LOG("\nSCTP:  Failed during Binding in ODU");
239    }
240    else if((ret = sctpSetSockOpts(&paramPtr->sockFd)) != ROK)
241    {
242       DU_LOG("\nSCTP : Failed to set Socket Opt in ODU");
243    }     
244    else
245    { 
246       if(ret != ROK)
247       {
248          DU_LOG("\nSCTP : Failed while establishing Req at DU");
249          ret = RFAILED;
250       }
251       else 
252       {
253          ret = cmInetSctpConnectx(&paramPtr->sockFd, &paramPtr->destIpNetAddr, &paramPtr->destAddrLst, paramPtr->destPort);
254          /* 115 error_code indicates that Operation is in progress and hence ignored if SctpConnect failed due to this */
255          if(ret == 18)             
256          {
257            ret = ROK; 
258          }
259       }
260    }
261    if((ret == ROK) & (paramPtr->itfState == DU_SCTP_DOWN))
262    {
263       paramPtr->itfState = DU_SCTP_UP;
264    }
265
266    /* Post the EVTSTRTPOLL Msg */
267    if(!pollingState)
268    {
269       pollingState = TRUE;
270       duFillSctpPst(&pst, EVTSTRTPOLL);
271    }
272    
273    RETVALUE(ret);
274 }
275
276 /******************************************************************************
277  *
278  * @brief Processes the assoc Req for the received interface type
279  *
280  * @details
281  *
282  *    Function : duSctpAssocReq
283  *
284  *    Functionality:
285  *       Processes the Assoc Req for the received interface type
286  *
287  * @params[in] itfType interface Type, 
288  * @params[in] cfm , represents the status of request
289  * 
290  * @return ROK     - success
291  *         RFAILED - failure
292  *
293  *******************************************************************************/
294
295 S16 duSctpAssocReq(U8 itfType, CmStatus *cfm)
296 {
297    S16 ret = ROK;
298    DuSctpDestCb *paramPtr = NULLP;
299    if(SGetSBuf(DU_APP_MEM_REGION, DU_POOL, (Data **)&paramPtr, (Size)sizeof(DuSctpDestCb)) != ROK)
300    {
301       printf("\nDU_APP : Failed to allocate memory");
302       RETVALUE(RFAILED);
303    }
304    switch(itfType)
305    {
306       case F1_INTERFACE:
307       {
308          paramPtr = &f1Params;
309          ret = establishReq(paramPtr);
310          break;
311       }
312       case E2_INTERFACE:
313       {
314          paramPtr = &ricParams;
315          ret = establishReq(paramPtr);
316          break;
317       }
318       default:
319       {
320          DU_LOG("\nSCTP : Invalid Interface Type");
321          break;
322       }
323    }  
324    if(ret != ROK)
325    { 
326       DU_LOG("\nSCTP : ASSOC Req Failed.");
327       cfm->status = LCM_PRIM_NOK;
328       cfm->reason = LCM_REASON_NOT_APPL;
329    }
330    else
331    {
332       cfm->status = LCM_PRIM_OK;
333       cfm->reason = LCM_REASON_NOT_APPL;
334    }
335
336    RETVALUE(ret);
337 }
338 /*******************************************************************
339  *
340  * @brief  Fills Pst struct for ENTSCTP
341  *
342  * @details
343  *
344  *    Function : duFillSctpPst
345  *
346  *    Functionality:
347  *       Fills Pst struct for ENTSCTP
348  *
349  * @params[in] 
350  * @return ROK     - success
351  *         RFAILED - failure
352  *
353  * ****************************************************************/
354 S16 duFillSctpPst(Pst *pst, Event event)
355 {
356    Buffer *mBuf;
357    if(SGetMsg(DFLT_REGION, DU_POOL, &mBuf) != ROK)
358    {
359       printf("\nDU_APP : Failed to allocate memory");
360       RETVALUE(RFAILED);
361    }
362    cmMemset((U8 *)pst, 0, sizeof(Pst));
363    pst->srcEnt = (Ent)ENTDUAPP;
364    pst->srcInst = (Inst)DU_INST;
365    pst->srcProcId = DU_PROC;
366    pst->dstEnt = (Ent)ENTSCTP;
367    pst->dstInst = (Inst)SCTP_INST;
368    pst->dstProcId = pst->srcProcId;
369    pst->event = event;
370    pst->selector = DU_SELECTOR_LC;
371    pst->pool= DU_POOL;
372    SPstTsk(pst, mBuf); 
373
374    RETVALUE(ROK);
375 }
376
377 /*******************************************************************
378  *
379  * @brief Sets socket options as per requirement
380  *
381  * @details
382  *
383  *    Function : sctpSetSockOpts
384  *
385  *    Functionality: 
386  *       Sets socket options as per requirement
387  *
388  * @params[in] sock_Fd  determines the sockFd to be set
389  * @return ROK     - success
390  *         RFAILED - failure
391  *
392  * ****************************************************************/
393 S16 sctpSetSockOpts(CmInetFd *sock_Fd)
394 {
395     S16 ret = ROK;
396     CmSctpEvent sctpEvent;
397
398    sctpEvent.dataIoEvent          = TRUE;
399    sctpEvent.associationEvent     = TRUE;
400    sctpEvent.addressEvent         = TRUE;
401    sctpEvent.sendFailureEvent     = TRUE;
402    sctpEvent.peerErrorEvent       = TRUE;
403    sctpEvent.shutdownEvent        = TRUE;
404    sctpEvent.partialDeliveryEvent = TRUE;
405    sctpEvent.adaptationLayerEvent = TRUE;
406
407    if((ret = cmInetSetOpt(sock_Fd, CM_SOCKOPT_LEVEL_SCTP, CM_SOCKOPT_OPT_SCTP_EVENTS, &sctpEvent) != ROK))
408    {
409      ret = RFAILED;
410    }
411
412    RETVALUE(ret);
413 }
414
415 /*******************************************************************
416  *
417  * @brief Post received data/notification to DU APP 
418  *
419  * @details
420  *
421  *    Function : sendToDuApp 
422  *
423  *    Functionality:
424  *         Post received data/notification to DU APP
425  *
426  * @params[in]  Message buffer
427  *              Message event
428  *
429  * @return ROK     - success
430  *         RFAILED - failure
431  *
432  * ****************************************************************/
433 void sendToDuApp(Buffer *mBuf, Event event)
434 {
435    Pst pst;
436    DU_LOG("\nSCTP : Forwarding received message to duApp");
437    SPrntMsg(mBuf, 0, 0);
438
439
440    cmMemset((U8 *)&(pst), 0, sizeof(Pst));
441    pst.srcEnt = (Ent)ENTSCTP;
442    pst.srcInst = (Inst)SCTP_INST;
443    pst.srcProcId = DU_PROC;
444    pst.dstEnt = (Ent)ENTDUAPP;
445    pst.dstInst = (Inst)DU_INST;
446    pst.dstProcId = pst.srcProcId;
447    pst.event = event;
448    pst.selector = DU_SELECTOR_LC;
449    pst.pool= DU_POOL;
450    pst.region = DFLT_REGION;
451
452    if (SPstTsk(&pst, mBuf) != ROK)
453    {
454       DU_LOG("\nSCTP : SPstTsk failed in duReadCfg");
455    }
456 }
457
458 /*******************************************************************
459  *
460  * @brief Handles an SCTP notification message
461  *
462  * @Sending *
463  *    Function : sctpNtfyHdlr
464  *
465  *    Functionality:
466  *      Handles an SCTP notification message
467  *
468  * @params[in] Notify message
469  *
470  * @return ROK     - success
471  *         RFAILED - failure
472  *
473  * ****************************************************************/
474 S16 sctpNtfyHdlr(CmInetSctpNotification *ntfy)
475 {
476    Pst pst;
477
478    switch(ntfy->header.nType)
479    {
480       case CM_INET_SCTP_ASSOC_CHANGE :
481          DU_LOG("\nSCTP : Assoc change notification received");
482          switch(ntfy->u.assocChange.state)
483          {
484             case CM_INET_SCTP_COMM_UP:
485                DU_LOG("Event : COMMUNICATION UP");
486                connUp = TRUE;
487                break;
488             case CM_INET_SCTP_COMM_LOST:
489                DU_LOG("Event : COMMUNICATION LOST");
490                connUp = FALSE;
491                break;
492             case CM_INET_SCTP_RESTART:
493                DU_LOG("Event : SCTP RESTART");
494                connUp = FALSE;
495                break;
496             case CM_INET_SCTP_SHUTDOWN_COMP: /* association gracefully shutdown */
497                DU_LOG("Event : SHUTDOWN COMPLETE");
498                connUp = FALSE;
499                break;
500             case CM_INET_SCTP_CANT_STR_ASSOC:
501                DU_LOG("Event : CANT START ASSOC");
502                connUp = FALSE;
503                break;
504             default:
505                DU_LOG("\nInvalid event");
506                break;
507          }
508          break;
509       case CM_INET_SCTP_PEER_ADDR_CHANGE :
510          DU_LOG("\nSCTP : Peer Address Change notificarion received");
511          /* Need to add handler */
512          break;
513       case CM_INET_SCTP_REMOTE_ERROR :
514          DU_LOG("\nSCTP : Remote Error notification received");
515          break;
516       case CM_INET_SCTP_SEND_FAILED :
517          DU_LOG("\nSCTP : Send Failed notification received\n");
518          break;
519       case CM_INET_SCTP_SHUTDOWN_EVENT : /* peer socket gracefully closed */
520          DU_LOG("\nSCTP : Shutdown Event notification received\n");
521          connUp = FALSE;
522          exit(0);
523          break;
524       case CM_INET_SCTP_ADAPTATION_INDICATION :
525          DU_LOG("\nSCTP : Adaptation Indication received\n");
526          break;
527       case CM_INET_SCTP_PARTIAL_DELIVERY_EVENT:
528          DU_LOG("\nSCTP : Partial Delivery Event received\n");
529          break;
530       default:
531          DU_LOG("\nSCTP : Invalid sctp notification type\n");
532          break;
533    }
534
535    /* Pack notification and send to APP */
536    DU_LOG("\nSCTP : Forwarding received message to duApp");
537     
538    cmMemset((U8 *)&(pst), 0, sizeof(Pst));
539    pst.srcEnt = (Ent)ENTSCTP;
540    pst.srcInst = (Inst)SCTP_INST;
541    pst.srcProcId = DU_PROC;
542    pst.dstEnt = (Ent)ENTDUAPP;
543    pst.dstInst = (Inst)DU_INST;
544    pst.dstProcId = pst.srcProcId;
545    pst.event = EVTSCTPNTFY;
546    pst.selector = DU_SELECTOR_LC;
547    pst.pool= DU_POOL;
548    pst.region = DFLT_REGION;
549    
550    if(cmPkSctpNtfy(&pst, ntfy) != ROK)
551    {
552       DU_LOG("\nSCTP : Failed to pack SCTP notification");
553       RETVALUE(RFAILED);
554    }
555    RETVALUE(ROK);
556 }
557
558 /*******************************************************************
559  *
560  * @brief checks for valid readFd and process the InetSctpRecvMsg
561  * during polling 
562  *
563  * @details
564  *
565  *    Function : processPolling
566  *
567  *    Functionality:
568  *         checks for valid readFd and process the InetSctpRecvMsg
569  *         during polling
570  *
571  * @params[in]  Params required for polling
572  * @params[in]  SockFd for file descriptor
573  * @params[in]  timeoutPtr indicates the timeout value
574  * @params[in]  MemInfo, recvMsgSet
575  *
576  * @return ROK     - success
577  *         RFAILED - failure
578  *
579  * ****************************************************************/
580
581 S16 processPolling(sctpSockPollParams *pollParams, CmInetFd *sockFd, U32 *timeoutPtr, CmInetMemInfo *memInfo, Bool recvMsgSet)
582 {
583    U16 ret = ROK;
584    CM_INET_FD_SET(sockFd, &pollParams->readFd);
585    ret = cmInetSelect(&pollParams->readFd, NULLP, timeoutPtr, &pollParams->numFds);
586    if(CM_INET_FD_ISSET(sockFd, &pollParams->readFd))
587    {
588       CM_INET_FD_CLR(sockFd, &pollParams->readFd);
589       ret = cmInetSctpRecvMsg(sockFd, &pollParams->addr, &pollParams->port, memInfo, &(pollParams->mBuf), &pollParams->bufLen, &pollParams->info, &pollParams->flag, &pollParams->ntfy);
590         
591       if(connUp && ret != ROK)
592       {
593          DU_LOG("\n SCTP: Failed to receive sctp msg for sockFd[%d]\n", sockFd->fd);
594          recvMsgSet = RFAILED;
595       }
596       else
597       {
598          if((((pollParams->flag & CM_INET_SCTP_MSG_NOTIFICATION) != 0)) && ret == ROK)
599          {
600             if(pollParams->port == f1Params.destPort)
601             {
602                f1Params.assocId = pollParams->ntfy.u.assocChange.assocId;
603                DU_LOG("\nSCTP : AssocId assigned to F1Params from PollParams [%d]\n", f1Params.assocId);
604             }
605             else if(pollParams->port == ricParams.destPort)
606             {
607                ricParams.assocId = pollParams->ntfy.u.assocChange.assocId;
608                DU_LOG("\nSCTP : AssocId assigned to ricParams from PollParams [%d]\n", ricParams.assocId);
609             }
610             else
611             {
612                DU_LOG("\nSCTP : Failed to fill AssocId\n");
613             }  
614             ret = sctpNtfyHdlr(&pollParams->ntfy);
615             if(ret != ROK)
616             {
617                DU_LOG("\nSCTP : Failed to process sctp notify msg\n");
618             }
619          }
620          else if(connUp & (pollParams->port == f1Params.destPort))
621          {  
622             sendToDuApp(pollParams->mBuf, EVTSCTPDATA);
623          }
624          else if(connUp & (pollParams->port == ricParams.destPort))
625          {  
626             sendToDuApp(pollParams->mBuf, EVTRICDATA);
627          }
628
629          else
630          {
631             SPutMsg(pollParams->mBuf);
632          }
633       }
634   }
635   RETVALUE(ROK);
636 }
637 /*******************************************************************
638  *
639  * @brief Receives message on the socket
640  *
641  * @details
642  *
643  *    Function : sctpSockPoll
644  *
645  *    Functionality:
646  *      Receives message on the socket
647  *
648  * @params[in] 
649  * @return ROK     - success
650  *         RFAILED - failure
651  *
652  * ****************************************************************/
653 S16 sctpSockPoll()
654 {
655    U16 ret       = ROK;
656    U32           timeout;
657    U32           *timeout_Ptr;
658    CmInetMemInfo memInfo;
659    sctpSockPollParams f1PollParams, e2PollParams;
660
661    memset(&f1PollParams, 0, sizeof(sctpSockPollParams));
662    memset(&e2PollParams, 0, sizeof(sctpSockPollParams));
663
664    if (f1Params.sockFd.blocking & ricParams.sockFd.blocking)
665    {
666       /* blocking */
667       timeout_Ptr = NULLP;
668    }
669    else
670    {
671       /* non-blocking */
672       timeout = 0;
673       timeout_Ptr = &timeout;
674    }
675    memInfo.region = DU_APP_MEM_REGION;
676    memInfo.pool   = DU_POOL;
677
678    CM_INET_FD_ZERO(&f1PollParams.readFd);
679    CM_INET_FD_ZERO(&e2PollParams.readFd);
680
681    DU_LOG("\nSCTP : Polling started at DU\n");
682    while(1)
683    {
684       if(f1Params.itfState)
685       {
686          if((ret = processPolling(&f1PollParams, &f1Params.sockFd, timeout_Ptr, &memInfo, f1Params.recvMsgSet)) != ROK)
687          {
688             DU_LOG("\nSCTP : Failed to RecvMsg for F1\n");
689          }
690       }
691       if(ricParams.itfState)
692       {
693          if((ret = processPolling(&e2PollParams, &ricParams.sockFd, timeout_Ptr, &memInfo, ricParams.recvMsgSet)) != ROK)
694          {
695             DU_LOG("\nSCTP : Failed to RecvMsg for E2\n");
696          }
697       }
698    };
699    RETVALUE(ret);
700 }/* End of sctpSockPoll() */
701
702 /*******************************************************************
703  *
704  * @brief Send message on SCTP socket
705  *
706  * @details
707  *
708  *    Function : sctpSend 
709  *
710  *    Functionality:
711  *        Send message on SCTP socket
712  *
713  * @params[in] 
714  * @return ROK     - success
715  *         RFAILED - failure
716  *
717  * ****************************************************************/
718 S16 sctpSend(Buffer *mBuf, U8 itfType)
719 {
720    U8               ret;
721    MsgLen           len;          /* number of actually sent octets */
722    CmInetMemInfo    memInfo;                        
723    
724    memInfo.region = DU_APP_MEM_REGION;               
725    memInfo.pool   = DU_POOL;
726
727    if(itfType == F1_INTERFACE)
728    {
729       DU_LOG("\nSCTP : sending the message to DuApp");
730       ret = cmInetSctpSendMsg(&f1Params.sockFd, &f1Params.destIpNetAddr, f1Params.destPort, &memInfo, mBuf, &len, 0, FALSE, 0, 0/*SCT_PROTID_NONE*/, RWOULDBLOCK);
731    }
732
733    if(itfType == E2_INTERFACE)
734    {
735       DU_LOG("\nSCTP : sending the message to ric");
736       ret = cmInetSctpSendMsg(&ricParams.sockFd, &ricParams.destIpNetAddr, ricParams.destPort, &memInfo, mBuf, &len, 0, FALSE, 0, 0/*SCT_PROTID_NONE*/, RWOULDBLOCK);
737    }
738
739    if(ret != ROK && ret != RWOULDBLOCK)
740    {
741       DU_LOG("\nSCTP : Failed sending the message");
742       RETVALUE(RFAILED);
743    }
744
745    RETVALUE(ROK);
746 } /* End of sctpSend */
747
748 /**********************************************************************
749          End of file
750 **********************************************************************/