1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 2007-2016. All Rights Reserved.
5%%
6%% Licensed under the Apache License, Version 2.0 (the "License");
7%% you may not use this file except in compliance with the License.
8%% You may obtain a copy of the License at
9%%
10%%     http://www.apache.org/licenses/LICENSE-2.0
11%%
12%% Unless required by applicable law or agreed to in writing, software
13%% distributed under the License is distributed on an "AS IS" BASIS,
14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15%% See the License for the specific language governing permissions and
16%% limitations under the License.
17%%
18%% %CopyrightEnd%
19%%
20
21%%
22%%----------------------------------------------------------------------
23%% Purpose: Timer handling
24%%----------------------------------------------------------------------
25
26-module(megaco_timer).
27
28%% Application internal export
29-export([
30	 init/1,
31	 restart/1,
32	 verify/1
33        ]).
34
35
36-include_lib("megaco/include/megaco.hrl").
37
38
39%%-----------------------------------------------------------------
40
41%% init(Timer) -> {TimeoutTime, NewTimer}
42%% Timer       = megaco_timer()
43%% NewTimer    = megaco_timer()
44%% TimeoutTime = infinity | integer()
45%%
46init(SingleWaitFor) when SingleWaitFor =:= infinity ->
47    {SingleWaitFor, timeout};
48init(SingleWaitFor) when is_integer(SingleWaitFor) and (SingleWaitFor >= 0) ->
49    {SingleWaitFor, timeout};
50init(Timer) when is_record(Timer, megaco_incr_timer) ->
51    return_incr(Timer).
52
53
54%% Returns {WaitFor, NewTimer} | {WaitFor, timeout}
55restart(#megaco_incr_timer{wait_for    = Old,
56			   factor      = Factor,
57			   incr        = Incr,
58			   max_retries = MaxRetries} = Timer) ->
59    New    = wait_for(Old, Factor, Incr),
60    Max    = decr(MaxRetries),
61    Timer2 = Timer#megaco_incr_timer{wait_for    = New,
62				     max_retries = Max},
63    return_incr(Timer2);
64restart({Timer, timeout}) when is_record(Timer, megaco_incr_timer) ->
65    restart(Timer).
66
67wait_for(Old, Factor, Incr) ->
68    New = (Old * Factor) + Incr,
69    if
70	New < 0 ->
71	    0;
72	true ->
73	    New
74    end.
75
76verify(#megaco_incr_timer{wait_for    = WaitFor,
77			  factor      = Factor,
78			  incr        = Incr,
79			  max_retries = MaxRetries}) ->
80    (megaco_config_misc:verify_strict_uint(WaitFor) and
81     megaco_config_misc:verify_strict_uint(Factor)  and
82     megaco_config_misc:verify_strict_int(Incr)     and
83     verify_max_retries(MaxRetries));
84verify(Timer) ->
85    megaco_config_misc:verify_uint(Timer).
86
87verify_max_retries(infinity_restartable) ->
88    true;
89verify_max_retries(Val) ->
90    megaco_config_misc:verify_uint(Val).
91
92
93%%-----------------------------------------------------------------
94
95
96return_incr(#megaco_incr_timer{wait_for    = WaitFor,
97			       max_retries = infinity} = Timer) ->
98    {WaitFor, Timer};
99
100return_incr(#megaco_incr_timer{wait_for    = WaitFor,
101			       max_retries = infinity_restartable} = Timer) ->
102    {WaitFor, {Timer, timeout}};
103
104return_incr(#megaco_incr_timer{wait_for    = WaitFor,
105			       max_retries = Int} = Timer)
106  when is_integer(Int) and (Int > 0) ->
107    {WaitFor, Timer};
108
109return_incr(#megaco_incr_timer{wait_for    = WaitFor,
110			       max_retries = 0} = _Timer) ->
111    {WaitFor, timeout}.
112
113
114decr(infinity = V)             -> V;
115decr(infinity_restartable = V) -> V;
116decr(Int) when is_integer(Int) -> Int - 1.
117
118
119