Commit b767470a authored by Navid Nikaein's avatar Navid Nikaein

x2ap handover updates

parent 982f239b
......@@ -401,6 +401,15 @@ add_library(X2AP_LIB
include_directories ("${X2AP_C_DIR}")
include_directories ("${X2AP_DIR}")
add_library(X2AP_ENB
${X2AP_C_DIR}/x2ap_ies_defs.h
${X2AP_DIR}/x2ap.c
${X2AP_DIR}/x2ap_eNB_decoder.c
${X2AP_DIR}/x2ap_eNB_encoder.c
${X2AP_DIR}/x2ap_eNB_handlers.c
${X2AP_DIR}/x2ap_eNB_itti_messaging.c
${X2AP_DIR}/x2ap_eNB_management_procedures.c
)
# Hardware dependant options
###################################
add_list1_option(NB_ANTENNAS_RX "2" "Number of antennas in reception" "1" "2" "4")
......@@ -460,6 +469,8 @@ include_directories ("${OPENAIR_TARGETS}/ARCH/COMMON")
##############################################################
add_boolean_option(ENABLE_SECURITY True "Enable LTE integrity and ciphering between RRC UE and eNB")
add_boolean_option(ENABLE_USE_MME True "eNB connected to MME (INTERFACE S1-C), not standalone eNB")
add_boolean_option(ENABLE_USE_X2 True "eNB connected to eNB (INTERFACE X2)")
add_boolean_option(NO_RRM True "DO WE HAVE A RADIO RESSOURCE MANAGER: NO")
add_boolean_option(USER_MODE True "????")
......
......@@ -30,7 +30,7 @@
################################################################################
# file build_helper
# brief
# author Laurent Thomas
# author Laurent Thomas and Navid Nikaein
#
#######################################
SUDO='sudo -E'
......@@ -277,6 +277,23 @@ install_asn1c_from_source(){
make > /tmp/log_compile_asn1c 2>&1
$SUDO make install
}
check_install_syscom_software () {
$SUDO apt-get update
$SUDO apt-get install -y pcscd pcsc-tools libccid
$SUDO apt-get install python-setuptools libpcsclite-dev # pyscard dependancies
echo_info "mkdir -p syscom_scripts"
mkdir -p syscom_scripts
cd syscom_scripts
wget http://sourceforge.net/projects/pyscard/files/latest/pyscard-1.7.0.tar.gz
tar -xzvf pyscard-1.7.0.tar.gz
cd pyscard-1.7.0/
echo_info "installing pyscard"
$SUDO python setup.py build_ext install
cd ..
git clone http://cgit.osmocom.org/pysim pysim
git clone -b zecke/tmp http://cgit.osmocom.org/pysim pysim-zecke
}
#################################################
# 2. compile
......
......@@ -33,8 +33,8 @@
#include <stdint.h>
typedef enum {
MIN_MSC_ENV = 0,
MSC_E_UTRAN = MIN_MSC_ENV,
MIN_MSC_ENV = 0,
MSC_E_UTRAN = MIN_MSC_ENV,
MSC_E_UTRAN_LIPA,
MSC_MME_GW,
MSC_MME,
......@@ -70,6 +70,8 @@ typedef enum {
MSC_S11_MME,
MSC_S6A_MME,
MSC_HSS,
MSC_X2AP_SRC_ENB,
MSC_X2AP_TARGET_ENB,
MAX_MSC_PROTOS,
} msc_proto_t;
......
......@@ -27,3 +27,20 @@
*******************************************************************************/
/* eNB application layer -> X2AP messages */
/* ITTI LOG messages */
/* ENCODER */
MESSAGE_DEF(X2AP_RESET_REQUST_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , x2ap_reset_request_log)
MESSAGE_DEF(X2AP_RESOURCE_STATUS_RESPONSE_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , x2ap_resource_status_response_log)
MESSAGE_DEF(X2AP_RESOURCE_STATUS_FAILUIRE_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , x2ap_resource_status_failure_log)
/* DECODER */
MESSAGE_DEF(X2AP_SETUP_REQUEST_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , x2ap_setup_request_log)
/* eNB application layer -> X2AP messages */
MESSAGE_DEF(X2AP_REGISTER_ENB_REQ , MESSAGE_PRIORITY_MED, x2ap_register_enb_req_t , x2ap_register_enb_req)
/* X2AP -> eNB application layer messages */
MESSAGE_DEF(X2AP_REGISTER_ENB_CNF , MESSAGE_PRIORITY_MED, x2ap_register_enb_cnf_t , x2ap_register_enb_cnf)
MESSAGE_DEF(X2AP_DEREGISTERED_ENB_IND , MESSAGE_PRIORITY_MED, x2ap_deregistered_enb_ind_t , x2ap_deregistered_enb_ind)
......@@ -26,3 +26,69 @@
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
#ifndef X2AP_MESSAGES_TYPES_H_
#define X2AP_MESSAGES_TYPES_H_
//-------------------------------------------------------------------------------------------//
// Defines to access message fields.
#define X2AP_REGISTER_ENB_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_register_enb_req
#define X2AP_MAX_NB_ENB_IP_ADDRESS 2
// eNB application layer -> X2AP messages
typedef struct x2ap_register_enb_req_s {
/* Unique eNB_id to identify the eNB within EPC.
* For macro eNB ids this field should be 20 bits long.
* For home eNB ids this field should be 28 bits long.
*/
uint32_t eNB_id;
/* The type of the cell */
enum cell_type_e cell_type;
/* Optional name for the cell
* NOTE: the name can be NULL (i.e no name) and will be cropped to 150
* characters.
*/
char *eNB_name;
/* Tracking area code */
uint16_t tac;
/* Mobile Country Code
* Mobile Network Code
*/
uint16_t mcc;
uint16_t mnc;
uint8_t mnc_digit_length;
/*
* EARFCN
*/
uint16_t fdd_uL_EARFCN;
uint16_t fdd_dL_EARFCN;
uint16_t tdd_EARFCN;
uint16_t fdd_uL_Transmission_Bandwidth;
uint16_t fdd_dL_Transmission_Bandwidth;
uint16_t tdd_Transmission_Bandwidth;
/* The local eNB IP address to bind */
net_ip_address_t enb_x2_ip_address;
/* Nb of MME to connect to */
uint8_t nb_x2;
/* List of target eNB to connect to for X2*/
net_ip_address_t target_enb_x2_ip_address[X2AP_MAX_NB_ENB_IP_ADDRESS];
/* Number of SCTP streams used for associations */
uint16_t sctp_in_streams;
uint16_t sctp_out_streams;
} x2ap_register_enb_req_t;
#endif /* X2AP_MESSAGES_TYPES_H_ */
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
Copyright(c) 1999 - 2015 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -56,7 +56,11 @@
# include "sctp_eNB_task.h"
# include "gtpv1u_eNB_task.h"
# endif
# if defined(ENABLE_USE_X2)
# include "x2ap.h"
//# include "sctp_eNB_task.h"
//# include "gtpv1u_eNB_task.h"
#endif
extern unsigned char NB_eNB_INST;
#endif
......@@ -194,7 +198,7 @@ static void configure_rrc(uint32_t enb_id, const Enb_properties_array_t *enb_pro
/*------------------------------------------------------------------------------*/
# if defined(ENABLE_USE_MME)
static uint32_t eNB_app_register(uint32_t enb_id_start, uint32_t enb_id_end, const Enb_properties_array_t *enb_properties)
static uint32_t eNB_app_register_s1(uint32_t enb_id_start, uint32_t enb_id_end, const Enb_properties_array_t *enb_properties)
{
uint32_t enb_id;
uint32_t mme_id;
......@@ -264,6 +268,81 @@ static uint32_t eNB_app_register(uint32_t enb_id_start, uint32_t enb_id_end, con
return register_enb_pending;
}
# endif
/*------------------------------------------------------------------------------*/
# if defined(ENABLE_USE_X2)
static uint32_t eNB_app_register_x2(uint32_t enb_id_start, uint32_t enb_id_end, const Enb_properties_array_t *enb_properties)
{
uint32_t enb_id;
uint32_t x2_id;
MessageDef *msg_p;
uint32_t register_enb_x2_pending = 0;
char *str = NULL;
struct in_addr addr;
# if defined(OAI_EMU)
# endif
for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) {
# if defined(OAI_EMU)
if (oai_emulation.info.cli_start_enb[enb_id] == 1)
# endif
{
x2ap_register_enb_req_t *x2ap_register_eNB;
msg_p = itti_alloc_new_message (TASK_ENB_APP, X2AP_REGISTER_ENB_REQ);
x2ap_register_eNB = &X2AP_REGISTER_ENB_REQ(msg_p);
/* Some default/random parameters */
x2ap_register_eNB->eNB_id = enb_properties->properties[enb_id]->eNB_id;
x2ap_register_eNB->cell_type = enb_properties->properties[enb_id]->cell_type;
x2ap_register_eNB->eNB_name = enb_properties->properties[enb_id]->eNB_name;
x2ap_register_eNB->tac = enb_properties->properties[enb_id]->tac;
x2ap_register_eNB->mcc = enb_properties->properties[enb_id]->mcc;
x2ap_register_eNB->mnc = enb_properties->properties[enb_id]->mnc;
x2ap_register_eNB->mnc_digit_length = enb_properties->properties[enb_id]->mnc_digit_length;
x2ap_register_eNB->nb_x2 = enb_properties->properties[enb_id]->nb_x2;
AssertFatal (x2ap_register_eNB->nb_x2 <= X2AP_MAX_NB_ENB_IP_ADDRESS, "Too many X2 interfaces for eNB %d (%d/%d)!",
enb_id, x2ap_register_eNB->nb_x2,
X2AP_MAX_NB_ENB_IP_ADDRESS);
for (x2_id = 0; x2_id < x2ap_register_eNB->nb_x2; x2_id++) {
x2ap_register_eNB->target_enb_x2_ip_address[x2_id].ipv4 = enb_properties->properties[enb_id]->target_enb_x2_ip_address[x2_id].ipv4;
x2ap_register_eNB->target_enb_x2_ip_address[x2_id].ipv6 = enb_properties->properties[enb_id]->target_enb_x2_ip_address[x2_id].ipv6;
strncpy (x2ap_register_eNB->target_enb_x2_ip_address[x2_id].ipv4_address,
enb_properties->properties[enb_id]->target_enb_x2_ip_address[x2_id].ipv4_address,
sizeof(x2ap_register_eNB->target_enb_x2_ip_address[0].ipv4_address));
strncpy (x2ap_register_eNB->target_enb_x2_ip_address[x2_id].ipv6_address,
enb_properties->properties[enb_id]->target_enb_x2_ip_address[x2_id].ipv6_address,
sizeof(x2ap_register_eNB->target_enb_x2_ip_address[0].ipv6_address));
}
x2ap_register_eNB->sctp_in_streams = enb_properties->properties[enb_id]->sctp_in_streams;
x2ap_register_eNB->sctp_out_streams = enb_properties->properties[enb_id]->sctp_out_streams;
x2ap_register_eNB->enb_x2_ip_address.ipv6 = 0;
x2ap_register_eNB->enb_x2_ip_address.ipv4 = 1;
addr.s_addr = enb_properties->properties[enb_id]->enb_ipv4_address_for_X2C;
str = inet_ntoa(addr);
strcpy(x2ap_register_eNB->enb_x2_ip_address.ipv4_address, str);
itti_send_msg_to_task (TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p);
register_enb_x2_pending++;
}
}
return register_enb_x2_pending;
}
# endif
#endif
/*------------------------------------------------------------------------------*/
......@@ -275,9 +354,14 @@ void *eNB_app_task(void *args_p)
uint32_t enb_id_start = 0;
uint32_t enb_id_end = enb_id_start + enb_nb;
# if defined(ENABLE_USE_MME)
uint32_t register_enb_pending;
uint32_t register_enb_pending; // s1ap
uint32_t registered_enb;
long enb_register_retry_timer_id;
# endif
# if defined(ENABLE_USE_X2)
uint32_t x2ap_register_enb_pending;
uint32_t x2ap_registered_enb;
long x2ap_enb_register_retry_timer_id;
# endif
uint32_t enb_id;
MessageDef *msg_p = NULL;
......@@ -311,15 +395,25 @@ void *eNB_app_task(void *args_p)
}
# if defined(ENABLE_USE_MME)
/* Try to register each eNB */
/* Try to register each eNB with MME*/
registered_enb = 0;
register_enb_pending = eNB_app_register (enb_id_start, enb_id_end, enb_properties_p);
register_enb_pending = eNB_app_register_s1 (enb_id_start, enb_id_end, enb_properties_p);
# else
/* Start L2L1 task */
msg_p = itti_alloc_new_message(TASK_ENB_APP, INITIALIZE_MESSAGE);
itti_send_msg_to_task(TASK_L2L1, INSTANCE_DEFAULT, msg_p);
# endif
# if defined(ENABLE_USE_X2)
/* Try to register each eNB with each other */
registered_enb_x2 = 0;
register_enb_x2_pending = eNB_app_register_x2 (enb_id_start, enb_id_end, enb_properties_p);
# else
# endif
do {
// Wait for a message
itti_receive_msg (TASK_ENB_APP, &msg_p);
......@@ -383,7 +477,7 @@ void *eNB_app_task(void *args_p)
sleep(ENB_REGISTER_RETRY_DELAY);
/* Restart the registration process */
registered_enb = 0;
register_enb_pending = eNB_app_register (enb_id_start, enb_id_end, enb_properties_p);
register_enb_pending = eNB_app_register_s1 (enb_id_start, enb_id_end, enb_properties_p);
}
}
}
......@@ -403,12 +497,48 @@ void *eNB_app_task(void *args_p)
if (TIMER_HAS_EXPIRED (msg_p).timer_id == enb_register_retry_timer_id) {
/* Restart the registration process */
registered_enb = 0;
register_enb_pending = eNB_app_register (enb_id_start, enb_id_end, enb_properties_p);
register_enb_pending = eNB_app_register_s1 (enb_id_start, enb_id_end, enb_properties_p);
}
break;
# endif
#ifdef ENABLE_USE_X2
case X2AP_DEREGISTERED_ENB_IND:
LOG_W(ENB_APP, "[eNB %d] Received %s: associated eNB %d\n", instance, msg_name,
X2AP_DEREGISTERED_ENB_IND(msg_p).nb_x2);
/* TODO handle recovering of registration */
break;
case S1AP_REGISTER_ENB_CNF:
LOG_I(ENB_APP, "[eNB %d] Received %s: associated eNB %d\n", instance, msg_name,
X2AP_REGISTER_ENB_CNF(msg_p).nb_x2);
DevAssert(register_enb_x2_pending > 0);
register_enb_x2_pending--;
/* Check if at least eNB is registered with one target eNB */
if (X2AP_REGISTER_ENB_CNF(msg_p).nb_x2 > 0) {
registered_enb_x2++;
}
/* Check if all register eNB requests have been processed */
if (register_enb_x2_pending == 0) {
if (registered_enb_x2 == enb_nb) {
/* If all eNB are registered, start L2L1 task */
}else {
uint32_t not_associated_x2 = enb_nb - registered_enb;
LOG_W(ENB_APP, " %d eNB %s not associated with the target\n",
not_associated, not_associated > 1 ? "are" : "is");
// timer to retry
}
}
break;
# endif
#endif
default:
LOG_E(ENB_APP, "Received unexpected message %s\n", msg_name);
break;
......
This diff is collapsed.
......@@ -46,6 +46,7 @@
#include "platform_constants.h"
#include "PHY/impl_defs_lte.h"
#include "s1ap_messages_types.h"
#include "x2ap_messages_types.h"
#ifdef CMAKER
#include "SystemInformationBlockType2.h"
#else
......@@ -78,6 +79,15 @@ typedef struct mme_ip_address_s {
char *ipv6_address;
} mme_ip_address_t;
typedef struct x2_enb_ip_address_s {
unsigned ipv4:1;
unsigned ipv6:1;
unsigned active:1;
char *ipv4_address;
char *ipv6_address;
} x2_enb_ip_address_t;
typedef struct Enb_properties_s {
/* Unique eNB_id to identify the eNB within EPC.
* For macro eNB ids this field should be 20 bits long.
......@@ -193,6 +203,11 @@ typedef struct Enb_properties_s {
/* List of MME to connect to */
mme_ip_address_t mme_ip_address[S1AP_MAX_NB_MME_IP_ADDRESS];
/* Nb of X2 to connect to */
uint8_t nb_x2;
/* List of X2 to connect to */
x2_enb_ip_address_t target_enb_x2_ip_address[X2AP_MAX_NB_ENB_IP_ADDRESS];
int sctp_in_streams;
int sctp_out_streams;
......@@ -203,6 +218,14 @@ typedef struct Enb_properties_s {
char *enb_interface_name_for_S1_MME;
in_addr_t enb_ipv4_address_for_S1_MME;
char *enb_interface_name_for_X2U;
in_addr_t enb_ipv4_address_for_X2U;
tcp_udp_port_t enb_port_for_X2U;
char *enb_interface_name_for_X2C;
in_addr_t enb_ipv4_address_for_X2C;
tcp_udp_port_t enb_port_for_X2C;
// otg config
/* Nb of OTG elements */
uint8_t num_otg_elements;
......
......@@ -3564,7 +3564,7 @@ static void rrc_ue_generate_MeasurementReport( const protocol_ctxt_t* const ctxt
UE_rrc_inst[ctxt_pP->module_id].rsrq_db_filtered[target_eNB_offset]);
// if (measFlag == 1) {
cellId = get_adjacent_cell_id(ctxt_pP->module_id, eNB_index); //PhycellId of serving cell
cellId = eNB_index; //get_adjacent_cell_id(ctxt_pP->module_id, eNB_index); //PhycellId of serving cell
targetCellId = UE_rrc_inst[ctxt_pP->module_id].HandoverInfoUe.targetCellId ;//get_adjacent_cell_id(ue_mod_idP,target_eNB_offset); //PhycellId of target cell
if (pframe!=ctxt_pP->frame) {
......@@ -3628,7 +3628,7 @@ void ue_measurement_report_triggering( const protocol_ctxt_t* const ctxt_pP, con
ttt_ms = timeToTrigger_ms[UE_rrc_inst[ctxt_pP->module_id].ReportConfig[i][reportConfigId
-1]->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.timeToTrigger];
// Freq specific offset of neighbor cell freq
ofn = 5;//((UE_rrc_inst[ctxt_pP->module_id].MeasObj[i][measObjId-1]->measObject.choice.measObjectEUTRA.offsetFreq != NULL) ?
ofn = 15;//((UE_rrc_inst[ctxt_pP->module_id].MeasObj[i][measObjId-1]->measObject.choice.measObjectEUTRA.offsetFreq != NULL) ?
// *UE_rrc_inst[ctxt_pP->module_id].MeasObj[i][measObjId-1]->measObject.choice.measObjectEUTRA.offsetFreq : 15); // /* 15 is the Default */
// cellIndividualOffset of neighbor cell - not defined yet
ocn = 0;
......
......@@ -1839,7 +1839,7 @@ rrc_eNB_generate_HandoverPreparationInformation(
memcpy((void *)&handoverInfo->as_config.sourceMasterInformationBlock,
(void*)&eNB_rrc_inst[ctxt_pP->module_id].carrier[0] /* CROUX TBC */.mib, sizeof(MasterInformationBlock_t));
memcpy((void *)&handoverInfo->as_config.sourceMeasConfig,
(void*)ue_context_pP->ue_context.measConfig, sizeof(MeasConfig_t));
(void*)&ue_context_pP->ue_context.measConfig, sizeof(MeasConfig_t));
// FIXME handoverInfo not used...
free( handoverInfo );
......@@ -1861,7 +1861,7 @@ rrc_eNB_generate_HandoverPreparationInformation(
ue_context_pP->ue_context.handover_info->as_context.reestablishmentInfo->targetCellShortMAC_I.size = 0;
ue_context_pP->ue_context.handover_info->as_context.reestablishmentInfo->targetCellShortMAC_I.bits_unused = 0;
ue_context_pP->ue_context.handover_info->as_context.reestablishmentInfo->additionalReestabInfoList = NULL;
ue_context_pP->ue_context.handover_info->ho_prepare = 0xFF; //0xF0;
ue_context_pP->ue_context.handover_info->ho_prepare = 0xFF;
ue_context_pP->ue_context.handover_info->ho_complete = 0;
if (mod_id_target != 0xFF) {
......@@ -1950,7 +1950,7 @@ check_handovers(
if (ue_context_p->ue_context.handover_info != NULL) {
if (ue_context_p->ue_context.handover_info->ho_prepare == 0xFF) {
LOG_D(RRC,
"[eNB %d] Frame %d: Incoming handover detected for new UE_idx %d (source eNB %d->target eNB %d) \n",
"[eNB %d] Frame %d: Incoming handover detected for new UE_id %x (source eNB %d->target eNB %d) \n",
ctxt_pP->module_id,
ctxt_pP->frame,
ctxt_pP->rnti,
......@@ -1960,29 +1960,29 @@ check_handovers(
rrc_eNB_process_handoverPreparationInformation(
ctxt_pP,
ue_context_p);
ue_context_p->ue_context.handover_info->ho_prepare = 0xF1;
ue_context_p->ue_context.handover_info->ho_prepare = 0xF0;
}
if (ue_context_p->ue_context.handover_info->ho_complete == 0xF1) {
LOG_D(RRC,
"[eNB %d] Frame %d: handover Command received for new UE_id %x current eNB %d target eNB: %d \n",
ctxt_pP->module_id,
ctxt_pP->frame,
ctxt_pP->rnti,
ctxt_pP->module_id,
ue_context_p->ue_context.handover_info->modid_t);
//if (ue_context_p->ue_context.handover_info->ho_complete == 0xF1) {
//LOG_D(RRC,
// "[eNB %d] Frame %d: handover Command received for new UE_id %x current eNB %d target eNB: %d \n",
//ctxt_pP->module_id,
//ctxt_pP->frame,
//ctxt_pP->rnti,
//ctxt_pP->module_id,
//ue_context_p->ue_context.handover_info->modid_t);
//rrc_eNB_process_handoverPreparationInformation(enb_mod_idP,frameP,i);
result = pdcp_data_req(ctxt_pP,
SRB_FLAG_YES,
DCCH,
rrc_eNB_mui++,
SDU_CONFIRM_NO,
ue_context_p->ue_context.handover_info->size,
ue_context_p->ue_context.handover_info->buf,
PDCP_TRANSMISSION_MODE_CONTROL);
AssertFatal(result == TRUE, "PDCP data request failed!\n");
ue_context_p->ue_context.handover_info->ho_complete = 0xF2;
}
//result = pdcp_data_req(ctxt_pP,
//SRB_FLAG_YES,
//DCCH,
//rrc_eNB_mui++,
//SDU_CONFIRM_NO,
//ue_context_p->ue_context.handover_info->size,
//ue_context_p->ue_context.handover_info->buf,
//PDCP_TRANSMISSION_MODE_CONTROL);
//AssertFatal(result == TRUE, "PDCP data request failed!\n");
//ue_context_p->ue_context.handover_info->ho_complete = 0xF2;
//}
}
}
}
......@@ -2277,6 +2277,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover(
LOG_D(RRC,
"handover_config [FRAME %05d][RRC_eNB][MOD %02d][][--- MAC_CONFIG_REQ (SRB1 UE %x) --->][MAC_eNB][MOD %02d][]\n",
ctxt_pP->frame, ctxt_pP->module_id, ue_context_pP->ue_context.rnti, ctxt_pP->module_id);
rrc_mac_config_req(
ctxt_pP->module_id,
ue_context_pP->ue_context.primaryCC_id,
......@@ -2780,7 +2781,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover(
// rrc_pdcp_config_req (enb_mod_idP, frameP, 1, CONFIG_ACTION_ADD, idx, UNDEF_SECURITY_MODE);
// rrc_rlc_config_req(enb_mod_idP,frameP,1,CONFIG_ACTION_ADD,Idx,SIGNALLING_RADIO_BEARER,Rlc_info_am_config);
rrc_pdcp_config_asn1_req(&ctxt,
rrc_pdcp_config_asn1_req(ctxt_pP,
ue_context_pP->ue_context.SRB_configList,
(DRB_ToAddModList_t *) NULL, (DRB_ToReleaseList_t *) NULL, 0xff, NULL, NULL, NULL
#ifdef Rel10
......@@ -2788,7 +2789,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover(
#endif
);
rrc_rlc_config_asn1_req(&ctxt,
rrc_rlc_config_asn1_req(ctxt_pP,
ue_context_pP->ue_context.SRB_configList,
(DRB_ToAddModList_t *) NULL, (DRB_ToReleaseList_t *) NULL
#ifdef Rel10
......@@ -2849,6 +2850,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover(
ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_eNB_mui, ctxt_pP->module_id, DCCH);
//rrc_rlc_data_req(ctxt_pP->module_id,frameP, 1,(ue_mod_idP*NB_RB_MAX)+DCCH,rrc_eNB_mui++,0,size,(char*)buffer);
//pdcp_data_req (ctxt_pP->module_id, frameP, 1, (ue_mod_idP * NB_RB_MAX) + DCCH,rrc_eNB_mui++, 0, size, (char *) buffer, 1);
rrc_mac_config_req(
ctxt_pP->module_id,
ue_context_pP->ue_context.primaryCC_id,
......@@ -2906,6 +2908,9 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover(
ctxt_pP->module_id, ctxt_pP->frame);
#endif
pdcp_rrc_data_req(ctxt_pP,DCCH,rrc_eNB_mui++,SDU_CONFIRM_NO,size,buffer,PDCP_TRANSMISSION_MODE_CONTROL);
}
/*
......
0 0 1800 4800 200
10 0 4700 4840 200
20 0 6500 4880 200
0 0 1800 4700 200
0 0 2680 4800 0
0 1 4648 4800 0
0 2 6648 4800 0
......@@ -27,6 +27,15 @@
*******************************************************************************/
/*! \file x2ap.c
* \brief x2ap protocol
* \author Navid Nikaein
* \date 2014 - 2015
* \version 1.0
* \company Eurecom
* \email: navid.nikaein@eurecom.fr
*/
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
......@@ -37,9 +46,207 @@
#include "x2ap.h"
#include "msc.h"
#include "assertions.h"
#include "conversions.h"
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);
static
void x2ap_eNB_handle_sctp_association_resp(instance_t instance,
sctp_new_association_resp_t *sctp_new_association_resp);
static
int x2ap_eNB_generate_x2_setup_request(x2ap_eNB_instance_t *instance_p,
x2ap_enb_data_t *x2ap_enb_data_p);
static
int x2ap_eNB_generate_x2_setup_response(x2ap_eNB_instance_t *instance_p,
x2ap_enb_data_t *x2ap_enb_data_p);
static
int x2ap_eNB_generate_x2_setup_failure(x2ap_eNB_instance_t *instance_p,
x2ap_enb_data_t *x2ap_enb_data_p);
static
void x2ap_eNB_handle_sctp_data_ind(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_mme_data_t *x2ap_enb_data_p;
DevAssert(sctp_new_association_resp != NULL);
instance_p = x2ap_eNB_get_instance(instance);
DevAssert(instance_p != NULL);
x2ap_enb_data_p = x2ap_eNB_get_eNB(instance_p, -1,
sctp_new_association_resp->ulp_cnx_id);
DevAssert(x2ap_enb_data_p != NULL);
if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
S1AP_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;
}
/* 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;
/* Prepare new x2 Setup Request */
x2ap_eNB_generate_x2_setup_request(instance_p, x2ap_enb_data_p);
}
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)
{
MessageDef *message_p = NULL;
sctp_new_association_req_t *sctp_new_association_req_p = NULL;
x2ap_eNB_data_t *x2ap_enb_data_p = NULL;
DevAssert(instance_p != NULL);
DevAssert(target_eNB_ip_address != NULL);
message_p = itti_alloc_new_message(TASK_X2AP, SCTP_NEW_ASSOCIATION_REQ);
sctp_new_association_req_p = &message_p->ittiMsg.sctp_new_association_req;
sctp_new_association_req_p->port = X2AP_PORT_NUMBER;
sctp_new_association_req_p->ppid = X2AP_SCTP_PPID;
sctp_new_association_req_p->in_streams = in_streams;
sctp_new_association_req_p->out_streams = out_streams;
memcpy(&sctp_new_association_req_p->remote_address,
target_eNB_ip_address,
sizeof(*target_eNB_ip_address));
memcpy(&sctp_new_association_req_p->local_address,
local_ip_addr,
sizeof(*local_ip_addr));
/* Create new MME 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();
sctp_new_association_req_p->ulp_cnx_id = x2ap_enb_data_p->cnx_id;
x2ap_enb_data_p->assoc_id = -1;
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);
s1ap_mme_data_p->state = X2AP_ENB_STATE_WAITING;
instance_p->x2ap_enb_nb ++;
instance_p->x2ap_enb_pending_nb ++;
itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message_p);
}
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);
//RB_INIT(&new_instance->x2ap_ue_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);
}
DevCheck(x2ap_register_eNB->nb_mme <= 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_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);
}
}
void *x2ap_task(void *arg)
{
......@@ -60,6 +267,23 @@ void *x2ap_task(void *arg)
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);
case SCTP_DATA_IND: {
x2ap_eNB_handle_sctp_data_ind(&received_msg->ittiMsg.sctp_data_ind);
}
break;
default:
X2AP_ERROR("Received unhandled message: %d:%s\n",
ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg));
......
......@@ -38,6 +38,9 @@
#ifndef X2AP_H_
#define X2AP_H_
#define X2AP_PORT_NUMBER (36422) ///< X2AP SCTP IANA ASSIGNED Port Number
#define X2AP_SCTP_PPID (27) ///< X2AP SCTP Payload Protocol Identifier (PPID)
typedef struct x2ap_config_s {
} x2ap_config_t;
......
This diff is collapsed.
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2015 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
*******************************************************************************/
/*! \file x2ap_eNB_decoder.c
* \brief x2ap pdu decode procedures for eNB
* \author Navid Nikaein
* \date 2015- 2016
* \version 0.1
*/
#include "x2ap_common.h"
#include "x2ap_ies_defs.h"
#ifndef X2AP_ENB_PDU_DECODER_H_
#define X2AP_ENB_PDU_DECODER_H_
int x2ap_eNB_decode_pdu(x2ap_message *x2ap_message, uint8_t *buffer, uint32_t len);
#endif /* X2AP_PDU_DECODER_H_ */
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
*******************************************************************************/
#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_ENB_OVERLOAD = 0x3,
/* Max number of states available */
X2AP_ENB_STATE_MAX,
} s1ap_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;
/* 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/S1AP */
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 {
/* Next s1ap eNB association.
* Only used for virtual mode.
*/
STAILQ_ENTRY(x2ap_eNB_instance_s) x2ap_eNB_entries;
/* Number of target eNBs requested by eNB (tree size) */
uint32_t x2ap_enb_nb;
/* Number of target eNBs for which association is pending */
uint32_t x2ap_target_enb_pending_nb;
/* Number of target eNB successfully associated to eNB */
uint32_t x2ap_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 */
enum cell_type_e 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 S1AP 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 */
RB_PROTOTYPE(x2ap_eNB_map, x2ap_eNB_data_s, entry,
x2ap_eNB_compare_assoc_id);
#endif /* S1AP_ENB_DEFS_H_ */
This diff is collapsed.
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
*******************************************************************************/
#ifndef X2AP_ENB_ENCODER_H_
#define X2AP_ENB_ENCODER_H_
int x2ap_eNB_encode_pdu(s1ap_message *message, uint8_t **buffer, uint32_t *len)
__attribute__ ((warn_unused_result));
#endif /* X2AP_ENB_ENCODER_H_ */
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/*! \file x2ap_eNB_generate_messages.c
* \brief x2ap message generator
* \author Navid Nikaein
* \date 2015 - 2016
* \version 1.0
* \company Eurecom
* \email: navid.nikaein@eurecom.fr
*/
#include "intertask_interface.h"
#include "x2ap.h"
#include "msc.h"
#include "assertions.h"
static
int x2ap_eNB_generate_x2_setup_request(x2ap_eNB_instance_t *instance_p,
x2ap_enb_data_t *x2ap_enb_data_p){
x2ap_message message;
X2SetupRequest_IEs_t *x2SetupRequest_p;
X2ap_PLMN_Identity_t plmnIdentity;
X2ap_PLMN_Identity_t broadcast_plmnIdentity_1;
X2ap_PLMN_Identity_t broadcast_plmnIdentity_2;
X2ap_PLMN_Identity_t broadcast_plmnIdentity_3;
ServedCellItem_t *served_cell= malloc(sizeof(ServedCellItem_t));;
uint8_t *buffer;
uint32_t len;
int ret = 0;
DevAssert(instance_p != NULL);
DevAssert(x2ap_enb_data_p != NULL);
memset(&message, 0, sizeof(x2ap_message));
message.direction = X2AP_PDU_PR_initiatingMessage;
message.procedureCode = X2ap_ProcedureCode_id_X2Setup;
message.criticality = X2ap_Criticality_reject;
x2SetupRequest_p = &message.msg.x2SetupRequest_IEs;
memset((void *)&plmnIdentity, 0, sizeof(X2ap_PLMN_Identity_t));
memset((void *)&broadcast_plmnIdentity_1, 0, sizeof(X2ap_PLMN_Identity_t));
memset((void *)&broadcast_plmnIdentity_2, 0, sizeof(X2ap_PLMN_Identity_t));
memset((void *)&broadcast_plmnIdentity_3, 0, sizeof(X2ap_PLMN_Identity_t));
x2ap_enb_data_p->state = X2AP_ENB_STATE_WAITING;
//----globalENB_ID------
x2SetupRequest_p->global_ENB_ID.eNB_ID.present = X2ap_ENB_ID_PR_macro_eNB_ID;
MACRO_ENB_ID_TO_BIT_STRING(instance_p->eNB_id,
&x2SetupRequest_p->global_ENB_ID.eNB_ID.choice.macroENB_ID);
MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
&x2SetupRequest_p->global_ENB_ID.pLMNidentity);
X2AP_INFO("%d -> %02x%02x%02x\n", instance_p->eNB_id,
x2SetupRequest_p->global_ENB_ID.eNB_ID.choice.macroENB_ID.buf[0],
x2SetupRequest_p->global_ENB_ID.eNB_ID.choice.macroENB_ID.buf[1],
x2SetupRequest_p->global_ENB_ID.eNB_ID.choice.macroENB_ID.buf[2]);
//----served cells------
#warning update the value of the message
served_cell->servedCellInfo.pCI = 6;
served_cell->servedCellInfo.eUTRA_Mode_Info.present = EUTRA_Mode_Info_PR_fDD;
served_cell->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_EARFCN = 3350;
served_cell->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_EARFCN = 3350;
served_cell->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = 0;
served_cell->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = 0;
MCC_MNC_TO_PLMNID(instance_p->mcc,instance_p->mnc,&served_cell->servedCellInfo.cellId.pLMN_Identity);
MCC_MNC_TO_PLMNID(0,0,&broadcast_plmnid_1);
MCC_MNC_TO_PLMNID(0,0,&broadcast_plmnid_2);
MCC_MNC_TO_PLMNID(0,0,&broadcast_plmnid_3);
ASN_SEQUENCE_ADD(&served_cell->servedCellInfo.broadcastPLMNs.list, &broadcast_plmnid_1);
ASN_SEQUENCE_ADD(&served_cell->servedCellInfo.broadcastPLMNs.list, &broadcast_plmnid_2);
ASN_SEQUENCE_ADD(&served_cell->servedCellInfo.broadcastPLMNs.list, &broadcast_plmnid_3);
ECI_TO_BIT_STRING(instance_p->eNB_id, &served_cell->servedCellInfo.cellId.eUTRANcellIdentifier);
TAC_TO_OCTET_STRING(instance_p->tac, &served_cell->servedCellInfo.tAC);
ASN_SEQUENCE_ADD(&x2SetupRequest_p->servedCells.list, served_cell);
if (x2ap_eNB_encode_pdu(&message, &buffer, &len) < 0) {
X2AP_ERROR("Failed to encode X2 setup request\n");
return -1;
}
/* Non UE-Associated signalling -> stream = 0 */
x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_enb_data_p->assoc_id, buffer, len, 0);
return ret;
}
This diff is collapsed.
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
*******************************************************************************/
#ifndef X2AP_ENB_HANDLERS_H_
#define X2AP_ENB_HANDLERS_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_ */
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
*******************************************************************************/
#include "intertask_interface.h"
#include "x2ap_eNB_itti_messaging.h"
void x2ap_eNB_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer,
uint32_t buffer_length, uint16_t stream)
{
MessageDef *message_p;
sctp_data_req_t *sctp_data_req;
message_p = itti_alloc_new_message(TASK_X2AP, SCTP_DATA_REQ);
sctp_data_req = &message_p->ittiMsg.sctp_data_req;
sctp_data_req->assoc_id = assoc_id;
sctp_data_req->buffer = buffer;
sctp_data_req->buffer_length = buffer_length;
sctp_data_req->stream = stream;
itti_send_msg_to_task(TASK_SCTP, instance, message_p);
}
/*
void x2ap_eNB_itti_send_nas_downlink_ind(instance_t instance,
uint16_t ue_initial_id,
uint32_t eNB_ue_s1ap_id,
uint8_t *nas_pdu,
uint32_t nas_pdu_length)
{
MessageDef *message_p;
x2ap_rrc_t *x2ap_rrc;
message_p = itti_alloc_new_message(TASK_X2AP, X2AP_RRC);
x2ap_rrc = &message_p->ittiMsg.x2ap_rrc;
x2ap_rrc->ue_initial_id = ue_initial_id;
x2ap_rrc->eNB_ue_x2ap_id = eNB_ue_x2ap_id;
x2ap_rrc->rrc_pdu.buffer = rrc_pdu;
x2ap_rrc->rrc_pdu.length = rrc_pdu_length;
itti_send_msg_to_task(TASK_RRC_ENB, instance, message_p);
}
*/
void x2ap_eNB_itti_send_sctp_close_association(instance_t instance, int32_t assoc_id)
{
MessageDef *message_p = NULL;
sctp_close_association_t *sctp_close_association_p = NULL;
message_p = itti_alloc_new_message(TASK_X2AP, SCTP_CLOSE_ASSOCIATION);
sctp_close_association_p = &message_p->ittiMsg.sctp_close_association;
sctp_close_association_p->assoc_id = assoc_id;
itti_send_msg_to_task(TASK_SCTP, instance, message_p);
}
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
*******************************************************************************/
#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.h"
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);
}
struct s1ap_eNB_mme_data_s *x2ap_eNB_get_taregt_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;
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;
}
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
*******************************************************************************/
#ifndef X2AP_ENB_MANAGEMENT_PROCEDURES_H_
#define X2AP_ENB_MANAGEMENT_PROCEDURES_H_
/*
struct x2ap_eNB_mme_data_s *s1ap_eNB_get_MME(
s1ap_eNB_instance_t *instance_p,
int32_t assoc_id, uint16_t cnx_id);
*/
void x2ap_eNB_insert_new_instance(x2ap_eNB_instance_t *new_instance_p);
x2ap_eNB_instance_t *x2ap_eNB_get_instance(uint8_t mod_id);
uint16_t x2ap_eNB_fetch_add_global_cnx_id(void);
void x2ap_eNB_prepare_internal_data(void);
#endif /* X2AP_ENB_MANAGEMENT_PROCEDURES_H_ */
......@@ -203,7 +203,7 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *
/* Trying to connect to provided list of MME ip address */
for (index = 0; index < s1ap_register_eNB->nb_mme; index++) {
s1ap_eNB_register_mme(new_instance,
&s1ap_register_eNB->mme_ip_address[index],
&s1ap_register_eNB->mme_ip_address[index],
&s1ap_register_eNB->enb_ip_address,
s1ap_register_eNB->sctp_in_streams,
s1ap_register_eNB->sctp_out_streams);
......
......@@ -220,7 +220,7 @@ int s1ap_eNB_decode_pdu(s1ap_message *message, const uint8_t * const buffer,
0);
if (dec_ret.code != RC_OK) {
S1AP_ERROR("Failed to decode pdu\n");
S1AP_ERROR("Failed to S1AP decode pdu\n");
return -1;
}
......
......@@ -30,6 +30,7 @@
/*! \file s1ap_eNB_encoder.c
* \brief s1ap pdu encode procedures for eNB
* \author Sebastien ROUX <sebastien.roux@eurecom.fr>
* \maintainer Navid Nikaein
* \date 2013
* \version 0.1
*/
......
......@@ -17,7 +17,7 @@ eNBs =
mobile_country_code = "208";
mobile_network_code = "93";
mobile_network_code = "92";
////////// Physical parameters:
......@@ -133,21 +133,38 @@ eNBs =
////////// MME parameters:
mme_ip_address = ( { ipv4 = "192.168.12.11";
mme_ip_address = ( { ipv4 = "10.0.1.1";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
NETWORK_INTERFACES :
///X2
target_enb_x2_ip_address = ( { ipv4 = "10.0.1.1";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
NETWORK_INTERFACES :
{
ENB_INTERFACE_NAME_FOR_S1_MME = "eth0";
ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.216/24";
ENB_IPV4_ADDRESS_FOR_S1_MME = "10.0.1.100/24";
ENB_INTERFACE_NAME_FOR_S1U = "eth0";
ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.216/24";
ENB_IPV4_ADDRESS_FOR_S1U = "10.0.1.100/24";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
ENB_INTERFACE_NAME_FOR_X2C = "eth0";
ENB_IPV4_ADDRESS_FOR_X2C = "10.0.1.100/24";
ENB_PORT_FOR_X2C = 1234; # Spec ?
ENB_INTERFACE_NAME_FOR_X2U = "eth0";
ENB_IPV4_ADDRESS_FOR_X2U = "10.0.1.100/24";
ENB_PORT_FOR_X2U = 1234; # Spec ?
};
log_config :
......
......@@ -46,7 +46,7 @@
<eNB_MOBILITY>
<eNB_INITIAL_DISTRIBUTION>random</eNB_INITIAL_DISTRIBUTION> <!-- use random here and trace for the mobility to define your own positions -->
<RANDOM_eNB_DISTRIBUTION>
<NUMBER_OF_CELLS>3</NUMBER_OF_CELLS>
<NUMBER_OF_CELLS>2</NUMBER_OF_CELLS>
</RANDOM_eNB_DISTRIBUTION>
<eNB_MOBILITY_TYPE>TRACE</eNB_MOBILITY_TYPE>
<TRACE_MOBILITY_FILE>hexagonal_eNBs.tr</TRACE_MOBILITY_FILE> <!-- file should be located at $(OPENAIR2)/UTIL/OMG/TRACE/, see README there-->
......
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