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("common_test/include/ct.hrl").
270-include_lib("megaco/include/megaco.hrl").
271-include_lib("megaco/include/megaco_message_v1.hrl").
272-include("megaco_test_lib.hrl").
273
274-define(VERSION, 1).
275
276-define(USER_MOD, megaco_mess_user_test).
277
278-define(TEST_VERBOSITY, debug).
279-define(MGC_VERBOSITY,  debug).
280-define(MG_VERBOSITY,   debug).
281
282-define(MGC_START(Pid, Mid, ET, Conf, Verb),
283	megaco_test_mgc:start(Pid, Mid, ET, Conf, Verb)).
284-define(MGC_STOP(Pid),        megaco_test_mgc:stop(Pid)).
285-define(MGC_REQ_PEND(Pid,To), megaco_test_mgc:request_pending(Pid,To)).
286-define(MGC_REQ_HP(Pid,To),   megaco_test_mgc:request_handle_pending(Pid,To)).
287-define(MGC_ACK_INFO(Pid),    megaco_test_mgc:ack_info(Pid,self())).
288
289-define(MG_START(Pid, Mid, Enc, Transp, Conf, Verb),
290	megaco_test_mg:start(Pid, Mid, Enc, Transp, Conf, Verb)).
291-define(MG_STOP(Pid), megaco_test_mg:stop(Pid)).
292-define(MG_SERV_CHANGE(Pid), megaco_test_mg:service_change(Pid)).
293-define(MG_NOTIF_REQ(Pid), megaco_test_mg:notify_request(Pid)).
294-define(MG_AWAIT_NOTIF_REP(Pid), megaco_test_mg:await_notify_reply(Pid)).
295-define(MG_CONN_INFO(Pid,Tag), megaco_test_mg:conn_info(Pid,Tag)).
296-define(MG_USER_INFO(Pid,Tag), megaco_test_mg:user_info(Pid,Tag)).
297-define(MG_NOTIF_RAR(Pid), megaco_test_mg:notify_request_and_reply(Pid)).
298
299-define(SEND(Expr),
300	?VERIFY(ok, ?USER_MOD:apply_proxy(fun() -> Expr end))).
301
302-define(USER(Expected, Reply),
303	?USER_MOD:reply(?MODULE,
304                        ?LINE,
305                        fun(Actual) ->
306                                case ?VERIFY(Expected, Actual) of
307                                    Expected   -> {ok, Reply};
308                                    UnExpected -> {error, {reply_verify,
309                                                           ?MODULE,
310                                                           ?LINE,
311                                                           UnExpected}}
312                                end
313                        end)).
314
315%% Some generator (utility) macros
316-define(GM_START(),              megaco_start).
317-define(GM_STOP(),               megaco_stop).
318-define(GM_START_USER(M, RI, C), {megaco_start_user, M, RI, C}).
319-define(GM_START_USER(M, RI),    ?GM_START_USER(M, RI, [])).
320-define(GM_STOP_USER(),          megaco_stop_user).
321-define(GMSI(I),                 {megaco_system_info, I}).
322-define(GMSI_USERS(),            ?GMSI(users)).
323-define(GMSI_CONNS(),            ?GMSI(connections)).
324-define(GMCAST(Reqs, Opts),      {megaco_cast, Reqs, Opts}).
325-define(GMCAST(Reqs),            ?GMCAST(Reqs, [])).
326-define(GMCB(CB, VF),            {megaco_callback, CB, VF}).
327-define(GMCB_CONNECT(VF),        ?GMCB(handle_connect, VF)).
328-define(GMCB_TRANS_REP(VF),      ?GMCB(handle_trans_reply, VF)).
329-define(GMT(T),                  {megaco_trace, T}).
330-define(GMT_ENABLE(),            ?GMT(enable)).
331-define(GMT_DISABLE(),           ?GMT(disable)).
332-define(GD(D),                   {debug, D}).
333-define(GD_ENABLE(),             ?GD(true)).
334-define(GD_DISABLE(),            ?GD(false)).
335-define(GS(T),                   {sleep, T}).
336
337-define(GSND(T, D),              {send, T, D}).
338-define(GERCV(T, VF, TO),        {expect_receive, T, {VF, TO}}).
339
340
341
342%%======================================================================
343%% Common Test interface functions
344%%======================================================================
345
346suite() ->
347    [{ct_hooks, [ts_install_cth]}].
348
349all() ->
350    [
351     connect,
352     {group, request_and_reply},
353     {group, pending_ack},
354     dist,
355     {group, tickets}
356    ].
357
358groups() ->
359    [
360     {request_and_reply, [], request_and_reply_cases()},
361     {pending_ack,       [], pending_ack_cases()},
362     {tickets,           [], tickets_cases()},
363     {otp6442,           [], otp6442_cases()},
364     {otp6865,           [], otp6865_cases()},
365     {otp8183,           [], otp8183_cases()}
366    ].
367
368request_and_reply_cases() ->
369    [
370     request_and_reply_plain,
371     request_and_no_reply,
372     request_and_reply_pending_ack_no_pending,
373     request_and_reply_pending_ack_one_pending,
374     single_trans_req_and_reply,
375     single_trans_req_and_reply_sendopts,
376     request_and_reply_and_ack,
377     request_and_reply_and_no_ack,
378     request_and_reply_and_late_ack,
379     trans_req_and_reply_and_req
380    ].
381
382pending_ack_cases() ->
383    [
384     pending_ack_plain,
385     request_and_pending_and_late_reply
386    ].
387
388tickets_cases() ->
389    [
390     otp_4359,
391     otp_4836,
392     otp_5805,
393     otp_5881,
394     otp_5887,
395     otp_6253,
396     otp_6275,
397     otp_6276,
398     {group, otp6442},
399     {group, otp6865},
400     otp_7189,
401     otp_7259,
402     otp_7713,
403     {group, otp8183},
404     otp_8212
405    ].
406
407otp6442_cases() ->
408    [
409     otp_6442_resend_request1,
410     otp_6442_resend_request2,
411     otp_6442_resend_reply1,
412     otp_6442_resend_reply2
413    ].
414
415otp6865_cases() ->
416    [
417     otp_6865_request_and_reply_plain_extra1,
418     otp_6865_request_and_reply_plain_extra2
419    ].
420
421otp8183_cases() ->
422    [
423     otp_8183_request1
424    ].
425
426
427
428%%
429%% -----
430%%
431
432init_per_suite(suite) ->
433    [];
434init_per_suite(doc) ->
435    [];
436init_per_suite(Config0) when is_list(Config0) ->
437
438    ?ANNOUNCE_SUITE_INIT(),
439
440    p("init_per_suite -> entry with"
441      "~n      Config: ~p"
442      "~n      Nodes:  ~p", [Config0, erlang:nodes()]),
443
444    case ?LIB:init_per_suite(Config0) of
445        {skip, _} = SKIP ->
446            SKIP;
447
448        Config1 when is_list(Config1) ->
449
450            %% We need a (local) monitor on this node also
451            megaco_test_sys_monitor:start(),
452
453            p("init_per_suite -> end when"
454              "~n      Config: ~p"
455              "~n      Nodes:  ~p", [Config1, erlang:nodes()]),
456
457            Config1
458    end.
459
460end_per_suite(suite) -> [];
461end_per_suite(doc) -> [];
462end_per_suite(Config0) when is_list(Config0) ->
463
464    p("end_per_suite -> entry with"
465      "~n      Config: ~p"
466      "~n      Nodes:  ~p", [Config0, erlang:nodes()]),
467
468    megaco_test_sys_monitor:stop(),
469    Config1 = ?LIB:end_per_suite(Config0),
470
471    p("end_per_suite -> end when"
472      "~n      Nodes:  ~p", [erlang:nodes()]),
473
474    Config1.
475
476
477%%
478%% -----
479%%
480
481init_per_group(Group, Config) ->
482    ?ANNOUNCE_GROUP_INIT(Group),
483
484    p("init_per_group -> entry with"
485      "~n   Config: ~p"
486      "~n", [Config]),
487
488    Config.
489
490end_per_group(_GroupName, Config) ->
491    p("end_per_group -> entry with"
492      "~n   Config: ~p"
493      "~n", [Config]),
494    Config.
495
496
497
498%%
499%% -----
500%%
501
502init_per_testcase(Case, Config) ->
503    process_flag(trap_exit, true),
504
505    ?ANNOUNCE_CASE_INIT(Case),
506
507    p("init_per_testcase -> entry with"
508      "~n   Config: ~p"
509      "~n   Nodes:  ~p", [Config, erlang:nodes()]),
510
511    init_per_testcase2(Case, Config).
512
513init_per_testcase2(otp_7189 = Case, Config) ->
514    C = lists:keydelete(tc_timeout, 1, Config),
515    init_per_testcase3(Case, [{tc_timeout, min(tfactor(2, Config))} |C]);
516init_per_testcase2(request_and_no_reply = Case, Config) ->
517    C = lists:keydelete(tc_timeout, 1, Config),
518    init_per_testcase3(Case, [{tc_timeout, min(tfactor(2, Config))} |C]);
519init_per_testcase2(Case, Config) ->
520    C = lists:keydelete(tc_timeout, 1, Config),
521    init_per_testcase3(Case, [{tc_timeout, min(tfactor(1, Config))} |C]).
522
523init_per_testcase3(Case, Config) ->
524    megaco_test_global_sys_monitor:reset_events(),
525    megaco_test_lib:init_per_testcase(Case, Config).
526
527
528
529end_per_testcase(Case, Config) ->
530
531    p("end_per_testcase -> entry with"
532      "~n   Config: ~p"
533      "~n   Nodes:  ~p", [Config, erlang:nodes()]),
534
535    p("system events during test: "
536      "~n   ~p", [megaco_test_global_sys_monitor:events()]),
537
538    megaco_test_lib:end_per_testcase(Case, Config).
539
540
541
542min(M) -> ?MINS(M).
543
544tfactor(T, Config) ->
545    case ?config(megaco_factor, Config) of
546        Factor when is_integer(Factor) andalso (Factor > 1) ->
547            T * Factor;
548        _ ->
549            T
550    end.
551
552
553%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
554
555connect(suite) ->
556    [];
557connect(doc) ->
558    [];
559connect(Config) when is_list(Config) ->
560    %% ?SKIP("Needs a re-write..."),
561    ?ACQUIRE_NODES(1, Config),
562    PrelMid = preliminary_mid,
563    MgMid   = ipv4_mid(4711),
564
565    d("connect -> start megaco app",[]),
566    ?VERIFY(ok, application:start(megaco)),
567    d("connect -> start (MG) user ~p",[MgMid]),
568    ?VERIFY(ok,	megaco:start_user(MgMid, [{send_mod, bad_send_mod},
569	                                  {request_timer, infinity},
570	                                  {reply_timer, infinity}])),
571
572    d("connect -> get receive info for ~p",[MgMid]),
573    MgRH = user_info(MgMid, receive_handle),
574    d("connect -> (MG) try connect to MGC",[]),
575    {ok, PrelCH} = ?VERIFY({ok, _}, megaco:connect(MgRH, PrelMid, sh, self())),
576
577    connections([PrelCH]),
578    ?VERIFY([PrelCH], megaco:user_info(MgMid, connections)),
579
580    ?VERIFY(bad_send_mod, megaco:user_info(MgMid, send_mod)),
581    ?VERIFY(bad_send_mod, megaco:conn_info(PrelCH, send_mod)),
582    SC = service_change_request(),
583    case megaco:call(PrelCH, [SC], []) of
584	{_Version,
585	 {error,
586	  {send_message_failed,
587	   {'EXIT', {undef, [{bad_send_mod, send_message, [sh, _]} | _]}}}}
588	} ->
589	    %% R14B and previous
590	    ?LOG("expected send failure (1)", []),
591	    ok;
592
593	%% As of R15, we also get some extra info (e.g. line numbers)
594	{_Version,
595	 {error,
596	  {send_message_failed,
597	   {'EXIT', {undef, [{bad_send_mod, send_message, [sh, _], _} | _]}}}}
598	} ->
599	    %% R15B and later
600	    ?LOG("expected send failure (2)", []),
601	    ok;
602
603	Unexpected ->
604	    ?ERROR(Unexpected)
605    end,
606
607    ?VERIFY(ok, megaco:disconnect(PrelCH, shutdown)),
608
609    ?VERIFY(ok,	megaco:stop_user(MgMid)),
610    ?VERIFY(ok, application:stop(megaco)),
611    ?RECEIVE([]),
612    ok.
613
614
615%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
616
617request_and_reply_plain(suite) ->
618    [];
619request_and_reply_plain(Config) when is_list(Config) ->
620    ?ACQUIRE_NODES(1, Config),
621    d("request_and_reply_plain -> start proxy",[]),
622    ?USER_MOD:start_proxy(),
623
624    PrelMid = preliminary_mid,
625    MgMid   = ipv4_mid(4711),
626    MgcMid  = ipv4_mid(),
627    UserMod = ?USER_MOD,
628    d("request_and_reply_plain -> start megaco app",[]),
629    ?VERIFY(ok, application:start(megaco)),
630    UserConfig = [{user_mod, UserMod}, {send_mod, UserMod},
631		  {request_timer, infinity}, {reply_timer, infinity}],
632    d("request_and_reply_plain -> start (MG) user ~p",[MgMid]),
633    ?VERIFY(ok,	megaco:start_user(MgMid, UserConfig)),
634
635    d("request_and_reply_plain -> start (MGC) user ~p",[MgcMid]),
636    ?VERIFY(ok,	megaco:start_user(MgcMid, UserConfig)),
637
638    d("request_and_reply_plain -> get receive info for ~p",[MgMid]),
639    MgRH = user_info(MgMid, receive_handle),
640    d("request_and_reply_plain -> get receive info for ~p",[MgcMid]),
641    MgcRH = user_info(MgcMid, receive_handle),
642    d("request_and_reply_plain -> start transport",[]),
643    {ok, MgPid, MgSH} =
644	?VERIFY({ok, _, _}, UserMod:start_transport(MgRH, MgcRH)),
645    PrelMgCH = #megaco_conn_handle{local_mid = MgMid,
646				   remote_mid = preliminary_mid},
647    MgCH  = #megaco_conn_handle{local_mid = MgMid,
648				remote_mid = MgcMid},
649    MgcCH = #megaco_conn_handle{local_mid = MgcMid,
650				remote_mid = MgMid},
651    d("request_and_reply_plain -> (MG) try connect to MGC",[]),
652    ?SEND(megaco:connect(MgRH, PrelMid, MgSH, MgPid)), % Mg prel
653    d("request_and_reply_plain -> (MGC) await connect from MG",[]),
654    ?USER({connect, PrelMgCH, _V, []}, ok),
655    ?RECEIVE([{res, _, {ok, PrelMgCH}}]),
656
657    d("request_and_reply_plain -> (MG) send service change request",[]),
658    Req = service_change_request(),
659    ?SEND(megaco:call(PrelMgCH, [Req], [])),
660
661    d("request_and_reply_plain -> (MGC) send service change reply",[]),
662    ?USER({connect, MgcCH, _V, []}, ok), % Mgc auto
663    Rep = service_change_reply(MgcMid),
664    ?USER({request, MgcCH, _V, [[Req]]}, {discard_ack, [Rep]}),
665    ?USER({connect, MgCH, _V, []}, ok), % Mg confirm
666    ?RECEIVE([{res, _, {1, {ok, [Rep]}}}]),
667
668    d("request_and_reply_plain -> get (system info) connections",[]),
669    connections([MgCH, MgcCH]),
670    d("request_and_reply_plain -> get (~p) connections",[MgMid]),
671    ?VERIFY([MgCH], megaco:user_info(MgMid, connections)),
672    d("request_and_reply_plain -> get (~p) connections",[MgcMid]),
673    ?VERIFY([MgcCH], megaco:user_info(MgcMid, connections)),
674
675    Reason = shutdown,
676    d("request_and_reply_plain -> (MG) disconnect",[]),
677    ?SEND(megaco:disconnect(MgCH, Reason)),
678    ?USER({disconnect, MgCH, _V, [{user_disconnect, Reason}]}, ok),
679    ?RECEIVE([{res, _, ok}]),
680    ?VERIFY(ok,	megaco:stop_user(MgMid)),
681
682    d("request_and_reply_plain -> (MGC) disconnect",[]),
683    ?SEND(megaco:disconnect(MgcCH, Reason)),
684    ?USER({disconnect, MgcCH, _V, [{user_disconnect, Reason}]}, ok),
685    ?RECEIVE([{res, _, ok}]),
686    ?VERIFY(ok,	megaco:stop_user(MgcMid)),
687
688    d("request_and_reply_plain -> stop megaco app",[]),
689    ?VERIFY(ok, application:stop(megaco)),
690    ?RECEIVE([]),
691    d("request_and_reply_plain -> done",[]),
692    ok.
693
694
695
696%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
697
698%% OTP-4760
699request_and_no_reply(suite) ->
700    [];
701request_and_no_reply(doc) ->
702    [];
703request_and_no_reply(Config) when is_list(Config) ->
704    Pre = fun() ->
705                  MgcNode = make_node_name(mgc),
706                  Mg1Node = make_node_name(mg1),
707                  Mg2Node = make_node_name(mg2),
708                  Mg3Node = make_node_name(mg3),
709                  Mg4Node = make_node_name(mg4),
710                  d("start nodes: "
711                    "~n      MgcNode: ~p"
712                    "~n      Mg1Node: ~p"
713                    "~n      Mg2Node: ~p"
714                    "~n      Mg3Node: ~p"
715                    "~n      Mg4Node: ~p",
716                    [MgcNode, Mg1Node, Mg2Node, Mg3Node, Mg4Node]),
717                  Nodes = [MgcNode, Mg1Node, Mg2Node, Mg3Node, Mg4Node],
718                  ok = ?START_NODES(Nodes, true),
719                  Nodes
720          end,
721    Case = fun do_request_and_no_reply/1,
722    Post = fun(Nodes) ->
723                   d("stop nodes"),
724                   ?STOP_NODES(lists:reverse(Nodes))
725           end,
726    try_tc(request_and_no_reply, Pre, Case, Post).
727
728do_request_and_no_reply([MgcNode, Mg1Node, Mg2Node, Mg3Node, Mg4Node]) ->
729    %% Start the MGC
730    i("[MGC] start"),
731    ET = [{text,tcp}, {text,udp}, {binary,tcp}, {binary,udp}],
732    {ok, Mgc} = ?MGC_START(MgcNode, {deviceName, "ctrl"}, ET, [], ?MGC_VERBOSITY),
733    ?SLEEP(?SECONDS(1)),
734
735    i("[MG] start"),
736    Mg1Mid = {deviceName, "mg1"},
737    Mg2Mid = {deviceName, "mg2"},
738    Mg3Mid = {deviceName, "mg3"},
739    Mg4Mid = {deviceName, "mg4"},
740    ReqTmr = #megaco_incr_timer{wait_for    = 3000,
741				factor      = 1,
742				incr        = 0,
743				max_retries = 2
744			       },
745    LongReqTmr = #megaco_incr_timer{wait_for    = 10000,
746				    factor      = 1,
747				    incr        = 0,
748				    max_retries = 3
749				   },
750    %% Start the MGs
751    PendingTmr = 10000,
752    ReplyTmr = 16000,
753    MgConfig = [{request_timer,      ReqTmr},
754		{long_request_timer, LongReqTmr},
755		{pending_timer,      PendingTmr},
756		{reply_timer,        ReplyTmr}],
757    {ok, Mg1} = ?MG_START(Mg1Node, Mg1Mid, text, tcp, MgConfig, ?MG_VERBOSITY),
758    ?SLEEP(?SECONDS(1)),
759    {ok, Mg2} = ?MG_START(Mg2Node, Mg2Mid, text, udp, MgConfig, ?MG_VERBOSITY),
760    ?SLEEP(?SECONDS(1)),
761    {ok, Mg3} = ?MG_START(Mg3Node, Mg3Mid, binary, tcp, MgConfig, ?MG_VERBOSITY),
762    ?SLEEP(?SECONDS(1)),
763    {ok, Mg4} = ?MG_START(Mg4Node, Mg4Mid, binary, udp, MgConfig, ?MG_VERBOSITY),
764    ?SLEEP(?SECONDS(1)),
765
766    d("MG1 user info: ~p", [?MG_USER_INFO(Mg1, all)]),
767    d("MG1 conn info: ~p", [?MG_CONN_INFO(Mg1, all)]),
768    d("MG2 user info: ~p", [?MG_USER_INFO(Mg2, all)]),
769    d("MG2 conn info: ~p", [?MG_CONN_INFO(Mg2, all)]),
770    d("MG3 user info: ~p", [?MG_USER_INFO(Mg3, all)]),
771    d("MG3 conn info: ~p", [?MG_CONN_INFO(Mg3, all)]),
772    d("MG4 user info: ~p", [?MG_USER_INFO(Mg4, all)]),
773    d("MG4 conn info: ~p", [?MG_CONN_INFO(Mg4, all)]),
774
775    i("[MG1] connect to the MGC (service change)"),
776    ServChRes1 = ?MG_SERV_CHANGE(Mg1),
777    d("service change result: ~p", [ServChRes1]),
778    d("MG1 user info: ~p", [?MG_USER_INFO(Mg1, all)]),
779    d("MG1 conn info: ~p", [?MG_CONN_INFO(Mg1, all)]),
780    ?SLEEP(?SECONDS(1)),
781
782    i("[MG2] connect to the MGC (service change)"),
783    ServChRes2 = ?MG_SERV_CHANGE(Mg2),
784    d("service change result: ~p", [ServChRes2]),
785    d("MG2 user info: ~p", [?MG_USER_INFO(Mg2, all)]),
786    d("MG2 conn info: ~p", [?MG_CONN_INFO(Mg2, all)]),
787    ?SLEEP(?SECONDS(1)),
788
789    i("[MG3] connect to the MGC (service change)"),
790    ServChRes3 = ?MG_SERV_CHANGE(Mg3),
791    d("service change result: ~p", [ServChRes3]),
792    d("MG3 user info: ~p", [?MG_USER_INFO(Mg3, all)]),
793    d("MG3 conn info: ~p", [?MG_CONN_INFO(Mg3, all)]),
794    ?SLEEP(?SECONDS(1)),
795
796    i("[MG4] connect to the MGC (service change)"),
797    ServChRes4 = ?MG_SERV_CHANGE(Mg4),
798    d("service change result: ~p", [ServChRes4]),
799    d("MG4 user info: ~p", [?MG_USER_INFO(Mg4, all)]),
800    d("MG4 conn info: ~p", [?MG_CONN_INFO(Mg4, all)]),
801    ?SLEEP(?SECONDS(1)),
802
803    d("tell the MGC to ignore requests"),
804    ?MGC_REQ_PEND(Mgc, infinity),
805    ?SLEEP(?SECONDS(1)),
806
807    d("[MG1] send the notify"),
808    ?MG_NOTIF_REQ(Mg1),
809    ?SLEEP(?SECONDS(1)),
810
811    d("[MG2] send the notify"),
812    ?MG_NOTIF_REQ(Mg2),
813    ?SLEEP(?SECONDS(1)),
814
815    d("[MG3] send the notify"),
816    ?MG_NOTIF_REQ(Mg3),
817    ?SLEEP(?SECONDS(1)),
818
819    d("[MG4] send the notify"),
820    ?MG_NOTIF_REQ(Mg4),
821    ?SLEEP(?SECONDS(1)),
822
823    d("[MG1] await notify reply"),
824    {ok, {_Vsn1, {error, timeout}}} = ?MG_AWAIT_NOTIF_REP(Mg1),
825    d("[MG1] received expected reply"),
826    ?SLEEP(?SECONDS(1)),
827
828    d("[MG2] await notify reply"),
829    {ok, {_Vsn2, {error, timeout}}} = ?MG_AWAIT_NOTIF_REP(Mg2),
830    d("[MG2] received expected reply"),
831    ?SLEEP(?SECONDS(1)),
832
833    d("[MG3] await notify reply"),
834    {ok, {_Vsn3, {error, timeout}}} = ?MG_AWAIT_NOTIF_REP(Mg3),
835    d("[MG3] received expected reply"),
836    ?SLEEP(?SECONDS(1)),
837
838    d("[MG4] await notify reply"),
839    {ok, {_Vsn4, {error, timeout}}} = ?MG_AWAIT_NOTIF_REP(Mg4),
840    d("[MG4] received expected reply"),
841    ?SLEEP(?SECONDS(1)),
842
843    d("MG1 user info: ~p", [?MG_USER_INFO(Mg1, all)]),
844    d("MG1 conn info: ~p", [?MG_CONN_INFO(Mg1, all)]),
845    d("MG2 user info: ~p", [?MG_USER_INFO(Mg2, all)]),
846    d("MG2 conn info: ~p", [?MG_CONN_INFO(Mg2, all)]),
847    d("MG3 user info: ~p", [?MG_USER_INFO(Mg3, all)]),
848    d("MG3 conn info: ~p", [?MG_CONN_INFO(Mg3, all)]),
849    d("MG4 user info: ~p", [?MG_USER_INFO(Mg4, all)]),
850    d("MG4 conn info: ~p", [?MG_CONN_INFO(Mg4, all)]),
851
852    %% Tell MG4 to stop
853    i("[MG4] stop"),
854    ?MG_STOP(Mg4),
855
856    %% Tell MG3 to stop
857    i("[MG3] stop"),
858    ?MG_STOP(Mg3),
859
860    %% Tell MG2 to stop
861    i("[MG2] stop"),
862    ?MG_STOP(Mg2),
863
864    %% Tell MG1 to stop
865    i("[MG1] stop"),
866    ?MG_STOP(Mg1),
867
868    %% Tell Mgc to stop
869    i("[MGC] stop"),
870    ?MGC_STOP(Mgc),
871
872    i("done", []),
873    ok.
874
875
876
877%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
878
879request_and_reply_pending_ack_no_pending(suite) ->
880    [];
881request_and_reply_pending_ack_no_pending(doc) ->
882    ["This test case tests that megaco correctly handles the return "
883     "value handle_pending_ack from handle_trans_request when NO "
884     "pending message has been sent"];
885request_and_reply_pending_ack_no_pending(Config) when is_list(Config) ->
886    Pre = fun() ->
887                  MgcNode = make_node_name(mgc),
888                  MgNode  = make_node_name(mg),
889                  d("start nodes: "
890                    "~n      MgcNode: ~p"
891                    "~n      MgNode:  ~p",
892                    [MgcNode, MgNode]),
893                  Nodes = [MgcNode, MgNode],
894                  ok = ?START_NODES(Nodes, true),
895                  Nodes
896          end,
897    Case = fun do_request_and_reply_pending_ack_no_pending/1,
898    Post = fun(Nodes) ->
899                   d("stop nodes"),
900                   ?STOP_NODES(lists:reverse(Nodes)),
901                   ok
902           end,
903    try_tc(rar_panp, Pre, Case, Post).
904
905do_request_and_reply_pending_ack_no_pending([MgcNode, MgNode]) ->
906    d("[MGC] start the simulator "),
907    {ok, Mgc} = megaco_test_megaco_generator:start_link("MGC", MgcNode),
908
909    d("[MGC] create the event sequence"),
910    MgcEvSeq = rarpanp_mgc_event_sequence(text, tcp),
911
912    i("wait some time before starting the MGC simulation"),
913    sleep(1000),
914
915    d("[MGC] start the simulation"),
916    {ok, MgcId} = megaco_test_megaco_generator:exec(Mgc, MgcEvSeq),
917
918    i("await MGC ready announcement"),
919    receive
920        announce_mgc ->
921            i("received MGC ready announcement"),
922            ok
923    end,
924
925    d("[MG] start the simulator (generator)"),
926    {ok, Mg} = megaco_test_tcp_generator:start_link("MG", MgNode),
927
928    d("[MG] create the event sequence"),
929    MgEvSeq = rarpanp_mg_event_sequence(text, tcp),
930
931    i("wait some time before starting the MG simulation"),
932    sleep(1000),
933
934    d("[MG] start the simulation"),
935    {ok, MgId} = megaco_test_tcp_generator:exec(Mg, MgEvSeq),
936
937    d("await the generator reply(s)"),
938    await_completion([MgcId, MgId]),
939
940    %% Tell Mgc to stop
941    i("[MGC] stop generator"),
942    megaco_test_tcp_generator:stop(Mgc),
943
944    %% Tell Mg to stop
945    i("[MG] stop generator"),
946    megaco_test_megaco_generator:stop(Mg),
947
948    i("done", []),
949    ok.
950
951
952%%
953%% MGC generator stuff
954%%
955-ifdef(megaco_hipe_special).
956-define(rarpanp_mgc_verify_handle_connect_fun(),
957        {?MODULE, rarpanp_mgc_verify_handle_connect, []}).
958-define(rarpanp_mgc_verify_service_change_req_fun(Mid),
959        {?MODULE, rarpanp_mgc_verify_service_change_req, [Mid]}).
960-define(rarpanp_mgc_verify_notify_req_fun(),
961        {?MODULE, rarpanp_mgc_verify_notify_request, []}).
962-define(rarpanp_mgc_verify_handle_disconnect_fun(),
963        {?MODULE, rarpanp_mgc_verify_handle_disconnect, []}).
964-else.
965-define(rarpanp_mgc_verify_handle_connect_fun(),
966        fun rarpanp_mgc_verify_handle_connect/1).
967-define(rarpanp_mgc_verify_service_change_req_fun(Mid),
968        rarpanp_mgc_verify_service_change_req_fun(Mid)).
969-define(rarpanp_mgc_verify_notify_req_fun(),
970	rarpanp_mgc_verify_notify_request_fun()).
971-define(rarpanp_mgc_verify_handle_disconnect_fun(),
972	fun rarpanp_mgc_verify_handle_disconnect/1).
973-endif.
974
975rarpanp_mgc_event_sequence(text, tcp) ->
976    CTRL = self(),
977    Mid = {deviceName,"ctrl"},
978    RI = [
979          {port,             2944},
980          {encoding_module,  megaco_pretty_text_encoder},
981          {encoding_config,  []},
982          {transport_module, megaco_tcp}
983         ],
984    ConnectVerify = ?rarpanp_mgc_verify_handle_connect_fun(),
985    ScrVerify     = ?rarpanp_mgc_verify_service_change_req_fun(Mid),
986    NrVerify      = ?rarpanp_mgc_verify_notify_req_fun(),
987    DiscoVerify   = ?rarpanp_mgc_verify_handle_disconnect_fun(),
988    EvSeq = [
989             {debug, true},
990             {megaco_trace, disable},
991             {megaco_trace, max},
992             megaco_start,
993             {megaco_start_user, Mid, RI, []},
994             {megaco_update_user_info, sent_pending_limit, 100},
995             start_transport,
996             listen,
997
998             %% ANNOUNCE READY
999             {trigger, fun() -> CTRL ! announce_mgc end},
1000
1001             {megaco_callback, handle_connect,       ConnectVerify},
1002             {megaco_conn_info, all},
1003             {megaco_callback, handle_trans_request, ScrVerify},
1004	     {megaco_callback, handle_trans_request, NrVerify},
1005             {megaco_callback, nocall, 10000},
1006             {megaco_callback, handle_disconnect,    DiscoVerify},
1007             megaco_stop_user,
1008             megaco_stop
1009            ],
1010    EvSeq.
1011
1012%% Connect verification
1013rarpanp_mgc_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
1014    {ok, CH, ok};
1015rarpanp_mgc_verify_handle_connect(Else) ->
1016    {error, Else, ok}.
1017
1018%% Service Change verification
1019-ifndef(megaco_hipe_special).
1020rarpanp_mgc_verify_service_change_req_fun(Mid) ->
1021    fun(Req) ->
1022	    rarpanp_mgc_verify_service_change_req(Req, Mid)
1023    end.
1024-endif.
1025
1026rarpanp_mgc_verify_service_change_req(
1027  {handle_trans_request, _, ?VERSION, [AR]}, Mid) ->
1028    io:format("rarpanp_mgc_verify_service_change_req -> entry with"
1029	      "~n   AR:  ~p"
1030	      "~n   Mid: ~p"
1031	      "~n", [AR, Mid]),
1032    (catch rarpanp_mgc_do_verify_service_change_req(AR, Mid));
1033rarpanp_mgc_verify_service_change_req(Crap, _Mid) ->
1034    ED       = cre_ErrDesc(Crap),
1035    ErrReply = {discard_ack, ED},
1036    {error, Crap, ErrReply}.
1037
1038rarpanp_mgc_do_verify_service_change_req(AR, Mid) ->
1039    io:format("rarpanp_mgc_do_verify_service_change_req -> entry with"
1040	      "~n   AR:  ~p"
1041	      "~n   Mid: ~p"
1042	      "~n", [AR, Mid]),
1043    CR =
1044	case AR of
1045	    #'ActionRequest'{commandRequests = [CmdReq]} ->
1046		CmdReq;
1047	    _ ->
1048		Err1      = {invalid_action_request, AR},
1049		ED1       = cre_ErrDesc(AR),
1050		ErrReply1 = {discard_ack, ED1},
1051		throw({error, Err1, ErrReply1})
1052	end,
1053    Cmd =
1054	case CR of
1055	    #'CommandRequest'{command = Command} ->
1056		Command;
1057	    _ ->
1058		Err2      = {invalid_command_request, CR},
1059		ED2       = cre_ErrDesc(CR),
1060		ErrReply2 = {discard_ack, ED2},
1061		throw({error, Err2, ErrReply2})
1062	end,
1063    {Tid, Parms} =
1064	case Cmd of
1065	    {serviceChangeReq,
1066	     #'ServiceChangeRequest'{terminationID = [TermID],
1067				     serviceChangeParms = ServChParms}} ->
1068		{TermID, ServChParms};
1069	    _ ->
1070		Err3      = {invalid_command, Cmd},
1071		ED3       = cre_ErrDesc(Cmd),
1072		ErrReply3 = {discard_ack, ED3},
1073		throw({error, Err3, ErrReply3})
1074	end,
1075    case Tid of
1076	#megaco_term_id{contains_wildcards = false, id = ["root"]} ->
1077	    ok;
1078	_ ->
1079	    Err4      = {invalid_termination_id, Tid},
1080	    ED4       = cre_ErrDesc(Tid),
1081	    ErrReply4 = {discard_ack, ED4},
1082	    throw({error, Err4, ErrReply4})
1083    end,
1084    case Parms of
1085	#'ServiceChangeParm'{serviceChangeMethod = restart,
1086			     serviceChangeReason = [[$9,$0,$1|_]]} ->
1087	    AckData = [rarpanp_mgc_service_change_reply_ar(Mid, 1)],
1088	    Reply   = {discard_ack, AckData},
1089	    {ok, AR, Reply};
1090	_ ->
1091	    Err5      = {invalid_SCP, Parms},
1092	    ED5       = cre_ErrDesc(Parms),
1093	    ErrReply5 = {discard_ack, ED5},
1094	    {error, Err5, ErrReply5}
1095    end.
1096
1097
1098%% Notify Request verification
1099-ifndef(megaco_hipe_special).
1100rarpanp_mgc_verify_notify_request_fun() ->
1101    fun(Req) ->
1102	    rarpanp_mgc_verify_notify_request(Req)
1103    end.
1104-endif.
1105
1106rarpanp_mgc_verify_notify_request(
1107  {handle_trans_request, _, ?VERSION, [AR]}) ->
1108    (catch rarpanp_mgc_do_verify_notify_request(AR));
1109rarpanp_mgc_verify_notify_request(Crap) ->
1110    ED = cre_ErrDesc(Crap),
1111    ErrReply = {discard_ack, ED},
1112    {error, Crap, ErrReply}.
1113
1114rarpanp_mgc_do_verify_notify_request(AR) ->
1115    io:format("rarpanp_mgc_do_verify_notify_request -> entry with"
1116	      "~n   AR: ~p"
1117	      "~n", [AR]),
1118    {Cid, CR} =
1119	case AR of
1120	    #'ActionRequest'{contextId       = CtxID,
1121			     commandRequests = [CmdReq]} ->
1122		{CtxID, CmdReq};
1123	    _ ->
1124		Err1      = {invalid_action_request, AR},
1125		ED1       = cre_ErrDesc(AR),
1126		ErrReply1 = {discard_ack, ED1},
1127		throw({error, Err1, ErrReply1})
1128	end,
1129    Cmd =
1130	case CR of
1131	    #'CommandRequest'{command = Command} ->
1132		Command;
1133	    _ ->
1134		Err2      = {invalid_command_request, CR},
1135		ED2       = cre_ErrDesc(CR),
1136		ErrReply2 = {discard_ack, ED2},
1137		throw({error, Err2, ErrReply2})
1138	end,
1139    NR =
1140	case Cmd of
1141	    {notifyReq, NotifReq} ->
1142		NotifReq;
1143	    _ ->
1144		Err3      = {invalid_command, Cmd},
1145		ED3       = cre_ErrDesc(Cmd),
1146		ErrReply3 = {discard_ack, ED3},
1147		throw({error, Err3, ErrReply3})
1148	end,
1149    {Tid, OED} =
1150	case NR of
1151	    #'NotifyRequest'{terminationID            = [TermID],
1152			     observedEventsDescriptor = ObsEvsDesc,
1153			     errorDescriptor          = asn1_NOVALUE} ->
1154		{TermID, ObsEvsDesc};
1155	    _ ->
1156		Err4      = {invalid_NR, NR},
1157		ED4       = cre_ErrDesc(NR),
1158		ErrReply4 = {discard_ack, ED4},
1159		throw({error, Err4, ErrReply4})
1160	end,
1161    OE =
1162	case OED of
1163	    #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
1164		ObsEvLst;
1165	    _ ->
1166		Err5      = {invalid_OED, OED},
1167		ED5       = cre_ErrDesc(NR),
1168		ErrReply5 = {discard_ack, ED5},
1169		throw({error, Err5, ErrReply5})
1170	end,
1171    case OE of
1172	#'ObservedEvent'{eventName = "al/of"} ->
1173	    AckData = notify_request_verified,
1174	    Replies = [rarpanp_mgc_notify_reply_ar(Cid, Tid)],
1175	    Reply   = {{handle_pending_ack, AckData}, Replies},
1176	    {ok, AR, Reply};
1177	_ ->
1178	    Err6      = {invalid_OE, OE},
1179	    ED6       = cre_ErrDesc(OE),
1180	    ErrReply6 = {discard_ack, ED6},
1181	    throw({error, Err6, ErrReply6})
1182    end.
1183
1184
1185%% Disconnect verification
1186rarpanp_mgc_verify_handle_disconnect({handle_disconnect, CH, ?VERSION, _R}) ->
1187    {ok, CH, ok};
1188rarpanp_mgc_verify_handle_disconnect(Else) ->
1189    {error, Else, ok}.
1190
1191rarpanp_mgc_service_change_reply_ar(Mid, Cid) ->
1192    SCRP  = cre_serviceChangeResParm(Mid),
1193    SCRes = cre_serviceChangeResult(SCRP),
1194    Root  = #megaco_term_id{id = ["root"]},
1195    SCR   = cre_serviceChangeReply([Root], SCRes),
1196    CR    = cre_cmdReply(SCR),
1197    AR    = cre_actionReply(Cid, [CR]),
1198    AR.
1199
1200rarpanp_mgc_notify_reply_ar(Cid, TermId) ->
1201    NR    = cre_notifyReply([TermId]),
1202    CR    = cre_cmdReply(NR),
1203    cre_actionReply(Cid, [CR]).
1204
1205
1206%%
1207%% MG generator stuff
1208%%
1209-ifdef(megaco_hipe_special).
1210-define(rarpanp_mg_decode_msg_fun(Mod, Conf),
1211	{?MODULE, decode_msg, [Mod, Conf]}).
1212-define(rarpanp_mg_encode_msg_fun(Mod, Conf),
1213	{?MODULE, encode_msg, [Mod, Conf]}).
1214-define(rarpanp_mg_verify_service_change_rep_msg_fun(),
1215	{?MODULE, rarpanp_mg_verify_service_change_rep_msg, []}).
1216-define(rarpanp_mg_verify_notify_rep_msg_fun(TransId, TermId),
1217	{?MODULE, rarpanp_mg_verify_notify_rep_msg, [TransId, TermId]}).
1218-else.
1219-define(rarpanp_mg_decode_msg_fun(Mod, Conf),
1220	rarpanp_mg_decode_msg_fun(Mod, Conf)).
1221-define(rarpanp_mg_encode_msg_fun(Mod, Conf),
1222	rarpanp_mg_encode_msg_fun(Mod, Conf)).
1223-define(rarpanp_mg_verify_service_change_rep_msg_fun(),
1224	rarpanp_mg_verify_service_change_rep_msg_fun()).
1225-define(rarpanp_mg_verify_notify_rep_msg_fun(TransId, TermId),
1226	rarpanp_mg_verify_notify_rep_msg_fun(TransId, TermId)).
1227-endif.
1228
1229rarpanp_mg_event_sequence(text, tcp) ->
1230    DecodeFun = ?rarpanp_mg_decode_msg_fun(megaco_pretty_text_encoder, []),
1231    EncodeFun = ?rarpanp_mg_encode_msg_fun(megaco_pretty_text_encoder, []),
1232    Mid       = {deviceName,"mg"},
1233    ServiceChangeReq = rarpanp_mg_service_change_request_msg(Mid, 1, 0),
1234    ScrVerifyFun = ?rarpanp_mg_verify_service_change_rep_msg_fun(),
1235    TransId = 2,
1236    TermId = #megaco_term_id{id = ["00000000","00000000","01101101"]},
1237    NotifyReq = rarpanp_mg_notify_request_msg(Mid, TransId, 1, TermId, 1),
1238    NrVerifyFun = ?rarpanp_mg_verify_notify_rep_msg_fun(TransId, TermId),
1239    EvSeq = [{debug,  true},
1240             {decode, DecodeFun},
1241             {encode, EncodeFun},
1242             {connect, 2944},
1243             {send, "service-change-request", ServiceChangeReq},
1244             {expect_receive, "service-change-reply", {ScrVerifyFun, 10000}},
1245             {send, "notify request", NotifyReq},
1246             {expect_receive, "notify-reply", {NrVerifyFun, 10000}},
1247             {expect_nothing, 11000},
1248             disconnect
1249            ],
1250    EvSeq.
1251
1252
1253-ifndef(megaco_hipe_special).
1254rarpanp_mg_encode_msg_fun(Mod, Conf) ->
1255    fun(M) ->
1256            encode_msg(M, Mod, Conf)
1257    end.
1258-endif.
1259
1260-ifndef(megaco_hipe_special).
1261rarpanp_mg_decode_msg_fun(Mod, Conf) ->
1262    fun(M) ->
1263            decode_msg(M, Mod, Conf)
1264    end.
1265-endif.
1266
1267-ifndef(megaco_hipe_special).
1268rarpanp_mg_verify_service_change_rep_msg_fun() ->
1269    fun(Msg) ->
1270	    (catch rarpanp_mg_verify_service_change_rep_msg(Msg))
1271    end.
1272-endif.
1273
1274rarpanp_mg_verify_service_change_rep_msg(#'MegacoMessage'{mess = Mess} = M) ->
1275    io:format("rarpanp_mg_verify_service_change_rep_msg -> entry with"
1276	      "~n   Mess:  ~p"
1277	      "~n", [Mess]),
1278    Body =
1279	case Mess of
1280	    #'Message'{version     = _V,
1281                       mId         = _MgMid,
1282                       messageBody = MsgBody} ->
1283		MsgBody;
1284	    _ ->
1285		throw({error, {invalid_Message, Mess}})
1286	end,
1287    Trans =
1288	case Body of
1289            {transactions, [Transactions]} ->
1290		Transactions;
1291	    _ ->
1292		throw({error, {invalid_messageBody, Body}})
1293	end,
1294    TR =
1295	case Trans of
1296            {transactionReply, TransReply} ->
1297		TransReply;
1298	    _ ->
1299		throw({error, {invalid_transactions, Trans}})
1300	end,
1301    TRes =
1302	case TR of
1303            #'TransactionReply'{transactionId = _Tid,
1304                                immAckRequired = asn1_NOVALUE,
1305                                transactionResult = TransRes} ->
1306		TransRes;
1307	    _ ->
1308		throw({error, {invalid_transactionReply, TR}})
1309	end,
1310    AR =
1311	case TRes of
1312            {actionReplies, [ActRes]} ->
1313		ActRes;
1314	    _ ->
1315		throw({error, {invalid_transactionResult, TRes}})
1316	end,
1317    CR =
1318	case AR of
1319            #'ActionReply'{contextId       = _Cid,
1320                           errorDescriptor = asn1_NOVALUE,
1321                           contextReply    = _CtxReq,
1322                           commandReply    = [CmdRep]} ->
1323		CmdRep;
1324	    _ ->
1325		throw({error, {invalid_actionReplies, AR}})
1326	end,
1327    SCR =
1328	case CR of
1329            {serviceChangeReply, ServChRep} ->
1330		ServChRep;
1331	    _ ->
1332		throw({error, {invalid_commandReply, CR}})
1333	end,
1334    SCRes =
1335	case SCR of
1336            #'ServiceChangeReply'{terminationID       = _TermID,
1337                                  serviceChangeResult = ServChRes} ->
1338		ServChRes;
1339	    _ ->
1340		throw({error, {invalid_serviceChangeReply, SCR}})
1341	end,
1342    SCRP =
1343	case SCRes of
1344            {serviceChangeResParms, Parms} ->
1345		Parms;
1346	    _ ->
1347		throw({error, {invalid_serviceChangeResult, SCRes}})
1348	end,
1349    case SCRP of
1350	#'ServiceChangeResParm'{serviceChangeMgcId = _MgcMid} ->
1351            {ok, M};
1352	_ ->
1353	    {error, {invalid_serviceChangeResParms, SCRP}}
1354    end;
1355rarpanp_mg_verify_service_change_rep_msg(Crap) ->
1356    {error, {invalid_message, Crap}}.
1357
1358-ifndef(megaco_hipe_special).
1359rarpanp_mg_verify_notify_rep_msg_fun(TransId, TermId) ->
1360    fun(Msg) ->
1361	    (catch rarpanp_mg_verify_notify_rep_msg(Msg, TransId, TermId))
1362    end.
1363-endif.
1364
1365rarpanp_mg_verify_notify_rep_msg(#'MegacoMessage'{mess = Mess} = M,
1366			     TransId, TermId) ->
1367    io:format("rarpanp_mg_verify_notify_rep_msg -> entry with"
1368	      "~n   TransId: ~p"
1369	      "~n   TermId:  ~p"
1370	      "~n   Mess:    ~p"
1371	      "~n", [TransId, TermId, Mess]),
1372    Body =
1373	case Mess of
1374	    #'Message'{version     = _V,
1375                       mId         = _MgMid,
1376                       messageBody = MsgBody} ->
1377		MsgBody;
1378	    _ ->
1379		throw({error, {invalid_Message, Mess}})
1380	end,
1381    Trans =
1382	case Body of
1383            {transactions, [Transactions]} ->
1384		Transactions;
1385	    _ ->
1386		throw({error, {invalid_messageBody, Body}})
1387	end,
1388    TR =
1389	case Trans of
1390            {transactionReply, TransReply} ->
1391		TransReply;
1392	    _ ->
1393		throw({error, {invalid_transactions, Trans}})
1394	end,
1395    TRes =
1396	case TR of
1397            #'TransactionReply'{transactionId     = TransId,
1398                                immAckRequired    = asn1_NOVALUE, % No ack
1399                                transactionResult = TransRes} ->
1400		TransRes;
1401	    _ ->
1402		throw({error, {invalid_transactionReply, TR}})
1403	end,
1404    AR =
1405	case TRes of
1406            {actionReplies, [ActRes]} ->
1407		ActRes;
1408	    _ ->
1409		throw({error, {invalid_transactionResult, TRes}})
1410	end,
1411    CR =
1412	case AR of
1413            #'ActionReply'{contextId       = _Cid,
1414                           errorDescriptor = asn1_NOVALUE,
1415                           contextReply    = _CtxReq,
1416                           commandReply    = [CmdRep]} ->
1417		CmdRep;
1418	    _ ->
1419		throw({error, {invalid_actionReplies, AR}})
1420	end,
1421    NR =
1422	case CR of
1423            {notifyReply, NotifyRep} ->
1424		NotifyRep;
1425	    _ ->
1426		throw({error, {invalid_commandReply, CR}})
1427	end,
1428
1429    case NR of
1430	#'NotifyReply'{terminationID   = [TermId],
1431		       errorDescriptor = asn1_NOVALUE} ->
1432	    io:format("rarpanp_mg_verify_notify_rep_msg -> done when verifyed"
1433		      "~n", []),
1434            {ok, M};
1435	#'NotifyReply'{terminationID   = A,
1436		       errorDescriptor = B} ->
1437	    throw({error, {invalid_notifyReply,
1438			   {A, TermId},
1439			   {B, asn1_NOVALUE}}});
1440	_ ->
1441	    throw({error, {invalid_notifyReply, NR}})
1442    end;
1443rarpanp_mg_verify_notify_rep_msg(_TransId, _TermId, Crap) ->
1444    {error, {invalid_message, Crap}}.
1445
1446rarpanp_mg_service_change_request_ar(_Mid, Cid) ->
1447    Prof  = cre_serviceChangeProf("resgw", 1),
1448    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
1449    Root  = #megaco_term_id{id = ["root"]},
1450    SCR   = cre_serviceChangeReq([Root], SCP),
1451    CMD   = cre_command(SCR),
1452    CR    = cre_cmdReq(CMD),
1453    cre_actionReq(Cid, [CR]).
1454
1455rarpanp_mg_service_change_request_msg(Mid, TransId, Cid) ->
1456    AR    = rarpanp_mg_service_change_request_ar(Mid, Cid),
1457    TR    = cre_transReq(TransId, [AR]),
1458    Trans = cre_transaction(TR),
1459    Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
1460    cre_megacoMessage(Mess).
1461
1462rarpanp_mg_notify_request_ar(Rid, Tid, Cid) ->
1463    TT      = cre_timeNotation("19990729", "22000000"),
1464    Ev      = cre_obsEvent("al/of", TT),
1465    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
1466    NR      = cre_notifyReq([Tid], EvsDesc),
1467    CMD     = cre_command(NR),
1468    CR      = cre_cmdReq(CMD),
1469    cre_actionReq(Cid, [CR]).
1470
1471rarpanp_mg_notify_request_msg(Mid, TransId, Rid, TermId, Cid) ->
1472    AR      = rarpanp_mg_notify_request_ar(Rid, TermId, Cid),
1473    TR      = cre_transReq(TransId, [AR]),
1474    Trans   = cre_transaction(TR),
1475    Mess    = cre_message(?VERSION, Mid, cre_transactions([Trans])),
1476    cre_megacoMessage(Mess).
1477
1478
1479%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1480
1481request_and_reply_pending_ack_one_pending(suite) ->
1482    [];
1483request_and_reply_pending_ack_one_pending(doc) ->
1484    ["This test case tests that megaco correctly handles the return "
1485     "value handle_pending_ack from handle_trans_request when ONE "
1486     "pending message has been sent"];
1487request_and_reply_pending_ack_one_pending(Config) when is_list(Config) ->
1488    Pre = fun() ->
1489                  MgcNode = make_node_name(mgc),
1490                  MgNode  = make_node_name(mg),
1491                  d("start nodes: "
1492                    "~n      MgcNode: ~p"
1493                    "~n      MgNode:  ~p",
1494                    [MgcNode, MgNode]),
1495                  Nodes = [MgcNode, MgNode],
1496                  ok = ?START_NODES(Nodes, true),
1497                  Nodes
1498          end,
1499    Case = fun do_request_and_reply_pending_ack_one_pending/1,
1500    Post = fun(Nodes) ->
1501                   d("stop nodes"),
1502                   ?STOP_NODES(lists:reverse(Nodes))
1503           end,
1504    try_tc(rar_paop, Pre, Case, Post).
1505
1506do_request_and_reply_pending_ack_one_pending([MgcNode, MgNode]) ->
1507    d("[MGC] start the simulator"),
1508    {ok, Mgc} = megaco_test_megaco_generator:start_link("MGC", MgcNode),
1509
1510    d("[MGC] create the event sequence"),
1511    %% MgcEvSeq = rarpaop_mgc_event_sequence(text, tcp),
1512    MgcEvSeq = rarpaop_mgc_event_sequence(binary, tcp),
1513
1514    i("wait some time before starting the MGC simulation"),
1515    sleep(1000),
1516
1517    d("[MGC] start the simulation"),
1518    {ok, MgcId} = megaco_test_megaco_generator:exec(Mgc, MgcEvSeq),
1519
1520    %% i("wait some time before starting the MG simulator"),
1521    %% sleep(1000),
1522
1523    i("await MGC ready announcement"),
1524    receive
1525        announce_mgc ->
1526            i("received MGC ready announcement"),
1527            ok
1528    end,
1529
1530    d("[MG] start the simulator (generator)"),
1531    {ok, Mg} = megaco_test_tcp_generator:start_link("MG", MgNode),
1532
1533    d("[MG] create the event sequence"),
1534    %% MgEvSeq = rarpaop_mg_event_sequence(text, tcp),
1535    MgEvSeq = rarpaop_mg_event_sequence(binary, tcp),
1536
1537    i("wait some time before starting the MG simulation"),
1538    sleep(1000),
1539
1540    d("[MG] start the simulation"),
1541    {ok, MgId} = megaco_test_tcp_generator:exec(Mg, MgEvSeq),
1542
1543    d("await the generator reply(s)"),
1544    await_completion([MgcId, MgId]),
1545
1546    %% Tell Mgc to stop
1547    i("[MGC] stop generator"),
1548    megaco_test_tcp_generator:stop(Mgc),
1549
1550    %% Tell Mg to stop
1551    i("[MG] stop generator"),
1552    megaco_test_megaco_generator:stop(Mg),
1553
1554    i("done", []),
1555    ok.
1556
1557
1558%%
1559%% MGC generator stuff
1560%%
1561-ifdef(megaco_hipe_special).
1562-define(rarpaop_mgc_verify_handle_connect_fun(),
1563        {?MODULE, rarpaop_mgc_verify_handle_connect, []}).
1564-define(rarpaop_mgc_verify_service_change_req_fun(Mid),
1565        {?MODULE, rarpaop_mgc_verify_service_change_req, [Mid]}).
1566-define(rarpaop_mgc_verify_notify_req_fun(),
1567        {?MODULE, rarpaop_mgc_verify_notify_request, []}).
1568-define(rarpaop_mgc_verify_reply_ack_fun(),
1569	{?MODULE, rarpaop_mgc_verify_reply_ack, []}).
1570-define(rarpaop_mgc_verify_handle_disconnect_fun(),
1571        {?MODULE, rarpaop_mgc_verify_handle_disconnect, []}).
1572-else.
1573-define(rarpaop_mgc_verify_handle_connect_fun(),
1574        fun rarpaop_mgc_verify_handle_connect/1).
1575-define(rarpaop_mgc_verify_service_change_req_fun(Mid),
1576        rarpaop_mgc_verify_service_change_req_fun(Mid)).
1577-define(rarpaop_mgc_verify_notify_req_fun(),
1578	rarpaop_mgc_verify_notify_request_fun()).
1579-define(rarpaop_mgc_verify_reply_ack_fun(),
1580	rarpaop_mgc_verify_reply_ack_fun()).
1581-define(rarpaop_mgc_verify_handle_disconnect_fun(),
1582	fun rarpaop_mgc_verify_handle_disconnect/1).
1583-endif.
1584
1585rarpaop_mgc_event_sequence(text, tcp) ->
1586    Port      = 2944,
1587    TranspMod = megaco_tcp,
1588    EncMod    = megaco_pretty_text_encoder,
1589    EncConf   = [],
1590    rarpaop_mgc_event_sequence(Port, TranspMod, EncMod, EncConf);
1591rarpaop_mgc_event_sequence(binary, tcp) ->
1592    Port      = 2945,
1593    TranspMod = megaco_tcp,
1594    EncMod    = megaco_ber_encoder,
1595    EncConf   = [],
1596    rarpaop_mgc_event_sequence(Port, TranspMod, EncMod, EncConf).
1597
1598rarpaop_mgc_event_sequence(Port, TranspMod, EncMod, EncConf) ->
1599    CTRL = self(),
1600    Mid = {deviceName,"ctrl"},
1601    RI = [
1602          {port,             Port},
1603          {transport_module, TranspMod},
1604          {encoding_module,  EncMod},
1605          {encoding_config,  EncConf}
1606         ],
1607    ConnectVerify = ?rarpaop_mgc_verify_handle_connect_fun(),
1608    ScrVerify     = ?rarpaop_mgc_verify_service_change_req_fun(Mid),
1609    NrVerify      = ?rarpaop_mgc_verify_notify_req_fun(),
1610    AckVerify     = ?rarpaop_mgc_verify_reply_ack_fun(),
1611    DiscoVerify   = ?rarpaop_mgc_verify_handle_disconnect_fun(),
1612    EvSeq = [
1613             {debug, true},
1614             {megaco_trace, disable},
1615             {megaco_trace, max},
1616             megaco_start,
1617             {megaco_start_user, Mid, RI, []},
1618             {megaco_update_user_info, sent_pending_limit, 100},
1619             start_transport,
1620             listen,
1621
1622             %% ANNOUNCE READY
1623             {trigger, fun() -> CTRL ! announce_mgc end},
1624
1625             {megaco_callback, handle_connect,       ConnectVerify},
1626             {megaco_conn_info, all},
1627             {megaco_callback, handle_trans_request, ScrVerify},
1628	     {megaco_callback, handle_trans_request, NrVerify},
1629	     {megaco_callback, handle_trans_ack,     AckVerify},
1630             {megaco_callback, nocall, 10000},
1631             {megaco_callback, handle_disconnect,    DiscoVerify},
1632             megaco_stop_user,
1633             megaco_stop
1634            ],
1635    EvSeq.
1636
1637%% Connect verification
1638rarpaop_mgc_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
1639    {ok, CH, ok};
1640rarpaop_mgc_verify_handle_connect(Else) ->
1641    {error, Else, ok}.
1642
1643%% Service Change verification
1644-ifndef(megaco_hipe_special).
1645rarpaop_mgc_verify_service_change_req_fun(Mid) ->
1646    fun(Req) ->
1647	    rarpaop_mgc_verify_service_change_req(Req, Mid)
1648    end.
1649-endif.
1650
1651rarpaop_mgc_verify_service_change_req(
1652  {handle_trans_request, _, ?VERSION, [AR]}, Mid) ->
1653    (catch rarpaop_do_verify_service_change_req(AR, Mid));
1654rarpaop_mgc_verify_service_change_req(Crap, _Mid) ->
1655    ED       = cre_ErrDesc(Crap),
1656    ErrReply = {discard_ack, ED},
1657    {error, Crap, ErrReply}.
1658
1659rarpaop_do_verify_service_change_req(AR, Mid) ->
1660    CR =
1661	case AR of
1662	    #'ActionRequest'{commandRequests = [CmdReq]} ->
1663		CmdReq;
1664	    _ ->
1665		Err1      = {invalid_action_request, AR},
1666		ED1       = cre_ErrDesc(AR),
1667		ErrReply1 = {discard_ack, ED1},
1668		throw({error, Err1, ErrReply1})
1669	end,
1670    Cmd =
1671	case CR of
1672	    #'CommandRequest'{command = Command} ->
1673		Command;
1674	    _ ->
1675		Err2      = {invalid_command_request, CR},
1676		ED2       = cre_ErrDesc(CR),
1677		ErrReply2 = {discard_ack, ED2},
1678		throw({error, Err2, ErrReply2})
1679	end,
1680    {Tid, Parms} =
1681	case Cmd of
1682	    {serviceChangeReq,
1683	     #'ServiceChangeRequest'{terminationID = [TermID],
1684				     serviceChangeParms = ServChParms}} ->
1685		{TermID, ServChParms};
1686	    _ ->
1687		Err3      = {invalid_command, Cmd},
1688		ED3       = cre_ErrDesc(Cmd),
1689		ErrReply3 = {discard_ack, ED3},
1690		throw({error, Err3, ErrReply3})
1691	end,
1692    case Tid of
1693	#megaco_term_id{contains_wildcards = false, id = ["root"]} ->
1694	    ok;
1695	_ ->
1696	    Err4      = {invalid_termination_id, Tid},
1697	    ED4       = cre_ErrDesc(Tid),
1698	    ErrReply4 = {discard_ack, ED4},
1699	    throw({error, Err4, ErrReply4})
1700    end,
1701    case Parms of
1702	#'ServiceChangeParm'{serviceChangeMethod = restart,
1703			     serviceChangeReason = [[$9,$0,$1|_]]} ->
1704	    AckData = [rarpaop_mgc_service_change_reply_ar(Mid, 1)],
1705	    Reply   = {discard_ack, AckData},
1706	    {ok, AR, Reply};
1707	_ ->
1708	    Err5      = {invalid_SCP, Parms},
1709	    ED5       = cre_ErrDesc(Parms),
1710	    ErrReply5 = {discard_ack, ED5},
1711	    {error, Err5, ErrReply5}
1712    end.
1713
1714
1715%% Notify Request verification
1716-ifndef(megaco_hipe_special).
1717rarpaop_mgc_verify_notify_request_fun() ->
1718    fun(Req) ->
1719	    rarpaop_mgc_verify_notify_request(Req)
1720    end.
1721-endif.
1722
1723rarpaop_mgc_verify_notify_request({handle_trans_request, _, ?VERSION, [AR]}) ->
1724    (catch rarpaop_mgc_do_verify_notify_request(AR));
1725rarpaop_mgc_verify_notify_request(Crap) ->
1726    ED       = cre_ErrDesc(Crap),
1727    ErrReply = {discard_ack, ED},
1728    {error, Crap, ErrReply}.
1729
1730rarpaop_mgc_do_verify_notify_request(AR) ->
1731    {Cid, CR} =
1732	case AR of
1733	    #'ActionRequest'{contextId       = CtxID,
1734			     commandRequests = [CmdReq]} ->
1735		{CtxID, CmdReq};
1736	    _ ->
1737		Err1      = {invalid_action_request, AR},
1738		ED1       = cre_ErrDesc(AR),
1739		ErrReply1 = {discard_ack, ED1},
1740		throw({error, Err1, ErrReply1})
1741	end,
1742    Cmd =
1743	case CR of
1744	    #'CommandRequest'{command = Command} ->
1745		Command;
1746	    _ ->
1747		Err2      = {invalid_command_request, CR},
1748		ED2       = cre_ErrDesc(CR),
1749		ErrReply2 = {discard_ack, ED2},
1750		throw({error, Err2, ErrReply2})
1751	end,
1752    NR =
1753	case Cmd of
1754	    {notifyReq, NotifReq} ->
1755		NotifReq;
1756	    _ ->
1757		Err3      = {invalid_command, Cmd},
1758		ED3       = cre_ErrDesc(Cmd),
1759		ErrReply3 = {discard_ack, ED3},
1760		throw({error, Err3, ErrReply3})
1761	end,
1762    {Tid, OED} =
1763	case NR of
1764	    #'NotifyRequest'{terminationID            = [TermID],
1765			     observedEventsDescriptor = ObsEvsDesc,
1766			     errorDescriptor          = asn1_NOVALUE} ->
1767		{TermID, ObsEvsDesc};
1768	    _ ->
1769		Err4      = {invalid_NR, NR},
1770		ED4       = cre_ErrDesc(NR),
1771		ErrReply4 = {discard_ack, ED4},
1772		throw({error, Err4, ErrReply4})
1773	end,
1774    OE =
1775	case OED of
1776	    #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
1777		ObsEvLst;
1778	    _ ->
1779		Err5      = {invalid_OED, OED},
1780		ED5       = cre_ErrDesc(NR),
1781		ErrReply5 = {discard_ack, ED5},
1782		throw({error, Err5, ErrReply5})
1783	end,
1784    case OE of
1785	#'ObservedEvent'{eventName = "al/of"} ->
1786	    AckData = notify_request_verified,
1787	    Replies = [rarpaop_mgc_notify_reply_ar(Cid, Tid)],
1788	    Reply   = {{handle_pending_ack, AckData}, Replies},
1789	    {ok, 5000, AR, Reply};
1790	_ ->
1791	    Err6      = {invalid_OE, OE},
1792	    ED6       = cre_ErrDesc(OE),
1793	    ErrReply6 = {discard_ack, ED6},
1794	    throw({error, Err6, ErrReply6})
1795    end.
1796
1797
1798%% Ack verification
1799-ifndef(megaco_hipe_special).
1800rarpaop_mgc_verify_reply_ack_fun() ->
1801    fun(M) ->
1802	    rarpaop_mgc_verify_reply_ack(M)
1803    end.
1804-endif.
1805
1806rarpaop_mgc_verify_reply_ack({handle_trans_ack, _, ?VERSION, ok, _}) ->
1807    io:format("rarpaop_mgc_verify_reply_ack -> ok~n", []),
1808    {ok, ok, ok};
1809rarpaop_mgc_verify_reply_ack({handle_trans_ack, _, ?VERSION, AS, AD} = Crap) ->
1810    io:format("rarpaop_mgc_verify_reply_ack -> incorrect ack-status:"
1811	      "~n   AS: ~p"
1812	      "~n   AD: ~p"
1813	      "~n", [AS, AD]),
1814    ED       = cre_ErrDesc({invalid_ack_status, {AS, AD}}),
1815    ErrReply = {discard_ack, ED},
1816    {error, Crap, ErrReply};
1817rarpaop_mgc_verify_reply_ack(Crap) ->
1818    io:format("rarpaop_mgc_verify_reply_ack -> invalid ack:"
1819	      "~n   Crap: ~p"
1820	      "~n", [Crap]),
1821    ED       = cre_ErrDesc(Crap),
1822    ErrReply = {discard_ack, ED},
1823    {error, Crap, ErrReply}.
1824
1825
1826%% Disconnect verification
1827rarpaop_mgc_verify_handle_disconnect({handle_disconnect, CH, ?VERSION, _R}) ->
1828    {ok, CH, ok};
1829rarpaop_mgc_verify_handle_disconnect(Else) ->
1830    {error, Else, ok}.
1831
1832rarpaop_mgc_service_change_reply_ar(Mid, Cid) ->
1833    SCRP  = cre_serviceChangeResParm(Mid),
1834    SCRes = cre_serviceChangeResult(SCRP),
1835    Root  = #megaco_term_id{id = ["root"]},
1836    SCR   = cre_serviceChangeReply([Root], SCRes),
1837    CR    = cre_cmdReply(SCR),
1838    AR    = cre_actionReply(Cid, [CR]),
1839    AR.
1840
1841rarpaop_mgc_notify_reply_ar(Cid, TermId) ->
1842    NR    = cre_notifyReply([TermId]),
1843    CR    = cre_cmdReply(NR),
1844    cre_actionReply(Cid, [CR]).
1845
1846
1847%%
1848%% MG generator stuff
1849%%
1850-ifdef(megaco_hipe_special).
1851-define(rarpaop_mg_decode_msg_fun(Mod, Conf),
1852	{?MODULE, decode_msg, [Mod, Conf]}).
1853-define(rarpaop_mg_encode_msg_fun(Mod, Conf),
1854	{?MODULE, encode_msg, [Mod, Conf]}).
1855-define(rarpaop_mg_verify_service_change_rep_msg_fun(),
1856	{?MODULE, rarpaop_mg_verify_service_change_rep_msg, []}).
1857-define(rarpaop_mg_verify_pending_msg_fun(TransId),
1858	{?MODULE, rarpaop_mg_verify_pending_msg, [TransId]}).
1859-define(rarpaop_mg_verify_notify_rep_msg_fun(TransId, TermId),
1860	{?MODULE, rarpaop_mg_verify_notify_rep_msg, [TransId, TermId]}).
1861-else.
1862-define(rarpaop_mg_decode_msg_fun(Mod, Conf),
1863	rarpaop_mg_decode_msg_fun(Mod, Conf)).
1864-define(rarpaop_mg_encode_msg_fun(Mod, Conf),
1865	rarpaop_mg_encode_msg_fun(Mod, Conf)).
1866-define(rarpaop_mg_verify_service_change_rep_msg_fun(),
1867	rarpaop_mg_verify_service_change_rep_msg_fun()).
1868-define(rarpaop_mg_verify_pending_msg_fun(TransId),
1869	rarpaop_mg_verify_pending_msg_fun(TransId)).
1870-define(rarpaop_mg_verify_notify_rep_msg_fun(TransId, TermId),
1871	rarpaop_mg_verify_notify_rep_msg_fun(TransId, TermId)).
1872-endif.
1873
1874rarpaop_mg_event_sequence(text, tcp) ->
1875    Port      = 2944,
1876    EncMod    = megaco_pretty_text_encoder,
1877    EncConf   = [],
1878    rarpaop_mg_event_sequence(Port, EncMod, EncConf);
1879rarpaop_mg_event_sequence(binary, tcp) ->
1880    Port      = 2945,
1881    EncMod    = megaco_ber_encoder,
1882    EncConf   = [],
1883    rarpaop_mg_event_sequence(Port, EncMod, EncConf).
1884
1885rarpaop_mg_event_sequence(Port, EncMod, EncConf) ->
1886    DecodeFun = ?rarpaop_mg_decode_msg_fun(EncMod, EncConf),
1887    EncodeFun = ?rarpaop_mg_encode_msg_fun(EncMod, EncConf),
1888    Mid       = {deviceName, "mg"},
1889    TransId = 2,
1890    TermId = #megaco_term_id{id = ["00000000","00000000","01101101"]},
1891    ServiceChangeReq = rarpaop_mg_service_change_request_msg(Mid, 1, 0),
1892    NotifyReq = rarpaop_mg_notify_request_msg(Mid, TransId, 1, TermId, 1),
1893    Ack = rarpaop_mg_ack_msg(Mid, TransId),
1894    ScrVerifyFun  = ?rarpaop_mg_verify_service_change_rep_msg_fun(),
1895    PendVerifyFun = ?rarpaop_mg_verify_pending_msg_fun(TransId),
1896    NrVerifyFun   = ?rarpaop_mg_verify_notify_rep_msg_fun(TransId, TermId),
1897    EvSeq = [{debug,  true},
1898             {decode, DecodeFun},
1899             {encode, EncodeFun},
1900             {connect, Port},
1901             {send, "service-change-request", ServiceChangeReq},
1902             {expect_receive, "service-change-reply", {ScrVerifyFun, 10000}},
1903             {send, "notify request", NotifyReq},
1904             {sleep, 2000},
1905             {send, "notify request", NotifyReq},
1906             {expect_receive, "pending", {PendVerifyFun, 5000}},
1907             {expect_receive, "notify-reply", {NrVerifyFun, 5000}},
1908             {send, "reply ack", Ack},
1909             {expect_nothing, 11000},
1910             disconnect
1911            ],
1912    EvSeq.
1913
1914-ifndef(megaco_hipe_special).
1915rarpaop_mg_encode_msg_fun(Mod, Conf) ->
1916    fun(M) ->
1917            encode_msg(M, Mod, Conf)
1918    end.
1919-endif.
1920
1921-ifndef(megaco_hipe_special).
1922rarpaop_mg_decode_msg_fun(Mod, Conf) ->
1923    fun(M) ->
1924            decode_msg(M, Mod, Conf)
1925    end.
1926-endif.
1927
1928-ifndef(megaco_hipe_special).
1929rarpaop_mg_verify_service_change_rep_msg_fun() ->
1930    fun(Msg) ->
1931	    (catch rarpaop_mg_verify_service_change_rep_msg(Msg))
1932    end.
1933-endif.
1934
1935rarpaop_mg_verify_service_change_rep_msg(#'MegacoMessage'{mess = Mess} = M) ->
1936    Body =
1937	case Mess of
1938	    #'Message'{version     = _V,
1939                       mId         = _MgMid,
1940                       messageBody = MsgBody} ->
1941		MsgBody;
1942	    _ ->
1943		throw({error, {invalid_Message, Mess}})
1944	end,
1945    Trans =
1946	case Body of
1947            {transactions, [Transactions]} ->
1948		Transactions;
1949	    _ ->
1950		throw({error, {invalid_messageBody, Body}})
1951	end,
1952    TR =
1953	case Trans of
1954            {transactionReply, TransReply} ->
1955		TransReply;
1956	    _ ->
1957		throw({error, {invalid_transactions, Trans}})
1958	end,
1959    TRes =
1960	case TR of
1961            #'TransactionReply'{transactionId = _Tid,
1962                                immAckRequired = asn1_NOVALUE,
1963                                transactionResult = TransRes} ->
1964		TransRes;
1965	    _ ->
1966		throw({error, {invalid_transactionReply, TR}})
1967	end,
1968    AR =
1969	case TRes of
1970            {actionReplies, [ActRes]} ->
1971		ActRes;
1972	    _ ->
1973		throw({error, {invalid_transactionResult, TRes}})
1974	end,
1975    CR =
1976	case AR of
1977            #'ActionReply'{contextId       = _Cid,
1978                           errorDescriptor = asn1_NOVALUE,
1979                           contextReply    = _CtxReq,
1980                           commandReply    = [CmdRep]} ->
1981		CmdRep;
1982	    _ ->
1983		throw({error, {invalid_actionReplies, AR}})
1984	end,
1985    SCR =
1986	case CR of
1987            {serviceChangeReply, ServChRep} ->
1988		ServChRep;
1989	    _ ->
1990		throw({error, {invalid_commandReply, CR}})
1991	end,
1992    SCRes =
1993	case SCR of
1994            #'ServiceChangeReply'{terminationID       = _TermID,
1995                                  serviceChangeResult = ServChRes} ->
1996		ServChRes;
1997	    _ ->
1998		throw({error, {invalid_serviceChangeReply, SCR}})
1999	end,
2000    SCRP =
2001	case SCRes of
2002            {serviceChangeResParms, Parms} ->
2003		Parms;
2004	    _ ->
2005		throw({error, {invalid_serviceChangeResult, SCRes}})
2006	end,
2007    case SCRP of
2008	#'ServiceChangeResParm'{serviceChangeMgcId = _MgcMid} ->
2009            {ok, M};
2010	_ ->
2011	    {error, {invalid_serviceChangeResParms, SCRP}}
2012    end;
2013rarpaop_mg_verify_service_change_rep_msg(Crap) ->
2014    {error, {invalid_message, Crap}}.
2015
2016-ifndef(megaco_hipe_special).
2017rarpaop_mg_verify_pending_msg_fun(TransId) ->
2018    fun(Msg) ->
2019	    (catch rarpaop_mg_verify_pending_msg(Msg, TransId))
2020    end.
2021-endif.
2022
2023rarpaop_mg_verify_pending_msg(#'MegacoMessage'{mess = Mess} = M, TransId) ->
2024    Body =
2025	case Mess of
2026	    #'Message'{version     = _V,
2027                       mId         = _MgMid,
2028                       messageBody = MsgBody} ->
2029		MsgBody;
2030	    _ ->
2031		throw({error, {invalid_Message, Mess}})
2032	end,
2033    Trans =
2034	case Body of
2035            {transactions, [Transactions]} ->
2036		Transactions;
2037	    _ ->
2038		throw({error, {invalid_messageBody, Body}})
2039	end,
2040    TP =
2041	case Trans of
2042            {transactionPending, TransPending} ->
2043		TransPending;
2044	    _ ->
2045		throw({error, {invalid_transactions, Trans}})
2046	end,
2047    case TP of
2048	#'TransactionPending'{transactionId = TransId} ->
2049	    {ok, M};
2050	_ ->
2051	    throw({error, {invalid_transactionPending, TP}})
2052    end;
2053rarpaop_mg_verify_pending_msg(Crap, _TransId) ->
2054    {error, {invalid_message, Crap}}.
2055
2056-ifndef(megaco_hipe_special).
2057rarpaop_mg_verify_notify_rep_msg_fun(TransId, TermId) ->
2058    fun(Msg) ->
2059	    (catch rarpaop_mg_verify_notify_rep_msg(Msg, TransId, TermId))
2060    end.
2061-endif.
2062
2063rarpaop_mg_verify_notify_rep_msg(#'MegacoMessage'{mess = Mess} = M,
2064				 TransId, TermId) ->
2065    Body =
2066	case Mess of
2067	    #'Message'{version     = _V,
2068                       mId         = _MgMid,
2069                       messageBody = MsgBody} ->
2070		MsgBody;
2071	    _ ->
2072		throw({error, {invalid_Message, Mess}})
2073	end,
2074    Trans =
2075	case Body of
2076            {transactions, [Transactions]} ->
2077		Transactions;
2078	    _ ->
2079		throw({error, {invalid_messageBody, Body}})
2080	end,
2081    TR =
2082	case Trans of
2083            {transactionReply, TransReply} ->
2084		TransReply;
2085	    _ ->
2086		throw({error, {invalid_transactions, Trans}})
2087	end,
2088    TRes =
2089	case TR of
2090            #'TransactionReply'{transactionId     = TransId,
2091                                immAckRequired    = 'NULL', % Ack
2092                                transactionResult = TransRes} ->
2093		TransRes;
2094	    _ ->
2095		throw({error, {invalid_transactionReply, TR}})
2096	end,
2097    AR =
2098	case TRes of
2099            {actionReplies, [ActRes]} ->
2100		ActRes;
2101	    _ ->
2102		throw({error, {invalid_transactionResult, TRes}})
2103	end,
2104    CR =
2105	case AR of
2106            #'ActionReply'{contextId       = _Cid,
2107                           errorDescriptor = asn1_NOVALUE,
2108                           contextReply    = _CtxReq,
2109                           commandReply    = [CmdRep]} ->
2110		CmdRep;
2111	    _ ->
2112		throw({error, {invalid_actionReplies, AR}})
2113	end,
2114    NR =
2115	case CR of
2116            {notifyReply, NotifyRep} ->
2117		NotifyRep;
2118	    _ ->
2119		throw({error, {invalid_commandReply, CR}})
2120	end,
2121
2122    case NR of
2123	#'NotifyReply'{terminationID   = [TermId],
2124		       errorDescriptor = asn1_NOVALUE} ->
2125            {ok, M};
2126	#'NotifyReply'{terminationID   = A,
2127		       errorDescriptor = B} ->
2128	    throw({error, {invalid_notifyReply,
2129			   {A, TermId},
2130			   {B, asn1_NOVALUE}}});
2131	_ ->
2132	    throw({error, {invalid_notifyReply, NR}})
2133    end;
2134rarpaop_mg_verify_notify_rep_msg(Crap, _TransId, _TermId) ->
2135    {error, {invalid_message, Crap}}.
2136
2137rarpaop_mg_service_change_request_ar(_Mid, Cid) ->
2138    Prof  = cre_serviceChangeProf("resgw", 1),
2139    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
2140    Root  = #megaco_term_id{id = ["root"]},
2141    SCR   = cre_serviceChangeReq([Root], SCP),
2142    CMD   = cre_command(SCR),
2143    CR    = cre_cmdReq(CMD),
2144    cre_actionReq(Cid, [CR]).
2145
2146rarpaop_mg_service_change_request_msg(Mid, TransId, Cid) ->
2147    AR    = rarpaop_mg_service_change_request_ar(Mid, Cid),
2148    TR    = cre_transReq(TransId, [AR]),
2149    Trans = cre_transaction(TR),
2150    Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
2151    cre_megacoMessage(Mess).
2152
2153rarpaop_mg_ack_msg(Mid, TransId) ->
2154    TR    = cre_transRespAck(cre_transAck(TransId)),
2155    Trans = cre_transaction(TR),
2156    Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
2157    cre_megacoMessage(Mess).
2158
2159rarpaop_mg_notify_request_ar(Rid, Tid, Cid) ->
2160    TT      = cre_timeNotation("19990729", "22000000"),
2161    Ev      = cre_obsEvent("al/of", TT),
2162    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
2163    NR      = cre_notifyReq([Tid], EvsDesc),
2164    CMD     = cre_command(NR),
2165    CR      = cre_cmdReq(CMD),
2166    cre_actionReq(Cid, [CR]).
2167
2168rarpaop_mg_notify_request_msg(Mid, TransId, Rid, TermId, Cid) ->
2169    AR      = rarpaop_mg_notify_request_ar(Rid, TermId, Cid),
2170    TR      = cre_transReq(TransId, [AR]),
2171    Trans   = cre_transaction(TR),
2172    Mess    = cre_message(?VERSION, Mid, cre_transactions([Trans])),
2173    cre_megacoMessage(Mess).
2174
2175
2176%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2177
2178single_trans_req_and_reply(suite) ->
2179    [];
2180single_trans_req_and_reply(doc) ->
2181    ["Receive a (single) transaction request and then send a "
2182     "reply (discard ack). "
2183     "The MGC is a megaco instance (megaco event sequence) and the "
2184     "MG is emulated (tcp event sequence)"];
2185single_trans_req_and_reply(Config) when is_list(Config) ->
2186    Pre = fun() ->
2187                  MgcNode = make_node_name(mgc),
2188                  MgNode  = make_node_name(mg),
2189                  d("start nodes: "
2190                    "~n      MgcNode: ~p"
2191                    "~n      MgNode:  ~p",
2192                    [MgcNode, MgNode]),
2193                  Nodes = [MgcNode, MgNode],
2194                  ok = ?START_NODES(Nodes, true),
2195                  Nodes
2196          end,
2197    Case = fun do_single_trans_req_and_reply/1,
2198    Post = fun(Nodes) ->
2199                   d("stop nodes"),
2200                   ?STOP_NODES(lists:reverse(Nodes))
2201           end,
2202    try_tc(strar, Pre, Case, Post).
2203
2204do_single_trans_req_and_reply([MgcNode, MgNode]) ->
2205    d("[MGC] start the simulator "),
2206    {ok, Mgc} = megaco_test_megaco_generator:start_link("MGC", MgcNode),
2207
2208    d("[MGC] create the event sequence"),
2209    MgcEvSeq = strar_mgc_event_sequence(text, tcp),
2210
2211    i("wait some time before starting the MGC simulation"),
2212    sleep(1000),
2213
2214    d("[MGC] start the simulation"),
2215    {ok, MgcId} = megaco_test_megaco_generator:exec(Mgc, MgcEvSeq),
2216
2217    %% i("wait some time before starting the MG simulator"),
2218    %% sleep(1000),
2219
2220    i("await MGC ready announcement"),
2221    receive
2222        announce_mgc ->
2223            i("received MGC ready announcement"),
2224            ok
2225    end,
2226
2227    d("[MG] start the simulator (generator)"),
2228    {ok, Mg} = megaco_test_megaco_generator:start_link("MG", MgNode),
2229
2230    d("[MG] create the event sequence"),
2231    MgEvSeq = strar_mg_event_sequence(text, tcp),
2232
2233    i("wait some time before starting the MG simulation"),
2234    sleep(1000),
2235
2236    d("[MG] start the simulation"),
2237    {ok, MgId} = megaco_test_megaco_generator:exec(Mg, MgEvSeq),
2238
2239    d("await the generator reply(s)"),
2240    await_completion([MgcId, MgId], 30000),
2241
2242    %% Tell Mgc to stop
2243    i("[MGC] stop generator"),
2244    megaco_test_megaco_generator:stop(Mgc),
2245
2246    %% Tell Mg to stop
2247    i("[MG] stop generator"),
2248    megaco_test_megaco_generator:stop(Mg),
2249
2250    i("done", []),
2251    ok.
2252
2253
2254%%
2255%% MGC generator stuff
2256%%
2257-ifdef(megaco_hipe_special).
2258-define(strar_mgc_verify_handle_connect_fun(),
2259        {?MODULE, strar_mgc_verify_handle_connect, []}).
2260-define(strar_mgc_verify_service_change_req_fun(Mid),
2261        {?MODULE, strar_mgc_verify_service_change_req, [Mid]}).
2262-define(strar_mgc_verify_notify_req_fun(),
2263        {?MODULE, strar_mgc_verify_notify_request, []}).
2264-define(strar_mgc_verify_handle_disconnect_fun(),
2265        {?MODULE, strar_mgc_verify_handle_disconnect, []}).
2266-else.
2267-define(strar_mgc_verify_handle_connect_fun(),
2268        fun strar_mgc_verify_handle_connect/1).
2269-define(strar_mgc_verify_service_change_req_fun(Mid),
2270        strar_mgc_verify_service_change_req_fun(Mid)).
2271-define(strar_mgc_verify_notify_req_fun(),
2272	strar_mgc_verify_notify_request_fun()).
2273-define(strar_mgc_verify_handle_disconnect_fun(),
2274	fun strar_mgc_verify_handle_disconnect/1).
2275-endif.
2276
2277strar_mgc_event_sequence(text, tcp) ->
2278    CTRL = self(),
2279    Mid = {deviceName,"ctrl"},
2280    RI = [
2281	  {port,             2944},
2282	  {encoding_module,  megaco_pretty_text_encoder},
2283	  {encoding_config,  []},
2284	  {transport_module, megaco_tcp}
2285	 ],
2286    ConnectVerify          = ?strar_mgc_verify_handle_connect_fun(),
2287    ServiceChangeReqVerify = ?strar_mgc_verify_service_change_req_fun(Mid),
2288    NotifyReqVerify        = ?strar_mgc_verify_notify_req_fun(),
2289    DiscoVerify            = ?strar_mgc_verify_handle_disconnect_fun(),
2290    EvSeq = [
2291	     {debug, true},
2292	     {megaco_trace, disable},
2293	     megaco_start,
2294	     {megaco_start_user, Mid, RI, []},
2295	     start_transport,
2296	     listen,
2297
2298             %% ANNOUNCE READY
2299             {trigger, fun() -> CTRL ! announce_mgc end},
2300
2301	     {megaco_callback, handle_connect,       ConnectVerify},
2302	     {megaco_callback, handle_trans_request, ServiceChangeReqVerify},
2303	     {megaco_callback, handle_trans_request, NotifyReqVerify},
2304	     {megaco_callback, handle_disconnect,    DiscoVerify},
2305	     {sleep, 1000},
2306	     megaco_stop_user,
2307	     megaco_stop
2308	    ],
2309    EvSeq.
2310
2311
2312strar_mgc_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
2313    io:format("strar_mgc_verify_handle_connect -> ok"
2314	      "~n   CH: ~p~n", [CH]),
2315    {ok, CH, ok};
2316strar_mgc_verify_handle_connect(Else) ->
2317    io:format("strar_mgc_verify_handle_connect -> unknown"
2318	      "~n   Else: ~p~n", [Else]),
2319    {error, Else, ok}.
2320
2321-ifndef(megaco_hipe_special).
2322strar_mgc_verify_service_change_req_fun(Mid) ->
2323    fun(Req) ->
2324	    strar_mgc_verify_service_change_req(Req, Mid)
2325    end.
2326-endif.
2327
2328strar_mgc_verify_service_change_req(
2329  {handle_trans_request, _, ?VERSION, [AR]}, Mid) ->
2330    (catch strar_mgc_do_verify_service_change_req(AR, Mid));
2331strar_mgc_verify_service_change_req(Crap, _Mid) ->
2332    ED       = cre_ErrDesc(Crap),
2333    ErrReply = {discard_ack, ED},
2334    {error, Crap, ErrReply}.
2335
2336strar_mgc_do_verify_service_change_req(AR, Mid) ->
2337    io:format("strar_mgc_verify_service_change_req -> entry with"
2338	      "~n   AR:  ~p"
2339	      "~n   Mid: ~p"
2340	      "~n", [AR, Mid]),
2341    CR =
2342	case AR of
2343	    #'ActionRequest'{commandRequests = [CmdReq]} ->
2344		CmdReq;
2345	    _ ->
2346                Err1      = {invalid_action_request, AR},
2347                ED1       = cre_ErrDesc(AR),
2348                ErrReply1 = {discard_ack, ED1},
2349                throw({error, Err1, ErrReply1})
2350	end,
2351    Cmd =
2352        case CR of
2353            #'CommandRequest'{command = Command} ->
2354                Command;
2355            _ ->
2356                Err2      = {invalid_command_request, CR},
2357                ED2       = cre_ErrDesc(CR),
2358                ErrReply2 = {discard_ack, ED2},
2359                throw({error, Err2, ErrReply2})
2360        end,
2361    {Tid, Parms} =
2362        case Cmd of
2363            {serviceChangeReq,
2364             #'ServiceChangeRequest'{terminationID = [TermID],
2365                                     serviceChangeParms = ServChParms}} ->
2366                {TermID, ServChParms};
2367            _ ->
2368                Err3      = {invalid_command, Cmd},
2369                ED3       = cre_ErrDesc(Cmd),
2370                ErrReply3 = {discard_ack, ED3},
2371                throw({error, Err3, ErrReply3})
2372        end,
2373    case Tid of
2374        #megaco_term_id{contains_wildcards = false, id = ["root"]} ->
2375            ok;
2376        _ ->
2377            Err4      = {invalid_termination_id, Tid},
2378            ED4       = cre_ErrDesc(Tid),
2379            ErrReply4 = {discard_ack, ED4},
2380            throw({error, Err4, ErrReply4})
2381    end,
2382    case Parms of
2383        #'ServiceChangeParm'{serviceChangeMethod = restart,
2384                             serviceChangeReason = [[$9,$0,$1|_]]} ->
2385            AckData = [strar_mgc_service_change_reply_ar(Mid, 1)],
2386            Reply   = {discard_ack, AckData},
2387            {ok, AR, Reply};
2388        _ ->
2389            Err5      = {invalid_SCP, Parms},
2390            ED5       = cre_ErrDesc(Parms),
2391            ErrReply5 = {discard_ack, ED5},
2392            {error, Err5, ErrReply5}
2393    end.
2394
2395-ifndef(megaco_hipe_special).
2396strar_mgc_verify_notify_request_fun() ->
2397    fun(Req) ->
2398	    strar_mgc_verify_notify_request(Req)
2399    end.
2400-endif.
2401
2402strar_mgc_verify_notify_request({handle_trans_request, _, ?VERSION, [AR]}) ->
2403    (catch strar_mgc_do_verify_notify_request(AR));
2404strar_mgc_verify_notify_request(Crap) ->
2405    ED       = cre_ErrDesc(Crap),
2406    ErrReply = {discard_ack, ED},
2407    {error, Crap, ErrReply}.
2408
2409strar_mgc_do_verify_notify_request(AR) ->
2410    io:format("strar_mgc_do_verify_notify_request -> ok"
2411	      "~n   AR: ~p~n", [AR]),
2412    {Cid, CR} =
2413	case AR of
2414	    #'ActionRequest'{contextId       = CtxID,
2415			     commandRequests = [CmdReq]} when (CtxID == 1) or
2416							      (CtxID == 2) ->
2417		{CtxID, CmdReq};
2418	    _ ->
2419                Err1      = {invalid_action_request, AR},
2420                ED1       = cre_ErrDesc(AR),
2421                ErrReply1 = {discard_ack, ED1},
2422                throw({error, Err1, ErrReply1})
2423        end,
2424    Cmd =
2425	case CR of
2426	    #'CommandRequest'{command = Command} ->
2427		Command;
2428	    _ ->
2429                Err2      = {invalid_command_request, CR},
2430                ED2       = cre_ErrDesc(CR),
2431                ErrReply2 = {discard_ack, ED2},
2432                throw({error, Err2, ErrReply2})
2433        end,
2434    NR =
2435        case Cmd of
2436	    {notifyReq, NotifReq} ->
2437		NotifReq;
2438	    _ ->
2439                Err3      = {invalid_command, Cmd},
2440                ED3       = cre_ErrDesc(Cmd),
2441                ErrReply3 = {discard_ack, ED3},
2442                throw({error, Err3, ErrReply3})
2443        end,
2444    {Tid, OED} =
2445        case NR of
2446            #'NotifyRequest'{terminationID            = [TermID],
2447                             observedEventsDescriptor = ObsEvsDesc,
2448                             errorDescriptor          = asn1_NOVALUE} ->
2449                {TermID, ObsEvsDesc};
2450            _ ->
2451                Err4      = {invalid_NR, NR},
2452                ED4       = cre_ErrDesc(NR),
2453                ErrReply4 = {discard_ack, ED4},
2454                throw({error, Err4, ErrReply4})
2455        end,
2456    OE =
2457	case OED of
2458	    #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
2459		ObsEvLst;
2460            _ ->
2461                Err5      = {invalid_OED, OED},
2462                ED5       = cre_ErrDesc(NR),
2463                ErrReply5 = {discard_ack, ED5},
2464                throw({error, Err5, ErrReply5})
2465        end,
2466    case OE of
2467	#'ObservedEvent'{eventName = "al/of"} ->
2468            Replies = [strar_mgc_notify_reply_ar(Cid, Tid)],
2469            Reply   = {discard_ack, Replies},
2470            {ok, AR, Reply};
2471        _ ->
2472            Err6      = {invalid_OE, OE},
2473            ED6       = cre_ErrDesc(OE),
2474            ErrReply6 = {discard_ack, ED6},
2475            {error, Err6, ErrReply6}
2476    end.
2477
2478strar_mgc_verify_handle_disconnect({handle_disconnect, CH, ?VERSION, R}) ->
2479    io:format("strar_mgc_verify_handle_disconnect -> ok"
2480	      "~n   CH: ~p"
2481	      "~n   R:  ~p"
2482	      "~n", [CH, R]),
2483    {ok, CH, ok};
2484strar_mgc_verify_handle_disconnect(Else) ->
2485    io:format("strar_mgc_verify_handle_disconnect -> unknown"
2486	      "~n   Else: ~p~n", [Else]),
2487    {error, Else, ok}.
2488
2489
2490strar_mgc_service_change_reply_ar(Mid, Cid) ->
2491    SCRP  = cre_serviceChangeResParm(Mid),
2492    SCRes = cre_serviceChangeResult(SCRP),
2493    Root  = #megaco_term_id{id = ["root"]},
2494    SCR   = cre_serviceChangeReply([Root], SCRes),
2495    CR    = cre_cmdReply(SCR),
2496    cre_actionReply(Cid, [CR]).
2497
2498strar_mgc_notify_reply_ar(Cid, TermId) ->
2499    NR    = cre_notifyReply([TermId]),
2500    CR    = cre_cmdReply(NR),
2501    cre_actionReply(Cid, [CR]).
2502
2503%% strar_mgc_notify_reply(Mid, TransId, Cid, TermId) ->
2504%%     AR    = strar_mgc_notify_reply_ar(Cid, TermId),
2505%%     TRes  = cre_transResult([AR]),
2506%%     TR    = cre_transReply(TransId, TRes),
2507%%     Trans = cre_transaction(TR),
2508%%     Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
2509%%     cre_megacoMessage(Mess).
2510
2511
2512%%
2513%% MG generator stuff
2514%%
2515-ifdef(megaco_hipe_special).
2516-define(strar_mg_verify_handle_connect_fun(),
2517	{?MODULE, strar_mg_verify_handle_connect, []}).
2518-define(strar_mg_verify_service_change_reply_fun(),
2519	{?MODULE, strar_mg_verify_service_change_reply, []}).
2520-define(strar_mg_verify_notify_reply_fun(),
2521	{?MODULE, strar_mg_verify_notify_reply, []}).
2522-else.
2523-define(strar_mg_verify_handle_connect_fun(),
2524	strar_mg_verify_handle_connect_fun()).
2525-define(strar_mg_verify_service_change_reply_fun(),
2526	strar_mg_verify_service_change_reply_fun()).
2527-define(strar_mg_verify_notify_reply_fun(),
2528	strar_mg_verify_notify_reply_fun()).
2529-endif.
2530
2531strar_mg_event_sequence(text, tcp) ->
2532    Mid = {deviceName, "mg"},
2533    RI = [
2534	  {port,             2944},
2535	  {encoding_module,  megaco_pretty_text_encoder},
2536	  {encoding_config,  []},
2537	  {transport_module, megaco_tcp}
2538	 ],
2539    ServiceChangeReq = [strar_mg_service_change_request_ar(Mid, 1)],
2540    Tid = #megaco_term_id{id = ["00000000","00000000","01101101"]},
2541    NR = fun(Cid, Rid) ->
2542		 [strar_mg_notify_request_ar(Rid, Tid, Cid)]
2543	 end,
2544    ConnectVerify            = ?strar_mg_verify_handle_connect_fun(),
2545    ServiceChangeReplyVerify = ?strar_mg_verify_service_change_reply_fun(),
2546    NotifyReplyVerify        = ?strar_mg_verify_notify_reply_fun(),
2547    EvSeq = [
2548	     {debug, true},
2549	     megaco_start,
2550	     {megaco_start_user, Mid, RI, []},
2551	     start_transport,
2552	     {megaco_trace, disable},
2553	     {megaco_system_info, users},
2554	     {megaco_system_info, connections},
2555	     connect,
2556	     {megaco_callback, handle_connect, ConnectVerify},
2557	     megaco_connect,
2558	     {megaco_cast, ServiceChangeReq, []},
2559	     {megaco_callback, handle_connect, ConnectVerify},
2560	     {megaco_callback, handle_trans_reply, ServiceChangeReplyVerify},
2561	     {sleep, 1000},
2562	     {megaco_system_info, users},
2563	     {megaco_system_info, connections},
2564	     {sleep, 1000},
2565	     {megaco_conn_info, all},
2566	     {megaco_cast, NR(1,1), []},
2567	     {megaco_callback, handle_trans_reply, NotifyReplyVerify},
2568	     {sleep, 3000},
2569	     megaco_stop_user,
2570	     megaco_stop,
2571	     {sleep, 1000}
2572	    ],
2573    EvSeq.
2574
2575-ifndef(megaco_hipe_special).
2576strar_mg_verify_handle_connect_fun() ->
2577    fun(Ev) ->
2578	    strar_mg_verify_handle_connect(Ev)
2579    end.
2580-endif.
2581
2582strar_mg_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
2583    io:format("strar_mg_verify_handle_connect -> ok"
2584	      "~n   CH: ~p~n", [CH]),
2585    {ok, CH, ok};
2586strar_mg_verify_handle_connect(Else) ->
2587    io:format("strar_mg_verify_handle_connect -> unknown"
2588	      "~n   Else: ~p~n", [Else]),
2589    {error, Else, ok}.
2590
2591-ifndef(megaco_hipe_special).
2592strar_mg_verify_service_change_reply_fun() ->
2593    fun(Rep) ->
2594	    strar_mg_verify_service_change_reply(Rep)
2595    end.
2596-endif.
2597
2598strar_mg_verify_service_change_reply(
2599  {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _}) ->
2600    (catch strar_mg_do_verify_service_change_reply(AR));
2601strar_mg_verify_service_change_reply(Crap) ->
2602    {error, Crap, ok}.
2603
2604strar_mg_do_verify_service_change_reply(AR) ->
2605    io:format("strar_mg_verify_service_change_reply -> ok"
2606	      "~n   AR: ~p~n", [AR]),
2607    CR =
2608	case AR of
2609	    #'ActionReply'{commandReply = [CmdRep]} ->
2610		CmdRep;
2611	    _ ->
2612		Reason1 = {invalid_action_reply, AR},
2613		throw({error, Reason1, ok})
2614	end,
2615    SCR =
2616	case CR of
2617	    {serviceChangeReply, ServChRep} ->
2618		ServChRep;
2619	    _ ->
2620		Reason2 = {invalid_command_reply, CR},
2621		throw({error, Reason2, ok})
2622	end,
2623    {Tid, SCRes} =
2624	case SCR of
2625	    #'ServiceChangeReply'{terminationID       = [TermID],
2626				  serviceChangeResult = Res} ->
2627		{TermID, Res};
2628	    _ ->
2629		Reason3 = {invalid_service_change_reply, SCR},
2630		throw({error, Reason3, ok})
2631	end,
2632    case Tid of
2633	#megaco_term_id{contains_wildcards = false, id = ["root"]} ->
2634	    ok;
2635	_ ->
2636	    Reason4 = {invalid_termination_id, Tid},
2637	    throw({error, Reason4, ok})
2638    end,
2639    SCRParm =
2640	case SCRes of
2641	    {serviceChangeResParms, ServChResParms} ->
2642		ServChResParms;
2643	    _ ->
2644		Reason5 = {invalid_serviceChangeResult, SCRes},
2645		throw({error, Reason5, ok})
2646	end,
2647    case SCRParm of
2648	#'ServiceChangeResParm'{serviceChangeMgcId = _RemoteMid} ->
2649	    {ok, AR, ok};
2650	_ ->
2651	    Reason6 = {invalid_service_change_result, SCRParm},
2652	    {error, Reason6, ok}
2653    end.
2654
2655-ifndef(megaco_hipe_special).
2656strar_mg_verify_notify_reply_fun() ->
2657    fun(Rep) ->
2658	    strar_mg_verify_notify_reply(Rep)
2659    end.
2660-endif.
2661
2662strar_mg_verify_notify_reply({handle_trans_reply, _CH, ?VERSION,
2663			      {ok, [AR]}, _}) ->
2664    io:format("strar_mg_verify_notify_reply -> ok"
2665	      "~n   AR: ~p~n", [AR]),
2666    {ok, AR, ok};
2667strar_mg_verify_notify_reply(Else) ->
2668    io:format("strar_mg_verify_notify_reply -> unknown"
2669	      "~n   Else: ~p~n", [Else]),
2670    {error, Else, ok}.
2671
2672strar_mg_service_change_request_ar(_Mid, Cid) ->
2673    Prof  = cre_serviceChangeProf("resgw", 1),
2674    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
2675    Root  = #megaco_term_id{id = ["root"]},
2676    SCR   = cre_serviceChangeReq([Root], SCP),
2677    CMD   = cre_command(SCR),
2678    CR    = cre_cmdReq(CMD),
2679    cre_actionReq(Cid, [CR]).
2680
2681strar_mg_notify_request_ar(Rid, Tid, Cid) ->
2682    TT      = cre_timeNotation("19990729", "22000000"),
2683    Ev      = cre_obsEvent("al/of", TT),
2684    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
2685    NR      = cre_notifyReq([Tid], EvsDesc),
2686    CMD     = cre_command(NR),
2687    CR      = cre_cmdReq(CMD),
2688    cre_actionReq(Cid, [CR]).
2689
2690
2691%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2692
2693single_trans_req_and_reply_sendopts(suite) ->
2694    [];
2695single_trans_req_and_reply_sendopts(doc) ->
2696    ["Receive a (single) transaction request and then send a "
2697     "reply with handle_ack and a reply_timer in sendoptions. "
2698     "The MGC is a megaco instance (megaco event sequence) and the "
2699     "MG is emulated (tcp event sequence)"];
2700single_trans_req_and_reply_sendopts(Config) when is_list(Config) ->
2701    Pre = fun() ->
2702                  %% <CONDITIONAL-SKIP>
2703                  Skippable = [{unix, [darwin, linux]}],
2704                  Condition = fun() -> ?OS_BASED_SKIP(Skippable) end,
2705                  ?NON_PC_TC_MAYBE_SKIP(Config, Condition),
2706                  %% </CONDITIONAL-SKIP>
2707
2708                  MgcNode = make_node_name(mgc),
2709                  MgNode  = make_node_name(mg),
2710                  d("start nodes: "
2711                    "~n      MgcNode: ~p"
2712                    "~n      MgNode:  ~p",
2713                    [MgcNode, MgNode]),
2714                  Nodes = [MgcNode, MgNode],
2715                  ok = ?START_NODES(Nodes, true),
2716                  Nodes
2717          end,
2718    Case = fun do_single_trans_req_and_reply_sendopts/1,
2719    Post = fun(Nodes) ->
2720                   d("stop nodes"),
2721                   ?STOP_NODES(lists:reverse(Nodes))
2722           end,
2723    try_tc(straro, Pre, Case, Post).
2724
2725do_single_trans_req_and_reply_sendopts([MgcNode, MgNode]) ->
2726    d("[MGC] start the simulator "),
2727    {ok, Mgc} = megaco_test_megaco_generator:start_link("MGC", MgcNode),
2728
2729    d("[MGC] create the event sequence"),
2730    MgcEvSeq = straro_mgc_event_sequence(text, tcp),
2731
2732    i("wait some time before starting the MGC simulation"),
2733    sleep(1000),
2734
2735    d("[MGC] start the simulation"),
2736    {ok, MgcId} = megaco_test_megaco_generator:exec(Mgc, MgcEvSeq),
2737
2738    %% i("wait some time before starting the MG simulator"),
2739    %% sleep(1000),
2740
2741    i("await MGC ready announcement"),
2742    receive
2743        announce_mgc ->
2744            i("received MGC ready announcement"),
2745            ok
2746    end,
2747
2748    d("[MG] start the simulator (generator)"),
2749    {ok, Mg} = megaco_test_megaco_generator:start_link("MG", MgNode),
2750
2751    d("[MG] create the event sequence"),
2752    MgEvSeq = straro_mg_event_sequence(text, tcp),
2753
2754    i("wait some time before starting the MG simulation"),
2755    sleep(1000),
2756
2757    d("[MG] start the simulation"),
2758    {ok, MgId} = megaco_test_megaco_generator:exec(Mg, MgEvSeq),
2759
2760    d("await the generator reply(s)"),
2761    await_completion([MgcId, MgId], 30000),
2762
2763    %% Tell Mgc to stop
2764    i("[MGC] stop generator"),
2765    megaco_test_megaco_generator:stop(Mgc),
2766
2767    %% Tell Mg to stop
2768    i("[MG] stop generator"),
2769    megaco_test_megaco_generator:stop(Mg),
2770
2771    i("done", []),
2772    ok.
2773
2774
2775%%
2776%% MGC generator stuff
2777%%
2778-ifdef(megaco_hipe_special).
2779-define(straro_mgc_verify_handle_connect_fun(),
2780        {?MODULE, straro_mgc_verify_handle_connect, []}).
2781-define(straro_mgc_verify_service_change_req_fun(Mid),
2782        {?MODULE, straro_mgc_verify_service_change_req, [Mid]}).
2783-define(straro_mgc_verify_notify_req_fun(),
2784        {?MODULE, straro_mgc_verify_notify_request, []}).
2785-define(straro_mgc_verify_handle_trans_ack_fun(),
2786        {?MODULE, straro_mgc_verify_handle_trans_ack, []}).
2787-else.
2788-define(straro_mgc_verify_handle_connect_fun(),
2789        fun straro_mgc_verify_handle_connect/1).
2790-define(straro_mgc_verify_service_change_req_fun(Mid),
2791        straro_mgc_verify_service_change_req_fun(Mid)).
2792-define(straro_mgc_verify_notify_req_fun(),
2793	straro_mgc_verify_notify_request_fun()).
2794-define(straro_mgc_verify_handle_trans_ack_fun(),
2795	straro_mgc_verify_handle_trans_ack_fun()).
2796-endif.
2797
2798straro_mgc_event_sequence(text, tcp) ->
2799    CTRL = self(),
2800    Mid = {deviceName,"ctrl"},
2801    RI = [
2802	  {port,             2944},
2803	  {encoding_module,  megaco_pretty_text_encoder},
2804	  {encoding_config,  []},
2805	  {transport_module, megaco_tcp}
2806	 ],
2807    ConnectVerify          = ?straro_mgc_verify_handle_connect_fun(),
2808    ServiceChangeReqVerify = ?straro_mgc_verify_service_change_req_fun(Mid),
2809    NotifyReqVerify        = ?straro_mgc_verify_notify_req_fun(),
2810    TransAckVerify         = ?straro_mgc_verify_handle_trans_ack_fun(),
2811    EvSeq = [
2812	     {debug, true},
2813	     {megaco_trace, disable},
2814	     megaco_start,
2815	     {megaco_start_user, Mid, RI, []},
2816	     start_transport,
2817	     listen,
2818
2819             %% ANNOUNCE READY
2820             {trigger, fun() -> CTRL ! announce_mgc end},
2821
2822	     {megaco_callback, handle_connect,       ConnectVerify},
2823	     {megaco_callback, handle_trans_request, ServiceChangeReqVerify},
2824	     {megaco_callback, handle_trans_request, NotifyReqVerify},
2825	     {megaco_callback, handle_trans_ack,     TransAckVerify},
2826	     megaco_stop_user,
2827	     megaco_stop
2828	    ],
2829    EvSeq.
2830
2831
2832straro_mgc_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
2833    io:format("straro_mgc_verify_handle_connect -> ok"
2834	      "~n   CH: ~p~n", [CH]),
2835    {ok, CH, ok};
2836straro_mgc_verify_handle_connect(Else) ->
2837    io:format("straro_mgc_verify_handle_connect -> unknown"
2838	      "~n   Else: ~p~n", [Else]),
2839    {error, Else, ok}.
2840
2841-ifndef(megaco_hipe_special).
2842straro_mgc_verify_service_change_req_fun(Mid) ->
2843    fun(Req) ->
2844	    straro_mgc_verify_service_change_req(Req, Mid)
2845    end.
2846-endif.
2847
2848straro_mgc_verify_service_change_req(
2849  {handle_trans_request, _, ?VERSION, [AR]}, Mid) ->
2850    (catch straro_mgc_do_verify_service_change_req(AR, Mid));
2851straro_mgc_verify_service_change_req(Crap, _Mid) ->
2852    ED       = cre_ErrDesc(Crap),
2853    ErrReply = {discard_ack, ED},
2854    {error, Crap, ErrReply}.
2855
2856straro_mgc_do_verify_service_change_req(AR, Mid) ->
2857    io:format("straro_mgc_do_verify_service_change_req -> ok"
2858	      "~n   AR: ~p~n", [AR]),
2859    CR =
2860	case AR of
2861	    #'ActionRequest'{commandRequests = [CmdReq]} ->
2862		CmdReq;
2863	    _ ->
2864                Err1      = {invalid_action_request, AR},
2865                ED1       = cre_ErrDesc(AR),
2866                ErrReply1 = {discard_ack, ED1},
2867                throw({error, Err1, ErrReply1})
2868	end,
2869    Cmd =
2870        case CR of
2871            #'CommandRequest'{command = Command} ->
2872                Command;
2873            _ ->
2874                Err2      = {invalid_command_request, CR},
2875                ED2       = cre_ErrDesc(CR),
2876                ErrReply2 = {discard_ack, ED2},
2877                throw({error, Err2, ErrReply2})
2878        end,
2879    {Tid, Parms} =
2880        case Cmd of
2881            {serviceChangeReq,
2882             #'ServiceChangeRequest'{terminationID = [TermID],
2883                                     serviceChangeParms = ServChParms}} ->
2884                {TermID, ServChParms};
2885            _ ->
2886                Err3      = {invalid_command, Cmd},
2887                ED3       = cre_ErrDesc(Cmd),
2888                ErrReply3 = {discard_ack, ED3},
2889                throw({error, Err3, ErrReply3})
2890        end,
2891    case Tid of
2892        #megaco_term_id{contains_wildcards = false, id = ["root"]} ->
2893            ok;
2894        _ ->
2895            Err4      = {invalid_termination_id, Tid},
2896            ED4       = cre_ErrDesc(Tid),
2897            ErrReply4 = {discard_ack, ED4},
2898            throw({error, Err4, ErrReply4})
2899    end,
2900    case Parms of
2901        #'ServiceChangeParm'{serviceChangeMethod = restart,
2902                             serviceChangeReason = [[$9,$0,$1|_]]} ->
2903            AckData = [straro_mgc_service_change_reply_ar(Mid, 1)],
2904            Reply   = {discard_ack, AckData},
2905            {ok, AR, Reply};
2906        _ ->
2907            Err5      = {invalid_SCP, Parms},
2908            ED5       = cre_ErrDesc(Parms),
2909            ErrReply5 = {discard_ack, ED5},
2910            {error, Err5, ErrReply5}
2911    end.
2912
2913-ifndef(megaco_hipe_special).
2914straro_mgc_verify_notify_request_fun() ->
2915    fun(Req) ->
2916	    straro_mgc_verify_notify_request(Req)
2917    end.
2918-endif.
2919
2920straro_mgc_verify_notify_request({handle_trans_request, _, ?VERSION, [AR]}) ->
2921    (catch straro_mgc_do_verify_notify_request(AR));
2922straro_mgc_verify_notify_request(Crap) ->
2923    ED       = cre_ErrDesc(Crap),
2924    ErrReply = {discard_ack, ED},
2925    {error, Crap, ErrReply}.
2926
2927straro_mgc_do_verify_notify_request(AR) ->
2928    io:format("straro_mgc_do_verify_notify_request -> ok"
2929	      "~n   AR: ~p~n", [AR]),
2930    {Cid, CR} =
2931	case AR of
2932	    #'ActionRequest'{contextId       = CtxID,
2933			     commandRequests = [CmdReq]} when (CtxID == 1) or
2934							      (CtxID == 2) ->
2935		{CtxID, CmdReq};
2936	    _ ->
2937                Err1      = {invalid_action_request, AR},
2938                ED1       = cre_ErrDesc(AR),
2939                ErrReply1 = {discard_ack, ED1},
2940                throw({error, Err1, ErrReply1})
2941        end,
2942    Cmd =
2943	case CR of
2944	    #'CommandRequest'{command = Command} ->
2945		Command;
2946	    _ ->
2947                Err2      = {invalid_command_request, CR},
2948                ED2       = cre_ErrDesc(CR),
2949                ErrReply2 = {discard_ack, ED2},
2950                throw({error, Err2, ErrReply2})
2951        end,
2952    NR =
2953        case Cmd of
2954	    {notifyReq, NotifReq} ->
2955		NotifReq;
2956	    _ ->
2957                Err3      = {invalid_command, Cmd},
2958                ED3       = cre_ErrDesc(Cmd),
2959                ErrReply3 = {discard_ack, ED3},
2960                throw({error, Err3, ErrReply3})
2961        end,
2962    {Tid, OED} =
2963        case NR of
2964            #'NotifyRequest'{terminationID            = [TermID],
2965                             observedEventsDescriptor = ObsEvsDesc,
2966                             errorDescriptor          = asn1_NOVALUE} ->
2967                {TermID, ObsEvsDesc};
2968            _ ->
2969                Err4      = {invalid_NR, NR},
2970                ED4       = cre_ErrDesc(NR),
2971                ErrReply4 = {discard_ack, ED4},
2972                throw({error, Err4, ErrReply4})
2973        end,
2974    OE =
2975	case OED of
2976	    #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
2977		ObsEvLst;
2978            _ ->
2979                Err5      = {invalid_OED, OED},
2980                ED5       = cre_ErrDesc(NR),
2981                ErrReply5 = {discard_ack, ED5},
2982                throw({error, Err5, ErrReply5})
2983        end,
2984    case OE of
2985	#'ObservedEvent'{eventName = "al/of"} ->
2986            Replies = [straro_mgc_notify_reply_ar(Cid, Tid)],
2987	    SendOpts = [{protocol_version, 99}],
2988            Reply   = {{handle_ack, get(tc)}, Replies, SendOpts},
2989            {ok, AR, Reply};
2990        _ ->
2991            Err6      = {invalid_OE, OE},
2992            ED6       = cre_ErrDesc(OE),
2993            ErrReply6 = {discard_ack, ED6},
2994            {error, Err6, ErrReply6}
2995    end.
2996
2997-ifndef(megaco_hipe_special).
2998straro_mgc_verify_handle_trans_ack_fun() ->
2999    fun(Ack) ->
3000	    straro_mgc_verify_handle_trans_ack(Ack)
3001    end.
3002-endif.
3003
3004straro_mgc_verify_handle_trans_ack(
3005  {handle_trans_ack, _CH, ?VERSION, AS, _AD}) ->
3006    (catch straro_mgc_do_verify_handle_trans_ack(AS));
3007straro_mgc_verify_handle_trans_ack(Crap) ->
3008    io:format("straro_mgc_verify_handle_trans_ack -> entry with"
3009	      "~n   Crap: ~p"
3010	      "~n", [Crap]),
3011    {error, Crap, ok}.
3012
3013straro_mgc_do_verify_handle_trans_ack({error, {EM, EF, [EC, Version, Msg], Reason}}) ->
3014    io:format("straro_mgc_do_handle_verify_handle_trans_ack -> entry with"
3015	      "~n   EM:      ~p"
3016	      "~n   EF:      ~p"
3017	      "~n   EC:      ~p"
3018	      "~n   Version: ~p"
3019	      "~n   Msg:     ~p"
3020	      "~n   Reason:  ~p"
3021	      "~n", [EM, EF, EC, Version, Msg, Reason]),
3022    case Reason of
3023	{bad_version, 99} ->
3024	    {ok, Reason, ok};
3025	_ ->
3026	    {error, {unexpected_reason, Reason}, ok}
3027    end;
3028straro_mgc_do_verify_handle_trans_ack(Else) ->
3029    io:format("straro_mgc_verify_handle_trans_ack -> unknown"
3030	      "~n   Else: ~p"
3031	      "~n", [Else]),
3032    {error, Else, ok}.
3033
3034%% straro_mgc_verify_handle_disconnect({handle_disconnect, CH, ?VERSION, R}) ->
3035%%     io:format("straro_mgc_verify_handle_disconnect -> ok"
3036%% 	      "~n   CH: ~p"
3037%% 	      "~n   R:  ~p"
3038%% 	      "~n", [CH, R]),
3039%%     {ok, CH, ok};
3040%% straro_mgc_verify_handle_disconnect(Else) ->
3041%%     io:format("straro_mgc_verify_handle_disconnect -> unknown"
3042%% 	      "~n   Else: ~p~n", [Else]),
3043%%     {error, Else, ok}.
3044
3045
3046straro_mgc_service_change_reply_ar(Mid, Cid) ->
3047    SCRP  = cre_serviceChangeResParm(Mid),
3048    SCRes = cre_serviceChangeResult(SCRP),
3049    Root  = #megaco_term_id{id = ["root"]},
3050    SCR   = cre_serviceChangeReply([Root], SCRes),
3051    CR    = cre_cmdReply(SCR),
3052    cre_actionReply(Cid, [CR]).
3053
3054straro_mgc_notify_reply_ar(Cid, TermId) ->
3055    NR    = cre_notifyReply([TermId]),
3056    CR    = cre_cmdReply(NR),
3057    cre_actionReply(Cid, [CR]).
3058
3059%% straro_mgc_notify_reply(Mid, TransId, Cid, TermId) ->
3060%%     AR    = straro_mgc_notify_reply_ar(Cid, TermId),
3061%%     TRes  = cre_transResult([AR]),
3062%%     TR    = cre_transReply(TransId, TRes),
3063%%     Trans = cre_transaction(TR),
3064%%     Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
3065%%     cre_megacoMessage(Mess).
3066
3067
3068%%
3069%% MG generator stuff
3070%%
3071-ifdef(megaco_hipe_special).
3072-define(straro_mg_verify_handle_connect_fun(),
3073	{?MODULE, straro_mg_verify_handle_connect, []}).
3074-define(straro_mg_verify_service_change_reply_fun(),
3075	{?MODULE, straro_mg_verify_service_change_reply, []}).
3076-define(straro_mg_verify_handle_disconnect_fun(),
3077	{?MODULE, straro_mg_verify_handle_disconnect, []}).
3078-else.
3079-define(straro_mg_verify_handle_connect_fun(),
3080	straro_mg_verify_handle_connect_fun()).
3081-define(straro_mg_verify_service_change_reply_fun(),
3082	straro_mg_verify_service_change_reply_fun()).
3083-define(straro_mg_verify_handle_disconnect_fun(),
3084	fun straro_mg_verify_handle_disconnect/1).
3085-endif.
3086
3087straro_mg_event_sequence(text, tcp) ->
3088    Mid = {deviceName, "mg"},
3089    RI = [
3090	  {port,             2944},
3091	  {encoding_module,  megaco_pretty_text_encoder},
3092	  {encoding_config,  []},
3093	  {transport_module, megaco_tcp}
3094	 ],
3095    ServiceChangeReq = [straro_mg_service_change_request_ar(Mid, 1)],
3096    Tid = #megaco_term_id{id = ["00000000","00000000","01101101"]},
3097    NR = fun(Cid, Rid) ->
3098		 [straro_mg_notify_request_ar(Rid, Tid, Cid)]
3099	 end,
3100    ConnectVerify            = ?straro_mg_verify_handle_connect_fun(),
3101    ServiceChangeReplyVerify = ?straro_mg_verify_service_change_reply_fun(),
3102    DiscoVerify              = ?straro_mg_verify_handle_disconnect_fun(),
3103%%     ConnectVerify            = straro_mg_verify_handle_connect_fun(),
3104%%     DiscoVerify              = fun straro_mg_verify_handle_disconnect/1,
3105%%     ServiceChangeReplyVerify = straro_mg_verify_service_change_reply_fun(),
3106    EvSeq = [
3107	     {debug, true},
3108	     megaco_start,
3109	     {megaco_start_user, Mid, RI, []},
3110	     start_transport,
3111	     {megaco_trace, disable},
3112	     {megaco_system_info, users},
3113	     {megaco_system_info, connections},
3114	     connect,
3115	     {megaco_callback, handle_connect, ConnectVerify},
3116	     megaco_connect,
3117	     {megaco_cast, ServiceChangeReq, []},
3118	     {megaco_callback, handle_connect, ConnectVerify},
3119	     {megaco_callback, handle_trans_reply, ServiceChangeReplyVerify},
3120	     {sleep, 1000},
3121	     {megaco_system_info, users},
3122	     {megaco_system_info, connections},
3123	     {sleep, 1000},
3124	     {megaco_conn_info, all},
3125	     {megaco_cast, NR(1,1), []},
3126	     {megaco_callback, handle_disconnect, DiscoVerify},
3127	     megaco_stop_user,
3128	     megaco_stop,
3129	     {sleep, 1000}
3130	    ],
3131    EvSeq.
3132
3133-ifndef(megaco_hipe_special).
3134straro_mg_verify_handle_connect_fun() ->
3135    fun(Ev) ->
3136	    straro_mg_verify_handle_connect(Ev)
3137    end.
3138-endif.
3139
3140straro_mg_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
3141    io:format("straro_mg_verify_handle_connect -> ok"
3142	      "~n   CH: ~p~n", [CH]),
3143    {ok, CH, ok};
3144straro_mg_verify_handle_connect(Else) ->
3145    io:format("straro_mg_verify_handle_connect -> unknown"
3146	      "~n   Else: ~p~n", [Else]),
3147    {error, Else, ok}.
3148
3149straro_mg_verify_handle_disconnect({handle_disconnect, CH, ?VERSION, R}) ->
3150    io:format("straro_mg_verify_handle_disconnect -> ok"
3151	      "~n   CH: ~p"
3152	      "~n   R:  ~p"
3153	      "~n", [CH, R]),
3154    {ok, CH, ok};
3155straro_mg_verify_handle_disconnect(Else) ->
3156    io:format("straro_mg_verify_handle_disconnect -> unknown"
3157	      "~n   Else: ~p~n", [Else]),
3158    {error, Else, ok}.
3159
3160
3161-ifndef(megaco_hipe_special).
3162straro_mg_verify_service_change_reply_fun() ->
3163    fun(Rep) ->
3164	    straro_mg_verify_service_change_reply(Rep)
3165    end.
3166-endif.
3167
3168straro_mg_verify_service_change_reply(
3169  {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _}) ->
3170    (catch straro_mg_do_verify_service_change_reply(AR));
3171straro_mg_verify_service_change_reply(Crap) ->
3172    {error, Crap, ok}.
3173
3174straro_mg_do_verify_service_change_reply(AR) ->
3175    io:format("straro_mg_verify_service_change_reply -> ok"
3176	      "~n   AR: ~p~n", [AR]),
3177    CR =
3178	case AR of
3179	    #'ActionReply'{commandReply = [CmdRep]} ->
3180		CmdRep;
3181	    _ ->
3182		Reason1 = {invalid_action_reply, AR},
3183		throw({error, Reason1, ok})
3184	end,
3185    SCR =
3186	case CR of
3187	    {serviceChangeReply, ServChRep} ->
3188		ServChRep;
3189	    _ ->
3190		Reason2 = {invalid_command_reply, CR},
3191		throw({error, Reason2, ok})
3192	end,
3193    {Tid, SCRes} =
3194	case SCR of
3195	    #'ServiceChangeReply'{terminationID       = [TermID],
3196				  serviceChangeResult = Res} ->
3197		{TermID, Res};
3198	    _ ->
3199		Reason3 = {invalid_service_change_reply, SCR},
3200		throw({error, Reason3, ok})
3201	end,
3202    case Tid of
3203	#megaco_term_id{contains_wildcards = false, id = ["root"]} ->
3204	    ok;
3205	_ ->
3206	    Reason4 = {invalid_termination_id, Tid},
3207	    throw({error, Reason4, ok})
3208    end,
3209    SCRParm =
3210	case SCRes of
3211	    {serviceChangeResParms, ServChResParms} ->
3212		ServChResParms;
3213	    _ ->
3214		Reason5 = {invalid_serviceChangeResult, SCRes},
3215		throw({error, Reason5, ok})
3216	end,
3217    case SCRParm of
3218	#'ServiceChangeResParm'{serviceChangeMgcId = _RemoteMid} ->
3219	    {ok, AR, ok};
3220	_ ->
3221	    Reason6 = {invalid_service_change_result, SCRParm},
3222	    {error, Reason6, ok}
3223    end.
3224
3225%% -ifndef(megaco_hipe_special).
3226%% straro_mg_verify_notify_reply_fun() ->
3227%%     fun(Rep) ->
3228%% 	    straro_mg_verify_notify_reply(Rep)
3229%%     end.
3230%% -endif.
3231
3232%% straro_mg_verify_notify_reply({handle_trans_reply, _CH, ?VERSION,
3233%% 			      {ok, [AR]}, _}) ->
3234%%     io:format("straro_mg_verify_notify_reply -> ok"
3235%% 	      "~n   AR: ~p~n", [AR]),
3236%%     {ok, AR, ok};
3237%% straro_mg_verify_notify_reply(Else) ->
3238%%     io:format("straro_mg_verify_notify_reply -> unknown"
3239%% 	      "~n   Else: ~p~n", [Else]),
3240%%     {error, Else, ok}.
3241
3242straro_mg_service_change_request_ar(_Mid, Cid) ->
3243    Prof  = cre_serviceChangeProf("resgw", 1),
3244    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
3245    Root  = #megaco_term_id{id = ["root"]},
3246    SCR   = cre_serviceChangeReq([Root], SCP),
3247    CMD   = cre_command(SCR),
3248    CR    = cre_cmdReq(CMD),
3249    cre_actionReq(Cid, [CR]).
3250
3251straro_mg_notify_request_ar(Rid, Tid, Cid) ->
3252    TT      = cre_timeNotation("19990729", "22000000"),
3253    Ev      = cre_obsEvent("al/of", TT),
3254    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
3255    NR      = cre_notifyReq([Tid], EvsDesc),
3256    CMD     = cre_command(NR),
3257    CR      = cre_cmdReq(CMD),
3258    cre_actionReq(Cid, [CR]).
3259
3260
3261%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3262
3263request_and_reply_and_ack(suite) ->
3264    [];
3265request_and_reply_and_ack(doc) ->
3266    ["This test case tests that megaco correctly handles three-way-handshake"];
3267request_and_reply_and_ack(Config) when is_list(Config) ->
3268    Pre = fun() ->
3269                  MgcNode = make_node_name(mgc),
3270                  MgNode  = make_node_name(mg),
3271                  d("start nodes: "
3272                    "~n   MgcNode: ~p"
3273                    "~n   MgNode:  ~p",
3274                    [MgcNode, MgNode]),
3275                  Nodes = [MgcNode, MgNode],
3276                  ok = ?START_NODES(Nodes, true),
3277                  Nodes
3278          end,
3279    Case = fun do_request_and_reply_and_ack/1,
3280    Post = fun(Nodes) ->
3281                   d("stop nodes"),
3282                   ?STOP_NODES(lists:reverse(Nodes))
3283           end,
3284    try_tc(raraa, Pre, Case, Post).
3285
3286do_request_and_reply_and_ack([MgcNode, MgNode]) ->
3287    d("[MGC] start the simulator "),
3288    {ok, Mgc} = megaco_test_megaco_generator:start_link("MGC", MgcNode),
3289
3290    d("[MGC] create the event sequence"),
3291    MgcEvSeq = raraa_mgc_event_sequence(text, tcp),
3292
3293    i("wait some time before starting the MGC simulation"),
3294    sleep(1000),
3295
3296    d("[MGC] start the simulation"),
3297    {ok, MgcId} = megaco_test_megaco_generator:exec(Mgc, MgcEvSeq),
3298
3299    %% i("wait some time before starting the MG simulator"),
3300    %% sleep(1000),
3301
3302    i("await MGC ready announcement"),
3303    receive
3304        announce_mgc ->
3305            i("received MGC ready announcement"),
3306            ok
3307    end,
3308
3309    d("[MG] start the simulator (generator)"),
3310    {ok, Mg} = megaco_test_tcp_generator:start_link("MG", MgNode),
3311
3312    d("[MG] create the event sequence"),
3313    MgEvSeq = raraa_mg_event_sequence(text, tcp),
3314
3315    i("wait some time before starting the MG simulation"),
3316    sleep(1000),
3317
3318    d("[MG] start the simulation"),
3319    {ok, MgId} = megaco_test_tcp_generator:exec(Mg, MgEvSeq),
3320
3321    d("await the generator reply(s)"),
3322    await_completion([MgcId, MgId]),
3323
3324    %% Tell Mgc to stop
3325    i("[MGC] stop generator"),
3326    megaco_test_megaco_generator:stop(Mgc),
3327
3328    %% Tell Mg to stop
3329    i("[MG] stop generator"),
3330    megaco_test_tcp_generator:stop(Mg),
3331
3332    i("done", []),
3333    ok.
3334
3335
3336%%
3337%% MGC generator stuff
3338%%
3339
3340-ifdef(megaco_hipe_special).
3341-define(raraa_mgc_verify_handle_connect_fun(),
3342        {?MODULE, raraa_mgc_verify_handle_connect, []}).
3343-define(raraa_mgc_verify_service_change_req_fun(Mid),
3344        {?MODULE, raraa_mgc_verify_service_change_req, [Mid]}).
3345-define(raraa_mgc_verify_notify_req_fun(),
3346        {?MODULE, raraa_mgc_verify_notify_req, []}).
3347-define(raraa_mgc_verify_handle_trans_ack_fun(),
3348        {?MODULE, raraa_mgc_verify_handle_trans_ack, []}).
3349-define(raraa_mgc_verify_handle_disconnect_fun(),
3350        {?MODULE, raraa_mgc_verify_handle_disconnect, []}).
3351-else.
3352-define(raraa_mgc_verify_handle_connect_fun(),
3353        fun raraa_mgc_verify_handle_connect/1).
3354-define(raraa_mgc_verify_service_change_req_fun(Mid),
3355        raraa_mgc_verify_service_change_req_fun(Mid)).
3356-define(raraa_mgc_verify_notify_req_fun(),
3357	raraa_mgc_verify_notify_req_fun()).
3358-define(raraa_mgc_verify_handle_trans_ack_fun(),
3359        raraa_mgc_verify_handle_trans_ack_fun()).
3360-define(raraa_mgc_verify_handle_disconnect_fun(),
3361	fun raraa_mgc_verify_handle_disconnect/1).
3362-endif.
3363
3364raraa_mgc_event_sequence(text, tcp) ->
3365    CTRL = self(),
3366    Mid = {deviceName,"ctrl"},
3367    RI = [
3368          {port,             2944},
3369          {encoding_module,  megaco_pretty_text_encoder},
3370          {encoding_config,  []},
3371          {transport_module, megaco_tcp}
3372         ],
3373    ConnectVerify = ?raraa_mgc_verify_handle_connect_fun(),
3374    ScrVerify     = ?raraa_mgc_verify_service_change_req_fun(Mid),
3375    NrVerify      = ?raraa_mgc_verify_notify_req_fun(),
3376    AckVerify     = ?raraa_mgc_verify_handle_trans_ack_fun(),
3377    DiscoVerify   = ?raraa_mgc_verify_handle_disconnect_fun(),
3378    EvSeq = [
3379             {debug, true},
3380             {megaco_trace, disable},
3381             {megaco_trace, max},
3382             megaco_start,
3383             {megaco_start_user, Mid, RI, []},
3384             {megaco_update_user_info, sent_pending_limit, 100},
3385             start_transport,
3386             listen,
3387
3388             %% ANNOUNCE READY
3389             {trigger, fun() -> CTRL ! announce_mgc end},
3390
3391             {megaco_callback, handle_connect,           ConnectVerify},
3392             {megaco_conn_info, all},
3393             {megaco_callback, handle_trans_request,     ScrVerify},
3394	     {megaco_callback, handle_trans_request,     NrVerify},
3395	     {megaco_callback, handle_trans_ack,         AckVerify},
3396             {megaco_callback, handle_disconnect,        DiscoVerify},
3397             megaco_stop_user,
3398             megaco_stop
3399            ],
3400    EvSeq.
3401
3402%% Connect verification
3403raraa_mgc_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
3404    {ok, CH, ok};
3405raraa_mgc_verify_handle_connect(Else) ->
3406    {error, Else, ok}.
3407
3408%% Service Change verification
3409-ifndef(megaco_hipe_special).
3410raraa_mgc_verify_service_change_req_fun(Mid) ->
3411    fun(Req) ->
3412	    raraa_mgc_verify_service_change_req(Req, Mid)
3413    end.
3414-endif.
3415
3416raraa_mgc_verify_service_change_req(
3417  {handle_trans_request, _, ?VERSION, [AR]}, Mid) ->
3418    (catch raraa_do_verify_service_change_req(AR, Mid));
3419raraa_mgc_verify_service_change_req(Crap, _Mid) ->
3420    ED       = cre_ErrDesc(Crap),
3421    ErrReply = {discard_ack, ED},
3422    {error, Crap, ErrReply}.
3423
3424raraa_do_verify_service_change_req(AR, Mid) ->
3425    io:format("raraa_mgc_verify_service_change_req -> entry with"
3426	      "~n   AR: ~p"
3427	      "~n   Mid: ~p"
3428	      "~n", [AR, Mid]),
3429    CR =
3430	case AR of
3431	    #'ActionRequest'{commandRequests = [CmdReq]} ->
3432		CmdReq;
3433	    _ ->
3434		Err1      = {invalid_action_request, AR},
3435		ED1       = cre_ErrDesc(AR),
3436		ErrReply1 = {discard_ack, ED1},
3437		throw({error, Err1, ErrReply1})
3438	end,
3439    Cmd =
3440	case CR of
3441	    #'CommandRequest'{command = Command} ->
3442		Command;
3443	    _ ->
3444		Err2      = {invalid_command_request, CR},
3445		ED2       = cre_ErrDesc(CR),
3446		ErrReply2 = {discard_ack, ED2},
3447		throw({error, Err2, ErrReply2})
3448	end,
3449    {Tid, Parms} =
3450	case Cmd of
3451	    {serviceChangeReq,
3452	     #'ServiceChangeRequest'{terminationID = [TermID],
3453				     serviceChangeParms = ServChParms}} ->
3454		{TermID, ServChParms};
3455	    _ ->
3456		Err3      = {invalid_command, Cmd},
3457		ED3       = cre_ErrDesc(Cmd),
3458		ErrReply3 = {discard_ack, ED3},
3459		throw({error, Err3, ErrReply3})
3460	end,
3461    case Tid of
3462	#megaco_term_id{contains_wildcards = false, id = ["root"]} ->
3463	    ok;
3464	_ ->
3465	    Err4      = {invalid_termination_id, Tid},
3466	    ED4       = cre_ErrDesc(Tid),
3467	    ErrReply4 = {discard_ack, ED4},
3468	    throw({error, Err4, ErrReply4})
3469    end,
3470    case Parms of
3471	#'ServiceChangeParm'{serviceChangeMethod = restart,
3472			     serviceChangeReason = [[$9,$0,$1|_]]} ->
3473	    AckData = [raraa_mgc_service_change_reply_ar(Mid, 1)],
3474	    Reply   = {discard_ack, AckData},
3475	    {ok, AR, Reply};
3476	_ ->
3477	    Err5      = {invalid_SCP, Parms},
3478	    ED5       = cre_ErrDesc(Parms),
3479	    ErrReply5 = {discard_ack, ED5},
3480	    {error, Err5, ErrReply5}
3481    end.
3482
3483
3484%% Notify Request verification
3485-ifndef(megaco_hipe_special).
3486raraa_mgc_verify_notify_req_fun() ->
3487    fun(Req) ->
3488	    raraa_mgc_verify_notify_req(Req)
3489    end.
3490-endif.
3491
3492raraa_mgc_verify_notify_req({handle_trans_request, _, ?VERSION, [AR]}) ->
3493    (catch raraa_mgc_do_verify_notify_req(AR));
3494raraa_mgc_verify_notify_req(Crap) ->
3495    ED       = cre_ErrDesc(Crap),
3496    ErrReply = {discard_ack, ED},
3497    {error, Crap, ErrReply}.
3498
3499raraa_mgc_do_verify_notify_req(AR) ->
3500    io:format("raraa_mgc_verify_notify_req -> entry with"
3501	      "~n   AR: ~p"
3502	      "~n", [AR]),
3503    {Cid, CR} =
3504	case AR of
3505	    #'ActionRequest'{contextId       = CtxID,
3506			     commandRequests = [CmdReq]} ->
3507		{CtxID, CmdReq};
3508	    _ ->
3509		Err1      = {invalid_action_request, AR},
3510		ED1       = cre_ErrDesc(AR),
3511		ErrReply1 = {discard_ack, ED1},
3512		throw({error, Err1, ErrReply1})
3513	end,
3514    Cmd =
3515	case CR of
3516	    #'CommandRequest'{command = Command} ->
3517		Command;
3518	    _ ->
3519		Err2      = {invalid_command_request, CR},
3520		ED2       = cre_ErrDesc(CR),
3521		ErrReply2 = {discard_ack, ED2},
3522		throw({error, Err2, ErrReply2})
3523	end,
3524    NR =
3525	case Cmd of
3526	    {notifyReq, NotifReq} ->
3527		NotifReq;
3528	    _ ->
3529		Err3      = {invalid_command, Cmd},
3530		ED3       = cre_ErrDesc(Cmd),
3531		ErrReply3 = {discard_ack, ED3},
3532		throw({error, Err3, ErrReply3})
3533	end,
3534    {Tid, OED} =
3535	case NR of
3536	    #'NotifyRequest'{terminationID            = [TermID],
3537			     observedEventsDescriptor = ObsEvsDesc,
3538			     errorDescriptor          = asn1_NOVALUE} ->
3539		{TermID, ObsEvsDesc};
3540	    _ ->
3541		Err4      = {invalid_NR, NR},
3542		ED4       = cre_ErrDesc(NR),
3543		ErrReply4 = {discard_ack, ED4},
3544		throw({error, Err4, ErrReply4})
3545	end,
3546    OE =
3547	case OED of
3548	    #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
3549		ObsEvLst;
3550	    _ ->
3551		Err5      = {invalid_OED, OED},
3552		ED5       = cre_ErrDesc(NR),
3553		ErrReply5 = {discard_ack, ED5},
3554		throw({error, Err5, ErrReply5})
3555	end,
3556    case OE of
3557	#'ObservedEvent'{eventName = "al/of"} ->
3558	    AckData = raraa,
3559	    Replies = [raraa_mgc_notify_reply_ar(Cid, Tid)],
3560	    Reply   = {{handle_ack, AckData}, Replies},
3561	    {ok, AR, Reply};
3562	_ ->
3563	    Err6      = {invalid_OE, OE},
3564	    ED6       = cre_ErrDesc(OE),
3565	    ErrReply6 = {discard_ack, ED6},
3566	    throw({error, Err6, ErrReply6})
3567    end.
3568
3569
3570-ifndef(megaco_hipe_special).
3571raraa_mgc_verify_handle_trans_ack_fun() ->
3572    fun(Ack) ->
3573	    raraa_mgc_verify_handle_trans_ack(Ack)
3574    end.
3575-endif.
3576
3577raraa_mgc_verify_handle_trans_ack(
3578  {handle_trans_ack, CH, ?VERSION, ok, raraa}) ->
3579    io:format("raraa_mgc_verify_handle_trans_ack -> ok"
3580              "~n   CH: ~p"
3581              "~n", [CH]),
3582    {ok, CH, ok};
3583raraa_mgc_verify_handle_trans_ack(Crap) ->
3584    io:format("raraa_mgc_verify_handle_trans_ack -> unknown"
3585              "~n   Crap: ~p~n", [Crap]),
3586    {error, Crap, ok}.
3587
3588
3589%% Disconnect verification
3590raraa_mgc_verify_handle_disconnect({handle_disconnect, CH, ?VERSION, _R}) ->
3591    {ok, CH, ok};
3592raraa_mgc_verify_handle_disconnect(Else) ->
3593    {error, Else, ok}.
3594
3595raraa_mgc_service_change_reply_ar(Mid, Cid) ->
3596    SCRP  = cre_serviceChangeResParm(Mid),
3597    SCRes = cre_serviceChangeResult(SCRP),
3598    Root  = #megaco_term_id{id = ["root"]},
3599    SCR   = cre_serviceChangeReply([Root], SCRes),
3600    CR    = cre_cmdReply(SCR),
3601    AR    = cre_actionReply(Cid, [CR]),
3602    AR.
3603
3604raraa_mgc_notify_reply_ar(Cid, TermId) ->
3605    NR    = cre_notifyReply([TermId]),
3606    CR    = cre_cmdReply(NR),
3607    cre_actionReply(Cid, [CR]).
3608
3609
3610%%
3611%% MG generator stuff
3612%%
3613-ifdef(megaco_hipe_special).
3614-define(raraa_mg_decode_msg_fun(Mod, Conf),
3615	{?MODULE, decode_msg, [Mod, Conf]}).
3616-define(raraa_mg_encode_msg_fun(Mod, Conf),
3617	{?MODULE, encode_msg, [Mod, Conf]}).
3618-define(raraa_mg_verify_service_change_rep_msg_fun(),
3619	{?MODULE, raraa_mg_verify_service_change_rep_msg, []}).
3620-define(raraa_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId),
3621	{?MODULE, raraa_mg_verify_notify_rep_msg, [TermId, TransId, ReqId, CtxId]}).
3622-else.
3623-define(raraa_mg_decode_msg_fun(Mod, Conf),
3624	raraa_mg_decode_msg_fun(Mod, Conf)).
3625-define(raraa_mg_encode_msg_fun(Mod, Conf),
3626	raraa_mg_encode_msg_fun(Mod, Conf)).
3627-define(raraa_mg_verify_service_change_rep_msg_fun(),
3628	raraa_mg_verify_service_change_rep_msg_fun()).
3629-define(raraa_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId),
3630	raraa_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId)).
3631-endif.
3632
3633raraa_mg_event_sequence(text, tcp) ->
3634    DecodeFun = ?raraa_mg_decode_msg_fun(megaco_pretty_text_encoder, []),
3635    EncodeFun = ?raraa_mg_encode_msg_fun(megaco_pretty_text_encoder, []),
3636    Mid       = {deviceName,"mg"},
3637    ServiceChangeReq = raraa_mg_service_change_request_msg(Mid, 1, 0),
3638    TermId  = #megaco_term_id{id = ["00000000","00000000","01101101"]},
3639    TransId = 2,
3640    ReqId   = 1,
3641    CtxId   = 1,
3642    NotifyReq = raraa_mg_notify_request_msg(Mid, TermId,
3643					    TransId, ReqId, CtxId),
3644    TransAck = raraa_mg_trans_ack_msg(Mid, TransId),
3645    ScrVerifyFun = ?raraa_mg_verify_service_change_rep_msg_fun(),
3646    NrVerifyFun  = ?raraa_mg_verify_notify_rep_msg_fun(TermId,
3647						       TransId, ReqId, CtxId),
3648    EvSeq = [{debug,  true},
3649             {decode, DecodeFun},
3650             {encode, EncodeFun},
3651             {connect, 2944},
3652             {send, "service-change-request", ServiceChangeReq},
3653             {expect_receive, "service-change-reply", {ScrVerifyFun, 10000}},
3654             {send, "notify request", NotifyReq},
3655             {expect_receive, "notify-reply", {NrVerifyFun, 10000}},
3656             {send, "transaction-ack", TransAck},
3657             {expect_nothing, 11000},
3658             disconnect
3659            ],
3660    EvSeq.
3661
3662-ifndef(megaco_hipe_special).
3663raraa_mg_encode_msg_fun(Mod, Conf) ->
3664    fun(M) ->
3665            encode_msg(M, Mod, Conf)
3666    end.
3667-endif.
3668
3669-ifndef(megaco_hipe_special).
3670raraa_mg_decode_msg_fun(Mod, Conf) ->
3671    fun(M) ->
3672            decode_msg(M, Mod, Conf)
3673    end.
3674-endif.
3675
3676-ifndef(megaco_hipe_special).
3677raraa_mg_verify_service_change_rep_msg_fun() ->
3678    fun(Msg) ->
3679	    (catch raraa_mg_verify_service_change_rep_msg(Msg))
3680    end.
3681-endif.
3682
3683raraa_mg_verify_service_change_rep_msg(#'MegacoMessage'{mess = Mess} = M) ->
3684    Body =
3685	case Mess of
3686	    #'Message'{version     = _V,
3687                       mId         = _MgMid,
3688                       messageBody = MsgBody} ->
3689		MsgBody;
3690	    _ ->
3691		throw({error, {invalid_Message, Mess}})
3692	end,
3693    Trans =
3694	case Body of
3695            {transactions, [Transactions]} ->
3696		Transactions;
3697	    _ ->
3698		throw({error, {invalid_messageBody, Body}})
3699	end,
3700    TR =
3701	case Trans of
3702            {transactionReply, TransReply} ->
3703		TransReply;
3704	    _ ->
3705		throw({error, {invalid_transactions, Trans}})
3706	end,
3707    TRes =
3708	case TR of
3709            #'TransactionReply'{transactionId = _Tid,
3710                                immAckRequired = asn1_NOVALUE,
3711                                transactionResult = TransRes} ->
3712		TransRes;
3713	    _ ->
3714		throw({error, {invalid_transactionReply, TR}})
3715	end,
3716    AR =
3717	case TRes of
3718            {actionReplies, [ActRes]} ->
3719		ActRes;
3720	    _ ->
3721		throw({error, {invalid_transactionResult, TRes}})
3722	end,
3723    CR =
3724	case AR of
3725            #'ActionReply'{contextId       = _Cid,
3726                           errorDescriptor = asn1_NOVALUE,
3727                           contextReply    = _CtxReq,
3728                           commandReply    = [CmdRep]} ->
3729		CmdRep;
3730	    _ ->
3731		throw({error, {invalid_actionReplies, AR}})
3732	end,
3733    SCR =
3734	case CR of
3735            {serviceChangeReply, ServChRep} ->
3736		ServChRep;
3737	    _ ->
3738		throw({error, {invalid_commandReply, CR}})
3739	end,
3740    SCRes =
3741	case SCR of
3742            #'ServiceChangeReply'{terminationID       = _TermID,
3743                                  serviceChangeResult = ServChRes} ->
3744		ServChRes;
3745	    _ ->
3746		throw({error, {invalid_serviceChangeReply, SCR}})
3747	end,
3748    SCRP =
3749	case SCRes of
3750            {serviceChangeResParms, Parms} ->
3751		Parms;
3752	    _ ->
3753		throw({error, {invalid_serviceChangeResult, SCRes}})
3754	end,
3755    case SCRP of
3756	#'ServiceChangeResParm'{serviceChangeMgcId = _MgcMid} ->
3757            {ok, M};
3758	_ ->
3759	    {error, {invalid_serviceChangeResParms, SCRP}}
3760    end;
3761raraa_mg_verify_service_change_rep_msg(Crap) ->
3762    {error, {invalid_message, Crap}}.
3763
3764-ifndef(megaco_hipe_special).
3765raraa_mg_verify_notify_rep_msg_fun(TermId, TransId, Rid, Cid) ->
3766    fun(Msg) ->
3767	    (catch raraa_mg_verify_notify_rep_msg(Msg,
3768						  TermId, TransId, Rid, Cid))
3769    end.
3770-endif.
3771
3772raraa_mg_verify_notify_rep_msg(#'MegacoMessage'{mess = Mess} = M,
3773			   TermId, TransId, Rid, Cid) ->
3774    io:format("raraa_mg_verify_notify_rep_msg -> entry with"
3775	      "~n   M:       ~p"
3776	      "~n   TermId:  ~p"
3777	      "~n   TransId: ~p"
3778	      "~n   Rid:     ~p"
3779	      "~n   Cid:     ~p"
3780	      "~n", [M, TermId, TransId, Rid, Cid]),
3781    Body =
3782	case Mess of
3783	    #'Message'{version     = ?VERSION,
3784                       mId         = _Mid,
3785                       messageBody = MsgBody} ->
3786		MsgBody;
3787	    _ ->
3788		throw({error, {invalid_Message, Mess}})
3789	end,
3790    Trans =
3791	case Body of
3792            {transactions, [Transactions]} ->
3793		Transactions;
3794	    _ ->
3795		throw({error, {invalid_messageBody, Body}})
3796	end,
3797    TR =
3798	case Trans of
3799            {transactionReply, TransReply} ->
3800		TransReply;
3801	    _ ->
3802		throw({error, {invalid_transactions, Trans}})
3803	end,
3804    TRes =
3805	case TR of
3806            #'TransactionReply'{transactionId     = TransId,
3807                                immAckRequired    = 'NULL',
3808                                transactionResult = TransRes} ->
3809		TransRes;
3810	    _ ->
3811		throw({error, {invalid_transactionReply, TR}})
3812	end,
3813    AR =
3814	case TRes of
3815            {actionReplies, [ActRes]} ->
3816		ActRes;
3817	    _ ->
3818		throw({error, {invalid_transactionResult, TRes}})
3819	end,
3820    CR =
3821	case AR of
3822            #'ActionReply'{contextId       = Cid,
3823                           errorDescriptor = asn1_NOVALUE,
3824                           contextReply    = _CtxReq,
3825                           commandReply    = [CmdRep]} ->
3826		CmdRep;
3827	    _ ->
3828		throw({error, {invalid_actionReplies, AR}})
3829	end,
3830    NR =
3831	case CR of
3832            {notifyReply, NotifyReply} ->
3833		NotifyReply;
3834	    _ ->
3835		throw({error, {invalid_commandReply, CR}})
3836	end,
3837    case NR of
3838	#'NotifyReply'{terminationID   = [TermId],
3839		       errorDescriptor = asn1_NOVALUE} ->
3840	    {ok, M};
3841	_ ->
3842	    {error, {invalid_notifyReply, NR}}
3843    end;
3844raraa_mg_verify_notify_rep_msg(Crap, _TermId, _TransId, _Rid, _Cid) ->
3845    {error, {invalid_message, Crap}}.
3846
3847raraa_mg_service_change_request_ar(_Mid, Cid) ->
3848    Prof  = cre_serviceChangeProf("resgw", 1),
3849    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
3850    Root  = #megaco_term_id{id = ["root"]},
3851    SCR   = cre_serviceChangeReq([Root], SCP),
3852    CMD   = cre_command(SCR),
3853    CR    = cre_cmdReq(CMD),
3854    cre_actionReq(Cid, [CR]).
3855
3856raraa_mg_service_change_request_msg(Mid, TransId, Cid) ->
3857    AR    = raraa_mg_service_change_request_ar(Mid, Cid),
3858    TR    = cre_transReq(TransId, [AR]),
3859    Trans = cre_transaction(TR),
3860    Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
3861    cre_megacoMessage(Mess).
3862
3863raraa_mg_notify_request_ar(Rid, Tid, Cid) ->
3864    TT      = cre_timeNotation("19990729", "22000000"),
3865    Ev      = cre_obsEvent("al/of", TT),
3866    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
3867    NR      = cre_notifyReq([Tid], EvsDesc),
3868    CMD     = cre_command(NR),
3869    CR      = cre_cmdReq(CMD),
3870    cre_actionReq(Cid, [CR]).
3871
3872raraa_mg_notify_request_msg(Mid, TermId, TransId, Rid, Cid) ->
3873    AR      = raraa_mg_notify_request_ar(Rid, TermId, Cid),
3874    TR      = cre_transReq(TransId, [AR]),
3875    Trans   = cre_transaction(TR),
3876    Mess    = cre_message(?VERSION, Mid, cre_transactions([Trans])),
3877    cre_megacoMessage(Mess).
3878
3879raraa_mg_trans_ack_msg(Mid, TransId) ->
3880    TR    = cre_transRespAck(cre_transAck(TransId)),
3881    Trans = cre_transaction(TR),
3882    Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
3883    cre_megacoMessage(Mess).
3884
3885
3886
3887%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3888
3889request_and_reply_and_no_ack(suite) ->
3890    [];
3891request_and_reply_and_no_ack(doc) ->
3892    ["This test case tests that megaco handles a failed three-way-handshake,"
3893     " i.e. when the ack never arrives"];
3894request_and_reply_and_no_ack(Config) when is_list(Config) ->
3895    Pre = fun() ->
3896                  MgcNode = make_node_name(mgc),
3897                  MgNode  = make_node_name(mg),
3898                  d("start nodes: "
3899                    "~n      MgcNode: ~p"
3900                    "~n      MgNode:  ~p",
3901                    [MgcNode, MgNode]),
3902                  Nodes = [MgcNode, MgNode],
3903                  ok = ?START_NODES(Nodes, true),
3904                  Nodes
3905          end,
3906    Case = fun do_request_and_reply_and_no_ack/1,
3907    Post = fun(Nodes) ->
3908                   d("stop nodes"),
3909                   ?STOP_NODES(lists:reverse(Nodes))
3910           end,
3911    try_tc(rarana, Pre, Case, Post).
3912
3913
3914do_request_and_reply_and_no_ack([MgcNode, MgNode]) ->
3915    d("[MGC] start the simulator "),
3916    {ok, Mgc} = megaco_test_megaco_generator:start_link("MGC", MgcNode),
3917
3918    d("[MGC] create the event sequence"),
3919    MgcEvSeq = rarana_mgc_event_sequence(text, tcp),
3920
3921    i("wait some time before starting the MGC simulation"),
3922    sleep(1000),
3923
3924    d("[MGC] start the simulation"),
3925    {ok, MgcId} = megaco_test_megaco_generator:exec(Mgc, MgcEvSeq),
3926
3927    %% i("wait some time before starting the MG simulator"),
3928    %% sleep(1000),
3929
3930    i("await MGC ready announcement"),
3931    receive
3932        announce_mgc ->
3933            i("received MGC ready announcement"),
3934            ok
3935    end,
3936
3937    d("[MG] start the simulator (generator)"),
3938    {ok, Mg} = megaco_test_tcp_generator:start_link("MG", MgNode),
3939
3940    d("[MG] create the event sequence"),
3941    MgEvSeq = rarana_mg_event_sequence(text, tcp),
3942
3943    i("wait some time before starting the MG simulation"),
3944    sleep(1000),
3945
3946    d("[MG] start the simulation"),
3947    {ok, MgId} = megaco_test_tcp_generator:exec(Mg, MgEvSeq),
3948
3949    d("await the generator reply(s)"),
3950    await_completion([MgcId, MgId]),
3951
3952    %% Tell Mgc to stop
3953    i("[MGC] stop generator"),
3954    megaco_test_megaco_generator:stop(Mgc),
3955
3956    %% Tell Mg to stop
3957    i("[MG] stop generator"),
3958    megaco_test_tcp_generator:stop(Mg),
3959
3960    i("done", []),
3961    ok.
3962
3963
3964%%
3965%% MGC generator stuff
3966%%
3967
3968-ifdef(megaco_hipe_special).
3969-define(rarana_mgc_verify_handle_connect_fun(),
3970        {?MODULE, rarana_mgc_verify_handle_connect, []}).
3971-define(rarana_mgc_verify_service_change_req_fun(Mid),
3972        {?MODULE, rarana_mgc_verify_service_change_req, [Mid]}).
3973-define(rarana_mgc_verify_notify_req_fun(),
3974        {?MODULE, rarana_mgc_verify_notify_req, []}).
3975-define(rarana_mgc_verify_handle_trans_ack_fun(),
3976	{?MODULE, rarana_mgc_verify_handle_trans_ack, []}).
3977-define(rarana_mgc_verify_handle_disconnect_fun(),
3978        {?MODULE, rarana_mgc_verify_handle_disconnect, []}).
3979-else.
3980-define(rarana_mgc_verify_handle_connect_fun(),
3981        fun rarana_mgc_verify_handle_connect/1).
3982-define(rarana_mgc_verify_service_change_req_fun(Mid),
3983        rarana_mgc_verify_service_change_req_fun(Mid)).
3984-define(rarana_mgc_verify_notify_req_fun(),
3985	rarana_mgc_verify_notify_req_fun()).
3986-define(rarana_mgc_verify_handle_trans_ack_fun(),
3987	rarana_mgc_verify_handle_trans_ack_fun()).
3988-define(rarana_mgc_verify_handle_disconnect_fun(),
3989	fun rarana_mgc_verify_handle_disconnect/1).
3990-endif.
3991
3992rarana_mgc_event_sequence(text, tcp) ->
3993    CTRL = self(),
3994    Mid = {deviceName,"ctrl"},
3995    RI = [
3996          {port,             2944},
3997          {encoding_module,  megaco_pretty_text_encoder},
3998          {encoding_config,  []},
3999          {transport_module, megaco_tcp}
4000         ],
4001    ConnectVerify = ?rarana_mgc_verify_handle_connect_fun(),
4002    ScrVerify     = ?rarana_mgc_verify_service_change_req_fun(Mid),
4003    NrVerify      = ?rarana_mgc_verify_notify_req_fun(),
4004    AckVerify     = ?rarana_mgc_verify_handle_trans_ack_fun(),
4005    DiscoVerify   = ?rarana_mgc_verify_handle_disconnect_fun(),
4006    EvSeq = [
4007             {debug, true},
4008             {megaco_trace, disable},
4009             {megaco_trace, max},
4010             megaco_start,
4011             {megaco_start_user, Mid, RI, []},
4012             {megaco_update_user_info, sent_pending_limit, 100},
4013             {megaco_update_user_info, reply_timer,        9000},
4014             start_transport,
4015             listen,
4016
4017             %% ANNOUNCE READY
4018             {trigger, fun() -> CTRL ! announce_mgc end},
4019
4020             {megaco_callback, handle_connect,           ConnectVerify},
4021             {megaco_conn_info, all},
4022             {megaco_callback, handle_trans_request,     ScrVerify},
4023	     {megaco_callback, handle_trans_request,     NrVerify},
4024	     {megaco_callback, handle_trans_ack,         AckVerify},
4025	     %% {megaco_callback, nocall,                   8000},
4026             {megaco_callback, handle_disconnect,        DiscoVerify},
4027             megaco_stop_user,
4028             megaco_stop
4029            ],
4030    EvSeq.
4031
4032%% Connect verification
4033rarana_mgc_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
4034    {ok, CH, ok};
4035rarana_mgc_verify_handle_connect(Else) ->
4036    {error, Else, ok}.
4037
4038%% Service Change verification
4039-ifndef(megaco_hipe_special).
4040rarana_mgc_verify_service_change_req_fun(Mid) ->
4041    fun(Req) ->
4042	    rarana_mgc_verify_service_change_req(Req, Mid)
4043    end.
4044-endif.
4045
4046rarana_mgc_verify_service_change_req(
4047  {handle_trans_request, _, ?VERSION, [AR]}, Mid) ->
4048    (catch rarana_do_verify_service_change_req(AR, Mid));
4049rarana_mgc_verify_service_change_req(Crap, _Mid) ->
4050    ED       = cre_ErrDesc(Crap),
4051    ErrReply = {discard_ack, ED},
4052    {error, Crap, ErrReply}.
4053
4054rarana_do_verify_service_change_req(AR, Mid) ->
4055    CR =
4056	case AR of
4057	    #'ActionRequest'{commandRequests = [CmdReq]} ->
4058		CmdReq;
4059	    _ ->
4060		Err1      = {invalid_action_request, AR},
4061		ED1       = cre_ErrDesc(AR),
4062		ErrReply1 = {discard_ack, ED1},
4063		throw({error, Err1, ErrReply1})
4064	end,
4065    Cmd =
4066	case CR of
4067	    #'CommandRequest'{command = Command} ->
4068		Command;
4069	    _ ->
4070		Err2      = {invalid_command_request, CR},
4071		ED2       = cre_ErrDesc(CR),
4072		ErrReply2 = {discard_ack, ED2},
4073		throw({error, Err2, ErrReply2})
4074	end,
4075    {Tid, Parms} =
4076	case Cmd of
4077	    {serviceChangeReq,
4078	     #'ServiceChangeRequest'{terminationID = [TermID],
4079				     serviceChangeParms = ServChParms}} ->
4080		{TermID, ServChParms};
4081	    _ ->
4082		Err3      = {invalid_command, Cmd},
4083		ED3       = cre_ErrDesc(Cmd),
4084		ErrReply3 = {discard_ack, ED3},
4085		throw({error, Err3, ErrReply3})
4086	end,
4087    case Tid of
4088	#megaco_term_id{contains_wildcards = false, id = ["root"]} ->
4089	    ok;
4090	_ ->
4091	    Err4      = {invalid_termination_id, Tid},
4092	    ED4       = cre_ErrDesc(Tid),
4093	    ErrReply4 = {discard_ack, ED4},
4094	    throw({error, Err4, ErrReply4})
4095    end,
4096    case Parms of
4097	#'ServiceChangeParm'{serviceChangeMethod = restart,
4098			     serviceChangeReason = [[$9,$0,$1|_]]} ->
4099	    AckData = [rarana_mgc_service_change_reply_ar(Mid, 1)],
4100	    Reply   = {discard_ack, AckData},
4101	    {ok, AR, Reply};
4102	_ ->
4103	    Err5      = {invalid_SCP, Parms},
4104	    ED5       = cre_ErrDesc(Parms),
4105	    ErrReply5 = {discard_ack, ED5},
4106	    {error, Err5, ErrReply5}
4107    end.
4108
4109
4110%% Notify Request verification
4111-ifndef(megaco_hipe_special).
4112rarana_mgc_verify_notify_req_fun() ->
4113    fun(Req) ->
4114	    rarana_mgc_verify_notify_req(Req)
4115    end.
4116-endif.
4117
4118rarana_mgc_verify_notify_req({handle_trans_request, _, ?VERSION, [AR]}) ->
4119    (catch rarana_mgc_do_verify_notify_req(AR));
4120rarana_mgc_verify_notify_req(Crap) ->
4121    ED       = cre_ErrDesc(Crap),
4122    ErrReply = {discard_ack, ED},
4123    {error, Crap, ErrReply}.
4124
4125rarana_mgc_do_verify_notify_req(AR) ->
4126    {Cid, CR} =
4127	case AR of
4128	    #'ActionRequest'{contextId       = CtxID,
4129			     commandRequests = [CmdReq]} ->
4130		{CtxID, CmdReq};
4131	    _ ->
4132		Err1      = {invalid_action_request, AR},
4133		ED1       = cre_ErrDesc(AR),
4134		ErrReply1 = {discard_ack, ED1},
4135		throw({error, Err1, ErrReply1})
4136	end,
4137    Cmd =
4138	case CR of
4139	    #'CommandRequest'{command = Command} ->
4140		Command;
4141	    _ ->
4142		Err2      = {invalid_command_request, CR},
4143		ED2       = cre_ErrDesc(CR),
4144		ErrReply2 = {discard_ack, ED2},
4145		throw({error, Err2, ErrReply2})
4146	end,
4147    NR =
4148	case Cmd of
4149	    {notifyReq, NotifReq} ->
4150		NotifReq;
4151	    _ ->
4152		Err3      = {invalid_command, Cmd},
4153		ED3       = cre_ErrDesc(Cmd),
4154		ErrReply3 = {discard_ack, ED3},
4155		throw({error, Err3, ErrReply3})
4156	end,
4157    {Tid, OED} =
4158	case NR of
4159	    #'NotifyRequest'{terminationID            = [TermID],
4160			     observedEventsDescriptor = ObsEvsDesc,
4161			     errorDescriptor          = asn1_NOVALUE} ->
4162		{TermID, ObsEvsDesc};
4163	    _ ->
4164		Err4      = {invalid_NR, NR},
4165		ED4       = cre_ErrDesc(NR),
4166		ErrReply4 = {discard_ack, ED4},
4167		throw({error, Err4, ErrReply4})
4168	end,
4169    OE =
4170	case OED of
4171	    #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
4172		ObsEvLst;
4173	    _ ->
4174		Err5      = {invalid_OED, OED},
4175		ED5       = cre_ErrDesc(NR),
4176		ErrReply5 = {discard_ack, ED5},
4177		throw({error, Err5, ErrReply5})
4178	end,
4179    case OE of
4180	#'ObservedEvent'{eventName = "al/of"} ->
4181	    AckData = rarana,
4182	    Replies = [rarana_mgc_notify_reply_ar(Cid, Tid)],
4183	    Reply   = {{handle_ack, AckData}, Replies},
4184	    {ok, AR, Reply};
4185	_ ->
4186	    Err6      = {invalid_OE, OE},
4187	    ED6       = cre_ErrDesc(OE),
4188	    ErrReply6 = {discard_ack, ED6},
4189	    throw({error, Err6, ErrReply6})
4190    end.
4191
4192
4193-ifndef(megaco_hipe_special).
4194rarana_mgc_verify_handle_trans_ack_fun() ->
4195    fun(Ack) ->
4196	    rarana_mgc_verify_handle_trans_ack(Ack)
4197    end.
4198-endif.
4199
4200rarana_mgc_verify_handle_trans_ack({handle_trans_ack, CH, ?VERSION,
4201			     {error, timeout}, rarana}) ->
4202    io:format("rarana_mgc_verify_handle_trans_ack -> expected error: ok"
4203              "~n   CH: ~p"
4204              "~n", [CH]),
4205    {ok, CH, ok};
4206rarana_mgc_verify_handle_trans_ack(Crap) ->
4207    io:format("rarana_mgc_verify_trans_ack -> unknown"
4208              "~n   Crap: ~p~n", [Crap]),
4209    {error, Crap, ok}.
4210
4211
4212%% Disconnect verification
4213rarana_mgc_verify_handle_disconnect({handle_disconnect, CH, ?VERSION, _R}) ->
4214    {ok, CH, ok};
4215rarana_mgc_verify_handle_disconnect(Else) ->
4216    {error, Else, ok}.
4217
4218rarana_mgc_service_change_reply_ar(Mid, Cid) ->
4219    SCRP  = cre_serviceChangeResParm(Mid),
4220    SCRes = cre_serviceChangeResult(SCRP),
4221    Root  = #megaco_term_id{id = ["root"]},
4222    SCR   = cre_serviceChangeReply([Root], SCRes),
4223    CR    = cre_cmdReply(SCR),
4224    AR    = cre_actionReply(Cid, [CR]),
4225    AR.
4226
4227rarana_mgc_notify_reply_ar(Cid, TermId) ->
4228    NR    = cre_notifyReply([TermId]),
4229    CR    = cre_cmdReply(NR),
4230    cre_actionReply(Cid, [CR]).
4231
4232
4233%%
4234%% MG generator stuff
4235%%
4236-ifdef(megaco_hipe_special).
4237-define(rarana_mg_decode_msg_fun(Mod, Conf),
4238	{?MODULE, decode_msg, [Mod, Conf]}).
4239-define(rarana_mg_encode_msg_fun(Mod, Conf),
4240	{?MODULE, encode_msg, [Mod, Conf]}).
4241-define(rarana_mg_verify_service_change_rep_msg_fun(),
4242	{?MODULE, rarana_mg_verify_service_change_rep_msg, []}).
4243-define(rarana_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId),
4244	{?MODULE, rarana_mg_verify_notify_rep_msg, [TermId, TransId, ReqId, CtxId]}).
4245-else.
4246-define(rarana_mg_decode_msg_fun(Mod, Conf),
4247	rarana_mg_decode_msg_fun(Mod, Conf)).
4248-define(rarana_mg_encode_msg_fun(Mod, Conf),
4249	rarana_mg_encode_msg_fun(Mod, Conf)).
4250-define(rarana_mg_verify_service_change_rep_msg_fun(),
4251	rarana_mg_verify_service_change_rep_msg_fun()).
4252-define(rarana_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId),
4253	rarana_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId)).
4254-endif.
4255
4256rarana_mg_event_sequence(text, tcp) ->
4257    DecodeFun = ?rarana_mg_decode_msg_fun(megaco_pretty_text_encoder, []),
4258    EncodeFun = ?rarana_mg_encode_msg_fun(megaco_pretty_text_encoder, []),
4259    Mid       = {deviceName,"mg"},
4260    ServiceChangeReq = rarana_mg_service_change_request_msg(Mid, 1, 0),
4261    TermId  = #megaco_term_id{id = ["00000000","00000000","01101101"]},
4262    TransId = 2,
4263    ReqId   = 1,
4264    CtxId   = 1,
4265    NotifyReq = rarana_mg_notify_request_msg(Mid, TermId,
4266					    TransId, ReqId, CtxId),
4267    ScrVerifyFun = ?rarana_mg_verify_service_change_rep_msg_fun(),
4268    NrVerifyFun  = ?rarana_mg_verify_notify_rep_msg_fun(TermId,
4269							TransId, ReqId, CtxId),
4270    EvSeq = [{debug,  true},
4271             {decode, DecodeFun},
4272             {encode, EncodeFun},
4273             {connect, 2944},
4274             {send, "service-change-request", ServiceChangeReq},
4275             {expect_receive, "service-change-reply", {ScrVerifyFun, 10000}},
4276             {send, "notify request", NotifyReq},
4277             {expect_receive, "notify-reply", {NrVerifyFun, 10000}},
4278             {expect_nothing, 11000},
4279             disconnect
4280            ],
4281    EvSeq.
4282
4283-ifndef(megaco_hipe_special).
4284rarana_mg_encode_msg_fun(Mod, Conf) ->
4285    fun(M) ->
4286            encode_msg(M, Mod, Conf)
4287    end.
4288-endif.
4289
4290-ifndef(megaco_hipe_special).
4291rarana_mg_decode_msg_fun(Mod, Conf) ->
4292    fun(M) ->
4293            decode_msg(M, Mod, Conf)
4294    end.
4295-endif.
4296
4297-ifndef(megaco_hipe_special).
4298rarana_mg_verify_service_change_rep_msg_fun() ->
4299    fun(Msg) ->
4300	    (catch rarana_mg_verify_service_change_rep_msg(Msg))
4301    end.
4302-endif.
4303
4304rarana_mg_verify_service_change_rep_msg(#'MegacoMessage'{mess = Mess} = M) ->
4305    Body =
4306	case Mess of
4307	    #'Message'{version     = _V,
4308                       mId         = _MgMid,
4309                       messageBody = MsgBody} ->
4310		MsgBody;
4311	    _ ->
4312		throw({error, {invalid_Message, Mess}})
4313	end,
4314    Trans =
4315	case Body of
4316            {transactions, [Transactions]} ->
4317		Transactions;
4318	    _ ->
4319		throw({error, {invalid_messageBody, Body}})
4320	end,
4321    TR =
4322	case Trans of
4323            {transactionReply, TransReply} ->
4324		TransReply;
4325	    _ ->
4326		throw({error, {invalid_transactions, Trans}})
4327	end,
4328    TRes =
4329	case TR of
4330            #'TransactionReply'{transactionId = _Tid,
4331                                immAckRequired = asn1_NOVALUE,
4332                                transactionResult = TransRes} ->
4333		TransRes;
4334	    _ ->
4335		throw({error, {invalid_transactionReply, TR}})
4336	end,
4337    AR =
4338	case TRes of
4339            {actionReplies, [ActRes]} ->
4340		ActRes;
4341	    _ ->
4342		throw({error, {invalid_transactionResult, TRes}})
4343	end,
4344    CR =
4345	case AR of
4346            #'ActionReply'{contextId       = _Cid,
4347                           errorDescriptor = asn1_NOVALUE,
4348                           contextReply    = _CtxReq,
4349                           commandReply    = [CmdRep]} ->
4350		CmdRep;
4351	    _ ->
4352		throw({error, {invalid_actionReplies, AR}})
4353	end,
4354    SCR =
4355	case CR of
4356            {serviceChangeReply, ServChRep} ->
4357		ServChRep;
4358	    _ ->
4359		throw({error, {invalid_commandReply, CR}})
4360	end,
4361    SCRes =
4362	case SCR of
4363            #'ServiceChangeReply'{terminationID       = _TermID,
4364                                  serviceChangeResult = ServChRes} ->
4365		ServChRes;
4366	    _ ->
4367		throw({error, {invalid_serviceChangeReply, SCR}})
4368	end,
4369    SCRP =
4370	case SCRes of
4371            {serviceChangeResParms, Parms} ->
4372		Parms;
4373	    _ ->
4374		throw({error, {invalid_serviceChangeResult, SCRes}})
4375	end,
4376    case SCRP of
4377	#'ServiceChangeResParm'{serviceChangeMgcId = _MgcMid} ->
4378            {ok, M};
4379	_ ->
4380	    {error, {invalid_serviceChangeResParms, SCRP}}
4381    end;
4382rarana_mg_verify_service_change_rep_msg(Crap) ->
4383    {error, {invalid_message, Crap}}.
4384
4385-ifndef(megaco_hipe_special).
4386rarana_mg_verify_notify_rep_msg_fun(TermId, TransId, Rid, Cid) ->
4387    fun(Msg) ->
4388	    (catch rarana_mg_verify_notify_rep_msg(Msg,
4389						   TermId, TransId, Rid, Cid))
4390    end.
4391-endif.
4392
4393rarana_mg_verify_notify_rep_msg(#'MegacoMessage'{mess = Mess} = M,
4394				TermId, TransId, Rid, Cid) ->
4395    io:format("rarana_mg_verify_notify_rep_msg -> entry with"
4396	      "~n   M:       ~p"
4397	      "~n   TermId:  ~p"
4398	      "~n   TransId: ~p"
4399	      "~n   Rid:     ~p"
4400	      "~n   Cid:     ~p"
4401	      "~n", [M, TermId, TransId, Rid, Cid]),
4402    Body =
4403	case Mess of
4404	    #'Message'{version     = ?VERSION,
4405                       mId         = _Mid,
4406                       messageBody = MsgBody} ->
4407		MsgBody;
4408	    _ ->
4409		throw({error, {invalid_Message, Mess}})
4410	end,
4411    Trans =
4412	case Body of
4413            {transactions, [Transactions]} ->
4414		Transactions;
4415	    _ ->
4416		throw({error, {invalid_messageBody, Body}})
4417	end,
4418    TR =
4419	case Trans of
4420            {transactionReply, TransReply} ->
4421		TransReply;
4422	    _ ->
4423		throw({error, {invalid_transactions, Trans}})
4424	end,
4425    TRes =
4426	case TR of
4427            #'TransactionReply'{transactionId     = TransId,
4428                                immAckRequired    = 'NULL',
4429                                transactionResult = TransRes} ->
4430		TransRes;
4431	    _ ->
4432		throw({error, {invalid_transactionReply, TR}})
4433	end,
4434    AR =
4435	case TRes of
4436            {actionReplies, [ActRes]} ->
4437		ActRes;
4438	    _ ->
4439		throw({error, {invalid_transactionResult, TRes}})
4440	end,
4441    CR =
4442	case AR of
4443            #'ActionReply'{contextId       = Cid,
4444                           errorDescriptor = asn1_NOVALUE,
4445                           contextReply    = _CtxReq,
4446                           commandReply    = [CmdRep]} ->
4447		CmdRep;
4448	    _ ->
4449		throw({error, {invalid_actionReplies, AR}})
4450	end,
4451    NR =
4452	case CR of
4453            {notifyReply, NotifyReply} ->
4454		NotifyReply;
4455	    _ ->
4456		throw({error, {invalid_commandReply, CR}})
4457	end,
4458    case NR of
4459	#'NotifyReply'{terminationID   = [TermId],
4460		       errorDescriptor = asn1_NOVALUE} ->
4461	    {ok, M};
4462	_ ->
4463	    {error, {invalid_notifyReply, NR}}
4464    end;
4465rarana_mg_verify_notify_rep_msg(Crap, _TermId, _TransId, _Rid, _Cid) ->
4466    {error, {invalid_message, Crap}}.
4467
4468rarana_mg_service_change_request_ar(_Mid, Cid) ->
4469    Prof  = cre_serviceChangeProf("resgw", 1),
4470    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
4471    Root  = #megaco_term_id{id = ["root"]},
4472    SCR   = cre_serviceChangeReq([Root], SCP),
4473    CMD   = cre_command(SCR),
4474    CR    = cre_cmdReq(CMD),
4475    cre_actionReq(Cid, [CR]).
4476
4477rarana_mg_service_change_request_msg(Mid, TransId, Cid) ->
4478    AR    = rarana_mg_service_change_request_ar(Mid, Cid),
4479    TR    = cre_transReq(TransId, [AR]),
4480    Trans = cre_transaction(TR),
4481    Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
4482    cre_megacoMessage(Mess).
4483
4484rarana_mg_notify_request_ar(Rid, Tid, Cid) ->
4485    TT      = cre_timeNotation("19990729", "22000000"),
4486    Ev      = cre_obsEvent("al/of", TT),
4487    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
4488    NR      = cre_notifyReq([Tid], EvsDesc),
4489    CMD     = cre_command(NR),
4490    CR      = cre_cmdReq(CMD),
4491    cre_actionReq(Cid, [CR]).
4492
4493rarana_mg_notify_request_msg(Mid, TermId, TransId, Rid, Cid) ->
4494    AR      = rarana_mg_notify_request_ar(Rid, TermId, Cid),
4495    TR      = cre_transReq(TransId, [AR]),
4496    Trans   = cre_transaction(TR),
4497    Mess    = cre_message(?VERSION, Mid, cre_transactions([Trans])),
4498    cre_megacoMessage(Mess).
4499
4500
4501%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4502
4503request_and_reply_and_late_ack(suite) ->
4504    [];
4505request_and_reply_and_late_ack(doc) ->
4506    ["This test case tests that megaco handles three-way-handshake "
4507     "when the ack is late (and requeire a retransmission)"];
4508request_and_reply_and_late_ack(Config) when is_list(Config) ->
4509    Pre = fun() ->
4510                  MgcNode = make_node_name(mgc),
4511                  MgNode  = make_node_name(mg),
4512                  d("start nodes: "
4513                    "~n   MgcNode: ~p"
4514                    "~n   MgNode:  ~p",
4515                    [MgcNode, MgNode]),
4516                  Nodes = [MgcNode, MgNode],
4517                  ok = ?START_NODES(Nodes, true),
4518                  Nodes
4519          end,
4520    Case = fun do_request_and_reply_and_late_ack/1,
4521    Post = fun(Nodes) ->
4522                   d("stop nodes"),
4523                   ?STOP_NODES(lists:reverse(Nodes))
4524           end,
4525    try_tc(rarala, Pre, Case, Post).
4526
4527do_request_and_reply_and_late_ack([MgcNode, MgNode]) ->
4528    d("[MGC] start the simulator "),
4529    {ok, Mgc} = megaco_test_megaco_generator:start_link("MGC", MgcNode),
4530
4531    d("[MGC] create the event sequence"),
4532    MgcEvSeq = rarala_mgc_event_sequence(text, tcp),
4533
4534    i("wait some time before starting the MGC simulation"),
4535    sleep(1000),
4536
4537    d("[MGC] start the simulation"),
4538    {ok, MgcId} = megaco_test_megaco_generator:exec(Mgc, MgcEvSeq),
4539
4540    %% i("wait some time before starting the MG simulator"),
4541    %% sleep(1000),
4542
4543    i("await MGC ready announcement"),
4544    receive
4545        announce_mgc ->
4546            i("received MGC ready announcement"),
4547            ok
4548    end,
4549
4550    d("[MG] start the simulator (generator)"),
4551    {ok, Mg} = megaco_test_tcp_generator:start_link("MG", MgNode),
4552
4553    d("[MG] create the event sequence"),
4554    MgEvSeq = rarala_mg_event_sequence(text, tcp),
4555
4556    i("wait some time before starting the MG simulation"),
4557    sleep(1000),
4558
4559    d("[MG] start the simulation"),
4560    {ok, MgId} = megaco_test_tcp_generator:exec(Mg, MgEvSeq),
4561
4562    d("await the generator reply(s)"),
4563    await_completion([MgcId, MgId]),
4564
4565    %% Tell Mgc to stop
4566    i("[MGC] stop generator"),
4567    megaco_test_megaco_generator:stop(Mgc),
4568
4569    %% Tell Mg to stop
4570    i("[MG] stop generator"),
4571    megaco_test_tcp_generator:stop(Mg),
4572
4573    i("done", []),
4574    ok.
4575
4576
4577%%
4578%% MGC generator stuff
4579%%
4580
4581-ifdef(megaco_hipe_special).
4582-define(rarala_mgc_verify_handle_connect_fun(),
4583        {?MODULE, rarala_mgc_verify_handle_connect, []}).
4584-define(rarala_mgc_verify_service_change_req_fun(Mid),
4585        {?MODULE, rarala_mgc_verify_service_change_req, [Mid]}).
4586-define(rarala_mgc_verify_notify_req_fun(),
4587        {?MODULE, rarala_mgc_verify_notify_req, []}).
4588-define(rarala_mgc_verify_handle_trans_ack_fun(),
4589	{?MODULE, rarala_mgc_verify_handle_trans_ack, []}).
4590-define(rarala_mgc_verify_handle_disconnect_fun(),
4591        {?MODULE, rarala_mgc_verify_handle_disconnect, []}).
4592-else.
4593-define(rarala_mgc_verify_handle_connect_fun(),
4594        fun rarala_mgc_verify_handle_connect/1).
4595-define(rarala_mgc_verify_service_change_req_fun(Mid),
4596        rarala_mgc_verify_service_change_req_fun(Mid)).
4597-define(rarala_mgc_verify_notify_req_fun(),
4598	rarala_mgc_verify_notify_req_fun()).
4599-define(rarala_mgc_verify_handle_trans_ack_fun(),
4600	rarala_mgc_verify_handle_trans_ack_fun()).
4601-define(rarala_mgc_verify_handle_disconnect_fun(),
4602	fun rarala_mgc_verify_handle_disconnect/1).
4603-endif.
4604
4605rarala_mgc_event_sequence(text, tcp) ->
4606    CTRL = self(),
4607    Mid = {deviceName,"ctrl"},
4608    RI = [
4609          {port,             2944},
4610          {encoding_module,  megaco_pretty_text_encoder},
4611          {encoding_config,  []},
4612          {transport_module, megaco_tcp}
4613         ],
4614    RepTmr = #megaco_incr_timer{wait_for    = 3000,
4615				factor      = 1,
4616				incr        = 0,
4617				max_retries = 2
4618			       },
4619    ConnectVerify = ?rarala_mgc_verify_handle_connect_fun(),
4620    ScrVerify     = ?rarala_mgc_verify_service_change_req_fun(Mid),
4621    NrVerify      = ?rarala_mgc_verify_notify_req_fun(),
4622    AckVerify     = ?rarala_mgc_verify_handle_trans_ack_fun(),
4623    DiscoVerify   = ?rarala_mgc_verify_handle_disconnect_fun(),
4624    EvSeq = [
4625             {debug, true},
4626             {megaco_trace, disable},
4627             {megaco_trace, max},
4628             megaco_start,
4629             {megaco_start_user, Mid, RI, []},
4630             {megaco_update_user_info, sent_pending_limit, 100},
4631             {megaco_update_user_info, reply_timer,        RepTmr},
4632             start_transport,
4633             listen,
4634
4635             %% ANNOUNCE READY
4636             {trigger, fun() -> CTRL ! announce_mgc end},
4637
4638             {megaco_callback, handle_connect,           ConnectVerify},
4639             {megaco_conn_info, all},
4640             {megaco_callback, handle_trans_request,     ScrVerify},
4641	     {megaco_callback, handle_trans_request,     NrVerify},
4642	     {megaco_callback, handle_trans_ack,         AckVerify},
4643             {megaco_callback, handle_disconnect,        DiscoVerify},
4644             megaco_stop_user,
4645             megaco_stop
4646            ],
4647    EvSeq.
4648
4649%% Connect verification
4650rarala_mgc_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
4651    {ok, CH, ok};
4652rarala_mgc_verify_handle_connect(Else) ->
4653    {error, Else, ok}.
4654
4655%% Service Change verification
4656-ifndef(megaco_hipe_special).
4657rarala_mgc_verify_service_change_req_fun(Mid) ->
4658    fun(Req) ->
4659	    rarala_mgc_verify_service_change_req(Req, Mid)
4660    end.
4661-endif.
4662
4663rarala_mgc_verify_service_change_req(
4664  {handle_trans_request, _, ?VERSION, [AR]}, Mid) ->
4665    (catch rarala_do_verify_service_change_req(AR, Mid));
4666rarala_mgc_verify_service_change_req(Crap, _Mid) ->
4667    ED       = cre_ErrDesc(Crap),
4668    ErrReply = {discard_ack, ED},
4669    {error, Crap, ErrReply}.
4670
4671rarala_do_verify_service_change_req(AR, Mid) ->
4672    io:format("rarala_mgc_do_verify_service_change_req -> entry with"
4673	      "~n   AR:  ~p"
4674	      "~n   Mid: ~p"
4675	      "~n", [AR, Mid]),
4676    CR =
4677	case AR of
4678	    #'ActionRequest'{commandRequests = [CmdReq]} ->
4679		CmdReq;
4680	    _ ->
4681		Err1      = {invalid_action_request, AR},
4682		ED1       = cre_ErrDesc(AR),
4683		ErrReply1 = {discard_ack, ED1},
4684		throw({error, Err1, ErrReply1})
4685	end,
4686    Cmd =
4687	case CR of
4688	    #'CommandRequest'{command = Command} ->
4689		Command;
4690	    _ ->
4691		Err2      = {invalid_command_request, CR},
4692		ED2       = cre_ErrDesc(CR),
4693		ErrReply2 = {discard_ack, ED2},
4694		throw({error, Err2, ErrReply2})
4695	end,
4696    {Tid, Parms} =
4697	case Cmd of
4698	    {serviceChangeReq,
4699	     #'ServiceChangeRequest'{terminationID = [TermID],
4700				     serviceChangeParms = ServChParms}} ->
4701		{TermID, ServChParms};
4702	    _ ->
4703		Err3      = {invalid_command, Cmd},
4704		ED3       = cre_ErrDesc(Cmd),
4705		ErrReply3 = {discard_ack, ED3},
4706		throw({error, Err3, ErrReply3})
4707	end,
4708    case Tid of
4709	#megaco_term_id{contains_wildcards = false, id = ["root"]} ->
4710	    ok;
4711	_ ->
4712	    Err4      = {invalid_termination_id, Tid},
4713	    ED4       = cre_ErrDesc(Tid),
4714	    ErrReply4 = {discard_ack, ED4},
4715	    throw({error, Err4, ErrReply4})
4716    end,
4717    case Parms of
4718	#'ServiceChangeParm'{serviceChangeMethod = restart,
4719			     serviceChangeReason = [[$9,$0,$1|_]]} ->
4720	    AckData = [rarala_mgc_service_change_reply_ar(Mid, 1)],
4721	    Reply   = {discard_ack, AckData},
4722	    {ok, AR, Reply};
4723	_ ->
4724	    Err5      = {invalid_SCP, Parms},
4725	    ED5       = cre_ErrDesc(Parms),
4726	    ErrReply5 = {discard_ack, ED5},
4727	    {error, Err5, ErrReply5}
4728    end.
4729
4730
4731%% Notify Request verification
4732-ifndef(megaco_hipe_special).
4733rarala_mgc_verify_notify_req_fun() ->
4734    fun(Req) ->
4735	    rarala_mgc_verify_notify_req(Req)
4736    end.
4737-endif.
4738
4739rarala_mgc_verify_notify_req({handle_trans_request, _, ?VERSION, [AR]}) ->
4740    (catch rarala_mgc_do_verify_notify_req(AR));
4741rarala_mgc_verify_notify_req(Crap) ->
4742    ED       = cre_ErrDesc(Crap),
4743    ErrReply = {discard_ack, ED},
4744    {error, Crap, ErrReply}.
4745
4746rarala_mgc_do_verify_notify_req(AR) ->
4747    io:format("rarala_mgc_do_verify_notify_req -> entry with"
4748	      "~n   AR: ~p"
4749	      "~n", [AR]),
4750    {Cid, CR} =
4751	case AR of
4752	    #'ActionRequest'{contextId       = CtxID,
4753			     commandRequests = [CmdReq]} ->
4754		{CtxID, CmdReq};
4755	    _ ->
4756		Err1      = {invalid_action_request, AR},
4757		ED1       = cre_ErrDesc(AR),
4758		ErrReply1 = {discard_ack, ED1},
4759		throw({error, Err1, ErrReply1})
4760	end,
4761    Cmd =
4762	case CR of
4763	    #'CommandRequest'{command = Command} ->
4764		Command;
4765	    _ ->
4766		Err2      = {invalid_command_request, CR},
4767		ED2       = cre_ErrDesc(CR),
4768		ErrReply2 = {discard_ack, ED2},
4769		throw({error, Err2, ErrReply2})
4770	end,
4771    NR =
4772	case Cmd of
4773	    {notifyReq, NotifReq} ->
4774		NotifReq;
4775	    _ ->
4776		Err3      = {invalid_command, Cmd},
4777		ED3       = cre_ErrDesc(Cmd),
4778		ErrReply3 = {discard_ack, ED3},
4779		throw({error, Err3, ErrReply3})
4780	end,
4781    {Tid, OED} =
4782	case NR of
4783	    #'NotifyRequest'{terminationID            = [TermID],
4784			     observedEventsDescriptor = ObsEvsDesc,
4785			     errorDescriptor          = asn1_NOVALUE} ->
4786		{TermID, ObsEvsDesc};
4787	    _ ->
4788		Err4      = {invalid_NR, NR},
4789		ED4       = cre_ErrDesc(NR),
4790		ErrReply4 = {discard_ack, ED4},
4791		throw({error, Err4, ErrReply4})
4792	end,
4793    OE =
4794	case OED of
4795	    #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
4796		ObsEvLst;
4797	    _ ->
4798		Err5      = {invalid_OED, OED},
4799		ED5       = cre_ErrDesc(NR),
4800		ErrReply5 = {discard_ack, ED5},
4801		throw({error, Err5, ErrReply5})
4802	end,
4803    case OE of
4804	#'ObservedEvent'{eventName = "al/of"} ->
4805	    AckData = rarala,
4806	    Replies = [rarala_mgc_notify_reply_ar(Cid, Tid)],
4807	    Reply   = {{handle_ack, AckData}, Replies},
4808	    {ok, AR, Reply};
4809	_ ->
4810	    Err6      = {invalid_OE, OE},
4811	    ED6       = cre_ErrDesc(OE),
4812	    ErrReply6 = {discard_ack, ED6},
4813	    throw({error, Err6, ErrReply6})
4814    end.
4815
4816
4817-ifndef(megaco_hipe_special).
4818rarala_mgc_verify_handle_trans_ack_fun() ->
4819    fun(Ack) ->
4820	    rarala_mgc_verify_handle_trans_ack(Ack)
4821    end.
4822-endif.
4823
4824rarala_mgc_verify_handle_trans_ack(
4825  {handle_trans_ack, CH, ?VERSION, ok, rarala}) ->
4826    io:format("rarala_mgc_verify_handle_trans_ack -> ok"
4827              "~n   CH: ~p"
4828              "~n", [CH]),
4829    {ok, CH, ok};
4830rarala_mgc_verify_handle_trans_ack(Crap) ->
4831    io:format("rarala_mgc_verify_handle_trans_ack -> unknown"
4832              "~n   Crap: ~p~n", [Crap]),
4833    {error, Crap, ok}.
4834
4835
4836%% Disconnect verification
4837rarala_mgc_verify_handle_disconnect({handle_disconnect, CH, ?VERSION, _R}) ->
4838    {ok, CH, ok};
4839rarala_mgc_verify_handle_disconnect(Else) ->
4840    {error, Else, ok}.
4841
4842rarala_mgc_service_change_reply_ar(Mid, Cid) ->
4843    SCRP  = cre_serviceChangeResParm(Mid),
4844    SCRes = cre_serviceChangeResult(SCRP),
4845    Root  = #megaco_term_id{id = ["root"]},
4846    SCR   = cre_serviceChangeReply([Root], SCRes),
4847    CR    = cre_cmdReply(SCR),
4848    AR    = cre_actionReply(Cid, [CR]),
4849    AR.
4850
4851rarala_mgc_notify_reply_ar(Cid, TermId) ->
4852    NR    = cre_notifyReply([TermId]),
4853    CR    = cre_cmdReply(NR),
4854    cre_actionReply(Cid, [CR]).
4855
4856
4857%%
4858%% MG generator stuff
4859%%
4860-ifdef(megaco_hipe_special).
4861-define(rarala_mg_decode_msg_fun(Mod, Conf),
4862	{?MODULE, decode_msg, [Mod, Conf]}).
4863-define(rarala_mg_encode_msg_fun(Mod, Conf),
4864	{?MODULE, encode_msg, [Mod, Conf]}).
4865-define(rarala_mg_verify_service_change_rep_msg_fun(),
4866	{?MODULE, rarala_mg_verify_service_change_rep_msg, []}).
4867-define(rarala_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId),
4868	{?MODULE, rarala_mg_verify_notify_rep_msg, [TermId, TransId, ReqId, CtxId]}).
4869-else.
4870-define(rarala_mg_decode_msg_fun(Mod, Conf),
4871	rarala_mg_decode_msg_fun(Mod, Conf)).
4872-define(rarala_mg_encode_msg_fun(Mod, Conf),
4873	rarala_mg_encode_msg_fun(Mod, Conf)).
4874-define(rarala_mg_verify_service_change_rep_msg_fun(),
4875	rarala_mg_verify_service_change_rep_msg_fun()).
4876-define(rarala_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId),
4877	rarala_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId)).
4878-endif.
4879
4880rarala_mg_event_sequence(text, tcp) ->
4881    DecodeFun = ?rarala_mg_decode_msg_fun(megaco_pretty_text_encoder, []),
4882    EncodeFun = ?rarala_mg_encode_msg_fun(megaco_pretty_text_encoder, []),
4883    Mid       = {deviceName,"mg"},
4884    ServiceChangeReq = rarala_mg_service_change_request_msg(Mid, 1, 0),
4885    TermId  = #megaco_term_id{id = ["00000000","00000000","01101101"]},
4886    TransId = 2,
4887    ReqId   = 1,
4888    CtxId   = 1,
4889    NotifyReq = rarala_mg_notify_request_msg(Mid, TermId,
4890					    TransId, ReqId, CtxId),
4891    TransAck = rarala_mg_trans_ack_msg(Mid, TransId),
4892    ScrVerifyFun = ?rarala_mg_verify_service_change_rep_msg_fun(),
4893    NrVerifyFun  = ?rarala_mg_verify_notify_rep_msg_fun(TermId,
4894							TransId, ReqId, CtxId),
4895    EvSeq = [{debug,  true},
4896             {decode, DecodeFun},
4897             {encode, EncodeFun},
4898             {connect, 2944},
4899             {send, "service-change-request", ServiceChangeReq},
4900             {expect_receive, "service-change-reply", {ScrVerifyFun, 10000}},
4901             {send, "notify request", NotifyReq},
4902             {expect_receive, "notify-reply", {NrVerifyFun, 4000}},
4903             {expect_receive, "notify-reply", {NrVerifyFun, 4000}},
4904             {expect_receive, "notify-reply", {NrVerifyFun, 4000}},
4905             {send, "transaction-ack", TransAck},
4906             {expect_nothing, 11000},
4907             disconnect
4908            ],
4909    EvSeq.
4910
4911-ifndef(megaco_hipe_special).
4912rarala_mg_encode_msg_fun(Mod, Conf) ->
4913    fun(M) ->
4914            encode_msg(M, Mod, Conf)
4915    end.
4916-endif.
4917
4918-ifndef(megaco_hipe_special).
4919rarala_mg_decode_msg_fun(Mod, Conf) ->
4920    fun(M) ->
4921            decode_msg(M, Mod, Conf)
4922    end.
4923-endif.
4924
4925-ifndef(megaco_hipe_special).
4926rarala_mg_verify_service_change_rep_msg_fun() ->
4927    fun(Msg) ->
4928	    (catch rarala_mg_verify_service_change_rep_msg(Msg))
4929    end.
4930-endif.
4931
4932rarala_mg_verify_service_change_rep_msg(#'MegacoMessage'{mess = Mess} = M) ->
4933    Body =
4934	case Mess of
4935	    #'Message'{version     = _V,
4936                       mId         = _MgMid,
4937                       messageBody = MsgBody} ->
4938		MsgBody;
4939	    _ ->
4940		throw({error, {invalid_Message, Mess}})
4941	end,
4942    Trans =
4943	case Body of
4944            {transactions, [Transactions]} ->
4945		Transactions;
4946	    _ ->
4947		throw({error, {invalid_messageBody, Body}})
4948	end,
4949    TR =
4950	case Trans of
4951            {transactionReply, TransReply} ->
4952		TransReply;
4953	    _ ->
4954		throw({error, {invalid_transactions, Trans}})
4955	end,
4956    TRes =
4957	case TR of
4958            #'TransactionReply'{transactionId = _Tid,
4959                                immAckRequired = asn1_NOVALUE,
4960                                transactionResult = TransRes} ->
4961		TransRes;
4962	    _ ->
4963		throw({error, {invalid_transactionReply, TR}})
4964	end,
4965    AR =
4966	case TRes of
4967            {actionReplies, [ActRes]} ->
4968		ActRes;
4969	    _ ->
4970		throw({error, {invalid_transactionResult, TRes}})
4971	end,
4972    CR =
4973	case AR of
4974            #'ActionReply'{contextId       = _Cid,
4975                           errorDescriptor = asn1_NOVALUE,
4976                           contextReply    = _CtxReq,
4977                           commandReply    = [CmdRep]} ->
4978		CmdRep;
4979	    _ ->
4980		throw({error, {invalid_actionReplies, AR}})
4981	end,
4982    SCR =
4983	case CR of
4984            {serviceChangeReply, ServChRep} ->
4985		ServChRep;
4986	    _ ->
4987		throw({error, {invalid_commandReply, CR}})
4988	end,
4989    SCRes =
4990	case SCR of
4991            #'ServiceChangeReply'{terminationID       = _TermID,
4992                                  serviceChangeResult = ServChRes} ->
4993		ServChRes;
4994	    _ ->
4995		throw({error, {invalid_serviceChangeReply, SCR}})
4996	end,
4997    SCRP =
4998	case SCRes of
4999            {serviceChangeResParms, Parms} ->
5000		Parms;
5001	    _ ->
5002		throw({error, {invalid_serviceChangeResult, SCRes}})
5003	end,
5004    case SCRP of
5005	#'ServiceChangeResParm'{serviceChangeMgcId = _MgcMid} ->
5006            {ok, M};
5007	_ ->
5008	    {error, {invalid_serviceChangeResParms, SCRP}}
5009    end;
5010rarala_mg_verify_service_change_rep_msg(Crap) ->
5011    {error, {invalid_message, Crap}}.
5012
5013-ifndef(megaco_hipe_special).
5014rarala_mg_verify_notify_rep_msg_fun(TermId, TransId, Rid, Cid) ->
5015    fun(Msg) ->
5016	    (catch rarala_mg_verify_notify_rep_msg(Msg,
5017						   TermId, TransId, Rid, Cid))
5018    end.
5019-endif.
5020
5021rarala_mg_verify_notify_rep_msg(#'MegacoMessage'{mess = Mess} = M,
5022				TermId, TransId, Rid, Cid) ->
5023    io:format("rarala_mg_verify_notify_rep_msg -> entry with"
5024	      "~n   M:       ~p"
5025	      "~n   TermId:  ~p"
5026	      "~n   TransId: ~p"
5027	      "~n   Rid:     ~p"
5028	      "~n   Cid:     ~p"
5029	      "~n", [M, TermId, TransId, Rid, Cid]),
5030    Body =
5031	case Mess of
5032	    #'Message'{version     = ?VERSION,
5033                       mId         = _Mid,
5034                       messageBody = MsgBody} ->
5035		MsgBody;
5036	    _ ->
5037		throw({error, {invalid_Message, Mess}})
5038	end,
5039    Trans =
5040	case Body of
5041            {transactions, [Transactions]} ->
5042		Transactions;
5043	    _ ->
5044		throw({error, {invalid_messageBody, Body}})
5045	end,
5046    TR =
5047	case Trans of
5048            {transactionReply, TransReply} ->
5049		TransReply;
5050	    _ ->
5051		throw({error, {invalid_transactions, Trans}})
5052	end,
5053    TRes =
5054	case TR of
5055            #'TransactionReply'{transactionId     = TransId,
5056                                immAckRequired    = 'NULL',
5057                                transactionResult = TransRes} ->
5058		TransRes;
5059	    _ ->
5060		throw({error, {invalid_transactionReply, TR}})
5061	end,
5062    AR =
5063	case TRes of
5064            {actionReplies, [ActRes]} ->
5065		ActRes;
5066	    _ ->
5067		throw({error, {invalid_transactionResult, TRes}})
5068	end,
5069    CR =
5070	case AR of
5071            #'ActionReply'{contextId       = Cid,
5072                           errorDescriptor = asn1_NOVALUE,
5073                           contextReply    = _CtxReq,
5074                           commandReply    = [CmdRep]} ->
5075		CmdRep;
5076	    _ ->
5077		throw({error, {invalid_actionReplies, AR}})
5078	end,
5079    NR =
5080	case CR of
5081            {notifyReply, NotifyReply} ->
5082		NotifyReply;
5083	    _ ->
5084		throw({error, {invalid_commandReply, CR}})
5085	end,
5086    case NR of
5087	#'NotifyReply'{terminationID   = [TermId],
5088		       errorDescriptor = asn1_NOVALUE} ->
5089	    {ok, M};
5090	_ ->
5091	    {error, {invalid_notifyReply, NR}}
5092    end;
5093rarala_mg_verify_notify_rep_msg(Crap, _TermId, _TransId, _Rid, _Cid) ->
5094    {error, {invalid_message, Crap}}.
5095
5096rarala_mg_service_change_request_ar(_Mid, Cid) ->
5097    Prof  = cre_serviceChangeProf("resgw", 1),
5098    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
5099    Root  = #megaco_term_id{id = ["root"]},
5100    SCR   = cre_serviceChangeReq([Root], SCP),
5101    CMD   = cre_command(SCR),
5102    CR    = cre_cmdReq(CMD),
5103    cre_actionReq(Cid, [CR]).
5104
5105rarala_mg_service_change_request_msg(Mid, TransId, Cid) ->
5106    AR    = rarala_mg_service_change_request_ar(Mid, Cid),
5107    TR    = cre_transReq(TransId, [AR]),
5108    Trans = cre_transaction(TR),
5109    Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
5110    cre_megacoMessage(Mess).
5111
5112rarala_mg_notify_request_ar(Rid, Tid, Cid) ->
5113    TT      = cre_timeNotation("19990729", "22000000"),
5114    Ev      = cre_obsEvent("al/of", TT),
5115    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
5116    NR      = cre_notifyReq([Tid], EvsDesc),
5117    CMD     = cre_command(NR),
5118    CR      = cre_cmdReq(CMD),
5119    cre_actionReq(Cid, [CR]).
5120
5121rarala_mg_notify_request_msg(Mid, TermId, TransId, Rid, Cid) ->
5122    AR      = rarala_mg_notify_request_ar(Rid, TermId, Cid),
5123    TR      = cre_transReq(TransId, [AR]),
5124    Trans   = cre_transaction(TR),
5125    Mess    = cre_message(?VERSION, Mid, cre_transactions([Trans])),
5126    cre_megacoMessage(Mess).
5127
5128rarala_mg_trans_ack_msg(Mid, TransId) ->
5129    TR    = cre_transRespAck(cre_transAck(TransId)),
5130    Trans = cre_transaction(TR),
5131    Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
5132    cre_megacoMessage(Mess).
5133
5134
5135
5136%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5137
5138trans_req_and_reply_and_req(suite) ->
5139    [];
5140trans_req_and_reply_and_req(doc) ->
5141    ["Receive a transaction request, send a reply (discard ack)"
5142     "then receive the same reply again after the timeout. "
5143     "The MGC is a megaco instance (megaco event sequence) and the "
5144     "MG is emulated (tcp event sequence)"];
5145trans_req_and_reply_and_req(Config) when is_list(Config) ->
5146    Pre = fun() ->
5147                  %% <CONDITIONAL-SKIP>
5148                  Skippable = [{unix, [darwin, linux]}],
5149                  Condition = fun() -> ?OS_BASED_SKIP(Skippable) end,
5150                  ?NON_PC_TC_MAYBE_SKIP(Config, Condition),
5151                  %% </CONDITIONAL-SKIP>
5152
5153                  MgcNode = make_node_name(mgc),
5154                  MgNode  = make_node_name(mg),
5155                  d("start nodes: "
5156                    "~n      MgcNode: ~p"
5157                    "~n      MgNode:  ~p",
5158                    [MgcNode, MgNode]),
5159                  Nodes = [MgcNode, MgNode],
5160                  ok = ?START_NODES(Nodes, true),
5161                  Nodes
5162          end,
5163    Case = fun do_trans_req_and_reply_and_req/1,
5164    Post = fun(Nodes) ->
5165                   d("stop nodes"),
5166                   ?STOP_NODES(lists:reverse(Nodes))
5167           end,
5168    try_tc(request_and_no_reply, Pre, Case, Post).
5169
5170do_trans_req_and_reply_and_req([MgcNode, MgNode]) ->
5171    d("[MGC] start the simulator "),
5172    {ok, Mgc} = megaco_test_megaco_generator:start_link("MGC", MgcNode),
5173
5174    d("[MGC] create the event sequence"),
5175    MgcEvSeq = trarar_mgc_event_sequence(text, tcp),
5176
5177    i("wait some time before starting the MGC simulation"),
5178    sleep(1000),
5179
5180    d("[MGC] start the simulation"),
5181    {ok, MgcId} = megaco_test_megaco_generator:exec(Mgc, MgcEvSeq),
5182
5183    %% i("wait some time before starting the MG simulator"),
5184    %% sleep(1000),
5185
5186    i("await MGC ready announcement"),
5187    receive
5188        announce_mgc ->
5189            i("received MGC ready announcement"),
5190            ok
5191    end,
5192
5193    d("[MG] start the simulator (generator)"),
5194    {ok, Mg} = megaco_test_tcp_generator:start_link("MG", MgNode),
5195
5196    d("[MG] create the event sequence"),
5197    MgEvSeq = trarar_mg_event_sequence(text, tcp),
5198
5199    i("wait some time before starting the MG simulation"),
5200    sleep(1000),
5201
5202    d("[MG] start the simulation"),
5203    {ok, MgId} = megaco_test_tcp_generator:exec(Mg, MgEvSeq),
5204
5205    d("await the generator reply(s)"),
5206    await_completion([MgcId, MgId], 60000),
5207
5208    %% Tell Mgc to stop
5209    i("[MGC] stop generator"),
5210    megaco_test_megaco_generator:stop(Mgc),
5211
5212    %% Tell Mg to stop
5213    i("[MG] stop generator"),
5214    megaco_test_tcp_generator:stop(Mg),
5215
5216    i("done", []),
5217    ok.
5218
5219
5220%%
5221%% MGC generator stuff
5222%%
5223-ifdef(megaco_hipe_special).
5224-define(trarar_mgc_verify_handle_connect_fun(),
5225        {?MODULE, trarar_mgc_verify_handle_connect, []}).
5226-define(trarar_mgc_verify_service_change_req_fun(Mid),
5227        {?MODULE, trarar_mgc_verify_service_change_req, [Mid]}).
5228-define(trarar_mgc_verify_notify_req_fun(Cid),
5229        {?MODULE, trarar_mgc_verify_notify_req, [Cid]}).
5230-define(trarar_mgc_verify_handle_disconnect_fun(),
5231        {?MODULE, trarar_mgc_verify_handle_disconnect, []}).
5232-else.
5233-define(trarar_mgc_verify_handle_connect_fun(),
5234        fun trarar_mgc_verify_handle_connect/1).
5235-define(trarar_mgc_verify_service_change_req_fun(Mid),
5236        trarar_mgc_verify_service_change_req_fun(Mid)).
5237-define(trarar_mgc_verify_notify_req_fun(Cid),
5238	trarar_mgc_verify_notify_req_fun(Cid)).
5239-define(trarar_mgc_verify_handle_disconnect_fun(),
5240	fun trarar_mgc_verify_handle_disconnect/1).
5241-endif.
5242
5243trarar_mgc_event_sequence(text, tcp) ->
5244    CTRL = self(),
5245    Mid = {deviceName,"ctrl"},
5246    RI = [
5247	  {port,             2944},
5248	  {encoding_module,  megaco_pretty_text_encoder},
5249	  {encoding_config,  []},
5250	  {transport_module, megaco_tcp}
5251	 ],
5252    ConnectVerify          = ?trarar_mgc_verify_handle_connect_fun(),
5253    ServiceChangeReqVerify = ?trarar_mgc_verify_service_change_req_fun(Mid),
5254    NotifyReqVerify1       = ?trarar_mgc_verify_notify_req_fun(1),
5255    NotifyReqVerify2       = ?trarar_mgc_verify_notify_req_fun(2),
5256    NotifyReqVerify3       = ?trarar_mgc_verify_notify_req_fun(3),
5257    NotifyReqVerify4       = ?trarar_mgc_verify_notify_req_fun(4),
5258    DiscoVerify            = ?trarar_mgc_verify_handle_disconnect_fun(),
5259    EvSeq = [
5260	     {debug, true},
5261	     {megaco_trace, disable},
5262	     megaco_start,
5263	     {megaco_start_user, Mid, RI, []},
5264             {megaco_update_user_info, reply_timer, 2000},
5265	     start_transport,
5266	     listen,
5267
5268             %% ANNOUNCE READY
5269             {trigger, fun() -> CTRL ! announce_mgc end},
5270
5271	     {megaco_callback, handle_connect,       ConnectVerify},
5272	     {megaco_callback, handle_trans_request, ServiceChangeReqVerify},
5273	     {megaco_callback, handle_trans_request, NotifyReqVerify1},
5274	     {megaco_callback, handle_trans_request, NotifyReqVerify2},
5275             {megaco_update_conn_info, reply_timer,  4000},
5276	     {megaco_callback, handle_trans_request, NotifyReqVerify3},
5277	     {megaco_callback, handle_trans_request, NotifyReqVerify4},
5278	     {megaco_callback, handle_disconnect,    DiscoVerify},
5279	     {sleep, 1000},
5280	     megaco_stop_user,
5281	     megaco_stop
5282	    ],
5283    EvSeq.
5284
5285
5286trarar_mgc_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
5287    io:format("trarar_mgc_verify_handle_connect -> ok"
5288	      "~n   CH: ~p~n", [CH]),
5289    {ok, CH, ok};
5290trarar_mgc_verify_handle_connect(Else) ->
5291    io:format("trarar_mgc_verify_handle_connect -> unknown"
5292	      "~n   Else: ~p~n", [Else]),
5293    {error, Else, ok}.
5294
5295-ifndef(megaco_hipe_special).
5296trarar_mgc_verify_service_change_req_fun(Mid) ->
5297    fun(Req) ->
5298	    trarar_mgc_verify_service_change_req(Req, Mid)
5299    end.
5300-endif.
5301
5302trarar_mgc_verify_service_change_req(
5303  {handle_trans_request, _, ?VERSION, [AR]}, Mid) ->
5304    (catch trarar_mgc_do_verify_service_change_req(AR, Mid));
5305trarar_mgc_verify_service_change_req(Crap, _Mid) ->
5306    ED = cre_ErrDesc(Crap),
5307    ErrReply = {discard_ack, ED},
5308    {error, Crap, ErrReply}.
5309
5310trarar_mgc_do_verify_service_change_req(AR, Mid) ->
5311    io:format("trarar_mgc_verify_service_change_req -> ok"
5312	      "~n   AR:  ~p"
5313	      "~n   Mid: ~p"
5314	      "~n", [AR, Mid]),
5315    CR =
5316	case AR of
5317	    #'ActionRequest'{commandRequests = [CmdReq]} ->
5318		CmdReq;
5319	    _ ->
5320                Err1      = {invalid_action_request, AR},
5321                ED1       = cre_ErrDesc(AR),
5322                ErrReply1 = {discard_ack, ED1},
5323                throw({error, Err1, ErrReply1})
5324	end,
5325    Cmd =
5326        case CR of
5327            #'CommandRequest'{command = Command} ->
5328                Command;
5329            _ ->
5330                Err2      = {invalid_command_request, CR},
5331                ED2       = cre_ErrDesc(CR),
5332                ErrReply2 = {discard_ack, ED2},
5333                throw({error, Err2, ErrReply2})
5334        end,
5335    {Tid, Parms} =
5336        case Cmd of
5337            {serviceChangeReq,
5338             #'ServiceChangeRequest'{terminationID = [TermID],
5339                                     serviceChangeParms = ServChParms}} ->
5340                {TermID, ServChParms};
5341            _ ->
5342                Err3      = {invalid_command, Cmd},
5343                ED3       = cre_ErrDesc(Cmd),
5344                ErrReply3 = {discard_ack, ED3},
5345                throw({error, Err3, ErrReply3})
5346        end,
5347    case Tid of
5348        #megaco_term_id{contains_wildcards = false, id = ["root"]} ->
5349            ok;
5350        _ ->
5351            Err4      = {invalid_termination_id, Tid},
5352            ED4       = cre_ErrDesc(Tid),
5353            ErrReply4 = {discard_ack, ED4},
5354            throw({error, Err4, ErrReply4})
5355    end,
5356    case Parms of
5357        #'ServiceChangeParm'{serviceChangeMethod = restart,
5358                             serviceChangeReason = [[$9,$0,$1|_]]} ->
5359            AckData = [trarar_mgc_service_change_reply_ar(Mid, 1)],
5360            Reply   = {discard_ack, AckData},
5361            {ok, AR, Reply};
5362        _ ->
5363            Err5      = {invalid_SCP, Parms},
5364            ED5       = cre_ErrDesc(Parms),
5365            ErrReply5 = {discard_ack, ED5},
5366            {error, Err5, ErrReply5}
5367    end.
5368
5369-ifndef(megaco_hipe_special).
5370trarar_mgc_verify_notify_req_fun(Cid) ->
5371    fun(Req) ->
5372	    trarar_mgc_verify_notify_req(Req, Cid)
5373    end.
5374-endif.
5375
5376trarar_mgc_verify_notify_req({handle_trans_request, _, ?VERSION, [AR]}, Cid) ->
5377    (catch trarar_mgc_do_verify_notify_req(AR, Cid));
5378trarar_mgc_verify_notify_req(Crap, _Cid) ->
5379    ED       = cre_ErrDesc(Crap),
5380    ErrReply = {discard_ack, ED},
5381    {error, Crap, ErrReply}.
5382
5383trarar_mgc_do_verify_notify_req(AR, Cid) ->
5384    io:format("trarar_mgc_do_verify_notify_req -> entry with"
5385	      "~n   AR:  ~p"
5386	      "~n   Cid: ~p"
5387	      "~n", [AR, Cid]),
5388    {ContextID, CR} =
5389	case AR of
5390	    #'ActionRequest'{contextId       = CtxID,
5391			     commandRequests = [CmdReq]} when (CtxID == Cid) ->
5392		{CtxID, CmdReq};
5393	    _ ->
5394                Err1      = {invalid_action_request, AR},
5395                ED1       = cre_ErrDesc(AR),
5396                ErrReply1 = {discard_ack, ED1},
5397                throw({error, Err1, ErrReply1})
5398        end,
5399    Cmd =
5400	case CR of
5401	    #'CommandRequest'{command = Command} ->
5402		Command;
5403	    _ ->
5404                Err2      = {invalid_command_request, CR},
5405                ED2       = cre_ErrDesc(CR),
5406                ErrReply2 = {discard_ack, ED2},
5407                throw({error, Err2, ErrReply2})
5408        end,
5409    NR =
5410        case Cmd of
5411	    {notifyReq, NotifReq} ->
5412		NotifReq;
5413	    _ ->
5414                Err3      = {invalid_command, Cmd},
5415                ED3       = cre_ErrDesc(Cmd),
5416                ErrReply3 = {discard_ack, ED3},
5417                throw({error, Err3, ErrReply3})
5418        end,
5419    {Tid, OED} =
5420        case NR of
5421            #'NotifyRequest'{terminationID            = [TermID],
5422                             observedEventsDescriptor = ObsEvsDesc,
5423                             errorDescriptor          = asn1_NOVALUE} ->
5424                {TermID, ObsEvsDesc};
5425            _ ->
5426                Err4      = {invalid_NR, NR},
5427                ED4       = cre_ErrDesc(NR),
5428                ErrReply4 = {discard_ack, ED4},
5429                throw({error, Err4, ErrReply4})
5430        end,
5431    OE =
5432	case OED of
5433	    #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
5434		ObsEvLst;
5435            _ ->
5436                Err5      = {invalid_OED, OED},
5437                ED5       = cre_ErrDesc(NR),
5438                ErrReply5 = {discard_ack, ED5},
5439                throw({error, Err5, ErrReply5})
5440        end,
5441    case OE of
5442	#'ObservedEvent'{eventName = "al/of"} ->
5443            Replies = [trarar_mgc_notify_reply_ar(ContextID, Tid)],
5444            Reply   = {discard_ack, Replies},
5445            {ok, AR, Reply};
5446        _ ->
5447            Err6      = {invalid_OE, OE},
5448            ED6       = cre_ErrDesc(OE),
5449            ErrReply6 = {discard_ack, ED6},
5450            {error, Err6, ErrReply6}
5451    end.
5452
5453trarar_mgc_verify_handle_disconnect({handle_disconnect, CH, ?VERSION, R}) ->
5454    io:format("trarar_mgc_verify_handle_disconnect -> ok"
5455	      "~n   CH: ~p"
5456	      "~n   R:  ~p"
5457	      "~n", [CH, R]),
5458    {ok, CH, ok};
5459trarar_mgc_verify_handle_disconnect(Else) ->
5460    io:format("trarar_mgc_verify_handle_disconnect -> unknown"
5461	      "~n   Else: ~p~n", [Else]),
5462    {error, Else, ok}.
5463
5464
5465trarar_mgc_service_change_reply_ar(Mid, Cid) ->
5466    SCRP  = cre_serviceChangeResParm(Mid),
5467    SCRes = cre_serviceChangeResult(SCRP),
5468    Root  = #megaco_term_id{id = ["root"]},
5469    SCR   = cre_serviceChangeReply([Root], SCRes),
5470    CR    = cre_cmdReply(SCR),
5471    cre_actionReply(Cid, [CR]).
5472
5473trarar_mgc_notify_reply_ar(Cid, TermId) ->
5474    NR    = cre_notifyReply([TermId]),
5475    CR    = cre_cmdReply(NR),
5476    cre_actionReply(Cid, [CR]).
5477
5478%% trarar_mgc_notify_reply(Mid, TransId, Cid, TermId) ->
5479%%     AR    = trarar_mgc_notify_reply_ar(Cid, TermId),
5480%%     TRes  = cre_transResult([AR]),
5481%%     TR    = cre_transReply(TransId, TRes),
5482%%     Trans = cre_transaction(TR),
5483%%     Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
5484%%     cre_megacoMessage(Mess).
5485
5486
5487%%
5488%% MG generator stuff
5489%%
5490-ifdef(megaco_hipe_special).
5491-define(trarar_mg_decode_msg_fun(Mod, Conf),
5492	{?MODULE, decode_msg, [Mod, Conf]}).
5493-define(trarar_mg_encode_msg_fun(Mod, Conf),
5494	{?MODULE, encode_msg, [Mod, Conf]}).
5495-define(trarar_mg_verify_service_change_rep_msg_fun(),
5496	{?MODULE, trarar_mg_verify_service_change_rep_msg, []}).
5497-define(trarar_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId),
5498	{?MODULE, trarar_mg_verify_notify_rep_msg, [TermId, TransId, ReqId, CtxId]}).
5499-else.
5500-define(trarar_mg_decode_msg_fun(Mod, Conf),
5501	trarar_mg_decode_msg_fun(Mod, Conf)).
5502-define(trarar_mg_encode_msg_fun(Mod, Conf),
5503	trarar_mg_encode_msg_fun(Mod, Conf)).
5504-define(trarar_mg_verify_service_change_rep_msg_fun(),
5505	trarar_mg_verify_service_change_rep_msg_fun()).
5506-define(trarar_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId),
5507	trarar_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId)).
5508-endif.
5509
5510trarar_mg_event_sequence(text, tcp) ->
5511    DecodeFun = ?trarar_mg_decode_msg_fun(megaco_pretty_text_encoder, []),
5512    EncodeFun = ?trarar_mg_encode_msg_fun(megaco_pretty_text_encoder, []),
5513    Mid       = {deviceName,"mg"},
5514    ServiceChangeReq = trarar_mg_service_change_request_msg(Mid, 1, 0),
5515    TermId  = #megaco_term_id{id = ["00000000","00000000","01101101"]},
5516    NotifyReq1 =
5517	trarar_mg_notify_request_msg(Mid, TermId, 2, 1, 1),
5518    NotifyReq2 =
5519	trarar_mg_notify_request_msg(Mid, TermId, 2, 2, 2),
5520    NotifyReq3 =
5521	trarar_mg_notify_request_msg(Mid, TermId, 2, 3, 3),
5522    NotifyReq4 =
5523	trarar_mg_notify_request_msg(Mid, TermId, 2, 4, 4),
5524    ScrVerifyFun = ?trarar_mg_verify_service_change_rep_msg_fun(),
5525    NrVerifyFun1 =
5526	?trarar_mg_verify_notify_rep_msg_fun(TermId, 2, 1, 1),
5527    NrVerifyFun2 =
5528	?trarar_mg_verify_notify_rep_msg_fun(TermId, 2, 2, 2),
5529    NrVerifyFun3 =
5530	?trarar_mg_verify_notify_rep_msg_fun(TermId, 2, 3, 3),
5531    NrVerifyFun4 =
5532	?trarar_mg_verify_notify_rep_msg_fun(TermId, 2, 4, 4),
5533    EvSeq = [{debug,  true},
5534             {decode, DecodeFun},
5535             {encode, EncodeFun},
5536             {connect, 2944},
5537
5538             {send, "service-change-request", ServiceChangeReq},
5539             {expect_receive, "service-change-reply", {ScrVerifyFun, 10000}},
5540
5541	     %% the original setting for reply timer is 2000
5542             {send, "notify request 1", NotifyReq1},
5543             {expect_receive, "notify-reply 1", {NrVerifyFun1, 2500}},
5544	     {sleep, 1000},
5545             {send, "notify request 2", NotifyReq2},
5546             {expect_receive, "notify-reply 2 (resend of 1)", {NrVerifyFun1, 2500}},
5547	     {sleep, 3000}, % reply timer is set to 2000
5548             {send, "notify request 3 (same as 2)", NotifyReq2},
5549             {expect_receive, "notify-reply 3", {NrVerifyFun2, 2500}},
5550
5551	     %% reply timer is now set to 4000 but previous was 2000
5552	     %% so, 3000 is enough to let the timer running with the
5553	     %% previous settings (2000) to time out
5554	     {sleep, 3000},
5555             {send, "notify request 4", NotifyReq3},
5556             {expect_receive, "notify-reply 4", {NrVerifyFun3, 4500}},
5557	     {sleep, 5000},
5558             {send, "notify request 5", NotifyReq4},
5559             {expect_receive, "notify-reply 5", {NrVerifyFun4, 4500}},
5560
5561             {expect_nothing, 5000},
5562             disconnect
5563            ],
5564    EvSeq.
5565
5566-ifndef(megaco_hipe_special).
5567trarar_mg_encode_msg_fun(Mod, Conf) ->
5568    fun(M) ->
5569            encode_msg(M, Mod, Conf)
5570    end.
5571-endif.
5572
5573-ifndef(megaco_hipe_special).
5574trarar_mg_decode_msg_fun(Mod, Conf) ->
5575    fun(M) ->
5576            decode_msg(M, Mod, Conf)
5577    end.
5578-endif.
5579
5580-ifndef(megaco_hipe_special).
5581trarar_mg_verify_service_change_rep_msg_fun() ->
5582    fun(Msg) ->
5583	    (catch trarar_mg_verify_service_change_rep_msg(Msg))
5584    end.
5585-endif.
5586
5587trarar_mg_verify_service_change_rep_msg(#'MegacoMessage'{mess = Mess} = M) ->
5588    Body =
5589	case Mess of
5590	    #'Message'{version     = _V,
5591                       mId         = _MgMid,
5592                       messageBody = MsgBody} ->
5593		MsgBody;
5594	    _ ->
5595		throw({error, {invalid_Message, Mess}})
5596	end,
5597    Trans =
5598	case Body of
5599            {transactions, [Transactions]} ->
5600		Transactions;
5601	    _ ->
5602		throw({error, {invalid_messageBody, Body}})
5603	end,
5604    TR =
5605	case Trans of
5606            {transactionReply, TransReply} ->
5607		TransReply;
5608	    _ ->
5609		throw({error, {invalid_transactions, Trans}})
5610	end,
5611    TRes =
5612	case TR of
5613            #'TransactionReply'{transactionId = _Tid,
5614                                immAckRequired = asn1_NOVALUE,
5615                                transactionResult = TransRes} ->
5616		TransRes;
5617	    _ ->
5618		throw({error, {invalid_transactionReply, TR}})
5619	end,
5620    AR =
5621	case TRes of
5622            {actionReplies, [ActRes]} ->
5623		ActRes;
5624	    _ ->
5625		throw({error, {invalid_transactionResult, TRes}})
5626	end,
5627    CR =
5628	case AR of
5629            #'ActionReply'{contextId       = _Cid,
5630                           errorDescriptor = asn1_NOVALUE,
5631                           contextReply    = _CtxReq,
5632                           commandReply    = [CmdRep]} ->
5633		CmdRep;
5634	    _ ->
5635		throw({error, {invalid_actionReplies, AR}})
5636	end,
5637    SCR =
5638	case CR of
5639            {serviceChangeReply, ServChRep} ->
5640		ServChRep;
5641	    _ ->
5642		throw({error, {invalid_commandReply, CR}})
5643	end,
5644    SCRes =
5645	case SCR of
5646            #'ServiceChangeReply'{terminationID       = _TermID,
5647                                  serviceChangeResult = ServChRes} ->
5648		ServChRes;
5649	    _ ->
5650		throw({error, {invalid_serviceChangeReply, SCR}})
5651	end,
5652    SCRP =
5653	case SCRes of
5654            {serviceChangeResParms, Parms} ->
5655		Parms;
5656	    _ ->
5657		throw({error, {invalid_serviceChangeResult, SCRes}})
5658	end,
5659    case SCRP of
5660	#'ServiceChangeResParm'{serviceChangeMgcId = _MgcMid} ->
5661            {ok, M};
5662	_ ->
5663	    {error, {invalid_serviceChangeResParms, SCRP}}
5664    end;
5665trarar_mg_verify_service_change_rep_msg(Crap) ->
5666    {error, {invalid_message, Crap}}.
5667
5668-ifndef(megaco_hipe_special).
5669trarar_mg_verify_notify_rep_msg_fun(TermId, TransId, Rid, Cid) ->
5670    fun(Msg) ->
5671	    (catch trarar_mg_verify_notify_rep_msg(Msg,
5672						   TermId, TransId, Rid, Cid))
5673    end.
5674-endif.
5675
5676trarar_mg_verify_notify_rep_msg(#'MegacoMessage'{mess = Mess} = M,
5677				TermId, TransId, Rid, Cid) ->
5678    io:format("trarar_mg_verify_notify_rep_msg -> entry with"
5679	      "~n   M:       ~p"
5680	      "~n   TermId:  ~p"
5681	      "~n   TransId: ~p"
5682	      "~n   Rid:     ~p"
5683	      "~n   Cid:     ~p"
5684	      "~n", [M, TermId, TransId, Rid, Cid]),
5685    Body =
5686	case Mess of
5687	    #'Message'{version     = ?VERSION,
5688                       mId         = _Mid,
5689                       messageBody = MsgBody} ->
5690		MsgBody;
5691	    _ ->
5692		throw({error, {invalid_Message, Mess}})
5693	end,
5694    io:format("trarar_mg_verify_notify_rep_msg -> "
5695	      "~n   Body: ~p"
5696	      "~n", [Body]),
5697    Trans =
5698	case Body of
5699            {transactions, [Transactions]} ->
5700		Transactions;
5701	    _ ->
5702		throw({error, {invalid_messageBody, Body}})
5703	end,
5704    io:format("trarar_mg_verify_notify_rep_msg -> "
5705	      "~n   Trans: ~p"
5706	      "~n", [Trans]),
5707    TR =
5708	case Trans of
5709            {transactionReply, TransReply} ->
5710		TransReply;
5711	    _ ->
5712		throw({error, {invalid_transactions, Trans}})
5713	end,
5714    io:format("trarar_mg_verify_notify_rep_msg -> "
5715	      "~n   TR: ~p"
5716	      "~n", [TR]),
5717    TRes =
5718	case TR of
5719            #'TransactionReply'{transactionId     = TransId,
5720                                immAckRequired    = asn1_NOVALUE,
5721                                transactionResult = TransRes} ->
5722		TransRes;
5723	    _ ->
5724		throw({error, {invalid_transactionReply, TR}})
5725	end,
5726    io:format("trarar_mg_verify_notify_rep_msg -> "
5727	      "~n   TRes: ~p"
5728	      "~n", [TRes]),
5729    AR =
5730	case TRes of
5731            {actionReplies, [ActRes]} ->
5732		ActRes;
5733	    _ ->
5734		throw({error, {invalid_transactionResult, TRes}})
5735	end,
5736    io:format("trarar_mg_verify_notify_rep_msg -> "
5737	      "~n   AR: ~p"
5738	      "~n", [AR]),
5739    CR =
5740	case AR of
5741            #'ActionReply'{contextId       = Cid,
5742                           errorDescriptor = asn1_NOVALUE,
5743                           contextReply    = _CtxReq,
5744                           commandReply    = [CmdRep]} ->
5745		CmdRep;
5746	    _ ->
5747		throw({error, {invalid_actionReplies, AR}})
5748	end,
5749    NR =
5750	case CR of
5751            {notifyReply, NotifyReply} ->
5752		NotifyReply;
5753	    _ ->
5754		throw({error, {invalid_commandReply, CR}})
5755	end,
5756    case NR of
5757	#'NotifyReply'{terminationID   = [TermId],
5758		       errorDescriptor = asn1_NOVALUE} ->
5759	    {ok, M};
5760	_ ->
5761	    {error, {invalid_notifyReply, NR}}
5762    end;
5763trarar_mg_verify_notify_rep_msg(Crap, _TermId, _TransId, _Rid, _Cid) ->
5764    {error, {invalid_message, Crap}}.
5765
5766trarar_mg_service_change_request_ar(_Mid, Cid) ->
5767    Prof  = cre_serviceChangeProf("resgw", 1),
5768    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
5769    Root  = #megaco_term_id{id = ["root"]},
5770    SCR   = cre_serviceChangeReq([Root], SCP),
5771    CMD   = cre_command(SCR),
5772    CR    = cre_cmdReq(CMD),
5773    cre_actionReq(Cid, [CR]).
5774
5775trarar_mg_service_change_request_msg(Mid, TransId, Cid) ->
5776    AR    = trarar_mg_service_change_request_ar(Mid, Cid),
5777    TR    = cre_transReq(TransId, [AR]),
5778    Trans = cre_transaction(TR),
5779    Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
5780    cre_megacoMessage(Mess).
5781
5782trarar_mg_notify_request_ar(Rid, Tid, Cid) ->
5783    TT      = cre_timeNotation("19990729", "22000000"),
5784    Ev      = cre_obsEvent("al/of", TT),
5785    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
5786    NR      = cre_notifyReq([Tid], EvsDesc),
5787    CMD     = cre_command(NR),
5788    CR      = cre_cmdReq(CMD),
5789    cre_actionReq(Cid, [CR]).
5790
5791trarar_mg_notify_request_msg(Mid, TermId, TransId, Rid, Cid) ->
5792    AR      = trarar_mg_notify_request_ar(Rid, TermId, Cid),
5793    TR      = cre_transReq(TransId, [AR]),
5794    Trans   = cre_transaction(TR),
5795    Mess    = cre_message(?VERSION, Mid, cre_transactions([Trans])),
5796    cre_megacoMessage(Mess).
5797
5798%% trarar_mg_trans_ack_msg(Mid, TransId) ->
5799%%     TR    = cre_transRespAck(cre_transAck(TransId)),
5800%%     Trans = cre_transaction(TR),
5801%%     Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
5802%%     cre_megacoMessage(Mess).
5803
5804
5805%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5806
5807pending_ack_plain(suite) ->
5808    [];
5809pending_ack_plain(doc) ->
5810    ["Receive a request and handle it as a long request, "
5811     "i.e. return with {pending, _} and expect a call to the "
5812     "long request function"];
5813pending_ack_plain(Config) when is_list(Config) ->
5814    Pre = fun() ->
5815                  MgcNode = make_node_name(mgc),
5816                  MgNode  = make_node_name(mg),
5817                  d("start nodes: "
5818                    "~n      MgcNode: ~p"
5819                    "~n      MgNode:  ~p",
5820                    [MgcNode, MgNode]),
5821                  Nodes = [MgcNode, MgNode],
5822                  ok = ?START_NODES(Nodes, true),
5823                  Nodes
5824          end,
5825    Case = fun do_pending_ack_plain/1,
5826    Post = fun(Nodes) ->
5827                   d("stop nodes"),
5828                   ?STOP_NODES(lists:reverse(Nodes))
5829           end,
5830    try_tc(pap, Pre, Case, Post).
5831
5832do_pending_ack_plain([MgcNode, MgNode]) ->
5833    d("[MGC] start the simulator "),
5834    {ok, Mgc} = megaco_test_megaco_generator:start_link("MGC", MgcNode),
5835
5836    d("[MGC] create the event sequence"),
5837    MgcEvSeq = pap_mgc_event_sequence(text, tcp),
5838
5839    i("wait some time before starting the MGC simulation"),
5840    sleep(1000),
5841
5842    d("[MGC] start the simulation"),
5843    {ok, MgcId} = megaco_test_megaco_generator:exec(Mgc, MgcEvSeq),
5844
5845    %% i("wait some time before starting the MG simulator"),
5846    %% sleep(1000),
5847
5848    i("await MGC ready announcement"),
5849    receive
5850        announce_mgc ->
5851            i("received MGC ready announcement"),
5852            ok
5853    end,
5854
5855    d("[MG] start the simulator (generator)"),
5856    {ok, Mg} = megaco_test_tcp_generator:start_link("MG", MgNode),
5857
5858    d("[MG] create the event sequence"),
5859    MgEvSeq = pap_mg_event_sequence(text, tcp),
5860
5861    i("wait some time before starting the MG simulation"),
5862    sleep(1000),
5863
5864    d("[MG] start the simulation"),
5865    {ok, MgId} = megaco_test_tcp_generator:exec(Mg, MgEvSeq),
5866
5867    d("await the generator reply(s)"),
5868    await_completion([MgcId, MgId]),
5869
5870    %% Tell Mgc to stop
5871    i("[MGC] stop generator"),
5872    megaco_test_megaco_generator:stop(Mgc),
5873
5874    %% Tell Mg to stop
5875    i("[MG] stop generator"),
5876    megaco_test_tcp_generator:stop(Mg),
5877
5878    i("done", []),
5879    ok.
5880
5881
5882%%
5883%% MGC generator stuff
5884%%
5885
5886-ifdef(megaco_hipe_special).
5887-define(pap_mgc_verify_handle_connect_fun(),
5888        {?MODULE, pap_mgc_verify_handle_connect, []}).
5889-define(pap_mgc_verify_service_change_req_fun(Mid),
5890        {?MODULE, pap_mgc_verify_service_change_req, [Mid]}).
5891-define(pap_mgc_verify_notify_req_fun(),
5892        {?MODULE, pap_mgc_verify_notify_req, []}).
5893-define(pap_mgc_verify_notify_req_long_fun(),
5894        {?MODULE, pap_mgc_verify_notify_req_long, []}).
5895-define(pap_mgc_verify_handle_trans_ack_fun(),
5896	{?MODULE, pap_mgc_verify_handle_trans_ack, []}).
5897-define(pap_mgc_verify_handle_disconnect_fun(),
5898        {?MODULE, pap_mgc_verify_handle_disconnect, []}).
5899-else.
5900-define(pap_mgc_verify_handle_connect_fun(),
5901        fun pap_mgc_verify_handle_connect/1).
5902-define(pap_mgc_verify_service_change_req_fun(Mid),
5903        pap_mgc_verify_service_change_req_fun(Mid)).
5904-define(pap_mgc_verify_notify_req_fun(),
5905	pap_mgc_verify_notify_req_fun()).
5906-define(pap_mgc_verify_notify_req_long_fun(),
5907	pap_mgc_verify_notify_req_long_fun()).
5908-define(pap_mgc_verify_handle_trans_ack_fun(),
5909	pap_mgc_verify_handle_trans_ack_fun()).
5910-define(pap_mgc_verify_handle_disconnect_fun(),
5911	fun pap_mgc_verify_handle_disconnect/1).
5912-endif.
5913
5914pap_mgc_event_sequence(text, tcp) ->
5915    CTRL = self(),
5916    Mid = {deviceName,"ctrl"},
5917    RI = [
5918          {port,             2944},
5919          {encoding_module,  megaco_pretty_text_encoder},
5920          {encoding_config,  []},
5921          {transport_module, megaco_tcp}
5922         ],
5923    ConnectVerify = ?pap_mgc_verify_handle_connect_fun(),
5924    ScrVerify     = ?pap_mgc_verify_service_change_req_fun(Mid),
5925    NrVerify1     = ?pap_mgc_verify_notify_req_fun(),
5926    NrVerify2     = ?pap_mgc_verify_notify_req_long_fun(),
5927    AckVerify     = ?pap_mgc_verify_handle_trans_ack_fun(),
5928    DiscoVerify   = ?pap_mgc_verify_handle_disconnect_fun(),
5929    EvSeq = [
5930             {debug, true},
5931             {megaco_trace, disable},
5932             {megaco_trace, max},
5933             megaco_start,
5934             {megaco_start_user, Mid, RI, []},
5935             {megaco_update_user_info, sent_pending_limit, 100},
5936             start_transport,
5937             listen,
5938
5939             %% ANNOUNCE READY
5940             {trigger, fun() -> CTRL ! announce_mgc end},
5941
5942             {megaco_callback, handle_connect,            ConnectVerify},
5943             {megaco_conn_info, all},
5944             {megaco_callback, handle_trans_request,      ScrVerify},
5945	     {megaco_callback, handle_trans_request,      NrVerify1},
5946	     {megaco_callback, handle_trans_long_request, NrVerify2},
5947	     {megaco_callback, handle_trans_ack,          AckVerify},
5948             {megaco_callback, handle_disconnect,         DiscoVerify},
5949             megaco_stop_user,
5950             megaco_stop
5951            ],
5952    EvSeq.
5953
5954%% Connect verification
5955pap_mgc_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
5956    {ok, CH, ok};
5957pap_mgc_verify_handle_connect(Else) ->
5958    {error, Else, ok}.
5959
5960%% Service Change verification
5961-ifndef(megaco_hipe_special).
5962pap_mgc_verify_service_change_req_fun(Mid) ->
5963    fun(Req) ->
5964	    pap_mgc_verify_service_change_req(Req, Mid)
5965    end.
5966-endif.
5967
5968pap_mgc_verify_service_change_req(
5969  {handle_trans_request, _, ?VERSION, [AR]}, Mid) ->
5970    (catch pap_do_verify_service_change_req(AR, Mid));
5971pap_mgc_verify_service_change_req(Crap, _Mid) ->
5972    ED       = cre_ErrDesc(Crap),
5973    ErrReply = {discard_ack, ED},
5974    {error, Crap, ErrReply}.
5975
5976pap_do_verify_service_change_req(AR, Mid) ->
5977    CR =
5978	case AR of
5979	    #'ActionRequest'{commandRequests = [CmdReq]} ->
5980		CmdReq;
5981	    _ ->
5982		Err1      = {invalid_action_request, AR},
5983		ED1       = cre_ErrDesc(AR),
5984		ErrReply1 = {discard_ack, ED1},
5985		throw({error, Err1, ErrReply1})
5986	end,
5987    Cmd =
5988	case CR of
5989	    #'CommandRequest'{command = Command} ->
5990		Command;
5991	    _ ->
5992		Err2      = {invalid_command_request, CR},
5993		ED2       = cre_ErrDesc(CR),
5994		ErrReply2 = {discard_ack, ED2},
5995		throw({error, Err2, ErrReply2})
5996	end,
5997    {Tid, Parms} =
5998	case Cmd of
5999	    {serviceChangeReq,
6000	     #'ServiceChangeRequest'{terminationID = [TermID],
6001				     serviceChangeParms = ServChParms}} ->
6002		{TermID, ServChParms};
6003	    _ ->
6004		Err3      = {invalid_command, Cmd},
6005		ED3       = cre_ErrDesc(Cmd),
6006		ErrReply3 = {discard_ack, ED3},
6007		throw({error, Err3, ErrReply3})
6008	end,
6009    case Tid of
6010	#megaco_term_id{contains_wildcards = false, id = ["root"]} ->
6011	    ok;
6012	_ ->
6013	    Err4      = {invalid_termination_id, Tid},
6014	    ED4       = cre_ErrDesc(Tid),
6015	    ErrReply4 = {discard_ack, ED4},
6016	    throw({error, Err4, ErrReply4})
6017    end,
6018    case Parms of
6019	#'ServiceChangeParm'{serviceChangeMethod = restart,
6020			     serviceChangeReason = [[$9,$0,$1|_]]} ->
6021	    AckData = [pap_mgc_service_change_reply_ar(Mid, 1)],
6022	    Reply   = {discard_ack, AckData},
6023	    {ok, AR, Reply};
6024	_ ->
6025	    Err5      = {invalid_SCP, Parms},
6026	    ED5       = cre_ErrDesc(Parms),
6027	    ErrReply5 = {discard_ack, ED5},
6028	    {error, Err5, ErrReply5}
6029    end.
6030
6031
6032%% Notify Request verification
6033-ifndef(megaco_hipe_special).
6034pap_mgc_verify_notify_req_fun() ->
6035    fun(Req) ->
6036	    pap_mgc_verify_notify_req(Req)
6037    end.
6038-endif.
6039
6040pap_mgc_verify_notify_req({handle_trans_request, _, ?VERSION, [AR]}) ->
6041    io:format("pap_mgc_verify_notify_req -> entry with"
6042	      "~n   AR: ~p"
6043	      "~n", [AR]),
6044    Reply = {pending, AR},
6045    {ok, AR, Reply};
6046pap_mgc_verify_notify_req(Crap) ->
6047    ED       = cre_ErrDesc(Crap),
6048    ErrReply = {discard_ack, ED},
6049    {error, Crap, ErrReply}.
6050
6051%% Notify Request verification
6052-ifndef(megaco_hipe_special).
6053pap_mgc_verify_notify_req_long_fun() ->
6054    fun(Req) ->
6055	    pap_mgc_verify_notify_req_long(Req)
6056    end.
6057-endif.
6058
6059pap_mgc_verify_notify_req_long(
6060  {handle_trans_long_request, _, ?VERSION, AR}) ->
6061    (catch pap_mgc_do_verify_notify_req_long(AR));
6062pap_mgc_verify_notify_req_long(Crap) ->
6063    ED       = cre_ErrDesc(Crap),
6064    ErrReply = {discard_ack, ED},
6065    {error, Crap, ErrReply}.
6066
6067pap_mgc_do_verify_notify_req_long(AR) ->
6068    io:format("pap_mgc_do_verify_notify_req_long -> entry with"
6069	      "~n   AR: ~p"
6070	      "~n", [AR]),
6071    {Cid, CR} =
6072	case AR of
6073	    #'ActionRequest'{contextId       = CtxID,
6074			     commandRequests = [CmdReq]} ->
6075		{CtxID, CmdReq};
6076	    _ ->
6077		Err1      = {invalid_action_request, AR},
6078		ED1       = cre_ErrDesc(AR),
6079		ErrReply1 = {discard_ack, ED1},
6080		throw({error, Err1, ErrReply1})
6081	end,
6082    Cmd =
6083	case CR of
6084	    #'CommandRequest'{command = Command} ->
6085		Command;
6086	    _ ->
6087		Err2      = {invalid_command_request, CR},
6088		ED2       = cre_ErrDesc(CR),
6089		ErrReply2 = {discard_ack, ED2},
6090		throw({error, Err2, ErrReply2})
6091	end,
6092    NR =
6093	case Cmd of
6094	    {notifyReq, NotifReq} ->
6095		NotifReq;
6096	    _ ->
6097		Err3      = {invalid_command, Cmd},
6098		ED3       = cre_ErrDesc(Cmd),
6099		ErrReply3 = {discard_ack, ED3},
6100		throw({error, Err3, ErrReply3})
6101	end,
6102    {Tid, OED} =
6103	case NR of
6104	    #'NotifyRequest'{terminationID            = [TermID],
6105			     observedEventsDescriptor = ObsEvsDesc,
6106			     errorDescriptor          = asn1_NOVALUE} ->
6107		{TermID, ObsEvsDesc};
6108	    _ ->
6109		Err4      = {invalid_NR, NR},
6110		ED4       = cre_ErrDesc(NR),
6111		ErrReply4 = {discard_ack, ED4},
6112		throw({error, Err4, ErrReply4})
6113	end,
6114    OE =
6115	case OED of
6116	    #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
6117		ObsEvLst;
6118	    _ ->
6119		Err5      = {invalid_OED, OED},
6120		ED5       = cre_ErrDesc(NR),
6121		ErrReply5 = {discard_ack, ED5},
6122		throw({error, Err5, ErrReply5})
6123	end,
6124    case OE of
6125	#'ObservedEvent'{eventName = "al/of"} ->
6126	    AckData = pap,
6127	    Replies = [pap_mgc_notify_reply_ar(Cid, Tid)],
6128	    Reply   = {{handle_ack, AckData}, Replies},
6129	    {ok, AR, Reply};
6130	_ ->
6131	    Err6      = {invalid_OE, OE},
6132	    ED6       = cre_ErrDesc(OE),
6133	    ErrReply6 = {discard_ack, ED6},
6134	    throw({error, Err6, ErrReply6})
6135    end.
6136
6137
6138-ifndef(megaco_hipe_special).
6139pap_mgc_verify_handle_trans_ack_fun() ->
6140    fun(Ack) ->
6141	    pap_mgc_verify_handle_trans_ack(Ack)
6142    end.
6143-endif.
6144
6145pap_mgc_verify_handle_trans_ack({handle_trans_ack, CH, ?VERSION, ok, pap}) ->
6146    io:format("pap_mgc_verify_handle_trans_ack -> ok"
6147              "~n   CH: ~p"
6148              "~n", [CH]),
6149    {ok, CH, ok};
6150pap_mgc_verify_handle_trans_ack(Crap) ->
6151    io:format("pap_mgc_verify_handle_trans_ack -> unknown"
6152              "~n   Crap: ~p~n", [Crap]),
6153    {error, Crap, ok}.
6154
6155
6156%% Disconnect verification
6157pap_mgc_verify_handle_disconnect({handle_disconnect, CH, ?VERSION, _R}) ->
6158    {ok, CH, ok};
6159pap_mgc_verify_handle_disconnect(Else) ->
6160    {error, Else, ok}.
6161
6162pap_mgc_service_change_reply_ar(Mid, Cid) ->
6163    SCRP  = cre_serviceChangeResParm(Mid),
6164    SCRes = cre_serviceChangeResult(SCRP),
6165    Root  = #megaco_term_id{id = ["root"]},
6166    SCR   = cre_serviceChangeReply([Root], SCRes),
6167    CR    = cre_cmdReply(SCR),
6168    AR    = cre_actionReply(Cid, [CR]),
6169    AR.
6170
6171pap_mgc_notify_reply_ar(Cid, TermId) ->
6172    NR    = cre_notifyReply([TermId]),
6173    CR    = cre_cmdReply(NR),
6174    cre_actionReply(Cid, [CR]).
6175
6176
6177%%
6178%% MG generator stuff
6179%%
6180-ifdef(megaco_hipe_special).
6181-define(pap_mg_decode_msg_fun(Mod, Conf),
6182	{?MODULE, decode_msg, [Mod, Conf]}).
6183-define(pap_mg_encode_msg_fun(Mod, Conf),
6184	{?MODULE, encode_msg, [Mod, Conf]}).
6185-define(pap_mg_verify_service_change_rep_msg_fun(),
6186	{?MODULE, pap_mg_verify_service_change_rep_msg, []}).
6187-define(pap_mg_verify_pending_msg_fun(TransId),
6188	{?MODULE, pap_mg_verify_pending_msg, [TransId]}).
6189-define(pap_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId),
6190	{?MODULE, pap_mg_verify_notify_rep_msg, [TermId, TransId, ReqId, CtxId]}).
6191-else.
6192-define(pap_mg_decode_msg_fun(Mod, Conf),
6193	pap_mg_decode_msg_fun(Mod, Conf)).
6194-define(pap_mg_encode_msg_fun(Mod, Conf),
6195	pap_mg_encode_msg_fun(Mod, Conf)).
6196-define(pap_mg_verify_service_change_rep_msg_fun(),
6197	pap_mg_verify_service_change_rep_msg_fun()).
6198-define(pap_mg_verify_pending_msg_fun(TransId),
6199	pap_mg_verify_pending_msg_fun(TransId)).
6200-define(pap_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId),
6201	pap_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId)).
6202-endif.
6203
6204pap_mg_event_sequence(text, tcp) ->
6205    DecodeFun = ?pap_mg_decode_msg_fun(megaco_pretty_text_encoder, []),
6206    EncodeFun = ?pap_mg_encode_msg_fun(megaco_pretty_text_encoder, []),
6207    Mid       = {deviceName,"mg"},
6208    ServiceChangeReq = pap_mg_service_change_request_msg(Mid, 1, 0),
6209    TermId  = #megaco_term_id{id = ["00000000","00000000","01101101"]},
6210    TransId = 2,
6211    ReqId   = 1,
6212    CtxId   = 1,
6213    NotifyReq =
6214	pap_mg_notify_request_msg(Mid, TermId, TransId, ReqId, CtxId),
6215    TransAck = pap_mg_trans_ack_msg(Mid, TransId),
6216    ScrVerifyFun = ?pap_mg_verify_service_change_rep_msg_fun(),
6217    PendingVerifyFun =
6218	?pap_mg_verify_pending_msg_fun(TransId),
6219    NrVerifyFun =
6220	?pap_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId),
6221    EvSeq = [{debug,  true},
6222             {decode, DecodeFun},
6223             {encode, EncodeFun},
6224             {connect, 2944},
6225             {send, "service-change-request", ServiceChangeReq},
6226             {expect_receive, "service-change-reply", {ScrVerifyFun, 10000}},
6227             {send, "notify request", NotifyReq},
6228             {expect_receive, "pending",      {PendingVerifyFun, 4000}},
6229             {expect_receive, "notify-reply", {NrVerifyFun, 4000}},
6230             {send, "transaction-ack", TransAck},
6231             {expect_nothing, 11000},
6232             disconnect
6233            ],
6234    EvSeq.
6235
6236-ifndef(megaco_hipe_special).
6237pap_mg_encode_msg_fun(Mod, Conf) ->
6238    fun(M) ->
6239            encode_msg(M, Mod, Conf)
6240    end.
6241-endif.
6242
6243-ifndef(megaco_hipe_special).
6244pap_mg_decode_msg_fun(Mod, Conf) ->
6245    fun(M) ->
6246            decode_msg(M, Mod, Conf)
6247    end.
6248-endif.
6249
6250-ifndef(megaco_hipe_special).
6251pap_mg_verify_service_change_rep_msg_fun() ->
6252    fun(Msg) ->
6253	    (catch pap_mg_verify_service_change_rep_msg(Msg))
6254    end.
6255-endif.
6256
6257pap_mg_verify_service_change_rep_msg(#'MegacoMessage'{mess = Mess} = M) ->
6258    Body =
6259	case Mess of
6260	    #'Message'{version     = _V,
6261                       mId         = _MgMid,
6262                       messageBody = MsgBody} ->
6263		MsgBody;
6264	    _ ->
6265		throw({error, {invalid_Message, Mess}})
6266	end,
6267    Trans =
6268	case Body of
6269            {transactions, [Transactions]} ->
6270		Transactions;
6271	    _ ->
6272		throw({error, {invalid_messageBody, Body}})
6273	end,
6274    TR =
6275	case Trans of
6276            {transactionReply, TransReply} ->
6277		TransReply;
6278	    _ ->
6279		throw({error, {invalid_transactions, Trans}})
6280	end,
6281    TRes =
6282	case TR of
6283            #'TransactionReply'{transactionId = _Tid,
6284                                immAckRequired = asn1_NOVALUE,
6285                                transactionResult = TransRes} ->
6286		TransRes;
6287	    _ ->
6288		throw({error, {invalid_transactionReply, TR}})
6289	end,
6290    AR =
6291	case TRes of
6292            {actionReplies, [ActRes]} ->
6293		ActRes;
6294	    _ ->
6295		throw({error, {invalid_transactionResult, TRes}})
6296	end,
6297    CR =
6298	case AR of
6299            #'ActionReply'{contextId       = _Cid,
6300                           errorDescriptor = asn1_NOVALUE,
6301                           contextReply    = _CtxReq,
6302                           commandReply    = [CmdRep]} ->
6303		CmdRep;
6304	    _ ->
6305		throw({error, {invalid_actionReplies, AR}})
6306	end,
6307    SCR =
6308	case CR of
6309            {serviceChangeReply, ServChRep} ->
6310		ServChRep;
6311	    _ ->
6312		throw({error, {invalid_commandReply, CR}})
6313	end,
6314    SCRes =
6315	case SCR of
6316            #'ServiceChangeReply'{terminationID       = _TermID,
6317                                  serviceChangeResult = ServChRes} ->
6318		ServChRes;
6319	    _ ->
6320		throw({error, {invalid_serviceChangeReply, SCR}})
6321	end,
6322    SCRP =
6323	case SCRes of
6324            {serviceChangeResParms, Parms} ->
6325		Parms;
6326	    _ ->
6327		throw({error, {invalid_serviceChangeResult, SCRes}})
6328	end,
6329    case SCRP of
6330	#'ServiceChangeResParm'{serviceChangeMgcId = _MgcMid} ->
6331            {ok, M};
6332	_ ->
6333	    {error, {invalid_serviceChangeResParms, SCRP}}
6334    end;
6335pap_mg_verify_service_change_rep_msg(Crap) ->
6336    {error, {invalid_message, Crap}}.
6337
6338-ifndef(megaco_hipe_special).
6339pap_mg_verify_pending_msg_fun(TransId) ->
6340    fun(Msg) ->
6341	    (catch pap_mg_verify_pending_msg(Msg, TransId))
6342    end.
6343-endif.
6344
6345pap_mg_verify_pending_msg(#'MegacoMessage'{mess = Mess} = M, TransId) ->
6346    io:format("pap_mg_verify_pending_msg -> entry with"
6347	      "~n   M:       ~p"
6348	      "~n   TransId: ~p"
6349	      "~n", [M, TransId]),
6350    Body =
6351	case Mess of
6352	    #'Message'{version     = ?VERSION,
6353                       mId         = _Mid,
6354                       messageBody = MsgBody} ->
6355		MsgBody;
6356	    _ ->
6357		throw({error, {invalid_Message, Mess}})
6358	end,
6359    Trans =
6360	case Body of
6361            {transactions, [Transactions]} ->
6362		Transactions;
6363	    _ ->
6364		throw({error, {invalid_messageBody, Body}})
6365	end,
6366    TP =
6367	case Trans of
6368            {transactionPending, TransPending} ->
6369		TransPending;
6370	    _ ->
6371		throw({error, {invalid_transactions, Trans}})
6372	end,
6373    case TP of
6374	#'TransactionPending'{transactionId = TransId} ->
6375	    {ok, M};
6376	_ ->
6377	    {error, {invalid_transactionPending, TP}}
6378    end;
6379pap_mg_verify_pending_msg(Crap, _TransId) ->
6380    {error, {invalid_message, Crap}}.
6381
6382-ifndef(megaco_hipe_special).
6383pap_mg_verify_notify_rep_msg_fun(TermId, TransId, Rid, Cid) ->
6384    fun(Msg) ->
6385	    (catch pap_mg_verify_notify_rep_msg(Msg,
6386						TermId, TransId, Rid, Cid))
6387    end.
6388-endif.
6389
6390pap_mg_verify_notify_rep_msg(#'MegacoMessage'{mess = Mess} = M,
6391			   TermId, TransId, Rid, Cid) ->
6392    io:format("pap_mg_verify_notify_rep_msg -> entry with"
6393	      "~n   M:       ~p"
6394	      "~n   TermId:  ~p"
6395	      "~n   TransId: ~p"
6396	      "~n   Rid:     ~p"
6397	      "~n   Cid:     ~p"
6398	      "~n", [M, TermId, TransId, Rid, Cid]),
6399    Body =
6400	case Mess of
6401	    #'Message'{version     = ?VERSION,
6402                       mId         = _Mid,
6403                       messageBody = MsgBody} ->
6404		MsgBody;
6405	    _ ->
6406		throw({error, {invalid_Message, Mess}})
6407	end,
6408    Trans =
6409	case Body of
6410            {transactions, [Transactions]} ->
6411		Transactions;
6412	    _ ->
6413		throw({error, {invalid_messageBody, Body}})
6414	end,
6415    TR =
6416	case Trans of
6417            {transactionReply, TransReply} ->
6418		TransReply;
6419	    _ ->
6420		throw({error, {invalid_transactions, Trans}})
6421	end,
6422    TRes =
6423	case TR of
6424            #'TransactionReply'{transactionId     = TransId,
6425                                immAckRequired    = 'NULL',
6426                                transactionResult = TransRes} ->
6427		TransRes;
6428	    _ ->
6429		throw({error, {invalid_transactionReply, TR}})
6430	end,
6431    AR =
6432	case TRes of
6433            {actionReplies, [ActRes]} ->
6434		ActRes;
6435	    _ ->
6436		throw({error, {invalid_transactionResult, TRes}})
6437	end,
6438    CR =
6439	case AR of
6440            #'ActionReply'{contextId       = Cid,
6441                           errorDescriptor = asn1_NOVALUE,
6442                           contextReply    = _CtxReq,
6443                           commandReply    = [CmdRep]} ->
6444		CmdRep;
6445	    _ ->
6446		throw({error, {invalid_actionReplies, AR}})
6447	end,
6448    NR =
6449	case CR of
6450            {notifyReply, NotifyReply} ->
6451		NotifyReply;
6452	    _ ->
6453		throw({error, {invalid_commandReply, CR}})
6454	end,
6455    case NR of
6456	#'NotifyReply'{terminationID   = [TermId],
6457		       errorDescriptor = asn1_NOVALUE} ->
6458	    {ok, M};
6459	_ ->
6460	    {error, {invalid_notifyReply, NR}}
6461    end;
6462pap_mg_verify_notify_rep_msg(Crap, _TermId, _TransId, _Rid, _Cid) ->
6463    {error, {invalid_message, Crap}}.
6464
6465pap_mg_service_change_request_ar(_Mid, Cid) ->
6466    Prof  = cre_serviceChangeProf("resgw", 1),
6467    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
6468    Root  = #megaco_term_id{id = ["root"]},
6469    SCR   = cre_serviceChangeReq([Root], SCP),
6470    CMD   = cre_command(SCR),
6471    CR    = cre_cmdReq(CMD),
6472    cre_actionReq(Cid, [CR]).
6473
6474pap_mg_service_change_request_msg(Mid, TransId, Cid) ->
6475    AR    = pap_mg_service_change_request_ar(Mid, Cid),
6476    TR    = cre_transReq(TransId, [AR]),
6477    Trans = cre_transaction(TR),
6478    Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
6479    cre_megacoMessage(Mess).
6480
6481pap_mg_notify_request_ar(Rid, Tid, Cid) ->
6482    TT      = cre_timeNotation("19990729", "22000000"),
6483    Ev      = cre_obsEvent("al/of", TT),
6484    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
6485    NR      = cre_notifyReq([Tid], EvsDesc),
6486    CMD     = cre_command(NR),
6487    CR      = cre_cmdReq(CMD),
6488    cre_actionReq(Cid, [CR]).
6489
6490pap_mg_notify_request_msg(Mid, TermId, TransId, Rid, Cid) ->
6491    AR      = pap_mg_notify_request_ar(Rid, TermId, Cid),
6492    TR      = cre_transReq(TransId, [AR]),
6493    Trans   = cre_transaction(TR),
6494    Mess    = cre_message(?VERSION, Mid, cre_transactions([Trans])),
6495    cre_megacoMessage(Mess).
6496
6497pap_mg_trans_ack_msg(Mid, TransId) ->
6498    TR    = cre_transRespAck(cre_transAck(TransId)),
6499    Trans = cre_transaction(TR),
6500    Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
6501    cre_megacoMessage(Mess).
6502
6503
6504%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6505
6506request_and_pending_and_late_reply(suite) ->
6507    [];
6508request_and_pending_and_late_reply(doc) ->
6509    ["Receive a request and handle it as a long request, "
6510     "i.e. return with {pending, _}. Then, expect the sender "
6511     "to keep re-sending the request until the reply is sent."];
6512request_and_pending_and_late_reply(Config) when is_list(Config) ->
6513    Pre = fun() ->
6514                  MgcNode = make_node_name(mgc),
6515                  MgNode  = make_node_name(mg),
6516                  d("start nodes: "
6517                    "~n      MgcNode: ~p"
6518                    "~n      MgNode:  ~p",
6519                    [MgcNode, MgNode]),
6520                  Nodes = [MgcNode, MgNode],
6521                  ok = ?START_NODES(Nodes, true),
6522                  Nodes
6523          end,
6524    Case = fun do_request_and_pending_and_late_reply/1,
6525    Post = fun(Nodes) ->
6526                   d("stop nodes"),
6527                   ?STOP_NODES(lists:reverse(Nodes))
6528           end,
6529    try_tc(rapalr, Pre, Case, Post).
6530
6531do_request_and_pending_and_late_reply([MgcNode, MgNode]) ->
6532    d("[MGC] start the simulator "),
6533    {ok, Mgc} = megaco_test_tcp_generator:start_link("MGC", MgcNode),
6534
6535    d("[MGC] create the event sequence"),
6536    MgcEvSeq = rapalr_mgc_event_sequence(text, tcp),
6537
6538    i("wait some time before starting the MGC simulation"),
6539    sleep(1000),
6540
6541    d("[MGC] start the simulation"),
6542    {ok, MgcId} = megaco_test_tcp_generator:exec(Mgc, MgcEvSeq),
6543
6544    %% i("wait some time before starting the MG simulator"),
6545    %% sleep(1000),
6546
6547    i("await MGC ready announcement"),
6548    receive
6549        announce_mgc ->
6550            i("received MGC ready announcement"),
6551            ok
6552    end,
6553
6554    d("[MG] start the simulator (generator)"),
6555    {ok, Mg} = megaco_test_megaco_generator:start_link("MG", MgNode),
6556
6557    d("[MG] create the event sequence"),
6558    MgEvSeq = rapalr_mg_event_sequence(text, tcp),
6559
6560    i("wait some time before starting the MG simulation"),
6561    sleep(1000),
6562
6563    d("[MG] start the simulation"),
6564    {ok, MgId} = megaco_test_megaco_generator:exec(Mg, MgEvSeq),
6565
6566    d("await the generator reply(s)"),
6567    await_completion([MgcId, MgId]),
6568
6569    %% Tell Mgc to stop
6570    i("[MGC] stop generator"),
6571    megaco_test_tcp_generator:stop(Mgc),
6572
6573    %% Tell Mg to stop
6574    i("[MG] stop generator"),
6575    megaco_test_megaco_generator:stop(Mg),
6576
6577    i("done", []),
6578    ok.
6579
6580
6581%%
6582%% MGC generator stuff
6583%%
6584
6585-ifdef(megaco_hipe_special).
6586-define(rapalr_mgc_decode_msg_fun(Mod, Conf),
6587	{?MODULE, decode_msg, [Mod, Conf]}).
6588-define(rapalr_mgc_encode_msg_fun(Mod, Conf),
6589	{?MODULE, encode_msg, [Mod, Conf]}).
6590-define(rapalr_mgc_verify_service_change_req_msg_fun(),
6591	{?MODULE, rapalr_mgc_verify_service_change_req_msg, []}).
6592-define(rapalr_mgc_verify_notify_req_msg_fun(TermId, TransId, ReqId, CtxId),
6593	{?MODULE, rapalr_mgc_verify_notify_req_msg, [TermId, TransId, ReqId, CtxId]}).
6594-define(rapalr_mgc_verify_trans_ack_msg_fun(TransId),
6595	{?MODULE, rapalr_mgc_verify_trans_ack_msg, [TransId]}).
6596-else.
6597-define(rapalr_mgc_decode_msg_fun(Mod, Conf),
6598	rapalr_mgc_decode_msg_fun(Mod, Conf)).
6599-define(rapalr_mgc_encode_msg_fun(Mod, Conf),
6600	rapalr_mgc_encode_msg_fun(Mod, Conf)).
6601-define(rapalr_mgc_verify_service_change_req_msg_fun(),
6602	rapalr_mgc_verify_service_change_req_msg_fun()).
6603-define(rapalr_mgc_verify_notify_req_msg_fun(TermId, TransId, ReqId, CtxId),
6604	rapalr_mgc_verify_notify_req_msg_fun(TermId, TransId, ReqId, CtxId)).
6605-define(rapalr_mgc_verify_trans_ack_msg_fun(TransId),
6606	rapalr_mgc_verify_trans_ack_msg_fun(TransId)).
6607-endif.
6608
6609rapalr_mgc_event_sequence(text, tcp) ->
6610    CTRL = self(),
6611    DecodeFun = ?rapalr_mgc_decode_msg_fun(megaco_pretty_text_encoder, []),
6612    EncodeFun = ?rapalr_mgc_encode_msg_fun(megaco_pretty_text_encoder, []),
6613    Mid       = {deviceName,"mgc"},
6614    ServiceChangeRep = rapalr_mgc_service_change_reply_msg(Mid, 1),
6615    TermId           =
6616	#megaco_term_id{id = ["00000000","00000000","01101101"]},
6617    TransId   = 2,
6618    ReqId     = 1,
6619    CtxId     = 1,
6620    Pending      = rapalr_mgc_trans_pending_msg(Mid, TransId),
6621    NotifyRep    = rapalr_mgc_notify_reply_msg(Mid, TransId,
6622					       CtxId, TermId),
6623    ScrVerifyFun = ?rapalr_mgc_verify_service_change_req_msg_fun(),
6624    NrVerifyFun  =
6625	?rapalr_mgc_verify_notify_req_msg_fun(TermId, TransId, ReqId, CtxId),
6626    AckVerifyFun = ?rapalr_mgc_verify_trans_ack_msg_fun(TransId),
6627    EvSeq = [{debug,  false},
6628             {decode, DecodeFun},
6629             {encode, EncodeFun},
6630             {listen, 2944},
6631
6632             %% ANNOUNCE READY
6633             {trigger, "announce ready", fun() -> CTRL ! announce_mgc end},
6634
6635	     {expect_accept, any},
6636             {expect_receive, "service-change-request", {ScrVerifyFun, 5000}},
6637             {send, "service-change-reply", ServiceChangeRep},
6638             {expect_receive, "notify-request(1)", {NrVerifyFun, 4000}},
6639             {send, "pending", Pending},
6640             {expect_receive, "notify-request(2)", {NrVerifyFun, 4000}},
6641             {expect_receive, "notify-request(3)", {NrVerifyFun, 4000}},
6642             {send, "notify reply", NotifyRep},
6643             {expect_receive, "ack", {AckVerifyFun, 4000}},
6644             {sleep, 1000},
6645             disconnect
6646            ],
6647    EvSeq.
6648
6649-ifndef(megaco_hipe_special).
6650rapalr_mgc_encode_msg_fun(Mod, Conf) ->
6651    fun(M) ->
6652            encode_msg(M, Mod, Conf)
6653    end.
6654-endif.
6655
6656-ifndef(megaco_hipe_special).
6657rapalr_mgc_decode_msg_fun(Mod, Conf) ->
6658    fun(M) ->
6659            decode_msg(M, Mod, Conf)
6660    end.
6661-endif.
6662
6663-ifndef(megaco_hipe_special).
6664rapalr_mgc_verify_service_change_req_msg_fun() ->
6665    fun(Msg) ->
6666	    (catch rapalr_mgc_verify_service_change_req_msg(Msg))
6667    end.
6668-endif.
6669
6670rapalr_mgc_verify_service_change_req_msg(#'MegacoMessage'{mess = Mess} = M) ->
6671    Body =
6672	case Mess of
6673	    #'Message'{version     = ?VERSION,
6674                       mId         = _MgMid,
6675                       messageBody = MsgBody} ->
6676		MsgBody;
6677	    _ ->
6678		throw({error, {invalid_Message, Mess}})
6679	end,
6680    Trans =
6681	case Body of
6682            {transactions, [Transactions]} ->
6683		Transactions;
6684	    _ ->
6685		throw({error, {invalid_messageBody, Body}})
6686	end,
6687    TR =
6688	case Trans of
6689            {transactionRequest, TransRequest} ->
6690		TransRequest;
6691	    _ ->
6692		throw({error, {invalid_transactions, Trans}})
6693	end,
6694    AR =
6695	case TR of
6696            #'TransactionRequest'{transactionId = _TransId,
6697				  actions       = [ActionReq]} ->
6698		ActionReq;
6699	    _ ->
6700		throw({error, {invalid_transactionRequest, TR}})
6701	end,
6702    CR =
6703	case AR of
6704	    #'ActionRequest'{contextId       = _Cid,
6705			     commandRequests = [CmdReq]} ->
6706		CmdReq;
6707	    _ ->
6708		throw({error, {invalid_action, AR}})
6709	end,
6710    Cmd =
6711	case CR of
6712	    #'CommandRequest'{command = Command} ->
6713		Command;
6714	    _ ->
6715		throw({error, {invalid_commandRequest, CR}})
6716	end,
6717    {Tid, Parms} =
6718	case Cmd of
6719	    {serviceChangeReq,
6720	     #'ServiceChangeRequest'{terminationID      = [TermID],
6721				     serviceChangeParms = ServChParms}} ->
6722		{TermID, ServChParms};
6723	    _ ->
6724		throw({error, {invalid_command, Cmd}})
6725	end,
6726    case Tid of
6727	#megaco_term_id{contains_wildcards = false, id = ["root"]} ->
6728	    ok;
6729	_ ->
6730	    throw({error, {invalid_terminationID, Tid}})
6731    end,
6732    case Parms of
6733	#'ServiceChangeParm'{serviceChangeMethod = restart,
6734			     serviceChangeReason = [[$9,$0,$1|_]]} ->
6735	    {ok, M};
6736	_ ->
6737	    {error, {invalid_serviceChangeParms, Parms}}
6738    end.
6739
6740-ifndef(megaco_hipe_special).
6741rapalr_mgc_verify_notify_req_msg_fun(TermId, TransId, Rid, Cid) ->
6742    fun(Msg) ->
6743	    (catch rapalr_mgc_verify_notify_req_msg(Msg,
6744						    TermId,
6745						    TransId, Rid, Cid))
6746    end.
6747-endif.
6748
6749rapalr_mgc_verify_notify_req_msg(#'MegacoMessage'{mess = Mess} = M,
6750			     TermId, TransId, Rid, Cid) ->
6751    io:format("rapalr_mgc_verify_notify_req_msg -> entry with"
6752	      "~n   M:       ~p"
6753	      "~n   TermId:  ~p"
6754	      "~n   TransId: ~p"
6755	      "~n   Rid:     ~p"
6756	      "~n   Cid:     ~p"
6757	      "~n", [M, TermId, TransId, Rid, Cid]),
6758    Body =
6759	case Mess of
6760	    #'Message'{version     = ?VERSION,
6761                       mId         = _Mid,
6762                       messageBody = MsgBody} ->
6763		MsgBody;
6764	    _ ->
6765		throw({error, {invalid_Message, Mess}})
6766	end,
6767    Trans =
6768	case Body of
6769            {transactions, [Transactions]} ->
6770		Transactions;
6771	    _ ->
6772		throw({error, {invalid_messageBody, Body}})
6773	end,
6774    TR =
6775	case Trans of
6776            {transactionRequest, TransRequest} ->
6777		TransRequest;
6778	    _ ->
6779		throw({error, {invalid_transactions, Trans}})
6780	end,
6781    AR =
6782	case TR of
6783            #'TransactionRequest'{transactionId = TransId,
6784				  actions       = [ActReq]} ->
6785		ActReq;
6786	    _ ->
6787		throw({error, {invalid_transactionRequest, TR}})
6788	end,
6789    CR =
6790	case AR of
6791	    #'ActionRequest'{contextId       = Cid,
6792			     commandRequests = [CmdReq]} ->
6793		CmdReq;
6794	    _ ->
6795		throw({error, {invalid_actions, AR}})
6796	end,
6797    Cmd =
6798	case CR of
6799	    #'CommandRequest'{command = Command} ->
6800		Command;
6801	    _ ->
6802		throw({error, {invalid_commandRequests, CR}})
6803	end,
6804    NR =
6805	case Cmd of
6806	    {notifyReq, NotifReq} ->
6807		NotifReq;
6808	    _ ->
6809		throw({error, {invalid_command, Cmd}})
6810	end,
6811    OED =
6812	case NR of
6813	    #'NotifyRequest'{terminationID            = [TermId],
6814			     observedEventsDescriptor = ObsEvsDesc,
6815			     errorDescriptor          = asn1_NOVALUE} ->
6816		ObsEvsDesc;
6817	    _ ->
6818		throw({error, {invalid_notifyReq, NR}})
6819	end,
6820    OE =
6821	case OED of
6822	    #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
6823		ObsEvLst;
6824	    _ ->
6825		throw({error, {invalid_observedEventsDescriptor, OED}})
6826	end,
6827    case OE of
6828	#'ObservedEvent'{eventName = "al/of"} ->
6829	    {ok, M};
6830	_ ->
6831	    throw({error, {invalid_observedEventLst, OE}})
6832    end;
6833rapalr_mgc_verify_notify_req_msg(Crap, _TermId, _TransId, _Rid, _Cid) ->
6834    {error, {invalid_MegacoMessage, Crap}}.
6835
6836-ifndef(megaco_hipe_special).
6837rapalr_mgc_verify_trans_ack_msg_fun(TransId) ->
6838    fun(Msg) ->
6839	    (catch rapalr_mgc_verify_trans_ack_msg(Msg, TransId))
6840    end.
6841-endif.
6842
6843rapalr_mgc_verify_trans_ack_msg(#'MegacoMessage'{mess = Mess} = M,
6844				TransId) ->
6845    io:format("rapalr_mgc_verify_trans_ack_msg -> entry with"
6846	      "~n   M:       ~p"
6847	      "~n   TransId: ~p"
6848	      "~n", [M, TransId]),
6849    Body =
6850	case Mess of
6851	    #'Message'{version     = ?VERSION,
6852                       mId         = _Mid,
6853                       messageBody = MsgBody} ->
6854		MsgBody;
6855	    _ ->
6856		throw({error, {invalid_Message, Mess}})
6857	end,
6858    Trans =
6859	case Body of
6860            {transactions, [Transactions]} ->
6861		Transactions;
6862	    _ ->
6863		throw({error, {invalid_messageBody, Body}})
6864	end,
6865    TA =
6866	case Trans of
6867            {transactionResponseAck, [TransAck]} ->
6868		TransAck;
6869	    _ ->
6870		throw({error, {invalid_transactions, Trans}})
6871	end,
6872    case TA of
6873            #'TransactionAck'{firstAck = TransId,
6874			      lastAck  = asn1_NOVALUE} ->
6875		{ok, M};
6876	    _ ->
6877		throw({error, {invalid_transactionResponseAck, TA}})
6878    end;
6879rapalr_mgc_verify_trans_ack_msg(Crap, _TransId) ->
6880    {error, {invalid_MegacoMessage, Crap}}.
6881
6882rapalr_mgc_service_change_reply_msg(Mid, Cid) ->
6883    SCRP  = cre_serviceChangeResParm(Mid),
6884    SCRes = cre_serviceChangeResult(SCRP),
6885    Root  = #megaco_term_id{id = ["root"]},
6886    SCR   = cre_serviceChangeReply([Root], SCRes),
6887    CR    = cre_cmdReply(SCR),
6888    AR    = cre_actionReply(Cid, [CR]),
6889    TRes  = cre_transResult([AR]),
6890    TR    = cre_transReply(1, TRes),
6891    Trans = cre_transaction(TR),
6892    Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
6893    cre_megacoMessage(Mess).
6894
6895rapalr_mgc_notify_reply_ar(Cid, TermId) ->
6896    NR    = cre_notifyReply([TermId]),
6897    CR    = cre_cmdReply(NR),
6898    cre_actionReply(Cid, [CR]).
6899
6900rapalr_mgc_notify_reply_msg(Mid, TransId, Cid, TermId) ->
6901    AR    = rapalr_mgc_notify_reply_ar(Cid, TermId),
6902    TRes  = cre_transResult([AR]),
6903    TR    = cre_transReply(TransId, 'NULL', TRes),
6904    Trans = cre_transaction(TR),
6905    Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
6906    cre_megacoMessage(Mess).
6907
6908rapalr_mgc_trans_pending_msg(Mid, TransId) ->
6909    TP   = #'TransactionPending'{transactionId = TransId},
6910    Body = {transactions, [{transactionPending, TP}]},
6911    Mess = #'Message'{version     = 1,
6912		      mId         = Mid,
6913		      messageBody = Body},
6914    #'MegacoMessage'{mess = Mess}.
6915
6916
6917
6918%%
6919%% MG generator stuff
6920%%
6921-ifdef(megaco_hipe_special).
6922-define(rapalr_mg_verify_handle_connect_fun(),
6923	{?MODULE, rapalr_mg_verify_handle_connect, []}).
6924-define(rapalr_mg_verify_service_change_rep_fun(),
6925	{?MODULE, rapalr_mg_verify_service_change_rep, []}).
6926-define(rapalr_mg_verify_notify_rep_fun(),
6927	{?MODULE, rapalr_mg_verify_notify_rep, []}).
6928-else.
6929-define(rapalr_mg_verify_handle_connect_fun(),
6930	rapalr_mg_verify_handle_connect_fun()).
6931-define(rapalr_mg_verify_service_change_rep_fun(),
6932	rapalr_mg_verify_service_change_rep_fun()).
6933-define(rapalr_mg_verify_notify_rep_fun(),
6934	rapalr_mg_verify_notify_rep_fun()).
6935-endif.
6936
6937rapalr_mg_event_sequence(text, tcp) ->
6938    Mid = {deviceName,"mg"},
6939    RI = [
6940          {port,             2944},
6941          {encoding_module,  megaco_pretty_text_encoder},
6942          {encoding_config,  []},
6943          {transport_module, megaco_tcp}
6944         ],
6945    LReqTmr = #megaco_incr_timer{wait_for    = 3000,
6946				 factor      = 1,
6947				 incr        = 0,
6948				 max_retries = 2
6949				},
6950    ServiceChangeReq = rapalr_mg_service_change_request_ar(Mid, 1),
6951    Tid = #megaco_term_id{id = ["00000000","00000000","01101101"]},
6952    NotifyReq = rapalr_mg_notify_request_ar(1, Tid, 1),
6953    ConnectVerify            = ?rapalr_mg_verify_handle_connect_fun(),
6954    ServiceChangeReplyVerify = ?rapalr_mg_verify_service_change_rep_fun(),
6955    NotifyReplyVerify        = ?rapalr_mg_verify_notify_rep_fun(),
6956%%     ConnectVerify            = rapalr_mg_verify_handle_connect_fun(),
6957%%     ServiceChangeReplyVerify = rapalr_mg_verify_service_change_reply_fun(),
6958%%     NotifyReplyVerify        = rapalr_mg_verify_notify_reply_fun(),
6959    EvSeq = [
6960             {debug, false},
6961             megaco_start,
6962             {megaco_start_user, Mid, RI, []},
6963             start_transport,
6964             {megaco_trace, disable},
6965             {megaco_system_info, users},
6966             {megaco_system_info, connections},
6967             {megaco_update_user_info, long_request_resend, true},
6968	     {megaco_update_user_info, long_request_timer,  LReqTmr},
6969             connect,
6970             {megaco_callback, handle_connect, ConnectVerify},
6971             megaco_connect,
6972             {megaco_cast,     [ServiceChangeReq], []},
6973             {megaco_callback, handle_connect,     ConnectVerify},
6974             {megaco_callback, handle_trans_reply, ServiceChangeReplyVerify},
6975             {sleep, 1000},
6976             {megaco_cast,     [NotifyReq],        []},
6977             {megaco_callback, handle_trans_reply, NotifyReplyVerify},
6978             {sleep, 1000},
6979             megaco_stop_user,
6980             megaco_stop,
6981             {sleep, 1000}
6982            ],
6983    EvSeq.
6984
6985
6986-ifndef(megaco_hipe_special).
6987rapalr_mg_verify_handle_connect_fun() ->
6988    fun(Ev) ->
6989	    rapalr_mg_verify_handle_connect(Ev)
6990    end.
6991-endif.
6992
6993rapalr_mg_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
6994    io:format("rapalr_mg_verify_handle_connect -> ok"
6995	      "~n   CH: ~p~n", [CH]),
6996    {ok, CH, ok};
6997rapalr_mg_verify_handle_connect(Else) ->
6998    io:format("rapalr_mg_verify_handle_connect -> unknown"
6999	      "~n   Else: ~p~n", [Else]),
7000    {error, Else, ok}.
7001
7002
7003-ifndef(megaco_hipe_special).
7004rapalr_mg_verify_service_change_rep_fun() ->
7005    fun(Rep) ->
7006	    rapalr_mg_verify_service_change_rep(Rep)
7007    end.
7008-endif.
7009
7010rapalr_mg_verify_service_change_rep(
7011  {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _}) ->
7012    (catch rapalr_mg_do_verify_service_change_rep(AR));
7013rapalr_mg_verify_service_change_rep(Crap) ->
7014    {error, Crap, ok}.
7015
7016rapalr_mg_do_verify_service_change_rep(AR) ->
7017    io:format("rapalr_mg_verify_service_change_rep -> ok"
7018	      "~n   AR: ~p~n", [AR]),
7019    CR =
7020	case AR of
7021	    #'ActionReply'{commandReply = [CmdRep]} ->
7022		CmdRep;
7023	    _ ->
7024		Reason1 = {invalid_action_reply, AR},
7025		throw({error, Reason1, ok})
7026	end,
7027    SCR =
7028	case CR of
7029	    {serviceChangeReply, ServChRep} ->
7030		ServChRep;
7031	    _ ->
7032		Reason2 = {invalid_command_reply, CR},
7033		throw({error, Reason2, ok})
7034	end,
7035    {Tid, SCRes} =
7036	case SCR of
7037	    #'ServiceChangeReply'{terminationID       = [TermID],
7038				  serviceChangeResult = Res} ->
7039		{TermID, Res};
7040	    _ ->
7041		Reason3 = {invalid_service_change_reply, SCR},
7042		throw({error, Reason3, ok})
7043	end,
7044    case Tid of
7045	#megaco_term_id{contains_wildcards = false, id = ["root"]} ->
7046	    ok;
7047	_ ->
7048	    Reason4 = {invalid_termination_id, Tid},
7049	    throw({error, Reason4, ok})
7050    end,
7051    SCRParm =
7052	case SCRes of
7053	    {serviceChangeResParms, ServChResParms} ->
7054		ServChResParms;
7055	    _ ->
7056		Reason5 = {invalid_serviceChangeResult, SCRes},
7057		throw({error, Reason5, ok})
7058	end,
7059    case SCRParm of
7060	#'ServiceChangeResParm'{serviceChangeMgcId = _RemoteMid} ->
7061	    {ok, AR, ok};
7062	_ ->
7063	    Reason6 = {invalid_service_change_result, SCRParm},
7064	    {error, Reason6, ok}
7065    end.
7066
7067-ifndef(megaco_hipe_special).
7068rapalr_mg_verify_notify_rep_fun() ->
7069    fun(Rep) ->
7070	    rapalr_mg_verify_notify_rep(Rep)
7071    end.
7072-endif.
7073
7074rapalr_mg_verify_notify_rep({handle_trans_reply, _CH, ?VERSION,
7075			      {ok, [AR]}, _}) ->
7076    io:format("rapalr_mg_verify_notify_rep -> ok"
7077	      "~n   AR: ~p~n", [AR]),
7078    {ok, AR, ok};
7079rapalr_mg_verify_notify_rep(Else) ->
7080    io:format("rapalr_mg_verify_notify_rep -> unknown"
7081	      "~n   Else: ~p~n", [Else]),
7082    {error, Else, ok}.
7083
7084
7085rapalr_mg_service_change_request_ar(_Mid, Cid) ->
7086    Prof  = cre_serviceChangeProf("resgw", 1),
7087    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
7088    Root  = #megaco_term_id{id = ["root"]},
7089    SCR   = cre_serviceChangeReq([Root], SCP),
7090    CMD   = cre_command(SCR),
7091    CR    = cre_cmdReq(CMD),
7092    cre_actionReq(Cid, [CR]).
7093
7094rapalr_mg_notify_request_ar(Rid, Tid, Cid) ->
7095    TT      = cre_timeNotation("19990729", "22000000"),
7096    Ev      = cre_obsEvent("al/of", TT),
7097    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
7098    NR      = cre_notifyReq([Tid], EvsDesc),
7099    CMD     = cre_command(NR),
7100    CR      = cre_cmdReq(CMD),
7101    cre_actionReq(Cid, [CR]).
7102
7103
7104
7105%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7106
7107dist(suite) ->
7108    [];
7109dist(Config) when is_list(Config) ->
7110    ?SKIP("Needs a re-write..."),
7111    [_Local, Dist] = ?ACQUIRE_NODES(2, Config),
7112    d("dist -> start proxy",[]),
7113    ?USER_MOD:start_proxy(),
7114
7115    PrelMid = preliminary_mid,
7116    MgMid   = ipv4_mid(4711),
7117    MgcMid  = ipv4_mid(),
7118    UserMod = ?USER_MOD,
7119    d("dist -> start megaco app",[]),
7120    ?VERIFY(ok, application:start(megaco)),
7121    UserConfig = [{user_mod, UserMod}, {send_mod, UserMod},
7122		  {request_timer, infinity}, {reply_timer, infinity}],
7123
7124    d("dist -> start megaco user MG (~p)",[MgMid]),
7125    ?VERIFY(ok,	megaco:start_user(MgMid, UserConfig)),
7126
7127    d("dist -> start megaco user MGC (~p)",[MgcMid]),
7128    ?VERIFY(ok,	megaco:start_user(MgcMid, UserConfig)),
7129
7130    d("dist -> retrieve (user info) receive_handle for MG",[]),
7131    MgRH = user_info(MgMid, receive_handle),
7132
7133    d("dist -> retrieve (user info) receive_handle for MGC",[]),
7134    MgcRH = user_info(MgcMid, receive_handle),
7135
7136    d("dist -> start transport",[]),
7137    {ok, MgPid, MgSH} =
7138	?VERIFY({ok, _, _}, UserMod:start_transport(MgRH, MgcRH)),
7139    PrelMgCH = #megaco_conn_handle{local_mid = MgMid,
7140				   remote_mid = preliminary_mid},
7141    MgCH  = #megaco_conn_handle{local_mid = MgMid,
7142				remote_mid = MgcMid},
7143    MgcCH = #megaco_conn_handle{local_mid = MgcMid,
7144				remote_mid = MgMid},
7145
7146    d("dist -> (MG) connect",[]),
7147    ?SEND(megaco:connect(MgRH, PrelMid, MgSH, MgPid)), % Mg prel
7148
7149    d("dist -> (MG) await connect",[]),
7150    ?USER({connect, PrelMgCH, _V, []}, ok),
7151    ?RECEIVE([{res, _, {ok, PrelMgCH}}]),
7152
7153    d("dist -> (MG) send service change request",[]),
7154    Req = service_change_request(),
7155    ?SEND(megaco:call(PrelMgCH, [Req], [])),
7156
7157    d("dist -> (MGC) await auto-connect",[]),
7158    ?USER({connect, MgcCH, _V, []}, ok), % Mgc auto
7159
7160
7161    Rep = service_change_reply(MgcMid),
7162    d("dist -> (MGC) "
7163      "await service change request and send reply when received",[]),
7164    ?USER({request, MgcCH, _V, [[Req]]}, {discard_ack, [Rep]}),
7165
7166    d("dist -> (MG) await connect",[]),
7167    ?USER({connect, MgCH, _V, []}, ok), % Mg confirm
7168
7169    d("dist -> (MG) await service change reply",[]),
7170    ?RECEIVE([{res, _, {1, {ok, [Rep]}}}]),
7171
7172    %% Dist
7173    d("dist -> start megaco on ~p", [Dist]),
7174    ?VERIFY(ok,	rpc:call(Dist, megaco, start, [])),
7175
7176    d("dist -> start megaco user on ~p", [Dist]),
7177    ?VERIFY(ok,	rpc:call(Dist, megaco, start_user, [MgcMid, UserConfig])),
7178
7179    d("dist -> (MG) connect to MGC", []),
7180    MgcPid = self(),
7181    MgcSH  = {element(2, MgSH), element(1, MgSH)},
7182    ?SEND(rpc:call(Dist, megaco, connect, [MgcRH, MgMid, MgcSH, MgcPid])), % Mgc dist
7183
7184    d("dist -> (MGC) await auto-connect (from MG on ~p)", [Dist]),
7185    ?USER({connect, MgcCH, _V, []}, ok), % Mgc dist auto
7186    ?RECEIVE([{res, _, {ok, MgcCH}}]),
7187
7188    d("dist -> (~p:MG) send service change request",[Dist]),
7189    ?SEND(rpc:call(Dist, megaco, call, [MgcCH, [Req], []])),
7190
7191    d("dist -> (MG????????) "
7192      "await service change request and send reply when received",[]),
7193    ?USER({request, MgCH, _V, [[Req]]}, {discard_ack, [Rep]}),
7194    ?RECEIVE([{res, _, {1, {ok, [Rep]}}}]),
7195
7196    d("dist -> retreive some info",[]),
7197    connections([MgCH, MgcCH]),
7198    ?VERIFY([MgCH], megaco:user_info(MgMid, connections)),
7199    ?VERIFY([MgcCH], megaco:user_info(MgcMid, connections)),
7200
7201    ?VERIFY([MgcCH], rpc:call(Dist, megaco, system_info, [connections])),
7202    ?VERIFY([], rpc:call(Dist, megaco, user_info, [MgMid, connections])),
7203    ?VERIFY([MgcCH], rpc:call(Dist, megaco, user_info, [MgcMid, connections])),
7204
7205    %% Shutdown
7206
7207    d("dist -> close down the shop...",[]),
7208    Reason = shutdown,
7209    ?SEND(megaco:disconnect(MgCH, Reason)),
7210    ?USER({disconnect, MgCH, _V, [{user_disconnect, Reason}]}, ok),
7211    ?RECEIVE([{res, _, ok}]),
7212    ?VERIFY(ok,	megaco:stop_user(MgMid)),
7213
7214    ?SEND(megaco:disconnect(MgcCH, Reason)),
7215    ?USER({disconnect, MgcCH, _V, [{user_disconnect, Reason}]}, ok),
7216    ?USER({disconnect, MgcCH, _V, [{user_disconnect, Reason}]}, ok),
7217    ?RECEIVE([{res, _, ok}]),
7218    ?VERIFY(ok,	megaco:stop_user(MgcMid)),
7219
7220    ?VERIFY(ok, application:stop(megaco)),
7221    ?RECEIVE([]),
7222
7223    d("dist -> stop proxy",[]),
7224    ?USER_MOD:stop_proxy(),
7225
7226    d("dist -> done", []),
7227    ok.
7228
7229
7230%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7231
7232otp_4359(suite) ->
7233    [];
7234otp_4359(Config) when is_list(Config) ->
7235    ?ACQUIRE_NODES(1, Config),
7236    Mid = {deviceName, "dummy_mid"},
7237
7238    io:format("otp_4359 -> start megaco application~n", []),
7239    ?VERIFY(ok, application:start(megaco)),
7240
7241    %% megaco:enable_trace(max, io),
7242    io:format("otp_4359 -> start and configure megaco user~n", []),
7243    ?VERIFY(ok,	megaco:start_user(Mid, [{send_mod,      ?MODULE},
7244					{request_timer, infinity},
7245					{reply_timer,   infinity}])),
7246
7247    io:format("otp_4359 -> update user info: user_mod -> ~p~n", [?MODULE]),
7248    ?VERIFY(ok, megaco:update_user_info(Mid, user_mod,  ?MODULE)),
7249    io:format("otp_4359 -> update user info: user_args -> ~p~n", [self()]),
7250    ?VERIFY(ok, megaco:update_user_info(Mid, user_args, [self()])),
7251    io:format("otp_4359 -> retreive receive_handle~n", []),
7252    RH0 = user_info(Mid, receive_handle),
7253    io:format("otp_4359 -> RH0: ~p~n", [RH0]),
7254    RH1 = RH0#megaco_receive_handle{send_mod        = ?MODULE,
7255				    encoding_mod    = megaco_compact_text_encoder,
7256				    encoding_config = []},
7257
7258    %% First an erroneous transaction (missing the transaction id number)
7259    %% then an valid transaction.
7260    M = "!/1 ml2 "
7261	"T={C=${A=${M{O {MO=SR,RG=OFF,RV=OFF}}}}}"
7262	"T=1{C=${A=${M{O {MO=SR,RG=OFF,RV=OFF}}}}}",
7263
7264    %% Simulate incomming message
7265    %% Will result in an (auto) connect first
7266    io:format("otp_4359 -> simulate receive message~n", []),
7267    megaco:receive_message(RH1, self(), self(), list_to_binary(M)),
7268    io:format("otp_4359 -> await actions~n", []),
7269    Actions = otp_4359_await_actions([{handle_connect, ignore},
7270				      {send_message, ?megaco_bad_request},
7271				      {handle_trans_request, ignore},
7272				      {send_message, ?megaco_not_implemented}]),
7273    io:format("otp_4359 -> analyze actions~n", []),
7274    otp_4359_analyze_result(RH1, Actions),
7275
7276    Conns = megaco:system_info(connections),
7277    io:format("otp_4359 -> connections~n~p~n", [Conns]),
7278    OKs   = lists:duplicate(length(Conns),ok),
7279    io:format("otp_4359 -> verify (all) connection disconnect~n", []),
7280    ?VERIFY(OKs, [megaco:disconnect(CH, test_complete) || CH <- Conns]),
7281    io:format("otp_4359 -> stop user (~p)~n", [Mid]),
7282    stop_user(Mid),
7283    io:format("otp_4359 -> stop megaco application~n", []),
7284    ?VERIFY(ok, application:stop(megaco)),
7285    io:format("otp_4359 -> make sure we have nothing in the message queue~n", []),
7286    ?RECEIVE([]),
7287    io:format("otp_4359 -> done~n", []),
7288    ok.
7289
7290
7291otp_4359_await_actions(Exp) ->
7292    otp_4359_await_actions(Exp, []).
7293
7294otp_4359_await_actions([], Rep) ->
7295    lists:reverse(Rep);
7296otp_4359_await_actions([{M,I}|R] = _All, Rep) ->
7297    receive
7298	{M, Info} ->
7299	    io:format("otp_4359 -> received expected event [~w]~n", [M]),
7300	    otp_4359_await_actions(R, [{M, I, Info}|Rep])
7301%% 	Else ->
7302%% 	    exit({received_unexpected_message, M, Else})
7303%% 	    %% io:format("received unexpected: ~p~n", [Else]),
7304%% 	    %% otp_4359_await_actions(All, Rep)
7305    after 10000 ->
7306	    exit({timeout,megaco_test_lib:flush()} )
7307    end.
7308
7309otp_4359_analyze_result(_RH, []) ->
7310    ok;
7311otp_4359_analyze_result(RH,
7312			[{send_message, ExpErrorCode, EncodedMessage}|L]) ->
7313    io:format("otp_4359_analyze_result -> send_message: ", []),
7314    otp_4359_analyze_encoded_message(RH, ExpErrorCode, EncodedMessage),
7315    otp_4359_analyze_result(RH,L);
7316otp_4359_analyze_result(RH, [{M,ignore,_}|T]) ->
7317    io:format("otp_4359_analyze_result -> ignoring ~p~n", [M]),
7318    otp_4359_analyze_result(RH,T).
7319
7320otp_4359_analyze_encoded_message(RH, ExpErrorCode, M)
7321  when is_record(RH, megaco_receive_handle) andalso is_binary(M) ->
7322    #megaco_receive_handle{encoding_mod    = Mod,
7323			   encoding_config = Conf} = RH,
7324    case (catch Mod:decode_message(Conf, M)) of
7325	{ok, #'MegacoMessage'{mess = #'Message'{messageBody = Body}}} ->
7326	    case Body of
7327		{transactions, [{transactionReply,Reply}]} ->
7328		    case Reply of
7329			#'TransactionReply'{transactionResult = Result} ->
7330			    case Result of
7331				{transactionError,ED} when is_record(ED, 'ErrorDescriptor') ->
7332				    case ED#'ErrorDescriptor'.errorCode of
7333					ExpErrorCode ->
7334					    io:format("error code ~p ok~n", [ExpErrorCode]),
7335					    ok;
7336					Code ->
7337					    io:format("error code ~p erroneous~n", [Code]),
7338					    exit({unexpected_error_code, ExpErrorCode, Code})
7339				    end;
7340				_ ->
7341				    io:format("unexpected trans result~n", []),
7342				    exit({unexpected_trans_result, Result})
7343			    end;
7344			_ ->
7345			    io:format("unexpected trans reply~n", []),
7346			    exit({unexpected_trans_reply, Reply})
7347		    end;
7348		_ ->
7349		    io:format("unexpected body~n", []),
7350		    exit({unexpected_body, Body})
7351	    end;
7352
7353	Else ->
7354	    io:format("unexpected decode result~n", []),
7355	    exit({unexpected_decode_result, Else})
7356    end.
7357
7358
7359
7360%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7361
7362otp_4836(suite) ->
7363    [];
7364otp_4836(Config) when is_list(Config) ->
7365    Pre = fun() ->
7366                  MgcNode = make_node_name(mgc),
7367                  MgNode  = make_node_name(mg),
7368                  d("start nodes: "
7369                    "~n      MgcNode: ~p"
7370                    "~n      MgNode:  ~p",
7371                    [MgcNode, MgNode]),
7372                  Nodes = [MgcNode, MgNode],
7373                  ok = ?START_NODES(Nodes, true),
7374                  Nodes
7375          end,
7376    Case = fun do_otp_4836/1,
7377    Post = fun(Nodes) ->
7378                   d("stop nodes"),
7379                   ?STOP_NODES(lists:reverse(Nodes))
7380           end,
7381    try_tc(otp_4836, Pre, Case, Post).
7382
7383do_otp_4836([MgcNode, MgNode]) ->
7384    d("start the MGC simulator (generator)"),
7385    {ok, Mgc} = megaco_test_tcp_generator:start_link("MGC", MgcNode),
7386
7387    d("create the MGC event sequence"),
7388    MgcEvSeq = otp_4836_mgc_event_sequence(text, tcp),
7389
7390    d("start the MGC simulation"),
7391    {ok, MgcId} = megaco_test_tcp_generator:exec(Mgc, MgcEvSeq),
7392
7393    i("await MGC ready announcement"),
7394    receive
7395        announce_mgc ->
7396            i("received MGC ready announcement"),
7397            ok
7398    end,
7399
7400    i("[MG] start"),
7401    MgMid = {deviceName, "mg"},
7402    ReqTmr = #megaco_incr_timer{wait_for    = 3000,
7403                                factor      = 1,
7404                                incr        = 0,
7405                                max_retries = 3},
7406    %% 5000,  %% Does not matter since we will not use this anyway...
7407    LongReqTmr = #megaco_incr_timer{wait_for    = 3000,
7408                                    factor      = 1,
7409                                    incr        = 0,
7410                                    max_retries = 3},
7411    PendingTmr = 10000,
7412    ReplyTmr = 16000,
7413    MgConfig = [{request_timer,      ReqTmr},
7414                {long_request_timer, LongReqTmr},
7415                {pending_timer,      PendingTmr},
7416                {reply_timer,        ReplyTmr}],
7417    {ok, Mg} = ?MG_START(MgNode, MgMid, text, tcp, MgConfig, ?MG_VERBOSITY),
7418
7419    i("[MG] connect to the MGC (service change)"),
7420    ServChRes = ?MG_SERV_CHANGE(Mg),
7421    d("service change result: ~p", [ServChRes]),
7422
7423    d("[MG] send the notify"),
7424    {ok, Reply} = (catch ?MG_NOTIF_RAR(Mg)),
7425    {1, {ok, [AR]}} = Reply,
7426    d("[MG] ActionReply: ~p", [AR]),
7427
7428    d("await the generator reply"),
7429    await_completion([MgcId]),
7430
7431    %% Tell MG to stop
7432    i("[MG] stop"),
7433    ?MG_STOP(Mg),
7434
7435    %% Tell Mgc to stop
7436    i("[MGC] stop generator"),
7437    megaco_test_tcp_generator:stop(Mgc),
7438
7439    i("done", []),
7440    ok.
7441
7442
7443-ifdef(megaco_hipe_special).
7444-define(otp_4836_mgc_decode_msg_fun(Mod, Conf),
7445	{?MODULE, decode_msg, [Mod, Conf]}).
7446-define(otp_4836_mgc_encode_msg_fun(Mod, Conf),
7447	{?MODULE, encode_msg, [Mod, Conf]}).
7448-define(otp_4836_mgc_verify_service_change_req_msg_fun(),
7449	{?MODULE, otp_4836_mgc_verify_service_change_req_msg, []}).
7450-define(otp_4836_mgc_verify_notify_req_msg_fun(),
7451	{?MODULE, otp_4836_mgc_verify_notify_req_msg, []}).
7452-else.
7453-define(otp_4836_mgc_decode_msg_fun(Mod, Conf),
7454	otp_4836_mgc_decode_msg_fun(Mod, Conf)).
7455-define(otp_4836_mgc_encode_msg_fun(Mod, Conf),
7456	otp_4836_mgc_encode_msg_fun(Mod, Conf)).
7457-define(otp_4836_mgc_verify_service_change_req_msg_fun(),
7458	otp_4836_mgc_verify_service_change_req_msg_fun()).
7459-define(otp_4836_mgc_verify_notify_req_msg_fun(),
7460	otp_4836_mgc_verify_notify_req_msg_fun()).
7461-endif.
7462
7463otp_4836_mgc_event_sequence(text, tcp) ->
7464    CTRL = self(),
7465    DecodeFun = ?otp_4836_mgc_decode_msg_fun(megaco_pretty_text_encoder, []),
7466    EncodeFun = ?otp_4836_mgc_encode_msg_fun(megaco_pretty_text_encoder, []),
7467    Mid = {deviceName,"ctrl"},
7468    ServiceChangeReply = otp_4836_service_change_reply_msg(Mid, 1, 0),
7469    TermId = #megaco_term_id{id = ["00000000","00000000","01101101"]},
7470    NotifyReply = otp_4836_notify_reply_msg(Mid, 2, 0, TermId),
7471    Pending = otp_4836_pending_msg(Mid,2),
7472    ServiceChangeVerifyFun = ?otp_4836_mgc_verify_service_change_req_msg_fun(),
7473    NotifyReqVerifyFun     = ?otp_4836_mgc_verify_notify_req_msg_fun(),
7474    MgcEvSeq = [{debug,  true},
7475		{decode, DecodeFun},
7476		{encode, EncodeFun},
7477		{listen, 2944},
7478
7479                %% ANNOUNCE READY
7480                {trigger, "announce ready", fun() -> CTRL ! announce_mgc end},
7481
7482		{expect_accept, any},
7483		{expect_receive, "service-change-request", {ServiceChangeVerifyFun, 10000}},
7484		{send, "service-change-reply", ServiceChangeReply},
7485		{expect_receive, "notify-request", {NotifyReqVerifyFun, 10000}},
7486		{send, "pending 1", Pending},
7487		{sleep, 100},
7488		{send, "pending 2", Pending},
7489		{sleep, 500},
7490  		{send, "notify-reply", NotifyReply},
7491		{sleep, 2000}
7492	       ],
7493    MgcEvSeq.
7494
7495otp_4836_service_change_reply_msg(Mid, TransId, Cid) ->
7496    SCRP  = #'ServiceChangeResParm'{serviceChangeMgcId = Mid},
7497    SCRPs = {serviceChangeResParms,SCRP},
7498    Root  = #megaco_term_id{id = ["root"]},
7499    SCR   = #'ServiceChangeReply'{terminationID       = [Root],
7500				  serviceChangeResult = SCRPs},
7501    CR    = {serviceChangeReply, SCR},
7502    otp_4836_msg(Mid, TransId, CR, Cid).
7503
7504otp_4836_notify_reply_msg(Mid, TransId, Cid, TermId) ->
7505    NR  = #'NotifyReply'{terminationID = [TermId]},
7506    CR  = {notifyReply, NR},
7507    otp_4836_msg(Mid, TransId, CR, Cid).
7508
7509otp_4836_msg(Mid, TransId, CR, Cid) ->
7510    AR  = #'ActionReply'{contextId    = Cid,
7511			 commandReply = [CR]},
7512    ARs  = {actionReplies, [AR]},
7513    TR   = #'TransactionReply'{transactionId     = TransId,
7514			       transactionResult = ARs},
7515    Body = {transactions, [{transactionReply, TR}]},
7516    Mess = #'Message'{version     = 1,
7517		      mId         = Mid,
7518		      messageBody = Body},
7519    #'MegacoMessage'{mess = Mess}.
7520
7521
7522otp_4836_pending_msg(Mid, TransId) ->
7523    TP   = #'TransactionPending'{transactionId = TransId},
7524    Body = {transactions, [{transactionPending, TP}]},
7525    Mess = #'Message'{version     = 1,
7526		      mId         = Mid,
7527		      messageBody = Body},
7528    #'MegacoMessage'{mess = Mess}.
7529
7530
7531-ifndef(megaco_hipe_special).
7532otp_4836_mgc_encode_msg_fun(Mod, Conf) ->
7533    fun(M) ->
7534	    encode_msg(M, Mod, Conf)
7535    end.
7536-endif.
7537%% otp_4836_mgc_encode_msg_fun(Mod, Conf, Ver) ->
7538%%     fun(M) ->
7539%% 	    encode_msg(M, Mod, Conf, Ver)
7540%%     end.
7541
7542-ifndef(megaco_hipe_special).
7543otp_4836_mgc_decode_msg_fun(Mod, Conf) ->
7544    fun(M) ->
7545	    decode_msg(M, Mod, Conf)
7546    end.
7547-endif.
7548%% otp_4836_mgc_decode_msg_fun(Mod, Conf, Ver) ->
7549%%     fun(M) ->
7550%% 	    decode_msg(M, Mod, Conf, Ver)
7551%%     end.
7552
7553%% otp_4836_verify_msg_fun() ->
7554%%     fun(M) ->
7555%% 	    {ok, M}
7556%%     end.
7557
7558-ifndef(megaco_hipe_special).
7559otp_4836_mgc_verify_service_change_req_msg_fun() ->
7560    fun(M) ->
7561	    otp_4836_mgc_verify_service_change_req_msg(M)
7562    end.
7563-endif.
7564
7565otp_4836_mgc_verify_service_change_req_msg(
7566  #'MegacoMessage'{mess = Mess} = M) ->
7567    #'Message'{version     = _V,
7568	       mId         = _Mid,
7569	       messageBody = Body} = Mess,
7570    {transactions, [Trans]} = Body,
7571    {transactionRequest, TR} = Trans,
7572    #'TransactionRequest'{transactionId = _Tid,
7573			  actions = [AR]} = TR,
7574    #'ActionRequest'{contextId = _Cid,
7575		     contextRequest = _CtxReq,
7576		     contextAttrAuditReq = _CtxAar,
7577		     commandRequests = [CR]} = AR,
7578    #'CommandRequest'{command = Cmd,
7579		      optional = _Opt,
7580		      wildcardReturn = _WR} = CR,
7581    {serviceChangeReq, SCR} = Cmd,
7582	    #'ServiceChangeRequest'{terminationID = _TermID,
7583				    serviceChangeParms = SCP} = SCR,
7584    #'ServiceChangeParm'{serviceChangeMethod = restart,
7585			 serviceChangeReason = [[$9,$0,$1|_]]} = SCP,
7586    {ok, M};
7587otp_4836_mgc_verify_service_change_req_msg(M) ->
7588    {error, {invalid_message, M}}.
7589
7590-ifndef(megaco_hipe_special).
7591otp_4836_mgc_verify_notify_req_msg_fun() ->
7592    fun(M) ->
7593	    otp_4836_mgc_verify_notify_req_msg(M)
7594    end.
7595-endif.
7596
7597otp_4836_mgc_verify_notify_req_msg(#'MegacoMessage'{mess = Mess} = M) ->
7598    #'Message'{messageBody = Body} = Mess,
7599    {transactions, [Trans]} = Body,
7600    {transactionRequest, TR} = Trans,
7601    #'TransactionRequest'{actions = [AR]} = TR,
7602    #'ActionRequest'{commandRequests = [CR1,CR2]} = AR,
7603    #'CommandRequest'{command = Cmd1} = CR1,
7604    {notifyReq, NR1} = Cmd1,
7605    #'NotifyRequest'{observedEventsDescriptor = OED1} = NR1,
7606    #'ObservedEventsDescriptor'{observedEventLst = [OE1]} = OED1,
7607    #'ObservedEvent'{eventName = "al/of"} = OE1,
7608    #'CommandRequest'{command = Cmd2} = CR2,
7609    {notifyReq, NR2} = Cmd2,
7610    #'NotifyRequest'{observedEventsDescriptor = OED2} = NR2,
7611    #'ObservedEventsDescriptor'{observedEventLst = [OE2]} = OED2,
7612    #'ObservedEvent'{eventName = "al/of"} = OE2,
7613    {ok, M};
7614otp_4836_mgc_verify_notify_req_msg(M) ->
7615    {error, {invalid_message, M}}.
7616
7617
7618
7619%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7620
7621otp_5805(suite) ->
7622    [];
7623otp_5805(Config) when is_list(Config) ->
7624    Pre = fun() ->
7625                  MgcNode = make_node_name(mgc),
7626                  MgNode  = make_node_name(mg),
7627                  d("start nodes: "
7628                    "~n   MgcNode: ~p"
7629                    "~n   MgNode:  ~p",
7630                    [MgcNode, MgNode]),
7631                  Nodes = [MgcNode, MgNode],
7632                  ok = ?START_NODES(Nodes, true),
7633                  Nodes
7634          end,
7635    Case = fun do_otp_5805/1,
7636    Post = fun(Nodes) ->
7637                   d("stop nodes"),
7638                   ?STOP_NODES(lists:reverse(Nodes))
7639           end,
7640    try_tc(otp_5805, Pre, Case, Post).
7641
7642do_otp_5805([MgcNode, MgNode]) ->
7643    d("[MGC] start the simulator "),
7644    {ok, Mgc} = megaco_test_megaco_generator:start_link("MGC", MgcNode),
7645
7646    d("[MGC] create the event sequence"),
7647    MgcEvSeq = otp_5805_mgc_event_sequence(text, tcp),
7648
7649    i("wait some time before starting the MGC simulation"),
7650    sleep(1000),
7651
7652    d("[MGC] start the simulation"),
7653    {ok, MgcId} =
7654	megaco_test_megaco_generator:exec(Mgc, MgcEvSeq, timer:minutes(1)),
7655
7656    %% i("wait some time before starting the MG simulator"),
7657    %% sleep(1000),
7658
7659    i("await MGC ready announcement"),
7660    receive
7661        announce_mgc ->
7662            i("received MGC ready announcement"),
7663            ok
7664    end,
7665
7666    d("start the MG simulator (generator)"),
7667    {ok, Mg} = megaco_test_tcp_generator:start_link("MG", MgNode),
7668
7669    d("create the MG event sequence"),
7670    MgEvSeq = otp_5805_mg_event_sequence(text, tcp),
7671
7672    d("start the MG simulation"),
7673    {ok, MgId} =
7674	megaco_test_tcp_generator:exec(Mg, MgEvSeq, timer:minutes(1)),
7675
7676    d("await the generator reply(s)"),
7677    await_completion([MgcId, MgId]),
7678
7679    %% Tell Mgc to stop
7680    i("[MGC] stop generator"),
7681    megaco_test_megaco_generator:stop(Mgc),
7682
7683    %% Tell Mg to stop
7684    i("[MG] stop generator"),
7685    megaco_test_tcp_generator:stop(Mg),
7686
7687    i("done", []),
7688    ok.
7689
7690
7691-ifdef(megaco_hipe_special).
7692-define(otp_5805_mg_decode_msg_fun(Mod, Conf),
7693	{?MODULE, decode_msg, [Mod, Conf]}).
7694-define(otp_5805_mg_encode_msg_fun(Mod, Conf),
7695	{?MODULE, encode_msg, [Mod, Conf]}).
7696-define(otp_5805_mg_verify_service_change_rep_msg_fun(),
7697	{?MODULE, otp_5805_mg_verify_service_change_rep_msg, []}).
7698-define(otp_5805_mg_verify_error_descriptor_msg_fun(),
7699	{?MODULE, otp_5805_mg_verify_error_descriptor_msg, []}).
7700-else.
7701-define(otp_5805_mg_decode_msg_fun(Mod, Conf),
7702	otp_5805_mg_decode_msg_fun(Mod, Conf)).
7703-define(otp_5805_mg_encode_msg_fun(Mod, Conf),
7704	otp_5805_mg_encode_msg_fun(Mod, Conf)).
7705-define(otp_5805_mg_verify_service_change_rep_msg_fun(),
7706	otp_5805_mg_verify_service_change_rep_msg_fun()).
7707-define(otp_5805_mg_verify_error_descriptor_msg_fun(),
7708	otp_5805_mg_verify_error_descriptor_msg_fun()).
7709-endif.
7710
7711otp_5805_mg_event_sequence(text, tcp) ->
7712    DecodeFun = ?otp_5805_mg_decode_msg_fun(megaco_pretty_text_encoder, []),
7713    EncodeFun = ?otp_5805_mg_encode_msg_fun(megaco_pretty_text_encoder, []),
7714    Mid = {deviceName,"mg"},
7715    ServiceChangeReq = otp_5805_mg_service_change_request_msg(Mid, 1, 0),
7716    NotifyReqNNV = otp_5805_mg_notify_request_msg("1"),
7717    NotifyReqUV = otp_5805_mg_notify_request_msg("4"),
7718    ServiceChangeReplyVerifyFun =
7719	?otp_5805_mg_verify_service_change_rep_msg_fun(),
7720    EDVerify =
7721	?otp_5805_mg_verify_error_descriptor_msg_fun(),
7722    MgEvSeq = [{debug,  true},
7723	       {decode, DecodeFun},
7724	       {encode, EncodeFun},
7725	       {connect, 2944},
7726
7727	       {send, "service-change-request", ServiceChangeReq},
7728	       {expect_receive, "service-change-reply", {ServiceChangeReplyVerifyFun, 5000}},
7729	       {sleep, 1000},
7730	       {send, "notify request (not negotiated version)", NotifyReqNNV},
7731	       {expect_receive, "error-descriptor", EDVerify},
7732	       {sleep, 1000},
7733 	       {send, "notify request (unsupported version)", NotifyReqUV},
7734	       {expect_receive, "error-descriptor", EDVerify},
7735
7736	       {expect_nothing, 4000},
7737	       disconnect
7738	      ],
7739    MgEvSeq.
7740
7741-ifndef(megaco_hipe_special).
7742otp_5805_mg_encode_msg_fun(Mod, Conf) ->
7743    fun(M) ->
7744            encode_msg(M, Mod, Conf)
7745    end.
7746-endif.
7747
7748-ifndef(megaco_hipe_special).
7749otp_5805_mg_decode_msg_fun(Mod, Conf) ->
7750    fun(M) ->
7751            decode_msg(M, Mod, Conf)
7752    end.
7753-endif.
7754
7755-ifndef(megaco_hipe_special).
7756otp_5805_mg_verify_service_change_rep_msg_fun() ->
7757    fun(M) ->
7758	    otp_5805_mg_verify_service_change_rep_msg(M)
7759    end.
7760-endif.
7761
7762otp_5805_mg_verify_service_change_rep_msg(#'MegacoMessage'{mess = Mess} = M) ->
7763    case Mess of
7764	#'Message'{version     = 1,
7765		   mId         = _MgMid,
7766		   messageBody = Body} ->
7767	    case Body of
7768		{transactions, [Trans]} ->
7769		    case Trans of
7770			{transactionReply, TR} ->
7771			    case TR of
7772				#'TransactionReply'{transactionId = _Tid,
7773						    immAckRequired = asn1_NOVALUE,
7774						    transactionResult = Res} ->
7775				    case Res of
7776					{actionReplies, [AR]} ->
7777					    case AR of
7778						#'ActionReply'{contextId = _Cid,
7779							       errorDescriptor = asn1_NOVALUE,
7780							       contextReply    = _CtxReq,
7781							       commandReply    = [CR]} ->
7782						    case CR of
7783							{serviceChangeReply, SCR} ->
7784							    case SCR of
7785								#'ServiceChangeReply'{
7786								       terminationID       = _TermID,
7787								       serviceChangeResult = SCRes} ->
7788								    case SCRes of
7789									{serviceChangeResParms, SCRP} ->
7790									    case SCRP of
7791										#'ServiceChangeResParm'{
7792											serviceChangeMgcId   = _MgcMid,
7793											serviceChangeVersion = 2} ->
7794										    {ok, M};
7795										_ ->
7796										    {error, {invalid_scrp, SCRP}}
7797									    end;
7798									_ ->
7799									    {error, {invalid_scres, SCRes}}
7800								    end;
7801								_ ->
7802								    {error, {invalid_scr, SCR}}
7803							    end;
7804							_ ->
7805							    {error, {invalid_cr, CR}}
7806						    end;
7807						_ ->
7808						    {error, {invalid_ar, AR}}
7809					    end;
7810					_ ->
7811					    {error, {invalid_tres, Res}}
7812				    end;
7813				_ ->
7814				    {error, {invalid_tr, TR}}
7815			    end;
7816			_ ->
7817			    {error, {invalid_trans, Trans}}
7818		    end;
7819		_ ->
7820		    {error, {invalid_body, Body}}
7821	    end;
7822	_ ->
7823	    {error, {invalid_mess, Mess}}
7824    end;
7825otp_5805_mg_verify_service_change_rep_msg(M) ->
7826    {error, {invalid_message, M}}.
7827
7828
7829-ifndef(megaco_hipe_special).
7830otp_5805_mg_verify_error_descriptor_msg_fun() ->
7831    fun(M) ->
7832	    otp_5805_mg_verify_error_descriptor_msg(M)
7833    end.
7834-endif.
7835
7836otp_5805_mg_verify_error_descriptor_msg(#'MegacoMessage'{mess = Mess} = M) ->
7837    case Mess of
7838	#'Message'{version     = 2,
7839		   mId         = _MgMid,
7840		   messageBody = Body} ->
7841	    io:format("otp_5805_mg_verify_error_descriptor_msg_fun -> ok"
7842		      "~n   Body:  ~p"
7843		      "~n", [Body]),
7844	    case Body of
7845		{messageError, ED} ->
7846		    case ED of
7847			#'ErrorDescriptor'{
7848			      errorCode = ?megaco_version_not_supported} ->
7849			    {ok, M};
7850			_ ->
7851			    {error, {invalid_ed, ED}}
7852		    end;
7853		_ ->
7854		    {error, {invalid_body, Body}}
7855	    end;
7856	_ ->
7857	    {error, {invalid_mess, Mess}}
7858    end;
7859otp_5805_mg_verify_error_descriptor_msg(M) ->
7860    {error, {invalid_message, M}}.
7861
7862otp_5805_mg_service_change_request_ar(_Mid, Cid) ->
7863    Prof  = cre_serviceChangeProf("resgw", 1),
7864    SCP   = cre_serviceChangeParm(restart, 2, ["901 mg col boot"], Prof),
7865    Root  = #megaco_term_id{id = ["root"]},
7866    SCR   = cre_serviceChangeReq([Root], SCP),
7867    CMD   = cre_command(SCR),
7868    CR    = cre_cmdReq(CMD),
7869    cre_actionReq(Cid, [CR]).
7870
7871otp_5805_mg_service_change_request_msg(Mid, TransId, Cid) ->
7872    AR    = otp_5805_mg_service_change_request_ar(Mid, Cid),
7873    TR    = cre_transReq(TransId, [AR]),
7874    Trans = cre_transaction(TR),
7875    Mess  = cre_message(1, Mid, cre_transactions([Trans])),
7876    cre_megacoMessage(Mess).
7877
7878%% otp_5805_mg_notify_request_ar(Rid, Tid, Cid) ->
7879%%     TT      = cre_timeNotation("19990729", "22000000"),
7880%%     Ev      = cre_obsEvent("al/of", TT),
7881%%     EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
7882%%     NR      = cre_notifyReq([Tid], EvsDesc),
7883%%     CMD     = cre_command(NR),
7884%%     CR      = cre_cmdReq(CMD),
7885%%     cre_actionReq(Cid, [CR]).
7886
7887otp_5805_mg_notify_request_msg(V) ->
7888    M =
7889"MEGACO/" ++ V ++ " mg
7890Transaction = 2 {
7891	Context = 1 {
7892		Notify = 00000000/00000000/01101101 {
7893			ObservedEvents = 1 {
7894				19990729T22000000:al/of
7895			}
7896		}
7897	}
7898}",
7899    list_to_binary(M).
7900
7901
7902%%
7903%% MGC generator stuff
7904%%
7905
7906-ifdef(megaco_hipe_special).
7907-define(otp_5805_mgc_verify_handle_connect_fun(),
7908        {?MODULE, otp_5805_mgc_verify_handle_connect, []}).
7909-define(otp_5805_mgc_verify_service_change_req_fun(Mid),
7910        {?MODULE, otp_5805_mgc_verify_service_change_req, [Mid]}).
7911-define(otp_5805_mgc_verify_handle_syntax_error_fun(),
7912        {?MODULE, otp_5805_mgc_verify_handle_syntax_error, []}).
7913-define(otp_5805_mgc_verify_handle_disconnect_fun(),
7914        {?MODULE, otp_5805_mgc_verify_handle_disconnect, []}).
7915-else.
7916-define(otp_5805_mgc_verify_handle_connect_fun(),
7917        fun otp_5805_mgc_verify_handle_connect/1).
7918-define(otp_5805_mgc_verify_service_change_req_fun(Mid),
7919        otp_5805_mgc_verify_service_change_req_fun(Mid)).
7920-define(otp_5805_mgc_verify_handle_syntax_error_fun(),
7921	fun otp_5805_mgc_verify_handle_syntax_error/1).
7922-define(otp_5805_mgc_verify_handle_disconnect_fun(),
7923	fun otp_5805_mgc_verify_handle_disconnect/1).
7924-endif.
7925
7926otp_5805_mgc_event_sequence(text, tcp) ->
7927    CTRL = self(),
7928    Mid = {deviceName,"ctrl"},
7929    RI = [
7930          {port,             2944},
7931          {encoding_module,  megaco_pretty_text_encoder},
7932          {encoding_config,  []},
7933          {transport_module, megaco_tcp}
7934         ],
7935    ConnectVerify          = ?otp_5805_mgc_verify_handle_connect_fun(),
7936    ServiceChangeReqVerify = ?otp_5805_mgc_verify_service_change_req_fun(Mid),
7937    SyntaxErrorVerify1     = ?otp_5805_mgc_verify_handle_syntax_error_fun(),
7938    SyntaxErrorVerify2     = ?otp_5805_mgc_verify_handle_syntax_error_fun(),
7939    DiscoVerify            = ?otp_5805_mgc_verify_handle_disconnect_fun(),
7940    EvSeq = [
7941             {debug, true},
7942	     {megaco_trace, disable},
7943	     {megaco_trace, max},
7944             megaco_start,
7945             {megaco_start_user, Mid, RI, []},
7946             start_transport,
7947             listen,
7948
7949             %% ANNOUNCE READY
7950             {trigger, fun() -> CTRL ! announce_mgc end},
7951
7952             {megaco_callback, handle_connect, ConnectVerify},
7953	     {megaco_conn_info, all},
7954             {megaco_callback, handle_trans_request_sc, ServiceChangeReqVerify},
7955	     {megaco_update_conn_info, protocol_version, 2},
7956             {megaco_callback, handle_syntax_error, SyntaxErrorVerify1},
7957             {megaco_callback, handle_syntax_error, SyntaxErrorVerify2},
7958             {megaco_callback, handle_disconnect, DiscoVerify},
7959             megaco_stop_user,
7960             megaco_stop
7961            ],
7962    EvSeq.
7963
7964otp_5805_mgc_verify_handle_connect({handle_connect, CH, 1}) ->
7965    io:format("otp_5805_mgc_verify_handle_connect -> ok"
7966	      "~n   CH:  ~p"
7967	      "~n", [CH]),
7968    {ok, CH, ok};
7969otp_5805_mgc_verify_handle_connect({handle_connect, CH, V}) ->
7970    io:format("otp_5805_mgc_verify_handle_connect -> unexpected version"
7971	      "~n   CH:  ~p"
7972	      "~n   V:   ~p"
7973	      "~n", [CH, V]),
7974    {error, {unexpected_version, V}, ok};
7975otp_5805_mgc_verify_handle_connect(Else) ->
7976    {error, Else, ok}.
7977
7978
7979-ifndef(megaco_hipe_special).
7980otp_5805_mgc_verify_service_change_req_fun(Mid) ->
7981    fun(Ev) ->
7982	    otp_5805_mgc_verify_service_change_req(Ev, Mid)
7983    end.
7984-endif.
7985
7986otp_5805_mgc_verify_service_change_req({handle_trans_request, _, V, [AR]},
7987				       Mid) ->
7988    io:format("otp_5805_mgc_verify_service_change_req -> ok so far"
7989	      "~n   V:   ~p"
7990	      "~n", [V]),
7991    case AR of
7992	#'ActionRequest'{commandRequests = [CR]} ->
7993	    case CR of
7994		#'CommandRequest'{command = Cmd} ->
7995		    case Cmd of
7996			{serviceChangeReq,
7997			 #'ServiceChangeRequest'{terminationID = [Tid],
7998						 serviceChangeParms = Parms}} ->
7999			    case Tid of
8000				#megaco_term_id{contains_wildcards = false,
8001						id = ["root"]} ->
8002				    case Parms of
8003					#'ServiceChangeParm'{
8004						 serviceChangeMethod = restart,
8005						 serviceChangeVersion = 2,
8006						 serviceChangeReason = [[$9,$0,$1|_]]} ->
8007					    Reply =
8008						{discard_ack,
8009						 [otp_5805_mgc_service_change_reply_ar(Mid, 1)]},
8010					    {ok, AR, Reply};
8011					_ ->
8012					    Err = {invalid_SCP, Parms},
8013					    ED = otp_5805_err_desc(Parms),
8014					    ErrReply =
8015						{discard_ack, ED},
8016					    {error, Err, ErrReply}
8017				    end;
8018				_ ->
8019				    Err = {invalid_termination_id, Tid},
8020				    ED = otp_5805_err_desc(Tid),
8021				    ErrReply = {discard_ack, ED},
8022				    {error, Err, ErrReply}
8023			    end;
8024			_ ->
8025			    Err = {invalid_command, Cmd},
8026			    ED = otp_5805_err_desc(Cmd),
8027			    ErrReply = {discard_ack, ED},
8028			    {error, Err, ErrReply}
8029		    end;
8030		_ ->
8031		    Err = {invalid_command_request, CR},
8032		    ED = otp_5805_err_desc(CR),
8033		    ErrReply = {discard_ack, ED},
8034		    {error, Err, ErrReply}
8035	    end;
8036	_ ->
8037	    Err = {invalid_action_request, AR},
8038	    ED = otp_5805_err_desc(AR),
8039	    ErrReply = {discard_ack, ED},
8040	    {error, Err, ErrReply}
8041    end;
8042otp_5805_mgc_verify_service_change_req(Else, _Mid) ->
8043    ED       = otp_5805_err_desc(Else),
8044    ErrReply = {discard_ack, ED},
8045    {error, Else, ErrReply}.
8046
8047otp_5805_mgc_verify_handle_syntax_error({handle_syntax_error, CH, _, ED})
8048  when is_record(ED, 'ErrorDescriptor') ->
8049    io:format("otp_5805_mgc_verify_handle_syntax_error -> ok so far"
8050	      "~n   CH: ~p"
8051	      "~n   ED:  ~p"
8052	      "~n", [CH, ED]),
8053    case ED of
8054	#'ErrorDescriptor'{errorCode = ?megaco_version_not_supported} ->
8055	    {ok, CH, reply};
8056	#'ErrorDescriptor'{errorCode = Code} ->
8057	    {error, {invalid_errorCode, Code}, ok}
8058    end;
8059otp_5805_mgc_verify_handle_syntax_error(Else) ->
8060    io:format("otp_5805_mgc_verify_handle_syntax_error -> unknown"
8061	      "~n   Else: ~p~n", [Else]),
8062    {error, Else, ok}.
8063
8064otp_5805_mgc_verify_handle_disconnect({handle_disconnect, CH, V, _R}) ->
8065    io:format("otp_5805_mgc_verify_handle_disconnect -> ok"
8066	      "~n   CH: ~p"
8067	      "~n   V:  ~p"
8068	      "~n   _R:  ~p"
8069	      "~n", [CH, V, _R]),
8070    {ok, CH, ok};
8071otp_5805_mgc_verify_handle_disconnect(Else) ->
8072    io:format("otp_5805_mgc_verify_handle_disconnect -> unknown"
8073	      "~n   Else: ~p~n", [Else]),
8074    {error, Else, ok}.
8075
8076otp_5805_mgc_service_change_reply_ar(Mid, Cid) ->
8077    SCRP  = cre_serviceChangeResParm(Mid, 2),
8078    SCRes = cre_serviceChangeResult(SCRP),
8079    Root  = #megaco_term_id{id = ["root"]},
8080    SCR   = cre_serviceChangeReply([Root], SCRes),
8081    CR    = cre_cmdReply(SCR),
8082    cre_actionReply(Cid, [CR]).
8083
8084%% otp_5805_mgc_notify_reply_ar(Cid, TermId) ->
8085%%     NR    = cre_notifyReply([TermId]),
8086%%     CR    = cre_cmdReply(NR),
8087%%     cre_actionReply(Cid, [CR]).
8088
8089
8090otp_5805_err_desc(T) ->
8091    EC = ?megaco_internal_gateway_error,
8092    ET = lists:flatten(io_lib:format("~w",[T])),
8093    #'ErrorDescriptor'{errorCode = EC, errorText = ET}.
8094
8095
8096%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8097
8098otp_5881(suite) ->
8099    [];
8100otp_5881(Config) when is_list(Config) ->
8101    ?SKIP("deprecated by OTP-5887"),
8102    put(verbosity, ?TEST_VERBOSITY),
8103    put(sname,     "TEST"),
8104    put(tc,        otp_5881),
8105    i("starting"),
8106
8107    MgcNode = make_node_name(mgc),
8108    MgNode  = make_node_name(mg),
8109    d("start nodes: "
8110      "~n   MgcNode: ~p"
8111      "~n   MgNode:  ~p",
8112      [MgcNode, MgNode]),
8113    Nodes = [MgcNode, MgNode],
8114    ok = ?START_NODES(Nodes, true),
8115
8116    d("start the MGC simulator (generator)"),
8117    {ok, Mgc} = megaco_test_tcp_generator:start_link("MGC", MgcNode),
8118
8119    d("create the MGC event sequence"),
8120    MgcEvSeq = otp_5881_mgc_event_sequence(text, tcp),
8121
8122    d("start the MGC simulation"),
8123    {ok, MgcId} = megaco_test_tcp_generator:exec(Mgc, MgcEvSeq),
8124
8125    i("await MGC ready announcement"),
8126    receive
8127        announce_mgc ->
8128            i("received MGC ready announcement"),
8129            ok
8130    end,
8131
8132    i("[MG] start"),
8133    MgMid = {deviceName, "mg"},
8134    ReqTmr = #megaco_incr_timer{wait_for    = 3000,
8135                                factor      = 1,
8136                                incr        = 0,
8137                                max_retries = 3},
8138    %% 5000,  %% Does not matter since we will not use this anyway...
8139    LongReqTmr = #megaco_incr_timer{wait_for    = 3000,
8140                                    factor      = 1,
8141                                    incr        = 0,
8142                                    max_retries = 3},
8143    PendingTmr = 10000,
8144    ReplyTmr = 16000,
8145    MgConfig = [{request_timer,      ReqTmr},
8146                {long_request_timer, LongReqTmr},
8147                {pending_timer,      PendingTmr},
8148                {reply_timer,        ReplyTmr}],
8149    {ok, Mg} = ?MG_START(MgNode, MgMid, text, tcp, MgConfig, ?MG_VERBOSITY),
8150
8151    i("[MG] verify transaction-id: undefined_serial"),
8152    otp_5881_verify_trans_id(Mg, undefined_serial),
8153
8154    i("[MG] connect to the MGC (service change)"),
8155    ServChRes = ?MG_SERV_CHANGE(Mg),
8156    d("service change result: ~p", [ServChRes]),
8157
8158    i("[MG] verify transaction-id: 1"),
8159    otp_5881_verify_trans_id(Mg, 1),
8160
8161    d("[MG] send the notify"),
8162    {ok, Reply} = (catch ?MG_NOTIF_RAR(Mg)),
8163    {1, {ok, [AR]}} = Reply,
8164    d("[MG] ActionReply: ~p", [AR]),
8165
8166    i("[MG] verify transaction-id: 2"),
8167    otp_5881_verify_trans_id(Mg, 2),
8168
8169    d("await the generator reply"),
8170    await_completion([MgcId]),
8171
8172    %% Tell MG to stop
8173    i("[MG] stop"),
8174    ?MG_STOP(Mg),
8175
8176    %% Tell Mgc to stop
8177    i("[MGC] stop generator"),
8178    megaco_test_tcp_generator:stop(Mgc),
8179
8180    %% Cleanup
8181    d("stop nodes"),
8182    ?STOP_NODES(lists:reverse(Nodes)),
8183
8184    i("done", []),
8185    ok.
8186
8187otp_5881_verify_trans_id(Mg, Expected) ->
8188    case ?MG_CONN_INFO(Mg, trans_id) of
8189	Expected ->
8190	    ok;
8191	ErroneousValue ->
8192	    throw({unexpected_transaction_id_value, ErroneousValue, Expected})
8193    end.
8194
8195
8196-ifdef(megaco_hipe_special).
8197-define(otp_5881_mgc_decode_msg_fun(Mod, Conf),
8198	{?MODULE, decode_msg, [Mod, Conf]}).
8199-define(otp_5881_mgc_encode_msg_fun(Mod, Conf),
8200	{?MODULE, encode_msg, [Mod, Conf]}).
8201-define(otp_5881_mgc_verify_service_change_req_msg_fun(),
8202	{?MODULE, otp_5881_mgc_verify_service_change_req_msg, []}).
8203-define(otp_5881_mgc_verify_notify_req_msg_fun(),
8204	{?MODULE, otp_5881_mgc_verify_notify_req_msg, []}).
8205-else.
8206-define(otp_5881_mgc_decode_msg_fun(Mod, Conf),
8207	otp_5881_mgc_decode_msg_fun(Mod, Conf)).
8208-define(otp_5881_mgc_encode_msg_fun(Mod, Conf),
8209	otp_5881_mgc_encode_msg_fun(Mod, Conf)).
8210-define(otp_5881_mgc_verify_service_change_req_msg_fun(),
8211	otp_5881_mgc_verify_service_change_req_msg_fun()).
8212-define(otp_5881_mgc_verify_notify_req_msg_fun(),
8213	otp_5881_mgc_verify_notify_req_msg_fun()).
8214-endif.
8215
8216otp_5881_mgc_event_sequence(text, tcp) ->
8217    CTRL = self(),
8218    DecodeFun = ?otp_5881_mgc_decode_msg_fun(megaco_pretty_text_encoder, []),
8219    EncodeFun = ?otp_5881_mgc_encode_msg_fun(megaco_pretty_text_encoder, []),
8220    Mid = {deviceName,"ctrl"},
8221    ServiceChangeReply = otp_5881_service_change_reply_msg(Mid, 1, 0),
8222    TermId = #megaco_term_id{id = ["00000000","00000000","01101101"]},
8223    NotifyReply = otp_5881_notify_reply_msg(Mid, 2, 0, TermId),
8224    %% Pending = otp_5881_pending_msg(Mid,2),
8225    ServiceChangeVerifyFun = ?otp_5881_mgc_verify_service_change_req_msg_fun(),
8226    NotifyReqVerifyFun     = ?otp_5881_mgc_verify_notify_req_msg_fun(),
8227    MgcEvSeq = [{debug,  true},
8228		{decode, DecodeFun},
8229		{encode, EncodeFun},
8230		{listen, 2944},
8231
8232                %% ANNOUNCE READY
8233                {trigger, "announce ready", fun() -> CTRL ! announce_mgc end},
8234
8235		{expect_accept, any},
8236		{expect_receive, "service-change-request", {ServiceChangeVerifyFun, 10000}},
8237		{send, "service-change-reply", ServiceChangeReply},
8238		{expect_receive, "notify-request", {NotifyReqVerifyFun, 10000}},
8239  		{send, "notify-reply", NotifyReply},
8240		{sleep, 2000}
8241	       ],
8242    MgcEvSeq.
8243
8244-ifndef(megaco_hipe_special).
8245otp_5881_mgc_encode_msg_fun(Mod, Conf) ->
8246    fun(M) ->
8247	    encode_msg(M, Mod, Conf)
8248    end.
8249-endif.
8250
8251-ifndef(megaco_hipe_special).
8252otp_5881_mgc_decode_msg_fun(Mod, Conf) ->
8253    fun(M) ->
8254	    decode_msg(M, Mod, Conf)
8255    end.
8256-endif.
8257
8258otp_5881_service_change_reply_msg(Mid, TransId, Cid) ->
8259    SCRP  = #'ServiceChangeResParm'{serviceChangeMgcId = Mid},
8260    SCRPs = {serviceChangeResParms,SCRP},
8261    Root  = #megaco_term_id{id = ["root"]},
8262    SCR   = #'ServiceChangeReply'{terminationID       = [Root],
8263				  serviceChangeResult = SCRPs},
8264    CR    = {serviceChangeReply, SCR},
8265    otp_5881_msg(Mid, TransId, CR, Cid).
8266
8267otp_5881_notify_reply_msg(Mid, TransId, Cid, TermId) ->
8268    NR  = #'NotifyReply'{terminationID = [TermId]},
8269    CR  = {notifyReply, NR},
8270    otp_5881_msg(Mid, TransId, CR, Cid).
8271
8272otp_5881_msg(Mid, TransId, CR, Cid) ->
8273    AR  = #'ActionReply'{contextId    = Cid,
8274			 commandReply = [CR]},
8275    ARs  = {actionReplies, [AR]},
8276    TR   = #'TransactionReply'{transactionId     = TransId,
8277			       transactionResult = ARs},
8278    Body = {transactions, [{transactionReply, TR}]},
8279    Mess = #'Message'{version     = 1,
8280		      mId         = Mid,
8281		      messageBody = Body},
8282    #'MegacoMessage'{mess = Mess}.
8283
8284
8285%% otp_5881_pending_msg(Mid, TransId) ->
8286%%     TP   = #'TransactionPending'{transactionId = TransId},
8287%%     Body = {transactions, [{transactionPending, TP}]},
8288%%     Mess = #'Message'{version     = 1,
8289%% 		      mId         = Mid,
8290%% 		      messageBody = Body},
8291%%     #'MegacoMessage'{mess = Mess}.
8292
8293
8294-ifndef(megaco_hipe_special).
8295otp_5881_mgc_verify_service_change_req_msg_fun() ->
8296    fun(M) ->
8297	    otp_5881_mgc_verify_service_change_req_msg(M)
8298    end.
8299-endif.
8300
8301otp_5881_mgc_verify_service_change_req_msg(
8302  #'MegacoMessage'{mess = Mess} = M) ->
8303    #'Message'{version     = _V,
8304	       mId         = _Mid,
8305	       messageBody = Body} = Mess,
8306    {transactions, [Trans]} = Body,
8307    {transactionRequest, TR} = Trans,
8308    #'TransactionRequest'{transactionId = _Tid,
8309			  actions = [AR]} = TR,
8310    #'ActionRequest'{contextId = _Cid,
8311		     contextRequest = _CtxReq,
8312		     contextAttrAuditReq = _CtxAar,
8313		     commandRequests = [CR]} = AR,
8314    #'CommandRequest'{command = Cmd,
8315		      optional = _Opt,
8316		      wildcardReturn = _WR} = CR,
8317    {serviceChangeReq, SCR} = Cmd,
8318    #'ServiceChangeRequest'{terminationID = _TermID,
8319			    serviceChangeParms = SCP} = SCR,
8320    #'ServiceChangeParm'{serviceChangeMethod = restart,
8321			 serviceChangeReason = [[$9,$0,$1|_]]} = SCP,
8322    {ok, M};
8323otp_5881_mgc_verify_service_change_req_msg(M) ->
8324    {error, {invalid_message, M}}.
8325
8326-ifndef(megaco_hipe_special).
8327otp_5881_mgc_verify_notify_req_msg_fun() ->
8328    fun(M) ->
8329	    otp_5881_mgc_verify_notify_req_msg(M)
8330    end.
8331-endif.
8332
8333otp_5881_mgc_verify_notify_req_msg(#'MegacoMessage'{mess = Mess} = M) ->
8334    #'Message'{messageBody = Body} = Mess,
8335    {transactions, [Trans]} = Body,
8336    {transactionRequest, TR} = Trans,
8337    #'TransactionRequest'{actions = [AR]} = TR,
8338    #'ActionRequest'{commandRequests = [CR1,CR2]} = AR,
8339    #'CommandRequest'{command = Cmd1} = CR1,
8340    {notifyReq, NR1} = Cmd1,
8341    #'NotifyRequest'{observedEventsDescriptor = OED1} = NR1,
8342    #'ObservedEventsDescriptor'{observedEventLst = [OE1]} = OED1,
8343    #'ObservedEvent'{eventName = "al/of"} = OE1,
8344    #'CommandRequest'{command = Cmd2} = CR2,
8345    {notifyReq, NR2} = Cmd2,
8346    #'NotifyRequest'{observedEventsDescriptor = OED2} = NR2,
8347    #'ObservedEventsDescriptor'{observedEventLst = [OE2]} = OED2,
8348    #'ObservedEvent'{eventName = "al/of"} = OE2,
8349    {ok, M};
8350otp_5881_mgc_verify_notify_req_msg(M) ->
8351    {error, {invalid_message, M}}.
8352
8353
8354
8355%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8356
8357otp_5887(suite) ->
8358    [];
8359otp_5887(Config) when is_list(Config) ->
8360    Pre = fun() ->
8361                  MgcNode = make_node_name(mgc),
8362                  MgNode  = make_node_name(mg),
8363                  d("start nodes: "
8364                    "~n      MgcNode: ~p"
8365                    "~n      MgNode:  ~p",
8366                    [MgcNode, MgNode]),
8367                  Nodes = [MgcNode, MgNode],
8368                  ok = ?START_NODES(Nodes, true),
8369                  Nodes
8370          end,
8371    Case = fun do_otp_5887/1,
8372    Post = fun(Nodes) ->
8373                   d("stop nodes"),
8374                   ?STOP_NODES(lists:reverse(Nodes))
8375           end,
8376    try_tc(otp_5887, Pre, Case, Post).
8377
8378do_otp_5887([MgcNode, MgNode]) ->
8379    d("start the MGC simulator (generator)"),
8380    {ok, Mgc} = megaco_test_tcp_generator:start_link("MGC", MgcNode),
8381
8382    d("create the MGC event sequence"),
8383    MgcEvSeq = otp_5887_mgc_event_sequence(text, tcp),
8384
8385    d("start the MGC simulation"),
8386    {ok, MgcId} = megaco_test_tcp_generator:exec(Mgc, MgcEvSeq),
8387
8388    i("await MGC ready announcement"),
8389    receive
8390        announce_mgc ->
8391            i("received MGC ready announcement"),
8392            ok
8393    end,
8394
8395    i("[MG] start"),
8396    MgMid = {deviceName, "mg"},
8397    ReqTmr = #megaco_incr_timer{wait_for    = 3000,
8398                                factor      = 1,
8399                                incr        = 0,
8400                                max_retries = 3},
8401    %% 5000,  %% Does not matter since we will not use this anyway...
8402    LongReqTmr = #megaco_incr_timer{wait_for    = 3000,
8403                                    factor      = 1,
8404                                    incr        = 0,
8405                                    max_retries = 3},
8406    PendingTmr = 10000,
8407    ReplyTmr = 16000,
8408    MgConfig = [{request_timer,      ReqTmr},
8409                {long_request_timer, LongReqTmr},
8410                {pending_timer,      PendingTmr},
8411                {reply_timer,        ReplyTmr}],
8412    {ok, Mg} = ?MG_START(MgNode, MgMid, text, tcp, MgConfig, ?MG_VERBOSITY),
8413
8414    i("[MG] conn info: ~n~p", [?MG_CONN_INFO(Mg, all)]),
8415
8416    i("[MG] verify conn transaction-id: 1"),
8417    otp_5887_verify_conn_trans_id(Mg, 1),
8418
8419    i("[MG] user info: ~n~p", [?MG_USER_INFO(Mg, all)]),
8420
8421    i("[MG] verify user transaction-id: undefined_serial"),
8422    otp_5887_verify_user_trans_id(Mg, undefined_serial),
8423
8424    i("[MG] connect to the MGC (service change)"),
8425    ServChRes = ?MG_SERV_CHANGE(Mg),
8426    d("service change result: ~p", [ServChRes]),
8427
8428    i("[MG] conn info: ~n~p", [?MG_CONN_INFO(Mg, all)]),
8429
8430    i("[MG] verify conn transaction-id: 2"),
8431    otp_5887_verify_conn_trans_id(Mg, 2),
8432
8433    i("[MG] user info: ~n~p", [?MG_USER_INFO(Mg, all)]),
8434
8435    i("[MG] verify user transaction-id: 1"),
8436    otp_5887_verify_user_trans_id(Mg, 1),
8437
8438    d("[MG] send the notify"),
8439    {ok, Reply} = (catch ?MG_NOTIF_RAR(Mg)),
8440    {1, {ok, [AR]}} = Reply,
8441    d("[MG] ActionReply: ~p", [AR]),
8442
8443    i("[MG] conn info: ~n~p", [?MG_CONN_INFO(Mg, all)]),
8444
8445    i("[MG] verify conn transaction-id: 3"),
8446    otp_5887_verify_conn_trans_id(Mg, 3),
8447
8448    i("[MG] user info: ~n~p", [?MG_USER_INFO(Mg, all)]),
8449
8450    i("[MG] verify user transaction-id: 2"),
8451    otp_5887_verify_user_trans_id(Mg, 2),
8452
8453    d("await the generator reply"),
8454    await_completion([MgcId]),
8455
8456    %% Tell MG to stop
8457    i("[MG] stop"),
8458    ?MG_STOP(Mg),
8459
8460    %% Tell Mgc to stop
8461    i("[MGC] stop generator"),
8462    megaco_test_tcp_generator:stop(Mgc),
8463
8464    i("done", []),
8465    ok.
8466
8467
8468otp_5887_verify_conn_trans_id(Mg, Expected) ->
8469    F = fun() -> (catch ?MG_CONN_INFO(Mg, trans_id)) end,
8470    otp_5887_verify_trans_id(F, Expected).
8471
8472otp_5887_verify_user_trans_id(Mg, Expected) ->
8473    F = fun() -> (catch ?MG_USER_INFO(Mg, trans_id)) end,
8474    otp_5887_verify_trans_id(F, Expected).
8475
8476otp_5887_verify_trans_id(F, Expected) ->
8477    case F() of
8478	Expected ->
8479	    ok;
8480	ErroneousValue ->
8481	    throw({unexpected_transaction_id_value, ErroneousValue, Expected})
8482    end.
8483
8484
8485-ifdef(megaco_hipe_special).
8486-define(otp_5887_mgc_decode_msg_fun(Mod, Conf),
8487	{?MODULE, decode_msg, [Mod, Conf]}).
8488-define(otp_5887_mgc_encode_msg_fun(Mod, Conf),
8489	{?MODULE, encode_msg, [Mod, Conf]}).
8490-define(otp_5887_mgc_verify_service_change_req_msg_fun(),
8491	{?MODULE, otp_5887_mgc_verify_service_change_req_msg, []}).
8492-define(otp_5887_mgc_verify_notify_req_msg_fun(),
8493	{?MODULE, otp_5887_mgc_verify_notify_req_msg, []}).
8494-else.
8495-define(otp_5887_mgc_decode_msg_fun(Mod, Conf),
8496	otp_5887_mgc_decode_msg_fun(Mod, Conf)).
8497-define(otp_5887_mgc_encode_msg_fun(Mod, Conf),
8498	otp_5887_mgc_encode_msg_fun(Mod, Conf)).
8499-define(otp_5887_mgc_verify_service_change_req_msg_fun(),
8500	otp_5887_mgc_verify_service_change_req_msg_fun()).
8501-define(otp_5887_mgc_verify_notify_req_msg_fun(),
8502	otp_5887_mgc_verify_notify_req_msg_fun()).
8503-endif.
8504
8505otp_5887_mgc_event_sequence(text, tcp) ->
8506    CTRL = self(),
8507    DecodeFun = ?otp_5887_mgc_decode_msg_fun(megaco_pretty_text_encoder, []),
8508    EncodeFun = ?otp_5887_mgc_encode_msg_fun(megaco_pretty_text_encoder, []),
8509    Mid = {deviceName,"ctrl"},
8510    ServiceChangeReply = otp_5887_service_change_reply_msg(Mid, 1, 0),
8511    TermId = #megaco_term_id{id = ["00000000","00000000","01101101"]},
8512    NotifyReply = otp_5887_notify_reply_msg(Mid, 2, 0, TermId),
8513    ServiceChangeVerifyFun = ?otp_5887_mgc_verify_service_change_req_msg_fun(),
8514    NotifyReqVerifyFun     = ?otp_5887_mgc_verify_notify_req_msg_fun(),
8515    MgcEvSeq = [{debug,  true},
8516		{decode, DecodeFun},
8517		{encode, EncodeFun},
8518		{listen, 2944},
8519
8520                %% ANNOUNCE READY
8521                {trigger, "announce ready", fun() -> CTRL ! announce_mgc end},
8522
8523		{expect_accept, any},
8524		{expect_receive, "service-change-request", {ServiceChangeVerifyFun, 10000}},
8525		{send, "service-change-reply", ServiceChangeReply},
8526		{expect_receive, "notify-request", {NotifyReqVerifyFun, 10000}},
8527  		{send, "notify-reply", NotifyReply},
8528		{sleep, 2000}
8529	       ],
8530    MgcEvSeq.
8531
8532otp_5887_service_change_reply_msg(Mid, TransId, Cid) ->
8533    SCRP  = #'ServiceChangeResParm'{serviceChangeMgcId = Mid},
8534    SCRPs = {serviceChangeResParms,SCRP},
8535    Root  = #megaco_term_id{id = ["root"]},
8536    SCR   = #'ServiceChangeReply'{terminationID       = [Root],
8537				  serviceChangeResult = SCRPs},
8538    CR    = {serviceChangeReply, SCR},
8539    otp_5887_msg(Mid, TransId, CR, Cid).
8540
8541otp_5887_notify_reply_msg(Mid, TransId, Cid, TermId) ->
8542    NR  = #'NotifyReply'{terminationID = [TermId]},
8543    CR  = {notifyReply, NR},
8544    otp_5887_msg(Mid, TransId, CR, Cid).
8545
8546otp_5887_msg(Mid, TransId, CR, Cid) ->
8547    AR  = #'ActionReply'{contextId    = Cid,
8548			 commandReply = [CR]},
8549    ARs  = {actionReplies, [AR]},
8550    TR   = #'TransactionReply'{transactionId     = TransId,
8551			       transactionResult = ARs},
8552    Body = {transactions, [{transactionReply, TR}]},
8553    Mess = #'Message'{version     = 1,
8554		      mId         = Mid,
8555		      messageBody = Body},
8556    #'MegacoMessage'{mess = Mess}.
8557
8558
8559%% otp_5887_pending_msg(Mid, TransId) ->
8560%%     TP   = #'TransactionPending'{transactionId = TransId},
8561%%     Body = {transactions, [{transactionPending, TP}]},
8562%%     Mess = #'Message'{version     = 1,
8563%% 		      mId         = Mid,
8564%% 		      messageBody = Body},
8565%%     #'MegacoMessage'{mess = Mess}.
8566
8567
8568-ifndef(megaco_hipe_special).
8569otp_5887_mgc_encode_msg_fun(Mod, Conf) ->
8570    fun(M) ->
8571	    encode_msg(M, Mod, Conf)
8572    end.
8573-endif.
8574%% otp_5887_mgc_encode_msg_fun(Mod, Conf, Ver) ->
8575%%     fun(M) ->
8576%% 	    encode_msg(M, Mod, Conf, Ver)
8577%%     end.
8578
8579-ifndef(megaco_hipe_special).
8580otp_5887_mgc_decode_msg_fun(Mod, Conf) ->
8581    fun(M) ->
8582	    decode_msg(M, Mod, Conf)
8583    end.
8584-endif.
8585%% otp_5887_mgc_decode_msg_fun(Mod, Conf, Ver) ->
8586%%     fun(M) ->
8587%% 	    decode_msg(M, Mod, Conf, Ver)
8588%%     end.
8589
8590-ifndef(megaco_hipe_special).
8591otp_5887_mgc_verify_service_change_req_msg_fun() ->
8592    fun(M) ->
8593	    otp_5887_mgc_verify_service_change_req_msg(M)
8594    end.
8595-endif.
8596
8597otp_5887_mgc_verify_service_change_req_msg(
8598  #'MegacoMessage'{mess = Mess} = M) ->
8599    #'Message'{version     = _V,
8600	       mId         = _Mid,
8601	       messageBody = Body} = Mess,
8602    {transactions, [Trans]} = Body,
8603    {transactionRequest, TR} = Trans,
8604    #'TransactionRequest'{transactionId = _Tid,
8605			  actions = [AR]} = TR,
8606    #'ActionRequest'{contextId = _Cid,
8607		     contextRequest = _CtxReq,
8608		     contextAttrAuditReq = _CtxAar,
8609		     commandRequests = [CR]} = AR,
8610    #'CommandRequest'{command = Cmd,
8611		      optional = _Opt,
8612		      wildcardReturn = _WR} = CR,
8613    {serviceChangeReq, SCR} = Cmd,
8614    #'ServiceChangeRequest'{terminationID = _TermID,
8615			    serviceChangeParms = SCP} = SCR,
8616    #'ServiceChangeParm'{serviceChangeMethod = restart,
8617			 serviceChangeReason = [[$9,$0,$1|_]]} = SCP,
8618    {ok, M};
8619otp_5887_mgc_verify_service_change_req_msg(M) ->
8620    {error, {invalid_message, M}}.
8621
8622
8623-ifndef(megaco_hipe_special).
8624otp_5887_mgc_verify_notify_req_msg_fun() ->
8625    fun(M) ->
8626	    otp_5887_mgc_verify_notify_req_msg(M)
8627    end.
8628-endif.
8629
8630otp_5887_mgc_verify_notify_req_msg(#'MegacoMessage'{mess = Mess} = M) ->
8631    #'Message'{messageBody = Body} = Mess,
8632    {transactions, [Trans]} = Body,
8633    {transactionRequest, TR} = Trans,
8634    #'TransactionRequest'{actions = [AR]} = TR,
8635    #'ActionRequest'{commandRequests = [CR1,CR2]} = AR,
8636    #'CommandRequest'{command = Cmd1} = CR1,
8637    {notifyReq, NR1} = Cmd1,
8638    #'NotifyRequest'{observedEventsDescriptor = OED1} = NR1,
8639    #'ObservedEventsDescriptor'{observedEventLst = [OE1]} = OED1,
8640    #'ObservedEvent'{eventName = "al/of"} = OE1,
8641    #'CommandRequest'{command = Cmd2} = CR2,
8642    {notifyReq, NR2} = Cmd2,
8643    #'NotifyRequest'{observedEventsDescriptor = OED2} = NR2,
8644    #'ObservedEventsDescriptor'{observedEventLst = [OE2]} = OED2,
8645    #'ObservedEvent'{eventName = "al/of"} = OE2,
8646    {ok, M};
8647otp_5887_mgc_verify_notify_req_msg(M) ->
8648    {error, {invalid_message, M}}.
8649
8650
8651%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8652
8653otp_6253(suite) ->
8654    [];
8655otp_6253(Config) when is_list(Config) ->
8656    ?ACQUIRE_NODES(1, Config),
8657
8658    put(verbosity, debug),
8659    put(tc, otp_6253),
8660
8661    d("otp_6253 -> start test case controller",[]),
8662    ok = megaco_tc_controller:start_link(),
8663
8664    PrelMid = preliminary_mid,
8665    MgMid   = ipv4_mid(4711),
8666
8667    ?VERIFY(ok, application:start(megaco)),
8668    ?VERIFY(ok,	megaco:start_user(MgMid, [{send_mod, ?USER_MOD},
8669	                                  {request_timer, infinity},
8670	                                  {reply_timer, infinity}])),
8671
8672    MgRH = user_info(MgMid, receive_handle),
8673    {ok, PrelCH} = ?VERIFY({ok, _}, megaco:connect(MgRH, PrelMid, sh, self())),
8674
8675    connections([PrelCH]),
8676    ?VERIFY([PrelCH], megaco:user_info(MgMid, connections)),
8677
8678    SC = service_change_request(),
8679
8680    %% Instruct the transport module to fail all send_message
8681    d("otp_6253 -> instruct transport module to fail message send",[]),
8682    ok = megaco_tc_controller:insert(allow_send_message, {fail, otp_6253}),
8683
8684    ?VERIFY({1, {error, {send_message_failed, otp_6253}}},
8685	    megaco:call(PrelCH, [SC], [])),
8686
8687    sleep(1000),
8688
8689    %% Instruct the transport module to cancel all send_message
8690    d("otp_6253 -> instruct transport module to cancel message send",[]),
8691    ok = megaco_tc_controller:insert(allow_send_message, {cancel, otp_6253}),
8692
8693    ?VERIFY({1, {error, {send_message_cancelled, otp_6253}}},
8694	    megaco:call(PrelCH, [SC], [])),
8695
8696    ?VERIFY(ok, megaco:disconnect(PrelCH, shutdown)),
8697
8698    ?VERIFY(ok,	megaco:stop_user(MgMid)),
8699    ?VERIFY(ok, application:stop(megaco)),
8700    ?RECEIVE([]),
8701    ok.
8702
8703
8704%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8705
8706otp_6275(suite) ->
8707    [];
8708otp_6275(Config) when is_list(Config) ->
8709    Pre = fun() ->
8710                  MgcNode = make_node_name(mgc),
8711                  MgNode  = make_node_name(mg),
8712                  d("start nodes: "
8713                    "~n      MgcNode: ~p"
8714                    "~n      MgNode:  ~p",
8715                    [MgcNode, MgNode]),
8716                  Nodes = [MgcNode, MgNode],
8717                  ok = ?START_NODES(Nodes, true),
8718                  Nodes
8719          end,
8720    Case = fun do_otp_6275/1,
8721    Post = fun(Nodes) ->
8722                   d("stop nodes"),
8723                   ?STOP_NODES(lists:reverse(Nodes))
8724           end,
8725    try_tc(otp_6275, Pre, Case, Post).
8726
8727do_otp_6275([MgcNode, MgNode]) ->
8728    d("start the MGC simulator (generator)"),
8729    {ok, Mgc} = megaco_test_tcp_generator:start_link("MGC", MgcNode),
8730
8731    d("create the MGC event sequence"),
8732    MgcEvSeq = otp_6275_mgc_event_sequence(text, tcp),
8733
8734    d("start the MGC simulation"),
8735    {ok, MgcId} = megaco_test_tcp_generator:exec(Mgc, MgcEvSeq),
8736
8737    i("await MGC ready announcement"),
8738    receive
8739        announce_mgc ->
8740            i("received MGC ready announcement"),
8741            ok
8742    end,
8743
8744    d("[MG] start the simulator (generator)"),
8745    {ok, Mg} = megaco_test_megaco_generator:start_link("MG", MgNode),
8746
8747    d("[MG] create the event sequence"),
8748    MgEvSeq = otp_6275_mg_event_sequence(text, tcp),
8749
8750    i("wait some time before starting the MG simulation"),
8751    sleep(1000),
8752
8753    d("[MG] start the simulation"),
8754    {ok, MgId} = megaco_test_megaco_generator:exec(Mg, MgEvSeq),
8755
8756    d("[MGC] await the generator reply"),
8757    await_completion([MgcId, MgId]),
8758
8759    %% Tell Mgc to stop
8760    i("[MGC] stop generator"),
8761    megaco_test_tcp_generator:stop(Mgc),
8762
8763    %% Tell Mg to stop
8764    i("[MG] stop generator"),
8765    megaco_test_megaco_generator:stop(Mg),
8766
8767    i("done", []),
8768    ok.
8769
8770
8771%%
8772%% MG generator stuff
8773%%
8774-ifdef(megaco_hipe_special).
8775-define(otp_6275_mg_verify_handle_connect_fun(),
8776        {?MODULE, otp_6275_mg_verify_handle_connect, []}).
8777-define(otp_6275_mg_verify_notify_req_fun(),
8778        {?MODULE, otp_6275_mg_verify_notify_req, []}).
8779-define(otp_6275_mg_verify_handle_trans_rep_fun(),
8780        {?MODULE, otp_6275_mg_verify_handle_trans_rep, []}).
8781-else.
8782-define(otp_6275_mg_verify_handle_connect_fun(),
8783        otp_6275_mg_verify_handle_connect_fun()).
8784-define(otp_6275_mg_verify_notify_req_fun(),
8785	otp_6275_mg_verify_notify_req_fun()).
8786-define(otp_6275_mg_verify_handle_trans_rep_fun(),
8787	otp_6275_mg_verify_handle_trans_rep_fun()).
8788-endif.
8789
8790otp_6275_mg_event_sequence(text, tcp) ->
8791    Mid = {deviceName,"mg"},
8792    RI = [
8793          {port,             2944},
8794          {encoding_module,  megaco_pretty_text_encoder},
8795          {encoding_config,  []},
8796          {transport_module, megaco_tcp}
8797         ],
8798    otp_6275_mg_event_sequence2(Mid, RI).
8799
8800otp_6275_mg_event_sequence2(Mid, RI) ->
8801    ServiceChangeReq = [otp_6275_mg_service_change_request_ar(Mid, 1)],
8802    _Tid = #megaco_term_id{id = ["00000000","00000000","01101101"]},
8803    ConnectVerify    = ?otp_6275_mg_verify_handle_connect_fun(),
8804    NotifyReqVerify  = ?otp_6275_mg_verify_notify_req_fun(),
8805    TransReplyVerify = ?otp_6275_mg_verify_handle_trans_rep_fun(),
8806    EvSeq = [
8807             {debug, true},
8808             megaco_start,
8809             {megaco_start_user, Mid, RI, []},
8810	     %% {megaco_update_user_info, recv_pending_limit, 4},
8811	     {megaco_update_user_info, request_timer, 3000},
8812             start_transport,
8813             {megaco_trace, disable}, %%100},
8814             {megaco_system_info, users},
8815             {megaco_system_info, connections},
8816             connect,
8817             {megaco_callback, handle_connect, ConnectVerify},
8818             megaco_connect,
8819             {megaco_cast, ServiceChangeReq, []},
8820             {megaco_callback, handle_connect, ConnectVerify},
8821             {megaco_callback, handle_trans_request, NotifyReqVerify},
8822             {megaco_callback, handle_trans_reply, TransReplyVerify},
8823             {sleep, 1000},
8824             megaco_stop_user,
8825             megaco_stop,
8826             {sleep, 1000}
8827            ],
8828    EvSeq.
8829
8830
8831-ifndef(megaco_hipe_special).
8832otp_6275_mg_verify_handle_connect_fun() ->
8833    fun(Event) ->
8834	    (catch otp_6275_mg_verify_handle_connect(Event))
8835    end.
8836-endif.
8837
8838otp_6275_mg_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
8839    io:format("otp_6275_mg_verify_handle_connect -> ok"
8840	      "~n   CH: ~p~n", [CH]),
8841    {ok, CH, ok};
8842otp_6275_mg_verify_handle_connect(Else) ->
8843    io:format("otp_6275_mg_verify_handle_connect -> unknown"
8844	      "~n   Else: ~p~n", [Else]),
8845    {error, Else, ok}.
8846
8847
8848-ifndef(megaco_hipe_special).
8849otp_6275_mg_verify_notify_req_fun() ->
8850    fun(Event) ->
8851	    (catch otp_6275_mg_verify_notify_req(Event))
8852    end.
8853-endif.
8854
8855otp_6275_mg_verify_notify_req(
8856  {handle_trans_request, _CH, ?VERSION, [AR]}) ->
8857    io:format("otp_6275_mg_verify_notify_req -> entry with"
8858	      "~n   AR: ~p"
8859	      "~n", [AR]),
8860    CR =
8861	case AR of
8862	    #'ActionRequest'{commandRequests = [CmdReq]} ->
8863		CmdReq;
8864	    _ ->
8865		ET1 = lists:flatten(
8866		       io_lib:format("Invalid action request: ~w", [AR])),
8867		EC1 = ?megaco_internal_gateway_error,
8868		ED1 = #'ErrorDescriptor'{errorCode = EC1,
8869					 errorText = ET1},
8870		throw({error, {invalid_ActionRequest, AR}, {discard_ack, ED1}})
8871	end,
8872
8873    Cmd =
8874	case CR of
8875	    #'CommandRequest'{command = Command} ->
8876		Command;
8877	    _ ->
8878		ET2 = lists:flatten(
8879			io_lib:format("Invalid command request: ~w", [CR])),
8880		EC2 = ?megaco_internal_gateway_error,
8881		ED2 = #'ErrorDescriptor'{errorCode = EC2,
8882					 errorText = ET2},
8883		throw({error, {invalid_CommandRequest, CR}, {discard_ack, ED2}})
8884	end,
8885
8886    case Cmd of
8887	{notifyReq, NotifyReq} ->
8888	    ET3 = "Unexpected request",
8889	    EC3 = ?megaco_transaction_req_received_before_servicechange_reply,
8890	    ED3 = #'ErrorDescriptor'{errorCode = EC3,
8891				     errorText = ET3},
8892	    throw({ok, {ok, NotifyReq}, {discard_ack, ED3}});
8893	_ ->
8894	    ET4 = lists:flatten(
8895		    io_lib:format("Invalid command: ~w", [Cmd])),
8896	    EC4 = ?megaco_internal_gateway_error,
8897	    ED4 = #'ErrorDescriptor'{errorCode = EC4,
8898				     errorText = ET4},
8899	    throw({error, {invalid_command, Cmd}, {discard_ack, ED4}})
8900    end;
8901otp_6275_mg_verify_notify_req({Tag, CH, Version, ARs}) ->
8902    io:format("otp_6275_mg_verify_notify_req -> ok"
8903	      "~n   Tag:     ~p"
8904	      "~n   CH:      ~p"
8905	      "~n   Version: ~p"
8906	      "~n   ARs:     ~p"
8907	      "~n", [Tag, CH, Version, ARs]),
8908    {error, {invalid_event, {Tag, CH, Version, ARs}}, ok};
8909otp_6275_mg_verify_notify_req(Else) ->
8910    io:format("otp_6275_mg_verify_notify_req -> unknown"
8911	      "~n   Else: ~p~n", [Else]),
8912    {error, Else, ok}.
8913
8914
8915-ifndef(megaco_hipe_special).
8916otp_6275_mg_verify_handle_trans_rep_fun() ->
8917    fun(Event) ->
8918	    (catch otp_6275_mg_verify_handle_trans_rep(Event))
8919    end.
8920-endif.
8921
8922otp_6275_mg_verify_handle_trans_rep(
8923  {handle_trans_reply, CH, ?VERSION, {error, timeout} = Error, _}) ->
8924    io:format("otp_6275_mg_verify_trans_rep -> expected error"
8925	      "~n", []),
8926    case CH of
8927	#megaco_conn_handle{remote_mid = preliminary_mid} ->
8928	    {ok, Error, error};
8929	_ ->
8930	    {error, {unexpected_connection, CH}, error}
8931    end;
8932otp_6275_mg_verify_handle_trans_rep(
8933  {handle_trans_reply, _CH, ?VERSION, Error, _}) ->
8934    io:format("otp_6275_mg_verify_handle_trans_rep -> unexpected error"
8935	      "~n   Error: ~p"
8936	      "~n", [Error]),
8937    {error, Error, error};
8938otp_6275_mg_verify_handle_trans_rep(Else) ->
8939    io:format("otp_6275_mg_verify_handle_trans_rep -> unknown"
8940	      "~n   Else: ~p~n", [Else]),
8941    {error, Else, error}.
8942
8943otp_6275_mg_service_change_request_ar(_Mid, Cid) ->
8944    Prof  = cre_serviceChangeProf("resgw", 1),
8945    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
8946    Root  = #megaco_term_id{id = ["root"]},
8947    SCR   = cre_serviceChangeReq([Root], SCP),
8948    CMD   = cre_command(SCR),
8949    CR    = cre_cmdReq(CMD),
8950    cre_actionReq(Cid, [CR]).
8951
8952
8953%%
8954%% MGC generator stuff
8955%%
8956-ifdef(megaco_hipe_special).
8957-define(otp_6275_mgc_decode_msg_fun(Mod, Conf),
8958	{?MODULE, decode_msg, [Mod, Conf]}).
8959-define(otp_6275_mgc_encode_msg_fun(Mod, Conf),
8960	{?MODULE, encode_msg, [Mod, Conf]}).
8961-define(otp_6275_mgc_verify_service_change_req_msg_fun(),
8962	{?MODULE, otp_6275_mgc_verify_service_change_req_msg, []}).
8963-define(otp_6275_mgc_verify_notify_rep_msg_fun(),
8964	{?MODULE, otp_6275_mgc_verify_notify_rep_msg, []}).
8965-else.
8966-define(otp_6275_mgc_decode_msg_fun(Mod, Conf),
8967	otp_6275_mgc_decode_msg_fun(Mod, Conf)).
8968-define(otp_6275_mgc_encode_msg_fun(Mod, Conf),
8969	otp_6275_mgc_encode_msg_fun(Mod, Conf)).
8970-define(otp_6275_mgc_verify_service_change_req_msg_fun(),
8971	otp_6275_mgc_verify_service_change_req_msg_fun()).
8972-define(otp_6275_mgc_verify_notify_rep_msg_fun(),
8973	otp_6275_mgc_verify_notify_rep_msg_fun()).
8974-endif.
8975
8976otp_6275_mgc_event_sequence(text, tcp) ->
8977    CTRL = self(),
8978    DecodeFun = ?otp_6275_mgc_decode_msg_fun(megaco_pretty_text_encoder, []),
8979    EncodeFun = ?otp_6275_mgc_encode_msg_fun(megaco_pretty_text_encoder, []),
8980    Mid = {deviceName,"ctrl"},
8981    TermId = #megaco_term_id{id = ["00000000","00000000","01101101"]},
8982    NotifyReq = otp_6275_mgc_notify_request_msg(Mid, 2, 1, TermId, 1),
8983    SCRVerifyFun         = ?otp_6275_mgc_verify_service_change_req_msg_fun(),
8984    NotifyReplyVerifyFun = ?otp_6275_mgc_verify_notify_rep_msg_fun(),
8985    MgcEvSeq =
8986	[{debug,  true},
8987	 {decode, DecodeFun},
8988	 {encode, EncodeFun},
8989	 {listen, 2944},
8990
8991         %% ANNOUNCE READY
8992         {trigger, "announce ready", fun() -> CTRL ! announce_mgc end},
8993
8994	 {expect_accept, any},
8995	 {expect_receive, "service-change-request", {SCRVerifyFun, 5000}},
8996	 {sleep, 1000}, %% Do _not_ send SC reply
8997	 {send, "notify-request", NotifyReq},
8998	 {expect_receive, "request before sc reply", {NotifyReplyVerifyFun, 5000}},
8999	 {sleep, 2000}
9000	],
9001    MgcEvSeq.
9002
9003-ifndef(megaco_hipe_special).
9004otp_6275_mgc_encode_msg_fun(Mod, Conf) ->
9005    fun(M) ->
9006	    encode_msg(M, Mod, Conf)
9007    end.
9008-endif.
9009
9010%% otp_6275_mgc_encode_msg_fun(Mod, Conf, Ver) ->
9011%%     fun(M) ->
9012%% 	    encode_msg(M, Mod, Conf, Ver)
9013%%     end.
9014
9015-ifndef(megaco_hipe_special).
9016otp_6275_mgc_decode_msg_fun(Mod, Conf) ->
9017    fun(M) ->
9018	    decode_msg(M, Mod, Conf)
9019    end.
9020-endif.
9021
9022%% otp_6275_mgc_decode_msg_fun(Mod, Conf, Ver) ->
9023%%     fun(M) ->
9024%% 	    decode_msg(M, Mod, Conf, Ver)
9025%%     end.
9026
9027-ifndef(megaco_hipe_special).
9028otp_6275_mgc_verify_service_change_req_msg_fun() ->
9029    fun(M) ->
9030	    (catch otp_6275_mgc_verify_service_change_req_msg(M))
9031    end.
9032-endif.
9033
9034otp_6275_mgc_verify_service_change_req_msg(
9035  #'MegacoMessage'{mess = Mess} = M) ->
9036    io:format("otp_6275_mgc_verify_service_change_req_msg -> entry with"
9037	      "~n   M: ~p"
9038	      "~n", [M]),
9039    Body =
9040	case Mess of
9041	    #'Message'{messageBody = MB} ->
9042		MB;
9043	    _ ->
9044		throw({error, {invalid_mess, Mess}})
9045	end,
9046
9047    Trans =
9048	case Body of
9049	    {transactions, [Transaction]} ->
9050		Transaction;
9051	    _ ->
9052		throw({error, {invalid_messageBody, Body}})
9053	end,
9054
9055    TR =
9056	case Trans of
9057	    {transactionRequest, TransReq} ->
9058		TransReq;
9059	    _ ->
9060		throw({error, {invalid_transaction, Trans}})
9061	end,
9062
9063    AR =
9064	case TR of
9065	    #'TransactionRequest'{actions = [ActionReq]} ->
9066		ActionReq;
9067	    _ ->
9068		throw({error, {invalid_transactionRequest, TR}})
9069	end,
9070
9071    CR =
9072	case AR of
9073	    #'ActionRequest'{commandRequests = [CmdReq]} ->
9074		CmdReq;
9075	    _ ->
9076		throw({error, {invalid_TransactionRequest, AR}})
9077	end,
9078
9079    Cmd =
9080	case CR of
9081	    #'CommandRequest'{command = Command} ->
9082		Command;
9083	    _ ->
9084		throw({error, {invalid_ActionRequest, CR}})
9085	end,
9086
9087    SCR =
9088	case Cmd of
9089	    {serviceChangeReq, ServiceChangeReq} ->
9090		ServiceChangeReq;
9091	    _ ->
9092		throw({error, {invalid_command, Cmd}})
9093	end,
9094
9095    SCP =
9096	case SCR of
9097	    #'ServiceChangeRequest'{serviceChangeParms = ServiceChangeParms} ->
9098		ServiceChangeParms;
9099	    _ ->
9100		throw({error, {invalid_serviceChangeReq, SCR}})
9101	end,
9102
9103    case SCP of
9104	#'ServiceChangeParm'{serviceChangeMethod = restart,
9105			     serviceChangeReason = [[$9,$0,$1|_]]} ->
9106	    {ok, M};
9107       _ ->
9108	    {error, {invalid_serviceChangeParms, SCP}}
9109    end;
9110otp_6275_mgc_verify_service_change_req_msg(Crap) ->
9111    {error, {invalid_MegacoMessage, Crap}}.
9112
9113-ifndef(megaco_hipe_special).
9114otp_6275_mgc_verify_notify_rep_msg_fun() ->
9115    fun(M) ->
9116	    (catch otp_6275_mgc_verify_notify_rep_msg(M))
9117    end.
9118-endif.
9119
9120otp_6275_mgc_verify_notify_rep_msg(#'MegacoMessage'{mess = Mess} = M) ->
9121    io:format("otp_6275_mgc_verify_notify_rep_msg -> entry with"
9122	      "~n   M: ~p"
9123	      "~n", [M]),
9124    Body =
9125	case Mess of
9126	    #'Message'{messageBody = MB} ->
9127		MB;
9128	    _ ->
9129		throw({error, {invalid_mess, Mess}})
9130	end,
9131
9132    Trans =
9133	case Body of
9134	    {transactions, [Transaction]} ->
9135		Transaction;
9136	    _ ->
9137		throw({error, {invalid_messageBody, Body}})
9138	end,
9139
9140    TR =
9141	case Trans of
9142	    {transactionReply, TransReply} ->
9143		TransReply;
9144	    _ ->
9145		throw({error, {invalid_transaction, Trans}})
9146	end,
9147
9148    Res =
9149	case TR of
9150	    #'TransactionReply'{transactionResult = TransRes} ->
9151		TransRes;
9152	    _ ->
9153		throw({error, {invalid_transactionReply, TR}})
9154	end,
9155
9156    ED =
9157	case Res of
9158	    {transactionError, ErrorDesc} ->
9159		ErrorDesc;
9160	    _ ->
9161		throw({error, {invalid_TransactionReply, Res}})
9162	end,
9163
9164    case ED of
9165	#'ErrorDescriptor'{errorCode = ?megaco_transaction_req_received_before_servicechange_reply} ->
9166	    ok;
9167	_ ->
9168	    throw({error, {invalid_transactionError, ED}})
9169    end,
9170    {ok, M};
9171otp_6275_mgc_verify_notify_rep_msg(Crap) ->
9172    {error, {invalid_MegacoMessage, Crap}}.
9173
9174
9175otp_6275_mgc_notify_request_ar(Rid, Tid, Cid) ->
9176    TT      = cre_timeNotation("19990729", "22000000"),
9177    Ev      = cre_obsEvent("al/of", TT),
9178    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
9179    NR      = cre_notifyReq([Tid], EvsDesc),
9180    CMD     = cre_command(NR),
9181    CR      = cre_cmdReq(CMD),
9182    cre_actionReq(Cid, [CR]).
9183
9184otp_6275_mgc_notify_request_msg(Mid, TransId, Cid, TermId, Rid) ->
9185    AR = otp_6275_mgc_notify_request_ar(Rid, TermId, Cid),
9186    otp_6275_msg(Mid, TransId, AR).
9187
9188
9189%% --
9190
9191otp_6275_msg(Mid, TransId, AR) ->
9192    TR    = cre_transReq(TransId, [AR]),
9193    Trans = cre_transaction(TR),
9194    Mess  = cre_message(1, Mid, cre_transactions([Trans])),
9195    cre_megacoMessage(Mess).
9196
9197%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9198
9199%% This test case can only be run with the stack compiled with
9200%% the MEGACO_TEST_CODE flag. Therefor there is no point in
9201%% including this test case in the usual test suite
9202-ifdef(MEGACO_TEST_CODE).
9203otp_6276(suite) ->
9204    [];
9205otp_6276(doc) ->
9206    "OTP-6276: Cancel when receiving reply raise condition";
9207otp_6276(Config) when is_list(Config) ->
9208    Pre = fun() ->
9209                  MgcNode = make_node_name(mgc),
9210                  MgNode  = make_node_name(mg),
9211                  d("start nodes: "
9212                    "~n      MgcNode: ~p"
9213                    "~n      MgNode:  ~p",
9214                    [MgcNode, MgNode]),
9215                  Nodes = [MgcNode, MgNode],
9216                  ok = ?START_NODES(Nodes, true),
9217                  Nodes
9218          end,
9219    Case = fun do_otp_6276/1,
9220    Post = fun(Nodes) ->
9221                   d("stop nodes"),
9222                   ?STOP_NODES(lists:reverse(Nodes))
9223           end,
9224    try_tc(otp_6276, Pre, Case, Post).
9225
9226do_otp_6276([MgcNode, MgNode]) ->
9227    d("create sequence controller"),
9228    CtrlPid = otp_6276_sequence_controller_start(),
9229
9230    d("[MGC] start the simulator "),
9231    {ok, Mgc} = megaco_test_tcp_generator:start_link("MGC", MgcNode),
9232
9233    d("[MGC] create the event sequence"),
9234    MgcEvSeq = otp_6276_mgc_event_sequence(text, tcp, CtrlPid),
9235
9236    i("wait some time before starting the MGC simulation"),
9237    sleep(1000),
9238
9239    d("[MGC] start the tcp-simulation"),
9240    {ok, MgcId} = megaco_test_tcp_generator:exec(Mgc, MgcEvSeq),
9241
9242    %% i("wait some time before starting the MG simulator"),
9243    %% sleep(1000),
9244
9245    i("await MGC ready announcement"),
9246    receive
9247        announce_mgc ->
9248            i("received MGC ready announcement"),
9249            ok
9250    end,
9251
9252    d("[MG] start the simulator (generator)"),
9253    {ok, Mg} = megaco_test_megaco_generator:start_link("MG", MgNode),
9254
9255    d("send start order to sequence controller"),
9256    CtrlPid ! {start, self(), Mgc, Mg},
9257
9258    d("[MG] create the event sequence"),
9259    MgEvSeq = otp_6276_mg_event_sequence(text, tcp, CtrlPid),
9260
9261    i("wait some time before starting the MG simulation"),
9262    sleep(1000),
9263
9264    d("[MG] start the megaco-simulation"),
9265    {ok, MgId} = megaco_test_megaco_generator:exec(Mg, MgEvSeq),
9266
9267    d("await the generator reply(s)"),
9268    await_completion([MgcId, MgId]),
9269
9270    %% Tell Mgc to stop
9271    i("[MGC] stop generator"),
9272    megaco_test_tcp_generator:stop(Mgc),
9273
9274    %% Tell Mg to stop
9275    i("[MG] stop generator"),
9276    megaco_test_megaco_generator:stop(Mg),
9277
9278    i("done", []),
9279    ok.
9280
9281
9282otp_6276_sequence_controller_start() ->
9283    Self = self(),
9284    erlang:spawn(fun() -> otp_6276_sequence_controller(Self) end).
9285
9286otp_6276_sequence_controller(Parent) ->
9287    io:format("otp_6276_sequence_controller -> entry with"
9288	      "~n   Parent: ~p"
9289	      "~n   self(): ~p"
9290	      "~n", [Parent, self()]),
9291
9292    d("start tc controller"),
9293    put(dbg,true),
9294    ok = megaco_tc_controller:start_link(),
9295
9296
9297    %% Await MGC announcement
9298    Mgc =
9299	receive
9300	    {announce_mgc, MgcPid} ->
9301		MgcPid
9302	end,
9303    io:format("otp_6276_sequence_controller -> MGC announced: "
9304	      "~n   Mgc: ~p"
9305	      "~n", [Mgc]),
9306
9307    %% Await MG announcement
9308    Mg =
9309	receive
9310	    {announce_mg, MgPid} ->
9311		MgPid
9312	end,
9313    io:format("otp_6276_sequence_controller -> MG announced: "
9314	      "~n   Mg: ~p"
9315	      "~n", [Mg]),
9316
9317    %% Await request_received notification
9318    receive
9319	{notify_request_received, Mgc} ->
9320	    io:format("otp_6276_sequence_controller -> "
9321		      "request received from MGC (~p)"
9322		      "~n", [Mgc]),
9323	    ok
9324    end,
9325
9326    %% Make sure the cancel operation gets blocked midway:
9327    megaco_tc_controller:insert(block_on_cancel, {cancel_block, self()}),
9328
9329    %% Send start cancel order
9330    io:format("otp_6276_sequence_controller -> "
9331	      "send cancel start order to MG (~p)"
9332	      "~n", [Mg]),
9333    Mg ! {start_cancel, self()},
9334    receive
9335	{started_cancel, Mg} ->
9336	    ok
9337    end,
9338    io:format("otp_6276_sequence_controller -> "
9339	      "cancel started - now await blocked"
9340	      "~n", []),
9341
9342    receive
9343	{cancel_block, Mg} ->
9344	    ok
9345    end,
9346    io:format("otp_6276_sequence_controller -> "
9347	      "cancel blocked - now instruct MGC to send notify reply"
9348	      "~n", []),
9349
9350    %% Make sure the cancel operation gets blocked midway:
9351    megaco_tc_controller:insert(block_on_reply, {reply_block, self()}),
9352
9353    %% Send NR-send order
9354    Mgc ! {notify_reply_send, self()},
9355    io:format("otp_6276_sequence_controller -> "
9356	      "NR-send order sent - now await notify reply blocked received"
9357	      "~n", []),
9358
9359    ReplyPid =
9360	receive
9361	    {reply_block, Pid, true} ->
9362		io:format("otp_6276_sequence_controller -> "
9363			  "notify reply blocked received from ~p (true) - "
9364			  "now unblock cancel"
9365			  "~n", [Pid]),
9366		%% Pid ! {reply_block, self()},
9367		Pid;
9368	    {reply_block, Pid, Info} ->
9369		io:format("otp_6276_sequence_controller -> "
9370			  "notify reply blocked received from ~p: ~p"
9371			  "~n", [Pid, Info]),
9372		Pid ! {reply_block, self()},
9373		exit({unexpected_reply_block_info, Info})
9374	end,
9375
9376    %% Send cancel continue (unblock) order
9377    Mg ! {cancel_block, self()},
9378    io:format("otp_6276_sequence_controller -> "
9379	      "cancel unblocked - now await notify-request cancelled"
9380	      "~n", []),
9381
9382    %% Await request cancelled
9383    receive
9384	{notify_request_cancelled, Mg} ->
9385	    ok;
9386	{notify_request_cancelled, Pid} ->
9387	    io:format("otp_6276_sequence_controller -> "
9388		      "notify-request cancelled - from ~p"
9389		      "~n", [Pid]),
9390	    ok
9391    end,
9392    io:format("otp_6276_sequence_controller -> "
9393	      "notify-request cancelled - now unblock notify-reply"
9394	      "~n", []),
9395
9396    %% await notify reply result
9397    ReplyPid ! {reply_block, self()},
9398    io:format("otp_6276_sequence_controller -> "
9399	      "notify-reply unblocked - now await unexpected trans"
9400	      "~n", []),
9401
9402    %% Await unexpected trans
9403    receive
9404	{unexpected_trans, Mg, _Trans} ->
9405	    ok;
9406	{unexpected_trans, Pid, _Trans} ->
9407	    io:format("otp_6276_sequence_controller -> "
9408		      "unexpected_trans - from ~p"
9409		      "~n", [Pid]),
9410	    ok
9411    end,
9412    io:format("otp_6276_sequence_controller -> "
9413	      "unexpected transaction received"
9414	      "~n", []),
9415
9416    %% Await unexpected trans
9417    Mgc ! {done, self()},
9418    receive
9419	{done, Mgc} ->
9420	    ok
9421    end,
9422    io:format("otp_6276_sequence_controller -> MGC instructed we are done"
9423	      "~n", []),
9424
9425    d("stop tc controller"),
9426    megaco_tc_controller:stop(),
9427
9428    io:format("otp_6276_sequence_controller -> done~n", []),
9429
9430    exit(normal).
9431
9432
9433%%
9434%% MGC generator stuff
9435%%
9436otp_6276_mgc_event_sequence(text, tcp, Ctrl) ->
9437    Mid = {deviceName,"ctrl"},
9438    EM  = megaco_pretty_text_encoder,
9439    EC  = [],
9440    otp_6276_mgc_event_sequence2(Mid, EM, EC, Ctrl).
9441
9442otp_6276_mgc_event_sequence2(Mid, EM, EC, Ctrl) ->
9443    CTRL = self(),
9444    DecodeFun = otp_6276_mgc_decode_msg_fun(EM, EC),
9445    EncodeFun = otp_6276_mgc_encode_msg_fun(EM, EC),
9446    AnnounceMe = otp_6276_mgc_announce_fun(Ctrl),
9447    ServiceChangeReqVerify =
9448	otp_6276_mgc_verify_service_change_req_fun(Mid),
9449    ServiceChangeReply =
9450	otp_6276_mgc_service_change_reply_msg(Mid, 1, 0),
9451    NotifyReqVerify = otp_6276_mgc_verify_notify_request_fun(Ctrl),
9452    TermId = #megaco_term_id{id = ["00000000","00000000","01101101"]},
9453    AwaitNrSendOrder = otp_6276_mgc_await_notify_reply_send_order_fun(Ctrl),
9454    NotifyReply = otp_6276_mgc_notify_reply_msg(Mid, 2, 0, TermId),
9455    AwaitDoneOrder = otp_6276_mgc_await_done_order_fun(Ctrl),
9456    EvSeq =
9457	[
9458	 {trigger, AnnounceMe},
9459	 {debug,  true},
9460	 {decode, DecodeFun},
9461	 {encode, EncodeFun},
9462	 {listen, 2944},
9463
9464         %% ANNOUNCE READY
9465         {trigger, fun() -> CTRL ! announce_mgc end},
9466
9467	 {expect_accept, any},
9468	 {expect_receive, "service-change-req",
9469	  {ServiceChangeReqVerify, 10000}},
9470	 {send, "service-change-reply", ServiceChangeReply},
9471	 {expect_receive, "notify-request", {NotifyReqVerify, 5000}},
9472
9473	 {trigger, AwaitNrSendOrder},
9474
9475	 {send, "notify-reply", NotifyReply},
9476
9477	 {trigger, AwaitDoneOrder},
9478
9479	 disconnect
9480	 ],
9481    EvSeq.
9482
9483otp_6276_mgc_announce_fun(Pid) ->
9484    fun() ->
9485	    Pid ! {announce_mgc, self()}
9486    end.
9487
9488otp_6276_mgc_await_notify_reply_send_order_fun(Pid) ->
9489    fun() ->
9490	    receive
9491		{notify_reply_send, Pid} ->
9492		    Pid ! {notify_reply_send, self()}
9493	    end
9494    end.
9495
9496otp_6276_mgc_await_done_order_fun(Pid) ->
9497    fun() ->
9498	    receive
9499		{done, Pid} ->
9500		    Pid ! {done, self()}
9501	    end
9502    end.
9503
9504otp_6276_mgc_encode_msg_fun(Mod, Conf) ->
9505    fun(M) ->
9506            Mod:encode_message(Conf, M)
9507    end.
9508
9509otp_6276_mgc_decode_msg_fun(Mod, Conf) ->
9510    fun(M) ->
9511            Mod:decode_message(Conf, M)
9512    end.
9513
9514otp_6276_mgc_service_change_reply_msg(Mid, TransId, Cid) ->
9515    SCRP  = #'ServiceChangeResParm'{serviceChangeMgcId = Mid},
9516    SCRPs = {serviceChangeResParms,SCRP},
9517    Root  = #megaco_term_id{id = ["root"]},
9518    SCR   = #'ServiceChangeReply'{terminationID       = [Root],
9519                                  serviceChangeResult = SCRPs},
9520    CR    = {serviceChangeReply, SCR},
9521    otp_6276_mgc_msg(Mid, TransId, CR, Cid).
9522
9523otp_6276_mgc_notify_reply_msg(Mid, TransId, Cid, TermId) ->
9524    NR  = #'NotifyReply'{terminationID = [TermId]},
9525    CR  = {notifyReply, NR},
9526    otp_6276_mgc_msg(Mid, TransId, CR, Cid).
9527
9528otp_6276_mgc_msg(Mid, TransId, CR, Cid) ->
9529    AR  = #'ActionReply'{contextId    = Cid,
9530                         commandReply = [CR]},
9531    ARs  = {actionReplies, [AR]},
9532    TR   = #'TransactionReply'{transactionId     = TransId,
9533                               transactionResult = ARs},
9534    Body = {transactions, [{transactionReply, TR}]},
9535    Mess = #'Message'{version     = 1,
9536                      mId         = Mid,
9537                      messageBody = Body},
9538    #'MegacoMessage'{mess = Mess}.
9539
9540otp_6276_mgc_pending_msg(Mid, TransId) ->
9541    TP   = #'TransactionPending'{transactionId = TransId},
9542    Body = {transactions, [{transactionPending, TP}]},
9543    Mess = #'Message'{version     = 1,
9544                      mId         = Mid,
9545                      messageBody = Body},
9546    #'MegacoMessage'{mess = Mess}.
9547
9548otp_6276_mgc_verify_service_change_req_fun(_) ->
9549    fun(#'MegacoMessage'{mess = Mess} = M) ->
9550            #'Message'{version     = _V,
9551                       mId         = _Mid,
9552                       messageBody = Body} = Mess,
9553            {transactions, [Trans]} = Body,
9554            {transactionRequest, TR} = Trans,
9555            #'TransactionRequest'{transactionId = _Tid,
9556                                  actions = [AR]} = TR,
9557            #'ActionRequest'{contextId = _Cid,
9558                             contextRequest = _CtxReq,
9559                             contextAttrAuditReq = _CtxAar,
9560                             commandRequests = [CR]} = AR,
9561            #'CommandRequest'{command = Cmd,
9562                              optional = _Opt,
9563                              wildcardReturn = _WR} = CR,
9564            {serviceChangeReq, SCR} = Cmd,
9565            #'ServiceChangeRequest'{terminationID = _TermID,
9566                                    serviceChangeParms = SCP} = SCR,
9567            #'ServiceChangeParm'{serviceChangeMethod = restart,
9568                                 serviceChangeReason = [[$9,$0,$1|_]]} = SCP,
9569            {ok, M};
9570       (M) ->
9571            {error, {invalid_message, M}}
9572    end.
9573
9574otp_6276_mgc_verify_notify_request_fun(Pid) ->
9575    fun(M) ->
9576	    (catch otp_6276_mgc_verify_notify_request(M, Pid))
9577    end.
9578
9579otp_6276_mgc_verify_notify_request(#'MegacoMessage'{mess = Mess} = M,
9580				   Pid) ->
9581    io:format("otp_6276_mgc_verify_notify_request -> entry with"
9582	      "~n   M: ~p"
9583	      "~n", [M]),
9584    Body =
9585	case Mess of
9586	    #'Message'{messageBody = MessageBody} ->
9587		MessageBody;
9588	    _ ->
9589		throw({error, {invalid_mess, Mess}})
9590	end,
9591
9592    Trans =
9593	case Body of
9594            {transactions, [Transaction]} ->
9595		Transaction;
9596	    _ ->
9597		throw({error, {invalid_messageBody, Body}})
9598	end,
9599
9600    TR =
9601	case Trans of
9602            {transactionRequest, TransReq} ->
9603		TransReq;
9604	    _ ->
9605		throw({error, {invalid_transaction, Trans}})
9606	end,
9607
9608    AR =
9609	case TR of
9610            #'TransactionRequest'{actions = [Action]} ->
9611		Action;
9612	    _ ->
9613		throw({error, {invalid_transactionRequest, TR}})
9614	end,
9615
9616    io:format("otp_6276_mgc_verify_notify_request -> "
9617	      "~n   AR: ~p"
9618	      "~n", [AR]),
9619
9620    CR =
9621	case AR of
9622            #'ActionRequest'{commandRequests = [CommandReq]} ->
9623		CommandReq;
9624	    _ ->
9625		throw({error, {invalid_TransactionRequest, AR}})
9626	end,
9627
9628    Cmd =
9629	case CR of
9630            #'CommandRequest'{command = Command} ->
9631		Command;
9632	    _ ->
9633		throw({error, {invalid_ActionRequest, CR}})
9634	end,
9635
9636    NR =
9637	case Cmd of
9638            {notifyReq, NotifReq} ->
9639		NotifReq;
9640	    _ ->
9641		throw({error, {invalid_CommandRequest, Cmd}})
9642	end,
9643
9644    OED =
9645	case NR of
9646            #'NotifyRequest'{observedEventsDescriptor = ObsEvDesc} ->
9647		ObsEvDesc;
9648	    _ ->
9649		throw({error, {invalid_notifyReq, NR}})
9650	end,
9651
9652    OE =
9653	case OED of
9654            #'ObservedEventsDescriptor'{observedEventLst = [ObsEv]} ->
9655		ObsEv;
9656	    _ ->
9657		throw({error, {invalid_NotifyRequest, OED}})
9658	end,
9659
9660    case OE of
9661	#'ObservedEvent'{eventName = "al/of"} ->
9662            ok;
9663	_ ->
9664	    throw({error, {invalid_ObservedEventsDescriptor, OE}})
9665    end,
9666    io:format("otp_6276_mgc_verify_notify_request -> "
9667	      "send notify_request received to "
9668	      "~n   Pid:    ~p"
9669	      "~n   self(): ~p"
9670	      "~n", [Pid, self()]),
9671    Pid ! {notify_request_received, self()},
9672    {ok, M};
9673otp_6276_mgc_verify_notify_request(M, _Pid) ->
9674    {error, {invalid_message, M}}.
9675
9676
9677%%
9678%% MG generator stuff
9679%%
9680otp_6276_mg_event_sequence(text, tcp, Ctrl) ->
9681    Mid = {deviceName,"mg"},
9682    RI = [
9683          {port,             2944},
9684          {encoding_module,  megaco_pretty_text_encoder},
9685          {encoding_config,  []},
9686          {transport_module, megaco_tcp}
9687         ],
9688    otp_6276_mg_event_sequence2(Mid, RI, Ctrl).
9689
9690otp_6276_mg_event_sequence2(Mid, RI, Ctrl) ->
9691    AnnounceMe = otp_6276_mg_announce_fun(Ctrl),
9692    ServiceChangeReq = [otp_6276_mg_service_change_request_ar(Mid, 1)],
9693    ConnectVerify = fun otp_6276_mg_verify_handle_connect/1,
9694    ServiceChangeReplyVerify =
9695	fun otp_6276_mg_verify_service_change_reply/1,
9696    Tid = #megaco_term_id{id = ["00000000","00000000","01101101"]},
9697    NotifyReq = [otp_6276_mg_notify_request_ar(1, Tid, 1)],
9698    AwaitCancelOrder = otp_6276_mg_await_cancel_order_fun(Ctrl),
9699    TransReplyVerify = otp_6276_mg_verify_trans_reply_fun(Ctrl),
9700    UnexpTransVerify = otp_6276_mg_verify_unexpected_trans_fun(Ctrl),
9701    EvSeq = [
9702	     {trigger, AnnounceMe},
9703             {debug, true},
9704             megaco_start,
9705             {megaco_start_user, Mid, RI, []},
9706	     {megaco_update_user_info, recv_pending_limit, 4},
9707             start_transport,
9708             {megaco_trace, disable}, %%100},
9709             {megaco_system_info, users},
9710             {megaco_system_info, connections},
9711             connect,
9712             {megaco_callback, handle_connect, ConnectVerify},
9713             megaco_connect,
9714             {megaco_cast, ServiceChangeReq, []},
9715             {megaco_callback, handle_connect, ConnectVerify},
9716             {megaco_callback, handle_trans_reply, ServiceChangeReplyVerify},
9717             {sleep, 1000},
9718             {megaco_cast, NotifyReq, []},
9719
9720	     {trigger, AwaitCancelOrder},
9721
9722	     {megaco_cancel, otp_6276},
9723
9724             {megaco_callback, handle_trans_reply, TransReplyVerify},
9725             {megaco_callback, handle_unexpected_trans,  UnexpTransVerify},
9726             {sleep, 1000},
9727             megaco_stop_user,
9728             megaco_stop,
9729             {sleep, 1000}
9730            ],
9731    EvSeq.
9732
9733otp_6276_mg_announce_fun(Pid) ->
9734    fun() ->
9735	    Pid ! {announce_mg, self()}
9736    end.
9737
9738otp_6276_mg_await_cancel_order_fun(Pid) ->
9739    fun() ->
9740	    io:format("otp_6276_mg_await_cancel_order_fun -> entry with"
9741		      "~n   Pid:    ~p"
9742		      "~n   self(): ~p"
9743		      "~n", [Pid, self()]),
9744	    receive
9745		{start_cancel, Pid} ->
9746		    io:format("otp_6276_mg_await_cancel_order_fun -> "
9747			      "received cancel start order"
9748			      "~n   Pid:    ~p"
9749			      "~n   self(): ~p"
9750			      "~n", [Pid, self()]),
9751		    Pid ! {started_cancel, self()}
9752	    end
9753    end.
9754
9755otp_6276_mg_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
9756    io:format("otp_6276_mg_verify_handle_connect -> ok"
9757	      "~n   CH: ~p~n", [CH]),
9758    {ok, CH, ok};
9759otp_6276_mg_verify_handle_connect(Else) ->
9760    io:format("otp_6276_mg_verify_handle_connect -> unknown"
9761	      "~n   Else: ~p~n", [Else]),
9762    {error, Else, ok}.
9763
9764otp_6276_mg_verify_service_change_reply({handle_trans_reply, _CH,
9765					       ?VERSION,
9766					       {ok, [AR]}, _}) ->
9767    io:format("otp_6276_mg_verify_service_change_reply -> ok"
9768	      "~n   AR: ~p~n", [AR]),
9769    case AR of
9770	#'ActionReply'{commandReply = [SCR]} ->
9771	    case SCR of
9772		{serviceChangeReply,
9773		 #'ServiceChangeReply'{terminationID = [Tid],
9774				       serviceChangeResult = Res}} ->
9775		    case Tid of
9776			#megaco_term_id{contains_wildcards = false,
9777					id = ["root"]} ->
9778			    case Res of
9779				{serviceChangeResParms,
9780				 #'ServiceChangeResParm'{
9781				   serviceChangeMgcId = _RemoteMid}} ->
9782				    {ok, AR, ok};
9783				{Tag, Val} ->
9784				    Err = {invalid_service_change_result,
9785					   Tag, Val},
9786				    {error, Err, ok}
9787			    end;
9788			_ ->
9789			    Err = {invalid_termination_id, Tid},
9790			    {error, Err, ok}
9791		    end;
9792		{Tag, Val} ->
9793		    Err = {invalid_command_reply, Tag, Val},
9794		    {error, Err, ok}
9795	    end;
9796	_ ->
9797	    Err = {invalid_action_reply, AR},
9798	    {error, Err, ok}
9799    end;
9800otp_6276_mg_verify_service_change_reply(Else) ->
9801    io:format("otp_6276_mg_verify_service_change_reply -> unknown"
9802	      "~n   Else: ~p~n", [Else]),
9803    {error, Else, ok}.
9804
9805otp_6276_mg_verify_trans_reply_fun(Pid) ->
9806    fun(Event) ->
9807	    otp_6276_mg_verify_trans_reply(Pid, Event)
9808    end.
9809
9810otp_6276_mg_verify_trans_reply(Pid,
9811  {handle_trans_reply, _CH, ?VERSION,
9812   {error, {user_cancel, otp_6276}} = E, _}) ->
9813    io:format("otp_6276_mg_verify_trans_reply -> expected error"
9814	      "~n", []),
9815    Pid ! {notify_request_cancelled, self()},
9816    {ok, E, error};
9817otp_6276_mg_verify_trans_reply(_Pid,
9818  {handle_trans_reply, _CH, ?VERSION,
9819   {error, Reason} = E, _}) ->
9820    io:format("otp_6276_mg_verify_trans_reply -> unexpected error"
9821	      "~n   Reason: ~p"
9822	      "~n", [Reason]),
9823    {error, E, error};
9824otp_6276_mg_verify_trans_reply(_Pid,
9825  {handle_trans_reply, _CH, ?VERSION, Result, _}) ->
9826    io:format("otp_6276_mg_verify_trans_reply -> unexpected result"
9827	      "~n   Result: ~p"
9828	      "~n", [Result]),
9829    {error, Result, error};
9830otp_6276_mg_verify_trans_reply(_Pid, Else) ->
9831    io:format("otp_6276_mg_verify_trans_reply -> unknown event"
9832	      "~n   Else: ~p"
9833	      "~n", [Else]),
9834    {error, Else, error}.
9835
9836otp_6276_mg_verify_unexpected_trans_fun(Pid) ->
9837    fun(Event) ->
9838	    otp_6276_mg_verify_unexpected_trans(Pid, Event)
9839    end.
9840
9841otp_6276_mg_verify_unexpected_trans(Pid,
9842  {handle_unexpected_trans, RH, ?VERSION, Trans}) ->
9843    io:format("otp_6276_mg_verify_unexpected_trans -> expected event"
9844	      "~n   RH:    ~p"
9845	      "~n   Trans: ~p"
9846	      "~n", [RH, Trans]),
9847    Pid ! {unexpected_trans, self(), Trans},
9848    {ok, Trans, error};
9849otp_6276_mg_verify_unexpected_trans(_Pid, Else) ->
9850    io:format("otp_6276_mg_verify_unexpected_trans -> unknown event"
9851	      "~n   Else: ~p"
9852	      "~n", [Else]),
9853    {error, Else, error}.
9854
9855otp_6276_mg_service_change_request_ar(_Mid, Cid) ->
9856    Prof  = cre_serviceChangeProf("resgw", 1),
9857    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
9858    Root  = #megaco_term_id{id = ["root"]},
9859    SCR   = cre_serviceChangeReq([Root], SCP),
9860    CMD   = cre_command(SCR),
9861    CR    = cre_cmdReq(CMD),
9862    cre_actionReq(Cid, [CR]).
9863
9864otp_6276_mg_notify_request_ar(Rid, Tid, Cid) ->
9865    TT      = cre_timeNotation("19990729", "22000000"),
9866    Ev      = cre_obsEvent("al/of", TT),
9867    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
9868    NR      = cre_notifyReq([Tid], EvsDesc),
9869    CMD     = cre_command(NR),
9870    CR      = cre_cmdReq(CMD),
9871    cre_actionReq(Cid, [CR]).
9872
9873
9874-else.  % -ifdef(MEGACO_TEST_CODE).
9875
9876otp_6276(suite) ->
9877    [];
9878otp_6276(doc) ->
9879    "OTP-6276";
9880otp_6276(Config) when is_list(Config) ->
9881
9882    ?SKIP("included only if compiled with USE_MEGACO_TEST_CODE=true").
9883
9884-endif. % -ifdef(MEGACO_TEST_CODE).
9885
9886
9887%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9888
9889
9890otp_6442_resend_request1(suite) ->
9891    [];
9892otp_6442_resend_request1(Config) when is_list(Config) ->
9893    Pre = fun() ->
9894                  MgNode = make_node_name(mg),
9895                  d("start (MG) node: ~p", [MgNode]),
9896                  Nodes = [MgNode],
9897                  ok = ?START_NODES(Nodes, true),
9898                  Nodes
9899          end,
9900    Case = fun do_otp_6442_resend_request1/1,
9901    Post = fun(Nodes) ->
9902                   d("stop nodes"),
9903                   ?STOP_NODES(lists:reverse(Nodes))
9904           end,
9905    try_tc(otp6442rreq1, Pre, Case, Post).
9906
9907do_otp_6442_resend_request1([MgNode]) ->
9908    d("[MG] start the simulator"),
9909    {ok, Mg} = megaco_test_megaco_generator:start_link("MG", MgNode),
9910
9911    d("[MG] create the event sequence (~p)", [Mg]),
9912    MgMid = {deviceName,"mg"},
9913    MgEvSeq = otp_6442_resend_request1_mg_event_sequence(MgMid),
9914
9915    i("wait some time before starting the MG simulation"),
9916    sleep(1000),
9917
9918    d("[MG] start the simulation"),
9919    {ok, MgId} = megaco_test_megaco_generator:exec(Mg, MgEvSeq),
9920
9921    i("await the transport module service change send_message event"),
9922    Pid = otp_6442_expect(fun otp_6442_rsrq1_verify_scr_msg/1, 5000),
9923
9924    i("wait some before issuing the service change reply"),
9925    sleep(500),
9926
9927    i("send the service change reply"),
9928    MgcMid = {deviceName,"mgc"},
9929    ServiceChangeReply = otp_6442_mgc_service_change_reply_msg(MgcMid, 1, 1),
9930    megaco_test_generic_transport:incomming_message(Pid, ServiceChangeReply),
9931
9932    i("await the transport module "
9933      "notify-request send_message event from MG: "
9934      "ignore"),
9935    ok = otp_6442_expect(fun otp_6442_rsrq1_verify_first_nr_msg/1, 5000),
9936
9937    i("await the transport module "
9938      "notify-request resend_message event from MG: "
9939      "reply"),
9940    {TransId2, Cid2, TermId2} =
9941	otp_6442_expect(fun otp_6442_rsrq1_verify_second_nr_msg/1, 10000),
9942
9943    i("wait some before issuing the notify reply"),
9944    sleep(500),
9945
9946    i("send the notify reply"),
9947    NotifyReply =
9948	otp_6442_mgc_notify_reply_msg(MgcMid, TransId2, Cid2, TermId2),
9949    megaco_test_generic_transport:incomming_message(Pid, NotifyReply),
9950
9951    d("await the generator reply"),
9952    await_completion([MgId]),
9953
9954    %% Tell Mg to stop
9955    i("[MG] stop generator"),
9956    megaco_test_megaco_generator:stop(Mg),
9957
9958    i("done", []),
9959    ok.
9960
9961
9962otp_6442_expect(Verify, Timeout) when (Timeout > 0) ->
9963    T = mtime(),
9964    receive
9965	Msg ->
9966	    case (catch Verify(Msg)) of
9967		{ok, Result} ->
9968		    d("verified after ~p msec", [mtime() - T]),
9969		    Result;
9970		skip ->
9971		    otp_6442_expect(Verify, to(Timeout, T));
9972		{error, Reason} ->
9973		    exit({verification_failed, Reason})
9974	    end
9975    after Timeout ->
9976	    exit(timeout)
9977    end;
9978otp_6442_expect(_, _Timeout) ->
9979    exit(timeout).
9980
9981otp_6442_rsrq1_verify_scr_msg(
9982  {transport_event, {send_message, _SH, {message, Msg}}, Pid})
9983  when is_record(Msg, 'MegacoMessage') ->
9984    d("received expected service change request message: "
9985      "~n   Msg: ~p", [Msg]),
9986    Reply = ok,
9987    Pid ! {transport_reply, Reply, self()},
9988    {ok, Pid};
9989otp_6442_rsrq1_verify_scr_msg(
9990  {transport_event, {send_message, _SH, BadMsg}, _Pid}) ->
9991    io:format("otp_6442_rsrq1_verify_scr_msg -> error: "
9992	      "~n   BadMsg: ~p"
9993	      "~n", [BadMsg]),
9994    {error, {invalid_message, BadMsg}};
9995otp_6442_rsrq1_verify_scr_msg({transport_event, BadEvent, _Pid}) ->
9996    io:format("otp_6442_rsrq1_verify_scr_msg -> error: "
9997	      "~n   BadEvent: ~p"
9998	      "~n", [BadEvent]),
9999    {error, {invalid_message, BadEvent}};
10000otp_6442_rsrq1_verify_scr_msg(Msg) ->
10001    io:format("otp_6442_rsrq1_verify_scr_msg -> error: "
10002	      "~n   Msg: ~p"
10003	      "~n", [Msg]),
10004    {error, {invalid_message, Msg}}.
10005
10006otp_6442_rsrq1_verify_first_nr_msg(
10007  {transport_event, {send_message, _SH, {message, Msg}}, Pid})
10008  when is_record(Msg, 'MegacoMessage') ->
10009    d("received expected first notify request send message: "
10010      "~n   Msg: ~p", [Msg]),
10011    Reply = ok,
10012    Pid ! {transport_reply, Reply, self()},
10013    {ok, ok};
10014otp_6442_rsrq1_verify_first_nr_msg(Msg) ->
10015    io:format("otp_6442_rsrq1_verify_nr_msg -> error: "
10016	      "~n   Msg: ~p"
10017	      "~n", [Msg]),
10018    {error, {invalid_message, Msg}}.
10019
10020otp_6442_rsrq1_verify_second_nr_msg(
10021  {transport_event, {send_message, _SH, {message, Msg}}, Pid})
10022  when is_record(Msg, 'MegacoMessage') ->
10023    io:format("otp_6442_rsrq1_verify_second_nr_msg -> "
10024	      "entry when received expected message with"
10025	      "~n   Msg: ~p"
10026	      "~n", [Msg]),
10027    Reply = ok,
10028    Pid ! {transport_reply, Reply, self()},
10029    #'MegacoMessage'{mess = Mess} = Msg,
10030    #'Message'{mId         = _Mid,
10031	       messageBody = Body} = Mess,
10032    {transactions, Transactions} = Body,
10033    [Transaction] = Transactions,
10034    {transactionRequest, TransReq} = Transaction,
10035    #'TransactionRequest'{transactionId = TransId,
10036			  actions       = Actions} = TransReq,
10037    [Action] = Actions,
10038    #'ActionRequest'{contextId       = Cid,
10039		     commandRequests = CmdReqs} = Action,
10040    [CmdReq] = CmdReqs,
10041    #'CommandRequest'{command = Cmd} = CmdReq,
10042    {notifyReq, NR} = Cmd,
10043    #'NotifyRequest'{terminationID = [TermId]} = NR,
10044    {ok, {TransId, Cid, TermId}};
10045otp_6442_rsrq1_verify_second_nr_msg(Msg) ->
10046    io:format("otp_6442_rsrq1_verify_second_nr_msg -> entry when error with"
10047	      "~n   Msg: ~p"
10048	      "~n", [Msg]),
10049    {error, {invalid_message, Msg}}.
10050
10051
10052otp_6442_mgc_service_change_reply_msg(Mid, TransId, Cid) ->
10053    SCRP  = #'ServiceChangeResParm'{serviceChangeMgcId = Mid},
10054    SCRPs = {serviceChangeResParms, SCRP},
10055    Root  = #megaco_term_id{id = ["root"]},
10056    SCR   = #'ServiceChangeReply'{terminationID       = [Root],
10057                                  serviceChangeResult = SCRPs},
10058    CR    = {serviceChangeReply, SCR},
10059    otp_6442_mgc_reply_msg(Mid, TransId, CR, Cid).
10060
10061otp_6442_mgc_notify_reply_msg(Mid, TransId, Cid, TermId) ->
10062    NR  = #'NotifyReply'{terminationID = [TermId]},
10063    CR  = {notifyReply, NR},
10064    otp_6442_mgc_reply_msg(Mid, TransId, CR, Cid).
10065
10066otp_6442_mgc_reply_msg(Mid, TransId, CR, Cid) ->
10067    AR  = #'ActionReply'{contextId    = Cid,
10068                         commandReply = [CR]},
10069    ARs  = {actionReplies, [AR]},
10070    TR   = #'TransactionReply'{transactionId     = TransId,
10071                               transactionResult = ARs},
10072    Body = {transactions, [{transactionReply, TR}]},
10073    Mess = #'Message'{version     = 1,
10074                      mId         = Mid,
10075                      messageBody = Body},
10076    #'MegacoMessage'{mess = Mess}.
10077
10078
10079%%
10080%% MG generator stuff
10081%%
10082-ifdef(megaco_hipe_special).
10083-define(otp_6442_resend_request1_mg_verify_handle_connect_fun(),
10084	{?MODULE, otp_6442_resend_request1_mg_verify_handle_connect, []}).
10085-define(otp_6442_resend_request1_mg_verify_service_change_rep_fun(),
10086	{?MODULE, otp_6442_resend_request1_mg_verify_service_change_rep, []}).
10087-define(otp_6442_resend_request1_mg_verify_notify_rep_fun(),
10088	{?MODULE, otp_6442_resend_request1_mg_verify_notify_rep, []}).
10089-else.
10090-define(otp_6442_resend_request1_mg_verify_handle_connect_fun(),
10091	otp_6442_resend_request1_mg_verify_handle_connect_fun()).
10092-define(otp_6442_resend_request1_mg_verify_service_change_rep_fun(),
10093	otp_6442_resend_request1_mg_verify_service_change_rep_fun()).
10094-define(otp_6442_resend_request1_mg_verify_notify_rep_fun(),
10095	otp_6442_resend_request1_mg_verify_notify_rep_fun()).
10096-endif.
10097
10098otp_6442_resend_request1_mg_event_sequence(Mid) ->
10099    RI = [
10100          {port,             self()}, % This is just a trick to get my pid to the transport module
10101          {encoding_module,  megaco_pretty_text_encoder},
10102          {encoding_config,  []},
10103          {transport_module, megaco_test_generic_transport}
10104         ],
10105    ServiceChangeReq =
10106	otp_6442_resend_request1_mg_service_change_request_ar(Mid, 1),
10107    Tid = #megaco_term_id{id = ["00000000","00000000","01101101"]},
10108    NotifyReq = otp_6442_resend_request1_mg_notify_request_ar(1, Tid, 1),
10109    ConnectVerify =
10110	?otp_6442_resend_request1_mg_verify_handle_connect_fun(),
10111    ServiceChangeReplyVerify =
10112	?otp_6442_resend_request1_mg_verify_service_change_rep_fun(),
10113    NotifyReplyVerify =
10114	?otp_6442_resend_request1_mg_verify_notify_rep_fun(),
10115    EvSeq = [
10116             {debug, false},
10117             megaco_start,
10118             {megaco_start_user, Mid, RI, []},
10119	     {megaco_update_user_info, resend_indication, false},
10120             start_transport,
10121             {megaco_trace, disable},
10122             {megaco_system_info, users},
10123             {megaco_system_info, connections},
10124             connect,
10125             {megaco_callback, handle_connect, ConnectVerify},
10126             megaco_connect,
10127             {megaco_cast,     [ServiceChangeReq], []},
10128             {megaco_callback, handle_connect,     ConnectVerify},
10129             {megaco_callback, handle_trans_reply, ServiceChangeReplyVerify},
10130             {sleep, 1000},
10131             {megaco_cast,     [NotifyReq],        []},
10132             {megaco_callback, handle_trans_reply, NotifyReplyVerify},
10133             {sleep, 1000},
10134             megaco_stop_user,
10135             megaco_stop,
10136             {sleep, 1000}
10137            ],
10138    EvSeq.
10139
10140
10141-ifndef(megaco_hipe_special).
10142otp_6442_resend_request1_mg_verify_handle_connect_fun() ->
10143    fun(Ev) ->
10144	    otp_6442_resend_request1_mg_verify_handle_connect(Ev)
10145    end.
10146-endif.
10147
10148otp_6442_resend_request1_mg_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
10149    io:format("otp_6442_resend_request1_mg_verify_handle_connect -> ok"
10150	      "~n   CH: ~p~n", [CH]),
10151    {ok, CH, ok};
10152otp_6442_resend_request1_mg_verify_handle_connect(Else) ->
10153    io:format("otp_6442_resend_request1_mg_verify_handle_connect -> unknown"
10154	      "~n   Else: ~p~n", [Else]),
10155    {error, Else, ok}.
10156
10157-ifndef(megaco_hipe_special).
10158otp_6442_resend_request1_mg_verify_service_change_rep_fun() ->
10159    fun(Rep) ->
10160	    otp_6442_resend_request1_mg_verify_service_change_rep(Rep)
10161    end.
10162-endif.
10163
10164otp_6442_resend_request1_mg_verify_service_change_rep(
10165  {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _}) ->
10166    (catch otp_6442_resend_request1_mg_do_verify_service_change_rep(AR));
10167otp_6442_resend_request1_mg_verify_service_change_rep(Crap) ->
10168    {error, Crap, ok}.
10169
10170otp_6442_resend_request1_mg_do_verify_service_change_rep(AR) ->
10171    io:format("otp_6442_resend_request1_mg_verify_service_change_rep -> ok"
10172	      "~n   AR: ~p~n", [AR]),
10173    CR =
10174	case AR of
10175	    #'ActionReply'{commandReply = [CmdRep]} ->
10176		CmdRep;
10177	    _ ->
10178		Reason1 = {invalid_action_reply, AR},
10179		throw({error, Reason1, ok})
10180	end,
10181    SCR =
10182	case CR of
10183	    {serviceChangeReply, ServChRep} ->
10184		ServChRep;
10185	    _ ->
10186		Reason2 = {invalid_command_reply, CR},
10187		throw({error, Reason2, ok})
10188	end,
10189    {Tid, SCRes} =
10190	case SCR of
10191	    #'ServiceChangeReply'{terminationID       = [TermID],
10192				  serviceChangeResult = Res} ->
10193		{TermID, Res};
10194	    _ ->
10195		Reason3 = {invalid_service_change_reply, SCR},
10196		throw({error, Reason3, ok})
10197	end,
10198    case Tid of
10199	#megaco_term_id{contains_wildcards = false, id = ["root"]} ->
10200	    ok;
10201	_ ->
10202	    Reason4 = {invalid_termination_id, Tid},
10203	    throw({error, Reason4, ok})
10204    end,
10205    SCRParm =
10206	case SCRes of
10207	    {serviceChangeResParms, ServChResParms} ->
10208		ServChResParms;
10209	    _ ->
10210		Reason5 = {invalid_serviceChangeResult, SCRes},
10211		throw({error, Reason5, ok})
10212	end,
10213    case SCRParm of
10214	#'ServiceChangeResParm'{serviceChangeMgcId = _RemoteMid} ->
10215	    {ok, AR, ok};
10216	_ ->
10217	    Reason6 = {invalid_service_change_result, SCRParm},
10218	    {error, Reason6, ok}
10219    end.
10220
10221-ifndef(megaco_hipe_special).
10222otp_6442_resend_request1_mg_verify_notify_rep_fun() ->
10223    fun(Rep) ->
10224	    otp_6442_resend_request1_mg_verify_notify_rep(Rep)
10225    end.
10226-endif.
10227
10228otp_6442_resend_request1_mg_verify_notify_rep(
10229  {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _}) ->
10230    io:format("otp_6442_resend_request1_mg_verify_notify_rep -> ok"
10231	      "~n   AR: ~p~n", [AR]),
10232    {ok, AR, ok};
10233otp_6442_resend_request1_mg_verify_notify_rep(Else) ->
10234    io:format("otp_6442_resend_request1_mg_verify_notify_rep -> unknown"
10235	      "~n   Else: ~p~n", [Else]),
10236    {error, Else, ok}.
10237
10238
10239otp_6442_resend_request1_mg_service_change_request_ar(_Mid, Cid) ->
10240    Prof  = cre_serviceChangeProf("resgw", 1),
10241    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
10242    Root  = #megaco_term_id{id = ["root"]},
10243    SCR   = cre_serviceChangeReq([Root], SCP),
10244    CMD   = cre_command(SCR),
10245    CR    = cre_cmdReq(CMD),
10246    cre_actionReq(Cid, [CR]).
10247
10248otp_6442_resend_request1_mg_notify_request_ar(Rid, Tid, Cid) ->
10249    TT      = cre_timeNotation("19990729", "22000000"),
10250    Ev      = cre_obsEvent("al/of", TT),
10251    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
10252    NR      = cre_notifyReq([Tid], EvsDesc),
10253    CMD     = cre_command(NR),
10254    CR      = cre_cmdReq(CMD),
10255    cre_actionReq(Cid, [CR]).
10256
10257
10258
10259%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10260
10261otp_6442_resend_request2(suite) ->
10262    [];
10263otp_6442_resend_request2(Config) when is_list(Config) ->
10264    Pre = fun() ->
10265                  MgNode = make_node_name(mg),
10266                  d("start (MG) node: ~p", [MgNode]),
10267                  Nodes = [MgNode],
10268                  ok = ?START_NODES(Nodes, true),
10269                  Nodes
10270          end,
10271    Case = fun do_otp_6442_resend_request2/1,
10272    Post = fun(Nodes) ->
10273                   d("stop nodes"),
10274                   ?STOP_NODES(lists:reverse(Nodes))
10275           end,
10276    try_tc(otp6442rreq2, Pre, Case, Post).
10277
10278do_otp_6442_resend_request2([MgNode]) ->
10279    d("[MG] start the simulator "),
10280    {ok, Mg} = megaco_test_megaco_generator:start_link("MG", MgNode),
10281
10282    d("[MG] create the event sequence"),
10283    Mid = {deviceName,"mg"},
10284    MgcMid = {deviceName,"mgc"},
10285    MgEvSeq = otp_6442_resend_request2_mg_event_sequence(Mid),
10286
10287    i("wait some time before starting the MG simulation"),
10288    sleep(1000),
10289
10290    d("[MG] start the simulation"),
10291    {ok, MgId} = megaco_test_megaco_generator:exec(Mg, MgEvSeq),
10292
10293    i("await the transport module service change send_message event"),
10294    Pid = otp_6442_expect(fun otp_6442_rsrq2_verify_scr_msg/1, 5000),
10295
10296    i("wait some before issuing the service change reply"),
10297    sleep(500),
10298
10299    i("send the service change reply"),
10300    ServiceChangeReply = otp_6442_mgc_service_change_reply_msg(MgcMid, 1, 1),
10301    megaco_test_generic_transport:incomming_message(Pid, ServiceChangeReply),
10302
10303    i("await the transport module notify-request send_message event from MG: ignore"),
10304    ok = otp_6442_expect(fun otp_6442_rsrq2_verify_first_nr_msg/1, 5000),
10305
10306    i("await the transport module notify-request resend_message event from MG: reply"),
10307    {TransId2, Cid2, TermId2} =
10308	otp_6442_expect(fun otp_6442_rsrq2_verify_second_nr_msg/1, 10000),
10309
10310    i("wait some before issuing the notify reply"),
10311    sleep(500),
10312
10313    i("send the notify reply"),
10314    NotifyReply = otp_6442_mgc_notify_reply_msg(MgcMid, TransId2, Cid2, TermId2),
10315    megaco_test_generic_transport:incomming_message(Pid, NotifyReply),
10316
10317    d("await the generator reply"),
10318    await_completion([MgId]),
10319
10320    %% Tell Mg to stop
10321    i("[MG] stop generator"),
10322    megaco_test_megaco_generator:stop(Mg),
10323
10324    i("done", []),
10325    ok.
10326
10327
10328otp_6442_rsrq2_verify_scr_msg(
10329  {transport_event, {send_message, _SH, {message, Msg}}, Pid})
10330  when is_record(Msg, 'MegacoMessage') ->
10331    d("received expected service change request message: "
10332      "~n   Msg: ~p", [Msg]),
10333    Reply = ok,
10334    Pid ! {transport_reply, Reply, self()},
10335    {ok, Pid};
10336otp_6442_rsrq2_verify_scr_msg(Msg) ->
10337    io:format("otp_6442_rsrq2_verify_nr_msg -> error: "
10338	      "~n   Msg: ~p"
10339	      "~n", [Msg]),
10340    {error, {invalid_message, Msg}}.
10341
10342otp_6442_rsrq2_verify_first_nr_msg(
10343  {transport_event, {send_message, _SH, {message, Msg}}, Pid})
10344  when is_record(Msg, 'MegacoMessage') ->
10345    d("received expected first notify request message: "
10346      "~n   Msg: ~p", [Msg]),
10347    Reply = ok,
10348    Pid ! {transport_reply, Reply, self()},
10349    {ok, ok};
10350otp_6442_rsrq2_verify_first_nr_msg(Msg) ->
10351    {error, {invalid_message, Msg}}.
10352
10353otp_6442_rsrq2_verify_second_nr_msg(
10354  {transport_event, {resend_message, _SH, {message, Msg}}, Pid})
10355  when is_record(Msg, 'MegacoMessage') ->
10356    d("received expected second notify request message: "
10357      "~n   Msg: ~p", [Msg]),
10358    Reply = ok,
10359    Pid ! {transport_reply, Reply, self()},
10360    #'MegacoMessage'{mess = Mess} = Msg,
10361    #'Message'{mId         = _Mid,
10362	       messageBody = Body} = Mess,
10363    {transactions, Transactions} = Body,
10364    [Transaction] = Transactions,
10365    {transactionRequest, TransReq} = Transaction,
10366    #'TransactionRequest'{transactionId = TransId,
10367			  actions       = Actions} = TransReq,
10368    [Action] = Actions,
10369    #'ActionRequest'{contextId       = Cid,
10370		     commandRequests = CmdReqs} = Action,
10371    [CmdReq] = CmdReqs,
10372    #'CommandRequest'{command = Cmd} = CmdReq,
10373    {notifyReq, NR} = Cmd,
10374    #'NotifyRequest'{terminationID = [TermId]} = NR,
10375    {ok, {TransId, Cid, TermId}};
10376otp_6442_rsrq2_verify_second_nr_msg(Msg) ->
10377    {error, {invalid_message, Msg}}.
10378
10379
10380%%
10381%% MG generator stuff
10382%%
10383-ifdef(megaco_hipe_special).
10384-define(otp_6442_resend_request2_mg_verify_handle_connect_fun(),
10385	{?MODULE, otp_6442_resend_request2_mg_verify_handle_connect, []}).
10386-define(otp_6442_resend_request2_mg_verify_service_change_rep_fun(),
10387	{?MODULE, otp_6442_resend_request2_mg_verify_service_change_rep, []}).
10388-define(otp_6442_resend_request2_mg_verify_notify_rep_fun(),
10389	{?MODULE, otp_6442_resend_request2_mg_verify_notify_rep, []}).
10390-else.
10391-define(otp_6442_resend_request2_mg_verify_handle_connect_fun(),
10392	otp_6442_resend_request2_mg_verify_handle_connect_fun()).
10393-define(otp_6442_resend_request2_mg_verify_service_change_rep_fun(),
10394	otp_6442_resend_request2_mg_verify_service_change_rep_fun()).
10395-define(otp_6442_resend_request2_mg_verify_notify_rep_fun(),
10396	otp_6442_resend_request2_mg_verify_notify_rep_fun()).
10397-endif.
10398
10399otp_6442_resend_request2_mg_event_sequence(Mid) ->
10400    RI = [
10401          {port,             self()}, % This is just a trick to get my pid to the transport module
10402          {encoding_module,  megaco_pretty_text_encoder},
10403          {encoding_config,  []},
10404          {transport_module, megaco_test_generic_transport}
10405         ],
10406    Tid = #megaco_term_id{id = ["00000000","00000000","01101101"]},
10407    NotifyReq = otp_6442_resend_request2_mg_notify_request_ar(1, Tid, 1),
10408    ServiceChangeReq =
10409	otp_6442_resend_request2_mg_service_change_request_ar(Mid, 1),
10410    ConnectVerify =
10411	?otp_6442_resend_request2_mg_verify_handle_connect_fun(),
10412    ServiceChangeReplyVerify =
10413	?otp_6442_resend_request2_mg_verify_service_change_rep_fun(),
10414    NotifyReplyVerify =
10415	?otp_6442_resend_request2_mg_verify_notify_rep_fun(),
10416%%     ConnectVerify =
10417%% 	otp_6442_resend_request2_mg_verify_handle_connect_fun(),
10418%%     ServiceChangeReplyVerify =
10419%% 	otp_6442_resend_request2_mg_verify_service_change_reply_fun(),
10420%%     NotifyReplyVerify = otp_6442_resend_request2_mg_verify_notify_reply_fun(),
10421    EvSeq = [
10422             {debug, false},
10423             megaco_start,
10424             {megaco_start_user, Mid, RI, []},
10425	     {megaco_update_user_info, resend_indication, true},
10426             start_transport,
10427             {megaco_trace, disable},
10428             {megaco_system_info, users},
10429             {megaco_system_info, connections},
10430             connect,
10431             {megaco_callback, handle_connect, ConnectVerify},
10432             megaco_connect,
10433             {megaco_cast,     [ServiceChangeReq], []},
10434             {megaco_callback, handle_connect,     ConnectVerify},
10435             {megaco_callback, handle_trans_reply, ServiceChangeReplyVerify},
10436             {sleep, 1000},
10437             {megaco_cast,     [NotifyReq],        []},
10438             {megaco_callback, handle_trans_reply, NotifyReplyVerify},
10439             {sleep, 1000},
10440             megaco_stop_user,
10441             megaco_stop,
10442             {sleep, 1000}
10443            ],
10444    EvSeq.
10445
10446
10447-ifndef(megaco_hipe_special).
10448otp_6442_resend_request2_mg_verify_handle_connect_fun() ->
10449    fun(Ev) ->
10450	    otp_6442_resend_request2_mg_verify_handle_connect(Ev)
10451    end.
10452-endif.
10453
10454otp_6442_resend_request2_mg_verify_handle_connect(
10455  {handle_connect, CH, ?VERSION}) ->
10456    io:format("otp_6442_resend_request2_mg_verify_handle_connect -> ok"
10457	      "~n   CH: ~p~n", [CH]),
10458    {ok, CH, ok};
10459otp_6442_resend_request2_mg_verify_handle_connect(Else) ->
10460    io:format("otp_6442_resend_request2_mg_verify_handle_connect -> unknown"
10461	      "~n   Else: ~p~n", [Else]),
10462    {error, Else, ok}.
10463
10464
10465-ifndef(megaco_hipe_special).
10466otp_6442_resend_request2_mg_verify_service_change_rep_fun() ->
10467    fun(Rep) ->
10468	    otp_6442_resend_request2_mg_verify_service_change_rep(Rep)
10469    end.
10470-endif.
10471
10472otp_6442_resend_request2_mg_verify_service_change_rep(
10473  {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _}) ->
10474    (catch otp_6442_resend_request2_mg_do_verify_service_change_rep(AR));
10475otp_6442_resend_request2_mg_verify_service_change_rep(Crap) ->
10476    {error, Crap, ok}.
10477
10478otp_6442_resend_request2_mg_do_verify_service_change_rep(AR) ->
10479    io:format("otp_6442_resend_request2_mg_verify_service_change_rep -> ok"
10480	      "~n   AR: ~p~n", [AR]),
10481    CR =
10482	case AR of
10483	    #'ActionReply'{commandReply = [CmdRep]} ->
10484		CmdRep;
10485	    _ ->
10486		Reason1 = {invalid_action_reply, AR},
10487		throw({error, Reason1, ok})
10488	end,
10489    SCR =
10490	case CR of
10491	    {serviceChangeReply, ServChRep} ->
10492		ServChRep;
10493	    _ ->
10494		Reason2 = {invalid_command_reply, CR},
10495		throw({error, Reason2, ok})
10496	end,
10497    {Tid, SCRes} =
10498	case SCR of
10499	    #'ServiceChangeReply'{terminationID       = [TermID],
10500				  serviceChangeResult = Res} ->
10501		{TermID, Res};
10502	    _ ->
10503		Reason3 = {invalid_service_change_reply, SCR},
10504		throw({error, Reason3, ok})
10505	end,
10506    case Tid of
10507	#megaco_term_id{contains_wildcards = false, id = ["root"]} ->
10508	    ok;
10509	_ ->
10510	    Reason4 = {invalid_termination_id, Tid},
10511	    throw({error, Reason4, ok})
10512    end,
10513    SCRParm =
10514	case SCRes of
10515	    {serviceChangeResParms, ServChResParms} ->
10516		ServChResParms;
10517	    _ ->
10518		Reason5 = {invalid_serviceChangeResult, SCRes},
10519		throw({error, Reason5, ok})
10520	end,
10521    case SCRParm of
10522	#'ServiceChangeResParm'{serviceChangeMgcId = _RemoteMid} ->
10523	    {ok, AR, ok};
10524	_ ->
10525	    Reason6 = {invalid_service_change_result, SCRParm},
10526	    {error, Reason6, ok}
10527    end.
10528
10529-ifndef(megaco_hipe_special).
10530otp_6442_resend_request2_mg_verify_notify_rep_fun() ->
10531    fun(Rep) ->
10532	    otp_6442_resend_request2_mg_verify_notify_rep(Rep)
10533    end.
10534-endif.
10535
10536otp_6442_resend_request2_mg_verify_notify_rep(
10537  {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _}) ->
10538    io:format("otp_6442_resend_request2_mg_verify_notify_rep -> ok"
10539	      "~n   AR: ~p~n", [AR]),
10540    {ok, AR, ok};
10541otp_6442_resend_request2_mg_verify_notify_rep(Else) ->
10542    io:format("otp_6442_resend_request2_mg_verify_notify_rep -> unknown"
10543	      "~n   Else: ~p~n", [Else]),
10544    {error, Else, ok}.
10545
10546
10547otp_6442_resend_request2_mg_service_change_request_ar(_Mid, Cid) ->
10548    Prof  = cre_serviceChangeProf("resgw", 1),
10549    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
10550    Root  = #megaco_term_id{id = ["root"]},
10551    SCR   = cre_serviceChangeReq([Root], SCP),
10552    CMD   = cre_command(SCR),
10553    CR    = cre_cmdReq(CMD),
10554    cre_actionReq(Cid, [CR]).
10555
10556otp_6442_resend_request2_mg_notify_request_ar(Rid, Tid, Cid) ->
10557    TT      = cre_timeNotation("19990729", "22000000"),
10558    Ev      = cre_obsEvent("al/of", TT),
10559    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
10560    NR      = cre_notifyReq([Tid], EvsDesc),
10561    CMD     = cre_command(NR),
10562    CR      = cre_cmdReq(CMD),
10563    cre_actionReq(Cid, [CR]).
10564
10565
10566
10567%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10568
10569otp_6442_resend_reply1(suite) ->
10570    [];
10571otp_6442_resend_reply1(Config) when is_list(Config) ->
10572    Factor = ?config(megaco_factor, Config),
10573    Pre = fun() ->
10574                  MgNode = make_node_name(mg),
10575                  d("start (MG) node: ~p", [MgNode]),
10576                  Nodes = [MgNode],
10577                  ok = ?START_NODES(Nodes, true),
10578                  Nodes
10579          end,
10580    Case = fun(Nodes) -> do_otp_6442_resend_reply1(Nodes, Factor) end,
10581    Post = fun(Nodes) ->
10582                   d("stop nodes"),
10583                   ?STOP_NODES(lists:reverse(Nodes))
10584           end,
10585    try_tc(request_and_no_reply, Pre, Case, Post).
10586
10587do_otp_6442_resend_reply1([MgNode], Factor) ->
10588    d("[MG] start the simulator "),
10589    {ok, Mg} = megaco_test_megaco_generator:start_link("MG", MgNode),
10590
10591    d("[MG] create the event sequence"),
10592    Mid     = {deviceName,"mg"},
10593    MgcMid  = {deviceName,"mgc"},
10594    TermId  = #megaco_term_id{id = ["00000000","00000000","01101101"]},
10595    MgEvSeq = otp_6442_resend_reply1_mg_event_sequence(Mid, TermId),
10596
10597    i("wait some time before starting the MG simulation"),
10598    sleep(1000),
10599
10600    d("[MG] start the simulation"),
10601    {ok, MgId} = megaco_test_megaco_generator:exec(Mg, MgEvSeq),
10602
10603    i("await the transport module service change send_message event"),
10604    Pid = otp_6442_expect(fun otp_6442_rsrp1_verify_scr_msg/1, Factor * 5000),
10605
10606    i("wait some before issuing the service change reply"),
10607    sleep(500),
10608
10609    i("simulate MGC sending the service change reply"),
10610    ServiceChangeReply = otp_6442_mgc_service_change_reply_msg(MgcMid, 1, 1),
10611    megaco_test_generic_transport:incomming_message(Pid, ServiceChangeReply),
10612
10613
10614    i("wait some before issuing the notify request"),
10615    sleep(500),
10616
10617    i("simulate MGC sending the notify request"),
10618    NotifyRequest = otp_6442_mgc_notify_request_msg(MgcMid, TermId, 2, 1),
10619    megaco_test_generic_transport:incomming_message(Pid, NotifyRequest),
10620
10621    i("await the transport module first notify-reply send_message event from MG: "
10622      "ignore"),
10623    otp_6442_expect(fun otp_6442_rsrp1_verify_first_nr_msg/1, Factor * 5000),
10624
10625    i("await the transport module second notify-reply send_message event from MG: "
10626      "ack"),
10627    {TransId, _, _} = otp_6442_expect(fun otp_6442_rsrp1_verify_second_nr_msg/1, 10000),
10628
10629    i("wait some before issuing the ack"),
10630    sleep(500),
10631
10632    i("simulate MGC sending the ack"),
10633    Ack = otp_6442_mgc_ack_msg(MgcMid, TransId),
10634    megaco_test_generic_transport:incomming_message(Pid, Ack),
10635
10636
10637    d("await the generator reply"),
10638    await_completion([MgId]),
10639
10640    %% Tell Mg to stop
10641    i("[MG] stop generator"),
10642    megaco_test_megaco_generator:stop(Mg),
10643
10644    i("done", []),
10645    ok.
10646
10647
10648otp_6442_rsrp1_verify_scr_msg(
10649  {transport_event, {send_message, _SH, {message, Msg}}, Pid})
10650  when is_record(Msg, 'MegacoMessage') ->
10651    d("received expected service change request message: "
10652      "~n   Msg: ~p", [Msg]),
10653    Reply = ok,
10654    Pid ! {transport_reply, Reply, self()},
10655    {ok, Pid};
10656otp_6442_rsrp1_verify_scr_msg(Msg) ->
10657    {error, {invalid_message, Msg}}.
10658
10659otp_6442_rsrp1_verify_first_nr_msg(
10660  {transport_event, {send_message, _SH, {message, Msg}}, Pid})
10661  when is_record(Msg, 'MegacoMessage') ->
10662    d("received expected first notify reply message: "
10663      "~n   Msg: ~p", [Msg]),
10664    Reply = ok,
10665    Pid ! {transport_reply, Reply, self()},
10666    {ok, ok};
10667otp_6442_rsrp1_verify_first_nr_msg(Msg) ->
10668    {error, {invalid_message, Msg}}.
10669
10670otp_6442_rsrp1_verify_second_nr_msg(
10671  {transport_event, {send_message, _SH, {message, Msg}}, Pid})
10672  when is_record(Msg, 'MegacoMessage') ->
10673    d("received expected second notify reply message: "
10674      "~n   Msg: ~p", [Msg]),
10675    Reply = ok,
10676    Pid ! {transport_reply, Reply, self()},
10677    #'MegacoMessage'{mess = Mess} = Msg,
10678    #'Message'{mId         = _Mid,
10679	       messageBody = Body} = Mess,
10680    {transactions, Transactions} = Body,
10681    [Transaction] = Transactions,
10682    {transactionReply, TransRep} = Transaction,
10683    #'TransactionReply'{transactionId     = TransId,
10684			immAckRequired    = 'NULL',
10685			transactionResult = TransRes} = TransRep,
10686    {actionReplies, ActReps} = TransRes,
10687    [ActRep] = ActReps,
10688    #'ActionReply'{contextId       = Cid,
10689		   errorDescriptor = asn1_NOVALUE,
10690		   contextReply    = asn1_NOVALUE,
10691		   commandReply    = CmdReps} = ActRep,
10692    [CmdRep] = CmdReps,
10693    {notifyReply, NR} = CmdRep,
10694    #'NotifyReply'{terminationID = TermId} = NR,
10695    {ok, {TransId, Cid, TermId}};
10696otp_6442_rsrp1_verify_second_nr_msg(Msg) ->
10697    {error, {invalid_message, Msg}}.
10698
10699
10700otp_6442_mgc_notify_request_msg(Mid, TermId, TransId, Cid) ->
10701    TT      = cre_timeNotation("19990729", "22000000"),
10702    Ev      = cre_obsEvent("al/of", TT),
10703    EvsDesc = cre_obsEvsDesc(1, [Ev]),
10704    NR      = cre_notifyReq([TermId], EvsDesc),
10705    CMD     = cre_command(NR),
10706    CR      = cre_cmdReq(CMD),
10707    AR      = cre_actionReq(Cid, [CR]),
10708    ARs     = [AR],
10709    TR      = cre_transReq(TransId, ARs),
10710    Trans   = cre_transaction(TR),
10711    Mess    = cre_message(?VERSION, Mid, cre_transactions([Trans])),
10712    cre_megacoMessage(Mess).
10713
10714
10715otp_6442_mgc_ack_msg(Mid, TransId) ->
10716    TR    = cre_transRespAck(cre_transAck(TransId)),
10717    Trans = cre_transaction(TR),
10718    Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
10719    cre_megacoMessage(Mess).
10720
10721
10722
10723%%
10724%% MG generator stuff
10725%%
10726-ifdef(megaco_hipe_special).
10727-define(otp_6442_resend_reply1_mg_verify_handle_connect_fun(),
10728	{?MODULE, otp_6442_resend_reply1_mg_verify_handle_connect, []}).
10729-define(otp_6442_resend_reply1_mg_verify_service_change_rep_fun(),
10730	{?MODULE, otp_6442_resend_reply1_mg_verify_service_change_rep, []}).
10731-define(otp_6442_resend_reply1_mg_verify_notify_req_fun(TermId),
10732	{?MODULE, otp_6442_resend_reply1_mg_verify_notify_req, [TermId]}).
10733-define(otp_6442_resend_reply1_mg_verify_ack_fun(),
10734	{?MODULE, otp_6442_resend_reply1_mg_verify_ack, []}).
10735-else.
10736-define(otp_6442_resend_reply1_mg_verify_handle_connect_fun(),
10737	otp_6442_resend_reply1_mg_verify_handle_connect_fun()).
10738-define(otp_6442_resend_reply1_mg_verify_service_change_rep_fun(),
10739	otp_6442_resend_reply1_mg_verify_service_change_rep_fun()).
10740-define(otp_6442_resend_reply1_mg_verify_notify_req_fun(TermId),
10741	otp_6442_resend_reply1_mg_verify_notify_req_fun(TermId)).
10742-define(otp_6442_resend_reply1_mg_verify_ack_fun(),
10743	otp_6442_resend_reply1_mg_verify_ack_fun()).
10744-endif.
10745
10746otp_6442_resend_reply1_mg_event_sequence(Mid, TermId) ->
10747    RI = [
10748          {port,             self()}, % This is just a trick to get my pid to the transport module
10749          {encoding_module,  megaco_pretty_text_encoder},
10750          {encoding_config,  []},
10751          {transport_module, megaco_test_generic_transport}
10752         ],
10753    ServiceChangeReq =
10754	otp_6442_resend_reply1_mg_service_change_request_ar(Mid, 1),
10755    RepTmr = #megaco_incr_timer{wait_for    = 2000,
10756                                factor      = 1,
10757                                max_retries = 1},
10758    ConnectVerify =
10759	?otp_6442_resend_reply1_mg_verify_handle_connect_fun(),
10760    ServiceChangeReplyVerify =
10761	?otp_6442_resend_reply1_mg_verify_service_change_rep_fun(),
10762    NotifyReqVerify =
10763	?otp_6442_resend_reply1_mg_verify_notify_req_fun(TermId),
10764    AckVerify =
10765	?otp_6442_resend_reply1_mg_verify_ack_fun(),
10766%%     ConnectVerify =
10767%% 	otp_6442_resend_reply1_mg_verify_handle_connect_fun(),
10768%%     ServiceChangeReplyVerify =
10769%% 	otp_6442_resend_reply1_mg_verify_service_change_reply_fun(),
10770%%     NotifyReqVerify =
10771%% 	otp_6442_resend_reply1_mg_verify_notify_request_fun(TermId),
10772%%     AckVerify =
10773%% 	otp_6442_resend_reply1_mg_verify_ack_fun(),
10774    EvSeq = [
10775             {debug, false},
10776             megaco_start,
10777             {megaco_start_user, Mid, RI, []},
10778	     {megaco_update_user_info, resend_indication, false},
10779	     {megaco_update_user_info, reply_timer,       RepTmr},
10780             start_transport,
10781             {megaco_trace, disable},
10782             {megaco_system_info, users},
10783             {megaco_system_info, connections},
10784             connect,
10785             {megaco_callback, handle_connect, ConnectVerify},
10786             megaco_connect,
10787             {megaco_cast,     [ServiceChangeReq], []},
10788             {megaco_callback, handle_connect,     ConnectVerify},
10789             {megaco_callback, handle_trans_reply, ServiceChangeReplyVerify},
10790             {sleep, 1000},
10791
10792             {megaco_callback, handle_trans_request, NotifyReqVerify},
10793             {megaco_callback, handle_trans_ack,     AckVerify},
10794
10795             {sleep, 1000},
10796             megaco_stop_user,
10797             megaco_stop,
10798             {sleep, 1000}
10799            ],
10800    EvSeq.
10801
10802
10803-ifndef(megaco_hipe_special).
10804otp_6442_resend_reply1_mg_verify_handle_connect_fun() ->
10805    fun(Ev) ->
10806	    otp_6442_resend_reply1_mg_verify_handle_connect(Ev)
10807    end.
10808-endif.
10809
10810otp_6442_resend_reply1_mg_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
10811    io:format("otp_6442_resend_reply1_mg_verify_handle_connect -> ok"
10812	      "~n   CH: ~p~n", [CH]),
10813    {ok, CH, ok};
10814otp_6442_resend_reply1_mg_verify_handle_connect(Else) ->
10815    io:format("otp_6442_resend_reply1_mg_verify_handle_connect -> unknown"
10816	      "~n   Else: ~p~n", [Else]),
10817    {error, Else, ok}.
10818
10819
10820-ifndef(megaco_hipe_special).
10821otp_6442_resend_reply1_mg_verify_service_change_rep_fun() ->
10822    fun(Rep) ->
10823	    otp_6442_resend_reply1_mg_verify_service_change_rep(Rep)
10824    end.
10825-endif.
10826
10827otp_6442_resend_reply1_mg_verify_service_change_rep(
10828  {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _}) ->
10829    (catch otp_6442_resend_reply1_mg_do_verify_service_change_rep(AR));
10830otp_6442_resend_reply1_mg_verify_service_change_rep(Crap) ->
10831    {error, Crap, ok}.
10832
10833otp_6442_resend_reply1_mg_do_verify_service_change_rep(AR) ->
10834    io:format("otp_6442_resend_reply1_mg_verify_service_change_rep -> ok"
10835	      "~n   AR: ~p~n", [AR]),
10836    CR =
10837	case AR of
10838	    #'ActionReply'{commandReply = [CmdRep]} ->
10839		CmdRep;
10840	    _ ->
10841		Reason1 = {invalid_action_reply, AR},
10842		throw({error, Reason1, ok})
10843	end,
10844    SCR =
10845	case CR of
10846	    {serviceChangeReply, ServChRep} ->
10847		ServChRep;
10848	    _ ->
10849		Reason2 = {invalid_command_reply, CR},
10850		throw({error, Reason2, ok})
10851	end,
10852    {Tid, SCRes} =
10853	case SCR of
10854	    #'ServiceChangeReply'{terminationID       = [TermID],
10855				  serviceChangeResult = Res} ->
10856		{TermID, Res};
10857	    _ ->
10858		Reason3 = {invalid_service_change_reply, SCR},
10859		throw({error, Reason3, ok})
10860	end,
10861    case Tid of
10862	#megaco_term_id{contains_wildcards = false, id = ["root"]} ->
10863	    ok;
10864	_ ->
10865	    Reason4 = {invalid_termination_id, Tid},
10866	    throw({error, Reason4, ok})
10867    end,
10868    SCRParm =
10869	case SCRes of
10870	    {serviceChangeResParms, ServChResParms} ->
10871		ServChResParms;
10872	    _ ->
10873		Reason5 = {invalid_serviceChangeResult, SCRes},
10874		throw({error, Reason5, ok})
10875	end,
10876    case SCRParm of
10877	#'ServiceChangeResParm'{serviceChangeMgcId = _RemoteMid} ->
10878	    {ok, AR, ok};
10879	_ ->
10880	    Reason6 = {invalid_service_change_result, SCRParm},
10881	    {error, Reason6, ok}
10882    end.
10883
10884-ifndef(megaco_hipe_special).
10885otp_6442_resend_reply1_mg_verify_notify_req_fun(TermId) ->
10886    fun(Req) ->
10887	    otp_6442_resend_reply1_mg_verify_notify_req(Req, TermId)
10888    end.
10889-endif.
10890
10891otp_6442_resend_reply1_mg_verify_notify_req(
10892  {handle_trans_request, _, ?VERSION, [AR]}, TermId) ->
10893    io:format("otp_6442_resend_reply1_mg_verify_notify_req -> ok"
10894	      "~n   AR: ~p~n", [AR]),
10895    case AR of
10896	#'ActionRequest'{contextId = 1 = Cid,
10897			 commandRequests = [CR]} ->
10898	    #'CommandRequest'{command = Cmd} = CR,
10899	    {notifyReq, NR} = Cmd,
10900	    #'NotifyRequest'{terminationID            = [TermId],
10901			     observedEventsDescriptor = OED,
10902			     errorDescriptor          = asn1_NOVALUE} = NR,
10903	    #'ObservedEventsDescriptor'{observedEventLst = [OE]} = OED,
10904	    #'ObservedEvent'{eventName = "al/of"} = OE,
10905	    HandleAck = {handle_ack, otp_6442_resend_reply1},
10906	    Reply = {HandleAck,
10907		     [otp_6442_resend_reply1_mg_notify_reply_ar(Cid, TermId)]},
10908	    {ok, AR, Reply};
10909	_ ->
10910	    ED = otp_6442_resend_reply1_err_desc(AR),
10911	    ErrReply = {discard_ack, ED},
10912	    {error, AR, ErrReply}
10913    end;
10914otp_6442_resend_reply1_mg_verify_notify_req(Else, TermId) ->
10915    io:format("otp_6442_resend_reply1_mg_verify_notify_request -> unknown"
10916	      "~n   Else:   ~p"
10917	      "~n   TermId: ~p"
10918	      "~n", [Else, TermId]),
10919    ED       = otp_6442_resend_reply1_err_desc(Else),
10920    ErrReply = {discard_ack, ED},
10921    {error, Else, ErrReply}.
10922
10923otp_6442_resend_reply1_mg_notify_reply_ar(Cid, TermId) ->
10924    NR = cre_notifyReply([TermId]),
10925    CR = cre_cmdReply(NR),
10926    cre_actionReply(Cid, [CR]).
10927
10928-ifndef(megaco_hipe_special).
10929otp_6442_resend_reply1_mg_verify_ack_fun() ->
10930    fun(Ack) ->
10931	    otp_6442_resend_reply1_mg_verify_ack(Ack)
10932    end.
10933-endif.
10934
10935otp_6442_resend_reply1_mg_verify_ack(
10936  {handle_trans_ack, CH, ?VERSION, ok, otp_6442_resend_reply1}) ->
10937    io:format("otp_6442_resend_reply1_verify_ack -> ok"
10938              "~n   CH: ~p"
10939              "~n", [CH]),
10940    {ok, CH, ok};
10941otp_6442_resend_reply1_mg_verify_ack(Else) ->
10942    io:format("otp_6442_resend_reply1_verify_ack -> unknown"
10943              "~n   Else: ~p~n", [Else]),
10944    {error, Else, ok}.
10945
10946
10947otp_6442_resend_reply1_mg_service_change_request_ar(_Mid, Cid) ->
10948    Prof  = cre_serviceChangeProf("resgw", 1),
10949    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
10950    Root  = #megaco_term_id{id = ["root"]},
10951    SCR   = cre_serviceChangeReq([Root], SCP),
10952    CMD   = cre_command(SCR),
10953    CR    = cre_cmdReq(CMD),
10954    cre_actionReq(Cid, [CR]).
10955
10956otp_6442_resend_reply1_err_desc(T) ->
10957    EC = ?megaco_internal_gateway_error,
10958    ET = lists:flatten(io_lib:format("~w",[T])),
10959    #'ErrorDescriptor'{errorCode = EC, errorText = ET}.
10960
10961
10962
10963%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10964
10965otp_6442_resend_reply2(suite) ->
10966    [];
10967otp_6442_resend_reply2(Config) when is_list(Config) ->
10968    Factor = ?config(megaco_factor, Config),
10969    Pre = fun() ->
10970                  MgNode = make_node_name(mg),
10971                  d("start (MG) node: ~p", [MgNode]),
10972                  Nodes = [MgNode],
10973                  ok = ?START_NODES(Nodes, true),
10974                  Nodes
10975          end,
10976    Case = fun(Nodes) -> do_otp_6442_resend_reply2(Nodes, Factor) end,
10977    Post = fun(Nodes) ->
10978                   d("stop nodes"),
10979                   ?STOP_NODES(lists:reverse(Nodes))
10980           end,
10981    try_tc(otp6442rrep2, Pre, Case, Post).
10982
10983do_otp_6442_resend_reply2([MgNode], Factor) ->
10984    d("[MG] start the simulator "),
10985    {ok, Mg} = megaco_test_megaco_generator:start_link("MG", MgNode),
10986
10987    d("[MG] create the event sequence"),
10988    Mid     = {deviceName,"mg"},
10989    MgcMid  = {deviceName,"mgc"},
10990    TermId  = #megaco_term_id{id = ["00000000","00000000","01101101"]},
10991    MgEvSeq = otp_6442_resend_reply2_mg_event_sequence(Mid, TermId),
10992
10993    i("wait some time before starting the MG simulation"),
10994    sleep(1000),
10995
10996    d("[MG] start the simulation"),
10997    {ok, MgId} = megaco_test_megaco_generator:exec(Mg, MgEvSeq),
10998
10999    i("await the transport module service change send_message event"),
11000    Pid = otp_6442_expect(fun otp_6442_rsrp2_verify_scr_msg/1, Factor * 5000),
11001
11002    i("wait some before issuing the service change reply"),
11003    sleep(500),
11004
11005    i("simulate MGC sending the service change reply"),
11006    ServiceChangeReply = otp_6442_mgc_service_change_reply_msg(MgcMid, 1, 1),
11007    megaco_test_generic_transport:incomming_message(Pid, ServiceChangeReply),
11008
11009
11010    i("wait some before issuing the notify request"),
11011    sleep(500),
11012
11013    i("simulate MGC sending the notify request"),
11014    NotifyRequest = otp_6442_mgc_notify_request_msg(MgcMid, TermId, 2, 1),
11015    megaco_test_generic_transport:incomming_message(Pid, NotifyRequest),
11016
11017    i("await the transport module notify-reply send_message event from MG: ignore"),
11018    otp_6442_expect(otp_6442_rsrp2_verify_first_nr_msg_fun(), Factor * 5000),
11019
11020    i("await the transport module notify-reply resend_message event from MG: ack"),
11021    {TransId, _, _} =
11022	otp_6442_expect(otp_6442_rsrp2_verify_second_nr_msg_fun(), 10000),
11023
11024    i("wait some before issuing the ack"),
11025    sleep(500),
11026
11027    i("simulate MGC sending the ack"),
11028    Ack = otp_6442_mgc_ack_msg(MgcMid, TransId),
11029    megaco_test_generic_transport:incomming_message(Pid, Ack),
11030
11031
11032    d("await the generator reply"),
11033    await_completion([MgId]),
11034
11035    %% Tell Mg to stop
11036    i("[MG] stop generator"),
11037    megaco_test_megaco_generator:stop(Mg),
11038
11039    i("done", []),
11040    ok.
11041
11042
11043otp_6442_rsrp2_verify_scr_msg(
11044  {transport_event, {send_message, _SH, {message, Msg}}, Pid})
11045  when is_record(Msg, 'MegacoMessage') ->
11046    d("received expected service change request message: "
11047      "~n   Msg: ~p", [Msg]),
11048    Reply = ok,
11049    Pid ! {transport_reply, Reply, self()},
11050    {ok, Pid};
11051otp_6442_rsrp2_verify_scr_msg(Msg) ->
11052    {error, {invalid_message, Msg}}.
11053
11054otp_6442_rsrp2_verify_first_nr_msg_fun() ->
11055    fun(E) ->
11056	    otp_6442_rsrp2_verify_first_nr_msg(E)
11057    end.
11058
11059otp_6442_rsrp2_verify_first_nr_msg(
11060  {transport_event, {send_message, _SH, {message, Msg}}, Pid})
11061  when is_record(Msg, 'MegacoMessage') ->
11062    d("received expected first notify reply message: "
11063      "~n   Msg: ~p", [Msg]),
11064    Reply = ok,
11065    Pid ! {transport_reply, Reply, self()},
11066    {ok, ok};
11067otp_6442_rsrp2_verify_first_nr_msg(Msg) ->
11068    {error, {invalid_message, Msg}}.
11069
11070otp_6442_rsrp2_verify_second_nr_msg_fun() ->
11071    fun(E) ->
11072	    otp_6442_rsrp2_verify_second_nr_msg(E)
11073    end.
11074
11075otp_6442_rsrp2_verify_second_nr_msg(
11076  {transport_event, {resend_message, _SH, {message, Msg}}, Pid})
11077  when is_record(Msg, 'MegacoMessage') ->
11078    d("received expected second notify reply message: "
11079      "~n   Msg: ~p", [Msg]),
11080    Reply = ok,
11081    Pid ! {transport_reply, Reply, self()},
11082    #'MegacoMessage'{mess = Mess} = Msg,
11083    #'Message'{mId         = _Mid,
11084	       messageBody = Body} = Mess,
11085    {transactions, Transactions} = Body,
11086    [Transaction] = Transactions,
11087    {transactionReply, TransRep} = Transaction,
11088    #'TransactionReply'{transactionId     = TransId,
11089			immAckRequired    = 'NULL',
11090			transactionResult = TransRes} = TransRep,
11091    {actionReplies, ActReps} = TransRes,
11092    [ActRep] = ActReps,
11093    #'ActionReply'{contextId       = Cid,
11094		   errorDescriptor = asn1_NOVALUE,
11095		   contextReply    = asn1_NOVALUE,
11096		   commandReply    = CmdReps} = ActRep,
11097    [CmdRep] = CmdReps,
11098    {notifyReply, NR} = CmdRep,
11099    #'NotifyReply'{terminationID = TermId} = NR,
11100    {ok, {TransId, Cid, TermId}};
11101otp_6442_rsrp2_verify_second_nr_msg(Msg) ->
11102    d("received expected bad second notify reply message: "
11103      "~n   Msg: ~p", [Msg]),
11104    {error, {invalid_message, Msg}}.
11105
11106
11107
11108%%
11109%% MG generator stuff
11110%%
11111-ifdef(megaco_hipe_special).
11112-define(otp_6442_resend_reply2_mg_verify_handle_connect_fun(),
11113	{?MODULE, otp_6442_resend_reply2_mg_verify_handle_connect, []}).
11114-define(otp_6442_resend_reply2_mg_verify_service_change_rep_fun(),
11115	{?MODULE, otp_6442_resend_reply2_mg_verify_service_change_rep, []}).
11116-define(otp_6442_resend_reply2_mg_verify_notify_req_fun(TermId),
11117	{?MODULE, otp_6442_resend_reply2_mg_verify_notify_req, [TermId]}).
11118-define(otp_6442_resend_reply2_mg_verify_ack_fun(),
11119	{?MODULE, otp_6442_resend_reply2_mg_verify_ack, []}).
11120-else.
11121-define(otp_6442_resend_reply2_mg_verify_handle_connect_fun(),
11122	otp_6442_resend_reply2_mg_verify_handle_connect_fun()).
11123-define(otp_6442_resend_reply2_mg_verify_service_change_rep_fun(),
11124	otp_6442_resend_reply2_mg_verify_service_change_rep_fun()).
11125-define(otp_6442_resend_reply2_mg_verify_notify_req_fun(TermId),
11126	otp_6442_resend_reply2_mg_verify_notify_req_fun(TermId)).
11127-define(otp_6442_resend_reply2_mg_verify_ack_fun(),
11128	otp_6442_resend_reply2_mg_verify_ack_fun()).
11129-endif.
11130
11131otp_6442_resend_reply2_mg_event_sequence(Mid, TermId) ->
11132    RI = [
11133          {port,             self()}, % This is just a trick to get my pid to the transport module
11134          {encoding_module,  megaco_pretty_text_encoder},
11135          {encoding_config,  []},
11136          {transport_module, megaco_test_generic_transport}
11137         ],
11138    ServiceChangeReq =
11139	otp_6442_resend_reply2_mg_service_change_request_ar(Mid, 1),
11140    RepTmr = #megaco_incr_timer{wait_for    = 2000,
11141                                factor      = 1,
11142                                max_retries = 1},
11143    ConnectVerify =
11144	?otp_6442_resend_reply2_mg_verify_handle_connect_fun(),
11145    ServiceChangeReplyVerify =
11146	?otp_6442_resend_reply2_mg_verify_service_change_rep_fun(),
11147    NotifyReqVerify =
11148	?otp_6442_resend_reply2_mg_verify_notify_req_fun(TermId),
11149    AckVerify =
11150	?otp_6442_resend_reply2_mg_verify_ack_fun(),
11151%%     ConnectVerify =
11152%% 	otp_6442_resend_reply2_mg_verify_handle_connect_fun(),
11153%%     ServiceChangeReplyVerify =
11154%% 	otp_6442_resend_reply2_mg_verify_service_change_reply_fun(),
11155%%     NotifyReqVerify =
11156%% 	otp_6442_resend_reply2_mg_verify_notify_request_fun(TermId),
11157%%     AckVerify =
11158%% 	otp_6442_resend_reply2_mg_verify_ack_fun(),
11159    EvSeq = [
11160             {debug, false},
11161             megaco_start,
11162             {megaco_start_user, Mid, RI, []},
11163	     {megaco_update_user_info, resend_indication, true},
11164	     {megaco_update_user_info, reply_timer,       RepTmr},
11165             start_transport,
11166             {megaco_trace, disable},
11167             {megaco_system_info, users},
11168             {megaco_system_info, connections},
11169             connect,
11170             {megaco_callback, handle_connect, ConnectVerify},
11171             megaco_connect,
11172             {megaco_cast,     [ServiceChangeReq], []},
11173             {megaco_callback, handle_connect,     ConnectVerify},
11174             {megaco_callback, handle_trans_reply, ServiceChangeReplyVerify},
11175             {sleep, 1000},
11176
11177             {megaco_callback, handle_trans_request, NotifyReqVerify},
11178             {megaco_callback, handle_trans_ack,     AckVerify},
11179
11180             {sleep, 1000},
11181             megaco_stop_user,
11182             megaco_stop,
11183             {sleep, 1000}
11184            ],
11185    EvSeq.
11186
11187
11188-ifndef(megaco_hipe_special).
11189otp_6442_resend_reply2_mg_verify_handle_connect_fun() ->
11190    fun(Ev) ->
11191	    otp_6442_resend_reply2_mg_verify_handle_connect(Ev)
11192    end.
11193-endif.
11194
11195otp_6442_resend_reply2_mg_verify_handle_connect(
11196  {handle_connect, CH, ?VERSION}) ->
11197    io:format("otp_6442_resend_reply2_mg_verify_handle_connect -> ok"
11198	      "~n   CH: ~p~n", [CH]),
11199    {ok, CH, ok};
11200otp_6442_resend_reply2_mg_verify_handle_connect(Else) ->
11201    io:format("otp_6442_resend_reply2_mg_verify_handle_connect -> unknown"
11202	      "~n   Else: ~p~n", [Else]),
11203    {error, Else, ok}.
11204
11205
11206-ifndef(megaco_hipe_special).
11207otp_6442_resend_reply2_mg_verify_service_change_rep_fun() ->
11208    fun(Rep) ->
11209	    otp_6442_resend_reply2_mg_verify_service_change_rep(Rep)
11210    end.
11211-endif.
11212
11213otp_6442_resend_reply2_mg_verify_service_change_rep(
11214  {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _}) ->
11215    (catch otp_6442_resend_reply2_mg_do_verify_service_change_rep(AR));
11216otp_6442_resend_reply2_mg_verify_service_change_rep(Crap) ->
11217    {error, Crap, ok}.
11218
11219otp_6442_resend_reply2_mg_do_verify_service_change_rep(AR) ->
11220    io:format("otp_6442_resend_reply2_mg_verify_service_change_rep -> ok"
11221	      "~n   AR: ~p~n", [AR]),
11222    CR =
11223	case AR of
11224	    #'ActionReply'{commandReply = [CmdRep]} ->
11225		CmdRep;
11226	    _ ->
11227		Reason1 = {invalid_action_reply, AR},
11228		throw({error, Reason1, ok})
11229	end,
11230    SCR =
11231	case CR of
11232	    {serviceChangeReply, ServChRep} ->
11233		ServChRep;
11234	    _ ->
11235		Reason2 = {invalid_command_reply, CR},
11236		throw({error, Reason2, ok})
11237	end,
11238    {Tid, SCRes} =
11239	case SCR of
11240	    #'ServiceChangeReply'{terminationID       = [TermID],
11241				  serviceChangeResult = Res} ->
11242		{TermID, Res};
11243	    _ ->
11244		Reason3 = {invalid_service_change_reply, SCR},
11245		throw({error, Reason3, ok})
11246	end,
11247    case Tid of
11248	#megaco_term_id{contains_wildcards = false, id = ["root"]} ->
11249	    ok;
11250	_ ->
11251	    Reason4 = {invalid_termination_id, Tid},
11252	    throw({error, Reason4, ok})
11253    end,
11254    SCRParm =
11255	case SCRes of
11256	    {serviceChangeResParms, ServChResParms} ->
11257		ServChResParms;
11258	    _ ->
11259		Reason5 = {invalid_serviceChangeResult, SCRes},
11260		throw({error, Reason5, ok})
11261	end,
11262    case SCRParm of
11263	#'ServiceChangeResParm'{serviceChangeMgcId = _RemoteMid} ->
11264	    {ok, AR, ok};
11265	_ ->
11266	    Reason6 = {invalid_service_change_result, SCRParm},
11267	    {error, Reason6, ok}
11268    end.
11269
11270-ifndef(megaco_hipe_special).
11271otp_6442_resend_reply2_mg_verify_notify_req_fun(TermId) ->
11272    fun(Req) ->
11273	    otp_6442_resend_reply2_mg_verify_notify_req(Req, TermId)
11274    end.
11275-endif.
11276
11277otp_6442_resend_reply2_mg_verify_notify_req(
11278  {handle_trans_request, _, ?VERSION, [AR]}, TermId) ->
11279    io:format("otp_6442_resend_reply2_mg_verify_notify_req -> ok"
11280	      "~n   AR: ~p~n", [AR]),
11281    case AR of
11282	#'ActionRequest'{contextId = 1 = Cid,
11283			 commandRequests = [CR]} ->
11284	    #'CommandRequest'{command = Cmd} = CR,
11285	    {notifyReq, NR} = Cmd,
11286	    #'NotifyRequest'{terminationID            = [TermId],
11287			     observedEventsDescriptor = OED,
11288			     errorDescriptor          = asn1_NOVALUE} = NR,
11289	    #'ObservedEventsDescriptor'{observedEventLst = [OE]} = OED,
11290	    #'ObservedEvent'{eventName = "al/of"} = OE,
11291	    HandleAck = {handle_ack, otp_6442_resend_reply2},
11292	    Reply = {HandleAck,
11293		     [otp_6442_resend_reply2_mg_notify_reply_ar(Cid, TermId)]},
11294	    {ok, AR, Reply};
11295	_ ->
11296	    ED = otp_6442_resend_reply2_err_desc(AR),
11297	    ErrReply = {discard_ack, ED},
11298	    {error, AR, ErrReply}
11299    end;
11300otp_6442_resend_reply2_mg_verify_notify_req(Else, TermId) ->
11301    io:format("otp_6442_resend_reply2_mg_verify_notify_req -> unknown"
11302	      "~n   Else:   ~p"
11303	      "~n   TermId: ~p"
11304	      "~n", [Else, TermId]),
11305    ED       = otp_6442_resend_reply2_err_desc(Else),
11306    ErrReply = {discard_ack, ED},
11307    {error, Else, ErrReply}.
11308
11309otp_6442_resend_reply2_mg_notify_reply_ar(Cid, TermId) ->
11310    NR = cre_notifyReply([TermId]),
11311    CR = cre_cmdReply(NR),
11312    cre_actionReply(Cid, [CR]).
11313
11314
11315-ifndef(megaco_hipe_special).
11316otp_6442_resend_reply2_mg_verify_ack_fun() ->
11317    fun(Ack) ->
11318	    otp_6442_resend_reply2_mg_verify_ack(Ack)
11319    end.
11320-endif.
11321
11322otp_6442_resend_reply2_mg_verify_ack(
11323  {handle_trans_ack, CH, ?VERSION, ok, otp_6442_resend_reply2}) ->
11324    io:format("otp_6442_resend_reply2_verify_ack -> ok"
11325              "~n   CH: ~p"
11326              "~n", [CH]),
11327    {ok, CH, ok};
11328otp_6442_resend_reply2_mg_verify_ack(Else) ->
11329    io:format("otp_6442_resend_reply2_verify_ack -> unknown"
11330              "~n   Else: ~p~n", [Else]),
11331    {error, Else, ok}.
11332
11333
11334otp_6442_resend_reply2_mg_service_change_request_ar(_Mid, Cid) ->
11335    Prof  = cre_serviceChangeProf("resgw", 1),
11336    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
11337    Root  = #megaco_term_id{id = ["root"]},
11338    SCR   = cre_serviceChangeReq([Root], SCP),
11339    CMD   = cre_command(SCR),
11340    CR    = cre_cmdReq(CMD),
11341    cre_actionReq(Cid, [CR]).
11342
11343
11344otp_6442_resend_reply2_err_desc(T) ->
11345    EC = ?megaco_internal_gateway_error,
11346    ET = lists:flatten(io_lib:format("~w",[T])),
11347    #'ErrorDescriptor'{errorCode = EC, errorText = ET}.
11348
11349
11350
11351%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11352
11353otp_6865_request_and_reply_plain_extra1(suite) ->
11354    [];
11355otp_6865_request_and_reply_plain_extra1(Config) when is_list(Config) ->
11356    ?ACQUIRE_NODES(1, Config),
11357
11358    put(sname,     "TEST"),
11359    put(verbosity, debug),
11360    put(tc,        otp6865e1),
11361    i("starting"),
11362
11363    d("start test case controller",[]),
11364    ok = megaco_tc_controller:start_link(),
11365
11366    %% Instruct the transport module to fail all send_message
11367    d("instruct transport module to provide extra info: ",[]),
11368    ExtraInfo = otp_6865_extra_info,
11369    ok = megaco_tc_controller:insert(extra_transport_info, ExtraInfo),
11370
11371    d("start proxy",[]),
11372    ?USER_MOD:start_proxy(),
11373
11374    PrelMid = preliminary_mid,
11375    MgMid   = ipv4_mid(4711),
11376    MgcMid  = ipv4_mid(),
11377    UserMod = ?USER_MOD,
11378    d("start megaco app",[]),
11379    ?VERIFY(ok, application:start(megaco)),
11380    UserConfig = [{user_mod, UserMod}, {send_mod, UserMod},
11381		  {request_timer, infinity}, {reply_timer, infinity}],
11382    d("start (MG) user ~p",[MgMid]),
11383    ?VERIFY(ok,	megaco:start_user(MgMid, UserConfig)),
11384
11385    d("start (MGC) user ~p",[MgcMid]),
11386    ?VERIFY(ok,	megaco:start_user(MgcMid, UserConfig)),
11387
11388    d("get receive info for ~p",[MgMid]),
11389    MgRH = user_info(MgMid, receive_handle),
11390    d("get receive info for ~p",[MgcMid]),
11391    MgcRH = user_info(MgcMid, receive_handle),
11392    d("start transport",[]),
11393    {ok, MgPid, MgSH} =
11394	?VERIFY({ok, _, _}, UserMod:start_transport(MgRH, MgcRH)),
11395    PrelMgCH = #megaco_conn_handle{local_mid = MgMid,
11396				   remote_mid = preliminary_mid},
11397    MgCH  = #megaco_conn_handle{local_mid = MgMid,
11398				remote_mid = MgcMid},
11399    MgcCH = #megaco_conn_handle{local_mid = MgcMid,
11400				remote_mid = MgMid},
11401    d("(MG) try connect to MGC",[]),
11402    ?SEND(megaco:connect(MgRH, PrelMid, MgSH, MgPid)), % Mg prel
11403    d("await connect from MG",[]),
11404    ?USER({connect, PrelMgCH, _V, []}, ok),
11405    ?RECEIVE([{res, _, {ok, PrelMgCH}}]),
11406
11407    d("(MG) send service change request",[]),
11408    Req = service_change_request(),
11409    ?SEND(megaco:call(PrelMgCH, [Req], [])),
11410
11411    d("(MGC) send service change reply",[]),
11412    ?USER({connect, MgcCH, _V, [ExtraInfo]}, ok), % Mgc auto
11413    Rep = service_change_reply(MgcMid),
11414    ?USER({request, MgcCH, _V, [[Req], ExtraInfo]}, {discard_ack, [Rep]}),
11415    ?USER({connect, MgCH, _V, [ExtraInfo]}, ok), % Mg confirm
11416    ?RECEIVE([{res, _, {1, {ok, [Rep], ExtraInfo}}}]),
11417
11418    d("get (system info) connections",[]),
11419    connections([MgCH, MgcCH]),
11420    d("get (~p) connections",[MgMid]),
11421    ?VERIFY([MgCH], megaco:user_info(MgMid, connections)),
11422    d("get (~p) connections",[MgcMid]),
11423    ?VERIFY([MgcCH], megaco:user_info(MgcMid, connections)),
11424
11425    Reason = shutdown,
11426    d("(MG) disconnect",[]),
11427    ?SEND(megaco:disconnect(MgCH, Reason)),
11428    ?USER({disconnect, MgCH, _V, [{user_disconnect, Reason}]}, ok),
11429    ?RECEIVE([{res, _, ok}]),
11430    ?VERIFY(ok,	megaco:stop_user(MgMid)),
11431
11432    d("(MGC) disconnect",[]),
11433    ?SEND(megaco:disconnect(MgcCH, Reason)),
11434    ?USER({disconnect, MgcCH, _V, [{user_disconnect, Reason}]}, ok),
11435    ?RECEIVE([{res, _, ok}]),
11436    ?VERIFY(ok,	megaco:stop_user(MgcMid)),
11437
11438    d("stop megaco app",[]),
11439    ?VERIFY(ok, application:stop(megaco)),
11440    ?RECEIVE([]),
11441
11442    d("stop test case controller",[]),
11443    ok = megaco_tc_controller:stop(),
11444
11445    d("done",[]),
11446    ok.
11447
11448
11449%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11450
11451otp_6865_request_and_reply_plain_extra2(suite) ->
11452    [];
11453otp_6865_request_and_reply_plain_extra2(doc) ->
11454    [];
11455otp_6865_request_and_reply_plain_extra2(Config) when is_list(Config) ->
11456    put(verbosity, ?TEST_VERBOSITY),
11457    put(sname,     "TEST"),
11458    put(tc,        otp6865e2),
11459    i("starting"),
11460
11461    d("start tc controller"),
11462    ok = megaco_tc_controller:start_link(),
11463
11464    %% Instruct the transport module to fail all send_message
11465    d("instruct transport module to provide extra info: ", []),
11466    ExtraInfo = otp6865e2_extra_info,
11467    ok = megaco_tc_controller:insert(extra_transport_info, ExtraInfo),
11468
11469    MgcNode = make_node_name(mgc),
11470    MgNode  = make_node_name(mg),
11471    d("start nodes: "
11472      "~n   MgcNode: ~p"
11473      "~n   MgNode:  ~p",
11474      [MgcNode, MgNode]),
11475    Nodes = [MgcNode, MgNode],
11476    ok = ?START_NODES(Nodes, true),
11477
11478
11479    d("[MGC] start the simulator "),
11480    {ok, Mgc} = megaco_test_megaco_generator:start_link("MGC", MgcNode),
11481
11482    d("[MGC] create the event sequence"),
11483    MgcEvSeq = otp6865e2_mgc_event_sequence(ExtraInfo, text, tcp),
11484
11485    i("wait some time before starting the MGC simulation"),
11486    sleep(1000),
11487
11488    d("[MGC] start the simulation"),
11489    {ok, MgcId} = megaco_test_megaco_generator:exec(Mgc, MgcEvSeq),
11490
11491    i("await MGC ready announcement"),
11492    receive
11493        announce_mgc ->
11494            i("received MGC ready announcement"),
11495            ok
11496    end,
11497
11498    d("[MG] start the simulator (generator)"),
11499    {ok, Mg} = megaco_test_tcp_generator:start_link("MG", MgNode),
11500
11501    d("[MG] create the event sequence"),
11502    MgEvSeq = otp6865e2_mg_event_sequence(text, tcp),
11503
11504    i("wait some time before starting the MG simulation"),
11505    sleep(1000),
11506
11507    d("[MG] start the simulation"),
11508    {ok, MgId} = megaco_test_tcp_generator:exec(Mg, MgEvSeq),
11509
11510    d("await the generator reply(s)"),
11511    await_completion([MgcId, MgId], 60000),
11512
11513    %% Tell Mgc to stop
11514    i("[MGC] stop generator"),
11515    megaco_test_megaco_generator:stop(Mgc),
11516
11517    %% Tell Mg to stop
11518    i("[MG] stop generator"),
11519    megaco_test_tcp_generator:stop(Mg),
11520
11521    i("stop tc controller"),
11522    ok = megaco_tc_controller:stop(),
11523
11524    %% Cleanup
11525    d("stop nodes"),
11526    ?STOP_NODES(lists:reverse(Nodes)),
11527
11528    i("done", []),
11529    ok.
11530
11531
11532%%
11533%% MGC generator stuff
11534%%
11535-ifdef(megaco_hipe_special).
11536-define(otp6865e2_mgc_verify_handle_connect_fun(ExtraInfo),
11537        {?MODULE, otp6865e2_mgc_verify_handle_connect, [ExtraInfo]}).
11538-define(otp6865e2_mgc_verify_service_change_req_fun(Mid, ExtraInfo),
11539        {?MODULE, otp6865e2_mgc_verify_service_change_req, [Mid, ExtraInfo]}).
11540-define(otp6865e2_mgc_verify_notify_req_fun(Cid, ExtraInfo, RequireAck),
11541        {?MODULE, otp6865e2_mgc_verify_notify_req, [Cid, ExtraInfo, RequireAck]}).
11542-define(otp6865e2_mgc_verify_reply_ack_fun(ExtraInfo),
11543	{?MODULE, otp6865e2_mgc_verify_reply_ack, [ExtraInfo]}).
11544-define(otp6865e2_mgc_verify_notify_reply_fun(ExtraInfo),
11545	{?MODULE, otp6865e2_mgc_verify_notify_reply, [ExtraInfo]}).
11546-define(otp6865e2_mgc_verify_handle_disconnect_fun(),
11547        {?MODULE, otp6865e2_mgc_verify_handle_disconnect, []}).
11548-else.
11549-define(otp6865e2_mgc_verify_handle_connect_fun(ExtraInfo),
11550        otp6865e2_mgc_verify_handle_connect(ExtraInfo)).
11551-define(otp6865e2_mgc_verify_service_change_req_fun(Mid, ExtraInfo),
11552        otp6865e2_mgc_verify_service_change_req_fun(Mid, ExtraInfo)).
11553-define(otp6865e2_mgc_verify_notify_req_fun(Cid, ExtraInfo, RequireAck),
11554	otp6865e2_mgc_verify_notify_req_fun(Cid, ExtraInfo, RequireAck)).
11555-define(otp6865e2_mgc_verify_reply_ack_fun(ExtraInfo),
11556	otp6865e2_mgc_verify_reply_ack_fun(ExtraInfo)).
11557-define(otp6865e2_mgc_verify_notify_reply_fun(ExtraInfo),
11558	otp6865e2_mgc_verify_notify_reply_fun(ExtraInfo)).
11559-define(otp6865e2_mgc_verify_handle_disconnect_fun(),
11560	fun otp6865e2_mgc_verify_handle_disconnect/1).
11561-endif.
11562
11563otp6865e2_mgc_event_sequence(ExtraInfo, text, tcp) ->
11564    Mid  = {deviceName, "ctrl"},
11565    CTRL = self(),
11566    RI   = [
11567            {port,             2944},
11568            {encoding_module,  megaco_pretty_text_encoder},
11569            {encoding_config,  []},
11570            {transport_module, megaco_tcp}
11571           ],
11572    ConnectVerify          =
11573	?otp6865e2_mgc_verify_handle_connect_fun(ExtraInfo),
11574    ServiceChangeReqVerify =
11575	?otp6865e2_mgc_verify_service_change_req_fun(Mid, ExtraInfo),
11576    NotifyReqVerify1       =
11577	?otp6865e2_mgc_verify_notify_req_fun(1, ExtraInfo, false),
11578    NotifyReqVerify2       =
11579	?otp6865e2_mgc_verify_notify_req_fun(2, ExtraInfo, true),
11580    AckVerify              = ?otp6865e2_mgc_verify_reply_ack_fun(ExtraInfo),
11581    Tid = #megaco_term_id{id = ["00000000","00000000","01101101"]},
11582    NotifyReq = [otp6865e2_mgc_notify_request_ar(1, Tid, 1)],
11583    NotifyReplyVerify = ?otp6865e2_mgc_verify_notify_reply_fun(ExtraInfo),
11584    DiscoVerify            =
11585	?otp6865e2_mgc_verify_handle_disconnect_fun(),
11586    EvSeq = [
11587	     {debug, true},
11588	     {megaco_trace, disable},
11589	     megaco_start,
11590	     {megaco_start_user, Mid, RI, []},
11591	     start_transport,
11592	     listen,
11593
11594             %% ANNOUNCE READY
11595             {trigger, fun() -> CTRL ! announce_mgc end},
11596
11597	     {megaco_callback, handle_connect,       ConnectVerify},
11598	     {megaco_callback, handle_trans_request, ServiceChangeReqVerify},
11599	     {megaco_callback, handle_trans_request, NotifyReqVerify1},
11600	     {megaco_callback, handle_trans_request, NotifyReqVerify2},
11601	     {megaco_callback, handle_trans_ack,     AckVerify},
11602	     {megaco_cast,     NotifyReq, []},
11603	     {megaco_callback, handle_trans_reply,   NotifyReplyVerify},
11604	     {megaco_callback, handle_disconnect,    DiscoVerify},
11605	     {sleep, 1000},
11606	     megaco_stop_user,
11607	     megaco_stop
11608	    ],
11609    EvSeq.
11610
11611
11612-ifndef(megaco_hipe_special).
11613otp6865e2_mgc_verify_handle_connect(ExtraInfo) ->
11614    fun(Req) ->
11615	    otp6865e2_mgc_verify_handle_connect(Req, ExtraInfo)
11616    end.
11617-endif.
11618
11619otp6865e2_mgc_verify_handle_connect({handle_connect, CH, ?VERSION, ExtraInfo},
11620				    ExtraInfo) ->
11621    io:format("otp6865e2_mgc_verify_handle_connect -> ok"
11622	      "~n   CH: ~p~n", [CH]),
11623    {ok, CH, ok};
11624otp6865e2_mgc_verify_handle_connect(Else, ExtraInfo) ->
11625    io:format("otp6865e2_mgc_verify_handle_connect -> unknown"
11626	      "~n   Else:      ~p"
11627	      "~n   ExtraInfo: ~p"
11628	      "~n", [Else, ExtraInfo]),
11629    {error, {Else, ExtraInfo}, ok}.
11630
11631-ifndef(megaco_hipe_special).
11632otp6865e2_mgc_verify_service_change_req_fun(Mid, ExtraInfo) ->
11633    fun(Req) ->
11634	    otp6865e2_mgc_verify_service_change_req(Req, Mid, ExtraInfo)
11635    end.
11636-endif.
11637
11638otp6865e2_mgc_verify_service_change_req(
11639  {handle_trans_request, _, ?VERSION, [AR], ExtraInfo}, Mid, ExtraInfo) ->
11640    (catch otp6865e2_mgc_do_verify_service_change_req(AR, Mid));
11641otp6865e2_mgc_verify_service_change_req(Crap, _Mid, ExtraInfo) ->
11642    ED = cre_ErrDesc({Crap, ExtraInfo}),
11643    ErrReply = {discard_ack, ED},
11644    {error, {Crap, ExtraInfo}, ErrReply}.
11645
11646otp6865e2_mgc_do_verify_service_change_req(AR, Mid) ->
11647    io:format("otp6865e2_mgc_verify_service_change_req -> ok"
11648	      "~n   AR:  ~p"
11649	      "~n   Mid: ~p"
11650	      "~n", [AR, Mid]),
11651    CR =
11652	case AR of
11653	    #'ActionRequest'{commandRequests = [CmdReq]} ->
11654		CmdReq;
11655	    _ ->
11656                Err1      = {invalid_action_request, AR},
11657                ED1       = cre_ErrDesc(AR),
11658                ErrReply1 = {discard_ack, ED1},
11659                throw({error, Err1, ErrReply1})
11660	end,
11661    Cmd =
11662        case CR of
11663            #'CommandRequest'{command = Command} ->
11664                Command;
11665            _ ->
11666                Err2      = {invalid_command_request, CR},
11667                ED2       = cre_ErrDesc(CR),
11668                ErrReply2 = {discard_ack, ED2},
11669                throw({error, Err2, ErrReply2})
11670        end,
11671    {Tid, Parms} =
11672        case Cmd of
11673            {serviceChangeReq,
11674             #'ServiceChangeRequest'{terminationID = [TermID],
11675                                     serviceChangeParms = ServChParms}} ->
11676                {TermID, ServChParms};
11677            _ ->
11678                Err3      = {invalid_command, Cmd},
11679                ED3       = cre_ErrDesc(Cmd),
11680                ErrReply3 = {discard_ack, ED3},
11681                throw({error, Err3, ErrReply3})
11682        end,
11683    case Tid of
11684        #megaco_term_id{contains_wildcards = false, id = ["root"]} ->
11685            ok;
11686        _ ->
11687            Err4      = {invalid_termination_id, Tid},
11688            ED4       = cre_ErrDesc(Tid),
11689            ErrReply4 = {discard_ack, ED4},
11690            throw({error, Err4, ErrReply4})
11691    end,
11692    case Parms of
11693        #'ServiceChangeParm'{serviceChangeMethod = restart,
11694                             serviceChangeReason = [[$9,$0,$1|_]]} ->
11695            AckData = [otp6865e2_mgc_service_change_reply_ar(Mid, 1)],
11696            Reply   = {discard_ack, AckData},
11697            {ok, AR, Reply};
11698        _ ->
11699            Err5      = {invalid_SCP, Parms},
11700            ED5       = cre_ErrDesc(Parms),
11701            ErrReply5 = {discard_ack, ED5},
11702            {error, Err5, ErrReply5}
11703    end.
11704
11705-ifndef(megaco_hipe_special).
11706otp6865e2_mgc_verify_notify_req_fun(Cid, ExtraInfo, RequireAck) ->
11707    fun(Req) ->
11708	    otp6865e2_mgc_verify_notify_req(Req, Cid, ExtraInfo, RequireAck)
11709    end.
11710-endif.
11711
11712otp6865e2_mgc_verify_notify_req(
11713  {handle_trans_request, _, ?VERSION, [AR], ExtraInfo},
11714  Cid, ExtraInfo, RequireAck) ->
11715    (catch otp6865e2_mgc_do_verify_notify_req(AR, Cid, RequireAck));
11716otp6865e2_mgc_verify_notify_req(Crap, _Cid, ExtraInfo, _RequireAck) ->
11717    ED       = cre_ErrDesc({Crap, ExtraInfo}),
11718    ErrReply = {discard_ack, ED},
11719    {error, {Crap, ExtraInfo}, ErrReply}.
11720
11721otp6865e2_mgc_do_verify_notify_req(AR, Cid, RequireAck) ->
11722    io:format("otp6865e2_mgc_do_verify_notify_req -> entry with"
11723	      "~n   AR:         ~p"
11724	      "~n   Cid:        ~p"
11725	      "~n   RequireAck: ~p"
11726	      "~n", [AR, Cid, RequireAck]),
11727    {ContextID, CR} =
11728	case AR of
11729	    #'ActionRequest'{contextId       = CtxID,
11730			     commandRequests = [CmdReq]} when (CtxID == Cid) ->
11731		{CtxID, CmdReq};
11732	    _ ->
11733                Err1      = {invalid_action_request, AR},
11734                ED1       = cre_ErrDesc(AR),
11735                ErrReply1 = {discard_ack, ED1},
11736                throw({error, Err1, ErrReply1})
11737        end,
11738    Cmd =
11739	case CR of
11740	    #'CommandRequest'{command = Command} ->
11741		Command;
11742	    _ ->
11743                Err2      = {invalid_command_request, CR},
11744                ED2       = cre_ErrDesc(CR),
11745                ErrReply2 = {discard_ack, ED2},
11746                throw({error, Err2, ErrReply2})
11747        end,
11748    NR =
11749        case Cmd of
11750	    {notifyReq, NotifReq} ->
11751		NotifReq;
11752	    _ ->
11753                Err3      = {invalid_command, Cmd},
11754                ED3       = cre_ErrDesc(Cmd),
11755                ErrReply3 = {discard_ack, ED3},
11756                throw({error, Err3, ErrReply3})
11757        end,
11758    {Tid, OED} =
11759        case NR of
11760            #'NotifyRequest'{terminationID            = [TermID],
11761                             observedEventsDescriptor = ObsEvsDesc,
11762                             errorDescriptor          = asn1_NOVALUE} ->
11763                {TermID, ObsEvsDesc};
11764            _ ->
11765                Err4      = {invalid_NR, NR},
11766                ED4       = cre_ErrDesc(NR),
11767                ErrReply4 = {discard_ack, ED4},
11768                throw({error, Err4, ErrReply4})
11769        end,
11770    OE =
11771	case OED of
11772	    #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
11773		ObsEvLst;
11774            _ ->
11775                Err5      = {invalid_OED, OED},
11776                ED5       = cre_ErrDesc(NR),
11777                ErrReply5 = {discard_ack, ED5},
11778                throw({error, Err5, ErrReply5})
11779        end,
11780    case OE of
11781	#'ObservedEvent'{eventName = "al/of"} ->
11782            Replies = [otp6865e2_mgc_notify_reply_ar(ContextID, Tid)],
11783            Reply   =
11784		case RequireAck of
11785		    true ->
11786			{{handle_ack, otp6865e2}, Replies};
11787		    false ->
11788			{discard_ack, Replies}
11789		end,
11790            {ok, AR, Reply};
11791        _ ->
11792            Err6      = {invalid_OE, OE},
11793            ED6       = cre_ErrDesc(OE),
11794            ErrReply6 = {discard_ack, ED6},
11795            {error, Err6, ErrReply6}
11796    end.
11797
11798%% Ack verification
11799-ifndef(megaco_hipe_special).
11800otp6865e2_mgc_verify_reply_ack_fun(ExtraInfo) ->
11801    fun(M) ->
11802	    otp6865e2_mgc_verify_reply_ack(M, ExtraInfo)
11803    end.
11804-endif.
11805
11806otp6865e2_mgc_verify_reply_ack(
11807  {handle_trans_ack, _, ?VERSION, ok, otp6865e2, ExtraInfo}, ExtraInfo) ->
11808    io:format("otp6865e2_mgc_verify_reply_ack -> ok~n", []),
11809    {ok, ok, ok};
11810otp6865e2_mgc_verify_reply_ack(
11811  {handle_trans_ack, _, ?VERSION, AS, AD, ExtraInfo1} = Crap, ExtraInfo2) ->
11812    io:format("otp6865e2_mgc_verify_reply_ack -> incorrect ack-status:"
11813	      "~n   AS:         ~p"
11814	      "~n   AD:         ~p"
11815	      "~n   ExtraInfo1: ~p"
11816	      "~n   ExtraInfo2: ~p"
11817	      "~n", [AS, AD, ExtraInfo1, ExtraInfo2]),
11818    ED       = cre_ErrDesc({invalid_ack_status,
11819			    {AS, AD, ExtraInfo1, ExtraInfo2}}),
11820    ErrReply = {discard_ack, ED},
11821    {error, Crap, ErrReply};
11822otp6865e2_mgc_verify_reply_ack(Crap, ExtraInfo) ->
11823    io:format("otp6865e2_mgc_verify_reply_ack -> invalid ack:"
11824	      "~n   Crap:      ~p"
11825	      "~n   ExtraInfo: ~p"
11826	      "~n", [Crap, ExtraInfo]),
11827    ED       = cre_ErrDesc({Crap, ExtraInfo}),
11828    ErrReply = {discard_ack, ED},
11829    {error, Crap, ErrReply}.
11830
11831
11832%% Notify reply verification
11833-ifndef(megaco_hipe_special).
11834otp6865e2_mgc_verify_notify_reply_fun(ExtraInfo) ->
11835    fun(Rep) ->
11836	    otp6865e2_mgc_verify_notify_reply(Rep, ExtraInfo)
11837    end.
11838-endif.
11839
11840otp6865e2_mgc_verify_notify_reply(
11841  {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _, ExtraInfo}, ExtraInfo) ->
11842    io:format("otp6865e2_mgc_verify_notify_reply -> ok"
11843	      "~n   AR:        ~p"
11844	      "~n   ExtraInfo: ~p"
11845	      "~n", [AR, ExtraInfo]),
11846    {ok, AR, ok};
11847otp6865e2_mgc_verify_notify_reply(Else, ExtraInfo) ->
11848    io:format("otp6865e2_mgc_verify_notify_reply -> received unknown event"
11849	      "~n   Else:      ~p"
11850	      "~n   ExtraInfo: ~p"
11851	      "~n", [Else, ExtraInfo]),
11852    {error, {Else, ExtraInfo}, ok}.
11853
11854
11855%% Disconnect verification
11856otp6865e2_mgc_verify_handle_disconnect(
11857  {handle_disconnect, CH, ?VERSION, R}) ->
11858    io:format("otp6865e2_mgc_verify_handle_disconnect -> ok"
11859	      "~n   CH: ~p"
11860	      "~n   R:  ~p"
11861	      "~n", [CH, R]),
11862    {ok, CH, ok};
11863otp6865e2_mgc_verify_handle_disconnect(Else) ->
11864    io:format("otp6865e2_mgc_verify_handle_disconnect -> unknown"
11865	      "~n   Else: ~p~n", [Else]),
11866    {error, Else, ok}.
11867
11868
11869otp6865e2_mgc_service_change_reply_ar(Mid, Cid) ->
11870    SCRP  = cre_serviceChangeResParm(Mid),
11871    SCRes = cre_serviceChangeResult(SCRP),
11872    Root  = #megaco_term_id{id = ["root"]},
11873    SCR   = cre_serviceChangeReply([Root], SCRes),
11874    CR    = cre_cmdReply(SCR),
11875    cre_actionReply(Cid, [CR]).
11876
11877otp6865e2_mgc_notify_reply_ar(Cid, TermId) ->
11878    NR    = cre_notifyReply([TermId]),
11879    CR    = cre_cmdReply(NR),
11880    cre_actionReply(Cid, [CR]).
11881
11882otp6865e2_mgc_notify_request_ar(Rid, Tid, Cid) ->
11883    TT      = cre_timeNotation("19990729", "22000000"),
11884    Ev      = cre_obsEvent("al/of", TT),
11885    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
11886    NR      = cre_notifyReq([Tid], EvsDesc),
11887    CMD     = cre_command(NR),
11888    CR      = cre_cmdReq(CMD),
11889    cre_actionReq(Cid, [CR]).
11890
11891
11892%%
11893%% MG generator stuff
11894%%
11895-ifdef(megaco_hipe_special).
11896-define(otp6865e2_mg_decode_msg_fun(Mod, Conf),
11897	{?MODULE, decode_msg, [Mod, Conf]}).
11898-define(otp6865e2_mg_encode_msg_fun(Mod, Conf),
11899	{?MODULE, encode_msg, [Mod, Conf]}).
11900-define(otp6865e2_mg_verify_service_change_rep_msg_fun(),
11901	{?MODULE, otp6865e2_mg_verify_service_change_rep_msg, []}).
11902-define(otp6865e2_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId, AckRequired),
11903	{?MODULE, otp6865e2_mg_verify_notify_rep_msg, [TermId, TransId, ReqId, CtxId, AckRequired]}).
11904-define(otp6865e2_mg_verify_notify_req_msg_fun(),
11905	{?MODULE, otp6865e2_mg_verify_notify_req_msg, []}).
11906-else.
11907-define(otp6865e2_mg_decode_msg_fun(Mod, Conf),
11908	otp6865e2_mg_decode_msg_fun(Mod, Conf)).
11909-define(otp6865e2_mg_encode_msg_fun(Mod, Conf),
11910	otp6865e2_mg_encode_msg_fun(Mod, Conf)).
11911-define(otp6865e2_mg_verify_service_change_rep_msg_fun(),
11912	otp6865e2_mg_verify_service_change_rep_msg_fun()).
11913-define(otp6865e2_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId, AckRequired),
11914	otp6865e2_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId, AckRequired)).
11915-define(otp6865e2_mg_verify_notify_req_msg_fun(),
11916	otp6865e2_mg_verify_notify_req_msg_fun()).
11917-endif.
11918
11919otp6865e2_mg_event_sequence(text, tcp) ->
11920    DecodeFun = ?otp6865e2_mg_decode_msg_fun(megaco_pretty_text_encoder, []),
11921    EncodeFun = ?otp6865e2_mg_encode_msg_fun(megaco_pretty_text_encoder, []),
11922    Mid       = {deviceName,"mg"},
11923    ServiceChangeReq = otp6865e2_mg_service_change_request_msg(Mid, 1, 0),
11924    ScrVerifyFun = ?otp6865e2_mg_verify_service_change_rep_msg_fun(),
11925    TermId1 = #megaco_term_id{id = ["00000000","00000000","01101101"]},
11926    TermId2 = #megaco_term_id{id = ["00000000","00000000","10010010"]},
11927    NotifyReq1 =
11928	otp6865e2_mg_notify_request_msg(Mid, TermId1, 2, 1, 1),
11929    NrVerifyFun1 =
11930	?otp6865e2_mg_verify_notify_rep_msg_fun(TermId1, 2, 1, 1, false),
11931    NotifyReq2 =
11932	otp6865e2_mg_notify_request_msg(Mid, TermId2, 3, 2, 2),
11933    NrVerifyFun2 =
11934	?otp6865e2_mg_verify_notify_rep_msg_fun(TermId2, 3, 2, 2, true),
11935    TransAck = otp6865e2_mg_trans_ack_msg(Mid, 3),
11936    NotifyReqVerifyFun  = ?otp6865e2_mg_verify_notify_req_msg_fun(),
11937    NotifyReply = otp6865e2_mg_notify_reply_msg(Mid, 1, 0, TermId1),
11938    EvSeq = [{debug,  true},
11939             {decode, DecodeFun},
11940             {encode, EncodeFun},
11941             {connect, 2944},
11942
11943             {send, "service-change-request", ServiceChangeReq},
11944             {expect_receive, "service-change-reply", {ScrVerifyFun, 10000}},
11945
11946	     %% the original setting for reply timer is 2000
11947             {send, "notify request 1", NotifyReq1},
11948             {expect_receive, "notify-reply 1", {NrVerifyFun1, 2500}},
11949	     {sleep, 1000},
11950             {send, "notify request 2", NotifyReq2},
11951             {expect_receive, "notify-reply 2", {NrVerifyFun2, 2500}},
11952	     {sleep, 100},
11953             {send, "transacktion-ack", TransAck},
11954             {expect_receive, "notify-request", {NotifyReqVerifyFun, 2500}},
11955	     {sleep, 100},
11956             {send, "notify-reply", NotifyReply},
11957
11958             {expect_nothing, 5000},
11959             disconnect
11960            ],
11961    EvSeq.
11962
11963-ifndef(megaco_hipe_special).
11964otp6865e2_mg_encode_msg_fun(Mod, Conf) ->
11965    fun(M) ->
11966            encode_msg(M, Mod, Conf)
11967    end.
11968-endif.
11969
11970-ifndef(megaco_hipe_special).
11971otp6865e2_mg_decode_msg_fun(Mod, Conf) ->
11972    fun(M) ->
11973            decode_msg(M, Mod, Conf)
11974    end.
11975-endif.
11976
11977-ifndef(megaco_hipe_special).
11978otp6865e2_mg_verify_service_change_rep_msg_fun() ->
11979    fun(Msg) ->
11980	    (catch otp6865e2_mg_verify_service_change_rep_msg(Msg))
11981    end.
11982-endif.
11983
11984otp6865e2_mg_verify_service_change_rep_msg(#'MegacoMessage'{mess = Mess} = M) ->
11985    Body =
11986	case Mess of
11987	    #'Message'{version     = _V,
11988                       mId         = _MgMid,
11989                       messageBody = MsgBody} ->
11990		MsgBody;
11991	    _ ->
11992		throw({error, {invalid_Message, Mess}})
11993	end,
11994    Trans =
11995	case Body of
11996            {transactions, [Transactions]} ->
11997		Transactions;
11998	    _ ->
11999		throw({error, {invalid_messageBody, Body}})
12000	end,
12001    TR =
12002	case Trans of
12003            {transactionReply, TransReply} ->
12004		TransReply;
12005	    _ ->
12006		throw({error, {invalid_transactions, Trans}})
12007	end,
12008    TRes =
12009	case TR of
12010            #'TransactionReply'{transactionId = _Tid,
12011                                immAckRequired = asn1_NOVALUE,
12012                                transactionResult = TransRes} ->
12013		TransRes;
12014	    _ ->
12015		throw({error, {invalid_transactionReply, TR}})
12016	end,
12017    AR =
12018	case TRes of
12019            {actionReplies, [ActRes]} ->
12020		ActRes;
12021	    _ ->
12022		throw({error, {invalid_transactionResult, TRes}})
12023	end,
12024    CR =
12025	case AR of
12026            #'ActionReply'{contextId       = _Cid,
12027                           errorDescriptor = asn1_NOVALUE,
12028                           contextReply    = _CtxReq,
12029                           commandReply    = [CmdRep]} ->
12030		CmdRep;
12031	    _ ->
12032		throw({error, {invalid_actionReplies, AR}})
12033	end,
12034    SCR =
12035	case CR of
12036            {serviceChangeReply, ServChRep} ->
12037		ServChRep;
12038	    _ ->
12039		throw({error, {invalid_commandReply, CR}})
12040	end,
12041    SCRes =
12042	case SCR of
12043            #'ServiceChangeReply'{terminationID       = _TermID,
12044                                  serviceChangeResult = ServChRes} ->
12045		ServChRes;
12046	    _ ->
12047		throw({error, {invalid_serviceChangeReply, SCR}})
12048	end,
12049    SCRP =
12050	case SCRes of
12051            {serviceChangeResParms, Parms} ->
12052		Parms;
12053	    _ ->
12054		throw({error, {invalid_serviceChangeResult, SCRes}})
12055	end,
12056    case SCRP of
12057	#'ServiceChangeResParm'{serviceChangeMgcId = _MgcMid} ->
12058            {ok, M};
12059	_ ->
12060	    {error, {invalid_serviceChangeResParms, SCRP}}
12061    end;
12062otp6865e2_mg_verify_service_change_rep_msg(Crap) ->
12063    {error, {invalid_message, Crap}}.
12064
12065-ifndef(megaco_hipe_special).
12066otp6865e2_mg_verify_notify_rep_msg_fun(TermId, TransId, Rid, Cid,
12067				       AckRequired) ->
12068    fun(Msg) ->
12069	    (catch otp6865e2_mg_verify_notify_rep_msg(Msg,
12070						      TermId, TransId,
12071						      Rid, Cid,
12072						      AckRequired))
12073    end.
12074-endif.
12075
12076otp6865e2_mg_verify_notify_rep_msg(#'MegacoMessage'{mess = Mess} = M,
12077				   TermId, TransId, Rid, Cid, AckRequired) ->
12078    io:format("otp6865e2_mg_verify_notify_rep_msg -> entry with"
12079	      "~n   M:       ~p"
12080	      "~n   TermId:  ~p"
12081	      "~n   TransId: ~p"
12082	      "~n   Rid:     ~p"
12083	      "~n   Cid:     ~p"
12084	      "~n", [M, TermId, TransId, Rid, Cid]),
12085    Body =
12086	case Mess of
12087	    #'Message'{version     = ?VERSION,
12088                       mId         = _Mid,
12089                       messageBody = MsgBody} ->
12090		MsgBody;
12091	    _ ->
12092		throw({error, {invalid_Message, Mess}})
12093	end,
12094    io:format("otp6865e2_mg_verify_notify_rep_msg -> "
12095	      "~n   Body: ~p"
12096	      "~n", [Body]),
12097    Trans =
12098	case Body of
12099            {transactions, [Transactions]} ->
12100		Transactions;
12101	    _ ->
12102		throw({error, {invalid_messageBody, Body}})
12103	end,
12104    io:format("otp6865e2_mg_verify_notify_rep_msg -> "
12105	      "~n   Trans: ~p"
12106	      "~n", [Trans]),
12107    TR =
12108	case Trans of
12109            {transactionReply, TransReply} ->
12110		TransReply;
12111	    _ ->
12112		throw({error, {invalid_transactions, Trans}})
12113	end,
12114    io:format("otp6865e2_mg_verify_notify_rep_msg -> "
12115	      "~n   TR: ~p"
12116	      "~n", [TR]),
12117    TRes =
12118	case TR of
12119            #'TransactionReply'{transactionId     = TransId,
12120                                immAckRequired    = asn1_NOVALUE,
12121                                transactionResult = TransRes} when (AckRequired == false) ->
12122		TransRes;
12123            #'TransactionReply'{transactionId     = TransId,
12124                                immAckRequired    = 'NULL',
12125                                transactionResult = TransRes} when (AckRequired == true) ->
12126		TransRes;
12127	    _ ->
12128		throw({error, {invalid_transactionReply, TR}})
12129	end,
12130    io:format("otp6865e2_mg_verify_notify_rep_msg -> "
12131	      "~n   TRes: ~p"
12132	      "~n", [TRes]),
12133    AR =
12134	case TRes of
12135            {actionReplies, [ActRes]} ->
12136		ActRes;
12137	    _ ->
12138		throw({error, {invalid_transactionResult, TRes}})
12139	end,
12140    io:format("otp6865e2_mg_verify_notify_rep_msg -> "
12141	      "~n   AR: ~p"
12142	      "~n", [AR]),
12143    CR =
12144	case AR of
12145            #'ActionReply'{contextId       = Cid,
12146                           errorDescriptor = asn1_NOVALUE,
12147                           contextReply    = _CtxReq,
12148                           commandReply    = [CmdRep]} ->
12149		CmdRep;
12150	    _ ->
12151		throw({error, {invalid_actionReplies, AR}})
12152	end,
12153    NR =
12154	case CR of
12155            {notifyReply, NotifyReply} ->
12156		NotifyReply;
12157	    _ ->
12158		throw({error, {invalid_commandReply, CR}})
12159	end,
12160    case NR of
12161	#'NotifyReply'{terminationID   = [TermId],
12162		       errorDescriptor = asn1_NOVALUE} ->
12163	    {ok, M};
12164	_ ->
12165	    {error, {invalid_notifyReply, NR}}
12166    end;
12167otp6865e2_mg_verify_notify_rep_msg(Crap, _TermId, _TransId, _Rid, _Cid, _AckRequired) ->
12168    {error, {invalid_message, Crap}}.
12169
12170-ifndef(megaco_hipe_special).
12171otp6865e2_mg_verify_notify_req_msg_fun() ->
12172    fun(M) ->
12173	    otp6865e2_mg_verify_notify_req_msg(M)
12174    end.
12175-endif.
12176
12177otp6865e2_mg_verify_notify_req_msg(#'MegacoMessage'{mess = Mess} = M) ->
12178    io:format("otp6865e2_mg_verify_notify_req_msg -> entry with"
12179	      "~n   M:       ~p"
12180	      "~n", [M]),
12181    Body =
12182	case Mess of
12183	    #'Message'{version     = ?VERSION,
12184                       mId         = _Mid,
12185                       messageBody = MsgBody} ->
12186		MsgBody;
12187	    _ ->
12188		throw({error, {invalid_Message, Mess}})
12189	end,
12190    io:format("otp6865e2_mg_verify_notify_req_msg -> "
12191	      "~n   Body: ~p"
12192	      "~n", [Body]),
12193    Trans =
12194	case Body of
12195            {transactions, [Transactions]} ->
12196		Transactions;
12197	    _ ->
12198		throw({error, {invalid_messageBody, Body}})
12199	end,
12200    io:format("otp6865e2_mg_verify_notify_req_msg -> "
12201	      "~n   Trans: ~p"
12202	      "~n", [Trans]),
12203    TR =
12204	case Trans of
12205            {transactionRequest, TransRequest} ->
12206		TransRequest;
12207	    _ ->
12208		throw({error, {invalid_transactions, Trans}})
12209	end,
12210    io:format("otp6865e2_mg_verify_notify_req_msg -> "
12211	      "~n   TR: ~p"
12212	      "~n", [TR]),
12213    AR =
12214	case TR of
12215            #'TransactionRequest'{transactionId = _TransId,
12216				  actions       = [ActReq]} ->
12217		ActReq;
12218	    _ ->
12219		throw({error, {invalid_transactionRequest, TR}})
12220	end,
12221    io:format("otp6865e2_mg_verify_notify_req_msg -> "
12222	      "~n   AR: ~p"
12223	      "~n", [AR]),
12224    CR =
12225	case AR of
12226	    #'ActionRequest'{contextId       = _Cid,
12227			     commandRequests = [CmdReq]} ->
12228		CmdReq;
12229	    _ ->
12230		throw({error, {invalid_actions, AR}})
12231	end,
12232    io:format("otp6865e2_mg_verify_notify_req_msg -> "
12233	      "~n   CR: ~p"
12234	      "~n", [CR]),
12235    Cmd =
12236	case CR of
12237	    #'CommandRequest'{command = Command} ->
12238		Command;
12239	    _ ->
12240		throw({error, {invalid_commandRequests, CR}})
12241	end,
12242    io:format("otp6865e2_mg_verify_notify_req_msg -> "
12243	      "~n   Cmd: ~p"
12244	      "~n", [Cmd]),
12245    NR =
12246	case Cmd of
12247	    {notifyReq, NotifReq} ->
12248		NotifReq;
12249	    _ ->
12250		throw({error, {invalid_command, Cmd}})
12251	end,
12252    io:format("otp6865e2_mg_verify_notify_req_msg -> "
12253	      "~n   NR: ~p"
12254	      "~n", [NR]),
12255    OED =
12256	case NR of
12257	    #'NotifyRequest'{terminationID            = [_TermId],
12258			     observedEventsDescriptor = ObsEvsDesc,
12259			     errorDescriptor          = asn1_NOVALUE} ->
12260		ObsEvsDesc;
12261	    _ ->
12262		throw({error, {invalid_notifyReq, NR}})
12263	end,
12264    io:format("otp6865e2_mg_verify_notify_req_msg -> "
12265	      "~n   OED: ~p"
12266	      "~n", [OED]),
12267    OE =
12268	case OED of
12269	    #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
12270		ObsEvLst;
12271	    _ ->
12272		throw({error, {invalid_observedEventsDescriptor, OED}})
12273	end,
12274    io:format("otp6865e2_mg_verify_notify_req_msg -> "
12275	      "~n   OE: ~p"
12276	      "~n", [OE]),
12277    case OE of
12278	#'ObservedEvent'{eventName = "al/of"} ->
12279	    io:format("otp6865e2_mg_verify_notify_req_msg -> verifyed"
12280		      "~n", []),
12281	    {ok, M};
12282	_ ->
12283	    throw({error, {invalid_observedEventLst, OE}})
12284    end;
12285otp6865e2_mg_verify_notify_req_msg(M) ->
12286    {error, {invalid_message, M}}.
12287
12288otp6865e2_mg_service_change_request_ar(_Mid, Cid) ->
12289    Prof  = cre_serviceChangeProf("resgw", 1),
12290    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
12291    Root  = #megaco_term_id{id = ["root"]},
12292    SCR   = cre_serviceChangeReq([Root], SCP),
12293    CMD   = cre_command(SCR),
12294    CR    = cre_cmdReq(CMD),
12295    cre_actionReq(Cid, [CR]).
12296
12297otp6865e2_mg_service_change_request_msg(Mid, TransId, Cid) ->
12298    AR    = otp6865e2_mg_service_change_request_ar(Mid, Cid),
12299    TR    = cre_transReq(TransId, [AR]),
12300    Trans = cre_transaction(TR),
12301    Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
12302    cre_megacoMessage(Mess).
12303
12304otp6865e2_mg_notify_request_ar(Rid, Tid, Cid) ->
12305    TT      = cre_timeNotation("19990729", "22000000"),
12306    Ev      = cre_obsEvent("al/of", TT),
12307    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
12308    NR      = cre_notifyReq([Tid], EvsDesc),
12309    CMD     = cre_command(NR),
12310    CR      = cre_cmdReq(CMD),
12311    cre_actionReq(Cid, [CR]).
12312
12313otp6865e2_mg_notify_request_msg(Mid, TermId, TransId, Rid, Cid) ->
12314    AR      = otp6865e2_mg_notify_request_ar(Rid, TermId, Cid),
12315    TR      = cre_transReq(TransId, [AR]),
12316    Trans   = cre_transaction(TR),
12317    Mess    = cre_message(?VERSION, Mid, cre_transactions([Trans])),
12318    cre_megacoMessage(Mess).
12319
12320otp6865e2_mg_notify_reply_msg(Mid, TransId, Cid, TermId) ->
12321    NR    = cre_notifyReply([TermId]),
12322    CR    = cre_cmdReply(NR),
12323    AR    = cre_actionReply(Cid, [CR]),
12324    TRes  = {actionReplies, [AR]},
12325    TR    = cre_transReply(TransId, TRes),
12326    Trans = cre_transaction(TR),
12327    Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
12328    cre_megacoMessage(Mess).
12329
12330otp6865e2_mg_trans_ack_msg(Mid, TransId) ->
12331    TR    = cre_transRespAck(cre_transAck(TransId)),
12332    Trans = cre_transaction(TR),
12333    Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
12334    cre_megacoMessage(Mess).
12335
12336
12337%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12338
12339otp_7189(suite) ->
12340    [];
12341otp_7189(doc) ->
12342    "...";
12343otp_7189(Config) when is_list(Config) ->
12344    Pre = fun() ->
12345                  MgcNode = make_node_name(mgc),
12346                  MgNode  = make_node_name(mg),
12347                  d("start nodes: "
12348                    "~n      MgcNode: ~p"
12349                    "~n      MgNode:  ~p",
12350                    [MgcNode, MgNode]),
12351                  Nodes = [MgcNode, MgNode],
12352                  ok = ?START_NODES(Nodes, true),
12353                  Nodes
12354          end,
12355    Case = fun do_otp_7189/1,
12356    Post = fun(Nodes) ->
12357                   d("stop nodes"),
12358                   ?STOP_NODES(lists:reverse(Nodes))
12359           end,
12360    try_tc(otp_7189, Pre, Case, Post).
12361
12362do_otp_7189([MgcNode, MgNode]) ->
12363    d("[MGC] start the simulator "),
12364    {ok, Mgc} = megaco_test_megaco_generator:start_link("MGC", MgcNode),
12365
12366    d("[MGC] create the event sequence"),
12367    MgcEvSeq = otp_7189_mgc_event_sequence(text, tcp),
12368
12369    i("wait some time before starting the MGC simulation"),
12370    sleep(1000),
12371
12372    d("[MGC] start the simulation"),
12373    {ok, MgcId} = megaco_test_megaco_generator:exec(Mgc, MgcEvSeq),
12374
12375    %% i("wait some time before starting the MG simulator"),
12376    %% sleep(1000),
12377
12378    i("await MGC ready announcement"),
12379    receive
12380        announce_mgc ->
12381            i("received MGC ready announcement"),
12382            ok
12383    end,
12384
12385    d("[MG] start the simulator (generator)"),
12386    {ok, Mg} = megaco_test_tcp_generator:start_link("MG", MgNode),
12387
12388    d("[MG] create the event sequence"),
12389    MgEvSeq = otp_7189_mg_event_sequence(text, tcp),
12390
12391    i("wait some time before starting the MG simulation"),
12392    sleep(1000),
12393
12394    d("[MG] start the simulation"),
12395    {ok, MgId} = megaco_test_tcp_generator:exec(Mg, MgEvSeq),
12396
12397    d("await the generator reply(s)"),
12398    await_completion([MgcId, MgId], 60000),
12399
12400    %% Tell Mgc to stop
12401    i("[MGC] stop generator"),
12402    megaco_test_megaco_generator:stop(Mgc),
12403
12404    %% Tell Mg to stop
12405    i("[MG] stop generator"),
12406    megaco_test_tcp_generator:stop(Mg),
12407
12408    i("done", []),
12409    ok.
12410
12411
12412%%
12413%% MGC generator stuff
12414%%
12415-ifdef(megaco_hipe_special).
12416-define(otp_7189_mgc_verify_handle_connect_fun(),
12417        {?MODULE, otp_7189_mgc_verify_handle_connect, []}).
12418-define(otp_7189_mgc_verify_service_change_req_fun(Mid),
12419        {?MODULE, otp_7189_mgc_verify_service_change_req, [Mid]}).
12420-define(otp_7189_mgc_verify_handle_trans_rep_fun(),
12421	{?MODULE, otp_7189_mgc_verify_handle_trans_rep, []}).
12422-define(otp_7189_mgc_verify_handle_disconnect_fun(),
12423        {?MODULE, otp_7189_mgc_verify_handle_disconnect, []}).
12424-else.
12425-define(otp_7189_mgc_verify_handle_connect_fun(),
12426        otp_7189_mgc_verify_handle_connect_fun()).
12427-define(otp_7189_mgc_verify_service_change_req_fun(Mid),
12428        otp_7189_mgc_verify_service_change_req_fun(Mid)).
12429-define(otp_7189_mgc_verify_handle_trans_rep_fun(),
12430	otp_7189_mgc_verify_handle_trans_rep_fun()).
12431-define(otp_7189_mgc_verify_handle_disconnect_fun(),
12432	fun otp_7189_mgc_verify_handle_disconnect/1).
12433-endif.
12434
12435otp_7189_mgc_event_sequence(text, tcp) ->
12436    CTRL = self(),
12437    Mid = {deviceName,"ctrl"},
12438    RI = [
12439          {port,             2944},
12440          {encoding_module,  megaco_pretty_text_encoder},
12441          {encoding_config,  []},
12442          {transport_module, megaco_tcp}
12443         ],
12444    Tid = #megaco_term_id{id = ["00000000","00000000","01101101"]},
12445    NotifyReq     = [otp_7189_mgc_notify_req_ar(1, Tid, 1)],
12446    ConnectVerify = ?otp_7189_mgc_verify_handle_connect_fun(),
12447    ScrVerify     = ?otp_7189_mgc_verify_service_change_req_fun(Mid),
12448    TransReplyVerify = ?otp_7189_mgc_verify_handle_trans_rep_fun(),
12449    PendingCountersVerify1 =
12450	fun([{Counter, 1}]) ->
12451		   io:format("received expected recv pending counter:"
12452			     "~n   Counter: ~p"
12453			     "~n", [Counter]),
12454		ok;
12455	   (BadCounters) ->
12456		io:format("ERROR: "
12457			  "received unexpected number of "
12458			  "recv pending counters "
12459			  "(expected one with counter value 1):"
12460			  "~n   BadCounters: ~p"
12461			  "~n", [BadCounters]),
12462		{error, {invalid_pending_counters, BadCounters}}
12463	end,
12464    PendingCountersVerify2 =
12465	fun([]) ->
12466		io:format("received expected number of recv pending counters (none)"
12467			  "~n", []),
12468		ok;
12469	   (BadCounters) ->
12470		io:format("ERROR: "
12471			  "received unexpected number of "
12472			  "recv pending counters "
12473			  "(expected none):"
12474			  "~n   BadCounters: ~p"
12475			  "~n", [BadCounters]),
12476		{error, {invalid_pending_counters, BadCounters}}
12477	end,
12478    EvSeq = [
12479             {debug, true},
12480	     {megaco_trace, disable},
12481	     {megaco_trace, max},
12482             megaco_start,
12483             {megaco_start_user, Mid, RI, []},
12484	     {megaco_update_user_info, recv_pending_limit, 10},
12485
12486	     {megaco_update_user_info, long_request_timer, timer:seconds(10)},
12487	     {megaco_user_info, all},
12488             start_transport,
12489             listen,
12490
12491             %% ANNOUNCE READY
12492             {trigger, fun() -> CTRL ! announce_mgc end},
12493
12494             {megaco_callback, handle_connect, ConnectVerify},
12495	     {megaco_conn_info, all},
12496             {megaco_callback, handle_trans_request, ScrVerify},
12497	     {sleep, 500},
12498             {megaco_cast, NotifyReq, []},
12499
12500	     %% Wait for 5 seconds to make sure we are on track
12501             {megaco_callback, nocall, timer:seconds(5)},
12502	     {megaco_system_info, recv_pending_counters, PendingCountersVerify1},
12503
12504	     %% Now wait for the timeout to hit
12505	     {megaco_callback, handle_trans_reply, TransReplyVerify},
12506	     {megaco_system_info, recv_pending_counters, PendingCountersVerify2},
12507
12508             megaco_stop_user,
12509             megaco_stop
12510            ],
12511    EvSeq.
12512
12513
12514-ifndef(megaco_hipe_special).
12515otp_7189_mgc_verify_handle_connect_fun() ->
12516    fun(M) ->
12517	    otp_7189_mgc_verify_handle_connect(M)
12518    end.
12519-endif.
12520
12521otp_7189_mgc_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
12522    {ok, CH, ok};
12523otp_7189_mgc_verify_handle_connect(Else) ->
12524    {error, Else, ok}.
12525
12526-ifndef(megaco_hipe_special).
12527otp_7189_mgc_verify_service_change_req_fun(Mid) ->
12528    fun(Req) ->
12529	    otp_7189_mgc_verify_service_change_req(Req, Mid)
12530    end.
12531-endif.
12532
12533otp_7189_mgc_verify_service_change_req(
12534  {handle_trans_request, _, ?VERSION, [AR]}, Mid) ->
12535    io:format("otp_7189_mgc_verify_service_change_req -> ok"
12536	      "~n   AR: ~p~n", [AR]),
12537    case AR of
12538	#'ActionRequest'{commandRequests = [CR]} ->
12539	    case CR of
12540		#'CommandRequest'{command = Cmd} ->
12541		    case Cmd of
12542			{serviceChangeReq,
12543			 #'ServiceChangeRequest'{terminationID = [Tid],
12544						 serviceChangeParms = Parms}} ->
12545			    case Tid of
12546				#megaco_term_id{contains_wildcards = false,
12547						id = ["root"]} ->
12548				    case Parms of
12549					#'ServiceChangeParm'{
12550						 serviceChangeMethod = restart,
12551						 serviceChangeReason = [[$9,$0,$1|_]]} ->
12552					    Reply =
12553						{discard_ack,
12554						 [otp_7189_mgc_service_change_reply_ar(Mid, 1)]},
12555					    {ok, AR, Reply};
12556					_ ->
12557					    Err = {invalid_SCP, Parms},
12558					    ED = otp_7189_err_desc(Parms),
12559					    ErrReply = {discard_ack, ED},
12560					    {error, Err, ErrReply}
12561				    end;
12562				_ ->
12563				    Err = {invalid_termination_id, Tid},
12564				    ED = otp_7189_err_desc(Tid),
12565				    ErrReply = {discard_ack, ED},
12566				    {error, Err, ErrReply}
12567			    end;
12568			_ ->
12569			    Err = {invalid_command, Cmd},
12570			    ED = otp_7189_err_desc(Cmd),
12571			    ErrReply = {discard_ack, ED},
12572			    {error, Err, ErrReply}
12573		    end;
12574		_ ->
12575		    Err = {invalid_command_request, CR},
12576		    ED = otp_7189_err_desc(CR),
12577		    ErrReply = {discard_ack, ED},
12578		    {error, Err, ErrReply}
12579	    end;
12580	_ ->
12581	    Err = {invalid_action_request, AR},
12582	    ED = otp_7189_err_desc(AR),
12583	    ErrReply = {discard_ack, ED},
12584	    {error, Err, ErrReply}
12585    end;
12586otp_7189_mgc_verify_service_change_req(Else, _Mid) ->
12587    io:format("otp_7189_mgc_verify_service_change_req -> unknown"
12588	      "~n   Else: ~p~n", [Else]),
12589    ED       = otp_7189_err_desc(Else),
12590    ErrReply = {discard_ack, ED},
12591    {error, Else, ErrReply}.
12592
12593otp_7189_mgc_notify_req_ar(Rid, Tid, Cid) ->
12594    TT      = cre_timeNotation("19990729", "22000000"),
12595    Ev      = cre_obsEvent("al/of", TT),
12596    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
12597    NR      = cre_notifyReq([Tid], EvsDesc),
12598    CMD     = cre_command(NR),
12599    CR      = cre_cmdReq(CMD),
12600    cre_actionReq(Cid, [CR]).
12601
12602otp_7189_mgc_service_change_reply_ar(Mid, Cid) ->
12603    SCRP  = cre_serviceChangeResParm(Mid),
12604    SCRes = cre_serviceChangeResult(SCRP),
12605    Root  = #megaco_term_id{id = ["root"]},
12606    SCR   = cre_serviceChangeReply([Root], SCRes),
12607    CR    = cre_cmdReply(SCR),
12608    AR    = cre_actionReply(Cid, [CR]),
12609    AR.
12610
12611-ifndef(megaco_hipe_special).
12612otp_7189_mgc_verify_handle_trans_rep_fun() ->
12613    fun(Event) ->
12614            (catch otp_7189_mgc_verify_handle_trans_rep(Event))
12615    end.
12616-endif.
12617
12618otp_7189_mgc_verify_handle_trans_rep(
12619  {handle_trans_reply, CH, ?VERSION, {error, timeout} = Error, _}) ->
12620    io:format("otp_6275_mgc_verify_trans_rep -> expected error"
12621	      "~n   CH: ~p"
12622              "~n", [CH]),
12623    {ok, Error, error};
12624otp_7189_mgc_verify_handle_trans_rep(
12625  {handle_trans_reply, _CH, ?VERSION, Error, _}) ->
12626    io:format("otp_6275_mgc_verify_handle_trans_rep -> unexpected error"
12627              "~n   Error: ~p"
12628              "~n", [Error]),
12629    {error, Error, error};
12630otp_7189_mgc_verify_handle_trans_rep(Else) ->
12631    io:format("otp_6275_mg_verify_handle_trans_rep -> unknown"
12632              "~n   Else: ~p~n", [Else]),
12633    {error, Else, error}.
12634
12635
12636
12637%%
12638%% MG generator stuff
12639%%
12640-ifdef(megaco_hipe_special).
12641-define(otp_7189_mg_decode_msg_fun(Mod, Conf),
12642	{?MODULE, decode_msg, [Mod, Conf]}).
12643-define(otp_7189_mg_encode_msg_fun(Mod, Conf),
12644	{?MODULE, encode_msg, [Mod, Conf]}).
12645-define(otp_7189_mg_verify_service_change_rep_msg_fun(),
12646	{?MODULE, otp_7189_mg_verify_service_change_rep_msg, []}).
12647-define(otp_7189_mg_verify_notify_req_msg_fun(TermId, TransId, ReqId, CtxId),
12648	{?MODULE, otp_7189_mg_verify_notify_req_msg, [TermId, TransId, ReqId, CtxId]}).
12649-else.
12650-define(otp_7189_mg_decode_msg_fun(Mod, Conf),
12651	otp_7189_mg_decode_msg_fun(Mod, Conf)).
12652-define(otp_7189_mg_encode_msg_fun(Mod, Conf),
12653	otp_7189_mg_encode_msg_fun(Mod, Conf)).
12654-define(otp_7189_mg_verify_service_change_rep_msg_fun(),
12655	otp_7189_mg_verify_service_change_rep_msg_fun()).
12656-define(otp_7189_mg_verify_notify_req_msg_fun(TermId, TransId, ReqId, CtxId),
12657	otp_7189_mg_verify_notify_req_msg_fun(TermId, TransId, ReqId, CtxId)).
12658-endif.
12659
12660otp_7189_mg_event_sequence(text, tcp) ->
12661    DecodeFun = ?otp_7189_mg_decode_msg_fun(megaco_pretty_text_encoder, []),
12662    EncodeFun = ?otp_7189_mg_encode_msg_fun(megaco_pretty_text_encoder, []),
12663    Mid = {deviceName,"mg"},
12664    ServiceChangeReq = otp_7189_mg_service_change_request_msg(Mid, 1, 0),
12665    TermId    =
12666        #megaco_term_id{id = ["00000000","00000000","01101101"]},
12667    TransId   = 1,
12668    ReqId     = 1,
12669    CtxId     = 1,
12670    Pending   = otp_7189_mg_trans_pending_msg(Mid, TransId),
12671    ServiceChangeReplyVerifyFun =
12672	?otp_7189_mg_verify_service_change_rep_msg_fun(),
12673    NotifyReqVerify = ?otp_7189_mg_verify_notify_req_msg_fun(TermId, TransId, ReqId, CtxId),
12674    EvSeq = [
12675	     ?GD_ENABLE(),
12676	     {decode, DecodeFun},
12677	     {encode, EncodeFun},
12678	     {connect, 2944},
12679	     ?GSND("service-change-request", ServiceChangeReq),
12680	     ?GERCV("service-change-reply", ServiceChangeReplyVerifyFun, ?SECS(5)),
12681	     ?GERCV("notify request",       NotifyReqVerify,             ?SECS(5)),
12682	     ?GS(100),
12683	     ?GSND("pending", Pending),
12684	     {expect_closed, timer:seconds(120)},
12685	     disconnect
12686	    ],
12687    EvSeq.
12688
12689otp_7189_mg_encode_msg_fun(Mod, Conf) ->
12690    fun(M) ->
12691            encode_msg(M, Mod, Conf)
12692    end.
12693
12694otp_7189_mg_decode_msg_fun(Mod, Conf) ->
12695    fun(M) ->
12696            decode_msg(M, Mod, Conf)
12697    end.
12698
12699otp_7189_mg_service_change_request_ar(_Mid, Cid) ->
12700    Prof  = cre_serviceChangeProf("resgw", 1),
12701    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
12702    Root  = #megaco_term_id{id = ["root"]},
12703    SCR   = cre_serviceChangeReq([Root], SCP),
12704    CMD   = cre_command(SCR),
12705    CR    = cre_cmdReq(CMD),
12706    cre_actionReq(Cid, [CR]).
12707
12708otp_7189_mg_service_change_request_msg(Mid, TransId, Cid) ->
12709    AR    = otp_7189_mg_service_change_request_ar(Mid, Cid),
12710    TR    = cre_transReq(TransId, [AR]),
12711    Trans = cre_transaction(TR),
12712    Mess  = cre_message(?VERSION, Mid, cre_transactions([Trans])),
12713    cre_megacoMessage(Mess).
12714
12715-ifndef(megaco_hipe_special).
12716otp_7189_mg_verify_service_change_rep_msg_fun() ->
12717    fun(M) ->
12718	    otp_7189_mg_verify_service_change_rep_msg(M)
12719    end.
12720-endif.
12721
12722otp_7189_mg_verify_service_change_rep_msg(
12723  #'MegacoMessage'{mess = Mess} = M) ->
12724    io:format("otp_7189_mg_verify_service_change_rep_msg -> "
12725	      "ok so far~n",[]),
12726    #'Message'{version     = _V,
12727	       mId         = _MgMid,
12728	       messageBody = Body} = Mess,
12729    {transactions, [Trans]} = Body,
12730    {transactionReply, TR} = Trans,
12731    #'TransactionReply'{transactionId = _Tid,
12732			immAckRequired = asn1_NOVALUE,
12733			transactionResult = Res} = TR,
12734    {actionReplies, [AR]} = Res,
12735    #'ActionReply'{contextId = _Cid,
12736		   errorDescriptor = asn1_NOVALUE,
12737		   contextReply = _CtxReq,
12738		   commandReply = [CR]} = AR,
12739    {serviceChangeReply, SCR} = CR,
12740    #'ServiceChangeReply'{terminationID = _TermID,
12741			  serviceChangeResult = SCRes} = SCR,
12742    {serviceChangeResParms, SCRP} = SCRes,
12743    #'ServiceChangeResParm'{serviceChangeMgcId = _MgcMid} = SCRP,
12744    {ok, M};
12745otp_7189_mg_verify_service_change_rep_msg(M) ->
12746    {error, {invalid_message, M}}.
12747
12748-ifndef(megaco_hipe_special).
12749otp_7189_mg_verify_notify_req_msg_fun(TermId, TransId, Rid, Cid) ->
12750    fun(Msg) ->
12751            (catch otp_7189_mg_verify_notify_req_msg(Msg,
12752						     TermId,
12753						     TransId, Rid, Cid))
12754    end.
12755-endif.
12756
12757otp_7189_mg_verify_notify_req_msg(#'MegacoMessage'{mess = Mess} = M,
12758				  TermId, TransId, Rid, Cid) ->
12759    io:format("otp_7189_mgc_verify_notify_req_msg -> entry with"
12760              "~n   M:       ~p"
12761              "~n   TermId:  ~p"
12762              "~n   TransId: ~p"
12763              "~n   Rid:     ~p"
12764              "~n   Cid:     ~p"
12765              "~n", [M, TermId, TransId, Rid, Cid]),
12766    Body =
12767        case Mess of
12768            #'Message'{version     = ?VERSION,
12769                       mId         = _Mid,
12770                       messageBody = MsgBody} ->
12771                MsgBody;
12772            _ ->
12773                throw({error, {invalid_Message, Mess}})
12774        end,
12775    Trans =
12776        case Body of
12777            {transactions, [Transactions]} ->
12778                Transactions;
12779            _ ->
12780                throw({error, {invalid_messageBody, Body}})
12781        end,
12782    TR =
12783        case Trans of
12784            {transactionRequest, TransRequest} ->
12785                TransRequest;
12786            _ ->
12787                throw({error, {invalid_transactions, Trans}})
12788        end,
12789    AR =
12790        case TR of
12791            #'TransactionRequest'{transactionId = TransId,
12792                                  actions       = [ActReq]} ->
12793                ActReq;
12794            _ ->
12795                throw({error, {invalid_transactionRequest, TR, TransId}})
12796        end,
12797    CR =
12798        case AR of
12799            #'ActionRequest'{contextId       = Cid,
12800                             commandRequests = [CmdReq]} ->
12801                CmdReq;
12802            _ ->
12803                throw({error, {invalid_actions, AR}})
12804        end,
12805    Cmd =
12806        case CR of
12807            #'CommandRequest'{command = Command} ->
12808                Command;
12809            _ ->
12810                throw({error, {invalid_commandRequests, CR}})
12811        end,
12812    NR =
12813        case Cmd of
12814            {notifyReq, NotifReq} ->
12815                NotifReq;
12816            _ ->
12817                throw({error, {invalid_command, Cmd}})
12818        end,
12819    OED =
12820        case NR of
12821            #'NotifyRequest'{terminationID            = [TermId],
12822                             observedEventsDescriptor = ObsEvsDesc,
12823                             errorDescriptor          = asn1_NOVALUE} ->
12824                ObsEvsDesc;
12825            _ ->
12826                throw({error, {invalid_notifyReq, NR}})
12827        end,
12828    OE =
12829        case OED of
12830            #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
12831                ObsEvLst;
12832            _ ->
12833                throw({error, {invalid_observedEventsDescriptor, OED}})
12834        end,
12835    case OE of
12836        #'ObservedEvent'{eventName = "al/of"} ->
12837            {ok, M};
12838        _ ->
12839            throw({error, {invalid_observedEventLst, OE}})
12840    end;
12841otp_7189_mg_verify_notify_req_msg(Crap, _TermId, _TransId, _Rid, _Cid) ->
12842    {error, {invalid_MegacoMessage, Crap}}.
12843
12844
12845otp_7189_mg_trans_pending_msg(Mid, TransId) ->
12846    TP   = #'TransactionPending'{transactionId = TransId},
12847    Body = {transactions, [{transactionPending, TP}]},
12848    Mess = #'Message'{version     = 1,
12849                      mId         = Mid,
12850                      messageBody = Body},
12851    #'MegacoMessage'{mess = Mess}.
12852
12853
12854otp_7189_err_desc(T) ->
12855    EC = ?megaco_internal_gateway_error,
12856    ET = lists:flatten(io_lib:format("~w",[T])),
12857    #'ErrorDescriptor'{errorCode = EC, errorText = ET}.
12858
12859
12860%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12861
12862
12863otp_7259(suite) ->
12864    [];
12865otp_7259(doc) ->
12866    ["This is a variant of ticket OTP-6442"];
12867otp_7259(Config) when is_list(Config) ->
12868    Pre = fun() ->
12869                  MgNode = make_node_name(mg),
12870                  d("start (MG) node: ~p", [MgNode]),
12871                  Nodes = [MgNode],
12872                  ok = ?START_NODES(Nodes, true),
12873                  Nodes
12874          end,
12875    Case = fun do_otp_7259/1,
12876    Post = fun(Nodes) ->
12877                   d("stop nodes"),
12878                   ?STOP_NODES(lists:reverse(Nodes))
12879           end,
12880    try_tc(otp7259rr, Pre, Case, Post).
12881
12882do_otp_7259([MgNode]) ->
12883    d("[MG] start the simulator "),
12884    {ok, Mg} = megaco_test_megaco_generator:start_link("MG", MgNode),
12885
12886    d("[MG] create the event sequence"),
12887    MgMid = {deviceName,"mg"},
12888    MgEvSeq = otp_7259_mg_event_sequence(MgMid),
12889
12890    i("wait some time before starting the MG simulation"),
12891    sleep(1000),
12892
12893    d("[MG] start the simulation"),
12894    {ok, MgId} = megaco_test_megaco_generator:exec(Mg, MgEvSeq),
12895
12896    i("await the transport module service change send_message event"),
12897    Pid = otp_7259_expect(fun otp_7259_verify_scr_msg/1, 5000),
12898
12899    i("wait some before issuing the service change reply"),
12900    sleep(500),
12901
12902    i("send the service change reply"),
12903    MgcMid = {deviceName,"mgc"},
12904    ServiceChangeReply = otp_7259_mgc_service_change_reply_msg(MgcMid, 1, 1),
12905    megaco_test_generic_transport:incomming_message(Pid, ServiceChangeReply),
12906
12907    i("await the transport module "
12908      "notify-request send_message event from MG: "
12909      "ignore"),
12910    ok = otp_7259_expect(fun otp_7259_verify_first_nr_msg/1, 5000),
12911
12912    i("await the transport module "
12913      "notify-request resend_message event from MG: "
12914      "reply"),
12915    {TransId2, Cid2, TermId2} =
12916	otp_7259_expect(fun otp_7259_verify_second_nr_msg/1, 10000),
12917
12918    i("wait some before issuing the notify reply"),
12919    sleep(500),
12920
12921    i("send the notify reply"),
12922    NotifyReply =
12923	otp_7259_mgc_notify_reply_msg(MgcMid, TransId2, Cid2, TermId2),
12924    megaco_test_generic_transport:incomming_message(Pid, NotifyReply),
12925
12926    d("[MG] await the generator reply"),
12927    await_completion([MgId], 7000),
12928
12929    %% Tell Mg to stop
12930    i("[MG] stop generator"),
12931    megaco_test_megaco_generator:stop(Mg),
12932
12933    i("done", []),
12934    ok.
12935
12936
12937otp_7259_expect(Verify, Timeout) when (Timeout > 0) ->
12938    T = mtime(),
12939    receive
12940	Msg ->
12941	    case (catch Verify(Msg)) of
12942		{ok, Result} ->
12943		    d("verified after ~p msec", [mtime() - T]),
12944		    Result;
12945		skip ->
12946		    otp_7259_expect(Verify, to(Timeout, T));
12947		{error, Reason} ->
12948		    exit({verification_failed, Reason})
12949	    end
12950    after Timeout ->
12951	    exit(timeout)
12952    end;
12953otp_7259_expect(_, _Timeout) ->
12954    exit(timeout).
12955
12956otp_7259_verify_scr_msg(
12957  {transport_event, {send_message, _SH, {message, Msg, Resend}}, Pid})
12958  when is_record(Msg, 'MegacoMessage') andalso ((Resend =:= true) orelse (Resend =:= false)) ->
12959    d("received expected service change request message: "
12960      "~n   Msg:    ~p"
12961      "~n   Resend: ~p", [Msg, Resend]),
12962    Reply = ok,
12963    Pid ! {transport_reply, Reply, self()},
12964    {ok, Pid};
12965otp_7259_verify_scr_msg(Msg) ->
12966    {error, {invalid_message, Msg}}.
12967
12968otp_7259_verify_first_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 first notify request send message: "
12972      "~n   Msg: ~p", [Msg]),
12973    Reply = ok,
12974    Pid ! {transport_reply, Reply, self()},
12975    {ok, ok};
12976otp_7259_verify_first_nr_msg(Msg) ->
12977    {error, {invalid_message, Msg}}.
12978
12979otp_7259_verify_second_nr_msg(
12980  {transport_event, {send_message, _SH, {message, Msg, Resend}}, Pid})
12981  when is_record(Msg, 'MegacoMessage') andalso ((Resend =:= true) orelse (Resend =:= false)) ->
12982    d("received expected second notify request send message: "
12983      "~n   Msg: ~p", [Msg]),
12984    Reply = ok,
12985    Pid ! {transport_reply, Reply, self()},
12986    #'MegacoMessage'{mess = Mess} = Msg,
12987    #'Message'{mId         = _Mid,
12988	       messageBody = Body} = Mess,
12989    {transactions, Transactions} = Body,
12990    [Transaction] = Transactions,
12991    {transactionRequest, TransReq} = Transaction,
12992    #'TransactionRequest'{transactionId = TransId,
12993			  actions       = Actions} = TransReq,
12994    [Action] = Actions,
12995    #'ActionRequest'{contextId       = Cid,
12996		     commandRequests = CmdReqs} = Action,
12997    [CmdReq] = CmdReqs,
12998    #'CommandRequest'{command = Cmd} = CmdReq,
12999    {notifyReq, NR} = Cmd,
13000    #'NotifyRequest'{terminationID = [TermId]} = NR,
13001    {ok, {TransId, Cid, TermId}};
13002otp_7259_verify_second_nr_msg(Msg) ->
13003    {error, {invalid_message, Msg}}.
13004
13005
13006otp_7259_mgc_service_change_reply_msg(Mid, TransId, Cid) ->
13007    SCRP  = #'ServiceChangeResParm'{serviceChangeMgcId = Mid},
13008    SCRPs = {serviceChangeResParms, SCRP},
13009    Root  = #megaco_term_id{id = ["root"]},
13010    SCR   = #'ServiceChangeReply'{terminationID       = [Root],
13011                                  serviceChangeResult = SCRPs},
13012    CR    = {serviceChangeReply, SCR},
13013    otp_7259_mgc_reply_msg(Mid, TransId, CR, Cid).
13014
13015otp_7259_mgc_notify_reply_msg(Mid, TransId, Cid, TermId) ->
13016    NR  = #'NotifyReply'{terminationID = [TermId]},
13017    CR  = {notifyReply, NR},
13018    otp_7259_mgc_reply_msg(Mid, TransId, CR, Cid).
13019
13020otp_7259_mgc_reply_msg(Mid, TransId, CR, Cid) ->
13021    AR  = #'ActionReply'{contextId    = Cid,
13022                         commandReply = [CR]},
13023    ARs  = {actionReplies, [AR]},
13024    TR   = #'TransactionReply'{transactionId     = TransId,
13025                               transactionResult = ARs},
13026    Body = {transactions, [{transactionReply, TR}]},
13027    Mess = #'Message'{version     = 1,
13028                      mId         = Mid,
13029                      messageBody = Body},
13030    #'MegacoMessage'{mess = Mess}.
13031
13032
13033%%
13034%% MG generator stuff
13035%%
13036-ifdef(megaco_hipe_special).
13037-define(otp_7259_mg_verify_handle_connect_fun(),
13038	{?MODULE, otp_7259_mg_verify_handle_connect, []}).
13039-define(otp_7259_mg_verify_service_change_rep_fun(),
13040	{?MODULE, otp_7259_mg_verify_service_change_rep, []}).
13041-define(otp_7259_mg_verify_notify_rep_fun(),
13042	{?MODULE, otp_7259_mg_verify_notify_rep, []}).
13043-else.
13044-define(otp_7259_mg_verify_handle_connect_fun(),
13045	otp_7259_mg_verify_handle_connect_fun()).
13046-define(otp_7259_mg_verify_service_change_rep_fun(),
13047	otp_7259_mg_verify_service_change_rep_fun()).
13048-define(otp_7259_mg_verify_notify_rep_fun(),
13049	otp_7259_mg_verify_notify_rep_fun()).
13050-endif.
13051
13052otp_7259_mg_event_sequence(Mid) ->
13053    RI = [
13054          {port,             self()}, % This is just a trick to get my pid to the transport module
13055          {encoding_module,  megaco_pretty_text_encoder},
13056          {encoding_config,  []},
13057          {transport_module, megaco_test_generic_transport}
13058         ],
13059    ServiceChangeReq =
13060	otp_7259_mg_service_change_request_ar(Mid, 1),
13061    Tid = #megaco_term_id{id = ["00000000","00000000","01101101"]},
13062    NotifyReq = otp_7259_mg_notify_request_ar(1, Tid, 1),
13063    ConnectVerify =
13064	?otp_7259_mg_verify_handle_connect_fun(),
13065    ServiceChangeReplyVerify =
13066	?otp_7259_mg_verify_service_change_rep_fun(),
13067    NotifyReplyVerify =
13068	?otp_7259_mg_verify_notify_rep_fun(),
13069    EvSeq = [
13070             {debug, false},
13071             megaco_start,
13072             {megaco_start_user, Mid, RI, []},
13073	     {megaco_update_user_info, resend_indication, flag},
13074             start_transport,
13075             {megaco_trace, disable},
13076             {megaco_system_info, users},
13077             {megaco_system_info, connections},
13078             connect,
13079             {megaco_callback, handle_connect, ConnectVerify},
13080             megaco_connect,
13081             {megaco_cast,     [ServiceChangeReq], []},
13082             {megaco_callback, handle_connect,     ConnectVerify},
13083             {megaco_callback, handle_trans_reply, ServiceChangeReplyVerify},
13084             {sleep, 1000},
13085             {megaco_cast,     [NotifyReq],        []},
13086             {megaco_callback, handle_trans_reply, NotifyReplyVerify},
13087             {sleep, 1000},
13088             megaco_stop_user,
13089             megaco_stop,
13090             {sleep, 1000}
13091            ],
13092    EvSeq.
13093
13094
13095-ifndef(megaco_hipe_special).
13096otp_7259_mg_verify_handle_connect_fun() ->
13097    fun(Ev) ->
13098	    otp_7259_mg_verify_handle_connect(Ev)
13099    end.
13100-endif.
13101
13102otp_7259_mg_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
13103    io:format("otp_7259_mg_verify_handle_connect -> ok"
13104	      "~n   CH: ~p~n", [CH]),
13105    {ok, CH, ok};
13106otp_7259_mg_verify_handle_connect(Else) ->
13107    io:format("otp_7259_mg_verify_handle_connect -> unknown"
13108	      "~n   Else: ~p~n", [Else]),
13109    {error, Else, ok}.
13110
13111-ifndef(megaco_hipe_special).
13112otp_7259_mg_verify_service_change_rep_fun() ->
13113    fun(Rep) ->
13114	    otp_7259_mg_verify_service_change_rep(Rep)
13115    end.
13116-endif.
13117
13118otp_7259_mg_verify_service_change_rep(
13119  {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _}) ->
13120    (catch otp_7259_mg_do_verify_service_change_rep(AR));
13121otp_7259_mg_verify_service_change_rep(Crap) ->
13122    {error, Crap, ok}.
13123
13124otp_7259_mg_do_verify_service_change_rep(AR) ->
13125    io:format("otp_7259_mg_verify_service_change_rep -> ok"
13126	      "~n   AR: ~p~n", [AR]),
13127    CR =
13128	case AR of
13129	    #'ActionReply'{commandReply = [CmdRep]} ->
13130		CmdRep;
13131	    _ ->
13132		Reason1 = {invalid_action_reply, AR},
13133		throw({error, Reason1, ok})
13134	end,
13135    SCR =
13136	case CR of
13137	    {serviceChangeReply, ServChRep} ->
13138		ServChRep;
13139	    _ ->
13140		Reason2 = {invalid_command_reply, CR},
13141		throw({error, Reason2, ok})
13142	end,
13143    {Tid, SCRes} =
13144	case SCR of
13145	    #'ServiceChangeReply'{terminationID       = [TermID],
13146				  serviceChangeResult = Res} ->
13147		{TermID, Res};
13148	    _ ->
13149		Reason3 = {invalid_service_change_reply, SCR},
13150		throw({error, Reason3, ok})
13151	end,
13152    case Tid of
13153	#megaco_term_id{contains_wildcards = false, id = ["root"]} ->
13154	    ok;
13155	_ ->
13156	    Reason4 = {invalid_termination_id, Tid},
13157	    throw({error, Reason4, ok})
13158    end,
13159    SCRParm =
13160	case SCRes of
13161	    {serviceChangeResParms, ServChResParms} ->
13162		ServChResParms;
13163	    _ ->
13164		Reason5 = {invalid_serviceChangeResult, SCRes},
13165		throw({error, Reason5, ok})
13166	end,
13167    case SCRParm of
13168	#'ServiceChangeResParm'{serviceChangeMgcId = _RemoteMid} ->
13169	    {ok, AR, ok};
13170	_ ->
13171	    Reason6 = {invalid_service_change_result, SCRParm},
13172	    {error, Reason6, ok}
13173    end.
13174
13175-ifndef(megaco_hipe_special).
13176otp_7259_mg_verify_notify_rep_fun() ->
13177    fun(Rep) ->
13178	    otp_7259_mg_verify_notify_rep(Rep)
13179    end.
13180-endif.
13181
13182otp_7259_mg_verify_notify_rep(
13183  {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _}) ->
13184    io:format("otp_7259_mg_verify_notify_rep -> ok"
13185	      "~n   AR: ~p~n", [AR]),
13186    {ok, AR, ok};
13187otp_7259_mg_verify_notify_rep(Else) ->
13188    io:format("otp_7259_mg_verify_notify_rep -> unknown"
13189	      "~n   Else: ~p~n", [Else]),
13190    {error, Else, ok}.
13191
13192
13193otp_7259_mg_service_change_request_ar(_Mid, Cid) ->
13194    Prof  = cre_serviceChangeProf("resgw", 1),
13195    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
13196    Root  = #megaco_term_id{id = ["root"]},
13197    SCR   = cre_serviceChangeReq([Root], SCP),
13198    CMD   = cre_command(SCR),
13199    CR    = cre_cmdReq(CMD),
13200    cre_actionReq(Cid, [CR]).
13201
13202otp_7259_mg_notify_request_ar(Rid, Tid, Cid) ->
13203    TT      = cre_timeNotation("19990729", "22000000"),
13204    Ev      = cre_obsEvent("al/of", TT),
13205    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
13206    NR      = cre_notifyReq([Tid], EvsDesc),
13207    CMD     = cre_command(NR),
13208    CR      = cre_cmdReq(CMD),
13209    cre_actionReq(Cid, [CR]).
13210
13211
13212%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13213
13214otp_7713(suite) ->
13215    [];
13216otp_7713(doc) ->
13217    [];
13218otp_7713(Config) when is_list(Config) ->
13219    ?ACQUIRE_NODES(1, Config),
13220
13221    put(verbosity, debug),
13222    put(sname,     "TEST"),
13223    put(tc,        otp7713),
13224    i("starting"),
13225
13226    d("start proxy",[]),
13227    ?USER_MOD:start_proxy(),
13228
13229    Extra = otp7713_extra,
13230    PrelMid = preliminary_mid,
13231    MgMid   = ipv4_mid(4711),
13232    MgcMid  = ipv4_mid(),
13233    UserMod = ?USER_MOD,
13234    d("start megaco app",[]),
13235    ?VERIFY(ok, application:start(megaco)),
13236    UserConfig = [{user_mod, UserMod}, {send_mod, UserMod},
13237		  {request_timer, infinity}, {reply_timer, infinity}],
13238    d("start (MG) user ~p",[MgMid]),
13239    ?VERIFY(ok,	megaco:start_user(MgMid, UserConfig)),
13240
13241    d("start (MGC) user ~p",[MgcMid]),
13242    ?VERIFY(ok,	megaco:start_user(MgcMid, UserConfig)),
13243
13244    d("get receive info for ~p",[MgMid]),
13245    MgRH = user_info(MgMid, receive_handle),
13246    d("get receive info for ~p",[MgcMid]),
13247    MgcRH = user_info(MgcMid, receive_handle),
13248    d("start transport",[]),
13249    {ok, MgPid, MgSH} =
13250	?VERIFY({ok, _, _}, UserMod:start_transport(MgRH, MgcRH)),
13251    PrelMgCH = #megaco_conn_handle{local_mid = MgMid,
13252				   remote_mid = preliminary_mid},
13253    MgCH  = #megaco_conn_handle{local_mid = MgMid,
13254				remote_mid = MgcMid},
13255    MgcCH = #megaco_conn_handle{local_mid = MgcMid,
13256				remote_mid = MgMid},
13257    d("(MG) try connect to MGC",[]),
13258    ?SEND(megaco:connect(MgRH, PrelMid, MgSH, MgPid, Extra)), % Mg prel
13259    d("await connect from MG", []),
13260    ?USER({connect, PrelMgCH, _V, [Extra]}, ok),
13261    ?RECEIVE([{res, _, {ok, PrelMgCH}}]),
13262
13263    d("(MG) send service change request",[]),
13264    Req = service_change_request(),
13265    ?SEND(megaco:call(PrelMgCH, [Req], [])),
13266
13267    d("(MGC) send service change reply",[]),
13268    ?USER({connect, MgcCH, _V, []}, ok), % Mgc auto
13269    Rep = service_change_reply(MgcMid),
13270    ?USER({request, MgcCH, _V, [[Req]]}, {discard_ack, [Rep]}),
13271    ?USER({connect, MgCH, _V, []}, ok), % Mg confirm
13272    ?RECEIVE([{res, _, {1, {ok, [Rep]}}}]),
13273
13274    d("get (system info) connections",[]),
13275    connections([MgCH, MgcCH]),
13276    d("get (~p) connections",[MgMid]),
13277    ?VERIFY([MgCH], megaco:user_info(MgMid, connections)),
13278    d("get (~p) connections",[MgcMid]),
13279    ?VERIFY([MgcCH], megaco:user_info(MgcMid, connections)),
13280
13281    Reason = shutdown,
13282    d("(MG) disconnect",[]),
13283    ?SEND(megaco:disconnect(MgCH, Reason)),
13284    ?USER({disconnect, MgCH, _V, [{user_disconnect, Reason}]}, ok),
13285    ?RECEIVE([{res, _, ok}]),
13286    ?VERIFY(ok,	megaco:stop_user(MgMid)),
13287
13288    d("(MGC) disconnect",[]),
13289    ?SEND(megaco:disconnect(MgcCH, Reason)),
13290    ?USER({disconnect, MgcCH, _V, [{user_disconnect, Reason}]}, ok),
13291    ?RECEIVE([{res, _, ok}]),
13292    ?VERIFY(ok,	megaco:stop_user(MgcMid)),
13293
13294    d("stop megaco app",[]),
13295    ?VERIFY(ok, application:stop(megaco)),
13296    ?RECEIVE([]),
13297
13298    d("done",[]),
13299    ok.
13300
13301
13302%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13303
13304otp_8183_request1(suite) ->
13305    [];
13306otp_8183_request1(Config) when is_list(Config) ->
13307    Pre = fun() ->
13308    put(verbosity, debug),
13309    put(sname,     "TEST"),
13310    put(tc,        otp8183r1),
13311    i("starting"),
13312
13313                  MgNode = make_node_name(mg),
13314                  d("start (MG) node: ~p", [MgNode]),
13315                  Nodes = [MgNode],
13316                  ok = ?START_NODES(Nodes, true),
13317                  Nodes
13318          end,
13319    Case = fun do_otp_8183_request1/1,
13320    Post = fun(Nodes) ->
13321                   d("stop nodes"),
13322                   ?STOP_NODES(lists:reverse(Nodes))
13323           end,
13324    try_tc(otp8183r1, Pre, Case, Post).
13325
13326do_otp_8183_request1([MgNode]) ->
13327    i("[MG] start the simulator "),
13328    {ok, Mg} = megaco_test_megaco_generator:start_link("MG", MgNode),
13329
13330    i("[MG] create the event sequence"),
13331    MgMid = {deviceName,"mg"},
13332    MgEvSeq = otp_8183_r1_mg_event_sequence(MgMid),
13333
13334    i("wait some time before starting the MG simulation"),
13335    sleep(1000),
13336
13337    i("[MG] start the simulation"),
13338    {ok, MgId} = megaco_test_megaco_generator:exec(Mg, MgEvSeq),
13339
13340    i("await the transport module service change send_message event"),
13341    Pid = otp_8183_expect(fun(Ev) -> otp_8183_r1_verify_scr_msg(Ev) end, 5000),
13342
13343    i("wait some before issuing the service change reply"),
13344    sleep(500),
13345
13346    i("send the service change reply"),
13347    MgcMid = {deviceName,"mgc"},
13348    ServiceChangeReply = otp_8183_r1_mgc_service_change_reply_msg(MgcMid, 1, 1),
13349    megaco_test_generic_transport:incomming_message(Pid, ServiceChangeReply),
13350
13351    i("await the transport module "
13352      "notify-request send_message event from MG: "
13353      "ignore"),
13354    {TransId2, Cid2, TermId2} =
13355	otp_8183_expect(fun(Ev) -> otp_8183_r1_verify_nr_msg(Ev) end, 5000),
13356
13357    i("wait some before issuing the notify reply (twice)"),
13358    sleep(500),
13359
13360    i("create notify reply"),
13361    NotifyReply =
13362	otp_8183_r1_mgc_notify_reply_msg(MgcMid, TransId2, Cid2, TermId2),
13363    i("send the first notify reply"),
13364    megaco_test_generic_transport:incomming_message(Pid, NotifyReply),
13365    sleep(100), %% This is to "make sure" the events come in the "right" order
13366    i("send the second notify reply"),
13367    megaco_test_generic_transport:incomming_message(Pid, NotifyReply),
13368
13369    d("await the generator reply"),
13370    await_completion([MgId]),
13371
13372    %% Tell Mg to stop
13373    i("[MG] stop generator"),
13374    megaco_test_megaco_generator:stop(Mg),
13375
13376    i("done", []),
13377    ok.
13378
13379
13380otp_8183_expect(Verify, Timeout) when (Timeout > 0) ->
13381    T = mtime(),
13382    receive
13383	Msg ->
13384	    case (catch Verify(Msg)) of
13385		{ok, Result} ->
13386		    d("verified after ~p msec", [mtime() - T]),
13387		    Result;
13388		skip ->
13389		    otp_8183_expect(Verify, to(Timeout, T));
13390		{error, Reason} ->
13391		    exit({verification_failed, Reason})
13392	    end
13393    after Timeout ->
13394	    exit(timeout)
13395    end;
13396otp_8183_expect(_, _Timeout) ->
13397    exit(timeout).
13398
13399otp_8183_r1_verify_scr_msg(
13400  {transport_event, {send_message, _SH, {message, Msg}}, Pid})
13401  when is_record(Msg, 'MegacoMessage') ->
13402    d("received expected service change request message: "
13403      "~n   Msg: ~p", [Msg]),
13404    Reply = ok,
13405    Pid ! {transport_reply, Reply, self()},
13406    {ok, Pid};
13407otp_8183_r1_verify_scr_msg(
13408  {transport_event, {send_message, _SH, BadMsg}, _Pid}) ->
13409    io:format("otp_8183_r1_verify_scr_msg -> error: "
13410	      "~n   BadMsg: ~p"
13411	      "~n", [BadMsg]),
13412    {error, {invalid_message, BadMsg}};
13413otp_8183_r1_verify_scr_msg({transport_event, BadEvent, _Pid}) ->
13414    io:format("otp_8183_r1_verify_scr_msg -> error: "
13415	      "~n   BadEvent: ~p"
13416	      "~n", [BadEvent]),
13417    {error, {invalid_message, BadEvent}};
13418otp_8183_r1_verify_scr_msg(Msg) ->
13419    io:format("otp_8183_r1_verify_scr_msg -> error: "
13420	      "~n   Msg: ~p"
13421	      "~n", [Msg]),
13422    {error, {invalid_message, Msg}}.
13423
13424otp_8183_r1_verify_nr_msg(
13425  {transport_event, {send_message, _SH, {message, Msg}}, Pid})
13426  when is_record(Msg, 'MegacoMessage') ->
13427    io:format("otp_8183_r1_verify_nr_msg -> "
13428              "entry when received expected message with"
13429              "~n   Msg: ~p"
13430              "~n", [Msg]),
13431    Reply = ok,
13432    Pid ! {transport_reply, Reply, self()},
13433    #'MegacoMessage'{mess = Mess} = Msg,
13434    #'Message'{mId         = _Mid,
13435               messageBody = Body} = Mess,
13436    {transactions, Transactions} = Body,
13437    [Transaction] = Transactions,
13438    {transactionRequest, TransReq} = Transaction,
13439    #'TransactionRequest'{transactionId = TransId,
13440                          actions       = Actions} = TransReq,
13441    [Action] = Actions,
13442    #'ActionRequest'{contextId       = Cid,
13443                     commandRequests = CmdReqs} = Action,
13444    [CmdReq] = CmdReqs,
13445    #'CommandRequest'{command = Cmd} = CmdReq,
13446    {notifyReq, NR} = Cmd,
13447    #'NotifyRequest'{terminationID = [TermId]} = NR,
13448    {ok, {TransId, Cid, TermId}};
13449otp_8183_r1_verify_nr_msg(Msg) ->
13450    io:format("otp_8183_r1_verify_nr_msg -> entry when error with"
13451              "~n   Msg: ~p"
13452              "~n", [Msg]),
13453    {error, {invalid_message, Msg}}.
13454
13455otp_8183_r1_mgc_service_change_reply_msg(Mid, TransId, Cid) ->
13456    SCRP  = #'ServiceChangeResParm'{serviceChangeMgcId = Mid},
13457    SCRPs = {serviceChangeResParms, SCRP},
13458    Root  = #megaco_term_id{id = ["root"]},
13459    SCR   = #'ServiceChangeReply'{terminationID       = [Root],
13460                                  serviceChangeResult = SCRPs},
13461    CR    = {serviceChangeReply, SCR},
13462    otp_8183_r1_mgc_reply_msg(Mid, TransId, CR, Cid).
13463
13464otp_8183_r1_mgc_notify_reply_msg(Mid, TransId, Cid, TermId) ->
13465    NR  = #'NotifyReply'{terminationID = [TermId]},
13466    CR  = {notifyReply, NR},
13467    otp_8183_r1_mgc_reply_msg(Mid, TransId, CR, Cid).
13468
13469otp_8183_r1_mgc_reply_msg(Mid, TransId, CR, Cid) ->
13470    AR  = #'ActionReply'{contextId    = Cid,
13471                         commandReply = [CR]},
13472    ARs  = {actionReplies, [AR]},
13473    TR   = #'TransactionReply'{transactionId     = TransId,
13474                               transactionResult = ARs},
13475    Body = {transactions, [{transactionReply, TR}]},
13476    Mess = #'Message'{version     = 1,
13477                      mId         = Mid,
13478                      messageBody = Body},
13479    #'MegacoMessage'{mess = Mess}.
13480
13481
13482%%
13483%% MG generator stuff
13484%%
13485-ifdef(megaco_hipe_special).
13486-define(otp_8183_r1_mg_verify_handle_connect_fun(),
13487	{?MODULE, otp_8183_r1_mg_verify_handle_connect, []}).
13488-define(otp_8183_r1_mg_verify_service_change_rep_fun(),
13489	{?MODULE, otp_8183_r1_mg_verify_service_change_rep, []}).
13490-define(otp_8183_r1_mg_verify_notify_rep_fun(Nr),
13491	{?MODULE, otp_8183_r1_mg_verify_notify_rep, [Nr]}).
13492-else.
13493-define(otp_8183_r1_mg_verify_handle_connect_fun(),
13494	otp_8183_r1_mg_verify_handle_connect_fun()).
13495-define(otp_8183_r1_mg_verify_service_change_rep_fun(),
13496	otp_8183_r1_mg_verify_service_change_rep_fun()).
13497-define(otp_8183_r1_mg_verify_notify_rep_fun(Nr),
13498	otp_8183_r1_mg_verify_notify_rep_fun(Nr)).
13499-endif.
13500
13501otp_8183_r1_mg_event_sequence(Mid) ->
13502    RI = [
13503          {port,             self()}, % This is just a trick to get my pid to the transport module
13504          {encoding_module,  megaco_pretty_text_encoder},
13505          {encoding_config,  []},
13506          {transport_module, megaco_test_generic_transport}
13507         ],
13508    ServiceChangeReq =
13509	otp_8183_r1_mg_service_change_request_ar(Mid, 1),
13510    Tid = #megaco_term_id{id = ["00000000","00000000","01101101"]},
13511    NotifyReq = otp_8183_r1_mg_notify_request_ar(1, Tid, 1),
13512    ConnectVerify =
13513	?otp_8183_r1_mg_verify_handle_connect_fun(),
13514    ServiceChangeReplyVerify =
13515	?otp_8183_r1_mg_verify_service_change_rep_fun(),
13516    NotifyReplyVerify =
13517	fun(Nr) ->
13518		?otp_8183_r1_mg_verify_notify_rep_fun(Nr)
13519	end,
13520    EvSeq = [
13521             {debug, true}, % false},
13522             megaco_start,
13523             {megaco_start_user, Mid, RI, []},
13524             start_transport,
13525             {megaco_trace, disable},
13526             {megaco_system_info, users},
13527             {megaco_system_info, connections},
13528             connect,
13529             {megaco_callback, handle_connect, ConnectVerify},
13530             megaco_connect,
13531             {megaco_cast,     [ServiceChangeReq], []},
13532             {megaco_callback, handle_connect,     ConnectVerify},
13533             {megaco_callback, handle_trans_reply, ServiceChangeReplyVerify},
13534
13535             {sleep, 1000},
13536             {megaco_cast,     [NotifyReq],        [{request_keep_alive_timeout, 5000}]},
13537             {megaco_callback, handle_trans_reply, NotifyReplyVerify(1)},
13538             {megaco_callback, handle_trans_reply, NotifyReplyVerify(2)},
13539             {sleep, 1000},
13540             megaco_stop_user,
13541             megaco_stop,
13542             {sleep, 1000}
13543            ],
13544    EvSeq.
13545
13546
13547-ifndef(megaco_hipe_special).
13548otp_8183_r1_mg_verify_handle_connect_fun() ->
13549    fun(Ev) ->
13550	    otp_8183_r1_mg_verify_handle_connect(Ev)
13551    end.
13552-endif.
13553
13554otp_8183_r1_mg_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
13555    io:format("otp_8183_r1_mg_verify_handle_connect -> ok"
13556	      "~n   CH: ~p~n", [CH]),
13557    {ok, CH, ok};
13558otp_8183_r1_mg_verify_handle_connect(Else) ->
13559    io:format("otp_8183_r1_mg_verify_handle_connect -> unknown"
13560	      "~n   Else: ~p~n", [Else]),
13561    {error, Else, ok}.
13562
13563-ifndef(megaco_hipe_special).
13564otp_8183_r1_mg_verify_service_change_rep_fun() ->
13565    fun(Rep) ->
13566	    otp_8183_r1_mg_verify_service_change_rep(Rep)
13567    end.
13568-endif.
13569
13570otp_8183_r1_mg_verify_service_change_rep(
13571  {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _}) ->
13572    (catch otp_8183_r1_mg_do_verify_service_change_rep(AR));
13573otp_8183_r1_mg_verify_service_change_rep(Crap) ->
13574    io:format("otp_8183_r1_mg_verify_service_change_rep -> crap"
13575	      "~n   Crap: ~p"
13576	      "~n", [Crap]),
13577    {error, Crap, ok}.
13578
13579otp_8183_r1_mg_do_verify_service_change_rep(AR) ->
13580    io:format("otp_8183_r1_mg_do_verify_service_change_rep -> ok"
13581	      "~n   AR: ~p~n", [AR]),
13582    CR =
13583	case AR of
13584	    #'ActionReply'{commandReply = [CmdRep]} ->
13585		CmdRep;
13586	    _ ->
13587		Reason1 = {invalid_action_reply, AR},
13588		throw({error, Reason1, ok})
13589	end,
13590    SCR =
13591	case CR of
13592	    {serviceChangeReply, ServChRep} ->
13593		ServChRep;
13594	    _ ->
13595		Reason2 = {invalid_command_reply, CR},
13596		throw({error, Reason2, ok})
13597	end,
13598    {Tid, SCRes} =
13599	case SCR of
13600	    #'ServiceChangeReply'{terminationID       = [TermID],
13601				  serviceChangeResult = Res} ->
13602		{TermID, Res};
13603	    _ ->
13604		Reason3 = {invalid_service_change_reply, SCR},
13605		throw({error, Reason3, ok})
13606	end,
13607    case Tid of
13608	#megaco_term_id{contains_wildcards = false, id = ["root"]} ->
13609	    ok;
13610	_ ->
13611	    Reason4 = {invalid_termination_id, Tid},
13612	    throw({error, Reason4, ok})
13613    end,
13614    SCRParm =
13615	case SCRes of
13616	    {serviceChangeResParms, ServChResParms} ->
13617		ServChResParms;
13618	    _ ->
13619		Reason5 = {invalid_serviceChangeResult, SCRes},
13620		throw({error, Reason5, ok})
13621	end,
13622    case SCRParm of
13623	#'ServiceChangeResParm'{serviceChangeMgcId = _RemoteMid} ->
13624	    {ok, AR, ok};
13625	_ ->
13626	    Reason6 = {invalid_service_change_result, SCRParm},
13627	    {error, Reason6, ok}
13628    end.
13629
13630-ifndef(megaco_hipe_special).
13631otp_8183_r1_mg_verify_notify_rep_fun(Nr) ->
13632    fun(Rep) ->
13633	    otp_8183_r1_mg_verify_notify_rep(Nr, Rep)
13634    end.
13635-endif.
13636
13637otp_8183_r1_mg_verify_notify_rep(
13638  Nr,
13639  {handle_trans_reply, _CH, ?VERSION, {ok, Nr, [AR]}, _}) ->
13640    io:format("otp_8183_r1_mg_verify_notify_rep -> ok"
13641	      "~n   Nr: ~p"
13642	      "~n   AR: ~p"
13643	      "~n", [Nr, AR]),
13644    {ok, AR, ok};
13645otp_8183_r1_mg_verify_notify_rep(
13646  ExpNr,
13647  {handle_trans_reply, _CH, ?VERSION, {ok, ActNr, [AR]}, _}) ->
13648    io:format("otp_8183_r1_mg_verify_notify_rep -> error"
13649	      "~n   Expected Nr: ~p"
13650	      "~n   Actual Nr:   ~p"
13651	      "~n   AR:          ~p"
13652	      "~n", [ExpNr, ActNr, AR]),
13653    Error = {unexpected_nr, ExpNr, ActNr},
13654    {error, Error, ok};
13655otp_8183_r1_mg_verify_notify_rep(
13656  Nr,
13657  {handle_trans_reply, _CH, ?VERSION, Res, _}) ->
13658    io:format("otp_8183_r1_mg_verify_notify_rep -> error"
13659	      "~n   Nr:  ~p"
13660	      "~n   Res: ~p"
13661	      "~n", [Nr, Res]),
13662    Error = {unexpected_result, Nr, Res},
13663    {error, Error, ok};
13664otp_8183_r1_mg_verify_notify_rep(Nr, Else) ->
13665    io:format("otp_8183_r1_mg_verify_notify_rep -> unknown"
13666	      "~n   Nr:   ~p"
13667	      "~n   Else: ~p"
13668	      "~n", [Nr, Else]),
13669    {error, Else, ok}.
13670
13671
13672otp_8183_r1_mg_service_change_request_ar(_Mid, Cid) ->
13673    Prof  = cre_serviceChangeProf("resgw", 1),
13674    SCP   = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
13675    Root  = #megaco_term_id{id = ["root"]},
13676    SCR   = cre_serviceChangeReq([Root], SCP),
13677    CMD   = cre_command(SCR),
13678    CR    = cre_cmdReq(CMD),
13679    cre_actionReq(Cid, [CR]).
13680
13681otp_8183_r1_mg_notify_request_ar(Rid, Tid, Cid) ->
13682    TT      = cre_timeNotation("19990729", "22000000"),
13683    Ev      = cre_obsEvent("al/of", TT),
13684    EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
13685    NR      = cre_notifyReq([Tid], EvsDesc),
13686    CMD     = cre_command(NR),
13687    CR      = cre_cmdReq(CMD),
13688    cre_actionReq(Cid, [CR]).
13689
13690
13691%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13692
13693otp8212_scr(MidStr) ->
13694    Msg = "!/1 " ++ MidStr ++ " T=19731{C=-{SC=ROOT{SV{MT=RS,RE=\"901\"}}}}",
13695    list_to_binary(Msg).
13696
13697otp_8212(suite) ->
13698    [];
13699otp_8212(doc) ->
13700    [];
13701otp_8212(Config) when is_list(Config) ->
13702    %% ?ACQUIRE_NODES(1, Config),
13703
13704    put(verbosity, debug),
13705    put(sname,     "TEST"),
13706    put(tc,        otp8212),
13707    i("starting"),
13708
13709    Extra         = otp8212_extra,
13710    NoMid         = preliminary_mid,
13711    LocalMid      = {deviceName, "MGC"},
13712    RemoteMidStr1 = "bgf1",
13713    RemoteMid1    = {deviceName, RemoteMidStr1},
13714    RemoteMidStr2 = "bgf2",
13715    RemoteMid2    = {deviceName, RemoteMidStr2},
13716    UserMod       = megaco_mess_otp8212_test,
13717
13718    d("set megaco trace level to max",[]),
13719    megaco:enable_trace(max, io),
13720
13721    d("start megaco app",[]),
13722    ?VERIFY(ok, application:start(megaco)),
13723
13724    d("start local user (MGC) ~p", [LocalMid]),
13725    UserConfig = [{user_mod, UserMod}, {send_mod, UserMod}],
13726    ?VERIFY(ok,	megaco:start_user(LocalMid, UserConfig)),
13727
13728    d("get (MGC) receive info for ~p", [LocalMid]),
13729    RH0 = user_info(LocalMid, receive_handle),
13730    RH  = RH0#megaco_receive_handle{encoding_mod = megaco_mess_otp8212_test,
13731				    encoding_config = []},
13732
13733    d("do a pre-connect for ~p", [LocalMid]),
13734    ControlPid = self(),
13735    SendHandle = {RH, ControlPid, RemoteMidStr1, RemoteMidStr2},
13736    ?VERIFY({ok, _}, megaco:connect(RH, NoMid, SendHandle, ControlPid)),
13737
13738    d("simulate incomming service change message from ~p",
13739      [RemoteMidStr1]),
13740    ?VERIFY(ok,
13741	    megaco:process_received_message(RH, ControlPid,
13742					    otp8212_scr,
13743					    otp8212_scr(RemoteMidStr1))),
13744
13745    d("get the updated connection handle", []),
13746    [CH] = megaco:user_info(LocalMid, connections),
13747
13748    d("verify connection with ~p", [RemoteMidStr1]),
13749    ?VERIFY(RemoteMid1, megaco:conn_info(CH, remote_mid)),
13750
13751    d("send a request to ~p but receive no reply but an unexpected call",
13752      [RemoteMidStr1]),
13753    Res = megaco:call(CH, ["action request"], [{request_timer, 2000}]),
13754    d("request result: ~p", [Res]),
13755    ?VERIFY({1, [{error, {wrong_mid, RemoteMid2, RemoteMid1, _}, {Extra, _}}]}, Res),
13756
13757    Conns = disconnect_all(LocalMid),
13758    await_disconnected(Conns),
13759
13760    d("stop megaco user ~p",[LocalMid]),
13761    ok = await_stopped_user(LocalMid),
13762
13763    d("stop megaco app",[]),
13764    ?VERIFY(ok, application:stop(megaco)),
13765    ?RECEIVE([]),
13766
13767    d("done",[]),
13768    ok.
13769
13770disconnect_all(LocalMid) ->
13771    Conns = megaco:user_info(LocalMid, connections),
13772    d("[~p] disconnect from all connections: ~n~p", [LocalMid, Conns]),
13773    lists:foreach(
13774      fun(Conn) ->
13775	      d("[~p] disconnect from connection ~p", [LocalMid, Conn]),
13776	      DiscoRes = megaco:disconnect(Conn, {otp8212_done, self()}),
13777	      d("[~p] disconnect result: ~p", [LocalMid, DiscoRes])
13778      end,
13779      Conns),
13780    Conns.
13781
13782await_disconnected([]) ->
13783    ok;
13784await_disconnected(Conns) ->
13785    receive
13786	{disconnected, Conn} ->
13787	    d("disconnected: ~p", [Conn]),
13788	    Conns2 = lists:delete(Conn, Conns),
13789	    await_disconnected(Conns2)
13790    end.
13791
13792
13793await_stopped_user(LocalMid) ->
13794    await_stopped_user(LocalMid, 10).
13795
13796await_stopped_user(LocalMid, N) when N =< 0 ->
13797    ?ERROR({failed_stopping_user, LocalMid});
13798await_stopped_user(LocalMid, N) ->
13799    case megaco:stop_user(LocalMid) of
13800	ok ->
13801	    d("user stopped(~w)", [N]),
13802	    ok;
13803	{error, {active_connections, _}} ->
13804	    d("still active connections when N = ~w", [N]),
13805	    Conns = disconnect_all(LocalMid),
13806	    await_disconnected(Conns),
13807	    ?SLEEP(500),
13808	    await_stopped_user(LocalMid, N-1)
13809    end.
13810
13811
13812%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13813
13814cre_ErrDesc(T) ->
13815    EC = ?megaco_internal_gateway_error,
13816    ET = lists:flatten(io_lib:format("~w",[T])),
13817    #'ErrorDescriptor'{errorCode = EC, errorText = ET}.
13818
13819
13820cre_serviceChangeParm(M,R,P) ->
13821    #'ServiceChangeParm'{serviceChangeMethod  = M,
13822                         serviceChangeReason  = R,
13823                         serviceChangeProfile = P}.
13824
13825cre_serviceChangeParm(M, V, R, P) ->
13826    #'ServiceChangeParm'{serviceChangeMethod  = M,
13827			 serviceChangeVersion = V,
13828                         serviceChangeReason  = R,
13829                         serviceChangeProfile = P}.
13830
13831cre_serviceChangeReq(Tid, Parms) ->
13832    #'ServiceChangeRequest'{terminationID      = Tid,
13833                            serviceChangeParms = Parms}.
13834
13835cre_timeNotation(D,T) ->
13836    #'TimeNotation'{date = D, time = T}.
13837
13838cre_obsEvent(Name, Not) ->
13839    #'ObservedEvent'{eventName    = Name,
13840                     timeNotation = Not}.
13841
13842cre_obsEvsDesc(Id, EvList) ->
13843    #'ObservedEventsDescriptor'{requestId        = Id,
13844                                observedEventLst = EvList}.
13845
13846cre_notifyReq(Tid, EvsDesc) ->
13847    #'NotifyRequest'{terminationID            = Tid,
13848                     observedEventsDescriptor = EvsDesc}.
13849
13850cre_command(R) when is_record(R, 'NotifyRequest') ->
13851    {notifyReq, R};
13852cre_command(R) when is_record(R, 'ServiceChangeRequest') ->
13853    {serviceChangeReq, R}.
13854
13855cre_cmdReq(Cmd) ->
13856    #'CommandRequest'{command = Cmd}.
13857
13858cre_actionReq(CtxId, CmdReqs) when is_list(CmdReqs) ->
13859    #'ActionRequest'{contextId       = CtxId,
13860                     commandRequests = CmdReqs}.
13861
13862cre_transReq(TransId, ARs) when is_list(ARs) ->
13863    #'TransactionRequest'{transactionId = TransId,
13864			  actions       = ARs}.
13865
13866cre_transResult(ED) when is_record(ED, 'ErrorDescriptor') ->
13867    {transactionError, ED};
13868cre_transResult([AR|_] = ARs) when is_record(AR, 'ActionReply') ->
13869    {actionReplies, ARs}.
13870
13871cre_transReply(TransId, Res) ->
13872    #'TransactionReply'{transactionId     = TransId,
13873			transactionResult = Res}.
13874
13875cre_transReply(TransId, IAR, Res) ->
13876    #'TransactionReply'{transactionId     = TransId,
13877			immAckRequired    = IAR,
13878			transactionResult = Res}.
13879
13880
13881%% --
13882
13883cre_serviceChangeResParm(Mid) ->
13884    cre_serviceChangeResParm(Mid, ?VERSION).
13885
13886cre_serviceChangeResParm(Mid, V) ->
13887    #'ServiceChangeResParm'{serviceChangeMgcId   = Mid,
13888			    serviceChangeVersion = V}.
13889
13890cre_serviceChangeResult(SCRP) when is_record(SCRP, 'ServiceChangeResParm') ->
13891    {serviceChangeResParms, SCRP};
13892cre_serviceChangeResult(ED) when is_record(ED, 'ErrorDescriptor') ->
13893    {errorDescriptor, ED}.
13894
13895cre_serviceChangeReply(Tid, Res) ->
13896    #'ServiceChangeReply'{terminationID       = Tid,
13897                          serviceChangeResult = Res}.
13898
13899cre_cmdReply(R) when is_record(R, 'NotifyReply') ->
13900    {notifyReply, R};
13901cre_cmdReply(R) when is_record(R, 'ServiceChangeReply') ->
13902    {serviceChangeReply, R}.
13903
13904cre_transRespAck(TransAck) when is_record(TransAck, 'TransactionAck') ->
13905    [TransAck];
13906cre_transRespAck(TRA) when is_list(TRA) ->
13907    TRA.
13908
13909cre_transAck(TransId) ->
13910    #'TransactionAck'{firstAck = TransId}.
13911
13912cre_notifyReply(Tid) ->
13913    #'NotifyReply'{terminationID = Tid}.
13914
13915cre_actionReply(CtxId, CmdRep) ->
13916    #'ActionReply'{contextId    = CtxId,
13917                   commandReply = CmdRep}.
13918
13919cre_serviceChangeProf(Name, Ver) when is_list(Name) andalso is_integer(Ver) ->
13920    #'ServiceChangeProfile'{profileName = Name,
13921                            version     = Ver}.
13922
13923cre_transaction(Trans) when is_record(Trans, 'TransactionRequest') ->
13924    {transactionRequest, Trans};
13925cre_transaction(Trans) when is_record(Trans, 'TransactionPending') ->
13926    {transactionPending, Trans};
13927cre_transaction(Trans) when is_record(Trans, 'TransactionReply') ->
13928    {transactionReply, Trans};
13929cre_transaction(Trans) when is_list(Trans) ->
13930    {transactionResponseAck, Trans}.
13931
13932cre_transactions(Trans) when is_list(Trans) ->
13933    {transactions, Trans}.
13934
13935cre_message(Version, Mid, Body) ->
13936    #'Message'{version     = Version,
13937               mId         = Mid,
13938               messageBody = Body}.
13939
13940cre_megacoMessage(Mess) ->
13941    #'MegacoMessage'{mess = Mess}.
13942
13943service_change_request() ->
13944    Parm = #'ServiceChangeParm'{serviceChangeMethod = restart,
13945				serviceChangeReason = [?megaco_cold_boot]},
13946    SCR = #'ServiceChangeRequest'{terminationID = [?megaco_root_termination_id],
13947				  serviceChangeParms = Parm},
13948    CR = #'CommandRequest'{command = {serviceChangeReq, SCR}},
13949    #'ActionRequest'{contextId = ?megaco_null_context_id,
13950		     commandRequests = [CR]}.
13951
13952service_change_reply(MgcMid) ->
13953    Res = {serviceChangeResParms, #'ServiceChangeResParm'{serviceChangeMgcId = MgcMid}},
13954    SCR = #'ServiceChangeReply'{terminationID = [?megaco_root_termination_id],
13955				serviceChangeResult = Res},
13956    #'ActionReply'{contextId = ?megaco_null_context_id,
13957		   commandReply = [{serviceChangeReply, SCR}]}.
13958
13959local_ip_address() ->
13960    {ok, Hostname} = inet:gethostname(),
13961    {ok, {A1, A2, A3, A4}} = inet:getaddr(Hostname, inet),
13962    {A1, A2, A3, A4}.
13963
13964ipv4_mid() ->
13965    ipv4_mid(asn1_NOVALUE).
13966
13967ipv4_mid(Port) ->
13968    IpAddr = local_ip_address(),
13969    Ip = tuple_to_list(IpAddr),
13970    {ip4Address, #'IP4Address'{address = Ip, portNumber = Port}}.
13971
13972
13973%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13974
13975%%% -------------------------------------------------------------------------------
13976%%% Megaco user callback interface
13977%%% -------------------------------------------------------------------------------
13978
13979handle_connect(ConnHandle, ProtocolVersion, Pid) ->
13980    Pid ! {handle_connect, {ConnHandle, ProtocolVersion}},
13981    ok.
13982
13983handle_disconnect(_, _, {user_disconnect, test_complete}, _) ->
13984    ok;
13985handle_disconnect(ConnHandle, ProtocolVersion, Reason, Pid) ->
13986    Pid ! {handle_disconnect, {ConnHandle, ProtocolVersion, Reason}},
13987    ok.
13988
13989handle_syntax_error(ConnHandle, ProtocolVersion, ErrorDescriptor, Pid) ->
13990    Pid ! {handle_syntax_error,{ConnHandle, ProtocolVersion, ErrorDescriptor}},
13991    reply.
13992
13993handle_message_error(ConnHandle, ProtocolVersion, ErrorDescriptor, Pid) ->
13994    Pid ! {handle_message_error,{ConnHandle, ProtocolVersion, ErrorDescriptor}},
13995    reply.
13996
13997handle_trans_request(ConnHandle, ProtocolVersion, ActionRequests, Pid) ->
13998    Pid ! {handle_trans_request,{ConnHandle, ProtocolVersion, ActionRequests}},
13999    ED = #'ErrorDescriptor'{errorCode = ?megaco_not_implemented,
14000			    errorText = "not implemented yet"},
14001    {discard_ack, ED}.
14002
14003handle_trans_long_request(ConnHandle, ProtocolVersion, Data, Pid) ->
14004    Pid ! {handle_trans_long_request,{ConnHandle, ProtocolVersion, Data}},
14005    ED = #'ErrorDescriptor'{errorCode = ?megaco_not_implemented,
14006			    errorText = "not implemented yet"},
14007    {discard_ack, ED}.
14008
14009handle_trans_reply(ConnHandle, ProtocolVersion, ActualReply, Data, Pid) ->
14010    Pid ! {handle_trans_reply,{ConnHandle, ProtocolVersion, ActualReply, Data}},
14011    ok.
14012
14013handle_trans_ack(ConnHandle, ProtocolVersion, Status, Data, Pid) ->
14014    Pid ! {handle_trans_ack,{ConnHandle, ProtocolVersion, Status, Data}},
14015    ok.
14016
14017handle_unexpected_trans(ReceiveHandle, ProtocolVersion, Trans, Pid) ->
14018    Pid ! {handle_unexpected_trans,
14019	   {ReceiveHandle, ProtocolVersion, Trans, Pid}},
14020    ok.
14021
14022handle_trans_request_abort(ReceiveHandle, ProtocolVersion, TransNo, HandlerPid, Pid) ->
14023    Pid ! {handle_trans_request_abort,
14024	   {ReceiveHandle, ProtocolVersion, TransNo, HandlerPid}},
14025    ok.
14026
14027
14028
14029%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14030
14031encode_msg(M, Mod, Conf) ->
14032    Mod:encode_message(Conf, M).
14033
14034%% encode_msg(M, Mod, Conf, Ver) ->
14035%%     Mod:encode_message(Conf, Ver, M).
14036
14037decode_msg(M, Mod, Conf) ->
14038    Mod:decode_message(Conf, M).
14039
14040%% decode_msg(M, Mod, Conf, Ver) ->
14041%%     Mod:decode_message(Conf, Ver, M).
14042
14043
14044
14045%%% -------------------------------------------------------------------------------
14046%%% Megaco transport module interface
14047%%% -------------------------------------------------------------------------------
14048
14049send_message(Pid, Data) ->
14050    Pid ! {send_message, Data},
14051    ok.
14052
14053% block(Pid) ->
14054%     Pid ! {block, dummy},
14055%     ok.
14056
14057unblock(Pid) ->
14058    Pid ! {unblock, dummy},
14059    ok.
14060
14061% close(Pid) ->
14062%     Pid ! {close, dummy},
14063%     ok.
14064
14065
14066%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14067
14068make_node_name(Name) ->
14069    case string:tokens(atom_to_list(node()), [$@]) of
14070	[_,Host] ->
14071	    list_to_atom(lists:concat([atom_to_list(Name) ++ "@" ++ Host]));
14072	_ ->
14073	    exit("Test node must be started with '-sname'")
14074    end.
14075
14076
14077%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14078
14079user_info(Mid, Key) ->
14080    case (catch megaco:user_info(Mid, Key)) of
14081	{'EXIT', _} = Error ->
14082	    ?ERROR(Error);
14083	Val ->
14084	    ?LOG("user_info -> ok: "
14085		 "~n   ~p"
14086		 "~n", [Val]),
14087	    Val
14088    end.
14089
14090
14091stop_user(Mid) ->
14092    case (catch megaco:stop_user(Mid)) of
14093	{'EXIT', _} = Error ->
14094	    ?ERROR(Error);
14095	Val ->
14096	    ?LOG("stop_user -> ok:"
14097		 "~n   ~p"
14098		 "~n", [Val]),
14099	    Val
14100    end.
14101
14102connections() ->
14103    system_info(connections).
14104
14105connections(Conns0) ->
14106    Conns1 = lists:sort(Conns0),
14107    case lists:sort(connections()) of
14108	Conns1 ->
14109	    ?LOG("connections -> ok:"
14110		 "~n   ~p"
14111		 "~n", [Conns1]),
14112	    Conns1;
14113	Conns2 ->
14114	    ?ERROR({Conns1, Conns2}),
14115	    Conns2
14116    end.
14117
14118system_info(Key) ->
14119    megaco:system_info(Key).
14120
14121
14122%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14123
14124await_completion(Ids) ->
14125    case megaco_test_generator_lib:await_completion(Ids) of
14126	{ok, Reply} ->
14127	    d("OK => Reply: ~n~p", [Reply]),
14128	    ok;
14129	{error, Reply} ->
14130	    d("ERROR => Reply: ~n~p", [Reply]),
14131	    ?ERROR({failed, Reply})
14132    end.
14133
14134await_completion(Ids, Timeout) ->
14135    case megaco_test_generator_lib:await_completion(Ids, Timeout) of
14136	{ok, Reply} ->
14137	    d("OK => Reply: ~n~p", [Reply]),
14138	    ok;
14139	{error, Reply} ->
14140	    d("ERROR => Reply: ~n~p", [Reply]),
14141	    ?ERROR({failed, Reply})
14142    end.
14143
14144
14145%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14146
14147sleep(X) -> receive after X -> ok end.
14148
14149% error_msg(F,A) -> error_logger:error_msg(F ++ "~n",A).
14150
14151
14152%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14153
14154to(To, Start) ->
14155    To - (mtime() - Start).
14156
14157%% Time in milli seconds
14158mtime() ->
14159    {A,B,C} = erlang:timestamp(),
14160    A*1000000000+B*1000+(C div 1000).
14161
14162
14163
14164%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14165
14166try_tc(TCName, Pre, Case, Post) ->
14167    try_tc(TCName, "TEST", ?TEST_VERBOSITY, Pre, Case, Post).
14168
14169try_tc(TCName, Name, Verbosity, Pre, Case, Post) ->
14170    ?TRY_TC(TCName, Name, Verbosity, Pre, Case, Post).
14171
14172
14173
14174%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14175
14176%% p(F) ->
14177%%     p(F, []).
14178
14179p(F, A) ->
14180    p(get(sname), F, A).
14181
14182p(S, F, A) when is_list(S) ->
14183    io:format("*** [~s] ~p ~s ***"
14184	      "~n   " ++ F ++ "~n",
14185	      [?FTS(), self(), S | A]);
14186p(_S, F, A) ->
14187    io:format("*** [~s] ~p *** "
14188	      "~n   " ++ F ++ "~n",
14189	      [?FTS(), self() | A]).
14190
14191
14192%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14193
14194i(F) ->
14195    i(F, []).
14196
14197i(F, A) ->
14198    print(info, "INF", F, A).
14199
14200
14201d(F) ->
14202    d(F, []).
14203
14204d(F, A) ->
14205    print(debug, "DBG", F, A).
14206
14207
14208print(Severity, PRE, FMT, ARGS) ->
14209    print(Severity, get(verbosity), erlang:timestamp(), get(tc), PRE, FMT, ARGS).
14210
14211print(Severity, Verbosity, Ts, Tc, P, F, A) ->
14212    print(printable(Severity,Verbosity), Ts, Tc, P, F, A).
14213
14214print(true, TS, TC, P, F, A) ->
14215    S = ?F("*** [~s] ~s ~p ~s:~w ***"
14216           "~n   " ++ F ++ "~n",
14217           [?FTS(TS), P, self(), get(sname), TC | A]),
14218    io:format("~s", [S]),
14219    io:format(user, "~s", [S]);
14220print(_, _, _, _, _, _) ->
14221    ok.
14222
14223
14224printable(_, debug)   -> true;
14225printable(info, info) -> true;
14226printable(_,_)        -> false.
14227
14228
14229
14230