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]));
117 /*******************************************************************
119 * @brief Builds and sends the F1SetupResponse
123 * Function : BuildAndSendF1SetupRsp
125 * Functionality: Constructs the F1SetupResponse message and sends
126 * it back to the DU through SCTP.
128 * @params[in] void **buf,Buffer to which encoded pattern is written into
129 * @params[in] int *size,size of buffer
131 * @return ROK - success
134 * ****************************************************************/
135 S16 BuildAndSendF1SetupRsp()
138 U8 elementCnt,cellCnt;
139 F1AP_PDU_t *f1apMsg = NULL;
140 F1SetupResponse_t *f1SetupRsp;
141 GNB_CU_Name_t *cuName;
142 Cells_to_be_Activated_List_t *cellToActivate;
143 RRC_Version_t *rrcVer;
144 asn_enc_rval_t encRetVal;
145 DU_LOG("\nF1AP : Building F1 Setup Response\n");
147 /* Allocate the memory for F1SetupRequest_t */
148 CU_ALLOC(f1apMsg, sizeof(F1AP_PDU_t));
151 DU_LOG("\nF1AP : Memory allocation for F1AP-PDU failed");
154 f1apMsg->present = F1AP_PDU_PR_successfulOutcome;
156 CU_ALLOC(f1apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcome_t));
157 if(f1apMsg->choice.successfulOutcome == NULLP)
159 DU_LOG("\nF1AP : Memory allocation for F1AP-PDU failed");
160 CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
164 f1apMsg->choice.successfulOutcome->procedureCode = ProcedureCode_id_F1Setup;
165 f1apMsg->choice.successfulOutcome->criticality = Criticality_reject;
166 f1apMsg->choice.successfulOutcome->value.present = \
167 SuccessfulOutcome__value_PR_F1SetupResponse;
168 f1SetupRsp = &f1apMsg->choice.successfulOutcome->value.choice.F1SetupResponse;
171 f1SetupRsp->protocolIEs.list.count = elementCnt;
172 f1SetupRsp->protocolIEs.list.size = elementCnt*sizeof(F1SetupResponseIEs_t *);
174 CU_ALLOC(f1SetupRsp->protocolIEs.list.array, \
175 elementCnt * sizeof(F1SetupResponseIEs_t *));
176 if(f1SetupRsp->protocolIEs.list.array == NULLP)
178 DU_LOG("\nF1AP : Memory allocation for F1ResponseIEs failed");
179 CU_FREE(f1apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcome_t));
180 CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
184 for(idx=0; idx<elementCnt; idx++)
186 CU_ALLOC(f1SetupRsp->protocolIEs.list.array[idx], \
187 sizeof(F1SetupResponseIEs_t));
188 if(f1SetupRsp->protocolIEs.list.array[idx] == NULLP)
190 CU_FREE(f1SetupRsp->protocolIEs.list.array,\
191 elementCnt * sizeof(F1SetupResponseIEs_t *));
192 CU_FREE(f1apMsg->choice.successfulOutcome, \
193 sizeof(SuccessfulOutcome_t));
194 CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
201 f1SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_ID_id_TransactionID;
202 f1SetupRsp->protocolIEs.list.array[idx]->criticality = Criticality_reject;
203 f1SetupRsp->protocolIEs.list.array[idx]->value.present = \
204 F1SetupResponseIEs__value_PR_TransactionID;
205 f1SetupRsp->protocolIEs.list.array[idx]->value.choice.TransactionID =\
210 f1SetupRsp->protocolIEs.list.array[idx]->id = ProtocolIE_ID_id_gNB_CU_Name;
211 f1SetupRsp->protocolIEs.list.array[idx]->criticality = Criticality_ignore;
212 f1SetupRsp->protocolIEs.list.array[idx]->value.present = \
213 F1SetupResponseIEs__value_PR_GNB_CU_Name;
214 cuName = &f1SetupRsp->protocolIEs.list.array[idx]->value.choice.GNB_CU_Name;
215 cuName->size = sizeof(cuCfgParams.cuName);
217 CU_ALLOC(cuName->buf, sizeof(cuName->size));
218 if(cuName->buf == NULLP)
220 for(idy=0; idy<elementCnt; idy++)
222 CU_FREE(f1SetupRsp->protocolIEs.list.array[idy],\
223 sizeof(F1SetupResponseIEs_t));
225 CU_FREE(f1SetupRsp->protocolIEs.list.array,\
226 elementCnt * sizeof(F1SetupResponseIEs_t *));
227 CU_FREE(f1apMsg->choice.successfulOutcome,\
228 sizeof(SuccessfulOutcome_t));
229 CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
232 strcpy((char*)cuName->buf, (char*)cuCfgParams.cuName);
234 /*Cells to be activated list*/
236 f1SetupRsp->protocolIEs.list.array[idx]->id = \
237 ProtocolIE_ID_id_Cells_to_be_Activated_List ;
238 f1SetupRsp->protocolIEs.list.array[idx]->criticality = Criticality_reject;
239 f1SetupRsp->protocolIEs.list.array[idx]->value.present = \
240 F1SetupResponseIEs__value_PR_Cells_to_be_Activated_List;
241 cellToActivate = &f1SetupRsp->protocolIEs.list.array[idx]->value.choice.\
242 Cells_to_be_Activated_List;
244 cellToActivate->list.count = cellCnt;
245 cellToActivate->list.size = \
246 cellCnt*sizeof(struct Cells_to_be_Activated_List_ItemIEs *);
247 CU_ALLOC(cellToActivate->list.array,\
248 sizeof(struct Cells_to_be_Activated_List_ItemIEs *));
249 if(cellToActivate->list.array == NULLP)
251 CU_FREE(cuName->buf, sizeof(cuName->size));
252 for(idy=0; idy<elementCnt; idy++)
254 CU_FREE(f1SetupRsp->protocolIEs.list.array[idy],\
255 sizeof(F1SetupResponseIEs_t));
257 CU_FREE(f1SetupRsp->protocolIEs.list.array,\
258 elementCnt * sizeof(F1SetupResponseIEs_t *));
259 CU_FREE(f1apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcome_t));
260 CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
263 for(idy=0; idy<cellCnt; idy++)
265 CU_ALLOC(cellToActivate->list.array[idy],\
266 sizeof(struct Cells_to_be_Activated_List_ItemIEs ));
267 if(cellToActivate->list.array[idy] == NULLP)
269 CU_FREE(cellToActivate->list.array,\
270 sizeof(struct Cells_to_be_Activated_List_ItemIEs *));
271 CU_FREE(cuName->buf, sizeof(cuName->size));
272 for(idy=0; idy<elementCnt; idy++)
274 CU_FREE(f1SetupRsp->protocolIEs.list.array[idy], \
275 sizeof(F1SetupResponseIEs_t));
277 CU_FREE(f1SetupRsp->protocolIEs.list.array, \
278 elementCnt * sizeof(F1SetupResponseIEs_t *));
279 CU_FREE(f1apMsg->choice.successfulOutcome, \
280 sizeof(SuccessfulOutcome_t));
281 CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
285 cellToActivate->list.array[0]->id = \
286 ProtocolIE_ID_id_Cells_to_be_Activated_List_Item;
287 cellToActivate->list.array[0]->criticality = Criticality_ignore;
288 cellToActivate->list.array[0]->value.present = \
289 Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item;
290 cellToActivate->list.array[0]->value.choice.Cells_to_be_Activated_List_Item.\
291 nRCGI.pLMN_Identity.size = 3*sizeof(uint8_t);
292 CU_ALLOC(cellToActivate->list.array[0]->\
293 value.choice.Cells_to_be_Activated_List_Item.nRCGI.pLMN_Identity.buf,\
295 if(cellToActivate->list.array[0]->value.choice.\
296 Cells_to_be_Activated_List_Item.nRCGI.pLMN_Identity.buf == NULLP)
299 for(idy=0; idy<cellCnt; idy++)
301 CU_FREE(cellToActivate->list.array[idy],\
302 sizeof(struct Cells_to_be_Activated_List_ItemIEs ));
305 CU_FREE(cellToActivate->list.array,\
306 sizeof(struct Cells_to_be_Activated_List_ItemIEs *));
307 CU_FREE(cuName->buf, sizeof(cuName->size));
308 for(idy=0; idy<elementCnt; idy++)
310 CU_FREE(f1SetupRsp->protocolIEs.list.array[idy], \
311 sizeof(F1SetupResponseIEs_t));
313 CU_FREE(f1SetupRsp->protocolIEs.list.array, \
314 elementCnt * sizeof(F1SetupResponseIEs_t *));
315 CU_FREE(f1apMsg->choice.successfulOutcome, \
316 sizeof(SuccessfulOutcome_t));
317 CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
320 plmnBuildCU(cuCfgParams.plmn , &cellToActivate->list.array[0]->value.choice.\
321 Cells_to_be_Activated_List_Item.nRCGI.pLMN_Identity);
322 cellToActivate->list.array[0]->value.choice.Cells_to_be_Activated_List_Item.\
323 nRCGI.nRCellIdentity.size = 5*sizeof(uint8_t);
324 CU_ALLOC(cellToActivate->list.array[0]->value.choice.\
325 Cells_to_be_Activated_List_Item.nRCGI.nRCellIdentity.buf,\
327 if(cellToActivate->list.array[0]->value.choice.\
328 Cells_to_be_Activated_List_Item.nRCGI.nRCellIdentity.buf == NULLP)
330 CU_FREE(cellToActivate->list.array[0]->\
331 value.choice.Cells_to_be_Activated_List_Item.nRCGI.pLMN_Identity.buf,\
333 for(idy=0; idy<cellCnt; idy++)
335 CU_FREE(cellToActivate->list.array[idy],\
336 sizeof(struct Cells_to_be_Activated_List_ItemIEs ));
339 CU_FREE(cellToActivate->list.array,\
340 sizeof(struct Cells_to_be_Activated_List_ItemIEs *));
341 CU_FREE(cuName->buf, sizeof(cuName->size));
342 for(idy=0; idy<elementCnt; idy++)
344 CU_FREE(f1SetupRsp->protocolIEs.list.array[idy], \
345 sizeof(F1SetupResponseIEs_t));
347 CU_FREE(f1SetupRsp->protocolIEs.list.array, \
348 elementCnt * sizeof(F1SetupResponseIEs_t *));
349 CU_FREE(f1apMsg->choice.successfulOutcome, \
350 sizeof(SuccessfulOutcome_t));
351 CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
354 for (int tmp = 0 ; tmp < cellToActivate->list.array[0]->value.\
355 choice.Cells_to_be_Activated_List_Item.\
356 nRCGI.nRCellIdentity.size-1; tmp++)
358 cellToActivate->list.array[0]->value.choice.\
359 Cells_to_be_Activated_List_Item.nRCGI.nRCellIdentity.buf[tmp] = 0;
361 cellToActivate->list.array[0]->value.choice.\
362 Cells_to_be_Activated_List_Item.nRCGI.nRCellIdentity.buf[4] = 16;
363 cellToActivate->list.array[0]->value.choice.Cells_to_be_Activated_List_Item.\
364 nRCGI.nRCellIdentity.bits_unused = 4;
368 f1SetupRsp->protocolIEs.list.array[idx]->id = \
369 ProtocolIE_ID_id_GNB_CU_RRC_Version;
370 f1SetupRsp->protocolIEs.list.array[idx]->criticality = Criticality_reject;
371 f1SetupRsp->protocolIEs.list.array[idx]->value.present = \
372 F1SetupResponseIEs__value_PR_RRC_Version;
373 rrcVer = &f1SetupRsp->protocolIEs.list.array[idx]->value.choice.RRC_Version;
374 rrcVer->latest_RRC_Version.size = RRC_SIZE;
376 CU_ALLOC(rrcVer->latest_RRC_Version.buf, sizeof(U8));
377 if(rrcVer->latest_RRC_Version.buf == NULLP)
379 CU_FREE(cuName->buf, sizeof(cuName->size));
380 for(idy=0; idy<elementCnt; idx++)
382 CU_FREE(f1SetupRsp->protocolIEs.list.array[idy], \
383 sizeof(F1SetupResponseIEs_t));
385 CU_FREE(f1SetupRsp->protocolIEs.list.array,\
386 elementCnt * sizeof(F1SetupResponseIEs_t *));
387 CU_FREE(f1apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcome_t));
388 CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
392 /* Need to check RRC Version */
393 rrcVer->latest_RRC_Version.buf[0] = cuCfgParams.rrcVersion.rrcVer;
394 rrcVer->latest_RRC_Version.bits_unused = 5; //TODO: pick from cuCfgParam. If not present, add it
395 CU_ALLOC(rrcVer->iE_Extensions,sizeof(ProtocolExtensionContainer_4624P81_t));
396 if(rrcVer->iE_Extensions == NULLP)
398 CU_FREE(rrcVer->latest_RRC_Version.buf, sizeof(U8));
399 CU_FREE(cuName->buf, sizeof(cuName->size));
400 for(idy=0; idy<elementCnt; idy++)
402 CU_FREE(f1SetupRsp->protocolIEs.list.array[idy], \
403 sizeof(F1SetupResponseIEs_t));
405 CU_FREE(f1SetupRsp->protocolIEs.list.array,\
406 elementCnt * sizeof(F1SetupResponseIEs_t *));
407 CU_FREE(f1apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcome_t));
408 CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
411 rrcVer->iE_Extensions->list.count = 1;
412 rrcVer->iE_Extensions->list.size = sizeof(struct RRC_Version_ExtIEs *);
413 CU_ALLOC(rrcVer->iE_Extensions->list.array,\
414 sizeof(struct RRC_Version_ExtIEs *));
415 if(rrcVer->iE_Extensions->list.array == NULLP)
417 CU_FREE(rrcVer->iE_Extensions,\
418 sizeof(ProtocolExtensionContainer_4624P81_t));
419 CU_FREE(rrcVer->latest_RRC_Version.buf, sizeof(U8));
420 CU_FREE(cuName->buf, sizeof(cuName->size));
421 for(idy=0; idy<elementCnt; idy++)
423 CU_FREE(f1SetupRsp->protocolIEs.list.array[idy], \
424 sizeof(F1SetupResponseIEs_t));
426 CU_FREE(f1SetupRsp->protocolIEs.list.array,\
427 elementCnt * sizeof(F1SetupResponseIEs_t *));
428 CU_FREE(f1apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcome_t));
429 CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
432 CU_ALLOC(rrcVer->iE_Extensions->list.array[0],\
433 sizeof(struct RRC_Version_ExtIEs));
434 if(rrcVer->iE_Extensions->list.array[0] == NULLP)
436 CU_FREE(rrcVer->iE_Extensions->list.array,\
437 sizeof(struct RRC_Version_ExtIEs *));
438 CU_FREE(rrcVer->iE_Extensions,\
439 sizeof(ProtocolExtensionContainer_4624P81_t));
440 CU_FREE(rrcVer->latest_RRC_Version.buf, sizeof(U8));
441 CU_FREE(cuName->buf, sizeof(cuName->size));
442 for(idy=0; idy<elementCnt; idy++)
444 CU_FREE(f1SetupRsp->protocolIEs.list.array[idy], \
445 sizeof(F1SetupResponseIEs_t));
447 CU_FREE(f1SetupRsp->protocolIEs.list.array,\
448 elementCnt * sizeof(F1SetupResponseIEs_t *));
449 CU_FREE(f1apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcome_t));
450 CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
453 rrcVer->iE_Extensions->list.array[0]->id = \
454 ProtocolIE_ID_id_latest_RRC_Version_Enhanced;
455 rrcVer->iE_Extensions->list.array[0]->criticality = Criticality_reject;
456 rrcVer->iE_Extensions->list.array[0]->extensionValue.present = \
457 RRC_Version_ExtIEs__extensionValue_PR_Latest_RRC_Version_Enhanced;
458 rrcVer->iE_Extensions->list.array[0]->extensionValue.choice.\
459 Latest_RRC_Version_Enhanced.size = 3*sizeof(U8);
460 CU_ALLOC(rrcVer->iE_Extensions->list.\
461 array[0]->extensionValue.choice.Latest_RRC_Version_Enhanced.buf,\
463 if(rrcVer->iE_Extensions->list.\
464 array[0]->extensionValue.choice.Latest_RRC_Version_Enhanced.buf == NULLP)
466 CU_FREE(rrcVer->iE_Extensions->list.array[0],\
467 sizeof(struct RRC_Version_ExtIEs));
468 CU_FREE(rrcVer->iE_Extensions->list.array,\
469 sizeof(struct RRC_Version_ExtIEs *));
470 CU_FREE(rrcVer->iE_Extensions,\
471 sizeof(ProtocolExtensionContainer_4624P81_t));
472 CU_FREE(rrcVer->latest_RRC_Version.buf, sizeof(U8));
473 CU_FREE(cuName->buf, sizeof(cuName->size));
474 for(idy=0; idy<elementCnt; idy++)
476 CU_FREE(f1SetupRsp->protocolIEs.list.array[idy], \
477 sizeof(F1SetupResponseIEs_t));
479 CU_FREE(f1SetupRsp->protocolIEs.list.array,\
480 elementCnt * sizeof(F1SetupResponseIEs_t *));
481 CU_FREE(f1apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcome_t));
482 CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
485 rrcVer->iE_Extensions->list.array[0]->extensionValue.choice.\
486 Latest_RRC_Version_Enhanced.buf[0] = 0;
487 rrcVer->iE_Extensions->list.array[0]->extensionValue.choice.\
488 Latest_RRC_Version_Enhanced.buf[1] = 5;
489 rrcVer->iE_Extensions->list.array[0]->extensionValue.choice.\
490 Latest_RRC_Version_Enhanced.buf[2] = 15;
492 xer_fprint(stdout, &asn_DEF_F1AP_PDU, f1apMsg);
494 /* Encode the F1SetupRequest type as UPER */
495 cmMemset((U8 *)encBuf, 0, ENC_BUF_MAX_LEN);
497 encRetVal = aper_encode(&asn_DEF_F1AP_PDU, 0, f1apMsg, PrepFinalEncBuf, encBuf);
500 CU_FREE(rrcVer->latest_RRC_Version.buf, sizeof(U8));
501 CU_FREE(cuName->buf, sizeof(cuName->size));
502 for(idx=0; idx<elementCnt; idx++)
504 CU_FREE(f1SetupRsp->protocolIEs.list.array[idx], sizeof(F1SetupResponseIEs_t));
506 CU_FREE(f1SetupRsp->protocolIEs.list.array, elementCnt * sizeof(F1SetupResponseIEs_t *));
507 CU_FREE(f1apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcome_t));
508 CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
510 /* Check encode results */
511 if(encRetVal.encoded == ENCODE_FAIL)
513 DU_LOG("\nF1AP : Could not encode F1SetupResponse structure (at %s)\n",\
514 encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
519 DU_LOG("\nF1AP : Created APER encoded buffer for F1SetupResponse\n");
520 for(int i=0; i< encBufSize; i++)
522 printf("%x",encBuf[i]);
527 if(SendF1APMsg(CU_APP_MEM_REG, CU_POOL) != ROK)
529 DU_LOG("\nF1AP : Sending F1 Setup Response failed");
534 }/* End of BuildAndSendF1SetupRsp */
536 /*******************************************************************
538 * @brief Builds and sends the DUUpdateAcknowledge
542 * Function : BuildAndSendDUUpdateAck
544 * Functionality: Constructs the DU Update Acknowledge message and sends
545 * it to the DU through SCTP.
547 * @params[in] void **buf,Buffer to which encoded pattern is written into
548 * @params[in] int *size,size of buffer
550 * @return ROK - success
553 * ****************************************************************/
555 S16 BuildAndSendDUUpdateAck()
559 F1AP_PDU_t *f1apMsg = NULL;
560 GNBDUConfigurationUpdateAcknowledge_t *gNBDuCfgAck;
561 asn_enc_rval_t enRetVal; /* Encoder return value */
563 DU_LOG("\nF1AP : Building GNB-DU Config Update Ack\n");
565 /* Allocate the memory for F1SetupRequest_t */
566 CU_ALLOC(f1apMsg, (Size)sizeof(F1AP_PDU_t));
569 DU_LOG("\nF1AP : Memory allocation for F1AP-PDU failed");
573 f1apMsg->present = F1AP_PDU_PR_successfulOutcome;
575 CU_ALLOC(f1apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcome_t));
576 if(f1apMsg->choice.successfulOutcome == NULLP)
578 DU_LOG("\nF1AP : Memory allocation for F1AP-PDU failed");
579 CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
583 f1apMsg->choice.successfulOutcome->procedureCode = ProcedureCode_id_gNBDUConfigurationUpdate;
584 f1apMsg->choice.successfulOutcome->criticality = Criticality_reject;
585 f1apMsg->choice.successfulOutcome->value.present = SuccessfulOutcome__value_PR_GNBDUConfigurationUpdateAcknowledge;
586 gNBDuCfgAck = &f1apMsg->choice.successfulOutcome->value.choice.GNBDUConfigurationUpdateAcknowledge;
589 gNBDuCfgAck->protocolIEs.list.count = elementCnt;
590 gNBDuCfgAck->protocolIEs.list.size = elementCnt*sizeof(GNBDUConfigurationUpdateAcknowledgeIEs_t);
592 /* Initialize the F1Setup members */
593 CU_ALLOC(gNBDuCfgAck->protocolIEs.list.array, elementCnt * sizeof(GNBDUConfigurationUpdateAcknowledgeIEs_t *));
594 if(gNBDuCfgAck->protocolIEs.list.array == NULLP)
596 DU_LOG("\nF1AP : Memory allocation for DuUpdateAcknowledgeIEs failed");
597 CU_FREE(f1apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcome_t));
598 CU_FREE(f1apMsg,(Size)sizeof(F1AP_PDU_t));
602 for(idx=0; idx<elementCnt; idx++)
604 CU_ALLOC(gNBDuCfgAck->protocolIEs.list.array[idx], sizeof(GNBDUConfigurationUpdateAcknowledgeIEs_t));
605 if(gNBDuCfgAck->protocolIEs.list.array[idx] == NULLP)
607 CU_FREE(gNBDuCfgAck->protocolIEs.list.array, elementCnt * sizeof(GNBDUConfigurationUpdateAcknowledgeIEs_t *));
608 CU_FREE(f1apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcome_t));
609 CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
616 gNBDuCfgAck->protocolIEs.list.array[idx]->id = ProtocolIE_ID_id_TransactionID ;
617 gNBDuCfgAck->protocolIEs.list.array[idx]->criticality = Criticality_reject;
618 gNBDuCfgAck->protocolIEs.list.array[idx]->value.present = GNBDUConfigurationUpdateAcknowledgeIEs__value_PR_TransactionID;
619 gNBDuCfgAck->protocolIEs.list.array[idx]->value.choice.TransactionID = TRANS_ID;
621 xer_fprint(stdout, &asn_DEF_F1AP_PDU, f1apMsg);
623 /* Encode the F1SetupRequest type as UPER */
624 cmMemset((U8 *)encBuf, 0, ENC_BUF_MAX_LEN);
626 enRetVal = aper_encode(&asn_DEF_F1AP_PDU, 0, f1apMsg, PrepFinalEncBuf, encBuf);
629 for(idx=0; idx<elementCnt; idx++)
631 CU_FREE(gNBDuCfgAck->protocolIEs.list.array[idx], sizeof(GNBDUConfigurationUpdateAcknowledgeIEs_t));
633 CU_FREE(gNBDuCfgAck->protocolIEs.list.array, elementCnt * sizeof(GNBDUConfigurationUpdateAcknowledgeIEs_t *));
634 CU_FREE(f1apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcome_t));
635 CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
637 /* Checking encode results */
638 if(enRetVal.encoded == ENCODE_FAIL)
640 DU_LOG("\nF1AP : Could not encode DUConfigUpdateAcknowledge structure (at %s)",enRetVal.failed_type ? enRetVal.failed_type->name : "unknown");
645 DU_LOG("\nF1AP : Created APER encoded buffer for DuConfigUpdateAcknowledge\n");
646 for(int i=0; i< encBufSize; i++)
648 printf("%x",encBuf[i]);
653 if(SendF1APMsg(CU_APP_MEM_REG, CU_POOL) != ROK)
655 DU_LOG("\nF1AP : Sending GNB-DU Config Update Ack failed");
661 }/* End of BuildAndSendDUUpdateAck*/
663 /*******************************************************************
665 * @brief Builds and sends the DLRRCMessageTransfer
669 * Function : BuildAndSendDLRRCMessageTransfer
671 * Functionality: Constructs the DL RRC Message Transfer and sends
672 * it to the CU through SCTP.
676 * @return ROK - success
679 * ****************************************************************/
680 S16 BuildAndSendDLRRCMessageTransfer()
686 F1AP_PDU_t *f1apMsg = NULL;
687 DLRRCMessageTransfer_t *dlRRCMsg;
688 asn_enc_rval_t encRetVal; /* Encoder return value */
690 DU_LOG("\n F1AP : Building DL RRC Message Transfer Message\n");
692 CU_ALLOC(f1apMsg, sizeof(F1AP_PDU_t));
695 DU_LOG(" F1AP : Memory allocation for F1AP-PDU failed");
699 f1apMsg->present = F1AP_PDU_PR_initiatingMessage;
700 CU_ALLOC(f1apMsg->choice.initiatingMessage,
701 sizeof(InitiatingMessage_t));
702 if(f1apMsg->choice.initiatingMessage == NULLP)
704 DU_LOG(" F1AP : Memory allocation for F1AP-PDU failed");
705 CU_FREE(f1apMsg,sizeof(F1AP_PDU_t));
709 f1apMsg->choice.initiatingMessage->procedureCode = \
710 ProcedureCode_id_DLRRCMessageTransfer;
711 f1apMsg->choice.initiatingMessage->criticality = Criticality_ignore;
712 f1apMsg->choice.initiatingMessage->value.present = \
713 InitiatingMessage__value_PR_DLRRCMessageTransfer;
715 &f1apMsg->choice.initiatingMessage->value.choice.DLRRCMessageTransfer;
717 dlRRCMsg->protocolIEs.list.count = elementCnt;
718 dlRRCMsg->protocolIEs.list.size = \
719 elementCnt * sizeof(DLRRCMessageTransferIEs_t *);
721 /* Initialize the F1Setup members */
722 CU_ALLOC(dlRRCMsg->protocolIEs.list.array, \
723 elementCnt * sizeof(DLRRCMessageTransferIEs_t *));
724 if(dlRRCMsg->protocolIEs.list.array == NULLP)
726 DU_LOG(" F1AP : Memory allocation for DL RRC MessageTransferIEs failed");
727 CU_FREE(f1apMsg->choice.initiatingMessage,
728 sizeof(InitiatingMessage_t));
729 CU_FREE(f1apMsg,(Size)sizeof(F1AP_PDU_t));
733 for(idx=0; idx<elementCnt; idx++)
735 CU_ALLOC(dlRRCMsg->protocolIEs.list.array[idx],\
736 sizeof(DLRRCMessageTransferIEs_t));
737 if(dlRRCMsg->protocolIEs.list.array[idx] == NULLP)
739 for(ieId=0; ieId<idx; ieId++)
741 CU_FREE(dlRRCMsg->protocolIEs.list.array[ieId],\
742 sizeof(DLRRCMessageTransferIEs_t));
744 CU_FREE(dlRRCMsg->protocolIEs.list.array,\
745 elementCnt * sizeof(DLRRCMessageTransferIEs_t *));
746 CU_FREE(f1apMsg->choice.initiatingMessage,\
747 sizeof(InitiatingMessage_t));
748 CU_FREE(f1apMsg,sizeof(F1AP_PDU_t));
755 /*GNB CU UE F1AP ID*/
756 dlRRCMsg->protocolIEs.list.array[idx]->id = \
757 ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
758 dlRRCMsg->protocolIEs.list.array[idx]->criticality = Criticality_reject;
759 dlRRCMsg->protocolIEs.list.array[idx]->value.present = \
760 DLRRCMessageTransferIEs__value_PR_GNB_CU_UE_F1AP_ID;
761 dlRRCMsg->protocolIEs.list.array[idx]->value.choice.GNB_CU_UE_F1AP_ID = CU_ID;
763 /*GNB DU UE F1AP ID*/
765 dlRRCMsg->protocolIEs.list.array[idx]->id = \
766 ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
767 dlRRCMsg->protocolIEs.list.array[idx]->criticality = Criticality_reject;
768 dlRRCMsg->protocolIEs.list.array[idx]->value.present = \
769 DLRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID;
770 dlRRCMsg->protocolIEs.list.array[idx]->value.choice.GNB_DU_UE_F1AP_ID = DU_ID;
774 dlRRCMsg->protocolIEs.list.array[idx]->id = \
775 ProtocolIE_ID_id_SRBID;
776 dlRRCMsg->protocolIEs.list.array[idx]->criticality = Criticality_reject;
777 dlRRCMsg->protocolIEs.list.array[idx]->value.present = \
778 DLRRCMessageTransferIEs__value_PR_SRBID;
779 dlRRCMsg->protocolIEs.list.array[idx]->value.choice.SRBID = DL_SRBID;
784 xer_fprint(stdout, &asn_DEF_F1AP_PDU, f1apMsg);
786 /* Encode the F1SetupRequest type as APER */
787 cmMemset((U8 *)encBuf, 0, ENC_BUF_MAX_LEN);
789 encRetVal = aper_encode(&asn_DEF_F1AP_PDU, 0, f1apMsg, PrepFinalEncBuf,\
792 if(encRetVal.encoded == ENCODE_FAIL)
794 DU_LOG( "\n F1AP : Could not encode DL RRC Message Transfer structure (at %s)\n",\
795 encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
800 DU_LOG("\n F1AP : Created APER encoded buffer for DL RRC Message transfer\n");
801 for(int i=0; i< encBufSize; i++)
803 printf("%x",encBuf[i]);
808 if(SendF1APMsg(CU_APP_MEM_REG,CU_POOL) != ROK)
810 DU_LOG("\n F1AP : Sending DL RRC Message Transfer Failed");
815 }/* End of BuildAndSendDLRRCMessageTransfer */
818 /*******************************************************************
820 * @brief Builds and sends the UE Setup Response
824 * Function : BuildAndSendUESetRsp
826 * Functionality: Constructs the UE Setup Response and sends
827 * it to the DU through SCTP.
831 * @return ROK - success
834 * ****************************************************************/
835 S16 BuildAndSendUESetRsp()
844 F1AP_PDU_t *f1apMsg = NULL;
845 UEContextSetupResponse_t *ueSetRsp;
846 asn_enc_rval_t encRetVal; /* Encoder return value */
848 DU_LOG("\n F1AP : Building UE Context Setup Response\n");
850 CU_ALLOC(f1apMsg, sizeof(F1AP_PDU_t));
853 DU_LOG(" F1AP : Memory allocation for F1AP-PDU failed");
857 f1apMsg->present = F1AP_PDU_PR_successfulOutcome;
858 CU_ALLOC(f1apMsg->choice.successfulOutcome,
859 sizeof(SuccessfulOutcome_t));
860 if(f1apMsg->choice.successfulOutcome == NULLP)
862 DU_LOG(" F1AP : Memory allocation for F1AP-PDU failed");
863 CU_FREE(f1apMsg,sizeof(F1AP_PDU_t));
867 f1apMsg->choice.successfulOutcome->procedureCode = \
868 ProcedureCode_id_UEContextSetup;
869 f1apMsg->choice.successfulOutcome->criticality = Criticality_reject;
870 f1apMsg->choice.successfulOutcome->value.present = \
871 SuccessfulOutcome__value_PR_UEContextSetupResponse;
873 &f1apMsg->choice.successfulOutcome->value.choice.UEContextSetupResponse;
875 ueSetRsp->protocolIEs.list.count = elementCnt;
876 ueSetRsp->protocolIEs.list.size = \
877 elementCnt * sizeof(UEContextSetupResponse_t *);
879 /* Initialize the UESetup members */
880 CU_ALLOC(ueSetRsp->protocolIEs.list.array, \
881 ueSetRsp->protocolIEs.list.size);
882 if(ueSetRsp->protocolIEs.list.array == NULLP)
884 DU_LOG(" F1AP : Memory allocation for UE Setup Response failed");
885 CU_FREE(f1apMsg->choice.successfulOutcome,
886 sizeof(SuccessfulOutcome_t));
887 CU_FREE(f1apMsg,(Size)sizeof(F1AP_PDU_t));
891 for(idx=0; idx<elementCnt; idx++)
893 CU_ALLOC(ueSetRsp->protocolIEs.list.array[idx],\
894 sizeof(UEContextSetupResponseIEs_t));
895 if(ueSetRsp->protocolIEs.list.array[idx] == NULLP)
897 for(ieId=0; ieId<idx; ieId++)
899 CU_FREE(ueSetRsp->protocolIEs.list.array[ieId],\
900 sizeof(UEContextSetupResponseIEs_t));
902 CU_FREE(ueSetRsp->protocolIEs.list.array,\
903 ueSetRsp->protocolIEs.list.size);
904 CU_FREE(f1apMsg->choice.successfulOutcome,\
905 sizeof(SuccessfulOutcome_t));
906 CU_FREE(f1apMsg,sizeof(F1AP_PDU_t));
913 /*GNB CU UE F1AP ID*/
914 ueSetRsp->protocolIEs.list.array[idx]->id = \
915 ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
916 ueSetRsp->protocolIEs.list.array[idx]->criticality = Criticality_reject;
917 ueSetRsp->protocolIEs.list.array[idx]->value.present = \
918 UEContextSetupResponseIEs__value_PR_GNB_CU_UE_F1AP_ID;
919 ueSetRsp->protocolIEs.list.array[idx]->value.choice.GNB_CU_UE_F1AP_ID = CU_ID;
921 /*GNB DU UE F1AP ID*/
923 ueSetRsp->protocolIEs.list.array[idx]->id = \
924 ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
925 ueSetRsp->protocolIEs.list.array[idx]->criticality = Criticality_reject;
926 ueSetRsp->protocolIEs.list.array[idx]->value.present = \
927 UEContextSetupResponseIEs__value_PR_GNB_DU_UE_F1AP_ID;
928 ueSetRsp->protocolIEs.list.array[idx]->value.choice.GNB_DU_UE_F1AP_ID = DU_ID;
931 xer_fprint(stdout, &asn_DEF_F1AP_PDU, f1apMsg);
933 /* Encode the F1SetupRequest type as APER */
934 cmMemset((U8 *)encBuf, 0, ENC_BUF_MAX_LEN);
936 encRetVal = aper_encode(&asn_DEF_F1AP_PDU, 0, f1apMsg, PrepFinalEncBuf,\
939 if(encRetVal.encoded == ENCODE_FAIL)
941 DU_LOG( "\n F1AP : Could not encode UE Context Setup Request structure (at %s)\n",\
942 encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
947 DU_LOG("\n F1AP : Created APER encoded buffer for UE Context Setup Request\n");
948 for(int i=0; i< encBufSize; i++)
950 printf("%x",encBuf[i]);
955 if(SendF1APMsg(CU_APP_MEM_REG,CU_POOL) != ROK)
957 DU_LOG("\n F1AP : Sending UE Context Setup Request Failed");
962 }/* End of BuildAndSendUESetRsp */
963 /*******************************************************************
965 * @brief Handles received F1AP message and sends back response
969 * Function : F1APMsgHdlr
972 * - Decodes received F1AP control message
973 * - Prepares response message, encodes and sends to SCTP
976 * @return ROK - success
979 * ****************************************************************/
980 void F1APMsgHdlr(Buffer *mBuf)
987 asn_dec_rval_t rval; /* Decoder return value */
988 F1AP_PDU_t f1apasnmsg ;
990 DU_LOG("\nF1AP : Received F1AP message buffer");
993 /* Copy mBuf into char array to decode it */
994 SFndLenMsg(mBuf, &recvBufLen);
995 if(SGetSBuf(DFLT_REGION, DFLT_POOL, (Data **)&recvBuf, (Size)recvBufLen) != ROK)
997 DU_LOG("\nF1AP : Memory allocation failed");
1000 if(SCpyMsgFix(mBuf, 0, recvBufLen, (Data *)recvBuf, ©Cnt) != ROK)
1002 DU_LOG("\nF1AP : Failed while copying %d", copyCnt);
1006 printf("\nF1AP : Received flat buffer to be decoded : ");
1007 for(i=0; i< recvBufLen; i++)
1009 printf("%x",recvBuf[i]);
1012 /* Decoding flat buffer into F1AP messsage */
1013 f1apMsg = &f1apasnmsg;
1014 memset(f1apMsg, 0, sizeof(F1AP_PDU_t));
1016 rval = aper_decode(0, &asn_DEF_F1AP_PDU, (void **)&f1apMsg, recvBuf, recvBufLen, 0, 0);
1017 SPutSBuf(DFLT_REGION, DFLT_POOL, (Data *)recvBuf, (Size)recvBufLen);
1018 if(rval.code == RC_FAIL || rval.code == RC_WMORE)
1020 DU_LOG("\nF1AP : ASN decode failed");
1024 xer_fprint(stdout, &asn_DEF_F1AP_PDU, f1apMsg);
1026 switch(f1apMsg->present)
1028 case F1AP_PDU_PR_initiatingMessage:
1030 switch(f1apMsg->choice.initiatingMessage->value.present)
1032 case InitiatingMessage__value_PR_F1SetupRequest:
1034 DU_LOG("\nF1AP : F1 setup request received");
1035 BuildAndSendF1SetupRsp();
1039 case InitiatingMessage__value_PR_GNBDUConfigurationUpdate:
1041 DU_LOG("\nF1AP : GNB-DU config update received");
1042 BuildAndSendDUUpdateAck();
1048 DU_LOG("\nF1AP : Invalid type of intiating message [%d]",f1apMsg->choice.initiatingMessage->value.present);
1051 }/* End of switch(initiatingMessage) */
1055 }/* End of switch(f1apMsg->present) */
1057 } /* End of F1APMsgHdlr */
1059 /**********************************************************************
1061 **********************************************************************/