Commit 9b127482 authored by Raphael Defosseux's avatar Raphael Defosseux
Browse files

Merge remote-tracking branch 'origin/x2' into develop_integration_2019_w10

parents ea0e313f 5bf595a0
......@@ -469,6 +469,7 @@ add_library(X2AP_ENB
${X2AP_DIR}/x2ap_eNB_itti_messaging.c
${X2AP_DIR}/x2ap_eNB_management_procedures.c
${X2AP_DIR}/x2ap_eNB_generate_messages.c
${X2AP_DIR}/x2ap_ids.c
)
add_dependencies(X2AP_ENB rrc_flag x2_flag)
......
......@@ -72,3 +72,6 @@ MESSAGE_DEF(NAS_CONN_ESTABLI_CNF, MESSAGE_PRIORITY_MED, NasConnEstab
MESSAGE_DEF(NAS_CONN_RELEASE_IND, MESSAGE_PRIORITY_MED, NasConnReleaseInd, nas_conn_release_ind)
MESSAGE_DEF(NAS_UPLINK_DATA_CNF, MESSAGE_PRIORITY_MED, NasUlDataCnf, nas_ul_data_cnf)
MESSAGE_DEF(NAS_DOWNLINK_DATA_IND, MESSAGE_PRIORITY_MED, NasDlDataInd, nas_dl_data_ind)
// eNB: realtime -> RRC messages
MESSAGE_DEF(RRC_SUBFRAME_PROCESS, MESSAGE_PRIORITY_MED, RrcSubframeProcess, rrc_subframe_process)
......@@ -81,6 +81,8 @@
#define NAS_UPLINK_DATA_CNF(mSGpTR) (mSGpTR)->ittiMsg.nas_ul_data_cnf
#define NAS_DOWNLINK_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.nas_dl_data_ind
#define RRC_SUBFRAME_PROCESS(mSGpTR) (mSGpTR)->ittiMsg.rrc_subframe_process
//-------------------------------------------------------------------------------------------//
typedef struct RrcStateInd_s {
Rrc_State_t state;
......@@ -399,4 +401,10 @@ typedef nas_release_ind_t NasConnReleaseInd;
typedef ul_info_transfer_cnf_t NasUlDataCnf;
typedef dl_info_transfer_ind_t NasDlDataInd;
// eNB: realtime -> RRC messages
typedef struct rrc_subframe_process_s {
protocol_ctxt_t ctxt;
int CC_id;
} RrcSubframeProcess;
#endif /* RRC_MESSAGES_TYPES_H_ */
......@@ -40,3 +40,6 @@ MESSAGE_DEF(X2AP_DEREGISTERED_ENB_IND , MESSAGE_PRIORITY_MED, x2ap_der
/* handover messages X2AP <-> RRC */
MESSAGE_DEF(X2AP_HANDOVER_REQ , MESSAGE_PRIORITY_MED, x2ap_handover_req_t , x2ap_handover_req)
MESSAGE_DEF(X2AP_HANDOVER_REQ_ACK , MESSAGE_PRIORITY_MED, x2ap_handover_req_ack_t , x2ap_handover_req_ack)
/* handover messages X2AP <-> S1AP */
MESSAGE_DEF(X2AP_UE_CONTEXT_RELEASE , MESSAGE_PRIORITY_MED, x2ap_ue_context_release_t , x2ap_ue_context_release)
......@@ -33,11 +33,21 @@
#define X2AP_HANDOVER_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_req_ack
#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_UE_CONTEXT_RELEASE(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ue_context_release
#define X2AP_MAX_NB_ENB_IP_ADDRESS 2
// eNB application layer -> X2AP messages
/* X2AP UE CONTEXT RELEASE */
typedef struct x2ap_ue_context_release_s {
/* used for X2AP->RRC in source and RRC->X2AP in target */
int rnti;
int source_assoc_id;
} x2ap_ue_context_release_t;
typedef struct x2ap_register_enb_req_s {
/* Unique eNB_id to identify the eNB within EPC.
* For macro eNB ids this field should be 20 bits long.
......@@ -128,12 +138,12 @@ typedef struct x2ap_lastvisitedcell_info_s {
uint64_t time_UE_StayedInCell;
}x2ap_lastvisitedcell_info_t;
//used for src
typedef struct x2ap_handover_req_s {
int source_rnti; /* TODO: to be fixed/remove */
int source_x2id; /* TODO: to be fixed/remove */
/* used for RRC->X2AP in source eNB */
int rnti;
int old_eNB_ue_x2ap_id;
/* used for X2AP->RRC in target eNB */
int x2_id;
LTE_PhysCellId_t target_physCellId;
......@@ -167,15 +177,17 @@ typedef struct x2ap_handover_req_s {
uint8_t rrc_buffer[1024 /* arbitrary, big enough */];
int rrc_buffer_size;
/* TODO: this parameter has to be removed */
int target_mod_id;
int target_assoc_id;
} x2ap_handover_req_t;
typedef struct x2ap_handover_req_ack_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;
/* used for RRC->X2AP in target and X2AP->RRC in source */
int rnti;
/* used for RRC->X2AP in target */
int x2_id_target;
int source_assoc_id;
uint8_t nb_e_rabs_tobesetup;
......
......@@ -1923,162 +1923,164 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) {
if (ENBParamList.numelt > 0) {
for (k = 0; k < ENBParamList.numelt; k++) {
if (ENBParamList.paramarray[k][ENB_ENB_ID_IDX].uptr == NULL) {
// Calculate a default eNB ID
if (ENBParamList.paramarray[k][ENB_ENB_ID_IDX].uptr == NULL) {
// Calculate a default eNB ID
if (EPC_MODE_ENABLED) {
uint32_t hash;
hash = s1ap_generate_eNB_id ();
enb_id = k + (hash & 0xFFFF8);
uint32_t hash;
hash = s1ap_generate_eNB_id ();
enb_id = k + (hash & 0xFFFF8);
} else {
enb_id = k;
enb_id = k;
}
} else {
enb_id = *(ENBParamList.paramarray[k][ENB_ENB_ID_IDX].uptr);
}
// search if in active list
for (j = 0; j < ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt; j++) {
if (strcmp(ENBSParams[ENB_ACTIVE_ENBS_IDX].strlistptr[j], *(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr)) == 0) {
paramdef_t PLMNParams[] = PLMNPARAMS_DESC;
paramlist_def_t PLMNParamList = {ENB_CONFIG_STRING_PLMN_LIST, NULL, 0};
/* map parameter checking array instances to parameter definition array instances */
checkedparam_t config_check_PLMNParams [] = PLMNPARAMS_CHECK;
for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I)
PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]);
paramdef_t X2Params[] = X2PARAMS_DESC;
paramlist_def_t X2ParamList = {ENB_CONFIG_STRING_TARGET_ENB_X2_IP_ADDRESS,NULL,0};
paramdef_t SCTPParams[] = SCTPPARAMS_DESC;
paramdef_t NETParams[] = NETPARAMS_DESC;
/* TODO: fix the size - if set lower we have a crash (MAX_OPTNAME_SIZE was 64 when this code was written) */
/* this is most probably a problem with the config module */
char aprefix[MAX_OPTNAME_SIZE*80 + 8];
sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k);
/* Some default/random parameters */
X2AP_REGISTER_ENB_REQ (msg_p).eNB_id = enb_id;
if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_MACRO_ENB") == 0) {
X2AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_MACRO_ENB;
} else if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_HOME_ENB") == 0) {
X2AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_HOME_ENB;
} else {
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for cell_type choice: CELL_MACRO_ENB or CELL_HOME_ENB !\n",
RC.config_file_name, i, *(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr));
}
X2AP_REGISTER_ENB_REQ (msg_p).eNB_name = strdup(*(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr));
X2AP_REGISTER_ENB_REQ (msg_p).tac = *ENBParamList.paramarray[k][ENB_TRACKING_AREA_CODE_IDX].uptr;
config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams)/sizeof(paramdef_t), aprefix);
if (PLMNParamList.numelt < 1 || PLMNParamList.numelt > 6)
AssertFatal(0, "The number of PLMN IDs must be in [1,6], but is %d\n",
PLMNParamList.numelt);
if (PLMNParamList.numelt > 1)
LOG_W(X2AP, "X2AP currently handles only one PLMN, ignoring the others!\n");
X2AP_REGISTER_ENB_REQ (msg_p).mcc = *PLMNParamList.paramarray[0][ENB_MOBILE_COUNTRY_CODE_IDX].uptr;
X2AP_REGISTER_ENB_REQ (msg_p).mnc = *PLMNParamList.paramarray[0][ENB_MOBILE_NETWORK_CODE_IDX].uptr;
X2AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length = *PLMNParamList.paramarray[0][ENB_MNC_DIGIT_LENGTH].u8ptr;
AssertFatal(X2AP_REGISTER_ENB_REQ(msg_p).mnc_digit_length == 3
|| X2AP_REGISTER_ENB_REQ(msg_p).mnc < 100,
"MNC %d cannot be encoded in two digits as requested (change mnc_digit_length to 3)\n",
X2AP_REGISTER_ENB_REQ(msg_p).mnc);
/* CC params */
config_getlist(&CCsParamList, NULL, 0, aprefix);
X2AP_REGISTER_ENB_REQ (msg_p).num_cc = CCsParamList.numelt;
if (CCsParamList.numelt > 0) {
//char ccspath[MAX_OPTNAME_SIZE*2 + 16];
for (J = 0; J < CCsParamList.numelt ; J++) {
sprintf(aprefix, "%s.[%i].%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, k, ENB_CONFIG_STRING_COMPONENT_CARRIERS, J);
config_get(CCsParams, sizeof(CCsParams)/sizeof(paramdef_t), aprefix);
X2AP_REGISTER_ENB_REQ (msg_p).eutra_band[J] = ccparams_lte.eutra_band;
X2AP_REGISTER_ENB_REQ (msg_p).downlink_frequency[J] = (uint32_t) ccparams_lte.downlink_frequency;
X2AP_REGISTER_ENB_REQ (msg_p).uplink_frequency_offset[J] = (unsigned int) ccparams_lte.uplink_frequency_offset;
X2AP_REGISTER_ENB_REQ (msg_p).Nid_cell[J]= ccparams_lte.Nid_cell;
if (ccparams_lte.Nid_cell>503) {
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for Nid_cell choice: 0...503 !\n",
RC.config_file_name, k, ccparams_lte.Nid_cell);
}
X2AP_REGISTER_ENB_REQ (msg_p).N_RB_DL[J]= ccparams_lte.N_RB_DL;
if ((ccparams_lte.N_RB_DL!=6) && (ccparams_lte.N_RB_DL!=15) && (ccparams_lte.N_RB_DL!=25) && (ccparams_lte.N_RB_DL!=50) && (ccparams_lte.N_RB_DL!=75) && (ccparams_lte.N_RB_DL!=100)) {
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for N_RB_DL choice: 6,15,25,50,75,100 !\n",
RC.config_file_name, k, ccparams_lte.N_RB_DL);
}
if (strcmp(ccparams_lte.frame_type, "FDD") == 0) {
X2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = FDD;
} else if (strcmp(ccparams_lte.frame_type, "TDD") == 0) {
X2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = TDD;
} else {
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for frame_type choice: FDD or TDD !\n",
RC.config_file_name, k, ccparams_lte.frame_type);
}
X2AP_REGISTER_ENB_REQ (msg_p).fdd_earfcn_DL[J] = to_earfcn_DL(ccparams_lte.eutra_band, ccparams_lte.downlink_frequency, ccparams_lte.N_RB_DL);
X2AP_REGISTER_ENB_REQ (msg_p).fdd_earfcn_UL[J] = to_earfcn_UL(ccparams_lte.eutra_band, ccparams_lte.downlink_frequency + ccparams_lte.uplink_frequency_offset, ccparams_lte.N_RB_DL);
}
}
sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k);
config_getlist( &X2ParamList,X2Params,sizeof(X2Params)/sizeof(paramdef_t),aprefix);
AssertFatal(X2ParamList.numelt <= X2AP_MAX_NB_ENB_IP_ADDRESS,
"value of X2ParamList.numelt %d must be lower than X2AP_MAX_NB_ENB_IP_ADDRESS %d value: reconsider to increase X2AP_MAX_NB_ENB_IP_ADDRESS\n",
X2ParamList.numelt,X2AP_MAX_NB_ENB_IP_ADDRESS);
X2AP_REGISTER_ENB_REQ (msg_p).nb_x2 = 0;
for (l = 0; l < X2ParamList.numelt; l++) {
X2AP_REGISTER_ENB_REQ (msg_p).nb_x2 += 1;
strcpy(X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4_address,*(X2ParamList.paramarray[l][ENB_X2_IPV4_ADDRESS_IDX].strptr));
strcpy(X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6_address,*(X2ParamList.paramarray[l][ENB_X2_IPV6_ADDRESS_IDX].strptr));
if (strcmp(*(X2ParamList.paramarray[l][ENB_X2_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv4") == 0) {
X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4 = 1;
} else if (strcmp(*(X2ParamList.paramarray[l][ENB_X2_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv6") == 0) {
X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6 = 1;
} else if (strcmp(*(X2ParamList.paramarray[l][ENB_X2_IP_ADDRESS_PREFERENCE_IDX].strptr), "no") == 0) {
X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4 = 1;
X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6 = 1;
}
}
// SCTP SETTING
X2AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = SCTP_OUT_STREAMS;
X2AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = SCTP_IN_STREAMS;
} else {
enb_id = *(ENBParamList.paramarray[k][ENB_ENB_ID_IDX].uptr);
}
// search if in active list
for (j = 0; j < ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt; j++) {
if (strcmp(ENBSParams[ENB_ACTIVE_ENBS_IDX].strlistptr[j], *(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr)) == 0) {
paramdef_t PLMNParams[] = PLMNPARAMS_DESC;
paramlist_def_t PLMNParamList = {ENB_CONFIG_STRING_PLMN_LIST, NULL, 0};
/* map parameter checking array instances to parameter definition array instances */
checkedparam_t config_check_PLMNParams [] = PLMNPARAMS_CHECK;
for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I)
PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]);
paramdef_t X2Params[] = X2PARAMS_DESC;
paramlist_def_t X2ParamList = {ENB_CONFIG_STRING_TARGET_ENB_X2_IP_ADDRESS,NULL,0};
paramdef_t SCTPParams[] = SCTPPARAMS_DESC;
paramdef_t NETParams[] = NETPARAMS_DESC;
/* TODO: fix the size - if set lower we have a crash (MAX_OPTNAME_SIZE was 64 when this code was written) */
/* this is most probably a problem with the config module */
char aprefix[MAX_OPTNAME_SIZE*80 + 8];
sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k);
/* Some default/random parameters */
X2AP_REGISTER_ENB_REQ (msg_p).eNB_id = enb_id;
if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_MACRO_ENB") == 0) {
X2AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_MACRO_ENB;
} else if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_HOME_ENB") == 0) {
X2AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_HOME_ENB;
} else {
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for cell_type choice: CELL_MACRO_ENB or CELL_HOME_ENB !\n",
RC.config_file_name, i, *(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr));
}
X2AP_REGISTER_ENB_REQ (msg_p).eNB_name = strdup(*(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr));
X2AP_REGISTER_ENB_REQ (msg_p).tac = *ENBParamList.paramarray[k][ENB_TRACKING_AREA_CODE_IDX].uptr;
config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams)/sizeof(paramdef_t), aprefix);
if (PLMNParamList.numelt < 1 || PLMNParamList.numelt > 6)
AssertFatal(0, "The number of PLMN IDs must be in [1,6], but is %d\n",
PLMNParamList.numelt);
if (PLMNParamList.numelt > 1)
LOG_W(X2AP, "X2AP currently handles only one PLMN, ignoring the others!\n");
X2AP_REGISTER_ENB_REQ (msg_p).mcc = *PLMNParamList.paramarray[0][ENB_MOBILE_COUNTRY_CODE_IDX].uptr;
X2AP_REGISTER_ENB_REQ (msg_p).mnc = *PLMNParamList.paramarray[0][ENB_MOBILE_NETWORK_CODE_IDX].uptr;
X2AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length = *PLMNParamList.paramarray[0][ENB_MNC_DIGIT_LENGTH].u8ptr;
AssertFatal(X2AP_REGISTER_ENB_REQ(msg_p).mnc_digit_length == 3
|| X2AP_REGISTER_ENB_REQ(msg_p).mnc < 100,
"MNC %d cannot be encoded in two digits as requested (change mnc_digit_length to 3)\n",
X2AP_REGISTER_ENB_REQ(msg_p).mnc);
/* CC params */
config_getlist(&CCsParamList, NULL, 0, aprefix);
X2AP_REGISTER_ENB_REQ (msg_p).num_cc = CCsParamList.numelt;
if (CCsParamList.numelt > 0) {
//char ccspath[MAX_OPTNAME_SIZE*2 + 16];
for (J = 0; J < CCsParamList.numelt ; J++) {
sprintf(aprefix, "%s.[%i].%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, k, ENB_CONFIG_STRING_COMPONENT_CARRIERS, J);
config_get(CCsParams, sizeof(CCsParams)/sizeof(paramdef_t), aprefix);
X2AP_REGISTER_ENB_REQ (msg_p).eutra_band[J] = ccparams_lte.eutra_band;
X2AP_REGISTER_ENB_REQ (msg_p).downlink_frequency[J] = (uint32_t) ccparams_lte.downlink_frequency;
X2AP_REGISTER_ENB_REQ (msg_p).uplink_frequency_offset[J] = (unsigned int) ccparams_lte.uplink_frequency_offset;
X2AP_REGISTER_ENB_REQ (msg_p).Nid_cell[J]= ccparams_lte.Nid_cell;
if (ccparams_lte.Nid_cell>503) {
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for Nid_cell choice: 0...503 !\n",
RC.config_file_name, k, ccparams_lte.Nid_cell);
}
X2AP_REGISTER_ENB_REQ (msg_p).N_RB_DL[J]= ccparams_lte.N_RB_DL;
if ((ccparams_lte.N_RB_DL!=6) && (ccparams_lte.N_RB_DL!=15) && (ccparams_lte.N_RB_DL!=25) && (ccparams_lte.N_RB_DL!=50) && (ccparams_lte.N_RB_DL!=75) && (ccparams_lte.N_RB_DL!=100)) {
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for N_RB_DL choice: 6,15,25,50,75,100 !\n",
RC.config_file_name, k, ccparams_lte.N_RB_DL);
}
if (strcmp(ccparams_lte.frame_type, "FDD") == 0) {
X2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = FDD;
} else if (strcmp(ccparams_lte.frame_type, "TDD") == 0) {
X2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = TDD;
} else {
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for frame_type choice: FDD or TDD !\n",
RC.config_file_name, k, ccparams_lte.frame_type);
}
X2AP_REGISTER_ENB_REQ (msg_p).fdd_earfcn_DL[J] = to_earfcn_DL(ccparams_lte.eutra_band, ccparams_lte.downlink_frequency, ccparams_lte.N_RB_DL);
X2AP_REGISTER_ENB_REQ (msg_p).fdd_earfcn_UL[J] = to_earfcn_UL(ccparams_lte.eutra_band, ccparams_lte.downlink_frequency + ccparams_lte.uplink_frequency_offset, ccparams_lte.N_RB_DL);
}
}
sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k);
config_getlist( &X2ParamList,X2Params,sizeof(X2Params)/sizeof(paramdef_t),aprefix);
AssertFatal(X2ParamList.numelt <= X2AP_MAX_NB_ENB_IP_ADDRESS,
"value of X2ParamList.numelt %d must be lower than X2AP_MAX_NB_ENB_IP_ADDRESS %d value: reconsider to increase X2AP_MAX_NB_ENB_IP_ADDRESS\n",
X2ParamList.numelt,X2AP_MAX_NB_ENB_IP_ADDRESS);
X2AP_REGISTER_ENB_REQ (msg_p).nb_x2 = 0;
for (l = 0; l < X2ParamList.numelt; l++) {
X2AP_REGISTER_ENB_REQ (msg_p).nb_x2 += 1;
strcpy(X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4_address,*(X2ParamList.paramarray[l][ENB_X2_IPV4_ADDRESS_IDX].strptr));
strcpy(X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6_address,*(X2ParamList.paramarray[l][ENB_X2_IPV6_ADDRESS_IDX].strptr));
if (strcmp(*(X2ParamList.paramarray[l][ENB_X2_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv4") == 0) {
X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4 = 1;
X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6 = 0;
} else if (strcmp(*(X2ParamList.paramarray[l][ENB_X2_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv6") == 0) {
X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4 = 0;
X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6 = 1;
} else if (strcmp(*(X2ParamList.paramarray[l][ENB_X2_IP_ADDRESS_PREFERENCE_IDX].strptr), "no") == 0) {
X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4 = 1;
X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6 = 1;
}
}
// SCTP SETTING
X2AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = SCTP_OUT_STREAMS;
X2AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = SCTP_IN_STREAMS;
if (EPC_MODE_ENABLED) {
sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_SCTP_CONFIG);
config_get( SCTPParams,sizeof(SCTPParams)/sizeof(paramdef_t),aprefix);
X2AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[ENB_SCTP_INSTREAMS_IDX].uptr);
X2AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = (uint16_t)*(SCTPParams[ENB_SCTP_OUTSTREAMS_IDX].uptr);
}
sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG);
// NETWORK_INTERFACES
config_get( NETParams,sizeof(NETParams)/sizeof(paramdef_t),aprefix);
X2AP_REGISTER_ENB_REQ (msg_p).enb_port_for_X2C = (uint32_t)*(NETParams[ENB_PORT_FOR_X2C_IDX].uptr);
if ((NETParams[ENB_IPV4_ADDR_FOR_X2C_IDX].strptr == NULL) || (X2AP_REGISTER_ENB_REQ (msg_p).enb_port_for_X2C == 0)) {
LOG_E(RRC,"Add eNB IPv4 address and/or port for X2C in the CONF file!\n");
exit(1);
sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_SCTP_CONFIG);
config_get( SCTPParams,sizeof(SCTPParams)/sizeof(paramdef_t),aprefix);
X2AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[ENB_SCTP_INSTREAMS_IDX].uptr);
X2AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = (uint16_t)*(SCTPParams[ENB_SCTP_OUTSTREAMS_IDX].uptr);
}
cidr = *(NETParams[ENB_IPV4_ADDR_FOR_X2C_IDX].strptr);
address = strtok(cidr, "/");
X2AP_REGISTER_ENB_REQ (msg_p).enb_x2_ip_address.ipv6 = 0;
X2AP_REGISTER_ENB_REQ (msg_p).enb_x2_ip_address.ipv4 = 1;
strcpy(X2AP_REGISTER_ENB_REQ (msg_p).enb_x2_ip_address.ipv4_address, address);
}
}
sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG);
// NETWORK_INTERFACES
config_get( NETParams,sizeof(NETParams)/sizeof(paramdef_t),aprefix);
X2AP_REGISTER_ENB_REQ (msg_p).enb_port_for_X2C = (uint32_t)*(NETParams[ENB_PORT_FOR_X2C_IDX].uptr);
if ((NETParams[ENB_IPV4_ADDR_FOR_X2C_IDX].strptr == NULL) || (X2AP_REGISTER_ENB_REQ (msg_p).enb_port_for_X2C == 0)) {
LOG_E(RRC,"Add eNB IPv4 address and/or port for X2C in the CONF file!\n");
exit(1);
}
cidr = *(NETParams[ENB_IPV4_ADDR_FOR_X2C_IDX].strptr);
address = strtok(cidr, "/");
X2AP_REGISTER_ENB_REQ (msg_p).enb_x2_ip_address.ipv6 = 0;
X2AP_REGISTER_ENB_REQ (msg_p).enb_x2_ip_address.ipv4 = 1;
strcpy(X2AP_REGISTER_ENB_REQ (msg_p).enb_x2_ip_address.ipv4_address, address);
}
}
}
}
}
......
......@@ -883,7 +883,7 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP,
rntiP, -1
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
,
-1
0
#endif
)) == -1)
{
......
......@@ -343,7 +343,8 @@ typedef enum HO_STATE_e {
HO_COMPLETE, // initiated by the target eNB
HO_REQUEST,
HO_ACK,
HO_CONFIGURED
HO_CONFIGURED,
HO_RELEASE
} HO_STATE_t;
typedef enum SL_TRIGGER_e {
......@@ -450,12 +451,14 @@ typedef struct HANDOVER_INFO_s {
HO_STATE_t state; //current state of handover
uint32_t modid_s; //module_idP of serving cell
uint32_t modid_t; //module_idP of target cell
int assoc_id;
uint8_t ueid_s; //UE index in serving cell
uint8_t ueid_t; //UE index in target cell
LTE_AS_Config_t as_config; /* these two parameters are taken from 36.331 section 10.2.2: HandoverPreparationInformation-r8-IEs */
LTE_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 */
int x2_id; /* X2AP UE ID in the target eNB */
} HANDOVER_INFO;
#define RRC_HEADER_SIZE_MAX 64
......
This diff is collapsed.
......@@ -426,7 +426,7 @@ static e_LTE_SecurityAlgorithmConfig__integrityProtAlgorithm rrc_eNB_select_inte
*\param security_capabilities The security capabilities received from S1AP.
*\return TRUE if at least one algorithm has been changed else FALSE.
*/
static int
int
rrc_eNB_process_security(
const protocol_ctxt_t *const ctxt_pP,
rrc_eNB_ue_context_t *const ue_context_pP,
......@@ -477,7 +477,7 @@ rrc_eNB_process_security(
*\param security_key_pP The security key received from S1AP.
*/
//------------------------------------------------------------------------------
static void process_eNB_security_key (
void process_eNB_security_key (
const protocol_ctxt_t *const ctxt_pP,
rrc_eNB_ue_context_t *const ue_context_pP,
uint8_t *security_key_pP
......@@ -1958,7 +1958,7 @@ int rrc_eNB_send_PATH_SWITCH_REQ(const protocol_ctxt_t *const ctxt_pP,
S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].eNB_addr = create_tunnel_resp.enb_addr;
LOG_I (RRC,"enb_gtp_addr (msg index %d, e_rab index %d, status %d): nb_of_e_rabs %d, e_rab_id %d, teid: %u, addr: %d.%d.%d.%d \n ",
e_rabs_done, e_rab, ue_context_pP->ue_context.e_rab[inde_list[e_rab]].status,
ue_context_pP->ue_context.nb_of_e_rabs,
S1AP_PATH_SWITCH_REQ (msg_p).nb_of_e_rabs,
S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].e_rab_id,
S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].gtp_teid,
S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].eNB_addr.buffer[0],
......@@ -1970,7 +1970,7 @@ int rrc_eNB_send_PATH_SWITCH_REQ(const protocol_ctxt_t *const ctxt_pP,
// NN: add conditions for e_rabs_failed
if (e_rabs_done > 0) {
LOG_I(RRC,"S1AP_PATH_SWITCH_REQ: sending the message: nb_of_erabstobeswitched %d, total e_rabs %d, index %d\n",
ue_context_pP->ue_context.nb_of_e_rabs, ue_context_pP->ue_context.setup_e_rabs, e_rab);
S1AP_PATH_SWITCH_REQ (msg_p).nb_of_e_rabs, ue_context_pP->ue_context.setup_e_rabs, e_rab);
MSC_LOG_TX_MESSAGE(
MSC_RRC_ENB,
MSC_S1AP_ENB,
......@@ -2017,46 +2017,64 @@ int rrc_eNB_process_S1AP_PATH_SWITCH_REQ_ACK (MessageDef *msg_p, const char *msg
ue_context_p->ue_context.mme_ue_s1ap_id = S1AP_PATH_SWITCH_REQ_ACK (msg_p).mme_ue_s1ap_id;
/* Save e RAB information for later */
{
ue_context_p->ue_context.nb_release_of_e_rabs = S1AP_PATH_SWITCH_REQ_ACK (msg_p).nb_e_rabs_tobereleased;
for (i = 0;
i < ue_context_p->ue_context.setup_e_rabs; // go over total number of e_rabs received through x2_ho_req msg
i++) {
// assume that we are releasing all the DRBs
ue_context_p->ue_context.e_rab[i].status = E_RAB_STATUS_TORELEASE;
i < ue_context_p->ue_context.setup_e_rabs; // go over total number of e_rabs received through x2_ho_req msg
i++) {
// assume that we are releasing all the DRBs
ue_context_p->ue_context.e_rab[i].status = E_RAB_STATUS_REESTABLISHED;
if (ue_context_p->ue_context.nb_release_of_e_rabs==0) {
LOG_I(RRC,"Bearer re-established with ID: %d\n", ue_context_p->ue_context.e_rab[i].param.e_rab_id);
}
}
//memset(&create_tunnel_req, 0 , sizeof(create_tunnel_req));
//uint8_t nb_e_rabs_tobeswitched = S1AP_PATH_SWITCH_REQ_ACK (msg_p).nb_e_rabs_tobeswitched;
uint8_t nb_e_rabs_tobeswitched = S1AP_PATH_SWITCH_REQ_ACK (msg_p).nb_e_rabs_tobeswitched;
// keep the previous bearer
// the index for the rec
for (i = 0;
i < 1;//nb_e_rabs_tobeswitched; // go over total number of e_rabs received through x2_ho_req msg
i++) {
LOG_I(RRC,"Bearer re-established with ID: %d\n", ue_context_p->ue_context.e_rab[i].param.e_rab_id);
/* Harmonize with enb_gtp_teid, enb_gtp_addrs, and enb_gtp_rbi vars in the top level structure */
ue_context_p->ue_context.e_rab[i].status = E_RAB_STATUS_REESTABLISHED;
//ue_context_p->ue_context.e_rab[i].param.e_rab_id = S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobeswitched[i].e_rab_id;
//ue_context_p->ue_context.e_rab[i].param.sgw_addr= S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobeswitched[i].sgw_addr;
//ue_context_p->ue_context.e_rab[i].param.gtp_teid = S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobeswitched[i].gtp_teid;
/* Tunnel must have been already created in X2_HO_REQ procedure */
if (nb_e_rabs_tobeswitched>0) {
int e_rab_switch_index=0;
for (i = 0;
i < ue_context_p->ue_context.setup_e_rabs; // go over total number of e_rabs received through x2_ho_req msg
i++) {
/* Harmonize with enb_gtp_teid, enb_gtp_addrs, and enb_gtp_rbi vars in the top level structure */
if (ue_context_p->ue_context.e_rab[i].param.e_rab_id == S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobeswitched[e_rab_switch_index].e_rab_id) {
ue_context_p->ue_context.e_rab[i].param.e_rab_id = S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobeswitched[e_rab_switch_index].e_rab_id;
ue_context_p->ue_context.e_rab[i].param.sgw_addr= S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobeswitched[e_rab_switch_index].sgw_addr;
ue_context_p->ue_context.e_rab[i].param.gtp_teid = S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobeswitched[e_rab_switch_index].gtp_teid;
e_rab_switch_index++;
}
}
}
ue_context_p->ue_context.setup_e_rabs=i;
ue_context_p->ue_context.nb_of_e_rabs=i;
}
ue_context_p->ue_context.ue_ambr=S1AP_PATH_SWITCH_REQ_ACK (msg_p).ue_ambr;
ue_context_p->ue_context.nb_release_of_e_rabs = S1AP_PATH_SWITCH_REQ_ACK (msg_p).nb_e_rabs_tobereleased;
memset(&delete_tunnel_req, 0, sizeof(delete_tunnel_req));
for (i = 0;
i < ue_context_p->ue_context.nb_release_of_e_rabs;
i++) {
LOG_I(RRC,"Bearer released with ID: %d\n", ue_context_p->ue_context.e_rab[i].param.e_rab_id);
ue_context_p->ue_context.e_rabs_tobereleased[i]=S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobereleased[i].e_rab_id;
delete_tunnel_req.eps_bearer_id[i] = S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobereleased[i].e_rab_id;
}
ue_context_p->ue_context.setup_e_rabs = ue_context_p->ue_context.setup_e_rabs - ue_context_p->ue_context.nb_release_of_e_rabs;
ue_context_p->ue_context.nb_of_e_rabs = ue_context_p->ue_context.nb_of_e_rabs - ue_context_p->ue_context.nb_release_of_e_rabs;
memset(&delete_tunnel_req, 0 , sizeof(delete_tunnel_req));
if (ue_context_p->ue_context.nb_release_of_e_rabs>0) {
int e_rab_release_index=0;
for (i = 0;
i < ue_context_p->ue_context.setup_e_rabs;
i++) {
if (ue_context_p->ue_context.e_rab[i].param.e_rab_id == S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobereleased[e_rab_release_index].e_rab_id) {
LOG_I(RRC,"Bearer released with ID: %d\n", ue_context_p->ue_context.e_rab[i].param.e_rab_id);
ue_context_p->ue_context.e_rab[i].status = E_RAB_STATUS_TORELEASE;
ue_context_p->ue_context.e_rabs_tobereleased[e_rab_release_index]=S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobereleased[e_rab_release_index].e_rab_id;
delete_tunnel_req.eps_bearer_id[e_rab_release_index] = S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobereleased[e_rab_release_index].e_rab_id;