Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
oai
openairinterface5G
Commits
1729b3dc
Commit
1729b3dc
authored
Sep 06, 2018
by
Konstantinos Alexandris
Browse files
X2AP: init funcs (register/association) + handler/management functions
SCTP: one to many sockets implementation
parent
3b3b9718
Changes
15
Hide whitespace changes
Inline
Side-by-side
cmake_targets/CMakeLists.txt
View file @
1729b3dc
...
...
@@ -474,15 +474,15 @@ add_library(X2AP_LIB
include_directories
(
"
${
X2AP_C_DIR
}
"
)
include_directories
(
"
${
X2AP_DIR
}
"
)
#
add_library(X2AP_ENB
#
${X2AP_DIR}/x2ap_eNB.c
add_library
(
X2AP_ENB
${
X2AP_DIR
}
/x2ap_eNB.c
# ${X2AP_DIR}/x2ap_eNB_decoder.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_management_procedures.c
${
X2AP_DIR
}
/x2ap_eNB_management_procedures.c
# ${X2AP_DIR}/x2ap_eNB_generate_messages.c
#
)
)
# Hardware dependant options
###################################
...
...
@@ -1947,7 +1947,7 @@ add_executable(lte-softmodem
target_link_libraries
(
lte-softmodem
-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
NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
-Wl,--end-group z dl
)
...
...
@@ -2023,7 +2023,7 @@ add_executable(lte-uesoftmodem
target_link_libraries
(
lte-uesoftmodem
-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
}
NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
-Wl,--end-group z dl
)
...
...
@@ -2140,7 +2140,7 @@ add_executable(test_epc_generate_scenario
${
OPENAIR3_DIR
}
/S1AP/s1ap_eNB_defs.h
)
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
...
...
@@ -2160,7 +2160,7 @@ add_executable(test_epc_play_scenario
)
target_include_directories
(
test_epc_play_scenario PUBLIC /usr/local/share/asn1c
)
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})
dlsim_tm4 dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim
pdcchsim pucchsim prachsim syncsim ulsim
#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_eth_transpro
FLPT_MSG ASYNC_IF FLEXRAN_AGENT HASHTABLE MSC UTIL OMG_SUMO SECU_OSA
...
...
openair2/COMMON/sctp_messages_def.h
View file @
1729b3dc
...
...
@@ -19,11 +19,13 @@
* contact@openairinterface.org
*/
MESSAGE_DEF
(
SCTP_NEW_ASSOCIATION_REQ
,
MESSAGE_PRIORITY_MED
,
sctp_new_association_req_t
,
sctp_new_association_req
)
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_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_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_CLOSE_ASSOCIATION
,
MESSAGE_PRIORITY_MAX
,
sctp_close_association_t
,
sctp_close_association
)
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_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_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_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
)
openair2/COMMON/sctp_messages_types.h
View file @
1729b3dc
...
...
@@ -22,13 +22,15 @@
#ifndef 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_RESP(mSGpTR)(mSGpTR)->ittiMsg.sctp_new_association_resp
#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_REQ(mSGpTR) (mSGpTR)->ittiMsg.sctp_data_req
#define SCTP_INIT_MSG(mSGpTR) (mSGpTR)->ittiMsg.sctp_init
#define SCTP_CLOSE_ASSOCIATION(mSGpTR) (mSGpTR)->ittiMsg.sctp_close_association
#define SCTP_NEW_ASSOCIATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.sctp_new_association_req
#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_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.sctp_data_ind
#define SCTP_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.sctp_data_req
#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
enum
sctp_state_e
{
SCTP_STATE_CLOSED
,
...
...
openair2/ENB_APP/enb_app.c
View file @
1729b3dc
...
...
@@ -46,7 +46,7 @@
# include "gtpv1u_eNB_task.h"
# endif
//
# include "x2ap_eNB.h"
# include "x2ap_eNB.h"
# include "x2ap_messages_types.h"
# 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)
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
++
;
}
...
...
@@ -176,8 +176,8 @@ void *eNB_app_task(void *args_p)
long
enb_register_retry_timer_id
;
# endif
uint32_t
x2_register_enb_pending
;
//
uint32_t x2_registered_enb;
//
long x2_enb_register_retry_timer_id;
uint32_t
x2_registered_enb
;
long
x2_enb_register_retry_timer_id
;
uint32_t
enb_id
;
MessageDef
*
msg_p
=
NULL
;
instance_t
instance
;
...
...
@@ -224,7 +224,7 @@ void *eNB_app_task(void *args_p)
# endif
/* 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
);
do
{
...
...
@@ -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);
}
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
;
# 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:
LOG_E
(
ENB_APP
,
"Received unexpected message %s
\n
"
,
ITTI_MSG_NAME
(
msg_p
));
...
...
openair2/X2AP/x2ap_common.h
View file @
1729b3dc
...
...
@@ -62,10 +62,12 @@ extern int asn1_xer_print;
#if defined(ENB_MODE)
# 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_WARN(x, args...) LOG_W(X2AP, x, ##args)
# define X2AP_DEBUG(x, args...) LOG_D(X2AP, x, ##args)
#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_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)
...
...
openair2/X2AP/x2ap_eNB.c
0 → 100644
View file @
1729b3dc
/*
* 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
<pthread.h>
#include
<stdio.h>
#include
<stdlib.h>
#include
<stdint.h>
#include
<arpa/inet.h>
#include
"intertask_interface.h"
#include
"x2ap_eNB.h"
#include
"x2ap_eNB_defs.h"
#include
"x2ap_eNB_management_procedures.h"
#include
"x2ap_eNB_handler.h"
#include
"x2ap_common.h"
#include
"queue.h"
#include
"assertions.h"
#include
"conversions.h"
struct
x2ap_enb_map
;
struct
x2ap_eNB_data_s
;
RB_PROTOTYPE
(
x2ap_enb_map
,
x2ap_eNB_data_s
,
entry
,
x2ap_eNB_compare_assoc_id
);
//static
//void x2ap_eNB_handle_sctp_data_ind(instance_t instance,
// sctp_data_ind_t *sctp_data_ind);
static
void
x2ap_eNB_handle_sctp_association_resp
(
instance_t
instance
,
sctp_new_association_resp_t
*
sctp_new_association_resp
);
static
void
x2ap_eNB_handle_sctp_association_ind
(
instance_t
instance
,
sctp_new_association_ind_t
*
sctp_new_association_ind
);
static
void
x2ap_eNB_handle_register_eNB
(
instance_t
instance
,
x2ap_register_enb_req_t
*
x2ap_register_eNB
);
static
void
x2ap_eNB_register_eNB
(
x2ap_eNB_instance_t
*
instance_p
,
net_ip_address_t
*
target_eNB_ip_addr
,
net_ip_address_t
*
local_ip_addr
,
uint16_t
in_streams
,
uint16_t
out_streams
,
uint32_t
enb_port_for_X2C
);
static
void
x2ap_eNB_handle_sctp_association_resp
(
instance_t
instance
,
sctp_new_association_resp_t
*
sctp_new_association_resp
);
/*
static
void x2ap_eNB_handle_sctp_data_ind(instance_t instance,
sctp_data_ind_t *sctp_data_ind) {
int result;
DevAssert(sctp_data_ind != NULL);
x2ap_eNB_handle_message(sctp_data_ind->assoc_id, sctp_data_ind->stream,
sctp_data_ind->buffer, sctp_data_ind->buffer_length);
result = itti_free(TASK_UNKNOWN, sctp_data_ind->buffer);
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
}*/
static
void
x2ap_eNB_handle_sctp_association_resp
(
instance_t
instance
,
sctp_new_association_resp_t
*
sctp_new_association_resp
)
{
x2ap_eNB_instance_t
*
instance_p
;
x2ap_eNB_data_t
*
x2ap_enb_data_p
;
DevAssert
(
sctp_new_association_resp
!=
NULL
);
printf
(
"x2ap_eNB_handle_sctp_association_resp at 1
\n
"
);
dump_trees
();
instance_p
=
x2ap_eNB_get_instance
(
instance
);
DevAssert
(
instance_p
!=
NULL
);
/* if the assoc_id is already known, it is certainly because an IND was received
* before. In this case, just update streams and return
*/
if
(
sctp_new_association_resp
->
assoc_id
!=
-
1
)
{
x2ap_enb_data_p
=
x2ap_get_eNB
(
instance_p
,
sctp_new_association_resp
->
assoc_id
,
sctp_new_association_resp
->
ulp_cnx_id
);
if
(
x2ap_enb_data_p
!=
NULL
)
{
/* some sanity check - to be refined at some point */
if
(
sctp_new_association_resp
->
sctp_state
!=
SCTP_STATE_ESTABLISHED
)
{
X2AP_ERROR
(
"x2ap_enb_data_p not NULL and sctp state not SCTP_STATE_ESTABLISHED, what to do?
\n
"
);
abort
();
}
x2ap_enb_data_p
->
in_streams
=
sctp_new_association_resp
->
in_streams
;
x2ap_enb_data_p
->
out_streams
=
sctp_new_association_resp
->
out_streams
;
return
;
}
}
x2ap_enb_data_p
=
x2ap_get_eNB
(
instance_p
,
-
1
,
sctp_new_association_resp
->
ulp_cnx_id
);
DevAssert
(
x2ap_enb_data_p
!=
NULL
);
printf
(
"x2ap_eNB_handle_sctp_association_resp at 2
\n
"
);
dump_trees
();
if
(
sctp_new_association_resp
->
sctp_state
!=
SCTP_STATE_ESTABLISHED
)
{
X2AP_WARN
(
"Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u
\n
"
,
sctp_new_association_resp
->
sctp_state
,
instance
,
sctp_new_association_resp
->
ulp_cnx_id
);
x2ap_handle_x2_setup_message
(
x2ap_enb_data_p
,
sctp_new_association_resp
->
sctp_state
==
SCTP_STATE_SHUTDOWN
);
return
;
}
printf
(
"x2ap_eNB_handle_sctp_association_resp at 3
\n
"
);
dump_trees
();
/* Update parameters */
x2ap_enb_data_p
->
assoc_id
=
sctp_new_association_resp
->
assoc_id
;
x2ap_enb_data_p
->
in_streams
=
sctp_new_association_resp
->
in_streams
;
x2ap_enb_data_p
->
out_streams
=
sctp_new_association_resp
->
out_streams
;
printf
(
"x2ap_eNB_handle_sctp_association_resp at 4
\n
"
);
dump_trees
();
/* Prepare new x2 Setup Request */
//x2ap_eNB_generate_x2_setup_request(instance_p, x2ap_enb_data_p);
}
static
void
x2ap_eNB_handle_sctp_association_ind
(
instance_t
instance
,
sctp_new_association_ind_t
*
sctp_new_association_ind
)
{
x2ap_eNB_instance_t
*
instance_p
;
x2ap_eNB_data_t
*
x2ap_enb_data_p
;
printf
(
"x2ap_eNB_handle_sctp_association_ind at 1 (called for instance %d)
\n
"
,
instance
);
dump_trees
();
DevAssert
(
sctp_new_association_ind
!=
NULL
);
instance_p
=
x2ap_eNB_get_instance
(
instance
);
DevAssert
(
instance_p
!=
NULL
);
x2ap_enb_data_p
=
x2ap_get_eNB
(
instance_p
,
sctp_new_association_ind
->
assoc_id
,
-
1
);
if
(
x2ap_enb_data_p
!=
NULL
)
abort
();
// DevAssert(x2ap_enb_data_p != NULL);
if
(
x2ap_enb_data_p
==
NULL
)
{
/* Create new eNB descriptor */
x2ap_enb_data_p
=
calloc
(
1
,
sizeof
(
*
x2ap_enb_data_p
));
DevAssert
(
x2ap_enb_data_p
!=
NULL
);
x2ap_enb_data_p
->
cnx_id
=
x2ap_eNB_fetch_add_global_cnx_id
();
x2ap_enb_data_p
->
x2ap_eNB_instance
=
instance_p
;
/* Insert the new descriptor in list of known eNB
* but not yet associated.
*/
RB_INSERT
(
x2ap_enb_map
,
&
instance_p
->
x2ap_enb_head
,
x2ap_enb_data_p
);
x2ap_enb_data_p
->
state
=
X2AP_ENB_STATE_CONNECTED
;
instance_p
->
x2_target_enb_nb
++
;
if
(
instance_p
->
x2_target_enb_pending_nb
>
0
)
{
instance_p
->
x2_target_enb_pending_nb
--
;
}
}
else
{
X2AP_WARN
(
"x2ap_enb_data_p already exists
\n
"
);
}
printf
(
"x2ap_eNB_handle_sctp_association_ind at 2
\n
"
);
dump_trees
();
/* Update parameters */
x2ap_enb_data_p
->
assoc_id
=
sctp_new_association_ind
->
assoc_id
;
x2ap_enb_data_p
->
in_streams
=
sctp_new_association_ind
->
in_streams
;
x2ap_enb_data_p
->
out_streams
=
sctp_new_association_ind
->
out_streams
;
printf
(
"x2ap_eNB_handle_sctp_association_ind at 3
\n
"
);
dump_trees
();
}
int
x2ap_eNB_init_sctp
(
x2ap_eNB_instance_t
*
instance_p
,
net_ip_address_t
*
local_ip_addr
,
uint32_t
enb_port_for_X2C
)
{
// Create and alloc new message
MessageDef
*
message
;
sctp_init_t
*
sctp_init
=
NULL
;
DevAssert
(
instance_p
!=
NULL
);
DevAssert
(
local_ip_addr
!=
NULL
);
message
=
itti_alloc_new_message
(
TASK_X2AP
,
SCTP_INIT_MSG_MULTI
);
sctp_init
=
&
message
->
ittiMsg
.
sctp_init_multi
;
sctp_init
->
port
=
enb_port_for_X2C
;
sctp_init
->
ppid
=
X2AP_SCTP_PPID
;
sctp_init
->
ipv4
=
1
;
sctp_init
->
ipv6
=
0
;
sctp_init
->
nb_ipv4_addr
=
1
;
#if 0
memcpy(&sctp_init->ipv4_address,
local_ip_addr,
sizeof(*local_ip_addr));
#endif
sctp_init
->
ipv4_address
[
0
]
=
inet_addr
(
local_ip_addr
->
ipv4_address
);
/*
* SR WARNING: ipv6 multi-homing fails sometimes for localhost.
* * * * Disable it for now.
*/
sctp_init
->
nb_ipv6_addr
=
0
;
sctp_init
->
ipv6_address
[
0
]
=
"0:0:0:0:0:0:0:1"
;
return
itti_send_msg_to_task
(
TASK_SCTP
,
instance_p
->
instance
,
message
);
}
static
void
x2ap_eNB_register_eNB
(
x2ap_eNB_instance_t
*
instance_p
,
net_ip_address_t
*
target_eNB_ip_address
,
net_ip_address_t
*
local_ip_addr
,
uint16_t
in_streams
,
uint16_t
out_streams
,
uint32_t
enb_port_for_X2C
)
{
MessageDef
*
message
=
NULL
;
sctp_new_association_req_t
*
sctp_new_association_req
=
NULL
;
x2ap_eNB_data_t
*
x2ap_enb_data
=
NULL
;
DevAssert
(
instance_p
!=
NULL
);
DevAssert
(
target_eNB_ip_address
!=
NULL
);
message
=
itti_alloc_new_message
(
TASK_X2AP
,
SCTP_NEW_ASSOCIATION_REQ_MULTI
);
sctp_new_association_req
=
&
message
->
ittiMsg
.
sctp_new_association_req_multi
;
sctp_new_association_req
->
port
=
enb_port_for_X2C
;
sctp_new_association_req
->
ppid
=
X2AP_SCTP_PPID
;
sctp_new_association_req
->
in_streams
=
in_streams
;
sctp_new_association_req
->
out_streams
=
out_streams
;
memcpy
(
&
sctp_new_association_req
->
remote_address
,
target_eNB_ip_address
,
sizeof
(
*
target_eNB_ip_address
));
memcpy
(
&
sctp_new_association_req
->
local_address
,
local_ip_addr
,
sizeof
(
*
local_ip_addr
));
/* Create new eNB descriptor */
x2ap_enb_data
=
calloc
(
1
,
sizeof
(
*
x2ap_enb_data
));
DevAssert
(
x2ap_enb_data
!=
NULL
);
x2ap_enb_data
->
cnx_id
=
x2ap_eNB_fetch_add_global_cnx_id
();
sctp_new_association_req
->
ulp_cnx_id
=
x2ap_enb_data
->
cnx_id
;
x2ap_enb_data
->
assoc_id
=
-
1
;
x2ap_enb_data
->
x2ap_eNB_instance
=
instance_p
;
/* Insert the new descriptor in list of known eNB
* but not yet associated.
*/
RB_INSERT
(
x2ap_enb_map
,
&
instance_p
->
x2ap_enb_head
,
x2ap_enb_data
);
x2ap_enb_data
->
state
=
X2AP_ENB_STATE_WAITING
;
instance_p
->
x2_target_enb_nb
++
;
instance_p
->
x2_target_enb_pending_nb
++
;
itti_send_msg_to_task
(
TASK_SCTP
,
instance_p
->
instance
,
message
);
}
static
void
x2ap_eNB_handle_register_eNB
(
instance_t
instance
,
x2ap_register_enb_req_t
*
x2ap_register_eNB
)
{
x2ap_eNB_instance_t
*
new_instance
;
uint8_t
index
;
DevAssert
(
x2ap_register_eNB
!=
NULL
);
/* Look if the provided instance already exists */
new_instance
=
x2ap_eNB_get_instance
(
instance
);
if
(
new_instance
!=
NULL
)
{
/* Checks if it is a retry on the same eNB */
DevCheck
(
new_instance
->
eNB_id
==
x2ap_register_eNB
->
eNB_id
,
new_instance
->
eNB_id
,
x2ap_register_eNB
->
eNB_id
,
0
);
DevCheck
(
new_instance
->
cell_type
==
x2ap_register_eNB
->
cell_type
,
new_instance
->
cell_type
,
x2ap_register_eNB
->
cell_type
,
0
);
DevCheck
(
new_instance
->
tac
==
x2ap_register_eNB
->
tac
,
new_instance
->
tac
,
x2ap_register_eNB
->
tac
,
0
);
DevCheck
(
new_instance
->
mcc
==
x2ap_register_eNB
->
mcc
,
new_instance
->
mcc
,
x2ap_register_eNB
->
mcc
,
0
);
DevCheck
(
new_instance
->
mnc
==
x2ap_register_eNB
->
mnc
,
new_instance
->
mnc
,
x2ap_register_eNB
->
mnc
,
0
);
}
else
{
new_instance
=
calloc
(
1
,
sizeof
(
x2ap_eNB_instance_t
));
DevAssert
(
new_instance
!=
NULL
);
RB_INIT
(
&
new_instance
->
x2ap_enb_head
);
/* Copy usefull parameters */
new_instance
->
instance
=
instance
;
new_instance
->
eNB_name
=
x2ap_register_eNB
->
eNB_name
;
new_instance
->
eNB_id
=
x2ap_register_eNB
->
eNB_id
;
new_instance
->
cell_type
=
x2ap_register_eNB
->
cell_type
;
new_instance
->
tac
=
x2ap_register_eNB
->
tac
;
new_instance
->
mcc
=
x2ap_register_eNB
->
mcc
;
new_instance
->
mnc
=
x2ap_register_eNB
->
mnc
;
new_instance
->
mnc_digit_length
=
x2ap_register_eNB
->
mnc_digit_length
;
/* Add the new instance to the list of eNB (meaningfull in virtual mode) */
x2ap_eNB_insert_new_instance
(
new_instance
);
X2AP_INFO
(
"Registered new eNB[%d] and %s eNB id %u
\n
"
,
instance
,
x2ap_register_eNB
->
cell_type
==
CELL_MACRO_ENB
?
"macro"
:
"home"
,
x2ap_register_eNB
->
eNB_id
);
/* initiate the SCTP listener */
if
(
x2ap_eNB_init_sctp
(
new_instance
,
&
x2ap_register_eNB
->
enb_x2_ip_address
,
x2ap_register_eNB
->
enb_port_for_X2C
)
<
0
)
{
X2AP_ERROR
(
"Error while sending SCTP_INIT_MSG to SCTP
\n
"
);
return
;
}
X2AP_INFO
(
"eNB[%d] eNB id %u acting as a listner (server)
\n
"
,
instance
,
x2ap_register_eNB
->
eNB_id
);
}
DevCheck
(
x2ap_register_eNB
->
nb_x2
<=
X2AP_MAX_NB_ENB_IP_ADDRESS
,
X2AP_MAX_NB_ENB_IP_ADDRESS
,
x2ap_register_eNB
->
nb_x2
,
0
);
/* Trying to connect to the provided list of eNB ip address */
for
(
index
=
0
;
index
<
x2ap_register_eNB
->
nb_x2
;
index
++
)
{
X2AP_INFO
(
"eNB[%d] eNB id %u acting as an initiator (client)
\n
"
,
instance
,
x2ap_register_eNB
->
eNB_id
);
x2ap_eNB_register_eNB
(
new_instance
,
&
x2ap_register_eNB
->
target_enb_x2_ip_address
[
index
],
&
x2ap_register_eNB
->
enb_x2_ip_address
,
x2ap_register_eNB
->
sctp_in_streams
,
x2ap_register_eNB
->
sctp_out_streams
,
x2ap_register_eNB
->
enb_port_for_X2C
);
}
}
void
*
x2ap_task
(
void
*
arg
)
{
MessageDef
*
received_msg
=
NULL
;
int
result
;
X2AP_DEBUG
(
"Starting X2AP layer
\n
"
);
x2ap_eNB_prepare_internal_data
();
itti_mark_task_ready
(
TASK_X2AP
);
while
(
1
)
{
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
;
case
X2AP_REGISTER_ENB_REQ
:
x2ap_eNB_handle_register_eNB
(
ITTI_MESSAGE_GET_INSTANCE
(
received_msg
),
&
X2AP_REGISTER_ENB_REQ
(
received_msg
));
break
;
case
SCTP_NEW_ASSOCIATION_RESP
:
x2ap_eNB_handle_sctp_association_resp
(
ITTI_MESSAGE_GET_INSTANCE
(
received_msg
),
&
received_msg
->
ittiMsg
.
sctp_new_association_resp
);
break
;
case
SCTP_NEW_ASSOCIATION_IND
:
x2ap_eNB_handle_sctp_association_ind
(
ITTI_MESSAGE_GET_INSTANCE
(
received_msg
),
&
received_msg
->
ittiMsg
.
sctp_new_association_ind
);
break
;