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