1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 2019-2019. 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: Megaco user behaviour module
24%%
25%% This callback functions are the default! Its possible for the user to
26%% provide a arbitrary number of "extra" arguments via the user_args
27%% config option.
28%% So, for instance, the handle_connect/2 could instead become
29%% handle_connect/4 if the user sets the user_args option to [foo, bar].
30%% This means that its impossible to define a proper behaviour.
31%% So what we do here is to define a behaviour with the "default interface"
32%% (the user_args option has the [] as the default value) and set them
33%% all to be optional!
34%%-------------------------------------------------------------------------
35
36-module(megaco_user).
37
38-export_type([
39              receive_handle/0,
40              conn_handle/0,
41              megaco_timer/0
42             ]).
43
44-include_lib("megaco/include/megaco.hrl").
45%% -include_lib("megaco/include/megaco_message_v1.hrl").
46
47-type receive_handle() :: #megaco_receive_handle{}.
48-type conn_handle()    :: #megaco_conn_handle{}.
49-type megaco_timer()   :: infinity | non_neg_integer() | #megaco_incr_timer{}.
50
51-callback handle_connect(ConnHandle, ProtocolVersion) ->
52    ok | error | {error, ErrorDescr} when
53      ConnHandle      :: conn_handle(),
54      ProtocolVersion :: megaco_encoder:protocol_version(),
55      ErrorDescr      :: megaco_encoder:error_desc().
56-callback handle_connect(ConnHandle, ProtocolVersion, Extra) ->
57    ok | error | {error, ErrorDescr} when
58      ConnHandle      :: conn_handle(),
59      ProtocolVersion :: megaco_encoder:protocol_version(),
60      Extra           :: term(),
61      ErrorDescr      :: megaco_encoder:error_desc().
62
63-callback handle_disconnect(ConnHandle, ProtocolVersion, Reason) ->
64    megaco:void() when
65      ConnHandle      :: conn_handle(),
66      ProtocolVersion :: megaco_encoder:protocol_version(),
67      Reason          :: term().
68
69-callback handle_syntax_error(ReceiveHandle, ProtocolVersion, DefaultED) ->
70    reply | {reply, ED} | no_reply | {no_reply, ED} when
71      ReceiveHandle   :: receive_handle(),
72      ProtocolVersion :: megaco_encoder:protocol_version(),
73      DefaultED       :: megaco_encoder:error_desc(),
74      ED              :: megaco_encoder:error_desc().
75-callback handle_syntax_error(ReceiveHandle, ProtocolVersion, DefaultED, Extra) ->
76    reply | {reply, ED} | no_reply | {no_reply, ED} when
77      ReceiveHandle   :: receive_handle(),
78      ProtocolVersion :: megaco_encoder:protocol_version(),
79      DefaultED       :: megaco_encoder:error_desc(),
80      ED              :: megaco_encoder:error_desc(),
81      Extra           :: term().
82
83-callback handle_message_error(ConnHandle, ProtocolVersion, ErrorDescr) ->
84    megaco:void() when
85      ConnHandle      :: conn_handle(),
86      ProtocolVersion :: megaco_encoder:protocol_version(),
87      ErrorDescr      :: megaco_encoder:error_desc().
88-callback handle_message_error(ConnHandle, ProtocolVersion, ErrorDescr, Extra) ->
89    megaco:void() when
90      ConnHandle      :: conn_handle(),
91      ProtocolVersion :: megaco_encoder:protocol_version(),
92      ErrorDescr      :: megaco_encoder:error_desc(),
93      Extra           :: term().
94
95-callback handle_trans_request(ConnHandle, ProtocolVersion, ActionRequests) ->
96    Pending | Reply | ignore_trans_request when
97      ConnHandle      :: conn_handle(),
98      ProtocolVersion :: megaco_encoder:protocol_version(),
99      ActionRequests  :: [megaco_encoder:action_request()],
100      Pending         :: {pending, ReqData},
101      ReqData         :: term(),
102      Reply           :: {AckAction, ActualReply} |
103                         {AckAction, ActualReply, SendOptions},
104      AckAction       :: discard_ack |
105                         {handle_ack,         AckData} |
106                         {handle_pending_ack, AckData} |
107                         {handle_sloppy_ack,  AckData},
108      ActualReply     :: [megaco_encoder:action_reply()] |
109                         megaco_encoder:error_desc(),
110      AckData         :: term(),
111      SendOptions     :: [SendOption],
112      SendOption      :: {reply_timer,      megaco_timer()} |
113                         {send_handle,      term()} |
114                         {protocol_version, integer()}.
115-callback handle_trans_request(ConnHandle,
116                               ProtocolVersion,
117                               ActionRequests,
118                               Extra) ->
119    Pending | Reply | ignore_trans_request when
120      ConnHandle      :: conn_handle(),
121      ProtocolVersion :: megaco_encoder:protocol_version(),
122      ActionRequests  :: [megaco_encoder:action_request()],
123      Extra           :: term(),
124      Pending         :: {pending, ReqData},
125      ReqData         :: term(),
126      Reply           :: {AckAction, ActualReply} |
127                         {AckAction, ActualReply, SendOptions},
128      AckAction       :: discard_ack |
129                         {handle_ack,         AckData} |
130                         {handle_pending_ack, AckData} |
131                         {handle_sloppy_ack,  AckData},
132      ActualReply     :: [megaco_encoder:action_reply()] |
133                         megaco_encoder:error_desc(),
134      AckData         :: term(),
135      SendOptions     :: [SendOption],
136      SendOption      :: {reply_timer,      megaco_timer()} |
137                         {send_handle,      term()} |
138                         {protocol_version, integer()}.
139
140-callback handle_trans_long_request(ConnHandle, ProtocolVersion, ReqData) ->
141    Reply when
142      ConnHandle      :: conn_handle(),
143      ProtocolVersion :: megaco_encoder:protocol_version(),
144      ReqData         :: term(),
145      Reply           :: {AckAction, ActualReply} |
146                         {AckAction, ActualReply, SendOptions},
147      AckAction       :: discard_ack |
148                         {handle_ack, AckData} |
149                         {handle_sloppy_ack, AckData},
150      ActualReply     :: [megaco_encoder:action_reply()] |
151                         megaco_encoder:error_desc(),
152      AckData         :: term(),
153      SendOptions     :: [SendOption],
154      SendOption      :: {reply_timer, megaco_timer()} |
155                         {send_handle, term()} |
156                         {protocol_version, megaco_encoder:protocol_version()}.
157-callback handle_trans_long_request(ConnHandle, ProtocolVersion, ReqData, Extra) ->
158    Reply when
159      ConnHandle      :: conn_handle(),
160      ProtocolVersion :: megaco_encoder:protocol_version(),
161      ReqData         :: term(),
162      Extra           :: term(),
163      Reply           :: {AckAction, ActualReply} |
164                         {AckAction, ActualReply, SendOptions},
165      AckAction       :: discard_ack |
166                         {handle_ack, AckData} |
167                         {handle_sloppy_ack, AckData},
168      ActualReply     :: [megaco_encoder:action_reply()] |
169                         megaco_encoder:error_desc(),
170      AckData         :: term(),
171      SendOptions     :: [SendOption],
172      SendOption      :: {reply_timer, megaco_timer()} |
173                         {send_handle, term()} |
174                         {protocol_version, megaco_encoder:protocol_version()}.
175
176-callback handle_trans_reply(ConnHandle,
177                             ProtocolVersion,
178                             UserReply,
179                             ReplyData) ->
180    ok when
181      ConnHandle           :: conn_handle(),
182      ProtocolVersion      :: megaco_encoder:protocol_version(),
183      UserReply            :: Success | Failure,
184      ReplyData            :: term(),
185      Success              :: {ok, Result},
186      Result               :: TransactionResult | SegmentResult,
187      TransactionResult    :: [megaco_encoder:action_reply()],
188      SegmentResult        :: {megaco_encoder:segment_no(),
189                               LastSegment,
190                               [megaco_encoder:action_reply()]},
191      Failure              :: {error, Reason} |
192                              {error, ReplyNo, Reason},
193      Reason               :: TransactionReason |
194                              SegmentReason |
195                              UserCancelReason |
196                              SendReason |
197                              OtherReason,
198      TransactionReason    :: megaco_encoder:error_desc(),
199      SegmentReason        :: {megaco_encoder:segment_no(),
200                               LastSegment,
201                               megaco_encoder:error_desc()},
202      OtherReason          :: timeout |
203                              {segment_timeout, MissingSegments} |
204                              exceeded_recv_pending_limit | term(),
205      LastSegment          :: boolean(),
206      MissingSegments      :: [megaco_encoder:segment_no()],
207      UserCancelReason     :: {user_cancel, ReasonForUserCancel},
208      ReasonForUserCancel  :: term(),
209      SendReason           :: SendCancelledReason | SendFailedReason,
210      SendCancelledReason  :: {send_message_cancelled,
211                               ReasonForSendCancel},
212      ReasonForSendCancel  :: term(),
213      SendFailedReason     :: {send_message_failed, ReasonForSendFailure},
214      ReasonForSendFailure :: term(),
215      ReplyNo              :: pos_integer().
216-callback handle_trans_reply(ConnHandle,
217                             ProtocolVersion,
218                             UserReply,
219                             ReplyData,
220                             Extra) ->
221    ok when
222      ConnHandle           :: conn_handle(),
223      ProtocolVersion      :: megaco_encoder:protocol_version(),
224      UserReply            :: Success | Failure,
225      ReplyData            :: term(),
226      Extra                :: term(),
227      Success              :: {ok, Result},
228      Result               :: TransactionResult | SegmentResult,
229      TransactionResult    :: [megaco_encoder:action_reply()],
230      SegmentResult        :: {megaco_encoder:segment_no(),
231                               LastSegment,
232                               [megaco_encoder:action_reply()]},
233      Failure              :: {error, Reason} |
234                              {error, ReplyNo, Reason},
235      Reason               :: TransactionReason |
236                              SegmentReason |
237                              UserCancelReason |
238                              SendReason |
239                              OtherReason,
240      TransactionReason    :: megaco_encoder:error_desc(),
241      SegmentReason        :: {megaco_encoder:segment_no(),
242                               LastSegment,
243                               megaco_encoder:error_desc()},
244      OtherReason          :: timeout |
245                              {segment_timeout, MissingSegments} |
246                              exceeded_recv_pending_limit | term(),
247      LastSegment          :: boolean(),
248      MissingSegments      :: [megaco_encoder:segment_no()],
249      UserCancelReason     :: {user_cancel, ReasonForUserCancel},
250      ReasonForUserCancel  :: term(),
251      SendReason           :: SendCancelledReason | SendFailedReason,
252      SendCancelledReason  :: {send_message_cancelled,
253                               ReasonForSendCancel},
254      ReasonForSendCancel  :: term(),
255      SendFailedReason     :: {send_message_failed, ReasonForSendFailure},
256      ReasonForSendFailure :: term(),
257      ReplyNo              :: pos_integer().
258
259
260-callback handle_trans_ack(ConnHandle,
261                           ProtocolVersion,
262                           AckStatus,
263                           AckData) ->
264    ok when
265      ConnHandle           :: conn_handle(),
266      ProtocolVersion      :: megaco_encoder:protocol_version(),
267      AckStatus            :: ok | {error, Reason},
268      AckData              :: term(),
269      Reason               :: UserCancelReason | SendReason | OtherReason,
270      UserCancelReason     :: {user_cancel, ReasonForUserCancel},
271      ReasonForUserCancel  :: term(),
272      SendReason           :: SendCancelledReason | SendFailedReason,
273      SendCancelledReason  :: {send_message_cancelled, ReasonForSendCancel},
274      ReasonForSendCancel  :: term(),
275      SendFailedReason     :: {send_message_failed, ReasonForSendFailure},
276      ReasonForSendFailure :: term(),
277      OtherReason          :: term().
278-callback handle_trans_ack(ConnHandle,
279                           ProtocolVersion,
280                           AckStatus,
281                           AckData,
282                           Extra) ->
283    ok when
284      ConnHandle           :: conn_handle(),
285      ProtocolVersion      :: megaco_encoder:protocol_version(),
286      AckStatus            :: ok | {error, Reason},
287      AckData              :: term(),
288      Extra                :: term(),
289      Reason               :: UserCancelReason | SendReason | OtherReason,
290      UserCancelReason     :: {user_cancel, ReasonForUserCancel},
291      ReasonForUserCancel  :: term(),
292      SendReason           :: SendCancelledReason | SendFailedReason,
293      SendCancelledReason  :: {send_message_cancelled, ReasonForSendCancel},
294      ReasonForSendCancel  :: term(),
295      SendFailedReason     :: {send_message_failed, ReasonForSendFailure},
296      ReasonForSendFailure :: term(),
297      OtherReason          :: term().
298
299-callback handle_unexpected_trans(ConnHandle, ProtocolVersion, Trans) ->
300    ok when
301      ConnHandle      :: conn_handle(),
302      ProtocolVersion :: megaco_encoder:protocol_version(),
303      Trans           :: megaco_encoder:transaction_pending() |
304                         megaco_encoder:transaction_reply() |
305                         megaco_encoder:transaction_response_ack().
306-callback handle_unexpected_trans(ConnHandle, ProtocolVersion, Trans, Extra) ->
307    ok when
308      ConnHandle      :: conn_handle(),
309      ProtocolVersion :: megaco_encoder:protocol_version(),
310      Trans           :: megaco_encoder:transaction_pending() |
311                         megaco_encoder:transaction_reply() |
312                         megaco_encoder:transaction_response_ack(),
313      Extra           :: term().
314
315-callback handle_trans_request_abort(ConnHandle,
316                                     ProtocolVersion,
317                                     TransNo,
318                                     Pid) ->
319    ok when
320      ConnHandle      :: conn_handle(),
321      ProtocolVersion :: megaco_encoder:protocol_version(),
322      TransNo         :: integer(),
323      Pid             :: undefined | pid().
324-callback handle_trans_request_abort(ConnHandle,
325                                     ProtocolVersion,
326                                     TransNo,
327                                     Pid,
328                                     Extra) ->
329    ok when
330      ConnHandle      :: conn_handle(),
331      ProtocolVersion :: megaco_encoder:protocol_version(),
332      TransNo         :: integer(),
333      Pid             :: undefined | pid(),
334      Extra           :: term().
335
336-callback handle_segment_reply(ConnHandle,
337                               ProtocolVersion,
338                               TransNo,
339                               SegNo,
340                               SegCompl) ->
341    ok when
342      ConnHandle      :: conn_handle(),
343      ProtocolVersion :: megaco_encoder:protocol_version(),
344      TransNo         :: integer(),
345      SegNo           :: integer(),
346      SegCompl        :: asn1_NOVALUE | 'NULL'.
347-callback handle_segment_reply(ConnHandle,
348                               ProtocolVersion,
349                               TransNo,
350                               SegNo,
351                               SegCompl,
352                               Extra) ->
353    ok when
354      ConnHandle      :: conn_handle(),
355      ProtocolVersion :: megaco_encoder:protocol_version(),
356      TransNo         :: integer(),
357      SegNo           :: megaco_encoder:segment_no(),
358      SegCompl        :: asn1_NOVALUE | 'NULL',
359      Extra           :: term().
360
361-optional_callbacks(
362   [
363    %% The actual number of arguments to *all* functions,
364    %% depend of the user_args config option.
365    handle_connect/2,
366    handle_connect/3,
367    handle_disconnect/3,
368    handle_syntax_error/3,
369    handle_syntax_error/4,
370    handle_message_error/3,
371    handle_message_error/4,
372    handle_trans_request/3,
373    handle_trans_request/4,
374    handle_trans_long_request/3,
375    handle_trans_long_request/4,
376    handle_trans_reply/4,
377    handle_trans_reply/5,
378    handle_trans_ack/4,
379    handle_trans_ack/5,
380    handle_unexpected_trans/3,
381    handle_unexpected_trans/4,
382    handle_trans_request_abort/4,
383    handle_trans_request_abort/5,
384    handle_segment_reply/5,
385    handle_segment_reply/6
386   ]).
387