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
969425f6
Commit
969425f6
authored
3 years ago
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
Expand all
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
This diff is collapsed.
Click to expand it.
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
);
...
...
This diff is collapsed.
Click to expand it.
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
;
}
}
...
...
This diff is collapsed.
Click to expand it.
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 */
...
...
This diff is collapsed.
Click to expand it.
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
;
}
...
...
This diff is collapsed.
Click to expand it.
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
,
...
...
This diff is collapsed.
Click to expand it.
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
;
}
This diff is collapsed.
Click to expand it.
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