Commit 9ca54779 authored by Cedric Roux's avatar Cedric Roux

integrate X2 code

parent 75418f50
......@@ -46,5 +46,6 @@ MESSAGE_DEF(X2AP_REGISTER_ENB_REQ , MESSAGE_PRIORITY_MED, x2ap_register
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)
/* handover messages X2AP <-> RRC */
MESSAGE_DEF(X2AP_HANDOVER_REQ , MESSAGE_PRIORITY_MED, x2ap_handover_req_t , x2ap_handover_req)
MESSAGE_DEF(X2AP_HANDOVER_RESP , MESSAGE_PRIORITY_MED, x2ap_handover_resp_t , x2ap_handover_resp)
......@@ -30,10 +30,14 @@
#ifndef X2AP_MESSAGES_TYPES_H_
#define X2AP_MESSAGES_TYPES_H_
#include "PhysCellId.h"
//-------------------------------------------------------------------------------------------//
// Defines to access message fields.
#define X2AP_REGISTER_ENB_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_register_enb_req
#define X2AP_HANDOVER_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_req
#define X2AP_HANDOVER_RESP(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_resp
#define X2AP_REGISTER_ENB_CNF(mSGpTR) (mSGpTR)->ittiMsg.x2ap_register_enb_cnf
#define X2AP_DEREGISTERED_ENB_IND(mSGpTR) (mSGpTR)->ittiMsg.x2ap_deregistered_enb_ind
......@@ -105,4 +109,22 @@ typedef struct x2ap_deregistered_enb_ind_s {
uint8_t nb_x2;
} x2ap_deregistered_enb_ind_t;
//-------------------------------------------------------------------------------------------//
// X2AP <-> RRC
typedef struct x2ap_handover_req_s {
int source_rnti; /* TODO: to be fixed/remove */
int source_x2id; /* TODO: to be fixed/remove */
PhysCellId_t target_physCellId;
/* TODO: this parameter has to be removed */
int target_mod_id;
} x2ap_handover_req_t;
typedef struct x2ap_handover_resp_s {
int source_rnti; /* TODO: to be fixed/remove */
int source_x2id; /* TODO: to be fixed/remove */
/* TODO: this parameter has to be removed */
int target_mod_id;
} x2ap_handover_resp_t;
#endif /* X2AP_MESSAGES_TYPES_H_ */
......@@ -165,7 +165,7 @@ int xer_sprint (char *string, size_t string_size, asn_TYPE_descriptor_t *td, voi
er.encoded = string_buffer.string_size;
} else {
if (er.encoded > string_buffer.string_size) {
LOG_E(RRC, "xer_sprint string buffer too small, got %d need %d!", string_buffer.string_size, er.encoded);
//LOG_E(RRC, "xer_sprint string buffer too small, got %d need %d!", string_buffer.string_size, er.encoded);
er.encoded = string_buffer.string_size;
}
}
......
......@@ -166,7 +166,11 @@ typedef enum HO_STATE_e {
HO_MEASURMENT,
HO_PREPARE,
HO_CMD, // initiated by the src eNB
HO_COMPLETE // initiated by the target eNB
HO_COMPLETE, // initiated by the target eNB
HO_REQUEST,
HO_ACK,
HO_CONFIGURED,
} HO_STATE_t;
//#define NUMBER_OF_UE_MAX MAX_MOBILES_PER_RG
......@@ -235,8 +239,8 @@ typedef struct e_rab_param_s {
/* Intermediate structure for Handover management. Associated per-UE in eNB_RRC_INST */
typedef struct HANDOVER_INFO_s {
uint8_t ho_prepare;
uint8_t ho_complete;
int ho_prepare, ho_complete;
HO_STATE_t state; //current state of handover
uint8_t modid_s; //module_idP of serving cell
uint8_t modid_t; //module_idP of target cell
uint16_t ueid_s; //UE index in serving cell
......@@ -245,6 +249,8 @@ typedef struct HANDOVER_INFO_s {
AS_Context_t as_context; /* They are mandatory for HO */
uint8_t buf[RRC_BUF_SIZE]; /* ASN.1 encoded handoverCommandMessage */
int size; /* size of above message in bytes */
/* TODO: to remove or not? */
int source_x2id;
} HANDOVER_INFO;
#define RRC_HEADER_SIZE_MAX 64
......
......@@ -1812,6 +1812,31 @@ rrc_eNB_process_MeasurementReport(
LOG_I(RRC, "RSRQ of Source %d\n", measResults2->measResultServCell.rsrqResult);
#endif
/* if the UE is not in handover mode, start handover procedure */
if (ue_context_pP->ue_context.Status != RRC_HO_EXECUTION) {
MessageDef *msg;
ue_context_pP->ue_context.Status = RRC_HO_EXECUTION;
ue_context_pP->ue_context.handover_info->state = HO_REQUEST;
rrc_eNB_generate_HandoverPreparationInformation(ctxt_pP,
ue_context_pP,
measResults2->measResultNeighCells->choice.
measResultListEUTRA.list.array[0]->physCellId);
msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_HANDOVER_REQ);
X2AP_HANDOVER_REQ(msg).source_rnti = ctxt_pP->rnti;
X2AP_HANDOVER_REQ(msg).target_physCellId = measResults2->measResultNeighCells->choice.
measResultListEUTRA.list.array[0]->physCellId;
/* TODO: don't do that, X2AP should find the target by itself */
X2AP_HANDOVER_REQ(msg).target_mod_id = get_adjacent_cell_mod_id(X2AP_HANDOVER_REQ(msg).target_physCellId);
itti_send_msg_to_task(TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), msg);
} else {
LOG_D(RRC, "[eNB %d] Frame %d: Ignoring MeasReport from UE %x as Handover is in progress... \n", ctxt_pP->module_id, ctxt_pP->frame,
ctxt_pP->rnti);
}
#if 0
if (ue_context_pP->ue_context.handover_info->ho_prepare != 0xF0) {
rrc_eNB_generate_HandoverPreparationInformation(ctxt_pP,
ue_context_pP,
......@@ -1821,6 +1846,7 @@ rrc_eNB_process_MeasurementReport(
LOG_D(RRC, "[eNB %d] Frame %d: Ignoring MeasReport from UE %x as Handover is in progress... \n", ctxt_pP->module_id, ctxt_pP->frame,
ctxt_pP->rnti);
}
#endif
//Look for IP address of the target eNB
//Send Handover Request -> target eNB
......@@ -1899,6 +1925,46 @@ rrc_eNB_generate_HandoverPreparationInformation(
}
}
static int global_rnti;
void rrc_eNB_process_handoverPreparationInformation(int mod_id, x2ap_handover_req_t *m)
{
struct rrc_eNB_ue_context_s* ue_context_target_p = NULL;
/* TODO: get proper UE rnti */
int rnti = taus() & 0xffff;
global_rnti = rnti;
ue_context_target_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[mod_id], rnti);
if (ue_context_target_p != NULL) {
LOG_E(RRC, "\nError in obtaining free UE id in target eNB for handover \n");
return;
}
ue_context_target_p = rrc_eNB_allocate_new_UE_context(&eNB_rrc_inst[mod_id]);
if (ue_context_target_p == NULL) {
LOG_E(RRC, "Cannot create new UE context\n");
return;
}
ue_context_target_p->ue_id_rnti = rnti;
ue_context_target_p->ue_context.rnti = rnti;
RB_INSERT(rrc_ue_tree_s, &eNB_rrc_inst[mod_id].rrc_ue_head, ue_context_target_p);
LOG_D(RRC, "eNB %d: Created new UE context uid %u\n", mod_id, ue_context_target_p->local_uid);
ue_context_target_p->ue_context.handover_info = CALLOC(1, sizeof(*(ue_context_target_p->ue_context.handover_info)));
ue_context_target_p->ue_context.handover_info->source_x2id = m->source_x2id;
ue_context_target_p->ue_context.Status = RRC_HO_EXECUTION;
ue_context_target_p->ue_context.handover_info->state = HO_ACK;
/* TODO: remove this hack */
ue_context_target_p->ue_context.handover_info->modid_t = mod_id;
ue_context_target_p->ue_context.handover_info->modid_s = 1-mod_id;
ue_context_target_p->ue_context.handover_info->ueid_s= m->source_rnti;
}
#if 0
//-----------------------------------------------------------------------------
void
rrc_eNB_process_handoverPreparationInformation(
......@@ -1983,6 +2049,7 @@ rrc_eNB_process_handoverPreparationInformation(
//rrc_create_old_crnti(ctxt_pP,ue_context_target_p->ue_context.handover_info->modid_s,0, ue_context_pP->ue_id_rnti);
}
#endif
//-----------------------------------------------------------------------------
void
......@@ -1994,12 +2061,12 @@ check_handovers(
int result;
struct rrc_eNB_ue_context_s* ue_context_p;
RB_FOREACH(ue_context_p, rrc_ue_tree_s, &eNB_rrc_inst[ctxt_pP->module_id].rrc_ue_head) {
ctxt_pP->rnti = ue_context_p->ue_id_rnti;
if (ue_context_p->ue_context.handover_info != NULL) {
if (ue_context_p->ue_context.handover_info->ho_prepare == 0xFF) {
if (ue_context_p->ue_context.Status == RRC_HO_EXECUTION && ue_context_p->ue_context.handover_info != NULL) {
/* in the source, UE in HO_PREPARE mode */
if (ue_context_p->ue_context.handover_info->state == HO_PREPARE /*ho_prepare == 0xFF*/) {
LOG_D(RRC,
"[eNB %d] Frame %d: Incoming handover detected for new UE_id %x (source eNB %d->target eNB %d) \n",
ctxt_pP->module_id,
......@@ -2008,19 +2075,45 @@ check_handovers(
ctxt_pP->module_id,
ue_context_p->ue_context.handover_info->modid_t);
// source eNB generates rrcconnectionreconfiguration to prepare the HO
LOG_I(RRC,
"[eNB %d] Frame %d : Logical Channel UL-DCCH, processing RRCHandoverPreparationInformation, sending RRCConnectionReconfiguration to UE %d \n",
ctxt_pP->module_id, ctxt_pP->frame, ue_context_p->ue_context.rnti);
/* TODO: remove this hack, this call has to be done here I think but we must do
* it before rrc_eNB_configure_rbs_handover because the SRBs are copied
* instead of coming from the X2AP message as should be done
*/
// rrc_eNB_generate_RRCConnectionReconfiguration_handover(
// ctxt_pP,
// ue_context_p,
// NULL,
// 0);
#if 0
rrc_eNB_process_handoverPreparationInformation(
ctxt_pP,
ue_context_p);
ue_context_p->ue_context.handover_info->ho_prepare = 0xF0;
#endif
//ue_context_p->ue_context.handover_info->ho_prepare = 0xF0;
ue_context_p->ue_context.handover_info->state = HO_COMPLETE;
}
if (ue_context_p->ue_context.handover_info->ho_prepare == 0xF2) {
// Configure target
rrc_eNB_configure_rbs_handover(ue_context_p,ctxt_pP);
ue_context_p->ue_context.handover_info->ho_prepare = 0x00;
/* in the target, UE in HO_ACK mode */
if (ue_context_p->ue_context.handover_info->state == HO_ACK /*ho_prepare == 0xF2*/) {
MessageDef *msg;
// Configure target
rrc_eNB_configure_rbs_handover(ue_context_p,ctxt_pP);
// ue_context_p->ue_context.handover_info->ho_prepare = 0x00;
ue_context_p->ue_context.handover_info->state = HO_CONFIGURED;
msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_HANDOVER_RESP);
/* TODO: remove this hack */
X2AP_HANDOVER_RESP(msg).target_mod_id = 1 - ctxt_pP->module_id;
X2AP_HANDOVER_RESP(msg).source_x2id = ue_context_p->ue_context.handover_info->source_x2id;
itti_send_msg_to_task(TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), msg);
}
/* THIS CODE IS NOT RUN */
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",
......@@ -2057,6 +2150,21 @@ rrc_eNB_configure_rbs_handover(struct rrc_eNB_ue_context_s* ue_context_p, protoc
&eNB_rrc_inst[ue_context_p->ue_context.handover_info->modid_s],
ue_context_p->ue_context.handover_info->ueid_s);
if(ue_source_context!=NULL){
/* HACK - we have to call rrc_eNB_generate_RRCConnectionReconfiguration_handover before for the SRBs to be okay */
/* to be removed when X2 messages are done */
{
protocol_ctxt_t c = *ctxt_pP;
c.module_id = 0;
c.enb_flag = 1;
c.instance = 0;
c.rnti = ue_source_context->ue_context.rnti;
c.eNB_index = 0;
rrc_eNB_generate_RRCConnectionReconfiguration_handover(
&c,
ue_source_context,
NULL,
0);
}
LOG_D(RRC,"Frame: %d-Entering target: C-RNTI %x-eNB: %d-MOD_ID: %d\n",ctxt_pP->frame,ctxt_pP->rnti,ctxt_pP->eNB_index,ctxt_pP->module_id);
// E-RABS
// Emulating transmission/reception (just a memory copy)
......@@ -2235,6 +2343,8 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover(
rv[i] = taus() & 0xff;
LOG_D(RRC, " %x.", rv[i]);
}
rv[0] = global_rnti&255;
rv[1] = (global_rnti>>8) & 255;
LOG_D(RRC, "[eNB %d] Frame %d : handover reparation: add target eNB SRB1 and PHYConfigDedicated reconfiguration\n",
ctxt_pP->module_id, ctxt_pP->frame);
......@@ -2276,6 +2386,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover(
*logicalchannelgroup = 0;
SRB1_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup;
ASN_SEQUENCE_ADD(&SRB_configList->list, SRB1_config);
ASN_SEQUENCE_ADD(&SRB_configList2->list, SRB1_config);
//2nd: now reconfigure phy config dedicated
......@@ -2484,8 +2595,8 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover(
// Configure target eNB SRB2
/// SRB2
SRB2_config = CALLOC(1, sizeof(*SRB2_config));
SRB_configList2 = CALLOC(1, sizeof(*SRB_configList2));
memset(SRB_configList2, 0, sizeof(*SRB_configList2));
//SRB_configList2 = CALLOC(1, sizeof(*SRB_configList2));
//memset(SRB_configList2, 0, sizeof(*SRB_configList2));
SRB2_config->srb_Identity = 1;
SRB2_rlc_config = CALLOC(1, sizeof(*SRB2_rlc_config));
......@@ -4548,6 +4659,20 @@ rrc_enb_task(
# endif
case X2AP_HANDOVER_REQ:
LOG_I(RRC, "[eNB %d] Received %s\n", instance, msg_name_p);
rrc_eNB_process_handoverPreparationInformation(instance, &X2AP_HANDOVER_REQ(msg_p));
break;
case X2AP_HANDOVER_RESP: {
struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(&eNB_rrc_inst[instance], X2AP_HANDOVER_RESP(msg_p).source_rnti);
LOG_I(RRC, "[eNB %d] Received %s\n", instance, msg_name_p);
DevAssert(ue_context_p != NULL);
if (ue_context_p->ue_context.handover_info->state != HO_REQUEST) abort();
ue_context_p->ue_context.handover_info->state = HO_PREPARE;
break;
}
/* Messages from eNB app */
case RRC_CONFIGURATION_REQ:
LOG_I(RRC, "[eNB %d] Received %s\n", instance, msg_name_p);
......
......@@ -29,7 +29,7 @@
/*! \file x2ap_eNB.c
* \brief x2ap protocol for eNB
* \author Navid Nikaein
* \author Navid Nikaein
* \date 2014 - 2015
* \version 1.0
* \company Eurecom
......@@ -66,31 +66,39 @@ 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_register_eNB(instance_t instance,
void x2ap_eNB_handle_register_eNB(instance_t instance,
x2ap_register_enb_req_t *x2ap_register_eNB);
static
static
void x2ap_eNB_handle_handover_req(instance_t instance,
x2ap_handover_req_t *x2ap_handover_req);
static
void x2ap_eNB_handle_handover_resp(instance_t instance,
x2ap_handover_resp_t *x2ap_handover_resp);
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,
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,
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,
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);
......@@ -141,7 +149,7 @@ dump_trees();
instance,
sctp_new_association_resp->ulp_cnx_id);
x2ap_handle_x2_setup_message(x2ap_enb_data_p,
x2ap_handle_x2_setup_message(x2ap_enb_data_p,
sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN);
return;
......@@ -217,13 +225,13 @@ int x2ap_eNB_init_sctp (x2ap_eNB_instance_t *instance_p,
// 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);
sctp_init = &message->ittiMsg.sctp_init;
sctp_init->port = X2AP_PORT_NUMBER;
sctp_init->ppid = X2AP_SCTP_PPID;
sctp_init->ipv4 = 1;
......@@ -243,11 +251,11 @@ int x2ap_eNB_init_sctp (x2ap_eNB_instance_t *instance_p,
*/
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,
......@@ -302,7 +310,7 @@ static void x2ap_eNB_register_eNB(x2ap_eNB_instance_t *instance_p,
}
static
void x2ap_eNB_handle_register_eNB(instance_t instance,
void x2ap_eNB_handle_register_eNB(instance_t instance,
x2ap_register_enb_req_t *x2ap_register_eNB)
{
......@@ -322,7 +330,7 @@ void x2ap_eNB_handle_register_eNB(instance_t instance,
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);
......@@ -351,11 +359,11 @@ void x2ap_eNB_handle_register_eNB(instance_t instance,
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++) {
if (x2ap_register_eNB->target_enb_x2_ip_address[index].active == 1 ){
X2AP_INFO("eNB[%d] eNB id %u acting as an initiator (client)\n",
instance, x2ap_register_eNB->eNB_id);
......@@ -366,7 +374,7 @@ void x2ap_eNB_handle_register_eNB(instance_t instance,
x2ap_register_eNB->sctp_out_streams);
}
else {
/* initiate the SCTP listener */
/* initiate the SCTP listener */
if (x2ap_eNB_init_sctp(new_instance,&x2ap_register_eNB->enb_x2_ip_address) < 0 ) {
X2AP_ERROR ("Error while sending SCTP_INIT_MSG to SCTP \n");
return;
......@@ -378,6 +386,64 @@ void x2ap_eNB_handle_register_eNB(instance_t instance,
}
/* TODO: remove this hack, it's to map rnti to X2 ID in the source eNB, only 1 UE supported */
/* so we directly use index 0, no search no lock no nothing */
int x2id_to_source_rnti[1];
/* TODO: remove that, it's for the hack below */
#include "enb_config.h"
static
void x2ap_eNB_handle_handover_req(instance_t instance,
x2ap_handover_req_t *x2ap_handover_req)
{
/* TODO: remove this hack (the goal is to find the correct
* eNodeB structure for the target) - we need a proper way for RRC
* and X2AP to identify eNodeBs
* RRC knows about mod_id and X2AP knows about eNB_id (eNB_ID in
* the configuration file)
* as far as I understand.. CROUX
*/
x2ap_eNB_instance_t *instance_p;
x2ap_eNB_data_t *target;
const Enb_properties_array_t *enb_properties = enb_config_get();
int target_enb_id = enb_properties->properties[x2ap_handover_req->target_mod_id]->eNB_id;
instance_p = x2ap_eNB_get_instance(instance);
DevAssert(instance_p != NULL);
target = x2ap_is_eNB_id_in_list(target_enb_id);
DevAssert(target != NULL);
/* store rnti at index 0 */
x2id_to_source_rnti[0] = x2ap_handover_req->source_rnti;
x2ap_eNB_generate_x2_handover_request(instance_p, target, 0);
}
static
void x2ap_eNB_handle_handover_resp(instance_t instance,
x2ap_handover_resp_t *x2ap_handover_resp)
{
/* TODO: remove this hack (the goal is to find the correct
* eNodeB structure for the other end) - we need a proper way for RRC
* and X2AP to identify eNodeBs
* RRC knows about mod_id and X2AP knows about eNB_id (eNB_ID in
* the configuration file)
* as far as I understand.. CROUX
*/
x2ap_eNB_instance_t *instance_p;
x2ap_eNB_data_t *target;
const Enb_properties_array_t *enb_properties = enb_config_get();
int target_enb_id = enb_properties->properties[x2ap_handover_resp->target_mod_id]->eNB_id;
instance_p = x2ap_eNB_get_instance(instance);
DevAssert(instance_p != NULL);
target = x2ap_is_eNB_id_in_list(target_enb_id);
DevAssert(target != NULL);
x2ap_eNB_generate_x2_handover_response(instance_p, target, x2ap_handover_resp->source_x2id);
}
void *x2ap_task(void *arg)
{
......@@ -398,16 +464,26 @@ void *x2ap_task(void *arg)
itti_exit_task();
break;
case X2AP_REGISTER_ENB_REQ:
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:
case X2AP_HANDOVER_REQ:
x2ap_eNB_handle_handover_req(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&X2AP_HANDOVER_REQ(received_msg));
break;
case X2AP_HANDOVER_RESP:
x2ap_eNB_handle_handover_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&X2AP_HANDOVER_RESP(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);
......
......@@ -29,7 +29,7 @@
/*! \file x2ap_eNB_generate_messages.c
* \brief x2ap message generator
* \author Navid Nikaein
* \author Navid Nikaein
* \date 2015 - 2016
* \version 1.0
* \company Eurecom
......@@ -48,21 +48,21 @@
#include "conversions.h"
int x2ap_eNB_generate_x2_setup_request(x2ap_eNB_instance_t *instance_p,
x2ap_eNB_data_t *x2ap_enb_data_p){
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;
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;
X2ap_ServedCellItem_t *served_cell= malloc(sizeof(X2ap_ServedCellItem_t));
uint8_t *buffer;
uint32_t len;
int ret = 0;
......@@ -83,7 +83,7 @@ int x2ap_eNB_generate_x2_setup_request(x2ap_eNB_instance_t *instance_p,
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------
......@@ -93,16 +93,16 @@ int x2ap_eNB_generate_x2_setup_request(x2ap_eNB_instance_t *instance_p,
MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
&x2SetupRequest->globalENB_ID.pLMN_Identity);
X2AP_INFO("%d -> %02x%02x%02x\n", instance_p->eNB_id,
x2SetupRequest->globalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[0],
X2AP_INFO("%d -> %02x%02x%02x\n", instance_p->eNB_id,
x2SetupRequest->globalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[0],
x2SetupRequest->globalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[1],
x2SetupRequest->globalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[2]);
//----served cells------
#warning update the value of the message
served_cell->servedCellInfo.pCI = 6;
served_cell->servedCellInfo.eUTRA_Mode_Info.present = X2ap_EUTRA_Mode_Info_PR_fDD;
served_cell->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_EARFCN = 3350;
served_cell->servedCellInfo.eUTRA_Mode_Info.present = X2ap_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;
......@@ -135,32 +135,32 @@ int x2ap_eNB_generate_x2_setup_request(x2ap_eNB_instance_t *instance_p,
}
int
int
x2ap_generate_x2_setup_response (x2ap_eNB_data_t * eNB_association)
{
x2ap_eNB_instance_t *instance=eNB_association->x2ap_eNB_instance;
x2ap_message message;
X2SetupResponse_IEs_t *x2SetupResponse;
// 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;
X2ap_ServedCellItem_t *served_cell = calloc(1, sizeof(X2ap_ServedCellItem_t));;
uint8_t *buffer;
uint32_t len;
int ret = 0;
// get the eNB instance
//
// get the eNB instance
//
DevAssert (eNB_association != NULL);
// Generating response
memset (&message, 0, sizeof (x2ap_message));
message.direction = X2AP_PDU_PR_successfulOutcome;
......@@ -168,13 +168,13 @@ x2ap_generate_x2_setup_response (x2ap_eNB_data_t * eNB_association)
message.criticality = X2ap_Criticality_reject;
x2SetupResponse = &message.msg.x2SetupResponse_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));
//----globalENB_ID------
x2SetupResponse->globalENB_ID.eNB_ID.present = X2ap_ENB_ID_PR_macro_eNB_ID;
MACRO_ENB_ID_TO_BIT_STRING(instance->eNB_id,
......@@ -182,16 +182,16 @@ x2ap_generate_x2_setup_response (x2ap_eNB_data_t * eNB_association)
MCC_MNC_TO_PLMNID(instance->mcc, instance->mnc, instance->mnc_digit_length,
&x2SetupResponse->globalENB_ID.pLMN_Identity);
X2AP_INFO("%d -> %02x%02x%02x\n", instance->eNB_id,
x2SetupResponse->globalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[0],
X2AP_INFO("%d -> %02x%02x%02x\n", instance->eNB_id,
x2SetupResponse->globalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[0],
x2SetupResponse->globalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[1],
x2SetupResponse->globalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[2]);
//----served cells------
#warning update the value of the message
served_cell->servedCellInfo.pCI = 6;
served_cell->servedCellInfo.eUTRA_Mode_Info.present = X2ap_EUTRA_Mode_Info_PR_fDD;
served_cell->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_EARFCN = 3350;
served_cell->servedCellInfo.eUTRA_Mode_Info.present = X2ap_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;
......@@ -213,7 +213,7 @@ x2ap_generate_x2_setup_response (x2ap_eNB_data_t * eNB_association)
X2AP_ERROR("Failed to encode X2 setup request\n");
return -1;
}
eNB_association->state = X2AP_ENB_STATE_READY;
MSC_LOG_TX_MESSAGE (MSC_X2AP_TARGET_ENB, MSC_X2AP_SRC_ENB, NULL, 0, "0 X2Setup/successfulOutcome assoc_id %u", eNB_association->assoc_id);
......@@ -232,8 +232,8 @@ int x2ap_eNB_set_cause (X2ap_Cause_t * cause_p,
int x2ap_eNB_generate_x2_setup_failure ( uint32_t assoc_id,
X2ap_Cause_PR cause_type,
long cause_value,
long time_to_wait){
long time_to_wait){
uint8_t *buffer_p;
uint32_t length;
x2ap_message message;
......@@ -245,19 +245,19 @@ int x2ap_eNB_generate_x2_setup_failure ( uint32_t assoc_id,
message.procedureCode = X2ap_ProcedureCode_id_x2Setup;
message.direction = X2AP_PDU_PR_unsuccessfulOutcome;
x2ap_eNB_set_cause (&x2_setup_failure_p->cause, cause_type, cause_value);
if (time_to_wait > -1) {
x2_setup_failure_p->presenceMask |= X2SETUPFAILURE_IES_TIMETOWAIT_PRESENT;
x2_setup_failure_p->timeToWait = time_to_wait;
}
if (x2ap_eNB_encode_pdu (&message, &buffer_p, &length) < 0) {
X2AP_ERROR ("Failed to encode x2 setup failure\n");
return -1;
}
MSC_LOG_TX_MESSAGE (MSC_X2AP_SRC_ENB,
MSC_X2AP_TARGET_ENB, NULL, 0,
"0 X2Setup/unsuccessfulOutcome assoc_id %u cause %u value %u",
}
MSC_LOG_TX_MESSAGE (MSC_X2AP_SRC_ENB,
MSC_X2AP_TARGET_ENB, NULL, 0,
"0 X2Setup/unsuccessfulOutcome assoc_id %u cause %u value %u",
assoc_id, cause_type, cause_value);
x2ap_eNB_itti_send_sctp_data_req (/* instance? */ 0, assoc_id, buffer_p, length, 0);
......@@ -277,22 +277,175 @@ int x2ap_eNB_set_cause (X2ap_Cause_t * cause_p,
case X2ap_Cause_PR_radioNetwork:
cause_p->choice.misc = cause_value;
break;
case X2ap_Cause_PR_transport:
cause_p->choice.transport = cause_value;
break;
case X2ap_Cause_PR_protocol:
cause_p->choice.protocol = cause_value;
break;
case X2ap_Cause_PR_misc:
cause_p->choice.misc = cause_value;
break;
default:
return -1;
}
return 0;
}
int x2ap_eNB_generate_x2_handover_request(x2ap_eNB_instance_t *instance_p,
x2ap_eNB_data_t *x2ap_enb_data_p,
int source_x2id)
{
/* TODO: set correct values in there */
x2ap_message message;
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_handoverPreparation;
message.criticality = X2ap_Criticality_reject;
message.msg.x2ap_HandoverRequest_IEs.old_eNB_UE_X2AP_ID = source_x2id;
message.msg.x2ap_HandoverRequest_IEs.cause.present = X2ap_Cause_PR_radioNetwork;
message.msg.x2ap_HandoverRequest_IEs.cause.choice.radioNetwork = X2ap_CauseRadioNetwork_handover_desirable_for_radio_reasons;
MCC_MNC_TO_PLMNID(123, 456, 3, &message.msg.x2ap_HandoverRequest_IEs.targetCell_ID.pLMN_Identity);
int eci1 = 79;
ECI_TO_BIT_STRING(eci1, &message.msg.x2ap_HandoverRequest_IEs.targetCell_ID.eUTRANcellIdentifier);
MCC_MNC_TO_PLMNID(456, 123, 3, &message.msg.x2ap_HandoverRequest_IEs.gummei_id.gU_Group_ID.pLMN_Identity);
MMEGID_TO_OCTET_STRING(26, &message.msg.x2ap_HandoverRequest_IEs.gummei_id.gU_Group_ID.mME_Group_ID);
MMEC_TO_OCTET_STRING(12, &message.msg.x2ap_HandoverRequest_IEs.gummei_id.mME_Code);
message.msg.x2ap_HandoverRequest_IEs.uE_ContextInformation.mME_UE_S1AP_ID = 12;
ENCRALG_TO_BIT_STRING(0,&message.msg.x2ap_HandoverRequest_IEs.uE_ContextInformation.uESecurityCapabilities.encryptionAlgorithms);
INTPROTALG_TO_BIT_STRING(0,&message.msg.x2ap_HandoverRequest_IEs.uE_ContextInformation.uESecurityCapabilities.integrityProtectionAlgorithms);
char KeNB_star[32] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 };
KENB_STAR_TO_BIT_STRING(KeNB_star,&message.msg.x2ap_HandoverRequest_IEs.uE_ContextInformation.aS_SecurityInformation.key_eNodeB_star);
message.msg.x2ap_HandoverRequest_IEs.uE_ContextInformation.aS_SecurityInformation.nextHopChainingCount = 1;
UEAGMAXBITRTD_TO_ASN_PRIMITIVES(3L,&message.msg.x2ap_HandoverRequest_IEs.uE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateDownlink);
UEAGMAXBITRTU_TO_ASN_PRIMITIVES(6L,&message.msg.x2ap_HandoverRequest_IEs.uE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateUplink);
X2ap_E_RABs_ToBeSetup_Item_t *e_RABs_ToBeSetup_Item1 = calloc(1, sizeof(X2ap_E_RABs_ToBeSetup_Item_t));
e_RABs_ToBeSetup_Item1->e_RAB_ID=10;
e_RABs_ToBeSetup_Item1->e_RAB_Level_QoS_Parameters.qCI=1;
e_RABs_ToBeSetup_Item1->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel = 1;
e_RABs_ToBeSetup_Item1->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionCapability = 0;
e_RABs_ToBeSetup_Item1->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionVulnerability = 0;
e_RABs_ToBeSetup_Item1->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.iE_Extensions = NULL;
TRLA_TO_BIT_STRING(1, &e_RABs_ToBeSetup_Item1->uL_GTPtunnelEndpoint.transportLayerAddress); // IPv4
GTP_TEID_TO_OCTET_STRING (12, &e_RABs_ToBeSetup_Item1->uL_GTPtunnelEndpoint.gTP_TEID);
X2ap_E_RABs_ToBeSetup_ListIEs_t *e_RABs_ToBeSetup_List1 = calloc(1, sizeof(X2ap_E_RABs_ToBeSetup_ListIEs_t));
ASN_SEQUENCE_ADD(e_RABs_ToBeSetup_List1, e_RABs_ToBeSetup_Item1);
x2ap_encode_x2ap_e_rabs_tobesetup_list(&message.msg.x2ap_HandoverRequest_IEs.uE_ContextInformation.e_RABs_ToBeSetup_List, e_RABs_ToBeSetup_List1);
#if 0
char RRC[81] = { 0x0a,0x10,0x00,0x00,0x03,0x41,0x60,0x08,0xcf,0x50,0x4a,0x0e,0x07,0x00,0x8c,0xf5,0x04,0xa0,0xe0,0x03,0xc0,0x51,0xc2,0x28,
0xb8,0x56,0xd1,0x80,0x4a,0x00,0x00,0x08,0x18,0x02,0x20,0x42,0x08,0x00,0x80,0x60,0x00,0x20,0x00,0x00,0x03,0x82,0xca,0x04,
0x06,0x14,0x08,0x0f,0x59,0x95,0x64,0x80,0x00,0x02,0x0a,0x5a,0x00,0x20,0x00,0x08,0x04,0x01,0x2f,0x39,0x57,0x96,0xde,0xc0,
0x00,0x88,0xea,0x46,0x7d,0x10,0x00,0x03,0x40 };
#endif
char RRC[] = {
0x0A,0x10,0x31,0xC5,0x20,0x00,0x05,0x00,0x10,0x40,0xC1,0xC9,0x85,0x8B,0xF8,0xDF,0xE2,0xFE,0x37,0xF8,0xBF,0x8D,0xFE,0x2F,0xE3,0x7F,0x8B,0xF8,0xDF,0xE2,0xFE,0x37,0xF7,0xF0,0xFF,0xE9,0x88,0x81,0x00,0x87,0x0C,0xA7,0x4A,0x92,0x20,0x20,0x58,0x00,0x00,0x00,0x00,0x00,0x15,0xD8,0x00,0x00,0x06,0x8B,0x02,0x00,0x02,0x90,0x21,0x59,0x70,0x00,0x00,0x72,0xA2,0x40,0x37,0xB0,0x11,0xFA,0x9C,0x0B,0x81,0x1F,0xA9,0xC0,0x83,0xEA,0x26,0xE0,0x25,0x75,0x38,0xA1,0xD8,0x84,0xF9,0x80,0x3E,0x55,0x8F,0xFD,0x15,0x35,0x86,0x1C,0x86,0xC8,0xA1,0x82,0x40,0xA1,0x35,0x00,0x00,0x00,0x24,0x10,0x92,0x80,0x02,0x00,0x00,0x10,0x2C,0x00,0x30,0x00,0x40,0xF6,0x07,0xCA,0xCB,0xB2,0x4C,0x00,0x6C,0x05,0x35,0x00,0x10,0x00,0x04,0x01,0x00,0xF7,0x52,0xAB,0xCA,0xF7,0x20,0x07,0x43,0x45,0xA0,0x1E,0xB8,0xE0,
};
OCTET_STRING_fromBuf(&message.msg.x2ap_HandoverRequest_IEs.uE_ContextInformation.rRC_Context, (char*) RRC, sizeof(RRC));
X2ap_LastVisitedCell_Item_t *lastVisitedCell_Item1 = calloc(1, sizeof(X2ap_LastVisitedCell_Item_t));
lastVisitedCell_Item1->present = X2ap_LastVisitedCell_Item_PR_e_UTRAN_Cell;
lastVisitedCell_Item1->choice.e_UTRAN_Cell.cellType.cell_Size=1;
lastVisitedCell_Item1->choice.e_UTRAN_Cell.time_UE_StayedInCell=2;
MCC_MNC_TO_PLMNID(987,765, 3, &lastVisitedCell_Item1->choice.e_UTRAN_Cell.global_Cell_ID.pLMN_Identity);
int eci2 = 55;
ECI_TO_BIT_STRING(eci2,&lastVisitedCell_Item1->choice.e_UTRAN_Cell.global_Cell_ID.eUTRANcellIdentifier);
ASN_SEQUENCE_ADD(&message.msg.x2ap_HandoverRequest_IEs.uE_HistoryInformation.list,lastVisitedCell_Item1);
if (x2ap_eNB_encode_pdu(&message, &buffer, &len) < 0) {
X2AP_ERROR("Failed to encode X2 setup request\n");
abort();
return -1;
}
/* TODO: use correct stream, 1 for the moment */
x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_enb_data_p->assoc_id, buffer, len, 1);
return ret;
}
int x2ap_eNB_generate_x2_handover_response(x2ap_eNB_instance_t *instance,
x2ap_eNB_data_t *x2ap_enb_data_p,
int source_x2id)
{
x2ap_message message;
uint8_t *buffer;
uint32_t len;
int ret = 0;
// Generating response
memset (&message, 0, sizeof (x2ap_message));
X2ap_E_RABs_Admitted_ListIEs_t *e_RABs_Admitted_List1;
X2ap_E_RABs_Admitted_Item_t *e_RABs_Admitted_Item1;
e_RABs_Admitted_Item1 = calloc(1, sizeof(X2ap_E_RABs_Admitted_Item_t));
e_RABs_Admitted_List1 = calloc(1, sizeof(X2ap_E_RABs_Admitted_ListIEs_t));
asn1_xer_print = 1;
asn_debug = 0;
X2ap_ProcedureCode_t procedure = X2ap_ProcedureCode_id_handoverPreparation;
X2ap_Criticality_t criticality = X2ap_Criticality_reject;
X2AP_PDU_PR present;
present = X2AP_PDU_PR_successfulOutcome;
message.procedureCode = procedure;
message.criticality= criticality;
message.direction = present;
//data is in file RRC_Context_acknowledge.txt
uint8_t RRC[63] = { 0x01,0xe9,0x00,0x90,0xa8,0x00,0x00,0x22,0x33,0xe9,0x42,0x80,0x02,0xf0,0x80,0x9e,0x20,0x23,0xc6,0x05,0x79,0x00,0xef,0x28,
0x21,0xe1,0x01,0x24,0x38,0x40,0x05,0x00,0x12,0x1c,0xa0,0x00,0x02,0x00,0x88,0x02,0x18,0x06,0x40,0x10,0xa0,0x2b,0x43,0x81,
0x1d,0xd9,0xc0,0x30,0x70,0x00,0xe0,0x21,0xc3,0x17,0x01,0x74,0x60,0x12,0x80 };
message.msg.x2ap_HandoverRequestAcknowledge_IEs.old_eNB_UE_X2AP_ID = source_x2id;
message.msg.x2ap_HandoverRequestAcknowledge_IEs.new_eNB_UE_X2AP_ID= 2001;
e_RABs_Admitted_Item1->e_RAB_ID=12;
e_RABs_Admitted_Item1->iE_Extensions = NULL;
ASN_SEQUENCE_ADD(e_RABs_Admitted_List1, e_RABs_Admitted_Item1);
memcpy(&message.msg.x2ap_HandoverRequestAcknowledge_IEs.e_RABs_Admitted_List, e_RABs_Admitted_List1, sizeof(X2ap_E_RABs_Admitted_ListIEs_t));
OCTET_STRING_fromBuf(&message.msg.x2ap_HandoverRequestAcknowledge_IEs.targeteNBtoSource_eNBTransparentContainer, (char*) RRC, sizeof(RRC));
if (x2ap_eNB_encode_pdu(&message, &buffer, &len) < 0) {
X2AP_ERROR("Failed to encode X2 handover response\n");
abort();
return -1;
}
//eNB_association->state = X2AP_ENB_STATE_READY;
/* TODO: use correct stream, 1 for the moment */
x2ap_eNB_itti_send_sctp_data_req(instance->instance, x2ap_enb_data_p->assoc_id, buffer, len, 1);
return ret;
}
......@@ -42,4 +42,13 @@ int x2ap_eNB_generate_x2_setup_failure ( uint32_t assoc_id,
X2ap_Cause_PR cause_type,
long cause_value,
long time_to_waitx);
int x2ap_eNB_generate_x2_handover_request(x2ap_eNB_instance_t *instance_p,
x2ap_eNB_data_t *x2ap_enb_data_p,
int source_x2id);
int x2ap_eNB_generate_x2_handover_response(x2ap_eNB_instance_t *instance_p,
x2ap_eNB_data_t *x2ap_enb_data_p,
int source_x2id);
#endif /* X2AP_ENB_GENERATE_MESSAGES_H_ */
......@@ -55,10 +55,18 @@
#include "conversions.h"
#include "msc.h"
static
static
int x2ap_eNB_handle_handover_preparation(uint32_t assoc_id,
uint32_t stream,
struct x2ap_message_s *message);
static
int x2ap_eNB_handle_handover_response(uint32_t assoc_id,
uint32_t stream,
struct x2ap_message_s *message);
static
int x2ap_eNB_handle_x2_setup_request (uint32_t assoc_id,
uint32_t stream,
struct x2ap_message_s *message);
uint32_t stream,
struct x2ap_message_s *message);
static
int x2ap_eNB_handle_x2_setup_response(uint32_t assoc_id,
uint32_t stream,
......@@ -70,23 +78,23 @@ int x2ap_eNB_handle_x2_setup_failure(uint32_t assoc_id,
static
int x2ap_eNB_handle_error_indication(uint32_t assoc_id,
uint32_t stream,
struct x2ap_message_s *message_p);
uint32_t stream,
struct x2ap_message_s *message_p);
int x2ap_eNB_handle_initial_context_request(uint32_t assoc_id,
uint32_t stream,
struct x2ap_message_s *message_p);
uint32_t stream,
struct x2ap_message_s *message_p);
static
int x2ap_eNB_handle_ue_context_release_command(uint32_t assoc_id,
uint32_t stream,
struct x2ap_message_s *message_p);
uint32_t stream,
struct x2ap_message_s *message_p);
/* Handlers matrix. Only eNB related procedure present here */
// x2ap_messages_callback[message.procedureCode][message.direction]
x2ap_message_decoded_callback x2ap_messages_callback[][3] = {
// { x2ap_eNB_handle_handover_preparation, 0, 0 }, /* HandoverPreparation */
{ 0, 0, 0 }, /* HandoverPreparation */
{ x2ap_eNB_handle_handover_preparation, x2ap_eNB_handle_handover_response, 0 }, /* HandoverPreparation */
{ 0, 0, 0 }, /* HandoverCancel */
{ 0, 0, 0 }, /* loadIndication */
{ x2ap_eNB_handle_error_indication, 0, 0 }, /* errorIndication */
......@@ -102,7 +110,7 @@ x2ap_message_decoded_callback x2ap_messages_callback[][3] = {
{ 0, 0, 0 }, /* rLFIndication */
{ 0, 0, 0 }, /* handoverReport */
{ 0, 0, 0 } /* cellActivation */
};
static const char *x2ap_direction2String[] = {
......@@ -133,7 +141,7 @@ int x2ap_eNB_handle_message(uint32_t assoc_id, int32_t stream,
assoc_id, message.procedureCode, message.direction);
return -1;
}
/* No handler present.
* This can mean not implemented or no procedure for eNB (wrong direction).
*/
......@@ -163,11 +171,11 @@ void x2ap_handle_x2_setup_message(x2ap_eNB_data_t *enb_desc_p, int sctp_shutdown
/* 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);
......@@ -175,15 +183,15 @@ void x2ap_handle_x2_setup_message(x2ap_eNB_data_t *enb_desc_p, int sctp_shutdown
}
} 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,
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;
......@@ -195,14 +203,172 @@ void x2ap_handle_x2_setup_message(x2ap_eNB_data_t *enb_desc_p, int sctp_shutdown
}
}
int
x2ap_eNB_handle_handover_preparation(uint32_t assoc_id,
uint32_t stream,
struct x2ap_message_s *message)
{
X2ap_HandoverRequest_IEs_t *x2HandoverRequest;
x2ap_eNB_data_t *x2ap_eNB_data;
uint32_t eNB_id = 0;
int ta_ret;
//uint16_t max_enb_connected;
MessageDef *m;
DevAssert (message != NULL);
x2HandoverRequest = &message->msg.x2ap_HandoverRequest_IEs;
if (stream == 0) {
X2AP_ERROR ("Received new x2 handover request on stream == 0\n");
/* TODO: send a x2 failure response */
return 0;
}
X2AP_DEBUG ("Received a new X2 handover request\n");
x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0);
DevAssert(x2ap_eNB_data != NULL);
m = itti_alloc_new_message(TASK_X2AP, X2AP_HANDOVER_REQ);
/* TODO: fill the message */
extern int x2id_to_source_rnti[1];
X2AP_HANDOVER_REQ(m).source_x2id = x2HandoverRequest->old_eNB_UE_X2AP_ID;
X2AP_HANDOVER_REQ(m).source_rnti = x2id_to_source_rnti[x2HandoverRequest->old_eNB_UE_X2AP_ID];
itti_send_msg_to_task(TASK_RRC_ENB, x2ap_eNB_data->x2ap_eNB_instance->instance, m);
return 0;
#if 0
if (x2SetupRequest->globalENB_ID.eNB_ID.present == X2ap_ENB_ID_PR_home_eNB_ID) {
// Home eNB ID = 28 bits
uint8_t *eNB_id_buf = x2SetupRequest->globalENB_ID.eNB_ID.choice.home_eNB_ID.buf;
if (x2SetupRequest->globalENB_ID.eNB_ID.choice.macro_eNB_ID.size != 28) {
//TODO: handle case were size != 28 -> notify ? reject ?
}
eNB_id = (eNB_id_buf[0] << 20) + (eNB_id_buf[1] << 12) + (eNB_id_buf[2] << 4) + ((eNB_id_buf[3] & 0xf0) >> 4);
X2AP_DEBUG ("Home eNB id: %07x\n", eNB_id);
} else {
// Macro eNB = 20 bits
uint8_t *eNB_id_buf = x2SetupRequest->globalENB_ID.eNB_ID.choice.macro_eNB_ID.buf;
if (x2SetupRequest->globalENB_ID.eNB_ID.choice.macro_eNB_ID.size != 20) {
//TODO: handle case were size != 20 -> notify ? reject ?
}
eNB_id = (eNB_id_buf[0] << 12) + (eNB_id_buf[1] << 4) + ((eNB_id_buf[2] & 0xf0) >> 4);
X2AP_DEBUG ("macro eNB id: %05x\n", eNB_id);
}
/*
* If none of the provided PLMNs/TAC match the one configured in MME,
* * * * the x2 setup should be rejected with a cause set to Unknown PLMN.
*/
// ta_ret = x2ap_eNB_compare_ta_lists (&x2SetupRequest_p->supportedTAs);
/*
* Source and Target eNBs have no common PLMN
*/
/*
if (ta_ret != TA_LIST_RET_OK) {
X2AP_ERROR ("No Common PLMN with the target eNB, generate_x2_setup_failure\n");
return x2ap_eNB_generate_x2_setup_failure (assoc_id,
X2ap_Cause_PR_misc,
X2ap_CauseMisc_unknown_PLMN,
X2ap_TimeToWait_v20s);
}
*/
X2AP_DEBUG ("Adding eNB to the list of associated eNBs\n");
if ((x2ap_eNB_data = x2ap_is_eNB_id_in_list (eNB_id)) == NULL) {
/*
* eNB has not been fount in list of associated eNB,
* * * * Add it to the tail of list and initialize data
*/
if ((x2ap_eNB_data = x2ap_is_eNB_assoc_id_in_list (assoc_id)) == NULL) {
/*
* ??
*/
return -1;
} else {
x2ap_eNB_data->state = X2AP_ENB_STATE_RESETTING;
x2ap_eNB_data->eNB_id = eNB_id;
}
} else {
x2ap_eNB_data->state = X2AP_ENB_STATE_RESETTING;
/*
* eNB has been fount in list, consider the x2 setup request as a reset connection,
* * * * reseting any previous UE state if sctp association is != than the previous one
*/
if (x2ap_eNB_data->assoc_id != assoc_id) {
X2SetupFailure_IEs_t x2SetupFailure;
memset (&x2SetupFailure, 0, sizeof (x2SetupFailure));
/*
* Send an overload cause...
*/
X2AP_ERROR ("Rejeting x2 setup request as eNB id %d is already associated to an active sctp association" "Previous known: %d, new one: %d\n", eNB_id, x2ap_eNB_data->assoc_id, assoc_id);
x2ap_eNB_generate_x2_setup_failure (assoc_id,
X2ap_Cause_PR_protocol,
X2ap_CauseProtocol_unspecified,
-1);
return -1;
}
/*
* TODO: call the reset procedure
*/
}
return x2ap_generate_x2_setup_response (x2ap_eNB_data);
#endif
}
int
x2ap_eNB_handle_handover_response(uint32_t assoc_id,
uint32_t stream,
struct x2ap_message_s *message)
{
X2ap_HandoverRequestAcknowledge_IEs_t *x2HandoverRequestAck;
x2ap_eNB_data_t *x2ap_eNB_data;
uint32_t eNB_id = 0;
int ta_ret;
//uint16_t max_enb_connected;
MessageDef *m;
DevAssert (message != NULL);
x2HandoverRequestAck = &message->msg.x2ap_HandoverRequestAcknowledge_IEs;
if (stream == 0) {
X2AP_ERROR ("Received new x2 handover response on stream == 0\n");
/* TODO: what to do? */
return 0;
}
X2AP_DEBUG ("Received a new X2 handover response\n");
x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0);
DevAssert(x2ap_eNB_data != NULL);
m = itti_alloc_new_message(TASK_X2AP, X2AP_HANDOVER_RESP);
/* TODO: fill the message */
extern int x2id_to_source_rnti[1];
X2AP_HANDOVER_RESP(m).source_x2id = x2HandoverRequestAck->old_eNB_UE_X2AP_ID;
X2AP_HANDOVER_RESP(m).source_rnti = x2id_to_source_rnti[x2HandoverRequestAck->old_eNB_UE_X2AP_ID];
itti_send_msg_to_task(TASK_RRC_ENB, x2ap_eNB_data->x2ap_eNB_instance->instance, m);
return 0;
}
int
x2ap_eNB_handle_x2_setup_request (uint32_t assoc_id,
uint32_t stream,
struct x2ap_message_s *message)
uint32_t stream,
struct x2ap_message_s *message)
{
X2SetupRequest_IEs_t *x2SetupRequest;
x2ap_eNB_data_t *x2ap_eNB_data;
uint32_t eNB_id = 0;
......@@ -211,12 +377,12 @@ x2ap_eNB_handle_x2_setup_request (uint32_t assoc_id,
DevAssert (message != NULL);
x2SetupRequest = &message->msg.x2SetupRequest_IEs;
MSC_LOG_RX_MESSAGE (MSC_X2AP_TARGET_ENB,
MSC_X2AP_SRC_ENB, NULL, 0,
"0 X2Setup/%s assoc_id %u stream %u",
x2ap_direction2String[message->direction],
assoc_id, stream);
MSC_LOG_RX_MESSAGE (MSC_X2AP_TARGET_ENB,
MSC_X2AP_SRC_ENB, NULL, 0,
"0 X2Setup/%s assoc_id %u stream %u",
x2ap_direction2String[message->direction],
assoc_id, stream);
/*
* We received a new valid X2 Setup Request on a stream != 0.
* * * * This should not happen -> reject eNB x2 setup request.
......@@ -227,52 +393,52 @@ x2ap_eNB_handle_x2_setup_request (uint32_t assoc_id,
/*
* Send a x2 setup failure with protocol cause unspecified
*/
return x2ap_eNB_generate_x2_setup_failure (assoc_id,
X2ap_Cause_PR_protocol,
X2ap_CauseProtocol_unspecified,
-1);
return x2ap_eNB_generate_x2_setup_failure (assoc_id,
X2ap_Cause_PR_protocol,
X2ap_CauseProtocol_unspecified,
-1);
}
X2AP_DEBUG ("Received a new X2 setup request\n");
if (x2SetupRequest->globalENB_ID.eNB_ID.present == X2ap_ENB_ID_PR_home_eNB_ID) {
// Home eNB ID = 28 bits
uint8_t *eNB_id_buf = x2SetupRequest->globalENB_ID.eNB_ID.choice.home_eNB_ID.buf;
if (x2SetupRequest->globalENB_ID.eNB_ID.choice.macro_eNB_ID.size != 28) {
//TODO: handle case were size != 28 -> notify ? reject ?
}
eNB_id = (eNB_id_buf[0] << 20) + (eNB_id_buf[1] << 12) + (eNB_id_buf[2] << 4) + ((eNB_id_buf[3] & 0xf0) >> 4);
X2AP_DEBUG ("Home eNB id: %07x\n", eNB_id);
} else {
// Macro eNB = 20 bits
uint8_t *eNB_id_buf = x2SetupRequest->globalENB_ID.eNB_ID.choice.macro_eNB_ID.buf;
if (x2SetupRequest->globalENB_ID.eNB_ID.choice.macro_eNB_ID.size != 20) {
//TODO: handle case were size != 20 -> notify ? reject ?
}
eNB_id = (eNB_id_buf[0] << 12) + (eNB_id_buf[1] << 4) + ((eNB_id_buf[2] & 0xf0) >> 4);
X2AP_DEBUG ("macro eNB id: %05x\n", eNB_id);
}
/*
* If none of the provided PLMNs/TAC match the one configured in MME,
* * * * the x2 setup should be rejected with a cause set to Unknown PLMN.
*/
// ta_ret = x2ap_eNB_compare_ta_lists (&x2SetupRequest_p->supportedTAs);
/*
* Source and Target eNBs have no common PLMN
*/
/*
if (ta_ret != TA_LIST_RET_OK) {
X2AP_ERROR ("No Common PLMN with the target eNB, generate_x2_setup_failure\n");
return x2ap_eNB_generate_x2_setup_failure (assoc_id,
X2ap_Cause_PR_misc,
X2ap_CauseMisc_unknown_PLMN,
X2ap_TimeToWait_v20s);
return x2ap_eNB_generate_x2_setup_failure (assoc_id,
X2ap_Cause_PR_misc,
X2ap_CauseMisc_unknown_PLMN,
X2ap_TimeToWait_v20s);
}
*/
X2AP_DEBUG ("Adding eNB to the list of associated eNBs\n");
......@@ -290,38 +456,38 @@ x2ap_eNB_handle_x2_setup_request (uint32_t assoc_id,
} else {
x2ap_eNB_data->state = X2AP_ENB_STATE_RESETTING;
x2ap_eNB_data->eNB_id = eNB_id;
}
}
} else {
x2ap_eNB_data->state = X2AP_ENB_STATE_RESETTING;
/*
* eNB has been fount in list, consider the x2 setup request as a reset connection,
* * * * reseting any previous UE state if sctp association is != than the previous one
*/
if (x2ap_eNB_data->assoc_id != assoc_id) {
X2SetupFailure_IEs_t x2SetupFailure;
memset (&x2SetupFailure, 0, sizeof (x2SetupFailure));
/*
* Send an overload cause...
*/
X2AP_ERROR ("Rejeting x2 setup request as eNB id %d is already associated to an active sctp association" "Previous known: %d, new one: %d\n", eNB_id, x2ap_eNB_data->assoc_id, assoc_id);
x2ap_eNB_generate_x2_setup_failure (assoc_id,
X2ap_Cause_PR_protocol,
X2ap_CauseProtocol_unspecified,
-1);
x2ap_eNB_generate_x2_setup_failure (assoc_id,
X2ap_Cause_PR_protocol,
X2ap_CauseProtocol_unspecified,
-1);
return -1;
}
/*
* TODO: call the reset procedure
*/
}
}
return x2ap_generate_x2_setup_response (x2ap_eNB_data);
}
static
......@@ -348,8 +514,8 @@ int x2ap_eNB_handle_x2_setup_failure(uint32_t assoc_id,
"eNB context\n", assoc_id);
return -1;
}
// need a FSM to handle all cases
// need a FSM to handle all cases
if ((x2_setup_failure->cause.present == X2ap_Cause_PR_misc) &&
(x2_setup_failure->cause.choice.misc == X2ap_CauseMisc_unspecified)) {
X2AP_WARN("Received X2 setup failure for eNB ... eNB is not ready\n");
......@@ -359,7 +525,7 @@ int x2ap_eNB_handle_x2_setup_failure(uint32_t assoc_id,
x2ap_eNB_data->state = X2AP_ENB_STATE_WAITING;
x2ap_handle_x2_setup_message(x2ap_eNB_data, 0);
return 0;
}
......@@ -372,15 +538,15 @@ int x2ap_eNB_handle_x2_setup_response(uint32_t assoc_id,
X2SetupResponse_IEs_t *x2SetupResponse;
x2ap_eNB_data_t *x2ap_eNB_data;
uint32_t eNB_id = 0;
DevAssert(message != NULL);
x2SetupResponse = &message->msg.x2SetupResponse_IEs;
MSC_LOG_RX_MESSAGE (MSC_X2AP_TARGET_ENB,
MSC_X2AP_SRC_ENB, NULL, 0,
"0 X2Setup/%s assoc_id %u stream %u",
x2ap_direction2String[message->direction],
assoc_id, stream);
MSC_LOG_RX_MESSAGE (MSC_X2AP_TARGET_ENB,
MSC_X2AP_SRC_ENB, NULL, 0,
"0 X2Setup/%s assoc_id %u stream %u",
x2ap_direction2String[message->direction],
assoc_id, stream);
/* X2 Setup Response == Non UE-related procedure -> stream 0 */
if (stream != 0) {
......@@ -394,30 +560,30 @@ int x2ap_eNB_handle_x2_setup_response(uint32_t assoc_id,
"MME context\n", assoc_id);
return -1;
}
/* check and store eNB info here*/
/* check and store eNB info here*/
if (x2SetupResponse->globalENB_ID.eNB_ID.present == X2ap_ENB_ID_PR_home_eNB_ID) {
// Home eNB ID = 28 bits
uint8_t *eNB_id_buf = x2SetupResponse->globalENB_ID.eNB_ID.choice.home_eNB_ID.buf;
if (x2SetupResponse->globalENB_ID.eNB_ID.choice.macro_eNB_ID.size != 28) {
//TODO: handle case were size != 28 -> notify ? reject ?
}
eNB_id = (eNB_id_buf[0] << 20) + (eNB_id_buf[1] << 12) + (eNB_id_buf[2] << 4) + ((eNB_id_buf[3] & 0xf0) >> 4);
X2AP_DEBUG ("Home eNB id: %07x\n", eNB_id);
} else {
// Macro eNB = 20 bits
uint8_t *eNB_id_buf = x2SetupResponse->globalENB_ID.eNB_ID.choice.macro_eNB_ID.buf;
if (x2SetupResponse->globalENB_ID.eNB_ID.choice.macro_eNB_ID.size != 20) {
//TODO: handle case were size != 20 -> notify ? reject ?
}
eNB_id = (eNB_id_buf[0] << 12) + (eNB_id_buf[1] << 4) + ((eNB_id_buf[2] & 0xf0) >> 4);
X2AP_DEBUG ("macro eNB id: %05x\n", eNB_id);
}
if ((x2ap_eNB_data = x2ap_is_eNB_id_in_list (eNB_id)) == NULL) {
/*
* eNB has not been fount in list of associated eNB,
......@@ -431,26 +597,26 @@ int x2ap_eNB_handle_x2_setup_response(uint32_t assoc_id,
} else {
x2ap_eNB_data->state = X2AP_ENB_STATE_RESETTING;
x2ap_eNB_data->eNB_id = eNB_id;
}
}
} else {
x2ap_eNB_data->state = X2AP_ENB_STATE_RESETTING;
/*
/*
if (x2ap_eNB_data->assoc_id != assoc_id) {
X2SetupFailure_IEs_t x2SetupFailure;
memset (&x2SetupFailure, 0, sizeof (x2SetupFailure));
// Send an overload cause
X2AP_ERROR ("Rejeting x2 setup response as eNB id %d is already associated to an active sctp association" "Previous known: %d, new one: %d\n", eNB_id, x2ap_eNB_data->assoc_id, assoc_id);
x2ap_eNB_generate_x2_setup_failure (assoc_id,
X2ap_Cause_PR_protocol,
X2ap_CauseProtocol_unspecified,
-1);
x2ap_eNB_generate_x2_setup_failure (assoc_id,
X2ap_Cause_PR_protocol,
X2ap_CauseProtocol_unspecified,
-1);
return -1;
}
*/
*/
/*
* TODO: call the reset procedure
*/
......@@ -459,7 +625,7 @@ int x2ap_eNB_handle_x2_setup_response(uint32_t assoc_id,
/* Optionaly set the target eNB name */
/* The association is now ready as source and target eNBs know parameters of each other.
* Mark the association as connected.
......@@ -494,9 +660,9 @@ int x2ap_eNB_handle_error_indication(uint32_t assoc_id,
}
x2ap_xer_print_x2ap_errorindication_(x2ap_xer__print2sp,
message_string,
message_p);
message_string,
message_p);
if ( x2_error_indication->presenceMask & X2AP_ERRORINDICATION_IES_OLD_ENB_UE_X2AP_ID_PRESENT ) {
X2AP_WARN("Received X2 Error indication OLD ENB UE X2AP ID 0x%x\n", x2_error_indication->old_eNB_UE_X2AP_ID);
}
......@@ -508,141 +674,141 @@ int x2ap_eNB_handle_error_indication(uint32_t assoc_id,
if ( x2_error_indication->presenceMask & X2AP_ERRORINDICATION_IES_CAUSE_PRESENT) {
switch(x2_error_indication->cause.present) {
case X2ap_Cause_PR_NOTHING:
X2AP_WARN("Received X2 Error indication cause NOTHING\n");
X2AP_WARN("Received X2 Error indication cause NOTHING\n");
break;
case X2ap_Cause_PR_radioNetwork:
switch (x2_error_indication->cause.choice.radioNetwork) {
case X2ap_CauseRadioNetwork_handover_desirable_for_radio_reasons:
switch (x2_error_indication->cause.choice.radioNetwork) {
case X2ap_CauseRadioNetwork_handover_desirable_for_radio_reasons:
X2AP_WARN("Received X2 Error indication X2ap_CauseRadioNetwork_handover_desirable_for_radio_reasons\n");
break;
case X2ap_CauseRadioNetwork_time_critical_handover:
case X2ap_CauseRadioNetwork_time_critical_handover:
X2AP_WARN("Received X2 Error indication X2ap_CauseRadioNetwork_time_critical_handover\n");
break;
case X2ap_CauseRadioNetwork_resource_optimisation_handover:
case X2ap_CauseRadioNetwork_resource_optimisation_handover:
X2AP_WARN("Received X2 Error indication X2ap_CauseRadioNetwork_resource_optimisation_handover\n");
break;
case X2ap_CauseRadioNetwork_reduce_load_in_serving_cell:
case X2ap_CauseRadioNetwork_reduce_load_in_serving_cell:
X2AP_WARN("Received X2 Error indication X2ap_CauseRadioNetwork_reduce_load_in_serving_cell\n");
break;
case X2ap_CauseRadioNetwork_partial_handover:
case X2ap_CauseRadioNetwork_partial_handover:
X2AP_WARN("Received X2 Error indication X2ap_CauseRadioNetwork_partial_handover\n");
break;
case X2ap_CauseRadioNetwork_unknown_new_eNB_UE_X2AP_ID:
case X2ap_CauseRadioNetwork_unknown_new_eNB_UE_X2AP_ID:
X2AP_WARN("Received X2 Error indication X2ap_CauseRadioNetwork_unknown_new_eNB_UE_X2AP_ID\n");
break;
case X2ap_CauseRadioNetwork_unknown_old_eNB_UE_X2AP_ID:
case X2ap_CauseRadioNetwork_unknown_old_eNB_UE_X2AP_ID:
X2AP_WARN("Received X2 Error indication X2ap_CauseRadioNetwork_unknown_old_eNB_UE_X2AP_ID\n");
break;
case X2ap_CauseRadioNetwork_unknown_pair_of_UE_X2AP_ID:
case X2ap_CauseRadioNetwork_unknown_pair_of_UE_X2AP_ID:
X2AP_WARN("Received X2 Error indication X2ap_CauseRadioNetwork_unknown_pair_of_UE_X2AP_ID\n");
break;
case X2ap_CauseRadioNetwork_ho_target_not_allowed:
case X2ap_CauseRadioNetwork_ho_target_not_allowed:
X2AP_WARN("Received X2 Error indication X2ap_CauseRadioNetwork_ho_target_not_allowed\n");
break;
case X2ap_CauseRadioNetwork_tx2relocoverall_expiry:
case X2ap_CauseRadioNetwork_tx2relocoverall_expiry:
X2AP_WARN("Received X2 Error indication X2ap_CauseRadioNetwork_tx2relocoverall_expiry\n");
break;
case X2ap_CauseRadioNetwork_trelocprep_expiry:
case X2ap_CauseRadioNetwork_trelocprep_expiry:
X2AP_WARN("Received X2 Error indication X2ap_CauseRadioNetwork_trelocprep_expiry\n");
break;
case X2ap_CauseRadioNetwork_cell_not_available:
case X2ap_CauseRadioNetwork_cell_not_available:
X2AP_WARN("Received X2 Error indication X2ap_CauseRadioNetwork_cell_not_available\n");
break;
case X2ap_CauseRadioNetwork_no_radio_resources_available_in_target_cell:
case X2ap_CauseRadioNetwork_no_radio_resources_available_in_target_cell:
X2AP_WARN("Received X2 Error indication X2ap_CauseRadioNetwork_no_radio_resources_available_in_target_cell\n");
break;
case X2ap_CauseRadioNetwork_invalid_MME_GroupID:
case X2ap_CauseRadioNetwork_invalid_MME_GroupID:
X2AP_WARN("Received X2 Error indication X2ap_CauseRadioNetwork_invalid_MME_GroupID\n");
break;
case X2ap_CauseRadioNetwork_unknown_MME_Code:
case X2ap_CauseRadioNetwork_unknown_MME_Code:
X2AP_WARN("Received X2 Error indication X2ap_CauseRadioNetwork_unknown_MME_Code\n");
break;
case X2ap_CauseRadioNetwork_encryption_and_or_integrity_protection_algorithms_not_supported:
case X2ap_CauseRadioNetwork_encryption_and_or_integrity_protection_algorithms_not_supported:
X2AP_WARN("Received X2 Error indication X2ap_CauseRadioNetwork_encryption_and_or_integrity_protection_algorithms_not_supported\n");
break;
case X2ap_CauseRadioNetwork_reportCharacteristicsEmpty:
case X2ap_CauseRadioNetwork_reportCharacteristicsEmpty:
X2AP_WARN("Received X2 Error indication X2ap_CauseRadioNetwork_reportCharacteristicsEmpty\n");
break;
case X2ap_CauseRadioNetwork_noReportPeriodicity:
case X2ap_CauseRadioNetwork_noReportPeriodicity:
X2AP_WARN("Received X2 Error indication X2ap_CauseRadioNetwork_noReportPeriodicity\n");
break;
case X2ap_CauseRadioNetwork_existingMeasurementID:
case X2ap_CauseRadioNetwork_existingMeasurementID:
X2AP_WARN("Received X2 Error indication X2ap_CauseRadioNetwork_existingMeasurementID\n");
break;
case X2ap_CauseRadioNetwork_unknown_eNB_Measurement_ID:
case X2ap_CauseRadioNetwork_unknown_eNB_Measurement_ID:
X2AP_WARN("Received X2 Error indication X2ap_CauseRadioNetwork_unknown_eNB_Measurement_ID\n");
break;
case X2ap_CauseRadioNetwork_measurement_temporarily_not_available:
case X2ap_CauseRadioNetwork_measurement_temporarily_not_available:
X2AP_WARN("Received X2 Error indication X2ap_CauseRadioNetwork_measurement_temporarily_not_available\n");
break;
case X2ap_CauseRadioNetwork_unspecified:
case X2ap_CauseRadioNetwork_unspecified:
X2AP_WARN("Received X2 Error indication X2ap_CauseRadioNetwork_unspecified\n");
break;
case X2ap_CauseRadioNetwork_load_balancing:
case X2ap_CauseRadioNetwork_load_balancing:
X2AP_WARN("Received X2 Error indication X2ap_CauseRadioNetwork_load_balancing\n");
break;
case X2ap_CauseRadioNetwork_handover_optimisation:
case X2ap_CauseRadioNetwork_handover_optimisation:
X2AP_WARN("Received X2 Error indication X2ap_CauseRadioNetwork_handover_optimisation\n");
break;
case X2ap_CauseRadioNetwork_value_out_of_allowed_range:
case X2ap_CauseRadioNetwork_value_out_of_allowed_range:
X2AP_WARN("Received X2 Error indication X2ap_CauseRadioNetwork_value_out_of_allowed_range\n");
break;
case X2ap_CauseRadioNetwork_multiple_E_RAB_ID_instances:
case X2ap_CauseRadioNetwork_multiple_E_RAB_ID_instances:
X2AP_WARN("Received X2 Error indication X2ap_CauseRadioNetwork_multiple_E_RAB_ID_instances\n");
break;
case X2ap_CauseRadioNetwork_switch_off_ongoing:
case X2ap_CauseRadioNetwork_switch_off_ongoing:
X2AP_WARN("Received X2 Error indication X2ap_CauseRadioNetwork_switch_off_ongoing\n");
break;
case X2ap_CauseRadioNetwork_not_supported_QCI_value:
case X2ap_CauseRadioNetwork_not_supported_QCI_value:
X2AP_WARN("Received X2 Error indication X2ap_CauseRadioNetwork_not_supported_QCI_value\n");
break;
case X2ap_CauseRadioNetwork_measurement_not_supported_for_the_object:
case X2ap_CauseRadioNetwork_measurement_not_supported_for_the_object:
X2AP_WARN("Received X2 Error indication X2ap_CauseRadioNetwork_measurement_not_supported_for_the_object\n");
default:
default:
X2AP_WARN("Received X2 Error indication cause radio network case not handled\n");
}
}
break;
case X2ap_Cause_PR_transport:
switch (x2_error_indication->cause.choice.transport) {
case X2ap_CauseTransport_transport_resource_unavailable:
switch (x2_error_indication->cause.choice.transport) {
case X2ap_CauseTransport_transport_resource_unavailable:
X2AP_WARN("Received X2 Error indication X2ap_CauseTransport_transport_resource_unavailable\n");
break;
case X2ap_CauseTransport_unspecified:
case X2ap_CauseTransport_unspecified:
X2AP_WARN("Received X2 Error indication SX2ap_CauseTransport_unspecified\n");
break;
default:
default:
X2AP_WARN("Received X2 Error indication cause transport case not handled\n");
}
}
break;
case X2ap_Cause_PR_protocol:
switch (x2_error_indication->cause.choice.protocol) {
case X2ap_CauseProtocol_transfer_syntax_error:
switch (x2_error_indication->cause.choice.protocol) {
case X2ap_CauseProtocol_transfer_syntax_error:
X2AP_WARN("Received X2 Error indication X2ap_CauseProtocol_transfer_syntax_error\n");
break;
case X2ap_CauseProtocol_abstract_syntax_error_reject:
case X2ap_CauseProtocol_abstract_syntax_error_reject:
X2AP_WARN("Received X2 Error indication X2ap_CauseProtocol_abstract_syntax_error_reject\n");
break;
case X2ap_CauseProtocol_abstract_syntax_error_ignore_and_notify:
case X2ap_CauseProtocol_abstract_syntax_error_ignore_and_notify:
X2AP_WARN("Received X2 Error indication X2ap_CauseProtocol_abstract_syntax_error_ignore_and_notify\n");
break;
case X2ap_CauseProtocol_message_not_compatible_with_receiver_state:
case X2ap_CauseProtocol_message_not_compatible_with_receiver_state:
X2AP_WARN("Received X2 Error indication X2ap_CauseProtocol_message_not_compatible_with_receiver_state\n");
break;
case X2ap_CauseProtocol_semantic_error:
case X2ap_CauseProtocol_semantic_error:
X2AP_WARN("Received X2 Error indication X2ap_CauseProtocol_semantic_error\n");
break;
case X2ap_CauseProtocol_unspecified:
case X2ap_CauseProtocol_unspecified:
X2AP_WARN("Received X2 Error indication X2ap_CauseProtocol_unspecified\n");
break;
case X2ap_CauseProtocol_abstract_syntax_error_falsely_constructed_message:
case X2ap_CauseProtocol_abstract_syntax_error_falsely_constructed_message:
X2AP_WARN("Received X2 Error indication X2ap_CauseProtocol_abstract_syntax_error_falsely_constructed_message\n");
break;
default:
default:
X2AP_WARN("Received X2 Error indication cause protocol case not handled\n");
}
}
break;
case X2ap_Cause_PR_misc:
......@@ -651,18 +817,18 @@ int x2ap_eNB_handle_error_indication(uint32_t assoc_id,
X2AP_WARN("Received X2 Error indication X2ap_CauseMisc_control_processing_overload\n");
break;
case X2ap_CauseMisc_hardware_failure:
X2AP_WARN("Received X2 Error indication X2ap_CauseMisc_hardware_failure\n");
break;
X2AP_WARN("Received X2 Error indication X2ap_CauseMisc_hardware_failure\n");
break;
case X2ap_CauseMisc_om_intervention:
X2AP_WARN("Received X2 Error indication X2ap_CauseMisc_om_intervention\n");
break;
X2AP_WARN("Received X2 Error indication X2ap_CauseMisc_om_intervention\n");
break;
case X2ap_CauseMisc_not_enough_user_plane_processing_resources:
X2AP_WARN("Received X2 Error indication X2ap_CauseMisc_not_enough_user_plane_processing_resources\n");
break;
X2AP_WARN("Received X2 Error indication X2ap_CauseMisc_not_enough_user_plane_processing_resources\n");
break;
case X2ap_CauseMisc_unspecified:
X2AP_WARN("Received X2 Error indication X2ap_CauseMisc_unspecified\n");
break;
default:
X2AP_WARN("Received X2 Error indication X2ap_CauseMisc_unspecified\n");
break;
default:
X2AP_WARN("Received X2 Error indication cause misc case not handled\n");
}
break;
......@@ -674,6 +840,3 @@ int x2ap_eNB_handle_error_indication(uint32_t assoc_id,
// TODO continue
return 0;
}
......@@ -206,8 +206,91 @@ do { \
(bitstring)->buf[1] = (eci) >> 12; \
(bitstring)->buf[2] = (eci) >> 4; \
(bitstring)->buf[3] = (eci) << 4; \
}while(0)
}while(0)
#define MMEGID_TO_OCTET_STRING(mmegid,octetstring) \
do { \
(octetstring)->size=2; \
(octetstring)->buf=calloc (2, sizeof (uint8_t)); \
(octetstring)->buf[0] = (mmegid) >> 8; \
(octetstring)->buf[1] = (mmegid); \
}while(0)
#define MMEC_TO_OCTET_STRING(mmec, octetstring) \
do { \
(octetstring)->size=1; \
(octetstring)->buf=calloc (1, sizeof (uint8_t));\
(octetstring)->buf[0] = (mmec); \
}while(0)
#define ENCRALG_TO_BIT_STRING(encralg, bitstring) \
do { \
(bitstring)->size=2; \
(bitstring)->bits_unused=0; \
(bitstring)->buf=calloc (1, sizeof (uint8_t)); \
(bitstring)->buf[0] = (encralg) >> 8; \
(bitstring)->buf[1] = (encralg); \
}while(0)
#define INTPROTALG_TO_BIT_STRING(intprotalg, bitstring) \
do { \
(bitstring)->size=2; \
(bitstring)->bits_unused=0; \
(bitstring)->buf=calloc (2, sizeof (uint8_t)); \
(bitstring)->buf[0] = (intprotalg) >> 8; \
(bitstring)->buf[1] = (intprotalg); \
}while(0)
#define KENB_STAR_TO_BIT_STRING(kenbstar, bitstring) \
do { \
(bitstring)->size=32; \
(bitstring)->bits_unused=0; \
(bitstring)->buf= calloc (32, sizeof (uint8_t));\
memcpy((bitstring)->buf, kenbstar, 32*sizeof(uint8_t)); \
}while(0)
#define UEAGMAXBITRTD_TO_ASN_PRIMITIVES(uegmaxbitrtd, asnprimitives) \
do { \
(asnprimitives)->size=5; \
(asnprimitives)->buf=calloc (5, sizeof (uint8_t)); \
(asnprimitives)->buf[0] = (uegmaxbitrtd) >> 32; \
(asnprimitives)->buf[1] = (uegmaxbitrtd) >> 24; \
(asnprimitives)->buf[2] = (uegmaxbitrtd) >> 16; \
(asnprimitives)->buf[3] = (uegmaxbitrtd) >> 8; \
(asnprimitives)->buf[4] = (uegmaxbitrtd); \
}while(0)
#define UEAGMAXBITRTU_TO_ASN_PRIMITIVES(uegmaxbitrtu, asnprimitives) \
do { \
(asnprimitives)->size=5; \
(asnprimitives)->buf=calloc (5, sizeof (uint8_t)); \
(asnprimitives)->buf[0] = (uegmaxbitrtu) >> 32; \
(asnprimitives)->buf[1] = (uegmaxbitrtu) >> 24; \
(asnprimitives)->buf[2] = (uegmaxbitrtu) >> 16; \
(asnprimitives)->buf[3] = (uegmaxbitrtu) >> 8; \
(asnprimitives)->buf[4] = (uegmaxbitrtu); \
}while(0)
#define TRLA_TO_BIT_STRING(trla, bitstring) \
do { \
(bitstring)->size=4; \
(bitstring)->bits_unused=0; \
(bitstring)->buf=calloc (4, sizeof (uint8_t)); \
(bitstring)->buf[0] = (trla)>>24; \
(bitstring)->buf[1] = (trla)>>16; \
(bitstring)->buf[2] = (trla)>>8; \
(bitstring)->buf[3] = (trla); \
}while(0)
#define GTP_TEID_TO_OCTET_STRING(gtpteid, octetstring) \
do { \
(octetstring)->size=4; \
(octetstring)->buf=calloc (4, sizeof (uint8_t));\
(octetstring)->buf[0] = (gtpteid)>>24; \
(octetstring)->buf[1] = (gtpteid)>>16; \
(octetstring)->buf[2] = (gtpteid)>>8; \
(octetstring)->buf[3] = (gtpteid); \
}while(0)
#define TAC_TO_OCTET_STRING(tac, octetstring)\
do { \
......
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