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
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
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
OpenXG
OpenXG-RAN
Commits
969425f6
Commit
969425f6
authored
Mar 09, 2021
by
masayuki.harada
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Replace to itti timer.
Fix nnsf selection. Fix indentation and opening brace.
parent
ff994453
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
225 additions
and
555 deletions
+225
-555
openair3/S1AP/s1ap_eNB.c
openair3/S1AP/s1ap_eNB.c
+136
-191
openair3/S1AP/s1ap_eNB_handlers.c
openair3/S1AP/s1ap_eNB_handlers.c
+14
-38
openair3/S1AP/s1ap_eNB_management_procedures.c
openair3/S1AP/s1ap_eNB_management_procedures.c
+9
-20
openair3/S1AP/s1ap_eNB_nas_procedures.c
openair3/S1AP/s1ap_eNB_nas_procedures.c
+4
-5
openair3/S1AP/s1ap_eNB_nnsf.c
openair3/S1AP/s1ap_eNB_nnsf.c
+46
-54
openair3/S1AP/s1ap_eNB_nnsf.h
openair3/S1AP/s1ap_eNB_nnsf.h
+1
-2
openair3/S1AP/s1ap_eNB_timer.c
openair3/S1AP/s1ap_eNB_timer.c
+15
-245
No files found.
openair3/S1AP/s1ap_eNB.c
View file @
969425f6
...
...
@@ -78,7 +78,7 @@ void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa
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
,
s1ap_
timer_has_expired_t
*
msg_p
);
timer_has_expired_t
*
msg_p
);
uint32_t
s1ap_generate_eNB_id
(
void
)
{
char
*
out
;
...
...
@@ -157,7 +157,6 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *
uint8_t
index
;
DevAssert
(
s1ap_register_eNB
!=
NULL
);
/* Look if the provided instance already exists */
s1ap_timer_init
();
new_instance
=
s1ap_eNB_get_instance
(
instance
);
if
(
new_instance
!=
NULL
)
{
...
...
@@ -268,36 +267,28 @@ void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa
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
)
{
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
)
{
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
){
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
,
S1AP_UE_CONTEXT_RELEASE_COMMAND
);
message_p
=
itti_alloc_new_message
(
TASK_S1AP
,
0
,
S1AP_UE_CONTEXT_RELEASE_COMMAND
);
if
(
message_p
!=
NULL
)
{
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
)
{
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
{
}
else
{
S1AP_ERROR
(
"Invalid message_p : eNB_ue_s1ap_id=%u
\n
"
,
ue_p
->
eNB_ue_s1ap_id
);
}
}
else
{
...
...
@@ -305,8 +296,7 @@ void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa
}
}
}
for
(
;
cnt
>
0
;
)
{
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
;
...
...
@@ -323,25 +313,21 @@ void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa
s1ap_mme_data_p
->
out_streams
=
0
;
s1ap_mme_data_p
->
assoc_id
=
-
1
;
while
(
!
STAILQ_EMPTY
(
&
s1ap_mme_data_p
->
served_gummei
))
{
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
))
{
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
))
{
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
))
{
while
(
!
STAILQ_EMPTY
(
&
gummeiInfo
->
mme_codes
))
{
mmeCode
=
STAILQ_FIRST
(
&
gummeiInfo
->
mme_codes
);
STAILQ_REMOVE_HEAD
(
&
gummeiInfo
->
mme_codes
,
next
);
free
(
mmeCode
);
...
...
@@ -351,45 +337,33 @@ void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa
STAILQ_INIT
(
&
s1ap_mme_data_p
->
served_gummei
);
if
(
s1ap_mme_data_p
->
state
==
S1AP_ENB_STATE_DISCONNECTED
)
{
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
)
)
{
(
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
)
{
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
{
}
else
{
S1AP_ERROR
(
"Retransmission count exceeded of SCTP : MME=%d
\n
"
,
s1ap_mme_data_p
->
cnx_id
);
}
}
else
{
}
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
)
)
{
(
instance_p
->
sctp_req_count
==
0xffff
)
)
{
s1ap_sctp_req
(
instance_p
,
s1ap_mme_data_p
);
}
else
{
}
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
{
}
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
;
...
...
@@ -423,7 +397,7 @@ void s1ap_eNB_handle_sctp_data_ind(sctp_data_ind_t *sctp_data_ind) {
void
s1ap_eNB_timer_expired
(
instance_t
instance
,
s1ap_
timer_has_expired_t
*
msg_p
)
timer_has_expired_t
*
msg_p
)
{
uint32_t
timer_kind
=
0
;
int16_t
line_ind
=
0
;
...
...
@@ -433,17 +407,14 @@ void s1ap_eNB_timer_expired(
long
timer_id
=
S1AP_TIMERID_INIT
;
instance_p
=
s1ap_eNB_get_instance
(
instance
);
timer_kind
=
msg_p
->
timer_kind
;
timer_kind
=
*
((
uint32_t
*
)
msg_p
->
arg
)
;
line_ind
=
(
int16_t
)(
timer_kind
&
S1AP_LINEIND
);
timer_id
=
msg_p
->
timer_id
;
if
(
(
timer_kind
&
S1AP_MMEIND
)
==
S1AP_MMEIND
)
{
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
)
{
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
;
...
...
@@ -452,12 +423,9 @@ void s1ap_eNB_timer_expired(
case
S1_SETRSP_WAIT
:
{
if
(
(
instance_p
->
s1_setupreq_count
>=
mme_desc_p
->
s1_setupreq_cnt
)
||
(
instance_p
->
s1_setupreq_count
==
0xffff
)
)
{
(
instance_p
->
s1_setupreq_count
==
0xffff
)
)
{
s1ap_eNB_generate_s1_setup_request
(
instance_p
,
mme_desc_p
);
}
else
{
}
else
{
S1AP_ERROR
(
"Retransmission count exceeded of S1 SETUP REQUEST : MME=%d
\n
"
,
line_ind
);
}
break
;
...
...
@@ -465,12 +433,9 @@ void s1ap_eNB_timer_expired(
case
S1_SETREQ_WAIT
:
{
if
(
(
instance_p
->
s1_setupreq_count
>=
mme_desc_p
->
s1_setupreq_cnt
)
||
(
instance_p
->
s1_setupreq_count
==
0xffff
)
)
{
(
instance_p
->
s1_setupreq_count
==
0xffff
)
)
{
s1ap_eNB_generate_s1_setup_request
(
instance_p
,
mme_desc_p
);
}
else
{
}
else
{
S1AP_ERROR
(
"Retransmission count exceeded of S1 SETUP REQUEST : MME=%d
\n
"
,
line_ind
);
}
break
;
...
...
@@ -478,12 +443,9 @@ void s1ap_eNB_timer_expired(
case
SCTP_REQ_WAIT
:
{
if
(
(
instance_p
->
sctp_req_count
>=
mme_desc_p
->
sctp_req_cnt
)
||
(
instance_p
->
sctp_req_count
==
0xffff
)
)
{
(
instance_p
->
sctp_req_count
==
0xffff
)
)
{
s1ap_sctp_req
(
instance_p
,
mme_desc_p
);
}
else
{
}
else
{
S1AP_ERROR
(
"Retransmission count exceeded of SCTP : MME=%d
\n
"
,
line_ind
);
}
break
;
...
...
@@ -494,29 +456,21 @@ void s1ap_eNB_timer_expired(
break
;
}
}
}
else
{
}
else
{
S1AP_DEBUG
(
"Unmatch timer id
\n
"
);
return
;
}
}
else
{
}
else
{
S1AP_WARN
(
"Not applicable MME detected : connection id = %d
\n
"
,
line_ind
);
return
;
}
}
else
{
}
return
;
}
void
s1ap_eNB_init
(
void
)
{
S1AP_DEBUG
(
"Starting S1AP layer
\n
"
);
s1ap_eNB_prepare_internal_data
();
s1ap_timer_init
();
itti_mark_task_ready
(
TASK_S1AP
);
MSC_START_USE
();
}
...
...
@@ -639,8 +593,8 @@ void *s1ap_eNB_process_itti_msg(void *notUsed) {
case
TIMER_HAS_EXPIRED
:
{
s1ap_eNB_timer_expired
(
ITTI_M
ESSAGE_GET
_INSTANCE
(
received_msg
),
(
s1ap_timer_has_expired_t
*
)
&
TIMER_HAS_EXPIRED
(
received_msg
)
);
s1ap_eNB_timer_expired
(
ITTI_M
SG_DESTINATION
_INSTANCE
(
received_msg
),
&
received_msg
->
ittiMsg
.
timer_has_expired
);
}
break
;
...
...
@@ -790,7 +744,7 @@ static int s1ap_sctp_req(s1ap_eNB_instance_t *instance_p,
return
-
1
;
}
message_p
=
itti_alloc_new_message
(
TASK_S1AP
,
SCTP_NEW_ASSOCIATION_REQ
);
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
;
...
...
@@ -798,36 +752,27 @@ static int s1ap_sctp_req(s1ap_eNB_instance_t *instance_p,
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
)
{
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
)
{
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
{
}
else
{
S1AP_ERROR
(
"Invalid IP Address Format V4(MME):V6
\n
"
);
return
-
1
;
}
}
else
{
}
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
)
{
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
{
}
else
{
S1AP_ERROR
(
"Invalid IP Address Format V6(MME):V4
\n
"
);
return
-
1
;
}
...
...
openair3/S1AP/s1ap_eNB_handlers.c
View file @
969425f6
...
...
@@ -290,8 +290,7 @@ 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
)
{
if
(
ie
==
NULL
)
{
return
-
1
;
}
...
...
@@ -302,19 +301,16 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id,
S1AP_ERROR
(
"Received s1 setup failure for MME... please check your parameters
\n
"
);
}
if
(
mme_desc_p
->
timer_id
!=
S1AP_TIMERID_INIT
)
{
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
)
)
{
(
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
)
{
if
(
ie
!=
NULL
)
{
switch
(
ie
->
value
.
choice
.
TimeToWait
)
{
case
S1AP_TimeToWait_v1s
:
...
...
@@ -339,9 +335,7 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id,
interval_sec
=
instance_p
->
s1_setupreq_wait_timer
;
break
;
}
}
else
{
}
else
{
interval_sec
=
instance_p
->
s1_setupreq_wait_timer
;
}
...
...
@@ -350,15 +344,11 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id,
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
)
{
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
{
}
else
{
S1AP_ERROR
(
"Retransmission count exceeded of S1 SETUP REQUEST : MME=%d
\n
"
,
mme_desc_p
->
cnx_id
);
}
return
0
;
...
...
@@ -391,16 +381,14 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id,
/* 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
)
{
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
)
{
if
(
ie
==
NULL
)
{
return
-
1
;
}
...
...
@@ -463,12 +451,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
);
...
...
@@ -486,7 +468,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
;
}
...
...
@@ -819,8 +800,7 @@ int s1ap_eNB_handle_error_indication(uint32_t assoc_id,
S1AP_ProtocolIE_ID_id_CriticalityDiagnostics
,
false
);
if
(
ie
)
{
if
(
ie
->
value
.
choice
.
CriticalityDiagnostics
.
procedureCode
)
{
if
(
ie
->
value
.
choice
.
CriticalityDiagnostics
.
procedureCode
)
{
S1AP_WARN
(
"Received S1 Error indication CriticalityDiagnostics procedureCode = %ld
\n
"
,
*
ie
->
value
.
choice
.
CriticalityDiagnostics
.
procedureCode
);
}
// TODO continue
...
...
@@ -1023,8 +1003,7 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id,
S1AP_FIND_PROTOCOLIE_BY_ID
(
S1AP_UEContextReleaseCommand_IEs_t
,
ie
,
container
,
S1AP_ProtocolIE_ID_id_Cause
,
true
);
if
(
ie
==
NULL
)
{
if
(
ie
==
NULL
)
{
S1AP_ERROR
(
"Mandatory Element Nothing : UEContextReleaseCommand(Cause)
\n
"
);
return
-
1
;
}
...
...
@@ -1076,9 +1055,6 @@ 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
)
...
...
@@ -1087,7 +1063,7 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id,
{
enb_ue_s1ap_id
=
ue_desc_p
->
eNB_ue_s1ap_id
;
message_p
=
itti_alloc_new_message
(
TASK_S1AP
,
S1AP_UE_CONTEXT_RELEASE_COMMAND
);
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
);
...
...
openair3/S1AP/s1ap_eNB_management_procedures.c
View file @
969425f6
...
...
@@ -102,8 +102,7 @@ struct s1ap_eNB_mme_data_s *s1ap_eNB_get_MME(
temp
.
assoc_id
=
assoc_id
;
temp
.
cnx_id
=
cnx_id
;
if
(
cnx_id
!=
0
)
{
if
(
cnx_id
!=
0
)
{
if
(
instance_p
==
NULL
)
{
STAILQ_FOREACH
(
instance_p
,
&
s1ap_eNB_internal_data
.
s1ap_eNB_instances_head
,
s1ap_eNB_entries
)
{
...
...
@@ -116,29 +115,19 @@ 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
)
{
}
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
)
{
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
)
{
}
else
{
RB_FOREACH
(
mme_p
,
s1ap_mme_map
,
&
instance_p
->
s1ap_mme_head
)
{
if
(
mme_p
->
assoc_id
==
assoc_id
)
{
return
mme_p
;
}
}
...
...
openair3/S1AP/s1ap_eNB_nas_procedures.c
View file @
969425f6
...
...
@@ -139,8 +139,7 @@ int s1ap_eNB_handle_nas_first_req(
*/
mme_desc_p
=
s1ap_eNB_nnsf_select_mme
(
instance_p
,
s1ap_nas_first_req_p
->
establishment_cause
,
s1ap_nas_first_req_p
->
selected_plmn_identity
);
s1ap_nas_first_req_p
->
establishment_cause
);
if
(
mme_desc_p
)
{
S1AP_INFO
(
"[eNB %ld] Chose MME '%s' (assoc_id %d) through highest relative capacity
\n
"
,
...
...
@@ -233,9 +232,9 @@ int s1ap_eNB_handle_nas_first_req(
MACRO_ENB_ID_TO_CELL_IDENTITY
(
instance_p
->
eNB_id
,
0
,
// Cell ID
&
ie
->
value
.
choice
.
EUTRAN_CGI
.
cell_ID
);
MCC_MNC_TO_TBCD
(
instance_p
->
mcc
[
mme_desc_p
->
broadcast_plmn_index
[
0
]
],
instance_p
->
mnc
[
mme_desc_p
->
broadcast_plmn_index
[
0
]
],
instance_p
->
mnc_digit_length
[
mme_desc_p
->
broadcast_plmn_index
[
0
]
],
MCC_MNC_TO_TBCD
(
instance_p
->
mcc
[
ue_desc_p
->
selected_plmn_identity
],
instance_p
->
mnc
[
ue_desc_p
->
selected_plmn_identity
],
instance_p
->
mnc_digit_length
[
ue_desc_p
->
selected_plmn_identity
],
&
ie
->
value
.
choice
.
EUTRAN_CGI
.
pLMNidentity
);
ASN_SEQUENCE_ADD
(
&
out
->
protocolIEs
.
list
,
ie
);
/* Set the establishment cause according to those provided by RRC */
...
...
openair3/S1AP/s1ap_eNB_nnsf.c
View file @
969425f6
...
...
@@ -36,17 +36,18 @@
#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
,
uint32_t
plmn_id
)
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
;
typedef
struct
MME_nnsf_inf
{
struct
s1ap_eNB_mme_data_s
*
mme_p
;
uint64_t
weight
;
}
MME_nnsf_inf_t
;
uint16_t
capacity_sum
=
0
;
MME_nnsf_inf_t
mme_inf
[
10
];
...
...
@@ -57,7 +58,6 @@ s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p,
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
;
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,
...
...
@@ -83,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.
*/
...
...
@@ -92,58 +93,27 @@ s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p,
continue
;
}
}
gummei_p
=
mme_data_p
->
served_gummei
.
stqh_first
;
if
(
gummei_p
!=
NULL
)
{
struct
plmn_identity_s
*
served_plmns_p
=
NULL
;
served_plmns_p
=
gummei_p
->
served_plmns
.
stqh_first
;
if
(
served_plmns_p
!=
0
)
for
(
cnt
=
0
;
cnt
<
8
;
cnt
++
)
{
if
(
(
served_plmns_p
->
mcc
==
instance_p
->
mcc
[
plmn_id
])
&&
(
served_plmns_p
->
mnc
==
instance_p
->
mnc
[
plmn_id
])
)
{
mme_inf
[
nb_mme
].
mme_p
=
mme_data_p
;
nb_mme
++
;
break
;
}
if
(
served_plmns_p
->
next
.
stqe_next
==
0
)
{
break
;
}
served_plmns_p
=
served_plmns_p
->
next
.
stqe_next
;
}
}
}
if
(
nb_mme
!=
0
)
{
for
(
cnt
=
0
;
cnt
<
nb_mme
;
cnt
++
)
{
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
)
{
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
{
}
else
{
mme_highest_capacity_p
=
NULL
;
}
if
(
mme_highest_capacity_p
!=
NULL
)
{
if
(
mme_highest_capacity_p
!=
NULL
)
{
mme_highest_capacity_p
->
nb_calls
++
;
}
return
mme_highest_capacity_p
;
}
...
...
@@ -154,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
;
...
...
@@ -198,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
;
}
}
...
...
@@ -206,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_nnsf.h
View file @
969425f6
...
...
@@ -24,8 +24,7 @@
struct
s1ap_eNB_mme_data_s
*
s1ap_eNB_nnsf_select_mme
(
s1ap_eNB_instance_t
*
instance_p
,
rrc_establishment_cause_t
cause
,
uint32_t
plmn_id
);
rrc_establishment_cause_t
cause
);
struct
s1ap_eNB_mme_data_s
*
s1ap_eNB_nnsf_select_mme_by_plmn_id
(
s1ap_eNB_instance_t
*
instance_p
,
...
...
openair3/S1AP/s1ap_eNB_timer.c
View file @
969425f6
...
...
@@ -36,91 +36,6 @@
#include "queue.h"
#include "s1ap_common.h"
struct
s1ap_timer_elm_s
{
task_id_t
task_id
;
///< Task ID which has requested the timer
int32_t
instance
;
///< Instance of the task which has requested the timer
uint32_t
timer_kind
;
///< Instance of the task which has requested the timer
timer_t
timer
;
///< Unique timer id
timer_type_t
type
;
///< Timer type
void
*
timer_arg
;
///< Optional argument that will be passed when timer expires
STAILQ_ENTRY
(
s1ap_timer_elm_s
)
entries
;
///< Pointer to next element
};
typedef
struct
timer_desc_s
{
STAILQ_HEAD
(
timer_list_head
,
s1ap_timer_elm_s
)
timer_queue
;
pthread_mutex_t
timer_list_mutex
;
struct
timespec
timeout
;
}
timer_desc_t
;
static
timer_desc_t
timer_desc
;
#define TIMER_SEARCH(vAR, tIMERfIELD, tIMERvALUE, tIMERqUEUE) \
do { \
STAILQ_FOREACH(vAR, tIMERqUEUE, entries) { \
if (((vAR)->tIMERfIELD == tIMERvALUE)) \
break; \
} \
} while(0)
int
s1ap_timer_timeout
(
sigval_t
info
)
{
struct
s1ap_timer_elm_s
*
timer_p
;
MessageDef
*
message_p
;
s1ap_timer_has_expired_t
*
timer_expired_p
;
task_id_t
task_id
;
int32_t
instance
;
uint32_t
timer_kind
;
timer_kind
=
info
.
sival_int
;
if
(
pthread_mutex_lock
(
&
timer_desc
.
timer_list_mutex
)
!=
0
)
{
S1AP_ERROR
(
"Failed to mutex lock timeout=%x
\n
"
,
timer_kind
);
return
-
1
;
}
TIMER_SEARCH
(
timer_p
,
timer_kind
,
timer_kind
,
&
timer_desc
.
timer_queue
);
if
(
pthread_mutex_unlock
(
&
timer_desc
.
timer_list_mutex
)
!=
0
)
{
S1AP_ERROR
(
"Failed to mutex unlock timeout=0x%x
\n
"
,
timer_kind
);
}
if
(
timer_p
==
NULL
)
{
S1AP_ERROR
(
"Didn't find timer 0x%x in list
\n
"
,
timer_kind
);
return
-
1
;
}
S1AP_DEBUG
(
"Timer kind 0x%x has expired
\n
"
,
timer_kind
);
task_id
=
timer_p
->
task_id
;
instance
=
timer_p
->
instance
;
message_p
=
itti_alloc_new_message
(
TASK_UNKNOWN
,
TIMER_HAS_EXPIRED
);
timer_expired_p
=
(
s1ap_timer_has_expired_t
*
)(
&
message_p
->
ittiMsg
.
timer_has_expired
);
timer_expired_p
->
timer_id
=
(
long
)
timer_p
->
timer
;
timer_expired_p
->
timer_kind
=
timer_p
->
timer_kind
;
timer_expired_p
->
arg
=
timer_p
->
timer_arg
;
/* Timer is a one shot timer, remove it */
if
(
(
int
)
timer_p
->
type
==
(
int
)
S1AP_TIMER_ONE_SHOT
)
{
if
(
s1ap_timer_remove
((
long
)
timer_p
->
timer
)
!=
0
)
{
S1AP_DEBUG
(
"Failed to delete timer 0x%lx
\n
"
,
(
long
)
timer_p
->
timer
);
}
}
/* Notify task of timer expiry */
if
(
itti_send_msg_to_task
(
task_id
,
instance
,
message_p
)
<
0
)
{
S1AP_ERROR
(
"Failed to send msg TIMER_HAS_EXPIRED to task %u
\n
"
,
task_id
);
free
(
message_p
);
return
-
1
;
}
return
0
;
}
int
s1ap_timer_setup
(
uint32_t
interval_sec
,
...
...
@@ -132,169 +47,24 @@ int s1ap_timer_setup(
void
*
timer_arg
,
long
*
timer_id
)
{
struct
sigevent
evp
;
struct
itimerspec
its
;
struct
s1ap_timer_elm_s
*
timer_p
;
timer_t
timer
;
if
(
timer_id
==
NULL
)
{
S1AP_ERROR
(
"Invalid timer_id
\n
"
);
return
-
1
;
}
if
(
(
int
)
type
>=
(
int
)
S1AP_TIMER_TYPE_MAX
)
{
S1AP_ERROR
(
"Invalid timer type (%d/%d)!
\n
"
,
type
,
TIMER_TYPE_MAX
);
return
-
1
;
}
if
(
*
timer_id
!=
S1AP_TIMERID_INIT
)
{
if
(
s1ap_timer_remove
(
*
timer_id
)
!=
0
)
{
S1AP_ERROR
(
"Failed to delete timer when the timer start 0x%lx
\n
"
,
*
timer_id
);
}
}
/* Allocate new timer list element */
timer_p
=
malloc
(
sizeof
(
struct
s1ap_timer_elm_s
));
if
(
timer_p
==
NULL
)
{
S1AP_ERROR
(
"Failed to create new timer element
\n
"
);
return
-
1
;
}
memset
(
&
timer
,
0
,
sizeof
(
timer_t
));
memset
(
&
evp
,
0
,
sizeof
(
evp
));
timer_p
->
task_id
=
task_id
;
timer_p
->
instance
=
instance
;
timer_p
->
timer_kind
=
timer_kind
;
timer_p
->
type
=
type
;
timer_p
->
timer_arg
=
timer_arg
;
evp
.
sigev_notify
=
(
int
)
SIGEV_THREAD
;
evp
.
sigev_notify_function
=
(
void
*
)
s1ap_timer_timeout
;
evp
.
sigev_signo
=
SIGRTMIN
;
evp
.
sigev_notify_attributes
=
NULL
;
evp
.
sigev_value
.
sival_int
=
timer_kind
;
/* At the timer creation, the timer structure will be filled in with timer_id,
* which is unique for this process. This id is allocated by kernel and the
* value might be used to distinguish timers.
*/
if
(
timer_create
(
CLOCK_REALTIME
,
&
evp
,
&
timer
)
<
0
)
{
S1AP_ERROR
(
"Failed to create timer: (%s:%d)
\n
"
,
strerror
(
errno
),
errno
);
free
(
timer_p
);
return
-
1
;
}
/* Fill in the first expiration value. */
its
.
it_value
.
tv_sec
=
interval_sec
;
its
.
it_value
.
tv_nsec
=
interval_us
*
1000
;
if
(
(
int
)
type
==
(
int
)
S1AP_TIMER_PERIODIC
)
{
/* Asked for periodic timer. We set the interval time */
its
.
it_interval
.
tv_sec
=
interval_sec
;
its
.
it_interval
.
tv_nsec
=
interval_us
*
1000
;
}
else
{
/* Asked for one-shot timer. Do not set the interval field */
its
.
it_interval
.
tv_sec
=
0
;
its
.
it_interval
.
tv_nsec
=
0
;
}
if
(
timer_settime
(
timer
,
0
,
&
its
,
NULL
)
)
{
S1AP_ERROR
(
"Failed to Settimer: (%s:%d)
\n
"
,
strerror
(
errno
),
errno
);
free
(
timer_p
);
return
-
1
;
}
/* Simply set the timer_id argument. so it can be used by caller */
*
timer_id
=
(
long
)
timer
;
timer_p
->
timer
=
timer
;
/* Lock the queue and insert the timer at the tail */
if
(
pthread_mutex_lock
(
&
timer_desc
.
timer_list_mutex
)
!=
0
)
{
S1AP_ERROR
(
"Failed to mutex lock
\n
"
);
if
(
timer_delete
(
timer_p
->
timer
)
<
0
)
{
S1AP_ERROR
(
"Failed to delete timer 0x%lx
\n
"
,
(
long
)
timer_p
->
timer
);
}
free
(
timer_p
);
timer_p
=
NULL
;
return
-
1
;
}
STAILQ_INSERT_TAIL
(
&
timer_desc
.
timer_queue
,
timer_p
,
entries
);
if
(
pthread_mutex_unlock
(
&
timer_desc
.
timer_list_mutex
)
!=
0
)
{
S1AP_ERROR
(
"Failed to mutex unlock
\n
"
);
}
return
0
;
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
rc
=
0
;
struct
s1ap_timer_elm_s
*
timer_p
;
if
(
pthread_mutex_lock
(
&
timer_desc
.
timer_list_mutex
)
!=
0
)
{
S1AP_ERROR
(
"Failed to mutex lock
\n
"
);
if
(
timer_delete
((
timer_t
)
timer_id
)
<
0
)
{
S1AP_ERROR
(
"Failed to delete timer 0x%lx
\n
"
,
(
long
)
timer_id
);
}
return
-
1
;
}
TIMER_SEARCH
(
timer_p
,
timer
,
((
timer_t
)
timer_id
),
&
timer_desc
.
timer_queue
);
/* We didn't find the timer in list */
if
(
timer_p
==
NULL
)
{
S1AP_ERROR
(
"Didn't find timer 0x%lx in list
\n
"
,
timer_id
);
if
(
pthread_mutex_unlock
(
&
timer_desc
.
timer_list_mutex
)
!=
0
)
{
S1AP_ERROR
(
"Failed to mutex unlock
\n
"
);
}
return
-
1
;
}
timer_delete
(
timer_p
->
timer
);
STAILQ_REMOVE
(
&
timer_desc
.
timer_queue
,
timer_p
,
s1ap_timer_elm_s
,
entries
);
if
(
pthread_mutex_unlock
(
&
timer_desc
.
timer_list_mutex
)
!=
0
)
{
S1AP_ERROR
(
"Failed to mutex unlock
\n
"
);
}
free
(
timer_p
);
timer_p
=
NULL
;
return
rc
;
int
ret
;
ret
=
timer_remove
(
timer_id
);
return
ret
;
}
int
s1ap_timer_init
(
void
)
{
memset
(
&
timer_desc
,
0
,
sizeof
(
timer_desc_t
));
STAILQ_INIT
(
&
timer_desc
.
timer_queue
);
pthread_mutex_init
(
&
timer_desc
.
timer_list_mutex
,
NULL
);
return
0
;
}
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