Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
sneltved
openairinterface5G
Commits
9b127482
Commit
9b127482
authored
Mar 07, 2019
by
Raphael Defosseux
Browse files
Merge remote-tracking branch 'origin/x2' into develop_integration_2019_w10
parents
ea0e313f
5bf595a0
Changes
25
Expand all
Hide whitespace changes
Inline
Side-by-side
cmake_targets/CMakeLists.txt
View file @
9b127482
...
...
@@ -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
)
...
...
openair2/COMMON/rrc_messages_def.h
View file @
9b127482
...
...
@@ -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
)
openair2/COMMON/rrc_messages_types.h
View file @
9b127482
...
...
@@ -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_ */
openair2/COMMON/x2ap_messages_def.h
View file @
9b127482
...
...
@@ -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
)
openair2/COMMON/x2ap_messages_types.h
View file @
9b127482
...
...
@@ -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
{
in
t
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
;
...
...
openair2/ENB_APP/enb_config.c
View file @
9b127482
...
...
@@ -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
);
}
}
}
}
}
...
...
openair2/LAYER2/MAC/config.c
View file @
9b127482
...
...
@@ -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
)
{
...
...
openair2/RRC/LTE/rrc_defs.h
View file @
9b127482
...
...
@@ -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
...
...
openair2/RRC/LTE/rrc_eNB.c
View file @
9b127482
This diff is collapsed.
Click to expand it.
openair2/RRC/LTE/rrc_eNB_S1AP.c
View file @
9b127482
...
...
@@ -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
;