X2AP: init funcs (register/association) + handler/management functions

SCTP: one to many sockets implementation
parent 3b3b9718
...@@ -474,15 +474,15 @@ add_library(X2AP_LIB ...@@ -474,15 +474,15 @@ add_library(X2AP_LIB
include_directories ("${X2AP_C_DIR}") include_directories ("${X2AP_C_DIR}")
include_directories ("${X2AP_DIR}") include_directories ("${X2AP_DIR}")
#add_library(X2AP_ENB add_library(X2AP_ENB
# ${X2AP_DIR}/x2ap_eNB.c ${X2AP_DIR}/x2ap_eNB.c
# ${X2AP_DIR}/x2ap_eNB_decoder.c # ${X2AP_DIR}/x2ap_eNB_decoder.c
# ${X2AP_DIR}/x2ap_eNB_encoder.c # ${X2AP_DIR}/x2ap_eNB_encoder.c
# ${X2AP_DIR}/x2ap_eNB_handler.c ${X2AP_DIR}/x2ap_eNB_handler.c
# ${X2AP_DIR}/x2ap_eNB_itti_messaging.c # ${X2AP_DIR}/x2ap_eNB_itti_messaging.c
# ${X2AP_DIR}/x2ap_eNB_management_procedures.c ${X2AP_DIR}/x2ap_eNB_management_procedures.c
# ${X2AP_DIR}/x2ap_eNB_generate_messages.c # ${X2AP_DIR}/x2ap_eNB_generate_messages.c
# ) )
# Hardware dependant options # Hardware dependant options
################################### ###################################
...@@ -1947,7 +1947,7 @@ add_executable(lte-softmodem ...@@ -1947,7 +1947,7 @@ add_executable(lte-softmodem
target_link_libraries (lte-softmodem target_link_libraries (lte-softmodem
-Wl,--start-group -Wl,--start-group
RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB PHY_COMMON PHY PHY_RU LFDS L2 RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB PHY_COMMON PHY PHY_RU LFDS L2
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7
NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
-Wl,--end-group z dl) -Wl,--end-group z dl)
...@@ -2023,7 +2023,7 @@ add_executable(lte-uesoftmodem ...@@ -2023,7 +2023,7 @@ add_executable(lte-uesoftmodem
target_link_libraries (lte-uesoftmodem target_link_libraries (lte-uesoftmodem
-Wl,--start-group -Wl,--start-group
RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_UE PHY_RU LFDS L2_UE SIMU RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_UE PHY_RU LFDS L2_UE SIMU
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES} ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES}
NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
-Wl,--end-group z dl) -Wl,--end-group z dl)
...@@ -2140,7 +2140,7 @@ add_executable(test_epc_generate_scenario ...@@ -2140,7 +2140,7 @@ add_executable(test_epc_generate_scenario
${OPENAIR3_DIR}/S1AP/s1ap_eNB_defs.h ${OPENAIR3_DIR}/S1AP/s1ap_eNB_defs.h
) )
target_link_libraries (test_epc_generate_scenario target_link_libraries (test_epc_generate_scenario
-Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS ${ITTI_LIB} ${MSC_LIB} L2 -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIBRARIES} -Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS ${ITTI_LIB} ${MSC_LIB} L2 -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIBRARIES}
) )
add_executable(test_epc_play_scenario add_executable(test_epc_play_scenario
...@@ -2160,7 +2160,7 @@ add_executable(test_epc_play_scenario ...@@ -2160,7 +2160,7 @@ add_executable(test_epc_play_scenario
) )
target_include_directories(test_epc_play_scenario PUBLIC /usr/local/share/asn1c) target_include_directories(test_epc_play_scenario PUBLIC /usr/local/share/asn1c)
target_link_libraries (test_epc_play_scenario target_link_libraries (test_epc_play_scenario
-Wl,--start-group RRC_LIB S1AP_LIB X2AP_LIB GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY_COMMON PHY PHY_UE LFDS ${ITTI_LIB} ${MSC_LIB} -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIBRARIES} -Wl,--start-group RRC_LIB S1AP_LIB X2AP_LIB X2AP_ENB GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY_COMMON PHY PHY_UE LFDS ${ITTI_LIB} ${MSC_LIB} -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIBRARIES}
) )
...@@ -2196,7 +2196,7 @@ if (${T_TRACER}) ...@@ -2196,7 +2196,7 @@ if (${T_TRACER})
dlsim_tm4 dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim dlsim_tm4 dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim
pdcchsim pucchsim prachsim syncsim ulsim pdcchsim pucchsim prachsim syncsim ulsim
#all "add_library" definitions #all "add_library" definitions
ITTI RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB ITTI RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB
oai_exmimodevif oai_usrpdevif oai_bladerfdevif oai_lmssdrdevif oai_exmimodevif oai_usrpdevif oai_bladerfdevif oai_lmssdrdevif
oai_eth_transpro oai_eth_transpro
FLPT_MSG ASYNC_IF FLEXRAN_AGENT HASHTABLE MSC UTIL OMG_SUMO SECU_OSA FLPT_MSG ASYNC_IF FLEXRAN_AGENT HASHTABLE MSC UTIL OMG_SUMO SECU_OSA
......
...@@ -20,10 +20,12 @@ ...@@ -20,10 +20,12 @@
*/ */
MESSAGE_DEF(SCTP_NEW_ASSOCIATION_REQ , MESSAGE_PRIORITY_MED, sctp_new_association_req_t , sctp_new_association_req) MESSAGE_DEF(SCTP_NEW_ASSOCIATION_REQ , MESSAGE_PRIORITY_MED, sctp_new_association_req_t , sctp_new_association_req)
MESSAGE_DEF(SCTP_NEW_ASSOCIATION_REQ_MULTI, MESSAGE_PRIORITY_MED, sctp_new_association_req_t , sctp_new_association_req_multi)
MESSAGE_DEF(SCTP_NEW_ASSOCIATION_RESP, MESSAGE_PRIORITY_MED, sctp_new_association_resp_t , sctp_new_association_resp) MESSAGE_DEF(SCTP_NEW_ASSOCIATION_RESP, MESSAGE_PRIORITY_MED, sctp_new_association_resp_t , sctp_new_association_resp)
MESSAGE_DEF(SCTP_NEW_ASSOCIATION_IND , MESSAGE_PRIORITY_MED, sctp_new_association_ind_t , sctp_new_association_ind) MESSAGE_DEF(SCTP_NEW_ASSOCIATION_IND , MESSAGE_PRIORITY_MED, sctp_new_association_ind_t , sctp_new_association_ind)
MESSAGE_DEF(SCTP_REGISTER_UPPER_LAYER, MESSAGE_PRIORITY_MED, sctp_listener_register_upper_layer_t, sctp_listener_register_upper_layer) MESSAGE_DEF(SCTP_REGISTER_UPPER_LAYER, MESSAGE_PRIORITY_MED, sctp_listener_register_upper_layer_t, sctp_listener_register_upper_layer)
MESSAGE_DEF(SCTP_DATA_REQ, MESSAGE_PRIORITY_MED, sctp_data_req_t , sctp_data_req) MESSAGE_DEF(SCTP_DATA_REQ, MESSAGE_PRIORITY_MED, sctp_data_req_t , sctp_data_req)
MESSAGE_DEF(SCTP_DATA_IND, MESSAGE_PRIORITY_MED, sctp_data_ind_t , sctp_data_ind) MESSAGE_DEF(SCTP_DATA_IND, MESSAGE_PRIORITY_MED, sctp_data_ind_t , sctp_data_ind)
MESSAGE_DEF(SCTP_INIT_MSG, MESSAGE_PRIORITY_MED, sctp_init_t , sctp_init) MESSAGE_DEF(SCTP_INIT_MSG, MESSAGE_PRIORITY_MED, sctp_init_t , sctp_init)
MESSAGE_DEF(SCTP_INIT_MSG_MULTI, MESSAGE_PRIORITY_MED, sctp_init_t , sctp_init_multi)
MESSAGE_DEF(SCTP_CLOSE_ASSOCIATION, MESSAGE_PRIORITY_MAX, sctp_close_association_t , sctp_close_association) MESSAGE_DEF(SCTP_CLOSE_ASSOCIATION, MESSAGE_PRIORITY_MAX, sctp_close_association_t , sctp_close_association)
...@@ -23,11 +23,13 @@ ...@@ -23,11 +23,13 @@
#define SCTP_MESSAGES_TYPES_H_ #define SCTP_MESSAGES_TYPES_H_
#define SCTP_NEW_ASSOCIATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.sctp_new_association_req #define SCTP_NEW_ASSOCIATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.sctp_new_association_req
#define SCTP_NEW_ASSOCIATION_RESP(mSGpTR)(mSGpTR)->ittiMsg.sctp_new_association_resp #define SCTP_NEW_ASSOCIATION_REQ_MULTI(mSGpTR) (mSGpTR)->ittiMsg.sctp_new_association_req_multi
#define SCTP_NEW_ASSOCIATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.sctp_new_association_resp
#define SCTP_NEW_ASSOCIATION_IND(mSGpTR) (mSGpTR)->ittiMsg.sctp_new_association_ind #define SCTP_NEW_ASSOCIATION_IND(mSGpTR) (mSGpTR)->ittiMsg.sctp_new_association_ind
#define SCTP_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.sctp_data_ind #define SCTP_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.sctp_data_ind
#define SCTP_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.sctp_data_req #define SCTP_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.sctp_data_req
#define SCTP_INIT_MSG(mSGpTR) (mSGpTR)->ittiMsg.sctp_init #define SCTP_INIT_MSG(mSGpTR) (mSGpTR)->ittiMsg.sctp_init
#define SCTP_INIT_MSG_MULTI(mSGpTR) (mSGpTR)->ittiMsg.sctp_init_multi
#define SCTP_CLOSE_ASSOCIATION(mSGpTR) (mSGpTR)->ittiMsg.sctp_close_association #define SCTP_CLOSE_ASSOCIATION(mSGpTR) (mSGpTR)->ittiMsg.sctp_close_association
enum sctp_state_e { enum sctp_state_e {
......
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
# include "gtpv1u_eNB_task.h" # include "gtpv1u_eNB_task.h"
# endif # endif
//# include "x2ap_eNB.h" # include "x2ap_eNB.h"
# include "x2ap_messages_types.h" # include "x2ap_messages_types.h"
# define X2AP_ENB_REGISTER_RETRY_DELAY 10 # define X2AP_ENB_REGISTER_RETRY_DELAY 10
...@@ -154,7 +154,7 @@ static uint32_t eNB_app_register_x2(uint32_t enb_id_start, uint32_t enb_id_end) ...@@ -154,7 +154,7 @@ static uint32_t eNB_app_register_x2(uint32_t enb_id_start, uint32_t enb_id_end)
RCconfig_X2(msg_p, enb_id); RCconfig_X2(msg_p, enb_id);
//itti_send_msg_to_task (TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); itti_send_msg_to_task (TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p);
register_enb_x2_pending++; register_enb_x2_pending++;
} }
...@@ -176,8 +176,8 @@ void *eNB_app_task(void *args_p) ...@@ -176,8 +176,8 @@ void *eNB_app_task(void *args_p)
long enb_register_retry_timer_id; long enb_register_retry_timer_id;
# endif # endif
uint32_t x2_register_enb_pending; uint32_t x2_register_enb_pending;
//uint32_t x2_registered_enb; uint32_t x2_registered_enb;
//long x2_enb_register_retry_timer_id; long x2_enb_register_retry_timer_id;
uint32_t enb_id; uint32_t enb_id;
MessageDef *msg_p = NULL; MessageDef *msg_p = NULL;
instance_t instance; instance_t instance;
...@@ -224,7 +224,7 @@ void *eNB_app_task(void *args_p) ...@@ -224,7 +224,7 @@ void *eNB_app_task(void *args_p)
# endif # endif
/* Try to register each eNB with each other */ /* Try to register each eNB with each other */
// x2_registered_enb = 0; x2_registered_enb = 0;
x2_register_enb_pending = eNB_app_register_x2 (enb_id_start, enb_id_end); x2_register_enb_pending = eNB_app_register_x2 (enb_id_start, enb_id_end);
do { do {
...@@ -301,8 +301,59 @@ void *eNB_app_task(void *args_p) ...@@ -301,8 +301,59 @@ void *eNB_app_task(void *args_p)
register_enb_pending = eNB_app_register (enb_id_start, enb_id_end);//, enb_properties_p); register_enb_pending = eNB_app_register (enb_id_start, enb_id_end);//, enb_properties_p);
} }
if (TIMER_HAS_EXPIRED (msg_p).timer_id == x2_enb_register_retry_timer_id) {
/* Restart the registration process */
x2_registered_enb = 0;
x2_register_enb_pending = eNB_app_register_x2 (enb_id_start, enb_id_end);
}
break; break;
# endif # endif
case X2AP_DEREGISTERED_ENB_IND:
LOG_W(ENB_APP, "[eNB %d] Received %s: associated eNB %d\n", instance, ITTI_MSG_NAME (msg_p),
X2AP_DEREGISTERED_ENB_IND(msg_p).nb_x2);
/* TODO handle recovering of registration */
break;
case X2AP_REGISTER_ENB_CNF:
LOG_I(ENB_APP, "[eNB %d] Received %s: associated eNB %d\n", instance, ITTI_MSG_NAME (msg_p),
X2AP_REGISTER_ENB_CNF(msg_p).nb_x2);
DevAssert(x2_register_enb_pending > 0);
x2_register_enb_pending--;
/* Check if at least eNB is registered with one target eNB */
if (X2AP_REGISTER_ENB_CNF(msg_p).nb_x2 > 0) {
x2_registered_enb++;
}
/* Check if all register eNB requests have been processed */
if (x2_register_enb_pending == 0) {
if (x2_registered_enb == enb_nb) {
/* If all eNB are registered, start RRC HO task */
}else {
uint32_t x2_not_associated = enb_nb - x2_registered_enb;
LOG_W(ENB_APP, " %d eNB %s not associated with the target\n",
x2_not_associated, x2_not_associated > 1 ? "are" : "is");
// timer to retry
/* Restart the eNB registration process in ENB_REGISTER_RETRY_DELAY seconds */
if (timer_setup (X2AP_ENB_REGISTER_RETRY_DELAY, 0, TASK_ENB_APP,
INSTANCE_DEFAULT, TIMER_ONE_SHOT, NULL,
&x2_enb_register_retry_timer_id) < 0) {
LOG_E(ENB_APP, " Can not start eNB X2AP register: retry timer, use \"sleep\" instead!\n");
sleep(X2AP_ENB_REGISTER_RETRY_DELAY);
/* Restart the registration process */
x2_registered_enb = 0;
x2_register_enb_pending = eNB_app_register_x2 (enb_id_start, enb_id_end);
}
}
}
break;
default: default:
LOG_E(ENB_APP, "Received unexpected message %s\n", ITTI_MSG_NAME (msg_p)); LOG_E(ENB_APP, "Received unexpected message %s\n", ITTI_MSG_NAME (msg_p));
......
...@@ -62,10 +62,12 @@ extern int asn1_xer_print; ...@@ -62,10 +62,12 @@ extern int asn1_xer_print;
#if defined(ENB_MODE) #if defined(ENB_MODE)
# include "log.h" # include "log.h"
# define X2AP_INFO(x, args...) LOG_I(X2AP, x, ##args)
# define X2AP_ERROR(x, args...) LOG_E(X2AP, x, ##args) # define X2AP_ERROR(x, args...) LOG_E(X2AP, x, ##args)
# define X2AP_WARN(x, args...) LOG_W(X2AP, x, ##args) # define X2AP_WARN(x, args...) LOG_W(X2AP, x, ##args)
# define X2AP_DEBUG(x, args...) LOG_D(X2AP, x, ##args) # define X2AP_DEBUG(x, args...) LOG_D(X2AP, x, ##args)
#else #else
# define X2AP_INFO(x, args...) do { fprintf(stdout, "[X2AP][I]"x, ##args); } while(0)
# define X2AP_ERROR(x, args...) do { fprintf(stdout, "[X2AP][E]"x, ##args); } while(0) # define X2AP_ERROR(x, args...) do { fprintf(stdout, "[X2AP][E]"x, ##args); } while(0)
# define X2AP_WARN(x, args...) do { fprintf(stdout, "[X2AP][W]"x, ##args); } while(0) # define X2AP_WARN(x, args...) do { fprintf(stdout, "[X2AP][W]"x, ##args); } while(0)
# define X2AP_DEBUG(x, args...) do { fprintf(stdout, "[X2AP][D]"x, ##args); } while(0) # define X2AP_DEBUG(x, args...) do { fprintf(stdout, "[X2AP][D]"x, ##args); } while(0)
......
This diff is collapsed.
...@@ -30,10 +30,12 @@ ...@@ -30,10 +30,12 @@
#ifndef X2AP_H_ #ifndef X2AP_H_
#define X2AP_H_ #define X2AP_H_
typedef struct x2ap_config_s { #define X2AP_SCTP_PPID (27) ///< X2AP SCTP Payload Protocol Identifier (PPID)
} x2ap_config_t; #include "x2ap_eNB_defs.h"
extern x2ap_config_t x2ap_config; int x2ap_eNB_init_sctp (x2ap_eNB_instance_t *instance_p,
net_ip_address_t *local_ip_addr,
uint32_t enb_port_for_X2C);
void *x2ap_task(void *arg); void *x2ap_task(void *arg);
......
/*
* 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
*/
#include <stdint.h>
#include "queue.h"
#include "tree.h"
#include "sctp_eNB_defs.h"
#ifndef X2AP_ENB_DEFS_H_
#define X2AP_ENB_DEFS_H_
#define X2AP_ENB_NAME_LENGTH_MAX (150)
typedef enum {
/* Disconnected state: initial state for any association. */
X2AP_ENB_STATE_DISCONNECTED = 0x0,
/* State waiting for x2 Setup response message if the target eNB accepts or
* X2 Setup failure if rejects the eNB.
*/
X2AP_ENB_STATE_WAITING = 0x1,
/* The eNB is successfully connected to another eNB. */
X2AP_ENB_STATE_CONNECTED = 0x2,
/* X2AP is ready, and the eNB is successfully connected to another eNB. */
X2AP_ENB_STATE_READY = 0x3,
X2AP_ENB_STATE_OVERLOAD = 0x4,
X2AP_ENB_STATE_RESETTING = 0x5,
/* Max number of states available */
X2AP_ENB_STATE_MAX,
} x2ap_eNB_state_t;
/* Served PLMN identity element */
struct plmn_identity_s {
uint16_t mcc;
uint16_t mnc;
uint8_t mnc_digit_length;
STAILQ_ENTRY(plmn_identity_s) next;
};
/* Served group id element */
struct served_group_id_s {
uint16_t enb_group_id;
STAILQ_ENTRY(served_group_id_s) next;
};
/* Served enn code for a particular eNB */
struct enb_code_s {
uint8_t enb_code;
STAILQ_ENTRY(enb_code_s) next;
};
struct x2ap_eNB_instance_s;
/* This structure describes association of a eNB to another eNB */
typedef struct x2ap_eNB_data_s {
/* eNB descriptors tree, ordered by sctp assoc id */
RB_ENTRY(x2ap_eNB_data_s) entry;
/* This is the optional name provided by the MME */
char *eNB_name;
/* target eNB ID */
uint32_t eNB_id;
/* Current eNB load information (if any). */
//x2ap_load_state_t overload_state;
/* Current eNB->eNB X2AP association state */
x2ap_eNB_state_t state;
/* Next usable stream for UE signalling */
int32_t nextstream;
/* Number of input/ouput streams */
uint16_t in_streams;
uint16_t out_streams;
/* Connexion id used between SCTP/X2AP */
uint16_t cnx_id;
/* SCTP association id */
int32_t assoc_id;
/* Only meaningfull in virtual mode */
struct x2ap_eNB_instance_s *x2ap_eNB_instance;
} x2ap_eNB_data_t;
typedef struct x2ap_eNB_instance_s {
/* used in simulation to store multiple eNB instances*/
STAILQ_ENTRY(x2ap_eNB_instance_s) x2ap_eNB_entries;
/* Number of target eNBs requested by eNB (tree size) */
uint32_t x2_target_enb_nb;
/* Number of target eNBs for which association is pending */
uint32_t x2_target_enb_pending_nb;
/* Number of target eNB successfully associated to eNB */
uint32_t x2_target_enb_associated_nb;
/* Tree of X2AP eNB associations ordered by association ID */
RB_HEAD(x2ap_enb_map, x2ap_eNB_data_s) x2ap_enb_head;
/* Tree of UE ordered by eNB_ue_x2ap_id's */
// RB_HEAD(x2ap_ue_map, x2ap_eNB_ue_context_s) x2ap_ue_head;
/* For virtual mode, mod_id as defined in the rest of the L1/L2 stack */
instance_t instance;
/* Displayable name of eNB */
char *eNB_name;
/* Unique eNB_id to identify the eNB within EPC.
* In our case the eNB is a macro eNB so the id will be 20 bits long.
* For Home eNB id, this field should be 28 bits long.
*/
uint32_t eNB_id;
/* The type of the cell */
cell_type_t cell_type;
/* Tracking area code */
uint16_t tac;
/* Mobile Country Code
* Mobile Network Code
*/
uint16_t mcc;
uint16_t mnc;
uint8_t mnc_digit_length;
} x2ap_eNB_instance_t;
typedef struct {
/* List of served eNBs
* Only used for virtual mode
*/
STAILQ_HEAD(x2ap_eNB_instances_head_s, x2ap_eNB_instance_s) x2ap_eNB_instances_head;
/* Nb of registered eNBs */
uint8_t nb_registered_eNBs;
/* Generate a unique connexion id used between X2AP and SCTP */
uint16_t global_cnx_id;
} x2ap_eNB_internal_data_t;
int x2ap_eNB_compare_assoc_id(struct x2ap_eNB_data_s *p1, struct x2ap_eNB_data_s *p2);
/* Generate the tree management functions */
struct x2ap_eNB_map;
struct x2ap_eNB_data_s;
RB_PROTOTYPE(x2ap_eNB_map, x2ap_eNB_data_s, entry, x2ap_eNB_compare_assoc_id);
#endif /* X2AP_ENB_DEFS_H_ */
/*
* 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
*/
#include <stdint.h>
#include "intertask_interface.h"
#include "asn1_conversions.h"
#include "x2ap_common.h"
#include "x2ap_eNB_defs.h"
#include "x2ap_eNB_handler.h"
#include "x2ap_eNB_management_procedures.h"
#include "assertions.h"
#include "conversions.h"
void x2ap_handle_x2_setup_message(x2ap_eNB_data_t *enb_desc_p, int sctp_shutdown)
{
if (sctp_shutdown) {
/* A previously connected eNB has been shutdown */
/* TODO check if it was used by some eNB and send a message to inform these eNB if there is no more associated eNB */
if (enb_desc_p->state == X2AP_ENB_STATE_CONNECTED) {
enb_desc_p->state = X2AP_ENB_STATE_DISCONNECTED;
if (enb_desc_p->x2ap_eNB_instance-> x2_target_enb_associated_nb > 0) {
/* Decrease associated eNB number */
enb_desc_p->x2ap_eNB_instance-> x2_target_enb_associated_nb --;
}
/* If there are no more associated eNB, inform eNB app */
if (enb_desc_p->x2ap_eNB_instance->x2_target_enb_associated_nb == 0) {
MessageDef *message_p;
message_p = itti_alloc_new_message(TASK_X2AP, X2AP_DEREGISTERED_ENB_IND);
X2AP_DEREGISTERED_ENB_IND(message_p).nb_x2 = 0;
itti_send_msg_to_task(TASK_ENB_APP, enb_desc_p->x2ap_eNB_instance->instance, message_p);
}
}
} else {
/* Check that at least one setup message is pending */
DevCheck(enb_desc_p->x2ap_eNB_instance->x2_target_enb_pending_nb > 0,
enb_desc_p->x2ap_eNB_instance->instance,
enb_desc_p->x2ap_eNB_instance->x2_target_enb_pending_nb, 0);
if (enb_desc_p->x2ap_eNB_instance->x2_target_enb_pending_nb > 0) {
/* Decrease pending messages number */
enb_desc_p->x2ap_eNB_instance->x2_target_enb_pending_nb --;
}
/* If there are no more pending messages, inform eNB app */
if (enb_desc_p->x2ap_eNB_instance->x2_target_enb_pending_nb == 0) {
MessageDef *message_p;
message_p = itti_alloc_new_message(TASK_X2AP, X2AP_REGISTER_ENB_CNF);
X2AP_REGISTER_ENB_CNF(message_p).nb_x2 = enb_desc_p->x2ap_eNB_instance->x2_target_enb_associated_nb;
itti_send_msg_to_task(TASK_ENB_APP, enb_desc_p->x2ap_eNB_instance->instance, message_p);
}
}
}
/*
* 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
*/
#ifndef X2AP_ENB_HANDLERS_H_
#define X2AP_ENB_HANDLERS_H_
#include "x2ap_eNB_defs.h"
void x2ap_handle_x2_setup_message(x2ap_eNB_data_t *mme_desc_p, int sctp_shutdown);
//int x2ap_eNB_handle_message(uint32_t assoc_id, int32_t stream,
// const uint8_t * const data, const uint32_t data_length);
#endif /* X2AP_ENB_HANDLERS_H_ */
/*
* 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
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "intertask_interface.h"
#include "assertions.h"
#include "conversions.h"
#include "x2ap_common.h"
#include "x2ap_eNB_defs.h"
#include "x2ap_eNB.h"
#define X2AP_DEBUG_LIST
#ifdef X2AP_DEBUG_LIST
# define X2AP_eNB_LIST_OUT(x, args...) X2AP_DEBUG("[eNB]%*s"x"\n", 4*indent, "", ##args)
#else
# define X2AP_eNB_LIST_OUT(x, args...)
#endif
static int indent = 0;
x2ap_eNB_internal_data_t x2ap_eNB_internal_data;
RB_GENERATE(x2ap_enb_map, x2ap_eNB_data_s, entry, x2ap_eNB_compare_assoc_id);
int x2ap_eNB_compare_assoc_id(
struct x2ap_eNB_data_s *p1, struct x2ap_eNB_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 x2ap_eNB_fetch_add_global_cnx_id(void)
{
return ++x2ap_eNB_internal_data.global_cnx_id;
}
void x2ap_eNB_prepare_internal_data(void)
{
memset(&x2ap_eNB_internal_data, 0, sizeof(x2ap_eNB_internal_data));
STAILQ_INIT(&x2ap_eNB_internal_data.x2ap_eNB_instances_head);
}
void x2ap_eNB_insert_new_instance(x2ap_eNB_instance_t *new_instance_p)
{
DevAssert(new_instance_p != NULL);
STAILQ_INSERT_TAIL(&x2ap_eNB_internal_data.x2ap_eNB_instances_head,
new_instance_p, x2ap_eNB_entries);
}
void dump_tree(x2ap_eNB_data_t *t)
{
if (t == NULL) return;
printf("-----------------------\n");
printf("eNB id %d %s\n", t->eNB_id, t->eNB_name);
printf("state %d\n", t->state);
printf("nextstream %d\n", t->nextstream);
printf("in_streams %d out_streams %d\n", t->in_streams, t->out_streams);
printf("cnx_id %d assoc_id %d\n", t->cnx_id, t->assoc_id);
dump_tree(t->entry.rbe_left);
dump_tree(t->entry.rbe_right);
}
void dump_trees(void)
{
x2ap_eNB_instance_t *zz;
STAILQ_FOREACH(zz, &x2ap_eNB_internal_data.x2ap_eNB_instances_head,
x2ap_eNB_entries) {
printf("here comes the tree (instance %d):\n---------------------------------------------\n", zz->instance);
dump_tree(zz->x2ap_enb_head.rbh_root);
printf("---------------------------------------------\n");
}
}
struct x2ap_eNB_data_s *x2ap_get_eNB(x2ap_eNB_instance_t *instance_p,
int32_t assoc_id,
uint16_t cnx_id)
{
struct x2ap_eNB_data_s temp;
struct x2ap_eNB_data_s *found;
printf("x2ap_get_eNB at 1 (looking for assoc_id %d cnx_id %d)\n", assoc_id, cnx_id);
dump_trees();
memset(&temp, 0, sizeof(struct x2ap_eNB_data_s));
temp.assoc_id = assoc_id;
temp.cnx_id = cnx_id;
if (instance_p == NULL) {
STAILQ_FOREACH(instance_p, &x2ap_eNB_internal_data.x2ap_eNB_instances_head,
x2ap_eNB_entries) {
found = RB_FIND(x2ap_enb_map, &instance_p->x2ap_enb_head, &temp);
if (found != NULL) {
return found;
}
}
} else {
return RB_FIND(x2ap_enb_map, &instance_p->x2ap_enb_head, &temp);
}
return NULL;
}
x2ap_eNB_instance_t *x2ap_eNB_get_instance(instance_t instance)
{
x2ap_eNB_instance_t *temp = NULL;
STAILQ_FOREACH(temp, &x2ap_eNB_internal_data.x2ap_eNB_instances_head,
x2ap_eNB_entries) {
if (temp->instance == instance) {
/* Matching occurence */
return temp;
}
}
return NULL;
}
/// utility functions
void x2ap_dump_eNB (x2ap_eNB_data_t * eNB_ref);
void
x2ap_dump_eNB_list (void) {
x2ap_eNB_instance_t *inst = NULL;
struct x2ap_eNB_data_s *found = NULL;
struct x2ap_eNB_data_s temp;
memset(&temp, 0, sizeof(struct x2ap_eNB_data_s));
STAILQ_FOREACH (inst, &x2ap_eNB_internal_data.x2ap_eNB_instances_head, x2ap_eNB_entries) {
found = RB_FIND(x2ap_enb_map, &inst->x2ap_enb_head, &temp);
x2ap_dump_eNB (found);
}
}
void x2ap_dump_eNB (x2ap_eNB_data_t * eNB_ref) {
if (eNB_ref == NULL) {
return;
}
X2AP_eNB_LIST_OUT ("");
X2AP_eNB_LIST_OUT ("eNB name: %s", eNB_ref->eNB_name == NULL ? "not present" : eNB_ref->eNB_name);
X2AP_eNB_LIST_OUT ("eNB STATE: %07x", eNB_ref->state);
X2AP_eNB_LIST_OUT ("eNB ID: %07x", eNB_ref->eNB_id);
indent++;
X2AP_eNB_LIST_OUT ("SCTP cnx id: %d", eNB_ref->cnx_id);
X2AP_eNB_LIST_OUT ("SCTP assoc id: %d", eNB_ref->assoc_id);
X2AP_eNB_LIST_OUT ("SCTP instreams: %d", eNB_ref->in_streams);
X2AP_eNB_LIST_OUT ("SCTP outstreams: %d", eNB_ref->out_streams);
indent--;
}
x2ap_eNB_data_t * x2ap_is_eNB_id_in_list (const uint32_t eNB_id)
{
x2ap_eNB_instance_t *inst;
struct x2ap_eNB_data_s *elm;
STAILQ_FOREACH(inst, &x2ap_eNB_internal_data.x2ap_eNB_instances_head, x2ap_eNB_entries) {
RB_FOREACH(elm, x2ap_enb_map, &inst->x2ap_enb_head) {
if (elm->eNB_id == eNB_id)
return elm;
}
}
return NULL;
}
x2ap_eNB_data_t * x2ap_is_eNB_assoc_id_in_list (const uint32_t sctp_assoc_id)
{
x2ap_eNB_instance_t *inst;
struct x2ap_eNB_data_s *found;
struct x2ap_eNB_data_s temp;
temp.assoc_id = sctp_assoc_id;
temp.cnx_id = -1;
STAILQ_FOREACH(inst, &x2ap_eNB_internal_data.x2ap_eNB_instances_head, x2ap_eNB_entries) {
found = RB_FIND(x2ap_enb_map, &inst->x2ap_enb_head, &temp);
if (found != NULL){
if (found->assoc_id == sctp_assoc_id) {
return found;
}
}
}
return NULL;
}
...@@ -19,53 +19,28 @@ ...@@ -19,53 +19,28 @@
* contact@openairinterface.org * contact@openairinterface.org
*/ */
#include <pthread.h> #ifndef X2AP_ENB_MANAGEMENT_PROCEDURES_H_
#include <stdio.h> #define X2AP_ENB_MANAGEMENT_PROCEDURES_H
#include <stdlib.h>
#include <stdint.h>
void x2ap_eNB_prepare_internal_data(void);
#include "intertask_interface.h" void dump_trees(void);
#include "x2ap.h" void x2ap_eNB_insert_new_instance(x2ap_eNB_instance_t *new_instance_p);
#include "assertions.h" x2ap_eNB_instance_t *x2ap_eNB_get_instance(uint8_t mod_id);
#include "conversions.h"
uint16_t x2ap_eNB_fetch_add_global_cnx_id(void);
void *x2ap_task(void *arg) void x2ap_eNB_prepare_internal_data(void);
{
MessageDef *received_msg = NULL;
int result;
X2AP_DEBUG("Starting X2AP layer\n"); x2ap_eNB_data_t* x2ap_is_eNB_id_in_list(uint32_t eNB_id);
x2ap_prepare_internal_data(); x2ap_eNB_data_t* x2ap_is_eNB_assoc_id_in_list(uint32_t sctp_assoc_id);
itti_mark_task_ready(TASK_X2AP); struct x2ap_eNB_data_s *x2ap_get_eNB(x2ap_eNB_instance_t *instance_p,
int32_t assoc_id,
while (1) { uint16_t cnx_id);
itti_receive_msg(TASK_X2AP, &received_msg);
switch (ITTI_MSG_ID(received_msg)) {
case TERMINATE_MESSAGE:
X2AP_WARN(" *** Exiting X2AP thread\n");
itti_exit_task();
break;
default:
X2AP_ERROR("Received unhandled message: %d:%s\n",
ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg));
break;
}
result = itti_free (ITTI_MSG_ORIGIN_ID(received_msg), received_msg);
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
received_msg = NULL;
}
return NULL;
}
#endif /* X2AP_ENB_MANAGEMENT_PROCEDURES_H_ */
...@@ -86,6 +86,12 @@ int sctp_get_sockinfo(int sock, uint16_t *instream, uint16_t *outstream, ...@@ -86,6 +86,12 @@ int sctp_get_sockinfo(int sock, uint16_t *instream, uint16_t *outstream,
memset(&status, 0, sizeof(struct sctp_status)); memset(&status, 0, sizeof(struct sctp_status));
i = sizeof(struct sctp_status); i = sizeof(struct sctp_status);
/* if sock refers to a multi SCTP endpoint, *assoc_id gives us
* the association ID that we want
*/
if (assoc_id != NULL)
status.sstat_assoc_id = *assoc_id;
if (getsockopt(sock, IPPROTO_SCTP, SCTP_STATUS, &status, &i) < 0) { if (getsockopt(sock, IPPROTO_SCTP, SCTP_STATUS, &status, &i) < 0) {
SCTP_ERROR("Getsockopt SCTP_STATUS failed: %s\n", strerror(errno)); SCTP_ERROR("Getsockopt SCTP_STATUS failed: %s\n", strerror(errno));
return -1; return -1;
......
This diff is collapsed.
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
# ifdef OPENAIR2 # ifdef OPENAIR2
# if defined(ENABLE_USE_MME) # if defined(ENABLE_USE_MME)
# include "sctp_eNB_task.h" # include "sctp_eNB_task.h"
# include "x2ap_eNB.h"
# include "s1ap_eNB.h" # include "s1ap_eNB.h"
# include "nas_ue_task.h" # include "nas_ue_task.h"
# include "udp_eNB_task.h" # include "udp_eNB_task.h"
...@@ -62,6 +63,11 @@ int create_tasks(uint32_t enb_nb) ...@@ -62,6 +63,11 @@ int create_tasks(uint32_t enb_nb)
# if defined(ENABLE_USE_MME) # if defined(ENABLE_USE_MME)
if (enb_nb > 0) { if (enb_nb > 0) {
if (itti_create_task (TASK_X2AP, x2ap_task, NULL) < 0) {
LOG_E(X2AP, "Create task for X2AP failed\n");
return -1;
}
if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) { if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) {
LOG_E(SCTP, "Create task for SCTP failed\n"); LOG_E(SCTP, "Create task for SCTP failed\n");
return -1; return -1;
......
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