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