d123ef6680774f87b521d758c693abdb7e5b2497
[o-du/l2.git] / src / du_app / F1AP / f1ap_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 F1AP message handler functions */
20
21 #include "du_mgr_main.h"
22 #include "cu_stub_sctp.h"
23 #include "f1ap_msg_hdl.h"
24
25 char encBuf[ENC_BUF_MAX_LEN];
26
27 /*******************************************************************
28  *
29  * @brief Writes the encoded chunks into a buffer
30  *
31  * @details
32  *
33  *    Function : write_out
34  *
35  *    Functionality:Fills the encoded buffer
36  *
37  * @params[in] void *buffer,initial encoded data
38  * @params[in] size_t size,size of buffer
39  * @params[in] void *app_key,final buffer
40  * @return ROK     - success
41  *         RFAILED - failure
42  *
43  * ****************************************************************/
44 static int PrepFinalEncBuf(const void *buffer, size_t size, void *encodedBuf)
45 {
46    memcpy(encodedBuf + encBufSize, buffer, size);
47    encBufSize += size;
48    return 0;
49 }
50
51 /*******************************************************************
52  *
53  * @brief Builds the F1SetupRequest
54  *
55  * @details
56  *
57  *    Function : BuildF1SetupReq
58  *
59  * Functionality:Fills the F1SetupRequest
60  *
61  * @return ROK     - success
62  *         RFAILED - failure
63  *
64  ******************************************************************/
65 S16 BuildF1SetupReq()
66 {
67    S16  ret;
68    U8   idx;
69    U8   elementCnt;
70    F1AP_PDU_t         *f1apMsg = NULL;
71    F1SetupRequest_t   *f1SetupReq;
72    asn_enc_rval_t     encRetVal;        /* Encoder return value */
73    
74    printf("\nBuilding F1 Setup Request\n");
75
76    ret = SGetSBuf(DU_APP_MEM_REGION, DU_POOL, (Data **)&f1apMsg, (Size)sizeof(F1AP_PDU_t));
77    if(ret != ROK)
78    {
79       printf("Memory allocation for F1AP-PDU failed");
80       RETVALUE(ret);
81    }
82
83    f1apMsg->present = F1AP_PDU_PR_initiatingMessage;
84    ret = SGetSBuf(DU_APP_MEM_REGION, DU_POOL, (Data **)&(f1apMsg->choice.initiatingMessage),\
85          (Size)sizeof(InitiatingMessage_t));
86    if(ret != ROK)
87    {
88       printf("Memory allocation for F1AP-PDU failed");
89       SPutSBuf(DU_APP_MEM_REGION,DU_POOL,(Data *)&f1apMsg,(Size)sizeof(F1AP_PDU_t));
90       RETVALUE(ret);
91    }
92
93    f1apMsg->choice.initiatingMessage->procedureCode = ProcedureCode_id_F1Setup;
94    f1apMsg->choice.initiatingMessage->criticality = Criticality_reject;
95    f1apMsg->choice.initiatingMessage->value.present = InitiatingMessage__value_PR_F1SetupRequest;
96
97    f1SetupReq = &f1apMsg->choice.initiatingMessage->value.choice.F1SetupRequest;
98
99    elementCnt = 3;
100    f1SetupReq->protocolIEs.list.count = elementCnt;
101    f1SetupReq->protocolIEs.list.size = elementCnt * sizeof(F1SetupRequestIEs_t *);
102
103    /* Initialize the F1Setup members */
104    ret = SGetSBuf(DU_APP_MEM_REGION, DU_POOL,(Data **)&(f1SetupReq->protocolIEs.list.array),\
105          (Size)elementCnt * sizeof(F1SetupRequestIEs_t *));
106    if(ret != ROK)
107    {
108       printf("Memory allocation for F1RequestIEs failed");
109       SPutSBuf(DU_APP_MEM_REGION, DU_POOL, (Data *)&(f1apMsg->choice.initiatingMessage),\
110             (Size)sizeof(InitiatingMessage_t));
111       SPutSBuf(DU_APP_MEM_REGION, DU_POOL, (Data *)&f1apMsg,(Size)sizeof(F1AP_PDU_t));
112       RETVALUE(ret);
113    }
114
115    for(idx=0; idx<elementCnt; idx++)
116    {
117       ret = SGetSBuf(DU_APP_MEM_REGION,DU_POOL,\
118             (Data **)&(f1SetupReq->protocolIEs.list.array[idx]),\
119             (Size)sizeof(F1SetupRequestIEs_t));
120       if(ret != ROK)
121       {
122          SPutSBuf(DU_APP_MEM_REGION, DU_POOL, (Data *)&(f1SetupReq->protocolIEs.list.array),\
123                (Size)elementCnt * sizeof(F1SetupRequestIEs_t *));
124          SPutSBuf(DU_APP_MEM_REGION, DU_POOL, (Data *)&(f1apMsg->choice.initiatingMessage),\
125                (Size)sizeof(InitiatingMessage_t));
126          SPutSBuf(DU_APP_MEM_REGION, DU_POOL, (Data *)&f1apMsg,(Size)sizeof(F1AP_PDU_t));
127          RETVALUE(ret);
128       }
129    }
130
131    /*TransactionID*/
132    f1SetupReq->protocolIEs.list.array[0]->id = ProtocolIE_ID_id_TransactionID ;
133    f1SetupReq->protocolIEs.list.array[0]->criticality = Criticality_reject;
134    f1SetupReq->protocolIEs.list.array[0]->value.present = F1SetupRequestIEs__value_PR_TransactionID;
135    f1SetupReq->protocolIEs.list.array[0]->value.choice.TransactionID = TRANS_ID;
136
137   /*DU ID*/
138    f1SetupReq->protocolIEs.list.array[1]->id = ProtocolIE_ID_id_gNB_DU_ID;
139    f1SetupReq->protocolIEs.list.array[1]->criticality = Criticality_reject;
140    f1SetupReq->protocolIEs.list.array[1]->value.present = \
141          F1SetupRequestIEs__value_PR_GNB_DU_ID;
142    f1SetupReq->protocolIEs.list.array[1]->value.choice.GNB_DU_ID.size = sizeof(U8);
143    ret = SGetSBuf(DU_APP_MEM_REGION, DU_POOL,\
144          (Data **)&(f1SetupReq->protocolIEs.list.array[1]->value.choice.GNB_DU_ID.buf),\
145          (Size)sizeof(uint8_t));
146
147    if(ret != ROK)
148    {
149       SPutSBuf(DU_APP_MEM_REGION, DU_POOL, (Data *)&(f1SetupReq->protocolIEs.list.array),\
150             (Size)elementCnt * sizeof(F1SetupRequestIEs_t *));
151       SPutSBuf(DU_APP_MEM_REGION, DU_POOL, (Data *)&(f1apMsg->choice.initiatingMessage),\
152             (Size)sizeof(InitiatingMessage_t));
153       SPutSBuf(DU_APP_MEM_REGION, DU_POOL, (Data *)&f1apMsg,(Size)sizeof(F1AP_PDU_t));
154       RETVALUE(ret);
155    }
156    f1SetupReq->protocolIEs.list.array[1]->value.choice.GNB_DU_ID.buf[0] = duCfgParam.duId;
157
158    /*DU Name*/
159    f1SetupReq->protocolIEs.list.array[2]->id = ProtocolIE_ID_id_gNB_DU_Name ;
160    f1SetupReq->protocolIEs.list.array[2]->criticality = Criticality_ignore;
161    f1SetupReq->protocolIEs.list.array[2]->value.present = \
162          F1SetupRequestIEs__value_PR_GNB_DU_Name;
163    f1SetupReq->protocolIEs.list.array[2]->value.choice.GNB_DU_Name.size = \
164          sizeof(duCfgParam.duName);
165    ret = SGetSBuf(DU_APP_MEM_REGION, DU_POOL,\
166          (Data **)&(f1SetupReq->protocolIEs.list.array[2]->value.choice.GNB_DU_Name.buf),\
167          (Size)sizeof(duCfgParam.duName));
168    if(ret != ROK)
169    {
170       SPutSBuf(DU_APP_MEM_REGION, DU_POOL,(Data *)&(f1SetupReq->protocolIEs.list.array[1]->value.choice.GNB_DU_ID.buf),\
171             (Size)sizeof(uint8_t));
172       SPutSBuf(DU_APP_MEM_REGION, DU_POOL,(Data *)&(f1SetupReq->protocolIEs.list.array),\
173             (Size)elementCnt * sizeof(F1SetupRequestIEs_t *));
174       SPutSBuf(DU_APP_MEM_REGION, DU_POOL,(Data *)&(f1apMsg->choice.initiatingMessage),\
175             (Size)sizeof(InitiatingMessage_t));
176       SPutSBuf(DU_APP_MEM_REGION, DU_POOL,(Data *)&f1apMsg,(Size)sizeof(F1AP_PDU_t));
177       RETVALUE(ret);
178    }
179
180    strcpy((char*)f1SetupReq->protocolIEs.list.array[2]->value.choice.GNB_DU_Name.buf,
181          (char*)&duCfgParam.duName);
182
183    xer_fprint(stdout, &asn_DEF_F1AP_PDU, f1apMsg);
184
185    /* Encode the F1SetupRequest type as UPER */
186    cmMemset((U8 *)encBuf, 0, ENC_BUF_MAX_LEN);
187    encBufSize = 0;
188    encRetVal = aper_encode(&asn_DEF_F1AP_PDU, 0, f1apMsg, PrepFinalEncBuf, encBuf);
189
190    if(encRetVal.encoded == ENCODE_FAIL)
191    {
192       printf( "\nCould not encode F1SetupRequest structure (at %s)\n",\
193             encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
194       RETVALUE(RFAILED);
195    }
196    else
197    {
198       printf("\nCreated APER encoded buffer for F1SetupRequest\n");
199       for(int i=0; i< encBufSize; i++)
200       {
201          printf("%x",encBuf[i]);
202       } 
203    }
204    RETVALUE(ROK);
205 }/* End of BuildF1SetupReq */
206
207 /*******************************************************************
208  *
209  * @brief Builds and sends the F1SetupResponse
210  *
211  * @details
212  *
213  *    Function : ExtractSendF1SetupRsp
214  *
215  *    Functionality: Constructs the F1SetupResponse message and sends
216  *                   it back to the DU through SCTP.
217  *
218  * @params[in] void **buf,Buffer to which encoded pattern is written into
219  * @params[in] int *size,size of buffer
220  *
221  * @return ROK     - success
222  *         RFAILED - failure
223  *
224  * ****************************************************************/
225 S16 BuildF1SetupRsp()
226 {
227    S16   ret;
228    U8    idx;
229    U8    elementCnt;
230    F1AP_PDU_t         *f1apMsg = NULL;
231    F1SetupResponse_t  *f1SetupRsp;
232    GNB_CU_Name_t      *cuName;
233    RRC_Version_t      *rrc_Ver;
234    asn_enc_rval_t     encRetVal; 
235
236    printf("\nBuilding F1 Setup Response\n");
237
238    /* Allocate the memory for F1SetupRequest_t */
239    ret = SGetSBuf(DU_APP_MEM_REGION, DU_POOL, (Data **)&f1apMsg, (Size)sizeof(F1AP_PDU_t)); 
240    if(ret != ROK)
241    {
242       printf("Memory allocation for F1AP-PDU failed");
243       RETVALUE(ret);
244    }
245    f1apMsg->present =  F1AP_PDU_PR_successfulOutcome;
246
247    ret = SGetSBuf(DU_APP_MEM_REGION,DU_POOL,(Data **)&(f1apMsg->choice.successfulOutcome),\
248          (Size)sizeof(SuccessfulOutcome_t));
249    if(ret != ROK)
250    {
251       printf("Memory allocation for F1AP-PDU failed");
252       SPutSBuf(DU_APP_MEM_REGION,DU_POOL,(Data *)&f1apMsg,(Size)sizeof(F1AP_PDU_t));
253       RETVALUE(ret);  
254    }
255
256    f1apMsg->choice.successfulOutcome->procedureCode = ProcedureCode_id_F1Setup;
257    f1apMsg->choice.successfulOutcome->criticality = Criticality_reject;
258    f1apMsg->choice.successfulOutcome->value.present = \
259          SuccessfulOutcome__value_PR_F1SetupResponse;
260    f1SetupRsp = &f1apMsg->choice.successfulOutcome->value.choice.F1SetupResponse;
261
262    elementCnt = 3;
263    f1SetupRsp->protocolIEs.list.count = elementCnt;
264    f1SetupRsp->protocolIEs.list.size = elementCnt*sizeof(F1SetupResponseIEs_t *);
265
266    ret = SGetSBuf(DU_APP_MEM_REGION,DU_POOL,(Data **)&(f1SetupRsp->protocolIEs.list.array),\
267          (Size)elementCnt * sizeof(F1SetupResponseIEs_t *));
268    if(ret != ROK)
269    {
270       printf("Memory allocation for F1ResponseIEs failed");
271       SPutSBuf(DU_APP_MEM_REGION,DU_POOL,(Data *)&(f1apMsg->choice.successfulOutcome),\
272             (Size)sizeof(SuccessfulOutcome_t));
273       SPutSBuf(DU_APP_MEM_REGION,DU_POOL,(Data *)&f1apMsg,(Size)sizeof(F1AP_PDU_t));
274       RETVALUE(ret);
275    }
276
277    for(idx=0; idx<elementCnt; idx++)
278    {
279       ret = SGetSBuf(DU_APP_MEM_REGION,DU_POOL,\
280             (Data **)&(f1SetupRsp->protocolIEs.list.array[idx]),\
281             (Size)sizeof(F1SetupResponseIEs_t)); 
282       if(ret != ROK)
283       {  
284          SPutSBuf(DU_APP_MEM_REGION,DU_POOL,(Data *)&(f1SetupRsp->protocolIEs.list.array),\
285                (Size)elementCnt * sizeof(F1SetupResponseIEs_t *));
286          SPutSBuf(DU_APP_MEM_REGION,DU_POOL,(Data *)&(f1apMsg->choice.successfulOutcome),\
287                (Size)sizeof(SuccessfulOutcome_t));
288          SPutSBuf(DU_APP_MEM_REGION,DU_POOL,(Data *)&f1apMsg,(Size)sizeof(F1AP_PDU_t));
289          RETVALUE(ret);
290       }    
291    }
292
293    /*TransactionID*/
294    f1SetupRsp->protocolIEs.list.array[0]->id = ProtocolIE_ID_id_TransactionID ;
295    f1SetupRsp->protocolIEs.list.array[0]->criticality = Criticality_reject;
296    f1SetupRsp->protocolIEs.list.array[0]->value.present = \
297          F1SetupResponseIEs__value_PR_TransactionID;
298    f1SetupRsp->protocolIEs.list.array[0]->value.choice.TransactionID = TRANS_ID;
299
300    /*CU Name*/
301    f1SetupRsp->protocolIEs.list.array[1]->id = ProtocolIE_ID_id_gNB_CU_Name;
302    f1SetupRsp->protocolIEs.list.array[1]->criticality = Criticality_ignore;
303    f1SetupRsp->protocolIEs.list.array[1]->value.present = \
304          F1SetupResponseIEs__value_PR_GNB_CU_Name;
305    cuName = &f1SetupRsp->protocolIEs.list.array[1]->value.choice.GNB_CU_Name;
306    cuName->size = sizeof(cuCfgParams.cuName);
307
308    ret = SGetSBuf(DU_APP_MEM_REGION,DU_POOL, (Data **)&(cuName->buf),\
309          (Size)sizeof(cuName->size)); 
310    if(ret != ROK)
311       {
312          SPutSBuf(DU_APP_MEM_REGION,DU_POOL,(Data *)&(f1SetupRsp->protocolIEs.list.array),\
313                (Size)elementCnt * sizeof(F1SetupResponseIEs_t *));
314          SPutSBuf(DU_APP_MEM_REGION,DU_POOL,(Data *)&(f1apMsg->choice.successfulOutcome),\
315                (Size)sizeof(SuccessfulOutcome_t));
316          SPutSBuf(DU_APP_MEM_REGION,DU_POOL,(Data *)&f1apMsg,(Size)sizeof(F1AP_PDU_t));
317          RETVALUE(ret);
318       }
319    strcpy((char*)cuName->buf, (char*)cuCfgParams.cuName);
320
321    /* RRC Version */
322    f1SetupRsp->protocolIEs.list.array[2]->id = ProtocolIE_ID_id_GNB_CU_RRC_Version;
323    f1SetupRsp->protocolIEs.list.array[2]->criticality = Criticality_reject;
324    f1SetupRsp->protocolIEs.list.array[2]->value.present = \
325          F1SetupResponseIEs__value_PR_RRC_Version;
326    rrc_Ver = &f1SetupRsp->protocolIEs.list.array[2]->value.choice.RRC_Version;
327    rrc_Ver->latest_RRC_Version.size = RRC_SIZE; 
328
329    ret = SGetSBuf(DU_APP_MEM_REGION,DU_POOL,\
330          (Data **)&(rrc_Ver->latest_RRC_Version.buf), sizeof(U8));
331    if(ret != ROK)
332       {  
333          SPutSBuf(DU_APP_MEM_REGION,DU_POOL,(Data *)&(cuName->buf),(Size)sizeof(cuName->size));
334          SPutSBuf(DU_APP_MEM_REGION,DU_POOL,(Data *)&(f1SetupRsp->protocolIEs.list.array),\
335                (Size)elementCnt * sizeof(F1SetupResponseIEs_t *));
336          SPutSBuf(DU_APP_MEM_REGION,DU_POOL,(Data *)&(f1apMsg->choice.successfulOutcome),\
337                (Size)sizeof(SuccessfulOutcome_t));
338          SPutSBuf(DU_APP_MEM_REGION,DU_POOL,(Data *)&f1apMsg,(Size)sizeof(F1AP_PDU_t));
339          RETVALUE(ret);
340       }
341
342   /* Need to check RRC Version */
343    rrc_Ver->latest_RRC_Version.buf[0] = cuCfgParams.rrcVersion.rrcVer; 
344    rrc_Ver->latest_RRC_Version.bits_unused = 5; //TODO: pick from cuCfgParam. If not present, add it
345
346    xer_fprint(stdout, &asn_DEF_F1AP_PDU, f1apMsg);
347
348    /* Encode the F1SetupRequest type as UPER */
349    cmMemset((U8 *)encBuf, 0, ENC_BUF_MAX_LEN);
350    encBufSize = 0;
351    encRetVal = aper_encode(&asn_DEF_F1AP_PDU, 0, f1apMsg, PrepFinalEncBuf, encBuf);
352
353    if(encRetVal.encoded == ENCODE_FAIL)
354    {
355       printf("Could not encode F1SetupResponse structure (at %s)\n",\
356             encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
357       ret = RFAILED;
358    } 
359    else 
360    {
361       printf("\nCreated APER encoded buffer for F1SetupResponse\n");
362       for(int i=0; i< encBufSize; i++)
363       {
364          printf("%x",encBuf[i]);
365       } 
366    }
367    return ret;
368 }/* End of BuildF1SetupRsp */
369
370 /*******************************************************************
371  *
372  * @brief Builds and sends the DUConfigUpdate
373  *
374  * @details
375  *
376  *    Function : BuildDUConfigUpdate
377  *
378  *    Functionality: Constructs the DU Update message and sends
379  *                   it to the CU through SCTP.
380  *
381  * @params[in] void **buf,Buffer to which encoded pattern is written into
382  * @params[in] int *size,size of buffer
383  *
384  * @return ROK     - success
385  *         RFAILED - failure
386  *
387  * ****************************************************************/
388
389 S16 BuildDUConfigUpdate()
390 {
391    S16   ret;
392    U8    idx;
393    U8    elementCnt;
394    asn_enc_rval_t encRetVal;      /* Encoder return value */
395    F1AP_PDU_t *f1apDuCfg = NULL;
396    GNBDUConfigurationUpdate_t *duCfgUpdate;
397
398    printf("\nBuilding DU config update\n");
399
400    /* Allocate the memory for F1DuCfg */
401    ret = SGetSBuf(DU_APP_MEM_REGION, DU_POOL, (Data **)&f1apDuCfg, (Size)sizeof(F1AP_PDU_t));
402    if(ret != ROK)
403    {
404       printf("Memory allocation for F1AP-PDU failed");
405       RETVALUE(ret);
406    }
407  
408    f1apDuCfg->present = F1AP_PDU_PR_initiatingMessage;
409    ret = SGetSBuf(DU_APP_MEM_REGION, DU_POOL, (Data **)&(f1apDuCfg->choice.initiatingMessage),\
410          (Size)sizeof(InitiatingMessage_t));
411    if(ret != ROK)
412    {
413       printf("Memory allocation for F1AP-PDU failed");
414       SPutSBuf(DU_APP_MEM_REGION, DU_POOL, (Data *)&f1apDuCfg, (Size)sizeof(F1AP_PDU_t));
415       RETVALUE(ret);
416    }
417    
418    f1apDuCfg->choice.initiatingMessage->procedureCode = ProcedureCode_id_gNBDUConfigurationUpdate;
419    f1apDuCfg->choice.initiatingMessage->criticality = Criticality_reject;
420    f1apDuCfg->choice.initiatingMessage->value.present = InitiatingMessage__value_PR_GNBDUConfigurationUpdate;
421    duCfgUpdate = &f1apDuCfg->choice.initiatingMessage->value.choice.GNBDUConfigurationUpdate;
422
423    elementCnt = 1;
424    duCfgUpdate->protocolIEs.list.count = elementCnt;
425    duCfgUpdate->protocolIEs.list.size = elementCnt * sizeof(GNBDUConfigurationUpdateIEs_t *);
426
427    /* Initialize the F1Setup members */
428    ret = SGetSBuf(DU_APP_MEM_REGION, DU_POOL, (Data **)&(duCfgUpdate->protocolIEs.list.array),\
429          (Size)elementCnt*sizeof(GNBDUConfigurationUpdateIEs_t *));
430    if(ret != ROK)
431    {
432       printf("Memory allocation for F1RequestIEs failed");
433       SPutSBuf(DU_APP_MEM_REGION, DU_POOL, (Data *)&(f1apDuCfg->choice.initiatingMessage),\
434               (Size)sizeof(InitiatingMessage_t));
435       SPutSBuf(DU_APP_MEM_REGION, DU_POOL, (Data *)&f1apDuCfg, (Size)sizeof(F1AP_PDU_t));
436       RETVALUE(ret);
437    }
438
439    for(idx=0;idx<elementCnt;idx++)
440    {
441       ret = SGetSBuf(DU_APP_MEM_REGION, DU_POOL,\
442         (Data **)&(duCfgUpdate->protocolIEs.list.array[idx]),\
443         (Size)sizeof(GNBDUConfigurationUpdateIEs_t));
444       if(ret != ROK)
445       {
446          SPutSBuf(DU_APP_MEM_REGION, DU_POOL, (Data *)&(duCfgUpdate->protocolIEs.list.array),\
447             (Size)elementCnt * sizeof(GNBDUConfigurationUpdateIEs_t *));
448          SPutSBuf(DU_APP_MEM_REGION, DU_POOL, (Data *)&(f1apDuCfg->choice.initiatingMessage), (Size)sizeof(InitiatingMessage_t));
449          SPutSBuf(DU_APP_MEM_REGION,DU_POOL,(Data *)&f1apDuCfg,(Size)sizeof(F1AP_PDU_t));
450          RETVALUE(ret);
451       }
452    }
453
454    /*TransactionID*/
455    duCfgUpdate->protocolIEs.list.array[0]->id = ProtocolIE_ID_id_TransactionID ;
456    duCfgUpdate->protocolIEs.list.array[0]->criticality = Criticality_reject;
457    duCfgUpdate->protocolIEs.list.array[0]->value.present = GNBDUConfigurationUpdateIEs__value_PR_TransactionID;
458    duCfgUpdate->protocolIEs.list.array[0]->value.choice.TransactionID = TRANS_ID;
459
460    xer_fprint(stdout, &asn_DEF_F1AP_PDU, f1apDuCfg);
461    
462    /* Encode the DU Config Update type as APER */
463    cmMemset((U8 *)encBuf, 0, ENC_BUF_MAX_LEN);
464    encBufSize = 0;
465    encRetVal = aper_encode(&asn_DEF_F1AP_PDU, 0, f1apDuCfg, PrepFinalEncBuf, encBuf);
466    if(encRetVal.encoded == ENCODE_FAIL) 
467    {
468       printf("Could not encode DUConfigUpdate structure (at %s)\n",encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
469       RETVALUE(RFAILED);
470    } 
471    else 
472    {
473       printf("\nCreated APER encoded buffer for DUConfigUpdate\n");
474       for(int i=0; i< encBufSize; i++)
475       {
476          printf("%x",encBuf[i]);
477       }
478    }
479    RETVALUE(ROK);
480 }/* End of BuildDUConfigUpdate */
481
482 /*******************************************************************
483  *
484  * @brief Builds and sends the DUUpdateAcknowledge
485  *
486  * @details
487  *
488  *    Function : BuildDUUpdateAck
489  *
490  *    Functionality: Constructs the DU Update Acknowledge message and sends
491  *                   it to the DU through SCTP.
492  *
493  * @params[in] void **buf,Buffer to which encoded pattern is written into
494  * @params[in] int *size,size of buffer
495  *
496  * @return ROK     - success
497  *         RFAILED - failure
498  *
499  * ****************************************************************/
500
501 S16 BuildDUUpdateAck()
502 {
503    S16  ret;
504    U8   idx;
505    U8   elementCnt;
506    F1AP_PDU_t *f1apMsg = NULL;
507    GNBDUConfigurationUpdateAcknowledge_t *gNBDuCfgAck;
508    asn_enc_rval_t enRetVal; /* Encoder return value */
509
510    printf("\nBuilding GNB-DU Config Update Ack\n");
511
512    /* Allocate the memory for F1SetupRequest_t */
513    ret = SGetSBuf(DU_APP_MEM_REGION, DU_POOL, (Data **)&f1apMsg, (Size)sizeof(F1AP_PDU_t));
514    if(ret != ROK)
515    {
516       printf("Memory allocation for F1AP-PDU failed");
517       RETVALUE(ret);
518    }
519
520    f1apMsg->present =  F1AP_PDU_PR_successfulOutcome;
521
522    ret = SGetSBuf(DU_APP_MEM_REGION,DU_POOL,(Data **)&(f1apMsg->choice.successfulOutcome),\
523          (Size)sizeof(SuccessfulOutcome_t));
524    if(ret != ROK)
525    {
526       printf("Memory allocation for F1AP-PDU failed");
527       SPutSBuf(DU_APP_MEM_REGION,DU_POOL,(Data *)&f1apMsg,(Size)sizeof(F1AP_PDU_t));
528       RETVALUE(ret);
529    }
530
531    f1apMsg->choice.successfulOutcome->procedureCode = ProcedureCode_id_gNBDUConfigurationUpdate;
532    f1apMsg->choice.successfulOutcome->criticality = Criticality_reject;
533    f1apMsg->choice.successfulOutcome->value.present = SuccessfulOutcome__value_PR_GNBDUConfigurationUpdateAcknowledge;
534    gNBDuCfgAck = &f1apMsg->choice.successfulOutcome->value.choice.GNBDUConfigurationUpdateAcknowledge;
535
536    elementCnt = 1;
537    gNBDuCfgAck->protocolIEs.list.count = elementCnt;
538    gNBDuCfgAck->protocolIEs.list.size = elementCnt*sizeof(GNBDUConfigurationUpdateAcknowledgeIEs_t);
539
540    /* Initialize the F1Setup members */
541    ret = SGetSBuf(DU_APP_MEM_REGION,DU_POOL,(Data **)&(gNBDuCfgAck->protocolIEs.list.array),\
542          (Size)elementCnt * sizeof(GNBDUConfigurationUpdateAcknowledgeIEs_t *));
543    if(ret != ROK)
544    {
545       printf("Memory allocation for DuUpdateAcknowledgeIEs failed");
546       SPutSBuf(DU_APP_MEM_REGION,DU_POOL,(Data *)&(f1apMsg->choice.successfulOutcome),\
547             (Size)sizeof(SuccessfulOutcome_t));
548       SPutSBuf(DU_APP_MEM_REGION,DU_POOL,(Data *)&f1apMsg,(Size)sizeof(F1AP_PDU_t));
549       RETVALUE(ret);
550    }
551
552     for(idx=0; idx<elementCnt; idx++)
553    {
554       ret = SGetSBuf(DU_APP_MEM_REGION,DU_POOL,\
555             (Data **)&(gNBDuCfgAck->protocolIEs.list.array[idx]),\
556             (Size)sizeof(GNBDUConfigurationUpdateAcknowledgeIEs_t));
557       if(ret != ROK)
558       {
559          SPutSBuf(DU_APP_MEM_REGION,DU_POOL,(Data *)&(gNBDuCfgAck->protocolIEs.list.array),\
560                (Size)elementCnt * sizeof(GNBDUConfigurationUpdateAcknowledgeIEs_t *));
561          SPutSBuf(DU_APP_MEM_REGION,DU_POOL,(Data *)&(f1apMsg->choice.successfulOutcome),\
562             (Size)sizeof(SuccessfulOutcome_t));
563
564          SPutSBuf(DU_APP_MEM_REGION,DU_POOL,(Data *)&f1apMsg,(Size)sizeof(F1AP_PDU_t));
565          RETVALUE(ret);
566       }
567    }
568
569    /*TransactionID*/ 
570    gNBDuCfgAck->protocolIEs.list.array[0]->id = ProtocolIE_ID_id_TransactionID ;
571    gNBDuCfgAck->protocolIEs.list.array[0]->criticality = Criticality_reject;
572    gNBDuCfgAck->protocolIEs.list.array[0]->value.present = GNBDUConfigurationUpdateAcknowledgeIEs__value_PR_TransactionID;
573    gNBDuCfgAck->protocolIEs.list.array[0]->value.choice.TransactionID = TRANS_ID;
574
575    xer_fprint(stdout, &asn_DEF_F1AP_PDU, f1apMsg);
576  
577    /* Encode the F1SetupRequest type as UPER */
578    cmMemset((U8 *)encBuf, 0, ENC_BUF_MAX_LEN);
579    encBufSize = 0;
580    enRetVal = aper_encode(&asn_DEF_F1AP_PDU, 0, f1apMsg, PrepFinalEncBuf, encBuf);
581    if(enRetVal.encoded == ENCODE_FAIL) 
582    {
583       printf("\nCould not encode DUConfigUpdateAcknowledge structure (at %s)",enRetVal.failed_type ? enRetVal.failed_type->name : "unknown");
584       RETVALUE(RFAILED); 
585    } 
586    else 
587    {
588       printf("\nCreated APER encoded buffer for DuConfigUpdateAcknowledge\n");
589       for(int i=0; i< encBufSize; i++)
590       {
591          printf("%x",encBuf[i]);
592       } 
593    }
594    RETVALUE(ROK);
595
596 }/* End of BuildDUUpdateAck*/
597
598 /*******************************************************************
599 *
600 * @brief Handles received F1AP message and sends back response  
601 *
602 * @details
603 *
604 *    Function : F1InmsgHdlr
605 *
606 *    Functionality:
607 *         - Decodes received F1AP control message
608 *         - Prepares response message, encodes and sends to SCTP
609 *
610 * @params[in] 
611 * @return ROK     - success
612 *         RFAILED - failure
613 *
614 * ****************************************************************/
615 void F1InmsgHdlr(Buffer *mBuf)
616 {
617    int i,j;
618    char *recvBuf;
619    char *finalBuf;
620    MsgLen copyCnt;
621    MsgLen recvBufLen;
622    F1AP_PDU_t *f1apmsg;
623    asn_dec_rval_t rval; /* Decoder return value */
624    F1AP_PDU_t f1apasnmsg ;
625    Buffer *respBuf;
626  
627    printf("\nReceived F1AP message buffer");
628    SPrntMsg(mBuf, 0,0);
629  
630    /* Copy mBuf into char array to decode it */
631    SFndLenMsg(mBuf, &recvBufLen);
632    if(SGetSBuf(1, 1, (Data **)&recvBuf, (Size)recvBufLen) != ROK)
633    {
634       printf("Memory allocation failed");
635       return;
636    }
637    if(SCpyMsgFix(mBuf, 0, recvBufLen, (Data *)recvBuf, &copyCnt) != ROK)
638    {
639       printf("\nFailed while copying %d", copyCnt);
640       return;
641    }
642
643    printf("\nReceived flat buffer to be decoded : ");
644    for(i=0; i< recvBufLen; i++)
645    {
646         printf("%x",recvBuf[i]);
647    }
648
649    /* Decoding flat buffer into F1AP messsage */
650    f1apmsg = &f1apasnmsg;
651    memset(f1apmsg, 0, sizeof(F1AP_PDU_t));
652  
653    rval = aper_decode(0, &asn_DEF_F1AP_PDU, (void **)&f1apmsg, recvBuf, recvBufLen, 0, 0);
654    SPutSBuf(1, 1, (Data *)recvBuf, (Size)recvBufLen);
655    if(rval.code == RC_FAIL || rval.code == RC_WMORE)
656    {
657       printf("\nASN decode failed");
658       return;
659    }
660    printf("\n");
661    xer_fprint(stdout, &asn_DEF_F1AP_PDU, f1apmsg);
662
663    switch(f1apmsg->present)
664    {
665       case F1AP_PDU_PR_initiatingMessage:
666       {
667          switch(f1apmsg->choice.initiatingMessage->value.present)
668          {
669             case InitiatingMessage__value_PR_F1SetupRequest:
670             {
671                printf("\nF1 setup request received");
672
673                BuildF1SetupRsp();
674                
675                /* Reversing the encoded string */
676                if(SGetSBuf(1, 1, (Data **)&finalBuf, (Size)encBufSize) != ROK)
677                {
678                   printf("Memory allocation failed");
679                   return;
680                }
681                for(i = 0, j = encBufSize-1; i<encBufSize; i++, j--)
682                {
683                   finalBuf[j] = encBuf[i];
684                }
685
686                if(SGetMsg(1, 1, &respBuf) == ROK)
687                {
688                   if(SCpyFixMsg((Data *)finalBuf, respBuf, 0, encBufSize, &copyCnt) == ROK)
689                   {
690                      printf("\nSending F1 setup response");
691                      SPrntMsg(respBuf, 0,0);
692                      if(sctpOutMsgSend(respBuf) != ROK)
693                      {
694                         printf("\nFailed Sending");
695                      }
696                      SPutMsg(respBuf);
697                   }
698                }
699                else
700                {
701                   printf("\nFailed to allocate memory");
702                   return;
703                }
704                break;
705             }
706
707             case InitiatingMessage__value_PR_GNBDUConfigurationUpdate:
708             {
709                printf("\nGNB-DU config update received");
710                BuildDUUpdateAck();
711                /* Reversing the encoded string */
712                if(SGetSBuf(1, 1, (Data **)&finalBuf, (Size)encBufSize) != ROK)
713                {
714                   printf("Memory allocation failed");
715                   return;
716                }
717                for(i = 0, j = encBufSize-1; i<encBufSize; i++, j--)
718                {
719                   finalBuf[j] = encBuf[i];
720                }
721
722                if(SGetMsg(1, 1, &respBuf) == ROK)
723                {
724                   if(SCpyFixMsg((Data *)finalBuf, respBuf, 0, encBufSize, &copyCnt) == ROK)
725                   {
726                      printf("\nSending GNB-DU Config Update Acknowledgement");
727                      SPrntMsg(respBuf, 0,0);
728                      if(sctpOutMsgSend(respBuf) != ROK)
729                      {
730                         printf("\nFailed Sending");
731                      }
732                      SPutMsg(respBuf);
733                   }
734                }
735                else
736                {
737                   printf("\nFailed to allocate memory");
738                   return;
739                }  
740                break;
741             }
742
743             default:
744             {
745                printf("\nInvalid type of intiating message [%d]",f1apmsg->choice.initiatingMessage->value.present);
746                return;
747             }
748          }/* End of switch(initiatingMessage) */
749          break;
750       }
751
752       case F1AP_PDU_PR_successfulOutcome:
753       {
754          switch(f1apmsg->choice.successfulOutcome->value.present)
755          {
756             case SuccessfulOutcome__value_PR_F1SetupResponse:
757             {
758                F1SetupResponse_t *f1SetRspMsg;
759                F1SetupRsp    f1SetRspDb;
760                GNB_CU_Name_t *cuName;
761                RRC_Version_t *rrc_Ver;
762
763                printf("\nF1 Setup Response");
764                
765                /* Store the received info in local database */
766                f1SetRspMsg = &f1apmsg->choice.successfulOutcome->value.choice.F1SetupResponse;
767                cuName = &f1SetRspMsg->protocolIEs.list.array[1]->value.choice.GNB_CU_Name;
768                rrc_Ver = &f1SetRspMsg->protocolIEs.list.array[2]->value.choice.RRC_Version;
769
770                f1SetRspDb.transId = f1SetRspMsg->protocolIEs.list.array[0]->value.choice.TransactionID;
771                strcpy(f1SetRspDb.cuName, cuName->buf);
772                //strcpy(f1SetRspDb.rrcVersion.rrcVer, rrc_Ver->latest_RRC_Version.buf[0]);
773
774                /* TODO :Check the deallocation */
775 #if 0
776                SPutSBuf(DU_APP_MEM_REGION, DU_POOL,(Data *)&(f1SetupRsp->protocolIEs.list.array),\
777                   (Size)elementCnt * sizeof(F1SetupResponseIEs_t *));
778                SPutSBuf(DU_APP_MEM_REGION, DU_POOL,(Data *)&(f1apMsg->choice.successfulOutcome),\
779                   (Size)sizeof(SuccessfulOutcome_t));
780                SPutSBuf(DU_APP_MEM_REGION, DU_POOL,(Data *)&f1apMsg,(Size)sizeof(F1AP_PDU_t));
781 #endif
782
783                /* Build and send GNB-DU config update */
784                BuildDUConfigUpdate();
785                
786                /* Reversing the encoded string */
787                if(SGetSBuf(1, 1, (Data **)&finalBuf, (Size)encBufSize) != ROK)
788                {
789                   printf("Memory allocation failed");
790                   return;
791                }
792                for(i = 0, j = encBufSize-1; i<encBufSize; i++, j--)
793                {
794                   finalBuf[j] = encBuf[i];
795                }
796
797                if(SGetMsg(1, 1, &respBuf) == ROK)
798                {
799                   if(SCpyFixMsg((Data *)finalBuf, respBuf, 0, encBufSize, &copyCnt) == ROK)
800                   {
801                      printf("\nSending GNB-DU Config Update");
802                      SPrntMsg(respBuf, 0,0);
803                      if(sctpOutMsgSend(respBuf) != ROK)
804                      {
805                         printf("\nFailed Sending");
806                      }
807                      SPutMsg(respBuf);
808                   }
809                }
810                else
811                {  
812                   printf("\nFailed to allocate memory");
813                   return;
814                }
815
816                break;
817             }
818             
819             case SuccessfulOutcome__value_PR_GNBDUConfigurationUpdateAcknowledge:
820             {
821                F1GnbDuCfgUpdAck duCfgUpdAckDb;
822                GNBDUConfigurationUpdateAcknowledge_t *gnbDuCfgUpdAckMsg;
823
824                printf("\nGNB-DU config update acknowledgment received");
825
826                /* Store the received info in local database */ 
827                gnbDuCfgUpdAckMsg = &f1apmsg->choice.successfulOutcome->value.choice.GNBDUConfigurationUpdateAcknowledge;
828                duCfgUpdAckDb.transId = gnbDuCfgUpdAckMsg->protocolIEs.list.array[0]->value.choice.TransactionID;
829               
830                /* TODO :Check the deallocation */
831 #if 0
832                SPutSBuf(DU_APP_MEM_REGION,DU_POOL,(Data *)&(gNBDuCfgAck->protocolIEs.list.array),\
833                   (Size)elementCnt * sizeof(GNBDUConfigurationUpdateAcknowledgeIEs_t *));
834                SPutSBuf(DU_APP_MEM_REGION,DU_POOL,(Data *)&(f1apMsg->choice.successfulOutcome),\
835                   (Size)sizeof(SuccessfulOutcome_t));
836                SPutSBuf(DU_APP_MEM_REGION,DU_POOL,(Data *)&f1apMsg,(Size)sizeof(F1AP_PDU_t));
837 #endif     
838                break;
839             }
840
841             default:
842             {
843                printf("\nInvalid type of successful outcome [%d]", f1apmsg->choice.successfulOutcome->value.present);
844                return;
845             }
846          }/* End of switch(successfulOutcome) */
847          break;
848       }
849       
850       default:
851       {
852          printf("\nInvalie type of f1apMsg->present [%d]",f1apmsg->present);
853          return;
854       }
855
856    }/* End of switch(f1apmsg->present) */
857  
858 } /* End of F1InmsgHdlr */
859  
860
861 /**********************************************************************
862          End of file
863  **********************************************************************/