Commit 41457d64 authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

Merge branch 'nrf' into 'develop'

Merge Nrf into develop

See merge request oai/cn5g/oai-cn5g-amf!10
parents bdf698a1 58c1bfb9
......@@ -34,8 +34,8 @@ AMF_CONF[@SD_0@]='123'
AMF_CONF[@SST_1@]='1'
AMF_CONF[@SD_1@]='12'
AMF_CONF[@AMF_INTERFACE_NAME_FOR_NGAP@]='ens3'
AMF_CONF[@AMF_INTERFACE_NAME_FOR_N11@]='ens3'
AMF_CONF[@AMF_INTERFACE_NAME_FOR_NGAP@]='enx0050b6f4ba5b'
AMF_CONF[@AMF_INTERFACE_NAME_FOR_N11@]='enx0050b6f4ba5b'
AMF_CONF[@SMF_INSTANCE_ID_0@]='1'
AMF_CONF[@SMF_IPV4_ADDR_0@]='192.168.122.1'
......@@ -44,6 +44,13 @@ AMF_CONF[@SMF_INSTANCE_ID_1@]='2'
AMF_CONF[@SMF_IPV4_ADDR_1@]='192.168.122.2'
AMF_CONF[@SMF_HTTP_VERSION_1@]='v1'
AMF_CONF[@NRF_IPV4_ADDRESS@]='192.168.1.23'
AMF_CONF[@NRF_PORT@]='80'
AMF_CONF[@NRF_API_VERSION@]='v1'
AMF_CONF[@AUSF_IPV4_ADDRESS@]='192.168.1.23'
AMF_CONF[@AUSF_PORT@]='80'
AMF_CONF[@AUSF_API_VERSION@]='v1'
AMF_CONF[@MYSQL_SERVER@]='127.0.0.1'
AMF_CONF[@MYSQL_USER@]='root'
......
......@@ -66,20 +66,45 @@ AMF =
PPID = 60; # YOUR NETWORK CONFIG HERE
};
# AMF binded interface for N11
# AMF binded interface for SBI (N11 (SMF)/N12 (AUSF), etc.)
N11:
{
INTERFACE_NAME = "@AMF_INTERFACE_NAME_FOR_N11@"; # YOUR NETWORK CONFIG HERE
IPV4_ADDRESS = "read";
PORT = 80; # YOUR NETWORK CONFIG HERE
API_VERSION = "v1"; # YOUR AMF API VERSION CONFIG HERE
SMF_INSTANCES_POOL = (
{SMF_INSTANCE_ID = @SMF_INSTANCE_ID_0@; IPV4_ADDRESS = "@SMF_IPV4_ADDR_0@"; PORT = "80"; VERSION = "@SMF_HTTP_VERSION_0@"; SELECTED = "true"}, # YOUR SMF CONFIG HERE
{SMF_INSTANCE_ID = @SMF_INSTANCE_ID_1@; IPV4_ADDRESS = "@SMF_IPV4_ADDR_1@"; PORT = "80"; VERSION = "@SMF_HTTP_VERSION_1@"; SELECTED = "false"} # YOUR SMF CONFIG HERE
);
};
NRF :
{
IPV4_ADDRESS = "192.168.66.9"; # "@NRF_IPV4_ADDRESS@"; # YOUR NRF CONFIG HERE
PORT = 80; # @NRF_PORT@; # YOUR NRF CONFIG HERE (default: 80)
API_VERSION = "v1"; # "@NRF_API_VERSION@"; # YOUR NRF API VERSION FOR SBI CONFIG HERE
};
AUSF :
{
IPV4_ADDRESS = "192.168.66.10"; # "@AUSF_IPV4_ADDRESS@"; # YOUR AUSF CONFIG HERE
PORT = 80; # @AUSF_PORT@; # YOUR AUSF CONFIG HERE (default: 80)
API_VERSION = "v1"; # "@AUSF_API_VERSION@"; # YOUR AUSF API VERSION FOR SBI CONFIG HERE
};
};
SUPPORT_FEATURES:
{
# STRING, {"yes", "no"},
NF_REGISTRATION = "no"; # Set to yes if AMF resgisters to an NRF
SMF_SELECTION = "no"; # Set to yes to enable SMF discovery and selection
EXTERNAL_AUSF = "no"; # Set to yes if AMF works with an external AUSF
EXTERNAL_UDM = "no"; # Set to yes if AMF works with an external UDM
}
AUTHENTICATION:
{
......
################################################################################
# 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
################################################################################
AMF =
{
INSTANCE_ID = 1; # 0 is the default
PID_DIRECTORY = "/var/run"; # /var/run is the default
AMF_NAME = "OAI-AMF";
RELATIVE_CAPACITY = 30;
# Display statistics about whole system (in seconds)
STATISTICS_TIMER_INTERVAL = 20; # YOUR CONFIG HERE
CORE_CONFIGURATION:
{
EMERGENCY_SUPPORT = "false";
};
GUAMI:
{
MCC = "208"; MNC = "95"; RegionID = "128"; AMFSetID = "1"; AMFPointer = "1" # YOUR GUAMI CONFIG HERE
}
SERVED_GUAMI_LIST = (
{MCC = "208"; MNC = "95"; RegionID = "128"; AMFSetID = "1"; AMFPointer = "0"}, #48bits <MCC><MNC><RegionID><AMFSetID><AMFPointer>
{MCC = "460"; MNC = "11"; RegionID = "10"; AMFSetID = "1"; AMFPointer = "1"} #48bits <MCC><MNC><RegionID><AMFSetID><AMFPointer>
);
PLMN_SUPPORT_LIST = (
{
MCC = "208"; MNC = "95"; TAC = 0xa000; # YOUR PLMN CONFIG HERE
SLICE_SUPPORT_LIST = (
{SST = "222"; SD = "123"}, # YOUR NSSAI CONFIG HERE
{SST = "1"; SD = "12"} # YOUR NSSAI CONFIG HERE
)
}
);
INTERFACES:
{
# AMF binded interface for N1/N2 interface (NGAP)
NGAP_AMF:
{
INTERFACE_NAME = "ens3"; # YOUR NETWORK CONFIG HERE
IPV4_ADDRESS = "read";
PORT = 38412; # YOUR NETWORK CONFIG HERE
PPID = 60; # YOUR NETWORK CONFIG HERE
};
# AMF binded interface for N11
N11:
{
INTERFACE_NAME = "ens3"; # YOUR NETWORK CONFIG HERE
IPV4_ADDRESS = "read";
PORT = 80; # YOUR NETWORK CONFIG HERE
SMF_INSTANCES_POOL = (
{SMF_INSTANCE_ID = 1; IPV4_ADDRESS = "192.168.122.1"; PORT = "80"; VERSION = "v1"; SELECTED = "true"}, # YOUR SMF CONFIG HERE
{SMF_INSTANCE_ID = 2; IPV4_ADDRESS = "192.168.122.2"; PORT = "80"; VERSION = "v1"; SELECTED = "false"} # YOUR SMF CONFIG HERE
);
};
};
AUTHENTICATION:
{
## MySQL mandatory options
MYSQL_server = "127.0.0.1"; # MySQL Server address
MYSQL_user = "root"; # Database server login
MYSQL_pass = "linux"; # Database server password
MYSQL_db = "oai_db"; # Your database name
## OP
OPERATOR_key = "63bfa50ee6523365ff14c1f45f88737d"; # OP key matching your database
RANDOM = "true";
};
NAS:
{
ORDERED_SUPPORTED_INTEGRITY_ALGORITHM_LIST = [ "NIA0" , "NIA1" , "NIA2" ];
ORDERED_SUPPORTED_CIPHERING_ALGORITHM_LIST = [ "NEA0" , "NEA1" , "NEA2" ];
};
};
MODULES =
{
NGAP_MESSAGE = (
{MSG_NAME = "NGSetupRequest"; ProcedureCode = 21; TypeOfMessage = "initialMessage"}
);
};
#
# Copyright (c) 2015, EURECOM (www.eurecom.fr)
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# The views and conclusions contained in the software and documentation are those
# of the authors and should not be interpreted as representing official policies,
# either expressed or implied, of the FreeBSD Project.
#
# see https://clang.llvm.org/docs/ClangFormatStyleOptions.html for explanation
# of style options
BasedOnStyle: Google
Language: Cpp
IndentWidth: 2
ColumnLimit: 80
IncludeBlocks: Preserve
SortIncludes: false
# alignment
AlignAfterOpenBracket: AlwaysBreak
AlignConsecutiveAssignments: true
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Right
AlignOperands: true
AlignTrailingComments: true
DerivePointerAlignment: false
PointerAlignment: Left
# function style
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortFunctionsOnASingleLine: Inline
AlwaysBreakAfterReturnType: None
IndentWrappedFunctionNames: false
# template style
AlwaysBreakTemplateDeclarations: Yes
# preprocessor style
IndentPPDirectives: None
# block style
AllowShortBlocksOnASingleLine: false
KeepEmptyLinesAtTheStartOfBlocks: false
# break style
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeTernaryOperators: false
BreakStringLiterals: true
CompactNamespaces: false
ContinuationIndentWidth: 4
MaxEmptyLinesToKeep: 1
ReflowComments: true
# spacing style
UseTab: Never
SpaceAfterCStyleCast: true
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
# class style
BreakConstructorInitializers: BeforeColon
BreakInheritanceList: BeforeColon
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
# case statements
IndentCaseLabels: true
# cpp
Cpp11BracedListStyle: true
FixNamespaceComments: true
NamespaceIndentation: None
SortUsingDeclarations: true
# todo
# AlwaysBreakBeforeMultilineStrings: bool
# PenaltyBreakAssignment (unsigned)
# PenaltyBreakBeforeFirstCallParameter (unsigned)
# PenaltyBreakComment (unsigned)
# PenaltyBreakFirstLessLess (unsigned)
# PenaltyBreakString (unsigned)
# PenaltyBreakTemplateDeclaration (unsigned)
# PenaltyExcessCharacter (unsigned)
# PenaltyReturnTypeOnItsOwnLine (unsigned)
......@@ -55,6 +55,7 @@ file(GLOB AMF_src_files
${CMAKE_CURRENT_SOURCE_DIR}/amf_n1.cpp
${CMAKE_CURRENT_SOURCE_DIR}/amf_n2.cpp
${CMAKE_CURRENT_SOURCE_DIR}/amf_n11.cpp
${CMAKE_CURRENT_SOURCE_DIR}/amf_profile.cpp
${CMAKE_CURRENT_SOURCE_DIR}/amf_statistics.cpp
${CMAKE_CURRENT_SOURCE_DIR}/mysql_db.cpp
${SRC_TOP_DIR}/nas/msgs/*.cpp
......
This diff is collapsed.
......@@ -3,9 +3,9 @@
* 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
* 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
*
......@@ -34,8 +34,10 @@
#include <string>
#include "amf_config.hpp"
#include "amf_module_from_config.hpp"
#include "amf_profile.hpp"
#include "itti_msg_amf_app.hpp"
#include "ue_context.hpp"
#include "itti.hpp"
using namespace config;
......@@ -46,39 +48,93 @@ namespace amf_application {
#define TASK_AMF_APP_PERIODIC_STATISTICS (0)
class amf_app {
private:
amf_profile nf_instance_profile; // AMF profile
std::string amf_instance_id; // AMF instance id
timer_id_t timer_nrf_heartbeat;
public:
explicit amf_app(const amf_config &amf_cfg);
explicit amf_app(const amf_config& amf_cfg);
amf_app(amf_app const&) = delete;
void operator=(amf_app const&) = delete;
void allRegistredModulesInit(const amf_modules &modules);
void allRegistredModulesInit(const amf_modules& modules);
long generate_amf_ue_ngap_id();
//itti handlers
void handle_itti_message(itti_nas_signalling_establishment_request &itti_msg);
void handle_itti_message(itti_n1n2_message_transfer_request &itti_msg);
//context management
// itti handlers
void handle_itti_message(itti_nas_signalling_establishment_request& itti_msg);
void handle_itti_message(itti_n1n2_message_transfer_request& itti_msg);
// context management
std::map<long, std::shared_ptr<ue_context>> amf_ue_ngap_id2ue_ctx;
mutable std::shared_mutex m_amf_ue_ngap_id2ue_ctx;
std::map<std::string, std::shared_ptr<ue_context>> ue_ctx_key;
mutable std::shared_mutex m_ue_ctx_key;
bool is_amf_ue_id_2_ue_context(const long &amf_ue_ngap_id) const;
std::map<std::string, std::shared_ptr<ue_context>> supi2ue_ctx;
mutable std::shared_mutex m_supi2ue_ctx;
bool is_amf_ue_id_2_ue_context(const long& amf_ue_ngap_id) const;
std::shared_ptr<ue_context> amf_ue_id_2_ue_context(
const long &amf_ue_ngap_id) const;
void set_amf_ue_ngap_id_2_ue_context(const long &amf_ue_ngap_id,
std::shared_ptr<ue_context> uc);
const long& amf_ue_ngap_id) const;
void set_amf_ue_ngap_id_2_ue_context(
const long& amf_ue_ngap_id, std::shared_ptr<ue_context> uc);
bool is_ran_amf_id_2_ue_context(const std::string &ue_context_key) const;
bool is_ran_amf_id_2_ue_context(const std::string& ue_context_key) const;
std::shared_ptr<ue_context> ran_amf_id_2_ue_context(
const std::string &ue_context_key) const;
void set_ran_amf_id_2_ue_context(const std::string &ue_context_key,
std::shared_ptr<ue_context> uc);
const std::string& ue_context_key) const;
void set_ran_amf_id_2_ue_context(
const std::string& ue_context_key, std::shared_ptr<ue_context> uc);
bool is_supi_2_ue_context(const string& supi) const;
std::shared_ptr<ue_context> supi_2_ue_context(const string& supi) const;
void set_supi_2_ue_context(
const string& ue_context_key, std::shared_ptr<ue_context>& uc);
bool find_pdu_session_context(
const string& supi, const std::uint8_t pdu_session_id,
std::shared_ptr<pdu_session_context>& psc);
// SMF Client response handlers
void handle_post_sm_context_response_error_400();
//others
bool generate_5g_guti(uint32_t ranid, long amfid, std::string &mcc,
std::string &mnc, uint32_t &tmsi);
// others
bool generate_5g_guti(
uint32_t ranid, long amfid, std::string& mcc, std::string& mnc,
uint32_t& tmsi);
/*
* Trigger NF instance registration to NRF
* @param [void]
* @return void
*/
void register_to_nrf();
/*
* Generate a random UUID for SMF instance
* @param [void]
* @return void
*/
void generate_uuid();
/*
* Generate a SMF profile for this instance
* @param [void]
* @return void
*/
void generate_amf_profile();
/*
* Send request to N11 task to trigger NF instance registration to NRF
* @param [void]
* @return void
*/
void trigger_nf_registration_request();
/*
* Send request to N11 task to trigger NF instance deregistration to NRF
* @param [void]
* @return void
*/
void trigger_nf_deregistration();
};
}
} // namespace amf_application
#endif
This diff is collapsed.
......@@ -3,9 +3,9 @@
* 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
* 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
*
......@@ -45,6 +45,8 @@
#define AMF_CONFIG_STRING_STATISTICS_TIMER_INTERVAL "STATISTICS_TIMER_INTERVAL"
#define AMF_CONFIG_STRING_INTERFACES "INTERFACES"
#define AMF_CONFIG_STRING_INTERFACE_NGAP_AMF "NGAP_AMF"
#define AMF_CONFIG_STRING_INTERFACE_NAUSF "NAUSF"
#define AMF_CONFIG_STRING_INTERFACE_NAME "INTERFACE_NAME"
#define AMF_CONFIG_STRING_IPV4_ADDRESS "IPV4_ADDRESS"
#define AMF_CONFIG_STRING_PORT "PORT"
......@@ -57,6 +59,13 @@
#define AMF_CONFIG_STRING_SMF_INSTANCE_VERSION "VERSION"
#define AMF_CONFIG_STRING_SMF_INSTANCE_SELECTED "SELECTED"
#define AMF_CONFIG_STRING_NRF "NRF"
#define AMF_CONFIG_STRING_NRF_IPV4_ADDRESS "IPV4_ADDRESS"
#define AMF_CONFIG_STRING_NRF_PORT "PORT"
#define AMF_CONFIG_STRING_API_VERSION "API_VERSION"
#define AMF_CONFIG_STRING_AUSF "AUSF"
#define AMF_CONFIG_STRING_SCHED_PARAMS "SCHED_PARAMS"
#define AMF_CONFIG_STRING_THREAD_RD_CPU_ID "CPU_ID"
#define AMF_CONFIG_STRING_THREAD_RD_SCHED_POLICY "SCHED_POLICY"
......@@ -86,8 +95,15 @@
#define AMF_CONFIG_STRING_AUTH_OPERATOR_KEY "OPERATOR_key"
#define AMF_CONFIG_STRING_AUTH_RANDOM "RANDOM"
#define AMF_CONFIG_STRING_NAS "NAS"
#define AMF_CONFIG_STRING_NAS_SUPPORTED_INTEGRITY_ALGORITHM_LIST "ORDERED_SUPPORTED_INTEGRITY_ALGORITHM_LIST"
#define AMF_CONFIG_STRING_NAS_SUPPORTED_CIPHERING_ALGORITHM_LIST "ORDERED_SUPPORTED_CIPHERING_ALGORITHM_LIST"
#define AMF_CONFIG_STRING_NAS_SUPPORTED_INTEGRITY_ALGORITHM_LIST \
"ORDERED_SUPPORTED_INTEGRITY_ALGORITHM_LIST"
#define AMF_CONFIG_STRING_NAS_SUPPORTED_CIPHERING_ALGORITHM_LIST \
"ORDERED_SUPPORTED_CIPHERING_ALGORITHM_LIST"
#define AMF_CONFIG_STRING_SUPPORT_FEATURES "SUPPORT_FEATURES"
#define AMF_CONFIG_STRING_SUPPORT_FEATURES_NF_REGISTRATION "NF_REGISTRATION"
#define AMF_CONFIG_STRING_SUPPORT_FEATURES_SMF_SELECTION "SMF_SELECTION"
#define AMF_CONFIG_STRING_SUPPORT_FEATURES_EXTERNAL_AUSF "EXTERNAL_AUSF"
#define AMF_CONFIG_STRING_SUPPORT_FEATURES_EXTERNAL_UDM "EXTERNAL_UDM"
using namespace libconfig;
......@@ -109,7 +125,6 @@ typedef struct interface_cfg_s {
struct in6_addr addr6;
unsigned int mtu;
unsigned int port;
util::thread_sched_params thread_rd_sched_params;
} interface_cfg_t;
typedef struct itti_cfg_s {
......@@ -157,17 +172,17 @@ class amf_config {
public:
amf_config();
~amf_config();
int load(const std::string &config_file);
int load_interface(const Setting &if_cfg, interface_cfg_t &cfg);
int load_thread_sched_params(
const libconfig::Setting &thread_sched_params_cfg,
util::thread_sched_params &cfg);
int load(const std::string& config_file);
int load_interface(const Setting& if_cfg, interface_cfg_t& cfg);
void display();
unsigned int instance;
std::string pid_dir;
interface_cfg_t n2;
interface_cfg_t n11;
interface_cfg_t nausf;
itti_cfg_t itti;
std::string sbi_api_version;
unsigned int statistics_interval;
std::string AMF_Name;
guami_t guami;
......@@ -178,8 +193,24 @@ class amf_config {
auth_conf auth_para;
nas_conf_t nas_cfg;
std::vector<smf_inst_t> smf_pool;
bool enable_nf_registration;
bool enable_smf_selection;
bool enable_external_ausf;
bool enable_external_udm;
struct {
struct in_addr ipv4_addr;
unsigned int port;
std::string api_version;
} nrf_addr;
struct {
struct in_addr ipv4_addr;
unsigned int port;
std::string api_version;
} ausf_addr;
};
}
} // namespace config
#endif
......@@ -3,9 +3,9 @@
* 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
* 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
*
......@@ -36,41 +36,44 @@
namespace config {
//------------------------------------------------------------------------------
int amf_modules::load(const std::string &config_file) {
Logger::amf_app().debug("\nLoad AMF module configuration file (%s)",
config_file.c_str());
int amf_modules::load(const std::string& config_file) {
Logger::amf_app().debug(
"\nLoad AMF module configuration file (%s)", config_file.c_str());
Config cfg;
try {
cfg.readFile(config_file.c_str());
} catch (const FileIOException &fioex) {
Logger::amf_app().error("I/O error while reading file %s - %s",
config_file.c_str(), fioex.what());
} catch (const FileIOException& fioex) {
Logger::amf_app().error(
"I/O error while reading file %s - %s", config_file.c_str(),
fioex.what());
throw;
} catch (const ParseException &pex) {
Logger::amf_app().error("Parse error at %s:%d - %s", pex.getFile(),
pex.getLine(), pex.getError());
} catch (const ParseException& pex) {
Logger::amf_app().error(
"Parse error at %s:%d - %s", pex.getFile(), pex.getLine(),
pex.getError());
throw;
}
const Setting &root = cfg.getRoot();
const Setting& root = cfg.getRoot();
try {
const Setting &modules = root[MODULES_CONFIG_STRING_AMF_MODULES];
} catch (const SettingNotFoundException &nfex) {
const Setting& modules = root[MODULES_CONFIG_STRING_AMF_MODULES];
} catch (const SettingNotFoundException& nfex) {
Logger::amf_app().error("%s : %s", nfex.what(), nfex.getPath());
return -1;
}
const Setting &modules = root[MODULES_CONFIG_STRING_AMF_MODULES];
const Setting &msg = modules[MODULES_CONFIG_STRING_AMF_MODULES_NGAP_MESSAGE];
const Setting& modules = root[MODULES_CONFIG_STRING_AMF_MODULES];
const Setting& msg = modules[MODULES_CONFIG_STRING_AMF_MODULES_NGAP_MESSAGE];
int count = msg.getLength();
for (int i = 0; i < count; i++) {
const Setting &item = msg[i];
const Setting& item = msg[i];
std::string typeOfMessage;
int procedure_code;
item.lookupValue(MODULES_CONFIG_STRING_AMF_MODULES_NGAP_MESSAGE_NAME,
msgName);
item.lookupValue(
MODULES_CONFIG_STRING_AMF_MODULES_NGAP_MESSAGE_NAME, msgName);
item.lookupValue(
MODULES_CONFIG_STRING_AMF_MODULES_NGAP_MESSAGE_PROCEDURECODE,
procedure_code);
item.lookupValue(MODULES_CONFIG_STRING_AMF_MODULES_NGAP_MESSAGE_TYPEOFMSG,
item.lookupValue(
MODULES_CONFIG_STRING_AMF_MODULES_NGAP_MESSAGE_TYPEOFMSG,
typeOfMessage);
procedureCode = (Ngap_ProcedureCode_t) procedure_code;
if (!(typeOfMessage.compare("initialMessage"))) {
......@@ -89,8 +92,9 @@ int amf_modules::load(const std::string &config_file) {
void amf_modules::display() {
Logger::config().info("======= AMF Registered Modules =======");
Logger::config().info("NGAP Message Modules:");
Logger::config().info("- %s(Procedure code %d, Type of Msg %d)\n",
msgName.c_str(), procedureCode, typeOfMsg);
Logger::config().info(
"- %s(Procedure code %d, Type of Msg %d)\n", msgName.c_str(),
procedureCode, typeOfMsg);
}
}
} // namespace config
......@@ -3,9 +3,9 @@
* 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
* 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
*
......@@ -29,18 +29,19 @@
#ifndef _AMF_MODULE_FROM_CONFIG_H_
#define _AMF_MODULE_FROM_CONFIG_H_
#include <libconfig.h++>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
#include <libconfig.h++>
#include "Ngap_ProcedureCode.h"
#include "Ngap_NGAP-PDU.h"
#include "Ngap_ProcedureCode.h"
#define MODULES_CONFIG_STRING_AMF_MODULES "MODULES"
#define MODULES_CONFIG_STRING_AMF_MODULES_NGAP_MESSAGE "NGAP_MESSAGE"
#define MODULES_CONFIG_STRING_AMF_MODULES_NGAP_MESSAGE_NAME "MSG_NAME"
#define MODULES_CONFIG_STRING_AMF_MODULES_NGAP_MESSAGE_PROCEDURECODE "ProcedureCode"
#define MODULES_CONFIG_STRING_AMF_MODULES_NGAP_MESSAGE_PROCEDURECODE \
"ProcedureCode"
#define MODULES_CONFIG_STRING_AMF_MODULES_NGAP_MESSAGE_TYPEOFMSG "TypeOfMessage"
using namespace libconfig;
......@@ -49,16 +50,16 @@ namespace config {
class amf_modules {
public:
int load(const std::string &config_file);
int load(const std::string& config_file);
void display();
void makeModulesAlive();
private:
std::string msgName; //vector to store more msgs
std::string msgName; // vector to store more msgs
Ngap_NGAP_PDU_PR typeOfMsg;
Ngap_ProcedureCode_t procedureCode;
// NGSetupRequestMsg *ngSetupRequest;
};
}
} // namespace config
#endif
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This diff is collapsed.
......@@ -3,9 +3,9 @@
* 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
* 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
*
......@@ -35,6 +35,8 @@
#include "itti_msg_n11.hpp"
#include "pdu_session_context.hpp"
#include "AuthenticationInfo.h"
#include "UEAuthenticationCtx.h"
namespace amf_application {
......@@ -46,33 +48,49 @@ class amf_n11 {
void handle_itti_message(itti_smf_services_consumer&);
void handle_pdu_session_initial_request(
std::string supi, std::shared_ptr<pdu_session_context> psc,
std::string smf_addr, bstring sm_msg, std::string dnn);
void handle_itti_message(itti_nsmf_pdusession_update_sm_context &itti_msg);
std::string smf_addr, std::string smf_api_version, bstring sm_msg,
std::string dnn);
void handle_itti_message(itti_nsmf_pdusession_update_sm_context& itti_msg);
void handle_itti_message(itti_nsmf_pdusession_release_sm_context& itti_msg);
void handle_itti_message(itti_pdu_session_resource_setup_response& itti_msg);
void send_pdu_session_update_sm_context_request(
std::string supi, std::shared_ptr<pdu_session_context> psc,
std::string smf_addr, bstring sm_msg, std::string dnn);
std::map<std::string, std::shared_ptr<pdu_session_context>> supi2pdu; // amf ue ngap id
std::map<std::string, std::shared_ptr<pdu_session_context>>
supi2pdu; // amf ue ngap id
mutable std::shared_mutex m_supi2pdu;
bool is_supi_to_pdu_ctx(const std::string &supi) const;
bool is_supi_to_pdu_ctx(const std::string& supi) const;
std::shared_ptr<pdu_session_context> supi_to_pdu_ctx(
const std::string &supi) const;
void set_supi_to_pdu_ctx(const std::string &supi,
std::shared_ptr<pdu_session_context> psc);
const std::string& supi) const;
void set_supi_to_pdu_ctx(
const std::string& supi, std::shared_ptr<pdu_session_context> psc);
std::map<uint8_t, std::string> pduid2supi;
bool smf_selection_from_configuration(std::string &smf_addr);
bool smf_selection_from_context(std::string &smf_addr);
bool smf_selection_from_configuration(
std::string& smf_addr, std::string& smf_api_version);
void handle_post_sm_context_response_error_400();
void handle_post_sm_context_response_error(long code, std::string cause,
bstring n1sm, std::string supi,
void handle_post_sm_context_response_error(
long code, std::string cause, bstring n1sm, std::string supi,
uint8_t pdu_session_id);
void curl_http_client(std::string remoteUri, std::string jsonData,
std::string n1SmMsg, std::string n2SmMsg,
std::string supi, uint8_t pdu_session_id);
void curl_http_client(
std::string remoteUri, std::string jsonData, std::string n1SmMsg,
std::string n2SmMsg, std::string supi, uint8_t pdu_session_id);
void curl_http_client(
std::string remoteUri, std::string Method, std::string msgBody,
std::string& Response);
bool discover_smf(
std::string& smf_addr, std::string& smf_api_version,
const snssai_t snssai, const plmn_t plmn, const std::string dnn);
bool send_ue_authentication_request(
oai::amf::model::AuthenticationInfo& auth_info,
oai::amf::model::UEAuthenticationCtx& ue_auth_ctx, uint8_t http_version);
};
}
} // namespace amf_application
#endif
This diff is collapsed.
......@@ -3,9 +3,9 @@
* 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
* 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
*
......@@ -29,41 +29,55 @@
#ifndef _AMF_N2_H_
#define _AMF_N2_H_
#include "ngap_app.hpp"
#include "DownlinkRANStatusTransfer.hpp"
#include "HandoverCommandMsg.hpp"
#include "HandoverRequest.hpp"
#include "PduSessionResourceReleaseCommand.hpp"
#include "itti_msg_n2.hpp"
#include "ngap_app.hpp"
#include "ue_ngap_context.hpp"
#include "amf.hpp"
namespace amf_application {
class amf_n2 : public ngap::ngap_app {
public:
amf_n2(const std::string &address, const uint16_t port_num);
amf_n2(const std::string& address, const uint16_t port_num);
~amf_n2();
void handle_itti_message(itti_new_sctp_association &new_assoc);
void handle_itti_message(itti_ng_setup_request &ngsetupreq);
void handle_itti_message(itti_initial_ue_message &init_ue_msg);
void handle_itti_message(itti_ul_nas_transport &ul_nas_transport);
void handle_itti_message(itti_dl_nas_transport &dl_nas_transport);
void handle_itti_message(itti_initial_context_setup_request &itti_msg);
void handle_itti_message(itti_pdu_session_resource_setup_request &itti_msg);
void handle_itti_message(itti_pdu_session_resource_release_command &itti_msg);
void handle_itti_message(itti_ue_context_release_request &itti_msg);
void handle_itti_message(itti_ue_radio_capability_indication &itti_msg);
void handle_itti_message(itti_new_sctp_association& new_assoc);
void handle_itti_message(itti_ng_setup_request& ngsetupreq);
void handle_itti_message(itti_initial_ue_message& init_ue_msg);
void handle_itti_message(itti_ul_nas_transport& ul_nas_transport);
void handle_itti_message(itti_dl_nas_transport& dl_nas_transport);
void handle_itti_message(itti_initial_context_setup_request& itti_msg);
void handle_itti_message(itti_pdu_session_resource_setup_request& itti_msg);
void handle_itti_message(itti_ue_context_release_request& itti_msg);
void handle_itti_message(itti_ue_radio_capability_indication& itti_msg);
void handle_itti_message(itti_ue_context_release_command& itti_msg);
void handle_itti_message(itti_pdu_session_resource_release_command& itti_msg);
void handle_itti_message(itti_handover_required& itti_msg);
void handle_itti_message(itti_handover_request_Ack& itti_msg);
void handle_itti_message(itti_handover_notify& itti_msg);
void handle_itti_message(itti_uplinkranstatsutransfer& itti_msg);
bool verifyPlmn(std::vector<SupportedItem_t> list);
std::vector<SupportedItem_t> get_common_plmn(
std::vector<SupportedItem_t> list);
private:
std::map<uint32_t, std::shared_ptr<ue_ngap_context>> ranid2uecontext; // ran ue ngap id
mutable std::shared_mutex m_ranid2uecontext;
bool is_ran_ue_id_2_ue_ngap_context(const uint32_t &ran_ue_ngap_id) const;
std::shared_ptr<ue_ngap_context> ran_ue_id_2_ue_ngap_context(
const uint32_t &ran_ue_ngap_id) const;
const uint32_t& ran_ue_ngap_id) const;
bool is_ran_ue_id_2_ue_ngap_context(const uint32_t& ran_ue_ngap_id) const;
void set_ran_ue_ngap_id_2_ue_ngap_context(
const uint32_t &ran_ue_ngap_id, std::shared_ptr<ue_ngap_context> unc);
const uint32_t& ran_ue_ngap_id, std::shared_ptr<ue_ngap_context> unc);
private:
std::map<uint32_t, std::shared_ptr<ue_ngap_context>>
ranid2uecontext; // ran ue ngap id
mutable std::shared_mutex m_ranid2uecontext;
};
}
} // namespace amf_application
#endif
This diff is collapsed.
This diff is collapsed.
......@@ -3,9 +3,9 @@
* 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
* 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
*
......@@ -33,52 +33,63 @@
//------------------------------------------------------------------------------
void statistics::display() {
Logger::amf_app().info("");
//Logger::amf_app().info("--------------------------------------------------");
//Logger::amf_app().info("| connected gNBs | connected UEs | registered UEs |");
//Logger::amf_app().info("--------------------------------------------------");
//Logger::amf_app().info("| %d | %d | %d |",gNB_connected,UE_connected,UE_registred);
//Logger::amf_app().info("--------------------------------------------------");
// Logger::amf_app().info("--------------------------------------------------");
// Logger::amf_app().info("| connected gNBs | connected UEs | registered UEs
// |");
// Logger::amf_app().info("--------------------------------------------------");
// Logger::amf_app().info("| %d | %d | %d
// |",gNB_connected,UE_connected,UE_registred);
// Logger::amf_app().info("--------------------------------------------------");
Logger::amf_app().info(
"|----------------------------------------------------------------------------------------------------------------|");
"|-----------------------------------------------------------------------"
"-----------------------------------------|");
Logger::amf_app().info(
"|----------------------------------------------------gNBs' information-------------------------------------------|");
"|----------------------------------------------------gNBs' "
"information-------------------------------------------|");
Logger::amf_app().info(
"| Index | Status | Global ID | gNB Name | Tracking Area (PLMN, TAC) |");
"| Index | Status | Global ID | gNB "
"Name | Tracking Area (PLMN, TAC) |");
if (gnbs.size() == 0) {
Logger::amf_app().info(
"| - | - | - | - | - |");
"| - | - | - | "
"- | - |");
}
//TODO: Show the list of common PLMNs
// TODO: Show the list of common PLMNs
for (int i = 0; i < gnbs.size(); i++) {
Logger::amf_app().info(
"| %d | Connected | 0x%x | %s | %s, %d | ",
"| %d | Connected | 0x%x | %s "
" | %s, %d | ",
i + 1, gnbs[i].gnb_id, gnbs[i].gnb_name.c_str(),
(gnbs[i].mcc + gnbs[i].mnc).c_str(), gnbs[i].tac);
}
Logger::amf_app().info(
"|----------------------------------------------------------------------------------------------------------------|");
"|-----------------------------------------------------------------------"
"-----------------------------------------|");
Logger::amf_app().info("");
Logger::amf_app().info(
"|----------------------------------------------------------------------------------------------------------------|");
"|-----------------------------------------------------------------------"
"-----------------------------------------|");
Logger::amf_app().info(
"|----------------------------------------------------UEs' information--------------------------------------------|");
"|----------------------------------------------------UEs' "
"information--------------------------------------------|");
Logger::amf_app().info(
"| Index | 5GMM state | IMSI | GUTI | RAN UE NGAP ID | AMF UE ID | PLMN |Cell ID|");
"| Index | 5GMM state | IMSI | GUTI | RAN "
"UE NGAP ID | AMF UE ID | PLMN |Cell ID|");
int i = 0;
for (auto const &ue : ue_infos) {
Logger::amf_app().info("|%7d|%22s|%18s|%15s|%16d|%11d|%9s|%7d|", i + 1,
ue.second.registerStatus.c_str(),
ue.second.imsi.c_str(), ue.second.guti.c_str(),
ue.second.ranid, ue.second.amfid,
(ue.second.mcc + ue.second.mnc).c_str(),
ue.second.cellId);
for (auto const& ue : ue_infos) {
Logger::amf_app().info(
"|%7d|%22s|%18s|%15s|%16d|%11d|%9s|%7d|", i + 1,
ue.second.registerStatus.c_str(), ue.second.imsi.c_str(),
ue.second.guti.c_str(), ue.second.ranid, ue.second.amfid,
(ue.second.mcc + ue.second.mnc).c_str(), ue.second.cellId);
i++;
}
Logger::amf_app().info(
"|----------------------------------------------------------------------------------------------------------------|");
"|-----------------------------------------------------------------------"
"-----------------------------------------|");
Logger::amf_app().info("");
}
......@@ -90,7 +101,7 @@ statistics::statistics() {
}
//------------------------------------------------------------------------------
void statistics::update_ue_info(const ue_info_t &ue_info) {
void statistics::update_ue_info(const ue_info_t& ue_info) {
if (!(ue_info.imsi.size() > 0)) {
Logger::amf_app().warn("Update UE Info with invalid IMSI");
}
......@@ -98,31 +109,31 @@ void statistics::update_ue_info(const ue_info_t &ue_info) {
if (ue_infos.count(ue_info.imsi) > 0) {
ue_infos.erase(ue_info.imsi);
ue_infos.insert(std::pair<std::string, ue_info_t>(ue_info.imsi, ue_info));
Logger::amf_app().debug("Update UE Info (IMSI %s) success",
ue_info.imsi.c_str());
Logger::amf_app().debug(
"Update UE Info (IMSI %s) success", ue_info.imsi.c_str());
} else {
ue_infos.insert(std::pair<std::string, ue_info_t>(ue_info.imsi, ue_info));
Logger::amf_app().debug("Add UE Info (IMSI %s) success",
ue_info.imsi.c_str());
Logger::amf_app().debug(
"Add UE Info (IMSI %s) success", ue_info.imsi.c_str());
}
}
//------------------------------------------------------------------------------
void statistics::update_5gmm_state(const std::string &imsi,
const std::string &state) {
void statistics::update_5gmm_state(
const std::string& imsi, const std::string& state) {
if (ue_infos.count(imsi) > 0) {
ue_info_t ue_info = ue_infos.at(imsi);
ue_info.registerStatus = state;
ue_infos.erase(ue_info.imsi);
ue_infos.insert(std::pair<std::string, ue_info_t>(imsi, ue_info));
Logger::amf_app().debug("Update UE State (IMSI %s, State %s) success",
imsi.c_str(), state.c_str());
Logger::amf_app().debug(
"Update UE State (IMSI %s, State %s) success", imsi.c_str(),
state.c_str());
} else {
Logger::amf_app().warn("Update UE State (IMSI %s), UE does not exist!",
imsi.c_str());
Logger::amf_app().warn(
"Update UE State (IMSI %s), UE does not exist!", imsi.c_str());
}
}
//------------------------------------------------------------------------------
statistics::~statistics() {
}
statistics::~statistics() {}
This diff is collapsed.
This diff is collapsed.
......@@ -3,9 +3,9 @@
* 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
* 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
*
......@@ -29,13 +29,14 @@
#ifndef _MYSQL_DB_HANDLERS_H_
#define _MYSQL_DB_HANDLERS_H_
#include <pthread.h>
#include <mysql/mysql.h>
#include <pthread.h>
#include <string>
#define KEY_LENGTH (16)
#define SQN_LENGTH (6)
#define RAND_LENGTH (16)
typedef struct {
uint8_t key[KEY_LENGTH];
uint8_t sqn[SQN_LENGTH];
......@@ -44,8 +45,8 @@ typedef struct {
} mysql_auth_info_t;
typedef struct {
//mysql reference connector object
MYSQL *db_conn;
// mysql reference connector object
MYSQL* db_conn;
std::string server;
std::string user;
std::string password;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
File mode changed from 100755 to 100644
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment