1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
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 #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
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 *******************************************************************************/
19 /* This file contains F1AP message handler functions */
21 #include "cu_stub_sctp.h"
22 #include "cu_f1ap_msg_hdl.h"
24 char encBuf[ENC_BUF_MAX_LEN];
26 /*******************************************************************
28 * @brief Writes the encoded chunks into a buffer
32 * Function : PrepFinalEncBuf
34 * Functionality:Fills the encoded buffer
36 * @params[in] void *buffer,initial encoded data
37 * @params[in] size_t size,size of buffer
38 * @params[in] void *encodedBuf,final buffer
39 * @return ROK - success
42 * ****************************************************************/
43 static int PrepFinalEncBuf(const void *buffer, size_t size, void *encodedBuf)
45 memcpy(encodedBuf + encBufSize, buffer, size);
48 } /* PrepFinalEncBuf */
50 /*******************************************************************
52 * @brief Sends F1 msg over SCTP
56 * Function : SendF1APMsg
58 * Functionality: Sends F1 msg over SCTP
60 * @params[in] Region region
62 * @return ROK - success
65 * ****************************************************************/
66 S16 SendF1APMsg(Region region, Pool pool)
70 if(SGetMsg(region, pool, &mBuf) == ROK)
72 if(SAddPstMsgMult((Data *)encBuf, encBufSize, mBuf) == ROK)
76 if(sctpSend(mBuf) != ROK)
78 DU_LOG("\nF1AP : SCTP Send failed");
85 DU_LOG("\nF1AP : SAddPstMsgMult failed");
93 DU_LOG("\nF1AP : Failed to allocate memory");
101 void plmnBuildCU(Plmn plmn, OCTET_STRING_t *octe)
105 octe->buf[0] = ((plmn.mcc[1] << 4) | (plmn.mcc[0]));
108 octe->buf[1] = ((0xf0) | (plmn.mcc[2]));
109 octe->buf[2] = ((plmn.mnc[1] << 4) | (plmn.mnc[0]));
113 octe->buf[1] = ((plmn.mnc[0] << 4) | (plmn.mcc[2]));
114 octe->buf[2] = ((plmn.mnc[2] << 4) | (plmn.mnc[1]));
118 /*******************************************************************
120 * @brief Builds NRCell ID
124 * Function : BuildNrCellId
126 * Functionality: Building the NR Cell ID
128 * @params[in] BIT_STRING_t *nrcell
129 * @return ROK - success
132 * ****************************************************************/
134 S16 BuildNrCellId(BIT_STRING_t *nrcell)
137 for (tmp = 0 ; tmp < nrcell->size-1; tmp++)
139 nrcell->buf[tmp] = 0;
142 nrcell->bits_unused = 4;
143 nrcell->size = 5 * sizeof(uint8_t);
147 /********************************************************************
149 * @brief Builds and sends the F1SetupResponse
153 * Function : BuildAndSendF1SetupRsp
155 * Functionality: Constructs the F1SetupResponse message and sends
156 * it back to the DU through SCTP.
158 * @params[in] void **buf,Buffer to which encoded pattern is written into
159 * @params[in] int *size,size of buffer
161 * @return ROK - success
164 * ****************************************************************/
165 S16 BuildAndSendF1SetupRsp()
168 U8 elementCnt,cellCnt;
169 F1AP_PDU_t *f1apMsg = NULL;
170 F1SetupResponse_t *f1SetupRsp;
171 GNB_CU_Name_t *cuName;
172 Cells_to_be_Activated_List_t *cellToActivate;
173 RRC_Version_t *rrcVer;
174 asn_enc_rval_t encRetVal;
175 DU_LOG("\nF1AP : Building F1 Setup Response\n");
177 /* Allocate the memory for F1SetupRequest_t */
178 CU_ALLOC(f1apMsg, sizeof(F1AP_PDU_t));
181 DU_LOG("\nF1AP : Memory allocation for F1AP-PDU failed");
184 f1apMsg->present = F1AP_PDU_PR_successfulOutcome;
186 CU_ALLOC(f1apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcome_t));
187 if(f1apMsg->choice.successfulOutcome == NULLP)
189 DU_LOG("\nF1AP : Memory allocation for F1AP-PDU failed");
190 CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
194 f1apMsg->choice.successfulOutcome->procedureCode = ProcedureCode_id_F1Setup;
195 f1apMsg->choice.successfulOutcome->criticality = Criticality_reject;
196 f1apMsg->choice.successfulOutcome->value.present = \
197 SuccessfulOutcome__value_PR_F1SetupResponse;
198 f1SetupRsp = &f1apMsg->choice.successfulOutcome->value.choice.F1SetupResponse;
201 f1SetupRsp->protocolIEs.list.count = elementCnt;
202 f1SetupRsp->protocolIEs.list.size = elementCnt*sizeof(F1SetupResponseIEs_t *);
204 CU_ALLOC(f1SetupRsp->protocolIEs.list.array, \
205 elementCnt * sizeof(F1SetupResponseIEs_t *));
206 if(f1SetupRsp->protocolIEs.list.array == NULLP)
208 DU_LOG("\nF1AP : Memory allocation for F1ResponseIEs failed");
209 CU_FREE(f1apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcome_t));
210 CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
214 for(idx=0; idx<elementCnt; idx++)
216 CU_ALLOC(f1SetupRsp->protocolIEs.list.array[idx], \
217 sizeof(F1SetupResponseIEs_t));
218 if(f1SetupRsp->protocolIEs.list.array[idx] == NULLP)
220 CU_FREE(f1SetupRsp->protocolIEs.list.array,\
221 elementCnt * sizeof(F1SetupResponseIEs_t *));
222 CU_FREE(f1apMsg->choice.successfulOutcome, \
223 sizeof(SuccessfulOutcome_t));
224 CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
231 f1SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_ID_id_TransactionID;
232 f1SetupRsp->protocolIEs.list.array[idx]->criticality = Criticality_reject;
233 f1SetupRsp->protocolIEs.list.array[idx]->value.present = \
234 F1SetupResponseIEs__value_PR_TransactionID;
235 f1SetupRsp->protocolIEs.list.array[idx]->value.choice.TransactionID =\
240 f1SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_ID_id_gNB_CU_Name;
241 f1SetupRsp->protocolIEs.list.array[idx]->criticality = Criticality_ignore;
242 f1SetupRsp->protocolIEs.list.array[idx]->value.present = \
243 F1SetupResponseIEs__value_PR_GNB_CU_Name;
244 cuName = &f1SetupRsp->protocolIEs.list.array[idx]->value.choice.GNB_CU_Name;
245 cuName->size = sizeof(cuCfgParams.cuName);
247 CU_ALLOC(cuName->buf, sizeof(cuName->size));
248 if(cuName->buf == NULLP)
250 for(idy=0; idy<elementCnt; idy++)
252 CU_FREE(f1SetupRsp->protocolIEs.list.array[idy],\
253 sizeof(F1SetupResponseIEs_t));
255 CU_FREE(f1SetupRsp->protocolIEs.list.array,\
256 elementCnt * sizeof(F1SetupResponseIEs_t *));
257 CU_FREE(f1apMsg->choice.successfulOutcome,\
258 sizeof(SuccessfulOutcome_t));
259 CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
262 strcpy((char*)cuName->buf, (char*)cuCfgParams.cuName);
264 /*Cells to be activated list*/
266 f1SetupRsp->protocolIEs.list.array[idx]->id = \
267 ProtocolIE_ID_id_Cells_to_be_Activated_List ;
268 f1SetupRsp->protocolIEs.list.array[idx]->criticality = Criticality_reject;
269 f1SetupRsp->protocolIEs.list.array[idx]->value.present = \
270 F1SetupResponseIEs__value_PR_Cells_to_be_Activated_List;
271 cellToActivate = &f1SetupRsp->protocolIEs.list.array[idx]->value.choice.\
272 Cells_to_be_Activated_List;
274 cellToActivate->list.count = cellCnt;
275 cellToActivate->list.size = \
276 cellCnt*sizeof(struct Cells_to_be_Activated_List_ItemIEs *);
277 CU_ALLOC(cellToActivate->list.array,\
278 sizeof(struct Cells_to_be_Activated_List_ItemIEs *));
279 if(cellToActivate->list.array == NULLP)
281 CU_FREE(cuName->buf, sizeof(cuName->size));
282 for(idy=0; idy<elementCnt; idy++)
284 CU_FREE(f1SetupRsp->protocolIEs.list.array[idy],\
285 sizeof(F1SetupResponseIEs_t));
287 CU_FREE(f1SetupRsp->protocolIEs.list.array,\
288 elementCnt * sizeof(F1SetupResponseIEs_t *));
289 CU_FREE(f1apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcome_t));
290 CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
293 for(idy=0; idy<cellCnt; idy++)
295 CU_ALLOC(cellToActivate->list.array[idy],\
296 sizeof(struct Cells_to_be_Activated_List_ItemIEs ));
297 if(cellToActivate->list.array[idy] == NULLP)
299 CU_FREE(cellToActivate->list.array,\
300 sizeof(struct Cells_to_be_Activated_List_ItemIEs *));
301 CU_FREE(cuName->buf, sizeof(cuName->size));
302 for(idy=0; idy<elementCnt; idy++)
304 CU_FREE(f1SetupRsp->protocolIEs.list.array[idy], \
305 sizeof(F1SetupResponseIEs_t));
307 CU_FREE(f1SetupRsp->protocolIEs.list.array, \
308 elementCnt * sizeof(F1SetupResponseIEs_t *));
309 CU_FREE(f1apMsg->choice.successfulOutcome, \
310 sizeof(SuccessfulOutcome_t));
311 CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
315 cellToActivate->list.array[0]->id = \
316 ProtocolIE_ID_id_Cells_to_be_Activated_List_Item;
317 cellToActivate->list.array[0]->criticality = Criticality_ignore;
318 cellToActivate->list.array[0]->value.present = \
319 Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item;
320 cellToActivate->list.array[0]->value.choice.Cells_to_be_Activated_List_Item.\
321 nRCGI.pLMN_Identity.size = 3*sizeof(uint8_t);
322 CU_ALLOC(cellToActivate->list.array[0]->\
323 value.choice.Cells_to_be_Activated_List_Item.nRCGI.pLMN_Identity.buf,\
325 if(cellToActivate->list.array[0]->value.choice.\
326 Cells_to_be_Activated_List_Item.nRCGI.pLMN_Identity.buf == NULLP)
329 for(idy=0; idy<cellCnt; idy++)
331 CU_FREE(cellToActivate->list.array[idy],\
332 sizeof(struct Cells_to_be_Activated_List_ItemIEs ));
335 CU_FREE(cellToActivate->list.array,\
336 sizeof(struct Cells_to_be_Activated_List_ItemIEs *));
337 CU_FREE(cuName->buf, sizeof(cuName->size));
338 for(idy=0; idy<elementCnt; idy++)
340 CU_FREE(f1SetupRsp->protocolIEs.list.array[idy], \
341 sizeof(F1SetupResponseIEs_t));
343 CU_FREE(f1SetupRsp->protocolIEs.list.array, \
344 elementCnt * sizeof(F1SetupResponseIEs_t *));
345 CU_FREE(f1apMsg->choice.successfulOutcome, \
346 sizeof(SuccessfulOutcome_t));
347 CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
350 plmnBuildCU(cuCfgParams.plmn , &cellToActivate->list.array[0]->value.choice.\
351 Cells_to_be_Activated_List_Item.nRCGI.pLMN_Identity);
352 cellToActivate->list.array[0]->value.choice.Cells_to_be_Activated_List_Item.\
353 nRCGI.nRCellIdentity.size = 5;
354 CU_ALLOC(cellToActivate->list.array[0]->value.choice.\
355 Cells_to_be_Activated_List_Item.nRCGI.nRCellIdentity.buf,\
357 if(cellToActivate->list.array[0]->value.choice.\
358 Cells_to_be_Activated_List_Item.nRCGI.nRCellIdentity.buf == NULLP)
360 CU_FREE(cellToActivate->list.array[0]->\
361 value.choice.Cells_to_be_Activated_List_Item.nRCGI.pLMN_Identity.buf,\
363 for(idy=0; idy<cellCnt; idy++)
365 CU_FREE(cellToActivate->list.array[idy],\
366 sizeof(struct Cells_to_be_Activated_List_ItemIEs ));
369 CU_FREE(cellToActivate->list.array,\
370 sizeof(struct Cells_to_be_Activated_List_ItemIEs *));
371 CU_FREE(cuName->buf, sizeof(cuName->size));
372 for(idy=0; idy<elementCnt; idy++)
374 CU_FREE(f1SetupRsp->protocolIEs.list.array[idy], \
375 sizeof(F1SetupResponseIEs_t));
377 CU_FREE(f1SetupRsp->protocolIEs.list.array, \
378 elementCnt * sizeof(F1SetupResponseIEs_t *));
379 CU_FREE(f1apMsg->choice.successfulOutcome, \
380 sizeof(SuccessfulOutcome_t));
381 CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
384 BuildNrCellId(&(cellToActivate->list.array[0]->value.choice.Cells_to_be_Activated_List_Item.nRCGI.nRCellIdentity));
387 f1SetupRsp->protocolIEs.list.array[idx]->id = \
388 ProtocolIE_ID_id_GNB_CU_RRC_Version;
389 f1SetupRsp->protocolIEs.list.array[idx]->criticality = Criticality_reject;
390 f1SetupRsp->protocolIEs.list.array[idx]->value.present = \
391 F1SetupResponseIEs__value_PR_RRC_Version;
392 rrcVer = &f1SetupRsp->protocolIEs.list.array[idx]->value.choice.RRC_Version;
393 rrcVer->latest_RRC_Version.size = RRC_SIZE;
395 CU_ALLOC(rrcVer->latest_RRC_Version.buf, sizeof(U8));
396 if(rrcVer->latest_RRC_Version.buf == NULLP)
398 CU_FREE(cuName->buf, sizeof(cuName->size));
399 for(idy=0; idy<elementCnt; idx++)
401 CU_FREE(f1SetupRsp->protocolIEs.list.array[idy], \
402 sizeof(F1SetupResponseIEs_t));
404 CU_FREE(f1SetupRsp->protocolIEs.list.array,\
405 elementCnt * sizeof(F1SetupResponseIEs_t *));
406 CU_FREE(f1apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcome_t));
407 CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
411 /* Need to check RRC Version */
412 rrcVer->latest_RRC_Version.buf[0] = cuCfgParams.rrcVersion.rrcVer;
413 rrcVer->latest_RRC_Version.bits_unused = 5; //TODO: pick from cuCfgParam. If not present, add it
414 CU_ALLOC(rrcVer->iE_Extensions,sizeof(ProtocolExtensionContainer_4624P81_t));
415 if(rrcVer->iE_Extensions == NULLP)
417 CU_FREE(rrcVer->latest_RRC_Version.buf, sizeof(U8));
418 CU_FREE(cuName->buf, sizeof(cuName->size));
419 for(idy=0; idy<elementCnt; idy++)
421 CU_FREE(f1SetupRsp->protocolIEs.list.array[idy], \
422 sizeof(F1SetupResponseIEs_t));
424 CU_FREE(f1SetupRsp->protocolIEs.list.array,\
425 elementCnt * sizeof(F1SetupResponseIEs_t *));
426 CU_FREE(f1apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcome_t));
427 CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
430 rrcVer->iE_Extensions->list.count = 1;
431 rrcVer->iE_Extensions->list.size = sizeof(struct RRC_Version_ExtIEs *);
432 CU_ALLOC(rrcVer->iE_Extensions->list.array,\
433 sizeof(struct RRC_Version_ExtIEs *));
434 if(rrcVer->iE_Extensions->list.array == NULLP)
436 CU_FREE(rrcVer->iE_Extensions,\
437 sizeof(ProtocolExtensionContainer_4624P81_t));
438 CU_FREE(rrcVer->latest_RRC_Version.buf, sizeof(U8));
439 CU_FREE(cuName->buf, sizeof(cuName->size));
440 for(idy=0; idy<elementCnt; idy++)
442 CU_FREE(f1SetupRsp->protocolIEs.list.array[idy], \
443 sizeof(F1SetupResponseIEs_t));
445 CU_FREE(f1SetupRsp->protocolIEs.list.array,\
446 elementCnt * sizeof(F1SetupResponseIEs_t *));
447 CU_FREE(f1apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcome_t));
448 CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
451 CU_ALLOC(rrcVer->iE_Extensions->list.array[0],\
452 sizeof(struct RRC_Version_ExtIEs));
453 if(rrcVer->iE_Extensions->list.array[0] == NULLP)
455 CU_FREE(rrcVer->iE_Extensions->list.array,\
456 sizeof(struct RRC_Version_ExtIEs *));
457 CU_FREE(rrcVer->iE_Extensions,\
458 sizeof(ProtocolExtensionContainer_4624P81_t));
459 CU_FREE(rrcVer->latest_RRC_Version.buf, sizeof(U8));
460 CU_FREE(cuName->buf, sizeof(cuName->size));
461 for(idy=0; idy<elementCnt; idy++)
463 CU_FREE(f1SetupRsp->protocolIEs.list.array[idy], \
464 sizeof(F1SetupResponseIEs_t));
466 CU_FREE(f1SetupRsp->protocolIEs.list.array,\
467 elementCnt * sizeof(F1SetupResponseIEs_t *));
468 CU_FREE(f1apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcome_t));
469 CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
472 rrcVer->iE_Extensions->list.array[0]->id = \
473 ProtocolIE_ID_id_latest_RRC_Version_Enhanced;
474 rrcVer->iE_Extensions->list.array[0]->criticality = Criticality_reject;
475 rrcVer->iE_Extensions->list.array[0]->extensionValue.present = \
476 RRC_Version_ExtIEs__extensionValue_PR_Latest_RRC_Version_Enhanced;
477 rrcVer->iE_Extensions->list.array[0]->extensionValue.choice.\
478 Latest_RRC_Version_Enhanced.size = 3*sizeof(U8);
479 CU_ALLOC(rrcVer->iE_Extensions->list.\
480 array[0]->extensionValue.choice.Latest_RRC_Version_Enhanced.buf,\
482 if(rrcVer->iE_Extensions->list.\
483 array[0]->extensionValue.choice.Latest_RRC_Version_Enhanced.buf == NULLP)
485 CU_FREE(rrcVer->iE_Extensions->list.array[0],\
486 sizeof(struct RRC_Version_ExtIEs));
487 CU_FREE(rrcVer->iE_Extensions->list.array,\
488 sizeof(struct RRC_Version_ExtIEs *));
489 CU_FREE(rrcVer->iE_Extensions,\
490 sizeof(ProtocolExtensionContainer_4624P81_t));
491 CU_FREE(rrcVer->latest_RRC_Version.buf, sizeof(U8));
492 CU_FREE(cuName->buf, sizeof(cuName->size));
493 for(idy=0; idy<elementCnt; idy++)
495 CU_FREE(f1SetupRsp->protocolIEs.list.array[idy], \
496 sizeof(F1SetupResponseIEs_t));
498 CU_FREE(f1SetupRsp->protocolIEs.list.array,\
499 elementCnt * sizeof(F1SetupResponseIEs_t *));
500 CU_FREE(f1apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcome_t));
501 CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
504 rrcVer->iE_Extensions->list.array[0]->extensionValue.choice.\
505 Latest_RRC_Version_Enhanced.buf[0] = 0;
506 rrcVer->iE_Extensions->list.array[0]->extensionValue.choice.\
507 Latest_RRC_Version_Enhanced.buf[1] = 5;
508 rrcVer->iE_Extensions->list.array[0]->extensionValue.choice.\
509 Latest_RRC_Version_Enhanced.buf[2] = 15;
511 xer_fprint(stdout, &asn_DEF_F1AP_PDU, f1apMsg);
513 /* Encode the F1SetupRequest type as UPER */
514 cmMemset((U8 *)encBuf, 0, ENC_BUF_MAX_LEN);
516 encRetVal = aper_encode(&asn_DEF_F1AP_PDU, 0, f1apMsg, PrepFinalEncBuf, encBuf);
519 CU_FREE(rrcVer->latest_RRC_Version.buf, sizeof(U8));
520 CU_FREE(cuName->buf, sizeof(cuName->size));
521 for(idx=0; idx<elementCnt; idx++)
523 CU_FREE(f1SetupRsp->protocolIEs.list.array[idx], sizeof(F1SetupResponseIEs_t));
525 CU_FREE(f1SetupRsp->protocolIEs.list.array, elementCnt * sizeof(F1SetupResponseIEs_t *));
526 CU_FREE(f1apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcome_t));
527 CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
529 /* Check encode results */
530 if(encRetVal.encoded == ENCODE_FAIL)
532 DU_LOG("\nF1AP : Could not encode F1SetupResponse structure (at %s)\n",\
533 encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
538 DU_LOG("\nF1AP : Created APER encoded buffer for F1SetupResponse\n");
539 for(int i=0; i< encBufSize; i++)
541 printf("%x",encBuf[i]);
546 if(SendF1APMsg(CU_APP_MEM_REG, CU_POOL) != ROK)
548 DU_LOG("\nF1AP : Sending F1 Setup Response failed");
553 }/* End of BuildAndSendF1SetupRsp */
555 /*******************************************************************
557 * @brief Builds and sends the DUUpdateAcknowledge
561 * Function : BuildAndSendDUUpdateAck
563 * Functionality: Constructs the DU Update Acknowledge message and sends
564 * it to the DU through SCTP.
566 * @params[in] void **buf,Buffer to which encoded pattern is written into
567 * @params[in] int *size,size of buffer
569 * @return ROK - success
572 * ****************************************************************/
574 S16 BuildAndSendDUUpdateAck()
578 F1AP_PDU_t *f1apMsg = NULL;
579 GNBDUConfigurationUpdateAcknowledge_t *gNBDuCfgAck;
580 asn_enc_rval_t enRetVal; /* Encoder return value */
582 DU_LOG("\nF1AP : Building GNB-DU Config Update Ack\n");
584 /* Allocate the memory for F1SetupRequest_t */
585 CU_ALLOC(f1apMsg, (Size)sizeof(F1AP_PDU_t));
588 DU_LOG("\nF1AP : Memory allocation for F1AP-PDU failed");
592 f1apMsg->present = F1AP_PDU_PR_successfulOutcome;
594 CU_ALLOC(f1apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcome_t));
595 if(f1apMsg->choice.successfulOutcome == NULLP)
597 DU_LOG("\nF1AP : Memory allocation for F1AP-PDU failed");
598 CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
602 f1apMsg->choice.successfulOutcome->procedureCode = ProcedureCode_id_gNBDUConfigurationUpdate;
603 f1apMsg->choice.successfulOutcome->criticality = Criticality_reject;
604 f1apMsg->choice.successfulOutcome->value.present = SuccessfulOutcome__value_PR_GNBDUConfigurationUpdateAcknowledge;
605 gNBDuCfgAck = &f1apMsg->choice.successfulOutcome->value.choice.GNBDUConfigurationUpdateAcknowledge;
608 gNBDuCfgAck->protocolIEs.list.count = elementCnt;
609 gNBDuCfgAck->protocolIEs.list.size = elementCnt*sizeof(GNBDUConfigurationUpdateAcknowledgeIEs_t);
611 /* Initialize the F1Setup members */
612 CU_ALLOC(gNBDuCfgAck->protocolIEs.list.array, elementCnt * sizeof(GNBDUConfigurationUpdateAcknowledgeIEs_t *));
613 if(gNBDuCfgAck->protocolIEs.list.array == NULLP)
615 DU_LOG("\nF1AP : Memory allocation for DuUpdateAcknowledgeIEs failed");
616 CU_FREE(f1apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcome_t));
617 CU_FREE(f1apMsg,(Size)sizeof(F1AP_PDU_t));
621 for(idx=0; idx<elementCnt; idx++)
623 CU_ALLOC(gNBDuCfgAck->protocolIEs.list.array[idx], sizeof(GNBDUConfigurationUpdateAcknowledgeIEs_t));
624 if(gNBDuCfgAck->protocolIEs.list.array[idx] == NULLP)
626 CU_FREE(gNBDuCfgAck->protocolIEs.list.array, elementCnt * sizeof(GNBDUConfigurationUpdateAcknowledgeIEs_t *));
627 CU_FREE(f1apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcome_t));
628 CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
635 gNBDuCfgAck->protocolIEs.list.array[idx]->id = ProtocolIE_ID_id_TransactionID ;
636 gNBDuCfgAck->protocolIEs.list.array[idx]->criticality = Criticality_reject;
637 gNBDuCfgAck->protocolIEs.list.array[idx]->value.present = GNBDUConfigurationUpdateAcknowledgeIEs__value_PR_TransactionID;
638 gNBDuCfgAck->protocolIEs.list.array[idx]->value.choice.TransactionID = TRANS_ID;
640 xer_fprint(stdout, &asn_DEF_F1AP_PDU, f1apMsg);
642 /* Encode the F1SetupRequest type as UPER */
643 cmMemset((U8 *)encBuf, 0, ENC_BUF_MAX_LEN);
645 enRetVal = aper_encode(&asn_DEF_F1AP_PDU, 0, f1apMsg, PrepFinalEncBuf, encBuf);
648 for(idx=0; idx<elementCnt; idx++)
650 CU_FREE(gNBDuCfgAck->protocolIEs.list.array[idx], sizeof(GNBDUConfigurationUpdateAcknowledgeIEs_t));
652 CU_FREE(gNBDuCfgAck->protocolIEs.list.array, elementCnt * sizeof(GNBDUConfigurationUpdateAcknowledgeIEs_t *));
653 CU_FREE(f1apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcome_t));
654 CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
656 /* Checking encode results */
657 if(enRetVal.encoded == ENCODE_FAIL)
659 DU_LOG("\nF1AP : Could not encode DUConfigUpdateAcknowledge structure (at %s)",enRetVal.failed_type ? enRetVal.failed_type->name : "unknown");
664 DU_LOG("\nF1AP : Created APER encoded buffer for DuConfigUpdateAcknowledge\n");
665 for(int i=0; i< encBufSize; i++)
667 printf("%x",encBuf[i]);
672 if(SendF1APMsg(CU_APP_MEM_REG, CU_POOL) != ROK)
674 DU_LOG("\nF1AP : Sending GNB-DU Config Update Ack failed");
680 }/* End of BuildAndSendDUUpdateAck*/
682 /*******************************************************************
684 * @brief Builds and sends the DLRRCMessageTransfer
688 * Function : BuildAndSendDLRRCMessageTransfer
690 * Functionality: Constructs the DL RRC Message Transfer and sends
691 * it to the CU through SCTP.
695 * @return ROK - success
698 * ****************************************************************/
699 S16 BuildAndSendDLRRCMessageTransfer()
705 F1AP_PDU_t *f1apMsg = NULL;
706 DLRRCMessageTransfer_t *dlRRCMsg;
707 asn_enc_rval_t encRetVal; /* Encoder return value */
709 DU_LOG("\n F1AP : Building DL RRC Message Transfer Message\n");
711 CU_ALLOC(f1apMsg, sizeof(F1AP_PDU_t));
714 DU_LOG(" F1AP : Memory allocation for F1AP-PDU failed");
718 f1apMsg->present = F1AP_PDU_PR_initiatingMessage;
719 CU_ALLOC(f1apMsg->choice.initiatingMessage,
720 sizeof(InitiatingMessage_t));
721 if(f1apMsg->choice.initiatingMessage == NULLP)
723 DU_LOG(" F1AP : Memory allocation for F1AP-PDU failed");
724 CU_FREE(f1apMsg,sizeof(F1AP_PDU_t));
728 f1apMsg->choice.initiatingMessage->procedureCode = \
729 ProcedureCode_id_DLRRCMessageTransfer;
730 f1apMsg->choice.initiatingMessage->criticality = Criticality_ignore;
731 f1apMsg->choice.initiatingMessage->value.present = \
732 InitiatingMessage__value_PR_DLRRCMessageTransfer;
734 &f1apMsg->choice.initiatingMessage->value.choice.DLRRCMessageTransfer;
736 dlRRCMsg->protocolIEs.list.count = elementCnt;
737 dlRRCMsg->protocolIEs.list.size = \
738 elementCnt * sizeof(DLRRCMessageTransferIEs_t *);
740 /* Initialize the F1Setup members */
741 CU_ALLOC(dlRRCMsg->protocolIEs.list.array, \
742 elementCnt * sizeof(DLRRCMessageTransferIEs_t *));
743 if(dlRRCMsg->protocolIEs.list.array == NULLP)
745 DU_LOG(" F1AP : Memory allocation for DL RRC MessageTransferIEs failed");
746 CU_FREE(f1apMsg->choice.initiatingMessage,
747 sizeof(InitiatingMessage_t));
748 CU_FREE(f1apMsg,(Size)sizeof(F1AP_PDU_t));
752 for(idx=0; idx<elementCnt; idx++)
754 CU_ALLOC(dlRRCMsg->protocolIEs.list.array[idx],\
755 sizeof(DLRRCMessageTransferIEs_t));
756 if(dlRRCMsg->protocolIEs.list.array[idx] == NULLP)
758 for(ieId=0; ieId<idx; ieId++)
760 CU_FREE(dlRRCMsg->protocolIEs.list.array[ieId],\
761 sizeof(DLRRCMessageTransferIEs_t));
763 CU_FREE(dlRRCMsg->protocolIEs.list.array,\
764 elementCnt * sizeof(DLRRCMessageTransferIEs_t *));
765 CU_FREE(f1apMsg->choice.initiatingMessage,\
766 sizeof(InitiatingMessage_t));
767 CU_FREE(f1apMsg,sizeof(F1AP_PDU_t));
774 /*GNB CU UE F1AP ID*/
775 dlRRCMsg->protocolIEs.list.array[idx]->id = \
776 ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
777 dlRRCMsg->protocolIEs.list.array[idx]->criticality = Criticality_reject;
778 dlRRCMsg->protocolIEs.list.array[idx]->value.present = \
779 DLRRCMessageTransferIEs__value_PR_GNB_CU_UE_F1AP_ID;
780 dlRRCMsg->protocolIEs.list.array[idx]->value.choice.GNB_CU_UE_F1AP_ID = CU_ID;
782 /*GNB DU UE F1AP ID*/
784 dlRRCMsg->protocolIEs.list.array[idx]->id = \
785 ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
786 dlRRCMsg->protocolIEs.list.array[idx]->criticality = Criticality_reject;
787 dlRRCMsg->protocolIEs.list.array[idx]->value.present = \
788 DLRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID;
789 dlRRCMsg->protocolIEs.list.array[idx]->value.choice.GNB_DU_UE_F1AP_ID = DU_ID;
793 dlRRCMsg->protocolIEs.list.array[idx]->id = \
794 ProtocolIE_ID_id_SRBID;
795 dlRRCMsg->protocolIEs.list.array[idx]->criticality = Criticality_reject;
796 dlRRCMsg->protocolIEs.list.array[idx]->value.present = \
797 DLRRCMessageTransferIEs__value_PR_SRBID;
798 dlRRCMsg->protocolIEs.list.array[idx]->value.choice.SRBID = DL_SRBID;
803 xer_fprint(stdout, &asn_DEF_F1AP_PDU, f1apMsg);
805 /* Encode the F1SetupRequest type as APER */
806 cmMemset((U8 *)encBuf, 0, ENC_BUF_MAX_LEN);
808 encRetVal = aper_encode(&asn_DEF_F1AP_PDU, 0, f1apMsg, PrepFinalEncBuf,\
811 if(encRetVal.encoded == ENCODE_FAIL)
813 DU_LOG( "\n F1AP : Could not encode DL RRC Message Transfer structure (at %s)\n",\
814 encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
819 DU_LOG("\n F1AP : Created APER encoded buffer for DL RRC Message transfer\n");
820 for(int i=0; i< encBufSize; i++)
822 printf("%x",encBuf[i]);
827 if(SendF1APMsg(CU_APP_MEM_REG,CU_POOL) != ROK)
829 DU_LOG("\n F1AP : Sending DL RRC Message Transfer Failed");
834 }/* End of BuildAndSendDLRRCMessageTransfer */
837 /*******************************************************************
839 * @brief Builds and sends the UE Setup Response
843 * Function : BuildAndSendUESetRsp
845 * Functionality: Constructs the UE Setup Response and sends
846 * it to the DU through SCTP.
850 * @return ROK - success
853 * ****************************************************************/
854 S16 BuildAndSendUESetRsp()
863 F1AP_PDU_t *f1apMsg = NULL;
864 UEContextSetupResponse_t *ueSetRsp;
865 asn_enc_rval_t encRetVal; /* Encoder return value */
867 DU_LOG("\n F1AP : Building UE Context Setup Response\n");
869 CU_ALLOC(f1apMsg, sizeof(F1AP_PDU_t));
872 DU_LOG(" F1AP : Memory allocation for F1AP-PDU failed");
876 f1apMsg->present = F1AP_PDU_PR_successfulOutcome;
877 CU_ALLOC(f1apMsg->choice.successfulOutcome,
878 sizeof(SuccessfulOutcome_t));
879 if(f1apMsg->choice.successfulOutcome == NULLP)
881 DU_LOG(" F1AP : Memory allocation for F1AP-PDU failed");
882 CU_FREE(f1apMsg,sizeof(F1AP_PDU_t));
886 f1apMsg->choice.successfulOutcome->procedureCode = \
887 ProcedureCode_id_UEContextSetup;
888 f1apMsg->choice.successfulOutcome->criticality = Criticality_reject;
889 f1apMsg->choice.successfulOutcome->value.present = \
890 SuccessfulOutcome__value_PR_UEContextSetupResponse;
892 &f1apMsg->choice.successfulOutcome->value.choice.UEContextSetupResponse;
894 ueSetRsp->protocolIEs.list.count = elementCnt;
895 ueSetRsp->protocolIEs.list.size = \
896 elementCnt * sizeof(UEContextSetupResponse_t *);
898 /* Initialize the UESetup members */
899 CU_ALLOC(ueSetRsp->protocolIEs.list.array, \
900 ueSetRsp->protocolIEs.list.size);
901 if(ueSetRsp->protocolIEs.list.array == NULLP)
903 DU_LOG(" F1AP : Memory allocation for UE Setup Response failed");
904 CU_FREE(f1apMsg->choice.successfulOutcome,
905 sizeof(SuccessfulOutcome_t));
906 CU_FREE(f1apMsg,(Size)sizeof(F1AP_PDU_t));
910 for(idx=0; idx<elementCnt; idx++)
912 CU_ALLOC(ueSetRsp->protocolIEs.list.array[idx],\
913 sizeof(UEContextSetupResponseIEs_t));
914 if(ueSetRsp->protocolIEs.list.array[idx] == NULLP)
916 for(ieId=0; ieId<idx; ieId++)
918 CU_FREE(ueSetRsp->protocolIEs.list.array[ieId],\
919 sizeof(UEContextSetupResponseIEs_t));
921 CU_FREE(ueSetRsp->protocolIEs.list.array,\
922 ueSetRsp->protocolIEs.list.size);
923 CU_FREE(f1apMsg->choice.successfulOutcome,\
924 sizeof(SuccessfulOutcome_t));
925 CU_FREE(f1apMsg,sizeof(F1AP_PDU_t));
932 /*GNB CU UE F1AP ID*/
933 ueSetRsp->protocolIEs.list.array[idx]->id = \
934 ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
935 ueSetRsp->protocolIEs.list.array[idx]->criticality = Criticality_reject;
936 ueSetRsp->protocolIEs.list.array[idx]->value.present = \
937 UEContextSetupResponseIEs__value_PR_GNB_CU_UE_F1AP_ID;
938 ueSetRsp->protocolIEs.list.array[idx]->value.choice.GNB_CU_UE_F1AP_ID = CU_ID;
940 /*GNB DU UE F1AP ID*/
942 ueSetRsp->protocolIEs.list.array[idx]->id = \
943 ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
944 ueSetRsp->protocolIEs.list.array[idx]->criticality = Criticality_reject;
945 ueSetRsp->protocolIEs.list.array[idx]->value.present = \
946 UEContextSetupResponseIEs__value_PR_GNB_DU_UE_F1AP_ID;
947 ueSetRsp->protocolIEs.list.array[idx]->value.choice.GNB_DU_UE_F1AP_ID = DU_ID;
950 xer_fprint(stdout, &asn_DEF_F1AP_PDU, f1apMsg);
952 /* Encode the F1SetupRequest type as APER */
953 cmMemset((U8 *)encBuf, 0, ENC_BUF_MAX_LEN);
955 encRetVal = aper_encode(&asn_DEF_F1AP_PDU, 0, f1apMsg, PrepFinalEncBuf,\
958 if(encRetVal.encoded == ENCODE_FAIL)
960 DU_LOG( "\n F1AP : Could not encode UE Context Setup Request structure (at %s)\n",\
961 encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
966 DU_LOG("\n F1AP : Created APER encoded buffer for UE Context Setup Request\n");
967 for(int i=0; i< encBufSize; i++)
969 printf("%x",encBuf[i]);
974 if(SendF1APMsg(CU_APP_MEM_REG,CU_POOL) != ROK)
976 DU_LOG("\n F1AP : Sending UE Context Setup Request Failed");
981 }/* End of BuildAndSendUESetRsp */
982 /*******************************************************************
984 * @brief Handles received F1AP message and sends back response
988 * Function : F1APMsgHdlr
991 * - Decodes received F1AP control message
992 * - Prepares response message, encodes and sends to SCTP
995 * @return ROK - success
998 * ****************************************************************/
999 void F1APMsgHdlr(Buffer *mBuf)
1005 F1AP_PDU_t *f1apMsg;
1006 asn_dec_rval_t rval; /* Decoder return value */
1007 F1AP_PDU_t f1apasnmsg ;
1009 DU_LOG("\nF1AP : Received F1AP message buffer");
1010 SPrntMsg(mBuf, 0,0);
1012 /* Copy mBuf into char array to decode it */
1013 SFndLenMsg(mBuf, &recvBufLen);
1014 if(SGetSBuf(DFLT_REGION, DFLT_POOL, (Data **)&recvBuf, (Size)recvBufLen) != ROK)
1016 DU_LOG("\nF1AP : Memory allocation failed");
1019 if(SCpyMsgFix(mBuf, 0, recvBufLen, (Data *)recvBuf, ©Cnt) != ROK)
1021 DU_LOG("\nF1AP : Failed while copying %d", copyCnt);
1025 printf("\nF1AP : Received flat buffer to be decoded : ");
1026 for(i=0; i< recvBufLen; i++)
1028 printf("%x",recvBuf[i]);
1031 /* Decoding flat buffer into F1AP messsage */
1032 f1apMsg = &f1apasnmsg;
1033 memset(f1apMsg, 0, sizeof(F1AP_PDU_t));
1035 rval = aper_decode(0, &asn_DEF_F1AP_PDU, (void **)&f1apMsg, recvBuf, recvBufLen, 0, 0);
1036 SPutSBuf(DFLT_REGION, DFLT_POOL, (Data *)recvBuf, (Size)recvBufLen);
1037 if(rval.code == RC_FAIL || rval.code == RC_WMORE)
1039 DU_LOG("\nF1AP : ASN decode failed");
1043 xer_fprint(stdout, &asn_DEF_F1AP_PDU, f1apMsg);
1045 switch(f1apMsg->present)
1047 case F1AP_PDU_PR_initiatingMessage:
1049 switch(f1apMsg->choice.initiatingMessage->value.present)
1051 case InitiatingMessage__value_PR_F1SetupRequest:
1053 DU_LOG("\nF1AP : F1 setup request received");
1054 BuildAndSendF1SetupRsp();
1058 case InitiatingMessage__value_PR_GNBDUConfigurationUpdate:
1060 DU_LOG("\nF1AP : GNB-DU config update received");
1061 BuildAndSendDUUpdateAck();
1067 DU_LOG("\nF1AP : Invalid type of intiating message [%d]",f1apMsg->choice.initiatingMessage->value.present);
1070 }/* End of switch(initiatingMessage) */
1074 }/* End of switch(f1apMsg->present) */
1076 } /* End of F1APMsgHdlr */
1078 /**********************************************************************
1080 **********************************************************************/