/* * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * * http://www.openairinterface.org/?page_id=698 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *------------------------------------------------------------------------------- * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org */ /*! \file ngap_gNB_management_procedures.c * \brief NGAP gNB task * \author Yoshio INOUE, Masayuki HARADA * \date 2020 * \email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com) * \version 1.0 * @ingroup _ngap */ #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include "intertask_interface.h" #include "assertions.h" #include "conversions.h" #include "ngap_common.h" #include "ngap_gNB_defs.h" #include "ngap_gNB.h" ngap_gNB_internal_data_t ngap_gNB_internal_data; RB_GENERATE(ngap_amf_map, ngap_gNB_amf_data_s, entry, ngap_gNB_compare_assoc_id); int ngap_gNB_compare_assoc_id( struct ngap_gNB_amf_data_s *p1, struct ngap_gNB_amf_data_s *p2) { if (p1->assoc_id == -1) { if (p1->cnx_id < p2->cnx_id) { return -1; } if (p1->cnx_id > p2->cnx_id) { return 1; } } else { if (p1->assoc_id < p2->assoc_id) { return -1; } if (p1->assoc_id > p2->assoc_id) { return 1; } } /* Matching reference */ return 0; } uint16_t ngap_gNB_fetch_add_global_cnx_id(void) { return ++ngap_gNB_internal_data.global_cnx_id; } void ngap_gNB_prepare_internal_data(void) { memset(&ngap_gNB_internal_data, 0, sizeof(ngap_gNB_internal_data)); STAILQ_INIT(&ngap_gNB_internal_data.ngap_gNB_instances_head); } void ngap_gNB_insert_new_instance(ngap_gNB_instance_t *new_instance_p) { DevAssert(new_instance_p != NULL); STAILQ_INSERT_TAIL(&ngap_gNB_internal_data.ngap_gNB_instances_head, new_instance_p, ngap_gNB_entries); } struct ngap_gNB_amf_data_s *ngap_gNB_get_AMF( ngap_gNB_instance_t *instance_p, int32_t assoc_id, uint16_t cnx_id) { struct ngap_gNB_amf_data_s temp; struct ngap_gNB_amf_data_s *found; memset(&temp, 0, sizeof(struct ngap_gNB_amf_data_s)); temp.assoc_id = assoc_id; temp.cnx_id = cnx_id; if (instance_p == NULL) { STAILQ_FOREACH(instance_p, &ngap_gNB_internal_data.ngap_gNB_instances_head, ngap_gNB_entries) { found = RB_FIND(ngap_amf_map, &instance_p->ngap_amf_head, &temp); if (found != NULL) { return found; } } } else { return RB_FIND(ngap_amf_map, &instance_p->ngap_amf_head, &temp); } return NULL; } struct ngap_gNB_amf_data_s *ngap_gNB_get_AMF_from_instance( ngap_gNB_instance_t *instance_p) { struct ngap_gNB_amf_data_s *amf = NULL; struct ngap_gNB_amf_data_s *amf_next = NULL; for (amf = RB_MIN(ngap_amf_map, &instance_p->ngap_amf_head); amf!=NULL ; amf = amf_next) { amf_next = RB_NEXT(ngap_amf_map, &instance_p->ngap_amf_head, amf); if (amf->ngap_gNB_instance == instance_p) { return amf; } } return NULL; } ngap_gNB_instance_t *ngap_gNB_get_instance(instance_t instance) { ngap_gNB_instance_t *temp = NULL; STAILQ_FOREACH(temp, &ngap_gNB_internal_data.ngap_gNB_instances_head, ngap_gNB_entries) { if (temp->instance == instance) { /* Matching occurence */ return temp; } } return NULL; } void ngap_gNB_remove_amf_desc(ngap_gNB_instance_t * instance) { struct ngap_gNB_amf_data_s *amf = NULL; struct ngap_gNB_amf_data_s *amfNext = NULL; struct plmn_identity_s* plmnInfo; struct served_region_id_s* regionInfo; struct served_guami_s* guamInfo; struct amf_set_id_s* amfSet; struct amf_pointer_s* amfPoint; for (amf = RB_MIN(ngap_amf_map, &instance->ngap_amf_head); amf; amf = amfNext) { amfNext = RB_NEXT(ngap_amf_map, &instance->ngap_amf_head, amf); RB_REMOVE(ngap_amf_map, &instance->ngap_amf_head, amf); while (!STAILQ_EMPTY(&amf->served_guami)) { guamInfo = STAILQ_FIRST(&amf->served_guami); STAILQ_REMOVE_HEAD(&amf->served_guami, next); while (!STAILQ_EMPTY(&guamInfo->served_plmns)) { plmnInfo = STAILQ_FIRST(&guamInfo->served_plmns); STAILQ_REMOVE_HEAD(&guamInfo->served_plmns, next); free(plmnInfo); } while (!STAILQ_EMPTY(&guamInfo->served_region_ids)) { regionInfo = STAILQ_FIRST(&guamInfo->served_region_ids); STAILQ_REMOVE_HEAD(&guamInfo->served_region_ids, next); free(regionInfo); } while (!STAILQ_EMPTY(&guamInfo->amf_set_ids)) { amfSet = STAILQ_FIRST(&guamInfo->amf_set_ids); STAILQ_REMOVE_HEAD(&guamInfo->amf_set_ids, next); free(amfSet); } while (!STAILQ_EMPTY(&guamInfo->amf_pointers)) { amfPoint = STAILQ_FIRST(&guamInfo->amf_pointers); STAILQ_REMOVE_HEAD(&guamInfo->amf_pointers, next); free(amfPoint); } free(guamInfo); } free(amf); } }