replaced cmMemSet, cmMemcpy with memset and memcpy resp AND Removed TRC() traces...
[o-du/l2.git] / src / ric_stub / ric_e2ap_msg_hdl.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 E2AP message handler functions */
20 #include "common_def.h"
21 #include "OCTET_STRING.h"
22 #include "BIT_STRING.h"
23 #include "odu_common_codec.h"
24 #include "ric_stub.h"
25 #include "ric_stub_sctp.h"
26 #include "ric_e2ap_msg_hdl.h"
27 #include "GlobalE2node-gNB-ID.h"
28 #include "ProtocolIE-FieldE2.h"
29 #include "E2AP-PDU.h"
30 #include "du_log.h"
31
32 Bool ricSubsStatus;
33
34 /*******************************************************************
35 *
36 * @brief Sends E2 msg over SCTP
37 *
38 * @details
39 *
40 *    Function : SendE2APMsg
41 *
42 *    Functionality: Sends E2 msg over SCTP
43 *
44 * @params[in] Region region
45 *             Pool pool
46 * @return ROK     - success
47 *         RFAILED - failure
48 *
49 * ****************************************************************/
50
51 S16 SendE2APMsg(Region region, Pool pool)
52 {
53    Buffer *mBuf;
54
55    if(ODU_GET_MSG_BUF(region, pool, &mBuf) == ROK)
56    {
57       if(ODU_ADD_POST_MSG_MULT((Data *)encBuf, encBufSize, mBuf) == ROK)
58       {
59          ODU_PRINT_MSG(mBuf, 0,0);
60  
61          if(sctpSend(mBuf) != ROK)
62          {
63             DU_LOG("\nE2AP : SCTP Send for E2  failed");
64             ODU_PUT_MSG_BUF(mBuf);
65             return RFAILED;
66          }
67       }
68       else
69       {
70          DU_LOG("\nE2AP : ODU_ADD_POST_MSG_MULT failed");
71          ODU_PUT_MSG_BUF(mBuf);
72          return RFAILED;
73       }
74       ODU_PUT_MSG_BUF(mBuf);
75    }
76    else
77    {
78       DU_LOG("\nE2AP : Failed to allocate memory");
79       return RFAILED;
80    }
81  
82    return ROK;
83 } /* SendE2APMsg */
84
85 /*******************************************************************
86  *
87  * @brief Builds Global RIC Id Params
88  *
89  * @details
90  *
91  *    Function : BuildGlobalRicId
92  *
93  *    Functionality: Building the Plmn and ric id
94  *
95  * @params[in] GlobalRIC_ID_t *ricId
96  * @return ROK     - success
97  *         RFAILED - failure
98  *
99  * ****************************************************************/
100
101 S16 BuildGlobalRicId(GlobalRIC_ID_t *ricId)
102 {
103    U8 unused = 4;
104    U8 byteSize = 3;
105    U8 val = 1;
106    if(ricId != NULLP)
107    {
108       ricId->pLMN_Identity.size = byteSize * sizeof(U8);
109       RIC_ALLOC(ricId->pLMN_Identity.buf,  ricId->pLMN_Identity.size);
110       buildPlmnId(ricCfgParams.plmn , ricId->pLMN_Identity.buf);
111       /* fill ric Id */
112       ricId->ric_ID.size = byteSize * sizeof(U8);
113       RIC_ALLOC(ricId->ric_ID.buf, ricId->ric_ID.size);
114       fillBitString(&ricId->ric_ID, unused, byteSize, val);
115    }
116    return ROK;   
117 }
118
119 /*******************************************************************
120  *
121  * @brief Builds and sends the E2SetupResponse
122  *
123  * @details
124  *
125  *    Function : BuildAndSendE2SetupRsp
126  *
127  *    Functionality: Constructs the F1SetupResponse message and sends
128  *                   it back to the DU through SCTP.
129  *
130  * @params[in] void **buf,Buffer to which encoded pattern is written into
131  * @params[in] int *size,size of buffer
132  *
133  * @return ROK     - success
134  *         RFAILED - failure
135  *
136  * ****************************************************************/
137 S16 BuildAndSendE2SetupRsp()
138 {
139    E2AP_PDU_t         *e2apMsg = NULL;
140    E2setupResponse_t  *e2SetupRsp;
141    asn_enc_rval_t     encRetVal; 
142    U8 idx;
143    U8 elementCnt;
144
145  
146    DU_LOG("\nE2AP : Building E2 Setup Response\n");
147
148    RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); 
149    if(e2apMsg == NULLP)
150    {
151       DU_LOG("\nE2AP : Memory allocation for E2AP-PDU failed");
152       return RFAILED;
153    }
154    e2apMsg->present =  E2AP_PDU_PR_successfulOutcome;
155    RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
156    if(e2apMsg->choice.successfulOutcome == NULLP)
157    {
158       DU_LOG("\nE2AP : Memory allocation for E2AP-PDU failed");
159       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
160       return RFAILED;  
161    }
162
163    e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_E2setup;
164    e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject;
165    e2apMsg->choice.successfulOutcome->value.present = \
166          SuccessfulOutcomeE2__value_PR_E2setupResponse;
167    e2SetupRsp = &e2apMsg->choice.successfulOutcome->value.choice.E2setupResponse;
168
169    elementCnt = 1;
170    e2SetupRsp->protocolIEs.list.count = elementCnt;
171    e2SetupRsp->protocolIEs.list.size  = elementCnt * sizeof(E2setupResponseIEs_t);
172
173    RIC_ALLOC(e2SetupRsp->protocolIEs.list.array, \
174               e2SetupRsp->protocolIEs.list.size);
175    if(e2SetupRsp->protocolIEs.list.array == NULLP)
176    {
177       DU_LOG("\nE2AP : Memory allocation for E2ResponseIEs failed");
178       RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t));
179       RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
180       return RFAILED;
181    }
182
183    for(idx=0; idx<elementCnt; idx++)
184    {
185       RIC_ALLOC(e2SetupRsp->protocolIEs.list.array[idx], \
186             sizeof(E2setupResponseIEs_t)); 
187       if(e2SetupRsp->protocolIEs.list.array[idx] == NULLP)
188       {  
189          RIC_FREE(e2SetupRsp->protocolIEs.list.array,\
190                    e2SetupRsp->protocolIEs.list.size);
191          RIC_FREE(e2apMsg->choice.successfulOutcome, \
192                sizeof(SuccessfulOutcomeE2_t));
193          RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t));
194          return RFAILED;
195       }    
196    }
197    /* Global RIC ID */
198    idx = 0;
199    e2SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_GlobalRIC_ID;
200    e2SetupRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
201    e2SetupRsp->protocolIEs.list.array[idx]->value.present = \
202                                      E2setupResponseIEs__value_PR_GlobalRIC_ID;
203
204    BuildGlobalRicId(&(e2SetupRsp->protocolIEs.list.array[idx]->value.choice.GlobalRIC_ID));
205
206    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
207    memset(encBuf, 0, ENC_BUF_MAX_LEN);
208    encBufSize = 0;
209    encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf);
210
211    /* Check encode results */
212    if(encRetVal.encoded == ENCODE_FAIL)
213    {
214            DU_LOG("\nE2AP : Could not encode E2SetupResponse structure (at %s)\n",\
215                            encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
216            return RFAILED;   
217    } 
218    else 
219    {
220            DU_LOG("\nE2AP : Created APER encoded buffer for E2SetupResponse\n");
221            for(int i=0; i< encBufSize; i++)
222            {
223                    printf("%x",encBuf[i]);
224            } 
225    }
226
227
228    if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL) != ROK)
229    {
230       DU_LOG("\nE2AP : Sending E2 Setup Response failed");      
231       return RFAILED;
232    }
233
234    return ROK;
235 }
236
237 /*******************************************************************
238  *
239  * @brief Builds Ric Request Id
240  *
241  * @details
242  *
243  *    Function : BuildRicRequestId
244  *
245  *    Functionality: Building the Ric Request Id
246  *
247  * @params[in] RICrequestID_t *ricReqId
248  * @return ROK     - success
249  *         RFAILED - failure
250  *
251  * ****************************************************************/
252
253 S16 BuildRicRequestId(RICrequestID_t *ricReqId)
254 {
255
256    if(ricReqId != NULLP)
257    {
258       ricReqId->ricRequestorID = 1;
259       ricReqId->ricInstanceID  = 1;
260    }
261    return ROK;
262 }
263
264 /*******************************************************************
265  *
266  * @brief Fills Ric Action To be Setup Item
267  *
268  * @details
269  *
270  *    Function : fillSetupItems
271  *
272  *    Functionality: Filling ricAction Id, RicActionType
273  *
274  * @params[in] RICaction_ToBeSetup_Item_t *setupItems
275  * @return pointer of type RICaction_ToBeSetup_Item_t
276  *
277  * ****************************************************************/
278
279 RICaction_ToBeSetup_Item_t* fillSetupItems(RICaction_ToBeSetup_Item_t *setupItems)
280 {
281    if(setupItems != NULLP)
282    {
283       setupItems->ricActionID = 0;
284       setupItems->ricActionType = RICactionType_report;
285    }
286
287    return (setupItems);
288 }
289
290 /*******************************************************************
291  *
292  * @brief Fills RIC Subscription Details Item List
293  *
294  * @details
295  *
296  *    Function : fillSubsDetails
297  *
298  *    Functionality: Fill the RIC Subscription Details Items List
299  *
300  * @params[in] RICaction_ToBeSetup_ItemIEs_t *items
301  * @return ROK     - success
302  *         RFAILED - failure
303  *
304  * ****************************************************************/
305
306 S16 fillSubsDetails(RICaction_ToBeSetup_ItemIEs_t *items)
307 {
308    if(items != NULLP)
309    {
310       items->id = ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item;
311       items->criticality   =  CriticalityE2_ignore;
312       items->value.present =  RICaction_ToBeSetup_ItemIEs__value_PR_RICaction_ToBeSetup_Item;
313       fillSetupItems(&(items->value.choice.RICaction_ToBeSetup_Item));
314    }
315    return ROK;
316 }
317
318 /*******************************************************************
319  *
320  * @brief builds RIC Subscription Details
321  *
322  * @details
323  *
324  *    Function : BuildsRicSubsDetails
325  *
326  *    Functionality: Builds the RIC Subscription Details
327  *
328  * @params[in] RICsubscriptionDetails_t *subsDetails
329  * @return ROK     - success
330  *         RFAILED - failure
331  *
332  * ****************************************************************/
333
334 S16 BuildRicSubsDetails(RICsubscriptionDetails_t *subsDetails)
335 {
336
337    U8 elementCnt;
338
339    if(subsDetails != NULLP)
340    {
341       /* Octet string to be build here */
342       /* Sending PLMN as Octect string */
343       U8 byteSize = 3;
344       subsDetails->ricEventTriggerDefinition.size = byteSize * sizeof(U8);
345       RIC_ALLOC(subsDetails->ricEventTriggerDefinition.buf,  subsDetails->ricEventTriggerDefinition.size);
346       buildPlmnId(ricCfgParams.plmn, subsDetails->ricEventTriggerDefinition.buf);
347       elementCnt = 1;
348       subsDetails->ricAction_ToBeSetup_List.list.count = elementCnt;
349       subsDetails->ricAction_ToBeSetup_List.list.size = \
350                       elementCnt * sizeof(RICaction_ToBeSetup_ItemIEs_t);
351       RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array, \
352                 subsDetails->ricAction_ToBeSetup_List.list.size);
353       if(subsDetails->ricAction_ToBeSetup_List.list.array  == NULLP)
354       {
355          DU_LOG("\nE2AP : Memory allocation for RICactionToBeSetup Items failed");
356          return RFAILED;
357       } 
358       RIC_ALLOC(subsDetails->ricAction_ToBeSetup_List.list.array[0],\
359                    sizeof(RICaction_ToBeSetup_ItemIEs_t));
360       fillSubsDetails(subsDetails->ricAction_ToBeSetup_List.list.array[0]);
361    }
362    return ROK;
363 }
364
365 /*******************************************************************
366  *
367  * @brief Builds and Send the RicSubscriptionReq
368  *
369  * @details
370  *
371  *    Function : BuildAndSendRicSubscriptionReq
372  *
373  * Functionality:Fills the RicSubscriptionReq
374  *
375  * @return ROK     - success
376  *         RFAILED - failure
377  *
378  ******************************************************************/
379
380 S16 BuildAndSendRicSubscriptionReq()
381 {
382
383    E2AP_PDU_t   *e2apRicMsg = NULL;
384    RICsubscriptionRequest_t   *ricSubscriptionReq;
385    U8   elementCnt;
386    U8   idx;
387    U8   ieId;
388    S16  ret; 
389    asn_enc_rval_t             encRetVal;        /* Encoder return value */
390    ricSubsStatus = TRUE;
391
392    DU_LOG("\nE2AP : Building RIC Subscription Request\n");
393
394    RIC_ALLOC(e2apRicMsg, sizeof(E2AP_PDU_t));
395    if(e2apRicMsg == NULLP)
396    {
397       DU_LOG("\nE2AP : Memory allocation for E2AP-PDU failed");
398       return RFAILED;
399    }
400
401    e2apRicMsg->present = E2AP_PDU_PR_initiatingMessage;
402    RIC_ALLOC(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
403    if(e2apRicMsg->choice.initiatingMessage == NULLP)
404    {
405       DU_LOG("\nE2AP : Memory allocation for E2AP-PDU failed");
406       RIC_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));
407       return RFAILED;
408    }
409    e2apRicMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscription;
410    e2apRicMsg->choice.initiatingMessage->criticality = CriticalityE2_reject;
411    e2apRicMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionRequest;
412    
413    RIC_ALLOC(ricSubscriptionReq, sizeof(RICsubscriptionRequest_t));
414    ricSubscriptionReq = &e2apRicMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest;
415    
416    elementCnt = 3;
417    ricSubscriptionReq->protocolIEs.list.count = elementCnt;
418    ricSubscriptionReq->protocolIEs.list.size  = elementCnt * sizeof(RICsubscriptionRequest_IEs_t);
419
420    /* Initialize the subscription members */
421    RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array, \
422               ricSubscriptionReq->protocolIEs.list.size);
423    if(ricSubscriptionReq->protocolIEs.list.array == NULLP)
424    {
425       DU_LOG("\nE2AP : Memory allocation for RICSubscriptionRequestIEs failed");
426       RIC_FREE(e2apRicMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t));
427       RIC_FREE(e2apRicMsg, (Size)sizeof(E2AP_PDU_t));
428       return RFAILED;
429    }
430    
431    for(idx=0; idx<elementCnt; idx++)
432    {
433       RIC_ALLOC(ricSubscriptionReq->protocolIEs.list.array[idx],\
434             sizeof(RICsubscriptionRequest_IEs_t));
435       if(ricSubscriptionReq->protocolIEs.list.array[idx] == NULLP)
436       {
437          for(ieId=0; ieId<idx; ieId++)
438          {
439             RIC_FREE(ricSubscriptionReq->protocolIEs.list.array[ieId],\
440                   sizeof(RICsubscriptionRequest_IEs_t));
441          }
442          RIC_FREE(ricSubscriptionReq->protocolIEs.list.array,\
443                   ricSubscriptionReq->protocolIEs.list.size);
444          RIC_FREE(e2apRicMsg->choice.initiatingMessage, \
445                sizeof(InitiatingMessageE2_t));
446          RIC_FREE(e2apRicMsg, sizeof(E2AP_PDU_t));
447          return RFAILED;
448       }
449    }
450
451    /* Filling RIC Request Id */
452    idx = 0;
453    ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID;
454    ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
455    ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
456                                     RICsubscriptionRequest_IEs__value_PR_RICrequestID;
457  
458    BuildRicRequestId(&ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICrequestID);
459
460
461    /* Filling RAN Function Id */
462    idx++;
463    ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID;
464    ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
465    ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
466                                     RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
467    ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RANfunctionID = 1;
468
469
470    /* Filling RIC Subscription Details */
471    idx++;
472    ricSubscriptionReq->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICsubscriptionDetails;
473    ricSubscriptionReq->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject;
474    ricSubscriptionReq->protocolIEs.list.array[idx]->value.present =\
475                                     RICsubscriptionRequest_IEs__value_PR_RICsubscriptionDetails;
476
477    BuildRicSubsDetails(&(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails));
478
479
480    /* Prints the Msg formed */
481    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apRicMsg);
482
483    memset(encBuf, 0, ENC_BUF_MAX_LEN);
484    encBufSize = 0;
485    encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apRicMsg, PrepFinalEncBuf,\
486                encBuf);
487    if(encRetVal.encoded == ENCODE_FAIL)
488    {
489       DU_LOG("\nE2AP : Could not encode RicSubscriptionRequest structure (at %s)\n",\
490       encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
491       return RFAILED;
492    }
493    else
494    {
495       DU_LOG("\nE2AP : Created APER encoded buffer for RicSubscriptionRequest\n");
496       for(int i=0; i< encBufSize; i++)
497       {
498           printf("%x",encBuf[i]);
499       } 
500    }
501
502
503    /* Sending msg */
504    if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL) != ROK)
505    {
506       DU_LOG("\nE2AP : Sending RIC subscription Request failed");
507       return RFAILED;
508    }
509
510    return ROK;
511 }
512
513  
514 /*******************************************************************
515 *
516 * @brief Handles received E2AP message and sends back response  
517 *
518 * @details
519 *
520 *    Function : E2APMsgHdlr
521 *
522 *    Functionality:
523 *         - Decodes received E2AP control message
524 *         - Prepares response message, encodes and sends to SCTP
525 *
526 * @params[in] 
527 * @return ROK     - success
528 *         RFAILED - failure
529 *
530 * ****************************************************************/
531 void E2APMsgHdlr(Buffer *mBuf)
532 {
533    int i;
534    char *recvBuf;
535    MsgLen copyCnt;
536    MsgLen recvBufLen;
537    E2AP_PDU_t *e2apMsg;
538    asn_dec_rval_t rval; /* Decoder return value */
539    E2AP_PDU_t e2apasnmsg ;
540  
541    DU_LOG("\nE2AP : Received E2AP message buffer");
542    ODU_PRINT_MSG(mBuf, 0,0);
543  
544    /* Copy mBuf into char array to decode it */
545    ODU_GET_MSG_LEN(mBuf, &recvBufLen);
546    RIC_ALLOC(recvBuf, (Size)recvBufLen);
547
548    if(recvBuf == NULLP)
549    {
550       DU_LOG("\nE2AP : Memory allocation failed");
551       return;
552    }
553    if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, &copyCnt) != ROK)
554    {
555       DU_LOG("\nE2AP : Failed while copying %d", copyCnt);
556       return;
557    }
558
559    printf("\nE2AP : Received flat buffer to be decoded : ");
560    for(i=0; i< recvBufLen; i++)
561    {
562         printf("%x",recvBuf[i]);
563    }
564
565    /* Decoding flat buffer into E2AP messsage */
566    e2apMsg = &e2apasnmsg;
567    memset(e2apMsg, 0, sizeof(E2AP_PDU_t));
568
569    rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0);
570    RIC_FREE(recvBuf, (Size)recvBufLen);
571
572    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
573    {
574       DU_LOG("\nE2AP : ASN decode failed");
575       return;
576    }
577    printf("\n");
578    xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg);
579
580    switch(e2apMsg->present)
581    {
582       case E2AP_PDU_PR_initiatingMessage:
583       {
584          switch(e2apMsg->choice.initiatingMessage->value.present)
585          {
586             case InitiatingMessageE2__value_PR_E2setupRequest:
587             {
588                DU_LOG("\nE2AP : E2 setup request received");
589                BuildAndSendE2SetupRsp();
590                break;
591             }
592             case InitiatingMessageE2__value_PR_RICindication:
593             {
594                DU_LOG("\nE2AP : RIC Indication Acknowledged");
595                break;
596             }
597             default:
598             {
599                DU_LOG("\nE2AP : Invalid type of intiating message [%d]",e2apMsg->choice.initiatingMessage->value.present);
600                return;
601             }
602          }/* End of switch(initiatingMessage) */
603          break;
604       }
605       case E2AP_PDU_PR_successfulOutcome: 
606       {
607          switch(e2apMsg->choice.successfulOutcome->value.present)
608          {
609             case SuccessfulOutcomeE2__value_PR_RICsubscriptionResponse:  
610             {
611                DU_LOG("\nE2AP : RICsubscriptionResponse Msg Acknowledged");
612                break;
613             }
614             default:
615             {
616                DU_LOG("\nE2AP : Invalid type of successfulOutcome message [%d]",e2apMsg->choice.successfulOutcome->value.present);
617                return;
618             }
619             break;
620          }
621          break; 
622       }
623       default:
624       {
625          DU_LOG("\nE2AP : Invalid type message type ");
626          return;
627       }
628  
629     }/* End of switch(e2apMsg->present) */
630
631     if(!ricSubsStatus)
632       BuildAndSendRicSubscriptionReq(); 
633        
634 } /* End of E2APMsgHdlr */
635
636
637 /**********************************************************************
638   End of file
639  **********************************************************************/