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 ...@@ -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_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) 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 @@ ...@@ -30,10 +30,14 @@
#ifndef X2AP_MESSAGES_TYPES_H_ #ifndef X2AP_MESSAGES_TYPES_H_
#define X2AP_MESSAGES_TYPES_H_ #define X2AP_MESSAGES_TYPES_H_
#include "PhysCellId.h"
//-------------------------------------------------------------------------------------------// //-------------------------------------------------------------------------------------------//
// Defines to access message fields. // Defines to access message fields.
#define X2AP_REGISTER_ENB_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_register_enb_req #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_REGISTER_ENB_CNF(mSGpTR) (mSGpTR)->ittiMsg.x2ap_register_enb_cnf
#define X2AP_DEREGISTERED_ENB_IND(mSGpTR) (mSGpTR)->ittiMsg.x2ap_deregistered_enb_ind #define X2AP_DEREGISTERED_ENB_IND(mSGpTR) (mSGpTR)->ittiMsg.x2ap_deregistered_enb_ind
...@@ -105,4 +109,22 @@ typedef struct x2ap_deregistered_enb_ind_s { ...@@ -105,4 +109,22 @@ typedef struct x2ap_deregistered_enb_ind_s {
uint8_t nb_x2; uint8_t nb_x2;
} x2ap_deregistered_enb_ind_t; } 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_ */ #endif /* X2AP_MESSAGES_TYPES_H_ */
...@@ -165,7 +165,7 @@ int xer_sprint (char *string, size_t string_size, asn_TYPE_descriptor_t *td, voi ...@@ -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; er.encoded = string_buffer.string_size;
} else { } else {
if (er.encoded > string_buffer.string_size) { 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; er.encoded = string_buffer.string_size;
} }
} }
......
...@@ -166,7 +166,11 @@ typedef enum HO_STATE_e { ...@@ -166,7 +166,11 @@ typedef enum HO_STATE_e {
HO_MEASURMENT, HO_MEASURMENT,
HO_PREPARE, HO_PREPARE,
HO_CMD, // initiated by the src eNB 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; } HO_STATE_t;
//#define NUMBER_OF_UE_MAX MAX_MOBILES_PER_RG //#define NUMBER_OF_UE_MAX MAX_MOBILES_PER_RG
...@@ -235,8 +239,8 @@ typedef struct e_rab_param_s { ...@@ -235,8 +239,8 @@ typedef struct e_rab_param_s {
/* Intermediate structure for Handover management. Associated per-UE in eNB_RRC_INST */ /* Intermediate structure for Handover management. Associated per-UE in eNB_RRC_INST */
typedef struct HANDOVER_INFO_s { typedef struct HANDOVER_INFO_s {
uint8_t ho_prepare; int ho_prepare, ho_complete;
uint8_t ho_complete; HO_STATE_t state; //current state of handover
uint8_t modid_s; //module_idP of serving cell uint8_t modid_s; //module_idP of serving cell
uint8_t modid_t; //module_idP of target cell uint8_t modid_t; //module_idP of target cell
uint16_t ueid_s; //UE index in serving cell uint16_t ueid_s; //UE index in serving cell
...@@ -245,6 +249,8 @@ typedef struct HANDOVER_INFO_s { ...@@ -245,6 +249,8 @@ typedef struct HANDOVER_INFO_s {
AS_Context_t as_context; /* They are mandatory for HO */ AS_Context_t as_context; /* They are mandatory for HO */
uint8_t buf[RRC_BUF_SIZE]; /* ASN.1 encoded handoverCommandMessage */ uint8_t buf[RRC_BUF_SIZE]; /* ASN.1 encoded handoverCommandMessage */
int size; /* size of above message in bytes */ int size; /* size of above message in bytes */
/* TODO: to remove or not? */
int source_x2id;
} HANDOVER_INFO; } HANDOVER_INFO;
#define RRC_HEADER_SIZE_MAX 64 #define RRC_HEADER_SIZE_MAX 64
......
This diff is collapsed.
...@@ -69,6 +69,14 @@ static ...@@ -69,6 +69,14 @@ 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); x2ap_register_enb_req_t *x2ap_register_eNB);
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 static
void x2ap_eNB_register_eNB(x2ap_eNB_instance_t *instance_p, void x2ap_eNB_register_eNB(x2ap_eNB_instance_t *instance_p,
net_ip_address_t *target_eNB_ip_addr, net_ip_address_t *target_eNB_ip_addr,
...@@ -378,6 +386,64 @@ void x2ap_eNB_handle_register_eNB(instance_t instance, ...@@ -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) void *x2ap_task(void *arg)
{ {
...@@ -403,6 +469,16 @@ void *x2ap_task(void *arg) ...@@ -403,6 +469,16 @@ void *x2ap_task(void *arg)
&X2AP_REGISTER_ENB_REQ(received_msg)); &X2AP_REGISTER_ENB_REQ(received_msg));
break; break;
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: case SCTP_NEW_ASSOCIATION_RESP:
x2ap_eNB_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg), x2ap_eNB_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&received_msg->ittiMsg.sctp_new_association_resp); &received_msg->ittiMsg.sctp_new_association_resp);
......
...@@ -49,8 +49,8 @@ ...@@ -49,8 +49,8 @@
int x2ap_eNB_generate_x2_setup_request(x2ap_eNB_instance_t *instance_p, int x2ap_eNB_generate_x2_setup_request(x2ap_eNB_instance_t *instance_p,
x2ap_eNB_data_t *x2ap_enb_data_p){ x2ap_eNB_data_t *x2ap_enb_data_p)
{
x2ap_message message; x2ap_message message;
X2SetupRequest_IEs_t *x2SetupRequest; X2SetupRequest_IEs_t *x2SetupRequest;
...@@ -296,3 +296,156 @@ int x2ap_eNB_set_cause (X2ap_Cause_t * cause_p, ...@@ -296,3 +296,156 @@ int x2ap_eNB_set_cause (X2ap_Cause_t * cause_p,
return 0; 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, ...@@ -42,4 +42,13 @@ int x2ap_eNB_generate_x2_setup_failure ( uint32_t assoc_id,
X2ap_Cause_PR cause_type, X2ap_Cause_PR cause_type,
long cause_value, long cause_value,
long time_to_waitx); 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_ */ #endif /* X2AP_ENB_GENERATE_MESSAGES_H_ */
...@@ -55,6 +55,14 @@ ...@@ -55,6 +55,14 @@
#include "conversions.h" #include "conversions.h"
#include "msc.h" #include "msc.h"
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 static
int x2ap_eNB_handle_x2_setup_request (uint32_t assoc_id, int x2ap_eNB_handle_x2_setup_request (uint32_t assoc_id,
uint32_t stream, uint32_t stream,
...@@ -86,7 +94,7 @@ int x2ap_eNB_handle_ue_context_release_command(uint32_t assoc_id, ...@@ -86,7 +94,7 @@ int x2ap_eNB_handle_ue_context_release_command(uint32_t assoc_id,
// x2ap_messages_callback[message.procedureCode][message.direction] // x2ap_messages_callback[message.procedureCode][message.direction]
x2ap_message_decoded_callback x2ap_messages_callback[][3] = { x2ap_message_decoded_callback x2ap_messages_callback[][3] = {
// { x2ap_eNB_handle_handover_preparation, 0, 0 }, /* HandoverPreparation */ // { 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 }, /* HandoverCancel */
{ 0, 0, 0 }, /* loadIndication */ { 0, 0, 0 }, /* loadIndication */
{ x2ap_eNB_handle_error_indication, 0, 0 }, /* errorIndication */ { x2ap_eNB_handle_error_indication, 0, 0 }, /* errorIndication */
...@@ -195,6 +203,164 @@ void x2ap_handle_x2_setup_message(x2ap_eNB_data_t *enb_desc_p, int sctp_shutdown ...@@ -195,6 +203,164 @@ 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 int
x2ap_eNB_handle_x2_setup_request (uint32_t assoc_id, x2ap_eNB_handle_x2_setup_request (uint32_t assoc_id,
...@@ -674,6 +840,3 @@ int x2ap_eNB_handle_error_indication(uint32_t assoc_id, ...@@ -674,6 +840,3 @@ int x2ap_eNB_handle_error_indication(uint32_t assoc_id,
// TODO continue // TODO continue
return 0; return 0;
} }
...@@ -208,6 +208,89 @@ do { \ ...@@ -208,6 +208,89 @@ do { \
(bitstring)->buf[3] = (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)\ #define TAC_TO_OCTET_STRING(tac, octetstring)\
do { \ 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