Files
openairinterface5g/openair2/ENB_APP/enb_config.c
T
2014-01-31 15:53:58 +00:00

280 lines
13 KiB
C
Executable File

/*******************************************************************************
Eurecom OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information
Openair Admin: openair_admin@eurecom.fr
Openair Tech : openair_tech@eurecom.fr
Forums : http://forums.eurecom.fr/openairinterface
Address : EURECOM, Campus SophiaTech, 450 Route des Chappes
06410 Biot FRANCE
*******************************************************************************/
#include <string.h>
#include <libconfig.h>
#include "log.h"
#include "assertions.h"
#include "enb_config.h"
#if defined(OAI_EMU)
# include "OCG.h"
# include "OCG_extern.h"
#endif
#if defined(ENABLE_ITTI)
# include "intertask_interface.h"
# if defined(ENABLE_USE_MME)
# include "s1ap_eNB.h"
# include "sctp_eNB_task.h"
# endif
#endif
#include "LAYER2/MAC/extern.h"
int enb_config_init(char* lib_config_file_name_pP, Enb_properties_t **enb_properties) {
config_t cfg;
config_setting_t *setting;
config_setting_t *setting_mme_addresses;
config_setting_t *setting_mme_address;
config_setting_t *setting_enb;
int num_enb_properties = 0;
int enb_properties_index = 0;
int num_enbs;
int num_mme_address;
int i;
int j;
int parse_error = 0;
long int enb_id;
const char* cell_type;
long int tac;
const char* enb_name;
long int mcc;
long int mnc;
const char* default_drx;
const char* frame_type;
const char* prefix_type;
long long int downlink_frequency;
long int uplink_frequency_offset;
char* ipv4;
char* ipv6;
char* active;
char* preference;
const char* active_enb[MAX_ENB];
memset((char*)enb_properties, 0 , MAX_ENB * sizeof(Enb_properties_t*));
memset((char*)active_enb, 0 , MAX_ENB * sizeof(char*));
config_init(&cfg);
if(lib_config_file_name_pP != NULL)
{
/* Read the file. If there is an error, report it and exit. */
if(! config_read_file(&cfg, lib_config_file_name_pP))
{
LOG_E(ENB_APP, "%s:%d - %s\n", lib_config_file_name_pP, config_error_line(&cfg), config_error_text(&cfg));
config_destroy(&cfg);
AssertFatal (0, "Failed to parse eNB configuration file %s!\n", lib_config_file_name_pP);
}
}
else
{
LOG_E(ENB_APP, "No eNB configuration file provided!\n");
config_destroy(&cfg);
AssertFatal (0, "No eNB configuration file provided!\n");
}
// Get list of active eNBs, (only these will be configured)
setting = config_lookup(&cfg, ENB_CONFIG_STRING_ACTIVE_ENBS);
if(setting != NULL)
{
num_enbs = config_setting_length(setting);
for (i = 0; i < num_enbs; i++) {
setting_enb = config_setting_get_elem(setting, i);
active_enb[i] = config_setting_get_string (setting_enb);
AssertFatal (active_enb[i] != NULL,
"Failed to parse config file %s, %uth attribute %s \n",
lib_config_file_name_pP, i, ENB_CONFIG_STRING_ACTIVE_ENBS);
active_enb[i] = strdup(active_enb[i]);
num_enb_properties += 1;
}
}
/* Output a list of all eNBs. */
setting = config_lookup(&cfg, ENB_CONFIG_STRING_ENB_LIST);
if(setting != NULL)
{
enb_properties_index = 0;
parse_error = 0;
num_enbs = config_setting_length(setting);
for (i = 0; i < num_enbs; i++) {
setting_enb = config_setting_get_elem(setting, i);
if(! config_setting_lookup_int(setting_enb, ENB_CONFIG_STRING_ENB_ID, &enb_id)) {
/* Calculate a default eNB ID */
# if defined(ENABLE_USE_MME)
uint32_t hash;
hash = s1ap_generate_eNB_id ();
enb_id = i + (hash & 0xFFFF8);
# else
enb_id = i;
# endif
}
if( !( config_setting_lookup_string(setting_enb, ENB_CONFIG_STRING_CELL_TYPE, &cell_type)
&& config_setting_lookup_string(setting_enb, ENB_CONFIG_STRING_ENB_NAME, &enb_name)
&& config_setting_lookup_int (setting_enb, ENB_CONFIG_STRING_TRACKING_AREA_CODE, &tac)
&& config_setting_lookup_int (setting_enb, ENB_CONFIG_STRING_MOBILE_COUNTRY_CODE, &mcc)
&& config_setting_lookup_int (setting_enb, ENB_CONFIG_STRING_MOBILE_NETWORK_CODE, &mnc)
&& config_setting_lookup_string(setting_enb, ENB_CONFIG_STRING_DEFAULT_PAGING_DRX, &default_drx)
)
) {
AssertError (0, parse_error ++,
"Failed to parse eNB configuration file %s, %u th enb\n",
lib_config_file_name_pP, i);
}
// search if in active list
for (j=0; j < num_enb_properties; j++) {
if (strcmp(active_enb[j], enb_name) == 0) {
enb_properties[enb_properties_index] = calloc(1, sizeof(Enb_properties_t));
enb_properties[enb_properties_index]->eNB_id = enb_id;
if (strcmp(cell_type, "CELL_MACRO_ENB") == 0) {
enb_properties[enb_properties_index]->cell_type = CELL_MACRO_ENB;
} else if (strcmp(cell_type, "CELL_HOME_ENB") == 0) {
enb_properties[enb_properties_index]->cell_type = CELL_HOME_ENB;
} else {
AssertError (0, parse_error ++,
"Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for cell_type choice: CELL_MACRO_ENB or CELL_HOME_ENB !\n",
lib_config_file_name_pP, i, cell_type);
}
enb_properties[enb_properties_index]->eNB_name = strdup(enb_name);
enb_properties[enb_properties_index]->tac = (uint16_t)tac;
enb_properties[enb_properties_index]->mcc = (uint16_t)mcc;
enb_properties[enb_properties_index]->mnc = (uint16_t)mnc;
if (strcmp(default_drx, "PAGING_DRX_32") == 0) {
enb_properties[enb_properties_index]->default_drx = PAGING_DRX_32;
} else if (strcmp(default_drx, "PAGING_DRX_64") == 0) {
enb_properties[enb_properties_index]->default_drx = PAGING_DRX_64;
} else if (strcmp(default_drx, "PAGING_DRX_128") == 0) {
enb_properties[enb_properties_index]->default_drx = PAGING_DRX_128;
} else if (strcmp(default_drx, "PAGING_DRX_256") == 0) {
enb_properties[enb_properties_index]->default_drx = PAGING_DRX_256;
} else {
AssertError (0, parse_error ++,
"Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for default_drx choice: PAGING_DRX_32..PAGING_DRX_256 !\n",
lib_config_file_name_pP, i, default_drx);
}
// Parse optional physical parameters
if(config_setting_lookup_string(setting_enb, ENB_CONFIG_STRING_FRAME_TYPE, &frame_type)) {
if (strcmp(frame_type, "FDD") == 0) {
enb_properties[enb_properties_index]->frame_type = FDD;
} else if (strcmp(frame_type, "TDD") == 0) {
enb_properties[enb_properties_index]->frame_type = TDD;
} else {
AssertError (0, parse_error ++,
"Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for frame_type choice: FDD or TDD !\n",
lib_config_file_name_pP, i, frame_type);
}
} else {
enb_properties[enb_properties_index]->frame_type = FDD; // Default frame type
}
if(config_setting_lookup_string(setting_enb, ENB_CONFIG_STRING_PREFIX_TYPE, &prefix_type)) {
if (strcmp(prefix_type, "NORMAL") == 0) {
enb_properties[enb_properties_index]->prefix_type = NORMAL;
} else if (strcmp(prefix_type, "EXTENDED") == 0) {
enb_properties[enb_properties_index]->prefix_type = EXTENDED;
} else {
AssertError (0, parse_error ++,
"Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for prefix_type choice: NORMAL or EXTENDED !\n",
lib_config_file_name_pP, i, prefix_type);
}
} else {
enb_properties[enb_properties_index]->prefix_type = NORMAL; // Default prefix type
}
if(config_setting_lookup_int64(setting_enb, ENB_CONFIG_STRING_DOWNLINK_FREQUENCY, &downlink_frequency)) {
enb_properties[enb_properties_index]->downlink_frequency = downlink_frequency;
} else {
enb_properties[enb_properties_index]->downlink_frequency = 2680000000UL; // Default downlink frequency
}
if(config_setting_lookup_int(setting_enb, ENB_CONFIG_STRING_UPLINK_FREQUENCY_OFFSET, &uplink_frequency_offset)) {
enb_properties[enb_properties_index]->uplink_frequency_offset = uplink_frequency_offset;
} else {
enb_properties[enb_properties_index]->uplink_frequency_offset = -120000000; // Default uplink frequency offset
}
setting_mme_addresses = config_setting_get_member (setting_enb, ENB_CONFIG_STRING_MME_IP_ADDRESS);
num_mme_address = config_setting_length(setting_mme_addresses);
enb_properties[enb_properties_index]->nb_mme = 0;
for (j = 0; j < num_mme_address; j++) {
setting_mme_address = config_setting_get_elem(setting_mme_addresses, j);
if( !(
config_setting_lookup_string(setting_mme_address, ENB_CONFIG_STRING_MME_IPV4_ADDRESS, (const char **)&ipv4)
&& config_setting_lookup_string(setting_mme_address, ENB_CONFIG_STRING_MME_IPV6_ADDRESS, (const char **)&ipv6)
&& config_setting_lookup_string(setting_mme_address, ENB_CONFIG_STRING_MME_IP_ADDRESS_ACTIVE, (const char **)&active)
&& config_setting_lookup_string(setting_mme_address, ENB_CONFIG_STRING_MME_IP_ADDRESS_PREFERENCE, (const char **)&preference)
)
) {
AssertError (0, parse_error ++,
"Failed to parse eNB configuration file %s, %u th enb %u th mme address !\n",
lib_config_file_name_pP, i, j);
}
enb_properties[enb_properties_index]->nb_mme += 1;
enb_properties[enb_properties_index]->mme_ip_address[j].ipv4_address = strdup(ipv4);
enb_properties[enb_properties_index]->mme_ip_address[j].ipv6_address = strdup(ipv6);
if (strcmp(active, "yes") == 0) {
enb_properties[enb_properties_index]->mme_ip_address[j].active = 1;
#if defined(ENABLE_USE_MME)
EPC_MODE_ENABLED = 1;
#endif
} // else { (calloc)
if (strcmp(preference, "ipv4") == 0) {
enb_properties[enb_properties_index]->mme_ip_address[j].ipv4 = 1;
} else if (strcmp(preference, "ipv6") == 0) {
enb_properties[enb_properties_index]->mme_ip_address[j].ipv6 = 1;
} else if (strcmp(preference, "no") == 0) {
enb_properties[enb_properties_index]->mme_ip_address[j].ipv4 = 1;
enb_properties[enb_properties_index]->mme_ip_address[j].ipv6 = 1;
}
}
enb_properties_index += 1;
break;
}
}
}
}
AssertError (enb_properties_index == num_enb_properties, parse_error ++,
"Failed to parse eNB configuration file %s, mismatch between %u active eNBs and %u corresponding defined eNBs !\n",
lib_config_file_name_pP, num_enb_properties, enb_properties_index);
AssertFatal (parse_error == 0,
"Failed to parse eNB configuration file %s, found %d error%s !\n",
lib_config_file_name_pP, parse_error, parse_error > 1 ? "s" : "");
return num_enb_properties;
}