Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-RAN
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Michael Black
OpenXG-RAN
Commits
de9c8634
Commit
de9c8634
authored
Mar 12, 2021
by
Remi Hardy
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/s1_subnormal' into integration_2021_wk10
parents
17e10eb2
535efa0f
Changes
23
Show whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
988 additions
and
183 deletions
+988
-183
openair2/COMMON/s1ap_messages_types.h
openair2/COMMON/s1ap_messages_types.h
+5
-0
openair2/ENB_APP/enb_config.c
openair2/ENB_APP/enb_config.c
+59
-0
openair2/ENB_APP/enb_paramdef.h
openair2/ENB_APP/enb_paramdef.h
+15
-0
openair2/RRC/LTE/rrc_eNB_S1AP.c
openair2/RRC/LTE/rrc_eNB_S1AP.c
+24
-8
openair2/X2AP/x2ap_eNB_handler.c
openair2/X2AP/x2ap_eNB_handler.c
+34
-1
openair3/GTPV1-U/gtpv1u_eNB.c
openair3/GTPV1-U/gtpv1u_eNB.c
+1
-1
openair3/NAS/COMMON/EMM/MSG/AttachAccept.c
openair3/NAS/COMMON/EMM/MSG/AttachAccept.c
+0
-1
openair3/NAS/COMMON/IES/SupportedCodecList.c
openair3/NAS/COMMON/IES/SupportedCodecList.c
+4
-0
openair3/NAS/UE/EMM/SAP/emm_as.c
openair3/NAS/UE/EMM/SAP/emm_as.c
+2
-2
openair3/NAS/UE/EMM/SecurityModeControl.c
openair3/NAS/UE/EMM/SecurityModeControl.c
+7
-7
openair3/S1AP/s1ap_common.h
openair3/S1AP/s1ap_common.h
+6
-1
openair3/S1AP/s1ap_eNB.c
openair3/S1AP/s1ap_eNB.c
+353
-68
openair3/S1AP/s1ap_eNB.h
openair3/S1AP/s1ap_eNB.h
+17
-0
openair3/S1AP/s1ap_eNB_decoder.c
openair3/S1AP/s1ap_eNB_decoder.c
+0
-2
openair3/S1AP/s1ap_eNB_defs.h
openair3/S1AP/s1ap_eNB_defs.h
+14
-0
openair3/S1AP/s1ap_eNB_handlers.c
openair3/S1AP/s1ap_eNB_handlers.c
+310
-55
openair3/S1AP/s1ap_eNB_management_procedures.c
openair3/S1AP/s1ap_eNB_management_procedures.c
+27
-7
openair3/S1AP/s1ap_eNB_nas_procedures.c
openair3/S1AP/s1ap_eNB_nas_procedures.c
+17
-5
openair3/S1AP/s1ap_eNB_nnsf.c
openair3/S1AP/s1ap_eNB_nnsf.c
+66
-16
openair3/S1AP/s1ap_eNB_overload.c
openair3/S1AP/s1ap_eNB_overload.c
+14
-2
openair3/S1AP/s1ap_eNB_trace.c
openair3/S1AP/s1ap_eNB_trace.c
+4
-0
openair3/SCTP/sctp_default_values.h
openair3/SCTP/sctp_default_values.h
+2
-2
openair3/SCTP/sctp_eNB_task.c
openair3/SCTP/sctp_eNB_task.c
+7
-5
No files found.
openair2/COMMON/s1ap_messages_types.h
View file @
de9c8634
...
...
@@ -398,6 +398,11 @@ typedef struct s1ap_register_enb_req_s {
/* Number of SCTP streams used for a mme association */
uint16_t
sctp_in_streams
;
uint16_t
sctp_out_streams
;
uint16_t
s1_setuprsp_wait_timer
;
uint16_t
s1_setupreq_wait_timer
;
uint16_t
s1_setupreq_count
;
uint16_t
sctp_req_timer
;
uint16_t
sctp_req_count
;
}
s1ap_register_enb_req_t
;
//-------------------------------------------------------------------------------------------//
...
...
openair2/ENB_APP/enb_config.c
View file @
de9c8634
...
...
@@ -2429,6 +2429,65 @@ int RCconfig_S1(
"to
\n
"
" tracking_area_code = 1; // no string!!
\n
"
" plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } )
\n
"
);
if
(
*
ENBParamList
.
paramarray
[
k
][
ENB_S1SETUP_RSP_TIMER_IDX
].
uptr
<=
0xffff
)
{
S1AP_REGISTER_ENB_REQ
(
msg_p
).
s1_setuprsp_wait_timer
=
*
ENBParamList
.
paramarray
[
k
][
ENB_S1SETUP_RSP_TIMER_IDX
].
uptr
;
}
else
{
LOG_E
(
S1AP
,
"s1setup_rsp_timer value in conf file is invalid (%d). Default value is set.
\n
"
,
*
ENBParamList
.
paramarray
[
k
][
ENB_S1SETUP_RSP_TIMER_IDX
].
uptr
);
S1AP_REGISTER_ENB_REQ
(
msg_p
).
s1_setuprsp_wait_timer
=
5
;
}
if
(
*
ENBParamList
.
paramarray
[
k
][
ENB_S1SETUP_REQ_TIMER_IDX
].
uptr
<=
0xffff
)
{
S1AP_REGISTER_ENB_REQ
(
msg_p
).
s1_setupreq_wait_timer
=
*
ENBParamList
.
paramarray
[
k
][
ENB_S1SETUP_REQ_TIMER_IDX
].
uptr
;
}
else
{
LOG_E
(
S1AP
,
"s1setup_req_timer value in conf file is invalid (%d). Default value is set.
\n
"
,
*
ENBParamList
.
paramarray
[
k
][
ENB_S1SETUP_REQ_TIMER_IDX
].
uptr
);
S1AP_REGISTER_ENB_REQ
(
msg_p
).
s1_setupreq_wait_timer
=
5
;
}
if
(
*
ENBParamList
.
paramarray
[
k
][
ENB_S1SETUP_REQ_COUNT_IDX
].
uptr
<=
0xffff
)
{
S1AP_REGISTER_ENB_REQ
(
msg_p
).
s1_setupreq_count
=
*
ENBParamList
.
paramarray
[
k
][
ENB_S1SETUP_REQ_COUNT_IDX
].
uptr
;
}
else
{
LOG_E
(
S1AP
,
"s1setup_req_count value in conf file is invalid (%d). Default value is set.
\n
"
,
*
ENBParamList
.
paramarray
[
k
][
ENB_S1SETUP_REQ_COUNT_IDX
].
uptr
);
S1AP_REGISTER_ENB_REQ
(
msg_p
).
s1_setupreq_count
=
0xffff
;
}
if
(
*
ENBParamList
.
paramarray
[
k
][
ENB_SCTP_REQ_TIMER_IDX
].
uptr
<=
0xffff
)
{
S1AP_REGISTER_ENB_REQ
(
msg_p
).
sctp_req_timer
=
*
ENBParamList
.
paramarray
[
k
][
ENB_SCTP_REQ_TIMER_IDX
].
uptr
;
}
else
{
LOG_E
(
S1AP
,
"sctp_req_timer value in conf file is invalid (%d). Default value is set.
\n
"
,
*
ENBParamList
.
paramarray
[
k
][
ENB_SCTP_REQ_TIMER_IDX
].
uptr
);
S1AP_REGISTER_ENB_REQ
(
msg_p
).
sctp_req_timer
=
180
;
}
if
(
*
ENBParamList
.
paramarray
[
k
][
ENB_SCTP_REQ_COUNT_IDX
].
uptr
<=
0xffff
)
{
S1AP_REGISTER_ENB_REQ
(
msg_p
).
sctp_req_count
=
*
ENBParamList
.
paramarray
[
k
][
ENB_SCTP_REQ_COUNT_IDX
].
uptr
;
}
else
{
LOG_E
(
S1AP
,
"sctp_req_count value in conf file is invalid (%d). Default value is set.
\n
"
,
*
ENBParamList
.
paramarray
[
k
][
ENB_SCTP_REQ_COUNT_IDX
].
uptr
);
S1AP_REGISTER_ENB_REQ
(
msg_p
).
sctp_req_count
=
0xffff
;
}
config_getlist
(
&
PLMNParamList
,
PLMNParams
,
sizeof
(
PLMNParams
)
/
sizeof
(
paramdef_t
),
aprefix
);
if
(
PLMNParamList
.
numelt
<
1
||
PLMNParamList
.
numelt
>
6
)
{
...
...
openair2/ENB_APP/enb_paramdef.h
View file @
de9c8634
...
...
@@ -214,6 +214,11 @@ typedef enum {
#define ENB_CONFIG_STRING_X2 "enable_x2"
#define ENB_CONFIG_STRING_ENB_M2 "enable_enb_m2"
#define ENB_CONFIG_STRING_MCE_M2 "enable_mce_m2"
#define ENB_CONFIG_STRING_S1SETUP_RSP_TIMER "s1setup_rsp_timer"
#define ENB_CONFIG_STRING_S1SETUP_REQ_TIMER "s1setup_req_timer"
#define ENB_CONFIG_STRING_S1SETUP_REQ_COUNT "s1setup_req_count"
#define ENB_CONFIG_STRING_SCTP_REQ_TIMER "sctp_req_timer"
#define ENB_CONFIG_STRING_SCTP_REQ_COUNT "sctp_req_count"
/*-----------------------------------------------------------------------------------------------------------------------------------------*/
/* cell configuration parameters */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
...
...
@@ -239,6 +244,11 @@ typedef enum {
{ENB_CONFIG_STRING_X2, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
{ENB_CONFIG_STRING_ENB_M2, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0}, \
{ENB_CONFIG_STRING_MCE_M2, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0}, \
{ENB_CONFIG_STRING_S1SETUP_RSP_TIMER, NULL, 0, uptr:NULL, defuintval:5, TYPE_UINT, 0}, \
{ENB_CONFIG_STRING_S1SETUP_REQ_TIMER, NULL, 0, uptr:NULL, defuintval:5, TYPE_UINT, 0}, \
{ENB_CONFIG_STRING_S1SETUP_REQ_COUNT, NULL, 0, uptr:NULL, defuintval:65535, TYPE_UINT, 0}, \
{ENB_CONFIG_STRING_SCTP_REQ_TIMER, NULL, 0, uptr:NULL, defuintval:180, TYPE_UINT, 0}, \
{ENB_CONFIG_STRING_SCTP_REQ_COUNT, NULL, 0, uptr:NULL, defuintval:65535, TYPE_UINT, 0}, \
}
#define ENB_ENB_ID_IDX 0
...
...
@@ -261,6 +271,11 @@ typedef enum {
#define ENB_ENABLE_X2 17
#define ENB_ENABLE_ENB_M2 18
#define ENB_ENABLE_MCE_M2 19
#define ENB_S1SETUP_RSP_TIMER_IDX 20
#define ENB_S1SETUP_REQ_TIMER_IDX 21
#define ENB_S1SETUP_REQ_COUNT_IDX 22
#define ENB_SCTP_REQ_TIMER_IDX 23
#define ENB_SCTP_REQ_COUNT_IDX 24
#define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD}
#define ENBPARAMS_CHECK { \
...
...
openair2/RRC/LTE/rrc_eNB_S1AP.c
View file @
de9c8634
...
...
@@ -782,21 +782,37 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ(
S1AP_NAS_FIRST_REQ
(
message_p
).
ue_identity
.
presenceMask
|=
UE_IDENTITIES_gummei
;
if
(
r_mme
->
plmn_Identity
!=
NULL
)
{
if
((
r_mme
->
plmn_Identity
->
mcc
!=
NULL
)
&&
(
r_mme
->
plmn_Identity
->
mcc
->
list
.
count
>
0
))
{
/* Use first indicated PLMN MCC if it is defined */
S1AP_NAS_FIRST_REQ
(
message_p
).
ue_identity
.
gummei
.
mcc
=
*
r_mme
->
plmn_Identity
->
mcc
->
list
.
array
[
selected_plmn_identity
];
if
((
r_mme
->
plmn_Identity
->
mcc
!=
NULL
)
&&
(
r_mme
->
plmn_Identity
->
mcc
->
list
.
count
==
3
))
{
S1AP_NAS_FIRST_REQ
(
message_p
).
ue_identity
.
gummei
.
mcc
=
(
*
r_mme
->
plmn_Identity
->
mcc
->
list
.
array
[
0
]
&
0xf
)
*
100
+
(
*
r_mme
->
plmn_Identity
->
mcc
->
list
.
array
[
1
]
&
0xf
)
*
10
+
(
*
r_mme
->
plmn_Identity
->
mcc
->
list
.
array
[
2
]
&
0xf
);
LOG_I
(
S1AP
,
"[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MCC %u ue %x
\n
"
,
ctxt_pP
->
module_id
,
S1AP_NAS_FIRST_REQ
(
message_p
).
ue_identity
.
gummei
.
mcc
,
ue_context_pP
->
ue_context
.
rnti
);
}
if
(
r_mme
->
plmn_Identity
->
mnc
.
list
.
count
>
0
)
{
/* Use first indicated PLMN MNC if it is defined */
S1AP_NAS_FIRST_REQ
(
message_p
).
ue_identity
.
gummei
.
mnc
=
*
r_mme
->
plmn_Identity
->
mnc
.
list
.
array
[
selected_plmn_identity
];
LOG_I
(
S1AP
,
"[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MNC %u ue %x
\n
"
,
if
(
r_mme
->
plmn_Identity
->
mnc
.
list
.
count
==
3
)
{
S1AP_NAS_FIRST_REQ
(
message_p
).
ue_identity
.
gummei
.
mnc
=
(
*
r_mme
->
plmn_Identity
->
mnc
.
list
.
array
[
0
]
&
0xf
)
*
100
+
(
*
r_mme
->
plmn_Identity
->
mnc
.
list
.
array
[
1
]
&
0xf
)
*
10
+
(
*
r_mme
->
plmn_Identity
->
mnc
.
list
.
array
[
2
]
&
0xf
);
S1AP_NAS_FIRST_REQ
(
message_p
).
ue_identity
.
gummei
.
mnc_len
=
3
;
LOG_I
(
S1AP
,
"[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MNC %u %udigit ue %x
\n
"
,
ctxt_pP
->
module_id
,
S1AP_NAS_FIRST_REQ
(
message_p
).
ue_identity
.
gummei
.
mnc
,
S1AP_NAS_FIRST_REQ
(
message_p
).
ue_identity
.
gummei
.
mnc_len
,
ue_context_pP
->
ue_context
.
rnti
);
}
else
if
(
r_mme
->
plmn_Identity
->
mnc
.
list
.
count
==
2
)
{
S1AP_NAS_FIRST_REQ
(
message_p
).
ue_identity
.
gummei
.
mnc
=
(
*
r_mme
->
plmn_Identity
->
mnc
.
list
.
array
[
0
]
&
0xf
)
*
10
+
(
*
r_mme
->
plmn_Identity
->
mnc
.
list
.
array
[
1
]
&
0xf
);
S1AP_NAS_FIRST_REQ
(
message_p
).
ue_identity
.
gummei
.
mnc_len
=
2
;
LOG_I
(
S1AP
,
"[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MNC %u %udigit ue %x
\n
"
,
ctxt_pP
->
module_id
,
S1AP_NAS_FIRST_REQ
(
message_p
).
ue_identity
.
gummei
.
mnc
,
S1AP_NAS_FIRST_REQ
(
message_p
).
ue_identity
.
gummei
.
mnc_len
,
ue_context_pP
->
ue_context
.
rnti
);
}
}
else
{
// end if plmn_Identity != NULL
...
...
openair2/X2AP/x2ap_eNB_handler.c
View file @
de9c8634
...
...
@@ -536,6 +536,14 @@ int x2ap_eNB_handle_x2_setup_response(instance_t instance,
return
-
1
;
}
if
((
x2ap_eNB_data
->
state
==
X2AP_ENB_STATE_CONNECTED
)
||
(
x2ap_eNB_data
->
state
==
X2AP_ENB_STATE_READY
))
{
X2AP_ERROR
(
"Received Unexpexted X2 Setup Response Message
\n
"
);
return
-
1
;
}
X2AP_DEBUG
(
"Received a new X2 setup response
\n
"
);
X2AP_FIND_PROTOCOLIE_BY_ID
(
X2AP_X2SetupResponse_IEs_t
,
ie
,
x2SetupResponse
,
...
...
@@ -662,6 +670,14 @@ int x2ap_eNB_handle_x2_setup_failure(instance_t instance,
return
-
1
;
}
if
((
x2ap_eNB_data
->
state
==
X2AP_ENB_STATE_CONNECTED
)
||
(
x2ap_eNB_data
->
state
==
X2AP_ENB_STATE_READY
))
{
X2AP_ERROR
(
"Received Unexpexted X2 Setup Failure Message
\n
"
);
return
-
1
;
}
X2AP_DEBUG
(
"Received a new X2 setup failure
\n
"
);
X2AP_FIND_PROTOCOLIE_BY_ID
(
X2AP_X2SetupFailure_IEs_t
,
ie
,
x2SetupFailure
,
...
...
@@ -730,6 +746,7 @@ int x2ap_eNB_handle_handover_preparation (instance_t instance,
X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID
,
true
);
if
(
ie
==
NULL
)
{
X2AP_ERROR
(
"%s %d: ie is a NULL pointer
\n
"
,
__FILE__
,
__LINE__
);
itti_free
(
ITTI_MSG_ORIGIN_ID
(
msg
),
msg
);
return
-
1
;
}
...
...
@@ -750,7 +767,11 @@ int x2ap_eNB_handle_handover_preparation (instance_t instance,
//measResultListEUTRA.list.array[ncell_index]->physCellId;
X2AP_FIND_PROTOCOLIE_BY_ID
(
X2AP_HandoverRequest_IEs_t
,
ie
,
x2HandoverRequest
,
X2AP_ProtocolIE_ID_id_GUMMEI_ID
,
true
);
if
(
ie
==
NULL
)
{
X2AP_ERROR
(
"%s %d: ie is a NULL pointer
\n
"
,
__FILE__
,
__LINE__
);
itti_free
(
ITTI_MSG_ORIGIN_ID
(
msg
),
msg
);
return
-
1
;
}
TBCD_TO_MCC_MNC
(
&
ie
->
value
.
choice
.
ECGI
.
pLMN_Identity
,
X2AP_HANDOVER_REQ
(
msg
).
ue_gummei
.
mcc
,
X2AP_HANDOVER_REQ
(
msg
).
ue_gummei
.
mnc
,
X2AP_HANDOVER_REQ
(
msg
).
ue_gummei
.
mnc_len
);
OCTET_STRING_TO_INT8
(
&
ie
->
value
.
choice
.
GUMMEI
.
mME_Code
,
X2AP_HANDOVER_REQ
(
msg
).
ue_gummei
.
mme_code
);
...
...
@@ -761,6 +782,7 @@ int x2ap_eNB_handle_handover_preparation (instance_t instance,
if
(
ie
==
NULL
)
{
X2AP_ERROR
(
"%s %d: ie is a NULL pointer
\n
"
,
__FILE__
,
__LINE__
);
itti_free
(
ITTI_MSG_ORIGIN_ID
(
msg
),
msg
);
return
-
1
;
}
...
...
@@ -872,6 +894,7 @@ int x2ap_eNB_handle_handover_response (instance_t instance,
if
(
ie
==
NULL
)
{
X2AP_ERROR
(
"%s %d: ie is a NULL pointer
\n
"
,
__FILE__
,
__LINE__
);
itti_free
(
ITTI_MSG_ORIGIN_ID
(
msg
),
msg
);
return
-
1
;
}
...
...
@@ -882,6 +905,7 @@ int x2ap_eNB_handle_handover_response (instance_t instance,
if
(
ie
==
NULL
)
{
X2AP_ERROR
(
"%s %d: ie is a NULL pointer
\n
"
,
__FILE__
,
__LINE__
);
itti_free
(
ITTI_MSG_ORIGIN_ID
(
msg
),
msg
);
return
-
1
;
}
...
...
@@ -912,6 +936,7 @@ int x2ap_eNB_handle_handover_response (instance_t instance,
if
(
ie
==
NULL
)
{
X2AP_ERROR
(
"%s %d: ie is a NULL pointer
\n
"
,
__FILE__
,
__LINE__
);
itti_free
(
ITTI_MSG_ORIGIN_ID
(
msg
),
msg
);
return
-
1
;
}
else
{
if
(
ie
->
value
.
choice
.
E_RABs_Admitted_List
.
list
.
count
>
0
)
{
...
...
@@ -959,6 +984,12 @@ int x2ap_eNB_handle_handover_response (instance_t instance,
X2AP_FIND_PROTOCOLIE_BY_ID
(
X2AP_HandoverRequestAcknowledge_IEs_t
,
ie
,
x2HandoverRequestAck
,
X2AP_ProtocolIE_ID_id_TargeteNBtoSource_eNBTransparentContainer
,
true
);
if
(
ie
==
NULL
)
{
X2AP_ERROR
(
"%s %d: ie is a NULL pointer
\n
"
,
__FILE__
,
__LINE__
);
itti_free
(
ITTI_MSG_ORIGIN_ID
(
msg
),
msg
);
return
-
1
;
}
X2AP_TargeteNBtoSource_eNBTransparentContainer_t
*
c
=
&
ie
->
value
.
choice
.
TargeteNBtoSource_eNBTransparentContainer
;
if
(
c
->
size
>
1024
/* TODO: this is the size of rrc_buffer in struct x2ap_handover_req_ack_s */
)
...
...
@@ -1012,6 +1043,7 @@ int x2ap_eNB_handle_ue_context_release (instance_t instance,
if
(
ie
==
NULL
)
{
X2AP_ERROR
(
"%s %d: ie is a NULL pointer
\n
"
,
__FILE__
,
__LINE__
);
itti_free
(
ITTI_MSG_ORIGIN_ID
(
msg
),
msg
);
return
-
1
;
}
...
...
@@ -1022,6 +1054,7 @@ int x2ap_eNB_handle_ue_context_release (instance_t instance,
if
(
ie
==
NULL
)
{
X2AP_ERROR
(
"%s %d: ie is a NULL pointer
\n
"
,
__FILE__
,
__LINE__
);
itti_free
(
ITTI_MSG_ORIGIN_ID
(
msg
),
msg
);
return
-
1
;
}
...
...
openair3/GTPV1-U/gtpv1u_eNB.c
View file @
de9c8634
...
...
@@ -1211,7 +1211,7 @@ int gtpv1u_eNB_init(void) {
//gtpv1u_data_g.udp_data;
RC
.
gtpv1u_data_g
->
seq_num
=
0
;
RC
.
gtpv1u_data_g
->
restart_counter
=
0
;
RC
.
gtpv1u_data_g
->
enb_ip_address_for_S1u_S12_S4_up
=
0
;
/* Initializing GTPv1-U stack */
if
((
rc
=
nwGtpv1uInitialize
(
&
RC
.
gtpv1u_data_g
->
gtpv1u_stack
,
GTPU_STACK_ENB
))
!=
NW_GTPV1U_OK
)
{
LOG_E
(
GTPU
,
"Failed to setup nwGtpv1u stack %x
\n
"
,
rc
);
...
...
openair3/NAS/COMMON/EMM/MSG/AttachAccept.c
View file @
de9c8634
...
...
@@ -190,7 +190,6 @@ int decode_attach_accept(attach_accept_msg *attach_accept, uint8_t *buffer, uint
default:
errorCodeDecoder
=
TLV_DECODE_UNEXPECTED_IEI
;
LOG_TRACE
(
WARNING
,
"DECODE_UNEXPECTED_IEI %x (4 bits)"
,
ieiDecoded
);
AssertFatal
(
0
,
" "
);
return
TLV_DECODE_UNEXPECTED_IEI
;
}
}
...
...
openair3/NAS/COMMON/IES/SupportedCodecList.c
View file @
de9c8634
...
...
@@ -43,13 +43,17 @@ int decode_supported_codec_list(SupportedCodecList *supportedcodeclist, uint8_t
CHECK_LENGTH_DECODER
(
len
-
decoded
,
ielen
);
supportedcodeclist
->
systemidentification
=
*
(
buffer
+
decoded
);
decoded
++
;
ielen
--
;
supportedcodeclist
->
lengthofbitmap
=
*
(
buffer
+
decoded
);
decoded
++
;
ielen
--
;
//IES_DECODE_U16(supportedcodeclist->codecbitmap, *(buffer + decoded));
IES_DECODE_U16
(
buffer
,
decoded
,
supportedcodeclist
->
codecbitmap
);
ielen
=
ielen
-
2
;
#if defined (NAS_DEBUG)
dump_supported_codec_list_xml
(
supportedcodeclist
,
iei
);
#endif
decoded
=
decoded
+
ielen
;
return
decoded
;
}
int
encode_supported_codec_list
(
SupportedCodecList
*
supportedcodeclist
,
uint8_t
iei
,
uint8_t
*
buffer
,
uint32_t
len
)
...
...
openair3/NAS/UE/EMM/SAP/emm_as.c
View file @
de9c8634
...
...
@@ -443,15 +443,15 @@ static int _emm_as_data_ind(nas_user_t *user, const emm_as_data_t *msg, int *emm
EPS_MOBILITY_MANAGEMENT_MESSAGE
)
{
/* Process EMM data */
rc
=
_emm_as_recv
(
user
,
plain_msg
,
bytes
,
emm_cause
);
free
(
plain_msg
);
}
else
if
(
header
.
protocol_discriminator
==
EPS_SESSION_MANAGEMENT_MESSAGE
)
{
const
OctetString
data
=
{
bytes
,
(
uint8_t
*
)
plain_msg
};
/* Foward ESM data to EPS session management */
rc
=
lowerlayer_data_ind
(
user
,
&
data
);
}
free
(
plain_msg
);
}
}
}
else
{
/* Process successfull lower layer transfer indication */
rc
=
lowerlayer_success
(
user
);
...
...
openair3/NAS/UE/EMM/SecurityModeControl.c
View file @
de9c8634
...
...
@@ -296,6 +296,8 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi,
else
{
/* Setup EMM cause code */
emm_cause
=
EMM_CAUSE_SECURITY_MODE_REJECTED
;
}
}
/* Release security mode control internal data */
if
(
security_data
->
kenb
.
value
)
{
...
...
@@ -303,8 +305,6 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi,
security_data
->
kenb
.
value
=
NULL
;
security_data
->
kenb
.
length
=
0
;
}
}
}
/* Setup EMM procedure handler to be executed upon receiving
* lower layer notification */
...
...
openair3/S1AP/s1ap_common.h
View file @
de9c8634
...
...
@@ -106,7 +106,12 @@ extern int asn1_xer_print;
if (ie == NULL ) { \
S1AP_ERROR("S1AP_FIND_PROTOCOLIE_BY_ID: %s %d: ie is NULL\n",__FILE__,__LINE__);\
} \
if (mandatory) DevAssert(ie != NULL); \
if (mandatory) { \
if (ie == NULL) { \
S1AP_ERROR("S1AP_FIND_PROTOCOLIE_BY_ID: %s %d: ie is NULL\n",__FILE__,__LINE__);\
return -1; \
} \
} \
} while(0)
/** \brief Function callback prototype.
**/
...
...
openair3/S1AP/s1ap_eNB.c
View file @
de9c8634
...
...
@@ -73,6 +73,42 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *
void
s1ap_eNB_handle_sctp_association_resp
(
instance_t
instance
,
sctp_new_association_resp_t
*
sctp_new_association_resp
);
static
int
s1ap_sctp_req
(
s1ap_eNB_instance_t
*
instance_p
,
s1ap_eNB_mme_data_t
*
s1ap_mme_data_p
);
void
s1ap_eNB_timer_expired
(
instance_t
instance
,
timer_has_expired_t
*
msg_p
);
int
s1ap_timer_setup
(
uint32_t
interval_sec
,
uint32_t
interval_us
,
task_id_t
task_id
,
int32_t
instance
,
uint32_t
timer_kind
,
timer_type_t
type
,
void
*
timer_arg
,
long
*
timer_id
)
{
uint32_t
*
timeoutArg
=
NULL
;
int
ret
=
0
;
timeoutArg
=
malloc
(
sizeof
(
uint32_t
));
*
timeoutArg
=
timer_kind
;
ret
=
timer_setup
(
interval_sec
,
interval_us
,
task_id
,
instance
,
type
,
(
void
*
)
timeoutArg
,
timer_id
);
return
ret
;
}
int
s1ap_timer_remove
(
long
timer_id
)
{
int
ret
;
ret
=
timer_remove
(
timer_id
);
return
ret
;
}
uint32_t
s1ap_generate_eNB_id
(
void
)
{
char
*
out
;
char
hostname
[
50
];
...
...
@@ -98,7 +134,7 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p,
MessageDef
*
message_p
=
NULL
;
sctp_new_association_req_t
*
sctp_new_association_req_p
=
NULL
;
s1ap_eNB_mme_data_t
*
s1ap_mme_data_p
=
NULL
;
struct
s1ap_eNB_mme_data_s
*
mme
=
NULL
;
//
struct s1ap_eNB_mme_data_s *mme = NULL;
DevAssert
(
instance_p
!=
NULL
);
DevAssert
(
mme_ip_address
!=
NULL
);
message_p
=
itti_alloc_new_message
(
TASK_S1AP
,
0
,
SCTP_NEW_ASSOCIATION_REQ
);
...
...
@@ -114,9 +150,6 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p,
local_ip_addr
,
sizeof
(
*
local_ip_addr
));
S1AP_INFO
(
"[eNB %ld] check the mme registration state
\n
"
,
instance_p
->
instance
);
mme
=
NULL
;
if
(
mme
==
NULL
)
{
/* Create new MME descriptor */
s1ap_mme_data_p
=
calloc
(
1
,
sizeof
(
*
s1ap_mme_data_p
));
DevAssert
(
s1ap_mme_data_p
!=
NULL
);
...
...
@@ -137,28 +170,12 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p,
* but not yet associated.
*/
RB_INSERT
(
s1ap_mme_map
,
&
instance_p
->
s1ap_mme_head
,
s1ap_mme_data_p
);
s1ap_mme_data_p
->
state
=
S1AP_ENB_STATE_WAITING
;
instance_p
->
s1ap_mme_nb
++
;
instance_p
->
s1ap_mme_pending_nb
++
;
}
else
if
(
mme
->
state
==
S1AP_ENB_STATE_WAITING
)
{
s1ap_mme_data_p
->
state
=
S1AP_ENB_STATE_DISCONNECTED
;
memcpy
(
&
(
s1ap_mme_data_p
->
mme_ip_address
),
mme_ip_address
,
sizeof
(
net_ip_address_t
)
);
s1ap_mme_data_p
->
overload_state
=
S1AP_NO_OVERLOAD
;
s1ap_mme_data_p
->
sctp_req_cnt
++
;
s1ap_mme_data_p
->
timer_id
=
S1AP_TIMERID_INIT
;
instance_p
->
s1ap_mme_pending_nb
++
;
sctp_new_association_req_p
->
ulp_cnx_id
=
mme
->
cnx_id
;
S1AP_INFO
(
"[eNB %ld] MME already registered, retrive the data (state %d, cnx %d, mme_nb %d, mme_pending_nb %d)
\n
"
,
instance_p
->
instance
,
mme
->
state
,
mme
->
cnx_id
,
instance_p
->
s1ap_mme_nb
,
instance_p
->
s1ap_mme_pending_nb
);
/*s1ap_mme_data_p->cnx_id = mme->cnx_id;
sctp_new_association_req_p->ulp_cnx_id = mme->cnx_id;
s1ap_mme_data_p->assoc_id = -1;
s1ap_mme_data_p->s1ap_eNB_instance = instance_p;
*/
}
else
{
S1AP_WARN
(
"[eNB %ld] MME already registered but not in the waiting state, retrive the data (state %d, cnx %d, mme_nb %d, mme_pending_nb %d)
\n
"
,
instance_p
->
instance
,
mme
->
state
,
mme
->
cnx_id
,
instance_p
->
s1ap_mme_nb
,
instance_p
->
s1ap_mme_pending_nb
);
}
itti_send_msg_to_task
(
TASK_SCTP
,
instance_p
->
instance
,
message_p
);
}
...
...
@@ -207,6 +224,15 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *
new_instance
->
mnc_digit_length
[
i
]
=
s1ap_register_eNB
->
mnc_digit_length
[
i
];
}
memcpy
(
&
(
new_instance
->
enb_ip_address
),
&
(
s1ap_register_eNB
->
enb_ip_address
),
sizeof
(
net_ip_address_t
)
);
new_instance
->
s1_setuprsp_wait_timer
=
s1ap_register_eNB
->
s1_setuprsp_wait_timer
;
new_instance
->
s1_setupreq_wait_timer
=
s1ap_register_eNB
->
s1_setupreq_wait_timer
;
new_instance
->
s1_setupreq_count
=
s1ap_register_eNB
->
s1_setupreq_count
;
new_instance
->
sctp_req_timer
=
s1ap_register_eNB
->
sctp_req_timer
;
new_instance
->
sctp_req_count
=
s1ap_register_eNB
->
sctp_req_count
;
new_instance
->
sctp_in_streams
=
s1ap_register_eNB
->
sctp_in_streams
;
new_instance
->
sctp_out_streams
=
s1ap_register_eNB
->
sctp_out_streams
;
new_instance
->
num_plmn
=
s1ap_register_eNB
->
num_plmn
;
new_instance
->
default_drx
=
s1ap_register_eNB
->
default_drx
;
/* Add the new instance to the list of eNB (meaningfull in virtual mode) */
...
...
@@ -217,8 +243,12 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *
s1ap_register_eNB
->
eNB_id
);
}
DevCheck
(
s1ap_register_eNB
->
nb_mme
<=
S1AP_MAX_NB_MME_IP_ADDRESS
,
S1AP_MAX_NB_MME_IP_ADDRESS
,
s1ap_register_eNB
->
nb_mme
,
0
);
if
(
s1ap_register_eNB
->
nb_mme
>
S1AP_MAX_NB_MME_IP_ADDRESS
)
{
S1AP_ERROR
(
"Invalid MME number = %d
\n
"
,
s1ap_register_eNB
->
nb_mme
);
s1ap_register_eNB
->
nb_mme
=
S1AP_MAX_NB_MME_IP_ADDRESS
;
}
new_instance
->
s1ap_mme_nb
=
s1ap_register_eNB
->
nb_mme
;
/* Trying to connect to provided list of MME ip address */
for
(
index
=
0
;
index
<
s1ap_register_eNB
->
nb_mme
;
index
++
)
{
...
...
@@ -250,28 +280,131 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *
void
s1ap_eNB_handle_sctp_association_resp
(
instance_t
instance
,
sctp_new_association_resp_t
*
sctp_new_association_resp
)
{
s1ap_eNB_instance_t
*
instance_p
;
s1ap_eNB_mme_data_t
*
s1ap_mme_data_p
;
s1ap_eNB_ue_context_t
*
ue_p
=
NULL
;
MessageDef
*
message_p
=
NULL
;
uint32_t
timer_kind
=
0
;
struct
plmn_identity_s
*
plmnInfo
;
struct
served_group_id_s
*
groupInfo
;
struct
served_gummei_s
*
gummeiInfo
;
struct
mme_code_s
*
mmeCode
;
int8_t
cnt
=
0
;
unsigned
enb_s1ap_id
[
NUMBER_OF_UE_MAX
];
DevAssert
(
sctp_new_association_resp
!=
NULL
);
instance_p
=
s1ap_eNB_get_instance
(
instance
);
DevAssert
(
instance_p
!=
NULL
);
s1ap_mme_data_p
=
s1ap_eNB_get_MME
(
instance_p
,
-
1
,
sctp_new_association_resp
->
ulp_cnx_id
);
DevAssert
(
s1ap_mme_data_p
!=
NULL
);
memset
(
enb_s1ap_id
,
0
,
sizeof
(
enb_s1ap_id
)
);
if
(
s1ap_mme_data_p
->
timer_id
!=
S1AP_TIMERID_INIT
)
{
s1ap_timer_remove
(
s1ap_mme_data_p
->
timer_id
);
s1ap_mme_data_p
->
timer_id
=
S1AP_TIMERID_INIT
;
}
if
(
sctp_new_association_resp
->
sctp_state
!=
SCTP_STATE_ESTABLISHED
)
{
S1AP_WARN
(
"Received unsuccessful result for SCTP association (%u), instance %ld, cnx_id %u
\n
"
,
sctp_new_association_resp
->
sctp_state
,
instance
,
sctp_new_association_resp
->
ulp_cnx_id
);
s1ap_handle_s1_setup_message
(
s1ap_mme_data_p
,
sctp_new_association_resp
->
sctp_state
==
SCTP_STATE_SHUTDOWN
);
return
;
if
(
sctp_new_association_resp
->
sctp_state
!=
SCTP_STATE_ESTABLISHED
)
{
RB_FOREACH
(
ue_p
,
s1ap_ue_map
,
&
instance_p
->
s1ap_ue_head
)
{
if
(
ue_p
->
mme_ref
==
s1ap_mme_data_p
)
{
if
(
cnt
<
NUMBER_OF_UE_MAX
)
{
enb_s1ap_id
[
cnt
]
=
ue_p
->
eNB_ue_s1ap_id
;
cnt
++
;
message_p
=
NULL
;
message_p
=
itti_alloc_new_message
(
TASK_S1AP
,
0
,
S1AP_UE_CONTEXT_RELEASE_COMMAND
);
if
(
message_p
!=
NULL
)
{
S1AP_UE_CONTEXT_RELEASE_COMMAND
(
message_p
).
eNB_ue_s1ap_id
=
ue_p
->
eNB_ue_s1ap_id
;
if
(
itti_send_msg_to_task
(
TASK_RRC_ENB
,
ue_p
->
eNB_instance
->
instance
,
message_p
)
<
0
)
{
S1AP_ERROR
(
"UE Context Release Command Transmission Failure: eNB_ue_s1ap_id=%u
\n
"
,
ue_p
->
eNB_ue_s1ap_id
);
}
}
else
{
S1AP_ERROR
(
"Invalid message_p : eNB_ue_s1ap_id=%u
\n
"
,
ue_p
->
eNB_ue_s1ap_id
);
}
}
else
{
S1AP_ERROR
(
"s1ap_eNB_handle_sctp_association_resp: cnt %d > max
\n
"
,
cnt
);
}
}
}
for
(
;
cnt
>
0
;
)
{
cnt
--
;
struct
s1ap_eNB_ue_context_s
*
ue_context_p
=
NULL
;
struct
s1ap_eNB_ue_context_s
*
s1ap_ue_context_p
=
NULL
;
ue_context_p
=
s1ap_eNB_get_ue_context
(
instance_p
,
(
uint32_t
)
enb_s1ap_id
[
cnt
]);
if
(
ue_context_p
!=
NULL
)
{
s1ap_ue_context_p
=
RB_REMOVE
(
s1ap_ue_map
,
&
instance_p
->
s1ap_ue_head
,
ue_context_p
);
s1ap_eNB_free_ue_context
(
s1ap_ue_context_p
);
}
}
s1ap_mme_data_p
->
mme_name
=
0
;
s1ap_mme_data_p
->
overload_state
=
S1AP_NO_OVERLOAD
;
s1ap_mme_data_p
->
nextstream
=
0
;
s1ap_mme_data_p
->
in_streams
=
0
;
s1ap_mme_data_p
->
out_streams
=
0
;
s1ap_mme_data_p
->
assoc_id
=
-
1
;
while
(
!
STAILQ_EMPTY
(
&
s1ap_mme_data_p
->
served_gummei
))
{
gummeiInfo
=
STAILQ_FIRST
(
&
s1ap_mme_data_p
->
served_gummei
);
STAILQ_REMOVE_HEAD
(
&
s1ap_mme_data_p
->
served_gummei
,
next
);
while
(
!
STAILQ_EMPTY
(
&
gummeiInfo
->
served_plmns
))
{
plmnInfo
=
STAILQ_FIRST
(
&
gummeiInfo
->
served_plmns
);
STAILQ_REMOVE_HEAD
(
&
gummeiInfo
->
served_plmns
,
next
);
free
(
plmnInfo
);
}
while
(
!
STAILQ_EMPTY
(
&
gummeiInfo
->
served_group_ids
))
{
groupInfo
=
STAILQ_FIRST
(
&
gummeiInfo
->
served_group_ids
);
STAILQ_REMOVE_HEAD
(
&
gummeiInfo
->
served_group_ids
,
next
);
free
(
groupInfo
);
}
while
(
!
STAILQ_EMPTY
(
&
gummeiInfo
->
mme_codes
))
{
mmeCode
=
STAILQ_FIRST
(
&
gummeiInfo
->
mme_codes
);
STAILQ_REMOVE_HEAD
(
&
gummeiInfo
->
mme_codes
,
next
);
free
(
mmeCode
);
}
free
(
gummeiInfo
);
}
STAILQ_INIT
(
&
s1ap_mme_data_p
->
served_gummei
);
if
(
s1ap_mme_data_p
->
state
==
S1AP_ENB_STATE_DISCONNECTED
)
{
if
(
(
s1ap_mme_data_p
->
sctp_req_cnt
<=
instance_p
->
sctp_req_count
)
||
(
instance_p
->
sctp_req_count
==
0xffff
)
)
{
timer_kind
=
s1ap_mme_data_p
->
cnx_id
;
timer_kind
=
timer_kind
|
S1AP_MMEIND
;
timer_kind
=
timer_kind
|
SCTP_REQ_WAIT
;
if
(
s1ap_timer_setup
(
instance_p
->
sctp_req_timer
,
0
,
TASK_S1AP
,
instance_p
->
instance
,
timer_kind
,
S1AP_TIMER_ONE_SHOT
,
NULL
,
&
s1ap_mme_data_p
->
timer_id
)
<
0
)
{
S1AP_ERROR
(
"Timer Start NG(SCTP retransmission wait timer) : MME=%d
\n
"
,
s1ap_mme_data_p
->
cnx_id
);
s1ap_sctp_req
(
instance_p
,
s1ap_mme_data_p
);
}
}
else
{
S1AP_ERROR
(
"Retransmission count exceeded of SCTP : MME=%d
\n
"
,
s1ap_mme_data_p
->
cnx_id
);
}
}
else
{
S1AP_ERROR
(
"SCTP disconnection reception : MME = %d
\n
"
,
s1ap_mme_data_p
->
cnx_id
);
if
(
(
s1ap_mme_data_p
->
sctp_req_cnt
<=
instance_p
->
sctp_req_count
)
||
(
instance_p
->
sctp_req_count
==
0xffff
)
)
{
s1ap_sctp_req
(
instance_p
,
s1ap_mme_data_p
);
}
else
{
S1AP_ERROR
(
"Retransmission count exceeded of SCTP : MME=%d
\n
"
,
s1ap_mme_data_p
->
cnx_id
);
}
s1ap_mme_data_p
->
state
=
S1AP_ENB_STATE_DISCONNECTED
;
}
}
else
{
/* Update parameters */
s1ap_mme_data_p
->
assoc_id
=
sctp_new_association_resp
->
assoc_id
;
s1ap_mme_data_p
->
in_streams
=
sctp_new_association_resp
->
in_streams
;
s1ap_mme_data_p
->
out_streams
=
sctp_new_association_resp
->
out_streams
;
/* Prepare new S1 Setup Request */
s1ap_eNB_generate_s1_setup_request
(
instance_p
,
s1ap_mme_data_p
);
s1ap_mme_data_p
->
s1_setupreq_cnt
=
0
;
s1ap_mme_data_p
->
sctp_req_cnt
=
0
;
if
(
s1ap_eNB_generate_s1_setup_request
(
instance_p
,
s1ap_mme_data_p
)
==
-
1
)
{
S1AP_ERROR
(
"s1ap eNB generate s1 setup request failed
\n
"
);
return
;
}
}
}
static
...
...
@@ -282,13 +415,94 @@ void s1ap_eNB_handle_sctp_data_ind(sctp_data_ind_t *sctp_data_ind) {
mme_test_s1_notify_sctp_data_ind
(
sctp_data_ind
->
assoc_id
,
sctp_data_ind
->
stream
,
sctp_data_ind
->
buffer
,
sctp_data_ind
->
buffer_length
);
#else
s1ap_eNB_handle_message
(
sctp_data_ind
->
assoc_id
,
sctp_data_ind
->
stream
,
sctp_data_ind
->
buffer
,
sctp_data_ind
->
buffer_length
);
if
(
s1ap_eNB_handle_message
(
sctp_data_ind
->
assoc_id
,
sctp_data_ind
->
stream
,
sctp_data_ind
->
buffer
,
sctp_data_ind
->
buffer_length
)
==
-
1
)
{
S1AP_ERROR
(
"Failed to handle s1ap eNB message
\n
"
);
}
#endif
result
=
itti_free
(
TASK_UNKNOWN
,
sctp_data_ind
->
buffer
);
AssertFatal
(
result
==
EXIT_SUCCESS
,
"Failed to free memory (%d)!
\n
"
,
result
);
}
void
s1ap_eNB_timer_expired
(
instance_t
instance
,
timer_has_expired_t
*
msg_p
)
{
uint32_t
timer_kind
=
0
;
int16_t
line_ind
=
0
;
s1ap_eNB_mme_data_t
*
mme_desc_p
=
NULL
;
uint32_t
timer_ind
=
0
;
s1ap_eNB_instance_t
*
instance_p
=
NULL
;
long
timer_id
=
S1AP_TIMERID_INIT
;
instance_p
=
s1ap_eNB_get_instance
(
instance
);
if
(
msg_p
->
arg
!=
NULL
){
timer_kind
=
*
((
uint32_t
*
)
msg_p
->
arg
);
free
(
msg_p
->
arg
);
}
else
{
S1AP_ERROR
(
"s1 timer timer_kind is NULL
\n
"
);
return
;
}
line_ind
=
(
int16_t
)(
timer_kind
&
S1AP_LINEIND
);
timer_id
=
msg_p
->
timer_id
;
if
(
(
timer_kind
&
S1AP_MMEIND
)
==
S1AP_MMEIND
)
{
mme_desc_p
=
s1ap_eNB_get_MME
(
instance_p
,
-
1
,
line_ind
);
if
(
mme_desc_p
!=
NULL
)
{
if
(
timer_id
==
mme_desc_p
->
timer_id
)
{
mme_desc_p
->
timer_id
=
S1AP_TIMERID_INIT
;
timer_ind
=
timer_kind
&
S1AP_TIMERIND
;
switch
(
timer_ind
)
{
case
S1_SETRSP_WAIT
:
{
if
(
(
instance_p
->
s1_setupreq_count
>=
mme_desc_p
->
s1_setupreq_cnt
)
||
(
instance_p
->
s1_setupreq_count
==
0xffff
)
)
{
s1ap_eNB_generate_s1_setup_request
(
instance_p
,
mme_desc_p
);
}
else
{
S1AP_ERROR
(
"Retransmission count exceeded of S1 SETUP REQUEST : MME=%d
\n
"
,
line_ind
);
}
break
;
}
case
S1_SETREQ_WAIT
:
{
if
(
(
instance_p
->
s1_setupreq_count
>=
mme_desc_p
->
s1_setupreq_cnt
)
||
(
instance_p
->
s1_setupreq_count
==
0xffff
)
)
{
s1ap_eNB_generate_s1_setup_request
(
instance_p
,
mme_desc_p
);
}
else
{
S1AP_ERROR
(
"Retransmission count exceeded of S1 SETUP REQUEST : MME=%d
\n
"
,
line_ind
);
}
break
;
}
case
SCTP_REQ_WAIT
:
{
if
(
(
instance_p
->
sctp_req_count
>=
mme_desc_p
->
sctp_req_cnt
)
||
(
instance_p
->
sctp_req_count
==
0xffff
)
)
{
s1ap_sctp_req
(
instance_p
,
mme_desc_p
);
}
else
{
S1AP_ERROR
(
"Retransmission count exceeded of SCTP : MME=%d
\n
"
,
line_ind
);
}
break
;
}
default:
{
S1AP_WARN
(
"Invalid Timer indication
\n
"
);
break
;
}
}
}
else
{
S1AP_DEBUG
(
"Unmatch timer id
\n
"
);
return
;
}
}
else
{
S1AP_WARN
(
"Not applicable MME detected : connection id = %d
\n
"
,
line_ind
);
return
;
}
}
return
;
}
void
s1ap_eNB_init
(
void
)
{
S1AP_DEBUG
(
"Starting S1AP layer
\n
"
);
s1ap_eNB_prepare_internal_data
();
...
...
@@ -412,6 +626,13 @@ void *s1ap_eNB_process_itti_msg(void *notUsed) {
}
break
;
case
TIMER_HAS_EXPIRED
:
{
s1ap_eNB_timer_expired
(
ITTI_MSG_DESTINATION_INSTANCE
(
received_msg
),
&
received_msg
->
ittiMsg
.
timer_has_expired
);
}
break
;
default:
S1AP_ERROR
(
"Received unhandled message: %d:%s
\n
"
,
ITTI_MSG_ID
(
received_msg
),
ITTI_MSG_NAME
(
received_msg
));
...
...
@@ -452,6 +673,7 @@ static int s1ap_eNB_generate_s1_setup_request(
uint8_t
*
buffer
=
NULL
;
uint32_t
len
=
0
;
int
ret
=
0
;
uint32_t
timer_kind
=
0
;
DevAssert
(
instance_p
!=
NULL
);
DevAssert
(
s1ap_mme_data_p
!=
NULL
);
s1ap_mme_data_p
->
state
=
S1AP_ENB_STATE_WAITING
;
...
...
@@ -526,6 +748,17 @@ static int s1ap_eNB_generate_s1_setup_request(
return
-
1
;
}
timer_kind
=
s1ap_mme_data_p
->
cnx_id
;
timer_kind
=
timer_kind
|
S1AP_MMEIND
;
timer_kind
=
timer_kind
|
S1_SETRSP_WAIT
;
if
(
s1ap_timer_setup
(
instance_p
->
s1_setuprsp_wait_timer
,
0
,
TASK_S1AP
,
instance_p
->
instance
,
timer_kind
,
S1AP_TIMER_ONE_SHOT
,
NULL
,
&
s1ap_mme_data_p
->
timer_id
)
<
0
)
{
S1AP_ERROR
(
"Timer Start NG(S1 Setup Response) : MME=%d
\n
"
,
s1ap_mme_data_p
->
cnx_id
);
}
s1ap_mme_data_p
->
s1_setupreq_cnt
++
;
/* Non UE-Associated signalling -> stream = 0 */
s1ap_eNB_itti_send_sctp_data_req
(
instance_p
->
instance
,
s1ap_mme_data_p
->
assoc_id
,
buffer
,
len
,
0
);
return
ret
;
...
...
@@ -534,3 +767,55 @@ static int s1ap_eNB_generate_s1_setup_request(
static
int
s1ap_sctp_req
(
s1ap_eNB_instance_t
*
instance_p
,
s1ap_eNB_mme_data_t
*
s1ap_mme_data_p
)
{
MessageDef
*
message_p
=
NULL
;
sctp_new_association_req_t
*
sctp_new_association_req_p
=
NULL
;
if
(
instance_p
==
NULL
)
{
S1AP_ERROR
(
"Invalid instance_p
\n
"
);
return
-
1
;
}
message_p
=
itti_alloc_new_message
(
TASK_S1AP
,
0
,
SCTP_NEW_ASSOCIATION_REQ
);
sctp_new_association_req_p
=
&
message_p
->
ittiMsg
.
sctp_new_association_req
;
sctp_new_association_req_p
->
port
=
S1AP_PORT_NUMBER
;
sctp_new_association_req_p
->
ppid
=
S1AP_SCTP_PPID
;
sctp_new_association_req_p
->
in_streams
=
instance_p
->
sctp_in_streams
;
sctp_new_association_req_p
->
out_streams
=
instance_p
->
sctp_out_streams
;
sctp_new_association_req_p
->
ulp_cnx_id
=
s1ap_mme_data_p
->
cnx_id
;
if
(
s1ap_mme_data_p
->
mme_ip_address
.
ipv4
!=
0
)
{
memcpy
(
&
sctp_new_association_req_p
->
remote_address
,
&
s1ap_mme_data_p
->
mme_ip_address
,
sizeof
(
net_ip_address_t
));
if
(
instance_p
->
enb_ip_address
.
ipv4
!=
0
)
{
memcpy
(
&
sctp_new_association_req_p
->
local_address
,
&
instance_p
->
enb_ip_address
,
sizeof
(
net_ip_address_t
));
}
else
{
S1AP_ERROR
(
"Invalid IP Address Format V4(MME):V6
\n
"
);
return
-
1
;
}
}
else
{
memcpy
(
&
sctp_new_association_req_p
->
remote_address
,
&
s1ap_mme_data_p
->
mme_ip_address
,
sizeof
(
net_ip_address_t
));
if
(
instance_p
->
enb_ip_address
.
ipv6
!=
0
)
{
memcpy
(
&
sctp_new_association_req_p
->
local_address
,
&
instance_p
->
enb_ip_address
,
sizeof
(
net_ip_address_t
));
}
else
{
S1AP_ERROR
(
"Invalid IP Address Format V6(MME):V4
\n
"
);
return
-
1
;
}
}
itti_send_msg_to_task
(
TASK_SCTP
,
instance_p
->
instance
,
message_p
);
s1ap_mme_data_p
->
sctp_req_cnt
++
;
return
0
;
}
openair3/S1AP/s1ap_eNB.h
View file @
de9c8634
...
...
@@ -30,6 +30,22 @@
#ifndef S1AP_ENB_H_
#define S1AP_ENB_H_
#define S1AP_MMEIND 0x80000000
#define S1AP_UEIND 0x00000000
#define S1_SETRSP_WAIT 0x00010000
#define S1_SETREQ_WAIT 0x00020000
#define SCTP_REQ_WAIT 0x00030000
#define S1AP_LINEIND 0x0000ffff
#define S1AP_TIMERIND 0x00ff0000
#define S1AP_TIMERID_INIT 0xffffffffffffffff
typedef
enum
s1ap_timer_type_s
{
S1AP_TIMER_PERIODIC
,
S1AP_TIMER_ONE_SHOT
,
S1AP_TIMER_TYPE_MAX
,
}
s1ap_timer_type_t
;
typedef
struct
s1ap_eNB_config_s
{
// MME related params
unsigned
char
mme_enabled
;
///< MME enabled ?
...
...
@@ -43,6 +59,7 @@ void *s1ap_eNB_process_itti_msg(void*);
void
s1ap_eNB_init
(
void
);
void
*
s1ap_eNB_task
(
void
*
arg
);
int
s1ap_timer_remove
(
long
timer_id
);
uint32_t
s1ap_generate_eNB_id
(
void
);
#endif
/* S1AP_ENB_H_ */
...
...
openair3/S1AP/s1ap_eNB_decoder.c
View file @
de9c8634
...
...
@@ -89,8 +89,6 @@ static int s1ap_eNB_decode_initiating_message(S1AP_S1AP_PDU_t *pdu) {
default:
S1AP_ERROR
(
"Unknown procedure ID (%d) for initiating message
\n
"
,
(
int
)
pdu
->
choice
.
initiatingMessage
.
procedureCode
);
AssertFatal
(
0
,
"Unknown procedure ID (%d) for initiating message
\n
"
,
(
int
)
pdu
->
choice
.
initiatingMessage
.
procedureCode
);
return
-
1
;
}
...
...
openair3/S1AP/s1ap_eNB_defs.h
View file @
de9c8634
...
...
@@ -165,6 +165,12 @@ typedef struct s1ap_eNB_mme_data_s {
/* Only meaningfull in virtual mode */
struct
s1ap_eNB_instance_s
*
s1ap_eNB_instance
;
uint32_t
nb_calls
;
net_ip_address_t
mme_ip_address
;
long
timer_id
;
uint16_t
s1_setupreq_cnt
;
uint16_t
sctp_req_cnt
;
}
s1ap_eNB_mme_data_t
;
typedef
struct
s1ap_eNB_instance_s
{
...
...
@@ -217,6 +223,14 @@ typedef struct s1ap_eNB_instance_s {
/* Default Paging DRX of the eNB as defined in TS 36.304 */
paging_drx_t
default_drx
;
net_ip_address_t
enb_ip_address
;
uint16_t
s1_setuprsp_wait_timer
;
uint16_t
s1_setupreq_wait_timer
;
uint16_t
s1_setupreq_count
;
uint16_t
sctp_req_timer
;
uint16_t
sctp_req_count
;
uint16_t
sctp_in_streams
;
uint16_t
sctp_out_streams
;
}
s1ap_eNB_instance_t
;
typedef
struct
{
...
...
openair3/S1AP/s1ap_eNB_handlers.c
View file @
de9c8634
...
...
@@ -38,6 +38,9 @@
#include "s1ap_eNB_defs.h"
#include "s1ap_eNB_handlers.h"
#include "s1ap_eNB_decoder.h"
#include "s1ap_eNB_encoder.h"
#include "s1ap_eNB_itti_messaging.h"
#include "s1ap_eNB_ue_context.h"
#include "s1ap_eNB_trace.h"
...
...
@@ -109,6 +112,20 @@ int s1ap_eNB_handle_s1_ENDC_e_rab_modification_confirm(uint32_t as
uint32_t
stream
,
S1AP_S1AP_PDU_t
*
pdu
);
static
int
s1ap_eNB_snd_s1_setup_request
(
s1ap_eNB_instance_t
*
instance_p
,
s1ap_eNB_mme_data_t
*
s1ap_mme_data_p
);
int
s1ap_timer_setup
(
uint32_t
interval_sec
,
uint32_t
interval_us
,
task_id_t
task_id
,
int32_t
instance
,
uint32_t
timer_kind
,
timer_type_t
type
,
void
*
timer_arg
,
long
*
timer_id
);
/* Handlers matrix. Only eNB related procedure present here */
s1ap_message_decoded_callback
messages_callback
[][
3
]
=
{
{
0
,
0
,
0
},
/* HandoverPreparation */
...
...
@@ -260,6 +277,10 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id,
S1AP_S1SetupFailure_t
*
container
;
S1AP_S1SetupFailureIEs_t
*
ie
;
s1ap_eNB_mme_data_t
*
mme_desc_p
;
uint32_t
interval_sec
=
0
;
uint32_t
timer_kind
=
0
;
s1ap_eNB_instance_t
*
instance_p
;
DevAssert
(
pdu
!=
NULL
);
container
=
&
pdu
->
choice
.
unsuccessfulOutcome
.
value
.
choice
.
S1SetupFailure
;
...
...
@@ -270,7 +291,7 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id,
}
if
((
mme_desc_p
=
s1ap_eNB_get_MME
(
NULL
,
assoc_id
,
0
))
==
NULL
)
{
S1AP_ERROR
(
"[SCTP %d] Received S1 setup
respons
e for non existing "
S1AP_ERROR
(
"[SCTP %d] Received S1 setup
failur
e for non existing "
"MME context
\n
"
,
assoc_id
);
return
-
1
;
}
...
...
@@ -278,6 +299,10 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id,
S1AP_FIND_PROTOCOLIE_BY_ID
(
S1AP_S1SetupFailureIEs_t
,
ie
,
container
,
S1AP_ProtocolIE_ID_id_Cause
,
true
);
if
(
ie
==
NULL
)
{
return
-
1
;
}
if
((
ie
->
value
.
choice
.
Cause
.
present
==
S1AP_Cause_PR_misc
)
&&
(
ie
->
value
.
choice
.
Cause
.
choice
.
misc
==
S1AP_CauseMisc_unspecified
))
{
S1AP_WARN
(
"Received s1 setup failure for MME... MME is not ready
\n
"
);
...
...
@@ -285,8 +310,56 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id,
S1AP_ERROR
(
"Received s1 setup failure for MME... please check your parameters
\n
"
);
}
mme_desc_p
->
state
=
S1AP_ENB_STATE_WAITING
;
s1ap_handle_s1_setup_message
(
mme_desc_p
,
0
);
if
(
mme_desc_p
->
timer_id
!=
S1AP_TIMERID_INIT
)
{
s1ap_timer_remove
(
mme_desc_p
->
timer_id
);
mme_desc_p
->
timer_id
=
S1AP_TIMERID_INIT
;
}
instance_p
=
mme_desc_p
->
s1ap_eNB_instance
;
if
(
(
instance_p
->
s1_setupreq_count
>=
mme_desc_p
->
s1_setupreq_cnt
)
||
(
instance_p
->
s1_setupreq_count
==
0xffff
)
)
{
S1AP_FIND_PROTOCOLIE_BY_ID
(
S1AP_S1SetupFailureIEs_t
,
ie
,
container
,
S1AP_ProtocolIE_ID_id_TimeToWait
,
false
);
if
(
ie
!=
NULL
)
{
switch
(
ie
->
value
.
choice
.
TimeToWait
)
{
case
S1AP_TimeToWait_v1s
:
interval_sec
=
1
;
break
;
case
S1AP_TimeToWait_v2s
:
interval_sec
=
2
;
break
;
case
S1AP_TimeToWait_v5s
:
interval_sec
=
5
;
break
;
case
S1AP_TimeToWait_v10s
:
interval_sec
=
10
;
break
;
case
S1AP_TimeToWait_v20s
:
interval_sec
=
20
;
break
;
case
S1AP_TimeToWait_v60s
:
interval_sec
=
60
;
break
;
default:
interval_sec
=
instance_p
->
s1_setupreq_wait_timer
;
break
;
}
}
else
{
interval_sec
=
instance_p
->
s1_setupreq_wait_timer
;
}
timer_kind
=
mme_desc_p
->
cnx_id
;
timer_kind
=
timer_kind
|
S1AP_MMEIND
;
timer_kind
=
timer_kind
|
S1_SETREQ_WAIT
;
if
(
s1ap_timer_setup
(
interval_sec
,
0
,
TASK_S1AP
,
instance_p
->
instance
,
timer_kind
,
S1AP_TIMER_ONE_SHOT
,
NULL
,
&
mme_desc_p
->
timer_id
)
<
0
)
{
S1AP_ERROR
(
"Timer Start NG(S1 Setup Request) : MME=%d
\n
"
,
mme_desc_p
->
cnx_id
);
s1ap_eNB_snd_s1_setup_request
(
instance_p
,
mme_desc_p
);
}
}
else
{
S1AP_ERROR
(
"Retransmission count exceeded of S1 SETUP REQUEST : MME=%d
\n
"
,
mme_desc_p
->
cnx_id
);
}
return
0
;
}
...
...
@@ -314,9 +387,27 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id,
return
-
1
;
}
/* Set the capacity of this MME */
S1AP_FIND_PROTOCOLIE_BY_ID
(
S1AP_S1SetupResponseIEs_t
,
ie
,
container
,
S1AP_ProtocolIE_ID_id_RelativeMMECapacity
,
true
);
if
(
ie
==
NULL
)
{
return
-
1
;
}
mme_desc_p
->
relative_mme_capacity
=
ie
->
value
.
choice
.
RelativeMMECapacity
;
S1AP_FIND_PROTOCOLIE_BY_ID
(
S1AP_S1SetupResponseIEs_t
,
ie
,
container
,
S1AP_ProtocolIE_ID_id_ServedGUMMEIs
,
true
);
if
(
ie
==
NULL
)
{
return
-
1
;
}
if
(
mme_desc_p
->
timer_id
!=
S1AP_TIMERID_INIT
)
{
s1ap_timer_remove
(
mme_desc_p
->
timer_id
);
mme_desc_p
->
timer_id
=
S1AP_TIMERID_INIT
;
}
mme_desc_p
->
s1_setupreq_cnt
=
0
;
mme_desc_p
->
sctp_req_cnt
=
0
;
/* The list of served gummei can contain at most 8 elements.
* LTE related gummei is the first element in the list, i.e with an id of 0.
*/
...
...
@@ -369,12 +460,6 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id,
STAILQ_INSERT_TAIL
(
&
mme_desc_p
->
served_gummei
,
new_gummei_p
,
next
);
}
/* Set the capacity of this MME */
S1AP_FIND_PROTOCOLIE_BY_ID
(
S1AP_S1SetupResponseIEs_t
,
ie
,
container
,
S1AP_ProtocolIE_ID_id_RelativeMMECapacity
,
true
);
mme_desc_p
->
relative_mme_capacity
=
ie
->
value
.
choice
.
RelativeMMECapacity
;
/* Optionaly set the mme name */
S1AP_FIND_PROTOCOLIE_BY_ID
(
S1AP_S1SetupResponseIEs_t
,
ie
,
container
,
S1AP_ProtocolIE_ID_id_MMEname
,
false
);
...
...
@@ -392,7 +477,6 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id,
*/
mme_desc_p
->
state
=
S1AP_ENB_STATE_CONNECTED
;
mme_desc_p
->
s1ap_eNB_instance
->
s1ap_mme_associated_nb
++
;
s1ap_handle_s1_setup_message
(
mme_desc_p
,
0
);
return
0
;
}
...
...
@@ -725,6 +809,9 @@ int s1ap_eNB_handle_error_indication(uint32_t assoc_id,
S1AP_ProtocolIE_ID_id_CriticalityDiagnostics
,
false
);
if
(
ie
)
{
if
(
ie
->
value
.
choice
.
CriticalityDiagnostics
.
procedureCode
)
{
S1AP_WARN
(
"Received S1 Error indication CriticalityDiagnostics procedureCode = %ld
\n
"
,
*
ie
->
value
.
choice
.
CriticalityDiagnostics
.
procedureCode
);
}
// TODO continue
}
...
...
@@ -807,9 +894,11 @@ int s1ap_eNB_handle_initial_context_request(uint32_t assoc_id,
&
(
S1AP_INITIAL_CONTEXT_SETUP_REQ
(
message_p
).
ue_ambr
.
br_dl
));
/* id-E-RABToBeSetupListCtxtSUReq */
}
else
{
itti_free
(
ITTI_MSG_ORIGIN_ID
(
message_p
),
message_p
);
return
-
1
;
}
S1AP_FIND_PROTOCOLIE_BY_ID
(
S1AP_InitialContextSetupRequestIEs_t
,
ie
,
container
,
S1AP_ProtocolIE_ID_id_E_RABToBeSetupListCtxtSUReq
,
true
);
...
...
@@ -852,6 +941,7 @@ int s1ap_eNB_handle_initial_context_request(uint32_t assoc_id,
item_p
->
e_RABlevelQoSParameters
.
allocationRetentionPriority
.
pre_emptionVulnerability
;
}
/* for i... */
}
else
{
/* ie != NULL */
itti_free
(
ITTI_MSG_ORIGIN_ID
(
message_p
),
message_p
);
return
-
1
;
}
...
...
@@ -865,6 +955,7 @@ int s1ap_eNB_handle_initial_context_request(uint32_t assoc_id,
S1AP_INITIAL_CONTEXT_SETUP_REQ
(
message_p
).
security_capabilities
.
integrity_algorithms
=
BIT_STRING_to_uint16
(
&
ie
->
value
.
choice
.
UESecurityCapabilities
.
integrityProtectionAlgorithms
);
}
else
{
/* ie != NULL */
itti_free
(
ITTI_MSG_ORIGIN_ID
(
message_p
),
message_p
);
return
-
1
;
}
...
...
@@ -876,6 +967,7 @@ int s1ap_eNB_handle_initial_context_request(uint32_t assoc_id,
memcpy
(
&
S1AP_INITIAL_CONTEXT_SETUP_REQ
(
message_p
).
security_key
,
ie
->
value
.
choice
.
SecurityKey
.
buf
,
ie
->
value
.
choice
.
SecurityKey
.
size
);
}
else
{
/* ie != NULL */
itti_free
(
ITTI_MSG_ORIGIN_ID
(
message_p
),
message_p
);
return
-
1
;
}
...
...
@@ -918,6 +1010,13 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id,
return
-
1
;
}
S1AP_FIND_PROTOCOLIE_BY_ID
(
S1AP_UEContextReleaseCommand_IEs_t
,
ie
,
container
,
S1AP_ProtocolIE_ID_id_Cause
,
true
);
if
(
ie
==
NULL
)
{
S1AP_ERROR
(
"Mandatory Element Nothing : UEContextReleaseCommand(Cause)
\n
"
);
return
-
1
;
}
S1AP_FIND_PROTOCOLIE_BY_ID
(
S1AP_UEContextReleaseCommand_IEs_t
,
ie
,
container
,
S1AP_ProtocolIE_ID_id_UE_S1AP_IDs
,
true
);
...
...
@@ -965,9 +1064,26 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id,
//#warning "TODO mapping mme_ue_s1ap_id enb_ue_s1ap_id?"
case
S1AP_UE_S1AP_IDs_PR_mME_UE_S1AP_ID
:
mme_ue_s1ap_id
=
ie
->
value
.
choice
.
UE_S1AP_IDs
.
choice
.
uE_S1AP_ID_pair
.
mME_UE_S1AP_ID
;
S1AP_ERROR
(
"TO DO mapping mme_ue_s1ap_id enb_ue_s1ap_id"
);
(
void
)
mme_ue_s1ap_id
;
/* TODO: remove - it's to remove gcc warning about unused var */
mme_ue_s1ap_id
=
ie
->
value
.
choice
.
UE_S1AP_IDs
.
choice
.
mME_UE_S1AP_ID
;
RB_FOREACH
(
ue_desc_p
,
s1ap_ue_map
,
&
mme_desc_p
->
s1ap_eNB_instance
->
s1ap_ue_head
)
{
if
(
ue_desc_p
->
mme_ue_s1ap_id
==
mme_ue_s1ap_id
)
{
enb_ue_s1ap_id
=
ue_desc_p
->
eNB_ue_s1ap_id
;
message_p
=
itti_alloc_new_message
(
TASK_S1AP
,
0
,
S1AP_UE_CONTEXT_RELEASE_COMMAND
);
S1AP_UE_CONTEXT_RELEASE_COMMAND
(
message_p
).
eNB_ue_s1ap_id
=
enb_ue_s1ap_id
;
itti_send_msg_to_task
(
TASK_RRC_ENB
,
ue_desc_p
->
eNB_instance
->
instance
,
message_p
);
return
0
;
}
}
S1AP_ERROR
(
"[SCTP %d] Received UE context release command(mME_UE_S1AP_ID) for non "
"existing UE context 0x%06lx
\n
"
,
assoc_id
,
mme_ue_s1ap_id
);
return
-
1
;
case
S1AP_UE_S1AP_IDs_PR_NOTHING
:
default:
...
...
@@ -975,12 +1091,10 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id,
return
-
1
;
}
}
else
{
S1AP_ERROR
(
"Mandatory Element Nothing : UEContextReleaseCommand(UE_S1AP_IDs)
\n
"
);
return
-
1
;
}
S1AP_FIND_PROTOCOLIE_BY_ID
(
S1AP_UEContextReleaseCommand_IEs_t
,
ie
,
container
,
S1AP_ProtocolIE_ID_id_Cause
,
true
);
/* TBD */
}
static
...
...
@@ -999,7 +1113,7 @@ int s1ap_eNB_handle_e_rab_setup_request(uint32_t assoc_id,
container
=
&
pdu
->
choice
.
initiatingMessage
.
value
.
choice
.
E_RABSetupRequest
;
if
((
mme_desc_p
=
s1ap_eNB_get_MME
(
NULL
,
assoc_id
,
0
))
==
NULL
)
{
S1AP_ERROR
(
"[SCTP %d] Received
initial context
setup request for non "
S1AP_ERROR
(
"[SCTP %d] Received
E-RAB
setup request for non "
"existing MME context
\n
"
,
assoc_id
);
return
-
1
;
}
...
...
@@ -1026,7 +1140,7 @@ int s1ap_eNB_handle_e_rab_setup_request(uint32_t assoc_id,
if
((
ue_desc_p
=
s1ap_eNB_get_ue_context
(
mme_desc_p
->
s1ap_eNB_instance
,
enb_ue_s1ap_id
))
==
NULL
)
{
S1AP_ERROR
(
"[SCTP %d] Received initial context
setup request for non "
S1AP_ERROR
(
"[SCTP %d] Received E-RAB
setup request for non "
"existing UE context 0x%06lx
\n
"
,
assoc_id
,
enb_ue_s1ap_id
);
return
-
1
;
...
...
@@ -1099,6 +1213,7 @@ int s1ap_eNB_handle_e_rab_setup_request(uint32_t assoc_id,
itti_send_msg_to_task
(
TASK_RRC_ENB
,
ue_desc_p
->
eNB_instance
->
instance
,
message_p
);
}
else
{
itti_free
(
ITTI_MSG_ORIGIN_ID
(
message_p
),
message_p
);
return
-
1
;
}
...
...
@@ -1119,13 +1234,6 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id,
// received Paging Message from MME
S1AP_DEBUG
(
"[SCTP %d] Received Paging Message From MME
\n
"
,
assoc_id
);
/* Paging procedure -> stream != 0 */
if
(
stream
==
0
)
{
LOG_W
(
S1AP
,
"[SCTP %d] Received Paging procedure on stream (%d)
\n
"
,
assoc_id
,
stream
);
return
-
1
;
}
if
((
mme_desc_p
=
s1ap_eNB_get_MME
(
NULL
,
assoc_id
,
0
))
==
NULL
)
{
S1AP_ERROR
(
"[SCTP %d] Received Paging for non "
"existing MME context
\n
"
,
assoc_id
);
...
...
@@ -1153,6 +1261,7 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id,
S1AP_PAGING_IND
(
message_p
).
ue_paging_identity
.
choice
.
s_tmsi
.
mme_code
=
0
;
S1AP_PAGING_IND
(
message_p
).
ue_paging_identity
.
choice
.
s_tmsi
.
m_tmsi
=
0
;
}
else
{
itti_free
(
ITTI_MSG_ORIGIN_ID
(
message_p
),
message_p
);
return
-
1
;
}
...
...
@@ -1180,6 +1289,7 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id,
if
(
i
!=
ie
->
value
.
choice
.
UEPagingID
.
choice
.
iMSI
.
size
-
1
)
{
/* invalid paging_p->uePagingID.choise.iMSI.buffer */
S1AP_ERROR
(
"[SCTP %d] Received Paging : uePagingID.choise.iMSI error(i %d 0x0F)
\n
"
,
assoc_id
,
i
);
itti_free
(
ITTI_MSG_ORIGIN_ID
(
message_p
),
message_p
);
return
-
1
;
}
}
else
{
...
...
@@ -1190,14 +1300,17 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id,
if
(
S1AP_PAGING_IND
(
message_p
).
ue_paging_identity
.
choice
.
imsi
.
length
>=
S1AP_IMSI_LENGTH
)
{
/* invalid paging_p->uePagingID.choise.iMSI.size */
S1AP_ERROR
(
"[SCTP %d] Received Paging : uePagingID.choise.iMSI.size(%d) is over IMSI length(%d)
\n
"
,
assoc_id
,
S1AP_PAGING_IND
(
message_p
).
ue_paging_identity
.
choice
.
imsi
.
length
,
S1AP_IMSI_LENGTH
);
itti_free
(
ITTI_MSG_ORIGIN_ID
(
message_p
),
message_p
);
return
-
1
;
}
}
else
{
/* of if (ie->value.choice.UEPagingID.present == S1AP_UEPagingID_PR_iMSI) */
/* invalid paging_p->uePagingID.present */
S1AP_ERROR
(
"[SCTP %d] Received Paging : uePagingID.present(%d) is unknown
\n
"
,
assoc_id
,
ie
->
value
.
choice
.
UEPagingID
.
present
);
itti_free
(
ITTI_MSG_ORIGIN_ID
(
message_p
),
message_p
);
return
-
1
;
}
}
else
{
/* of ie != NULL */
itti_free
(
ITTI_MSG_ORIGIN_ID
(
message_p
),
message_p
);
return
-
1
;
}
...
...
@@ -1230,6 +1343,7 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id,
return
-
1
;
}
}
else
{
itti_free
(
ITTI_MSG_ORIGIN_ID
(
message_p
),
message_p
);
return
-
1
;
}
...
...
@@ -1257,6 +1371,7 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id,
S1AP_PAGING_IND
(
message_p
).
tac
[
i
]);
}
}
else
{
itti_free
(
ITTI_MSG_ORIGIN_ID
(
message_p
),
message_p
);
return
-
1
;
}
...
...
@@ -1351,6 +1466,7 @@ int s1ap_eNB_handle_e_rab_modify_request(uint32_t assoc_id,
S1AP_E_RAB_MODIFY_RESP
(
message_p
).
e_rabs_failed
[
nb_of_e_rabs_failed
].
cause_value
=
S1AP_CauseRadioNetwork_unknown_mme_ue_s1ap_id
;
}
}
else
{
itti_free
(
ITTI_MSG_ORIGIN_ID
(
message_p
),
message_p
);
return
-
1
;
}
...
...
@@ -1403,6 +1519,7 @@ int s1ap_eNB_handle_e_rab_modify_request(uint32_t assoc_id,
itti_send_msg_to_task
(
TASK_RRC_ENB
,
ue_desc_p
->
eNB_instance
->
instance
,
message_p
);
}
else
{
/* of if (ie != NULL)*/
itti_free
(
ITTI_MSG_ORIGIN_ID
(
message_p
),
message_p
);
return
-
1
;
}
...
...
@@ -1476,22 +1593,6 @@ int s1ap_eNB_handle_e_rab_release_command(uint32_t assoc_id,
message_p
=
itti_alloc_new_message
(
TASK_S1AP
,
0
,
S1AP_E_RAB_RELEASE_COMMAND
);
S1AP_E_RAB_RELEASE_COMMAND
(
message_p
).
eNB_ue_s1ap_id
=
enb_ue_s1ap_id
;
S1AP_E_RAB_RELEASE_COMMAND
(
message_p
).
mme_ue_s1ap_id
=
mme_ue_s1ap_id
;
/* id-NAS-PDU */
S1AP_FIND_PROTOCOLIE_BY_ID
(
S1AP_E_RABReleaseCommandIEs_t
,
ie
,
container
,
S1AP_ProtocolIE_ID_id_NAS_PDU
,
false
);
if
(
ie
&&
ie
->
value
.
choice
.
NAS_PDU
.
size
>
0
)
{
S1AP_E_RAB_RELEASE_COMMAND
(
message_p
).
nas_pdu
.
length
=
ie
->
value
.
choice
.
NAS_PDU
.
size
;
S1AP_E_RAB_RELEASE_COMMAND
(
message_p
).
nas_pdu
.
buffer
=
malloc
(
sizeof
(
uint8_t
)
*
ie
->
value
.
choice
.
NAS_PDU
.
size
);
memcpy
(
S1AP_E_RAB_RELEASE_COMMAND
(
message_p
).
nas_pdu
.
buffer
,
ie
->
value
.
choice
.
NAS_PDU
.
buf
,
ie
->
value
.
choice
.
NAS_PDU
.
size
);
}
else
{
S1AP_E_RAB_RELEASE_COMMAND
(
message_p
).
nas_pdu
.
length
=
0
;
S1AP_E_RAB_RELEASE_COMMAND
(
message_p
).
nas_pdu
.
buffer
=
NULL
;
}
/* id-E-RABToBeReleasedList */
S1AP_FIND_PROTOCOLIE_BY_ID
(
S1AP_E_RABReleaseCommandIEs_t
,
ie
,
container
,
S1AP_ProtocolIE_ID_id_E_RABToBeReleasedList
,
true
);
...
...
@@ -1506,9 +1607,25 @@ int s1ap_eNB_handle_e_rab_release_command(uint32_t assoc_id,
S1AP_DEBUG
(
"[SCTP] Received E-RAB release command for e-rab id %ld
\n
"
,
item_p
->
e_RAB_ID
);
}
}
else
{
itti_free
(
ITTI_MSG_ORIGIN_ID
(
message_p
),
message_p
);
return
-
1
;
}
/* id-NAS-PDU */
S1AP_FIND_PROTOCOLIE_BY_ID
(
S1AP_E_RABReleaseCommandIEs_t
,
ie
,
container
,
S1AP_ProtocolIE_ID_id_NAS_PDU
,
false
);
if
(
ie
&&
ie
->
value
.
choice
.
NAS_PDU
.
size
>
0
)
{
S1AP_E_RAB_RELEASE_COMMAND
(
message_p
).
nas_pdu
.
length
=
ie
->
value
.
choice
.
NAS_PDU
.
size
;
S1AP_E_RAB_RELEASE_COMMAND
(
message_p
).
nas_pdu
.
buffer
=
malloc
(
sizeof
(
uint8_t
)
*
ie
->
value
.
choice
.
NAS_PDU
.
size
);
memcpy
(
S1AP_E_RAB_RELEASE_COMMAND
(
message_p
).
nas_pdu
.
buffer
,
ie
->
value
.
choice
.
NAS_PDU
.
buf
,
ie
->
value
.
choice
.
NAS_PDU
.
size
);
}
else
{
S1AP_E_RAB_RELEASE_COMMAND
(
message_p
).
nas_pdu
.
length
=
0
;
S1AP_E_RAB_RELEASE_COMMAND
(
message_p
).
nas_pdu
.
buffer
=
NULL
;
}
itti_send_msg_to_task
(
TASK_RRC_ENB
,
ue_desc_p
->
eNB_instance
->
instance
,
message_p
);
return
0
;
}
...
...
@@ -1533,7 +1650,6 @@ int s1ap_eNB_handle_s1_path_switch_request_ack(uint32_t assoc_id,
if
(
stream
==
0
)
{
S1AP_ERROR
(
"[SCTP %d] Received s1 path switch request ack on stream (%d)
\n
"
,
assoc_id
,
stream
);
//return -1;
}
if
((
mme_desc_p
=
s1ap_eNB_get_MME
(
NULL
,
assoc_id
,
0
))
==
NULL
)
{
...
...
@@ -1550,6 +1666,7 @@ int s1ap_eNB_handle_s1_path_switch_request_ack(uint32_t assoc_id,
if
(
ie
==
NULL
)
{
S1AP_ERROR
(
"[SCTP %d] Received path switch request ack for non "
"ie context is NULL
\n
"
,
assoc_id
);
itti_free
(
ITTI_MSG_ORIGIN_ID
(
message_p
),
message_p
);
return
-
1
;
}
...
...
@@ -1572,6 +1689,7 @@ int s1ap_eNB_handle_s1_path_switch_request_ack(uint32_t assoc_id,
if
(
ie
==
NULL
)
{
S1AP_ERROR
(
"[SCTP %d] Received path switch request ack for non "
"ie context is NULL
\n
"
,
assoc_id
);
itti_free
(
ITTI_MSG_ORIGIN_ID
(
message_p
),
message_p
);
return
-
1
;
}
...
...
@@ -1589,6 +1707,7 @@ int s1ap_eNB_handle_s1_path_switch_request_ack(uint32_t assoc_id,
if
(
ie
==
NULL
)
{
S1AP_ERROR
(
"[SCTP %d] Received path switch request ack for non "
"ie context is NULL
\n
"
,
assoc_id
);
itti_free
(
ITTI_MSG_ORIGIN_ID
(
message_p
),
message_p
);
return
-
1
;
}
...
...
@@ -1602,14 +1721,10 @@ int s1ap_eNB_handle_s1_path_switch_request_ack(uint32_t assoc_id,
S1AP_ProtocolIE_ID_id_uEaggregateMaximumBitrate
,
false
);
if
(
ie
)
{
OCTET_STRING_TO_INT32
(
&
ie
->
value
.
choice
.
UEAggregateMaximumBitrate
.
uEaggregateMaximumBitRateUL
,
S1AP_PATH_SWITCH_REQ_ACK
(
message_p
).
ue_ambr
.
br_ul
);
OCTET_STRING_TO_INT32
(
&
ie
->
value
.
choice
.
UEAggregateMaximumBitrate
.
uEaggregateMaximumBitRateDL
,
S1AP_PATH_SWITCH_REQ_ACK
(
message_p
).
ue_ambr
.
br_dl
);
asn_INTEGER2ulong
(
&
ie
->
value
.
choice
.
UEAggregateMaximumBitrate
.
uEaggregateMaximumBitRateUL
,
&
S1AP_PATH_SWITCH_REQ_ACK
(
message_p
).
ue_ambr
.
br_ul
);
asn_INTEGER2ulong
(
&
ie
->
value
.
choice
.
UEAggregateMaximumBitrate
.
uEaggregateMaximumBitRateDL
,
&
S1AP_PATH_SWITCH_REQ_ACK
(
message_p
).
ue_ambr
.
br_dl
);
}
else
{
S1AP_WARN
(
"UEAggregateMaximumBitrate not supported
\n
"
);
S1AP_PATH_SWITCH_REQ_ACK
(
message_p
).
ue_ambr
.
br_ul
=
0
;
...
...
@@ -1688,9 +1803,8 @@ int s1ap_eNB_handle_s1_path_switch_request_failure(uint32_t assoc_
pathSwitchRequestFailure
=
&
pdu
->
choice
.
unsuccessfulOutcome
.
value
.
choice
.
PathSwitchRequestFailure
;
if
(
stream
!=
0
)
{
S1AP_
ERROR
(
"[SCTP %d] Received s1 path switch request failure on stream != 0 (%d)
\n
"
,
S1AP_
WARN
(
"[SCTP %d] Received s1 path switch request failure on stream != 0 (%d)
\n
"
,
assoc_id
,
stream
);
return
-
1
;
}
if
((
mme_desc_p
=
s1ap_eNB_get_MME
(
NULL
,
assoc_id
,
0
))
==
NULL
)
{
...
...
@@ -1754,3 +1868,144 @@ int s1ap_eNB_handle_s1_ENDC_e_rab_modification_confirm(uint32_t as
return
0
;
}
//-----------------------------------------------------------------------------
/*
* eNB generate a S1 setup request towards MME
*/
static
int
s1ap_eNB_snd_s1_setup_request
(
s1ap_eNB_instance_t
*
instance_p
,
s1ap_eNB_mme_data_t
*
s1ap_mme_data_p
)
//-----------------------------------------------------------------------------
{
S1AP_S1AP_PDU_t
pdu
;
S1AP_S1SetupRequest_t
*
out
=
NULL
;
S1AP_S1SetupRequestIEs_t
*
ie
=
NULL
;
S1AP_SupportedTAs_Item_t
*
ta
=
NULL
;
S1AP_PLMNidentity_t
*
plmn
=
NULL
;
uint8_t
*
buffer
=
NULL
;
uint32_t
len
=
0
;
int
ret
=
0
;
uint32_t
timer_kind
=
0
;
DevAssert
(
instance_p
!=
NULL
);
DevAssert
(
s1ap_mme_data_p
!=
NULL
);
s1ap_mme_data_p
->
state
=
S1AP_ENB_STATE_WAITING
;
/* Prepare the S1AP message to encode */
memset
(
&
pdu
,
0
,
sizeof
(
pdu
));
pdu
.
present
=
S1AP_S1AP_PDU_PR_initiatingMessage
;
pdu
.
choice
.
initiatingMessage
.
procedureCode
=
S1AP_ProcedureCode_id_S1Setup
;
pdu
.
choice
.
initiatingMessage
.
criticality
=
S1AP_Criticality_reject
;
pdu
.
choice
.
initiatingMessage
.
value
.
present
=
S1AP_InitiatingMessage__value_PR_S1SetupRequest
;
out
=
&
pdu
.
choice
.
initiatingMessage
.
value
.
choice
.
S1SetupRequest
;
/* mandatory */
ie
=
(
S1AP_S1SetupRequestIEs_t
*
)
calloc
(
1
,
sizeof
(
S1AP_S1SetupRequestIEs_t
));
ie
->
id
=
S1AP_ProtocolIE_ID_id_Global_ENB_ID
;
ie
->
criticality
=
S1AP_Criticality_reject
;
ie
->
value
.
present
=
S1AP_S1SetupRequestIEs__value_PR_Global_ENB_ID
;
MCC_MNC_TO_PLMNID
(
instance_p
->
mcc
[
s1ap_mme_data_p
->
broadcast_plmn_index
[
0
]],
instance_p
->
mnc
[
s1ap_mme_data_p
->
broadcast_plmn_index
[
0
]],
instance_p
->
mnc_digit_length
[
s1ap_mme_data_p
->
broadcast_plmn_index
[
0
]],
&
ie
->
value
.
choice
.
Global_ENB_ID
.
pLMNidentity
);
ie
->
value
.
choice
.
Global_ENB_ID
.
eNB_ID
.
present
=
S1AP_ENB_ID_PR_macroENB_ID
;
MACRO_ENB_ID_TO_BIT_STRING
(
instance_p
->
eNB_id
,
&
ie
->
value
.
choice
.
Global_ENB_ID
.
eNB_ID
.
choice
.
macroENB_ID
);
S1AP_INFO
(
"%d -> %02x%02x%02x
\n
"
,
instance_p
->
eNB_id
,
ie
->
value
.
choice
.
Global_ENB_ID
.
eNB_ID
.
choice
.
macroENB_ID
.
buf
[
0
],
ie
->
value
.
choice
.
Global_ENB_ID
.
eNB_ID
.
choice
.
macroENB_ID
.
buf
[
1
],
ie
->
value
.
choice
.
Global_ENB_ID
.
eNB_ID
.
choice
.
macroENB_ID
.
buf
[
2
]);
ASN_SEQUENCE_ADD
(
&
out
->
protocolIEs
.
list
,
ie
);
/* optional */
if
(
instance_p
->
eNB_name
)
{
ie
=
(
S1AP_S1SetupRequestIEs_t
*
)
calloc
(
1
,
sizeof
(
S1AP_S1SetupRequestIEs_t
));
ie
->
id
=
S1AP_ProtocolIE_ID_id_eNBname
;
ie
->
criticality
=
S1AP_Criticality_ignore
;
ie
->
value
.
present
=
S1AP_S1SetupRequestIEs__value_PR_ENBname
;
OCTET_STRING_fromBuf
(
&
ie
->
value
.
choice
.
ENBname
,
instance_p
->
eNB_name
,
strlen
(
instance_p
->
eNB_name
));
ASN_SEQUENCE_ADD
(
&
out
->
protocolIEs
.
list
,
ie
);
}
/* mandatory */
ie
=
(
S1AP_S1SetupRequestIEs_t
*
)
calloc
(
1
,
sizeof
(
S1AP_S1SetupRequestIEs_t
));
ie
->
id
=
S1AP_ProtocolIE_ID_id_SupportedTAs
;
ie
->
criticality
=
S1AP_Criticality_reject
;
ie
->
value
.
present
=
S1AP_S1SetupRequestIEs__value_PR_SupportedTAs
;
{
ta
=
(
S1AP_SupportedTAs_Item_t
*
)
calloc
(
1
,
sizeof
(
S1AP_SupportedTAs_Item_t
));
INT16_TO_OCTET_STRING
(
instance_p
->
tac
,
&
ta
->
tAC
);
{
for
(
int
i
=
0
;
i
<
s1ap_mme_data_p
->
broadcast_plmn_num
;
++
i
)
{
plmn
=
(
S1AP_PLMNidentity_t
*
)
calloc
(
1
,
sizeof
(
S1AP_PLMNidentity_t
));
MCC_MNC_TO_TBCD
(
instance_p
->
mcc
[
s1ap_mme_data_p
->
broadcast_plmn_index
[
i
]],
instance_p
->
mnc
[
s1ap_mme_data_p
->
broadcast_plmn_index
[
i
]],
instance_p
->
mnc_digit_length
[
s1ap_mme_data_p
->
broadcast_plmn_index
[
i
]],
plmn
);
ASN_SEQUENCE_ADD
(
&
ta
->
broadcastPLMNs
.
list
,
plmn
);
}
}
ASN_SEQUENCE_ADD
(
&
ie
->
value
.
choice
.
SupportedTAs
.
list
,
ta
);
}
ASN_SEQUENCE_ADD
(
&
out
->
protocolIEs
.
list
,
ie
);
/* mandatory */
ie
=
(
S1AP_S1SetupRequestIEs_t
*
)
calloc
(
1
,
sizeof
(
S1AP_S1SetupRequestIEs_t
));
ie
->
id
=
S1AP_ProtocolIE_ID_id_DefaultPagingDRX
;
ie
->
criticality
=
S1AP_Criticality_ignore
;
ie
->
value
.
present
=
S1AP_S1SetupRequestIEs__value_PR_PagingDRX
;
ie
->
value
.
choice
.
PagingDRX
=
instance_p
->
default_drx
;
ASN_SEQUENCE_ADD
(
&
out
->
protocolIEs
.
list
,
ie
);
/* optional */
if
(
0
)
{
ie
=
(
S1AP_S1SetupRequestIEs_t
*
)
calloc
(
1
,
sizeof
(
S1AP_S1SetupRequestIEs_t
));
ie
->
id
=
S1AP_ProtocolIE_ID_id_CSG_IdList
;
ie
->
criticality
=
S1AP_Criticality_reject
;
ie
->
value
.
present
=
S1AP_S1SetupRequestIEs__value_PR_CSG_IdList
;
// ie->value.choice.CSG_IdList = ;
ASN_SEQUENCE_ADD
(
&
out
->
protocolIEs
.
list
,
ie
);
}
/* optional */
#if (S1AP_VERSION >= MAKE_VERSION(13, 0, 0))
if
(
0
)
{
ie
=
(
S1AP_S1SetupRequestIEs_t
*
)
calloc
(
1
,
sizeof
(
S1AP_S1SetupRequestIEs_t
));
ie
->
id
=
S1AP_ProtocolIE_ID_id_UE_RetentionInformation
;
ie
->
criticality
=
S1AP_Criticality_ignore
;
ie
->
value
.
present
=
S1AP_S1SetupRequestIEs__value_PR_UE_RetentionInformation
;
// ie->value.choice.UE_RetentionInformation = ;
ASN_SEQUENCE_ADD
(
&
out
->
protocolIEs
.
list
,
ie
);
}
/* optional */
if
(
0
)
{
ie
=
(
S1AP_S1SetupRequestIEs_t
*
)
calloc
(
1
,
sizeof
(
S1AP_S1SetupRequestIEs_t
));
ie
->
id
=
S1AP_ProtocolIE_ID_id_NB_IoT_DefaultPagingDRX
;
ie
->
criticality
=
S1AP_Criticality_ignore
;
ie
->
value
.
present
=
S1AP_S1SetupRequestIEs__value_PR_NB_IoT_DefaultPagingDRX
;
// ie->value.choice.NB_IoT_DefaultPagingDRX = ;
ASN_SEQUENCE_ADD
(
&
out
->
protocolIEs
.
list
,
ie
);
}
#endif
/* #if (S1AP_VERSION >= MAKE_VERSION(14, 0, 0)) */
if
(
s1ap_eNB_encode_pdu
(
&
pdu
,
&
buffer
,
&
len
)
<
0
)
{
S1AP_ERROR
(
"Failed to encode S1 setup request
\n
"
);
return
-
1
;
}
timer_kind
=
s1ap_mme_data_p
->
cnx_id
;
timer_kind
=
timer_kind
|
S1AP_MMEIND
;
timer_kind
=
timer_kind
|
S1_SETRSP_WAIT
;
if
(
s1ap_timer_setup
(
instance_p
->
s1_setuprsp_wait_timer
,
0
,
TASK_S1AP
,
instance_p
->
instance
,
timer_kind
,
S1AP_TIMER_ONE_SHOT
,
NULL
,
&
s1ap_mme_data_p
->
timer_id
)
<
0
)
{
S1AP_ERROR
(
"Timer Start NG(S1 Setup Response) : MME=%d
\n
"
,
s1ap_mme_data_p
->
cnx_id
);
}
s1ap_mme_data_p
->
s1_setupreq_cnt
++
;
/* Non UE-Associated signalling -> stream = 0 */
s1ap_eNB_itti_send_sctp_data_req
(
instance_p
->
instance
,
s1ap_mme_data_p
->
assoc_id
,
buffer
,
len
,
0
);
return
ret
;
}
openair3/S1AP/s1ap_eNB_management_procedures.c
View file @
de9c8634
...
...
@@ -95,12 +95,14 @@ struct s1ap_eNB_mme_data_s *s1ap_eNB_get_MME(
{
struct
s1ap_eNB_mme_data_s
temp
;
struct
s1ap_eNB_mme_data_s
*
found
;
struct
s1ap_eNB_mme_data_s
*
mme_p
;
memset
(
&
temp
,
0
,
sizeof
(
struct
s1ap_eNB_mme_data_s
));
temp
.
assoc_id
=
assoc_id
;
temp
.
cnx_id
=
cnx_id
;
if
(
cnx_id
!=
0
)
{
if
(
instance_p
==
NULL
)
{
STAILQ_FOREACH
(
instance_p
,
&
s1ap_eNB_internal_data
.
s1ap_eNB_instances_head
,
s1ap_eNB_entries
)
{
...
...
@@ -113,6 +115,24 @@ struct s1ap_eNB_mme_data_s *s1ap_eNB_get_MME(
}
else
{
return
RB_FIND
(
s1ap_mme_map
,
&
instance_p
->
s1ap_mme_head
,
&
temp
);
}
}
else
{
if
(
instance_p
==
NULL
)
{
STAILQ_FOREACH
(
instance_p
,
&
s1ap_eNB_internal_data
.
s1ap_eNB_instances_head
,
s1ap_eNB_entries
)
{
RB_FOREACH
(
mme_p
,
s1ap_mme_map
,
&
instance_p
->
s1ap_mme_head
)
{
if
(
mme_p
->
assoc_id
==
assoc_id
)
{
return
mme_p
;
}
}
}
}
else
{
RB_FOREACH
(
mme_p
,
s1ap_mme_map
,
&
instance_p
->
s1ap_mme_head
)
{
if
(
mme_p
->
assoc_id
==
assoc_id
)
{
return
mme_p
;
}
}
}
}
return
NULL
;
}
...
...
openair3/S1AP/s1ap_eNB_nas_procedures.c
View file @
de9c8634
...
...
@@ -358,10 +358,18 @@ int s1ap_eNB_handle_nas_downlink(uint32_t assoc_id,
container
=
&
pdu
->
choice
.
initiatingMessage
.
value
.
choice
.
DownlinkNASTransport
;
S1AP_FIND_PROTOCOLIE_BY_ID
(
S1AP_DownlinkNASTransport_IEs_t
,
ie
,
container
,
S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID
,
true
);
if
(
ie
==
NULL
)
{
return
-
1
;
}
mme_ue_s1ap_id
=
ie
->
value
.
choice
.
MME_UE_S1AP_ID
;
S1AP_FIND_PROTOCOLIE_BY_ID
(
S1AP_DownlinkNASTransport_IEs_t
,
ie
,
container
,
S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID
,
true
);
if
(
ie
==
NULL
)
{
return
-
1
;
}
enb_ue_s1ap_id
=
ie
->
value
.
choice
.
ENB_UE_S1AP_ID
;
if
((
ue_desc_p
=
s1ap_eNB_get_ue_context
(
s1ap_eNB_instance
,
...
...
@@ -416,6 +424,10 @@ int s1ap_eNB_handle_nas_downlink(uint32_t assoc_id,
S1AP_FIND_PROTOCOLIE_BY_ID
(
S1AP_DownlinkNASTransport_IEs_t
,
ie
,
container
,
S1AP_ProtocolIE_ID_id_NAS_PDU
,
true
);
if
(
ie
==
NULL
)
{
return
-
1
;
}
/* Forward the NAS PDU to RRC */
s1ap_eNB_itti_send_nas_downlink_ind
(
s1ap_eNB_instance
->
instance
,
ue_desc_p
->
ue_initial_id
,
...
...
@@ -494,9 +506,9 @@ int s1ap_eNB_nas_uplink(instance_t instance, s1ap_uplink_nas_t *s1ap_uplink_nas_
ie
->
criticality
=
S1AP_Criticality_ignore
;
ie
->
value
.
present
=
S1AP_UplinkNASTransport_IEs__value_PR_EUTRAN_CGI
;
MCC_MNC_TO_PLMNID
(
s1ap_eNB_instance_p
->
mcc
[
ue_context_p
->
selected_plmn_identity
],
s1ap_eNB_instance_p
->
mnc
[
ue_context_p
->
selected_plmn_identity
],
s1ap_eNB_instance_p
->
mnc_digit_length
[
ue_context_p
->
selected_plmn_identity
],
s1ap_eNB_instance_p
->
mcc
[
ue_context_p
->
mme_ref
->
broadcast_plmn_index
[
0
]
],
s1ap_eNB_instance_p
->
mnc
[
ue_context_p
->
mme_ref
->
broadcast_plmn_index
[
0
]
],
s1ap_eNB_instance_p
->
mnc_digit_length
[
ue_context_p
->
mme_ref
->
broadcast_plmn_index
[
0
]
],
&
ie
->
value
.
choice
.
EUTRAN_CGI
.
pLMNidentity
);
//#warning "TODO get cell id from RRC"
MACRO_ENB_ID_TO_CELL_IDENTITY
(
s1ap_eNB_instance_p
->
eNB_id
,
...
...
openair3/S1AP/s1ap_eNB_nnsf.c
View file @
de9c8634
...
...
@@ -36,15 +36,29 @@
#include "s1ap_eNB_defs.h"
#include "s1ap_eNB_nnsf.h"
typedef
struct
MME_nnsf_inf
{
struct
s1ap_eNB_mme_data_s
*
mme_p
;
uint64_t
weight
;
}
MME_nnsf_inf_t
;
struct
s1ap_eNB_mme_data_s
*
s1ap_eNB_nnsf_select_mme
(
s1ap_eNB_instance_t
*
instance_p
,
rrc_establishment_cause_t
cause
)
{
struct
s1ap_eNB_mme_data_s
*
mme_data_p
=
NULL
;
struct
s1ap_eNB_mme_data_s
*
mme_highest_capacity_p
=
NULL
;
uint8_t
current_capacity
=
0
;
uint16_t
capacity_sum
=
0
;
MME_nnsf_inf_t
mme_inf
[
10
];
int
cnt
;
int
nb_mme
=
0
;
uint64_t
weight
=
0
;
memset
(
mme_inf
,
0
,
sizeof
(
mme_inf
));
RB_FOREACH
(
mme_data_p
,
s1ap_mme_map
,
&
instance_p
->
s1ap_mme_head
)
{
capacity_sum
=
capacity_sum
+
mme_data_p
->
relative_mme_capacity
;
if
(
mme_data_p
->
state
!=
S1AP_ENB_STATE_CONNECTED
)
{
/* The association between MME and eNB is not ready for the moment,
* go to the next known MME.
...
...
@@ -69,7 +83,8 @@ s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p,
||
(
cause
==
RRC_CAUSE_HIGH_PRIO_ACCESS
)))
{
continue
;
}
mme_inf
[
nb_mme
].
mme_p
=
mme_data_p
;
nb_mme
++
;
/* At this point, the RRC establishment can be handled by the MME
* even if it is in overload state.
*/
...
...
@@ -78,14 +93,27 @@ s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p,
continue
;
}
}
}
if
(
current_capacity
<
mme_data_p
->
relative_mme_capacity
)
{
/* We find a better MME, keep a reference to it */
current_capacity
=
mme_data
_p
->
relative_mme_capacity
;
mme_
highest_capacity_p
=
mme_data_p
;
if
(
nb_mme
!=
0
)
{
for
(
cnt
=
0
;
cnt
<
nb_mme
;
cnt
++
)
{
mme_inf
[
cnt
].
weight
=
(
capacity_sum
*
10
)
/
mme_inf
[
cnt
].
mme
_p
->
relative_mme_capacity
;
mme_
inf
[
cnt
].
weight
=
(
mme_inf
[
cnt
].
weight
)
*
(
mme_inf
[
cnt
].
mme_p
->
nb_calls
+
1
)
;
}
mme_highest_capacity_p
=
mme_inf
[
0
].
mme_p
;
weight
=
mme_inf
[
0
].
weight
;
for
(
cnt
=
1
;
cnt
<
nb_mme
;
cnt
++
)
{
if
(
weight
>
mme_inf
[
cnt
].
weight
)
{
mme_highest_capacity_p
=
mme_inf
[
cnt
].
mme_p
;
weight
=
mme_inf
[
cnt
].
weight
;
}
}
}
else
{
mme_highest_capacity_p
=
NULL
;
}
if
(
mme_highest_capacity_p
!=
NULL
)
{
mme_highest_capacity_p
->
nb_calls
++
;
}
return
mme_highest_capacity_p
;
}
...
...
@@ -96,7 +124,14 @@ s1ap_eNB_nnsf_select_mme_by_plmn_id(s1ap_eNB_instance_t *instance_p,
{
struct
s1ap_eNB_mme_data_s
*
mme_data_p
=
NULL
;
struct
s1ap_eNB_mme_data_s
*
mme_highest_capacity_p
=
NULL
;
uint8_t
current_capacity
=
0
;
uint16_t
capacity_sum
=
0
;
MME_nnsf_inf_t
mme_inf
[
10
];
int
cnt
;
int
nb_mme
=
0
;
uint64_t
weight
=
0
;
memset
(
mme_inf
,
0
,
sizeof
(
mme_inf
));
RB_FOREACH
(
mme_data_p
,
s1ap_mme_map
,
&
instance_p
->
s1ap_mme_head
)
{
struct
served_gummei_s
*
gummei_p
=
NULL
;
...
...
@@ -140,6 +175,8 @@ s1ap_eNB_nnsf_select_mme_by_plmn_id(s1ap_eNB_instance_t *instance_p,
STAILQ_FOREACH
(
served_plmn_p
,
&
gummei_p
->
served_plmns
,
next
)
{
if
((
served_plmn_p
->
mcc
==
instance_p
->
mcc
[
selected_plmn_identity
])
&&
(
served_plmn_p
->
mnc
==
instance_p
->
mnc
[
selected_plmn_identity
]))
{
mme_inf
[
nb_mme
].
mme_p
=
mme_data_p
;
nb_mme
++
;
break
;
}
}
...
...
@@ -148,14 +185,27 @@ s1ap_eNB_nnsf_select_mme_by_plmn_id(s1ap_eNB_instance_t *instance_p,
}
/* if we didn't find such a served PLMN, go on with the next MME */
if
(
!
served_plmn_p
)
continue
;
}
if
(
current_capacity
<
mme_data_p
->
relative_mme_capacity
)
{
/* We find a better MME, keep a reference to it */
current_capacity
=
mme_data
_p
->
relative_mme_capacity
;
mme_
highest_capacity_p
=
mme_data_p
;
if
(
nb_mme
!=
0
)
{
for
(
cnt
=
0
;
cnt
<
nb_mme
;
cnt
++
)
{
mme_inf
[
cnt
].
weight
=
(
capacity_sum
*
10
)
/
mme_inf
[
cnt
].
mme
_p
->
relative_mme_capacity
;
mme_
inf
[
cnt
].
weight
=
(
mme_inf
[
cnt
].
weight
)
*
(
mme_inf
[
cnt
].
mme_p
->
nb_calls
+
1
)
;
}
mme_highest_capacity_p
=
mme_inf
[
0
].
mme_p
;
weight
=
mme_inf
[
0
].
weight
;
for
(
cnt
=
1
;
cnt
<
nb_mme
;
cnt
++
)
{
if
(
weight
>
mme_inf
[
cnt
].
weight
)
{
mme_highest_capacity_p
=
mme_inf
[
cnt
].
mme_p
;
weight
=
mme_inf
[
cnt
].
weight
;
}
}
}
else
{
mme_highest_capacity_p
=
NULL
;
}
if
(
mme_highest_capacity_p
!=
NULL
)
{
mme_highest_capacity_p
->
nb_calls
++
;
}
return
mme_highest_capacity_p
;
}
...
...
openair3/S1AP/s1ap_eNB_overload.c
View file @
de9c8634
...
...
@@ -62,8 +62,16 @@ int s1ap_eNB_handle_overload_start(uint32_t assoc_id,
S1AP_OverloadResponse_PR_overloadAction
,
S1AP_OverloadResponse_PR_overloadAction
,
0
,
0
);
}
else
{
return
-
1
;
}
/* Non UE-associated signalling -> stream 0 */
DevCheck
(
stream
==
0
,
stream
,
0
,
0
);
if
(
stream
!=
0
)
{
S1AP_ERROR
(
"[SCTP %d] Received s1 overload start on stream != 0 (%d)
\n
"
,
assoc_id
,
stream
);
return
-
1
;
}
if
((
mme_desc_p
=
s1ap_eNB_get_MME
(
NULL
,
assoc_id
,
0
))
==
NULL
)
{
/* No MME context associated */
...
...
@@ -93,7 +101,11 @@ int s1ap_eNB_handle_overload_stop(uint32_t assoc_id,
s1ap_eNB_mme_data_t
*
mme_desc_p
;
/* Non UE-associated signalling -> stream 0 */
DevCheck
(
stream
==
0
,
stream
,
0
,
0
);
if
(
stream
!=
0
)
{
S1AP_ERROR
(
"[SCTP %d] Received s1 overload stop on stream != 0 (%d)
\n
"
,
assoc_id
,
stream
);
return
-
1
;
}
if
((
mme_desc_p
=
s1ap_eNB_get_MME
(
NULL
,
assoc_id
,
0
))
==
NULL
)
{
/* No MME context associated */
...
...
openair3/S1AP/s1ap_eNB_trace.c
View file @
de9c8634
...
...
@@ -121,6 +121,10 @@ int s1ap_eNB_handle_trace_start(uint32_t assoc_id,
if
(
ie
!=
NULL
)
{
ue_desc_p
=
s1ap_eNB_get_ue_context
(
mme_ref_p
->
s1ap_eNB_instance
,
ie
->
value
.
choice
.
ENB_UE_S1AP_ID
);
}
else
{
return
-
1
;
}
if
(
ue_desc_p
==
NULL
)
{
/* Could not find context associated with this eNB_ue_s1ap_id -> generate
...
...
openair3/SCTP/sctp_default_values.h
View file @
de9c8634
...
...
@@ -24,8 +24,8 @@
#define SCTP_OUT_STREAMS (16)
#define SCTP_IN_STREAMS (16)
#define SCTP_MAX_ATTEMPTS (
2
)
#define SCTP_TIMEOUT (
5
)
#define SCTP_MAX_ATTEMPTS (
8
)
#define SCTP_TIMEOUT (
60000
)
#define SCTP_RECV_BUFFER_SIZE (8192)
#endif
/* SCTP_DEFAULT_VALUES_H_ */
openair3/SCTP/sctp_eNB_task.c
View file @
de9c8634
...
...
@@ -270,7 +270,7 @@ sctp_handle_new_association_req_multi(
sctp_new_association_req_p
->
remote_address
.
ipv6_address
);
//close(sd);
//return;
exit
(
1
);
exit
_fun
(
"sctp_handle_new_association_req_multi fatal: inet_pton error"
);
}
SCTP_DEBUG
(
"Converted ipv6 address %*s to network type
\n
"
,
...
...
@@ -290,7 +290,7 @@ sctp_handle_new_association_req_multi(
sctp_new_association_req_p
->
remote_address
.
ipv4_address
);
//close(sd);
//return;
exit
(
1
);
exit
_fun
(
"sctp_handle_new_association_req_multi fatal: inet_pton error"
);
}
SCTP_DEBUG
(
"Converted ipv4 address %*s to network type
\n
"
,
...
...
@@ -329,7 +329,7 @@ sctp_handle_new_association_req_multi(
if
(
ns
==
-
1
)
{
perror
(
"sctp_peeloff"
);
printf
(
"sctp_peeloff: sd=%d assoc_id=%d
\n
"
,
sd
,
assoc_id
);
exit
(
1
);
exit
_fun
(
"sctp_handle_new_association_req_multi fatal: sctp_peeloff error"
);
}
sctp_cnx
=
calloc
(
1
,
sizeof
(
*
sctp_cnx
));
...
...
@@ -943,10 +943,12 @@ sctp_eNB_read_from_socket(
&
sinfo
,
&
flags
);
if
(
n
<
0
)
{
if
(
errno
==
ENOTCONN
)
{
if
(
(
errno
==
ENOTCONN
)
||
(
errno
==
ECONNRESET
)
||
(
errno
==
ETIMEDOUT
)
||
(
errno
==
ECONNREFUSED
)
)
{
itti_unsubscribe_event_fd
(
TASK_SCTP
,
sctp_cnx
->
sd
);
SCTP_DEBUG
(
"Received not connected for sd %d
\n
"
,
sctp_cnx
->
sd
);
SCTP_ERROR
(
"sctp_recvmsg (fd %d, len %d ): %s:%d
\n
"
,
sctp_cnx
->
sd
,
n
,
strerror
(
errno
),
errno
);
sctp_itti_send_association_resp
(
sctp_cnx
->
task_id
,
sctp_cnx
->
instance
,
-
1
,
...
...
@@ -969,7 +971,7 @@ sctp_eNB_read_from_socket(
if
(
!
(
flags
&
MSG_EOR
))
{
SCTP_ERROR
(
"fatal: partial SCTP messages are not handled
\n
"
);
exit
(
1
);
exit
_fun
(
"fatal: partial SCTP messages are not handled"
);
}
if
(
flags
&
MSG_NOTIFICATION
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment