1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 1999-2020. 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: Verify the implementation of the ITU-T protocol H.248
24%%----------------------------------------------------------------------
25
26-module(megaco_mess_SUITE).
27
28-export([
29         suite/0, all/0, groups/0,
30	 init_per_suite/1,    end_per_suite/1,
31         init_per_group/2,    end_per_group/2,
32	 init_per_testcase/2, end_per_testcase/2,
33
34	 connect/1,
35
36	 request_and_reply_plain/1,
37	 request_and_no_reply/1,
38	 request_and_reply_pending_ack_no_pending/1,
39	 request_and_reply_pending_ack_one_pending/1,
40	 single_trans_req_and_reply/1,
41	 single_trans_req_and_reply_sendopts/1,
42	 request_and_reply_and_ack/1,
43	 request_and_reply_and_no_ack/1,
44	 request_and_reply_and_late_ack/1,
45	 trans_req_and_reply_and_req/1,
46
47
48	 pending_ack_plain/1,
49	 request_and_pending_and_late_reply/1,
50
51	 dist/1,
52
53
54	 otp_4359/1,
55	 otp_4836/1,
56	 otp_5805/1,
57	 otp_5881/1,
58	 otp_5887/1,
59	 otp_6253/1,
60	 otp_6275/1,
61	 otp_6276/1,
62
63	 otp_6442_resend_request1/1,
64	 otp_6442_resend_request2/1,
65	 otp_6442_resend_reply1/1,
66	 otp_6442_resend_reply2/1,
67
68	 otp_6865_request_and_reply_plain_extra1/1,
69	 otp_6865_request_and_reply_plain_extra2/1,
70	 otp_7189/1,
71	 otp_7259/1,
72	 otp_7713/1,
73
74	 otp_8183_request1/1,
75	 otp_8212/1
76	]).
77
78%% -behaviour(megaco_user).
79-export([
80	 handle_connect/3,
81	 handle_disconnect/4,
82	 handle_syntax_error/4,
83	 handle_message_error/4,
84	 handle_trans_request/4,
85	 handle_trans_long_request/4,
86	 handle_trans_reply/5,
87	 handle_trans_ack/5,
88	 handle_unexpected_trans/4,
89	 handle_trans_request_abort/5
90	]).
91
92%% -behaviour(megaco_transport).
93-export([
94	 send_message/2,
95	 unblock/1
96	]).
97
98-ifdef(megaco_hipe_special).
99-export([
100	 %% Case: request_and_reply_pending_ack_no_pending
101	 rarpanp_mgc_verify_handle_connect/1,
102	 rarpanp_mgc_verify_service_change_req/2,
103	 rarpanp_mgc_verify_notify_request/1,
104	 rarpanp_mgc_verify_handle_disconnect/1,
105	 rarpanp_mg_verify_service_change_rep_msg/1,
106	 rarpanp_mg_verify_notify_rep_msg/3,
107
108	 %% Case: request_and_reply_pending_ack_one_pending
109	 rarpaop_mgc_verify_handle_connect/1,
110	 rarpaop_mgc_verify_service_change_req/2,
111	 rarpaop_mgc_verify_notify_request/1,
112	 rarpaop_mgc_verify_reply_ack/1,
113	 rarpaop_mgc_verify_handle_disconnect/1,
114	 rarpaop_mg_verify_service_change_rep_msg/1,
115	 rarpaop_mg_verify_pending_msg/2,
116	 rarpaop_mg_verify_notify_rep_msg/3,
117
118	 %% Case: single_trans_req_and_reply
119	 strar_mgc_verify_handle_connect/1,
120	 strar_mgc_verify_service_change_req/2,
121	 strar_mgc_verify_notify_request/1,
122	 strar_mgc_verify_handle_disconnect/1,
123	 strar_mg_verify_handle_connect/1,
124	 strar_mg_verify_service_change_reply/1,
125	 strar_mg_verify_notify_reply/1,
126
127	 %% Case: single_trans_req_and_reply_sendopts
128	 straro_mgc_verify_handle_connect/1,
129	 straro_mgc_verify_service_change_req/2,
130	 straro_mgc_verify_notify_request/1,
131	 straro_mgc_verify_handle_trans_ack/1,
132	 straro_mg_verify_handle_connect/1,
133	 straro_mg_verify_service_change_reply/1,
134	 straro_mg_verify_handle_disconnect/1,
135
136	 %% Case: request_and_reply_and_ack
137	 raraa_mgc_verify_handle_connect/1,
138	 raraa_mgc_verify_service_change_req/2,
139	 raraa_mgc_verify_notify_req/1,
140	 raraa_mgc_verify_handle_trans_ack/1,
141	 raraa_mgc_verify_handle_disconnect/1,
142	 raraa_mg_verify_service_change_rep_msg/1,
143	 raraa_mg_verify_notify_rep_msg/5,
144
145	 %% Case: request_and_reply_and_no_ack
146	 rarana_mgc_verify_handle_connect/1,
147	 rarana_mgc_verify_service_change_req/2,
148	 rarana_mgc_verify_notify_req/1,
149	 rarana_mgc_verify_handle_trans_ack/1,
150	 rarana_mgc_verify_handle_disconnect/1,
151	 rarana_mg_verify_service_change_rep_msg/1,
152	 rarana_mg_verify_notify_rep_msg/5,
153
154	 %% Case: request_and_reply_and_late_ack
155	 rarala_mgc_verify_handle_connect/1,
156	 rarala_mgc_verify_service_change_req/2,
157	 rarala_mgc_verify_notify_req/1,
158	 rarala_mgc_verify_handle_trans_ack/1,
159	 rarala_mgc_verify_handle_disconnect/1,
160	 rarala_mg_verify_service_change_rep_msg/1,
161	 rarala_mg_verify_notify_rep_msg/5,
162
163	 %% Case: trans_req_and_reply_and_req
164	 trarar_mgc_verify_handle_connect/1,
165	 trarar_mgc_verify_service_change_req/2,
166	 trarar_mgc_verify_notify_req/2,
167	 trarar_mgc_verify_handle_disconnect/1,
168	 trarar_mg_verify_service_change_rep_msg/1,
169	 trarar_mg_verify_notify_rep_msg/5,
170
171	 %% Case: pending_ack_plain
172	 pap_mgc_verify_handle_connect/1,
173	 pap_mgc_verify_service_change_req/2,
174	 pap_mgc_verify_notify_req/1,
175	 pap_mgc_verify_notify_req_long/1,
176	 pap_mgc_verify_handle_trans_ack/1,
177	 pap_mgc_verify_handle_disconnect/1,
178	 pap_mg_verify_service_change_rep_msg/1,
179	 pap_mg_verify_pending_msg/2,
180	 pap_mg_verify_notify_rep_msg/5,
181
182	 %% Case: request_and_pending_and_late_reply
183	 rapalr_mgc_verify_service_change_req_msg/1,
184	 rapalr_mgc_verify_notify_req_msg/5,
185	 rapalr_mgc_verify_trans_ack_msg/2,
186	 rapalr_mg_verify_handle_connect/1,
187	 rapalr_mg_verify_service_change_rep/1,
188	 rapalr_mg_verify_notify_rep/1,
189
190	 %% Case: otp_4836
191	 otp_4836_mgc_verify_service_change_req_msg/1,
192	 otp_4836_mgc_verify_notify_req_msg/1,
193
194	 %% Case: otp_5805
195	 otp_5805_mgc_verify_handle_connect/1,
196	 otp_5805_mgc_verify_service_change_req/2,
197	 otp_5805_mgc_verify_handle_syntax_error/1,
198	 otp_5805_mgc_verify_handle_disconnect/1,
199	 otp_5805_mg_verify_service_change_rep_msg/1,
200	 otp_5805_mg_verify_error_descriptor_msg/1,
201
202	 %% Case: otp_5881
203	 otp_5881_mgc_verify_service_change_req_msg/1,
204	 otp_5881_mgc_verify_notify_req_msg/1,
205
206	 %% Case: otp_5887
207	 otp_5887_mgc_verify_service_change_req_msg/1,
208	 otp_5887_mgc_verify_notify_req_msg/1,
209
210	 %% Case: otp_6275
211	 otp_6275_mgc_verify_service_change_req_msg/1,
212	 otp_6275_mgc_verify_notify_rep_msg/1,
213	 otp_6275_mg_verify_handle_connect/1,
214	 otp_6275_mg_verify_notify_req/1,
215	 otp_6275_mg_verify_handle_trans_rep/1,
216
217	 %% Case: otp_6442_resend_request1
218	 otp_6442_resend_request1_mg_verify_handle_connect/1,
219	 otp_6442_resend_request1_mg_verify_service_change_rep/1,
220	 otp_6442_resend_request1_mg_verify_notify_rep/1,
221
222	 %% Case: otp_6442_resend_request2
223	 otp_6442_resend_request2_mg_verify_handle_connect/1,
224	 otp_6442_resend_request2_mg_verify_service_change_rep/1,
225	 otp_6442_resend_request2_mg_verify_notify_rep/1,
226
227	 %% Case: otp_6442_resend_reply1
228	 otp_6442_resend_reply1_mg_verify_handle_connect/1,
229	 otp_6442_resend_reply1_mg_verify_service_change_rep/1,
230	 otp_6442_resend_reply1_mg_verify_notify_req/2,
231	 otp_6442_resend_reply1_mg_verify_ack/1,
232
233	 %% Case: otp_6442_resend_reply2
234	 otp_6442_resend_reply2_mg_verify_handle_connect/1,
235	 otp_6442_resend_reply2_mg_verify_service_change_rep/1,
236	 otp_6442_resend_reply2_mg_verify_notify_req/2,
237	 otp_6442_resend_reply2_mg_verify_ack/1,
238
239	 %% Case: otp_6865_request_and_reply_plain_extra2
240	 otp6865e2_mgc_verify_handle_connect/1,
241	 otp6865e2_mgc_verify_service_change_req/3,
242	 otp6865e2_mgc_verify_notify_req/4,
243	 otp6865e2_mgc_verify_reply_ack/2,
244	 otp6865e2_mgc_verify_notify_reply/2,
245	 otp6865e2_mgc_verify_handle_disconnect/1,
246	 otp6865e2_mg_verify_service_change_rep_msg/1,
247	 otp6865e2_mg_verify_notify_rep_msg/6,
248	 otp6865e2_mg_verify_notify_req_msg/1,
249
250	 %% Case: otp_7189
251	 otp_7189_mgc_verify_handle_connect/1,
252	 otp_7189_mgc_verify_service_change_req/2,
253	 otp_7189_mgc_verify_handle_trans_reply_req/1,
254	 otp_7189_mgc_verify_handle_disconnect/1,
255	 otp_7189_mg_verify_service_change_rep_msg/1,
256	 otp_7189_mg_verify_notify_req_msg/1,
257
258	 %% Case: otp_6442_resend_request1
259	 otp_8183_request1_mg_verify_handle_connect/1,
260	 otp_8183_request1_mg_verify_service_change_rep/1,
261	 otp_8183_request1_mg_verify_notify_rep/1,
262
263	 %% Utility
264	 encode_msg/3,
265	 decode_msg/3
266	]).
267-endif.
268
269-include_lib("megaco/include/megaco.hrl").
270-include_lib("megaco/include/megaco_message_v1.hrl").
271-include("megaco_test_lib.hrl").
272
273-define(VERSION, 1).
274
275-define(USER_MOD, megaco_mess_user_test).
276
277-define(TEST_VERBOSITY, debug).
278-define(MGC_VERBOSITY,  debug).
279-define(MG_VERBOSITY,   debug).
280
281-define(MGC_START(Pid, Mid, ET, Conf, Verb),
282	megaco_test_mgc:start(Pid, Mid, ET, Conf, Verb)).
283-define(MGC_STOP(Pid),        megaco_test_mgc:stop(Pid)).
284-define(MGC_REQ_PEND(Pid,To), megaco_test_mgc:request_pending(Pid,To)).
285-define(MGC_REQ_HP(Pid,To),   megaco_test_mgc:request_handle_pending(Pid,To)).
286-define(MGC_ACK_INFO(Pid),    megaco_test_mgc:ack_info(Pid,self())).
287
288-define(MG_START(Pid, Mid, Enc, Transp, Conf, Verb),
289	megaco_test_mg:start(Pid, Mid, Enc, Transp, Conf, Verb)).
290-define(MG_STOP(Pid), megaco_test_mg:stop(Pid)).
291-define(MG_SERV_CHANGE(Pid), megaco_test_mg:service_change(Pid)).
292-define(MG_NOTIF_REQ(Pid), megaco_test_mg:notify_request(Pid)).
293-define(MG_AWAIT_NOTIF_REP(Pid), megaco_test_mg:await_notify_reply(Pid)).
294-define(MG_CONN_INFO(Pid,Tag), megaco_test_mg:conn_info(Pid,Tag)).
295-define(MG_USER_INFO(Pid,Tag), megaco_test_mg:user_info(Pid,Tag)).
296-define(MG_NOTIF_RAR(Pid), megaco_test_mg:notify_request_and_reply(Pid)).
297
298-define(SEND(Expr),
299	?VERIFY(ok, ?USER_MOD:apply_proxy(fun() -> Expr end))).
300
301-define(USER(Expected, Reply),
302	?USER_MOD:reply(?MODULE,
303                        ?LINE,
304                        fun(Actual) ->
305                                case ?VERIFY(Expected, Actual) of
306                                    Expected   -> {ok, Reply};
307                                    UnExpected -> {error, {reply_verify,
308                                                           ?MODULE,
309                                                           ?LINE,
310                                                           UnExpected}}
311                                end
312                        end)).
313
314%% Some generator (utility) macros
315-define(GM_START(),              megaco_start).
316-define(GM_STOP(),               megaco_stop).
317-define(GM_START_USER(M, RI, C), {megaco_start_user, M, RI, C}).
318-define(GM_START_USER(M, RI),    ?GM_START_USER(M, RI, [])).
319-define(GM_STOP_USER(),          megaco_stop_user).
320-define(GMSI(I),                 {megaco_system_info, I}).
321-define(GMSI_USERS(),            ?GMSI(users)).
322-define(GMSI_CONNS(),            ?GMSI(connections)).
323-define(GMCAST(Reqs, Opts),      {megaco_cast, Reqs, Opts}).
324-define(GMCAST(Reqs),            ?GMCAST(Reqs, [])).
325-define(GMCB(CB, VF),            {megaco_callback, CB, VF}).
326-define(GMCB_CONNECT(VF),        ?GMCB(handle_connect, VF)).
327-define(GMCB_TRANS_REP(VF),      ?GMCB(handle_trans_reply, VF)).
328-define(GMT(T),                  {megaco_trace, T}).
329-define(GMT_ENABLE(),            ?GMT(enable)).
330-define(GMT_DISABLE(),           ?GMT(disable)).
331-define(GD(D),                   {debug, D}).
332-define(GD_ENABLE(),             ?GD(true)).
333-define(GD_DISABLE(),            ?GD(false)).
334-define(GS(T),                   {sleep, T}).
335
336-define(GSND(T, D),              {send, T, D}).
337-define(GERCV(T, VF, TO),        {expect_receive, T, {VF, TO}}).
338
339
340
341%%======================================================================
342%% Common Test interface functions
343%%======================================================================
344
345suite() ->
346    [{ct_hooks, [ts_install_cth]}].
347
348all() ->
349    [
350     connect,
351     {group, request_and_reply},
352     {group, pending_ack},
353     dist,
354     {group, tickets}
355    ].
356
357groups() ->
358    [
359     {request_and_reply, [], request_and_reply_cases()},
360     {pending_ack,       [], pending_ack_cases()},
361     {tickets,           [], tickets_cases()},
362     {otp6442,           [], otp6442_cases()},
363     {otp6865,           [], otp6865_cases()},
364     {otp8183,           [], otp8183_cases()}
365    ].
366
367request_and_reply_cases() ->
368    [
369     request_and_reply_plain,
370     request_and_no_reply,
371     request_and_reply_pending_ack_no_pending,
372     request_and_reply_pending_ack_one_pending,
373     single_trans_req_and_reply,
374     single_trans_req_and_reply_sendopts,
375     request_and_reply_and_ack,
376     request_and_reply_and_no_ack,
377     request_and_reply_and_late_ack,
378     trans_req_and_reply_and_req
379    ].
380
381pending_ack_cases() ->
382    [
383     pending_ack_plain,
384     request_and_pending_and_late_reply
385    ].
386
387tickets_cases() ->
388    [
389     otp_4359,
390     otp_4836,
391     otp_5805,
392     otp_5881,
393     otp_5887,
394     otp_6253,
395     otp_6275,
396     otp_6276,
397     {group, otp6442},
398     {group, otp6865},
399     otp_7189,
400     otp_7259,
401     otp_7713,
402     {group, otp8183},
403     otp_8212
404    ].
405
406otp6442_cases() ->
407    [
408     otp_6442_resend_request1,
409     otp_6442_resend_request2,
410     otp_6442_resend_reply1,
411     otp_6442_resend_reply2
412    ].
413
414otp6865_cases() ->
415    [
416     otp_6865_request_and_reply_plain_extra1,
417     otp_6865_request_and_reply_plain_extra2
418    ].
419
420otp8183_cases() ->
421    [
422     otp_8183_request1
423    ].
424
425
426
427%%
428%% -----
429%%
430
431init_per_suite(suite) ->
432    [];
433init_per_suite(doc) ->
434    [];
435init_per_suite(Config0) when is_list(Config0) ->
436
437    ?ANNOUNCE_SUITE_INIT(),
438
439    p("init_per_suite -> entry with"
440      "~n      Config: ~p"
441      "~n      Nodes:  ~p", [Config0, erlang:nodes()]),
442
443    case ?LIB:init_per_suite(Config0) of
444        {skip, _} = SKIP ->
445            SKIP;
446
447        Config1 when is_list(Config1) ->
448
449            %% We need a (local) monitor on this node also
450            megaco_test_sys_monitor:start(),
451
452            p("init_per_suite -> end when"
453              "~n      Config: ~p"
454              "~n      Nodes:  ~p", [Config1, erlang:nodes()]),
455
456            Config1
457    end.
458
459end_per_suite(suite) -> [];
460end_per_suite(doc) -> [];
461end_per_suite(Config0) when is_list(Config0) ->
462
463    p("end_per_suite -> entry with"
464      "~n      Config: ~p"
465      "~n      Nodes:  ~p", [Config0, erlang:nodes()]),
466
467    megaco_test_sys_monitor:stop(),
468    Config1 = ?LIB:end_per_suite(Config0),
469
470    p("end_per_suite -> end when"
471      "~n      Nodes:  ~p", [erlang:nodes()]),
472
473    Config1.
474
475
476%%
477%% -----
478%%
479
480init_per_group(Group, Config) ->
481    ?ANNOUNCE_GROUP_INIT(Group),
482
483    p("init_per_group -> entry with"
484      "~n   Config: ~p"
485      "~n", [Config]),
486
487    Config.
488
489end_per_group(_GroupName, Config) ->
490    p("end_per_group -> entry with"
491      "~n   Config: ~p"
492      "~n", [Config]),
493    Config.
494
495
496
497%%
498%% -----
499%%
500
501init_per_testcase(Case, Config) ->
502    process_flag(trap_exit, true),
503
504    ?ANNOUNCE_CASE_INIT(Case),
505
506    p("init_per_testcase -> entry with"
507      "~n   Config: ~p"
508      "~n   Nodes:  ~p", [Config, erlang:nodes()]),
509
510    init_per_testcase2(Case, Config).
511
512init_per_testcase2(otp_7189 = Case, Config) ->
513    C = lists:keydelete(tc_timeout, 1, Config),
514    init_per_testcase3(Case, [{tc_timeout, min(2)} |C]);
515init_per_testcase2(request_and_no_reply = Case, Config) ->
516    C = lists:keydelete(tc_timeout, 1, Config),
517    init_per_testcase3(Case, [{tc_timeout, min(2)} |C]);
518init_per_testcase2(Case, Config) ->
519    C = lists:keydelete(tc_timeout, 1, Config),
520    init_per_testcase3(Case, [{tc_timeout, min(1)} |C]).
521
522init_per_testcase3(Case, Config) ->
523    megaco_test_global_sys_monitor:reset_events(),
524    megaco_test_lib:init_per_testcase(Case, Config).
525
526
527end_per_testcase(Case, Config) ->
528
529    p("end_per_testcase -> entry with"
530      "~n   Config: ~p"
531      "~n   Nodes:  ~p", [Config, erlang:nodes()]),
532
533    p("system events during test: "
534      "~n   ~p", [megaco_test_global_sys_monitor:events()]),
535
536    megaco_test_lib:end_per_testcase(Case, Config).
537
538
539
540min(M) -> ?MINS(M).
541
542
543
544%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
545
546connect(suite) ->
547    [];
548connect(doc) ->
549    [];
550connect(Config) when is_list(Config) ->
551    %% ?SKIP("Needs a re-write..."),
552    ?ACQUIRE_NODES(1, Config),
553    PrelMid = preliminary_mid,
554    MgMid   = ipv4_mid(4711),
555
556    d("connect -> start megaco app",[]),
557    ?VERIFY(ok, application:start(megaco)),
558    d("connect -> start (MG) user ~p",[MgMid]),
559    ?VERIFY(ok,	megaco:start_user(MgMid, [{send_mod, bad_send_mod},
560	                                  {request_timer, infinity},
561	                                  {reply_timer, infinity}])),
562
563    d("connect -> get receive info for ~p",[MgMid]),
564    MgRH = user_info(MgMid, receive_handle),
565    d("connect -> (MG) try connect to MGC",[]),
566    {ok, PrelCH} = ?VERIFY({ok, _}, megaco:connect(MgRH, PrelMid, sh, self())),
567
568    connections([PrelCH]),
569    ?VERIFY([PrelCH], megaco:user_info(MgMid, connections)),
570
571    ?VERIFY(bad_send_mod, megaco:user_info(MgMid, send_mod)),
572    ?VERIFY(bad_send_mod, megaco:conn_info(PrelCH, send_mod)),
573    SC = service_change_request(),
574    case megaco:call(PrelCH, [SC], []) of
575	{_Version,
576	 {error,
577	  {send_message_failed,
578	   {'EXIT', {undef, [{bad_send_mod, send_message, [sh, _]} | _]}}}}
579	} ->
580	    %% R14B and previous
581	    ?LOG("expected send failure (1)", []),
582	    ok;
583
584	%% As of R15, we also get some extra info (e.g. line numbers)
585	{_Version,
586	 {error,
587	  {send_message_failed,
588	   {'EXIT', {undef, [{bad_send_mod, send_message, [sh, _], _} | _]}}}}
589	} ->
590	    %% R15B and later
591	    ?LOG("expected send failure (2)", []),
592	    ok;
593
594	Unexpected ->
595	    ?ERROR(Unexpected)
596    end,
597
598    ?VERIFY(ok, megaco:disconnect(PrelCH, shutdown)),
599
600    ?VERIFY(ok,	megaco:stop_user(MgMid)),
601    ?VERIFY(ok, application:stop(megaco)),
602    ?RECEIVE([]),
603    ok.
604
605
606%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
607
608request_and_reply_plain(suite) ->
609    [];
610request_and_reply_plain(Config) when is_list(Config) ->
611    ?ACQUIRE_NODES(1, Config),
612    d("request_and_reply_plain -> start proxy",[]),
613    ?USER_MOD:start_proxy(),
614
615    PrelMid = preliminary_mid,
616    MgMid   = ipv4_mid(4711),
617    MgcMid  = ipv4_mid(),
618    UserMod = ?USER_MOD,
619    d("request_and_reply_plain -> start megaco app",[]),
620    ?VERIFY(ok, application:start(megaco)),
621    UserConfig = [{user_mod, UserMod}, {send_mod, UserMod},
622		  {request_timer, infinity}, {reply_timer, infinity}],
623    d("request_and_reply_plain -> start (MG) user ~p",[MgMid]),
624    ?VERIFY(ok,	megaco:start_user(MgMid, UserConfig)),
625
626    d("request_and_reply_plain -> start (MGC) user ~p",[MgcMid]),
627    ?VERIFY(ok,	megaco:start_user(MgcMid, UserConfig)),
628
629    d("request_and_reply_plain -> get receive info for ~p",[MgMid]),
630    MgRH = user_info(MgMid, receive_handle),
631    d("request_and_reply_plain -> get receive info for ~p",[MgcMid]),
632    MgcRH = user_info(MgcMid, receive_handle),
633    d("request_and_reply_plain -> start transport",[]),
634    {ok, MgPid, MgSH} =
635	?VERIFY({ok, _, _}, UserMod:start_transport(MgRH, MgcRH)),
636    PrelMgCH = #megaco_conn_handle{local_mid = MgMid,
637				   remote_mid = preliminary_mid},
638    MgCH  = #megaco_conn_handle{local_mid = MgMid,
639				remote_mid = MgcMid},
640    MgcCH = #megaco_conn_handle{local_mid = MgcMid,
641				remote_mid = MgMid},
642    d("request_and_reply_plain -> (MG) try connect to MGC",[]),
643    ?SEND(megaco:connect(MgRH, PrelMid, MgSH, MgPid)), % Mg prel
644    d("request_and_reply_plain -> (MGC) await connect from MG",[]),
645    ?USER({connect, PrelMgCH, _V, []}, ok),
646    ?RECEIVE([{res, _, {ok, PrelMgCH}}]),
647
648    d("request_and_reply_plain -> (MG) send service change request",[]),
649    Req = service_change_request(),
650    ?SEND(megaco:call(PrelMgCH, [Req], [])),
651
652    d("request_and_reply_plain -> (MGC) send service change reply",[]),
653    ?USER({connect, MgcCH, _V, []}, ok), % Mgc auto
654    Rep = service_change_reply(MgcMid),
655    ?USER({request, MgcCH, _V, [[Req]]}, {discard_ack, [Rep]}),
656    ?USER({connect, MgCH, _V, []}, ok), % Mg confirm
657    ?RECEIVE([{res, _, {1, {ok, [Rep]}}}]),
658
659    d("request_and_reply_plain -> get (system info) connections",[]),
660    connections([MgCH, MgcCH]),
661    d("request_and_reply_plain -> get (~p) connections",[MgMid]),
662    ?VERIFY([MgCH], megaco:user_info(MgMid, connections)),
663    d("request_and_reply_plain -> get (~p) connections",[MgcMid]),
664    ?VERIFY([MgcCH], megaco:user_info(MgcMid, connections)),
665
666    Reason = shutdown,
667    d("request_and_reply_plain -> (MG) disconnect",[]),
668    ?SEND(megaco:disconnect(MgCH, Reason)),
669    ?USER({disconnect, MgCH, _V, [{user_disconnect, Reason}]}, ok),
670    ?RECEIVE([{res, _, ok}]),
671    ?VERIFY(ok,	megaco:stop_user(MgMid)),
672
673    d("request_and_reply_plain -> (MGC) disconnect",[]),
674    ?SEND(megaco:disconnect(MgcCH, Reason)),
675    ?USER({disconnect, MgcCH, _V, [{user_disconnect, Reason}]}, ok),
676    ?RECEIVE([{res, _, ok}]),
677    ?VERIFY(ok,	megaco:stop_user(MgcMid)),
678
679    d("request_and_reply_plain -> stop megaco app",[]),
680    ?VERIFY(ok, application:stop(megaco)),
681    ?RECEIVE([]),
682    d("request_and_reply_plain -> done",[]),
683    ok.
684
685
686
687%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
688
689%% OTP-4760
690request_and_no_reply(suite) ->
691    [];
692request_and_no_reply(doc) ->
693    [];
694request_and_no_reply(Config) when is_list(Config) ->
695    Pre = fun() ->
696                  MgcNode = make_node_name(mgc),
697                  Mg1Node = make_node_name(mg1),
698                  Mg2Node = make_node_name(mg2),
699                  Mg3Node = make_node_name(mg3),
700                  Mg4Node = make_node_name(mg4),
701                  d("start nodes: "
702                    "~n      MgcNode: ~p"
703                    "~n      Mg1Node: ~p"
704                    "~n      Mg2Node: ~p"
705                    "~n      Mg3Node: ~p"
706                    "~n      Mg4Node: ~p",
707                    [MgcNode, Mg1Node, Mg2Node, Mg3Node, Mg4Node]),
708                  Nodes = [MgcNode, Mg1Node, Mg2Node, Mg3Node, Mg4Node],
709                  ok = ?START_NODES(Nodes, true),
710                  Nodes
711          end,
712    Case = fun do_request_and_no_reply/1,
713    Post = fun(Nodes) ->
714                   d("stop nodes"),
715                   ?STOP_NODES(lists:reverse(Nodes))
716           end,
717    try_tc(request_and_no_reply, Pre, Case, Post).
718
719do_request_and_no_reply([MgcNode, Mg1Node, Mg2Node, Mg3Node, Mg4Node]) ->
720    %% Start the MGC
721    i("[MGC] start"),
722    ET = [{text,tcp}, {text,udp}, {binary,tcp}, {binary,udp}],
723    {ok, Mgc} = ?MGC_START(MgcNode, {deviceName, "ctrl"}, ET, [], ?MGC_VERBOSITY),
724    ?SLEEP(?SECONDS(1)),
725
726    i("[MG] start"),
727    Mg1Mid = {deviceName, "mg1"},
728    Mg2Mid = {deviceName, "mg2"},
729    Mg3Mid = {deviceName, "mg3"},
730    Mg4Mid = {deviceName, "mg4"},
731    ReqTmr = #megaco_incr_timer{wait_for    = 3000,
732				factor      = 1,
733				incr        = 0,
734				max_retries = 2
735			       },
736    LongReqTmr = #megaco_incr_timer{wait_for    = 10000,
737				    factor      = 1,
738				    incr        = 0,
739				    max_retries = 3
740				   },
741    %% Start the MGs
742    PendingTmr = 10000,
743    ReplyTmr = 16000,
744    MgConfig = [{request_timer,      ReqTmr},
745		{long_request_timer, LongReqTmr},
746		{pending_timer,      PendingTmr},
747		{reply_timer,        ReplyTmr}],
748    {ok, Mg1} = ?MG_START(Mg1Node, Mg1Mid, text, tcp, MgConfig, ?MG_VERBOSITY),
749    ?SLEEP(?SECONDS(1)),
750    {ok, Mg2} = ?MG_START(Mg2Node, Mg2Mid, text, udp, MgConfig, ?MG_VERBOSITY),
751    ?SLEEP(?SECONDS(1)),
752    {ok, Mg3} = ?MG_START(Mg3Node, Mg3Mid, binary, tcp, MgConfig, ?MG_VERBOSITY),
753    ?SLEEP(?SECONDS(1)),
754    {ok, Mg4} = ?MG_START(Mg4Node, Mg4Mid, binary, udp, MgConfig, ?MG_VERBOSITY),
755    ?SLEEP(?SECONDS(1)),
756
757    d("MG1 user info: ~p", [?MG_USER_INFO(Mg1, all)]),
758    d("MG1 conn info: ~p", [?MG_CONN_INFO(Mg1, all)]),
759    d("MG2 user info: ~p", [?MG_USER_INFO(Mg2, all)]),
760    d("MG2 conn info: ~p", [?MG_CONN_INFO(Mg2, all)]),
761    d("MG3 user info: ~p", [?MG_USER_INFO(Mg3, all)]),
762    d("MG3 conn info: ~p", [?MG_CONN_INFO(Mg3, all)]),
763    d("MG4 user info: ~p", [?MG_USER_INFO(Mg4, all)]),
764    d("MG4 conn info: ~p", [?MG_CONN_INFO(Mg4, all)]),
765
766    i("[MG1] connect to the MGC (service change)"),
767    ServChRes1 = ?MG_SERV_CHANGE(Mg1),
768    d("service change result: ~p", [ServChRes1]),
769    d("MG1 user info: ~p", [?MG_USER_INFO(Mg1, all)]),
770    d("MG1 conn info: ~p", [?MG_CONN_INFO(Mg1, all)]),
771    ?SLEEP(?SECONDS(1)),
772
773    i("[MG2] connect to the MGC (service change)"),
774    ServChRes2 = ?MG_SERV_CHANGE(Mg2),
775    d("service change result: ~p", [ServChRes2]),
776    d("MG2 user info: ~p", [?MG_USER_INFO(Mg2, all)]),
777    d("MG2 conn info: ~p", [?MG_CONN_INFO(Mg2, all)]),
778    ?SLEEP(?SECONDS(1)),
779
780    i("[MG3] connect to the MGC (service change)"),
781    ServChRes3 = ?MG_SERV_CHANGE(Mg3),
782    d("service change result: ~p", [ServChRes3]),
783    d("MG3 user info: ~p", [?MG_USER_INFO(Mg3, all)]),
784    d("MG3 conn info: ~p", [?MG_CONN_INFO(Mg3, all)]),
785    ?SLEEP(?SECONDS(1)),
786
787    i("[MG4] connect to the MGC (service change)"),
788    ServChRes4 = ?MG_SERV_CHANGE(Mg4),
789    d("service change result: ~p", [ServChRes4]),
790    d("MG4 user info: ~p", [?MG_USER_INFO(Mg4, all)]),
791    d("MG4 conn info: ~p", [?MG_CONN_INFO(Mg4, all)]),
792    ?SLEEP(?SECONDS(1)),
793
794    d("tell the MGC to ignore requests"),
795    ?MGC_REQ_PEND(Mgc, infinity),
796    ?SLEEP(?SECONDS(1)),
797
798    d("[MG1] send the notify"),
799    ?MG_NOTIF_REQ(Mg1),
800    ?SLEEP(?SECONDS(1)),
801
802    d("[MG2] send the notify"),
803    ?MG_NOTIF_REQ(Mg2),
804    ?SLEEP(?SECONDS(1)),
805
806    d("[MG3] send the notify"),
807    ?MG_NOTIF_REQ(Mg3),
808    ?SLEEP(?SECONDS(1)),
809
810    d("[MG4] send the notify"),
811    ?MG_NOTIF_REQ(Mg4),
812    ?SLEEP(?SECONDS(1)),
813
814    d("[MG1] await notify reply"),
815    {ok, {_Vsn1, {error, timeout}}} = ?MG_AWAIT_NOTIF_REP(Mg1),
816    d("[MG1] received expected reply"),
817    ?SLEEP(?SECONDS(1)),
818
819    d("[MG2] await notify reply"),
820    {ok, {_Vsn2, {error, timeout}}} = ?MG_AWAIT_NOTIF_REP(Mg2),
821    d("[MG2] received expected reply"),
822    ?SLEEP(?SECONDS(1)),
823
824    d("[MG3] await notify reply"),
825    {ok, {_Vsn3, {error, timeout}}} = ?MG_AWAIT_NOTIF_REP(Mg3),
826    d("[MG3] received expected reply"),
827    ?SLEEP(?SECONDS(1)),
828
829    d("[MG4] await notify reply"),
830    {ok, {_Vsn4, {error, timeout}}} = ?MG_AWAIT_NOTIF_REP(Mg4),
831    d("[MG4] received expected reply"),
832    ?SLEEP(?SECONDS(1)),
833
834    d("MG1 user info: ~p", [?MG_USER_INFO(Mg1, all)]),
835    d("MG1 conn info: ~p", [?MG_CONN_INFO(Mg1, all)]),
836    d("MG2 user info: ~p", [?MG_USER_INFO(Mg2, all)]),
837    d("MG2 conn info: ~p", [?MG_CONN_INFO(Mg2, all)]),
838    d("MG3 user info: ~p", [?MG_USER_INFO(Mg3, all)]),
839    d("MG3 conn info: ~p", [?MG_CONN_INFO(Mg3, all)]),
840    d("MG4 user info: ~p", [?MG_USER_INFO(Mg4, all)]),
841    d("MG4 conn info: ~p", [?MG_CONN_INFO(Mg4, all)]),
842
843    %% Tell MG4 to stop
844    i("[MG4] stop"),
845    ?MG_STOP(Mg4),
846
847    %% Tell MG3 to stop
848    i("[MG3] stop"),
849    ?MG_STOP(Mg3),
850
851    %% Tell MG2 to stop
852    i("[MG2] stop"),
853    ?MG_STOP(Mg2),
854
855    %% Tell MG1 to stop
856    i("[MG1] stop"),
857    ?MG_STOP(Mg1),
858
859    %% Tell Mgc to stop
860    i("[MGC] stop"),
861    ?MGC_STOP(Mgc),
862
863    i("done", []),
864    ok.
865
866
867
868%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
869
870request_and_reply_pending_ack_no_pending(suite) ->
871    [];
872request_and_reply_pending_ack_no_pending(doc) ->
873    ["This test case tests that megaco correctly handles the return "
874     "value handle_pending_ack from handle_trans_request when NO "
875     "pending message has been sent"];
876request_and_reply_pending_ack_no_pending(Config) when is_list(Config) ->
877    Pre = fun() ->
878                  MgcNode = make_node_name(mgc),
879                  MgNode  = make_node_name(mg),
880                  d("start nodes: "
881                    "~n      MgcNode: ~p"
882                    "~n      MgNode:  ~p",
883                    [MgcNode, MgNode]),
884                  Nodes = [MgcNode, MgNode],
885                  ok = ?START_NODES(Nodes, true),
886                  Nodes
887          end,
888    Case = fun do_request_and_reply_pending_ack_no_pending/1,
889    Post = fun(Nodes) ->
890                   d("stop nodes"),
891                   ?STOP_NODES(lists:reverse(Nodes)),
892                   ok
893           end,
894    try_tc(rar_panp, Pre, Case, Post).
895
896do_request_and_reply_pending_ack_no_pending([MgcNode, MgNode]) ->
897    d("[MGC] start the simulator "),
898    {ok, Mgc} = megaco_test_megaco_generator:start_link("MGC", MgcNode),
899
900    d("[MGC] create the event sequence"),
901    MgcEvSeq = rarpanp_mgc_event_sequence(text, tcp),
902
903    i("wait some time before starting the MGC simulation"),
904    sleep(1000),
905
906    d("[MGC] start the simulation"),
907    {ok, MgcId} = megaco_test_megaco_generator:exec(Mgc, MgcEvSeq),
908
909    i("await MGC ready announcement"),
910    receive
911        announce_mgc ->
912            i("received MGC ready announcement"),
913            ok
914    end,
915
916    d("[MG] start the simulator (generator)"),
917    {ok, Mg} = megaco_test_tcp_generator:start_link("MG", MgNode),
918
919    d("[MG] create the event sequence"),
920    MgEvSeq = rarpanp_mg_event_sequence(text, tcp),
921
922    i("wait some time before starting the MG simulation"),
923    sleep(1000),
924
925    d("[MG] start the simulation"),
926    {ok, MgId} = megaco_test_tcp_generator:exec(Mg, MgEvSeq),
927
928    d("await the generator reply(s)"),
929    await_completion([MgcId, MgId]),
930
931    %% Tell Mgc to stop
932    i("[MGC] stop generator"),
933    megaco_test_tcp_generator:stop(Mgc),
934
935    %% Tell Mg to stop
936    i("[MG] stop generator"),
937    megaco_test_megaco_generator:stop(Mg),
938
939    i("done", []),
940    ok.
941
942
943%%
944%% MGC generator stuff
945%%
946-ifdef(megaco_hipe_special).
947-define(rarpanp_mgc_verify_handle_connect_fun(),
948        {?MODULE, rarpanp_mgc_verify_handle_connect, []}).
949-define(rarpanp_mgc_verify_service_change_req_fun(Mid),
950        {?MODULE, rarpanp_mgc_verify_service_change_req, [Mid]}).
951-define(rarpanp_mgc_verify_notify_req_fun(),
952        {?MODULE, rarpanp_mgc_verify_notify_request, []}).
953-define(rarpanp_mgc_verify_handle_disconnect_fun(),
954        {?MODULE, rarpanp_mgc_verify_handle_disconnect, []}).
955-else.
956-define(rarpanp_mgc_verify_handle_connect_fun(),
957        fun rarpanp_mgc_verify_handle_connect/1).
958-define(rarpanp_mgc_verify_service_change_req_fun(Mid),
959        rarpanp_mgc_verify_service_change_req_fun(Mid)).
960-define(rarpanp_mgc_verify_notify_req_fun(),
961	rarpanp_mgc_verify_notify_request_fun()).
962-define(rarpanp_mgc_verify_handle_disconnect_fun(),
963	fun rarpanp_mgc_verify_handle_disconnect/1).
964-endif.
965
966rarpanp_mgc_event_sequence(text, tcp) ->
967    CTRL = self(),
968    Mid = {deviceName,"ctrl"},
969    RI = [
970          {port,             2944},
971          {encoding_module,  megaco_pretty_text_encoder},
972          {encoding_config,  []},
973          {transport_module, megaco_tcp}
974         ],
975    ConnectVerify = ?rarpanp_mgc_verify_handle_connect_fun(),
976    ScrVerify     = ?rarpanp_mgc_verify_service_change_req_fun(Mid),
977    NrVerify      = ?rarpanp_mgc_verify_notify_req_fun(),
978    DiscoVerify   = ?rarpanp_mgc_verify_handle_disconnect_fun(),
979    EvSeq = [
980             {debug, true},
981             {megaco_trace, disable},
982             {megaco_trace, max},
983             megaco_start,
984             {megaco_start_user, Mid, RI, []},
985             {megaco_update_user_info, sent_pending_limit, 100},
986             start_transport,
987             listen,
988
989             %% ANNOUNCE READY
990             {trigger, fun() -> CTRL ! announce_mgc end},
991
992             {megaco_callback, handle_connect,       ConnectVerify},
993             {megaco_conn_info, all},
994             {megaco_callback, handle_trans_request, ScrVerify},
995	     {megaco_callback, handle_trans_request, NrVerify},
996             {megaco_callback, nocall, 10000},
997             {megaco_callback, handle_disconnect,    DiscoVerify},
998             megaco_stop_user,
999             megaco_stop
1000            ],
1001    EvSeq.
1002
1003%% Connect verification
1004rarpanp_mgc_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
1005    {ok, CH, ok};
1006rarpanp_mgc_verify_handle_connect(Else) ->
1007    {error, Else, ok}.
1008
1009%% Service Change verification
1010-ifndef(megaco_hipe_special).
1011rarpanp_mgc_verify_service_change_req_fun(Mid) ->
1012    fun(Req) ->
1013	    rarpanp_mgc_verify_service_change_req(Req, Mid)
1014    end.
1015-endif.
1016
1017rarpanp_mgc_verify_service_change_req(
1018  {handle_trans_request, _, ?VERSION, [AR]}, Mid) ->
1019    io:format("rarpanp_mgc_verify_service_change_req -> entry with"
1020	      "~n   AR:  ~p"
1021	      "~n   Mid: ~p"
1022	      "~n", [AR, Mid]),
1023    (catch rarpanp_mgc_do_verify_service_change_req(AR, Mid));
1024rarpanp_mgc_verify_service_change_req(Crap, _Mid) ->
1025    ED       = cre_ErrDesc(Crap),
1026    ErrReply = {discard_ack, ED},
1027    {error, Crap, ErrReply}.
1028
1029rarpanp_mgc_do_verify_service_change_req(AR, Mid) ->
1030    io:format("rarpanp_mgc_do_verify_service_change_req -> entry with"
1031	      "~n   AR:  ~p"
1032	      "~n   Mid: ~p"
1033	      "~n", [AR, Mid]),
1034    CR =
1035	case AR of
1036	    #'ActionRequest'{commandRequests = [CmdReq]} ->
1037		CmdReq;
1038	    _ ->
1039		Err1      = {invalid_action_request, AR},
1040		ED1       = cre_ErrDesc(AR),
1041		ErrReply1 = {discard_ack, ED1},
1042		throw({error, Err1, ErrReply1})
1043	end,
1044    Cmd =
1045	case CR of
1046	    #'CommandRequest'{command = Command} ->
1047		Command;
1048	    _ ->
1049		Err2      = {invalid_command_request, CR},
1050		ED2       = cre_ErrDesc(CR),
1051		ErrReply2 = {discard_ack, ED2},
1052		throw({error, Err2, ErrReply2})
1053	end,
1054    {Tid, Parms} =
1055	case Cmd of
1056	    {serviceChangeReq,
1057	     #'ServiceChangeRequest'{terminationID = [TermID],
1058				     serviceChangeParms = ServChParms}} ->
1059		{TermID, ServChParms};
1060	    _ ->
1061		Err3      = {invalid_command, Cmd},
1062		ED3       = cre_ErrDesc(Cmd),
1063		ErrReply3 = {discard_ack, ED3},
1064		throw({error, Err3, ErrReply3})
1065	end,
1066    case Tid of
1067	#megaco_term_id{contains_wildcards = false, id = ["root"]} ->
1068	    ok;
1069	_ ->
1070	    Err4      = {invalid_termination_id, Tid},
1071	    ED4       = cre_ErrDesc(Tid),
1072	    ErrReply4 = {discard_ack, ED4},
1073	    throw({error, Err4, ErrReply4})
1074    end,
1075    case Parms of
1076	#'ServiceChangeParm'{serviceChangeMethod = restart,
1077			     serviceChangeReason = [[$9,$0,$1|_]]} ->
1078	    AckData = [rarpanp_mgc_service_change_reply_ar(Mid, 1)],
1079	    Reply   = {discard_ack, AckData},
1080	    {ok, AR, Reply};
1081	_ ->
1082	    Err5      = {invalid_SCP, Parms},
1083	    ED5       = cre_ErrDesc(Parms),
1084	    ErrReply5 = {discard_ack, ED5},
1085	    {error, Err5, ErrReply5}
1086    end.
1087
1088
1089%% Notify Request verification
1090-ifndef(megaco_hipe_special).
1091rarpanp_mgc_verify_notify_request_fun() ->
1092    fun(Req) ->
1093	    rarpanp_mgc_verify_notify_request(Req)
1094    end.
1095-endif.
1096
1097rarpanp_mgc_verify_notify_request(
1098  {handle_trans_request, _, ?VERSION, [AR]}) ->
1099    (catch rarpanp_mgc_do_verify_notify_request(AR));
1100rarpanp_mgc_verify_notify_request(Crap) ->
1101    ED = cre_ErrDesc(Crap),
1102    ErrReply = {discard_ack, ED},
1103    {error, Crap, ErrReply}.
1104
1105rarpanp_mgc_do_verify_notify_request(AR) ->
1106    io:format("rarpanp_mgc_do_verify_notify_request -> entry with"
1107	      "~n   AR: ~p"
1108	      "~n", [AR]),
1109    {Cid, CR} =
1110	case AR of
1111	    #'ActionRequest'{contextId       = CtxID,
1112			     commandRequests = [CmdReq]} ->
1113		{CtxID, CmdReq};
1114	    _ ->
1115		Err1      = {invalid_action_request, AR},
1116		ED1       = cre_ErrDesc(AR),
1117		ErrReply1 = {discard_ack, ED1},
1118		throw({error, Err1, ErrReply1})
1119	end,
1120    Cmd =
1121	case CR of
1122	    #'CommandRequest'{command = Command} ->
1123		Command;
1124	    _ ->
1125		Err2      = {invalid_command_request, CR},
1126		ED2       = cre_ErrDesc(CR),
1127		ErrReply2 = {discard_ack, ED2},
1128		throw({error, Err2, ErrReply2})
1129	end,
1130    NR =
1131	case Cmd of
1132	    {notifyReq, NotifReq} ->
1133		NotifReq;
1134	    _ ->
1135		Err3      = {invalid_command, Cmd},
1136		ED3       = cre_ErrDesc(Cmd),
1137		ErrReply3 = {discard_ack, ED3},
1138		throw({error, Err3, ErrReply3})
1139	end,
1140    {Tid, OED} =
1141	case NR of
1142	    #'NotifyRequest'{terminationID            = [TermID],
1143			     observedEventsDescriptor = ObsEvsDesc,
1144			     errorDescriptor          = asn1_NOVALUE} ->
1145		{TermID, ObsEvsDesc};
1146	    _ ->
1147		Err4      = {invalid_NR, NR},
1148		ED4       = cre_ErrDesc(NR),
1149		ErrReply4 = {discard_ack, ED4},
1150		throw({error, Err4, ErrReply4})
1151	end,
1152    OE =
1153	case OED of
1154	    #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
1155		ObsEvLst;
1156	    _ ->
1157		Err5      = {invalid_OED, OED},
1158		ED5       = cre_ErrDesc(NR),
1159		ErrReply5 = {discard_ack, ED5},
1160		throw({error, Err5, ErrReply5})
1161	end,
1162    case OE of
1163	#'ObservedEvent'{eventName = "al/of"} ->
1164	    AckData = notify_request_verified,
1165	    Replies = [rarpanp_mgc_notify_reply_ar(Cid, Tid)],
1166	    Reply   = {{handle_pending_ack, AckData}, Replies},
1167	    {ok, AR, Reply};
1168	_ ->
1169	    Err6      = {invalid_OE, OE},
1170	    ED6       = cre_ErrDesc(OE),
1171	    ErrReply6 = {discard_ack, ED6},
1172	    throw({error, Err6, ErrReply6})
1173    end.
1174
1175
1176%% Disconnect verification
1177rarpanp_mgc_verify_handle_disconnect({handle_disconnect, CH, ?VERSION, _R}) ->
1178    {ok, CH, ok};
1179rarpanp_mgc_verify_handle_disconnect(Else) ->
1180    {error, Else, ok}.
1181
1182rarpanp_mgc_service_change_reply_ar(Mid, Cid) ->
1183    SCRP  = cre_serviceChangeResParm(Mid),
1184    SCRes = cre_serviceChangeResult(SCRP),
1185    Root  = #megaco_term_id{id = ["root"]},
1186    SCR   = cre_serviceChangeReply([Root], SCRes),
1187    CR    = cre_cmdReply(SCR),
1188    AR    = cre_actionReply(Cid, [CR]),
1189    AR.
1190
1191rarpanp_mgc_notify_reply_ar(Cid, TermId) ->
1192    NR    = cre_notifyReply([TermId]),
1193    CR    = cre_cmdReply(NR),
1194    cre_actionReply(Cid, [CR]).
1195
1196
1197%%
1198%% MG generator stuff
1199%%
1200-ifdef(megaco_hipe_special).
1201-define(rarpanp_mg_decode_msg_fun(Mod, Conf),
1202	{?MODULE, decode_msg, [Mod, Conf]}).
1203-define(rarpanp_mg_encode_msg_fun(Mod, Conf),
1204	{?MODULE, encode_msg, [Mod, Conf]}).
1205-define(rarpanp_mg_verify_service_change_rep_msg_fun(),
1206	{?MODULE, rarpanp_mg_verify_service_change_rep_msg, []}).
1207-define(rarpanp_mg_verify_notify_rep_msg_fun(TransId, TermId),
1208	{?MODULE, rarpanp_mg_verify_notify_rep_msg, [TransId, TermId]}).
1209-else.
1210-define(rarpanp_mg_decode_msg_fun(Mod, Conf),
1211	rarpanp_mg_decode_msg_fun(Mod, Conf)).
1212-define(rarpanp_mg_encode_msg_fun(Mod, Conf),
1213	rarpanp_mg_encode_msg_fun(Mod, Conf)).
1214-define(rarpanp_mg_verify_service_change_rep_msg_fun(),
1215	rarpanp_mg_verify_service_change_rep_msg_fun()).
1216-define(rarpanp_mg_verify_notify_rep_msg_fun(TransId, TermId),
1217	rarpanp_mg_verify_notify_rep_msg_fun(TransId, TermId)).
1218-endif.
1219
1220rarpanp_mg_event_sequence(text, tcp) ->
1221    DecodeFun = ?rarpanp_mg_decode_msg_fun(megaco_pretty_text_encoder, []),
1222    EncodeFun = ?rarpanp_mg_encode_msg_fun(megaco_pretty_text_encoder, []),
1223    Mid       = {deviceName,"mg"},
1224    ServiceChangeReq = rarpanp_mg_service_change_request_msg(Mid, 1, 0),
1225    ScrVerifyFun = ?rarpanp_mg_verify_service_change_rep_msg_fun(),
1226    TransId = 2,
1227    TermId = #megaco_term_id{id = ["00000000","00000000","01101101"]},
1228    NotifyReq = rarpanp_mg_notify_request_msg(Mid, TransId, 1, TermId, 1),
1229    NrVerifyFun = ?rarpanp_mg_verify_notify_rep_msg_fun(TransId, TermId),
1230    EvSeq = [{debug,  true},
1231             {decode, DecodeFun},
1232             {encode, EncodeFun},
1233             {connect, 2944},
1234             {send, "service-change-request", ServiceChangeReq},
1235             {expect_receive, "service-change-reply", {ScrVerifyFun, 10000}},
1236             {send, "notify request", NotifyReq},
1237             {expect_receive, "notify-reply", {NrVerifyFun, 10000}},
1238             {expect_nothing, 11000},
1239             disconnect
1240            ],
1241    EvSeq.
1242
1243
1244-ifndef(megaco_hipe_special).
1245rarpanp_mg_encode_msg_fun(Mod, Conf) ->
1246    fun(M) ->
1247            encode_msg(M, Mod, Conf)
1248    end.
1249-endif.
1250
1251-ifndef(megaco_hipe_special).
1252rarpanp_mg_decode_msg_fun(Mod, Conf) ->
1253    fun(M) ->
1254            decode_msg(M, Mod, Conf)
1255    end.
1256-endif.
1257
1258-ifndef(megaco_hipe_special).
1259rarpanp_mg_verify_service_change_rep_msg_fun() ->
1260    fun(Msg) ->
1261	    (catch rarpanp_mg_verify_service_change_rep_msg(Msg))
1262    end.
1263-endif.
1264
1265rarpanp_mg_verify_service_change_rep_msg(#'MegacoMessage'{mess = Mess} = M) ->
1266    io:format("rarpanp_mg_verify_service_change_rep_msg -> entry with"
1267	      "~n   Mess:  ~p"
1268	      "~n", [Mess]),
1269    Body =
1270	case Mess of
1271	    #'Message'{version     = _V,
1272                       mId         = _MgMid,
1273                       messageBody = MsgBody} ->
1274		MsgBody;
1275	    _ ->
1276		throw({error, {invalid_Message, Mess}})
1277	end,
1278    Trans =
1279	case Body of
1280            {transactions, [Transactions]} ->
1281		Transactions;
1282	    _ ->
1283		throw({error, {invalid_messageBody, Body}})
1284	end,
1285    TR =
1286	case Trans of
1287            {transactionReply, TransReply} ->
1288		TransReply;
1289	    _ ->
1290		throw({error, {invalid_transactions, Trans}})
1291	end,
1292    TRes =
1293	case TR of
1294            #'TransactionReply'{transactionId = _Tid,
1295                                immAckRequired = asn1_NOVALUE,
1296                                transactionResult = TransRes} ->
1297		TransRes;
1298	    _ ->
1299		throw({error, {invalid_transactionReply, TR}})
1300	end,
1301    AR =
1302	case TRes of
1303            {actionReplies, [ActRes]} ->
1304		ActRes;
1305	    _ ->
1306		throw({error, {invalid_transactionResult, TRes}})
1307	end,
1308    CR =
1309	case AR of
1310            #'ActionReply'{contextId       = _Cid,
1311                           errorDescriptor = asn1_NOVALUE,
1312                           contextReply    = _CtxReq,
1313                           commandReply    = [CmdRep]} ->
1314		CmdRep;
1315	    _ ->
1316		throw({error, {invalid_actionReplies, AR}})
1317	end,
1318    SCR =
1319	case CR of
1320            {serviceChangeReply, ServChRep} ->
1321		ServChRep;
1322	    _ ->
1323		throw({error, {invalid_commandReply, CR}})
1324	end,
1325    SCRes =
1326	case SCR of
1327            #'ServiceChangeReply'{terminationID       = _TermID,
1328                                  serviceChangeResult = ServChRes} ->
1329		ServChRes;
1330	    _ ->
1331		throw({error, {invalid_serviceChangeReply, SCR}})
1332	end,
1333    SCRP =
1334	case SCRes of
1335            {serviceChangeResParms, Parms} ->
1336		Parms;
1337	    _ ->
1338		throw({error, {invalid_serviceChangeResult, SCRes}})
1339	end,
1340    case SCRP of
1341	#'ServiceChangeResParm'{serviceChangeMgcId = _MgcMid} ->
1342            {ok, M};
1343	_ ->
1344	    {error, {invalid_serviceChangeResParms, SCRP}}
1345    end;
1346rarpanp_mg_verify_service_change_rep_msg(Crap) ->
1347    {error, {invalid_message, Crap}}.
1348
1349-ifndef(megaco_hipe_special).
1350rarpanp_mg_verify_notify_rep_msg_fun(TransId, TermId) ->
1351    fun(Msg) ->
1352	    (catch rarpanp_mg_verify_notify_rep_msg(Msg, TransId, TermId))
1353    end.
1354-endif.
1355
1356rarpanp_mg_verify_notify_rep_msg(#'MegacoMessage'{mess = Mess} = M,
1357			     TransId, TermId) ->
1358    io:format("rarpanp_mg_verify_notify_rep_msg -> entry with"
1359	      "~n   TransId: ~p"
1360	      "~n   TermId:  ~p"
1361	      "~n   Mess:    ~p"
1362	      "~n", [TransId, TermId, Mess]),
1363    Body =
1364	case Mess of
1365	    #'Message'{version     = _V,
1366                       mId         = _MgMid,
1367                       messageBody = MsgBody} ->
1368		MsgBody;
1369	    _ ->
1370		throw({error, {invalid_Message, Mess}})
1371	end,
1372    Trans =
1373	case Body of
1374            {transactions, [Transactions]} ->
1375		Transactions;
1376	    _ ->
1377		throw({error, {invalid_messageBody, Body}})
1378	end,
1379    TR =
1380	case Trans of
1381            {transactionReply, TransReply} ->
1382		TransReply;
1383	    _ ->
1384		throw({error, {invalid_transactions, Trans}})
1385	end,
1386    TRes =
1387	case TR of
1388            #'TransactionReply'{transactionId     = TransId,
1389                                immAckRequired    = asn1_NOVALUE, % No ack
1390                                transactionResult = TransRes} ->
1391		TransRes;
1392	    _ ->
1393		throw({error, {invalid_transactionReply, TR}})
1394	end,
1395    AR =
1396	case TRes of
1397            {actionReplies, [ActRes]} ->
1398		ActRes;
1399	    _ ->
1400		throw({error, {invalid_transactionResult, TRes}})
1401	end,
1402    CR =
1403	case AR of
1404            #'ActionReply'{contextId       = _Cid,
1405                           errorDescriptor = asn1_NOVALUE,
1406                           contextReply    = _CtxReq,
1407                           commandReply    = [CmdRep]} ->
1408		CmdRep;
1409	    _ ->
1410		throw({error, {invalid_actionReplies, AR}})
1411	end,
1412    NR =
1413	case CR of
1414            {notifyReply, NotifyRep} ->
1415		NotifyRep;
1416	    _ ->
1417		throw({error, {invalid_commandReply, CR}})
1418	end,
1419
1420    case NR of
1421	#'NotifyReply'{terminationID   = [TermId],
1422		       errorDescriptor = asn1_NOVALUE} ->
1423	    io:format("rarpanp_mg_verify_notify_rep_msg -> done when verifyed"
1424		      "~n", []),
1425            {ok, M};
1426	#'NotifyReply'{terminationID   = A,
1427		       errorDescriptor = B} ->
1428	    throw({error, {invalid_notifyReply,
1429			   {A, TermId},
1430			   {B, asn1_NOVALUE}}});
1431	_ ->
1432	    throw({error, {invalid_notifyReply, NR}})
1433    end;
1434rarpanp_mg_verify_notify_rep_msg(_TransId, _TermId, Crap) ->
1435    {error, {invalid_message, Crap}}.
1436
1437rarpanp_mg_service_change_request_ar(_Mid, Cid) ->
1438    Prof  = cre_serviceChangeProf("resgw", 1),
1439    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
1440    Root  = #megaco_term_id{id = ["root"]},
1441    SCR   = cre_serviceChangeReq([Root], SCP),
1442    CMD   = cre_command(SCR),
1443    CR    = cre_cmdReq(CMD),
1444    cre_actionReq(Cid, [CR]).
1445
1446rarpanp_mg_service_change_request_msg(Mid, TransId, Cid) ->
1447    AR    = rarpanp_mg_service_change_request_ar(Mid, Cid),
1448    TR    = cre_transReq(TransId, [AR]),
1449    Trans = cre_transaction(TR),
1450    Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
1451    cre_megacoMessage(Mess).
1452
1453rarpanp_mg_notify_request_ar(Rid, Tid, Cid) ->
1454    TT      = cre_timeNotation("19990729", "22000000"),
1455    Ev      = cre_obsEvent("al/of", TT),
1456    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
1457    NR      = cre_notifyReq([Tid], EvsDesc),
1458    CMD     = cre_command(NR),
1459    CR      = cre_cmdReq(CMD),
1460    cre_actionReq(Cid, [CR]).
1461
1462rarpanp_mg_notify_request_msg(Mid, TransId, Rid, TermId, Cid) ->
1463    AR      = rarpanp_mg_notify_request_ar(Rid, TermId, Cid),
1464    TR      = cre_transReq(TransId, [AR]),
1465    Trans   = cre_transaction(TR),
1466    Mess    = cre_message(?VERSION, Mid, cre_transactions([Trans])),
1467    cre_megacoMessage(Mess).
1468
1469
1470%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1471
1472request_and_reply_pending_ack_one_pending(suite) ->
1473    [];
1474request_and_reply_pending_ack_one_pending(doc) ->
1475    ["This test case tests that megaco correctly handles the return "
1476     "value handle_pending_ack from handle_trans_request when ONE "
1477     "pending message has been sent"];
1478request_and_reply_pending_ack_one_pending(Config) when is_list(Config) ->
1479    Pre = fun() ->
1480                  MgcNode = make_node_name(mgc),
1481                  MgNode  = make_node_name(mg),
1482                  d("start nodes: "
1483                    "~n      MgcNode: ~p"
1484                    "~n      MgNode:  ~p",
1485                    [MgcNode, MgNode]),
1486                  Nodes = [MgcNode, MgNode],
1487                  ok = ?START_NODES(Nodes, true),
1488                  Nodes
1489          end,
1490    Case = fun do_request_and_reply_pending_ack_one_pending/1,
1491    Post = fun(Nodes) ->
1492                   d("stop nodes"),
1493                   ?STOP_NODES(lists:reverse(Nodes))
1494           end,
1495    try_tc(rar_paop, Pre, Case, Post).
1496
1497do_request_and_reply_pending_ack_one_pending([MgcNode, MgNode]) ->
1498    d("[MGC] start the simulator"),
1499    {ok, Mgc} = megaco_test_megaco_generator:start_link("MGC", MgcNode),
1500
1501    d("[MGC] create the event sequence"),
1502    %% MgcEvSeq = rarpaop_mgc_event_sequence(text, tcp),
1503    MgcEvSeq = rarpaop_mgc_event_sequence(binary, tcp),
1504
1505    i("wait some time before starting the MGC simulation"),
1506    sleep(1000),
1507
1508    d("[MGC] start the simulation"),
1509    {ok, MgcId} = megaco_test_megaco_generator:exec(Mgc, MgcEvSeq),
1510
1511    %% i("wait some time before starting the MG simulator"),
1512    %% sleep(1000),
1513
1514    i("await MGC ready announcement"),
1515    receive
1516        announce_mgc ->
1517            i("received MGC ready announcement"),
1518            ok
1519    end,
1520
1521    d("[MG] start the simulator (generator)"),
1522    {ok, Mg} = megaco_test_tcp_generator:start_link("MG", MgNode),
1523
1524    d("[MG] create the event sequence"),
1525    %% MgEvSeq = rarpaop_mg_event_sequence(text, tcp),
1526    MgEvSeq = rarpaop_mg_event_sequence(binary, tcp),
1527
1528    i("wait some time before starting the MG simulation"),
1529    sleep(1000),
1530
1531    d("[MG] start the simulation"),
1532    {ok, MgId} = megaco_test_tcp_generator:exec(Mg, MgEvSeq),
1533
1534    d("await the generator reply(s)"),
1535    await_completion([MgcId, MgId]),
1536
1537    %% Tell Mgc to stop
1538    i("[MGC] stop generator"),
1539    megaco_test_tcp_generator:stop(Mgc),
1540
1541    %% Tell Mg to stop
1542    i("[MG] stop generator"),
1543    megaco_test_megaco_generator:stop(Mg),
1544
1545    i("done", []),
1546    ok.
1547
1548
1549%%
1550%% MGC generator stuff
1551%%
1552-ifdef(megaco_hipe_special).
1553-define(rarpaop_mgc_verify_handle_connect_fun(),
1554        {?MODULE, rarpaop_mgc_verify_handle_connect, []}).
1555-define(rarpaop_mgc_verify_service_change_req_fun(Mid),
1556        {?MODULE, rarpaop_mgc_verify_service_change_req, [Mid]}).
1557-define(rarpaop_mgc_verify_notify_req_fun(),
1558        {?MODULE, rarpaop_mgc_verify_notify_request, []}).
1559-define(rarpaop_mgc_verify_reply_ack_fun(),
1560	{?MODULE, rarpaop_mgc_verify_reply_ack, []}).
1561-define(rarpaop_mgc_verify_handle_disconnect_fun(),
1562        {?MODULE, rarpaop_mgc_verify_handle_disconnect, []}).
1563-else.
1564-define(rarpaop_mgc_verify_handle_connect_fun(),
1565        fun rarpaop_mgc_verify_handle_connect/1).
1566-define(rarpaop_mgc_verify_service_change_req_fun(Mid),
1567        rarpaop_mgc_verify_service_change_req_fun(Mid)).
1568-define(rarpaop_mgc_verify_notify_req_fun(),
1569	rarpaop_mgc_verify_notify_request_fun()).
1570-define(rarpaop_mgc_verify_reply_ack_fun(),
1571	rarpaop_mgc_verify_reply_ack_fun()).
1572-define(rarpaop_mgc_verify_handle_disconnect_fun(),
1573	fun rarpaop_mgc_verify_handle_disconnect/1).
1574-endif.
1575
1576rarpaop_mgc_event_sequence(text, tcp) ->
1577    Port      = 2944,
1578    TranspMod = megaco_tcp,
1579    EncMod    = megaco_pretty_text_encoder,
1580    EncConf   = [],
1581    rarpaop_mgc_event_sequence(Port, TranspMod, EncMod, EncConf);
1582rarpaop_mgc_event_sequence(binary, tcp) ->
1583    Port      = 2945,
1584    TranspMod = megaco_tcp,
1585    EncMod    = megaco_ber_encoder,
1586    EncConf   = [],
1587    rarpaop_mgc_event_sequence(Port, TranspMod, EncMod, EncConf).
1588
1589rarpaop_mgc_event_sequence(Port, TranspMod, EncMod, EncConf) ->
1590    CTRL = self(),
1591    Mid = {deviceName,"ctrl"},
1592    RI = [
1593          {port,             Port},
1594          {transport_module, TranspMod},
1595          {encoding_module,  EncMod},
1596          {encoding_config,  EncConf}
1597         ],
1598    ConnectVerify = ?rarpaop_mgc_verify_handle_connect_fun(),
1599    ScrVerify     = ?rarpaop_mgc_verify_service_change_req_fun(Mid),
1600    NrVerify      = ?rarpaop_mgc_verify_notify_req_fun(),
1601    AckVerify     = ?rarpaop_mgc_verify_reply_ack_fun(),
1602    DiscoVerify   = ?rarpaop_mgc_verify_handle_disconnect_fun(),
1603    EvSeq = [
1604             {debug, true},
1605             {megaco_trace, disable},
1606             {megaco_trace, max},
1607             megaco_start,
1608             {megaco_start_user, Mid, RI, []},
1609             {megaco_update_user_info, sent_pending_limit, 100},
1610             start_transport,
1611             listen,
1612
1613             %% ANNOUNCE READY
1614             {trigger, fun() -> CTRL ! announce_mgc end},
1615
1616             {megaco_callback, handle_connect,       ConnectVerify},
1617             {megaco_conn_info, all},
1618             {megaco_callback, handle_trans_request, ScrVerify},
1619	     {megaco_callback, handle_trans_request, NrVerify},
1620	     {megaco_callback, handle_trans_ack,     AckVerify},
1621             {megaco_callback, nocall, 10000},
1622             {megaco_callback, handle_disconnect,    DiscoVerify},
1623             megaco_stop_user,
1624             megaco_stop
1625            ],
1626    EvSeq.
1627
1628%% Connect verification
1629rarpaop_mgc_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
1630    {ok, CH, ok};
1631rarpaop_mgc_verify_handle_connect(Else) ->
1632    {error, Else, ok}.
1633
1634%% Service Change verification
1635-ifndef(megaco_hipe_special).
1636rarpaop_mgc_verify_service_change_req_fun(Mid) ->
1637    fun(Req) ->
1638	    rarpaop_mgc_verify_service_change_req(Req, Mid)
1639    end.
1640-endif.
1641
1642rarpaop_mgc_verify_service_change_req(
1643  {handle_trans_request, _, ?VERSION, [AR]}, Mid) ->
1644    (catch rarpaop_do_verify_service_change_req(AR, Mid));
1645rarpaop_mgc_verify_service_change_req(Crap, _Mid) ->
1646    ED       = cre_ErrDesc(Crap),
1647    ErrReply = {discard_ack, ED},
1648    {error, Crap, ErrReply}.
1649
1650rarpaop_do_verify_service_change_req(AR, Mid) ->
1651    CR =
1652	case AR of
1653	    #'ActionRequest'{commandRequests = [CmdReq]} ->
1654		CmdReq;
1655	    _ ->
1656		Err1      = {invalid_action_request, AR},
1657		ED1       = cre_ErrDesc(AR),
1658		ErrReply1 = {discard_ack, ED1},
1659		throw({error, Err1, ErrReply1})
1660	end,
1661    Cmd =
1662	case CR of
1663	    #'CommandRequest'{command = Command} ->
1664		Command;
1665	    _ ->
1666		Err2      = {invalid_command_request, CR},
1667		ED2       = cre_ErrDesc(CR),
1668		ErrReply2 = {discard_ack, ED2},
1669		throw({error, Err2, ErrReply2})
1670	end,
1671    {Tid, Parms} =
1672	case Cmd of
1673	    {serviceChangeReq,
1674	     #'ServiceChangeRequest'{terminationID = [TermID],
1675				     serviceChangeParms = ServChParms}} ->
1676		{TermID, ServChParms};
1677	    _ ->
1678		Err3      = {invalid_command, Cmd},
1679		ED3       = cre_ErrDesc(Cmd),
1680		ErrReply3 = {discard_ack, ED3},
1681		throw({error, Err3, ErrReply3})
1682	end,
1683    case Tid of
1684	#megaco_term_id{contains_wildcards = false, id = ["root"]} ->
1685	    ok;
1686	_ ->
1687	    Err4      = {invalid_termination_id, Tid},
1688	    ED4       = cre_ErrDesc(Tid),
1689	    ErrReply4 = {discard_ack, ED4},
1690	    throw({error, Err4, ErrReply4})
1691    end,
1692    case Parms of
1693	#'ServiceChangeParm'{serviceChangeMethod = restart,
1694			     serviceChangeReason = [[$9,$0,$1|_]]} ->
1695	    AckData = [rarpaop_mgc_service_change_reply_ar(Mid, 1)],
1696	    Reply   = {discard_ack, AckData},
1697	    {ok, AR, Reply};
1698	_ ->
1699	    Err5      = {invalid_SCP, Parms},
1700	    ED5       = cre_ErrDesc(Parms),
1701	    ErrReply5 = {discard_ack, ED5},
1702	    {error, Err5, ErrReply5}
1703    end.
1704
1705
1706%% Notify Request verification
1707-ifndef(megaco_hipe_special).
1708rarpaop_mgc_verify_notify_request_fun() ->
1709    fun(Req) ->
1710	    rarpaop_mgc_verify_notify_request(Req)
1711    end.
1712-endif.
1713
1714rarpaop_mgc_verify_notify_request({handle_trans_request, _, ?VERSION, [AR]}) ->
1715    (catch rarpaop_mgc_do_verify_notify_request(AR));
1716rarpaop_mgc_verify_notify_request(Crap) ->
1717    ED       = cre_ErrDesc(Crap),
1718    ErrReply = {discard_ack, ED},
1719    {error, Crap, ErrReply}.
1720
1721rarpaop_mgc_do_verify_notify_request(AR) ->
1722    {Cid, CR} =
1723	case AR of
1724	    #'ActionRequest'{contextId       = CtxID,
1725			     commandRequests = [CmdReq]} ->
1726		{CtxID, CmdReq};
1727	    _ ->
1728		Err1      = {invalid_action_request, AR},
1729		ED1       = cre_ErrDesc(AR),
1730		ErrReply1 = {discard_ack, ED1},
1731		throw({error, Err1, ErrReply1})
1732	end,
1733    Cmd =
1734	case CR of
1735	    #'CommandRequest'{command = Command} ->
1736		Command;
1737	    _ ->
1738		Err2      = {invalid_command_request, CR},
1739		ED2       = cre_ErrDesc(CR),
1740		ErrReply2 = {discard_ack, ED2},
1741		throw({error, Err2, ErrReply2})
1742	end,
1743    NR =
1744	case Cmd of
1745	    {notifyReq, NotifReq} ->
1746		NotifReq;
1747	    _ ->
1748		Err3      = {invalid_command, Cmd},
1749		ED3       = cre_ErrDesc(Cmd),
1750		ErrReply3 = {discard_ack, ED3},
1751		throw({error, Err3, ErrReply3})
1752	end,
1753    {Tid, OED} =
1754	case NR of
1755	    #'NotifyRequest'{terminationID            = [TermID],
1756			     observedEventsDescriptor = ObsEvsDesc,
1757			     errorDescriptor          = asn1_NOVALUE} ->
1758		{TermID, ObsEvsDesc};
1759	    _ ->
1760		Err4      = {invalid_NR, NR},
1761		ED4       = cre_ErrDesc(NR),
1762		ErrReply4 = {discard_ack, ED4},
1763		throw({error, Err4, ErrReply4})
1764	end,
1765    OE =
1766	case OED of
1767	    #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
1768		ObsEvLst;
1769	    _ ->
1770		Err5      = {invalid_OED, OED},
1771		ED5       = cre_ErrDesc(NR),
1772		ErrReply5 = {discard_ack, ED5},
1773		throw({error, Err5, ErrReply5})
1774	end,
1775    case OE of
1776	#'ObservedEvent'{eventName = "al/of"} ->
1777	    AckData = notify_request_verified,
1778	    Replies = [rarpaop_mgc_notify_reply_ar(Cid, Tid)],
1779	    Reply   = {{handle_pending_ack, AckData}, Replies},
1780	    {ok, 5000, AR, Reply};
1781	_ ->
1782	    Err6      = {invalid_OE, OE},
1783	    ED6       = cre_ErrDesc(OE),
1784	    ErrReply6 = {discard_ack, ED6},
1785	    throw({error, Err6, ErrReply6})
1786    end.
1787
1788
1789%% Ack verification
1790-ifndef(megaco_hipe_special).
1791rarpaop_mgc_verify_reply_ack_fun() ->
1792    fun(M) ->
1793	    rarpaop_mgc_verify_reply_ack(M)
1794    end.
1795-endif.
1796
1797rarpaop_mgc_verify_reply_ack({handle_trans_ack, _, ?VERSION, ok, _}) ->
1798    io:format("rarpaop_mgc_verify_reply_ack -> ok~n", []),
1799    {ok, ok, ok};
1800rarpaop_mgc_verify_reply_ack({handle_trans_ack, _, ?VERSION, AS, AD} = Crap) ->
1801    io:format("rarpaop_mgc_verify_reply_ack -> incorrect ack-status:"
1802	      "~n   AS: ~p"
1803	      "~n   AD: ~p"
1804	      "~n", [AS, AD]),
1805    ED       = cre_ErrDesc({invalid_ack_status, {AS, AD}}),
1806    ErrReply = {discard_ack, ED},
1807    {error, Crap, ErrReply};
1808rarpaop_mgc_verify_reply_ack(Crap) ->
1809    io:format("rarpaop_mgc_verify_reply_ack -> invalid ack:"
1810	      "~n   Crap: ~p"
1811	      "~n", [Crap]),
1812    ED       = cre_ErrDesc(Crap),
1813    ErrReply = {discard_ack, ED},
1814    {error, Crap, ErrReply}.
1815
1816
1817%% Disconnect verification
1818rarpaop_mgc_verify_handle_disconnect({handle_disconnect, CH, ?VERSION, _R}) ->
1819    {ok, CH, ok};
1820rarpaop_mgc_verify_handle_disconnect(Else) ->
1821    {error, Else, ok}.
1822
1823rarpaop_mgc_service_change_reply_ar(Mid, Cid) ->
1824    SCRP  = cre_serviceChangeResParm(Mid),
1825    SCRes = cre_serviceChangeResult(SCRP),
1826    Root  = #megaco_term_id{id = ["root"]},
1827    SCR   = cre_serviceChangeReply([Root], SCRes),
1828    CR    = cre_cmdReply(SCR),
1829    AR    = cre_actionReply(Cid, [CR]),
1830    AR.
1831
1832rarpaop_mgc_notify_reply_ar(Cid, TermId) ->
1833    NR    = cre_notifyReply([TermId]),
1834    CR    = cre_cmdReply(NR),
1835    cre_actionReply(Cid, [CR]).
1836
1837
1838%%
1839%% MG generator stuff
1840%%
1841-ifdef(megaco_hipe_special).
1842-define(rarpaop_mg_decode_msg_fun(Mod, Conf),
1843	{?MODULE, decode_msg, [Mod, Conf]}).
1844-define(rarpaop_mg_encode_msg_fun(Mod, Conf),
1845	{?MODULE, encode_msg, [Mod, Conf]}).
1846-define(rarpaop_mg_verify_service_change_rep_msg_fun(),
1847	{?MODULE, rarpaop_mg_verify_service_change_rep_msg, []}).
1848-define(rarpaop_mg_verify_pending_msg_fun(TransId),
1849	{?MODULE, rarpaop_mg_verify_pending_msg, [TransId]}).
1850-define(rarpaop_mg_verify_notify_rep_msg_fun(TransId, TermId),
1851	{?MODULE, rarpaop_mg_verify_notify_rep_msg, [TransId, TermId]}).
1852-else.
1853-define(rarpaop_mg_decode_msg_fun(Mod, Conf),
1854	rarpaop_mg_decode_msg_fun(Mod, Conf)).
1855-define(rarpaop_mg_encode_msg_fun(Mod, Conf),
1856	rarpaop_mg_encode_msg_fun(Mod, Conf)).
1857-define(rarpaop_mg_verify_service_change_rep_msg_fun(),
1858	rarpaop_mg_verify_service_change_rep_msg_fun()).
1859-define(rarpaop_mg_verify_pending_msg_fun(TransId),
1860	rarpaop_mg_verify_pending_msg_fun(TransId)).
1861-define(rarpaop_mg_verify_notify_rep_msg_fun(TransId, TermId),
1862	rarpaop_mg_verify_notify_rep_msg_fun(TransId, TermId)).
1863-endif.
1864
1865rarpaop_mg_event_sequence(text, tcp) ->
1866    Port      = 2944,
1867    EncMod    = megaco_pretty_text_encoder,
1868    EncConf   = [],
1869    rarpaop_mg_event_sequence(Port, EncMod, EncConf);
1870rarpaop_mg_event_sequence(binary, tcp) ->
1871    Port      = 2945,
1872    EncMod    = megaco_ber_encoder,
1873    EncConf   = [],
1874    rarpaop_mg_event_sequence(Port, EncMod, EncConf).
1875
1876rarpaop_mg_event_sequence(Port, EncMod, EncConf) ->
1877    DecodeFun = ?rarpaop_mg_decode_msg_fun(EncMod, EncConf),
1878    EncodeFun = ?rarpaop_mg_encode_msg_fun(EncMod, EncConf),
1879    Mid       = {deviceName, "mg"},
1880    TransId = 2,
1881    TermId = #megaco_term_id{id = ["00000000","00000000","01101101"]},
1882    ServiceChangeReq = rarpaop_mg_service_change_request_msg(Mid, 1, 0),
1883    NotifyReq = rarpaop_mg_notify_request_msg(Mid, TransId, 1, TermId, 1),
1884    Ack = rarpaop_mg_ack_msg(Mid, TransId),
1885    ScrVerifyFun  = ?rarpaop_mg_verify_service_change_rep_msg_fun(),
1886    PendVerifyFun = ?rarpaop_mg_verify_pending_msg_fun(TransId),
1887    NrVerifyFun   = ?rarpaop_mg_verify_notify_rep_msg_fun(TransId, TermId),
1888    EvSeq = [{debug,  true},
1889             {decode, DecodeFun},
1890             {encode, EncodeFun},
1891             {connect, Port},
1892             {send, "service-change-request", ServiceChangeReq},
1893             {expect_receive, "service-change-reply", {ScrVerifyFun, 10000}},
1894             {send, "notify request", NotifyReq},
1895             {sleep, 2000},
1896             {send, "notify request", NotifyReq},
1897             {expect_receive, "pending", {PendVerifyFun, 5000}},
1898             {expect_receive, "notify-reply", {NrVerifyFun, 5000}},
1899             {send, "reply ack", Ack},
1900             {expect_nothing, 11000},
1901             disconnect
1902            ],
1903    EvSeq.
1904
1905-ifndef(megaco_hipe_special).
1906rarpaop_mg_encode_msg_fun(Mod, Conf) ->
1907    fun(M) ->
1908            encode_msg(M, Mod, Conf)
1909    end.
1910-endif.
1911
1912-ifndef(megaco_hipe_special).
1913rarpaop_mg_decode_msg_fun(Mod, Conf) ->
1914    fun(M) ->
1915            decode_msg(M, Mod, Conf)
1916    end.
1917-endif.
1918
1919-ifndef(megaco_hipe_special).
1920rarpaop_mg_verify_service_change_rep_msg_fun() ->
1921    fun(Msg) ->
1922	    (catch rarpaop_mg_verify_service_change_rep_msg(Msg))
1923    end.
1924-endif.
1925
1926rarpaop_mg_verify_service_change_rep_msg(#'MegacoMessage'{mess = Mess} = M) ->
1927    Body =
1928	case Mess of
1929	    #'Message'{version     = _V,
1930                       mId         = _MgMid,
1931                       messageBody = MsgBody} ->
1932		MsgBody;
1933	    _ ->
1934		throw({error, {invalid_Message, Mess}})
1935	end,
1936    Trans =
1937	case Body of
1938            {transactions, [Transactions]} ->
1939		Transactions;
1940	    _ ->
1941		throw({error, {invalid_messageBody, Body}})
1942	end,
1943    TR =
1944	case Trans of
1945            {transactionReply, TransReply} ->
1946		TransReply;
1947	    _ ->
1948		throw({error, {invalid_transactions, Trans}})
1949	end,
1950    TRes =
1951	case TR of
1952            #'TransactionReply'{transactionId = _Tid,
1953                                immAckRequired = asn1_NOVALUE,
1954                                transactionResult = TransRes} ->
1955		TransRes;
1956	    _ ->
1957		throw({error, {invalid_transactionReply, TR}})
1958	end,
1959    AR =
1960	case TRes of
1961            {actionReplies, [ActRes]} ->
1962		ActRes;
1963	    _ ->
1964		throw({error, {invalid_transactionResult, TRes}})
1965	end,
1966    CR =
1967	case AR of
1968            #'ActionReply'{contextId       = _Cid,
1969                           errorDescriptor = asn1_NOVALUE,
1970                           contextReply    = _CtxReq,
1971                           commandReply    = [CmdRep]} ->
1972		CmdRep;
1973	    _ ->
1974		throw({error, {invalid_actionReplies, AR}})
1975	end,
1976    SCR =
1977	case CR of
1978            {serviceChangeReply, ServChRep} ->
1979		ServChRep;
1980	    _ ->
1981		throw({error, {invalid_commandReply, CR}})
1982	end,
1983    SCRes =
1984	case SCR of
1985            #'ServiceChangeReply'{terminationID       = _TermID,
1986                                  serviceChangeResult = ServChRes} ->
1987		ServChRes;
1988	    _ ->
1989		throw({error, {invalid_serviceChangeReply, SCR}})
1990	end,
1991    SCRP =
1992	case SCRes of
1993            {serviceChangeResParms, Parms} ->
1994		Parms;
1995	    _ ->
1996		throw({error, {invalid_serviceChangeResult, SCRes}})
1997	end,
1998    case SCRP of
1999	#'ServiceChangeResParm'{serviceChangeMgcId = _MgcMid} ->
2000            {ok, M};
2001	_ ->
2002	    {error, {invalid_serviceChangeResParms, SCRP}}
2003    end;
2004rarpaop_mg_verify_service_change_rep_msg(Crap) ->
2005    {error, {invalid_message, Crap}}.
2006
2007-ifndef(megaco_hipe_special).
2008rarpaop_mg_verify_pending_msg_fun(TransId) ->
2009    fun(Msg) ->
2010	    (catch rarpaop_mg_verify_pending_msg(Msg, TransId))
2011    end.
2012-endif.
2013
2014rarpaop_mg_verify_pending_msg(#'MegacoMessage'{mess = Mess} = M, TransId) ->
2015    Body =
2016	case Mess of
2017	    #'Message'{version     = _V,
2018                       mId         = _MgMid,
2019                       messageBody = MsgBody} ->
2020		MsgBody;
2021	    _ ->
2022		throw({error, {invalid_Message, Mess}})
2023	end,
2024    Trans =
2025	case Body of
2026            {transactions, [Transactions]} ->
2027		Transactions;
2028	    _ ->
2029		throw({error, {invalid_messageBody, Body}})
2030	end,
2031    TP =
2032	case Trans of
2033            {transactionPending, TransPending} ->
2034		TransPending;
2035	    _ ->
2036		throw({error, {invalid_transactions, Trans}})
2037	end,
2038    case TP of
2039	#'TransactionPending'{transactionId = TransId} ->
2040	    {ok, M};
2041	_ ->
2042	    throw({error, {invalid_transactionPending, TP}})
2043    end;
2044rarpaop_mg_verify_pending_msg(Crap, _TransId) ->
2045    {error, {invalid_message, Crap}}.
2046
2047-ifndef(megaco_hipe_special).
2048rarpaop_mg_verify_notify_rep_msg_fun(TransId, TermId) ->
2049    fun(Msg) ->
2050	    (catch rarpaop_mg_verify_notify_rep_msg(Msg, TransId, TermId))
2051    end.
2052-endif.
2053
2054rarpaop_mg_verify_notify_rep_msg(#'MegacoMessage'{mess = Mess} = M,
2055				 TransId, TermId) ->
2056    Body =
2057	case Mess of
2058	    #'Message'{version     = _V,
2059                       mId         = _MgMid,
2060                       messageBody = MsgBody} ->
2061		MsgBody;
2062	    _ ->
2063		throw({error, {invalid_Message, Mess}})
2064	end,
2065    Trans =
2066	case Body of
2067            {transactions, [Transactions]} ->
2068		Transactions;
2069	    _ ->
2070		throw({error, {invalid_messageBody, Body}})
2071	end,
2072    TR =
2073	case Trans of
2074            {transactionReply, TransReply} ->
2075		TransReply;
2076	    _ ->
2077		throw({error, {invalid_transactions, Trans}})
2078	end,
2079    TRes =
2080	case TR of
2081            #'TransactionReply'{transactionId     = TransId,
2082                                immAckRequired    = 'NULL', % Ack
2083                                transactionResult = TransRes} ->
2084		TransRes;
2085	    _ ->
2086		throw({error, {invalid_transactionReply, TR}})
2087	end,
2088    AR =
2089	case TRes of
2090            {actionReplies, [ActRes]} ->
2091		ActRes;
2092	    _ ->
2093		throw({error, {invalid_transactionResult, TRes}})
2094	end,
2095    CR =
2096	case AR of
2097            #'ActionReply'{contextId       = _Cid,
2098                           errorDescriptor = asn1_NOVALUE,
2099                           contextReply    = _CtxReq,
2100                           commandReply    = [CmdRep]} ->
2101		CmdRep;
2102	    _ ->
2103		throw({error, {invalid_actionReplies, AR}})
2104	end,
2105    NR =
2106	case CR of
2107            {notifyReply, NotifyRep} ->
2108		NotifyRep;
2109	    _ ->
2110		throw({error, {invalid_commandReply, CR}})
2111	end,
2112
2113    case NR of
2114	#'NotifyReply'{terminationID   = [TermId],
2115		       errorDescriptor = asn1_NOVALUE} ->
2116            {ok, M};
2117	#'NotifyReply'{terminationID   = A,
2118		       errorDescriptor = B} ->
2119	    throw({error, {invalid_notifyReply,
2120			   {A, TermId},
2121			   {B, asn1_NOVALUE}}});
2122	_ ->
2123	    throw({error, {invalid_notifyReply, NR}})
2124    end;
2125rarpaop_mg_verify_notify_rep_msg(Crap, _TransId, _TermId) ->
2126    {error, {invalid_message, Crap}}.
2127
2128rarpaop_mg_service_change_request_ar(_Mid, Cid) ->
2129    Prof  = cre_serviceChangeProf("resgw", 1),
2130    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
2131    Root  = #megaco_term_id{id = ["root"]},
2132    SCR   = cre_serviceChangeReq([Root], SCP),
2133    CMD   = cre_command(SCR),
2134    CR    = cre_cmdReq(CMD),
2135    cre_actionReq(Cid, [CR]).
2136
2137rarpaop_mg_service_change_request_msg(Mid, TransId, Cid) ->
2138    AR    = rarpaop_mg_service_change_request_ar(Mid, Cid),
2139    TR    = cre_transReq(TransId, [AR]),
2140    Trans = cre_transaction(TR),
2141    Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
2142    cre_megacoMessage(Mess).
2143
2144rarpaop_mg_ack_msg(Mid, TransId) ->
2145    TR    = cre_transRespAck(cre_transAck(TransId)),
2146    Trans = cre_transaction(TR),
2147    Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
2148    cre_megacoMessage(Mess).
2149
2150rarpaop_mg_notify_request_ar(Rid, Tid, Cid) ->
2151    TT      = cre_timeNotation("19990729", "22000000"),
2152    Ev      = cre_obsEvent("al/of", TT),
2153    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
2154    NR      = cre_notifyReq([Tid], EvsDesc),
2155    CMD     = cre_command(NR),
2156    CR      = cre_cmdReq(CMD),
2157    cre_actionReq(Cid, [CR]).
2158
2159rarpaop_mg_notify_request_msg(Mid, TransId, Rid, TermId, Cid) ->
2160    AR      = rarpaop_mg_notify_request_ar(Rid, TermId, Cid),
2161    TR      = cre_transReq(TransId, [AR]),
2162    Trans   = cre_transaction(TR),
2163    Mess    = cre_message(?VERSION, Mid, cre_transactions([Trans])),
2164    cre_megacoMessage(Mess).
2165
2166
2167%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2168
2169single_trans_req_and_reply(suite) ->
2170    [];
2171single_trans_req_and_reply(doc) ->
2172    ["Receive a (single) transaction request and then send a "
2173     "reply (discard ack). "
2174     "The MGC is a megaco instance (megaco event sequence) and the "
2175     "MG is emulated (tcp event sequence)"];
2176single_trans_req_and_reply(Config) when is_list(Config) ->
2177    Pre = fun() ->
2178                  MgcNode = make_node_name(mgc),
2179                  MgNode  = make_node_name(mg),
2180                  d("start nodes: "
2181                    "~n      MgcNode: ~p"
2182                    "~n      MgNode:  ~p",
2183                    [MgcNode, MgNode]),
2184                  Nodes = [MgcNode, MgNode],
2185                  ok = ?START_NODES(Nodes, true),
2186                  Nodes
2187          end,
2188    Case = fun do_single_trans_req_and_reply/1,
2189    Post = fun(Nodes) ->
2190                   d("stop nodes"),
2191                   ?STOP_NODES(lists:reverse(Nodes))
2192           end,
2193    try_tc(strar, Pre, Case, Post).
2194
2195do_single_trans_req_and_reply([MgcNode, MgNode]) ->
2196    d("[MGC] start the simulator "),
2197    {ok, Mgc} = megaco_test_megaco_generator:start_link("MGC", MgcNode),
2198
2199    d("[MGC] create the event sequence"),
2200    MgcEvSeq = strar_mgc_event_sequence(text, tcp),
2201
2202    i("wait some time before starting the MGC simulation"),
2203    sleep(1000),
2204
2205    d("[MGC] start the simulation"),
2206    {ok, MgcId} = megaco_test_megaco_generator:exec(Mgc, MgcEvSeq),
2207
2208    %% i("wait some time before starting the MG simulator"),
2209    %% sleep(1000),
2210
2211    i("await MGC ready announcement"),
2212    receive
2213        announce_mgc ->
2214            i("received MGC ready announcement"),
2215            ok
2216    end,
2217
2218    d("[MG] start the simulator (generator)"),
2219    {ok, Mg} = megaco_test_megaco_generator:start_link("MG", MgNode),
2220
2221    d("[MG] create the event sequence"),
2222    MgEvSeq = strar_mg_event_sequence(text, tcp),
2223
2224    i("wait some time before starting the MG simulation"),
2225    sleep(1000),
2226
2227    d("[MG] start the simulation"),
2228    {ok, MgId} = megaco_test_megaco_generator:exec(Mg, MgEvSeq),
2229
2230    d("await the generator reply(s)"),
2231    await_completion([MgcId, MgId], 30000),
2232
2233    %% Tell Mgc to stop
2234    i("[MGC] stop generator"),
2235    megaco_test_megaco_generator:stop(Mgc),
2236
2237    %% Tell Mg to stop
2238    i("[MG] stop generator"),
2239    megaco_test_megaco_generator:stop(Mg),
2240
2241    i("done", []),
2242    ok.
2243
2244
2245%%
2246%% MGC generator stuff
2247%%
2248-ifdef(megaco_hipe_special).
2249-define(strar_mgc_verify_handle_connect_fun(),
2250        {?MODULE, strar_mgc_verify_handle_connect, []}).
2251-define(strar_mgc_verify_service_change_req_fun(Mid),
2252        {?MODULE, strar_mgc_verify_service_change_req, [Mid]}).
2253-define(strar_mgc_verify_notify_req_fun(),
2254        {?MODULE, strar_mgc_verify_notify_request, []}).
2255-define(strar_mgc_verify_handle_disconnect_fun(),
2256        {?MODULE, strar_mgc_verify_handle_disconnect, []}).
2257-else.
2258-define(strar_mgc_verify_handle_connect_fun(),
2259        fun strar_mgc_verify_handle_connect/1).
2260-define(strar_mgc_verify_service_change_req_fun(Mid),
2261        strar_mgc_verify_service_change_req_fun(Mid)).
2262-define(strar_mgc_verify_notify_req_fun(),
2263	strar_mgc_verify_notify_request_fun()).
2264-define(strar_mgc_verify_handle_disconnect_fun(),
2265	fun strar_mgc_verify_handle_disconnect/1).
2266-endif.
2267
2268strar_mgc_event_sequence(text, tcp) ->
2269    CTRL = self(),
2270    Mid = {deviceName,"ctrl"},
2271    RI = [
2272	  {port,             2944},
2273	  {encoding_module,  megaco_pretty_text_encoder},
2274	  {encoding_config,  []},
2275	  {transport_module, megaco_tcp}
2276	 ],
2277    ConnectVerify          = ?strar_mgc_verify_handle_connect_fun(),
2278    ServiceChangeReqVerify = ?strar_mgc_verify_service_change_req_fun(Mid),
2279    NotifyReqVerify        = ?strar_mgc_verify_notify_req_fun(),
2280    DiscoVerify            = ?strar_mgc_verify_handle_disconnect_fun(),
2281    EvSeq = [
2282	     {debug, true},
2283	     {megaco_trace, disable},
2284	     megaco_start,
2285	     {megaco_start_user, Mid, RI, []},
2286	     start_transport,
2287	     listen,
2288
2289             %% ANNOUNCE READY
2290             {trigger, fun() -> CTRL ! announce_mgc end},
2291
2292	     {megaco_callback, handle_connect,       ConnectVerify},
2293	     {megaco_callback, handle_trans_request, ServiceChangeReqVerify},
2294	     {megaco_callback, handle_trans_request, NotifyReqVerify},
2295	     {megaco_callback, handle_disconnect,    DiscoVerify},
2296	     {sleep, 1000},
2297	     megaco_stop_user,
2298	     megaco_stop
2299	    ],
2300    EvSeq.
2301
2302
2303strar_mgc_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
2304    io:format("strar_mgc_verify_handle_connect -> ok"
2305	      "~n   CH: ~p~n", [CH]),
2306    {ok, CH, ok};
2307strar_mgc_verify_handle_connect(Else) ->
2308    io:format("strar_mgc_verify_handle_connect -> unknown"
2309	      "~n   Else: ~p~n", [Else]),
2310    {error, Else, ok}.
2311
2312-ifndef(megaco_hipe_special).
2313strar_mgc_verify_service_change_req_fun(Mid) ->
2314    fun(Req) ->
2315	    strar_mgc_verify_service_change_req(Req, Mid)
2316    end.
2317-endif.
2318
2319strar_mgc_verify_service_change_req(
2320  {handle_trans_request, _, ?VERSION, [AR]}, Mid) ->
2321    (catch strar_mgc_do_verify_service_change_req(AR, Mid));
2322strar_mgc_verify_service_change_req(Crap, _Mid) ->
2323    ED       = cre_ErrDesc(Crap),
2324    ErrReply = {discard_ack, ED},
2325    {error, Crap, ErrReply}.
2326
2327strar_mgc_do_verify_service_change_req(AR, Mid) ->
2328    io:format("strar_mgc_verify_service_change_req -> entry with"
2329	      "~n   AR:  ~p"
2330	      "~n   Mid: ~p"
2331	      "~n", [AR, Mid]),
2332    CR =
2333	case AR of
2334	    #'ActionRequest'{commandRequests = [CmdReq]} ->
2335		CmdReq;
2336	    _ ->
2337                Err1      = {invalid_action_request, AR},
2338                ED1       = cre_ErrDesc(AR),
2339                ErrReply1 = {discard_ack, ED1},
2340                throw({error, Err1, ErrReply1})
2341	end,
2342    Cmd =
2343        case CR of
2344            #'CommandRequest'{command = Command} ->
2345                Command;
2346            _ ->
2347                Err2      = {invalid_command_request, CR},
2348                ED2       = cre_ErrDesc(CR),
2349                ErrReply2 = {discard_ack, ED2},
2350                throw({error, Err2, ErrReply2})
2351        end,
2352    {Tid, Parms} =
2353        case Cmd of
2354            {serviceChangeReq,
2355             #'ServiceChangeRequest'{terminationID = [TermID],
2356                                     serviceChangeParms = ServChParms}} ->
2357                {TermID, ServChParms};
2358            _ ->
2359                Err3      = {invalid_command, Cmd},
2360                ED3       = cre_ErrDesc(Cmd),
2361                ErrReply3 = {discard_ack, ED3},
2362                throw({error, Err3, ErrReply3})
2363        end,
2364    case Tid of
2365        #megaco_term_id{contains_wildcards = false, id = ["root"]} ->
2366            ok;
2367        _ ->
2368            Err4      = {invalid_termination_id, Tid},
2369            ED4       = cre_ErrDesc(Tid),
2370            ErrReply4 = {discard_ack, ED4},
2371            throw({error, Err4, ErrReply4})
2372    end,
2373    case Parms of
2374        #'ServiceChangeParm'{serviceChangeMethod = restart,
2375                             serviceChangeReason = [[$9,$0,$1|_]]} ->
2376            AckData = [strar_mgc_service_change_reply_ar(Mid, 1)],
2377            Reply   = {discard_ack, AckData},
2378            {ok, AR, Reply};
2379        _ ->
2380            Err5      = {invalid_SCP, Parms},
2381            ED5       = cre_ErrDesc(Parms),
2382            ErrReply5 = {discard_ack, ED5},
2383            {error, Err5, ErrReply5}
2384    end.
2385
2386-ifndef(megaco_hipe_special).
2387strar_mgc_verify_notify_request_fun() ->
2388    fun(Req) ->
2389	    strar_mgc_verify_notify_request(Req)
2390    end.
2391-endif.
2392
2393strar_mgc_verify_notify_request({handle_trans_request, _, ?VERSION, [AR]}) ->
2394    (catch strar_mgc_do_verify_notify_request(AR));
2395strar_mgc_verify_notify_request(Crap) ->
2396    ED       = cre_ErrDesc(Crap),
2397    ErrReply = {discard_ack, ED},
2398    {error, Crap, ErrReply}.
2399
2400strar_mgc_do_verify_notify_request(AR) ->
2401    io:format("strar_mgc_do_verify_notify_request -> ok"
2402	      "~n   AR: ~p~n", [AR]),
2403    {Cid, CR} =
2404	case AR of
2405	    #'ActionRequest'{contextId       = CtxID,
2406			     commandRequests = [CmdReq]} when (CtxID == 1) or
2407							      (CtxID == 2) ->
2408		{CtxID, CmdReq};
2409	    _ ->
2410                Err1      = {invalid_action_request, AR},
2411                ED1       = cre_ErrDesc(AR),
2412                ErrReply1 = {discard_ack, ED1},
2413                throw({error, Err1, ErrReply1})
2414        end,
2415    Cmd =
2416	case CR of
2417	    #'CommandRequest'{command = Command} ->
2418		Command;
2419	    _ ->
2420                Err2      = {invalid_command_request, CR},
2421                ED2       = cre_ErrDesc(CR),
2422                ErrReply2 = {discard_ack, ED2},
2423                throw({error, Err2, ErrReply2})
2424        end,
2425    NR =
2426        case Cmd of
2427	    {notifyReq, NotifReq} ->
2428		NotifReq;
2429	    _ ->
2430                Err3      = {invalid_command, Cmd},
2431                ED3       = cre_ErrDesc(Cmd),
2432                ErrReply3 = {discard_ack, ED3},
2433                throw({error, Err3, ErrReply3})
2434        end,
2435    {Tid, OED} =
2436        case NR of
2437            #'NotifyRequest'{terminationID            = [TermID],
2438                             observedEventsDescriptor = ObsEvsDesc,
2439                             errorDescriptor          = asn1_NOVALUE} ->
2440                {TermID, ObsEvsDesc};
2441            _ ->
2442                Err4      = {invalid_NR, NR},
2443                ED4       = cre_ErrDesc(NR),
2444                ErrReply4 = {discard_ack, ED4},
2445                throw({error, Err4, ErrReply4})
2446        end,
2447    OE =
2448	case OED of
2449	    #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
2450		ObsEvLst;
2451            _ ->
2452                Err5      = {invalid_OED, OED},
2453                ED5       = cre_ErrDesc(NR),
2454                ErrReply5 = {discard_ack, ED5},
2455                throw({error, Err5, ErrReply5})
2456        end,
2457    case OE of
2458	#'ObservedEvent'{eventName = "al/of"} ->
2459            Replies = [strar_mgc_notify_reply_ar(Cid, Tid)],
2460            Reply   = {discard_ack, Replies},
2461            {ok, AR, Reply};
2462        _ ->
2463            Err6      = {invalid_OE, OE},
2464            ED6       = cre_ErrDesc(OE),
2465            ErrReply6 = {discard_ack, ED6},
2466            {error, Err6, ErrReply6}
2467    end.
2468
2469strar_mgc_verify_handle_disconnect({handle_disconnect, CH, ?VERSION, R}) ->
2470    io:format("strar_mgc_verify_handle_disconnect -> ok"
2471	      "~n   CH: ~p"
2472	      "~n   R:  ~p"
2473	      "~n", [CH, R]),
2474    {ok, CH, ok};
2475strar_mgc_verify_handle_disconnect(Else) ->
2476    io:format("strar_mgc_verify_handle_disconnect -> unknown"
2477	      "~n   Else: ~p~n", [Else]),
2478    {error, Else, ok}.
2479
2480
2481strar_mgc_service_change_reply_ar(Mid, Cid) ->
2482    SCRP  = cre_serviceChangeResParm(Mid),
2483    SCRes = cre_serviceChangeResult(SCRP),
2484    Root  = #megaco_term_id{id = ["root"]},
2485    SCR   = cre_serviceChangeReply([Root], SCRes),
2486    CR    = cre_cmdReply(SCR),
2487    cre_actionReply(Cid, [CR]).
2488
2489strar_mgc_notify_reply_ar(Cid, TermId) ->
2490    NR    = cre_notifyReply([TermId]),
2491    CR    = cre_cmdReply(NR),
2492    cre_actionReply(Cid, [CR]).
2493
2494%% strar_mgc_notify_reply(Mid, TransId, Cid, TermId) ->
2495%%     AR    = strar_mgc_notify_reply_ar(Cid, TermId),
2496%%     TRes  = cre_transResult([AR]),
2497%%     TR    = cre_transReply(TransId, TRes),
2498%%     Trans = cre_transaction(TR),
2499%%     Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
2500%%     cre_megacoMessage(Mess).
2501
2502
2503%%
2504%% MG generator stuff
2505%%
2506-ifdef(megaco_hipe_special).
2507-define(strar_mg_verify_handle_connect_fun(),
2508	{?MODULE, strar_mg_verify_handle_connect, []}).
2509-define(strar_mg_verify_service_change_reply_fun(),
2510	{?MODULE, strar_mg_verify_service_change_reply, []}).
2511-define(strar_mg_verify_notify_reply_fun(),
2512	{?MODULE, strar_mg_verify_notify_reply, []}).
2513-else.
2514-define(strar_mg_verify_handle_connect_fun(),
2515	strar_mg_verify_handle_connect_fun()).
2516-define(strar_mg_verify_service_change_reply_fun(),
2517	strar_mg_verify_service_change_reply_fun()).
2518-define(strar_mg_verify_notify_reply_fun(),
2519	strar_mg_verify_notify_reply_fun()).
2520-endif.
2521
2522strar_mg_event_sequence(text, tcp) ->
2523    Mid = {deviceName, "mg"},
2524    RI = [
2525	  {port,             2944},
2526	  {encoding_module,  megaco_pretty_text_encoder},
2527	  {encoding_config,  []},
2528	  {transport_module, megaco_tcp}
2529	 ],
2530    ServiceChangeReq = [strar_mg_service_change_request_ar(Mid, 1)],
2531    Tid = #megaco_term_id{id = ["00000000","00000000","01101101"]},
2532    NR = fun(Cid, Rid) ->
2533		 [strar_mg_notify_request_ar(Rid, Tid, Cid)]
2534	 end,
2535    ConnectVerify            = ?strar_mg_verify_handle_connect_fun(),
2536    ServiceChangeReplyVerify = ?strar_mg_verify_service_change_reply_fun(),
2537    NotifyReplyVerify        = ?strar_mg_verify_notify_reply_fun(),
2538    EvSeq = [
2539	     {debug, true},
2540	     megaco_start,
2541	     {megaco_start_user, Mid, RI, []},
2542	     start_transport,
2543	     {megaco_trace, disable},
2544	     {megaco_system_info, users},
2545	     {megaco_system_info, connections},
2546	     connect,
2547	     {megaco_callback, handle_connect, ConnectVerify},
2548	     megaco_connect,
2549	     {megaco_cast, ServiceChangeReq, []},
2550	     {megaco_callback, handle_connect, ConnectVerify},
2551	     {megaco_callback, handle_trans_reply, ServiceChangeReplyVerify},
2552	     {sleep, 1000},
2553	     {megaco_system_info, users},
2554	     {megaco_system_info, connections},
2555	     {sleep, 1000},
2556	     {megaco_conn_info, all},
2557	     {megaco_cast, NR(1,1), []},
2558	     {megaco_callback, handle_trans_reply, NotifyReplyVerify},
2559	     {sleep, 3000},
2560	     megaco_stop_user,
2561	     megaco_stop,
2562	     {sleep, 1000}
2563	    ],
2564    EvSeq.
2565
2566-ifndef(megaco_hipe_special).
2567strar_mg_verify_handle_connect_fun() ->
2568    fun(Ev) ->
2569	    strar_mg_verify_handle_connect(Ev)
2570    end.
2571-endif.
2572
2573strar_mg_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
2574    io:format("strar_mg_verify_handle_connect -> ok"
2575	      "~n   CH: ~p~n", [CH]),
2576    {ok, CH, ok};
2577strar_mg_verify_handle_connect(Else) ->
2578    io:format("strar_mg_verify_handle_connect -> unknown"
2579	      "~n   Else: ~p~n", [Else]),
2580    {error, Else, ok}.
2581
2582-ifndef(megaco_hipe_special).
2583strar_mg_verify_service_change_reply_fun() ->
2584    fun(Rep) ->
2585	    strar_mg_verify_service_change_reply(Rep)
2586    end.
2587-endif.
2588
2589strar_mg_verify_service_change_reply(
2590  {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _}) ->
2591    (catch strar_mg_do_verify_service_change_reply(AR));
2592strar_mg_verify_service_change_reply(Crap) ->
2593    {error, Crap, ok}.
2594
2595strar_mg_do_verify_service_change_reply(AR) ->
2596    io:format("strar_mg_verify_service_change_reply -> ok"
2597	      "~n   AR: ~p~n", [AR]),
2598    CR =
2599	case AR of
2600	    #'ActionReply'{commandReply = [CmdRep]} ->
2601		CmdRep;
2602	    _ ->
2603		Reason1 = {invalid_action_reply, AR},
2604		throw({error, Reason1, ok})
2605	end,
2606    SCR =
2607	case CR of
2608	    {serviceChangeReply, ServChRep} ->
2609		ServChRep;
2610	    _ ->
2611		Reason2 = {invalid_command_reply, CR},
2612		throw({error, Reason2, ok})
2613	end,
2614    {Tid, SCRes} =
2615	case SCR of
2616	    #'ServiceChangeReply'{terminationID       = [TermID],
2617				  serviceChangeResult = Res} ->
2618		{TermID, Res};
2619	    _ ->
2620		Reason3 = {invalid_service_change_reply, SCR},
2621		throw({error, Reason3, ok})
2622	end,
2623    case Tid of
2624	#megaco_term_id{contains_wildcards = false, id = ["root"]} ->
2625	    ok;
2626	_ ->
2627	    Reason4 = {invalid_termination_id, Tid},
2628	    throw({error, Reason4, ok})
2629    end,
2630    SCRParm =
2631	case SCRes of
2632	    {serviceChangeResParms, ServChResParms} ->
2633		ServChResParms;
2634	    _ ->
2635		Reason5 = {invalid_serviceChangeResult, SCRes},
2636		throw({error, Reason5, ok})
2637	end,
2638    case SCRParm of
2639	#'ServiceChangeResParm'{serviceChangeMgcId = _RemoteMid} ->
2640	    {ok, AR, ok};
2641	_ ->
2642	    Reason6 = {invalid_service_change_result, SCRParm},
2643	    {error, Reason6, ok}
2644    end.
2645
2646-ifndef(megaco_hipe_special).
2647strar_mg_verify_notify_reply_fun() ->
2648    fun(Rep) ->
2649	    strar_mg_verify_notify_reply(Rep)
2650    end.
2651-endif.
2652
2653strar_mg_verify_notify_reply({handle_trans_reply, _CH, ?VERSION,
2654			      {ok, [AR]}, _}) ->
2655    io:format("strar_mg_verify_notify_reply -> ok"
2656	      "~n   AR: ~p~n", [AR]),
2657    {ok, AR, ok};
2658strar_mg_verify_notify_reply(Else) ->
2659    io:format("strar_mg_verify_notify_reply -> unknown"
2660	      "~n   Else: ~p~n", [Else]),
2661    {error, Else, ok}.
2662
2663strar_mg_service_change_request_ar(_Mid, Cid) ->
2664    Prof  = cre_serviceChangeProf("resgw", 1),
2665    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
2666    Root  = #megaco_term_id{id = ["root"]},
2667    SCR   = cre_serviceChangeReq([Root], SCP),
2668    CMD   = cre_command(SCR),
2669    CR    = cre_cmdReq(CMD),
2670    cre_actionReq(Cid, [CR]).
2671
2672strar_mg_notify_request_ar(Rid, Tid, Cid) ->
2673    TT      = cre_timeNotation("19990729", "22000000"),
2674    Ev      = cre_obsEvent("al/of", TT),
2675    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
2676    NR      = cre_notifyReq([Tid], EvsDesc),
2677    CMD     = cre_command(NR),
2678    CR      = cre_cmdReq(CMD),
2679    cre_actionReq(Cid, [CR]).
2680
2681
2682%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2683
2684single_trans_req_and_reply_sendopts(suite) ->
2685    [];
2686single_trans_req_and_reply_sendopts(doc) ->
2687    ["Receive a (single) transaction request and then send a "
2688     "reply with handle_ack and a reply_timer in sendoptions. "
2689     "The MGC is a megaco instance (megaco event sequence) and the "
2690     "MG is emulated (tcp event sequence)"];
2691single_trans_req_and_reply_sendopts(Config) when is_list(Config) ->
2692    Pre = fun() ->
2693                  %% <CONDITIONAL-SKIP>
2694                  Skippable = [{unix, [darwin, linux]}],
2695                  Condition = fun() -> ?OS_BASED_SKIP(Skippable) end,
2696                  ?NON_PC_TC_MAYBE_SKIP(Config, Condition),
2697                  %% </CONDITIONAL-SKIP>
2698
2699                  MgcNode = make_node_name(mgc),
2700                  MgNode  = make_node_name(mg),
2701                  d("start nodes: "
2702                    "~n      MgcNode: ~p"
2703                    "~n      MgNode:  ~p",
2704                    [MgcNode, MgNode]),
2705                  Nodes = [MgcNode, MgNode],
2706                  ok = ?START_NODES(Nodes, true),
2707                  Nodes
2708          end,
2709    Case = fun do_single_trans_req_and_reply_sendopts/1,
2710    Post = fun(Nodes) ->
2711                   d("stop nodes"),
2712                   ?STOP_NODES(lists:reverse(Nodes))
2713           end,
2714    try_tc(straro, Pre, Case, Post).
2715
2716do_single_trans_req_and_reply_sendopts([MgcNode, MgNode]) ->
2717    d("[MGC] start the simulator "),
2718    {ok, Mgc} = megaco_test_megaco_generator:start_link("MGC", MgcNode),
2719
2720    d("[MGC] create the event sequence"),
2721    MgcEvSeq = straro_mgc_event_sequence(text, tcp),
2722
2723    i("wait some time before starting the MGC simulation"),
2724    sleep(1000),
2725
2726    d("[MGC] start the simulation"),
2727    {ok, MgcId} = megaco_test_megaco_generator:exec(Mgc, MgcEvSeq),
2728
2729    %% i("wait some time before starting the MG simulator"),
2730    %% sleep(1000),
2731
2732    i("await MGC ready announcement"),
2733    receive
2734        announce_mgc ->
2735            i("received MGC ready announcement"),
2736            ok
2737    end,
2738
2739    d("[MG] start the simulator (generator)"),
2740    {ok, Mg} = megaco_test_megaco_generator:start_link("MG", MgNode),
2741
2742    d("[MG] create the event sequence"),
2743    MgEvSeq = straro_mg_event_sequence(text, tcp),
2744
2745    i("wait some time before starting the MG simulation"),
2746    sleep(1000),
2747
2748    d("[MG] start the simulation"),
2749    {ok, MgId} = megaco_test_megaco_generator:exec(Mg, MgEvSeq),
2750
2751    d("await the generator reply(s)"),
2752    await_completion([MgcId, MgId], 30000),
2753
2754    %% Tell Mgc to stop
2755    i("[MGC] stop generator"),
2756    megaco_test_megaco_generator:stop(Mgc),
2757
2758    %% Tell Mg to stop
2759    i("[MG] stop generator"),
2760    megaco_test_megaco_generator:stop(Mg),
2761
2762    i("done", []),
2763    ok.
2764
2765
2766%%
2767%% MGC generator stuff
2768%%
2769-ifdef(megaco_hipe_special).
2770-define(straro_mgc_verify_handle_connect_fun(),
2771        {?MODULE, straro_mgc_verify_handle_connect, []}).
2772-define(straro_mgc_verify_service_change_req_fun(Mid),
2773        {?MODULE, straro_mgc_verify_service_change_req, [Mid]}).
2774-define(straro_mgc_verify_notify_req_fun(),
2775        {?MODULE, straro_mgc_verify_notify_request, []}).
2776-define(straro_mgc_verify_handle_trans_ack_fun(),
2777        {?MODULE, straro_mgc_verify_handle_trans_ack, []}).
2778-else.
2779-define(straro_mgc_verify_handle_connect_fun(),
2780        fun straro_mgc_verify_handle_connect/1).
2781-define(straro_mgc_verify_service_change_req_fun(Mid),
2782        straro_mgc_verify_service_change_req_fun(Mid)).
2783-define(straro_mgc_verify_notify_req_fun(),
2784	straro_mgc_verify_notify_request_fun()).
2785-define(straro_mgc_verify_handle_trans_ack_fun(),
2786	straro_mgc_verify_handle_trans_ack_fun()).
2787-endif.
2788
2789straro_mgc_event_sequence(text, tcp) ->
2790    CTRL = self(),
2791    Mid = {deviceName,"ctrl"},
2792    RI = [
2793	  {port,             2944},
2794	  {encoding_module,  megaco_pretty_text_encoder},
2795	  {encoding_config,  []},
2796	  {transport_module, megaco_tcp}
2797	 ],
2798    ConnectVerify          = ?straro_mgc_verify_handle_connect_fun(),
2799    ServiceChangeReqVerify = ?straro_mgc_verify_service_change_req_fun(Mid),
2800    NotifyReqVerify        = ?straro_mgc_verify_notify_req_fun(),
2801    TransAckVerify         = ?straro_mgc_verify_handle_trans_ack_fun(),
2802    EvSeq = [
2803	     {debug, true},
2804	     {megaco_trace, disable},
2805	     megaco_start,
2806	     {megaco_start_user, Mid, RI, []},
2807	     start_transport,
2808	     listen,
2809
2810             %% ANNOUNCE READY
2811             {trigger, fun() -> CTRL ! announce_mgc end},
2812
2813	     {megaco_callback, handle_connect,       ConnectVerify},
2814	     {megaco_callback, handle_trans_request, ServiceChangeReqVerify},
2815	     {megaco_callback, handle_trans_request, NotifyReqVerify},
2816	     {megaco_callback, handle_trans_ack,     TransAckVerify},
2817	     megaco_stop_user,
2818	     megaco_stop
2819	    ],
2820    EvSeq.
2821
2822
2823straro_mgc_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
2824    io:format("straro_mgc_verify_handle_connect -> ok"
2825	      "~n   CH: ~p~n", [CH]),
2826    {ok, CH, ok};
2827straro_mgc_verify_handle_connect(Else) ->
2828    io:format("straro_mgc_verify_handle_connect -> unknown"
2829	      "~n   Else: ~p~n", [Else]),
2830    {error, Else, ok}.
2831
2832-ifndef(megaco_hipe_special).
2833straro_mgc_verify_service_change_req_fun(Mid) ->
2834    fun(Req) ->
2835	    straro_mgc_verify_service_change_req(Req, Mid)
2836    end.
2837-endif.
2838
2839straro_mgc_verify_service_change_req(
2840  {handle_trans_request, _, ?VERSION, [AR]}, Mid) ->
2841    (catch straro_mgc_do_verify_service_change_req(AR, Mid));
2842straro_mgc_verify_service_change_req(Crap, _Mid) ->
2843    ED       = cre_ErrDesc(Crap),
2844    ErrReply = {discard_ack, ED},
2845    {error, Crap, ErrReply}.
2846
2847straro_mgc_do_verify_service_change_req(AR, Mid) ->
2848    io:format("straro_mgc_do_verify_service_change_req -> ok"
2849	      "~n   AR: ~p~n", [AR]),
2850    CR =
2851	case AR of
2852	    #'ActionRequest'{commandRequests = [CmdReq]} ->
2853		CmdReq;
2854	    _ ->
2855                Err1      = {invalid_action_request, AR},
2856                ED1       = cre_ErrDesc(AR),
2857                ErrReply1 = {discard_ack, ED1},
2858                throw({error, Err1, ErrReply1})
2859	end,
2860    Cmd =
2861        case CR of
2862            #'CommandRequest'{command = Command} ->
2863                Command;
2864            _ ->
2865                Err2      = {invalid_command_request, CR},
2866                ED2       = cre_ErrDesc(CR),
2867                ErrReply2 = {discard_ack, ED2},
2868                throw({error, Err2, ErrReply2})
2869        end,
2870    {Tid, Parms} =
2871        case Cmd of
2872            {serviceChangeReq,
2873             #'ServiceChangeRequest'{terminationID = [TermID],
2874                                     serviceChangeParms = ServChParms}} ->
2875                {TermID, ServChParms};
2876            _ ->
2877                Err3      = {invalid_command, Cmd},
2878                ED3       = cre_ErrDesc(Cmd),
2879                ErrReply3 = {discard_ack, ED3},
2880                throw({error, Err3, ErrReply3})
2881        end,
2882    case Tid of
2883        #megaco_term_id{contains_wildcards = false, id = ["root"]} ->
2884            ok;
2885        _ ->
2886            Err4      = {invalid_termination_id, Tid},
2887            ED4       = cre_ErrDesc(Tid),
2888            ErrReply4 = {discard_ack, ED4},
2889            throw({error, Err4, ErrReply4})
2890    end,
2891    case Parms of
2892        #'ServiceChangeParm'{serviceChangeMethod = restart,
2893                             serviceChangeReason = [[$9,$0,$1|_]]} ->
2894            AckData = [straro_mgc_service_change_reply_ar(Mid, 1)],
2895            Reply   = {discard_ack, AckData},
2896            {ok, AR, Reply};
2897        _ ->
2898            Err5      = {invalid_SCP, Parms},
2899            ED5       = cre_ErrDesc(Parms),
2900            ErrReply5 = {discard_ack, ED5},
2901            {error, Err5, ErrReply5}
2902    end.
2903
2904-ifndef(megaco_hipe_special).
2905straro_mgc_verify_notify_request_fun() ->
2906    fun(Req) ->
2907	    straro_mgc_verify_notify_request(Req)
2908    end.
2909-endif.
2910
2911straro_mgc_verify_notify_request({handle_trans_request, _, ?VERSION, [AR]}) ->
2912    (catch straro_mgc_do_verify_notify_request(AR));
2913straro_mgc_verify_notify_request(Crap) ->
2914    ED       = cre_ErrDesc(Crap),
2915    ErrReply = {discard_ack, ED},
2916    {error, Crap, ErrReply}.
2917
2918straro_mgc_do_verify_notify_request(AR) ->
2919    io:format("straro_mgc_do_verify_notify_request -> ok"
2920	      "~n   AR: ~p~n", [AR]),
2921    {Cid, CR} =
2922	case AR of
2923	    #'ActionRequest'{contextId       = CtxID,
2924			     commandRequests = [CmdReq]} when (CtxID == 1) or
2925							      (CtxID == 2) ->
2926		{CtxID, CmdReq};
2927	    _ ->
2928                Err1      = {invalid_action_request, AR},
2929                ED1       = cre_ErrDesc(AR),
2930                ErrReply1 = {discard_ack, ED1},
2931                throw({error, Err1, ErrReply1})
2932        end,
2933    Cmd =
2934	case CR of
2935	    #'CommandRequest'{command = Command} ->
2936		Command;
2937	    _ ->
2938                Err2      = {invalid_command_request, CR},
2939                ED2       = cre_ErrDesc(CR),
2940                ErrReply2 = {discard_ack, ED2},
2941                throw({error, Err2, ErrReply2})
2942        end,
2943    NR =
2944        case Cmd of
2945	    {notifyReq, NotifReq} ->
2946		NotifReq;
2947	    _ ->
2948                Err3      = {invalid_command, Cmd},
2949                ED3       = cre_ErrDesc(Cmd),
2950                ErrReply3 = {discard_ack, ED3},
2951                throw({error, Err3, ErrReply3})
2952        end,
2953    {Tid, OED} =
2954        case NR of
2955            #'NotifyRequest'{terminationID            = [TermID],
2956                             observedEventsDescriptor = ObsEvsDesc,
2957                             errorDescriptor          = asn1_NOVALUE} ->
2958                {TermID, ObsEvsDesc};
2959            _ ->
2960                Err4      = {invalid_NR, NR},
2961                ED4       = cre_ErrDesc(NR),
2962                ErrReply4 = {discard_ack, ED4},
2963                throw({error, Err4, ErrReply4})
2964        end,
2965    OE =
2966	case OED of
2967	    #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
2968		ObsEvLst;
2969            _ ->
2970                Err5      = {invalid_OED, OED},
2971                ED5       = cre_ErrDesc(NR),
2972                ErrReply5 = {discard_ack, ED5},
2973                throw({error, Err5, ErrReply5})
2974        end,
2975    case OE of
2976	#'ObservedEvent'{eventName = "al/of"} ->
2977            Replies = [straro_mgc_notify_reply_ar(Cid, Tid)],
2978	    SendOpts = [{protocol_version, 99}],
2979            Reply   = {{handle_ack, get(tc)}, Replies, SendOpts},
2980            {ok, AR, Reply};
2981        _ ->
2982            Err6      = {invalid_OE, OE},
2983            ED6       = cre_ErrDesc(OE),
2984            ErrReply6 = {discard_ack, ED6},
2985            {error, Err6, ErrReply6}
2986    end.
2987
2988-ifndef(megaco_hipe_special).
2989straro_mgc_verify_handle_trans_ack_fun() ->
2990    fun(Ack) ->
2991	    straro_mgc_verify_handle_trans_ack(Ack)
2992    end.
2993-endif.
2994
2995straro_mgc_verify_handle_trans_ack(
2996  {handle_trans_ack, _CH, ?VERSION, AS, _AD}) ->
2997    (catch straro_mgc_do_verify_handle_trans_ack(AS));
2998straro_mgc_verify_handle_trans_ack(Crap) ->
2999    io:format("straro_mgc_verify_handle_trans_ack -> entry with"
3000	      "~n   Crap: ~p"
3001	      "~n", [Crap]),
3002    {error, Crap, ok}.
3003
3004straro_mgc_do_verify_handle_trans_ack({error, {EM, EF, [EC, Version, Msg], Reason}}) ->
3005    io:format("straro_mgc_do_handle_verify_handle_trans_ack -> entry with"
3006	      "~n   EM:      ~p"
3007	      "~n   EF:      ~p"
3008	      "~n   EC:      ~p"
3009	      "~n   Version: ~p"
3010	      "~n   Msg:     ~p"
3011	      "~n   Reason:  ~p"
3012	      "~n", [EM, EF, EC, Version, Msg, Reason]),
3013    case Reason of
3014	{bad_version, 99} ->
3015	    {ok, Reason, ok};
3016	_ ->
3017	    {error, {unexpected_reason, Reason}, ok}
3018    end;
3019straro_mgc_do_verify_handle_trans_ack(Else) ->
3020    io:format("straro_mgc_verify_handle_trans_ack -> unknown"
3021	      "~n   Else: ~p"
3022	      "~n", [Else]),
3023    {error, Else, ok}.
3024
3025%% straro_mgc_verify_handle_disconnect({handle_disconnect, CH, ?VERSION, R}) ->
3026%%     io:format("straro_mgc_verify_handle_disconnect -> ok"
3027%% 	      "~n   CH: ~p"
3028%% 	      "~n   R:  ~p"
3029%% 	      "~n", [CH, R]),
3030%%     {ok, CH, ok};
3031%% straro_mgc_verify_handle_disconnect(Else) ->
3032%%     io:format("straro_mgc_verify_handle_disconnect -> unknown"
3033%% 	      "~n   Else: ~p~n", [Else]),
3034%%     {error, Else, ok}.
3035
3036
3037straro_mgc_service_change_reply_ar(Mid, Cid) ->
3038    SCRP  = cre_serviceChangeResParm(Mid),
3039    SCRes = cre_serviceChangeResult(SCRP),
3040    Root  = #megaco_term_id{id = ["root"]},
3041    SCR   = cre_serviceChangeReply([Root], SCRes),
3042    CR    = cre_cmdReply(SCR),
3043    cre_actionReply(Cid, [CR]).
3044
3045straro_mgc_notify_reply_ar(Cid, TermId) ->
3046    NR    = cre_notifyReply([TermId]),
3047    CR    = cre_cmdReply(NR),
3048    cre_actionReply(Cid, [CR]).
3049
3050%% straro_mgc_notify_reply(Mid, TransId, Cid, TermId) ->
3051%%     AR    = straro_mgc_notify_reply_ar(Cid, TermId),
3052%%     TRes  = cre_transResult([AR]),
3053%%     TR    = cre_transReply(TransId, TRes),
3054%%     Trans = cre_transaction(TR),
3055%%     Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
3056%%     cre_megacoMessage(Mess).
3057
3058
3059%%
3060%% MG generator stuff
3061%%
3062-ifdef(megaco_hipe_special).
3063-define(straro_mg_verify_handle_connect_fun(),
3064	{?MODULE, straro_mg_verify_handle_connect, []}).
3065-define(straro_mg_verify_service_change_reply_fun(),
3066	{?MODULE, straro_mg_verify_service_change_reply, []}).
3067-define(straro_mg_verify_handle_disconnect_fun(),
3068	{?MODULE, straro_mg_verify_handle_disconnect, []}).
3069-else.
3070-define(straro_mg_verify_handle_connect_fun(),
3071	straro_mg_verify_handle_connect_fun()).
3072-define(straro_mg_verify_service_change_reply_fun(),
3073	straro_mg_verify_service_change_reply_fun()).
3074-define(straro_mg_verify_handle_disconnect_fun(),
3075	fun straro_mg_verify_handle_disconnect/1).
3076-endif.
3077
3078straro_mg_event_sequence(text, tcp) ->
3079    Mid = {deviceName, "mg"},
3080    RI = [
3081	  {port,             2944},
3082	  {encoding_module,  megaco_pretty_text_encoder},
3083	  {encoding_config,  []},
3084	  {transport_module, megaco_tcp}
3085	 ],
3086    ServiceChangeReq = [straro_mg_service_change_request_ar(Mid, 1)],
3087    Tid = #megaco_term_id{id = ["00000000","00000000","01101101"]},
3088    NR = fun(Cid, Rid) ->
3089		 [straro_mg_notify_request_ar(Rid, Tid, Cid)]
3090	 end,
3091    ConnectVerify            = ?straro_mg_verify_handle_connect_fun(),
3092    ServiceChangeReplyVerify = ?straro_mg_verify_service_change_reply_fun(),
3093    DiscoVerify              = ?straro_mg_verify_handle_disconnect_fun(),
3094%%     ConnectVerify            = straro_mg_verify_handle_connect_fun(),
3095%%     DiscoVerify              = fun straro_mg_verify_handle_disconnect/1,
3096%%     ServiceChangeReplyVerify = straro_mg_verify_service_change_reply_fun(),
3097    EvSeq = [
3098	     {debug, true},
3099	     megaco_start,
3100	     {megaco_start_user, Mid, RI, []},
3101	     start_transport,
3102	     {megaco_trace, disable},
3103	     {megaco_system_info, users},
3104	     {megaco_system_info, connections},
3105	     connect,
3106	     {megaco_callback, handle_connect, ConnectVerify},
3107	     megaco_connect,
3108	     {megaco_cast, ServiceChangeReq, []},
3109	     {megaco_callback, handle_connect, ConnectVerify},
3110	     {megaco_callback, handle_trans_reply, ServiceChangeReplyVerify},
3111	     {sleep, 1000},
3112	     {megaco_system_info, users},
3113	     {megaco_system_info, connections},
3114	     {sleep, 1000},
3115	     {megaco_conn_info, all},
3116	     {megaco_cast, NR(1,1), []},
3117	     {megaco_callback, handle_disconnect, DiscoVerify},
3118	     megaco_stop_user,
3119	     megaco_stop,
3120	     {sleep, 1000}
3121	    ],
3122    EvSeq.
3123
3124-ifndef(megaco_hipe_special).
3125straro_mg_verify_handle_connect_fun() ->
3126    fun(Ev) ->
3127	    straro_mg_verify_handle_connect(Ev)
3128    end.
3129-endif.
3130
3131straro_mg_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
3132    io:format("straro_mg_verify_handle_connect -> ok"
3133	      "~n   CH: ~p~n", [CH]),
3134    {ok, CH, ok};
3135straro_mg_verify_handle_connect(Else) ->
3136    io:format("straro_mg_verify_handle_connect -> unknown"
3137	      "~n   Else: ~p~n", [Else]),
3138    {error, Else, ok}.
3139
3140straro_mg_verify_handle_disconnect({handle_disconnect, CH, ?VERSION, R}) ->
3141    io:format("straro_mg_verify_handle_disconnect -> ok"
3142	      "~n   CH: ~p"
3143	      "~n   R:  ~p"
3144	      "~n", [CH, R]),
3145    {ok, CH, ok};
3146straro_mg_verify_handle_disconnect(Else) ->
3147    io:format("straro_mg_verify_handle_disconnect -> unknown"
3148	      "~n   Else: ~p~n", [Else]),
3149    {error, Else, ok}.
3150
3151
3152-ifndef(megaco_hipe_special).
3153straro_mg_verify_service_change_reply_fun() ->
3154    fun(Rep) ->
3155	    straro_mg_verify_service_change_reply(Rep)
3156    end.
3157-endif.
3158
3159straro_mg_verify_service_change_reply(
3160  {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _}) ->
3161    (catch straro_mg_do_verify_service_change_reply(AR));
3162straro_mg_verify_service_change_reply(Crap) ->
3163    {error, Crap, ok}.
3164
3165straro_mg_do_verify_service_change_reply(AR) ->
3166    io:format("straro_mg_verify_service_change_reply -> ok"
3167	      "~n   AR: ~p~n", [AR]),
3168    CR =
3169	case AR of
3170	    #'ActionReply'{commandReply = [CmdRep]} ->
3171		CmdRep;
3172	    _ ->
3173		Reason1 = {invalid_action_reply, AR},
3174		throw({error, Reason1, ok})
3175	end,
3176    SCR =
3177	case CR of
3178	    {serviceChangeReply, ServChRep} ->
3179		ServChRep;
3180	    _ ->
3181		Reason2 = {invalid_command_reply, CR},
3182		throw({error, Reason2, ok})
3183	end,
3184    {Tid, SCRes} =
3185	case SCR of
3186	    #'ServiceChangeReply'{terminationID       = [TermID],
3187				  serviceChangeResult = Res} ->
3188		{TermID, Res};
3189	    _ ->
3190		Reason3 = {invalid_service_change_reply, SCR},
3191		throw({error, Reason3, ok})
3192	end,
3193    case Tid of
3194	#megaco_term_id{contains_wildcards = false, id = ["root"]} ->
3195	    ok;
3196	_ ->
3197	    Reason4 = {invalid_termination_id, Tid},
3198	    throw({error, Reason4, ok})
3199    end,
3200    SCRParm =
3201	case SCRes of
3202	    {serviceChangeResParms, ServChResParms} ->
3203		ServChResParms;
3204	    _ ->
3205		Reason5 = {invalid_serviceChangeResult, SCRes},
3206		throw({error, Reason5, ok})
3207	end,
3208    case SCRParm of
3209	#'ServiceChangeResParm'{serviceChangeMgcId = _RemoteMid} ->
3210	    {ok, AR, ok};
3211	_ ->
3212	    Reason6 = {invalid_service_change_result, SCRParm},
3213	    {error, Reason6, ok}
3214    end.
3215
3216%% -ifndef(megaco_hipe_special).
3217%% straro_mg_verify_notify_reply_fun() ->
3218%%     fun(Rep) ->
3219%% 	    straro_mg_verify_notify_reply(Rep)
3220%%     end.
3221%% -endif.
3222
3223%% straro_mg_verify_notify_reply({handle_trans_reply, _CH, ?VERSION,
3224%% 			      {ok, [AR]}, _}) ->
3225%%     io:format("straro_mg_verify_notify_reply -> ok"
3226%% 	      "~n   AR: ~p~n", [AR]),
3227%%     {ok, AR, ok};
3228%% straro_mg_verify_notify_reply(Else) ->
3229%%     io:format("straro_mg_verify_notify_reply -> unknown"
3230%% 	      "~n   Else: ~p~n", [Else]),
3231%%     {error, Else, ok}.
3232
3233straro_mg_service_change_request_ar(_Mid, Cid) ->
3234    Prof  = cre_serviceChangeProf("resgw", 1),
3235    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
3236    Root  = #megaco_term_id{id = ["root"]},
3237    SCR   = cre_serviceChangeReq([Root], SCP),
3238    CMD   = cre_command(SCR),
3239    CR    = cre_cmdReq(CMD),
3240    cre_actionReq(Cid, [CR]).
3241
3242straro_mg_notify_request_ar(Rid, Tid, Cid) ->
3243    TT      = cre_timeNotation("19990729", "22000000"),
3244    Ev      = cre_obsEvent("al/of", TT),
3245    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
3246    NR      = cre_notifyReq([Tid], EvsDesc),
3247    CMD     = cre_command(NR),
3248    CR      = cre_cmdReq(CMD),
3249    cre_actionReq(Cid, [CR]).
3250
3251
3252%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3253
3254request_and_reply_and_ack(suite) ->
3255    [];
3256request_and_reply_and_ack(doc) ->
3257    ["This test case tests that megaco correctly handles three-way-handshake"];
3258request_and_reply_and_ack(Config) when is_list(Config) ->
3259    Pre = fun() ->
3260                  MgcNode = make_node_name(mgc),
3261                  MgNode  = make_node_name(mg),
3262                  d("start nodes: "
3263                    "~n   MgcNode: ~p"
3264                    "~n   MgNode:  ~p",
3265                    [MgcNode, MgNode]),
3266                  Nodes = [MgcNode, MgNode],
3267                  ok = ?START_NODES(Nodes, true),
3268                  Nodes
3269          end,
3270    Case = fun do_request_and_reply_and_ack/1,
3271    Post = fun(Nodes) ->
3272                   d("stop nodes"),
3273                   ?STOP_NODES(lists:reverse(Nodes))
3274           end,
3275    try_tc(raraa, Pre, Case, Post).
3276
3277do_request_and_reply_and_ack([MgcNode, MgNode]) ->
3278    d("[MGC] start the simulator "),
3279    {ok, Mgc} = megaco_test_megaco_generator:start_link("MGC", MgcNode),
3280
3281    d("[MGC] create the event sequence"),
3282    MgcEvSeq = raraa_mgc_event_sequence(text, tcp),
3283
3284    i("wait some time before starting the MGC simulation"),
3285    sleep(1000),
3286
3287    d("[MGC] start the simulation"),
3288    {ok, MgcId} = megaco_test_megaco_generator:exec(Mgc, MgcEvSeq),
3289
3290    %% i("wait some time before starting the MG simulator"),
3291    %% sleep(1000),
3292
3293    i("await MGC ready announcement"),
3294    receive
3295        announce_mgc ->
3296            i("received MGC ready announcement"),
3297            ok
3298    end,
3299
3300    d("[MG] start the simulator (generator)"),
3301    {ok, Mg} = megaco_test_tcp_generator:start_link("MG", MgNode),
3302
3303    d("[MG] create the event sequence"),
3304    MgEvSeq = raraa_mg_event_sequence(text, tcp),
3305
3306    i("wait some time before starting the MG simulation"),
3307    sleep(1000),
3308
3309    d("[MG] start the simulation"),
3310    {ok, MgId} = megaco_test_tcp_generator:exec(Mg, MgEvSeq),
3311
3312    d("await the generator reply(s)"),
3313    await_completion([MgcId, MgId]),
3314
3315    %% Tell Mgc to stop
3316    i("[MGC] stop generator"),
3317    megaco_test_megaco_generator:stop(Mgc),
3318
3319    %% Tell Mg to stop
3320    i("[MG] stop generator"),
3321    megaco_test_tcp_generator:stop(Mg),
3322
3323    i("done", []),
3324    ok.
3325
3326
3327%%
3328%% MGC generator stuff
3329%%
3330
3331-ifdef(megaco_hipe_special).
3332-define(raraa_mgc_verify_handle_connect_fun(),
3333        {?MODULE, raraa_mgc_verify_handle_connect, []}).
3334-define(raraa_mgc_verify_service_change_req_fun(Mid),
3335        {?MODULE, raraa_mgc_verify_service_change_req, [Mid]}).
3336-define(raraa_mgc_verify_notify_req_fun(),
3337        {?MODULE, raraa_mgc_verify_notify_req, []}).
3338-define(raraa_mgc_verify_handle_trans_ack_fun(),
3339        {?MODULE, raraa_mgc_verify_handle_trans_ack, []}).
3340-define(raraa_mgc_verify_handle_disconnect_fun(),
3341        {?MODULE, raraa_mgc_verify_handle_disconnect, []}).
3342-else.
3343-define(raraa_mgc_verify_handle_connect_fun(),
3344        fun raraa_mgc_verify_handle_connect/1).
3345-define(raraa_mgc_verify_service_change_req_fun(Mid),
3346        raraa_mgc_verify_service_change_req_fun(Mid)).
3347-define(raraa_mgc_verify_notify_req_fun(),
3348	raraa_mgc_verify_notify_req_fun()).
3349-define(raraa_mgc_verify_handle_trans_ack_fun(),
3350        raraa_mgc_verify_handle_trans_ack_fun()).
3351-define(raraa_mgc_verify_handle_disconnect_fun(),
3352	fun raraa_mgc_verify_handle_disconnect/1).
3353-endif.
3354
3355raraa_mgc_event_sequence(text, tcp) ->
3356    CTRL = self(),
3357    Mid = {deviceName,"ctrl"},
3358    RI = [
3359          {port,             2944},
3360          {encoding_module,  megaco_pretty_text_encoder},
3361          {encoding_config,  []},
3362          {transport_module, megaco_tcp}
3363         ],
3364    ConnectVerify = ?raraa_mgc_verify_handle_connect_fun(),
3365    ScrVerify     = ?raraa_mgc_verify_service_change_req_fun(Mid),
3366    NrVerify      = ?raraa_mgc_verify_notify_req_fun(),
3367    AckVerify     = ?raraa_mgc_verify_handle_trans_ack_fun(),
3368    DiscoVerify   = ?raraa_mgc_verify_handle_disconnect_fun(),
3369    EvSeq = [
3370             {debug, true},
3371             {megaco_trace, disable},
3372             {megaco_trace, max},
3373             megaco_start,
3374             {megaco_start_user, Mid, RI, []},
3375             {megaco_update_user_info, sent_pending_limit, 100},
3376             start_transport,
3377             listen,
3378
3379             %% ANNOUNCE READY
3380             {trigger, fun() -> CTRL ! announce_mgc end},
3381
3382             {megaco_callback, handle_connect,           ConnectVerify},
3383             {megaco_conn_info, all},
3384             {megaco_callback, handle_trans_request,     ScrVerify},
3385	     {megaco_callback, handle_trans_request,     NrVerify},
3386	     {megaco_callback, handle_trans_ack,         AckVerify},
3387             {megaco_callback, handle_disconnect,        DiscoVerify},
3388             megaco_stop_user,
3389             megaco_stop
3390            ],
3391    EvSeq.
3392
3393%% Connect verification
3394raraa_mgc_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
3395    {ok, CH, ok};
3396raraa_mgc_verify_handle_connect(Else) ->
3397    {error, Else, ok}.
3398
3399%% Service Change verification
3400-ifndef(megaco_hipe_special).
3401raraa_mgc_verify_service_change_req_fun(Mid) ->
3402    fun(Req) ->
3403	    raraa_mgc_verify_service_change_req(Req, Mid)
3404    end.
3405-endif.
3406
3407raraa_mgc_verify_service_change_req(
3408  {handle_trans_request, _, ?VERSION, [AR]}, Mid) ->
3409    (catch raraa_do_verify_service_change_req(AR, Mid));
3410raraa_mgc_verify_service_change_req(Crap, _Mid) ->
3411    ED       = cre_ErrDesc(Crap),
3412    ErrReply = {discard_ack, ED},
3413    {error, Crap, ErrReply}.
3414
3415raraa_do_verify_service_change_req(AR, Mid) ->
3416    io:format("raraa_mgc_verify_service_change_req -> entry with"
3417	      "~n   AR: ~p"
3418	      "~n   Mid: ~p"
3419	      "~n", [AR, Mid]),
3420    CR =
3421	case AR of
3422	    #'ActionRequest'{commandRequests = [CmdReq]} ->
3423		CmdReq;
3424	    _ ->
3425		Err1      = {invalid_action_request, AR},
3426		ED1       = cre_ErrDesc(AR),
3427		ErrReply1 = {discard_ack, ED1},
3428		throw({error, Err1, ErrReply1})
3429	end,
3430    Cmd =
3431	case CR of
3432	    #'CommandRequest'{command = Command} ->
3433		Command;
3434	    _ ->
3435		Err2      = {invalid_command_request, CR},
3436		ED2       = cre_ErrDesc(CR),
3437		ErrReply2 = {discard_ack, ED2},
3438		throw({error, Err2, ErrReply2})
3439	end,
3440    {Tid, Parms} =
3441	case Cmd of
3442	    {serviceChangeReq,
3443	     #'ServiceChangeRequest'{terminationID = [TermID],
3444				     serviceChangeParms = ServChParms}} ->
3445		{TermID, ServChParms};
3446	    _ ->
3447		Err3      = {invalid_command, Cmd},
3448		ED3       = cre_ErrDesc(Cmd),
3449		ErrReply3 = {discard_ack, ED3},
3450		throw({error, Err3, ErrReply3})
3451	end,
3452    case Tid of
3453	#megaco_term_id{contains_wildcards = false, id = ["root"]} ->
3454	    ok;
3455	_ ->
3456	    Err4      = {invalid_termination_id, Tid},
3457	    ED4       = cre_ErrDesc(Tid),
3458	    ErrReply4 = {discard_ack, ED4},
3459	    throw({error, Err4, ErrReply4})
3460    end,
3461    case Parms of
3462	#'ServiceChangeParm'{serviceChangeMethod = restart,
3463			     serviceChangeReason = [[$9,$0,$1|_]]} ->
3464	    AckData = [raraa_mgc_service_change_reply_ar(Mid, 1)],
3465	    Reply   = {discard_ack, AckData},
3466	    {ok, AR, Reply};
3467	_ ->
3468	    Err5      = {invalid_SCP, Parms},
3469	    ED5       = cre_ErrDesc(Parms),
3470	    ErrReply5 = {discard_ack, ED5},
3471	    {error, Err5, ErrReply5}
3472    end.
3473
3474
3475%% Notify Request verification
3476-ifndef(megaco_hipe_special).
3477raraa_mgc_verify_notify_req_fun() ->
3478    fun(Req) ->
3479	    raraa_mgc_verify_notify_req(Req)
3480    end.
3481-endif.
3482
3483raraa_mgc_verify_notify_req({handle_trans_request, _, ?VERSION, [AR]}) ->
3484    (catch raraa_mgc_do_verify_notify_req(AR));
3485raraa_mgc_verify_notify_req(Crap) ->
3486    ED       = cre_ErrDesc(Crap),
3487    ErrReply = {discard_ack, ED},
3488    {error, Crap, ErrReply}.
3489
3490raraa_mgc_do_verify_notify_req(AR) ->
3491    io:format("raraa_mgc_verify_notify_req -> entry with"
3492	      "~n   AR: ~p"
3493	      "~n", [AR]),
3494    {Cid, CR} =
3495	case AR of
3496	    #'ActionRequest'{contextId       = CtxID,
3497			     commandRequests = [CmdReq]} ->
3498		{CtxID, CmdReq};
3499	    _ ->
3500		Err1      = {invalid_action_request, AR},
3501		ED1       = cre_ErrDesc(AR),
3502		ErrReply1 = {discard_ack, ED1},
3503		throw({error, Err1, ErrReply1})
3504	end,
3505    Cmd =
3506	case CR of
3507	    #'CommandRequest'{command = Command} ->
3508		Command;
3509	    _ ->
3510		Err2      = {invalid_command_request, CR},
3511		ED2       = cre_ErrDesc(CR),
3512		ErrReply2 = {discard_ack, ED2},
3513		throw({error, Err2, ErrReply2})
3514	end,
3515    NR =
3516	case Cmd of
3517	    {notifyReq, NotifReq} ->
3518		NotifReq;
3519	    _ ->
3520		Err3      = {invalid_command, Cmd},
3521		ED3       = cre_ErrDesc(Cmd),
3522		ErrReply3 = {discard_ack, ED3},
3523		throw({error, Err3, ErrReply3})
3524	end,
3525    {Tid, OED} =
3526	case NR of
3527	    #'NotifyRequest'{terminationID            = [TermID],
3528			     observedEventsDescriptor = ObsEvsDesc,
3529			     errorDescriptor          = asn1_NOVALUE} ->
3530		{TermID, ObsEvsDesc};
3531	    _ ->
3532		Err4      = {invalid_NR, NR},
3533		ED4       = cre_ErrDesc(NR),
3534		ErrReply4 = {discard_ack, ED4},
3535		throw({error, Err4, ErrReply4})
3536	end,
3537    OE =
3538	case OED of
3539	    #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
3540		ObsEvLst;
3541	    _ ->
3542		Err5      = {invalid_OED, OED},
3543		ED5       = cre_ErrDesc(NR),
3544		ErrReply5 = {discard_ack, ED5},
3545		throw({error, Err5, ErrReply5})
3546	end,
3547    case OE of
3548	#'ObservedEvent'{eventName = "al/of"} ->
3549	    AckData = raraa,
3550	    Replies = [raraa_mgc_notify_reply_ar(Cid, Tid)],
3551	    Reply   = {{handle_ack, AckData}, Replies},
3552	    {ok, AR, Reply};
3553	_ ->
3554	    Err6      = {invalid_OE, OE},
3555	    ED6       = cre_ErrDesc(OE),
3556	    ErrReply6 = {discard_ack, ED6},
3557	    throw({error, Err6, ErrReply6})
3558    end.
3559
3560
3561-ifndef(megaco_hipe_special).
3562raraa_mgc_verify_handle_trans_ack_fun() ->
3563    fun(Ack) ->
3564	    raraa_mgc_verify_handle_trans_ack(Ack)
3565    end.
3566-endif.
3567
3568raraa_mgc_verify_handle_trans_ack(
3569  {handle_trans_ack, CH, ?VERSION, ok, raraa}) ->
3570    io:format("raraa_mgc_verify_handle_trans_ack -> ok"
3571              "~n   CH: ~p"
3572              "~n", [CH]),
3573    {ok, CH, ok};
3574raraa_mgc_verify_handle_trans_ack(Crap) ->
3575    io:format("raraa_mgc_verify_handle_trans_ack -> unknown"
3576              "~n   Crap: ~p~n", [Crap]),
3577    {error, Crap, ok}.
3578
3579
3580%% Disconnect verification
3581raraa_mgc_verify_handle_disconnect({handle_disconnect, CH, ?VERSION, _R}) ->
3582    {ok, CH, ok};
3583raraa_mgc_verify_handle_disconnect(Else) ->
3584    {error, Else, ok}.
3585
3586raraa_mgc_service_change_reply_ar(Mid, Cid) ->
3587    SCRP  = cre_serviceChangeResParm(Mid),
3588    SCRes = cre_serviceChangeResult(SCRP),
3589    Root  = #megaco_term_id{id = ["root"]},
3590    SCR   = cre_serviceChangeReply([Root], SCRes),
3591    CR    = cre_cmdReply(SCR),
3592    AR    = cre_actionReply(Cid, [CR]),
3593    AR.
3594
3595raraa_mgc_notify_reply_ar(Cid, TermId) ->
3596    NR    = cre_notifyReply([TermId]),
3597    CR    = cre_cmdReply(NR),
3598    cre_actionReply(Cid, [CR]).
3599
3600
3601%%
3602%% MG generator stuff
3603%%
3604-ifdef(megaco_hipe_special).
3605-define(raraa_mg_decode_msg_fun(Mod, Conf),
3606	{?MODULE, decode_msg, [Mod, Conf]}).
3607-define(raraa_mg_encode_msg_fun(Mod, Conf),
3608	{?MODULE, encode_msg, [Mod, Conf]}).
3609-define(raraa_mg_verify_service_change_rep_msg_fun(),
3610	{?MODULE, raraa_mg_verify_service_change_rep_msg, []}).
3611-define(raraa_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId),
3612	{?MODULE, raraa_mg_verify_notify_rep_msg, [TermId, TransId, ReqId, CtxId]}).
3613-else.
3614-define(raraa_mg_decode_msg_fun(Mod, Conf),
3615	raraa_mg_decode_msg_fun(Mod, Conf)).
3616-define(raraa_mg_encode_msg_fun(Mod, Conf),
3617	raraa_mg_encode_msg_fun(Mod, Conf)).
3618-define(raraa_mg_verify_service_change_rep_msg_fun(),
3619	raraa_mg_verify_service_change_rep_msg_fun()).
3620-define(raraa_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId),
3621	raraa_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId)).
3622-endif.
3623
3624raraa_mg_event_sequence(text, tcp) ->
3625    DecodeFun = ?raraa_mg_decode_msg_fun(megaco_pretty_text_encoder, []),
3626    EncodeFun = ?raraa_mg_encode_msg_fun(megaco_pretty_text_encoder, []),
3627    Mid       = {deviceName,"mg"},
3628    ServiceChangeReq = raraa_mg_service_change_request_msg(Mid, 1, 0),
3629    TermId  = #megaco_term_id{id = ["00000000","00000000","01101101"]},
3630    TransId = 2,
3631    ReqId   = 1,
3632    CtxId   = 1,
3633    NotifyReq = raraa_mg_notify_request_msg(Mid, TermId,
3634					    TransId, ReqId, CtxId),
3635    TransAck = raraa_mg_trans_ack_msg(Mid, TransId),
3636    ScrVerifyFun = ?raraa_mg_verify_service_change_rep_msg_fun(),
3637    NrVerifyFun  = ?raraa_mg_verify_notify_rep_msg_fun(TermId,
3638						       TransId, ReqId, CtxId),
3639    EvSeq = [{debug,  true},
3640             {decode, DecodeFun},
3641             {encode, EncodeFun},
3642             {connect, 2944},
3643             {send, "service-change-request", ServiceChangeReq},
3644             {expect_receive, "service-change-reply", {ScrVerifyFun, 10000}},
3645             {send, "notify request", NotifyReq},
3646             {expect_receive, "notify-reply", {NrVerifyFun, 10000}},
3647             {send, "transaction-ack", TransAck},
3648             {expect_nothing, 11000},
3649             disconnect
3650            ],
3651    EvSeq.
3652
3653-ifndef(megaco_hipe_special).
3654raraa_mg_encode_msg_fun(Mod, Conf) ->
3655    fun(M) ->
3656            encode_msg(M, Mod, Conf)
3657    end.
3658-endif.
3659
3660-ifndef(megaco_hipe_special).
3661raraa_mg_decode_msg_fun(Mod, Conf) ->
3662    fun(M) ->
3663            decode_msg(M, Mod, Conf)
3664    end.
3665-endif.
3666
3667-ifndef(megaco_hipe_special).
3668raraa_mg_verify_service_change_rep_msg_fun() ->
3669    fun(Msg) ->
3670	    (catch raraa_mg_verify_service_change_rep_msg(Msg))
3671    end.
3672-endif.
3673
3674raraa_mg_verify_service_change_rep_msg(#'MegacoMessage'{mess = Mess} = M) ->
3675    Body =
3676	case Mess of
3677	    #'Message'{version     = _V,
3678                       mId         = _MgMid,
3679                       messageBody = MsgBody} ->
3680		MsgBody;
3681	    _ ->
3682		throw({error, {invalid_Message, Mess}})
3683	end,
3684    Trans =
3685	case Body of
3686            {transactions, [Transactions]} ->
3687		Transactions;
3688	    _ ->
3689		throw({error, {invalid_messageBody, Body}})
3690	end,
3691    TR =
3692	case Trans of
3693            {transactionReply, TransReply} ->
3694		TransReply;
3695	    _ ->
3696		throw({error, {invalid_transactions, Trans}})
3697	end,
3698    TRes =
3699	case TR of
3700            #'TransactionReply'{transactionId = _Tid,
3701                                immAckRequired = asn1_NOVALUE,
3702                                transactionResult = TransRes} ->
3703		TransRes;
3704	    _ ->
3705		throw({error, {invalid_transactionReply, TR}})
3706	end,
3707    AR =
3708	case TRes of
3709            {actionReplies, [ActRes]} ->
3710		ActRes;
3711	    _ ->
3712		throw({error, {invalid_transactionResult, TRes}})
3713	end,
3714    CR =
3715	case AR of
3716            #'ActionReply'{contextId       = _Cid,
3717                           errorDescriptor = asn1_NOVALUE,
3718                           contextReply    = _CtxReq,
3719                           commandReply    = [CmdRep]} ->
3720		CmdRep;
3721	    _ ->
3722		throw({error, {invalid_actionReplies, AR}})
3723	end,
3724    SCR =
3725	case CR of
3726            {serviceChangeReply, ServChRep} ->
3727		ServChRep;
3728	    _ ->
3729		throw({error, {invalid_commandReply, CR}})
3730	end,
3731    SCRes =
3732	case SCR of
3733            #'ServiceChangeReply'{terminationID       = _TermID,
3734                                  serviceChangeResult = ServChRes} ->
3735		ServChRes;
3736	    _ ->
3737		throw({error, {invalid_serviceChangeReply, SCR}})
3738	end,
3739    SCRP =
3740	case SCRes of
3741            {serviceChangeResParms, Parms} ->
3742		Parms;
3743	    _ ->
3744		throw({error, {invalid_serviceChangeResult, SCRes}})
3745	end,
3746    case SCRP of
3747	#'ServiceChangeResParm'{serviceChangeMgcId = _MgcMid} ->
3748            {ok, M};
3749	_ ->
3750	    {error, {invalid_serviceChangeResParms, SCRP}}
3751    end;
3752raraa_mg_verify_service_change_rep_msg(Crap) ->
3753    {error, {invalid_message, Crap}}.
3754
3755-ifndef(megaco_hipe_special).
3756raraa_mg_verify_notify_rep_msg_fun(TermId, TransId, Rid, Cid) ->
3757    fun(Msg) ->
3758	    (catch raraa_mg_verify_notify_rep_msg(Msg,
3759						  TermId, TransId, Rid, Cid))
3760    end.
3761-endif.
3762
3763raraa_mg_verify_notify_rep_msg(#'MegacoMessage'{mess = Mess} = M,
3764			   TermId, TransId, Rid, Cid) ->
3765    io:format("raraa_mg_verify_notify_rep_msg -> entry with"
3766	      "~n   M:       ~p"
3767	      "~n   TermId:  ~p"
3768	      "~n   TransId: ~p"
3769	      "~n   Rid:     ~p"
3770	      "~n   Cid:     ~p"
3771	      "~n", [M, TermId, TransId, Rid, Cid]),
3772    Body =
3773	case Mess of
3774	    #'Message'{version     = ?VERSION,
3775                       mId         = _Mid,
3776                       messageBody = MsgBody} ->
3777		MsgBody;
3778	    _ ->
3779		throw({error, {invalid_Message, Mess}})
3780	end,
3781    Trans =
3782	case Body of
3783            {transactions, [Transactions]} ->
3784		Transactions;
3785	    _ ->
3786		throw({error, {invalid_messageBody, Body}})
3787	end,
3788    TR =
3789	case Trans of
3790            {transactionReply, TransReply} ->
3791		TransReply;
3792	    _ ->
3793		throw({error, {invalid_transactions, Trans}})
3794	end,
3795    TRes =
3796	case TR of
3797            #'TransactionReply'{transactionId     = TransId,
3798                                immAckRequired    = 'NULL',
3799                                transactionResult = TransRes} ->
3800		TransRes;
3801	    _ ->
3802		throw({error, {invalid_transactionReply, TR}})
3803	end,
3804    AR =
3805	case TRes of
3806            {actionReplies, [ActRes]} ->
3807		ActRes;
3808	    _ ->
3809		throw({error, {invalid_transactionResult, TRes}})
3810	end,
3811    CR =
3812	case AR of
3813            #'ActionReply'{contextId       = Cid,
3814                           errorDescriptor = asn1_NOVALUE,
3815                           contextReply    = _CtxReq,
3816                           commandReply    = [CmdRep]} ->
3817		CmdRep;
3818	    _ ->
3819		throw({error, {invalid_actionReplies, AR}})
3820	end,
3821    NR =
3822	case CR of
3823            {notifyReply, NotifyReply} ->
3824		NotifyReply;
3825	    _ ->
3826		throw({error, {invalid_commandReply, CR}})
3827	end,
3828    case NR of
3829	#'NotifyReply'{terminationID   = [TermId],
3830		       errorDescriptor = asn1_NOVALUE} ->
3831	    {ok, M};
3832	_ ->
3833	    {error, {invalid_notifyReply, NR}}
3834    end;
3835raraa_mg_verify_notify_rep_msg(Crap, _TermId, _TransId, _Rid, _Cid) ->
3836    {error, {invalid_message, Crap}}.
3837
3838raraa_mg_service_change_request_ar(_Mid, Cid) ->
3839    Prof  = cre_serviceChangeProf("resgw", 1),
3840    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
3841    Root  = #megaco_term_id{id = ["root"]},
3842    SCR   = cre_serviceChangeReq([Root], SCP),
3843    CMD   = cre_command(SCR),
3844    CR    = cre_cmdReq(CMD),
3845    cre_actionReq(Cid, [CR]).
3846
3847raraa_mg_service_change_request_msg(Mid, TransId, Cid) ->
3848    AR    = raraa_mg_service_change_request_ar(Mid, Cid),
3849    TR    = cre_transReq(TransId, [AR]),
3850    Trans = cre_transaction(TR),
3851    Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
3852    cre_megacoMessage(Mess).
3853
3854raraa_mg_notify_request_ar(Rid, Tid, Cid) ->
3855    TT      = cre_timeNotation("19990729", "22000000"),
3856    Ev      = cre_obsEvent("al/of", TT),
3857    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
3858    NR      = cre_notifyReq([Tid], EvsDesc),
3859    CMD     = cre_command(NR),
3860    CR      = cre_cmdReq(CMD),
3861    cre_actionReq(Cid, [CR]).
3862
3863raraa_mg_notify_request_msg(Mid, TermId, TransId, Rid, Cid) ->
3864    AR      = raraa_mg_notify_request_ar(Rid, TermId, Cid),
3865    TR      = cre_transReq(TransId, [AR]),
3866    Trans   = cre_transaction(TR),
3867    Mess    = cre_message(?VERSION, Mid, cre_transactions([Trans])),
3868    cre_megacoMessage(Mess).
3869
3870raraa_mg_trans_ack_msg(Mid, TransId) ->
3871    TR    = cre_transRespAck(cre_transAck(TransId)),
3872    Trans = cre_transaction(TR),
3873    Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
3874    cre_megacoMessage(Mess).
3875
3876
3877
3878%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3879
3880request_and_reply_and_no_ack(suite) ->
3881    [];
3882request_and_reply_and_no_ack(doc) ->
3883    ["This test case tests that megaco handles a failed three-way-handshake,"
3884     " i.e. when the ack never arrives"];
3885request_and_reply_and_no_ack(Config) when is_list(Config) ->
3886    Pre = fun() ->
3887                  MgcNode = make_node_name(mgc),
3888                  MgNode  = make_node_name(mg),
3889                  d("start nodes: "
3890                    "~n      MgcNode: ~p"
3891                    "~n      MgNode:  ~p",
3892                    [MgcNode, MgNode]),
3893                  Nodes = [MgcNode, MgNode],
3894                  ok = ?START_NODES(Nodes, true),
3895                  Nodes
3896          end,
3897    Case = fun do_request_and_reply_and_no_ack/1,
3898    Post = fun(Nodes) ->
3899                   d("stop nodes"),
3900                   ?STOP_NODES(lists:reverse(Nodes))
3901           end,
3902    try_tc(rarana, Pre, Case, Post).
3903
3904
3905do_request_and_reply_and_no_ack([MgcNode, MgNode]) ->
3906    d("[MGC] start the simulator "),
3907    {ok, Mgc} = megaco_test_megaco_generator:start_link("MGC", MgcNode),
3908
3909    d("[MGC] create the event sequence"),
3910    MgcEvSeq = rarana_mgc_event_sequence(text, tcp),
3911
3912    i("wait some time before starting the MGC simulation"),
3913    sleep(1000),
3914
3915    d("[MGC] start the simulation"),
3916    {ok, MgcId} = megaco_test_megaco_generator:exec(Mgc, MgcEvSeq),
3917
3918    %% i("wait some time before starting the MG simulator"),
3919    %% sleep(1000),
3920
3921    i("await MGC ready announcement"),
3922    receive
3923        announce_mgc ->
3924            i("received MGC ready announcement"),
3925            ok
3926    end,
3927
3928    d("[MG] start the simulator (generator)"),
3929    {ok, Mg} = megaco_test_tcp_generator:start_link("MG", MgNode),
3930
3931    d("[MG] create the event sequence"),
3932    MgEvSeq = rarana_mg_event_sequence(text, tcp),
3933
3934    i("wait some time before starting the MG simulation"),
3935    sleep(1000),
3936
3937    d("[MG] start the simulation"),
3938    {ok, MgId} = megaco_test_tcp_generator:exec(Mg, MgEvSeq),
3939
3940    d("await the generator reply(s)"),
3941    await_completion([MgcId, MgId]),
3942
3943    %% Tell Mgc to stop
3944    i("[MGC] stop generator"),
3945    megaco_test_megaco_generator:stop(Mgc),
3946
3947    %% Tell Mg to stop
3948    i("[MG] stop generator"),
3949    megaco_test_tcp_generator:stop(Mg),
3950
3951    i("done", []),
3952    ok.
3953
3954
3955%%
3956%% MGC generator stuff
3957%%
3958
3959-ifdef(megaco_hipe_special).
3960-define(rarana_mgc_verify_handle_connect_fun(),
3961        {?MODULE, rarana_mgc_verify_handle_connect, []}).
3962-define(rarana_mgc_verify_service_change_req_fun(Mid),
3963        {?MODULE, rarana_mgc_verify_service_change_req, [Mid]}).
3964-define(rarana_mgc_verify_notify_req_fun(),
3965        {?MODULE, rarana_mgc_verify_notify_req, []}).
3966-define(rarana_mgc_verify_handle_trans_ack_fun(),
3967	{?MODULE, rarana_mgc_verify_handle_trans_ack, []}).
3968-define(rarana_mgc_verify_handle_disconnect_fun(),
3969        {?MODULE, rarana_mgc_verify_handle_disconnect, []}).
3970-else.
3971-define(rarana_mgc_verify_handle_connect_fun(),
3972        fun rarana_mgc_verify_handle_connect/1).
3973-define(rarana_mgc_verify_service_change_req_fun(Mid),
3974        rarana_mgc_verify_service_change_req_fun(Mid)).
3975-define(rarana_mgc_verify_notify_req_fun(),
3976	rarana_mgc_verify_notify_req_fun()).
3977-define(rarana_mgc_verify_handle_trans_ack_fun(),
3978	rarana_mgc_verify_handle_trans_ack_fun()).
3979-define(rarana_mgc_verify_handle_disconnect_fun(),
3980	fun rarana_mgc_verify_handle_disconnect/1).
3981-endif.
3982
3983rarana_mgc_event_sequence(text, tcp) ->
3984    CTRL = self(),
3985    Mid = {deviceName,"ctrl"},
3986    RI = [
3987          {port,             2944},
3988          {encoding_module,  megaco_pretty_text_encoder},
3989          {encoding_config,  []},
3990          {transport_module, megaco_tcp}
3991         ],
3992    ConnectVerify = ?rarana_mgc_verify_handle_connect_fun(),
3993    ScrVerify     = ?rarana_mgc_verify_service_change_req_fun(Mid),
3994    NrVerify      = ?rarana_mgc_verify_notify_req_fun(),
3995    AckVerify     = ?rarana_mgc_verify_handle_trans_ack_fun(),
3996    DiscoVerify   = ?rarana_mgc_verify_handle_disconnect_fun(),
3997    EvSeq = [
3998             {debug, true},
3999             {megaco_trace, disable},
4000             {megaco_trace, max},
4001             megaco_start,
4002             {megaco_start_user, Mid, RI, []},
4003             {megaco_update_user_info, sent_pending_limit, 100},
4004             {megaco_update_user_info, reply_timer,        9000},
4005             start_transport,
4006             listen,
4007
4008             %% ANNOUNCE READY
4009             {trigger, fun() -> CTRL ! announce_mgc end},
4010
4011             {megaco_callback, handle_connect,           ConnectVerify},
4012             {megaco_conn_info, all},
4013             {megaco_callback, handle_trans_request,     ScrVerify},
4014	     {megaco_callback, handle_trans_request,     NrVerify},
4015	     {megaco_callback, handle_trans_ack,         AckVerify},
4016	     %% {megaco_callback, nocall,                   8000},
4017             {megaco_callback, handle_disconnect,        DiscoVerify},
4018             megaco_stop_user,
4019             megaco_stop
4020            ],
4021    EvSeq.
4022
4023%% Connect verification
4024rarana_mgc_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
4025    {ok, CH, ok};
4026rarana_mgc_verify_handle_connect(Else) ->
4027    {error, Else, ok}.
4028
4029%% Service Change verification
4030-ifndef(megaco_hipe_special).
4031rarana_mgc_verify_service_change_req_fun(Mid) ->
4032    fun(Req) ->
4033	    rarana_mgc_verify_service_change_req(Req, Mid)
4034    end.
4035-endif.
4036
4037rarana_mgc_verify_service_change_req(
4038  {handle_trans_request, _, ?VERSION, [AR]}, Mid) ->
4039    (catch rarana_do_verify_service_change_req(AR, Mid));
4040rarana_mgc_verify_service_change_req(Crap, _Mid) ->
4041    ED       = cre_ErrDesc(Crap),
4042    ErrReply = {discard_ack, ED},
4043    {error, Crap, ErrReply}.
4044
4045rarana_do_verify_service_change_req(AR, Mid) ->
4046    CR =
4047	case AR of
4048	    #'ActionRequest'{commandRequests = [CmdReq]} ->
4049		CmdReq;
4050	    _ ->
4051		Err1      = {invalid_action_request, AR},
4052		ED1       = cre_ErrDesc(AR),
4053		ErrReply1 = {discard_ack, ED1},
4054		throw({error, Err1, ErrReply1})
4055	end,
4056    Cmd =
4057	case CR of
4058	    #'CommandRequest'{command = Command} ->
4059		Command;
4060	    _ ->
4061		Err2      = {invalid_command_request, CR},
4062		ED2       = cre_ErrDesc(CR),
4063		ErrReply2 = {discard_ack, ED2},
4064		throw({error, Err2, ErrReply2})
4065	end,
4066    {Tid, Parms} =
4067	case Cmd of
4068	    {serviceChangeReq,
4069	     #'ServiceChangeRequest'{terminationID = [TermID],
4070				     serviceChangeParms = ServChParms}} ->
4071		{TermID, ServChParms};
4072	    _ ->
4073		Err3      = {invalid_command, Cmd},
4074		ED3       = cre_ErrDesc(Cmd),
4075		ErrReply3 = {discard_ack, ED3},
4076		throw({error, Err3, ErrReply3})
4077	end,
4078    case Tid of
4079	#megaco_term_id{contains_wildcards = false, id = ["root"]} ->
4080	    ok;
4081	_ ->
4082	    Err4      = {invalid_termination_id, Tid},
4083	    ED4       = cre_ErrDesc(Tid),
4084	    ErrReply4 = {discard_ack, ED4},
4085	    throw({error, Err4, ErrReply4})
4086    end,
4087    case Parms of
4088	#'ServiceChangeParm'{serviceChangeMethod = restart,
4089			     serviceChangeReason = [[$9,$0,$1|_]]} ->
4090	    AckData = [rarana_mgc_service_change_reply_ar(Mid, 1)],
4091	    Reply   = {discard_ack, AckData},
4092	    {ok, AR, Reply};
4093	_ ->
4094	    Err5      = {invalid_SCP, Parms},
4095	    ED5       = cre_ErrDesc(Parms),
4096	    ErrReply5 = {discard_ack, ED5},
4097	    {error, Err5, ErrReply5}
4098    end.
4099
4100
4101%% Notify Request verification
4102-ifndef(megaco_hipe_special).
4103rarana_mgc_verify_notify_req_fun() ->
4104    fun(Req) ->
4105	    rarana_mgc_verify_notify_req(Req)
4106    end.
4107-endif.
4108
4109rarana_mgc_verify_notify_req({handle_trans_request, _, ?VERSION, [AR]}) ->
4110    (catch rarana_mgc_do_verify_notify_req(AR));
4111rarana_mgc_verify_notify_req(Crap) ->
4112    ED       = cre_ErrDesc(Crap),
4113    ErrReply = {discard_ack, ED},
4114    {error, Crap, ErrReply}.
4115
4116rarana_mgc_do_verify_notify_req(AR) ->
4117    {Cid, CR} =
4118	case AR of
4119	    #'ActionRequest'{contextId       = CtxID,
4120			     commandRequests = [CmdReq]} ->
4121		{CtxID, CmdReq};
4122	    _ ->
4123		Err1      = {invalid_action_request, AR},
4124		ED1       = cre_ErrDesc(AR),
4125		ErrReply1 = {discard_ack, ED1},
4126		throw({error, Err1, ErrReply1})
4127	end,
4128    Cmd =
4129	case CR of
4130	    #'CommandRequest'{command = Command} ->
4131		Command;
4132	    _ ->
4133		Err2      = {invalid_command_request, CR},
4134		ED2       = cre_ErrDesc(CR),
4135		ErrReply2 = {discard_ack, ED2},
4136		throw({error, Err2, ErrReply2})
4137	end,
4138    NR =
4139	case Cmd of
4140	    {notifyReq, NotifReq} ->
4141		NotifReq;
4142	    _ ->
4143		Err3      = {invalid_command, Cmd},
4144		ED3       = cre_ErrDesc(Cmd),
4145		ErrReply3 = {discard_ack, ED3},
4146		throw({error, Err3, ErrReply3})
4147	end,
4148    {Tid, OED} =
4149	case NR of
4150	    #'NotifyRequest'{terminationID            = [TermID],
4151			     observedEventsDescriptor = ObsEvsDesc,
4152			     errorDescriptor          = asn1_NOVALUE} ->
4153		{TermID, ObsEvsDesc};
4154	    _ ->
4155		Err4      = {invalid_NR, NR},
4156		ED4       = cre_ErrDesc(NR),
4157		ErrReply4 = {discard_ack, ED4},
4158		throw({error, Err4, ErrReply4})
4159	end,
4160    OE =
4161	case OED of
4162	    #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
4163		ObsEvLst;
4164	    _ ->
4165		Err5      = {invalid_OED, OED},
4166		ED5       = cre_ErrDesc(NR),
4167		ErrReply5 = {discard_ack, ED5},
4168		throw({error, Err5, ErrReply5})
4169	end,
4170    case OE of
4171	#'ObservedEvent'{eventName = "al/of"} ->
4172	    AckData = rarana,
4173	    Replies = [rarana_mgc_notify_reply_ar(Cid, Tid)],
4174	    Reply   = {{handle_ack, AckData}, Replies},
4175	    {ok, AR, Reply};
4176	_ ->
4177	    Err6      = {invalid_OE, OE},
4178	    ED6       = cre_ErrDesc(OE),
4179	    ErrReply6 = {discard_ack, ED6},
4180	    throw({error, Err6, ErrReply6})
4181    end.
4182
4183
4184-ifndef(megaco_hipe_special).
4185rarana_mgc_verify_handle_trans_ack_fun() ->
4186    fun(Ack) ->
4187	    rarana_mgc_verify_handle_trans_ack(Ack)
4188    end.
4189-endif.
4190
4191rarana_mgc_verify_handle_trans_ack({handle_trans_ack, CH, ?VERSION,
4192			     {error, timeout}, rarana}) ->
4193    io:format("rarana_mgc_verify_handle_trans_ack -> expected error: ok"
4194              "~n   CH: ~p"
4195              "~n", [CH]),
4196    {ok, CH, ok};
4197rarana_mgc_verify_handle_trans_ack(Crap) ->
4198    io:format("rarana_mgc_verify_trans_ack -> unknown"
4199              "~n   Crap: ~p~n", [Crap]),
4200    {error, Crap, ok}.
4201
4202
4203%% Disconnect verification
4204rarana_mgc_verify_handle_disconnect({handle_disconnect, CH, ?VERSION, _R}) ->
4205    {ok, CH, ok};
4206rarana_mgc_verify_handle_disconnect(Else) ->
4207    {error, Else, ok}.
4208
4209rarana_mgc_service_change_reply_ar(Mid, Cid) ->
4210    SCRP  = cre_serviceChangeResParm(Mid),
4211    SCRes = cre_serviceChangeResult(SCRP),
4212    Root  = #megaco_term_id{id = ["root"]},
4213    SCR   = cre_serviceChangeReply([Root], SCRes),
4214    CR    = cre_cmdReply(SCR),
4215    AR    = cre_actionReply(Cid, [CR]),
4216    AR.
4217
4218rarana_mgc_notify_reply_ar(Cid, TermId) ->
4219    NR    = cre_notifyReply([TermId]),
4220    CR    = cre_cmdReply(NR),
4221    cre_actionReply(Cid, [CR]).
4222
4223
4224%%
4225%% MG generator stuff
4226%%
4227-ifdef(megaco_hipe_special).
4228-define(rarana_mg_decode_msg_fun(Mod, Conf),
4229	{?MODULE, decode_msg, [Mod, Conf]}).
4230-define(rarana_mg_encode_msg_fun(Mod, Conf),
4231	{?MODULE, encode_msg, [Mod, Conf]}).
4232-define(rarana_mg_verify_service_change_rep_msg_fun(),
4233	{?MODULE, rarana_mg_verify_service_change_rep_msg, []}).
4234-define(rarana_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId),
4235	{?MODULE, rarana_mg_verify_notify_rep_msg, [TermId, TransId, ReqId, CtxId]}).
4236-else.
4237-define(rarana_mg_decode_msg_fun(Mod, Conf),
4238	rarana_mg_decode_msg_fun(Mod, Conf)).
4239-define(rarana_mg_encode_msg_fun(Mod, Conf),
4240	rarana_mg_encode_msg_fun(Mod, Conf)).
4241-define(rarana_mg_verify_service_change_rep_msg_fun(),
4242	rarana_mg_verify_service_change_rep_msg_fun()).
4243-define(rarana_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId),
4244	rarana_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId)).
4245-endif.
4246
4247rarana_mg_event_sequence(text, tcp) ->
4248    DecodeFun = ?rarana_mg_decode_msg_fun(megaco_pretty_text_encoder, []),
4249    EncodeFun = ?rarana_mg_encode_msg_fun(megaco_pretty_text_encoder, []),
4250    Mid       = {deviceName,"mg"},
4251    ServiceChangeReq = rarana_mg_service_change_request_msg(Mid, 1, 0),
4252    TermId  = #megaco_term_id{id = ["00000000","00000000","01101101"]},
4253    TransId = 2,
4254    ReqId   = 1,
4255    CtxId   = 1,
4256    NotifyReq = rarana_mg_notify_request_msg(Mid, TermId,
4257					    TransId, ReqId, CtxId),
4258    ScrVerifyFun = ?rarana_mg_verify_service_change_rep_msg_fun(),
4259    NrVerifyFun  = ?rarana_mg_verify_notify_rep_msg_fun(TermId,
4260							TransId, ReqId, CtxId),
4261    EvSeq = [{debug,  true},
4262             {decode, DecodeFun},
4263             {encode, EncodeFun},
4264             {connect, 2944},
4265             {send, "service-change-request", ServiceChangeReq},
4266             {expect_receive, "service-change-reply", {ScrVerifyFun, 10000}},
4267             {send, "notify request", NotifyReq},
4268             {expect_receive, "notify-reply", {NrVerifyFun, 10000}},
4269             {expect_nothing, 11000},
4270             disconnect
4271            ],
4272    EvSeq.
4273
4274-ifndef(megaco_hipe_special).
4275rarana_mg_encode_msg_fun(Mod, Conf) ->
4276    fun(M) ->
4277            encode_msg(M, Mod, Conf)
4278    end.
4279-endif.
4280
4281-ifndef(megaco_hipe_special).
4282rarana_mg_decode_msg_fun(Mod, Conf) ->
4283    fun(M) ->
4284            decode_msg(M, Mod, Conf)
4285    end.
4286-endif.
4287
4288-ifndef(megaco_hipe_special).
4289rarana_mg_verify_service_change_rep_msg_fun() ->
4290    fun(Msg) ->
4291	    (catch rarana_mg_verify_service_change_rep_msg(Msg))
4292    end.
4293-endif.
4294
4295rarana_mg_verify_service_change_rep_msg(#'MegacoMessage'{mess = Mess} = M) ->
4296    Body =
4297	case Mess of
4298	    #'Message'{version     = _V,
4299                       mId         = _MgMid,
4300                       messageBody = MsgBody} ->
4301		MsgBody;
4302	    _ ->
4303		throw({error, {invalid_Message, Mess}})
4304	end,
4305    Trans =
4306	case Body of
4307            {transactions, [Transactions]} ->
4308		Transactions;
4309	    _ ->
4310		throw({error, {invalid_messageBody, Body}})
4311	end,
4312    TR =
4313	case Trans of
4314            {transactionReply, TransReply} ->
4315		TransReply;
4316	    _ ->
4317		throw({error, {invalid_transactions, Trans}})
4318	end,
4319    TRes =
4320	case TR of
4321            #'TransactionReply'{transactionId = _Tid,
4322                                immAckRequired = asn1_NOVALUE,
4323                                transactionResult = TransRes} ->
4324		TransRes;
4325	    _ ->
4326		throw({error, {invalid_transactionReply, TR}})
4327	end,
4328    AR =
4329	case TRes of
4330            {actionReplies, [ActRes]} ->
4331		ActRes;
4332	    _ ->
4333		throw({error, {invalid_transactionResult, TRes}})
4334	end,
4335    CR =
4336	case AR of
4337            #'ActionReply'{contextId       = _Cid,
4338                           errorDescriptor = asn1_NOVALUE,
4339                           contextReply    = _CtxReq,
4340                           commandReply    = [CmdRep]} ->
4341		CmdRep;
4342	    _ ->
4343		throw({error, {invalid_actionReplies, AR}})
4344	end,
4345    SCR =
4346	case CR of
4347            {serviceChangeReply, ServChRep} ->
4348		ServChRep;
4349	    _ ->
4350		throw({error, {invalid_commandReply, CR}})
4351	end,
4352    SCRes =
4353	case SCR of
4354            #'ServiceChangeReply'{terminationID       = _TermID,
4355                                  serviceChangeResult = ServChRes} ->
4356		ServChRes;
4357	    _ ->
4358		throw({error, {invalid_serviceChangeReply, SCR}})
4359	end,
4360    SCRP =
4361	case SCRes of
4362            {serviceChangeResParms, Parms} ->
4363		Parms;
4364	    _ ->
4365		throw({error, {invalid_serviceChangeResult, SCRes}})
4366	end,
4367    case SCRP of
4368	#'ServiceChangeResParm'{serviceChangeMgcId = _MgcMid} ->
4369            {ok, M};
4370	_ ->
4371	    {error, {invalid_serviceChangeResParms, SCRP}}
4372    end;
4373rarana_mg_verify_service_change_rep_msg(Crap) ->
4374    {error, {invalid_message, Crap}}.
4375
4376-ifndef(megaco_hipe_special).
4377rarana_mg_verify_notify_rep_msg_fun(TermId, TransId, Rid, Cid) ->
4378    fun(Msg) ->
4379	    (catch rarana_mg_verify_notify_rep_msg(Msg,
4380						   TermId, TransId, Rid, Cid))
4381    end.
4382-endif.
4383
4384rarana_mg_verify_notify_rep_msg(#'MegacoMessage'{mess = Mess} = M,
4385				TermId, TransId, Rid, Cid) ->
4386    io:format("rarana_mg_verify_notify_rep_msg -> entry with"
4387	      "~n   M:       ~p"
4388	      "~n   TermId:  ~p"
4389	      "~n   TransId: ~p"
4390	      "~n   Rid:     ~p"
4391	      "~n   Cid:     ~p"
4392	      "~n", [M, TermId, TransId, Rid, Cid]),
4393    Body =
4394	case Mess of
4395	    #'Message'{version     = ?VERSION,
4396                       mId         = _Mid,
4397                       messageBody = MsgBody} ->
4398		MsgBody;
4399	    _ ->
4400		throw({error, {invalid_Message, Mess}})
4401	end,
4402    Trans =
4403	case Body of
4404            {transactions, [Transactions]} ->
4405		Transactions;
4406	    _ ->
4407		throw({error, {invalid_messageBody, Body}})
4408	end,
4409    TR =
4410	case Trans of
4411            {transactionReply, TransReply} ->
4412		TransReply;
4413	    _ ->
4414		throw({error, {invalid_transactions, Trans}})
4415	end,
4416    TRes =
4417	case TR of
4418            #'TransactionReply'{transactionId     = TransId,
4419                                immAckRequired    = 'NULL',
4420                                transactionResult = TransRes} ->
4421		TransRes;
4422	    _ ->
4423		throw({error, {invalid_transactionReply, TR}})
4424	end,
4425    AR =
4426	case TRes of
4427            {actionReplies, [ActRes]} ->
4428		ActRes;
4429	    _ ->
4430		throw({error, {invalid_transactionResult, TRes}})
4431	end,
4432    CR =
4433	case AR of
4434            #'ActionReply'{contextId       = Cid,
4435                           errorDescriptor = asn1_NOVALUE,
4436                           contextReply    = _CtxReq,
4437                           commandReply    = [CmdRep]} ->
4438		CmdRep;
4439	    _ ->
4440		throw({error, {invalid_actionReplies, AR}})
4441	end,
4442    NR =
4443	case CR of
4444            {notifyReply, NotifyReply} ->
4445		NotifyReply;
4446	    _ ->
4447		throw({error, {invalid_commandReply, CR}})
4448	end,
4449    case NR of
4450	#'NotifyReply'{terminationID   = [TermId],
4451		       errorDescriptor = asn1_NOVALUE} ->
4452	    {ok, M};
4453	_ ->
4454	    {error, {invalid_notifyReply, NR}}
4455    end;
4456rarana_mg_verify_notify_rep_msg(Crap, _TermId, _TransId, _Rid, _Cid) ->
4457    {error, {invalid_message, Crap}}.
4458
4459rarana_mg_service_change_request_ar(_Mid, Cid) ->
4460    Prof  = cre_serviceChangeProf("resgw", 1),
4461    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
4462    Root  = #megaco_term_id{id = ["root"]},
4463    SCR   = cre_serviceChangeReq([Root], SCP),
4464    CMD   = cre_command(SCR),
4465    CR    = cre_cmdReq(CMD),
4466    cre_actionReq(Cid, [CR]).
4467
4468rarana_mg_service_change_request_msg(Mid, TransId, Cid) ->
4469    AR    = rarana_mg_service_change_request_ar(Mid, Cid),
4470    TR    = cre_transReq(TransId, [AR]),
4471    Trans = cre_transaction(TR),
4472    Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
4473    cre_megacoMessage(Mess).
4474
4475rarana_mg_notify_request_ar(Rid, Tid, Cid) ->
4476    TT      = cre_timeNotation("19990729", "22000000"),
4477    Ev      = cre_obsEvent("al/of", TT),
4478    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
4479    NR      = cre_notifyReq([Tid], EvsDesc),
4480    CMD     = cre_command(NR),
4481    CR      = cre_cmdReq(CMD),
4482    cre_actionReq(Cid, [CR]).
4483
4484rarana_mg_notify_request_msg(Mid, TermId, TransId, Rid, Cid) ->
4485    AR      = rarana_mg_notify_request_ar(Rid, TermId, Cid),
4486    TR      = cre_transReq(TransId, [AR]),
4487    Trans   = cre_transaction(TR),
4488    Mess    = cre_message(?VERSION, Mid, cre_transactions([Trans])),
4489    cre_megacoMessage(Mess).
4490
4491
4492%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4493
4494request_and_reply_and_late_ack(suite) ->
4495    [];
4496request_and_reply_and_late_ack(doc) ->
4497    ["This test case tests that megaco handles three-way-handshake "
4498     "when the ack is late (and requeire a retransmission)"];
4499request_and_reply_and_late_ack(Config) when is_list(Config) ->
4500    Pre = fun() ->
4501                  MgcNode = make_node_name(mgc),
4502                  MgNode  = make_node_name(mg),
4503                  d("start nodes: "
4504                    "~n   MgcNode: ~p"
4505                    "~n   MgNode:  ~p",
4506                    [MgcNode, MgNode]),
4507                  Nodes = [MgcNode, MgNode],
4508                  ok = ?START_NODES(Nodes, true),
4509                  Nodes
4510          end,
4511    Case = fun do_request_and_reply_and_late_ack/1,
4512    Post = fun(Nodes) ->
4513                   d("stop nodes"),
4514                   ?STOP_NODES(lists:reverse(Nodes))
4515           end,
4516    try_tc(rarala, Pre, Case, Post).
4517
4518do_request_and_reply_and_late_ack([MgcNode, MgNode]) ->
4519    d("[MGC] start the simulator "),
4520    {ok, Mgc} = megaco_test_megaco_generator:start_link("MGC", MgcNode),
4521
4522    d("[MGC] create the event sequence"),
4523    MgcEvSeq = rarala_mgc_event_sequence(text, tcp),
4524
4525    i("wait some time before starting the MGC simulation"),
4526    sleep(1000),
4527
4528    d("[MGC] start the simulation"),
4529    {ok, MgcId} = megaco_test_megaco_generator:exec(Mgc, MgcEvSeq),
4530
4531    %% i("wait some time before starting the MG simulator"),
4532    %% sleep(1000),
4533
4534    i("await MGC ready announcement"),
4535    receive
4536        announce_mgc ->
4537            i("received MGC ready announcement"),
4538            ok
4539    end,
4540
4541    d("[MG] start the simulator (generator)"),
4542    {ok, Mg} = megaco_test_tcp_generator:start_link("MG", MgNode),
4543
4544    d("[MG] create the event sequence"),
4545    MgEvSeq = rarala_mg_event_sequence(text, tcp),
4546
4547    i("wait some time before starting the MG simulation"),
4548    sleep(1000),
4549
4550    d("[MG] start the simulation"),
4551    {ok, MgId} = megaco_test_tcp_generator:exec(Mg, MgEvSeq),
4552
4553    d("await the generator reply(s)"),
4554    await_completion([MgcId, MgId]),
4555
4556    %% Tell Mgc to stop
4557    i("[MGC] stop generator"),
4558    megaco_test_megaco_generator:stop(Mgc),
4559
4560    %% Tell Mg to stop
4561    i("[MG] stop generator"),
4562    megaco_test_tcp_generator:stop(Mg),
4563
4564    i("done", []),
4565    ok.
4566
4567
4568%%
4569%% MGC generator stuff
4570%%
4571
4572-ifdef(megaco_hipe_special).
4573-define(rarala_mgc_verify_handle_connect_fun(),
4574        {?MODULE, rarala_mgc_verify_handle_connect, []}).
4575-define(rarala_mgc_verify_service_change_req_fun(Mid),
4576        {?MODULE, rarala_mgc_verify_service_change_req, [Mid]}).
4577-define(rarala_mgc_verify_notify_req_fun(),
4578        {?MODULE, rarala_mgc_verify_notify_req, []}).
4579-define(rarala_mgc_verify_handle_trans_ack_fun(),
4580	{?MODULE, rarala_mgc_verify_handle_trans_ack, []}).
4581-define(rarala_mgc_verify_handle_disconnect_fun(),
4582        {?MODULE, rarala_mgc_verify_handle_disconnect, []}).
4583-else.
4584-define(rarala_mgc_verify_handle_connect_fun(),
4585        fun rarala_mgc_verify_handle_connect/1).
4586-define(rarala_mgc_verify_service_change_req_fun(Mid),
4587        rarala_mgc_verify_service_change_req_fun(Mid)).
4588-define(rarala_mgc_verify_notify_req_fun(),
4589	rarala_mgc_verify_notify_req_fun()).
4590-define(rarala_mgc_verify_handle_trans_ack_fun(),
4591	rarala_mgc_verify_handle_trans_ack_fun()).
4592-define(rarala_mgc_verify_handle_disconnect_fun(),
4593	fun rarala_mgc_verify_handle_disconnect/1).
4594-endif.
4595
4596rarala_mgc_event_sequence(text, tcp) ->
4597    CTRL = self(),
4598    Mid = {deviceName,"ctrl"},
4599    RI = [
4600          {port,             2944},
4601          {encoding_module,  megaco_pretty_text_encoder},
4602          {encoding_config,  []},
4603          {transport_module, megaco_tcp}
4604         ],
4605    RepTmr = #megaco_incr_timer{wait_for    = 3000,
4606				factor      = 1,
4607				incr        = 0,
4608				max_retries = 2
4609			       },
4610    ConnectVerify = ?rarala_mgc_verify_handle_connect_fun(),
4611    ScrVerify     = ?rarala_mgc_verify_service_change_req_fun(Mid),
4612    NrVerify      = ?rarala_mgc_verify_notify_req_fun(),
4613    AckVerify     = ?rarala_mgc_verify_handle_trans_ack_fun(),
4614    DiscoVerify   = ?rarala_mgc_verify_handle_disconnect_fun(),
4615    EvSeq = [
4616             {debug, true},
4617             {megaco_trace, disable},
4618             {megaco_trace, max},
4619             megaco_start,
4620             {megaco_start_user, Mid, RI, []},
4621             {megaco_update_user_info, sent_pending_limit, 100},
4622             {megaco_update_user_info, reply_timer,        RepTmr},
4623             start_transport,
4624             listen,
4625
4626             %% ANNOUNCE READY
4627             {trigger, fun() -> CTRL ! announce_mgc end},
4628
4629             {megaco_callback, handle_connect,           ConnectVerify},
4630             {megaco_conn_info, all},
4631             {megaco_callback, handle_trans_request,     ScrVerify},
4632	     {megaco_callback, handle_trans_request,     NrVerify},
4633	     {megaco_callback, handle_trans_ack,         AckVerify},
4634             {megaco_callback, handle_disconnect,        DiscoVerify},
4635             megaco_stop_user,
4636             megaco_stop
4637            ],
4638    EvSeq.
4639
4640%% Connect verification
4641rarala_mgc_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
4642    {ok, CH, ok};
4643rarala_mgc_verify_handle_connect(Else) ->
4644    {error, Else, ok}.
4645
4646%% Service Change verification
4647-ifndef(megaco_hipe_special).
4648rarala_mgc_verify_service_change_req_fun(Mid) ->
4649    fun(Req) ->
4650	    rarala_mgc_verify_service_change_req(Req, Mid)
4651    end.
4652-endif.
4653
4654rarala_mgc_verify_service_change_req(
4655  {handle_trans_request, _, ?VERSION, [AR]}, Mid) ->
4656    (catch rarala_do_verify_service_change_req(AR, Mid));
4657rarala_mgc_verify_service_change_req(Crap, _Mid) ->
4658    ED       = cre_ErrDesc(Crap),
4659    ErrReply = {discard_ack, ED},
4660    {error, Crap, ErrReply}.
4661
4662rarala_do_verify_service_change_req(AR, Mid) ->
4663    io:format("rarala_mgc_do_verify_service_change_req -> entry with"
4664	      "~n   AR:  ~p"
4665	      "~n   Mid: ~p"
4666	      "~n", [AR, Mid]),
4667    CR =
4668	case AR of
4669	    #'ActionRequest'{commandRequests = [CmdReq]} ->
4670		CmdReq;
4671	    _ ->
4672		Err1      = {invalid_action_request, AR},
4673		ED1       = cre_ErrDesc(AR),
4674		ErrReply1 = {discard_ack, ED1},
4675		throw({error, Err1, ErrReply1})
4676	end,
4677    Cmd =
4678	case CR of
4679	    #'CommandRequest'{command = Command} ->
4680		Command;
4681	    _ ->
4682		Err2      = {invalid_command_request, CR},
4683		ED2       = cre_ErrDesc(CR),
4684		ErrReply2 = {discard_ack, ED2},
4685		throw({error, Err2, ErrReply2})
4686	end,
4687    {Tid, Parms} =
4688	case Cmd of
4689	    {serviceChangeReq,
4690	     #'ServiceChangeRequest'{terminationID = [TermID],
4691				     serviceChangeParms = ServChParms}} ->
4692		{TermID, ServChParms};
4693	    _ ->
4694		Err3      = {invalid_command, Cmd},
4695		ED3       = cre_ErrDesc(Cmd),
4696		ErrReply3 = {discard_ack, ED3},
4697		throw({error, Err3, ErrReply3})
4698	end,
4699    case Tid of
4700	#megaco_term_id{contains_wildcards = false, id = ["root"]} ->
4701	    ok;
4702	_ ->
4703	    Err4      = {invalid_termination_id, Tid},
4704	    ED4       = cre_ErrDesc(Tid),
4705	    ErrReply4 = {discard_ack, ED4},
4706	    throw({error, Err4, ErrReply4})
4707    end,
4708    case Parms of
4709	#'ServiceChangeParm'{serviceChangeMethod = restart,
4710			     serviceChangeReason = [[$9,$0,$1|_]]} ->
4711	    AckData = [rarala_mgc_service_change_reply_ar(Mid, 1)],
4712	    Reply   = {discard_ack, AckData},
4713	    {ok, AR, Reply};
4714	_ ->
4715	    Err5      = {invalid_SCP, Parms},
4716	    ED5       = cre_ErrDesc(Parms),
4717	    ErrReply5 = {discard_ack, ED5},
4718	    {error, Err5, ErrReply5}
4719    end.
4720
4721
4722%% Notify Request verification
4723-ifndef(megaco_hipe_special).
4724rarala_mgc_verify_notify_req_fun() ->
4725    fun(Req) ->
4726	    rarala_mgc_verify_notify_req(Req)
4727    end.
4728-endif.
4729
4730rarala_mgc_verify_notify_req({handle_trans_request, _, ?VERSION, [AR]}) ->
4731    (catch rarala_mgc_do_verify_notify_req(AR));
4732rarala_mgc_verify_notify_req(Crap) ->
4733    ED       = cre_ErrDesc(Crap),
4734    ErrReply = {discard_ack, ED},
4735    {error, Crap, ErrReply}.
4736
4737rarala_mgc_do_verify_notify_req(AR) ->
4738    io:format("rarala_mgc_do_verify_notify_req -> entry with"
4739	      "~n   AR: ~p"
4740	      "~n", [AR]),
4741    {Cid, CR} =
4742	case AR of
4743	    #'ActionRequest'{contextId       = CtxID,
4744			     commandRequests = [CmdReq]} ->
4745		{CtxID, CmdReq};
4746	    _ ->
4747		Err1      = {invalid_action_request, AR},
4748		ED1       = cre_ErrDesc(AR),
4749		ErrReply1 = {discard_ack, ED1},
4750		throw({error, Err1, ErrReply1})
4751	end,
4752    Cmd =
4753	case CR of
4754	    #'CommandRequest'{command = Command} ->
4755		Command;
4756	    _ ->
4757		Err2      = {invalid_command_request, CR},
4758		ED2       = cre_ErrDesc(CR),
4759		ErrReply2 = {discard_ack, ED2},
4760		throw({error, Err2, ErrReply2})
4761	end,
4762    NR =
4763	case Cmd of
4764	    {notifyReq, NotifReq} ->
4765		NotifReq;
4766	    _ ->
4767		Err3      = {invalid_command, Cmd},
4768		ED3       = cre_ErrDesc(Cmd),
4769		ErrReply3 = {discard_ack, ED3},
4770		throw({error, Err3, ErrReply3})
4771	end,
4772    {Tid, OED} =
4773	case NR of
4774	    #'NotifyRequest'{terminationID            = [TermID],
4775			     observedEventsDescriptor = ObsEvsDesc,
4776			     errorDescriptor          = asn1_NOVALUE} ->
4777		{TermID, ObsEvsDesc};
4778	    _ ->
4779		Err4      = {invalid_NR, NR},
4780		ED4       = cre_ErrDesc(NR),
4781		ErrReply4 = {discard_ack, ED4},
4782		throw({error, Err4, ErrReply4})
4783	end,
4784    OE =
4785	case OED of
4786	    #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
4787		ObsEvLst;
4788	    _ ->
4789		Err5      = {invalid_OED, OED},
4790		ED5       = cre_ErrDesc(NR),
4791		ErrReply5 = {discard_ack, ED5},
4792		throw({error, Err5, ErrReply5})
4793	end,
4794    case OE of
4795	#'ObservedEvent'{eventName = "al/of"} ->
4796	    AckData = rarala,
4797	    Replies = [rarala_mgc_notify_reply_ar(Cid, Tid)],
4798	    Reply   = {{handle_ack, AckData}, Replies},
4799	    {ok, AR, Reply};
4800	_ ->
4801	    Err6      = {invalid_OE, OE},
4802	    ED6       = cre_ErrDesc(OE),
4803	    ErrReply6 = {discard_ack, ED6},
4804	    throw({error, Err6, ErrReply6})
4805    end.
4806
4807
4808-ifndef(megaco_hipe_special).
4809rarala_mgc_verify_handle_trans_ack_fun() ->
4810    fun(Ack) ->
4811	    rarala_mgc_verify_handle_trans_ack(Ack)
4812    end.
4813-endif.
4814
4815rarala_mgc_verify_handle_trans_ack(
4816  {handle_trans_ack, CH, ?VERSION, ok, rarala}) ->
4817    io:format("rarala_mgc_verify_handle_trans_ack -> ok"
4818              "~n   CH: ~p"
4819              "~n", [CH]),
4820    {ok, CH, ok};
4821rarala_mgc_verify_handle_trans_ack(Crap) ->
4822    io:format("rarala_mgc_verify_handle_trans_ack -> unknown"
4823              "~n   Crap: ~p~n", [Crap]),
4824    {error, Crap, ok}.
4825
4826
4827%% Disconnect verification
4828rarala_mgc_verify_handle_disconnect({handle_disconnect, CH, ?VERSION, _R}) ->
4829    {ok, CH, ok};
4830rarala_mgc_verify_handle_disconnect(Else) ->
4831    {error, Else, ok}.
4832
4833rarala_mgc_service_change_reply_ar(Mid, Cid) ->
4834    SCRP  = cre_serviceChangeResParm(Mid),
4835    SCRes = cre_serviceChangeResult(SCRP),
4836    Root  = #megaco_term_id{id = ["root"]},
4837    SCR   = cre_serviceChangeReply([Root], SCRes),
4838    CR    = cre_cmdReply(SCR),
4839    AR    = cre_actionReply(Cid, [CR]),
4840    AR.
4841
4842rarala_mgc_notify_reply_ar(Cid, TermId) ->
4843    NR    = cre_notifyReply([TermId]),
4844    CR    = cre_cmdReply(NR),
4845    cre_actionReply(Cid, [CR]).
4846
4847
4848%%
4849%% MG generator stuff
4850%%
4851-ifdef(megaco_hipe_special).
4852-define(rarala_mg_decode_msg_fun(Mod, Conf),
4853	{?MODULE, decode_msg, [Mod, Conf]}).
4854-define(rarala_mg_encode_msg_fun(Mod, Conf),
4855	{?MODULE, encode_msg, [Mod, Conf]}).
4856-define(rarala_mg_verify_service_change_rep_msg_fun(),
4857	{?MODULE, rarala_mg_verify_service_change_rep_msg, []}).
4858-define(rarala_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId),
4859	{?MODULE, rarala_mg_verify_notify_rep_msg, [TermId, TransId, ReqId, CtxId]}).
4860-else.
4861-define(rarala_mg_decode_msg_fun(Mod, Conf),
4862	rarala_mg_decode_msg_fun(Mod, Conf)).
4863-define(rarala_mg_encode_msg_fun(Mod, Conf),
4864	rarala_mg_encode_msg_fun(Mod, Conf)).
4865-define(rarala_mg_verify_service_change_rep_msg_fun(),
4866	rarala_mg_verify_service_change_rep_msg_fun()).
4867-define(rarala_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId),
4868	rarala_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId)).
4869-endif.
4870
4871rarala_mg_event_sequence(text, tcp) ->
4872    DecodeFun = ?rarala_mg_decode_msg_fun(megaco_pretty_text_encoder, []),
4873    EncodeFun = ?rarala_mg_encode_msg_fun(megaco_pretty_text_encoder, []),
4874    Mid       = {deviceName,"mg"},
4875    ServiceChangeReq = rarala_mg_service_change_request_msg(Mid, 1, 0),
4876    TermId  = #megaco_term_id{id = ["00000000","00000000","01101101"]},
4877    TransId = 2,
4878    ReqId   = 1,
4879    CtxId   = 1,
4880    NotifyReq = rarala_mg_notify_request_msg(Mid, TermId,
4881					    TransId, ReqId, CtxId),
4882    TransAck = rarala_mg_trans_ack_msg(Mid, TransId),
4883    ScrVerifyFun = ?rarala_mg_verify_service_change_rep_msg_fun(),
4884    NrVerifyFun  = ?rarala_mg_verify_notify_rep_msg_fun(TermId,
4885							TransId, ReqId, CtxId),
4886    EvSeq = [{debug,  true},
4887             {decode, DecodeFun},
4888             {encode, EncodeFun},
4889             {connect, 2944},
4890             {send, "service-change-request", ServiceChangeReq},
4891             {expect_receive, "service-change-reply", {ScrVerifyFun, 10000}},
4892             {send, "notify request", NotifyReq},
4893             {expect_receive, "notify-reply", {NrVerifyFun, 4000}},
4894             {expect_receive, "notify-reply", {NrVerifyFun, 4000}},
4895             {expect_receive, "notify-reply", {NrVerifyFun, 4000}},
4896             {send, "transaction-ack", TransAck},
4897             {expect_nothing, 11000},
4898             disconnect
4899            ],
4900    EvSeq.
4901
4902-ifndef(megaco_hipe_special).
4903rarala_mg_encode_msg_fun(Mod, Conf) ->
4904    fun(M) ->
4905            encode_msg(M, Mod, Conf)
4906    end.
4907-endif.
4908
4909-ifndef(megaco_hipe_special).
4910rarala_mg_decode_msg_fun(Mod, Conf) ->
4911    fun(M) ->
4912            decode_msg(M, Mod, Conf)
4913    end.
4914-endif.
4915
4916-ifndef(megaco_hipe_special).
4917rarala_mg_verify_service_change_rep_msg_fun() ->
4918    fun(Msg) ->
4919	    (catch rarala_mg_verify_service_change_rep_msg(Msg))
4920    end.
4921-endif.
4922
4923rarala_mg_verify_service_change_rep_msg(#'MegacoMessage'{mess = Mess} = M) ->
4924    Body =
4925	case Mess of
4926	    #'Message'{version     = _V,
4927                       mId         = _MgMid,
4928                       messageBody = MsgBody} ->
4929		MsgBody;
4930	    _ ->
4931		throw({error, {invalid_Message, Mess}})
4932	end,
4933    Trans =
4934	case Body of
4935            {transactions, [Transactions]} ->
4936		Transactions;
4937	    _ ->
4938		throw({error, {invalid_messageBody, Body}})
4939	end,
4940    TR =
4941	case Trans of
4942            {transactionReply, TransReply} ->
4943		TransReply;
4944	    _ ->
4945		throw({error, {invalid_transactions, Trans}})
4946	end,
4947    TRes =
4948	case TR of
4949            #'TransactionReply'{transactionId = _Tid,
4950                                immAckRequired = asn1_NOVALUE,
4951                                transactionResult = TransRes} ->
4952		TransRes;
4953	    _ ->
4954		throw({error, {invalid_transactionReply, TR}})
4955	end,
4956    AR =
4957	case TRes of
4958            {actionReplies, [ActRes]} ->
4959		ActRes;
4960	    _ ->
4961		throw({error, {invalid_transactionResult, TRes}})
4962	end,
4963    CR =
4964	case AR of
4965            #'ActionReply'{contextId       = _Cid,
4966                           errorDescriptor = asn1_NOVALUE,
4967                           contextReply    = _CtxReq,
4968                           commandReply    = [CmdRep]} ->
4969		CmdRep;
4970	    _ ->
4971		throw({error, {invalid_actionReplies, AR}})
4972	end,
4973    SCR =
4974	case CR of
4975            {serviceChangeReply, ServChRep} ->
4976		ServChRep;
4977	    _ ->
4978		throw({error, {invalid_commandReply, CR}})
4979	end,
4980    SCRes =
4981	case SCR of
4982            #'ServiceChangeReply'{terminationID       = _TermID,
4983                                  serviceChangeResult = ServChRes} ->
4984		ServChRes;
4985	    _ ->
4986		throw({error, {invalid_serviceChangeReply, SCR}})
4987	end,
4988    SCRP =
4989	case SCRes of
4990            {serviceChangeResParms, Parms} ->
4991		Parms;
4992	    _ ->
4993		throw({error, {invalid_serviceChangeResult, SCRes}})
4994	end,
4995    case SCRP of
4996	#'ServiceChangeResParm'{serviceChangeMgcId = _MgcMid} ->
4997            {ok, M};
4998	_ ->
4999	    {error, {invalid_serviceChangeResParms, SCRP}}
5000    end;
5001rarala_mg_verify_service_change_rep_msg(Crap) ->
5002    {error, {invalid_message, Crap}}.
5003
5004-ifndef(megaco_hipe_special).
5005rarala_mg_verify_notify_rep_msg_fun(TermId, TransId, Rid, Cid) ->
5006    fun(Msg) ->
5007	    (catch rarala_mg_verify_notify_rep_msg(Msg,
5008						   TermId, TransId, Rid, Cid))
5009    end.
5010-endif.
5011
5012rarala_mg_verify_notify_rep_msg(#'MegacoMessage'{mess = Mess} = M,
5013				TermId, TransId, Rid, Cid) ->
5014    io:format("rarala_mg_verify_notify_rep_msg -> entry with"
5015	      "~n   M:       ~p"
5016	      "~n   TermId:  ~p"
5017	      "~n   TransId: ~p"
5018	      "~n   Rid:     ~p"
5019	      "~n   Cid:     ~p"
5020	      "~n", [M, TermId, TransId, Rid, Cid]),
5021    Body =
5022	case Mess of
5023	    #'Message'{version     = ?VERSION,
5024                       mId         = _Mid,
5025                       messageBody = MsgBody} ->
5026		MsgBody;
5027	    _ ->
5028		throw({error, {invalid_Message, Mess}})
5029	end,
5030    Trans =
5031	case Body of
5032            {transactions, [Transactions]} ->
5033		Transactions;
5034	    _ ->
5035		throw({error, {invalid_messageBody, Body}})
5036	end,
5037    TR =
5038	case Trans of
5039            {transactionReply, TransReply} ->
5040		TransReply;
5041	    _ ->
5042		throw({error, {invalid_transactions, Trans}})
5043	end,
5044    TRes =
5045	case TR of
5046            #'TransactionReply'{transactionId     = TransId,
5047                                immAckRequired    = 'NULL',
5048                                transactionResult = TransRes} ->
5049		TransRes;
5050	    _ ->
5051		throw({error, {invalid_transactionReply, TR}})
5052	end,
5053    AR =
5054	case TRes of
5055            {actionReplies, [ActRes]} ->
5056		ActRes;
5057	    _ ->
5058		throw({error, {invalid_transactionResult, TRes}})
5059	end,
5060    CR =
5061	case AR of
5062            #'ActionReply'{contextId       = Cid,
5063                           errorDescriptor = asn1_NOVALUE,
5064                           contextReply    = _CtxReq,
5065                           commandReply    = [CmdRep]} ->
5066		CmdRep;
5067	    _ ->
5068		throw({error, {invalid_actionReplies, AR}})
5069	end,
5070    NR =
5071	case CR of
5072            {notifyReply, NotifyReply} ->
5073		NotifyReply;
5074	    _ ->
5075		throw({error, {invalid_commandReply, CR}})
5076	end,
5077    case NR of
5078	#'NotifyReply'{terminationID   = [TermId],
5079		       errorDescriptor = asn1_NOVALUE} ->
5080	    {ok, M};
5081	_ ->
5082	    {error, {invalid_notifyReply, NR}}
5083    end;
5084rarala_mg_verify_notify_rep_msg(Crap, _TermId, _TransId, _Rid, _Cid) ->
5085    {error, {invalid_message, Crap}}.
5086
5087rarala_mg_service_change_request_ar(_Mid, Cid) ->
5088    Prof  = cre_serviceChangeProf("resgw", 1),
5089    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
5090    Root  = #megaco_term_id{id = ["root"]},
5091    SCR   = cre_serviceChangeReq([Root], SCP),
5092    CMD   = cre_command(SCR),
5093    CR    = cre_cmdReq(CMD),
5094    cre_actionReq(Cid, [CR]).
5095
5096rarala_mg_service_change_request_msg(Mid, TransId, Cid) ->
5097    AR    = rarala_mg_service_change_request_ar(Mid, Cid),
5098    TR    = cre_transReq(TransId, [AR]),
5099    Trans = cre_transaction(TR),
5100    Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
5101    cre_megacoMessage(Mess).
5102
5103rarala_mg_notify_request_ar(Rid, Tid, Cid) ->
5104    TT      = cre_timeNotation("19990729", "22000000"),
5105    Ev      = cre_obsEvent("al/of", TT),
5106    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
5107    NR      = cre_notifyReq([Tid], EvsDesc),
5108    CMD     = cre_command(NR),
5109    CR      = cre_cmdReq(CMD),
5110    cre_actionReq(Cid, [CR]).
5111
5112rarala_mg_notify_request_msg(Mid, TermId, TransId, Rid, Cid) ->
5113    AR      = rarala_mg_notify_request_ar(Rid, TermId, Cid),
5114    TR      = cre_transReq(TransId, [AR]),
5115    Trans   = cre_transaction(TR),
5116    Mess    = cre_message(?VERSION, Mid, cre_transactions([Trans])),
5117    cre_megacoMessage(Mess).
5118
5119rarala_mg_trans_ack_msg(Mid, TransId) ->
5120    TR    = cre_transRespAck(cre_transAck(TransId)),
5121    Trans = cre_transaction(TR),
5122    Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
5123    cre_megacoMessage(Mess).
5124
5125
5126
5127%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5128
5129trans_req_and_reply_and_req(suite) ->
5130    [];
5131trans_req_and_reply_and_req(doc) ->
5132    ["Receive a transaction request, send a reply (discard ack)"
5133     "then receive the same reply again after the timeout. "
5134     "The MGC is a megaco instance (megaco event sequence) and the "
5135     "MG is emulated (tcp event sequence)"];
5136trans_req_and_reply_and_req(Config) when is_list(Config) ->
5137    Pre = fun() ->
5138                  %% <CONDITIONAL-SKIP>
5139                  Skippable = [{unix, [darwin, linux]}],
5140                  Condition = fun() -> ?OS_BASED_SKIP(Skippable) end,
5141                  ?NON_PC_TC_MAYBE_SKIP(Config, Condition),
5142                  %% </CONDITIONAL-SKIP>
5143
5144                  MgcNode = make_node_name(mgc),
5145                  MgNode  = make_node_name(mg),
5146                  d("start nodes: "
5147                    "~n      MgcNode: ~p"
5148                    "~n      MgNode:  ~p",
5149                    [MgcNode, MgNode]),
5150                  Nodes = [MgcNode, MgNode],
5151                  ok = ?START_NODES(Nodes, true),
5152                  Nodes
5153          end,
5154    Case = fun do_trans_req_and_reply_and_req/1,
5155    Post = fun(Nodes) ->
5156                   d("stop nodes"),
5157                   ?STOP_NODES(lists:reverse(Nodes))
5158           end,
5159    try_tc(request_and_no_reply, Pre, Case, Post).
5160
5161do_trans_req_and_reply_and_req([MgcNode, MgNode]) ->
5162    d("[MGC] start the simulator "),
5163    {ok, Mgc} = megaco_test_megaco_generator:start_link("MGC", MgcNode),
5164
5165    d("[MGC] create the event sequence"),
5166    MgcEvSeq = trarar_mgc_event_sequence(text, tcp),
5167
5168    i("wait some time before starting the MGC simulation"),
5169    sleep(1000),
5170
5171    d("[MGC] start the simulation"),
5172    {ok, MgcId} = megaco_test_megaco_generator:exec(Mgc, MgcEvSeq),
5173
5174    %% i("wait some time before starting the MG simulator"),
5175    %% sleep(1000),
5176
5177    i("await MGC ready announcement"),
5178    receive
5179        announce_mgc ->
5180            i("received MGC ready announcement"),
5181            ok
5182    end,
5183
5184    d("[MG] start the simulator (generator)"),
5185    {ok, Mg} = megaco_test_tcp_generator:start_link("MG", MgNode),
5186
5187    d("[MG] create the event sequence"),
5188    MgEvSeq = trarar_mg_event_sequence(text, tcp),
5189
5190    i("wait some time before starting the MG simulation"),
5191    sleep(1000),
5192
5193    d("[MG] start the simulation"),
5194    {ok, MgId} = megaco_test_tcp_generator:exec(Mg, MgEvSeq),
5195
5196    d("await the generator reply(s)"),
5197    await_completion([MgcId, MgId], 60000),
5198
5199    %% Tell Mgc to stop
5200    i("[MGC] stop generator"),
5201    megaco_test_megaco_generator:stop(Mgc),
5202
5203    %% Tell Mg to stop
5204    i("[MG] stop generator"),
5205    megaco_test_tcp_generator:stop(Mg),
5206
5207    i("done", []),
5208    ok.
5209
5210
5211%%
5212%% MGC generator stuff
5213%%
5214-ifdef(megaco_hipe_special).
5215-define(trarar_mgc_verify_handle_connect_fun(),
5216        {?MODULE, trarar_mgc_verify_handle_connect, []}).
5217-define(trarar_mgc_verify_service_change_req_fun(Mid),
5218        {?MODULE, trarar_mgc_verify_service_change_req, [Mid]}).
5219-define(trarar_mgc_verify_notify_req_fun(Cid),
5220        {?MODULE, trarar_mgc_verify_notify_req, [Cid]}).
5221-define(trarar_mgc_verify_handle_disconnect_fun(),
5222        {?MODULE, trarar_mgc_verify_handle_disconnect, []}).
5223-else.
5224-define(trarar_mgc_verify_handle_connect_fun(),
5225        fun trarar_mgc_verify_handle_connect/1).
5226-define(trarar_mgc_verify_service_change_req_fun(Mid),
5227        trarar_mgc_verify_service_change_req_fun(Mid)).
5228-define(trarar_mgc_verify_notify_req_fun(Cid),
5229	trarar_mgc_verify_notify_req_fun(Cid)).
5230-define(trarar_mgc_verify_handle_disconnect_fun(),
5231	fun trarar_mgc_verify_handle_disconnect/1).
5232-endif.
5233
5234trarar_mgc_event_sequence(text, tcp) ->
5235    CTRL = self(),
5236    Mid = {deviceName,"ctrl"},
5237    RI = [
5238	  {port,             2944},
5239	  {encoding_module,  megaco_pretty_text_encoder},
5240	  {encoding_config,  []},
5241	  {transport_module, megaco_tcp}
5242	 ],
5243    ConnectVerify          = ?trarar_mgc_verify_handle_connect_fun(),
5244    ServiceChangeReqVerify = ?trarar_mgc_verify_service_change_req_fun(Mid),
5245    NotifyReqVerify1       = ?trarar_mgc_verify_notify_req_fun(1),
5246    NotifyReqVerify2       = ?trarar_mgc_verify_notify_req_fun(2),
5247    NotifyReqVerify3       = ?trarar_mgc_verify_notify_req_fun(3),
5248    NotifyReqVerify4       = ?trarar_mgc_verify_notify_req_fun(4),
5249    DiscoVerify            = ?trarar_mgc_verify_handle_disconnect_fun(),
5250    EvSeq = [
5251	     {debug, true},
5252	     {megaco_trace, disable},
5253	     megaco_start,
5254	     {megaco_start_user, Mid, RI, []},
5255             {megaco_update_user_info, reply_timer, 2000},
5256	     start_transport,
5257	     listen,
5258
5259             %% ANNOUNCE READY
5260             {trigger, fun() -> CTRL ! announce_mgc end},
5261
5262	     {megaco_callback, handle_connect,       ConnectVerify},
5263	     {megaco_callback, handle_trans_request, ServiceChangeReqVerify},
5264	     {megaco_callback, handle_trans_request, NotifyReqVerify1},
5265	     {megaco_callback, handle_trans_request, NotifyReqVerify2},
5266             {megaco_update_conn_info, reply_timer,  4000},
5267	     {megaco_callback, handle_trans_request, NotifyReqVerify3},
5268	     {megaco_callback, handle_trans_request, NotifyReqVerify4},
5269	     {megaco_callback, handle_disconnect,    DiscoVerify},
5270	     {sleep, 1000},
5271	     megaco_stop_user,
5272	     megaco_stop
5273	    ],
5274    EvSeq.
5275
5276
5277trarar_mgc_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
5278    io:format("trarar_mgc_verify_handle_connect -> ok"
5279	      "~n   CH: ~p~n", [CH]),
5280    {ok, CH, ok};
5281trarar_mgc_verify_handle_connect(Else) ->
5282    io:format("trarar_mgc_verify_handle_connect -> unknown"
5283	      "~n   Else: ~p~n", [Else]),
5284    {error, Else, ok}.
5285
5286-ifndef(megaco_hipe_special).
5287trarar_mgc_verify_service_change_req_fun(Mid) ->
5288    fun(Req) ->
5289	    trarar_mgc_verify_service_change_req(Req, Mid)
5290    end.
5291-endif.
5292
5293trarar_mgc_verify_service_change_req(
5294  {handle_trans_request, _, ?VERSION, [AR]}, Mid) ->
5295    (catch trarar_mgc_do_verify_service_change_req(AR, Mid));
5296trarar_mgc_verify_service_change_req(Crap, _Mid) ->
5297    ED = cre_ErrDesc(Crap),
5298    ErrReply = {discard_ack, ED},
5299    {error, Crap, ErrReply}.
5300
5301trarar_mgc_do_verify_service_change_req(AR, Mid) ->
5302    io:format("trarar_mgc_verify_service_change_req -> ok"
5303	      "~n   AR:  ~p"
5304	      "~n   Mid: ~p"
5305	      "~n", [AR, Mid]),
5306    CR =
5307	case AR of
5308	    #'ActionRequest'{commandRequests = [CmdReq]} ->
5309		CmdReq;
5310	    _ ->
5311                Err1      = {invalid_action_request, AR},
5312                ED1       = cre_ErrDesc(AR),
5313                ErrReply1 = {discard_ack, ED1},
5314                throw({error, Err1, ErrReply1})
5315	end,
5316    Cmd =
5317        case CR of
5318            #'CommandRequest'{command = Command} ->
5319                Command;
5320            _ ->
5321                Err2      = {invalid_command_request, CR},
5322                ED2       = cre_ErrDesc(CR),
5323                ErrReply2 = {discard_ack, ED2},
5324                throw({error, Err2, ErrReply2})
5325        end,
5326    {Tid, Parms} =
5327        case Cmd of
5328            {serviceChangeReq,
5329             #'ServiceChangeRequest'{terminationID = [TermID],
5330                                     serviceChangeParms = ServChParms}} ->
5331                {TermID, ServChParms};
5332            _ ->
5333                Err3      = {invalid_command, Cmd},
5334                ED3       = cre_ErrDesc(Cmd),
5335                ErrReply3 = {discard_ack, ED3},
5336                throw({error, Err3, ErrReply3})
5337        end,
5338    case Tid of
5339        #megaco_term_id{contains_wildcards = false, id = ["root"]} ->
5340            ok;
5341        _ ->
5342            Err4      = {invalid_termination_id, Tid},
5343            ED4       = cre_ErrDesc(Tid),
5344            ErrReply4 = {discard_ack, ED4},
5345            throw({error, Err4, ErrReply4})
5346    end,
5347    case Parms of
5348        #'ServiceChangeParm'{serviceChangeMethod = restart,
5349                             serviceChangeReason = [[$9,$0,$1|_]]} ->
5350            AckData = [trarar_mgc_service_change_reply_ar(Mid, 1)],
5351            Reply   = {discard_ack, AckData},
5352            {ok, AR, Reply};
5353        _ ->
5354            Err5      = {invalid_SCP, Parms},
5355            ED5       = cre_ErrDesc(Parms),
5356            ErrReply5 = {discard_ack, ED5},
5357            {error, Err5, ErrReply5}
5358    end.
5359
5360-ifndef(megaco_hipe_special).
5361trarar_mgc_verify_notify_req_fun(Cid) ->
5362    fun(Req) ->
5363	    trarar_mgc_verify_notify_req(Req, Cid)
5364    end.
5365-endif.
5366
5367trarar_mgc_verify_notify_req({handle_trans_request, _, ?VERSION, [AR]}, Cid) ->
5368    (catch trarar_mgc_do_verify_notify_req(AR, Cid));
5369trarar_mgc_verify_notify_req(Crap, _Cid) ->
5370    ED       = cre_ErrDesc(Crap),
5371    ErrReply = {discard_ack, ED},
5372    {error, Crap, ErrReply}.
5373
5374trarar_mgc_do_verify_notify_req(AR, Cid) ->
5375    io:format("trarar_mgc_do_verify_notify_req -> entry with"
5376	      "~n   AR:  ~p"
5377	      "~n   Cid: ~p"
5378	      "~n", [AR, Cid]),
5379    {ContextID, CR} =
5380	case AR of
5381	    #'ActionRequest'{contextId       = CtxID,
5382			     commandRequests = [CmdReq]} when (CtxID == Cid) ->
5383		{CtxID, CmdReq};
5384	    _ ->
5385                Err1      = {invalid_action_request, AR},
5386                ED1       = cre_ErrDesc(AR),
5387                ErrReply1 = {discard_ack, ED1},
5388                throw({error, Err1, ErrReply1})
5389        end,
5390    Cmd =
5391	case CR of
5392	    #'CommandRequest'{command = Command} ->
5393		Command;
5394	    _ ->
5395                Err2      = {invalid_command_request, CR},
5396                ED2       = cre_ErrDesc(CR),
5397                ErrReply2 = {discard_ack, ED2},
5398                throw({error, Err2, ErrReply2})
5399        end,
5400    NR =
5401        case Cmd of
5402	    {notifyReq, NotifReq} ->
5403		NotifReq;
5404	    _ ->
5405                Err3      = {invalid_command, Cmd},
5406                ED3       = cre_ErrDesc(Cmd),
5407                ErrReply3 = {discard_ack, ED3},
5408                throw({error, Err3, ErrReply3})
5409        end,
5410    {Tid, OED} =
5411        case NR of
5412            #'NotifyRequest'{terminationID            = [TermID],
5413                             observedEventsDescriptor = ObsEvsDesc,
5414                             errorDescriptor          = asn1_NOVALUE} ->
5415                {TermID, ObsEvsDesc};
5416            _ ->
5417                Err4      = {invalid_NR, NR},
5418                ED4       = cre_ErrDesc(NR),
5419                ErrReply4 = {discard_ack, ED4},
5420                throw({error, Err4, ErrReply4})
5421        end,
5422    OE =
5423	case OED of
5424	    #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
5425		ObsEvLst;
5426            _ ->
5427                Err5      = {invalid_OED, OED},
5428                ED5       = cre_ErrDesc(NR),
5429                ErrReply5 = {discard_ack, ED5},
5430                throw({error, Err5, ErrReply5})
5431        end,
5432    case OE of
5433	#'ObservedEvent'{eventName = "al/of"} ->
5434            Replies = [trarar_mgc_notify_reply_ar(ContextID, Tid)],
5435            Reply   = {discard_ack, Replies},
5436            {ok, AR, Reply};
5437        _ ->
5438            Err6      = {invalid_OE, OE},
5439            ED6       = cre_ErrDesc(OE),
5440            ErrReply6 = {discard_ack, ED6},
5441            {error, Err6, ErrReply6}
5442    end.
5443
5444trarar_mgc_verify_handle_disconnect({handle_disconnect, CH, ?VERSION, R}) ->
5445    io:format("trarar_mgc_verify_handle_disconnect -> ok"
5446	      "~n   CH: ~p"
5447	      "~n   R:  ~p"
5448	      "~n", [CH, R]),
5449    {ok, CH, ok};
5450trarar_mgc_verify_handle_disconnect(Else) ->
5451    io:format("trarar_mgc_verify_handle_disconnect -> unknown"
5452	      "~n   Else: ~p~n", [Else]),
5453    {error, Else, ok}.
5454
5455
5456trarar_mgc_service_change_reply_ar(Mid, Cid) ->
5457    SCRP  = cre_serviceChangeResParm(Mid),
5458    SCRes = cre_serviceChangeResult(SCRP),
5459    Root  = #megaco_term_id{id = ["root"]},
5460    SCR   = cre_serviceChangeReply([Root], SCRes),
5461    CR    = cre_cmdReply(SCR),
5462    cre_actionReply(Cid, [CR]).
5463
5464trarar_mgc_notify_reply_ar(Cid, TermId) ->
5465    NR    = cre_notifyReply([TermId]),
5466    CR    = cre_cmdReply(NR),
5467    cre_actionReply(Cid, [CR]).
5468
5469%% trarar_mgc_notify_reply(Mid, TransId, Cid, TermId) ->
5470%%     AR    = trarar_mgc_notify_reply_ar(Cid, TermId),
5471%%     TRes  = cre_transResult([AR]),
5472%%     TR    = cre_transReply(TransId, TRes),
5473%%     Trans = cre_transaction(TR),
5474%%     Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
5475%%     cre_megacoMessage(Mess).
5476
5477
5478%%
5479%% MG generator stuff
5480%%
5481-ifdef(megaco_hipe_special).
5482-define(trarar_mg_decode_msg_fun(Mod, Conf),
5483	{?MODULE, decode_msg, [Mod, Conf]}).
5484-define(trarar_mg_encode_msg_fun(Mod, Conf),
5485	{?MODULE, encode_msg, [Mod, Conf]}).
5486-define(trarar_mg_verify_service_change_rep_msg_fun(),
5487	{?MODULE, trarar_mg_verify_service_change_rep_msg, []}).
5488-define(trarar_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId),
5489	{?MODULE, trarar_mg_verify_notify_rep_msg, [TermId, TransId, ReqId, CtxId]}).
5490-else.
5491-define(trarar_mg_decode_msg_fun(Mod, Conf),
5492	trarar_mg_decode_msg_fun(Mod, Conf)).
5493-define(trarar_mg_encode_msg_fun(Mod, Conf),
5494	trarar_mg_encode_msg_fun(Mod, Conf)).
5495-define(trarar_mg_verify_service_change_rep_msg_fun(),
5496	trarar_mg_verify_service_change_rep_msg_fun()).
5497-define(trarar_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId),
5498	trarar_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId)).
5499-endif.
5500
5501trarar_mg_event_sequence(text, tcp) ->
5502    DecodeFun = ?trarar_mg_decode_msg_fun(megaco_pretty_text_encoder, []),
5503    EncodeFun = ?trarar_mg_encode_msg_fun(megaco_pretty_text_encoder, []),
5504    Mid       = {deviceName,"mg"},
5505    ServiceChangeReq = trarar_mg_service_change_request_msg(Mid, 1, 0),
5506    TermId  = #megaco_term_id{id = ["00000000","00000000","01101101"]},
5507    NotifyReq1 =
5508	trarar_mg_notify_request_msg(Mid, TermId, 2, 1, 1),
5509    NotifyReq2 =
5510	trarar_mg_notify_request_msg(Mid, TermId, 2, 2, 2),
5511    NotifyReq3 =
5512	trarar_mg_notify_request_msg(Mid, TermId, 2, 3, 3),
5513    NotifyReq4 =
5514	trarar_mg_notify_request_msg(Mid, TermId, 2, 4, 4),
5515    ScrVerifyFun = ?trarar_mg_verify_service_change_rep_msg_fun(),
5516    NrVerifyFun1 =
5517	?trarar_mg_verify_notify_rep_msg_fun(TermId, 2, 1, 1),
5518    NrVerifyFun2 =
5519	?trarar_mg_verify_notify_rep_msg_fun(TermId, 2, 2, 2),
5520    NrVerifyFun3 =
5521	?trarar_mg_verify_notify_rep_msg_fun(TermId, 2, 3, 3),
5522    NrVerifyFun4 =
5523	?trarar_mg_verify_notify_rep_msg_fun(TermId, 2, 4, 4),
5524    EvSeq = [{debug,  true},
5525             {decode, DecodeFun},
5526             {encode, EncodeFun},
5527             {connect, 2944},
5528
5529             {send, "service-change-request", ServiceChangeReq},
5530             {expect_receive, "service-change-reply", {ScrVerifyFun, 10000}},
5531
5532	     %% the original setting for reply timer is 2000
5533             {send, "notify request 1", NotifyReq1},
5534             {expect_receive, "notify-reply 1", {NrVerifyFun1, 2500}},
5535	     {sleep, 1000},
5536             {send, "notify request 2", NotifyReq2},
5537             {expect_receive, "notify-reply 2 (resend of 1)", {NrVerifyFun1, 2500}},
5538	     {sleep, 3000}, % reply timer is set to 2000
5539             {send, "notify request 3 (same as 2)", NotifyReq2},
5540             {expect_receive, "notify-reply 3", {NrVerifyFun2, 2500}},
5541
5542	     %% reply timer is now set to 4000 but previous was 2000
5543	     %% so, 3000 is enough to let the timer running with the
5544	     %% previous settings (2000) to time out
5545	     {sleep, 3000},
5546             {send, "notify request 4", NotifyReq3},
5547             {expect_receive, "notify-reply 4", {NrVerifyFun3, 4500}},
5548	     {sleep, 5000},
5549             {send, "notify request 5", NotifyReq4},
5550             {expect_receive, "notify-reply 5", {NrVerifyFun4, 4500}},
5551
5552             {expect_nothing, 5000},
5553             disconnect
5554            ],
5555    EvSeq.
5556
5557-ifndef(megaco_hipe_special).
5558trarar_mg_encode_msg_fun(Mod, Conf) ->
5559    fun(M) ->
5560            encode_msg(M, Mod, Conf)
5561    end.
5562-endif.
5563
5564-ifndef(megaco_hipe_special).
5565trarar_mg_decode_msg_fun(Mod, Conf) ->
5566    fun(M) ->
5567            decode_msg(M, Mod, Conf)
5568    end.
5569-endif.
5570
5571-ifndef(megaco_hipe_special).
5572trarar_mg_verify_service_change_rep_msg_fun() ->
5573    fun(Msg) ->
5574	    (catch trarar_mg_verify_service_change_rep_msg(Msg))
5575    end.
5576-endif.
5577
5578trarar_mg_verify_service_change_rep_msg(#'MegacoMessage'{mess = Mess} = M) ->
5579    Body =
5580	case Mess of
5581	    #'Message'{version     = _V,
5582                       mId         = _MgMid,
5583                       messageBody = MsgBody} ->
5584		MsgBody;
5585	    _ ->
5586		throw({error, {invalid_Message, Mess}})
5587	end,
5588    Trans =
5589	case Body of
5590            {transactions, [Transactions]} ->
5591		Transactions;
5592	    _ ->
5593		throw({error, {invalid_messageBody, Body}})
5594	end,
5595    TR =
5596	case Trans of
5597            {transactionReply, TransReply} ->
5598		TransReply;
5599	    _ ->
5600		throw({error, {invalid_transactions, Trans}})
5601	end,
5602    TRes =
5603	case TR of
5604            #'TransactionReply'{transactionId = _Tid,
5605                                immAckRequired = asn1_NOVALUE,
5606                                transactionResult = TransRes} ->
5607		TransRes;
5608	    _ ->
5609		throw({error, {invalid_transactionReply, TR}})
5610	end,
5611    AR =
5612	case TRes of
5613            {actionReplies, [ActRes]} ->
5614		ActRes;
5615	    _ ->
5616		throw({error, {invalid_transactionResult, TRes}})
5617	end,
5618    CR =
5619	case AR of
5620            #'ActionReply'{contextId       = _Cid,
5621                           errorDescriptor = asn1_NOVALUE,
5622                           contextReply    = _CtxReq,
5623                           commandReply    = [CmdRep]} ->
5624		CmdRep;
5625	    _ ->
5626		throw({error, {invalid_actionReplies, AR}})
5627	end,
5628    SCR =
5629	case CR of
5630            {serviceChangeReply, ServChRep} ->
5631		ServChRep;
5632	    _ ->
5633		throw({error, {invalid_commandReply, CR}})
5634	end,
5635    SCRes =
5636	case SCR of
5637            #'ServiceChangeReply'{terminationID       = _TermID,
5638                                  serviceChangeResult = ServChRes} ->
5639		ServChRes;
5640	    _ ->
5641		throw({error, {invalid_serviceChangeReply, SCR}})
5642	end,
5643    SCRP =
5644	case SCRes of
5645            {serviceChangeResParms, Parms} ->
5646		Parms;
5647	    _ ->
5648		throw({error, {invalid_serviceChangeResult, SCRes}})
5649	end,
5650    case SCRP of
5651	#'ServiceChangeResParm'{serviceChangeMgcId = _MgcMid} ->
5652            {ok, M};
5653	_ ->
5654	    {error, {invalid_serviceChangeResParms, SCRP}}
5655    end;
5656trarar_mg_verify_service_change_rep_msg(Crap) ->
5657    {error, {invalid_message, Crap}}.
5658
5659-ifndef(megaco_hipe_special).
5660trarar_mg_verify_notify_rep_msg_fun(TermId, TransId, Rid, Cid) ->
5661    fun(Msg) ->
5662	    (catch trarar_mg_verify_notify_rep_msg(Msg,
5663						   TermId, TransId, Rid, Cid))
5664    end.
5665-endif.
5666
5667trarar_mg_verify_notify_rep_msg(#'MegacoMessage'{mess = Mess} = M,
5668				TermId, TransId, Rid, Cid) ->
5669    io:format("trarar_mg_verify_notify_rep_msg -> entry with"
5670	      "~n   M:       ~p"
5671	      "~n   TermId:  ~p"
5672	      "~n   TransId: ~p"
5673	      "~n   Rid:     ~p"
5674	      "~n   Cid:     ~p"
5675	      "~n", [M, TermId, TransId, Rid, Cid]),
5676    Body =
5677	case Mess of
5678	    #'Message'{version     = ?VERSION,
5679                       mId         = _Mid,
5680                       messageBody = MsgBody} ->
5681		MsgBody;
5682	    _ ->
5683		throw({error, {invalid_Message, Mess}})
5684	end,
5685    io:format("trarar_mg_verify_notify_rep_msg -> "
5686	      "~n   Body: ~p"
5687	      "~n", [Body]),
5688    Trans =
5689	case Body of
5690            {transactions, [Transactions]} ->
5691		Transactions;
5692	    _ ->
5693		throw({error, {invalid_messageBody, Body}})
5694	end,
5695    io:format("trarar_mg_verify_notify_rep_msg -> "
5696	      "~n   Trans: ~p"
5697	      "~n", [Trans]),
5698    TR =
5699	case Trans of
5700            {transactionReply, TransReply} ->
5701		TransReply;
5702	    _ ->
5703		throw({error, {invalid_transactions, Trans}})
5704	end,
5705    io:format("trarar_mg_verify_notify_rep_msg -> "
5706	      "~n   TR: ~p"
5707	      "~n", [TR]),
5708    TRes =
5709	case TR of
5710            #'TransactionReply'{transactionId     = TransId,
5711                                immAckRequired    = asn1_NOVALUE,
5712                                transactionResult = TransRes} ->
5713		TransRes;
5714	    _ ->
5715		throw({error, {invalid_transactionReply, TR}})
5716	end,
5717    io:format("trarar_mg_verify_notify_rep_msg -> "
5718	      "~n   TRes: ~p"
5719	      "~n", [TRes]),
5720    AR =
5721	case TRes of
5722            {actionReplies, [ActRes]} ->
5723		ActRes;
5724	    _ ->
5725		throw({error, {invalid_transactionResult, TRes}})
5726	end,
5727    io:format("trarar_mg_verify_notify_rep_msg -> "
5728	      "~n   AR: ~p"
5729	      "~n", [AR]),
5730    CR =
5731	case AR of
5732            #'ActionReply'{contextId       = Cid,
5733                           errorDescriptor = asn1_NOVALUE,
5734                           contextReply    = _CtxReq,
5735                           commandReply    = [CmdRep]} ->
5736		CmdRep;
5737	    _ ->
5738		throw({error, {invalid_actionReplies, AR}})
5739	end,
5740    NR =
5741	case CR of
5742            {notifyReply, NotifyReply} ->
5743		NotifyReply;
5744	    _ ->
5745		throw({error, {invalid_commandReply, CR}})
5746	end,
5747    case NR of
5748	#'NotifyReply'{terminationID   = [TermId],
5749		       errorDescriptor = asn1_NOVALUE} ->
5750	    {ok, M};
5751	_ ->
5752	    {error, {invalid_notifyReply, NR}}
5753    end;
5754trarar_mg_verify_notify_rep_msg(Crap, _TermId, _TransId, _Rid, _Cid) ->
5755    {error, {invalid_message, Crap}}.
5756
5757trarar_mg_service_change_request_ar(_Mid, Cid) ->
5758    Prof  = cre_serviceChangeProf("resgw", 1),
5759    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
5760    Root  = #megaco_term_id{id = ["root"]},
5761    SCR   = cre_serviceChangeReq([Root], SCP),
5762    CMD   = cre_command(SCR),
5763    CR    = cre_cmdReq(CMD),
5764    cre_actionReq(Cid, [CR]).
5765
5766trarar_mg_service_change_request_msg(Mid, TransId, Cid) ->
5767    AR    = trarar_mg_service_change_request_ar(Mid, Cid),
5768    TR    = cre_transReq(TransId, [AR]),
5769    Trans = cre_transaction(TR),
5770    Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
5771    cre_megacoMessage(Mess).
5772
5773trarar_mg_notify_request_ar(Rid, Tid, Cid) ->
5774    TT      = cre_timeNotation("19990729", "22000000"),
5775    Ev      = cre_obsEvent("al/of", TT),
5776    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
5777    NR      = cre_notifyReq([Tid], EvsDesc),
5778    CMD     = cre_command(NR),
5779    CR      = cre_cmdReq(CMD),
5780    cre_actionReq(Cid, [CR]).
5781
5782trarar_mg_notify_request_msg(Mid, TermId, TransId, Rid, Cid) ->
5783    AR      = trarar_mg_notify_request_ar(Rid, TermId, Cid),
5784    TR      = cre_transReq(TransId, [AR]),
5785    Trans   = cre_transaction(TR),
5786    Mess    = cre_message(?VERSION, Mid, cre_transactions([Trans])),
5787    cre_megacoMessage(Mess).
5788
5789%% trarar_mg_trans_ack_msg(Mid, TransId) ->
5790%%     TR    = cre_transRespAck(cre_transAck(TransId)),
5791%%     Trans = cre_transaction(TR),
5792%%     Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
5793%%     cre_megacoMessage(Mess).
5794
5795
5796%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5797
5798pending_ack_plain(suite) ->
5799    [];
5800pending_ack_plain(doc) ->
5801    ["Receive a request and handle it as a long request, "
5802     "i.e. return with {pending, _} and expect a call to the "
5803     "long request function"];
5804pending_ack_plain(Config) when is_list(Config) ->
5805    Pre = fun() ->
5806                  MgcNode = make_node_name(mgc),
5807                  MgNode  = make_node_name(mg),
5808                  d("start nodes: "
5809                    "~n      MgcNode: ~p"
5810                    "~n      MgNode:  ~p",
5811                    [MgcNode, MgNode]),
5812                  Nodes = [MgcNode, MgNode],
5813                  ok = ?START_NODES(Nodes, true),
5814                  Nodes
5815          end,
5816    Case = fun do_pending_ack_plain/1,
5817    Post = fun(Nodes) ->
5818                   d("stop nodes"),
5819                   ?STOP_NODES(lists:reverse(Nodes))
5820           end,
5821    try_tc(pap, Pre, Case, Post).
5822
5823do_pending_ack_plain([MgcNode, MgNode]) ->
5824    d("[MGC] start the simulator "),
5825    {ok, Mgc} = megaco_test_megaco_generator:start_link("MGC", MgcNode),
5826
5827    d("[MGC] create the event sequence"),
5828    MgcEvSeq = pap_mgc_event_sequence(text, tcp),
5829
5830    i("wait some time before starting the MGC simulation"),
5831    sleep(1000),
5832
5833    d("[MGC] start the simulation"),
5834    {ok, MgcId} = megaco_test_megaco_generator:exec(Mgc, MgcEvSeq),
5835
5836    %% i("wait some time before starting the MG simulator"),
5837    %% sleep(1000),
5838
5839    i("await MGC ready announcement"),
5840    receive
5841        announce_mgc ->
5842            i("received MGC ready announcement"),
5843            ok
5844    end,
5845
5846    d("[MG] start the simulator (generator)"),
5847    {ok, Mg} = megaco_test_tcp_generator:start_link("MG", MgNode),
5848
5849    d("[MG] create the event sequence"),
5850    MgEvSeq = pap_mg_event_sequence(text, tcp),
5851
5852    i("wait some time before starting the MG simulation"),
5853    sleep(1000),
5854
5855    d("[MG] start the simulation"),
5856    {ok, MgId} = megaco_test_tcp_generator:exec(Mg, MgEvSeq),
5857
5858    d("await the generator reply(s)"),
5859    await_completion([MgcId, MgId]),
5860
5861    %% Tell Mgc to stop
5862    i("[MGC] stop generator"),
5863    megaco_test_megaco_generator:stop(Mgc),
5864
5865    %% Tell Mg to stop
5866    i("[MG] stop generator"),
5867    megaco_test_tcp_generator:stop(Mg),
5868
5869    i("done", []),
5870    ok.
5871
5872
5873%%
5874%% MGC generator stuff
5875%%
5876
5877-ifdef(megaco_hipe_special).
5878-define(pap_mgc_verify_handle_connect_fun(),
5879        {?MODULE, pap_mgc_verify_handle_connect, []}).
5880-define(pap_mgc_verify_service_change_req_fun(Mid),
5881        {?MODULE, pap_mgc_verify_service_change_req, [Mid]}).
5882-define(pap_mgc_verify_notify_req_fun(),
5883        {?MODULE, pap_mgc_verify_notify_req, []}).
5884-define(pap_mgc_verify_notify_req_long_fun(),
5885        {?MODULE, pap_mgc_verify_notify_req_long, []}).
5886-define(pap_mgc_verify_handle_trans_ack_fun(),
5887	{?MODULE, pap_mgc_verify_handle_trans_ack, []}).
5888-define(pap_mgc_verify_handle_disconnect_fun(),
5889        {?MODULE, pap_mgc_verify_handle_disconnect, []}).
5890-else.
5891-define(pap_mgc_verify_handle_connect_fun(),
5892        fun pap_mgc_verify_handle_connect/1).
5893-define(pap_mgc_verify_service_change_req_fun(Mid),
5894        pap_mgc_verify_service_change_req_fun(Mid)).
5895-define(pap_mgc_verify_notify_req_fun(),
5896	pap_mgc_verify_notify_req_fun()).
5897-define(pap_mgc_verify_notify_req_long_fun(),
5898	pap_mgc_verify_notify_req_long_fun()).
5899-define(pap_mgc_verify_handle_trans_ack_fun(),
5900	pap_mgc_verify_handle_trans_ack_fun()).
5901-define(pap_mgc_verify_handle_disconnect_fun(),
5902	fun pap_mgc_verify_handle_disconnect/1).
5903-endif.
5904
5905pap_mgc_event_sequence(text, tcp) ->
5906    CTRL = self(),
5907    Mid = {deviceName,"ctrl"},
5908    RI = [
5909          {port,             2944},
5910          {encoding_module,  megaco_pretty_text_encoder},
5911          {encoding_config,  []},
5912          {transport_module, megaco_tcp}
5913         ],
5914    ConnectVerify = ?pap_mgc_verify_handle_connect_fun(),
5915    ScrVerify     = ?pap_mgc_verify_service_change_req_fun(Mid),
5916    NrVerify1     = ?pap_mgc_verify_notify_req_fun(),
5917    NrVerify2     = ?pap_mgc_verify_notify_req_long_fun(),
5918    AckVerify     = ?pap_mgc_verify_handle_trans_ack_fun(),
5919    DiscoVerify   = ?pap_mgc_verify_handle_disconnect_fun(),
5920    EvSeq = [
5921             {debug, true},
5922             {megaco_trace, disable},
5923             {megaco_trace, max},
5924             megaco_start,
5925             {megaco_start_user, Mid, RI, []},
5926             {megaco_update_user_info, sent_pending_limit, 100},
5927             start_transport,
5928             listen,
5929
5930             %% ANNOUNCE READY
5931             {trigger, fun() -> CTRL ! announce_mgc end},
5932
5933             {megaco_callback, handle_connect,            ConnectVerify},
5934             {megaco_conn_info, all},
5935             {megaco_callback, handle_trans_request,      ScrVerify},
5936	     {megaco_callback, handle_trans_request,      NrVerify1},
5937	     {megaco_callback, handle_trans_long_request, NrVerify2},
5938	     {megaco_callback, handle_trans_ack,          AckVerify},
5939             {megaco_callback, handle_disconnect,         DiscoVerify},
5940             megaco_stop_user,
5941             megaco_stop
5942            ],
5943    EvSeq.
5944
5945%% Connect verification
5946pap_mgc_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
5947    {ok, CH, ok};
5948pap_mgc_verify_handle_connect(Else) ->
5949    {error, Else, ok}.
5950
5951%% Service Change verification
5952-ifndef(megaco_hipe_special).
5953pap_mgc_verify_service_change_req_fun(Mid) ->
5954    fun(Req) ->
5955	    pap_mgc_verify_service_change_req(Req, Mid)
5956    end.
5957-endif.
5958
5959pap_mgc_verify_service_change_req(
5960  {handle_trans_request, _, ?VERSION, [AR]}, Mid) ->
5961    (catch pap_do_verify_service_change_req(AR, Mid));
5962pap_mgc_verify_service_change_req(Crap, _Mid) ->
5963    ED       = cre_ErrDesc(Crap),
5964    ErrReply = {discard_ack, ED},
5965    {error, Crap, ErrReply}.
5966
5967pap_do_verify_service_change_req(AR, Mid) ->
5968    CR =
5969	case AR of
5970	    #'ActionRequest'{commandRequests = [CmdReq]} ->
5971		CmdReq;
5972	    _ ->
5973		Err1      = {invalid_action_request, AR},
5974		ED1       = cre_ErrDesc(AR),
5975		ErrReply1 = {discard_ack, ED1},
5976		throw({error, Err1, ErrReply1})
5977	end,
5978    Cmd =
5979	case CR of
5980	    #'CommandRequest'{command = Command} ->
5981		Command;
5982	    _ ->
5983		Err2      = {invalid_command_request, CR},
5984		ED2       = cre_ErrDesc(CR),
5985		ErrReply2 = {discard_ack, ED2},
5986		throw({error, Err2, ErrReply2})
5987	end,
5988    {Tid, Parms} =
5989	case Cmd of
5990	    {serviceChangeReq,
5991	     #'ServiceChangeRequest'{terminationID = [TermID],
5992				     serviceChangeParms = ServChParms}} ->
5993		{TermID, ServChParms};
5994	    _ ->
5995		Err3      = {invalid_command, Cmd},
5996		ED3       = cre_ErrDesc(Cmd),
5997		ErrReply3 = {discard_ack, ED3},
5998		throw({error, Err3, ErrReply3})
5999	end,
6000    case Tid of
6001	#megaco_term_id{contains_wildcards = false, id = ["root"]} ->
6002	    ok;
6003	_ ->
6004	    Err4      = {invalid_termination_id, Tid},
6005	    ED4       = cre_ErrDesc(Tid),
6006	    ErrReply4 = {discard_ack, ED4},
6007	    throw({error, Err4, ErrReply4})
6008    end,
6009    case Parms of
6010	#'ServiceChangeParm'{serviceChangeMethod = restart,
6011			     serviceChangeReason = [[$9,$0,$1|_]]} ->
6012	    AckData = [pap_mgc_service_change_reply_ar(Mid, 1)],
6013	    Reply   = {discard_ack, AckData},
6014	    {ok, AR, Reply};
6015	_ ->
6016	    Err5      = {invalid_SCP, Parms},
6017	    ED5       = cre_ErrDesc(Parms),
6018	    ErrReply5 = {discard_ack, ED5},
6019	    {error, Err5, ErrReply5}
6020    end.
6021
6022
6023%% Notify Request verification
6024-ifndef(megaco_hipe_special).
6025pap_mgc_verify_notify_req_fun() ->
6026    fun(Req) ->
6027	    pap_mgc_verify_notify_req(Req)
6028    end.
6029-endif.
6030
6031pap_mgc_verify_notify_req({handle_trans_request, _, ?VERSION, [AR]}) ->
6032    io:format("pap_mgc_verify_notify_req -> entry with"
6033	      "~n   AR: ~p"
6034	      "~n", [AR]),
6035    Reply = {pending, AR},
6036    {ok, AR, Reply};
6037pap_mgc_verify_notify_req(Crap) ->
6038    ED       = cre_ErrDesc(Crap),
6039    ErrReply = {discard_ack, ED},
6040    {error, Crap, ErrReply}.
6041
6042%% Notify Request verification
6043-ifndef(megaco_hipe_special).
6044pap_mgc_verify_notify_req_long_fun() ->
6045    fun(Req) ->
6046	    pap_mgc_verify_notify_req_long(Req)
6047    end.
6048-endif.
6049
6050pap_mgc_verify_notify_req_long(
6051  {handle_trans_long_request, _, ?VERSION, AR}) ->
6052    (catch pap_mgc_do_verify_notify_req_long(AR));
6053pap_mgc_verify_notify_req_long(Crap) ->
6054    ED       = cre_ErrDesc(Crap),
6055    ErrReply = {discard_ack, ED},
6056    {error, Crap, ErrReply}.
6057
6058pap_mgc_do_verify_notify_req_long(AR) ->
6059    io:format("pap_mgc_do_verify_notify_req_long -> entry with"
6060	      "~n   AR: ~p"
6061	      "~n", [AR]),
6062    {Cid, CR} =
6063	case AR of
6064	    #'ActionRequest'{contextId       = CtxID,
6065			     commandRequests = [CmdReq]} ->
6066		{CtxID, CmdReq};
6067	    _ ->
6068		Err1      = {invalid_action_request, AR},
6069		ED1       = cre_ErrDesc(AR),
6070		ErrReply1 = {discard_ack, ED1},
6071		throw({error, Err1, ErrReply1})
6072	end,
6073    Cmd =
6074	case CR of
6075	    #'CommandRequest'{command = Command} ->
6076		Command;
6077	    _ ->
6078		Err2      = {invalid_command_request, CR},
6079		ED2       = cre_ErrDesc(CR),
6080		ErrReply2 = {discard_ack, ED2},
6081		throw({error, Err2, ErrReply2})
6082	end,
6083    NR =
6084	case Cmd of
6085	    {notifyReq, NotifReq} ->
6086		NotifReq;
6087	    _ ->
6088		Err3      = {invalid_command, Cmd},
6089		ED3       = cre_ErrDesc(Cmd),
6090		ErrReply3 = {discard_ack, ED3},
6091		throw({error, Err3, ErrReply3})
6092	end,
6093    {Tid, OED} =
6094	case NR of
6095	    #'NotifyRequest'{terminationID            = [TermID],
6096			     observedEventsDescriptor = ObsEvsDesc,
6097			     errorDescriptor          = asn1_NOVALUE} ->
6098		{TermID, ObsEvsDesc};
6099	    _ ->
6100		Err4      = {invalid_NR, NR},
6101		ED4       = cre_ErrDesc(NR),
6102		ErrReply4 = {discard_ack, ED4},
6103		throw({error, Err4, ErrReply4})
6104	end,
6105    OE =
6106	case OED of
6107	    #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
6108		ObsEvLst;
6109	    _ ->
6110		Err5      = {invalid_OED, OED},
6111		ED5       = cre_ErrDesc(NR),
6112		ErrReply5 = {discard_ack, ED5},
6113		throw({error, Err5, ErrReply5})
6114	end,
6115    case OE of
6116	#'ObservedEvent'{eventName = "al/of"} ->
6117	    AckData = pap,
6118	    Replies = [pap_mgc_notify_reply_ar(Cid, Tid)],
6119	    Reply   = {{handle_ack, AckData}, Replies},
6120	    {ok, AR, Reply};
6121	_ ->
6122	    Err6      = {invalid_OE, OE},
6123	    ED6       = cre_ErrDesc(OE),
6124	    ErrReply6 = {discard_ack, ED6},
6125	    throw({error, Err6, ErrReply6})
6126    end.
6127
6128
6129-ifndef(megaco_hipe_special).
6130pap_mgc_verify_handle_trans_ack_fun() ->
6131    fun(Ack) ->
6132	    pap_mgc_verify_handle_trans_ack(Ack)
6133    end.
6134-endif.
6135
6136pap_mgc_verify_handle_trans_ack({handle_trans_ack, CH, ?VERSION, ok, pap}) ->
6137    io:format("pap_mgc_verify_handle_trans_ack -> ok"
6138              "~n   CH: ~p"
6139              "~n", [CH]),
6140    {ok, CH, ok};
6141pap_mgc_verify_handle_trans_ack(Crap) ->
6142    io:format("pap_mgc_verify_handle_trans_ack -> unknown"
6143              "~n   Crap: ~p~n", [Crap]),
6144    {error, Crap, ok}.
6145
6146
6147%% Disconnect verification
6148pap_mgc_verify_handle_disconnect({handle_disconnect, CH, ?VERSION, _R}) ->
6149    {ok, CH, ok};
6150pap_mgc_verify_handle_disconnect(Else) ->
6151    {error, Else, ok}.
6152
6153pap_mgc_service_change_reply_ar(Mid, Cid) ->
6154    SCRP  = cre_serviceChangeResParm(Mid),
6155    SCRes = cre_serviceChangeResult(SCRP),
6156    Root  = #megaco_term_id{id = ["root"]},
6157    SCR   = cre_serviceChangeReply([Root], SCRes),
6158    CR    = cre_cmdReply(SCR),
6159    AR    = cre_actionReply(Cid, [CR]),
6160    AR.
6161
6162pap_mgc_notify_reply_ar(Cid, TermId) ->
6163    NR    = cre_notifyReply([TermId]),
6164    CR    = cre_cmdReply(NR),
6165    cre_actionReply(Cid, [CR]).
6166
6167
6168%%
6169%% MG generator stuff
6170%%
6171-ifdef(megaco_hipe_special).
6172-define(pap_mg_decode_msg_fun(Mod, Conf),
6173	{?MODULE, decode_msg, [Mod, Conf]}).
6174-define(pap_mg_encode_msg_fun(Mod, Conf),
6175	{?MODULE, encode_msg, [Mod, Conf]}).
6176-define(pap_mg_verify_service_change_rep_msg_fun(),
6177	{?MODULE, pap_mg_verify_service_change_rep_msg, []}).
6178-define(pap_mg_verify_pending_msg_fun(TransId),
6179	{?MODULE, pap_mg_verify_pending_msg, [TransId]}).
6180-define(pap_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId),
6181	{?MODULE, pap_mg_verify_notify_rep_msg, [TermId, TransId, ReqId, CtxId]}).
6182-else.
6183-define(pap_mg_decode_msg_fun(Mod, Conf),
6184	pap_mg_decode_msg_fun(Mod, Conf)).
6185-define(pap_mg_encode_msg_fun(Mod, Conf),
6186	pap_mg_encode_msg_fun(Mod, Conf)).
6187-define(pap_mg_verify_service_change_rep_msg_fun(),
6188	pap_mg_verify_service_change_rep_msg_fun()).
6189-define(pap_mg_verify_pending_msg_fun(TransId),
6190	pap_mg_verify_pending_msg_fun(TransId)).
6191-define(pap_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId),
6192	pap_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId)).
6193-endif.
6194
6195pap_mg_event_sequence(text, tcp) ->
6196    DecodeFun = ?pap_mg_decode_msg_fun(megaco_pretty_text_encoder, []),
6197    EncodeFun = ?pap_mg_encode_msg_fun(megaco_pretty_text_encoder, []),
6198    Mid       = {deviceName,"mg"},
6199    ServiceChangeReq = pap_mg_service_change_request_msg(Mid, 1, 0),
6200    TermId  = #megaco_term_id{id = ["00000000","00000000","01101101"]},
6201    TransId = 2,
6202    ReqId   = 1,
6203    CtxId   = 1,
6204    NotifyReq =
6205	pap_mg_notify_request_msg(Mid, TermId, TransId, ReqId, CtxId),
6206    TransAck = pap_mg_trans_ack_msg(Mid, TransId),
6207    ScrVerifyFun = ?pap_mg_verify_service_change_rep_msg_fun(),
6208    PendingVerifyFun =
6209	?pap_mg_verify_pending_msg_fun(TransId),
6210    NrVerifyFun =
6211	?pap_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId),
6212    EvSeq = [{debug,  true},
6213             {decode, DecodeFun},
6214             {encode, EncodeFun},
6215             {connect, 2944},
6216             {send, "service-change-request", ServiceChangeReq},
6217             {expect_receive, "service-change-reply", {ScrVerifyFun, 10000}},
6218             {send, "notify request", NotifyReq},
6219             {expect_receive, "pending",      {PendingVerifyFun, 4000}},
6220             {expect_receive, "notify-reply", {NrVerifyFun, 4000}},
6221             {send, "transaction-ack", TransAck},
6222             {expect_nothing, 11000},
6223             disconnect
6224            ],
6225    EvSeq.
6226
6227-ifndef(megaco_hipe_special).
6228pap_mg_encode_msg_fun(Mod, Conf) ->
6229    fun(M) ->
6230            encode_msg(M, Mod, Conf)
6231    end.
6232-endif.
6233
6234-ifndef(megaco_hipe_special).
6235pap_mg_decode_msg_fun(Mod, Conf) ->
6236    fun(M) ->
6237            decode_msg(M, Mod, Conf)
6238    end.
6239-endif.
6240
6241-ifndef(megaco_hipe_special).
6242pap_mg_verify_service_change_rep_msg_fun() ->
6243    fun(Msg) ->
6244	    (catch pap_mg_verify_service_change_rep_msg(Msg))
6245    end.
6246-endif.
6247
6248pap_mg_verify_service_change_rep_msg(#'MegacoMessage'{mess = Mess} = M) ->
6249    Body =
6250	case Mess of
6251	    #'Message'{version     = _V,
6252                       mId         = _MgMid,
6253                       messageBody = MsgBody} ->
6254		MsgBody;
6255	    _ ->
6256		throw({error, {invalid_Message, Mess}})
6257	end,
6258    Trans =
6259	case Body of
6260            {transactions, [Transactions]} ->
6261		Transactions;
6262	    _ ->
6263		throw({error, {invalid_messageBody, Body}})
6264	end,
6265    TR =
6266	case Trans of
6267            {transactionReply, TransReply} ->
6268		TransReply;
6269	    _ ->
6270		throw({error, {invalid_transactions, Trans}})
6271	end,
6272    TRes =
6273	case TR of
6274            #'TransactionReply'{transactionId = _Tid,
6275                                immAckRequired = asn1_NOVALUE,
6276                                transactionResult = TransRes} ->
6277		TransRes;
6278	    _ ->
6279		throw({error, {invalid_transactionReply, TR}})
6280	end,
6281    AR =
6282	case TRes of
6283            {actionReplies, [ActRes]} ->
6284		ActRes;
6285	    _ ->
6286		throw({error, {invalid_transactionResult, TRes}})
6287	end,
6288    CR =
6289	case AR of
6290            #'ActionReply'{contextId       = _Cid,
6291                           errorDescriptor = asn1_NOVALUE,
6292                           contextReply    = _CtxReq,
6293                           commandReply    = [CmdRep]} ->
6294		CmdRep;
6295	    _ ->
6296		throw({error, {invalid_actionReplies, AR}})
6297	end,
6298    SCR =
6299	case CR of
6300            {serviceChangeReply, ServChRep} ->
6301		ServChRep;
6302	    _ ->
6303		throw({error, {invalid_commandReply, CR}})
6304	end,
6305    SCRes =
6306	case SCR of
6307            #'ServiceChangeReply'{terminationID       = _TermID,
6308                                  serviceChangeResult = ServChRes} ->
6309		ServChRes;
6310	    _ ->
6311		throw({error, {invalid_serviceChangeReply, SCR}})
6312	end,
6313    SCRP =
6314	case SCRes of
6315            {serviceChangeResParms, Parms} ->
6316		Parms;
6317	    _ ->
6318		throw({error, {invalid_serviceChangeResult, SCRes}})
6319	end,
6320    case SCRP of
6321	#'ServiceChangeResParm'{serviceChangeMgcId = _MgcMid} ->
6322            {ok, M};
6323	_ ->
6324	    {error, {invalid_serviceChangeResParms, SCRP}}
6325    end;
6326pap_mg_verify_service_change_rep_msg(Crap) ->
6327    {error, {invalid_message, Crap}}.
6328
6329-ifndef(megaco_hipe_special).
6330pap_mg_verify_pending_msg_fun(TransId) ->
6331    fun(Msg) ->
6332	    (catch pap_mg_verify_pending_msg(Msg, TransId))
6333    end.
6334-endif.
6335
6336pap_mg_verify_pending_msg(#'MegacoMessage'{mess = Mess} = M, TransId) ->
6337    io:format("pap_mg_verify_pending_msg -> entry with"
6338	      "~n   M:       ~p"
6339	      "~n   TransId: ~p"
6340	      "~n", [M, TransId]),
6341    Body =
6342	case Mess of
6343	    #'Message'{version     = ?VERSION,
6344                       mId         = _Mid,
6345                       messageBody = MsgBody} ->
6346		MsgBody;
6347	    _ ->
6348		throw({error, {invalid_Message, Mess}})
6349	end,
6350    Trans =
6351	case Body of
6352            {transactions, [Transactions]} ->
6353		Transactions;
6354	    _ ->
6355		throw({error, {invalid_messageBody, Body}})
6356	end,
6357    TP =
6358	case Trans of
6359            {transactionPending, TransPending} ->
6360		TransPending;
6361	    _ ->
6362		throw({error, {invalid_transactions, Trans}})
6363	end,
6364    case TP of
6365	#'TransactionPending'{transactionId = TransId} ->
6366	    {ok, M};
6367	_ ->
6368	    {error, {invalid_transactionPending, TP}}
6369    end;
6370pap_mg_verify_pending_msg(Crap, _TransId) ->
6371    {error, {invalid_message, Crap}}.
6372
6373-ifndef(megaco_hipe_special).
6374pap_mg_verify_notify_rep_msg_fun(TermId, TransId, Rid, Cid) ->
6375    fun(Msg) ->
6376	    (catch pap_mg_verify_notify_rep_msg(Msg,
6377						TermId, TransId, Rid, Cid))
6378    end.
6379-endif.
6380
6381pap_mg_verify_notify_rep_msg(#'MegacoMessage'{mess = Mess} = M,
6382			   TermId, TransId, Rid, Cid) ->
6383    io:format("pap_mg_verify_notify_rep_msg -> entry with"
6384	      "~n   M:       ~p"
6385	      "~n   TermId:  ~p"
6386	      "~n   TransId: ~p"
6387	      "~n   Rid:     ~p"
6388	      "~n   Cid:     ~p"
6389	      "~n", [M, TermId, TransId, Rid, Cid]),
6390    Body =
6391	case Mess of
6392	    #'Message'{version     = ?VERSION,
6393                       mId         = _Mid,
6394                       messageBody = MsgBody} ->
6395		MsgBody;
6396	    _ ->
6397		throw({error, {invalid_Message, Mess}})
6398	end,
6399    Trans =
6400	case Body of
6401            {transactions, [Transactions]} ->
6402		Transactions;
6403	    _ ->
6404		throw({error, {invalid_messageBody, Body}})
6405	end,
6406    TR =
6407	case Trans of
6408            {transactionReply, TransReply} ->
6409		TransReply;
6410	    _ ->
6411		throw({error, {invalid_transactions, Trans}})
6412	end,
6413    TRes =
6414	case TR of
6415            #'TransactionReply'{transactionId     = TransId,
6416                                immAckRequired    = 'NULL',
6417                                transactionResult = TransRes} ->
6418		TransRes;
6419	    _ ->
6420		throw({error, {invalid_transactionReply, TR}})
6421	end,
6422    AR =
6423	case TRes of
6424            {actionReplies, [ActRes]} ->
6425		ActRes;
6426	    _ ->
6427		throw({error, {invalid_transactionResult, TRes}})
6428	end,
6429    CR =
6430	case AR of
6431            #'ActionReply'{contextId       = Cid,
6432                           errorDescriptor = asn1_NOVALUE,
6433                           contextReply    = _CtxReq,
6434                           commandReply    = [CmdRep]} ->
6435		CmdRep;
6436	    _ ->
6437		throw({error, {invalid_actionReplies, AR}})
6438	end,
6439    NR =
6440	case CR of
6441            {notifyReply, NotifyReply} ->
6442		NotifyReply;
6443	    _ ->
6444		throw({error, {invalid_commandReply, CR}})
6445	end,
6446    case NR of
6447	#'NotifyReply'{terminationID   = [TermId],
6448		       errorDescriptor = asn1_NOVALUE} ->
6449	    {ok, M};
6450	_ ->
6451	    {error, {invalid_notifyReply, NR}}
6452    end;
6453pap_mg_verify_notify_rep_msg(Crap, _TermId, _TransId, _Rid, _Cid) ->
6454    {error, {invalid_message, Crap}}.
6455
6456pap_mg_service_change_request_ar(_Mid, Cid) ->
6457    Prof  = cre_serviceChangeProf("resgw", 1),
6458    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
6459    Root  = #megaco_term_id{id = ["root"]},
6460    SCR   = cre_serviceChangeReq([Root], SCP),
6461    CMD   = cre_command(SCR),
6462    CR    = cre_cmdReq(CMD),
6463    cre_actionReq(Cid, [CR]).
6464
6465pap_mg_service_change_request_msg(Mid, TransId, Cid) ->
6466    AR    = pap_mg_service_change_request_ar(Mid, Cid),
6467    TR    = cre_transReq(TransId, [AR]),
6468    Trans = cre_transaction(TR),
6469    Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
6470    cre_megacoMessage(Mess).
6471
6472pap_mg_notify_request_ar(Rid, Tid, Cid) ->
6473    TT      = cre_timeNotation("19990729", "22000000"),
6474    Ev      = cre_obsEvent("al/of", TT),
6475    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
6476    NR      = cre_notifyReq([Tid], EvsDesc),
6477    CMD     = cre_command(NR),
6478    CR      = cre_cmdReq(CMD),
6479    cre_actionReq(Cid, [CR]).
6480
6481pap_mg_notify_request_msg(Mid, TermId, TransId, Rid, Cid) ->
6482    AR      = pap_mg_notify_request_ar(Rid, TermId, Cid),
6483    TR      = cre_transReq(TransId, [AR]),
6484    Trans   = cre_transaction(TR),
6485    Mess    = cre_message(?VERSION, Mid, cre_transactions([Trans])),
6486    cre_megacoMessage(Mess).
6487
6488pap_mg_trans_ack_msg(Mid, TransId) ->
6489    TR    = cre_transRespAck(cre_transAck(TransId)),
6490    Trans = cre_transaction(TR),
6491    Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
6492    cre_megacoMessage(Mess).
6493
6494
6495%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6496
6497request_and_pending_and_late_reply(suite) ->
6498    [];
6499request_and_pending_and_late_reply(doc) ->
6500    ["Receive a request and handle it as a long request, "
6501     "i.e. return with {pending, _}. Then, expect the sender "
6502     "to keep re-sending the request until the reply is sent."];
6503request_and_pending_and_late_reply(Config) when is_list(Config) ->
6504    Pre = fun() ->
6505                  MgcNode = make_node_name(mgc),
6506                  MgNode  = make_node_name(mg),
6507                  d("start nodes: "
6508                    "~n      MgcNode: ~p"
6509                    "~n      MgNode:  ~p",
6510                    [MgcNode, MgNode]),
6511                  Nodes = [MgcNode, MgNode],
6512                  ok = ?START_NODES(Nodes, true),
6513                  Nodes
6514          end,
6515    Case = fun do_request_and_pending_and_late_reply/1,
6516    Post = fun(Nodes) ->
6517                   d("stop nodes"),
6518                   ?STOP_NODES(lists:reverse(Nodes))
6519           end,
6520    try_tc(rapalr, Pre, Case, Post).
6521
6522do_request_and_pending_and_late_reply([MgcNode, MgNode]) ->
6523    d("[MGC] start the simulator "),
6524    {ok, Mgc} = megaco_test_tcp_generator:start_link("MGC", MgcNode),
6525
6526    d("[MGC] create the event sequence"),
6527    MgcEvSeq = rapalr_mgc_event_sequence(text, tcp),
6528
6529    i("wait some time before starting the MGC simulation"),
6530    sleep(1000),
6531
6532    d("[MGC] start the simulation"),
6533    {ok, MgcId} = megaco_test_tcp_generator:exec(Mgc, MgcEvSeq),
6534
6535    %% i("wait some time before starting the MG simulator"),
6536    %% sleep(1000),
6537
6538    i("await MGC ready announcement"),
6539    receive
6540        announce_mgc ->
6541            i("received MGC ready announcement"),
6542            ok
6543    end,
6544
6545    d("[MG] start the simulator (generator)"),
6546    {ok, Mg} = megaco_test_megaco_generator:start_link("MG", MgNode),
6547
6548    d("[MG] create the event sequence"),
6549    MgEvSeq = rapalr_mg_event_sequence(text, tcp),
6550
6551    i("wait some time before starting the MG simulation"),
6552    sleep(1000),
6553
6554    d("[MG] start the simulation"),
6555    {ok, MgId} = megaco_test_megaco_generator:exec(Mg, MgEvSeq),
6556
6557    d("await the generator reply(s)"),
6558    await_completion([MgcId, MgId]),
6559
6560    %% Tell Mgc to stop
6561    i("[MGC] stop generator"),
6562    megaco_test_tcp_generator:stop(Mgc),
6563
6564    %% Tell Mg to stop
6565    i("[MG] stop generator"),
6566    megaco_test_megaco_generator:stop(Mg),
6567
6568    i("done", []),
6569    ok.
6570
6571
6572%%
6573%% MGC generator stuff
6574%%
6575
6576-ifdef(megaco_hipe_special).
6577-define(rapalr_mgc_decode_msg_fun(Mod, Conf),
6578	{?MODULE, decode_msg, [Mod, Conf]}).
6579-define(rapalr_mgc_encode_msg_fun(Mod, Conf),
6580	{?MODULE, encode_msg, [Mod, Conf]}).
6581-define(rapalr_mgc_verify_service_change_req_msg_fun(),
6582	{?MODULE, rapalr_mgc_verify_service_change_req_msg, []}).
6583-define(rapalr_mgc_verify_notify_req_msg_fun(TermId, TransId, ReqId, CtxId),
6584	{?MODULE, rapalr_mgc_verify_notify_req_msg, [TermId, TransId, ReqId, CtxId]}).
6585-define(rapalr_mgc_verify_trans_ack_msg_fun(TransId),
6586	{?MODULE, rapalr_mgc_verify_trans_ack_msg, [TransId]}).
6587-else.
6588-define(rapalr_mgc_decode_msg_fun(Mod, Conf),
6589	rapalr_mgc_decode_msg_fun(Mod, Conf)).
6590-define(rapalr_mgc_encode_msg_fun(Mod, Conf),
6591	rapalr_mgc_encode_msg_fun(Mod, Conf)).
6592-define(rapalr_mgc_verify_service_change_req_msg_fun(),
6593	rapalr_mgc_verify_service_change_req_msg_fun()).
6594-define(rapalr_mgc_verify_notify_req_msg_fun(TermId, TransId, ReqId, CtxId),
6595	rapalr_mgc_verify_notify_req_msg_fun(TermId, TransId, ReqId, CtxId)).
6596-define(rapalr_mgc_verify_trans_ack_msg_fun(TransId),
6597	rapalr_mgc_verify_trans_ack_msg_fun(TransId)).
6598-endif.
6599
6600rapalr_mgc_event_sequence(text, tcp) ->
6601    CTRL = self(),
6602    DecodeFun = ?rapalr_mgc_decode_msg_fun(megaco_pretty_text_encoder, []),
6603    EncodeFun = ?rapalr_mgc_encode_msg_fun(megaco_pretty_text_encoder, []),
6604    Mid       = {deviceName,"mgc"},
6605    ServiceChangeRep = rapalr_mgc_service_change_reply_msg(Mid, 1),
6606    TermId           =
6607	#megaco_term_id{id = ["00000000","00000000","01101101"]},
6608    TransId   = 2,
6609    ReqId     = 1,
6610    CtxId     = 1,
6611    Pending      = rapalr_mgc_trans_pending_msg(Mid, TransId),
6612    NotifyRep    = rapalr_mgc_notify_reply_msg(Mid, TransId,
6613					       CtxId, TermId),
6614    ScrVerifyFun = ?rapalr_mgc_verify_service_change_req_msg_fun(),
6615    NrVerifyFun  =
6616	?rapalr_mgc_verify_notify_req_msg_fun(TermId, TransId, ReqId, CtxId),
6617    AckVerifyFun = ?rapalr_mgc_verify_trans_ack_msg_fun(TransId),
6618    EvSeq = [{debug,  false},
6619             {decode, DecodeFun},
6620             {encode, EncodeFun},
6621             {listen, 2944},
6622
6623             %% ANNOUNCE READY
6624             {trigger, "announce ready", fun() -> CTRL ! announce_mgc end},
6625
6626	     {expect_accept, any},
6627             {expect_receive, "service-change-request", {ScrVerifyFun, 5000}},
6628             {send, "service-change-reply", ServiceChangeRep},
6629             {expect_receive, "notify-request(1)", {NrVerifyFun, 4000}},
6630             {send, "pending", Pending},
6631             {expect_receive, "notify-request(2)", {NrVerifyFun, 4000}},
6632             {expect_receive, "notify-request(3)", {NrVerifyFun, 4000}},
6633             {send, "notify reply", NotifyRep},
6634             {expect_receive, "ack", {AckVerifyFun, 4000}},
6635             {sleep, 1000},
6636             disconnect
6637            ],
6638    EvSeq.
6639
6640-ifndef(megaco_hipe_special).
6641rapalr_mgc_encode_msg_fun(Mod, Conf) ->
6642    fun(M) ->
6643            encode_msg(M, Mod, Conf)
6644    end.
6645-endif.
6646
6647-ifndef(megaco_hipe_special).
6648rapalr_mgc_decode_msg_fun(Mod, Conf) ->
6649    fun(M) ->
6650            decode_msg(M, Mod, Conf)
6651    end.
6652-endif.
6653
6654-ifndef(megaco_hipe_special).
6655rapalr_mgc_verify_service_change_req_msg_fun() ->
6656    fun(Msg) ->
6657	    (catch rapalr_mgc_verify_service_change_req_msg(Msg))
6658    end.
6659-endif.
6660
6661rapalr_mgc_verify_service_change_req_msg(#'MegacoMessage'{mess = Mess} = M) ->
6662    Body =
6663	case Mess of
6664	    #'Message'{version     = ?VERSION,
6665                       mId         = _MgMid,
6666                       messageBody = MsgBody} ->
6667		MsgBody;
6668	    _ ->
6669		throw({error, {invalid_Message, Mess}})
6670	end,
6671    Trans =
6672	case Body of
6673            {transactions, [Transactions]} ->
6674		Transactions;
6675	    _ ->
6676		throw({error, {invalid_messageBody, Body}})
6677	end,
6678    TR =
6679	case Trans of
6680            {transactionRequest, TransRequest} ->
6681		TransRequest;
6682	    _ ->
6683		throw({error, {invalid_transactions, Trans}})
6684	end,
6685    AR =
6686	case TR of
6687            #'TransactionRequest'{transactionId = _TransId,
6688				  actions       = [ActionReq]} ->
6689		ActionReq;
6690	    _ ->
6691		throw({error, {invalid_transactionRequest, TR}})
6692	end,
6693    CR =
6694	case AR of
6695	    #'ActionRequest'{contextId       = _Cid,
6696			     commandRequests = [CmdReq]} ->
6697		CmdReq;
6698	    _ ->
6699		throw({error, {invalid_action, AR}})
6700	end,
6701    Cmd =
6702	case CR of
6703	    #'CommandRequest'{command = Command} ->
6704		Command;
6705	    _ ->
6706		throw({error, {invalid_commandRequest, CR}})
6707	end,
6708    {Tid, Parms} =
6709	case Cmd of
6710	    {serviceChangeReq,
6711	     #'ServiceChangeRequest'{terminationID      = [TermID],
6712				     serviceChangeParms = ServChParms}} ->
6713		{TermID, ServChParms};
6714	    _ ->
6715		throw({error, {invalid_command, Cmd}})
6716	end,
6717    case Tid of
6718	#megaco_term_id{contains_wildcards = false, id = ["root"]} ->
6719	    ok;
6720	_ ->
6721	    throw({error, {invalid_terminationID, Tid}})
6722    end,
6723    case Parms of
6724	#'ServiceChangeParm'{serviceChangeMethod = restart,
6725			     serviceChangeReason = [[$9,$0,$1|_]]} ->
6726	    {ok, M};
6727	_ ->
6728	    {error, {invalid_serviceChangeParms, Parms}}
6729    end.
6730
6731-ifndef(megaco_hipe_special).
6732rapalr_mgc_verify_notify_req_msg_fun(TermId, TransId, Rid, Cid) ->
6733    fun(Msg) ->
6734	    (catch rapalr_mgc_verify_notify_req_msg(Msg,
6735						    TermId,
6736						    TransId, Rid, Cid))
6737    end.
6738-endif.
6739
6740rapalr_mgc_verify_notify_req_msg(#'MegacoMessage'{mess = Mess} = M,
6741			     TermId, TransId, Rid, Cid) ->
6742    io:format("rapalr_mgc_verify_notify_req_msg -> entry with"
6743	      "~n   M:       ~p"
6744	      "~n   TermId:  ~p"
6745	      "~n   TransId: ~p"
6746	      "~n   Rid:     ~p"
6747	      "~n   Cid:     ~p"
6748	      "~n", [M, TermId, TransId, Rid, Cid]),
6749    Body =
6750	case Mess of
6751	    #'Message'{version     = ?VERSION,
6752                       mId         = _Mid,
6753                       messageBody = MsgBody} ->
6754		MsgBody;
6755	    _ ->
6756		throw({error, {invalid_Message, Mess}})
6757	end,
6758    Trans =
6759	case Body of
6760            {transactions, [Transactions]} ->
6761		Transactions;
6762	    _ ->
6763		throw({error, {invalid_messageBody, Body}})
6764	end,
6765    TR =
6766	case Trans of
6767            {transactionRequest, TransRequest} ->
6768		TransRequest;
6769	    _ ->
6770		throw({error, {invalid_transactions, Trans}})
6771	end,
6772    AR =
6773	case TR of
6774            #'TransactionRequest'{transactionId = TransId,
6775				  actions       = [ActReq]} ->
6776		ActReq;
6777	    _ ->
6778		throw({error, {invalid_transactionRequest, TR}})
6779	end,
6780    CR =
6781	case AR of
6782	    #'ActionRequest'{contextId       = Cid,
6783			     commandRequests = [CmdReq]} ->
6784		CmdReq;
6785	    _ ->
6786		throw({error, {invalid_actions, AR}})
6787	end,
6788    Cmd =
6789	case CR of
6790	    #'CommandRequest'{command = Command} ->
6791		Command;
6792	    _ ->
6793		throw({error, {invalid_commandRequests, CR}})
6794	end,
6795    NR =
6796	case Cmd of
6797	    {notifyReq, NotifReq} ->
6798		NotifReq;
6799	    _ ->
6800		throw({error, {invalid_command, Cmd}})
6801	end,
6802    OED =
6803	case NR of
6804	    #'NotifyRequest'{terminationID            = [TermId],
6805			     observedEventsDescriptor = ObsEvsDesc,
6806			     errorDescriptor          = asn1_NOVALUE} ->
6807		ObsEvsDesc;
6808	    _ ->
6809		throw({error, {invalid_notifyReq, NR}})
6810	end,
6811    OE =
6812	case OED of
6813	    #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
6814		ObsEvLst;
6815	    _ ->
6816		throw({error, {invalid_observedEventsDescriptor, OED}})
6817	end,
6818    case OE of
6819	#'ObservedEvent'{eventName = "al/of"} ->
6820	    {ok, M};
6821	_ ->
6822	    throw({error, {invalid_observedEventLst, OE}})
6823    end;
6824rapalr_mgc_verify_notify_req_msg(Crap, _TermId, _TransId, _Rid, _Cid) ->
6825    {error, {invalid_MegacoMessage, Crap}}.
6826
6827-ifndef(megaco_hipe_special).
6828rapalr_mgc_verify_trans_ack_msg_fun(TransId) ->
6829    fun(Msg) ->
6830	    (catch rapalr_mgc_verify_trans_ack_msg(Msg, TransId))
6831    end.
6832-endif.
6833
6834rapalr_mgc_verify_trans_ack_msg(#'MegacoMessage'{mess = Mess} = M,
6835				TransId) ->
6836    io:format("rapalr_mgc_verify_trans_ack_msg -> entry with"
6837	      "~n   M:       ~p"
6838	      "~n   TransId: ~p"
6839	      "~n", [M, TransId]),
6840    Body =
6841	case Mess of
6842	    #'Message'{version     = ?VERSION,
6843                       mId         = _Mid,
6844                       messageBody = MsgBody} ->
6845		MsgBody;
6846	    _ ->
6847		throw({error, {invalid_Message, Mess}})
6848	end,
6849    Trans =
6850	case Body of
6851            {transactions, [Transactions]} ->
6852		Transactions;
6853	    _ ->
6854		throw({error, {invalid_messageBody, Body}})
6855	end,
6856    TA =
6857	case Trans of
6858            {transactionResponseAck, [TransAck]} ->
6859		TransAck;
6860	    _ ->
6861		throw({error, {invalid_transactions, Trans}})
6862	end,
6863    case TA of
6864            #'TransactionAck'{firstAck = TransId,
6865			      lastAck  = asn1_NOVALUE} ->
6866		{ok, M};
6867	    _ ->
6868		throw({error, {invalid_transactionResponseAck, TA}})
6869    end;
6870rapalr_mgc_verify_trans_ack_msg(Crap, _TransId) ->
6871    {error, {invalid_MegacoMessage, Crap}}.
6872
6873rapalr_mgc_service_change_reply_msg(Mid, Cid) ->
6874    SCRP  = cre_serviceChangeResParm(Mid),
6875    SCRes = cre_serviceChangeResult(SCRP),
6876    Root  = #megaco_term_id{id = ["root"]},
6877    SCR   = cre_serviceChangeReply([Root], SCRes),
6878    CR    = cre_cmdReply(SCR),
6879    AR    = cre_actionReply(Cid, [CR]),
6880    TRes  = cre_transResult([AR]),
6881    TR    = cre_transReply(1, TRes),
6882    Trans = cre_transaction(TR),
6883    Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
6884    cre_megacoMessage(Mess).
6885
6886rapalr_mgc_notify_reply_ar(Cid, TermId) ->
6887    NR    = cre_notifyReply([TermId]),
6888    CR    = cre_cmdReply(NR),
6889    cre_actionReply(Cid, [CR]).
6890
6891rapalr_mgc_notify_reply_msg(Mid, TransId, Cid, TermId) ->
6892    AR    = rapalr_mgc_notify_reply_ar(Cid, TermId),
6893    TRes  = cre_transResult([AR]),
6894    TR    = cre_transReply(TransId, 'NULL', TRes),
6895    Trans = cre_transaction(TR),
6896    Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
6897    cre_megacoMessage(Mess).
6898
6899rapalr_mgc_trans_pending_msg(Mid, TransId) ->
6900    TP   = #'TransactionPending'{transactionId = TransId},
6901    Body = {transactions, [{transactionPending, TP}]},
6902    Mess = #'Message'{version     = 1,
6903		      mId         = Mid,
6904		      messageBody = Body},
6905    #'MegacoMessage'{mess = Mess}.
6906
6907
6908
6909%%
6910%% MG generator stuff
6911%%
6912-ifdef(megaco_hipe_special).
6913-define(rapalr_mg_verify_handle_connect_fun(),
6914	{?MODULE, rapalr_mg_verify_handle_connect, []}).
6915-define(rapalr_mg_verify_service_change_rep_fun(),
6916	{?MODULE, rapalr_mg_verify_service_change_rep, []}).
6917-define(rapalr_mg_verify_notify_rep_fun(),
6918	{?MODULE, rapalr_mg_verify_notify_rep, []}).
6919-else.
6920-define(rapalr_mg_verify_handle_connect_fun(),
6921	rapalr_mg_verify_handle_connect_fun()).
6922-define(rapalr_mg_verify_service_change_rep_fun(),
6923	rapalr_mg_verify_service_change_rep_fun()).
6924-define(rapalr_mg_verify_notify_rep_fun(),
6925	rapalr_mg_verify_notify_rep_fun()).
6926-endif.
6927
6928rapalr_mg_event_sequence(text, tcp) ->
6929    Mid = {deviceName,"mg"},
6930    RI = [
6931          {port,             2944},
6932          {encoding_module,  megaco_pretty_text_encoder},
6933          {encoding_config,  []},
6934          {transport_module, megaco_tcp}
6935         ],
6936    LReqTmr = #megaco_incr_timer{wait_for    = 3000,
6937				 factor      = 1,
6938				 incr        = 0,
6939				 max_retries = 2
6940				},
6941    ServiceChangeReq = rapalr_mg_service_change_request_ar(Mid, 1),
6942    Tid = #megaco_term_id{id = ["00000000","00000000","01101101"]},
6943    NotifyReq = rapalr_mg_notify_request_ar(1, Tid, 1),
6944    ConnectVerify            = ?rapalr_mg_verify_handle_connect_fun(),
6945    ServiceChangeReplyVerify = ?rapalr_mg_verify_service_change_rep_fun(),
6946    NotifyReplyVerify        = ?rapalr_mg_verify_notify_rep_fun(),
6947%%     ConnectVerify            = rapalr_mg_verify_handle_connect_fun(),
6948%%     ServiceChangeReplyVerify = rapalr_mg_verify_service_change_reply_fun(),
6949%%     NotifyReplyVerify        = rapalr_mg_verify_notify_reply_fun(),
6950    EvSeq = [
6951             {debug, false},
6952             megaco_start,
6953             {megaco_start_user, Mid, RI, []},
6954             start_transport,
6955             {megaco_trace, disable},
6956             {megaco_system_info, users},
6957             {megaco_system_info, connections},
6958             {megaco_update_user_info, long_request_resend, true},
6959	     {megaco_update_user_info, long_request_timer,  LReqTmr},
6960             connect,
6961             {megaco_callback, handle_connect, ConnectVerify},
6962             megaco_connect,
6963             {megaco_cast,     [ServiceChangeReq], []},
6964             {megaco_callback, handle_connect,     ConnectVerify},
6965             {megaco_callback, handle_trans_reply, ServiceChangeReplyVerify},
6966             {sleep, 1000},
6967             {megaco_cast,     [NotifyReq],        []},
6968             {megaco_callback, handle_trans_reply, NotifyReplyVerify},
6969             {sleep, 1000},
6970             megaco_stop_user,
6971             megaco_stop,
6972             {sleep, 1000}
6973            ],
6974    EvSeq.
6975
6976
6977-ifndef(megaco_hipe_special).
6978rapalr_mg_verify_handle_connect_fun() ->
6979    fun(Ev) ->
6980	    rapalr_mg_verify_handle_connect(Ev)
6981    end.
6982-endif.
6983
6984rapalr_mg_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
6985    io:format("rapalr_mg_verify_handle_connect -> ok"
6986	      "~n   CH: ~p~n", [CH]),
6987    {ok, CH, ok};
6988rapalr_mg_verify_handle_connect(Else) ->
6989    io:format("rapalr_mg_verify_handle_connect -> unknown"
6990	      "~n   Else: ~p~n", [Else]),
6991    {error, Else, ok}.
6992
6993
6994-ifndef(megaco_hipe_special).
6995rapalr_mg_verify_service_change_rep_fun() ->
6996    fun(Rep) ->
6997	    rapalr_mg_verify_service_change_rep(Rep)
6998    end.
6999-endif.
7000
7001rapalr_mg_verify_service_change_rep(
7002  {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _}) ->
7003    (catch rapalr_mg_do_verify_service_change_rep(AR));
7004rapalr_mg_verify_service_change_rep(Crap) ->
7005    {error, Crap, ok}.
7006
7007rapalr_mg_do_verify_service_change_rep(AR) ->
7008    io:format("rapalr_mg_verify_service_change_rep -> ok"
7009	      "~n   AR: ~p~n", [AR]),
7010    CR =
7011	case AR of
7012	    #'ActionReply'{commandReply = [CmdRep]} ->
7013		CmdRep;
7014	    _ ->
7015		Reason1 = {invalid_action_reply, AR},
7016		throw({error, Reason1, ok})
7017	end,
7018    SCR =
7019	case CR of
7020	    {serviceChangeReply, ServChRep} ->
7021		ServChRep;
7022	    _ ->
7023		Reason2 = {invalid_command_reply, CR},
7024		throw({error, Reason2, ok})
7025	end,
7026    {Tid, SCRes} =
7027	case SCR of
7028	    #'ServiceChangeReply'{terminationID       = [TermID],
7029				  serviceChangeResult = Res} ->
7030		{TermID, Res};
7031	    _ ->
7032		Reason3 = {invalid_service_change_reply, SCR},
7033		throw({error, Reason3, ok})
7034	end,
7035    case Tid of
7036	#megaco_term_id{contains_wildcards = false, id = ["root"]} ->
7037	    ok;
7038	_ ->
7039	    Reason4 = {invalid_termination_id, Tid},
7040	    throw({error, Reason4, ok})
7041    end,
7042    SCRParm =
7043	case SCRes of
7044	    {serviceChangeResParms, ServChResParms} ->
7045		ServChResParms;
7046	    _ ->
7047		Reason5 = {invalid_serviceChangeResult, SCRes},
7048		throw({error, Reason5, ok})
7049	end,
7050    case SCRParm of
7051	#'ServiceChangeResParm'{serviceChangeMgcId = _RemoteMid} ->
7052	    {ok, AR, ok};
7053	_ ->
7054	    Reason6 = {invalid_service_change_result, SCRParm},
7055	    {error, Reason6, ok}
7056    end.
7057
7058-ifndef(megaco_hipe_special).
7059rapalr_mg_verify_notify_rep_fun() ->
7060    fun(Rep) ->
7061	    rapalr_mg_verify_notify_rep(Rep)
7062    end.
7063-endif.
7064
7065rapalr_mg_verify_notify_rep({handle_trans_reply, _CH, ?VERSION,
7066			      {ok, [AR]}, _}) ->
7067    io:format("rapalr_mg_verify_notify_rep -> ok"
7068	      "~n   AR: ~p~n", [AR]),
7069    {ok, AR, ok};
7070rapalr_mg_verify_notify_rep(Else) ->
7071    io:format("rapalr_mg_verify_notify_rep -> unknown"
7072	      "~n   Else: ~p~n", [Else]),
7073    {error, Else, ok}.
7074
7075
7076rapalr_mg_service_change_request_ar(_Mid, Cid) ->
7077    Prof  = cre_serviceChangeProf("resgw", 1),
7078    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
7079    Root  = #megaco_term_id{id = ["root"]},
7080    SCR   = cre_serviceChangeReq([Root], SCP),
7081    CMD   = cre_command(SCR),
7082    CR    = cre_cmdReq(CMD),
7083    cre_actionReq(Cid, [CR]).
7084
7085rapalr_mg_notify_request_ar(Rid, Tid, Cid) ->
7086    TT      = cre_timeNotation("19990729", "22000000"),
7087    Ev      = cre_obsEvent("al/of", TT),
7088    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
7089    NR      = cre_notifyReq([Tid], EvsDesc),
7090    CMD     = cre_command(NR),
7091    CR      = cre_cmdReq(CMD),
7092    cre_actionReq(Cid, [CR]).
7093
7094
7095
7096%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7097
7098dist(suite) ->
7099    [];
7100dist(Config) when is_list(Config) ->
7101    ?SKIP("Needs a re-write..."),
7102    [_Local, Dist] = ?ACQUIRE_NODES(2, Config),
7103    d("dist -> start proxy",[]),
7104    ?USER_MOD:start_proxy(),
7105
7106    PrelMid = preliminary_mid,
7107    MgMid   = ipv4_mid(4711),
7108    MgcMid  = ipv4_mid(),
7109    UserMod = ?USER_MOD,
7110    d("dist -> start megaco app",[]),
7111    ?VERIFY(ok, application:start(megaco)),
7112    UserConfig = [{user_mod, UserMod}, {send_mod, UserMod},
7113		  {request_timer, infinity}, {reply_timer, infinity}],
7114
7115    d("dist -> start megaco user MG (~p)",[MgMid]),
7116    ?VERIFY(ok,	megaco:start_user(MgMid, UserConfig)),
7117
7118    d("dist -> start megaco user MGC (~p)",[MgcMid]),
7119    ?VERIFY(ok,	megaco:start_user(MgcMid, UserConfig)),
7120
7121    d("dist -> retrieve (user info) receive_handle for MG",[]),
7122    MgRH = user_info(MgMid, receive_handle),
7123
7124    d("dist -> retrieve (user info) receive_handle for MGC",[]),
7125    MgcRH = user_info(MgcMid, receive_handle),
7126
7127    d("dist -> start transport",[]),
7128    {ok, MgPid, MgSH} =
7129	?VERIFY({ok, _, _}, UserMod:start_transport(MgRH, MgcRH)),
7130    PrelMgCH = #megaco_conn_handle{local_mid = MgMid,
7131				   remote_mid = preliminary_mid},
7132    MgCH  = #megaco_conn_handle{local_mid = MgMid,
7133				remote_mid = MgcMid},
7134    MgcCH = #megaco_conn_handle{local_mid = MgcMid,
7135				remote_mid = MgMid},
7136
7137    d("dist -> (MG) connect",[]),
7138    ?SEND(megaco:connect(MgRH, PrelMid, MgSH, MgPid)), % Mg prel
7139
7140    d("dist -> (MG) await connect",[]),
7141    ?USER({connect, PrelMgCH, _V, []}, ok),
7142    ?RECEIVE([{res, _, {ok, PrelMgCH}}]),
7143
7144    d("dist -> (MG) send service change request",[]),
7145    Req = service_change_request(),
7146    ?SEND(megaco:call(PrelMgCH, [Req], [])),
7147
7148    d("dist -> (MGC) await auto-connect",[]),
7149    ?USER({connect, MgcCH, _V, []}, ok), % Mgc auto
7150
7151
7152    Rep = service_change_reply(MgcMid),
7153    d("dist -> (MGC) "
7154      "await service change request and send reply when received",[]),
7155    ?USER({request, MgcCH, _V, [[Req]]}, {discard_ack, [Rep]}),
7156
7157    d("dist -> (MG) await connect",[]),
7158    ?USER({connect, MgCH, _V, []}, ok), % Mg confirm
7159
7160    d("dist -> (MG) await service change reply",[]),
7161    ?RECEIVE([{res, _, {1, {ok, [Rep]}}}]),
7162
7163    %% Dist
7164    d("dist -> start megaco on ~p", [Dist]),
7165    ?VERIFY(ok,	rpc:call(Dist, megaco, start, [])),
7166
7167    d("dist -> start megaco user on ~p", [Dist]),
7168    ?VERIFY(ok,	rpc:call(Dist, megaco, start_user, [MgcMid, UserConfig])),
7169
7170    d("dist -> (MG) connect to MGC", []),
7171    MgcPid = self(),
7172    MgcSH  = {element(2, MgSH), element(1, MgSH)},
7173    ?SEND(rpc:call(Dist, megaco, connect, [MgcRH, MgMid, MgcSH, MgcPid])), % Mgc dist
7174
7175    d("dist -> (MGC) await auto-connect (from MG on ~p)", [Dist]),
7176    ?USER({connect, MgcCH, _V, []}, ok), % Mgc dist auto
7177    ?RECEIVE([{res, _, {ok, MgcCH}}]),
7178
7179    d("dist -> (~p:MG) send service change request",[Dist]),
7180    ?SEND(rpc:call(Dist, megaco, call, [MgcCH, [Req], []])),
7181
7182    d("dist -> (MG????????) "
7183      "await service change request and send reply when received",[]),
7184    ?USER({request, MgCH, _V, [[Req]]}, {discard_ack, [Rep]}),
7185    ?RECEIVE([{res, _, {1, {ok, [Rep]}}}]),
7186
7187    d("dist -> retreive some info",[]),
7188    connections([MgCH, MgcCH]),
7189    ?VERIFY([MgCH], megaco:user_info(MgMid, connections)),
7190    ?VERIFY([MgcCH], megaco:user_info(MgcMid, connections)),
7191
7192    ?VERIFY([MgcCH], rpc:call(Dist, megaco, system_info, [connections])),
7193    ?VERIFY([], rpc:call(Dist, megaco, user_info, [MgMid, connections])),
7194    ?VERIFY([MgcCH], rpc:call(Dist, megaco, user_info, [MgcMid, connections])),
7195
7196    %% Shutdown
7197
7198    d("dist -> close down the shop...",[]),
7199    Reason = shutdown,
7200    ?SEND(megaco:disconnect(MgCH, Reason)),
7201    ?USER({disconnect, MgCH, _V, [{user_disconnect, Reason}]}, ok),
7202    ?RECEIVE([{res, _, ok}]),
7203    ?VERIFY(ok,	megaco:stop_user(MgMid)),
7204
7205    ?SEND(megaco:disconnect(MgcCH, Reason)),
7206    ?USER({disconnect, MgcCH, _V, [{user_disconnect, Reason}]}, ok),
7207    ?USER({disconnect, MgcCH, _V, [{user_disconnect, Reason}]}, ok),
7208    ?RECEIVE([{res, _, ok}]),
7209    ?VERIFY(ok,	megaco:stop_user(MgcMid)),
7210
7211    ?VERIFY(ok, application:stop(megaco)),
7212    ?RECEIVE([]),
7213
7214    d("dist -> stop proxy",[]),
7215    ?USER_MOD:stop_proxy(),
7216
7217    d("dist -> done", []),
7218    ok.
7219
7220
7221%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7222
7223otp_4359(suite) ->
7224    [];
7225otp_4359(Config) when is_list(Config) ->
7226    ?ACQUIRE_NODES(1, Config),
7227    Mid = {deviceName, "dummy_mid"},
7228
7229    io:format("otp_4359 -> start megaco application~n", []),
7230    ?VERIFY(ok, application:start(megaco)),
7231
7232    %% megaco:enable_trace(max, io),
7233    io:format("otp_4359 -> start and configure megaco user~n", []),
7234    ?VERIFY(ok,	megaco:start_user(Mid, [{send_mod,      ?MODULE},
7235					{request_timer, infinity},
7236					{reply_timer,   infinity}])),
7237
7238    io:format("otp_4359 -> update user info: user_mod -> ~p~n", [?MODULE]),
7239    ?VERIFY(ok, megaco:update_user_info(Mid, user_mod,  ?MODULE)),
7240    io:format("otp_4359 -> update user info: user_args -> ~p~n", [self()]),
7241    ?VERIFY(ok, megaco:update_user_info(Mid, user_args, [self()])),
7242    io:format("otp_4359 -> retreive receive_handle~n", []),
7243    RH0 = user_info(Mid, receive_handle),
7244    io:format("otp_4359 -> RH0: ~p~n", [RH0]),
7245    RH1 = RH0#megaco_receive_handle{send_mod        = ?MODULE,
7246				    encoding_mod    = megaco_compact_text_encoder,
7247				    encoding_config = []},
7248
7249    %% First an erroneous transaction (missing the transaction id number)
7250    %% then an valid transaction.
7251    M = "!/1 ml2 "
7252	"T={C=${A=${M{O {MO=SR,RG=OFF,RV=OFF}}}}}"
7253	"T=1{C=${A=${M{O {MO=SR,RG=OFF,RV=OFF}}}}}",
7254
7255    %% Simulate incomming message
7256    %% Will result in an (auto) connect first
7257    io:format("otp_4359 -> simulate receive message~n", []),
7258    megaco:receive_message(RH1, self(), self(), list_to_binary(M)),
7259    io:format("otp_4359 -> await actions~n", []),
7260    Actions = otp_4359_await_actions([{handle_connect, ignore},
7261				      {send_message, ?megaco_bad_request},
7262				      {handle_trans_request, ignore},
7263				      {send_message, ?megaco_not_implemented}]),
7264    io:format("otp_4359 -> analyze actions~n", []),
7265    otp_4359_analyze_result(RH1, Actions),
7266
7267    Conns = megaco:system_info(connections),
7268    io:format("otp_4359 -> connections~n~p~n", [Conns]),
7269    OKs   = lists:duplicate(length(Conns),ok),
7270    io:format("otp_4359 -> verify (all) connection disconnect~n", []),
7271    ?VERIFY(OKs, [megaco:disconnect(CH, test_complete) || CH <- Conns]),
7272    io:format("otp_4359 -> stop user (~p)~n", [Mid]),
7273    stop_user(Mid),
7274    io:format("otp_4359 -> stop megaco application~n", []),
7275    ?VERIFY(ok, application:stop(megaco)),
7276    io:format("otp_4359 -> make sure we have nothing in the message queue~n", []),
7277    ?RECEIVE([]),
7278    io:format("otp_4359 -> done~n", []),
7279    ok.
7280
7281
7282otp_4359_await_actions(Exp) ->
7283    otp_4359_await_actions(Exp, []).
7284
7285otp_4359_await_actions([], Rep) ->
7286    lists:reverse(Rep);
7287otp_4359_await_actions([{M,I}|R] = _All, Rep) ->
7288    receive
7289	{M, Info} ->
7290	    io:format("otp_4359 -> received expected event [~w]~n", [M]),
7291	    otp_4359_await_actions(R, [{M, I, Info}|Rep])
7292%% 	Else ->
7293%% 	    exit({received_unexpected_message, M, Else})
7294%% 	    %% io:format("received unexpected: ~p~n", [Else]),
7295%% 	    %% otp_4359_await_actions(All, Rep)
7296    after 10000 ->
7297	    exit({timeout,megaco_test_lib:flush()} )
7298    end.
7299
7300otp_4359_analyze_result(_RH, []) ->
7301    ok;
7302otp_4359_analyze_result(RH,
7303			[{send_message, ExpErrorCode, EncodedMessage}|L]) ->
7304    io:format("otp_4359_analyze_result -> send_message: ", []),
7305    otp_4359_analyze_encoded_message(RH, ExpErrorCode, EncodedMessage),
7306    otp_4359_analyze_result(RH,L);
7307otp_4359_analyze_result(RH, [{M,ignore,_}|T]) ->
7308    io:format("otp_4359_analyze_result -> ignoring ~p~n", [M]),
7309    otp_4359_analyze_result(RH,T).
7310
7311otp_4359_analyze_encoded_message(RH, ExpErrorCode, M)
7312  when is_record(RH, megaco_receive_handle) andalso is_binary(M) ->
7313    #megaco_receive_handle{encoding_mod    = Mod,
7314			   encoding_config = Conf} = RH,
7315    case (catch Mod:decode_message(Conf, M)) of
7316	{ok, #'MegacoMessage'{mess = #'Message'{messageBody = Body}}} ->
7317	    case Body of
7318		{transactions, [{transactionReply,Reply}]} ->
7319		    case Reply of
7320			#'TransactionReply'{transactionResult = Result} ->
7321			    case Result of
7322				{transactionError,ED} when is_record(ED, 'ErrorDescriptor') ->
7323				    case ED#'ErrorDescriptor'.errorCode of
7324					ExpErrorCode ->
7325					    io:format("error code ~p ok~n", [ExpErrorCode]),
7326					    ok;
7327					Code ->
7328					    io:format("error code ~p erroneous~n", [Code]),
7329					    exit({unexpected_error_code, ExpErrorCode, Code})
7330				    end;
7331				_ ->
7332				    io:format("unexpected trans result~n", []),
7333				    exit({unexpected_trans_result, Result})
7334			    end;
7335			_ ->
7336			    io:format("unexpected trans reply~n", []),
7337			    exit({unexpected_trans_reply, Reply})
7338		    end;
7339		_ ->
7340		    io:format("unexpected body~n", []),
7341		    exit({unexpected_body, Body})
7342	    end;
7343
7344	Else ->
7345	    io:format("unexpected decode result~n", []),
7346	    exit({unexpected_decode_result, Else})
7347    end.
7348
7349
7350
7351%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7352
7353otp_4836(suite) ->
7354    [];
7355otp_4836(Config) when is_list(Config) ->
7356    Pre = fun() ->
7357                  MgcNode = make_node_name(mgc),
7358                  MgNode  = make_node_name(mg),
7359                  d("start nodes: "
7360                    "~n      MgcNode: ~p"
7361                    "~n      MgNode:  ~p",
7362                    [MgcNode, MgNode]),
7363                  Nodes = [MgcNode, MgNode],
7364                  ok = ?START_NODES(Nodes, true),
7365                  Nodes
7366          end,
7367    Case = fun do_otp_4836/1,
7368    Post = fun(Nodes) ->
7369                   d("stop nodes"),
7370                   ?STOP_NODES(lists:reverse(Nodes))
7371           end,
7372    try_tc(otp_4836, Pre, Case, Post).
7373
7374do_otp_4836([MgcNode, MgNode]) ->
7375    d("start the MGC simulator (generator)"),
7376    {ok, Mgc} = megaco_test_tcp_generator:start_link("MGC", MgcNode),
7377
7378    d("create the MGC event sequence"),
7379    MgcEvSeq = otp_4836_mgc_event_sequence(text, tcp),
7380
7381    d("start the MGC simulation"),
7382    {ok, MgcId} = megaco_test_tcp_generator:exec(Mgc, MgcEvSeq),
7383
7384    i("await MGC ready announcement"),
7385    receive
7386        announce_mgc ->
7387            i("received MGC ready announcement"),
7388            ok
7389    end,
7390
7391    i("[MG] start"),
7392    MgMid = {deviceName, "mg"},
7393    ReqTmr = #megaco_incr_timer{wait_for    = 3000,
7394                                factor      = 1,
7395                                incr        = 0,
7396                                max_retries = 3},
7397    %% 5000,  %% Does not matter since we will not use this anyway...
7398    LongReqTmr = #megaco_incr_timer{wait_for    = 3000,
7399                                    factor      = 1,
7400                                    incr        = 0,
7401                                    max_retries = 3},
7402    PendingTmr = 10000,
7403    ReplyTmr = 16000,
7404    MgConfig = [{request_timer,      ReqTmr},
7405                {long_request_timer, LongReqTmr},
7406                {pending_timer,      PendingTmr},
7407                {reply_timer,        ReplyTmr}],
7408    {ok, Mg} = ?MG_START(MgNode, MgMid, text, tcp, MgConfig, ?MG_VERBOSITY),
7409
7410    i("[MG] connect to the MGC (service change)"),
7411    ServChRes = ?MG_SERV_CHANGE(Mg),
7412    d("service change result: ~p", [ServChRes]),
7413
7414    d("[MG] send the notify"),
7415    {ok, Reply} = (catch ?MG_NOTIF_RAR(Mg)),
7416    {1, {ok, [AR]}} = Reply,
7417    d("[MG] ActionReply: ~p", [AR]),
7418
7419    d("await the generator reply"),
7420    await_completion([MgcId]),
7421
7422    %% Tell MG to stop
7423    i("[MG] stop"),
7424    ?MG_STOP(Mg),
7425
7426    %% Tell Mgc to stop
7427    i("[MGC] stop generator"),
7428    megaco_test_tcp_generator:stop(Mgc),
7429
7430    i("done", []),
7431    ok.
7432
7433
7434-ifdef(megaco_hipe_special).
7435-define(otp_4836_mgc_decode_msg_fun(Mod, Conf),
7436	{?MODULE, decode_msg, [Mod, Conf]}).
7437-define(otp_4836_mgc_encode_msg_fun(Mod, Conf),
7438	{?MODULE, encode_msg, [Mod, Conf]}).
7439-define(otp_4836_mgc_verify_service_change_req_msg_fun(),
7440	{?MODULE, otp_4836_mgc_verify_service_change_req_msg, []}).
7441-define(otp_4836_mgc_verify_notify_req_msg_fun(),
7442	{?MODULE, otp_4836_mgc_verify_notify_req_msg, []}).
7443-else.
7444-define(otp_4836_mgc_decode_msg_fun(Mod, Conf),
7445	otp_4836_mgc_decode_msg_fun(Mod, Conf)).
7446-define(otp_4836_mgc_encode_msg_fun(Mod, Conf),
7447	otp_4836_mgc_encode_msg_fun(Mod, Conf)).
7448-define(otp_4836_mgc_verify_service_change_req_msg_fun(),
7449	otp_4836_mgc_verify_service_change_req_msg_fun()).
7450-define(otp_4836_mgc_verify_notify_req_msg_fun(),
7451	otp_4836_mgc_verify_notify_req_msg_fun()).
7452-endif.
7453
7454otp_4836_mgc_event_sequence(text, tcp) ->
7455    CTRL = self(),
7456    DecodeFun = ?otp_4836_mgc_decode_msg_fun(megaco_pretty_text_encoder, []),
7457    EncodeFun = ?otp_4836_mgc_encode_msg_fun(megaco_pretty_text_encoder, []),
7458    Mid = {deviceName,"ctrl"},
7459    ServiceChangeReply = otp_4836_service_change_reply_msg(Mid, 1, 0),
7460    TermId = #megaco_term_id{id = ["00000000","00000000","01101101"]},
7461    NotifyReply = otp_4836_notify_reply_msg(Mid, 2, 0, TermId),
7462    Pending = otp_4836_pending_msg(Mid,2),
7463    ServiceChangeVerifyFun = ?otp_4836_mgc_verify_service_change_req_msg_fun(),
7464    NotifyReqVerifyFun     = ?otp_4836_mgc_verify_notify_req_msg_fun(),
7465    MgcEvSeq = [{debug,  true},
7466		{decode, DecodeFun},
7467		{encode, EncodeFun},
7468		{listen, 2944},
7469
7470                %% ANNOUNCE READY
7471                {trigger, "announce ready", fun() -> CTRL ! announce_mgc end},
7472
7473		{expect_accept, any},
7474		{expect_receive, "service-change-request", {ServiceChangeVerifyFun, 10000}},
7475		{send, "service-change-reply", ServiceChangeReply},
7476		{expect_receive, "notify-request", {NotifyReqVerifyFun, 10000}},
7477		{send, "pending 1", Pending},
7478		{sleep, 100},
7479		{send, "pending 2", Pending},
7480		{sleep, 500},
7481  		{send, "notify-reply", NotifyReply},
7482		{sleep, 2000}
7483	       ],
7484    MgcEvSeq.
7485
7486otp_4836_service_change_reply_msg(Mid, TransId, Cid) ->
7487    SCRP  = #'ServiceChangeResParm'{serviceChangeMgcId = Mid},
7488    SCRPs = {serviceChangeResParms,SCRP},
7489    Root  = #megaco_term_id{id = ["root"]},
7490    SCR   = #'ServiceChangeReply'{terminationID       = [Root],
7491				  serviceChangeResult = SCRPs},
7492    CR    = {serviceChangeReply, SCR},
7493    otp_4836_msg(Mid, TransId, CR, Cid).
7494
7495otp_4836_notify_reply_msg(Mid, TransId, Cid, TermId) ->
7496    NR  = #'NotifyReply'{terminationID = [TermId]},
7497    CR  = {notifyReply, NR},
7498    otp_4836_msg(Mid, TransId, CR, Cid).
7499
7500otp_4836_msg(Mid, TransId, CR, Cid) ->
7501    AR  = #'ActionReply'{contextId    = Cid,
7502			 commandReply = [CR]},
7503    ARs  = {actionReplies, [AR]},
7504    TR   = #'TransactionReply'{transactionId     = TransId,
7505			       transactionResult = ARs},
7506    Body = {transactions, [{transactionReply, TR}]},
7507    Mess = #'Message'{version     = 1,
7508		      mId         = Mid,
7509		      messageBody = Body},
7510    #'MegacoMessage'{mess = Mess}.
7511
7512
7513otp_4836_pending_msg(Mid, TransId) ->
7514    TP   = #'TransactionPending'{transactionId = TransId},
7515    Body = {transactions, [{transactionPending, TP}]},
7516    Mess = #'Message'{version     = 1,
7517		      mId         = Mid,
7518		      messageBody = Body},
7519    #'MegacoMessage'{mess = Mess}.
7520
7521
7522-ifndef(megaco_hipe_special).
7523otp_4836_mgc_encode_msg_fun(Mod, Conf) ->
7524    fun(M) ->
7525	    encode_msg(M, Mod, Conf)
7526    end.
7527-endif.
7528%% otp_4836_mgc_encode_msg_fun(Mod, Conf, Ver) ->
7529%%     fun(M) ->
7530%% 	    encode_msg(M, Mod, Conf, Ver)
7531%%     end.
7532
7533-ifndef(megaco_hipe_special).
7534otp_4836_mgc_decode_msg_fun(Mod, Conf) ->
7535    fun(M) ->
7536	    decode_msg(M, Mod, Conf)
7537    end.
7538-endif.
7539%% otp_4836_mgc_decode_msg_fun(Mod, Conf, Ver) ->
7540%%     fun(M) ->
7541%% 	    decode_msg(M, Mod, Conf, Ver)
7542%%     end.
7543
7544%% otp_4836_verify_msg_fun() ->
7545%%     fun(M) ->
7546%% 	    {ok, M}
7547%%     end.
7548
7549-ifndef(megaco_hipe_special).
7550otp_4836_mgc_verify_service_change_req_msg_fun() ->
7551    fun(M) ->
7552	    otp_4836_mgc_verify_service_change_req_msg(M)
7553    end.
7554-endif.
7555
7556otp_4836_mgc_verify_service_change_req_msg(
7557  #'MegacoMessage'{mess = Mess} = M) ->
7558    #'Message'{version     = _V,
7559	       mId         = _Mid,
7560	       messageBody = Body} = Mess,
7561    {transactions, [Trans]} = Body,
7562    {transactionRequest, TR} = Trans,
7563    #'TransactionRequest'{transactionId = _Tid,
7564			  actions = [AR]} = TR,
7565    #'ActionRequest'{contextId = _Cid,
7566		     contextRequest = _CtxReq,
7567		     contextAttrAuditReq = _CtxAar,
7568		     commandRequests = [CR]} = AR,
7569    #'CommandRequest'{command = Cmd,
7570		      optional = _Opt,
7571		      wildcardReturn = _WR} = CR,
7572    {serviceChangeReq, SCR} = Cmd,
7573	    #'ServiceChangeRequest'{terminationID = _TermID,
7574				    serviceChangeParms = SCP} = SCR,
7575    #'ServiceChangeParm'{serviceChangeMethod = restart,
7576			 serviceChangeReason = [[$9,$0,$1|_]]} = SCP,
7577    {ok, M};
7578otp_4836_mgc_verify_service_change_req_msg(M) ->
7579    {error, {invalid_message, M}}.
7580
7581-ifndef(megaco_hipe_special).
7582otp_4836_mgc_verify_notify_req_msg_fun() ->
7583    fun(M) ->
7584	    otp_4836_mgc_verify_notify_req_msg(M)
7585    end.
7586-endif.
7587
7588otp_4836_mgc_verify_notify_req_msg(#'MegacoMessage'{mess = Mess} = M) ->
7589    #'Message'{messageBody = Body} = Mess,
7590    {transactions, [Trans]} = Body,
7591    {transactionRequest, TR} = Trans,
7592    #'TransactionRequest'{actions = [AR]} = TR,
7593    #'ActionRequest'{commandRequests = [CR1,CR2]} = AR,
7594    #'CommandRequest'{command = Cmd1} = CR1,
7595    {notifyReq, NR1} = Cmd1,
7596    #'NotifyRequest'{observedEventsDescriptor = OED1} = NR1,
7597    #'ObservedEventsDescriptor'{observedEventLst = [OE1]} = OED1,
7598    #'ObservedEvent'{eventName = "al/of"} = OE1,
7599    #'CommandRequest'{command = Cmd2} = CR2,
7600    {notifyReq, NR2} = Cmd2,
7601    #'NotifyRequest'{observedEventsDescriptor = OED2} = NR2,
7602    #'ObservedEventsDescriptor'{observedEventLst = [OE2]} = OED2,
7603    #'ObservedEvent'{eventName = "al/of"} = OE2,
7604    {ok, M};
7605otp_4836_mgc_verify_notify_req_msg(M) ->
7606    {error, {invalid_message, M}}.
7607
7608
7609
7610%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7611
7612otp_5805(suite) ->
7613    [];
7614otp_5805(Config) when is_list(Config) ->
7615    Pre = fun() ->
7616                  MgcNode = make_node_name(mgc),
7617                  MgNode  = make_node_name(mg),
7618                  d("start nodes: "
7619                    "~n   MgcNode: ~p"
7620                    "~n   MgNode:  ~p",
7621                    [MgcNode, MgNode]),
7622                  Nodes = [MgcNode, MgNode],
7623                  ok = ?START_NODES(Nodes, true),
7624                  Nodes
7625          end,
7626    Case = fun do_otp_5805/1,
7627    Post = fun(Nodes) ->
7628                   d("stop nodes"),
7629                   ?STOP_NODES(lists:reverse(Nodes))
7630           end,
7631    try_tc(otp_5805, Pre, Case, Post).
7632
7633do_otp_5805([MgcNode, MgNode]) ->
7634    d("[MGC] start the simulator "),
7635    {ok, Mgc} = megaco_test_megaco_generator:start_link("MGC", MgcNode),
7636
7637    d("[MGC] create the event sequence"),
7638    MgcEvSeq = otp_5805_mgc_event_sequence(text, tcp),
7639
7640    i("wait some time before starting the MGC simulation"),
7641    sleep(1000),
7642
7643    d("[MGC] start the simulation"),
7644    {ok, MgcId} =
7645	megaco_test_megaco_generator:exec(Mgc, MgcEvSeq, timer:minutes(1)),
7646
7647    %% i("wait some time before starting the MG simulator"),
7648    %% sleep(1000),
7649
7650    i("await MGC ready announcement"),
7651    receive
7652        announce_mgc ->
7653            i("received MGC ready announcement"),
7654            ok
7655    end,
7656
7657    d("start the MG simulator (generator)"),
7658    {ok, Mg} = megaco_test_tcp_generator:start_link("MG", MgNode),
7659
7660    d("create the MG event sequence"),
7661    MgEvSeq = otp_5805_mg_event_sequence(text, tcp),
7662
7663    d("start the MG simulation"),
7664    {ok, MgId} =
7665	megaco_test_tcp_generator:exec(Mg, MgEvSeq, timer:minutes(1)),
7666
7667    d("await the generator reply(s)"),
7668    await_completion([MgcId, MgId]),
7669
7670    %% Tell Mgc to stop
7671    i("[MGC] stop generator"),
7672    megaco_test_megaco_generator:stop(Mgc),
7673
7674    %% Tell Mg to stop
7675    i("[MG] stop generator"),
7676    megaco_test_tcp_generator:stop(Mg),
7677
7678    i("done", []),
7679    ok.
7680
7681
7682-ifdef(megaco_hipe_special).
7683-define(otp_5805_mg_decode_msg_fun(Mod, Conf),
7684	{?MODULE, decode_msg, [Mod, Conf]}).
7685-define(otp_5805_mg_encode_msg_fun(Mod, Conf),
7686	{?MODULE, encode_msg, [Mod, Conf]}).
7687-define(otp_5805_mg_verify_service_change_rep_msg_fun(),
7688	{?MODULE, otp_5805_mg_verify_service_change_rep_msg, []}).
7689-define(otp_5805_mg_verify_error_descriptor_msg_fun(),
7690	{?MODULE, otp_5805_mg_verify_error_descriptor_msg, []}).
7691-else.
7692-define(otp_5805_mg_decode_msg_fun(Mod, Conf),
7693	otp_5805_mg_decode_msg_fun(Mod, Conf)).
7694-define(otp_5805_mg_encode_msg_fun(Mod, Conf),
7695	otp_5805_mg_encode_msg_fun(Mod, Conf)).
7696-define(otp_5805_mg_verify_service_change_rep_msg_fun(),
7697	otp_5805_mg_verify_service_change_rep_msg_fun()).
7698-define(otp_5805_mg_verify_error_descriptor_msg_fun(),
7699	otp_5805_mg_verify_error_descriptor_msg_fun()).
7700-endif.
7701
7702otp_5805_mg_event_sequence(text, tcp) ->
7703    DecodeFun = ?otp_5805_mg_decode_msg_fun(megaco_pretty_text_encoder, []),
7704    EncodeFun = ?otp_5805_mg_encode_msg_fun(megaco_pretty_text_encoder, []),
7705    Mid = {deviceName,"mg"},
7706    ServiceChangeReq = otp_5805_mg_service_change_request_msg(Mid, 1, 0),
7707    NotifyReqNNV = otp_5805_mg_notify_request_msg("1"),
7708    NotifyReqUV = otp_5805_mg_notify_request_msg("4"),
7709    ServiceChangeReplyVerifyFun =
7710	?otp_5805_mg_verify_service_change_rep_msg_fun(),
7711    EDVerify =
7712	?otp_5805_mg_verify_error_descriptor_msg_fun(),
7713    MgEvSeq = [{debug,  true},
7714	       {decode, DecodeFun},
7715	       {encode, EncodeFun},
7716	       {connect, 2944},
7717
7718	       {send, "service-change-request", ServiceChangeReq},
7719	       {expect_receive, "service-change-reply", {ServiceChangeReplyVerifyFun, 5000}},
7720	       {sleep, 1000},
7721	       {send, "notify request (not negotiated version)", NotifyReqNNV},
7722	       {expect_receive, "error-descriptor", EDVerify},
7723	       {sleep, 1000},
7724 	       {send, "notify request (unsupported version)", NotifyReqUV},
7725	       {expect_receive, "error-descriptor", EDVerify},
7726
7727	       {expect_nothing, 4000},
7728	       disconnect
7729	      ],
7730    MgEvSeq.
7731
7732-ifndef(megaco_hipe_special).
7733otp_5805_mg_encode_msg_fun(Mod, Conf) ->
7734    fun(M) ->
7735            encode_msg(M, Mod, Conf)
7736    end.
7737-endif.
7738
7739-ifndef(megaco_hipe_special).
7740otp_5805_mg_decode_msg_fun(Mod, Conf) ->
7741    fun(M) ->
7742            decode_msg(M, Mod, Conf)
7743    end.
7744-endif.
7745
7746-ifndef(megaco_hipe_special).
7747otp_5805_mg_verify_service_change_rep_msg_fun() ->
7748    fun(M) ->
7749	    otp_5805_mg_verify_service_change_rep_msg(M)
7750    end.
7751-endif.
7752
7753otp_5805_mg_verify_service_change_rep_msg(#'MegacoMessage'{mess = Mess} = M) ->
7754    case Mess of
7755	#'Message'{version     = 1,
7756		   mId         = _MgMid,
7757		   messageBody = Body} ->
7758	    case Body of
7759		{transactions, [Trans]} ->
7760		    case Trans of
7761			{transactionReply, TR} ->
7762			    case TR of
7763				#'TransactionReply'{transactionId = _Tid,
7764						    immAckRequired = asn1_NOVALUE,
7765						    transactionResult = Res} ->
7766				    case Res of
7767					{actionReplies, [AR]} ->
7768					    case AR of
7769						#'ActionReply'{contextId = _Cid,
7770							       errorDescriptor = asn1_NOVALUE,
7771							       contextReply    = _CtxReq,
7772							       commandReply    = [CR]} ->
7773						    case CR of
7774							{serviceChangeReply, SCR} ->
7775							    case SCR of
7776								#'ServiceChangeReply'{
7777								       terminationID       = _TermID,
7778								       serviceChangeResult = SCRes} ->
7779								    case SCRes of
7780									{serviceChangeResParms, SCRP} ->
7781									    case SCRP of
7782										#'ServiceChangeResParm'{
7783											serviceChangeMgcId   = _MgcMid,
7784											serviceChangeVersion = 2} ->
7785										    {ok, M};
7786										_ ->
7787										    {error, {invalid_scrp, SCRP}}
7788									    end;
7789									_ ->
7790									    {error, {invalid_scres, SCRes}}
7791								    end;
7792								_ ->
7793								    {error, {invalid_scr, SCR}}
7794							    end;
7795							_ ->
7796							    {error, {invalid_cr, CR}}
7797						    end;
7798						_ ->
7799						    {error, {invalid_ar, AR}}
7800					    end;
7801					_ ->
7802					    {error, {invalid_tres, Res}}
7803				    end;
7804				_ ->
7805				    {error, {invalid_tr, TR}}
7806			    end;
7807			_ ->
7808			    {error, {invalid_trans, Trans}}
7809		    end;
7810		_ ->
7811		    {error, {invalid_body, Body}}
7812	    end;
7813	_ ->
7814	    {error, {invalid_mess, Mess}}
7815    end;
7816otp_5805_mg_verify_service_change_rep_msg(M) ->
7817    {error, {invalid_message, M}}.
7818
7819
7820-ifndef(megaco_hipe_special).
7821otp_5805_mg_verify_error_descriptor_msg_fun() ->
7822    fun(M) ->
7823	    otp_5805_mg_verify_error_descriptor_msg(M)
7824    end.
7825-endif.
7826
7827otp_5805_mg_verify_error_descriptor_msg(#'MegacoMessage'{mess = Mess} = M) ->
7828    case Mess of
7829	#'Message'{version     = 2,
7830		   mId         = _MgMid,
7831		   messageBody = Body} ->
7832	    io:format("otp_5805_mg_verify_error_descriptor_msg_fun -> ok"
7833		      "~n   Body:  ~p"
7834		      "~n", [Body]),
7835	    case Body of
7836		{messageError, ED} ->
7837		    case ED of
7838			#'ErrorDescriptor'{
7839			      errorCode = ?megaco_version_not_supported} ->
7840			    {ok, M};
7841			_ ->
7842			    {error, {invalid_ed, ED}}
7843		    end;
7844		_ ->
7845		    {error, {invalid_body, Body}}
7846	    end;
7847	_ ->
7848	    {error, {invalid_mess, Mess}}
7849    end;
7850otp_5805_mg_verify_error_descriptor_msg(M) ->
7851    {error, {invalid_message, M}}.
7852
7853otp_5805_mg_service_change_request_ar(_Mid, Cid) ->
7854    Prof  = cre_serviceChangeProf("resgw", 1),
7855    SCP   = cre_serviceChangeParm(restart, 2, ["901 mg col boot"], Prof),
7856    Root  = #megaco_term_id{id = ["root"]},
7857    SCR   = cre_serviceChangeReq([Root], SCP),
7858    CMD   = cre_command(SCR),
7859    CR    = cre_cmdReq(CMD),
7860    cre_actionReq(Cid, [CR]).
7861
7862otp_5805_mg_service_change_request_msg(Mid, TransId, Cid) ->
7863    AR    = otp_5805_mg_service_change_request_ar(Mid, Cid),
7864    TR    = cre_transReq(TransId, [AR]),
7865    Trans = cre_transaction(TR),
7866    Mess  = cre_message(1, Mid, cre_transactions([Trans])),
7867    cre_megacoMessage(Mess).
7868
7869%% otp_5805_mg_notify_request_ar(Rid, Tid, Cid) ->
7870%%     TT      = cre_timeNotation("19990729", "22000000"),
7871%%     Ev      = cre_obsEvent("al/of", TT),
7872%%     EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
7873%%     NR      = cre_notifyReq([Tid], EvsDesc),
7874%%     CMD     = cre_command(NR),
7875%%     CR      = cre_cmdReq(CMD),
7876%%     cre_actionReq(Cid, [CR]).
7877
7878otp_5805_mg_notify_request_msg(V) ->
7879    M =
7880"MEGACO/" ++ V ++ " mg
7881Transaction = 2 {
7882	Context = 1 {
7883		Notify = 00000000/00000000/01101101 {
7884			ObservedEvents = 1 {
7885				19990729T22000000:al/of
7886			}
7887		}
7888	}
7889}",
7890    list_to_binary(M).
7891
7892
7893%%
7894%% MGC generator stuff
7895%%
7896
7897-ifdef(megaco_hipe_special).
7898-define(otp_5805_mgc_verify_handle_connect_fun(),
7899        {?MODULE, otp_5805_mgc_verify_handle_connect, []}).
7900-define(otp_5805_mgc_verify_service_change_req_fun(Mid),
7901        {?MODULE, otp_5805_mgc_verify_service_change_req, [Mid]}).
7902-define(otp_5805_mgc_verify_handle_syntax_error_fun(),
7903        {?MODULE, otp_5805_mgc_verify_handle_syntax_error, []}).
7904-define(otp_5805_mgc_verify_handle_disconnect_fun(),
7905        {?MODULE, otp_5805_mgc_verify_handle_disconnect, []}).
7906-else.
7907-define(otp_5805_mgc_verify_handle_connect_fun(),
7908        fun otp_5805_mgc_verify_handle_connect/1).
7909-define(otp_5805_mgc_verify_service_change_req_fun(Mid),
7910        otp_5805_mgc_verify_service_change_req_fun(Mid)).
7911-define(otp_5805_mgc_verify_handle_syntax_error_fun(),
7912	fun otp_5805_mgc_verify_handle_syntax_error/1).
7913-define(otp_5805_mgc_verify_handle_disconnect_fun(),
7914	fun otp_5805_mgc_verify_handle_disconnect/1).
7915-endif.
7916
7917otp_5805_mgc_event_sequence(text, tcp) ->
7918    CTRL = self(),
7919    Mid = {deviceName,"ctrl"},
7920    RI = [
7921          {port,             2944},
7922          {encoding_module,  megaco_pretty_text_encoder},
7923          {encoding_config,  []},
7924          {transport_module, megaco_tcp}
7925         ],
7926    ConnectVerify          = ?otp_5805_mgc_verify_handle_connect_fun(),
7927    ServiceChangeReqVerify = ?otp_5805_mgc_verify_service_change_req_fun(Mid),
7928    SyntaxErrorVerify1     = ?otp_5805_mgc_verify_handle_syntax_error_fun(),
7929    SyntaxErrorVerify2     = ?otp_5805_mgc_verify_handle_syntax_error_fun(),
7930    DiscoVerify            = ?otp_5805_mgc_verify_handle_disconnect_fun(),
7931    EvSeq = [
7932             {debug, true},
7933	     {megaco_trace, disable},
7934	     {megaco_trace, max},
7935             megaco_start,
7936             {megaco_start_user, Mid, RI, []},
7937             start_transport,
7938             listen,
7939
7940             %% ANNOUNCE READY
7941             {trigger, fun() -> CTRL ! announce_mgc end},
7942
7943             {megaco_callback, handle_connect, ConnectVerify},
7944	     {megaco_conn_info, all},
7945             {megaco_callback, handle_trans_request_sc, ServiceChangeReqVerify},
7946	     {megaco_update_conn_info, protocol_version, 2},
7947             {megaco_callback, handle_syntax_error, SyntaxErrorVerify1},
7948             {megaco_callback, handle_syntax_error, SyntaxErrorVerify2},
7949             {megaco_callback, handle_disconnect, DiscoVerify},
7950             megaco_stop_user,
7951             megaco_stop
7952            ],
7953    EvSeq.
7954
7955otp_5805_mgc_verify_handle_connect({handle_connect, CH, 1}) ->
7956    io:format("otp_5805_mgc_verify_handle_connect -> ok"
7957	      "~n   CH:  ~p"
7958	      "~n", [CH]),
7959    {ok, CH, ok};
7960otp_5805_mgc_verify_handle_connect({handle_connect, CH, V}) ->
7961    io:format("otp_5805_mgc_verify_handle_connect -> unexpected version"
7962	      "~n   CH:  ~p"
7963	      "~n   V:   ~p"
7964	      "~n", [CH, V]),
7965    {error, {unexpected_version, V}, ok};
7966otp_5805_mgc_verify_handle_connect(Else) ->
7967    {error, Else, ok}.
7968
7969
7970-ifndef(megaco_hipe_special).
7971otp_5805_mgc_verify_service_change_req_fun(Mid) ->
7972    fun(Ev) ->
7973	    otp_5805_mgc_verify_service_change_req(Ev, Mid)
7974    end.
7975-endif.
7976
7977otp_5805_mgc_verify_service_change_req({handle_trans_request, _, V, [AR]},
7978				       Mid) ->
7979    io:format("otp_5805_mgc_verify_service_change_req -> ok so far"
7980	      "~n   V:   ~p"
7981	      "~n", [V]),
7982    case AR of
7983	#'ActionRequest'{commandRequests = [CR]} ->
7984	    case CR of
7985		#'CommandRequest'{command = Cmd} ->
7986		    case Cmd of
7987			{serviceChangeReq,
7988			 #'ServiceChangeRequest'{terminationID = [Tid],
7989						 serviceChangeParms = Parms}} ->
7990			    case Tid of
7991				#megaco_term_id{contains_wildcards = false,
7992						id = ["root"]} ->
7993				    case Parms of
7994					#'ServiceChangeParm'{
7995						 serviceChangeMethod = restart,
7996						 serviceChangeVersion = 2,
7997						 serviceChangeReason = [[$9,$0,$1|_]]} ->
7998					    Reply =
7999						{discard_ack,
8000						 [otp_5805_mgc_service_change_reply_ar(Mid, 1)]},
8001					    {ok, AR, Reply};
8002					_ ->
8003					    Err = {invalid_SCP, Parms},
8004					    ED = otp_5805_err_desc(Parms),
8005					    ErrReply =
8006						{discard_ack, ED},
8007					    {error, Err, ErrReply}
8008				    end;
8009				_ ->
8010				    Err = {invalid_termination_id, Tid},
8011				    ED = otp_5805_err_desc(Tid),
8012				    ErrReply = {discard_ack, ED},
8013				    {error, Err, ErrReply}
8014			    end;
8015			_ ->
8016			    Err = {invalid_command, Cmd},
8017			    ED = otp_5805_err_desc(Cmd),
8018			    ErrReply = {discard_ack, ED},
8019			    {error, Err, ErrReply}
8020		    end;
8021		_ ->
8022		    Err = {invalid_command_request, CR},
8023		    ED = otp_5805_err_desc(CR),
8024		    ErrReply = {discard_ack, ED},
8025		    {error, Err, ErrReply}
8026	    end;
8027	_ ->
8028	    Err = {invalid_action_request, AR},
8029	    ED = otp_5805_err_desc(AR),
8030	    ErrReply = {discard_ack, ED},
8031	    {error, Err, ErrReply}
8032    end;
8033otp_5805_mgc_verify_service_change_req(Else, _Mid) ->
8034    ED       = otp_5805_err_desc(Else),
8035    ErrReply = {discard_ack, ED},
8036    {error, Else, ErrReply}.
8037
8038otp_5805_mgc_verify_handle_syntax_error({handle_syntax_error, CH, _, ED})
8039  when is_record(ED, 'ErrorDescriptor') ->
8040    io:format("otp_5805_mgc_verify_handle_syntax_error -> ok so far"
8041	      "~n   CH: ~p"
8042	      "~n   ED:  ~p"
8043	      "~n", [CH, ED]),
8044    case ED of
8045	#'ErrorDescriptor'{errorCode = ?megaco_version_not_supported} ->
8046	    {ok, CH, reply};
8047	#'ErrorDescriptor'{errorCode = Code} ->
8048	    {error, {invalid_errorCode, Code}, ok}
8049    end;
8050otp_5805_mgc_verify_handle_syntax_error(Else) ->
8051    io:format("otp_5805_mgc_verify_handle_syntax_error -> unknown"
8052	      "~n   Else: ~p~n", [Else]),
8053    {error, Else, ok}.
8054
8055otp_5805_mgc_verify_handle_disconnect({handle_disconnect, CH, V, _R}) ->
8056    io:format("otp_5805_mgc_verify_handle_disconnect -> ok"
8057	      "~n   CH: ~p"
8058	      "~n   V:  ~p"
8059	      "~n   _R:  ~p"
8060	      "~n", [CH, V, _R]),
8061    {ok, CH, ok};
8062otp_5805_mgc_verify_handle_disconnect(Else) ->
8063    io:format("otp_5805_mgc_verify_handle_disconnect -> unknown"
8064	      "~n   Else: ~p~n", [Else]),
8065    {error, Else, ok}.
8066
8067otp_5805_mgc_service_change_reply_ar(Mid, Cid) ->
8068    SCRP  = cre_serviceChangeResParm(Mid, 2),
8069    SCRes = cre_serviceChangeResult(SCRP),
8070    Root  = #megaco_term_id{id = ["root"]},
8071    SCR   = cre_serviceChangeReply([Root], SCRes),
8072    CR    = cre_cmdReply(SCR),
8073    cre_actionReply(Cid, [CR]).
8074
8075%% otp_5805_mgc_notify_reply_ar(Cid, TermId) ->
8076%%     NR    = cre_notifyReply([TermId]),
8077%%     CR    = cre_cmdReply(NR),
8078%%     cre_actionReply(Cid, [CR]).
8079
8080
8081otp_5805_err_desc(T) ->
8082    EC = ?megaco_internal_gateway_error,
8083    ET = lists:flatten(io_lib:format("~w",[T])),
8084    #'ErrorDescriptor'{errorCode = EC, errorText = ET}.
8085
8086
8087%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8088
8089otp_5881(suite) ->
8090    [];
8091otp_5881(Config) when is_list(Config) ->
8092    ?SKIP("deprecated by OTP-5887"),
8093    put(verbosity, ?TEST_VERBOSITY),
8094    put(sname,     "TEST"),
8095    put(tc,        otp_5881),
8096    i("starting"),
8097
8098    MgcNode = make_node_name(mgc),
8099    MgNode  = make_node_name(mg),
8100    d("start nodes: "
8101      "~n   MgcNode: ~p"
8102      "~n   MgNode:  ~p",
8103      [MgcNode, MgNode]),
8104    Nodes = [MgcNode, MgNode],
8105    ok = ?START_NODES(Nodes, true),
8106
8107    d("start the MGC simulator (generator)"),
8108    {ok, Mgc} = megaco_test_tcp_generator:start_link("MGC", MgcNode),
8109
8110    d("create the MGC event sequence"),
8111    MgcEvSeq = otp_5881_mgc_event_sequence(text, tcp),
8112
8113    d("start the MGC simulation"),
8114    {ok, MgcId} = megaco_test_tcp_generator:exec(Mgc, MgcEvSeq),
8115
8116    i("await MGC ready announcement"),
8117    receive
8118        announce_mgc ->
8119            i("received MGC ready announcement"),
8120            ok
8121    end,
8122
8123    i("[MG] start"),
8124    MgMid = {deviceName, "mg"},
8125    ReqTmr = #megaco_incr_timer{wait_for    = 3000,
8126                                factor      = 1,
8127                                incr        = 0,
8128                                max_retries = 3},
8129    %% 5000,  %% Does not matter since we will not use this anyway...
8130    LongReqTmr = #megaco_incr_timer{wait_for    = 3000,
8131                                    factor      = 1,
8132                                    incr        = 0,
8133                                    max_retries = 3},
8134    PendingTmr = 10000,
8135    ReplyTmr = 16000,
8136    MgConfig = [{request_timer,      ReqTmr},
8137                {long_request_timer, LongReqTmr},
8138                {pending_timer,      PendingTmr},
8139                {reply_timer,        ReplyTmr}],
8140    {ok, Mg} = ?MG_START(MgNode, MgMid, text, tcp, MgConfig, ?MG_VERBOSITY),
8141
8142    i("[MG] verify transaction-id: undefined_serial"),
8143    otp_5881_verify_trans_id(Mg, undefined_serial),
8144
8145    i("[MG] connect to the MGC (service change)"),
8146    ServChRes = ?MG_SERV_CHANGE(Mg),
8147    d("service change result: ~p", [ServChRes]),
8148
8149    i("[MG] verify transaction-id: 1"),
8150    otp_5881_verify_trans_id(Mg, 1),
8151
8152    d("[MG] send the notify"),
8153    {ok, Reply} = (catch ?MG_NOTIF_RAR(Mg)),
8154    {1, {ok, [AR]}} = Reply,
8155    d("[MG] ActionReply: ~p", [AR]),
8156
8157    i("[MG] verify transaction-id: 2"),
8158    otp_5881_verify_trans_id(Mg, 2),
8159
8160    d("await the generator reply"),
8161    await_completion([MgcId]),
8162
8163    %% Tell MG to stop
8164    i("[MG] stop"),
8165    ?MG_STOP(Mg),
8166
8167    %% Tell Mgc to stop
8168    i("[MGC] stop generator"),
8169    megaco_test_tcp_generator:stop(Mgc),
8170
8171    %% Cleanup
8172    d("stop nodes"),
8173    ?STOP_NODES(lists:reverse(Nodes)),
8174
8175    i("done", []),
8176    ok.
8177
8178otp_5881_verify_trans_id(Mg, Expected) ->
8179    case ?MG_CONN_INFO(Mg, trans_id) of
8180	Expected ->
8181	    ok;
8182	ErroneousValue ->
8183	    throw({unexpected_transaction_id_value, ErroneousValue, Expected})
8184    end.
8185
8186
8187-ifdef(megaco_hipe_special).
8188-define(otp_5881_mgc_decode_msg_fun(Mod, Conf),
8189	{?MODULE, decode_msg, [Mod, Conf]}).
8190-define(otp_5881_mgc_encode_msg_fun(Mod, Conf),
8191	{?MODULE, encode_msg, [Mod, Conf]}).
8192-define(otp_5881_mgc_verify_service_change_req_msg_fun(),
8193	{?MODULE, otp_5881_mgc_verify_service_change_req_msg, []}).
8194-define(otp_5881_mgc_verify_notify_req_msg_fun(),
8195	{?MODULE, otp_5881_mgc_verify_notify_req_msg, []}).
8196-else.
8197-define(otp_5881_mgc_decode_msg_fun(Mod, Conf),
8198	otp_5881_mgc_decode_msg_fun(Mod, Conf)).
8199-define(otp_5881_mgc_encode_msg_fun(Mod, Conf),
8200	otp_5881_mgc_encode_msg_fun(Mod, Conf)).
8201-define(otp_5881_mgc_verify_service_change_req_msg_fun(),
8202	otp_5881_mgc_verify_service_change_req_msg_fun()).
8203-define(otp_5881_mgc_verify_notify_req_msg_fun(),
8204	otp_5881_mgc_verify_notify_req_msg_fun()).
8205-endif.
8206
8207otp_5881_mgc_event_sequence(text, tcp) ->
8208    CTRL = self(),
8209    DecodeFun = ?otp_5881_mgc_decode_msg_fun(megaco_pretty_text_encoder, []),
8210    EncodeFun = ?otp_5881_mgc_encode_msg_fun(megaco_pretty_text_encoder, []),
8211    Mid = {deviceName,"ctrl"},
8212    ServiceChangeReply = otp_5881_service_change_reply_msg(Mid, 1, 0),
8213    TermId = #megaco_term_id{id = ["00000000","00000000","01101101"]},
8214    NotifyReply = otp_5881_notify_reply_msg(Mid, 2, 0, TermId),
8215    %% Pending = otp_5881_pending_msg(Mid,2),
8216    ServiceChangeVerifyFun = ?otp_5881_mgc_verify_service_change_req_msg_fun(),
8217    NotifyReqVerifyFun     = ?otp_5881_mgc_verify_notify_req_msg_fun(),
8218    MgcEvSeq = [{debug,  true},
8219		{decode, DecodeFun},
8220		{encode, EncodeFun},
8221		{listen, 2944},
8222
8223                %% ANNOUNCE READY
8224                {trigger, "announce ready", fun() -> CTRL ! announce_mgc end},
8225
8226		{expect_accept, any},
8227		{expect_receive, "service-change-request", {ServiceChangeVerifyFun, 10000}},
8228		{send, "service-change-reply", ServiceChangeReply},
8229		{expect_receive, "notify-request", {NotifyReqVerifyFun, 10000}},
8230  		{send, "notify-reply", NotifyReply},
8231		{sleep, 2000}
8232	       ],
8233    MgcEvSeq.
8234
8235-ifndef(megaco_hipe_special).
8236otp_5881_mgc_encode_msg_fun(Mod, Conf) ->
8237    fun(M) ->
8238	    encode_msg(M, Mod, Conf)
8239    end.
8240-endif.
8241
8242-ifndef(megaco_hipe_special).
8243otp_5881_mgc_decode_msg_fun(Mod, Conf) ->
8244    fun(M) ->
8245	    decode_msg(M, Mod, Conf)
8246    end.
8247-endif.
8248
8249otp_5881_service_change_reply_msg(Mid, TransId, Cid) ->
8250    SCRP  = #'ServiceChangeResParm'{serviceChangeMgcId = Mid},
8251    SCRPs = {serviceChangeResParms,SCRP},
8252    Root  = #megaco_term_id{id = ["root"]},
8253    SCR   = #'ServiceChangeReply'{terminationID       = [Root],
8254				  serviceChangeResult = SCRPs},
8255    CR    = {serviceChangeReply, SCR},
8256    otp_5881_msg(Mid, TransId, CR, Cid).
8257
8258otp_5881_notify_reply_msg(Mid, TransId, Cid, TermId) ->
8259    NR  = #'NotifyReply'{terminationID = [TermId]},
8260    CR  = {notifyReply, NR},
8261    otp_5881_msg(Mid, TransId, CR, Cid).
8262
8263otp_5881_msg(Mid, TransId, CR, Cid) ->
8264    AR  = #'ActionReply'{contextId    = Cid,
8265			 commandReply = [CR]},
8266    ARs  = {actionReplies, [AR]},
8267    TR   = #'TransactionReply'{transactionId     = TransId,
8268			       transactionResult = ARs},
8269    Body = {transactions, [{transactionReply, TR}]},
8270    Mess = #'Message'{version     = 1,
8271		      mId         = Mid,
8272		      messageBody = Body},
8273    #'MegacoMessage'{mess = Mess}.
8274
8275
8276%% otp_5881_pending_msg(Mid, TransId) ->
8277%%     TP   = #'TransactionPending'{transactionId = TransId},
8278%%     Body = {transactions, [{transactionPending, TP}]},
8279%%     Mess = #'Message'{version     = 1,
8280%% 		      mId         = Mid,
8281%% 		      messageBody = Body},
8282%%     #'MegacoMessage'{mess = Mess}.
8283
8284
8285-ifndef(megaco_hipe_special).
8286otp_5881_mgc_verify_service_change_req_msg_fun() ->
8287    fun(M) ->
8288	    otp_5881_mgc_verify_service_change_req_msg(M)
8289    end.
8290-endif.
8291
8292otp_5881_mgc_verify_service_change_req_msg(
8293  #'MegacoMessage'{mess = Mess} = M) ->
8294    #'Message'{version     = _V,
8295	       mId         = _Mid,
8296	       messageBody = Body} = Mess,
8297    {transactions, [Trans]} = Body,
8298    {transactionRequest, TR} = Trans,
8299    #'TransactionRequest'{transactionId = _Tid,
8300			  actions = [AR]} = TR,
8301    #'ActionRequest'{contextId = _Cid,
8302		     contextRequest = _CtxReq,
8303		     contextAttrAuditReq = _CtxAar,
8304		     commandRequests = [CR]} = AR,
8305    #'CommandRequest'{command = Cmd,
8306		      optional = _Opt,
8307		      wildcardReturn = _WR} = CR,
8308    {serviceChangeReq, SCR} = Cmd,
8309    #'ServiceChangeRequest'{terminationID = _TermID,
8310			    serviceChangeParms = SCP} = SCR,
8311    #'ServiceChangeParm'{serviceChangeMethod = restart,
8312			 serviceChangeReason = [[$9,$0,$1|_]]} = SCP,
8313    {ok, M};
8314otp_5881_mgc_verify_service_change_req_msg(M) ->
8315    {error, {invalid_message, M}}.
8316
8317-ifndef(megaco_hipe_special).
8318otp_5881_mgc_verify_notify_req_msg_fun() ->
8319    fun(M) ->
8320	    otp_5881_mgc_verify_notify_req_msg(M)
8321    end.
8322-endif.
8323
8324otp_5881_mgc_verify_notify_req_msg(#'MegacoMessage'{mess = Mess} = M) ->
8325    #'Message'{messageBody = Body} = Mess,
8326    {transactions, [Trans]} = Body,
8327    {transactionRequest, TR} = Trans,
8328    #'TransactionRequest'{actions = [AR]} = TR,
8329    #'ActionRequest'{commandRequests = [CR1,CR2]} = AR,
8330    #'CommandRequest'{command = Cmd1} = CR1,
8331    {notifyReq, NR1} = Cmd1,
8332    #'NotifyRequest'{observedEventsDescriptor = OED1} = NR1,
8333    #'ObservedEventsDescriptor'{observedEventLst = [OE1]} = OED1,
8334    #'ObservedEvent'{eventName = "al/of"} = OE1,
8335    #'CommandRequest'{command = Cmd2} = CR2,
8336    {notifyReq, NR2} = Cmd2,
8337    #'NotifyRequest'{observedEventsDescriptor = OED2} = NR2,
8338    #'ObservedEventsDescriptor'{observedEventLst = [OE2]} = OED2,
8339    #'ObservedEvent'{eventName = "al/of"} = OE2,
8340    {ok, M};
8341otp_5881_mgc_verify_notify_req_msg(M) ->
8342    {error, {invalid_message, M}}.
8343
8344
8345
8346%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8347
8348otp_5887(suite) ->
8349    [];
8350otp_5887(Config) when is_list(Config) ->
8351    Pre = fun() ->
8352                  MgcNode = make_node_name(mgc),
8353                  MgNode  = make_node_name(mg),
8354                  d("start nodes: "
8355                    "~n      MgcNode: ~p"
8356                    "~n      MgNode:  ~p",
8357                    [MgcNode, MgNode]),
8358                  Nodes = [MgcNode, MgNode],
8359                  ok = ?START_NODES(Nodes, true),
8360                  Nodes
8361          end,
8362    Case = fun do_otp_5887/1,
8363    Post = fun(Nodes) ->
8364                   d("stop nodes"),
8365                   ?STOP_NODES(lists:reverse(Nodes))
8366           end,
8367    try_tc(otp_5887, Pre, Case, Post).
8368
8369do_otp_5887([MgcNode, MgNode]) ->
8370    d("start the MGC simulator (generator)"),
8371    {ok, Mgc} = megaco_test_tcp_generator:start_link("MGC", MgcNode),
8372
8373    d("create the MGC event sequence"),
8374    MgcEvSeq = otp_5887_mgc_event_sequence(text, tcp),
8375
8376    d("start the MGC simulation"),
8377    {ok, MgcId} = megaco_test_tcp_generator:exec(Mgc, MgcEvSeq),
8378
8379    i("await MGC ready announcement"),
8380    receive
8381        announce_mgc ->
8382            i("received MGC ready announcement"),
8383            ok
8384    end,
8385
8386    i("[MG] start"),
8387    MgMid = {deviceName, "mg"},
8388    ReqTmr = #megaco_incr_timer{wait_for    = 3000,
8389                                factor      = 1,
8390                                incr        = 0,
8391                                max_retries = 3},
8392    %% 5000,  %% Does not matter since we will not use this anyway...
8393    LongReqTmr = #megaco_incr_timer{wait_for    = 3000,
8394                                    factor      = 1,
8395                                    incr        = 0,
8396                                    max_retries = 3},
8397    PendingTmr = 10000,
8398    ReplyTmr = 16000,
8399    MgConfig = [{request_timer,      ReqTmr},
8400                {long_request_timer, LongReqTmr},
8401                {pending_timer,      PendingTmr},
8402                {reply_timer,        ReplyTmr}],
8403    {ok, Mg} = ?MG_START(MgNode, MgMid, text, tcp, MgConfig, ?MG_VERBOSITY),
8404
8405    i("[MG] conn info: ~n~p", [?MG_CONN_INFO(Mg, all)]),
8406
8407    i("[MG] verify conn transaction-id: 1"),
8408    otp_5887_verify_conn_trans_id(Mg, 1),
8409
8410    i("[MG] user info: ~n~p", [?MG_USER_INFO(Mg, all)]),
8411
8412    i("[MG] verify user transaction-id: undefined_serial"),
8413    otp_5887_verify_user_trans_id(Mg, undefined_serial),
8414
8415    i("[MG] connect to the MGC (service change)"),
8416    ServChRes = ?MG_SERV_CHANGE(Mg),
8417    d("service change result: ~p", [ServChRes]),
8418
8419    i("[MG] conn info: ~n~p", [?MG_CONN_INFO(Mg, all)]),
8420
8421    i("[MG] verify conn transaction-id: 2"),
8422    otp_5887_verify_conn_trans_id(Mg, 2),
8423
8424    i("[MG] user info: ~n~p", [?MG_USER_INFO(Mg, all)]),
8425
8426    i("[MG] verify user transaction-id: 1"),
8427    otp_5887_verify_user_trans_id(Mg, 1),
8428
8429    d("[MG] send the notify"),
8430    {ok, Reply} = (catch ?MG_NOTIF_RAR(Mg)),
8431    {1, {ok, [AR]}} = Reply,
8432    d("[MG] ActionReply: ~p", [AR]),
8433
8434    i("[MG] conn info: ~n~p", [?MG_CONN_INFO(Mg, all)]),
8435
8436    i("[MG] verify conn transaction-id: 3"),
8437    otp_5887_verify_conn_trans_id(Mg, 3),
8438
8439    i("[MG] user info: ~n~p", [?MG_USER_INFO(Mg, all)]),
8440
8441    i("[MG] verify user transaction-id: 2"),
8442    otp_5887_verify_user_trans_id(Mg, 2),
8443
8444    d("await the generator reply"),
8445    await_completion([MgcId]),
8446
8447    %% Tell MG to stop
8448    i("[MG] stop"),
8449    ?MG_STOP(Mg),
8450
8451    %% Tell Mgc to stop
8452    i("[MGC] stop generator"),
8453    megaco_test_tcp_generator:stop(Mgc),
8454
8455    i("done", []),
8456    ok.
8457
8458
8459otp_5887_verify_conn_trans_id(Mg, Expected) ->
8460    F = fun() -> (catch ?MG_CONN_INFO(Mg, trans_id)) end,
8461    otp_5887_verify_trans_id(F, Expected).
8462
8463otp_5887_verify_user_trans_id(Mg, Expected) ->
8464    F = fun() -> (catch ?MG_USER_INFO(Mg, trans_id)) end,
8465    otp_5887_verify_trans_id(F, Expected).
8466
8467otp_5887_verify_trans_id(F, Expected) ->
8468    case F() of
8469	Expected ->
8470	    ok;
8471	ErroneousValue ->
8472	    throw({unexpected_transaction_id_value, ErroneousValue, Expected})
8473    end.
8474
8475
8476-ifdef(megaco_hipe_special).
8477-define(otp_5887_mgc_decode_msg_fun(Mod, Conf),
8478	{?MODULE, decode_msg, [Mod, Conf]}).
8479-define(otp_5887_mgc_encode_msg_fun(Mod, Conf),
8480	{?MODULE, encode_msg, [Mod, Conf]}).
8481-define(otp_5887_mgc_verify_service_change_req_msg_fun(),
8482	{?MODULE, otp_5887_mgc_verify_service_change_req_msg, []}).
8483-define(otp_5887_mgc_verify_notify_req_msg_fun(),
8484	{?MODULE, otp_5887_mgc_verify_notify_req_msg, []}).
8485-else.
8486-define(otp_5887_mgc_decode_msg_fun(Mod, Conf),
8487	otp_5887_mgc_decode_msg_fun(Mod, Conf)).
8488-define(otp_5887_mgc_encode_msg_fun(Mod, Conf),
8489	otp_5887_mgc_encode_msg_fun(Mod, Conf)).
8490-define(otp_5887_mgc_verify_service_change_req_msg_fun(),
8491	otp_5887_mgc_verify_service_change_req_msg_fun()).
8492-define(otp_5887_mgc_verify_notify_req_msg_fun(),
8493	otp_5887_mgc_verify_notify_req_msg_fun()).
8494-endif.
8495
8496otp_5887_mgc_event_sequence(text, tcp) ->
8497    CTRL = self(),
8498    DecodeFun = ?otp_5887_mgc_decode_msg_fun(megaco_pretty_text_encoder, []),
8499    EncodeFun = ?otp_5887_mgc_encode_msg_fun(megaco_pretty_text_encoder, []),
8500    Mid = {deviceName,"ctrl"},
8501    ServiceChangeReply = otp_5887_service_change_reply_msg(Mid, 1, 0),
8502    TermId = #megaco_term_id{id = ["00000000","00000000","01101101"]},
8503    NotifyReply = otp_5887_notify_reply_msg(Mid, 2, 0, TermId),
8504    ServiceChangeVerifyFun = ?otp_5887_mgc_verify_service_change_req_msg_fun(),
8505    NotifyReqVerifyFun     = ?otp_5887_mgc_verify_notify_req_msg_fun(),
8506    MgcEvSeq = [{debug,  true},
8507		{decode, DecodeFun},
8508		{encode, EncodeFun},
8509		{listen, 2944},
8510
8511                %% ANNOUNCE READY
8512                {trigger, "announce ready", fun() -> CTRL ! announce_mgc end},
8513
8514		{expect_accept, any},
8515		{expect_receive, "service-change-request", {ServiceChangeVerifyFun, 10000}},
8516		{send, "service-change-reply", ServiceChangeReply},
8517		{expect_receive, "notify-request", {NotifyReqVerifyFun, 10000}},
8518  		{send, "notify-reply", NotifyReply},
8519		{sleep, 2000}
8520	       ],
8521    MgcEvSeq.
8522
8523otp_5887_service_change_reply_msg(Mid, TransId, Cid) ->
8524    SCRP  = #'ServiceChangeResParm'{serviceChangeMgcId = Mid},
8525    SCRPs = {serviceChangeResParms,SCRP},
8526    Root  = #megaco_term_id{id = ["root"]},
8527    SCR   = #'ServiceChangeReply'{terminationID       = [Root],
8528				  serviceChangeResult = SCRPs},
8529    CR    = {serviceChangeReply, SCR},
8530    otp_5887_msg(Mid, TransId, CR, Cid).
8531
8532otp_5887_notify_reply_msg(Mid, TransId, Cid, TermId) ->
8533    NR  = #'NotifyReply'{terminationID = [TermId]},
8534    CR  = {notifyReply, NR},
8535    otp_5887_msg(Mid, TransId, CR, Cid).
8536
8537otp_5887_msg(Mid, TransId, CR, Cid) ->
8538    AR  = #'ActionReply'{contextId    = Cid,
8539			 commandReply = [CR]},
8540    ARs  = {actionReplies, [AR]},
8541    TR   = #'TransactionReply'{transactionId     = TransId,
8542			       transactionResult = ARs},
8543    Body = {transactions, [{transactionReply, TR}]},
8544    Mess = #'Message'{version     = 1,
8545		      mId         = Mid,
8546		      messageBody = Body},
8547    #'MegacoMessage'{mess = Mess}.
8548
8549
8550%% otp_5887_pending_msg(Mid, TransId) ->
8551%%     TP   = #'TransactionPending'{transactionId = TransId},
8552%%     Body = {transactions, [{transactionPending, TP}]},
8553%%     Mess = #'Message'{version     = 1,
8554%% 		      mId         = Mid,
8555%% 		      messageBody = Body},
8556%%     #'MegacoMessage'{mess = Mess}.
8557
8558
8559-ifndef(megaco_hipe_special).
8560otp_5887_mgc_encode_msg_fun(Mod, Conf) ->
8561    fun(M) ->
8562	    encode_msg(M, Mod, Conf)
8563    end.
8564-endif.
8565%% otp_5887_mgc_encode_msg_fun(Mod, Conf, Ver) ->
8566%%     fun(M) ->
8567%% 	    encode_msg(M, Mod, Conf, Ver)
8568%%     end.
8569
8570-ifndef(megaco_hipe_special).
8571otp_5887_mgc_decode_msg_fun(Mod, Conf) ->
8572    fun(M) ->
8573	    decode_msg(M, Mod, Conf)
8574    end.
8575-endif.
8576%% otp_5887_mgc_decode_msg_fun(Mod, Conf, Ver) ->
8577%%     fun(M) ->
8578%% 	    decode_msg(M, Mod, Conf, Ver)
8579%%     end.
8580
8581-ifndef(megaco_hipe_special).
8582otp_5887_mgc_verify_service_change_req_msg_fun() ->
8583    fun(M) ->
8584	    otp_5887_mgc_verify_service_change_req_msg(M)
8585    end.
8586-endif.
8587
8588otp_5887_mgc_verify_service_change_req_msg(
8589  #'MegacoMessage'{mess = Mess} = M) ->
8590    #'Message'{version     = _V,
8591	       mId         = _Mid,
8592	       messageBody = Body} = Mess,
8593    {transactions, [Trans]} = Body,
8594    {transactionRequest, TR} = Trans,
8595    #'TransactionRequest'{transactionId = _Tid,
8596			  actions = [AR]} = TR,
8597    #'ActionRequest'{contextId = _Cid,
8598		     contextRequest = _CtxReq,
8599		     contextAttrAuditReq = _CtxAar,
8600		     commandRequests = [CR]} = AR,
8601    #'CommandRequest'{command = Cmd,
8602		      optional = _Opt,
8603		      wildcardReturn = _WR} = CR,
8604    {serviceChangeReq, SCR} = Cmd,
8605    #'ServiceChangeRequest'{terminationID = _TermID,
8606			    serviceChangeParms = SCP} = SCR,
8607    #'ServiceChangeParm'{serviceChangeMethod = restart,
8608			 serviceChangeReason = [[$9,$0,$1|_]]} = SCP,
8609    {ok, M};
8610otp_5887_mgc_verify_service_change_req_msg(M) ->
8611    {error, {invalid_message, M}}.
8612
8613
8614-ifndef(megaco_hipe_special).
8615otp_5887_mgc_verify_notify_req_msg_fun() ->
8616    fun(M) ->
8617	    otp_5887_mgc_verify_notify_req_msg(M)
8618    end.
8619-endif.
8620
8621otp_5887_mgc_verify_notify_req_msg(#'MegacoMessage'{mess = Mess} = M) ->
8622    #'Message'{messageBody = Body} = Mess,
8623    {transactions, [Trans]} = Body,
8624    {transactionRequest, TR} = Trans,
8625    #'TransactionRequest'{actions = [AR]} = TR,
8626    #'ActionRequest'{commandRequests = [CR1,CR2]} = AR,
8627    #'CommandRequest'{command = Cmd1} = CR1,
8628    {notifyReq, NR1} = Cmd1,
8629    #'NotifyRequest'{observedEventsDescriptor = OED1} = NR1,
8630    #'ObservedEventsDescriptor'{observedEventLst = [OE1]} = OED1,
8631    #'ObservedEvent'{eventName = "al/of"} = OE1,
8632    #'CommandRequest'{command = Cmd2} = CR2,
8633    {notifyReq, NR2} = Cmd2,
8634    #'NotifyRequest'{observedEventsDescriptor = OED2} = NR2,
8635    #'ObservedEventsDescriptor'{observedEventLst = [OE2]} = OED2,
8636    #'ObservedEvent'{eventName = "al/of"} = OE2,
8637    {ok, M};
8638otp_5887_mgc_verify_notify_req_msg(M) ->
8639    {error, {invalid_message, M}}.
8640
8641
8642%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8643
8644otp_6253(suite) ->
8645    [];
8646otp_6253(Config) when is_list(Config) ->
8647    ?ACQUIRE_NODES(1, Config),
8648
8649    put(verbosity, debug),
8650    put(tc, otp_6253),
8651
8652    d("otp_6253 -> start test case controller",[]),
8653    ok = megaco_tc_controller:start_link(),
8654
8655    PrelMid = preliminary_mid,
8656    MgMid   = ipv4_mid(4711),
8657
8658    ?VERIFY(ok, application:start(megaco)),
8659    ?VERIFY(ok,	megaco:start_user(MgMid, [{send_mod, ?USER_MOD},
8660	                                  {request_timer, infinity},
8661	                                  {reply_timer, infinity}])),
8662
8663    MgRH = user_info(MgMid, receive_handle),
8664    {ok, PrelCH} = ?VERIFY({ok, _}, megaco:connect(MgRH, PrelMid, sh, self())),
8665
8666    connections([PrelCH]),
8667    ?VERIFY([PrelCH], megaco:user_info(MgMid, connections)),
8668
8669    SC = service_change_request(),
8670
8671    %% Instruct the transport module to fail all send_message
8672    d("otp_6253 -> instruct transport module to fail message send",[]),
8673    ok = megaco_tc_controller:insert(allow_send_message, {fail, otp_6253}),
8674
8675    ?VERIFY({1, {error, {send_message_failed, otp_6253}}},
8676	    megaco:call(PrelCH, [SC], [])),
8677
8678    sleep(1000),
8679
8680    %% Instruct the transport module to cancel all send_message
8681    d("otp_6253 -> instruct transport module to cancel message send",[]),
8682    ok = megaco_tc_controller:insert(allow_send_message, {cancel, otp_6253}),
8683
8684    ?VERIFY({1, {error, {send_message_cancelled, otp_6253}}},
8685	    megaco:call(PrelCH, [SC], [])),
8686
8687    ?VERIFY(ok, megaco:disconnect(PrelCH, shutdown)),
8688
8689    ?VERIFY(ok,	megaco:stop_user(MgMid)),
8690    ?VERIFY(ok, application:stop(megaco)),
8691    ?RECEIVE([]),
8692    ok.
8693
8694
8695%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8696
8697otp_6275(suite) ->
8698    [];
8699otp_6275(Config) when is_list(Config) ->
8700    Pre = fun() ->
8701                  MgcNode = make_node_name(mgc),
8702                  MgNode  = make_node_name(mg),
8703                  d("start nodes: "
8704                    "~n      MgcNode: ~p"
8705                    "~n      MgNode:  ~p",
8706                    [MgcNode, MgNode]),
8707                  Nodes = [MgcNode, MgNode],
8708                  ok = ?START_NODES(Nodes, true),
8709                  Nodes
8710          end,
8711    Case = fun do_otp_6275/1,
8712    Post = fun(Nodes) ->
8713                   d("stop nodes"),
8714                   ?STOP_NODES(lists:reverse(Nodes))
8715           end,
8716    try_tc(otp_6275, Pre, Case, Post).
8717
8718do_otp_6275([MgcNode, MgNode]) ->
8719    d("start the MGC simulator (generator)"),
8720    {ok, Mgc} = megaco_test_tcp_generator:start_link("MGC", MgcNode),
8721
8722    d("create the MGC event sequence"),
8723    MgcEvSeq = otp_6275_mgc_event_sequence(text, tcp),
8724
8725    d("start the MGC simulation"),
8726    {ok, MgcId} = megaco_test_tcp_generator:exec(Mgc, MgcEvSeq),
8727
8728    i("await MGC ready announcement"),
8729    receive
8730        announce_mgc ->
8731            i("received MGC ready announcement"),
8732            ok
8733    end,
8734
8735    d("[MG] start the simulator (generator)"),
8736    {ok, Mg} = megaco_test_megaco_generator:start_link("MG", MgNode),
8737
8738    d("[MG] create the event sequence"),
8739    MgEvSeq = otp_6275_mg_event_sequence(text, tcp),
8740
8741    i("wait some time before starting the MG simulation"),
8742    sleep(1000),
8743
8744    d("[MG] start the simulation"),
8745    {ok, MgId} = megaco_test_megaco_generator:exec(Mg, MgEvSeq),
8746
8747    d("[MGC] await the generator reply"),
8748    await_completion([MgcId, MgId]),
8749
8750    %% Tell Mgc to stop
8751    i("[MGC] stop generator"),
8752    megaco_test_tcp_generator:stop(Mgc),
8753
8754    %% Tell Mg to stop
8755    i("[MG] stop generator"),
8756    megaco_test_megaco_generator:stop(Mg),
8757
8758    i("done", []),
8759    ok.
8760
8761
8762%%
8763%% MG generator stuff
8764%%
8765-ifdef(megaco_hipe_special).
8766-define(otp_6275_mg_verify_handle_connect_fun(),
8767        {?MODULE, otp_6275_mg_verify_handle_connect, []}).
8768-define(otp_6275_mg_verify_notify_req_fun(),
8769        {?MODULE, otp_6275_mg_verify_notify_req, []}).
8770-define(otp_6275_mg_verify_handle_trans_rep_fun(),
8771        {?MODULE, otp_6275_mg_verify_handle_trans_rep, []}).
8772-else.
8773-define(otp_6275_mg_verify_handle_connect_fun(),
8774        otp_6275_mg_verify_handle_connect_fun()).
8775-define(otp_6275_mg_verify_notify_req_fun(),
8776	otp_6275_mg_verify_notify_req_fun()).
8777-define(otp_6275_mg_verify_handle_trans_rep_fun(),
8778	otp_6275_mg_verify_handle_trans_rep_fun()).
8779-endif.
8780
8781otp_6275_mg_event_sequence(text, tcp) ->
8782    Mid = {deviceName,"mg"},
8783    RI = [
8784          {port,             2944},
8785          {encoding_module,  megaco_pretty_text_encoder},
8786          {encoding_config,  []},
8787          {transport_module, megaco_tcp}
8788         ],
8789    otp_6275_mg_event_sequence2(Mid, RI).
8790
8791otp_6275_mg_event_sequence2(Mid, RI) ->
8792    ServiceChangeReq = [otp_6275_mg_service_change_request_ar(Mid, 1)],
8793    _Tid = #megaco_term_id{id = ["00000000","00000000","01101101"]},
8794    ConnectVerify    = ?otp_6275_mg_verify_handle_connect_fun(),
8795    NotifyReqVerify  = ?otp_6275_mg_verify_notify_req_fun(),
8796    TransReplyVerify = ?otp_6275_mg_verify_handle_trans_rep_fun(),
8797    EvSeq = [
8798             {debug, true},
8799             megaco_start,
8800             {megaco_start_user, Mid, RI, []},
8801	     %% {megaco_update_user_info, recv_pending_limit, 4},
8802	     {megaco_update_user_info, request_timer, 3000},
8803             start_transport,
8804             {megaco_trace, disable}, %%100},
8805             {megaco_system_info, users},
8806             {megaco_system_info, connections},
8807             connect,
8808             {megaco_callback, handle_connect, ConnectVerify},
8809             megaco_connect,
8810             {megaco_cast, ServiceChangeReq, []},
8811             {megaco_callback, handle_connect, ConnectVerify},
8812             {megaco_callback, handle_trans_request, NotifyReqVerify},
8813             {megaco_callback, handle_trans_reply, TransReplyVerify},
8814             {sleep, 1000},
8815             megaco_stop_user,
8816             megaco_stop,
8817             {sleep, 1000}
8818            ],
8819    EvSeq.
8820
8821
8822-ifndef(megaco_hipe_special).
8823otp_6275_mg_verify_handle_connect_fun() ->
8824    fun(Event) ->
8825	    (catch otp_6275_mg_verify_handle_connect(Event))
8826    end.
8827-endif.
8828
8829otp_6275_mg_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
8830    io:format("otp_6275_mg_verify_handle_connect -> ok"
8831	      "~n   CH: ~p~n", [CH]),
8832    {ok, CH, ok};
8833otp_6275_mg_verify_handle_connect(Else) ->
8834    io:format("otp_6275_mg_verify_handle_connect -> unknown"
8835	      "~n   Else: ~p~n", [Else]),
8836    {error, Else, ok}.
8837
8838
8839-ifndef(megaco_hipe_special).
8840otp_6275_mg_verify_notify_req_fun() ->
8841    fun(Event) ->
8842	    (catch otp_6275_mg_verify_notify_req(Event))
8843    end.
8844-endif.
8845
8846otp_6275_mg_verify_notify_req(
8847  {handle_trans_request, _CH, ?VERSION, [AR]}) ->
8848    io:format("otp_6275_mg_verify_notify_req -> entry with"
8849	      "~n   AR: ~p"
8850	      "~n", [AR]),
8851    CR =
8852	case AR of
8853	    #'ActionRequest'{commandRequests = [CmdReq]} ->
8854		CmdReq;
8855	    _ ->
8856		ET1 = lists:flatten(
8857		       io_lib:format("Invalid action request: ~w", [AR])),
8858		EC1 = ?megaco_internal_gateway_error,
8859		ED1 = #'ErrorDescriptor'{errorCode = EC1,
8860					 errorText = ET1},
8861		throw({error, {invalid_ActionRequest, AR}, {discard_ack, ED1}})
8862	end,
8863
8864    Cmd =
8865	case CR of
8866	    #'CommandRequest'{command = Command} ->
8867		Command;
8868	    _ ->
8869		ET2 = lists:flatten(
8870			io_lib:format("Invalid command request: ~w", [CR])),
8871		EC2 = ?megaco_internal_gateway_error,
8872		ED2 = #'ErrorDescriptor'{errorCode = EC2,
8873					 errorText = ET2},
8874		throw({error, {invalid_CommandRequest, CR}, {discard_ack, ED2}})
8875	end,
8876
8877    case Cmd of
8878	{notifyReq, NotifyReq} ->
8879	    ET3 = "Unexpected request",
8880	    EC3 = ?megaco_transaction_req_received_before_servicechange_reply,
8881	    ED3 = #'ErrorDescriptor'{errorCode = EC3,
8882				     errorText = ET3},
8883	    throw({ok, {ok, NotifyReq}, {discard_ack, ED3}});
8884	_ ->
8885	    ET4 = lists:flatten(
8886		    io_lib:format("Invalid command: ~w", [Cmd])),
8887	    EC4 = ?megaco_internal_gateway_error,
8888	    ED4 = #'ErrorDescriptor'{errorCode = EC4,
8889				     errorText = ET4},
8890	    throw({error, {invalid_command, Cmd}, {discard_ack, ED4}})
8891    end;
8892otp_6275_mg_verify_notify_req({Tag, CH, Version, ARs}) ->
8893    io:format("otp_6275_mg_verify_notify_req -> ok"
8894	      "~n   Tag:     ~p"
8895	      "~n   CH:      ~p"
8896	      "~n   Version: ~p"
8897	      "~n   ARs:     ~p"
8898	      "~n", [Tag, CH, Version, ARs]),
8899    {error, {invalid_event, {Tag, CH, Version, ARs}}, ok};
8900otp_6275_mg_verify_notify_req(Else) ->
8901    io:format("otp_6275_mg_verify_notify_req -> unknown"
8902	      "~n   Else: ~p~n", [Else]),
8903    {error, Else, ok}.
8904
8905
8906-ifndef(megaco_hipe_special).
8907otp_6275_mg_verify_handle_trans_rep_fun() ->
8908    fun(Event) ->
8909	    (catch otp_6275_mg_verify_handle_trans_rep(Event))
8910    end.
8911-endif.
8912
8913otp_6275_mg_verify_handle_trans_rep(
8914  {handle_trans_reply, CH, ?VERSION, {error, timeout} = Error, _}) ->
8915    io:format("otp_6275_mg_verify_trans_rep -> expected error"
8916	      "~n", []),
8917    case CH of
8918	#megaco_conn_handle{remote_mid = preliminary_mid} ->
8919	    {ok, Error, error};
8920	_ ->
8921	    {error, {unexpected_connection, CH}, error}
8922    end;
8923otp_6275_mg_verify_handle_trans_rep(
8924  {handle_trans_reply, _CH, ?VERSION, Error, _}) ->
8925    io:format("otp_6275_mg_verify_handle_trans_rep -> unexpected error"
8926	      "~n   Error: ~p"
8927	      "~n", [Error]),
8928    {error, Error, error};
8929otp_6275_mg_verify_handle_trans_rep(Else) ->
8930    io:format("otp_6275_mg_verify_handle_trans_rep -> unknown"
8931	      "~n   Else: ~p~n", [Else]),
8932    {error, Else, error}.
8933
8934otp_6275_mg_service_change_request_ar(_Mid, Cid) ->
8935    Prof  = cre_serviceChangeProf("resgw", 1),
8936    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
8937    Root  = #megaco_term_id{id = ["root"]},
8938    SCR   = cre_serviceChangeReq([Root], SCP),
8939    CMD   = cre_command(SCR),
8940    CR    = cre_cmdReq(CMD),
8941    cre_actionReq(Cid, [CR]).
8942
8943
8944%%
8945%% MGC generator stuff
8946%%
8947-ifdef(megaco_hipe_special).
8948-define(otp_6275_mgc_decode_msg_fun(Mod, Conf),
8949	{?MODULE, decode_msg, [Mod, Conf]}).
8950-define(otp_6275_mgc_encode_msg_fun(Mod, Conf),
8951	{?MODULE, encode_msg, [Mod, Conf]}).
8952-define(otp_6275_mgc_verify_service_change_req_msg_fun(),
8953	{?MODULE, otp_6275_mgc_verify_service_change_req_msg, []}).
8954-define(otp_6275_mgc_verify_notify_rep_msg_fun(),
8955	{?MODULE, otp_6275_mgc_verify_notify_rep_msg, []}).
8956-else.
8957-define(otp_6275_mgc_decode_msg_fun(Mod, Conf),
8958	otp_6275_mgc_decode_msg_fun(Mod, Conf)).
8959-define(otp_6275_mgc_encode_msg_fun(Mod, Conf),
8960	otp_6275_mgc_encode_msg_fun(Mod, Conf)).
8961-define(otp_6275_mgc_verify_service_change_req_msg_fun(),
8962	otp_6275_mgc_verify_service_change_req_msg_fun()).
8963-define(otp_6275_mgc_verify_notify_rep_msg_fun(),
8964	otp_6275_mgc_verify_notify_rep_msg_fun()).
8965-endif.
8966
8967otp_6275_mgc_event_sequence(text, tcp) ->
8968    CTRL = self(),
8969    DecodeFun = ?otp_6275_mgc_decode_msg_fun(megaco_pretty_text_encoder, []),
8970    EncodeFun = ?otp_6275_mgc_encode_msg_fun(megaco_pretty_text_encoder, []),
8971    Mid = {deviceName,"ctrl"},
8972    TermId = #megaco_term_id{id = ["00000000","00000000","01101101"]},
8973    NotifyReq = otp_6275_mgc_notify_request_msg(Mid, 2, 1, TermId, 1),
8974    SCRVerifyFun         = ?otp_6275_mgc_verify_service_change_req_msg_fun(),
8975    NotifyReplyVerifyFun = ?otp_6275_mgc_verify_notify_rep_msg_fun(),
8976    MgcEvSeq =
8977	[{debug,  true},
8978	 {decode, DecodeFun},
8979	 {encode, EncodeFun},
8980	 {listen, 2944},
8981
8982         %% ANNOUNCE READY
8983         {trigger, "announce ready", fun() -> CTRL ! announce_mgc end},
8984
8985	 {expect_accept, any},
8986	 {expect_receive, "service-change-request", {SCRVerifyFun, 5000}},
8987	 {sleep, 1000}, %% Do _not_ send SC reply
8988	 {send, "notify-request", NotifyReq},
8989	 {expect_receive, "request before sc reply", {NotifyReplyVerifyFun, 5000}},
8990	 {sleep, 2000}
8991	],
8992    MgcEvSeq.
8993
8994-ifndef(megaco_hipe_special).
8995otp_6275_mgc_encode_msg_fun(Mod, Conf) ->
8996    fun(M) ->
8997	    encode_msg(M, Mod, Conf)
8998    end.
8999-endif.
9000
9001%% otp_6275_mgc_encode_msg_fun(Mod, Conf, Ver) ->
9002%%     fun(M) ->
9003%% 	    encode_msg(M, Mod, Conf, Ver)
9004%%     end.
9005
9006-ifndef(megaco_hipe_special).
9007otp_6275_mgc_decode_msg_fun(Mod, Conf) ->
9008    fun(M) ->
9009	    decode_msg(M, Mod, Conf)
9010    end.
9011-endif.
9012
9013%% otp_6275_mgc_decode_msg_fun(Mod, Conf, Ver) ->
9014%%     fun(M) ->
9015%% 	    decode_msg(M, Mod, Conf, Ver)
9016%%     end.
9017
9018-ifndef(megaco_hipe_special).
9019otp_6275_mgc_verify_service_change_req_msg_fun() ->
9020    fun(M) ->
9021	    (catch otp_6275_mgc_verify_service_change_req_msg(M))
9022    end.
9023-endif.
9024
9025otp_6275_mgc_verify_service_change_req_msg(
9026  #'MegacoMessage'{mess = Mess} = M) ->
9027    io:format("otp_6275_mgc_verify_service_change_req_msg -> entry with"
9028	      "~n   M: ~p"
9029	      "~n", [M]),
9030    Body =
9031	case Mess of
9032	    #'Message'{messageBody = MB} ->
9033		MB;
9034	    _ ->
9035		throw({error, {invalid_mess, Mess}})
9036	end,
9037
9038    Trans =
9039	case Body of
9040	    {transactions, [Transaction]} ->
9041		Transaction;
9042	    _ ->
9043		throw({error, {invalid_messageBody, Body}})
9044	end,
9045
9046    TR =
9047	case Trans of
9048	    {transactionRequest, TransReq} ->
9049		TransReq;
9050	    _ ->
9051		throw({error, {invalid_transaction, Trans}})
9052	end,
9053
9054    AR =
9055	case TR of
9056	    #'TransactionRequest'{actions = [ActionReq]} ->
9057		ActionReq;
9058	    _ ->
9059		throw({error, {invalid_transactionRequest, TR}})
9060	end,
9061
9062    CR =
9063	case AR of
9064	    #'ActionRequest'{commandRequests = [CmdReq]} ->
9065		CmdReq;
9066	    _ ->
9067		throw({error, {invalid_TransactionRequest, AR}})
9068	end,
9069
9070    Cmd =
9071	case CR of
9072	    #'CommandRequest'{command = Command} ->
9073		Command;
9074	    _ ->
9075		throw({error, {invalid_ActionRequest, CR}})
9076	end,
9077
9078    SCR =
9079	case Cmd of
9080	    {serviceChangeReq, ServiceChangeReq} ->
9081		ServiceChangeReq;
9082	    _ ->
9083		throw({error, {invalid_command, Cmd}})
9084	end,
9085
9086    SCP =
9087	case SCR of
9088	    #'ServiceChangeRequest'{serviceChangeParms = ServiceChangeParms} ->
9089		ServiceChangeParms;
9090	    _ ->
9091		throw({error, {invalid_serviceChangeReq, SCR}})
9092	end,
9093
9094    case SCP of
9095	#'ServiceChangeParm'{serviceChangeMethod = restart,
9096			     serviceChangeReason = [[$9,$0,$1|_]]} ->
9097	    {ok, M};
9098       _ ->
9099	    {error, {invalid_serviceChangeParms, SCP}}
9100    end;
9101otp_6275_mgc_verify_service_change_req_msg(Crap) ->
9102    {error, {invalid_MegacoMessage, Crap}}.
9103
9104-ifndef(megaco_hipe_special).
9105otp_6275_mgc_verify_notify_rep_msg_fun() ->
9106    fun(M) ->
9107	    (catch otp_6275_mgc_verify_notify_rep_msg(M))
9108    end.
9109-endif.
9110
9111otp_6275_mgc_verify_notify_rep_msg(#'MegacoMessage'{mess = Mess} = M) ->
9112    io:format("otp_6275_mgc_verify_notify_rep_msg -> entry with"
9113	      "~n   M: ~p"
9114	      "~n", [M]),
9115    Body =
9116	case Mess of
9117	    #'Message'{messageBody = MB} ->
9118		MB;
9119	    _ ->
9120		throw({error, {invalid_mess, Mess}})
9121	end,
9122
9123    Trans =
9124	case Body of
9125	    {transactions, [Transaction]} ->
9126		Transaction;
9127	    _ ->
9128		throw({error, {invalid_messageBody, Body}})
9129	end,
9130
9131    TR =
9132	case Trans of
9133	    {transactionReply, TransReply} ->
9134		TransReply;
9135	    _ ->
9136		throw({error, {invalid_transaction, Trans}})
9137	end,
9138
9139    Res =
9140	case TR of
9141	    #'TransactionReply'{transactionResult = TransRes} ->
9142		TransRes;
9143	    _ ->
9144		throw({error, {invalid_transactionReply, TR}})
9145	end,
9146
9147    ED =
9148	case Res of
9149	    {transactionError, ErrorDesc} ->
9150		ErrorDesc;
9151	    _ ->
9152		throw({error, {invalid_TransactionReply, Res}})
9153	end,
9154
9155    case ED of
9156	#'ErrorDescriptor'{errorCode = ?megaco_transaction_req_received_before_servicechange_reply} ->
9157	    ok;
9158	_ ->
9159	    throw({error, {invalid_transactionError, ED}})
9160    end,
9161    {ok, M};
9162otp_6275_mgc_verify_notify_rep_msg(Crap) ->
9163    {error, {invalid_MegacoMessage, Crap}}.
9164
9165
9166otp_6275_mgc_notify_request_ar(Rid, Tid, Cid) ->
9167    TT      = cre_timeNotation("19990729", "22000000"),
9168    Ev      = cre_obsEvent("al/of", TT),
9169    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
9170    NR      = cre_notifyReq([Tid], EvsDesc),
9171    CMD     = cre_command(NR),
9172    CR      = cre_cmdReq(CMD),
9173    cre_actionReq(Cid, [CR]).
9174
9175otp_6275_mgc_notify_request_msg(Mid, TransId, Cid, TermId, Rid) ->
9176    AR = otp_6275_mgc_notify_request_ar(Rid, TermId, Cid),
9177    otp_6275_msg(Mid, TransId, AR).
9178
9179
9180%% --
9181
9182otp_6275_msg(Mid, TransId, AR) ->
9183    TR    = cre_transReq(TransId, [AR]),
9184    Trans = cre_transaction(TR),
9185    Mess  = cre_message(1, Mid, cre_transactions([Trans])),
9186    cre_megacoMessage(Mess).
9187
9188%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9189
9190%% This test case can only be run with the stack compiled with
9191%% the MEGACO_TEST_CODE flag. Therefor there is no point in
9192%% including this test case in the usual test suite
9193-ifdef(MEGACO_TEST_CODE).
9194otp_6276(suite) ->
9195    [];
9196otp_6276(doc) ->
9197    "OTP-6276: Cancel when receiving reply raise condition";
9198otp_6276(Config) when is_list(Config) ->
9199    Pre = fun() ->
9200                  MgcNode = make_node_name(mgc),
9201                  MgNode  = make_node_name(mg),
9202                  d("start nodes: "
9203                    "~n      MgcNode: ~p"
9204                    "~n      MgNode:  ~p",
9205                    [MgcNode, MgNode]),
9206                  Nodes = [MgcNode, MgNode],
9207                  ok = ?START_NODES(Nodes, true),
9208                  Nodes
9209          end,
9210    Case = fun do_otp_6276/1,
9211    Post = fun(Nodes) ->
9212                   d("stop nodes"),
9213                   ?STOP_NODES(lists:reverse(Nodes))
9214           end,
9215    try_tc(otp_6276, Pre, Case, Post).
9216
9217do_otp_6276([MgcNode, MgNode]) ->
9218    d("create sequence controller"),
9219    CtrlPid = otp_6276_sequence_controller_start(),
9220
9221    d("[MGC] start the simulator "),
9222    {ok, Mgc} = megaco_test_tcp_generator:start_link("MGC", MgcNode),
9223
9224    d("[MGC] create the event sequence"),
9225    MgcEvSeq = otp_6276_mgc_event_sequence(text, tcp, CtrlPid),
9226
9227    i("wait some time before starting the MGC simulation"),
9228    sleep(1000),
9229
9230    d("[MGC] start the tcp-simulation"),
9231    {ok, MgcId} = megaco_test_tcp_generator:exec(Mgc, MgcEvSeq),
9232
9233    %% i("wait some time before starting the MG simulator"),
9234    %% sleep(1000),
9235
9236    i("await MGC ready announcement"),
9237    receive
9238        announce_mgc ->
9239            i("received MGC ready announcement"),
9240            ok
9241    end,
9242
9243    d("[MG] start the simulator (generator)"),
9244    {ok, Mg} = megaco_test_megaco_generator:start_link("MG", MgNode),
9245
9246    d("send start order to sequence controller"),
9247    CtrlPid ! {start, self(), Mgc, Mg},
9248
9249    d("[MG] create the event sequence"),
9250    MgEvSeq = otp_6276_mg_event_sequence(text, tcp, CtrlPid),
9251
9252    i("wait some time before starting the MG simulation"),
9253    sleep(1000),
9254
9255    d("[MG] start the megaco-simulation"),
9256    {ok, MgId} = megaco_test_megaco_generator:exec(Mg, MgEvSeq),
9257
9258    d("await the generator reply(s)"),
9259    await_completion([MgcId, MgId]),
9260
9261    %% Tell Mgc to stop
9262    i("[MGC] stop generator"),
9263    megaco_test_tcp_generator:stop(Mgc),
9264
9265    %% Tell Mg to stop
9266    i("[MG] stop generator"),
9267    megaco_test_megaco_generator:stop(Mg),
9268
9269    i("done", []),
9270    ok.
9271
9272
9273otp_6276_sequence_controller_start() ->
9274    Self = self(),
9275    erlang:spawn(fun() -> otp_6276_sequence_controller(Self) end).
9276
9277otp_6276_sequence_controller(Parent) ->
9278    io:format("otp_6276_sequence_controller -> entry with"
9279	      "~n   Parent: ~p"
9280	      "~n   self(): ~p"
9281	      "~n", [Parent, self()]),
9282
9283    d("start tc controller"),
9284    put(dbg,true),
9285    ok = megaco_tc_controller:start_link(),
9286
9287
9288    %% Await MGC announcement
9289    Mgc =
9290	receive
9291	    {announce_mgc, MgcPid} ->
9292		MgcPid
9293	end,
9294    io:format("otp_6276_sequence_controller -> MGC announced: "
9295	      "~n   Mgc: ~p"
9296	      "~n", [Mgc]),
9297
9298    %% Await MG announcement
9299    Mg =
9300	receive
9301	    {announce_mg, MgPid} ->
9302		MgPid
9303	end,
9304    io:format("otp_6276_sequence_controller -> MG announced: "
9305	      "~n   Mg: ~p"
9306	      "~n", [Mg]),
9307
9308    %% Await request_received notification
9309    receive
9310	{notify_request_received, Mgc} ->
9311	    io:format("otp_6276_sequence_controller -> "
9312		      "request received from MGC (~p)"
9313		      "~n", [Mgc]),
9314	    ok
9315    end,
9316
9317    %% Make sure the cancel operation gets blocked midway:
9318    megaco_tc_controller:insert(block_on_cancel, {cancel_block, self()}),
9319
9320    %% Send start cancel order
9321    io:format("otp_6276_sequence_controller -> "
9322	      "send cancel start order to MG (~p)"
9323	      "~n", [Mg]),
9324    Mg ! {start_cancel, self()},
9325    receive
9326	{started_cancel, Mg} ->
9327	    ok
9328    end,
9329    io:format("otp_6276_sequence_controller -> "
9330	      "cancel started - now await blocked"
9331	      "~n", []),
9332
9333    receive
9334	{cancel_block, Mg} ->
9335	    ok
9336    end,
9337    io:format("otp_6276_sequence_controller -> "
9338	      "cancel blocked - now instruct MGC to send notify reply"
9339	      "~n", []),
9340
9341    %% Make sure the cancel operation gets blocked midway:
9342    megaco_tc_controller:insert(block_on_reply, {reply_block, self()}),
9343
9344    %% Send NR-send order
9345    Mgc ! {notify_reply_send, self()},
9346    io:format("otp_6276_sequence_controller -> "
9347	      "NR-send order sent - now await notify reply blocked received"
9348	      "~n", []),
9349
9350    ReplyPid =
9351	receive
9352	    {reply_block, Pid, true} ->
9353		io:format("otp_6276_sequence_controller -> "
9354			  "notify reply blocked received from ~p (true) - "
9355			  "now unblock cancel"
9356			  "~n", [Pid]),
9357		%% Pid ! {reply_block, self()},
9358		Pid;
9359	    {reply_block, Pid, Info} ->
9360		io:format("otp_6276_sequence_controller -> "
9361			  "notify reply blocked received from ~p: ~p"
9362			  "~n", [Pid, Info]),
9363		Pid ! {reply_block, self()},
9364		exit({unexpected_reply_block_info, Info})
9365	end,
9366
9367    %% Send cancel continue (unblock) order
9368    Mg ! {cancel_block, self()},
9369    io:format("otp_6276_sequence_controller -> "
9370	      "cancel unblocked - now await notify-request cancelled"
9371	      "~n", []),
9372
9373    %% Await request cancelled
9374    receive
9375	{notify_request_cancelled, Mg} ->
9376	    ok;
9377	{notify_request_cancelled, Pid} ->
9378	    io:format("otp_6276_sequence_controller -> "
9379		      "notify-request cancelled - from ~p"
9380		      "~n", [Pid]),
9381	    ok
9382    end,
9383    io:format("otp_6276_sequence_controller -> "
9384	      "notify-request cancelled - now unblock notify-reply"
9385	      "~n", []),
9386
9387    %% await notify reply result
9388    ReplyPid ! {reply_block, self()},
9389    io:format("otp_6276_sequence_controller -> "
9390	      "notify-reply unblocked - now await unexpected trans"
9391	      "~n", []),
9392
9393    %% Await unexpected trans
9394    receive
9395	{unexpected_trans, Mg, _Trans} ->
9396	    ok;
9397	{unexpected_trans, Pid, _Trans} ->
9398	    io:format("otp_6276_sequence_controller -> "
9399		      "unexpected_trans - from ~p"
9400		      "~n", [Pid]),
9401	    ok
9402    end,
9403    io:format("otp_6276_sequence_controller -> "
9404	      "unexpected transaction received"
9405	      "~n", []),
9406
9407    %% Await unexpected trans
9408    Mgc ! {done, self()},
9409    receive
9410	{done, Mgc} ->
9411	    ok
9412    end,
9413    io:format("otp_6276_sequence_controller -> MGC instructed we are done"
9414	      "~n", []),
9415
9416    d("stop tc controller"),
9417    megaco_tc_controller:stop(),
9418
9419    io:format("otp_6276_sequence_controller -> done~n", []),
9420
9421    exit(normal).
9422
9423
9424%%
9425%% MGC generator stuff
9426%%
9427otp_6276_mgc_event_sequence(text, tcp, Ctrl) ->
9428    Mid = {deviceName,"ctrl"},
9429    EM  = megaco_pretty_text_encoder,
9430    EC  = [],
9431    otp_6276_mgc_event_sequence2(Mid, EM, EC, Ctrl).
9432
9433otp_6276_mgc_event_sequence2(Mid, EM, EC, Ctrl) ->
9434    CTRL = self(),
9435    DecodeFun = otp_6276_mgc_decode_msg_fun(EM, EC),
9436    EncodeFun = otp_6276_mgc_encode_msg_fun(EM, EC),
9437    AnnounceMe = otp_6276_mgc_announce_fun(Ctrl),
9438    ServiceChangeReqVerify =
9439	otp_6276_mgc_verify_service_change_req_fun(Mid),
9440    ServiceChangeReply =
9441	otp_6276_mgc_service_change_reply_msg(Mid, 1, 0),
9442    NotifyReqVerify = otp_6276_mgc_verify_notify_request_fun(Ctrl),
9443    TermId = #megaco_term_id{id = ["00000000","00000000","01101101"]},
9444    AwaitNrSendOrder = otp_6276_mgc_await_notify_reply_send_order_fun(Ctrl),
9445    NotifyReply = otp_6276_mgc_notify_reply_msg(Mid, 2, 0, TermId),
9446    AwaitDoneOrder = otp_6276_mgc_await_done_order_fun(Ctrl),
9447    EvSeq =
9448	[
9449	 {trigger, AnnounceMe},
9450	 {debug,  true},
9451	 {decode, DecodeFun},
9452	 {encode, EncodeFun},
9453	 {listen, 2944},
9454
9455         %% ANNOUNCE READY
9456         {trigger, fun() -> CTRL ! announce_mgc end},
9457
9458	 {expect_accept, any},
9459	 {expect_receive, "service-change-req",
9460	  {ServiceChangeReqVerify, 10000}},
9461	 {send, "service-change-reply", ServiceChangeReply},
9462	 {expect_receive, "notify-request", {NotifyReqVerify, 5000}},
9463
9464	 {trigger, AwaitNrSendOrder},
9465
9466	 {send, "notify-reply", NotifyReply},
9467
9468	 {trigger, AwaitDoneOrder},
9469
9470	 disconnect
9471	 ],
9472    EvSeq.
9473
9474otp_6276_mgc_announce_fun(Pid) ->
9475    fun() ->
9476	    Pid ! {announce_mgc, self()}
9477    end.
9478
9479otp_6276_mgc_await_notify_reply_send_order_fun(Pid) ->
9480    fun() ->
9481	    receive
9482		{notify_reply_send, Pid} ->
9483		    Pid ! {notify_reply_send, self()}
9484	    end
9485    end.
9486
9487otp_6276_mgc_await_done_order_fun(Pid) ->
9488    fun() ->
9489	    receive
9490		{done, Pid} ->
9491		    Pid ! {done, self()}
9492	    end
9493    end.
9494
9495otp_6276_mgc_encode_msg_fun(Mod, Conf) ->
9496    fun(M) ->
9497            Mod:encode_message(Conf, M)
9498    end.
9499
9500otp_6276_mgc_decode_msg_fun(Mod, Conf) ->
9501    fun(M) ->
9502            Mod:decode_message(Conf, M)
9503    end.
9504
9505otp_6276_mgc_service_change_reply_msg(Mid, TransId, Cid) ->
9506    SCRP  = #'ServiceChangeResParm'{serviceChangeMgcId = Mid},
9507    SCRPs = {serviceChangeResParms,SCRP},
9508    Root  = #megaco_term_id{id = ["root"]},
9509    SCR   = #'ServiceChangeReply'{terminationID       = [Root],
9510                                  serviceChangeResult = SCRPs},
9511    CR    = {serviceChangeReply, SCR},
9512    otp_6276_mgc_msg(Mid, TransId, CR, Cid).
9513
9514otp_6276_mgc_notify_reply_msg(Mid, TransId, Cid, TermId) ->
9515    NR  = #'NotifyReply'{terminationID = [TermId]},
9516    CR  = {notifyReply, NR},
9517    otp_6276_mgc_msg(Mid, TransId, CR, Cid).
9518
9519otp_6276_mgc_msg(Mid, TransId, CR, Cid) ->
9520    AR  = #'ActionReply'{contextId    = Cid,
9521                         commandReply = [CR]},
9522    ARs  = {actionReplies, [AR]},
9523    TR   = #'TransactionReply'{transactionId     = TransId,
9524                               transactionResult = ARs},
9525    Body = {transactions, [{transactionReply, TR}]},
9526    Mess = #'Message'{version     = 1,
9527                      mId         = Mid,
9528                      messageBody = Body},
9529    #'MegacoMessage'{mess = Mess}.
9530
9531otp_6276_mgc_pending_msg(Mid, TransId) ->
9532    TP   = #'TransactionPending'{transactionId = TransId},
9533    Body = {transactions, [{transactionPending, TP}]},
9534    Mess = #'Message'{version     = 1,
9535                      mId         = Mid,
9536                      messageBody = Body},
9537    #'MegacoMessage'{mess = Mess}.
9538
9539otp_6276_mgc_verify_service_change_req_fun(_) ->
9540    fun(#'MegacoMessage'{mess = Mess} = M) ->
9541            #'Message'{version     = _V,
9542                       mId         = _Mid,
9543                       messageBody = Body} = Mess,
9544            {transactions, [Trans]} = Body,
9545            {transactionRequest, TR} = Trans,
9546            #'TransactionRequest'{transactionId = _Tid,
9547                                  actions = [AR]} = TR,
9548            #'ActionRequest'{contextId = _Cid,
9549                             contextRequest = _CtxReq,
9550                             contextAttrAuditReq = _CtxAar,
9551                             commandRequests = [CR]} = AR,
9552            #'CommandRequest'{command = Cmd,
9553                              optional = _Opt,
9554                              wildcardReturn = _WR} = CR,
9555            {serviceChangeReq, SCR} = Cmd,
9556            #'ServiceChangeRequest'{terminationID = _TermID,
9557                                    serviceChangeParms = SCP} = SCR,
9558            #'ServiceChangeParm'{serviceChangeMethod = restart,
9559                                 serviceChangeReason = [[$9,$0,$1|_]]} = SCP,
9560            {ok, M};
9561       (M) ->
9562            {error, {invalid_message, M}}
9563    end.
9564
9565otp_6276_mgc_verify_notify_request_fun(Pid) ->
9566    fun(M) ->
9567	    (catch otp_6276_mgc_verify_notify_request(M, Pid))
9568    end.
9569
9570otp_6276_mgc_verify_notify_request(#'MegacoMessage'{mess = Mess} = M,
9571				   Pid) ->
9572    io:format("otp_6276_mgc_verify_notify_request -> entry with"
9573	      "~n   M: ~p"
9574	      "~n", [M]),
9575    Body =
9576	case Mess of
9577	    #'Message'{messageBody = MessageBody} ->
9578		MessageBody;
9579	    _ ->
9580		throw({error, {invalid_mess, Mess}})
9581	end,
9582
9583    Trans =
9584	case Body of
9585            {transactions, [Transaction]} ->
9586		Transaction;
9587	    _ ->
9588		throw({error, {invalid_messageBody, Body}})
9589	end,
9590
9591    TR =
9592	case Trans of
9593            {transactionRequest, TransReq} ->
9594		TransReq;
9595	    _ ->
9596		throw({error, {invalid_transaction, Trans}})
9597	end,
9598
9599    AR =
9600	case TR of
9601            #'TransactionRequest'{actions = [Action]} ->
9602		Action;
9603	    _ ->
9604		throw({error, {invalid_transactionRequest, TR}})
9605	end,
9606
9607    io:format("otp_6276_mgc_verify_notify_request -> "
9608	      "~n   AR: ~p"
9609	      "~n", [AR]),
9610
9611    CR =
9612	case AR of
9613            #'ActionRequest'{commandRequests = [CommandReq]} ->
9614		CommandReq;
9615	    _ ->
9616		throw({error, {invalid_TransactionRequest, AR}})
9617	end,
9618
9619    Cmd =
9620	case CR of
9621            #'CommandRequest'{command = Command} ->
9622		Command;
9623	    _ ->
9624		throw({error, {invalid_ActionRequest, CR}})
9625	end,
9626
9627    NR =
9628	case Cmd of
9629            {notifyReq, NotifReq} ->
9630		NotifReq;
9631	    _ ->
9632		throw({error, {invalid_CommandRequest, Cmd}})
9633	end,
9634
9635    OED =
9636	case NR of
9637            #'NotifyRequest'{observedEventsDescriptor = ObsEvDesc} ->
9638		ObsEvDesc;
9639	    _ ->
9640		throw({error, {invalid_notifyReq, NR}})
9641	end,
9642
9643    OE =
9644	case OED of
9645            #'ObservedEventsDescriptor'{observedEventLst = [ObsEv]} ->
9646		ObsEv;
9647	    _ ->
9648		throw({error, {invalid_NotifyRequest, OED}})
9649	end,
9650
9651    case OE of
9652	#'ObservedEvent'{eventName = "al/of"} ->
9653            ok;
9654	_ ->
9655	    throw({error, {invalid_ObservedEventsDescriptor, OE}})
9656    end,
9657    io:format("otp_6276_mgc_verify_notify_request -> "
9658	      "send notify_request received to "
9659	      "~n   Pid:    ~p"
9660	      "~n   self(): ~p"
9661	      "~n", [Pid, self()]),
9662    Pid ! {notify_request_received, self()},
9663    {ok, M};
9664otp_6276_mgc_verify_notify_request(M, _Pid) ->
9665    {error, {invalid_message, M}}.
9666
9667
9668%%
9669%% MG generator stuff
9670%%
9671otp_6276_mg_event_sequence(text, tcp, Ctrl) ->
9672    Mid = {deviceName,"mg"},
9673    RI = [
9674          {port,             2944},
9675          {encoding_module,  megaco_pretty_text_encoder},
9676          {encoding_config,  []},
9677          {transport_module, megaco_tcp}
9678         ],
9679    otp_6276_mg_event_sequence2(Mid, RI, Ctrl).
9680
9681otp_6276_mg_event_sequence2(Mid, RI, Ctrl) ->
9682    AnnounceMe = otp_6276_mg_announce_fun(Ctrl),
9683    ServiceChangeReq = [otp_6276_mg_service_change_request_ar(Mid, 1)],
9684    ConnectVerify = fun otp_6276_mg_verify_handle_connect/1,
9685    ServiceChangeReplyVerify =
9686	fun otp_6276_mg_verify_service_change_reply/1,
9687    Tid = #megaco_term_id{id = ["00000000","00000000","01101101"]},
9688    NotifyReq = [otp_6276_mg_notify_request_ar(1, Tid, 1)],
9689    AwaitCancelOrder = otp_6276_mg_await_cancel_order_fun(Ctrl),
9690    TransReplyVerify = otp_6276_mg_verify_trans_reply_fun(Ctrl),
9691    UnexpTransVerify = otp_6276_mg_verify_unexpected_trans_fun(Ctrl),
9692    EvSeq = [
9693	     {trigger, AnnounceMe},
9694             {debug, true},
9695             megaco_start,
9696             {megaco_start_user, Mid, RI, []},
9697	     {megaco_update_user_info, recv_pending_limit, 4},
9698             start_transport,
9699             {megaco_trace, disable}, %%100},
9700             {megaco_system_info, users},
9701             {megaco_system_info, connections},
9702             connect,
9703             {megaco_callback, handle_connect, ConnectVerify},
9704             megaco_connect,
9705             {megaco_cast, ServiceChangeReq, []},
9706             {megaco_callback, handle_connect, ConnectVerify},
9707             {megaco_callback, handle_trans_reply, ServiceChangeReplyVerify},
9708             {sleep, 1000},
9709             {megaco_cast, NotifyReq, []},
9710
9711	     {trigger, AwaitCancelOrder},
9712
9713	     {megaco_cancel, otp_6276},
9714
9715             {megaco_callback, handle_trans_reply, TransReplyVerify},
9716             {megaco_callback, handle_unexpected_trans,  UnexpTransVerify},
9717             {sleep, 1000},
9718             megaco_stop_user,
9719             megaco_stop,
9720             {sleep, 1000}
9721            ],
9722    EvSeq.
9723
9724otp_6276_mg_announce_fun(Pid) ->
9725    fun() ->
9726	    Pid ! {announce_mg, self()}
9727    end.
9728
9729otp_6276_mg_await_cancel_order_fun(Pid) ->
9730    fun() ->
9731	    io:format("otp_6276_mg_await_cancel_order_fun -> entry with"
9732		      "~n   Pid:    ~p"
9733		      "~n   self(): ~p"
9734		      "~n", [Pid, self()]),
9735	    receive
9736		{start_cancel, Pid} ->
9737		    io:format("otp_6276_mg_await_cancel_order_fun -> "
9738			      "received cancel start order"
9739			      "~n   Pid:    ~p"
9740			      "~n   self(): ~p"
9741			      "~n", [Pid, self()]),
9742		    Pid ! {started_cancel, self()}
9743	    end
9744    end.
9745
9746otp_6276_mg_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
9747    io:format("otp_6276_mg_verify_handle_connect -> ok"
9748	      "~n   CH: ~p~n", [CH]),
9749    {ok, CH, ok};
9750otp_6276_mg_verify_handle_connect(Else) ->
9751    io:format("otp_6276_mg_verify_handle_connect -> unknown"
9752	      "~n   Else: ~p~n", [Else]),
9753    {error, Else, ok}.
9754
9755otp_6276_mg_verify_service_change_reply({handle_trans_reply, _CH,
9756					       ?VERSION,
9757					       {ok, [AR]}, _}) ->
9758    io:format("otp_6276_mg_verify_service_change_reply -> ok"
9759	      "~n   AR: ~p~n", [AR]),
9760    case AR of
9761	#'ActionReply'{commandReply = [SCR]} ->
9762	    case SCR of
9763		{serviceChangeReply,
9764		 #'ServiceChangeReply'{terminationID = [Tid],
9765				       serviceChangeResult = Res}} ->
9766		    case Tid of
9767			#megaco_term_id{contains_wildcards = false,
9768					id = ["root"]} ->
9769			    case Res of
9770				{serviceChangeResParms,
9771				 #'ServiceChangeResParm'{
9772				   serviceChangeMgcId = _RemoteMid}} ->
9773				    {ok, AR, ok};
9774				{Tag, Val} ->
9775				    Err = {invalid_service_change_result,
9776					   Tag, Val},
9777				    {error, Err, ok}
9778			    end;
9779			_ ->
9780			    Err = {invalid_termination_id, Tid},
9781			    {error, Err, ok}
9782		    end;
9783		{Tag, Val} ->
9784		    Err = {invalid_command_reply, Tag, Val},
9785		    {error, Err, ok}
9786	    end;
9787	_ ->
9788	    Err = {invalid_action_reply, AR},
9789	    {error, Err, ok}
9790    end;
9791otp_6276_mg_verify_service_change_reply(Else) ->
9792    io:format("otp_6276_mg_verify_service_change_reply -> unknown"
9793	      "~n   Else: ~p~n", [Else]),
9794    {error, Else, ok}.
9795
9796otp_6276_mg_verify_trans_reply_fun(Pid) ->
9797    fun(Event) ->
9798	    otp_6276_mg_verify_trans_reply(Pid, Event)
9799    end.
9800
9801otp_6276_mg_verify_trans_reply(Pid,
9802  {handle_trans_reply, _CH, ?VERSION,
9803   {error, {user_cancel, otp_6276}} = E, _}) ->
9804    io:format("otp_6276_mg_verify_trans_reply -> expected error"
9805	      "~n", []),
9806    Pid ! {notify_request_cancelled, self()},
9807    {ok, E, error};
9808otp_6276_mg_verify_trans_reply(_Pid,
9809  {handle_trans_reply, _CH, ?VERSION,
9810   {error, Reason} = E, _}) ->
9811    io:format("otp_6276_mg_verify_trans_reply -> unexpected error"
9812	      "~n   Reason: ~p"
9813	      "~n", [Reason]),
9814    {error, E, error};
9815otp_6276_mg_verify_trans_reply(_Pid,
9816  {handle_trans_reply, _CH, ?VERSION, Result, _}) ->
9817    io:format("otp_6276_mg_verify_trans_reply -> unexpected result"
9818	      "~n   Result: ~p"
9819	      "~n", [Result]),
9820    {error, Result, error};
9821otp_6276_mg_verify_trans_reply(_Pid, Else) ->
9822    io:format("otp_6276_mg_verify_trans_reply -> unknown event"
9823	      "~n   Else: ~p"
9824	      "~n", [Else]),
9825    {error, Else, error}.
9826
9827otp_6276_mg_verify_unexpected_trans_fun(Pid) ->
9828    fun(Event) ->
9829	    otp_6276_mg_verify_unexpected_trans(Pid, Event)
9830    end.
9831
9832otp_6276_mg_verify_unexpected_trans(Pid,
9833  {handle_unexpected_trans, RH, ?VERSION, Trans}) ->
9834    io:format("otp_6276_mg_verify_unexpected_trans -> expected event"
9835	      "~n   RH:    ~p"
9836	      "~n   Trans: ~p"
9837	      "~n", [RH, Trans]),
9838    Pid ! {unexpected_trans, self(), Trans},
9839    {ok, Trans, error};
9840otp_6276_mg_verify_unexpected_trans(_Pid, Else) ->
9841    io:format("otp_6276_mg_verify_unexpected_trans -> unknown event"
9842	      "~n   Else: ~p"
9843	      "~n", [Else]),
9844    {error, Else, error}.
9845
9846otp_6276_mg_service_change_request_ar(_Mid, Cid) ->
9847    Prof  = cre_serviceChangeProf("resgw", 1),
9848    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
9849    Root  = #megaco_term_id{id = ["root"]},
9850    SCR   = cre_serviceChangeReq([Root], SCP),
9851    CMD   = cre_command(SCR),
9852    CR    = cre_cmdReq(CMD),
9853    cre_actionReq(Cid, [CR]).
9854
9855otp_6276_mg_notify_request_ar(Rid, Tid, Cid) ->
9856    TT      = cre_timeNotation("19990729", "22000000"),
9857    Ev      = cre_obsEvent("al/of", TT),
9858    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
9859    NR      = cre_notifyReq([Tid], EvsDesc),
9860    CMD     = cre_command(NR),
9861    CR      = cre_cmdReq(CMD),
9862    cre_actionReq(Cid, [CR]).
9863
9864
9865-else.  % -ifdef(MEGACO_TEST_CODE).
9866
9867otp_6276(suite) ->
9868    [];
9869otp_6276(doc) ->
9870    "OTP-6276";
9871otp_6276(Config) when is_list(Config) ->
9872
9873    ?SKIP("included only if compiled with USE_MEGACO_TEST_CODE=true").
9874
9875-endif. % -ifdef(MEGACO_TEST_CODE).
9876
9877
9878%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9879
9880
9881otp_6442_resend_request1(suite) ->
9882    [];
9883otp_6442_resend_request1(Config) when is_list(Config) ->
9884    Pre = fun() ->
9885                  MgNode = make_node_name(mg),
9886                  d("start (MG) node: ~p", [MgNode]),
9887                  Nodes = [MgNode],
9888                  ok = ?START_NODES(Nodes, true),
9889                  Nodes
9890          end,
9891    Case = fun do_otp_6442_resend_request1/1,
9892    Post = fun(Nodes) ->
9893                   d("stop nodes"),
9894                   ?STOP_NODES(lists:reverse(Nodes))
9895           end,
9896    try_tc(otp6442rreq1, Pre, Case, Post).
9897
9898do_otp_6442_resend_request1([MgNode]) ->
9899    d("[MG] start the simulator"),
9900    {ok, Mg} = megaco_test_megaco_generator:start_link("MG", MgNode),
9901
9902    d("[MG] create the event sequence (~p)", [Mg]),
9903    MgMid = {deviceName,"mg"},
9904    MgEvSeq = otp_6442_resend_request1_mg_event_sequence(MgMid),
9905
9906    i("wait some time before starting the MG simulation"),
9907    sleep(1000),
9908
9909    d("[MG] start the simulation"),
9910    {ok, MgId} = megaco_test_megaco_generator:exec(Mg, MgEvSeq),
9911
9912    i("await the transport module service change send_message event"),
9913    Pid = otp_6442_expect(fun otp_6442_rsrq1_verify_scr_msg/1, 5000),
9914
9915    i("wait some before issuing the service change reply"),
9916    sleep(500),
9917
9918    i("send the service change reply"),
9919    MgcMid = {deviceName,"mgc"},
9920    ServiceChangeReply = otp_6442_mgc_service_change_reply_msg(MgcMid, 1, 1),
9921    megaco_test_generic_transport:incomming_message(Pid, ServiceChangeReply),
9922
9923    i("await the transport module "
9924      "notify-request send_message event from MG: "
9925      "ignore"),
9926    ok = otp_6442_expect(fun otp_6442_rsrq1_verify_first_nr_msg/1, 5000),
9927
9928    i("await the transport module "
9929      "notify-request resend_message event from MG: "
9930      "reply"),
9931    {TransId2, Cid2, TermId2} =
9932	otp_6442_expect(fun otp_6442_rsrq1_verify_second_nr_msg/1, 10000),
9933
9934    i("wait some before issuing the notify reply"),
9935    sleep(500),
9936
9937    i("send the notify reply"),
9938    NotifyReply =
9939	otp_6442_mgc_notify_reply_msg(MgcMid, TransId2, Cid2, TermId2),
9940    megaco_test_generic_transport:incomming_message(Pid, NotifyReply),
9941
9942    d("await the generator reply"),
9943    await_completion([MgId]),
9944
9945    %% Tell Mg to stop
9946    i("[MG] stop generator"),
9947    megaco_test_megaco_generator:stop(Mg),
9948
9949    i("done", []),
9950    ok.
9951
9952
9953otp_6442_expect(Verify, Timeout) when (Timeout > 0) ->
9954    T = mtime(),
9955    receive
9956	Msg ->
9957	    case (catch Verify(Msg)) of
9958		{ok, Result} ->
9959		    d("verified after ~p msec", [mtime() - T]),
9960		    Result;
9961		skip ->
9962		    otp_6442_expect(Verify, to(Timeout, T));
9963		{error, Reason} ->
9964		    exit({verification_failed, Reason})
9965	    end
9966    after Timeout ->
9967	    exit(timeout)
9968    end;
9969otp_6442_expect(_, _Timeout) ->
9970    exit(timeout).
9971
9972otp_6442_rsrq1_verify_scr_msg(
9973  {transport_event, {send_message, _SH, {message, Msg}}, Pid})
9974  when is_record(Msg, 'MegacoMessage') ->
9975    d("received expected service change request message: "
9976      "~n   Msg: ~p", [Msg]),
9977    Reply = ok,
9978    Pid ! {transport_reply, Reply, self()},
9979    {ok, Pid};
9980otp_6442_rsrq1_verify_scr_msg(
9981  {transport_event, {send_message, _SH, BadMsg}, _Pid}) ->
9982    io:format("otp_6442_rsrq1_verify_scr_msg -> error: "
9983	      "~n   BadMsg: ~p"
9984	      "~n", [BadMsg]),
9985    {error, {invalid_message, BadMsg}};
9986otp_6442_rsrq1_verify_scr_msg({transport_event, BadEvent, _Pid}) ->
9987    io:format("otp_6442_rsrq1_verify_scr_msg -> error: "
9988	      "~n   BadEvent: ~p"
9989	      "~n", [BadEvent]),
9990    {error, {invalid_message, BadEvent}};
9991otp_6442_rsrq1_verify_scr_msg(Msg) ->
9992    io:format("otp_6442_rsrq1_verify_scr_msg -> error: "
9993	      "~n   Msg: ~p"
9994	      "~n", [Msg]),
9995    {error, {invalid_message, Msg}}.
9996
9997otp_6442_rsrq1_verify_first_nr_msg(
9998  {transport_event, {send_message, _SH, {message, Msg}}, Pid})
9999  when is_record(Msg, 'MegacoMessage') ->
10000    d("received expected first notify request send message: "
10001      "~n   Msg: ~p", [Msg]),
10002    Reply = ok,
10003    Pid ! {transport_reply, Reply, self()},
10004    {ok, ok};
10005otp_6442_rsrq1_verify_first_nr_msg(Msg) ->
10006    io:format("otp_6442_rsrq1_verify_nr_msg -> error: "
10007	      "~n   Msg: ~p"
10008	      "~n", [Msg]),
10009    {error, {invalid_message, Msg}}.
10010
10011otp_6442_rsrq1_verify_second_nr_msg(
10012  {transport_event, {send_message, _SH, {message, Msg}}, Pid})
10013  when is_record(Msg, 'MegacoMessage') ->
10014    io:format("otp_6442_rsrq1_verify_second_nr_msg -> "
10015	      "entry when received expected message with"
10016	      "~n   Msg: ~p"
10017	      "~n", [Msg]),
10018    Reply = ok,
10019    Pid ! {transport_reply, Reply, self()},
10020    #'MegacoMessage'{mess = Mess} = Msg,
10021    #'Message'{mId         = _Mid,
10022	       messageBody = Body} = Mess,
10023    {transactions, Transactions} = Body,
10024    [Transaction] = Transactions,
10025    {transactionRequest, TransReq} = Transaction,
10026    #'TransactionRequest'{transactionId = TransId,
10027			  actions       = Actions} = TransReq,
10028    [Action] = Actions,
10029    #'ActionRequest'{contextId       = Cid,
10030		     commandRequests = CmdReqs} = Action,
10031    [CmdReq] = CmdReqs,
10032    #'CommandRequest'{command = Cmd} = CmdReq,
10033    {notifyReq, NR} = Cmd,
10034    #'NotifyRequest'{terminationID = [TermId]} = NR,
10035    {ok, {TransId, Cid, TermId}};
10036otp_6442_rsrq1_verify_second_nr_msg(Msg) ->
10037    io:format("otp_6442_rsrq1_verify_second_nr_msg -> entry when error with"
10038	      "~n   Msg: ~p"
10039	      "~n", [Msg]),
10040    {error, {invalid_message, Msg}}.
10041
10042
10043otp_6442_mgc_service_change_reply_msg(Mid, TransId, Cid) ->
10044    SCRP  = #'ServiceChangeResParm'{serviceChangeMgcId = Mid},
10045    SCRPs = {serviceChangeResParms, SCRP},
10046    Root  = #megaco_term_id{id = ["root"]},
10047    SCR   = #'ServiceChangeReply'{terminationID       = [Root],
10048                                  serviceChangeResult = SCRPs},
10049    CR    = {serviceChangeReply, SCR},
10050    otp_6442_mgc_reply_msg(Mid, TransId, CR, Cid).
10051
10052otp_6442_mgc_notify_reply_msg(Mid, TransId, Cid, TermId) ->
10053    NR  = #'NotifyReply'{terminationID = [TermId]},
10054    CR  = {notifyReply, NR},
10055    otp_6442_mgc_reply_msg(Mid, TransId, CR, Cid).
10056
10057otp_6442_mgc_reply_msg(Mid, TransId, CR, Cid) ->
10058    AR  = #'ActionReply'{contextId    = Cid,
10059                         commandReply = [CR]},
10060    ARs  = {actionReplies, [AR]},
10061    TR   = #'TransactionReply'{transactionId     = TransId,
10062                               transactionResult = ARs},
10063    Body = {transactions, [{transactionReply, TR}]},
10064    Mess = #'Message'{version     = 1,
10065                      mId         = Mid,
10066                      messageBody = Body},
10067    #'MegacoMessage'{mess = Mess}.
10068
10069
10070%%
10071%% MG generator stuff
10072%%
10073-ifdef(megaco_hipe_special).
10074-define(otp_6442_resend_request1_mg_verify_handle_connect_fun(),
10075	{?MODULE, otp_6442_resend_request1_mg_verify_handle_connect, []}).
10076-define(otp_6442_resend_request1_mg_verify_service_change_rep_fun(),
10077	{?MODULE, otp_6442_resend_request1_mg_verify_service_change_rep, []}).
10078-define(otp_6442_resend_request1_mg_verify_notify_rep_fun(),
10079	{?MODULE, otp_6442_resend_request1_mg_verify_notify_rep, []}).
10080-else.
10081-define(otp_6442_resend_request1_mg_verify_handle_connect_fun(),
10082	otp_6442_resend_request1_mg_verify_handle_connect_fun()).
10083-define(otp_6442_resend_request1_mg_verify_service_change_rep_fun(),
10084	otp_6442_resend_request1_mg_verify_service_change_rep_fun()).
10085-define(otp_6442_resend_request1_mg_verify_notify_rep_fun(),
10086	otp_6442_resend_request1_mg_verify_notify_rep_fun()).
10087-endif.
10088
10089otp_6442_resend_request1_mg_event_sequence(Mid) ->
10090    RI = [
10091          {port,             self()}, % This is just a trick to get my pid to the transport module
10092          {encoding_module,  megaco_pretty_text_encoder},
10093          {encoding_config,  []},
10094          {transport_module, megaco_test_generic_transport}
10095         ],
10096    ServiceChangeReq =
10097	otp_6442_resend_request1_mg_service_change_request_ar(Mid, 1),
10098    Tid = #megaco_term_id{id = ["00000000","00000000","01101101"]},
10099    NotifyReq = otp_6442_resend_request1_mg_notify_request_ar(1, Tid, 1),
10100    ConnectVerify =
10101	?otp_6442_resend_request1_mg_verify_handle_connect_fun(),
10102    ServiceChangeReplyVerify =
10103	?otp_6442_resend_request1_mg_verify_service_change_rep_fun(),
10104    NotifyReplyVerify =
10105	?otp_6442_resend_request1_mg_verify_notify_rep_fun(),
10106    EvSeq = [
10107             {debug, false},
10108             megaco_start,
10109             {megaco_start_user, Mid, RI, []},
10110	     {megaco_update_user_info, resend_indication, false},
10111             start_transport,
10112             {megaco_trace, disable},
10113             {megaco_system_info, users},
10114             {megaco_system_info, connections},
10115             connect,
10116             {megaco_callback, handle_connect, ConnectVerify},
10117             megaco_connect,
10118             {megaco_cast,     [ServiceChangeReq], []},
10119             {megaco_callback, handle_connect,     ConnectVerify},
10120             {megaco_callback, handle_trans_reply, ServiceChangeReplyVerify},
10121             {sleep, 1000},
10122             {megaco_cast,     [NotifyReq],        []},
10123             {megaco_callback, handle_trans_reply, NotifyReplyVerify},
10124             {sleep, 1000},
10125             megaco_stop_user,
10126             megaco_stop,
10127             {sleep, 1000}
10128            ],
10129    EvSeq.
10130
10131
10132-ifndef(megaco_hipe_special).
10133otp_6442_resend_request1_mg_verify_handle_connect_fun() ->
10134    fun(Ev) ->
10135	    otp_6442_resend_request1_mg_verify_handle_connect(Ev)
10136    end.
10137-endif.
10138
10139otp_6442_resend_request1_mg_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
10140    io:format("otp_6442_resend_request1_mg_verify_handle_connect -> ok"
10141	      "~n   CH: ~p~n", [CH]),
10142    {ok, CH, ok};
10143otp_6442_resend_request1_mg_verify_handle_connect(Else) ->
10144    io:format("otp_6442_resend_request1_mg_verify_handle_connect -> unknown"
10145	      "~n   Else: ~p~n", [Else]),
10146    {error, Else, ok}.
10147
10148-ifndef(megaco_hipe_special).
10149otp_6442_resend_request1_mg_verify_service_change_rep_fun() ->
10150    fun(Rep) ->
10151	    otp_6442_resend_request1_mg_verify_service_change_rep(Rep)
10152    end.
10153-endif.
10154
10155otp_6442_resend_request1_mg_verify_service_change_rep(
10156  {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _}) ->
10157    (catch otp_6442_resend_request1_mg_do_verify_service_change_rep(AR));
10158otp_6442_resend_request1_mg_verify_service_change_rep(Crap) ->
10159    {error, Crap, ok}.
10160
10161otp_6442_resend_request1_mg_do_verify_service_change_rep(AR) ->
10162    io:format("otp_6442_resend_request1_mg_verify_service_change_rep -> ok"
10163	      "~n   AR: ~p~n", [AR]),
10164    CR =
10165	case AR of
10166	    #'ActionReply'{commandReply = [CmdRep]} ->
10167		CmdRep;
10168	    _ ->
10169		Reason1 = {invalid_action_reply, AR},
10170		throw({error, Reason1, ok})
10171	end,
10172    SCR =
10173	case CR of
10174	    {serviceChangeReply, ServChRep} ->
10175		ServChRep;
10176	    _ ->
10177		Reason2 = {invalid_command_reply, CR},
10178		throw({error, Reason2, ok})
10179	end,
10180    {Tid, SCRes} =
10181	case SCR of
10182	    #'ServiceChangeReply'{terminationID       = [TermID],
10183				  serviceChangeResult = Res} ->
10184		{TermID, Res};
10185	    _ ->
10186		Reason3 = {invalid_service_change_reply, SCR},
10187		throw({error, Reason3, ok})
10188	end,
10189    case Tid of
10190	#megaco_term_id{contains_wildcards = false, id = ["root"]} ->
10191	    ok;
10192	_ ->
10193	    Reason4 = {invalid_termination_id, Tid},
10194	    throw({error, Reason4, ok})
10195    end,
10196    SCRParm =
10197	case SCRes of
10198	    {serviceChangeResParms, ServChResParms} ->
10199		ServChResParms;
10200	    _ ->
10201		Reason5 = {invalid_serviceChangeResult, SCRes},
10202		throw({error, Reason5, ok})
10203	end,
10204    case SCRParm of
10205	#'ServiceChangeResParm'{serviceChangeMgcId = _RemoteMid} ->
10206	    {ok, AR, ok};
10207	_ ->
10208	    Reason6 = {invalid_service_change_result, SCRParm},
10209	    {error, Reason6, ok}
10210    end.
10211
10212-ifndef(megaco_hipe_special).
10213otp_6442_resend_request1_mg_verify_notify_rep_fun() ->
10214    fun(Rep) ->
10215	    otp_6442_resend_request1_mg_verify_notify_rep(Rep)
10216    end.
10217-endif.
10218
10219otp_6442_resend_request1_mg_verify_notify_rep(
10220  {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _}) ->
10221    io:format("otp_6442_resend_request1_mg_verify_notify_rep -> ok"
10222	      "~n   AR: ~p~n", [AR]),
10223    {ok, AR, ok};
10224otp_6442_resend_request1_mg_verify_notify_rep(Else) ->
10225    io:format("otp_6442_resend_request1_mg_verify_notify_rep -> unknown"
10226	      "~n   Else: ~p~n", [Else]),
10227    {error, Else, ok}.
10228
10229
10230otp_6442_resend_request1_mg_service_change_request_ar(_Mid, Cid) ->
10231    Prof  = cre_serviceChangeProf("resgw", 1),
10232    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
10233    Root  = #megaco_term_id{id = ["root"]},
10234    SCR   = cre_serviceChangeReq([Root], SCP),
10235    CMD   = cre_command(SCR),
10236    CR    = cre_cmdReq(CMD),
10237    cre_actionReq(Cid, [CR]).
10238
10239otp_6442_resend_request1_mg_notify_request_ar(Rid, Tid, Cid) ->
10240    TT      = cre_timeNotation("19990729", "22000000"),
10241    Ev      = cre_obsEvent("al/of", TT),
10242    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
10243    NR      = cre_notifyReq([Tid], EvsDesc),
10244    CMD     = cre_command(NR),
10245    CR      = cre_cmdReq(CMD),
10246    cre_actionReq(Cid, [CR]).
10247
10248
10249
10250%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10251
10252otp_6442_resend_request2(suite) ->
10253    [];
10254otp_6442_resend_request2(Config) when is_list(Config) ->
10255    Pre = fun() ->
10256                  MgNode = make_node_name(mg),
10257                  d("start (MG) node: ~p", [MgNode]),
10258                  Nodes = [MgNode],
10259                  ok = ?START_NODES(Nodes, true),
10260                  Nodes
10261          end,
10262    Case = fun do_otp_6442_resend_request2/1,
10263    Post = fun(Nodes) ->
10264                   d("stop nodes"),
10265                   ?STOP_NODES(lists:reverse(Nodes))
10266           end,
10267    try_tc(otp6442rreq2, Pre, Case, Post).
10268
10269do_otp_6442_resend_request2([MgNode]) ->
10270    d("[MG] start the simulator "),
10271    {ok, Mg} = megaco_test_megaco_generator:start_link("MG", MgNode),
10272
10273    d("[MG] create the event sequence"),
10274    Mid = {deviceName,"mg"},
10275    MgcMid = {deviceName,"mgc"},
10276    MgEvSeq = otp_6442_resend_request2_mg_event_sequence(Mid),
10277
10278    i("wait some time before starting the MG simulation"),
10279    sleep(1000),
10280
10281    d("[MG] start the simulation"),
10282    {ok, MgId} = megaco_test_megaco_generator:exec(Mg, MgEvSeq),
10283
10284    i("await the transport module service change send_message event"),
10285    Pid = otp_6442_expect(fun otp_6442_rsrq2_verify_scr_msg/1, 5000),
10286
10287    i("wait some before issuing the service change reply"),
10288    sleep(500),
10289
10290    i("send the service change reply"),
10291    ServiceChangeReply = otp_6442_mgc_service_change_reply_msg(MgcMid, 1, 1),
10292    megaco_test_generic_transport:incomming_message(Pid, ServiceChangeReply),
10293
10294    i("await the transport module notify-request send_message event from MG: ignore"),
10295    ok = otp_6442_expect(fun otp_6442_rsrq2_verify_first_nr_msg/1, 5000),
10296
10297    i("await the transport module notify-request resend_message event from MG: reply"),
10298    {TransId2, Cid2, TermId2} =
10299	otp_6442_expect(fun otp_6442_rsrq2_verify_second_nr_msg/1, 10000),
10300
10301    i("wait some before issuing the notify reply"),
10302    sleep(500),
10303
10304    i("send the notify reply"),
10305    NotifyReply = otp_6442_mgc_notify_reply_msg(MgcMid, TransId2, Cid2, TermId2),
10306    megaco_test_generic_transport:incomming_message(Pid, NotifyReply),
10307
10308    d("await the generator reply"),
10309    await_completion([MgId]),
10310
10311    %% Tell Mg to stop
10312    i("[MG] stop generator"),
10313    megaco_test_megaco_generator:stop(Mg),
10314
10315    i("done", []),
10316    ok.
10317
10318
10319otp_6442_rsrq2_verify_scr_msg(
10320  {transport_event, {send_message, _SH, {message, Msg}}, Pid})
10321  when is_record(Msg, 'MegacoMessage') ->
10322    d("received expected service change request message: "
10323      "~n   Msg: ~p", [Msg]),
10324    Reply = ok,
10325    Pid ! {transport_reply, Reply, self()},
10326    {ok, Pid};
10327otp_6442_rsrq2_verify_scr_msg(Msg) ->
10328    io:format("otp_6442_rsrq2_verify_nr_msg -> error: "
10329	      "~n   Msg: ~p"
10330	      "~n", [Msg]),
10331    {error, {invalid_message, Msg}}.
10332
10333otp_6442_rsrq2_verify_first_nr_msg(
10334  {transport_event, {send_message, _SH, {message, Msg}}, Pid})
10335  when is_record(Msg, 'MegacoMessage') ->
10336    d("received expected first notify request message: "
10337      "~n   Msg: ~p", [Msg]),
10338    Reply = ok,
10339    Pid ! {transport_reply, Reply, self()},
10340    {ok, ok};
10341otp_6442_rsrq2_verify_first_nr_msg(Msg) ->
10342    {error, {invalid_message, Msg}}.
10343
10344otp_6442_rsrq2_verify_second_nr_msg(
10345  {transport_event, {resend_message, _SH, {message, Msg}}, Pid})
10346  when is_record(Msg, 'MegacoMessage') ->
10347    d("received expected second notify request message: "
10348      "~n   Msg: ~p", [Msg]),
10349    Reply = ok,
10350    Pid ! {transport_reply, Reply, self()},
10351    #'MegacoMessage'{mess = Mess} = Msg,
10352    #'Message'{mId         = _Mid,
10353	       messageBody = Body} = Mess,
10354    {transactions, Transactions} = Body,
10355    [Transaction] = Transactions,
10356    {transactionRequest, TransReq} = Transaction,
10357    #'TransactionRequest'{transactionId = TransId,
10358			  actions       = Actions} = TransReq,
10359    [Action] = Actions,
10360    #'ActionRequest'{contextId       = Cid,
10361		     commandRequests = CmdReqs} = Action,
10362    [CmdReq] = CmdReqs,
10363    #'CommandRequest'{command = Cmd} = CmdReq,
10364    {notifyReq, NR} = Cmd,
10365    #'NotifyRequest'{terminationID = [TermId]} = NR,
10366    {ok, {TransId, Cid, TermId}};
10367otp_6442_rsrq2_verify_second_nr_msg(Msg) ->
10368    {error, {invalid_message, Msg}}.
10369
10370
10371%%
10372%% MG generator stuff
10373%%
10374-ifdef(megaco_hipe_special).
10375-define(otp_6442_resend_request2_mg_verify_handle_connect_fun(),
10376	{?MODULE, otp_6442_resend_request2_mg_verify_handle_connect, []}).
10377-define(otp_6442_resend_request2_mg_verify_service_change_rep_fun(),
10378	{?MODULE, otp_6442_resend_request2_mg_verify_service_change_rep, []}).
10379-define(otp_6442_resend_request2_mg_verify_notify_rep_fun(),
10380	{?MODULE, otp_6442_resend_request2_mg_verify_notify_rep, []}).
10381-else.
10382-define(otp_6442_resend_request2_mg_verify_handle_connect_fun(),
10383	otp_6442_resend_request2_mg_verify_handle_connect_fun()).
10384-define(otp_6442_resend_request2_mg_verify_service_change_rep_fun(),
10385	otp_6442_resend_request2_mg_verify_service_change_rep_fun()).
10386-define(otp_6442_resend_request2_mg_verify_notify_rep_fun(),
10387	otp_6442_resend_request2_mg_verify_notify_rep_fun()).
10388-endif.
10389
10390otp_6442_resend_request2_mg_event_sequence(Mid) ->
10391    RI = [
10392          {port,             self()}, % This is just a trick to get my pid to the transport module
10393          {encoding_module,  megaco_pretty_text_encoder},
10394          {encoding_config,  []},
10395          {transport_module, megaco_test_generic_transport}
10396         ],
10397    Tid = #megaco_term_id{id = ["00000000","00000000","01101101"]},
10398    NotifyReq = otp_6442_resend_request2_mg_notify_request_ar(1, Tid, 1),
10399    ServiceChangeReq =
10400	otp_6442_resend_request2_mg_service_change_request_ar(Mid, 1),
10401    ConnectVerify =
10402	?otp_6442_resend_request2_mg_verify_handle_connect_fun(),
10403    ServiceChangeReplyVerify =
10404	?otp_6442_resend_request2_mg_verify_service_change_rep_fun(),
10405    NotifyReplyVerify =
10406	?otp_6442_resend_request2_mg_verify_notify_rep_fun(),
10407%%     ConnectVerify =
10408%% 	otp_6442_resend_request2_mg_verify_handle_connect_fun(),
10409%%     ServiceChangeReplyVerify =
10410%% 	otp_6442_resend_request2_mg_verify_service_change_reply_fun(),
10411%%     NotifyReplyVerify = otp_6442_resend_request2_mg_verify_notify_reply_fun(),
10412    EvSeq = [
10413             {debug, false},
10414             megaco_start,
10415             {megaco_start_user, Mid, RI, []},
10416	     {megaco_update_user_info, resend_indication, true},
10417             start_transport,
10418             {megaco_trace, disable},
10419             {megaco_system_info, users},
10420             {megaco_system_info, connections},
10421             connect,
10422             {megaco_callback, handle_connect, ConnectVerify},
10423             megaco_connect,
10424             {megaco_cast,     [ServiceChangeReq], []},
10425             {megaco_callback, handle_connect,     ConnectVerify},
10426             {megaco_callback, handle_trans_reply, ServiceChangeReplyVerify},
10427             {sleep, 1000},
10428             {megaco_cast,     [NotifyReq],        []},
10429             {megaco_callback, handle_trans_reply, NotifyReplyVerify},
10430             {sleep, 1000},
10431             megaco_stop_user,
10432             megaco_stop,
10433             {sleep, 1000}
10434            ],
10435    EvSeq.
10436
10437
10438-ifndef(megaco_hipe_special).
10439otp_6442_resend_request2_mg_verify_handle_connect_fun() ->
10440    fun(Ev) ->
10441	    otp_6442_resend_request2_mg_verify_handle_connect(Ev)
10442    end.
10443-endif.
10444
10445otp_6442_resend_request2_mg_verify_handle_connect(
10446  {handle_connect, CH, ?VERSION}) ->
10447    io:format("otp_6442_resend_request2_mg_verify_handle_connect -> ok"
10448	      "~n   CH: ~p~n", [CH]),
10449    {ok, CH, ok};
10450otp_6442_resend_request2_mg_verify_handle_connect(Else) ->
10451    io:format("otp_6442_resend_request2_mg_verify_handle_connect -> unknown"
10452	      "~n   Else: ~p~n", [Else]),
10453    {error, Else, ok}.
10454
10455
10456-ifndef(megaco_hipe_special).
10457otp_6442_resend_request2_mg_verify_service_change_rep_fun() ->
10458    fun(Rep) ->
10459	    otp_6442_resend_request2_mg_verify_service_change_rep(Rep)
10460    end.
10461-endif.
10462
10463otp_6442_resend_request2_mg_verify_service_change_rep(
10464  {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _}) ->
10465    (catch otp_6442_resend_request2_mg_do_verify_service_change_rep(AR));
10466otp_6442_resend_request2_mg_verify_service_change_rep(Crap) ->
10467    {error, Crap, ok}.
10468
10469otp_6442_resend_request2_mg_do_verify_service_change_rep(AR) ->
10470    io:format("otp_6442_resend_request2_mg_verify_service_change_rep -> ok"
10471	      "~n   AR: ~p~n", [AR]),
10472    CR =
10473	case AR of
10474	    #'ActionReply'{commandReply = [CmdRep]} ->
10475		CmdRep;
10476	    _ ->
10477		Reason1 = {invalid_action_reply, AR},
10478		throw({error, Reason1, ok})
10479	end,
10480    SCR =
10481	case CR of
10482	    {serviceChangeReply, ServChRep} ->
10483		ServChRep;
10484	    _ ->
10485		Reason2 = {invalid_command_reply, CR},
10486		throw({error, Reason2, ok})
10487	end,
10488    {Tid, SCRes} =
10489	case SCR of
10490	    #'ServiceChangeReply'{terminationID       = [TermID],
10491				  serviceChangeResult = Res} ->
10492		{TermID, Res};
10493	    _ ->
10494		Reason3 = {invalid_service_change_reply, SCR},
10495		throw({error, Reason3, ok})
10496	end,
10497    case Tid of
10498	#megaco_term_id{contains_wildcards = false, id = ["root"]} ->
10499	    ok;
10500	_ ->
10501	    Reason4 = {invalid_termination_id, Tid},
10502	    throw({error, Reason4, ok})
10503    end,
10504    SCRParm =
10505	case SCRes of
10506	    {serviceChangeResParms, ServChResParms} ->
10507		ServChResParms;
10508	    _ ->
10509		Reason5 = {invalid_serviceChangeResult, SCRes},
10510		throw({error, Reason5, ok})
10511	end,
10512    case SCRParm of
10513	#'ServiceChangeResParm'{serviceChangeMgcId = _RemoteMid} ->
10514	    {ok, AR, ok};
10515	_ ->
10516	    Reason6 = {invalid_service_change_result, SCRParm},
10517	    {error, Reason6, ok}
10518    end.
10519
10520-ifndef(megaco_hipe_special).
10521otp_6442_resend_request2_mg_verify_notify_rep_fun() ->
10522    fun(Rep) ->
10523	    otp_6442_resend_request2_mg_verify_notify_rep(Rep)
10524    end.
10525-endif.
10526
10527otp_6442_resend_request2_mg_verify_notify_rep(
10528  {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _}) ->
10529    io:format("otp_6442_resend_request2_mg_verify_notify_rep -> ok"
10530	      "~n   AR: ~p~n", [AR]),
10531    {ok, AR, ok};
10532otp_6442_resend_request2_mg_verify_notify_rep(Else) ->
10533    io:format("otp_6442_resend_request2_mg_verify_notify_rep -> unknown"
10534	      "~n   Else: ~p~n", [Else]),
10535    {error, Else, ok}.
10536
10537
10538otp_6442_resend_request2_mg_service_change_request_ar(_Mid, Cid) ->
10539    Prof  = cre_serviceChangeProf("resgw", 1),
10540    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
10541    Root  = #megaco_term_id{id = ["root"]},
10542    SCR   = cre_serviceChangeReq([Root], SCP),
10543    CMD   = cre_command(SCR),
10544    CR    = cre_cmdReq(CMD),
10545    cre_actionReq(Cid, [CR]).
10546
10547otp_6442_resend_request2_mg_notify_request_ar(Rid, Tid, Cid) ->
10548    TT      = cre_timeNotation("19990729", "22000000"),
10549    Ev      = cre_obsEvent("al/of", TT),
10550    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
10551    NR      = cre_notifyReq([Tid], EvsDesc),
10552    CMD     = cre_command(NR),
10553    CR      = cre_cmdReq(CMD),
10554    cre_actionReq(Cid, [CR]).
10555
10556
10557
10558%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10559
10560otp_6442_resend_reply1(suite) ->
10561    [];
10562otp_6442_resend_reply1(Config) when is_list(Config) ->
10563    Pre = fun() ->
10564                  MgNode = make_node_name(mg),
10565                  d("start (MG) node: ~p", [MgNode]),
10566                  Nodes = [MgNode],
10567                  ok = ?START_NODES(Nodes, true),
10568                  Nodes
10569          end,
10570    Case = fun do_otp_6442_resend_reply1/1,
10571    Post = fun(Nodes) ->
10572                   d("stop nodes"),
10573                   ?STOP_NODES(lists:reverse(Nodes))
10574           end,
10575    try_tc(request_and_no_reply, Pre, Case, Post).
10576
10577do_otp_6442_resend_reply1([MgNode]) ->
10578    d("[MG] start the simulator "),
10579    {ok, Mg} = megaco_test_megaco_generator:start_link("MG", MgNode),
10580
10581    d("[MG] create the event sequence"),
10582    Mid     = {deviceName,"mg"},
10583    MgcMid  = {deviceName,"mgc"},
10584    TermId  = #megaco_term_id{id = ["00000000","00000000","01101101"]},
10585    MgEvSeq = otp_6442_resend_reply1_mg_event_sequence(Mid, TermId),
10586
10587    i("wait some time before starting the MG simulation"),
10588    sleep(1000),
10589
10590    d("[MG] start the simulation"),
10591    {ok, MgId} = megaco_test_megaco_generator:exec(Mg, MgEvSeq),
10592
10593    i("await the transport module service change send_message event"),
10594    Pid = otp_6442_expect(fun otp_6442_rsrp1_verify_scr_msg/1, 5000),
10595
10596    i("wait some before issuing the service change reply"),
10597    sleep(500),
10598
10599    i("simulate MGC sending the service change reply"),
10600    ServiceChangeReply = otp_6442_mgc_service_change_reply_msg(MgcMid, 1, 1),
10601    megaco_test_generic_transport:incomming_message(Pid, ServiceChangeReply),
10602
10603
10604    i("wait some before issuing the notify request"),
10605    sleep(500),
10606
10607    i("simulate MGC sending the notify request"),
10608    NotifyRequest = otp_6442_mgc_notify_request_msg(MgcMid, TermId, 2, 1),
10609    megaco_test_generic_transport:incomming_message(Pid, NotifyRequest),
10610
10611    i("await the transport module first notify-reply send_message event from MG: "
10612      "ignore"),
10613    otp_6442_expect(fun otp_6442_rsrp1_verify_first_nr_msg/1, 5000),
10614
10615    i("await the transport module second notify-reply send_message event from MG: "
10616      "ack"),
10617    {TransId, _, _} = otp_6442_expect(fun otp_6442_rsrp1_verify_second_nr_msg/1, 10000),
10618
10619    i("wait some before issuing the ack"),
10620    sleep(500),
10621
10622    i("simulate MGC sending the ack"),
10623    Ack = otp_6442_mgc_ack_msg(MgcMid, TransId),
10624    megaco_test_generic_transport:incomming_message(Pid, Ack),
10625
10626
10627    d("await the generator reply"),
10628    await_completion([MgId]),
10629
10630    %% Tell Mg to stop
10631    i("[MG] stop generator"),
10632    megaco_test_megaco_generator:stop(Mg),
10633
10634    i("done", []),
10635    ok.
10636
10637
10638otp_6442_rsrp1_verify_scr_msg(
10639  {transport_event, {send_message, _SH, {message, Msg}}, Pid})
10640  when is_record(Msg, 'MegacoMessage') ->
10641    d("received expected service change request message: "
10642      "~n   Msg: ~p", [Msg]),
10643    Reply = ok,
10644    Pid ! {transport_reply, Reply, self()},
10645    {ok, Pid};
10646otp_6442_rsrp1_verify_scr_msg(Msg) ->
10647    {error, {invalid_message, Msg}}.
10648
10649otp_6442_rsrp1_verify_first_nr_msg(
10650  {transport_event, {send_message, _SH, {message, Msg}}, Pid})
10651  when is_record(Msg, 'MegacoMessage') ->
10652    d("received expected first notify reply message: "
10653      "~n   Msg: ~p", [Msg]),
10654    Reply = ok,
10655    Pid ! {transport_reply, Reply, self()},
10656    {ok, ok};
10657otp_6442_rsrp1_verify_first_nr_msg(Msg) ->
10658    {error, {invalid_message, Msg}}.
10659
10660otp_6442_rsrp1_verify_second_nr_msg(
10661  {transport_event, {send_message, _SH, {message, Msg}}, Pid})
10662  when is_record(Msg, 'MegacoMessage') ->
10663    d("received expected second notify reply message: "
10664      "~n   Msg: ~p", [Msg]),
10665    Reply = ok,
10666    Pid ! {transport_reply, Reply, self()},
10667    #'MegacoMessage'{mess = Mess} = Msg,
10668    #'Message'{mId         = _Mid,
10669	       messageBody = Body} = Mess,
10670    {transactions, Transactions} = Body,
10671    [Transaction] = Transactions,
10672    {transactionReply, TransRep} = Transaction,
10673    #'TransactionReply'{transactionId     = TransId,
10674			immAckRequired    = 'NULL',
10675			transactionResult = TransRes} = TransRep,
10676    {actionReplies, ActReps} = TransRes,
10677    [ActRep] = ActReps,
10678    #'ActionReply'{contextId       = Cid,
10679		   errorDescriptor = asn1_NOVALUE,
10680		   contextReply    = asn1_NOVALUE,
10681		   commandReply    = CmdReps} = ActRep,
10682    [CmdRep] = CmdReps,
10683    {notifyReply, NR} = CmdRep,
10684    #'NotifyReply'{terminationID = TermId} = NR,
10685    {ok, {TransId, Cid, TermId}};
10686otp_6442_rsrp1_verify_second_nr_msg(Msg) ->
10687    {error, {invalid_message, Msg}}.
10688
10689
10690otp_6442_mgc_notify_request_msg(Mid, TermId, TransId, Cid) ->
10691    TT      = cre_timeNotation("19990729", "22000000"),
10692    Ev      = cre_obsEvent("al/of", TT),
10693    EvsDesc = cre_obsEvsDesc(1, [Ev]),
10694    NR      = cre_notifyReq([TermId], EvsDesc),
10695    CMD     = cre_command(NR),
10696    CR      = cre_cmdReq(CMD),
10697    AR      = cre_actionReq(Cid, [CR]),
10698    ARs     = [AR],
10699    TR      = cre_transReq(TransId, ARs),
10700    Trans   = cre_transaction(TR),
10701    Mess    = cre_message(?VERSION, Mid, cre_transactions([Trans])),
10702    cre_megacoMessage(Mess).
10703
10704
10705otp_6442_mgc_ack_msg(Mid, TransId) ->
10706    TR    = cre_transRespAck(cre_transAck(TransId)),
10707    Trans = cre_transaction(TR),
10708    Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
10709    cre_megacoMessage(Mess).
10710
10711
10712
10713%%
10714%% MG generator stuff
10715%%
10716-ifdef(megaco_hipe_special).
10717-define(otp_6442_resend_reply1_mg_verify_handle_connect_fun(),
10718	{?MODULE, otp_6442_resend_reply1_mg_verify_handle_connect, []}).
10719-define(otp_6442_resend_reply1_mg_verify_service_change_rep_fun(),
10720	{?MODULE, otp_6442_resend_reply1_mg_verify_service_change_rep, []}).
10721-define(otp_6442_resend_reply1_mg_verify_notify_req_fun(TermId),
10722	{?MODULE, otp_6442_resend_reply1_mg_verify_notify_req, [TermId]}).
10723-define(otp_6442_resend_reply1_mg_verify_ack_fun(),
10724	{?MODULE, otp_6442_resend_reply1_mg_verify_ack, []}).
10725-else.
10726-define(otp_6442_resend_reply1_mg_verify_handle_connect_fun(),
10727	otp_6442_resend_reply1_mg_verify_handle_connect_fun()).
10728-define(otp_6442_resend_reply1_mg_verify_service_change_rep_fun(),
10729	otp_6442_resend_reply1_mg_verify_service_change_rep_fun()).
10730-define(otp_6442_resend_reply1_mg_verify_notify_req_fun(TermId),
10731	otp_6442_resend_reply1_mg_verify_notify_req_fun(TermId)).
10732-define(otp_6442_resend_reply1_mg_verify_ack_fun(),
10733	otp_6442_resend_reply1_mg_verify_ack_fun()).
10734-endif.
10735
10736otp_6442_resend_reply1_mg_event_sequence(Mid, TermId) ->
10737    RI = [
10738          {port,             self()}, % This is just a trick to get my pid to the transport module
10739          {encoding_module,  megaco_pretty_text_encoder},
10740          {encoding_config,  []},
10741          {transport_module, megaco_test_generic_transport}
10742         ],
10743    ServiceChangeReq =
10744	otp_6442_resend_reply1_mg_service_change_request_ar(Mid, 1),
10745    RepTmr = #megaco_incr_timer{wait_for    = 2000,
10746                                factor      = 1,
10747                                max_retries = 1},
10748    ConnectVerify =
10749	?otp_6442_resend_reply1_mg_verify_handle_connect_fun(),
10750    ServiceChangeReplyVerify =
10751	?otp_6442_resend_reply1_mg_verify_service_change_rep_fun(),
10752    NotifyReqVerify =
10753	?otp_6442_resend_reply1_mg_verify_notify_req_fun(TermId),
10754    AckVerify =
10755	?otp_6442_resend_reply1_mg_verify_ack_fun(),
10756%%     ConnectVerify =
10757%% 	otp_6442_resend_reply1_mg_verify_handle_connect_fun(),
10758%%     ServiceChangeReplyVerify =
10759%% 	otp_6442_resend_reply1_mg_verify_service_change_reply_fun(),
10760%%     NotifyReqVerify =
10761%% 	otp_6442_resend_reply1_mg_verify_notify_request_fun(TermId),
10762%%     AckVerify =
10763%% 	otp_6442_resend_reply1_mg_verify_ack_fun(),
10764    EvSeq = [
10765             {debug, false},
10766             megaco_start,
10767             {megaco_start_user, Mid, RI, []},
10768	     {megaco_update_user_info, resend_indication, false},
10769	     {megaco_update_user_info, reply_timer,       RepTmr},
10770             start_transport,
10771             {megaco_trace, disable},
10772             {megaco_system_info, users},
10773             {megaco_system_info, connections},
10774             connect,
10775             {megaco_callback, handle_connect, ConnectVerify},
10776             megaco_connect,
10777             {megaco_cast,     [ServiceChangeReq], []},
10778             {megaco_callback, handle_connect,     ConnectVerify},
10779             {megaco_callback, handle_trans_reply, ServiceChangeReplyVerify},
10780             {sleep, 1000},
10781
10782             {megaco_callback, handle_trans_request, NotifyReqVerify},
10783             {megaco_callback, handle_trans_ack,     AckVerify},
10784
10785             {sleep, 1000},
10786             megaco_stop_user,
10787             megaco_stop,
10788             {sleep, 1000}
10789            ],
10790    EvSeq.
10791
10792
10793-ifndef(megaco_hipe_special).
10794otp_6442_resend_reply1_mg_verify_handle_connect_fun() ->
10795    fun(Ev) ->
10796	    otp_6442_resend_reply1_mg_verify_handle_connect(Ev)
10797    end.
10798-endif.
10799
10800otp_6442_resend_reply1_mg_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
10801    io:format("otp_6442_resend_reply1_mg_verify_handle_connect -> ok"
10802	      "~n   CH: ~p~n", [CH]),
10803    {ok, CH, ok};
10804otp_6442_resend_reply1_mg_verify_handle_connect(Else) ->
10805    io:format("otp_6442_resend_reply1_mg_verify_handle_connect -> unknown"
10806	      "~n   Else: ~p~n", [Else]),
10807    {error, Else, ok}.
10808
10809
10810-ifndef(megaco_hipe_special).
10811otp_6442_resend_reply1_mg_verify_service_change_rep_fun() ->
10812    fun(Rep) ->
10813	    otp_6442_resend_reply1_mg_verify_service_change_rep(Rep)
10814    end.
10815-endif.
10816
10817otp_6442_resend_reply1_mg_verify_service_change_rep(
10818  {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _}) ->
10819    (catch otp_6442_resend_reply1_mg_do_verify_service_change_rep(AR));
10820otp_6442_resend_reply1_mg_verify_service_change_rep(Crap) ->
10821    {error, Crap, ok}.
10822
10823otp_6442_resend_reply1_mg_do_verify_service_change_rep(AR) ->
10824    io:format("otp_6442_resend_reply1_mg_verify_service_change_rep -> ok"
10825	      "~n   AR: ~p~n", [AR]),
10826    CR =
10827	case AR of
10828	    #'ActionReply'{commandReply = [CmdRep]} ->
10829		CmdRep;
10830	    _ ->
10831		Reason1 = {invalid_action_reply, AR},
10832		throw({error, Reason1, ok})
10833	end,
10834    SCR =
10835	case CR of
10836	    {serviceChangeReply, ServChRep} ->
10837		ServChRep;
10838	    _ ->
10839		Reason2 = {invalid_command_reply, CR},
10840		throw({error, Reason2, ok})
10841	end,
10842    {Tid, SCRes} =
10843	case SCR of
10844	    #'ServiceChangeReply'{terminationID       = [TermID],
10845				  serviceChangeResult = Res} ->
10846		{TermID, Res};
10847	    _ ->
10848		Reason3 = {invalid_service_change_reply, SCR},
10849		throw({error, Reason3, ok})
10850	end,
10851    case Tid of
10852	#megaco_term_id{contains_wildcards = false, id = ["root"]} ->
10853	    ok;
10854	_ ->
10855	    Reason4 = {invalid_termination_id, Tid},
10856	    throw({error, Reason4, ok})
10857    end,
10858    SCRParm =
10859	case SCRes of
10860	    {serviceChangeResParms, ServChResParms} ->
10861		ServChResParms;
10862	    _ ->
10863		Reason5 = {invalid_serviceChangeResult, SCRes},
10864		throw({error, Reason5, ok})
10865	end,
10866    case SCRParm of
10867	#'ServiceChangeResParm'{serviceChangeMgcId = _RemoteMid} ->
10868	    {ok, AR, ok};
10869	_ ->
10870	    Reason6 = {invalid_service_change_result, SCRParm},
10871	    {error, Reason6, ok}
10872    end.
10873
10874-ifndef(megaco_hipe_special).
10875otp_6442_resend_reply1_mg_verify_notify_req_fun(TermId) ->
10876    fun(Req) ->
10877	    otp_6442_resend_reply1_mg_verify_notify_req(Req, TermId)
10878    end.
10879-endif.
10880
10881otp_6442_resend_reply1_mg_verify_notify_req(
10882  {handle_trans_request, _, ?VERSION, [AR]}, TermId) ->
10883    io:format("otp_6442_resend_reply1_mg_verify_notify_req -> ok"
10884	      "~n   AR: ~p~n", [AR]),
10885    case AR of
10886	#'ActionRequest'{contextId = 1 = Cid,
10887			 commandRequests = [CR]} ->
10888	    #'CommandRequest'{command = Cmd} = CR,
10889	    {notifyReq, NR} = Cmd,
10890	    #'NotifyRequest'{terminationID            = [TermId],
10891			     observedEventsDescriptor = OED,
10892			     errorDescriptor          = asn1_NOVALUE} = NR,
10893	    #'ObservedEventsDescriptor'{observedEventLst = [OE]} = OED,
10894	    #'ObservedEvent'{eventName = "al/of"} = OE,
10895	    HandleAck = {handle_ack, otp_6442_resend_reply1},
10896	    Reply = {HandleAck,
10897		     [otp_6442_resend_reply1_mg_notify_reply_ar(Cid, TermId)]},
10898	    {ok, AR, Reply};
10899	_ ->
10900	    ED = otp_6442_resend_reply1_err_desc(AR),
10901	    ErrReply = {discard_ack, ED},
10902	    {error, AR, ErrReply}
10903    end;
10904otp_6442_resend_reply1_mg_verify_notify_req(Else, TermId) ->
10905    io:format("otp_6442_resend_reply1_mg_verify_notify_request -> unknown"
10906	      "~n   Else:   ~p"
10907	      "~n   TermId: ~p"
10908	      "~n", [Else, TermId]),
10909    ED       = otp_6442_resend_reply1_err_desc(Else),
10910    ErrReply = {discard_ack, ED},
10911    {error, Else, ErrReply}.
10912
10913otp_6442_resend_reply1_mg_notify_reply_ar(Cid, TermId) ->
10914    NR = cre_notifyReply([TermId]),
10915    CR = cre_cmdReply(NR),
10916    cre_actionReply(Cid, [CR]).
10917
10918-ifndef(megaco_hipe_special).
10919otp_6442_resend_reply1_mg_verify_ack_fun() ->
10920    fun(Ack) ->
10921	    otp_6442_resend_reply1_mg_verify_ack(Ack)
10922    end.
10923-endif.
10924
10925otp_6442_resend_reply1_mg_verify_ack(
10926  {handle_trans_ack, CH, ?VERSION, ok, otp_6442_resend_reply1}) ->
10927    io:format("otp_6442_resend_reply1_verify_ack -> ok"
10928              "~n   CH: ~p"
10929              "~n", [CH]),
10930    {ok, CH, ok};
10931otp_6442_resend_reply1_mg_verify_ack(Else) ->
10932    io:format("otp_6442_resend_reply1_verify_ack -> unknown"
10933              "~n   Else: ~p~n", [Else]),
10934    {error, Else, ok}.
10935
10936
10937otp_6442_resend_reply1_mg_service_change_request_ar(_Mid, Cid) ->
10938    Prof  = cre_serviceChangeProf("resgw", 1),
10939    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
10940    Root  = #megaco_term_id{id = ["root"]},
10941    SCR   = cre_serviceChangeReq([Root], SCP),
10942    CMD   = cre_command(SCR),
10943    CR    = cre_cmdReq(CMD),
10944    cre_actionReq(Cid, [CR]).
10945
10946otp_6442_resend_reply1_err_desc(T) ->
10947    EC = ?megaco_internal_gateway_error,
10948    ET = lists:flatten(io_lib:format("~w",[T])),
10949    #'ErrorDescriptor'{errorCode = EC, errorText = ET}.
10950
10951
10952
10953%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10954
10955otp_6442_resend_reply2(suite) ->
10956    [];
10957otp_6442_resend_reply2(Config) when is_list(Config) ->
10958    Pre = fun() ->
10959                  MgNode = make_node_name(mg),
10960                  d("start (MG) node: ~p", [MgNode]),
10961                  Nodes = [MgNode],
10962                  ok = ?START_NODES(Nodes, true),
10963                  Nodes
10964          end,
10965    Case = fun do_otp_6442_resend_reply2/1,
10966    Post = fun(Nodes) ->
10967                   d("stop nodes"),
10968                   ?STOP_NODES(lists:reverse(Nodes))
10969           end,
10970    try_tc(otp6442rrep2, Pre, Case, Post).
10971
10972do_otp_6442_resend_reply2([MgNode]) ->
10973    d("[MG] start the simulator "),
10974    {ok, Mg} = megaco_test_megaco_generator:start_link("MG", MgNode),
10975
10976    d("[MG] create the event sequence"),
10977    Mid     = {deviceName,"mg"},
10978    MgcMid  = {deviceName,"mgc"},
10979    TermId  = #megaco_term_id{id = ["00000000","00000000","01101101"]},
10980    MgEvSeq = otp_6442_resend_reply2_mg_event_sequence(Mid, TermId),
10981
10982    i("wait some time before starting the MG simulation"),
10983    sleep(1000),
10984
10985    d("[MG] start the simulation"),
10986    {ok, MgId} = megaco_test_megaco_generator:exec(Mg, MgEvSeq),
10987
10988    i("await the transport module service change send_message event"),
10989    Pid = otp_6442_expect(fun otp_6442_rsrp2_verify_scr_msg/1, 5000),
10990
10991    i("wait some before issuing the service change reply"),
10992    sleep(500),
10993
10994    i("simulate MGC sending the service change reply"),
10995    ServiceChangeReply = otp_6442_mgc_service_change_reply_msg(MgcMid, 1, 1),
10996    megaco_test_generic_transport:incomming_message(Pid, ServiceChangeReply),
10997
10998
10999    i("wait some before issuing the notify request"),
11000    sleep(500),
11001
11002    i("simulate MGC sending the notify request"),
11003    NotifyRequest = otp_6442_mgc_notify_request_msg(MgcMid, TermId, 2, 1),
11004    megaco_test_generic_transport:incomming_message(Pid, NotifyRequest),
11005
11006    i("await the transport module notify-reply send_message event from MG: ignore"),
11007    otp_6442_expect(otp_6442_rsrp2_verify_first_nr_msg_fun(), 5000),
11008
11009    i("await the transport module notify-reply resend_message event from MG: ack"),
11010    {TransId, _, _} =
11011	otp_6442_expect(otp_6442_rsrp2_verify_second_nr_msg_fun(), 10000),
11012
11013    i("wait some before issuing the ack"),
11014    sleep(500),
11015
11016    i("simulate MGC sending the ack"),
11017    Ack = otp_6442_mgc_ack_msg(MgcMid, TransId),
11018    megaco_test_generic_transport:incomming_message(Pid, Ack),
11019
11020
11021    d("await the generator reply"),
11022    await_completion([MgId]),
11023
11024    %% Tell Mg to stop
11025    i("[MG] stop generator"),
11026    megaco_test_megaco_generator:stop(Mg),
11027
11028    i("done", []),
11029    ok.
11030
11031
11032otp_6442_rsrp2_verify_scr_msg(
11033  {transport_event, {send_message, _SH, {message, Msg}}, Pid})
11034  when is_record(Msg, 'MegacoMessage') ->
11035    d("received expected service change request message: "
11036      "~n   Msg: ~p", [Msg]),
11037    Reply = ok,
11038    Pid ! {transport_reply, Reply, self()},
11039    {ok, Pid};
11040otp_6442_rsrp2_verify_scr_msg(Msg) ->
11041    {error, {invalid_message, Msg}}.
11042
11043otp_6442_rsrp2_verify_first_nr_msg_fun() ->
11044    fun(E) ->
11045	    otp_6442_rsrp2_verify_first_nr_msg(E)
11046    end.
11047
11048otp_6442_rsrp2_verify_first_nr_msg(
11049  {transport_event, {send_message, _SH, {message, Msg}}, Pid})
11050  when is_record(Msg, 'MegacoMessage') ->
11051    d("received expected first notify reply message: "
11052      "~n   Msg: ~p", [Msg]),
11053    Reply = ok,
11054    Pid ! {transport_reply, Reply, self()},
11055    {ok, ok};
11056otp_6442_rsrp2_verify_first_nr_msg(Msg) ->
11057    {error, {invalid_message, Msg}}.
11058
11059otp_6442_rsrp2_verify_second_nr_msg_fun() ->
11060    fun(E) ->
11061	    otp_6442_rsrp2_verify_second_nr_msg(E)
11062    end.
11063
11064otp_6442_rsrp2_verify_second_nr_msg(
11065  {transport_event, {resend_message, _SH, {message, Msg}}, Pid})
11066  when is_record(Msg, 'MegacoMessage') ->
11067    d("received expected second notify reply message: "
11068      "~n   Msg: ~p", [Msg]),
11069    Reply = ok,
11070    Pid ! {transport_reply, Reply, self()},
11071    #'MegacoMessage'{mess = Mess} = Msg,
11072    #'Message'{mId         = _Mid,
11073	       messageBody = Body} = Mess,
11074    {transactions, Transactions} = Body,
11075    [Transaction] = Transactions,
11076    {transactionReply, TransRep} = Transaction,
11077    #'TransactionReply'{transactionId     = TransId,
11078			immAckRequired    = 'NULL',
11079			transactionResult = TransRes} = TransRep,
11080    {actionReplies, ActReps} = TransRes,
11081    [ActRep] = ActReps,
11082    #'ActionReply'{contextId       = Cid,
11083		   errorDescriptor = asn1_NOVALUE,
11084		   contextReply    = asn1_NOVALUE,
11085		   commandReply    = CmdReps} = ActRep,
11086    [CmdRep] = CmdReps,
11087    {notifyReply, NR} = CmdRep,
11088    #'NotifyReply'{terminationID = TermId} = NR,
11089    {ok, {TransId, Cid, TermId}};
11090otp_6442_rsrp2_verify_second_nr_msg(Msg) ->
11091    d("received expected bad second notify reply message: "
11092      "~n   Msg: ~p", [Msg]),
11093    {error, {invalid_message, Msg}}.
11094
11095
11096
11097%%
11098%% MG generator stuff
11099%%
11100-ifdef(megaco_hipe_special).
11101-define(otp_6442_resend_reply2_mg_verify_handle_connect_fun(),
11102	{?MODULE, otp_6442_resend_reply2_mg_verify_handle_connect, []}).
11103-define(otp_6442_resend_reply2_mg_verify_service_change_rep_fun(),
11104	{?MODULE, otp_6442_resend_reply2_mg_verify_service_change_rep, []}).
11105-define(otp_6442_resend_reply2_mg_verify_notify_req_fun(TermId),
11106	{?MODULE, otp_6442_resend_reply2_mg_verify_notify_req, [TermId]}).
11107-define(otp_6442_resend_reply2_mg_verify_ack_fun(),
11108	{?MODULE, otp_6442_resend_reply2_mg_verify_ack, []}).
11109-else.
11110-define(otp_6442_resend_reply2_mg_verify_handle_connect_fun(),
11111	otp_6442_resend_reply2_mg_verify_handle_connect_fun()).
11112-define(otp_6442_resend_reply2_mg_verify_service_change_rep_fun(),
11113	otp_6442_resend_reply2_mg_verify_service_change_rep_fun()).
11114-define(otp_6442_resend_reply2_mg_verify_notify_req_fun(TermId),
11115	otp_6442_resend_reply2_mg_verify_notify_req_fun(TermId)).
11116-define(otp_6442_resend_reply2_mg_verify_ack_fun(),
11117	otp_6442_resend_reply2_mg_verify_ack_fun()).
11118-endif.
11119
11120otp_6442_resend_reply2_mg_event_sequence(Mid, TermId) ->
11121    RI = [
11122          {port,             self()}, % This is just a trick to get my pid to the transport module
11123          {encoding_module,  megaco_pretty_text_encoder},
11124          {encoding_config,  []},
11125          {transport_module, megaco_test_generic_transport}
11126         ],
11127    ServiceChangeReq =
11128	otp_6442_resend_reply2_mg_service_change_request_ar(Mid, 1),
11129    RepTmr = #megaco_incr_timer{wait_for    = 2000,
11130                                factor      = 1,
11131                                max_retries = 1},
11132    ConnectVerify =
11133	?otp_6442_resend_reply2_mg_verify_handle_connect_fun(),
11134    ServiceChangeReplyVerify =
11135	?otp_6442_resend_reply2_mg_verify_service_change_rep_fun(),
11136    NotifyReqVerify =
11137	?otp_6442_resend_reply2_mg_verify_notify_req_fun(TermId),
11138    AckVerify =
11139	?otp_6442_resend_reply2_mg_verify_ack_fun(),
11140%%     ConnectVerify =
11141%% 	otp_6442_resend_reply2_mg_verify_handle_connect_fun(),
11142%%     ServiceChangeReplyVerify =
11143%% 	otp_6442_resend_reply2_mg_verify_service_change_reply_fun(),
11144%%     NotifyReqVerify =
11145%% 	otp_6442_resend_reply2_mg_verify_notify_request_fun(TermId),
11146%%     AckVerify =
11147%% 	otp_6442_resend_reply2_mg_verify_ack_fun(),
11148    EvSeq = [
11149             {debug, false},
11150             megaco_start,
11151             {megaco_start_user, Mid, RI, []},
11152	     {megaco_update_user_info, resend_indication, true},
11153	     {megaco_update_user_info, reply_timer,       RepTmr},
11154             start_transport,
11155             {megaco_trace, disable},
11156             {megaco_system_info, users},
11157             {megaco_system_info, connections},
11158             connect,
11159             {megaco_callback, handle_connect, ConnectVerify},
11160             megaco_connect,
11161             {megaco_cast,     [ServiceChangeReq], []},
11162             {megaco_callback, handle_connect,     ConnectVerify},
11163             {megaco_callback, handle_trans_reply, ServiceChangeReplyVerify},
11164             {sleep, 1000},
11165
11166             {megaco_callback, handle_trans_request, NotifyReqVerify},
11167             {megaco_callback, handle_trans_ack,     AckVerify},
11168
11169             {sleep, 1000},
11170             megaco_stop_user,
11171             megaco_stop,
11172             {sleep, 1000}
11173            ],
11174    EvSeq.
11175
11176
11177-ifndef(megaco_hipe_special).
11178otp_6442_resend_reply2_mg_verify_handle_connect_fun() ->
11179    fun(Ev) ->
11180	    otp_6442_resend_reply2_mg_verify_handle_connect(Ev)
11181    end.
11182-endif.
11183
11184otp_6442_resend_reply2_mg_verify_handle_connect(
11185  {handle_connect, CH, ?VERSION}) ->
11186    io:format("otp_6442_resend_reply2_mg_verify_handle_connect -> ok"
11187	      "~n   CH: ~p~n", [CH]),
11188    {ok, CH, ok};
11189otp_6442_resend_reply2_mg_verify_handle_connect(Else) ->
11190    io:format("otp_6442_resend_reply2_mg_verify_handle_connect -> unknown"
11191	      "~n   Else: ~p~n", [Else]),
11192    {error, Else, ok}.
11193
11194
11195-ifndef(megaco_hipe_special).
11196otp_6442_resend_reply2_mg_verify_service_change_rep_fun() ->
11197    fun(Rep) ->
11198	    otp_6442_resend_reply2_mg_verify_service_change_rep(Rep)
11199    end.
11200-endif.
11201
11202otp_6442_resend_reply2_mg_verify_service_change_rep(
11203  {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _}) ->
11204    (catch otp_6442_resend_reply2_mg_do_verify_service_change_rep(AR));
11205otp_6442_resend_reply2_mg_verify_service_change_rep(Crap) ->
11206    {error, Crap, ok}.
11207
11208otp_6442_resend_reply2_mg_do_verify_service_change_rep(AR) ->
11209    io:format("otp_6442_resend_reply2_mg_verify_service_change_rep -> ok"
11210	      "~n   AR: ~p~n", [AR]),
11211    CR =
11212	case AR of
11213	    #'ActionReply'{commandReply = [CmdRep]} ->
11214		CmdRep;
11215	    _ ->
11216		Reason1 = {invalid_action_reply, AR},
11217		throw({error, Reason1, ok})
11218	end,
11219    SCR =
11220	case CR of
11221	    {serviceChangeReply, ServChRep} ->
11222		ServChRep;
11223	    _ ->
11224		Reason2 = {invalid_command_reply, CR},
11225		throw({error, Reason2, ok})
11226	end,
11227    {Tid, SCRes} =
11228	case SCR of
11229	    #'ServiceChangeReply'{terminationID       = [TermID],
11230				  serviceChangeResult = Res} ->
11231		{TermID, Res};
11232	    _ ->
11233		Reason3 = {invalid_service_change_reply, SCR},
11234		throw({error, Reason3, ok})
11235	end,
11236    case Tid of
11237	#megaco_term_id{contains_wildcards = false, id = ["root"]} ->
11238	    ok;
11239	_ ->
11240	    Reason4 = {invalid_termination_id, Tid},
11241	    throw({error, Reason4, ok})
11242    end,
11243    SCRParm =
11244	case SCRes of
11245	    {serviceChangeResParms, ServChResParms} ->
11246		ServChResParms;
11247	    _ ->
11248		Reason5 = {invalid_serviceChangeResult, SCRes},
11249		throw({error, Reason5, ok})
11250	end,
11251    case SCRParm of
11252	#'ServiceChangeResParm'{serviceChangeMgcId = _RemoteMid} ->
11253	    {ok, AR, ok};
11254	_ ->
11255	    Reason6 = {invalid_service_change_result, SCRParm},
11256	    {error, Reason6, ok}
11257    end.
11258
11259-ifndef(megaco_hipe_special).
11260otp_6442_resend_reply2_mg_verify_notify_req_fun(TermId) ->
11261    fun(Req) ->
11262	    otp_6442_resend_reply2_mg_verify_notify_req(Req, TermId)
11263    end.
11264-endif.
11265
11266otp_6442_resend_reply2_mg_verify_notify_req(
11267  {handle_trans_request, _, ?VERSION, [AR]}, TermId) ->
11268    io:format("otp_6442_resend_reply2_mg_verify_notify_req -> ok"
11269	      "~n   AR: ~p~n", [AR]),
11270    case AR of
11271	#'ActionRequest'{contextId = 1 = Cid,
11272			 commandRequests = [CR]} ->
11273	    #'CommandRequest'{command = Cmd} = CR,
11274	    {notifyReq, NR} = Cmd,
11275	    #'NotifyRequest'{terminationID            = [TermId],
11276			     observedEventsDescriptor = OED,
11277			     errorDescriptor          = asn1_NOVALUE} = NR,
11278	    #'ObservedEventsDescriptor'{observedEventLst = [OE]} = OED,
11279	    #'ObservedEvent'{eventName = "al/of"} = OE,
11280	    HandleAck = {handle_ack, otp_6442_resend_reply2},
11281	    Reply = {HandleAck,
11282		     [otp_6442_resend_reply2_mg_notify_reply_ar(Cid, TermId)]},
11283	    {ok, AR, Reply};
11284	_ ->
11285	    ED = otp_6442_resend_reply2_err_desc(AR),
11286	    ErrReply = {discard_ack, ED},
11287	    {error, AR, ErrReply}
11288    end;
11289otp_6442_resend_reply2_mg_verify_notify_req(Else, TermId) ->
11290    io:format("otp_6442_resend_reply2_mg_verify_notify_req -> unknown"
11291	      "~n   Else:   ~p"
11292	      "~n   TermId: ~p"
11293	      "~n", [Else, TermId]),
11294    ED       = otp_6442_resend_reply2_err_desc(Else),
11295    ErrReply = {discard_ack, ED},
11296    {error, Else, ErrReply}.
11297
11298otp_6442_resend_reply2_mg_notify_reply_ar(Cid, TermId) ->
11299    NR = cre_notifyReply([TermId]),
11300    CR = cre_cmdReply(NR),
11301    cre_actionReply(Cid, [CR]).
11302
11303
11304-ifndef(megaco_hipe_special).
11305otp_6442_resend_reply2_mg_verify_ack_fun() ->
11306    fun(Ack) ->
11307	    otp_6442_resend_reply2_mg_verify_ack(Ack)
11308    end.
11309-endif.
11310
11311otp_6442_resend_reply2_mg_verify_ack(
11312  {handle_trans_ack, CH, ?VERSION, ok, otp_6442_resend_reply2}) ->
11313    io:format("otp_6442_resend_reply2_verify_ack -> ok"
11314              "~n   CH: ~p"
11315              "~n", [CH]),
11316    {ok, CH, ok};
11317otp_6442_resend_reply2_mg_verify_ack(Else) ->
11318    io:format("otp_6442_resend_reply2_verify_ack -> unknown"
11319              "~n   Else: ~p~n", [Else]),
11320    {error, Else, ok}.
11321
11322
11323otp_6442_resend_reply2_mg_service_change_request_ar(_Mid, Cid) ->
11324    Prof  = cre_serviceChangeProf("resgw", 1),
11325    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
11326    Root  = #megaco_term_id{id = ["root"]},
11327    SCR   = cre_serviceChangeReq([Root], SCP),
11328    CMD   = cre_command(SCR),
11329    CR    = cre_cmdReq(CMD),
11330    cre_actionReq(Cid, [CR]).
11331
11332
11333otp_6442_resend_reply2_err_desc(T) ->
11334    EC = ?megaco_internal_gateway_error,
11335    ET = lists:flatten(io_lib:format("~w",[T])),
11336    #'ErrorDescriptor'{errorCode = EC, errorText = ET}.
11337
11338
11339
11340%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11341
11342otp_6865_request_and_reply_plain_extra1(suite) ->
11343    [];
11344otp_6865_request_and_reply_plain_extra1(Config) when is_list(Config) ->
11345    ?ACQUIRE_NODES(1, Config),
11346
11347    put(sname,     "TEST"),
11348    put(verbosity, debug),
11349    put(tc,        otp6865e1),
11350    i("starting"),
11351
11352    d("start test case controller",[]),
11353    ok = megaco_tc_controller:start_link(),
11354
11355    %% Instruct the transport module to fail all send_message
11356    d("instruct transport module to provide extra info: ",[]),
11357    ExtraInfo = otp_6865_extra_info,
11358    ok = megaco_tc_controller:insert(extra_transport_info, ExtraInfo),
11359
11360    d("start proxy",[]),
11361    ?USER_MOD:start_proxy(),
11362
11363    PrelMid = preliminary_mid,
11364    MgMid   = ipv4_mid(4711),
11365    MgcMid  = ipv4_mid(),
11366    UserMod = ?USER_MOD,
11367    d("start megaco app",[]),
11368    ?VERIFY(ok, application:start(megaco)),
11369    UserConfig = [{user_mod, UserMod}, {send_mod, UserMod},
11370		  {request_timer, infinity}, {reply_timer, infinity}],
11371    d("start (MG) user ~p",[MgMid]),
11372    ?VERIFY(ok,	megaco:start_user(MgMid, UserConfig)),
11373
11374    d("start (MGC) user ~p",[MgcMid]),
11375    ?VERIFY(ok,	megaco:start_user(MgcMid, UserConfig)),
11376
11377    d("get receive info for ~p",[MgMid]),
11378    MgRH = user_info(MgMid, receive_handle),
11379    d("get receive info for ~p",[MgcMid]),
11380    MgcRH = user_info(MgcMid, receive_handle),
11381    d("start transport",[]),
11382    {ok, MgPid, MgSH} =
11383	?VERIFY({ok, _, _}, UserMod:start_transport(MgRH, MgcRH)),
11384    PrelMgCH = #megaco_conn_handle{local_mid = MgMid,
11385				   remote_mid = preliminary_mid},
11386    MgCH  = #megaco_conn_handle{local_mid = MgMid,
11387				remote_mid = MgcMid},
11388    MgcCH = #megaco_conn_handle{local_mid = MgcMid,
11389				remote_mid = MgMid},
11390    d("(MG) try connect to MGC",[]),
11391    ?SEND(megaco:connect(MgRH, PrelMid, MgSH, MgPid)), % Mg prel
11392    d("await connect from MG",[]),
11393    ?USER({connect, PrelMgCH, _V, []}, ok),
11394    ?RECEIVE([{res, _, {ok, PrelMgCH}}]),
11395
11396    d("(MG) send service change request",[]),
11397    Req = service_change_request(),
11398    ?SEND(megaco:call(PrelMgCH, [Req], [])),
11399
11400    d("(MGC) send service change reply",[]),
11401    ?USER({connect, MgcCH, _V, [ExtraInfo]}, ok), % Mgc auto
11402    Rep = service_change_reply(MgcMid),
11403    ?USER({request, MgcCH, _V, [[Req], ExtraInfo]}, {discard_ack, [Rep]}),
11404    ?USER({connect, MgCH, _V, [ExtraInfo]}, ok), % Mg confirm
11405    ?RECEIVE([{res, _, {1, {ok, [Rep], ExtraInfo}}}]),
11406
11407    d("get (system info) connections",[]),
11408    connections([MgCH, MgcCH]),
11409    d("get (~p) connections",[MgMid]),
11410    ?VERIFY([MgCH], megaco:user_info(MgMid, connections)),
11411    d("get (~p) connections",[MgcMid]),
11412    ?VERIFY([MgcCH], megaco:user_info(MgcMid, connections)),
11413
11414    Reason = shutdown,
11415    d("(MG) disconnect",[]),
11416    ?SEND(megaco:disconnect(MgCH, Reason)),
11417    ?USER({disconnect, MgCH, _V, [{user_disconnect, Reason}]}, ok),
11418    ?RECEIVE([{res, _, ok}]),
11419    ?VERIFY(ok,	megaco:stop_user(MgMid)),
11420
11421    d("(MGC) disconnect",[]),
11422    ?SEND(megaco:disconnect(MgcCH, Reason)),
11423    ?USER({disconnect, MgcCH, _V, [{user_disconnect, Reason}]}, ok),
11424    ?RECEIVE([{res, _, ok}]),
11425    ?VERIFY(ok,	megaco:stop_user(MgcMid)),
11426
11427    d("stop megaco app",[]),
11428    ?VERIFY(ok, application:stop(megaco)),
11429    ?RECEIVE([]),
11430
11431    d("stop test case controller",[]),
11432    ok = megaco_tc_controller:stop(),
11433
11434    d("done",[]),
11435    ok.
11436
11437
11438%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11439
11440otp_6865_request_and_reply_plain_extra2(suite) ->
11441    [];
11442otp_6865_request_and_reply_plain_extra2(doc) ->
11443    [];
11444otp_6865_request_and_reply_plain_extra2(Config) when is_list(Config) ->
11445    put(verbosity, ?TEST_VERBOSITY),
11446    put(sname,     "TEST"),
11447    put(tc,        otp6865e2),
11448    i("starting"),
11449
11450    d("start tc controller"),
11451    ok = megaco_tc_controller:start_link(),
11452
11453    %% Instruct the transport module to fail all send_message
11454    d("instruct transport module to provide extra info: ", []),
11455    ExtraInfo = otp6865e2_extra_info,
11456    ok = megaco_tc_controller:insert(extra_transport_info, ExtraInfo),
11457
11458    MgcNode = make_node_name(mgc),
11459    MgNode  = make_node_name(mg),
11460    d("start nodes: "
11461      "~n   MgcNode: ~p"
11462      "~n   MgNode:  ~p",
11463      [MgcNode, MgNode]),
11464    Nodes = [MgcNode, MgNode],
11465    ok = ?START_NODES(Nodes, true),
11466
11467
11468    d("[MGC] start the simulator "),
11469    {ok, Mgc} = megaco_test_megaco_generator:start_link("MGC", MgcNode),
11470
11471    d("[MGC] create the event sequence"),
11472    MgcEvSeq = otp6865e2_mgc_event_sequence(ExtraInfo, text, tcp),
11473
11474    i("wait some time before starting the MGC simulation"),
11475    sleep(1000),
11476
11477    d("[MGC] start the simulation"),
11478    {ok, MgcId} = megaco_test_megaco_generator:exec(Mgc, MgcEvSeq),
11479
11480    i("await MGC ready announcement"),
11481    receive
11482        announce_mgc ->
11483            i("received MGC ready announcement"),
11484            ok
11485    end,
11486
11487    d("[MG] start the simulator (generator)"),
11488    {ok, Mg} = megaco_test_tcp_generator:start_link("MG", MgNode),
11489
11490    d("[MG] create the event sequence"),
11491    MgEvSeq = otp6865e2_mg_event_sequence(text, tcp),
11492
11493    i("wait some time before starting the MG simulation"),
11494    sleep(1000),
11495
11496    d("[MG] start the simulation"),
11497    {ok, MgId} = megaco_test_tcp_generator:exec(Mg, MgEvSeq),
11498
11499    d("await the generator reply(s)"),
11500    await_completion([MgcId, MgId], 60000),
11501
11502    %% Tell Mgc to stop
11503    i("[MGC] stop generator"),
11504    megaco_test_megaco_generator:stop(Mgc),
11505
11506    %% Tell Mg to stop
11507    i("[MG] stop generator"),
11508    megaco_test_tcp_generator:stop(Mg),
11509
11510    i("stop tc controller"),
11511    ok = megaco_tc_controller:stop(),
11512
11513    %% Cleanup
11514    d("stop nodes"),
11515    ?STOP_NODES(lists:reverse(Nodes)),
11516
11517    i("done", []),
11518    ok.
11519
11520
11521%%
11522%% MGC generator stuff
11523%%
11524-ifdef(megaco_hipe_special).
11525-define(otp6865e2_mgc_verify_handle_connect_fun(ExtraInfo),
11526        {?MODULE, otp6865e2_mgc_verify_handle_connect, [ExtraInfo]}).
11527-define(otp6865e2_mgc_verify_service_change_req_fun(Mid, ExtraInfo),
11528        {?MODULE, otp6865e2_mgc_verify_service_change_req, [Mid, ExtraInfo]}).
11529-define(otp6865e2_mgc_verify_notify_req_fun(Cid, ExtraInfo, RequireAck),
11530        {?MODULE, otp6865e2_mgc_verify_notify_req, [Cid, ExtraInfo, RequireAck]}).
11531-define(otp6865e2_mgc_verify_reply_ack_fun(ExtraInfo),
11532	{?MODULE, otp6865e2_mgc_verify_reply_ack, [ExtraInfo]}).
11533-define(otp6865e2_mgc_verify_notify_reply_fun(ExtraInfo),
11534	{?MODULE, otp6865e2_mgc_verify_notify_reply, [ExtraInfo]}).
11535-define(otp6865e2_mgc_verify_handle_disconnect_fun(),
11536        {?MODULE, otp6865e2_mgc_verify_handle_disconnect, []}).
11537-else.
11538-define(otp6865e2_mgc_verify_handle_connect_fun(ExtraInfo),
11539        otp6865e2_mgc_verify_handle_connect(ExtraInfo)).
11540-define(otp6865e2_mgc_verify_service_change_req_fun(Mid, ExtraInfo),
11541        otp6865e2_mgc_verify_service_change_req_fun(Mid, ExtraInfo)).
11542-define(otp6865e2_mgc_verify_notify_req_fun(Cid, ExtraInfo, RequireAck),
11543	otp6865e2_mgc_verify_notify_req_fun(Cid, ExtraInfo, RequireAck)).
11544-define(otp6865e2_mgc_verify_reply_ack_fun(ExtraInfo),
11545	otp6865e2_mgc_verify_reply_ack_fun(ExtraInfo)).
11546-define(otp6865e2_mgc_verify_notify_reply_fun(ExtraInfo),
11547	otp6865e2_mgc_verify_notify_reply_fun(ExtraInfo)).
11548-define(otp6865e2_mgc_verify_handle_disconnect_fun(),
11549	fun otp6865e2_mgc_verify_handle_disconnect/1).
11550-endif.
11551
11552otp6865e2_mgc_event_sequence(ExtraInfo, text, tcp) ->
11553    Mid  = {deviceName, "ctrl"},
11554    CTRL = self(),
11555    RI   = [
11556            {port,             2944},
11557            {encoding_module,  megaco_pretty_text_encoder},
11558            {encoding_config,  []},
11559            {transport_module, megaco_tcp}
11560           ],
11561    ConnectVerify          =
11562	?otp6865e2_mgc_verify_handle_connect_fun(ExtraInfo),
11563    ServiceChangeReqVerify =
11564	?otp6865e2_mgc_verify_service_change_req_fun(Mid, ExtraInfo),
11565    NotifyReqVerify1       =
11566	?otp6865e2_mgc_verify_notify_req_fun(1, ExtraInfo, false),
11567    NotifyReqVerify2       =
11568	?otp6865e2_mgc_verify_notify_req_fun(2, ExtraInfo, true),
11569    AckVerify              = ?otp6865e2_mgc_verify_reply_ack_fun(ExtraInfo),
11570    Tid = #megaco_term_id{id = ["00000000","00000000","01101101"]},
11571    NotifyReq = [otp6865e2_mgc_notify_request_ar(1, Tid, 1)],
11572    NotifyReplyVerify = ?otp6865e2_mgc_verify_notify_reply_fun(ExtraInfo),
11573    DiscoVerify            =
11574	?otp6865e2_mgc_verify_handle_disconnect_fun(),
11575    EvSeq = [
11576	     {debug, true},
11577	     {megaco_trace, disable},
11578	     megaco_start,
11579	     {megaco_start_user, Mid, RI, []},
11580	     start_transport,
11581	     listen,
11582
11583             %% ANNOUNCE READY
11584             {trigger, fun() -> CTRL ! announce_mgc end},
11585
11586	     {megaco_callback, handle_connect,       ConnectVerify},
11587	     {megaco_callback, handle_trans_request, ServiceChangeReqVerify},
11588	     {megaco_callback, handle_trans_request, NotifyReqVerify1},
11589	     {megaco_callback, handle_trans_request, NotifyReqVerify2},
11590	     {megaco_callback, handle_trans_ack,     AckVerify},
11591	     {megaco_cast,     NotifyReq, []},
11592	     {megaco_callback, handle_trans_reply,   NotifyReplyVerify},
11593	     {megaco_callback, handle_disconnect,    DiscoVerify},
11594	     {sleep, 1000},
11595	     megaco_stop_user,
11596	     megaco_stop
11597	    ],
11598    EvSeq.
11599
11600
11601-ifndef(megaco_hipe_special).
11602otp6865e2_mgc_verify_handle_connect(ExtraInfo) ->
11603    fun(Req) ->
11604	    otp6865e2_mgc_verify_handle_connect(Req, ExtraInfo)
11605    end.
11606-endif.
11607
11608otp6865e2_mgc_verify_handle_connect({handle_connect, CH, ?VERSION, ExtraInfo},
11609				    ExtraInfo) ->
11610    io:format("otp6865e2_mgc_verify_handle_connect -> ok"
11611	      "~n   CH: ~p~n", [CH]),
11612    {ok, CH, ok};
11613otp6865e2_mgc_verify_handle_connect(Else, ExtraInfo) ->
11614    io:format("otp6865e2_mgc_verify_handle_connect -> unknown"
11615	      "~n   Else:      ~p"
11616	      "~n   ExtraInfo: ~p"
11617	      "~n", [Else, ExtraInfo]),
11618    {error, {Else, ExtraInfo}, ok}.
11619
11620-ifndef(megaco_hipe_special).
11621otp6865e2_mgc_verify_service_change_req_fun(Mid, ExtraInfo) ->
11622    fun(Req) ->
11623	    otp6865e2_mgc_verify_service_change_req(Req, Mid, ExtraInfo)
11624    end.
11625-endif.
11626
11627otp6865e2_mgc_verify_service_change_req(
11628  {handle_trans_request, _, ?VERSION, [AR], ExtraInfo}, Mid, ExtraInfo) ->
11629    (catch otp6865e2_mgc_do_verify_service_change_req(AR, Mid));
11630otp6865e2_mgc_verify_service_change_req(Crap, _Mid, ExtraInfo) ->
11631    ED = cre_ErrDesc({Crap, ExtraInfo}),
11632    ErrReply = {discard_ack, ED},
11633    {error, {Crap, ExtraInfo}, ErrReply}.
11634
11635otp6865e2_mgc_do_verify_service_change_req(AR, Mid) ->
11636    io:format("otp6865e2_mgc_verify_service_change_req -> ok"
11637	      "~n   AR:  ~p"
11638	      "~n   Mid: ~p"
11639	      "~n", [AR, Mid]),
11640    CR =
11641	case AR of
11642	    #'ActionRequest'{commandRequests = [CmdReq]} ->
11643		CmdReq;
11644	    _ ->
11645                Err1      = {invalid_action_request, AR},
11646                ED1       = cre_ErrDesc(AR),
11647                ErrReply1 = {discard_ack, ED1},
11648                throw({error, Err1, ErrReply1})
11649	end,
11650    Cmd =
11651        case CR of
11652            #'CommandRequest'{command = Command} ->
11653                Command;
11654            _ ->
11655                Err2      = {invalid_command_request, CR},
11656                ED2       = cre_ErrDesc(CR),
11657                ErrReply2 = {discard_ack, ED2},
11658                throw({error, Err2, ErrReply2})
11659        end,
11660    {Tid, Parms} =
11661        case Cmd of
11662            {serviceChangeReq,
11663             #'ServiceChangeRequest'{terminationID = [TermID],
11664                                     serviceChangeParms = ServChParms}} ->
11665                {TermID, ServChParms};
11666            _ ->
11667                Err3      = {invalid_command, Cmd},
11668                ED3       = cre_ErrDesc(Cmd),
11669                ErrReply3 = {discard_ack, ED3},
11670                throw({error, Err3, ErrReply3})
11671        end,
11672    case Tid of
11673        #megaco_term_id{contains_wildcards = false, id = ["root"]} ->
11674            ok;
11675        _ ->
11676            Err4      = {invalid_termination_id, Tid},
11677            ED4       = cre_ErrDesc(Tid),
11678            ErrReply4 = {discard_ack, ED4},
11679            throw({error, Err4, ErrReply4})
11680    end,
11681    case Parms of
11682        #'ServiceChangeParm'{serviceChangeMethod = restart,
11683                             serviceChangeReason = [[$9,$0,$1|_]]} ->
11684            AckData = [otp6865e2_mgc_service_change_reply_ar(Mid, 1)],
11685            Reply   = {discard_ack, AckData},
11686            {ok, AR, Reply};
11687        _ ->
11688            Err5      = {invalid_SCP, Parms},
11689            ED5       = cre_ErrDesc(Parms),
11690            ErrReply5 = {discard_ack, ED5},
11691            {error, Err5, ErrReply5}
11692    end.
11693
11694-ifndef(megaco_hipe_special).
11695otp6865e2_mgc_verify_notify_req_fun(Cid, ExtraInfo, RequireAck) ->
11696    fun(Req) ->
11697	    otp6865e2_mgc_verify_notify_req(Req, Cid, ExtraInfo, RequireAck)
11698    end.
11699-endif.
11700
11701otp6865e2_mgc_verify_notify_req(
11702  {handle_trans_request, _, ?VERSION, [AR], ExtraInfo},
11703  Cid, ExtraInfo, RequireAck) ->
11704    (catch otp6865e2_mgc_do_verify_notify_req(AR, Cid, RequireAck));
11705otp6865e2_mgc_verify_notify_req(Crap, _Cid, ExtraInfo, _RequireAck) ->
11706    ED       = cre_ErrDesc({Crap, ExtraInfo}),
11707    ErrReply = {discard_ack, ED},
11708    {error, {Crap, ExtraInfo}, ErrReply}.
11709
11710otp6865e2_mgc_do_verify_notify_req(AR, Cid, RequireAck) ->
11711    io:format("otp6865e2_mgc_do_verify_notify_req -> entry with"
11712	      "~n   AR:         ~p"
11713	      "~n   Cid:        ~p"
11714	      "~n   RequireAck: ~p"
11715	      "~n", [AR, Cid, RequireAck]),
11716    {ContextID, CR} =
11717	case AR of
11718	    #'ActionRequest'{contextId       = CtxID,
11719			     commandRequests = [CmdReq]} when (CtxID == Cid) ->
11720		{CtxID, CmdReq};
11721	    _ ->
11722                Err1      = {invalid_action_request, AR},
11723                ED1       = cre_ErrDesc(AR),
11724                ErrReply1 = {discard_ack, ED1},
11725                throw({error, Err1, ErrReply1})
11726        end,
11727    Cmd =
11728	case CR of
11729	    #'CommandRequest'{command = Command} ->
11730		Command;
11731	    _ ->
11732                Err2      = {invalid_command_request, CR},
11733                ED2       = cre_ErrDesc(CR),
11734                ErrReply2 = {discard_ack, ED2},
11735                throw({error, Err2, ErrReply2})
11736        end,
11737    NR =
11738        case Cmd of
11739	    {notifyReq, NotifReq} ->
11740		NotifReq;
11741	    _ ->
11742                Err3      = {invalid_command, Cmd},
11743                ED3       = cre_ErrDesc(Cmd),
11744                ErrReply3 = {discard_ack, ED3},
11745                throw({error, Err3, ErrReply3})
11746        end,
11747    {Tid, OED} =
11748        case NR of
11749            #'NotifyRequest'{terminationID            = [TermID],
11750                             observedEventsDescriptor = ObsEvsDesc,
11751                             errorDescriptor          = asn1_NOVALUE} ->
11752                {TermID, ObsEvsDesc};
11753            _ ->
11754                Err4      = {invalid_NR, NR},
11755                ED4       = cre_ErrDesc(NR),
11756                ErrReply4 = {discard_ack, ED4},
11757                throw({error, Err4, ErrReply4})
11758        end,
11759    OE =
11760	case OED of
11761	    #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
11762		ObsEvLst;
11763            _ ->
11764                Err5      = {invalid_OED, OED},
11765                ED5       = cre_ErrDesc(NR),
11766                ErrReply5 = {discard_ack, ED5},
11767                throw({error, Err5, ErrReply5})
11768        end,
11769    case OE of
11770	#'ObservedEvent'{eventName = "al/of"} ->
11771            Replies = [otp6865e2_mgc_notify_reply_ar(ContextID, Tid)],
11772            Reply   =
11773		case RequireAck of
11774		    true ->
11775			{{handle_ack, otp6865e2}, Replies};
11776		    false ->
11777			{discard_ack, Replies}
11778		end,
11779            {ok, AR, Reply};
11780        _ ->
11781            Err6      = {invalid_OE, OE},
11782            ED6       = cre_ErrDesc(OE),
11783            ErrReply6 = {discard_ack, ED6},
11784            {error, Err6, ErrReply6}
11785    end.
11786
11787%% Ack verification
11788-ifndef(megaco_hipe_special).
11789otp6865e2_mgc_verify_reply_ack_fun(ExtraInfo) ->
11790    fun(M) ->
11791	    otp6865e2_mgc_verify_reply_ack(M, ExtraInfo)
11792    end.
11793-endif.
11794
11795otp6865e2_mgc_verify_reply_ack(
11796  {handle_trans_ack, _, ?VERSION, ok, otp6865e2, ExtraInfo}, ExtraInfo) ->
11797    io:format("otp6865e2_mgc_verify_reply_ack -> ok~n", []),
11798    {ok, ok, ok};
11799otp6865e2_mgc_verify_reply_ack(
11800  {handle_trans_ack, _, ?VERSION, AS, AD, ExtraInfo1} = Crap, ExtraInfo2) ->
11801    io:format("otp6865e2_mgc_verify_reply_ack -> incorrect ack-status:"
11802	      "~n   AS:         ~p"
11803	      "~n   AD:         ~p"
11804	      "~n   ExtraInfo1: ~p"
11805	      "~n   ExtraInfo2: ~p"
11806	      "~n", [AS, AD, ExtraInfo1, ExtraInfo2]),
11807    ED       = cre_ErrDesc({invalid_ack_status,
11808			    {AS, AD, ExtraInfo1, ExtraInfo2}}),
11809    ErrReply = {discard_ack, ED},
11810    {error, Crap, ErrReply};
11811otp6865e2_mgc_verify_reply_ack(Crap, ExtraInfo) ->
11812    io:format("otp6865e2_mgc_verify_reply_ack -> invalid ack:"
11813	      "~n   Crap:      ~p"
11814	      "~n   ExtraInfo: ~p"
11815	      "~n", [Crap, ExtraInfo]),
11816    ED       = cre_ErrDesc({Crap, ExtraInfo}),
11817    ErrReply = {discard_ack, ED},
11818    {error, Crap, ErrReply}.
11819
11820
11821%% Notify reply verification
11822-ifndef(megaco_hipe_special).
11823otp6865e2_mgc_verify_notify_reply_fun(ExtraInfo) ->
11824    fun(Rep) ->
11825	    otp6865e2_mgc_verify_notify_reply(Rep, ExtraInfo)
11826    end.
11827-endif.
11828
11829otp6865e2_mgc_verify_notify_reply(
11830  {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _, ExtraInfo}, ExtraInfo) ->
11831    io:format("otp6865e2_mgc_verify_notify_reply -> ok"
11832	      "~n   AR:        ~p"
11833	      "~n   ExtraInfo: ~p"
11834	      "~n", [AR, ExtraInfo]),
11835    {ok, AR, ok};
11836otp6865e2_mgc_verify_notify_reply(Else, ExtraInfo) ->
11837    io:format("otp6865e2_mgc_verify_notify_reply -> received unknown event"
11838	      "~n   Else:      ~p"
11839	      "~n   ExtraInfo: ~p"
11840	      "~n", [Else, ExtraInfo]),
11841    {error, {Else, ExtraInfo}, ok}.
11842
11843
11844%% Disconnect verification
11845otp6865e2_mgc_verify_handle_disconnect(
11846  {handle_disconnect, CH, ?VERSION, R}) ->
11847    io:format("otp6865e2_mgc_verify_handle_disconnect -> ok"
11848	      "~n   CH: ~p"
11849	      "~n   R:  ~p"
11850	      "~n", [CH, R]),
11851    {ok, CH, ok};
11852otp6865e2_mgc_verify_handle_disconnect(Else) ->
11853    io:format("otp6865e2_mgc_verify_handle_disconnect -> unknown"
11854	      "~n   Else: ~p~n", [Else]),
11855    {error, Else, ok}.
11856
11857
11858otp6865e2_mgc_service_change_reply_ar(Mid, Cid) ->
11859    SCRP  = cre_serviceChangeResParm(Mid),
11860    SCRes = cre_serviceChangeResult(SCRP),
11861    Root  = #megaco_term_id{id = ["root"]},
11862    SCR   = cre_serviceChangeReply([Root], SCRes),
11863    CR    = cre_cmdReply(SCR),
11864    cre_actionReply(Cid, [CR]).
11865
11866otp6865e2_mgc_notify_reply_ar(Cid, TermId) ->
11867    NR    = cre_notifyReply([TermId]),
11868    CR    = cre_cmdReply(NR),
11869    cre_actionReply(Cid, [CR]).
11870
11871otp6865e2_mgc_notify_request_ar(Rid, Tid, Cid) ->
11872    TT      = cre_timeNotation("19990729", "22000000"),
11873    Ev      = cre_obsEvent("al/of", TT),
11874    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
11875    NR      = cre_notifyReq([Tid], EvsDesc),
11876    CMD     = cre_command(NR),
11877    CR      = cre_cmdReq(CMD),
11878    cre_actionReq(Cid, [CR]).
11879
11880
11881%%
11882%% MG generator stuff
11883%%
11884-ifdef(megaco_hipe_special).
11885-define(otp6865e2_mg_decode_msg_fun(Mod, Conf),
11886	{?MODULE, decode_msg, [Mod, Conf]}).
11887-define(otp6865e2_mg_encode_msg_fun(Mod, Conf),
11888	{?MODULE, encode_msg, [Mod, Conf]}).
11889-define(otp6865e2_mg_verify_service_change_rep_msg_fun(),
11890	{?MODULE, otp6865e2_mg_verify_service_change_rep_msg, []}).
11891-define(otp6865e2_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId, AckRequired),
11892	{?MODULE, otp6865e2_mg_verify_notify_rep_msg, [TermId, TransId, ReqId, CtxId, AckRequired]}).
11893-define(otp6865e2_mg_verify_notify_req_msg_fun(),
11894	{?MODULE, otp6865e2_mg_verify_notify_req_msg, []}).
11895-else.
11896-define(otp6865e2_mg_decode_msg_fun(Mod, Conf),
11897	otp6865e2_mg_decode_msg_fun(Mod, Conf)).
11898-define(otp6865e2_mg_encode_msg_fun(Mod, Conf),
11899	otp6865e2_mg_encode_msg_fun(Mod, Conf)).
11900-define(otp6865e2_mg_verify_service_change_rep_msg_fun(),
11901	otp6865e2_mg_verify_service_change_rep_msg_fun()).
11902-define(otp6865e2_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId, AckRequired),
11903	otp6865e2_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId, AckRequired)).
11904-define(otp6865e2_mg_verify_notify_req_msg_fun(),
11905	otp6865e2_mg_verify_notify_req_msg_fun()).
11906-endif.
11907
11908otp6865e2_mg_event_sequence(text, tcp) ->
11909    DecodeFun = ?otp6865e2_mg_decode_msg_fun(megaco_pretty_text_encoder, []),
11910    EncodeFun = ?otp6865e2_mg_encode_msg_fun(megaco_pretty_text_encoder, []),
11911    Mid       = {deviceName,"mg"},
11912    ServiceChangeReq = otp6865e2_mg_service_change_request_msg(Mid, 1, 0),
11913    ScrVerifyFun = ?otp6865e2_mg_verify_service_change_rep_msg_fun(),
11914    TermId1 = #megaco_term_id{id = ["00000000","00000000","01101101"]},
11915    TermId2 = #megaco_term_id{id = ["00000000","00000000","10010010"]},
11916    NotifyReq1 =
11917	otp6865e2_mg_notify_request_msg(Mid, TermId1, 2, 1, 1),
11918    NrVerifyFun1 =
11919	?otp6865e2_mg_verify_notify_rep_msg_fun(TermId1, 2, 1, 1, false),
11920    NotifyReq2 =
11921	otp6865e2_mg_notify_request_msg(Mid, TermId2, 3, 2, 2),
11922    NrVerifyFun2 =
11923	?otp6865e2_mg_verify_notify_rep_msg_fun(TermId2, 3, 2, 2, true),
11924    TransAck = otp6865e2_mg_trans_ack_msg(Mid, 3),
11925    NotifyReqVerifyFun  = ?otp6865e2_mg_verify_notify_req_msg_fun(),
11926    NotifyReply = otp6865e2_mg_notify_reply_msg(Mid, 1, 0, TermId1),
11927    EvSeq = [{debug,  true},
11928             {decode, DecodeFun},
11929             {encode, EncodeFun},
11930             {connect, 2944},
11931
11932             {send, "service-change-request", ServiceChangeReq},
11933             {expect_receive, "service-change-reply", {ScrVerifyFun, 10000}},
11934
11935	     %% the original setting for reply timer is 2000
11936             {send, "notify request 1", NotifyReq1},
11937             {expect_receive, "notify-reply 1", {NrVerifyFun1, 2500}},
11938	     {sleep, 1000},
11939             {send, "notify request 2", NotifyReq2},
11940             {expect_receive, "notify-reply 2", {NrVerifyFun2, 2500}},
11941	     {sleep, 100},
11942             {send, "transacktion-ack", TransAck},
11943             {expect_receive, "notify-request", {NotifyReqVerifyFun, 2500}},
11944	     {sleep, 100},
11945             {send, "notify-reply", NotifyReply},
11946
11947             {expect_nothing, 5000},
11948             disconnect
11949            ],
11950    EvSeq.
11951
11952-ifndef(megaco_hipe_special).
11953otp6865e2_mg_encode_msg_fun(Mod, Conf) ->
11954    fun(M) ->
11955            encode_msg(M, Mod, Conf)
11956    end.
11957-endif.
11958
11959-ifndef(megaco_hipe_special).
11960otp6865e2_mg_decode_msg_fun(Mod, Conf) ->
11961    fun(M) ->
11962            decode_msg(M, Mod, Conf)
11963    end.
11964-endif.
11965
11966-ifndef(megaco_hipe_special).
11967otp6865e2_mg_verify_service_change_rep_msg_fun() ->
11968    fun(Msg) ->
11969	    (catch otp6865e2_mg_verify_service_change_rep_msg(Msg))
11970    end.
11971-endif.
11972
11973otp6865e2_mg_verify_service_change_rep_msg(#'MegacoMessage'{mess = Mess} = M) ->
11974    Body =
11975	case Mess of
11976	    #'Message'{version     = _V,
11977                       mId         = _MgMid,
11978                       messageBody = MsgBody} ->
11979		MsgBody;
11980	    _ ->
11981		throw({error, {invalid_Message, Mess}})
11982	end,
11983    Trans =
11984	case Body of
11985            {transactions, [Transactions]} ->
11986		Transactions;
11987	    _ ->
11988		throw({error, {invalid_messageBody, Body}})
11989	end,
11990    TR =
11991	case Trans of
11992            {transactionReply, TransReply} ->
11993		TransReply;
11994	    _ ->
11995		throw({error, {invalid_transactions, Trans}})
11996	end,
11997    TRes =
11998	case TR of
11999            #'TransactionReply'{transactionId = _Tid,
12000                                immAckRequired = asn1_NOVALUE,
12001                                transactionResult = TransRes} ->
12002		TransRes;
12003	    _ ->
12004		throw({error, {invalid_transactionReply, TR}})
12005	end,
12006    AR =
12007	case TRes of
12008            {actionReplies, [ActRes]} ->
12009		ActRes;
12010	    _ ->
12011		throw({error, {invalid_transactionResult, TRes}})
12012	end,
12013    CR =
12014	case AR of
12015            #'ActionReply'{contextId       = _Cid,
12016                           errorDescriptor = asn1_NOVALUE,
12017                           contextReply    = _CtxReq,
12018                           commandReply    = [CmdRep]} ->
12019		CmdRep;
12020	    _ ->
12021		throw({error, {invalid_actionReplies, AR}})
12022	end,
12023    SCR =
12024	case CR of
12025            {serviceChangeReply, ServChRep} ->
12026		ServChRep;
12027	    _ ->
12028		throw({error, {invalid_commandReply, CR}})
12029	end,
12030    SCRes =
12031	case SCR of
12032            #'ServiceChangeReply'{terminationID       = _TermID,
12033                                  serviceChangeResult = ServChRes} ->
12034		ServChRes;
12035	    _ ->
12036		throw({error, {invalid_serviceChangeReply, SCR}})
12037	end,
12038    SCRP =
12039	case SCRes of
12040            {serviceChangeResParms, Parms} ->
12041		Parms;
12042	    _ ->
12043		throw({error, {invalid_serviceChangeResult, SCRes}})
12044	end,
12045    case SCRP of
12046	#'ServiceChangeResParm'{serviceChangeMgcId = _MgcMid} ->
12047            {ok, M};
12048	_ ->
12049	    {error, {invalid_serviceChangeResParms, SCRP}}
12050    end;
12051otp6865e2_mg_verify_service_change_rep_msg(Crap) ->
12052    {error, {invalid_message, Crap}}.
12053
12054-ifndef(megaco_hipe_special).
12055otp6865e2_mg_verify_notify_rep_msg_fun(TermId, TransId, Rid, Cid,
12056				       AckRequired) ->
12057    fun(Msg) ->
12058	    (catch otp6865e2_mg_verify_notify_rep_msg(Msg,
12059						      TermId, TransId,
12060						      Rid, Cid,
12061						      AckRequired))
12062    end.
12063-endif.
12064
12065otp6865e2_mg_verify_notify_rep_msg(#'MegacoMessage'{mess = Mess} = M,
12066				   TermId, TransId, Rid, Cid, AckRequired) ->
12067    io:format("otp6865e2_mg_verify_notify_rep_msg -> entry with"
12068	      "~n   M:       ~p"
12069	      "~n   TermId:  ~p"
12070	      "~n   TransId: ~p"
12071	      "~n   Rid:     ~p"
12072	      "~n   Cid:     ~p"
12073	      "~n", [M, TermId, TransId, Rid, Cid]),
12074    Body =
12075	case Mess of
12076	    #'Message'{version     = ?VERSION,
12077                       mId         = _Mid,
12078                       messageBody = MsgBody} ->
12079		MsgBody;
12080	    _ ->
12081		throw({error, {invalid_Message, Mess}})
12082	end,
12083    io:format("otp6865e2_mg_verify_notify_rep_msg -> "
12084	      "~n   Body: ~p"
12085	      "~n", [Body]),
12086    Trans =
12087	case Body of
12088            {transactions, [Transactions]} ->
12089		Transactions;
12090	    _ ->
12091		throw({error, {invalid_messageBody, Body}})
12092	end,
12093    io:format("otp6865e2_mg_verify_notify_rep_msg -> "
12094	      "~n   Trans: ~p"
12095	      "~n", [Trans]),
12096    TR =
12097	case Trans of
12098            {transactionReply, TransReply} ->
12099		TransReply;
12100	    _ ->
12101		throw({error, {invalid_transactions, Trans}})
12102	end,
12103    io:format("otp6865e2_mg_verify_notify_rep_msg -> "
12104	      "~n   TR: ~p"
12105	      "~n", [TR]),
12106    TRes =
12107	case TR of
12108            #'TransactionReply'{transactionId     = TransId,
12109                                immAckRequired    = asn1_NOVALUE,
12110                                transactionResult = TransRes} when (AckRequired == false) ->
12111		TransRes;
12112            #'TransactionReply'{transactionId     = TransId,
12113                                immAckRequired    = 'NULL',
12114                                transactionResult = TransRes} when (AckRequired == true) ->
12115		TransRes;
12116	    _ ->
12117		throw({error, {invalid_transactionReply, TR}})
12118	end,
12119    io:format("otp6865e2_mg_verify_notify_rep_msg -> "
12120	      "~n   TRes: ~p"
12121	      "~n", [TRes]),
12122    AR =
12123	case TRes of
12124            {actionReplies, [ActRes]} ->
12125		ActRes;
12126	    _ ->
12127		throw({error, {invalid_transactionResult, TRes}})
12128	end,
12129    io:format("otp6865e2_mg_verify_notify_rep_msg -> "
12130	      "~n   AR: ~p"
12131	      "~n", [AR]),
12132    CR =
12133	case AR of
12134            #'ActionReply'{contextId       = Cid,
12135                           errorDescriptor = asn1_NOVALUE,
12136                           contextReply    = _CtxReq,
12137                           commandReply    = [CmdRep]} ->
12138		CmdRep;
12139	    _ ->
12140		throw({error, {invalid_actionReplies, AR}})
12141	end,
12142    NR =
12143	case CR of
12144            {notifyReply, NotifyReply} ->
12145		NotifyReply;
12146	    _ ->
12147		throw({error, {invalid_commandReply, CR}})
12148	end,
12149    case NR of
12150	#'NotifyReply'{terminationID   = [TermId],
12151		       errorDescriptor = asn1_NOVALUE} ->
12152	    {ok, M};
12153	_ ->
12154	    {error, {invalid_notifyReply, NR}}
12155    end;
12156otp6865e2_mg_verify_notify_rep_msg(Crap, _TermId, _TransId, _Rid, _Cid, _AckRequired) ->
12157    {error, {invalid_message, Crap}}.
12158
12159-ifndef(megaco_hipe_special).
12160otp6865e2_mg_verify_notify_req_msg_fun() ->
12161    fun(M) ->
12162	    otp6865e2_mg_verify_notify_req_msg(M)
12163    end.
12164-endif.
12165
12166otp6865e2_mg_verify_notify_req_msg(#'MegacoMessage'{mess = Mess} = M) ->
12167    io:format("otp6865e2_mg_verify_notify_req_msg -> entry with"
12168	      "~n   M:       ~p"
12169	      "~n", [M]),
12170    Body =
12171	case Mess of
12172	    #'Message'{version     = ?VERSION,
12173                       mId         = _Mid,
12174                       messageBody = MsgBody} ->
12175		MsgBody;
12176	    _ ->
12177		throw({error, {invalid_Message, Mess}})
12178	end,
12179    io:format("otp6865e2_mg_verify_notify_req_msg -> "
12180	      "~n   Body: ~p"
12181	      "~n", [Body]),
12182    Trans =
12183	case Body of
12184            {transactions, [Transactions]} ->
12185		Transactions;
12186	    _ ->
12187		throw({error, {invalid_messageBody, Body}})
12188	end,
12189    io:format("otp6865e2_mg_verify_notify_req_msg -> "
12190	      "~n   Trans: ~p"
12191	      "~n", [Trans]),
12192    TR =
12193	case Trans of
12194            {transactionRequest, TransRequest} ->
12195		TransRequest;
12196	    _ ->
12197		throw({error, {invalid_transactions, Trans}})
12198	end,
12199    io:format("otp6865e2_mg_verify_notify_req_msg -> "
12200	      "~n   TR: ~p"
12201	      "~n", [TR]),
12202    AR =
12203	case TR of
12204            #'TransactionRequest'{transactionId = _TransId,
12205				  actions       = [ActReq]} ->
12206		ActReq;
12207	    _ ->
12208		throw({error, {invalid_transactionRequest, TR}})
12209	end,
12210    io:format("otp6865e2_mg_verify_notify_req_msg -> "
12211	      "~n   AR: ~p"
12212	      "~n", [AR]),
12213    CR =
12214	case AR of
12215	    #'ActionRequest'{contextId       = _Cid,
12216			     commandRequests = [CmdReq]} ->
12217		CmdReq;
12218	    _ ->
12219		throw({error, {invalid_actions, AR}})
12220	end,
12221    io:format("otp6865e2_mg_verify_notify_req_msg -> "
12222	      "~n   CR: ~p"
12223	      "~n", [CR]),
12224    Cmd =
12225	case CR of
12226	    #'CommandRequest'{command = Command} ->
12227		Command;
12228	    _ ->
12229		throw({error, {invalid_commandRequests, CR}})
12230	end,
12231    io:format("otp6865e2_mg_verify_notify_req_msg -> "
12232	      "~n   Cmd: ~p"
12233	      "~n", [Cmd]),
12234    NR =
12235	case Cmd of
12236	    {notifyReq, NotifReq} ->
12237		NotifReq;
12238	    _ ->
12239		throw({error, {invalid_command, Cmd}})
12240	end,
12241    io:format("otp6865e2_mg_verify_notify_req_msg -> "
12242	      "~n   NR: ~p"
12243	      "~n", [NR]),
12244    OED =
12245	case NR of
12246	    #'NotifyRequest'{terminationID            = [_TermId],
12247			     observedEventsDescriptor = ObsEvsDesc,
12248			     errorDescriptor          = asn1_NOVALUE} ->
12249		ObsEvsDesc;
12250	    _ ->
12251		throw({error, {invalid_notifyReq, NR}})
12252	end,
12253    io:format("otp6865e2_mg_verify_notify_req_msg -> "
12254	      "~n   OED: ~p"
12255	      "~n", [OED]),
12256    OE =
12257	case OED of
12258	    #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
12259		ObsEvLst;
12260	    _ ->
12261		throw({error, {invalid_observedEventsDescriptor, OED}})
12262	end,
12263    io:format("otp6865e2_mg_verify_notify_req_msg -> "
12264	      "~n   OE: ~p"
12265	      "~n", [OE]),
12266    case OE of
12267	#'ObservedEvent'{eventName = "al/of"} ->
12268	    io:format("otp6865e2_mg_verify_notify_req_msg -> verifyed"
12269		      "~n", []),
12270	    {ok, M};
12271	_ ->
12272	    throw({error, {invalid_observedEventLst, OE}})
12273    end;
12274otp6865e2_mg_verify_notify_req_msg(M) ->
12275    {error, {invalid_message, M}}.
12276
12277otp6865e2_mg_service_change_request_ar(_Mid, Cid) ->
12278    Prof  = cre_serviceChangeProf("resgw", 1),
12279    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
12280    Root  = #megaco_term_id{id = ["root"]},
12281    SCR   = cre_serviceChangeReq([Root], SCP),
12282    CMD   = cre_command(SCR),
12283    CR    = cre_cmdReq(CMD),
12284    cre_actionReq(Cid, [CR]).
12285
12286otp6865e2_mg_service_change_request_msg(Mid, TransId, Cid) ->
12287    AR    = otp6865e2_mg_service_change_request_ar(Mid, Cid),
12288    TR    = cre_transReq(TransId, [AR]),
12289    Trans = cre_transaction(TR),
12290    Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
12291    cre_megacoMessage(Mess).
12292
12293otp6865e2_mg_notify_request_ar(Rid, Tid, Cid) ->
12294    TT      = cre_timeNotation("19990729", "22000000"),
12295    Ev      = cre_obsEvent("al/of", TT),
12296    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
12297    NR      = cre_notifyReq([Tid], EvsDesc),
12298    CMD     = cre_command(NR),
12299    CR      = cre_cmdReq(CMD),
12300    cre_actionReq(Cid, [CR]).
12301
12302otp6865e2_mg_notify_request_msg(Mid, TermId, TransId, Rid, Cid) ->
12303    AR      = otp6865e2_mg_notify_request_ar(Rid, TermId, Cid),
12304    TR      = cre_transReq(TransId, [AR]),
12305    Trans   = cre_transaction(TR),
12306    Mess    = cre_message(?VERSION, Mid, cre_transactions([Trans])),
12307    cre_megacoMessage(Mess).
12308
12309otp6865e2_mg_notify_reply_msg(Mid, TransId, Cid, TermId) ->
12310    NR    = cre_notifyReply([TermId]),
12311    CR    = cre_cmdReply(NR),
12312    AR    = cre_actionReply(Cid, [CR]),
12313    TRes  = {actionReplies, [AR]},
12314    TR    = cre_transReply(TransId, TRes),
12315    Trans = cre_transaction(TR),
12316    Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
12317    cre_megacoMessage(Mess).
12318
12319otp6865e2_mg_trans_ack_msg(Mid, TransId) ->
12320    TR    = cre_transRespAck(cre_transAck(TransId)),
12321    Trans = cre_transaction(TR),
12322    Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
12323    cre_megacoMessage(Mess).
12324
12325
12326%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12327
12328otp_7189(suite) ->
12329    [];
12330otp_7189(doc) ->
12331    "...";
12332otp_7189(Config) when is_list(Config) ->
12333    Pre = fun() ->
12334                  MgcNode = make_node_name(mgc),
12335                  MgNode  = make_node_name(mg),
12336                  d("start nodes: "
12337                    "~n      MgcNode: ~p"
12338                    "~n      MgNode:  ~p",
12339                    [MgcNode, MgNode]),
12340                  Nodes = [MgcNode, MgNode],
12341                  ok = ?START_NODES(Nodes, true),
12342                  Nodes
12343          end,
12344    Case = fun do_otp_7189/1,
12345    Post = fun(Nodes) ->
12346                   d("stop nodes"),
12347                   ?STOP_NODES(lists:reverse(Nodes))
12348           end,
12349    try_tc(otp_7189, Pre, Case, Post).
12350
12351do_otp_7189([MgcNode, MgNode]) ->
12352    d("[MGC] start the simulator "),
12353    {ok, Mgc} = megaco_test_megaco_generator:start_link("MGC", MgcNode),
12354
12355    d("[MGC] create the event sequence"),
12356    MgcEvSeq = otp_7189_mgc_event_sequence(text, tcp),
12357
12358    i("wait some time before starting the MGC simulation"),
12359    sleep(1000),
12360
12361    d("[MGC] start the simulation"),
12362    {ok, MgcId} = megaco_test_megaco_generator:exec(Mgc, MgcEvSeq),
12363
12364    %% i("wait some time before starting the MG simulator"),
12365    %% sleep(1000),
12366
12367    i("await MGC ready announcement"),
12368    receive
12369        announce_mgc ->
12370            i("received MGC ready announcement"),
12371            ok
12372    end,
12373
12374    d("[MG] start the simulator (generator)"),
12375    {ok, Mg} = megaco_test_tcp_generator:start_link("MG", MgNode),
12376
12377    d("[MG] create the event sequence"),
12378    MgEvSeq = otp_7189_mg_event_sequence(text, tcp),
12379
12380    i("wait some time before starting the MG simulation"),
12381    sleep(1000),
12382
12383    d("[MG] start the simulation"),
12384    {ok, MgId} = megaco_test_tcp_generator:exec(Mg, MgEvSeq),
12385
12386    d("await the generator reply(s)"),
12387    await_completion([MgcId, MgId], 60000),
12388
12389    %% Tell Mgc to stop
12390    i("[MGC] stop generator"),
12391    megaco_test_megaco_generator:stop(Mgc),
12392
12393    %% Tell Mg to stop
12394    i("[MG] stop generator"),
12395    megaco_test_tcp_generator:stop(Mg),
12396
12397    i("done", []),
12398    ok.
12399
12400
12401%%
12402%% MGC generator stuff
12403%%
12404-ifdef(megaco_hipe_special).
12405-define(otp_7189_mgc_verify_handle_connect_fun(),
12406        {?MODULE, otp_7189_mgc_verify_handle_connect, []}).
12407-define(otp_7189_mgc_verify_service_change_req_fun(Mid),
12408        {?MODULE, otp_7189_mgc_verify_service_change_req, [Mid]}).
12409-define(otp_7189_mgc_verify_handle_trans_rep_fun(),
12410	{?MODULE, otp_7189_mgc_verify_handle_trans_rep, []}).
12411-define(otp_7189_mgc_verify_handle_disconnect_fun(),
12412        {?MODULE, otp_7189_mgc_verify_handle_disconnect, []}).
12413-else.
12414-define(otp_7189_mgc_verify_handle_connect_fun(),
12415        otp_7189_mgc_verify_handle_connect_fun()).
12416-define(otp_7189_mgc_verify_service_change_req_fun(Mid),
12417        otp_7189_mgc_verify_service_change_req_fun(Mid)).
12418-define(otp_7189_mgc_verify_handle_trans_rep_fun(),
12419	otp_7189_mgc_verify_handle_trans_rep_fun()).
12420-define(otp_7189_mgc_verify_handle_disconnect_fun(),
12421	fun otp_7189_mgc_verify_handle_disconnect/1).
12422-endif.
12423
12424otp_7189_mgc_event_sequence(text, tcp) ->
12425    CTRL = self(),
12426    Mid = {deviceName,"ctrl"},
12427    RI = [
12428          {port,             2944},
12429          {encoding_module,  megaco_pretty_text_encoder},
12430          {encoding_config,  []},
12431          {transport_module, megaco_tcp}
12432         ],
12433    Tid = #megaco_term_id{id = ["00000000","00000000","01101101"]},
12434    NotifyReq     = [otp_7189_mgc_notify_req_ar(1, Tid, 1)],
12435    ConnectVerify = ?otp_7189_mgc_verify_handle_connect_fun(),
12436    ScrVerify     = ?otp_7189_mgc_verify_service_change_req_fun(Mid),
12437    TransReplyVerify = ?otp_7189_mgc_verify_handle_trans_rep_fun(),
12438    PendingCountersVerify1 =
12439	fun([{Counter, 1}]) ->
12440		   io:format("received expected recv pending counter:"
12441			     "~n   Counter: ~p"
12442			     "~n", [Counter]),
12443		ok;
12444	   (BadCounters) ->
12445		io:format("ERROR: "
12446			  "received unexpected number of "
12447			  "recv pending counters "
12448			  "(expected one with counter value 1):"
12449			  "~n   BadCounters: ~p"
12450			  "~n", [BadCounters]),
12451		{error, {invalid_pending_counters, BadCounters}}
12452	end,
12453    PendingCountersVerify2 =
12454	fun([]) ->
12455		io:format("received expected number of recv pending counters (none)"
12456			  "~n", []),
12457		ok;
12458	   (BadCounters) ->
12459		io:format("ERROR: "
12460			  "received unexpected number of "
12461			  "recv pending counters "
12462			  "(expected none):"
12463			  "~n   BadCounters: ~p"
12464			  "~n", [BadCounters]),
12465		{error, {invalid_pending_counters, BadCounters}}
12466	end,
12467    EvSeq = [
12468             {debug, true},
12469	     {megaco_trace, disable},
12470	     {megaco_trace, max},
12471             megaco_start,
12472             {megaco_start_user, Mid, RI, []},
12473	     {megaco_update_user_info, recv_pending_limit, 10},
12474
12475	     {megaco_update_user_info, long_request_timer, timer:seconds(10)},
12476	     {megaco_user_info, all},
12477             start_transport,
12478             listen,
12479
12480             %% ANNOUNCE READY
12481             {trigger, fun() -> CTRL ! announce_mgc end},
12482
12483             {megaco_callback, handle_connect, ConnectVerify},
12484	     {megaco_conn_info, all},
12485             {megaco_callback, handle_trans_request, ScrVerify},
12486	     {sleep, 500},
12487             {megaco_cast, NotifyReq, []},
12488
12489	     %% Wait for 5 seconds to make sure we are on track
12490             {megaco_callback, nocall, timer:seconds(5)},
12491	     {megaco_system_info, recv_pending_counters, PendingCountersVerify1},
12492
12493	     %% Now wait for the timeout to hit
12494	     {megaco_callback, handle_trans_reply, TransReplyVerify},
12495	     {megaco_system_info, recv_pending_counters, PendingCountersVerify2},
12496
12497             megaco_stop_user,
12498             megaco_stop
12499            ],
12500    EvSeq.
12501
12502
12503-ifndef(megaco_hipe_special).
12504otp_7189_mgc_verify_handle_connect_fun() ->
12505    fun(M) ->
12506	    otp_7189_mgc_verify_handle_connect(M)
12507    end.
12508-endif.
12509
12510otp_7189_mgc_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
12511    {ok, CH, ok};
12512otp_7189_mgc_verify_handle_connect(Else) ->
12513    {error, Else, ok}.
12514
12515-ifndef(megaco_hipe_special).
12516otp_7189_mgc_verify_service_change_req_fun(Mid) ->
12517    fun(Req) ->
12518	    otp_7189_mgc_verify_service_change_req(Req, Mid)
12519    end.
12520-endif.
12521
12522otp_7189_mgc_verify_service_change_req(
12523  {handle_trans_request, _, ?VERSION, [AR]}, Mid) ->
12524    io:format("otp_7189_mgc_verify_service_change_req -> ok"
12525	      "~n   AR: ~p~n", [AR]),
12526    case AR of
12527	#'ActionRequest'{commandRequests = [CR]} ->
12528	    case CR of
12529		#'CommandRequest'{command = Cmd} ->
12530		    case Cmd of
12531			{serviceChangeReq,
12532			 #'ServiceChangeRequest'{terminationID = [Tid],
12533						 serviceChangeParms = Parms}} ->
12534			    case Tid of
12535				#megaco_term_id{contains_wildcards = false,
12536						id = ["root"]} ->
12537				    case Parms of
12538					#'ServiceChangeParm'{
12539						 serviceChangeMethod = restart,
12540						 serviceChangeReason = [[$9,$0,$1|_]]} ->
12541					    Reply =
12542						{discard_ack,
12543						 [otp_7189_mgc_service_change_reply_ar(Mid, 1)]},
12544					    {ok, AR, Reply};
12545					_ ->
12546					    Err = {invalid_SCP, Parms},
12547					    ED = otp_7189_err_desc(Parms),
12548					    ErrReply = {discard_ack, ED},
12549					    {error, Err, ErrReply}
12550				    end;
12551				_ ->
12552				    Err = {invalid_termination_id, Tid},
12553				    ED = otp_7189_err_desc(Tid),
12554				    ErrReply = {discard_ack, ED},
12555				    {error, Err, ErrReply}
12556			    end;
12557			_ ->
12558			    Err = {invalid_command, Cmd},
12559			    ED = otp_7189_err_desc(Cmd),
12560			    ErrReply = {discard_ack, ED},
12561			    {error, Err, ErrReply}
12562		    end;
12563		_ ->
12564		    Err = {invalid_command_request, CR},
12565		    ED = otp_7189_err_desc(CR),
12566		    ErrReply = {discard_ack, ED},
12567		    {error, Err, ErrReply}
12568	    end;
12569	_ ->
12570	    Err = {invalid_action_request, AR},
12571	    ED = otp_7189_err_desc(AR),
12572	    ErrReply = {discard_ack, ED},
12573	    {error, Err, ErrReply}
12574    end;
12575otp_7189_mgc_verify_service_change_req(Else, _Mid) ->
12576    io:format("otp_7189_mgc_verify_service_change_req -> unknown"
12577	      "~n   Else: ~p~n", [Else]),
12578    ED       = otp_7189_err_desc(Else),
12579    ErrReply = {discard_ack, ED},
12580    {error, Else, ErrReply}.
12581
12582otp_7189_mgc_notify_req_ar(Rid, Tid, Cid) ->
12583    TT      = cre_timeNotation("19990729", "22000000"),
12584    Ev      = cre_obsEvent("al/of", TT),
12585    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
12586    NR      = cre_notifyReq([Tid], EvsDesc),
12587    CMD     = cre_command(NR),
12588    CR      = cre_cmdReq(CMD),
12589    cre_actionReq(Cid, [CR]).
12590
12591otp_7189_mgc_service_change_reply_ar(Mid, Cid) ->
12592    SCRP  = cre_serviceChangeResParm(Mid),
12593    SCRes = cre_serviceChangeResult(SCRP),
12594    Root  = #megaco_term_id{id = ["root"]},
12595    SCR   = cre_serviceChangeReply([Root], SCRes),
12596    CR    = cre_cmdReply(SCR),
12597    AR    = cre_actionReply(Cid, [CR]),
12598    AR.
12599
12600-ifndef(megaco_hipe_special).
12601otp_7189_mgc_verify_handle_trans_rep_fun() ->
12602    fun(Event) ->
12603            (catch otp_7189_mgc_verify_handle_trans_rep(Event))
12604    end.
12605-endif.
12606
12607otp_7189_mgc_verify_handle_trans_rep(
12608  {handle_trans_reply, CH, ?VERSION, {error, timeout} = Error, _}) ->
12609    io:format("otp_6275_mgc_verify_trans_rep -> expected error"
12610	      "~n   CH: ~p"
12611              "~n", [CH]),
12612    {ok, Error, error};
12613otp_7189_mgc_verify_handle_trans_rep(
12614  {handle_trans_reply, _CH, ?VERSION, Error, _}) ->
12615    io:format("otp_6275_mgc_verify_handle_trans_rep -> unexpected error"
12616              "~n   Error: ~p"
12617              "~n", [Error]),
12618    {error, Error, error};
12619otp_7189_mgc_verify_handle_trans_rep(Else) ->
12620    io:format("otp_6275_mg_verify_handle_trans_rep -> unknown"
12621              "~n   Else: ~p~n", [Else]),
12622    {error, Else, error}.
12623
12624
12625
12626%%
12627%% MG generator stuff
12628%%
12629-ifdef(megaco_hipe_special).
12630-define(otp_7189_mg_decode_msg_fun(Mod, Conf),
12631	{?MODULE, decode_msg, [Mod, Conf]}).
12632-define(otp_7189_mg_encode_msg_fun(Mod, Conf),
12633	{?MODULE, encode_msg, [Mod, Conf]}).
12634-define(otp_7189_mg_verify_service_change_rep_msg_fun(),
12635	{?MODULE, otp_7189_mg_verify_service_change_rep_msg, []}).
12636-define(otp_7189_mg_verify_notify_req_msg_fun(TermId, TransId, ReqId, CtxId),
12637	{?MODULE, otp_7189_mg_verify_notify_req_msg, [TermId, TransId, ReqId, CtxId]}).
12638-else.
12639-define(otp_7189_mg_decode_msg_fun(Mod, Conf),
12640	otp_7189_mg_decode_msg_fun(Mod, Conf)).
12641-define(otp_7189_mg_encode_msg_fun(Mod, Conf),
12642	otp_7189_mg_encode_msg_fun(Mod, Conf)).
12643-define(otp_7189_mg_verify_service_change_rep_msg_fun(),
12644	otp_7189_mg_verify_service_change_rep_msg_fun()).
12645-define(otp_7189_mg_verify_notify_req_msg_fun(TermId, TransId, ReqId, CtxId),
12646	otp_7189_mg_verify_notify_req_msg_fun(TermId, TransId, ReqId, CtxId)).
12647-endif.
12648
12649otp_7189_mg_event_sequence(text, tcp) ->
12650    DecodeFun = ?otp_7189_mg_decode_msg_fun(megaco_pretty_text_encoder, []),
12651    EncodeFun = ?otp_7189_mg_encode_msg_fun(megaco_pretty_text_encoder, []),
12652    Mid = {deviceName,"mg"},
12653    ServiceChangeReq = otp_7189_mg_service_change_request_msg(Mid, 1, 0),
12654    TermId    =
12655        #megaco_term_id{id = ["00000000","00000000","01101101"]},
12656    TransId   = 1,
12657    ReqId     = 1,
12658    CtxId     = 1,
12659    Pending   = otp_7189_mg_trans_pending_msg(Mid, TransId),
12660    ServiceChangeReplyVerifyFun =
12661	?otp_7189_mg_verify_service_change_rep_msg_fun(),
12662    NotifyReqVerify = ?otp_7189_mg_verify_notify_req_msg_fun(TermId, TransId, ReqId, CtxId),
12663    EvSeq = [
12664	     ?GD_ENABLE(),
12665	     {decode, DecodeFun},
12666	     {encode, EncodeFun},
12667	     {connect, 2944},
12668	     ?GSND("service-change-request", ServiceChangeReq),
12669	     ?GERCV("service-change-reply", ServiceChangeReplyVerifyFun, ?SECS(5)),
12670	     ?GERCV("notify request",       NotifyReqVerify,             ?SECS(5)),
12671	     ?GS(100),
12672	     ?GSND("pending", Pending),
12673	     {expect_closed, timer:seconds(120)},
12674	     disconnect
12675	    ],
12676    EvSeq.
12677
12678otp_7189_mg_encode_msg_fun(Mod, Conf) ->
12679    fun(M) ->
12680            encode_msg(M, Mod, Conf)
12681    end.
12682
12683otp_7189_mg_decode_msg_fun(Mod, Conf) ->
12684    fun(M) ->
12685            decode_msg(M, Mod, Conf)
12686    end.
12687
12688otp_7189_mg_service_change_request_ar(_Mid, Cid) ->
12689    Prof  = cre_serviceChangeProf("resgw", 1),
12690    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
12691    Root  = #megaco_term_id{id = ["root"]},
12692    SCR   = cre_serviceChangeReq([Root], SCP),
12693    CMD   = cre_command(SCR),
12694    CR    = cre_cmdReq(CMD),
12695    cre_actionReq(Cid, [CR]).
12696
12697otp_7189_mg_service_change_request_msg(Mid, TransId, Cid) ->
12698    AR    = otp_7189_mg_service_change_request_ar(Mid, Cid),
12699    TR    = cre_transReq(TransId, [AR]),
12700    Trans = cre_transaction(TR),
12701    Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
12702    cre_megacoMessage(Mess).
12703
12704-ifndef(megaco_hipe_special).
12705otp_7189_mg_verify_service_change_rep_msg_fun() ->
12706    fun(M) ->
12707	    otp_7189_mg_verify_service_change_rep_msg(M)
12708    end.
12709-endif.
12710
12711otp_7189_mg_verify_service_change_rep_msg(
12712  #'MegacoMessage'{mess = Mess} = M) ->
12713    io:format("otp_7189_mg_verify_service_change_rep_msg -> "
12714	      "ok so far~n",[]),
12715    #'Message'{version     = _V,
12716	       mId         = _MgMid,
12717	       messageBody = Body} = Mess,
12718    {transactions, [Trans]} = Body,
12719    {transactionReply, TR} = Trans,
12720    #'TransactionReply'{transactionId = _Tid,
12721			immAckRequired = asn1_NOVALUE,
12722			transactionResult = Res} = TR,
12723    {actionReplies, [AR]} = Res,
12724    #'ActionReply'{contextId = _Cid,
12725		   errorDescriptor = asn1_NOVALUE,
12726		   contextReply = _CtxReq,
12727		   commandReply = [CR]} = AR,
12728    {serviceChangeReply, SCR} = CR,
12729    #'ServiceChangeReply'{terminationID = _TermID,
12730			  serviceChangeResult = SCRes} = SCR,
12731    {serviceChangeResParms, SCRP} = SCRes,
12732    #'ServiceChangeResParm'{serviceChangeMgcId = _MgcMid} = SCRP,
12733    {ok, M};
12734otp_7189_mg_verify_service_change_rep_msg(M) ->
12735    {error, {invalid_message, M}}.
12736
12737-ifndef(megaco_hipe_special).
12738otp_7189_mg_verify_notify_req_msg_fun(TermId, TransId, Rid, Cid) ->
12739    fun(Msg) ->
12740            (catch otp_7189_mg_verify_notify_req_msg(Msg,
12741						     TermId,
12742						     TransId, Rid, Cid))
12743    end.
12744-endif.
12745
12746otp_7189_mg_verify_notify_req_msg(#'MegacoMessage'{mess = Mess} = M,
12747				  TermId, TransId, Rid, Cid) ->
12748    io:format("otp_7189_mgc_verify_notify_req_msg -> entry with"
12749              "~n   M:       ~p"
12750              "~n   TermId:  ~p"
12751              "~n   TransId: ~p"
12752              "~n   Rid:     ~p"
12753              "~n   Cid:     ~p"
12754              "~n", [M, TermId, TransId, Rid, Cid]),
12755    Body =
12756        case Mess of
12757            #'Message'{version     = ?VERSION,
12758                       mId         = _Mid,
12759                       messageBody = MsgBody} ->
12760                MsgBody;
12761            _ ->
12762                throw({error, {invalid_Message, Mess}})
12763        end,
12764    Trans =
12765        case Body of
12766            {transactions, [Transactions]} ->
12767                Transactions;
12768            _ ->
12769                throw({error, {invalid_messageBody, Body}})
12770        end,
12771    TR =
12772        case Trans of
12773            {transactionRequest, TransRequest} ->
12774                TransRequest;
12775            _ ->
12776                throw({error, {invalid_transactions, Trans}})
12777        end,
12778    AR =
12779        case TR of
12780            #'TransactionRequest'{transactionId = TransId,
12781                                  actions       = [ActReq]} ->
12782                ActReq;
12783            _ ->
12784                throw({error, {invalid_transactionRequest, TR, TransId}})
12785        end,
12786    CR =
12787        case AR of
12788            #'ActionRequest'{contextId       = Cid,
12789                             commandRequests = [CmdReq]} ->
12790                CmdReq;
12791            _ ->
12792                throw({error, {invalid_actions, AR}})
12793        end,
12794    Cmd =
12795        case CR of
12796            #'CommandRequest'{command = Command} ->
12797                Command;
12798            _ ->
12799                throw({error, {invalid_commandRequests, CR}})
12800        end,
12801    NR =
12802        case Cmd of
12803            {notifyReq, NotifReq} ->
12804                NotifReq;
12805            _ ->
12806                throw({error, {invalid_command, Cmd}})
12807        end,
12808    OED =
12809        case NR of
12810            #'NotifyRequest'{terminationID            = [TermId],
12811                             observedEventsDescriptor = ObsEvsDesc,
12812                             errorDescriptor          = asn1_NOVALUE} ->
12813                ObsEvsDesc;
12814            _ ->
12815                throw({error, {invalid_notifyReq, NR}})
12816        end,
12817    OE =
12818        case OED of
12819            #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
12820                ObsEvLst;
12821            _ ->
12822                throw({error, {invalid_observedEventsDescriptor, OED}})
12823        end,
12824    case OE of
12825        #'ObservedEvent'{eventName = "al/of"} ->
12826            {ok, M};
12827        _ ->
12828            throw({error, {invalid_observedEventLst, OE}})
12829    end;
12830otp_7189_mg_verify_notify_req_msg(Crap, _TermId, _TransId, _Rid, _Cid) ->
12831    {error, {invalid_MegacoMessage, Crap}}.
12832
12833
12834otp_7189_mg_trans_pending_msg(Mid, TransId) ->
12835    TP   = #'TransactionPending'{transactionId = TransId},
12836    Body = {transactions, [{transactionPending, TP}]},
12837    Mess = #'Message'{version     = 1,
12838                      mId         = Mid,
12839                      messageBody = Body},
12840    #'MegacoMessage'{mess = Mess}.
12841
12842
12843otp_7189_err_desc(T) ->
12844    EC = ?megaco_internal_gateway_error,
12845    ET = lists:flatten(io_lib:format("~w",[T])),
12846    #'ErrorDescriptor'{errorCode = EC, errorText = ET}.
12847
12848
12849%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12850
12851
12852otp_7259(suite) ->
12853    [];
12854otp_7259(doc) ->
12855    ["This is a variant of ticket OTP-6442"];
12856otp_7259(Config) when is_list(Config) ->
12857    Pre = fun() ->
12858                  MgNode = make_node_name(mg),
12859                  d("start (MG) node: ~p", [MgNode]),
12860                  Nodes = [MgNode],
12861                  ok = ?START_NODES(Nodes, true),
12862                  Nodes
12863          end,
12864    Case = fun do_otp_7259/1,
12865    Post = fun(Nodes) ->
12866                   d("stop nodes"),
12867                   ?STOP_NODES(lists:reverse(Nodes))
12868           end,
12869    try_tc(otp7259rr, Pre, Case, Post).
12870
12871do_otp_7259([MgNode]) ->
12872    d("[MG] start the simulator "),
12873    {ok, Mg} = megaco_test_megaco_generator:start_link("MG", MgNode),
12874
12875    d("[MG] create the event sequence"),
12876    MgMid = {deviceName,"mg"},
12877    MgEvSeq = otp_7259_mg_event_sequence(MgMid),
12878
12879    i("wait some time before starting the MG simulation"),
12880    sleep(1000),
12881
12882    d("[MG] start the simulation"),
12883    {ok, MgId} = megaco_test_megaco_generator:exec(Mg, MgEvSeq),
12884
12885    i("await the transport module service change send_message event"),
12886    Pid = otp_7259_expect(fun otp_7259_verify_scr_msg/1, 5000),
12887
12888    i("wait some before issuing the service change reply"),
12889    sleep(500),
12890
12891    i("send the service change reply"),
12892    MgcMid = {deviceName,"mgc"},
12893    ServiceChangeReply = otp_7259_mgc_service_change_reply_msg(MgcMid, 1, 1),
12894    megaco_test_generic_transport:incomming_message(Pid, ServiceChangeReply),
12895
12896    i("await the transport module "
12897      "notify-request send_message event from MG: "
12898      "ignore"),
12899    ok = otp_7259_expect(fun otp_7259_verify_first_nr_msg/1, 5000),
12900
12901    i("await the transport module "
12902      "notify-request resend_message event from MG: "
12903      "reply"),
12904    {TransId2, Cid2, TermId2} =
12905	otp_7259_expect(fun otp_7259_verify_second_nr_msg/1, 10000),
12906
12907    i("wait some before issuing the notify reply"),
12908    sleep(500),
12909
12910    i("send the notify reply"),
12911    NotifyReply =
12912	otp_7259_mgc_notify_reply_msg(MgcMid, TransId2, Cid2, TermId2),
12913    megaco_test_generic_transport:incomming_message(Pid, NotifyReply),
12914
12915    d("[MG] await the generator reply"),
12916    await_completion([MgId], 7000),
12917
12918    %% Tell Mg to stop
12919    i("[MG] stop generator"),
12920    megaco_test_megaco_generator:stop(Mg),
12921
12922    i("done", []),
12923    ok.
12924
12925
12926otp_7259_expect(Verify, Timeout) when (Timeout > 0) ->
12927    T = mtime(),
12928    receive
12929	Msg ->
12930	    case (catch Verify(Msg)) of
12931		{ok, Result} ->
12932		    d("verified after ~p msec", [mtime() - T]),
12933		    Result;
12934		skip ->
12935		    otp_7259_expect(Verify, to(Timeout, T));
12936		{error, Reason} ->
12937		    exit({verification_failed, Reason})
12938	    end
12939    after Timeout ->
12940	    exit(timeout)
12941    end;
12942otp_7259_expect(_, _Timeout) ->
12943    exit(timeout).
12944
12945otp_7259_verify_scr_msg(
12946  {transport_event, {send_message, _SH, {message, Msg, Resend}}, Pid})
12947  when is_record(Msg, 'MegacoMessage') andalso ((Resend =:= true) orelse (Resend =:= false)) ->
12948    d("received expected service change request message: "
12949      "~n   Msg:    ~p"
12950      "~n   Resend: ~p", [Msg, Resend]),
12951    Reply = ok,
12952    Pid ! {transport_reply, Reply, self()},
12953    {ok, Pid};
12954otp_7259_verify_scr_msg(Msg) ->
12955    {error, {invalid_message, Msg}}.
12956
12957otp_7259_verify_first_nr_msg(
12958  {transport_event, {send_message, _SH, {message, Msg, Resend}}, Pid})
12959  when is_record(Msg, 'MegacoMessage') andalso ((Resend =:= true) orelse (Resend =:= false)) ->
12960    d("received expected first notify request send message: "
12961      "~n   Msg: ~p", [Msg]),
12962    Reply = ok,
12963    Pid ! {transport_reply, Reply, self()},
12964    {ok, ok};
12965otp_7259_verify_first_nr_msg(Msg) ->
12966    {error, {invalid_message, Msg}}.
12967
12968otp_7259_verify_second_nr_msg(
12969  {transport_event, {send_message, _SH, {message, Msg, Resend}}, Pid})
12970  when is_record(Msg, 'MegacoMessage') andalso ((Resend =:= true) orelse (Resend =:= false)) ->
12971    d("received expected second notify request send message: "
12972      "~n   Msg: ~p", [Msg]),
12973    Reply = ok,
12974    Pid ! {transport_reply, Reply, self()},
12975    #'MegacoMessage'{mess = Mess} = Msg,
12976    #'Message'{mId         = _Mid,
12977	       messageBody = Body} = Mess,
12978    {transactions, Transactions} = Body,
12979    [Transaction] = Transactions,
12980    {transactionRequest, TransReq} = Transaction,
12981    #'TransactionRequest'{transactionId = TransId,
12982			  actions       = Actions} = TransReq,
12983    [Action] = Actions,
12984    #'ActionRequest'{contextId       = Cid,
12985		     commandRequests = CmdReqs} = Action,
12986    [CmdReq] = CmdReqs,
12987    #'CommandRequest'{command = Cmd} = CmdReq,
12988    {notifyReq, NR} = Cmd,
12989    #'NotifyRequest'{terminationID = [TermId]} = NR,
12990    {ok, {TransId, Cid, TermId}};
12991otp_7259_verify_second_nr_msg(Msg) ->
12992    {error, {invalid_message, Msg}}.
12993
12994
12995otp_7259_mgc_service_change_reply_msg(Mid, TransId, Cid) ->
12996    SCRP  = #'ServiceChangeResParm'{serviceChangeMgcId = Mid},
12997    SCRPs = {serviceChangeResParms, SCRP},
12998    Root  = #megaco_term_id{id = ["root"]},
12999    SCR   = #'ServiceChangeReply'{terminationID       = [Root],
13000                                  serviceChangeResult = SCRPs},
13001    CR    = {serviceChangeReply, SCR},
13002    otp_7259_mgc_reply_msg(Mid, TransId, CR, Cid).
13003
13004otp_7259_mgc_notify_reply_msg(Mid, TransId, Cid, TermId) ->
13005    NR  = #'NotifyReply'{terminationID = [TermId]},
13006    CR  = {notifyReply, NR},
13007    otp_7259_mgc_reply_msg(Mid, TransId, CR, Cid).
13008
13009otp_7259_mgc_reply_msg(Mid, TransId, CR, Cid) ->
13010    AR  = #'ActionReply'{contextId    = Cid,
13011                         commandReply = [CR]},
13012    ARs  = {actionReplies, [AR]},
13013    TR   = #'TransactionReply'{transactionId     = TransId,
13014                               transactionResult = ARs},
13015    Body = {transactions, [{transactionReply, TR}]},
13016    Mess = #'Message'{version     = 1,
13017                      mId         = Mid,
13018                      messageBody = Body},
13019    #'MegacoMessage'{mess = Mess}.
13020
13021
13022%%
13023%% MG generator stuff
13024%%
13025-ifdef(megaco_hipe_special).
13026-define(otp_7259_mg_verify_handle_connect_fun(),
13027	{?MODULE, otp_7259_mg_verify_handle_connect, []}).
13028-define(otp_7259_mg_verify_service_change_rep_fun(),
13029	{?MODULE, otp_7259_mg_verify_service_change_rep, []}).
13030-define(otp_7259_mg_verify_notify_rep_fun(),
13031	{?MODULE, otp_7259_mg_verify_notify_rep, []}).
13032-else.
13033-define(otp_7259_mg_verify_handle_connect_fun(),
13034	otp_7259_mg_verify_handle_connect_fun()).
13035-define(otp_7259_mg_verify_service_change_rep_fun(),
13036	otp_7259_mg_verify_service_change_rep_fun()).
13037-define(otp_7259_mg_verify_notify_rep_fun(),
13038	otp_7259_mg_verify_notify_rep_fun()).
13039-endif.
13040
13041otp_7259_mg_event_sequence(Mid) ->
13042    RI = [
13043          {port,             self()}, % This is just a trick to get my pid to the transport module
13044          {encoding_module,  megaco_pretty_text_encoder},
13045          {encoding_config,  []},
13046          {transport_module, megaco_test_generic_transport}
13047         ],
13048    ServiceChangeReq =
13049	otp_7259_mg_service_change_request_ar(Mid, 1),
13050    Tid = #megaco_term_id{id = ["00000000","00000000","01101101"]},
13051    NotifyReq = otp_7259_mg_notify_request_ar(1, Tid, 1),
13052    ConnectVerify =
13053	?otp_7259_mg_verify_handle_connect_fun(),
13054    ServiceChangeReplyVerify =
13055	?otp_7259_mg_verify_service_change_rep_fun(),
13056    NotifyReplyVerify =
13057	?otp_7259_mg_verify_notify_rep_fun(),
13058    EvSeq = [
13059             {debug, false},
13060             megaco_start,
13061             {megaco_start_user, Mid, RI, []},
13062	     {megaco_update_user_info, resend_indication, flag},
13063             start_transport,
13064             {megaco_trace, disable},
13065             {megaco_system_info, users},
13066             {megaco_system_info, connections},
13067             connect,
13068             {megaco_callback, handle_connect, ConnectVerify},
13069             megaco_connect,
13070             {megaco_cast,     [ServiceChangeReq], []},
13071             {megaco_callback, handle_connect,     ConnectVerify},
13072             {megaco_callback, handle_trans_reply, ServiceChangeReplyVerify},
13073             {sleep, 1000},
13074             {megaco_cast,     [NotifyReq],        []},
13075             {megaco_callback, handle_trans_reply, NotifyReplyVerify},
13076             {sleep, 1000},
13077             megaco_stop_user,
13078             megaco_stop,
13079             {sleep, 1000}
13080            ],
13081    EvSeq.
13082
13083
13084-ifndef(megaco_hipe_special).
13085otp_7259_mg_verify_handle_connect_fun() ->
13086    fun(Ev) ->
13087	    otp_7259_mg_verify_handle_connect(Ev)
13088    end.
13089-endif.
13090
13091otp_7259_mg_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
13092    io:format("otp_7259_mg_verify_handle_connect -> ok"
13093	      "~n   CH: ~p~n", [CH]),
13094    {ok, CH, ok};
13095otp_7259_mg_verify_handle_connect(Else) ->
13096    io:format("otp_7259_mg_verify_handle_connect -> unknown"
13097	      "~n   Else: ~p~n", [Else]),
13098    {error, Else, ok}.
13099
13100-ifndef(megaco_hipe_special).
13101otp_7259_mg_verify_service_change_rep_fun() ->
13102    fun(Rep) ->
13103	    otp_7259_mg_verify_service_change_rep(Rep)
13104    end.
13105-endif.
13106
13107otp_7259_mg_verify_service_change_rep(
13108  {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _}) ->
13109    (catch otp_7259_mg_do_verify_service_change_rep(AR));
13110otp_7259_mg_verify_service_change_rep(Crap) ->
13111    {error, Crap, ok}.
13112
13113otp_7259_mg_do_verify_service_change_rep(AR) ->
13114    io:format("otp_7259_mg_verify_service_change_rep -> ok"
13115	      "~n   AR: ~p~n", [AR]),
13116    CR =
13117	case AR of
13118	    #'ActionReply'{commandReply = [CmdRep]} ->
13119		CmdRep;
13120	    _ ->
13121		Reason1 = {invalid_action_reply, AR},
13122		throw({error, Reason1, ok})
13123	end,
13124    SCR =
13125	case CR of
13126	    {serviceChangeReply, ServChRep} ->
13127		ServChRep;
13128	    _ ->
13129		Reason2 = {invalid_command_reply, CR},
13130		throw({error, Reason2, ok})
13131	end,
13132    {Tid, SCRes} =
13133	case SCR of
13134	    #'ServiceChangeReply'{terminationID       = [TermID],
13135				  serviceChangeResult = Res} ->
13136		{TermID, Res};
13137	    _ ->
13138		Reason3 = {invalid_service_change_reply, SCR},
13139		throw({error, Reason3, ok})
13140	end,
13141    case Tid of
13142	#megaco_term_id{contains_wildcards = false, id = ["root"]} ->
13143	    ok;
13144	_ ->
13145	    Reason4 = {invalid_termination_id, Tid},
13146	    throw({error, Reason4, ok})
13147    end,
13148    SCRParm =
13149	case SCRes of
13150	    {serviceChangeResParms, ServChResParms} ->
13151		ServChResParms;
13152	    _ ->
13153		Reason5 = {invalid_serviceChangeResult, SCRes},
13154		throw({error, Reason5, ok})
13155	end,
13156    case SCRParm of
13157	#'ServiceChangeResParm'{serviceChangeMgcId = _RemoteMid} ->
13158	    {ok, AR, ok};
13159	_ ->
13160	    Reason6 = {invalid_service_change_result, SCRParm},
13161	    {error, Reason6, ok}
13162    end.
13163
13164-ifndef(megaco_hipe_special).
13165otp_7259_mg_verify_notify_rep_fun() ->
13166    fun(Rep) ->
13167	    otp_7259_mg_verify_notify_rep(Rep)
13168    end.
13169-endif.
13170
13171otp_7259_mg_verify_notify_rep(
13172  {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _}) ->
13173    io:format("otp_7259_mg_verify_notify_rep -> ok"
13174	      "~n   AR: ~p~n", [AR]),
13175    {ok, AR, ok};
13176otp_7259_mg_verify_notify_rep(Else) ->
13177    io:format("otp_7259_mg_verify_notify_rep -> unknown"
13178	      "~n   Else: ~p~n", [Else]),
13179    {error, Else, ok}.
13180
13181
13182otp_7259_mg_service_change_request_ar(_Mid, Cid) ->
13183    Prof  = cre_serviceChangeProf("resgw", 1),
13184    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
13185    Root  = #megaco_term_id{id = ["root"]},
13186    SCR   = cre_serviceChangeReq([Root], SCP),
13187    CMD   = cre_command(SCR),
13188    CR    = cre_cmdReq(CMD),
13189    cre_actionReq(Cid, [CR]).
13190
13191otp_7259_mg_notify_request_ar(Rid, Tid, Cid) ->
13192    TT      = cre_timeNotation("19990729", "22000000"),
13193    Ev      = cre_obsEvent("al/of", TT),
13194    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
13195    NR      = cre_notifyReq([Tid], EvsDesc),
13196    CMD     = cre_command(NR),
13197    CR      = cre_cmdReq(CMD),
13198    cre_actionReq(Cid, [CR]).
13199
13200
13201%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13202
13203otp_7713(suite) ->
13204    [];
13205otp_7713(doc) ->
13206    [];
13207otp_7713(Config) when is_list(Config) ->
13208    ?ACQUIRE_NODES(1, Config),
13209
13210    put(verbosity, debug),
13211    put(sname,     "TEST"),
13212    put(tc,        otp7713),
13213    i("starting"),
13214
13215    d("start proxy",[]),
13216    ?USER_MOD:start_proxy(),
13217
13218    Extra = otp7713_extra,
13219    PrelMid = preliminary_mid,
13220    MgMid   = ipv4_mid(4711),
13221    MgcMid  = ipv4_mid(),
13222    UserMod = ?USER_MOD,
13223    d("start megaco app",[]),
13224    ?VERIFY(ok, application:start(megaco)),
13225    UserConfig = [{user_mod, UserMod}, {send_mod, UserMod},
13226		  {request_timer, infinity}, {reply_timer, infinity}],
13227    d("start (MG) user ~p",[MgMid]),
13228    ?VERIFY(ok,	megaco:start_user(MgMid, UserConfig)),
13229
13230    d("start (MGC) user ~p",[MgcMid]),
13231    ?VERIFY(ok,	megaco:start_user(MgcMid, UserConfig)),
13232
13233    d("get receive info for ~p",[MgMid]),
13234    MgRH = user_info(MgMid, receive_handle),
13235    d("get receive info for ~p",[MgcMid]),
13236    MgcRH = user_info(MgcMid, receive_handle),
13237    d("start transport",[]),
13238    {ok, MgPid, MgSH} =
13239	?VERIFY({ok, _, _}, UserMod:start_transport(MgRH, MgcRH)),
13240    PrelMgCH = #megaco_conn_handle{local_mid = MgMid,
13241				   remote_mid = preliminary_mid},
13242    MgCH  = #megaco_conn_handle{local_mid = MgMid,
13243				remote_mid = MgcMid},
13244    MgcCH = #megaco_conn_handle{local_mid = MgcMid,
13245				remote_mid = MgMid},
13246    d("(MG) try connect to MGC",[]),
13247    ?SEND(megaco:connect(MgRH, PrelMid, MgSH, MgPid, Extra)), % Mg prel
13248    d("await connect from MG", []),
13249    ?USER({connect, PrelMgCH, _V, [Extra]}, ok),
13250    ?RECEIVE([{res, _, {ok, PrelMgCH}}]),
13251
13252    d("(MG) send service change request",[]),
13253    Req = service_change_request(),
13254    ?SEND(megaco:call(PrelMgCH, [Req], [])),
13255
13256    d("(MGC) send service change reply",[]),
13257    ?USER({connect, MgcCH, _V, []}, ok), % Mgc auto
13258    Rep = service_change_reply(MgcMid),
13259    ?USER({request, MgcCH, _V, [[Req]]}, {discard_ack, [Rep]}),
13260    ?USER({connect, MgCH, _V, []}, ok), % Mg confirm
13261    ?RECEIVE([{res, _, {1, {ok, [Rep]}}}]),
13262
13263    d("get (system info) connections",[]),
13264    connections([MgCH, MgcCH]),
13265    d("get (~p) connections",[MgMid]),
13266    ?VERIFY([MgCH], megaco:user_info(MgMid, connections)),
13267    d("get (~p) connections",[MgcMid]),
13268    ?VERIFY([MgcCH], megaco:user_info(MgcMid, connections)),
13269
13270    Reason = shutdown,
13271    d("(MG) disconnect",[]),
13272    ?SEND(megaco:disconnect(MgCH, Reason)),
13273    ?USER({disconnect, MgCH, _V, [{user_disconnect, Reason}]}, ok),
13274    ?RECEIVE([{res, _, ok}]),
13275    ?VERIFY(ok,	megaco:stop_user(MgMid)),
13276
13277    d("(MGC) disconnect",[]),
13278    ?SEND(megaco:disconnect(MgcCH, Reason)),
13279    ?USER({disconnect, MgcCH, _V, [{user_disconnect, Reason}]}, ok),
13280    ?RECEIVE([{res, _, ok}]),
13281    ?VERIFY(ok,	megaco:stop_user(MgcMid)),
13282
13283    d("stop megaco app",[]),
13284    ?VERIFY(ok, application:stop(megaco)),
13285    ?RECEIVE([]),
13286
13287    d("done",[]),
13288    ok.
13289
13290
13291%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13292
13293otp_8183_request1(suite) ->
13294    [];
13295otp_8183_request1(Config) when is_list(Config) ->
13296    Pre = fun() ->
13297    put(verbosity, debug),
13298    put(sname,     "TEST"),
13299    put(tc,        otp8183r1),
13300    i("starting"),
13301
13302                  MgNode = make_node_name(mg),
13303                  d("start (MG) node: ~p", [MgNode]),
13304                  Nodes = [MgNode],
13305                  ok = ?START_NODES(Nodes, true),
13306                  Nodes
13307          end,
13308    Case = fun do_otp_8183_request1/1,
13309    Post = fun(Nodes) ->
13310                   d("stop nodes"),
13311                   ?STOP_NODES(lists:reverse(Nodes))
13312           end,
13313    try_tc(otp8183r1, Pre, Case, Post).
13314
13315do_otp_8183_request1([MgNode]) ->
13316    d("[MG] start the simulator "),
13317    {ok, Mg} = megaco_test_megaco_generator:start_link("MG", MgNode),
13318
13319    d("[MG] create the event sequence"),
13320    MgMid = {deviceName,"mg"},
13321    MgEvSeq = otp_8183_r1_mg_event_sequence(MgMid),
13322
13323    i("wait some time before starting the MG simulation"),
13324    sleep(1000),
13325
13326    d("[MG] start the simulation"),
13327    {ok, MgId} = megaco_test_megaco_generator:exec(Mg, MgEvSeq),
13328
13329    i("await the transport module service change send_message event"),
13330    Pid = otp_8183_expect(fun(Ev) -> otp_8183_r1_verify_scr_msg(Ev) end, 5000),
13331
13332    i("wait some before issuing the service change reply"),
13333    sleep(500),
13334
13335    i("send the service change reply"),
13336    MgcMid = {deviceName,"mgc"},
13337    ServiceChangeReply = otp_8183_r1_mgc_service_change_reply_msg(MgcMid, 1, 1),
13338    megaco_test_generic_transport:incomming_message(Pid, ServiceChangeReply),
13339
13340    i("await the transport module "
13341      "notify-request send_message event from MG: "
13342      "ignore"),
13343    {TransId2, Cid2, TermId2} =
13344	otp_8183_expect(fun(Ev) -> otp_8183_r1_verify_nr_msg(Ev) end, 5000),
13345
13346    i("wait some before issuing the notify reply (twice)"),
13347    sleep(500),
13348
13349    i("send the notify reply - twice"),
13350    NotifyReply =
13351	otp_8183_r1_mgc_notify_reply_msg(MgcMid, TransId2, Cid2, TermId2),
13352    megaco_test_generic_transport:incomming_message(Pid, NotifyReply),
13353    sleep(100), %% This is to "make sure" the events come in the "right" order
13354    megaco_test_generic_transport:incomming_message(Pid, NotifyReply),
13355
13356    d("await the generator reply"),
13357    await_completion([MgId]),
13358
13359    %% Tell Mg to stop
13360    i("[MG] stop generator"),
13361    megaco_test_megaco_generator:stop(Mg),
13362
13363    i("done", []),
13364    ok.
13365
13366
13367otp_8183_expect(Verify, Timeout) when (Timeout > 0) ->
13368    T = mtime(),
13369    receive
13370	Msg ->
13371	    case (catch Verify(Msg)) of
13372		{ok, Result} ->
13373		    d("verified after ~p msec", [mtime() - T]),
13374		    Result;
13375		skip ->
13376		    otp_8183_expect(Verify, to(Timeout, T));
13377		{error, Reason} ->
13378		    exit({verification_failed, Reason})
13379	    end
13380    after Timeout ->
13381	    exit(timeout)
13382    end;
13383otp_8183_expect(_, _Timeout) ->
13384    exit(timeout).
13385
13386otp_8183_r1_verify_scr_msg(
13387  {transport_event, {send_message, _SH, {message, Msg}}, Pid})
13388  when is_record(Msg, 'MegacoMessage') ->
13389    d("received expected service change request message: "
13390      "~n   Msg: ~p", [Msg]),
13391    Reply = ok,
13392    Pid ! {transport_reply, Reply, self()},
13393    {ok, Pid};
13394otp_8183_r1_verify_scr_msg(
13395  {transport_event, {send_message, _SH, BadMsg}, _Pid}) ->
13396    io:format("otp_8183_r1_verify_scr_msg -> error: "
13397	      "~n   BadMsg: ~p"
13398	      "~n", [BadMsg]),
13399    {error, {invalid_message, BadMsg}};
13400otp_8183_r1_verify_scr_msg({transport_event, BadEvent, _Pid}) ->
13401    io:format("otp_8183_r1_verify_scr_msg -> error: "
13402	      "~n   BadEvent: ~p"
13403	      "~n", [BadEvent]),
13404    {error, {invalid_message, BadEvent}};
13405otp_8183_r1_verify_scr_msg(Msg) ->
13406    io:format("otp_8183_r1_verify_scr_msg -> error: "
13407	      "~n   Msg: ~p"
13408	      "~n", [Msg]),
13409    {error, {invalid_message, Msg}}.
13410
13411otp_8183_r1_verify_nr_msg(
13412  {transport_event, {send_message, _SH, {message, Msg}}, Pid})
13413  when is_record(Msg, 'MegacoMessage') ->
13414    io:format("otp_8183_r1_verify_nr_msg -> "
13415              "entry when received expected message with"
13416              "~n   Msg: ~p"
13417              "~n", [Msg]),
13418    Reply = ok,
13419    Pid ! {transport_reply, Reply, self()},
13420    #'MegacoMessage'{mess = Mess} = Msg,
13421    #'Message'{mId         = _Mid,
13422               messageBody = Body} = Mess,
13423    {transactions, Transactions} = Body,
13424    [Transaction] = Transactions,
13425    {transactionRequest, TransReq} = Transaction,
13426    #'TransactionRequest'{transactionId = TransId,
13427                          actions       = Actions} = TransReq,
13428    [Action] = Actions,
13429    #'ActionRequest'{contextId       = Cid,
13430                     commandRequests = CmdReqs} = Action,
13431    [CmdReq] = CmdReqs,
13432    #'CommandRequest'{command = Cmd} = CmdReq,
13433    {notifyReq, NR} = Cmd,
13434    #'NotifyRequest'{terminationID = [TermId]} = NR,
13435    {ok, {TransId, Cid, TermId}};
13436otp_8183_r1_verify_nr_msg(Msg) ->
13437    io:format("otp_8183_r1_verify_nr_msg -> entry when error with"
13438              "~n   Msg: ~p"
13439              "~n", [Msg]),
13440    {error, {invalid_message, Msg}}.
13441
13442otp_8183_r1_mgc_service_change_reply_msg(Mid, TransId, Cid) ->
13443    SCRP  = #'ServiceChangeResParm'{serviceChangeMgcId = Mid},
13444    SCRPs = {serviceChangeResParms, SCRP},
13445    Root  = #megaco_term_id{id = ["root"]},
13446    SCR   = #'ServiceChangeReply'{terminationID       = [Root],
13447                                  serviceChangeResult = SCRPs},
13448    CR    = {serviceChangeReply, SCR},
13449    otp_8183_r1_mgc_reply_msg(Mid, TransId, CR, Cid).
13450
13451otp_8183_r1_mgc_notify_reply_msg(Mid, TransId, Cid, TermId) ->
13452    NR  = #'NotifyReply'{terminationID = [TermId]},
13453    CR  = {notifyReply, NR},
13454    otp_8183_r1_mgc_reply_msg(Mid, TransId, CR, Cid).
13455
13456otp_8183_r1_mgc_reply_msg(Mid, TransId, CR, Cid) ->
13457    AR  = #'ActionReply'{contextId    = Cid,
13458                         commandReply = [CR]},
13459    ARs  = {actionReplies, [AR]},
13460    TR   = #'TransactionReply'{transactionId     = TransId,
13461                               transactionResult = ARs},
13462    Body = {transactions, [{transactionReply, TR}]},
13463    Mess = #'Message'{version     = 1,
13464                      mId         = Mid,
13465                      messageBody = Body},
13466    #'MegacoMessage'{mess = Mess}.
13467
13468
13469%%
13470%% MG generator stuff
13471%%
13472-ifdef(megaco_hipe_special).
13473-define(otp_8183_r1_mg_verify_handle_connect_fun(),
13474	{?MODULE, otp_8183_r1_mg_verify_handle_connect, []}).
13475-define(otp_8183_r1_mg_verify_service_change_rep_fun(),
13476	{?MODULE, otp_8183_r1_mg_verify_service_change_rep, []}).
13477-define(otp_8183_r1_mg_verify_notify_rep_fun(Nr
13478	{?MODULE, otp_8183_r1_mg_verify_notify_rep, [Nr).
13479-else.
13480-define(otp_8183_r1_mg_verify_handle_connect_fun(),
13481	otp_8183_r1_mg_verify_handle_connect_fun()).
13482-define(otp_8183_r1_mg_verify_service_change_rep_fun(),
13483	otp_8183_r1_mg_verify_service_change_rep_fun()).
13484-define(otp_8183_r1_mg_verify_notify_rep_fun(Nr),
13485	otp_8183_r1_mg_verify_notify_rep_fun(Nr)).
13486-endif.
13487
13488otp_8183_r1_mg_event_sequence(Mid) ->
13489    RI = [
13490          {port,             self()}, % This is just a trick to get my pid to the transport module
13491          {encoding_module,  megaco_pretty_text_encoder},
13492          {encoding_config,  []},
13493          {transport_module, megaco_test_generic_transport}
13494         ],
13495    ServiceChangeReq =
13496	otp_8183_r1_mg_service_change_request_ar(Mid, 1),
13497    Tid = #megaco_term_id{id = ["00000000","00000000","01101101"]},
13498    NotifyReq = otp_8183_r1_mg_notify_request_ar(1, Tid, 1),
13499    ConnectVerify =
13500	?otp_8183_r1_mg_verify_handle_connect_fun(),
13501    ServiceChangeReplyVerify =
13502	?otp_8183_r1_mg_verify_service_change_rep_fun(),
13503    NotifyReplyVerify =
13504	fun(Nr) ->
13505		?otp_8183_r1_mg_verify_notify_rep_fun(Nr)
13506	end,
13507    EvSeq = [
13508             {debug, true}, % false},
13509             megaco_start,
13510             {megaco_start_user, Mid, RI, []},
13511             start_transport,
13512             {megaco_trace, disable},
13513             {megaco_system_info, users},
13514             {megaco_system_info, connections},
13515             connect,
13516             {megaco_callback, handle_connect, ConnectVerify},
13517             megaco_connect,
13518             {megaco_cast,     [ServiceChangeReq], []},
13519             {megaco_callback, handle_connect,     ConnectVerify},
13520             {megaco_callback, handle_trans_reply, ServiceChangeReplyVerify},
13521
13522             {sleep, 1000},
13523             {megaco_cast,     [NotifyReq],        [{request_keep_alive_timeout, 5000}]},
13524             {megaco_callback, handle_trans_reply, NotifyReplyVerify(1)},
13525             {megaco_callback, handle_trans_reply, NotifyReplyVerify(2)},
13526             {sleep, 1000},
13527             megaco_stop_user,
13528             megaco_stop,
13529             {sleep, 1000}
13530            ],
13531    EvSeq.
13532
13533
13534-ifndef(megaco_hipe_special).
13535otp_8183_r1_mg_verify_handle_connect_fun() ->
13536    fun(Ev) ->
13537	    otp_8183_r1_mg_verify_handle_connect(Ev)
13538    end.
13539-endif.
13540
13541otp_8183_r1_mg_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
13542    io:format("otp_8183_r1_mg_verify_handle_connect -> ok"
13543	      "~n   CH: ~p~n", [CH]),
13544    {ok, CH, ok};
13545otp_8183_r1_mg_verify_handle_connect(Else) ->
13546    io:format("otp_8183_r1_mg_verify_handle_connect -> unknown"
13547	      "~n   Else: ~p~n", [Else]),
13548    {error, Else, ok}.
13549
13550-ifndef(megaco_hipe_special).
13551otp_8183_r1_mg_verify_service_change_rep_fun() ->
13552    fun(Rep) ->
13553	    otp_8183_r1_mg_verify_service_change_rep(Rep)
13554    end.
13555-endif.
13556
13557otp_8183_r1_mg_verify_service_change_rep(
13558  {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _}) ->
13559    (catch otp_8183_r1_mg_do_verify_service_change_rep(AR));
13560otp_8183_r1_mg_verify_service_change_rep(Crap) ->
13561    io:format("otp_8183_r1_mg_verify_service_change_rep -> crap"
13562	      "~n   Crap: ~p"
13563	      "~n", [Crap]),
13564    {error, Crap, ok}.
13565
13566otp_8183_r1_mg_do_verify_service_change_rep(AR) ->
13567    io:format("otp_8183_r1_mg_do_verify_service_change_rep -> ok"
13568	      "~n   AR: ~p~n", [AR]),
13569    CR =
13570	case AR of
13571	    #'ActionReply'{commandReply = [CmdRep]} ->
13572		CmdRep;
13573	    _ ->
13574		Reason1 = {invalid_action_reply, AR},
13575		throw({error, Reason1, ok})
13576	end,
13577    SCR =
13578	case CR of
13579	    {serviceChangeReply, ServChRep} ->
13580		ServChRep;
13581	    _ ->
13582		Reason2 = {invalid_command_reply, CR},
13583		throw({error, Reason2, ok})
13584	end,
13585    {Tid, SCRes} =
13586	case SCR of
13587	    #'ServiceChangeReply'{terminationID       = [TermID],
13588				  serviceChangeResult = Res} ->
13589		{TermID, Res};
13590	    _ ->
13591		Reason3 = {invalid_service_change_reply, SCR},
13592		throw({error, Reason3, ok})
13593	end,
13594    case Tid of
13595	#megaco_term_id{contains_wildcards = false, id = ["root"]} ->
13596	    ok;
13597	_ ->
13598	    Reason4 = {invalid_termination_id, Tid},
13599	    throw({error, Reason4, ok})
13600    end,
13601    SCRParm =
13602	case SCRes of
13603	    {serviceChangeResParms, ServChResParms} ->
13604		ServChResParms;
13605	    _ ->
13606		Reason5 = {invalid_serviceChangeResult, SCRes},
13607		throw({error, Reason5, ok})
13608	end,
13609    case SCRParm of
13610	#'ServiceChangeResParm'{serviceChangeMgcId = _RemoteMid} ->
13611	    {ok, AR, ok};
13612	_ ->
13613	    Reason6 = {invalid_service_change_result, SCRParm},
13614	    {error, Reason6, ok}
13615    end.
13616
13617-ifndef(megaco_hipe_special).
13618otp_8183_r1_mg_verify_notify_rep_fun(Nr) ->
13619    fun(Rep) ->
13620	    otp_8183_r1_mg_verify_notify_rep(Nr, Rep)
13621    end.
13622-endif.
13623
13624otp_8183_r1_mg_verify_notify_rep(
13625  Nr,
13626  {handle_trans_reply, _CH, ?VERSION, {ok, Nr, [AR]}, _}) ->
13627    io:format("otp_8183_r1_mg_verify_notify_rep -> ok"
13628	      "~n   Nr: ~p"
13629	      "~n   AR: ~p"
13630	      "~n", [Nr, AR]),
13631    {ok, AR, ok};
13632otp_8183_r1_mg_verify_notify_rep(
13633  ExpNr,
13634  {handle_trans_reply, _CH, ?VERSION, {ok, ActNr, [AR]}, _}) ->
13635    io:format("otp_8183_r1_mg_verify_notify_rep -> error"
13636	      "~n   Expected Nr: ~p"
13637	      "~n   Actual Nr:   ~p"
13638	      "~n   AR:          ~p"
13639	      "~n", [ExpNr, ActNr, AR]),
13640    Error = {unexpected_nr, ExpNr, ActNr},
13641    {error, Error, ok};
13642otp_8183_r1_mg_verify_notify_rep(
13643  Nr,
13644  {handle_trans_reply, _CH, ?VERSION, Res, _}) ->
13645    io:format("otp_8183_r1_mg_verify_notify_rep -> error"
13646	      "~n   Nr:  ~p"
13647	      "~n   Res: ~p"
13648	      "~n", [Nr, Res]),
13649    Error = {unexpected_result, Nr, Res},
13650    {error, Error, ok};
13651otp_8183_r1_mg_verify_notify_rep(Nr, Else) ->
13652    io:format("otp_8183_r1_mg_verify_notify_rep -> unknown"
13653	      "~n   Nr:   ~p"
13654	      "~n   Else: ~p"
13655	      "~n", [Nr, Else]),
13656    {error, Else, ok}.
13657
13658
13659otp_8183_r1_mg_service_change_request_ar(_Mid, Cid) ->
13660    Prof  = cre_serviceChangeProf("resgw", 1),
13661    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
13662    Root  = #megaco_term_id{id = ["root"]},
13663    SCR   = cre_serviceChangeReq([Root], SCP),
13664    CMD   = cre_command(SCR),
13665    CR    = cre_cmdReq(CMD),
13666    cre_actionReq(Cid, [CR]).
13667
13668otp_8183_r1_mg_notify_request_ar(Rid, Tid, Cid) ->
13669    TT      = cre_timeNotation("19990729", "22000000"),
13670    Ev      = cre_obsEvent("al/of", TT),
13671    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
13672    NR      = cre_notifyReq([Tid], EvsDesc),
13673    CMD     = cre_command(NR),
13674    CR      = cre_cmdReq(CMD),
13675    cre_actionReq(Cid, [CR]).
13676
13677
13678%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13679
13680otp8212_scr(MidStr) ->
13681    Msg = "!/1 " ++ MidStr ++ " T=19731{C=-{SC=ROOT{SV{MT=RS,RE=\"901\"}}}}",
13682    list_to_binary(Msg).
13683
13684otp_8212(suite) ->
13685    [];
13686otp_8212(doc) ->
13687    [];
13688otp_8212(Config) when is_list(Config) ->
13689    %% ?ACQUIRE_NODES(1, Config),
13690
13691    put(verbosity, debug),
13692    put(sname,     "TEST"),
13693    put(tc,        otp8212),
13694    i("starting"),
13695
13696    Extra         = otp8212_extra,
13697    NoMid         = preliminary_mid,
13698    LocalMid      = {deviceName, "MGC"},
13699    RemoteMidStr1 = "bgf1",
13700    RemoteMid1    = {deviceName, RemoteMidStr1},
13701    RemoteMidStr2 = "bgf2",
13702    RemoteMid2    = {deviceName, RemoteMidStr2},
13703    UserMod       = megaco_mess_otp8212_test,
13704
13705    d("set megaco trace level to max",[]),
13706    megaco:enable_trace(max, io),
13707
13708    d("start megaco app",[]),
13709    ?VERIFY(ok, application:start(megaco)),
13710
13711    d("start local user (MGC) ~p", [LocalMid]),
13712    UserConfig = [{user_mod, UserMod}, {send_mod, UserMod}],
13713    ?VERIFY(ok,	megaco:start_user(LocalMid, UserConfig)),
13714
13715    d("get (MGC) receive info for ~p", [LocalMid]),
13716    RH0 = user_info(LocalMid, receive_handle),
13717    RH  = RH0#megaco_receive_handle{encoding_mod = megaco_mess_otp8212_test,
13718				    encoding_config = []},
13719
13720    d("do a pre-connect for ~p", [LocalMid]),
13721    ControlPid = self(),
13722    SendHandle = {RH, ControlPid, RemoteMidStr1, RemoteMidStr2},
13723    ?VERIFY({ok, _}, megaco:connect(RH, NoMid, SendHandle, ControlPid)),
13724
13725    d("simulate incomming service change message from ~p",
13726      [RemoteMidStr1]),
13727    ?VERIFY(ok,
13728	    megaco:process_received_message(RH, ControlPid,
13729					    otp8212_scr,
13730					    otp8212_scr(RemoteMidStr1))),
13731
13732    d("get the updated connection handle", []),
13733    [CH] = megaco:user_info(LocalMid, connections),
13734
13735    d("verify connection with ~p", [RemoteMidStr1]),
13736    ?VERIFY(RemoteMid1, megaco:conn_info(CH, remote_mid)),
13737
13738    d("send a request to ~p but receive no reply but an unexpected call",
13739      [RemoteMidStr1]),
13740    Res = megaco:call(CH, ["action request"], [{request_timer, 2000}]),
13741    d("request result: ~p", [Res]),
13742    ?VERIFY({1, [{error, {wrong_mid, RemoteMid2, RemoteMid1, _}, {Extra, _}}]}, Res),
13743
13744    Conns = disconnect_all(LocalMid),
13745    await_disconnected(Conns),
13746
13747    d("stop megaco user ~p",[LocalMid]),
13748    ok = await_stopped_user(LocalMid),
13749
13750    d("stop megaco app",[]),
13751    ?VERIFY(ok, application:stop(megaco)),
13752    ?RECEIVE([]),
13753
13754    d("done",[]),
13755    ok.
13756
13757disconnect_all(LocalMid) ->
13758    Conns = megaco:user_info(LocalMid, connections),
13759    d("[~p] disconnect from all connections: ~n~p", [LocalMid, Conns]),
13760    lists:foreach(
13761      fun(Conn) ->
13762	      d("[~p] disconnect from connection ~p", [LocalMid, Conn]),
13763	      DiscoRes = megaco:disconnect(Conn, {otp8212_done, self()}),
13764	      d("[~p] disconnect result: ~p", [LocalMid, DiscoRes])
13765      end,
13766      Conns),
13767    Conns.
13768
13769await_disconnected([]) ->
13770    ok;
13771await_disconnected(Conns) ->
13772    receive
13773	{disconnected, Conn} ->
13774	    d("disconnected: ~p", [Conn]),
13775	    Conns2 = lists:delete(Conn, Conns),
13776	    await_disconnected(Conns2)
13777    end.
13778
13779
13780await_stopped_user(LocalMid) ->
13781    await_stopped_user(LocalMid, 10).
13782
13783await_stopped_user(LocalMid, N) when N =< 0 ->
13784    ?ERROR({failed_stopping_user, LocalMid});
13785await_stopped_user(LocalMid, N) ->
13786    case megaco:stop_user(LocalMid) of
13787	ok ->
13788	    d("user stopped(~w)", [N]),
13789	    ok;
13790	{error, {active_connections, _}} ->
13791	    d("still active connections when N = ~w", [N]),
13792	    Conns = disconnect_all(LocalMid),
13793	    await_disconnected(Conns),
13794	    ?SLEEP(500),
13795	    await_stopped_user(LocalMid, N-1)
13796    end.
13797
13798
13799%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13800
13801cre_ErrDesc(T) ->
13802    EC = ?megaco_internal_gateway_error,
13803    ET = lists:flatten(io_lib:format("~w",[T])),
13804    #'ErrorDescriptor'{errorCode = EC, errorText = ET}.
13805
13806
13807cre_serviceChangeParm(M,R,P) ->
13808    #'ServiceChangeParm'{serviceChangeMethod  = M,
13809                         serviceChangeReason  = R,
13810                         serviceChangeProfile = P}.
13811
13812cre_serviceChangeParm(M, V, R, P) ->
13813    #'ServiceChangeParm'{serviceChangeMethod  = M,
13814			 serviceChangeVersion = V,
13815                         serviceChangeReason  = R,
13816                         serviceChangeProfile = P}.
13817
13818cre_serviceChangeReq(Tid, Parms) ->
13819    #'ServiceChangeRequest'{terminationID      = Tid,
13820                            serviceChangeParms = Parms}.
13821
13822cre_timeNotation(D,T) ->
13823    #'TimeNotation'{date = D, time = T}.
13824
13825cre_obsEvent(Name, Not) ->
13826    #'ObservedEvent'{eventName    = Name,
13827                     timeNotation = Not}.
13828
13829cre_obsEvsDesc(Id, EvList) ->
13830    #'ObservedEventsDescriptor'{requestId        = Id,
13831                                observedEventLst = EvList}.
13832
13833cre_notifyReq(Tid, EvsDesc) ->
13834    #'NotifyRequest'{terminationID            = Tid,
13835                     observedEventsDescriptor = EvsDesc}.
13836
13837cre_command(R) when is_record(R, 'NotifyRequest') ->
13838    {notifyReq, R};
13839cre_command(R) when is_record(R, 'ServiceChangeRequest') ->
13840    {serviceChangeReq, R}.
13841
13842cre_cmdReq(Cmd) ->
13843    #'CommandRequest'{command = Cmd}.
13844
13845cre_actionReq(CtxId, CmdReqs) when is_list(CmdReqs) ->
13846    #'ActionRequest'{contextId       = CtxId,
13847                     commandRequests = CmdReqs}.
13848
13849cre_transReq(TransId, ARs) when is_list(ARs) ->
13850    #'TransactionRequest'{transactionId = TransId,
13851			  actions       = ARs}.
13852
13853cre_transResult(ED) when is_record(ED, 'ErrorDescriptor') ->
13854    {transactionError, ED};
13855cre_transResult([AR|_] = ARs) when is_record(AR, 'ActionReply') ->
13856    {actionReplies, ARs}.
13857
13858cre_transReply(TransId, Res) ->
13859    #'TransactionReply'{transactionId     = TransId,
13860			transactionResult = Res}.
13861
13862cre_transReply(TransId, IAR, Res) ->
13863    #'TransactionReply'{transactionId     = TransId,
13864			immAckRequired    = IAR,
13865			transactionResult = Res}.
13866
13867
13868%% --
13869
13870cre_serviceChangeResParm(Mid) ->
13871    cre_serviceChangeResParm(Mid, ?VERSION).
13872
13873cre_serviceChangeResParm(Mid, V) ->
13874    #'ServiceChangeResParm'{serviceChangeMgcId   = Mid,
13875			    serviceChangeVersion = V}.
13876
13877cre_serviceChangeResult(SCRP) when is_record(SCRP, 'ServiceChangeResParm') ->
13878    {serviceChangeResParms, SCRP};
13879cre_serviceChangeResult(ED) when is_record(ED, 'ErrorDescriptor') ->
13880    {errorDescriptor, ED}.
13881
13882cre_serviceChangeReply(Tid, Res) ->
13883    #'ServiceChangeReply'{terminationID       = Tid,
13884                          serviceChangeResult = Res}.
13885
13886cre_cmdReply(R) when is_record(R, 'NotifyReply') ->
13887    {notifyReply, R};
13888cre_cmdReply(R) when is_record(R, 'ServiceChangeReply') ->
13889    {serviceChangeReply, R}.
13890
13891cre_transRespAck(TransAck) when is_record(TransAck, 'TransactionAck') ->
13892    [TransAck];
13893cre_transRespAck(TRA) when is_list(TRA) ->
13894    TRA.
13895
13896cre_transAck(TransId) ->
13897    #'TransactionAck'{firstAck = TransId}.
13898
13899cre_notifyReply(Tid) ->
13900    #'NotifyReply'{terminationID = Tid}.
13901
13902cre_actionReply(CtxId, CmdRep) ->
13903    #'ActionReply'{contextId    = CtxId,
13904                   commandReply = CmdRep}.
13905
13906cre_serviceChangeProf(Name, Ver) when is_list(Name) andalso is_integer(Ver) ->
13907    #'ServiceChangeProfile'{profileName = Name,
13908                            version     = Ver}.
13909
13910cre_transaction(Trans) when is_record(Trans, 'TransactionRequest') ->
13911    {transactionRequest, Trans};
13912cre_transaction(Trans) when is_record(Trans, 'TransactionPending') ->
13913    {transactionPending, Trans};
13914cre_transaction(Trans) when is_record(Trans, 'TransactionReply') ->
13915    {transactionReply, Trans};
13916cre_transaction(Trans) when is_list(Trans) ->
13917    {transactionResponseAck, Trans}.
13918
13919cre_transactions(Trans) when is_list(Trans) ->
13920    {transactions, Trans}.
13921
13922cre_message(Version, Mid, Body) ->
13923    #'Message'{version     = Version,
13924               mId         = Mid,
13925               messageBody = Body}.
13926
13927cre_megacoMessage(Mess) ->
13928    #'MegacoMessage'{mess = Mess}.
13929
13930service_change_request() ->
13931    Parm = #'ServiceChangeParm'{serviceChangeMethod = restart,
13932				serviceChangeReason = [?megaco_cold_boot]},
13933    SCR = #'ServiceChangeRequest'{terminationID = [?megaco_root_termination_id],
13934				  serviceChangeParms = Parm},
13935    CR = #'CommandRequest'{command = {serviceChangeReq, SCR}},
13936    #'ActionRequest'{contextId = ?megaco_null_context_id,
13937		     commandRequests = [CR]}.
13938
13939service_change_reply(MgcMid) ->
13940    Res = {serviceChangeResParms, #'ServiceChangeResParm'{serviceChangeMgcId = MgcMid}},
13941    SCR = #'ServiceChangeReply'{terminationID = [?megaco_root_termination_id],
13942				serviceChangeResult = Res},
13943    #'ActionReply'{contextId = ?megaco_null_context_id,
13944		   commandReply = [{serviceChangeReply, SCR}]}.
13945
13946local_ip_address() ->
13947    {ok, Hostname} = inet:gethostname(),
13948    {ok, {A1, A2, A3, A4}} = inet:getaddr(Hostname, inet),
13949    {A1, A2, A3, A4}.
13950
13951ipv4_mid() ->
13952    ipv4_mid(asn1_NOVALUE).
13953
13954ipv4_mid(Port) ->
13955    IpAddr = local_ip_address(),
13956    Ip = tuple_to_list(IpAddr),
13957    {ip4Address, #'IP4Address'{address = Ip, portNumber = Port}}.
13958
13959
13960%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13961
13962%%% -------------------------------------------------------------------------------
13963%%% Megaco user callback interface
13964%%% -------------------------------------------------------------------------------
13965
13966handle_connect(ConnHandle, ProtocolVersion, Pid) ->
13967    Pid ! {handle_connect, {ConnHandle, ProtocolVersion}},
13968    ok.
13969
13970handle_disconnect(_, _, {user_disconnect, test_complete}, _) ->
13971    ok;
13972handle_disconnect(ConnHandle, ProtocolVersion, Reason, Pid) ->
13973    Pid ! {handle_disconnect, {ConnHandle, ProtocolVersion, Reason}},
13974    ok.
13975
13976handle_syntax_error(ConnHandle, ProtocolVersion, ErrorDescriptor, Pid) ->
13977    Pid ! {handle_syntax_error,{ConnHandle, ProtocolVersion, ErrorDescriptor}},
13978    reply.
13979
13980handle_message_error(ConnHandle, ProtocolVersion, ErrorDescriptor, Pid) ->
13981    Pid ! {handle_message_error,{ConnHandle, ProtocolVersion, ErrorDescriptor}},
13982    reply.
13983
13984handle_trans_request(ConnHandle, ProtocolVersion, ActionRequests, Pid) ->
13985    Pid ! {handle_trans_request,{ConnHandle, ProtocolVersion, ActionRequests}},
13986    ED = #'ErrorDescriptor'{errorCode = ?megaco_not_implemented,
13987			    errorText = "not implemented yet"},
13988    {discard_ack, ED}.
13989
13990handle_trans_long_request(ConnHandle, ProtocolVersion, Data, Pid) ->
13991    Pid ! {handle_trans_long_request,{ConnHandle, ProtocolVersion, Data}},
13992    ED = #'ErrorDescriptor'{errorCode = ?megaco_not_implemented,
13993			    errorText = "not implemented yet"},
13994    {discard_ack, ED}.
13995
13996handle_trans_reply(ConnHandle, ProtocolVersion, ActualReply, Data, Pid) ->
13997    Pid ! {handle_trans_reply,{ConnHandle, ProtocolVersion, ActualReply, Data}},
13998    ok.
13999
14000handle_trans_ack(ConnHandle, ProtocolVersion, Status, Data, Pid) ->
14001    Pid ! {handle_trans_ack,{ConnHandle, ProtocolVersion, Status, Data}},
14002    ok.
14003
14004handle_unexpected_trans(ReceiveHandle, ProtocolVersion, Trans, Pid) ->
14005    Pid ! {handle_unexpected_trans,
14006	   {ReceiveHandle, ProtocolVersion, Trans, Pid}},
14007    ok.
14008
14009handle_trans_request_abort(ReceiveHandle, ProtocolVersion, TransNo, HandlerPid, Pid) ->
14010    Pid ! {handle_trans_request_abort,
14011	   {ReceiveHandle, ProtocolVersion, TransNo, HandlerPid}},
14012    ok.
14013
14014
14015
14016%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14017
14018encode_msg(M, Mod, Conf) ->
14019    Mod:encode_message(Conf, M).
14020
14021%% encode_msg(M, Mod, Conf, Ver) ->
14022%%     Mod:encode_message(Conf, Ver, M).
14023
14024decode_msg(M, Mod, Conf) ->
14025    Mod:decode_message(Conf, M).
14026
14027%% decode_msg(M, Mod, Conf, Ver) ->
14028%%     Mod:decode_message(Conf, Ver, M).
14029
14030
14031
14032%%% -------------------------------------------------------------------------------
14033%%% Megaco transport module interface
14034%%% -------------------------------------------------------------------------------
14035
14036send_message(Pid, Data) ->
14037    Pid ! {send_message, Data},
14038    ok.
14039
14040% block(Pid) ->
14041%     Pid ! {block, dummy},
14042%     ok.
14043
14044unblock(Pid) ->
14045    Pid ! {unblock, dummy},
14046    ok.
14047
14048% close(Pid) ->
14049%     Pid ! {close, dummy},
14050%     ok.
14051
14052
14053%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14054
14055make_node_name(Name) ->
14056    case string:tokens(atom_to_list(node()), [$@]) of
14057	[_,Host] ->
14058	    list_to_atom(lists:concat([atom_to_list(Name) ++ "@" ++ Host]));
14059	_ ->
14060	    exit("Test node must be started with '-sname'")
14061    end.
14062
14063
14064%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14065
14066user_info(Mid, Key) ->
14067    case (catch megaco:user_info(Mid, Key)) of
14068	{'EXIT', _} = Error ->
14069	    ?ERROR(Error);
14070	Val ->
14071	    ?LOG("user_info -> ok: "
14072		 "~n   ~p"
14073		 "~n", [Val]),
14074	    Val
14075    end.
14076
14077
14078stop_user(Mid) ->
14079    case (catch megaco:stop_user(Mid)) of
14080	{'EXIT', _} = Error ->
14081	    ?ERROR(Error);
14082	Val ->
14083	    ?LOG("stop_user -> ok:"
14084		 "~n   ~p"
14085		 "~n", [Val]),
14086	    Val
14087    end.
14088
14089connections() ->
14090    system_info(connections).
14091
14092connections(Conns0) ->
14093    Conns1 = lists:sort(Conns0),
14094    case lists:sort(connections()) of
14095	Conns1 ->
14096	    ?LOG("connections -> ok:"
14097		 "~n   ~p"
14098		 "~n", [Conns1]),
14099	    Conns1;
14100	Conns2 ->
14101	    ?ERROR({Conns1, Conns2}),
14102	    Conns2
14103    end.
14104
14105system_info(Key) ->
14106    megaco:system_info(Key).
14107
14108
14109%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14110
14111await_completion(Ids) ->
14112    case megaco_test_generator_lib:await_completion(Ids) of
14113	{ok, Reply} ->
14114	    d("OK => Reply: ~n~p", [Reply]),
14115	    ok;
14116	{error, Reply} ->
14117	    d("ERROR => Reply: ~n~p", [Reply]),
14118	    ?ERROR({failed, Reply})
14119    end.
14120
14121await_completion(Ids, Timeout) ->
14122    case megaco_test_generator_lib:await_completion(Ids, Timeout) of
14123	{ok, Reply} ->
14124	    d("OK => Reply: ~n~p", [Reply]),
14125	    ok;
14126	{error, Reply} ->
14127	    d("ERROR => Reply: ~n~p", [Reply]),
14128	    ?ERROR({failed, Reply})
14129    end.
14130
14131
14132%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14133
14134sleep(X) -> receive after X -> ok end.
14135
14136% error_msg(F,A) -> error_logger:error_msg(F ++ "~n",A).
14137
14138
14139%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14140
14141to(To, Start) ->
14142    To - (mtime() - Start).
14143
14144%% Time in milli seconds
14145mtime() ->
14146    {A,B,C} = erlang:timestamp(),
14147    A*1000000000+B*1000+(C div 1000).
14148
14149
14150
14151%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14152
14153try_tc(TCName, Pre, Case, Post) ->
14154    try_tc(TCName, "TEST", ?TEST_VERBOSITY, Pre, Case, Post).
14155
14156try_tc(TCName, Name, Verbosity, Pre, Case, Post) ->
14157    ?TRY_TC(TCName, Name, Verbosity, Pre, Case, Post).
14158
14159
14160
14161%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14162
14163%% p(F) ->
14164%%     p(F, []).
14165
14166p(F, A) ->
14167    p(get(sname), F, A).
14168
14169p(S, F, A) when is_list(S) ->
14170    io:format("*** [~s] ~p ~s ***"
14171	      "~n   " ++ F ++ "~n",
14172	      [?FTS(), self(), S | A]);
14173p(_S, F, A) ->
14174    io:format("*** [~s] ~p *** "
14175	      "~n   " ++ F ++ "~n",
14176	      [?FTS(), self() | A]).
14177
14178
14179%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14180
14181i(F) ->
14182    i(F, []).
14183
14184i(F, A) ->
14185    print(info, "INF", F, A).
14186
14187
14188d(F) ->
14189    d(F, []).
14190
14191d(F, A) ->
14192    print(debug, "DBG", F, A).
14193
14194
14195print(Severity, PRE, FMT, ARGS) ->
14196    print(Severity, get(verbosity), erlang:timestamp(), get(tc), PRE, FMT, ARGS).
14197
14198print(Severity, Verbosity, Ts, Tc, P, F, A) ->
14199    print(printable(Severity,Verbosity), Ts, Tc, P, F, A).
14200
14201print(true, TS, TC, P, F, A) ->
14202    S = ?F("*** [~s] ~s ~p ~s:~w ***"
14203           "~n   " ++ F ++ "~n",
14204           [?FTS(TS), P, self(), get(sname), TC | A]),
14205    io:format("~s", [S]),
14206    io:format(user, "~s", [S]);
14207print(_, _, _, _, _, _) ->
14208    ok.
14209
14210
14211printable(_, debug)   -> true;
14212printable(info, info) -> true;
14213printable(_,_)        -> false.
14214
14215
14216
14217