aboutsummaryrefslogtreecommitdiffstats
path: root/lib/megaco/test/megaco_mess_test.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/megaco/test/megaco_mess_test.erl')
-rw-r--r--lib/megaco/test/megaco_mess_test.erl13733
1 files changed, 13733 insertions, 0 deletions
diff --git a/lib/megaco/test/megaco_mess_test.erl b/lib/megaco/test/megaco_mess_test.erl
new file mode 100644
index 0000000000..368800fa54
--- /dev/null
+++ b/lib/megaco/test/megaco_mess_test.erl
@@ -0,0 +1,13733 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%%----------------------------------------------------------------------
+%% Purpose: Verify the implementation of the ITU-T protocol H.248
+%%----------------------------------------------------------------------
+%% Run the entire test suite with:
+%%
+%% megaco_test_lib:t(megaco_test).
+%% megaco_test_lib:t({megaco_test, all}).
+%%
+%% Or parts of it:
+%%
+%% megaco_test_lib:t({megaco_test, accept}).
+%%----------------------------------------------------------------------
+-module(megaco_mess_test).
+
+%% -compile(export_all).
+-export([
+ all/1,
+ init_per_testcase/2,
+ fin_per_testcase/2,
+
+ connect/1,
+
+ request_and_reply/1,
+ request_and_reply_plain/1,
+ request_and_no_reply/1,
+ request_and_reply_pending_ack_no_pending/1,
+ request_and_reply_pending_ack_one_pending/1,
+ single_trans_req_and_reply/1,
+ single_trans_req_and_reply_sendopts/1,
+ request_and_reply_and_ack/1,
+ request_and_reply_and_no_ack/1,
+ request_and_reply_and_late_ack/1,
+ trans_req_and_reply_and_req/1,
+
+ pending_ack/1,
+ pending_ack_plain/1,
+ request_and_pending_and_late_reply/1,
+
+ dist/1,
+
+ tickets/1,
+ otp_4359/1,
+ otp_4836/1,
+ otp_5805/1,
+ otp_5881/1,
+ otp_5887/1,
+ otp_6253/1,
+ otp_6275/1,
+ otp_6276/1,
+ otp_6442/1,
+ otp_6442_resend_request1/1,
+ otp_6442_resend_request2/1,
+ otp_6442_resend_reply1/1,
+ otp_6442_resend_reply2/1,
+ otp_6865/1,
+ otp_6865_request_and_reply_plain_extra1/1,
+ otp_6865_request_and_reply_plain_extra2/1,
+ otp_7189/1,
+ otp_7259/1,
+ otp_7713/1,
+ otp_8183/1,
+ otp_8183_request1/1,
+ otp_8212/1
+ ]).
+
+%% -behaviour(megaco_user).
+-export([
+ handle_connect/3,
+ handle_disconnect/4,
+ handle_syntax_error/4,
+ handle_message_error/4,
+ handle_trans_request/4,
+ handle_trans_long_request/4,
+ handle_trans_reply/5,
+ handle_trans_ack/5,
+ handle_unexpected_trans/4,
+ handle_trans_request_abort/5
+ ]).
+
+%% -behaviour(megaco_transport).
+-export([
+ send_message/2,
+ unblock/1
+ ]).
+
+-ifdef(megaco_hipe_special).
+-export([
+ %% Case: request_and_reply_pending_ack_no_pending
+ rarpanp_mgc_verify_handle_connect/1,
+ rarpanp_mgc_verify_service_change_req/2,
+ rarpanp_mgc_verify_notify_request/1,
+ rarpanp_mgc_verify_handle_disconnect/1,
+ rarpanp_mg_verify_service_change_rep_msg/1,
+ rarpanp_mg_verify_notify_rep_msg/3,
+
+ %% Case: request_and_reply_pending_ack_one_pending
+ rarpaop_mgc_verify_handle_connect/1,
+ rarpaop_mgc_verify_service_change_req/2,
+ rarpaop_mgc_verify_notify_request/1,
+ rarpaop_mgc_verify_reply_ack/1,
+ rarpaop_mgc_verify_handle_disconnect/1,
+ rarpaop_mg_verify_service_change_rep_msg/1,
+ rarpaop_mg_verify_pending_msg/2,
+ rarpaop_mg_verify_notify_rep_msg/3,
+
+ %% Case: single_trans_req_and_reply
+ strar_mgc_verify_handle_connect/1,
+ strar_mgc_verify_service_change_req/2,
+ strar_mgc_verify_notify_request/1,
+ strar_mgc_verify_handle_disconnect/1,
+ strar_mg_verify_handle_connect/1,
+ strar_mg_verify_service_change_reply/1,
+ strar_mg_verify_notify_reply/1,
+
+ %% Case: single_trans_req_and_reply_sendopts
+ straro_mgc_verify_handle_connect/1,
+ straro_mgc_verify_service_change_req/2,
+ straro_mgc_verify_notify_request/1,
+ straro_mgc_verify_handle_trans_ack/1,
+ straro_mg_verify_handle_connect/1,
+ straro_mg_verify_service_change_reply/1,
+ straro_mg_verify_handle_disconnect/1,
+
+ %% Case: request_and_reply_and_ack
+ raraa_mgc_verify_handle_connect/1,
+ raraa_mgc_verify_service_change_req/2,
+ raraa_mgc_verify_notify_req/1,
+ raraa_mgc_verify_handle_trans_ack/1,
+ raraa_mgc_verify_handle_disconnect/1,
+ raraa_mg_verify_service_change_rep_msg/1,
+ raraa_mg_verify_notify_rep_msg/5,
+
+ %% Case: request_and_reply_and_no_ack
+ rarana_mgc_verify_handle_connect/1,
+ rarana_mgc_verify_service_change_req/2,
+ rarana_mgc_verify_notify_req/1,
+ rarana_mgc_verify_handle_trans_ack/1,
+ rarana_mgc_verify_handle_disconnect/1,
+ rarana_mg_verify_service_change_rep_msg/1,
+ rarana_mg_verify_notify_rep_msg/5,
+
+ %% Case: request_and_reply_and_late_ack
+ rarala_mgc_verify_handle_connect/1,
+ rarala_mgc_verify_service_change_req/2,
+ rarala_mgc_verify_notify_req/1,
+ rarala_mgc_verify_handle_trans_ack/1,
+ rarala_mgc_verify_handle_disconnect/1,
+ rarala_mg_verify_service_change_rep_msg/1,
+ rarala_mg_verify_notify_rep_msg/5,
+
+ %% Case: trans_req_and_reply_and_req
+ trarar_mgc_verify_handle_connect/1,
+ trarar_mgc_verify_service_change_req/2,
+ trarar_mgc_verify_notify_req/2,
+ trarar_mgc_verify_handle_disconnect/1,
+ trarar_mg_verify_service_change_rep_msg/1,
+ trarar_mg_verify_notify_rep_msg/5,
+
+ %% Case: pending_ack_plain
+ pap_mgc_verify_handle_connect/1,
+ pap_mgc_verify_service_change_req/2,
+ pap_mgc_verify_notify_req/1,
+ pap_mgc_verify_notify_req_long/1,
+ pap_mgc_verify_handle_trans_ack/1,
+ pap_mgc_verify_handle_disconnect/1,
+ pap_mg_verify_service_change_rep_msg/1,
+ pap_mg_verify_pending_msg/2,
+ pap_mg_verify_notify_rep_msg/5,
+
+ %% Case: request_and_pending_and_late_reply
+ rapalr_mgc_verify_service_change_req_msg/1,
+ rapalr_mgc_verify_notify_req_msg/5,
+ rapalr_mgc_verify_trans_ack_msg/2,
+ rapalr_mg_verify_handle_connect/1,
+ rapalr_mg_verify_service_change_rep/1,
+ rapalr_mg_verify_notify_rep/1,
+
+ %% Case: otp_4836
+ otp_4836_mgc_verify_service_change_req_msg/1,
+ otp_4836_mgc_verify_notify_req_msg/1,
+
+ %% Case: otp_5805
+ otp_5805_mgc_verify_handle_connect/1,
+ otp_5805_mgc_verify_service_change_req/2,
+ otp_5805_mgc_verify_handle_syntax_error/1,
+ otp_5805_mgc_verify_handle_disconnect/1,
+ otp_5805_mg_verify_service_change_rep_msg/1,
+ otp_5805_mg_verify_error_descriptor_msg/1,
+
+ %% Case: otp_5881
+ otp_5881_mgc_verify_service_change_req_msg/1,
+ otp_5881_mgc_verify_notify_req_msg/1,
+
+ %% Case: otp_5887
+ otp_5887_mgc_verify_service_change_req_msg/1,
+ otp_5887_mgc_verify_notify_req_msg/1,
+
+ %% Case: otp_6275
+ otp_6275_mgc_verify_service_change_req_msg/1,
+ otp_6275_mgc_verify_notify_rep_msg/1,
+ otp_6275_mg_verify_handle_connect/1,
+ otp_6275_mg_verify_notify_req/1,
+ otp_6275_mg_verify_handle_trans_rep/1,
+
+ %% Case: otp_6442_resend_request1
+ otp_6442_resend_request1_mg_verify_handle_connect/1,
+ otp_6442_resend_request1_mg_verify_service_change_rep/1,
+ otp_6442_resend_request1_mg_verify_notify_rep/1,
+
+ %% Case: otp_6442_resend_request2
+ otp_6442_resend_request2_mg_verify_handle_connect/1,
+ otp_6442_resend_request2_mg_verify_service_change_rep/1,
+ otp_6442_resend_request2_mg_verify_notify_rep/1,
+
+ %% Case: otp_6442_resend_reply1
+ otp_6442_resend_reply1_mg_verify_handle_connect/1,
+ otp_6442_resend_reply1_mg_verify_service_change_rep/1,
+ otp_6442_resend_reply1_mg_verify_notify_req/2,
+ otp_6442_resend_reply1_mg_verify_ack/1,
+
+ %% Case: otp_6442_resend_reply2
+ otp_6442_resend_reply2_mg_verify_handle_connect/1,
+ otp_6442_resend_reply2_mg_verify_service_change_rep/1,
+ otp_6442_resend_reply2_mg_verify_notify_req/2,
+ otp_6442_resend_reply2_mg_verify_ack/1,
+
+ %% Case: otp_6865_request_and_reply_plain_extra2
+ otp6865e2_mgc_verify_handle_connect/1,
+ otp6865e2_mgc_verify_service_change_req/3,
+ otp6865e2_mgc_verify_notify_req/4,
+ otp6865e2_mgc_verify_reply_ack/2,
+ otp6865e2_mgc_verify_notify_reply/2,
+ otp6865e2_mgc_verify_handle_disconnect/1,
+ otp6865e2_mg_verify_service_change_rep_msg/1,
+ otp6865e2_mg_verify_notify_rep_msg/6,
+ otp6865e2_mg_verify_notify_req_msg/1,
+
+ %% Case: otp_7189
+ otp_7189_mgc_verify_handle_connect/1,
+ otp_7189_mgc_verify_service_change_req/2,
+ otp_7189_mgc_verify_handle_trans_reply_req/1,
+ otp_7189_mgc_verify_handle_disconnect/1,
+ otp_7189_mg_verify_service_change_rep_msg/1,
+ otp_7189_mg_verify_notify_req_msg/1,
+
+ %% Case: otp_6442_resend_request1
+ otp_8183_request1_mg_verify_handle_connect/1,
+ otp_8183_request1_mg_verify_service_change_rep/1,
+ otp_8183_request1_mg_verify_notify_rep/1,
+
+ %% Utility
+ encode_msg/3,
+ decode_msg/3
+ ]).
+-endif.
+
+-include_lib("megaco/include/megaco.hrl").
+-include_lib("megaco/include/megaco_message_v1.hrl").
+-include("megaco_test_lib.hrl").
+
+-define(VERSION, 1).
+
+-define(TEST_VERBOSITY, debug).
+-define(MGC_VERBOSITY, debug).
+-define(MG_VERBOSITY, debug).
+
+-define(MGC_START(Pid, Mid, ET, Conf, Verb),
+ megaco_test_mgc:start(Pid, Mid, ET, Conf, Verb)).
+-define(MGC_STOP(Pid), megaco_test_mgc:stop(Pid)).
+-define(MGC_REQ_PEND(Pid,To), megaco_test_mgc:request_pending(Pid,To)).
+-define(MGC_REQ_HP(Pid,To), megaco_test_mgc:request_handle_pending(Pid,To)).
+-define(MGC_ACK_INFO(Pid), megaco_test_mgc:ack_info(Pid,self())).
+
+-define(MG_START(Pid, Mid, Enc, Transp, Conf, Verb),
+ megaco_test_mg:start(Pid, Mid, Enc, Transp, Conf, Verb)).
+-define(MG_STOP(Pid), megaco_test_mg:stop(Pid)).
+-define(MG_SERV_CHANGE(Pid), megaco_test_mg:service_change(Pid)).
+-define(MG_NOTIF_REQ(Pid), megaco_test_mg:notify_request(Pid)).
+-define(MG_AWAIT_NOTIF_REP(Pid), megaco_test_mg:await_notify_reply(Pid)).
+-define(MG_CONN_INFO(Pid,Tag), megaco_test_mg:conn_info(Pid,Tag)).
+-define(MG_USER_INFO(Pid,Tag), megaco_test_mg:user_info(Pid,Tag)).
+-define(MG_NOTIF_RAR(Pid), megaco_test_mg:notify_request_and_reply(Pid)).
+
+-define(SEND(Expr),
+ ?VERIFY(ok, megaco_mess_user_test:apply_proxy(fun() -> Expr end))).
+
+-define(USER(Expected, Reply),
+ megaco_mess_user_test:reply(?MODULE,
+ ?LINE,
+ fun(Actual) ->
+ case ?VERIFY(Expected, Actual) of
+ Expected -> {ok, Reply};
+ UnExpected -> {error, {reply_verify,
+ ?MODULE,
+ ?LINE,
+ UnExpected}}
+ end
+ end)).
+
+%% t() -> megaco_test_lib:t(?MODULE).
+%% t(Case) -> megaco_test_lib:t({?MODULE, Case}).
+
+
+min(M) -> timer:minutes(M).
+
+%% Test server callbacks
+% init_per_testcase(pending_ack = Case, Config) ->
+% put(dbg,true),
+% megaco_test_lib:init_per_testcase(Case, Config);
+init_per_testcase(otp_7189 = Case, Config) ->
+ C = lists:keydelete(tc_timeout, 1, Config),
+ megaco_test_lib:init_per_testcase(Case, [{tc_timeout, min(2)} |C]);
+init_per_testcase(request_and_no_reply = Case, Config) ->
+ C = lists:keydelete(tc_timeout, 1, Config),
+ megaco_test_lib:init_per_testcase(Case, [{tc_timeout, min(2)} |C]);
+init_per_testcase(Case, Config) ->
+ C = lists:keydelete(tc_timeout, 1, Config),
+ megaco_test_lib:init_per_testcase(Case, [{tc_timeout, min(1)} |C]).
+
+% fin_per_testcase(pending_ack = Case, Config) ->
+% erase(dbg),
+% megaco_test_lib:fin_per_testcase(Case, Config);
+fin_per_testcase(Case, Config) ->
+ megaco_test_lib:fin_per_testcase(Case, Config).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+all(suite) ->
+ [
+ connect,
+ request_and_reply,
+ pending_ack,
+ dist,
+
+ %% Tickets last
+ tickets
+ ].
+
+request_and_reply(suite) ->
+ [
+ request_and_reply_plain,
+ request_and_no_reply,
+ request_and_reply_pending_ack_no_pending,
+ request_and_reply_pending_ack_one_pending,
+ single_trans_req_and_reply,
+ single_trans_req_and_reply_sendopts,
+ request_and_reply_and_ack,
+ request_and_reply_and_no_ack,
+ request_and_reply_and_late_ack,
+ trans_req_and_reply_and_req
+ ].
+
+pending_ack(suite) ->
+ [
+ pending_ack_plain,
+ request_and_pending_and_late_reply
+ ].
+
+tickets(suite) ->
+ [
+ otp_4359,
+ otp_4836,
+ otp_5805,
+ otp_5881,
+ otp_5887,
+ otp_6253,
+ otp_6275,
+ otp_6276,
+ otp_6442,
+ otp_6865,
+ otp_7189,
+ otp_7259,
+ otp_7713,
+ otp_8183,
+ otp_8212
+ ].
+
+otp_6442(suite) ->
+ [
+ otp_6442_resend_request1,
+ otp_6442_resend_request2,
+ otp_6442_resend_reply1,
+ otp_6442_resend_reply2
+ ].
+
+otp_6865(suite) ->
+ [
+ otp_6865_request_and_reply_plain_extra1,
+ otp_6865_request_and_reply_plain_extra2
+ ].
+
+otp_8183(suite) ->
+ [
+ otp_8183_request1
+ ].
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+connect(suite) ->
+ [];
+connect(doc) ->
+ [];
+connect(Config) when is_list(Config) ->
+ ?ACQUIRE_NODES(1, Config),
+ PrelMid = preliminary_mid,
+ MgMid = ipv4_mid(4711),
+
+ ?VERIFY(ok, application:start(megaco)),
+ ?VERIFY(ok, megaco:start_user(MgMid, [{send_mod, bad_send_mod},
+ {request_timer, infinity},
+ {reply_timer, infinity}])),
+
+ MgRH = user_info(MgMid, receive_handle),
+ {ok, PrelCH} = ?VERIFY({ok, _}, megaco:connect(MgRH, PrelMid, sh, self())),
+
+ connections([PrelCH]),
+ ?VERIFY([PrelCH], megaco:user_info(MgMid, connections)),
+
+ ?VERIFY(bad_send_mod, megaco:user_info(MgMid, send_mod)),
+ ?VERIFY(bad_send_mod, megaco:conn_info(PrelCH, send_mod)),
+ SC = service_change_request(),
+ ?VERIFY({1, {error, {send_message_failed, {'EXIT',
+ {undef, [{bad_send_mod, send_message, [sh, _]} | _]}}}}},
+ megaco:call(PrelCH, [SC], [])),
+
+ ?VERIFY(ok, megaco:disconnect(PrelCH, shutdown)),
+
+ ?VERIFY(ok, megaco:stop_user(MgMid)),
+ ?VERIFY(ok, application:stop(megaco)),
+ ?RECEIVE([]),
+ ok.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+request_and_reply_plain(suite) ->
+ [];
+request_and_reply_plain(Config) when is_list(Config) ->
+ ?ACQUIRE_NODES(1, Config),
+ d("request_and_reply_plain -> start proxy",[]),
+ megaco_mess_user_test:start_proxy(),
+
+ PrelMid = preliminary_mid,
+ MgMid = ipv4_mid(4711),
+ MgcMid = ipv4_mid(),
+ UserMod = megaco_mess_user_test,
+ d("request_and_reply_plain -> start megaco app",[]),
+ ?VERIFY(ok, application:start(megaco)),
+ UserConfig = [{user_mod, UserMod}, {send_mod, UserMod},
+ {request_timer, infinity}, {reply_timer, infinity}],
+ d("request_and_reply_plain -> start (MG) user ~p",[MgMid]),
+ ?VERIFY(ok, megaco:start_user(MgMid, UserConfig)),
+
+ d("request_and_reply_plain -> start (MGC) user ~p",[MgcMid]),
+ ?VERIFY(ok, megaco:start_user(MgcMid, UserConfig)),
+
+ d("request_and_reply_plain -> get receive info for ~p",[MgMid]),
+ MgRH = user_info(MgMid, receive_handle),
+ d("request_and_reply_plain -> get receive info for ~p",[MgcMid]),
+ MgcRH = user_info(MgcMid, receive_handle),
+ d("request_and_reply_plain -> start transport",[]),
+ {ok, MgPid, MgSH} =
+ ?VERIFY({ok, _, _}, UserMod:start_transport(MgRH, MgcRH)),
+ PrelMgCH = #megaco_conn_handle{local_mid = MgMid,
+ remote_mid = preliminary_mid},
+ MgCH = #megaco_conn_handle{local_mid = MgMid,
+ remote_mid = MgcMid},
+ MgcCH = #megaco_conn_handle{local_mid = MgcMid,
+ remote_mid = MgMid},
+ d("request_and_reply_plain -> (MG) try connect to MGC",[]),
+ ?SEND(megaco:connect(MgRH, PrelMid, MgSH, MgPid)), % Mg prel
+ d("request_and_reply_plain -> (MGC) await connect from MG",[]),
+ ?USER({connect, PrelMgCH, _V, []}, ok),
+ ?RECEIVE([{res, _, {ok, PrelMgCH}}]),
+
+ d("request_and_reply_plain -> (MG) send service change request",[]),
+ Req = service_change_request(),
+ ?SEND(megaco:call(PrelMgCH, [Req], [])),
+
+ d("request_and_reply_plain -> (MGC) send service change reply",[]),
+ ?USER({connect, MgcCH, _V, []}, ok), % Mgc auto
+ Rep = service_change_reply(MgcMid),
+ ?USER({request, MgcCH, _V, [[Req]]}, {discard_ack, [Rep]}),
+ ?USER({connect, MgCH, _V, []}, ok), % Mg confirm
+ ?RECEIVE([{res, _, {1, {ok, [Rep]}}}]),
+
+ d("request_and_reply_plain -> get (system info) connections",[]),
+ connections([MgCH, MgcCH]),
+ d("request_and_reply_plain -> get (~p) connections",[MgMid]),
+ ?VERIFY([MgCH], megaco:user_info(MgMid, connections)),
+ d("request_and_reply_plain -> get (~p) connections",[MgcMid]),
+ ?VERIFY([MgcCH], megaco:user_info(MgcMid, connections)),
+
+ Reason = shutdown,
+ d("request_and_reply_plain -> (MG) disconnect",[]),
+ ?SEND(megaco:disconnect(MgCH, Reason)),
+ ?USER({disconnect, MgCH, _V, [{user_disconnect, Reason}]}, ok),
+ ?RECEIVE([{res, _, ok}]),
+ ?VERIFY(ok, megaco:stop_user(MgMid)),
+
+ d("request_and_reply_plain -> (MGC) disconnect",[]),
+ ?SEND(megaco:disconnect(MgcCH, Reason)),
+ ?USER({disconnect, MgcCH, _V, [{user_disconnect, Reason}]}, ok),
+ ?RECEIVE([{res, _, ok}]),
+ ?VERIFY(ok, megaco:stop_user(MgcMid)),
+
+ d("request_and_reply_plain -> stop megaco app",[]),
+ ?VERIFY(ok, application:stop(megaco)),
+ ?RECEIVE([]),
+ d("request_and_reply_plain -> done",[]),
+ ok.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% OTP-4760
+request_and_no_reply(suite) ->
+ [];
+request_and_no_reply(doc) ->
+ [];
+request_and_no_reply(Config) when is_list(Config) ->
+ put(verbosity, ?TEST_VERBOSITY),
+ put(sname, "TEST"),
+ put(tc, request_and_no_reply),
+ i("starting"),
+
+ MgcNode = make_node_name(mgc),
+ Mg1Node = make_node_name(mg1),
+ Mg2Node = make_node_name(mg2),
+ Mg3Node = make_node_name(mg3),
+ Mg4Node = make_node_name(mg4),
+ d("start nodes: "
+ "~n MgcNode: ~p"
+ "~n Mg1Node: ~p"
+ "~n Mg2Node: ~p"
+ "~n Mg3Node: ~p"
+ "~n Mg4Node: ~p",
+ [MgcNode, Mg1Node, Mg2Node, Mg3Node, Mg4Node]),
+ Nodes = [MgcNode, Mg1Node, Mg2Node, Mg3Node, Mg4Node],
+ ok = megaco_test_lib:start_nodes(Nodes, ?FILE, ?LINE),
+
+ %% Start the MGC
+ i("[MGC] start"),
+ ET = [{text,tcp}, {text,udp}, {binary,tcp}, {binary,udp}],
+ {ok, Mgc} =
+ ?MGC_START(MgcNode, {deviceName, "ctrl"}, ET, [], ?MGC_VERBOSITY),
+
+ i("[MG] start"),
+ Mg1Mid = {deviceName, "mg1"},
+ Mg2Mid = {deviceName, "mg2"},
+ Mg3Mid = {deviceName, "mg3"},
+ Mg4Mid = {deviceName, "mg4"},
+ ReqTmr = #megaco_incr_timer{wait_for = 3000,
+ factor = 1,
+ incr = 0,
+ max_retries = 2
+ },
+ LongReqTmr = #megaco_incr_timer{wait_for = 10000,
+ factor = 1,
+ incr = 0,
+ max_retries = 3
+ },
+ %% Start the MGs
+ PendingTmr = 10000,
+ ReplyTmr = 16000,
+ MgConfig = [{request_timer, ReqTmr},
+ {long_request_timer, LongReqTmr},
+ {pending_timer, PendingTmr},
+ {reply_timer, ReplyTmr}],
+ {ok, Mg1} = ?MG_START(Mg1Node, Mg1Mid, text, tcp, MgConfig, ?MG_VERBOSITY),
+ {ok, Mg2} = ?MG_START(Mg2Node, Mg2Mid, text, udp, MgConfig, ?MG_VERBOSITY),
+ {ok, Mg3} = ?MG_START(Mg3Node, Mg3Mid, binary, tcp, MgConfig, ?MG_VERBOSITY),
+ {ok, Mg4} = ?MG_START(Mg4Node, Mg4Mid, binary, udp, MgConfig, ?MG_VERBOSITY),
+
+ d("MG1 user info: ~p", [?MG_USER_INFO(Mg1, all)]),
+ d("MG1 conn info: ~p", [?MG_CONN_INFO(Mg1, all)]),
+ d("MG2 user info: ~p", [?MG_USER_INFO(Mg2, all)]),
+ d("MG2 conn info: ~p", [?MG_CONN_INFO(Mg2, all)]),
+ d("MG3 user info: ~p", [?MG_USER_INFO(Mg3, all)]),
+ d("MG3 conn info: ~p", [?MG_CONN_INFO(Mg3, all)]),
+ d("MG4 user info: ~p", [?MG_USER_INFO(Mg4, all)]),
+ d("MG4 conn info: ~p", [?MG_CONN_INFO(Mg4, all)]),
+
+ i("[MG1] connect to the MGC (service change)"),
+ ServChRes1 = ?MG_SERV_CHANGE(Mg1),
+ d("service change result: ~p", [ServChRes1]),
+ d("MG1 user info: ~p", [?MG_USER_INFO(Mg1, all)]),
+ d("MG1 conn info: ~p", [?MG_CONN_INFO(Mg1, all)]),
+
+ i("[MG2] connect to the MGC (service change)"),
+ ServChRes2 = ?MG_SERV_CHANGE(Mg2),
+ d("service change result: ~p", [ServChRes2]),
+ d("MG2 user info: ~p", [?MG_USER_INFO(Mg2, all)]),
+ d("MG2 conn info: ~p", [?MG_CONN_INFO(Mg2, all)]),
+
+ i("[MG3] connect to the MGC (service change)"),
+ ServChRes3 = ?MG_SERV_CHANGE(Mg3),
+ d("service change result: ~p", [ServChRes3]),
+ d("MG3 user info: ~p", [?MG_USER_INFO(Mg3, all)]),
+ d("MG3 conn info: ~p", [?MG_CONN_INFO(Mg3, all)]),
+
+ i("[MG4] connect to the MGC (service change)"),
+ ServChRes4 = ?MG_SERV_CHANGE(Mg4),
+ d("service change result: ~p", [ServChRes4]),
+ d("MG4 user info: ~p", [?MG_USER_INFO(Mg4, all)]),
+ d("MG4 conn info: ~p", [?MG_CONN_INFO(Mg4, all)]),
+
+ d("tell the MGC to ignore requests"),
+ ?MGC_REQ_PEND(Mgc, infinity),
+
+ d("[MG1] send the notify"),
+ ?MG_NOTIF_REQ(Mg1),
+
+ d("[MG2] send the notify"),
+ ?MG_NOTIF_REQ(Mg2),
+
+ d("[MG3] send the notify"),
+ ?MG_NOTIF_REQ(Mg3),
+
+ d("[MG4] send the notify"),
+ ?MG_NOTIF_REQ(Mg4),
+
+ d("[MG1] await notify reply"),
+ {ok, {_Vsn1, {error, timeout}}} = ?MG_AWAIT_NOTIF_REP(Mg1),
+ d("[MG1] received expected reply"),
+
+ d("[MG2] await notify reply"),
+ {ok, {_Vsn2, {error, timeout}}} = ?MG_AWAIT_NOTIF_REP(Mg2),
+ d("[MG2] received expected reply"),
+
+ d("[MG3] await notify reply"),
+ {ok, {_Vsn3, {error, timeout}}} = ?MG_AWAIT_NOTIF_REP(Mg3),
+ d("[MG3] received expected reply"),
+
+ d("[MG4] await notify reply"),
+ {ok, {_Vsn4, {error, timeout}}} = ?MG_AWAIT_NOTIF_REP(Mg4),
+ d("[MG4] received expected reply"),
+
+ d("MG1 user info: ~p", [?MG_USER_INFO(Mg1, all)]),
+ d("MG1 conn info: ~p", [?MG_CONN_INFO(Mg1, all)]),
+ d("MG2 user info: ~p", [?MG_USER_INFO(Mg2, all)]),
+ d("MG2 conn info: ~p", [?MG_CONN_INFO(Mg2, all)]),
+ d("MG3 user info: ~p", [?MG_USER_INFO(Mg3, all)]),
+ d("MG3 conn info: ~p", [?MG_CONN_INFO(Mg3, all)]),
+ d("MG4 user info: ~p", [?MG_USER_INFO(Mg4, all)]),
+ d("MG4 conn info: ~p", [?MG_CONN_INFO(Mg4, all)]),
+
+ ok.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+request_and_reply_pending_ack_no_pending(suite) ->
+ [];
+request_and_reply_pending_ack_no_pending(doc) ->
+ ["This test case tests that megaco correctly handles the return "
+ "value handle_pending_ack from handle_trans_request when NO "
+ "pending message has been sent"];
+request_and_reply_pending_ack_no_pending(Config) when is_list(Config) ->
+ put(verbosity, ?TEST_VERBOSITY),
+ put(sname, "TEST"),
+ put(tc, rar_panp),
+ i("starting"),
+
+ MgcNode = make_node_name(mgc),
+ MgNode = make_node_name(mg),
+ d("start nodes: "
+ "~n MgcNode: ~p"
+ "~n MgNode: ~p",
+ [MgcNode, MgNode]),
+ Nodes = [MgcNode, MgNode],
+ ok = megaco_test_lib:start_nodes(Nodes, ?FILE, ?LINE),
+
+ d("[MGC] start the simulator "),
+ {ok, Mgc} = megaco_test_megaco_generator:start_link("MGC", MgcNode),
+
+ d("[MGC] create the event sequence"),
+ MgcEvSeq = rarpanp_mgc_event_sequence(text, tcp),
+
+ i("wait some time before starting the MGC simulation"),
+ sleep(1000),
+
+ d("[MGC] start the simulation"),
+ {ok, MgcId} = megaco_test_megaco_generator:exec(Mgc, MgcEvSeq),
+
+ i("wait some time before starting the MG simulator"),
+ sleep(1000),
+
+ d("[MG] start the simulator (generator)"),
+ {ok, Mg} = megaco_test_tcp_generator:start_link("MG", MgNode),
+
+ d("[MG] create the event sequence"),
+ MgEvSeq = rarpanp_mg_event_sequence(text, tcp),
+
+ i("wait some time before starting the MG simulation"),
+ sleep(1000),
+
+ d("[MG] start the simulation"),
+ {ok, MgId} = megaco_test_tcp_generator:exec(Mg, MgEvSeq),
+
+ d("await the generator reply(s)"),
+ await_completion([MgcId, MgId]),
+
+ %% Tell Mgc to stop
+ i("[MGC] stop generator"),
+ megaco_test_tcp_generator:stop(Mgc),
+
+ %% Tell Mg to stop
+ i("[MG] stop generator"),
+ megaco_test_megaco_generator:stop(Mg),
+
+ i("done", []),
+ ok.
+
+
+%%
+%% MGC generator stuff
+%%
+-ifdef(megaco_hipe_special).
+-define(rarpanp_mgc_verify_handle_connect_fun(),
+ {?MODULE, rarpanp_mgc_verify_handle_connect, []}).
+-define(rarpanp_mgc_verify_service_change_req_fun(Mid),
+ {?MODULE, rarpanp_mgc_verify_service_change_req, [Mid]}).
+-define(rarpanp_mgc_verify_notify_req_fun(),
+ {?MODULE, rarpanp_mgc_verify_notify_request, []}).
+-define(rarpanp_mgc_verify_handle_disconnect_fun(),
+ {?MODULE, rarpanp_mgc_verify_handle_disconnect, []}).
+-else.
+-define(rarpanp_mgc_verify_handle_connect_fun(),
+ fun rarpanp_mgc_verify_handle_connect/1).
+-define(rarpanp_mgc_verify_service_change_req_fun(Mid),
+ rarpanp_mgc_verify_service_change_req_fun(Mid)).
+-define(rarpanp_mgc_verify_notify_req_fun(),
+ rarpanp_mgc_verify_notify_request_fun()).
+-define(rarpanp_mgc_verify_handle_disconnect_fun(),
+ fun rarpanp_mgc_verify_handle_disconnect/1).
+-endif.
+
+rarpanp_mgc_event_sequence(text, tcp) ->
+ Mid = {deviceName,"ctrl"},
+ RI = [
+ {port, 2944},
+ {encoding_module, megaco_pretty_text_encoder},
+ {encoding_config, []},
+ {transport_module, megaco_tcp}
+ ],
+ ConnectVerify = ?rarpanp_mgc_verify_handle_connect_fun(),
+ ScrVerify = ?rarpanp_mgc_verify_service_change_req_fun(Mid),
+ NrVerify = ?rarpanp_mgc_verify_notify_req_fun(),
+ DiscoVerify = ?rarpanp_mgc_verify_handle_disconnect_fun(),
+%% ConnectVerify = fun rarpanp_mgc_verify_handle_connect/1,
+%% ScrVerify = rarpanp_mgc_verify_service_change_req_fun(Mid),
+%% NrVerify = rarpanp_mgc_verify_notify_request_fun(),
+%% DiscoVerify = fun rarpanp_mgc_verify_handle_disconnect/1,
+ EvSeq = [
+ {debug, true},
+ {megaco_trace, disable},
+ {megaco_trace, max},
+ megaco_start,
+ {megaco_start_user, Mid, RI, []},
+ {megaco_update_user_info, sent_pending_limit, 100},
+ start_transport,
+ listen,
+ {megaco_callback, handle_connect, ConnectVerify},
+ {megaco_conn_info, all},
+ {megaco_callback, handle_trans_request, ScrVerify},
+ {megaco_callback, handle_trans_request, NrVerify},
+ {megaco_callback, nocall, 10000},
+ {megaco_callback, handle_disconnect, DiscoVerify},
+ megaco_stop_user,
+ megaco_stop
+ ],
+ EvSeq.
+
+%% Connect verification
+rarpanp_mgc_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
+ {ok, CH, ok};
+rarpanp_mgc_verify_handle_connect(Else) ->
+ {error, Else, ok}.
+
+%% Service Change verification
+-ifndef(megaco_hipe_special).
+rarpanp_mgc_verify_service_change_req_fun(Mid) ->
+ fun(Req) ->
+ rarpanp_mgc_verify_service_change_req(Req, Mid)
+ end.
+-endif.
+
+rarpanp_mgc_verify_service_change_req(
+ {handle_trans_request, _, ?VERSION, [AR]}, Mid) ->
+ io:format("rarpanp_mgc_verify_service_change_req -> entry with"
+ "~n AR: ~p"
+ "~n Mid: ~p"
+ "~n", [AR, Mid]),
+ (catch rarpanp_mgc_do_verify_service_change_req(AR, Mid));
+rarpanp_mgc_verify_service_change_req(Crap, _Mid) ->
+ ED = cre_ErrDesc(Crap),
+ ErrReply = {discard_ack, ED},
+ {error, Crap, ErrReply}.
+
+rarpanp_mgc_do_verify_service_change_req(AR, Mid) ->
+ io:format("rarpanp_mgc_do_verify_service_change_req -> entry with"
+ "~n AR: ~p"
+ "~n Mid: ~p"
+ "~n", [AR, Mid]),
+ CR =
+ case AR of
+ #'ActionRequest'{commandRequests = [CmdReq]} ->
+ CmdReq;
+ _ ->
+ Err1 = {invalid_action_request, AR},
+ ED1 = cre_ErrDesc(AR),
+ ErrReply1 = {discard_ack, ED1},
+ throw({error, Err1, ErrReply1})
+ end,
+ Cmd =
+ case CR of
+ #'CommandRequest'{command = Command} ->
+ Command;
+ _ ->
+ Err2 = {invalid_command_request, CR},
+ ED2 = cre_ErrDesc(CR),
+ ErrReply2 = {discard_ack, ED2},
+ throw({error, Err2, ErrReply2})
+ end,
+ {Tid, Parms} =
+ case Cmd of
+ {serviceChangeReq,
+ #'ServiceChangeRequest'{terminationID = [TermID],
+ serviceChangeParms = ServChParms}} ->
+ {TermID, ServChParms};
+ _ ->
+ Err3 = {invalid_command, Cmd},
+ ED3 = cre_ErrDesc(Cmd),
+ ErrReply3 = {discard_ack, ED3},
+ throw({error, Err3, ErrReply3})
+ end,
+ case Tid of
+ #megaco_term_id{contains_wildcards = false, id = ["root"]} ->
+ ok;
+ _ ->
+ Err4 = {invalid_termination_id, Tid},
+ ED4 = cre_ErrDesc(Tid),
+ ErrReply4 = {discard_ack, ED4},
+ throw({error, Err4, ErrReply4})
+ end,
+ case Parms of
+ #'ServiceChangeParm'{serviceChangeMethod = restart,
+ serviceChangeReason = [[$9,$0,$1|_]]} ->
+ AckData = [rarpanp_mgc_service_change_reply_ar(Mid, 1)],
+ Reply = {discard_ack, AckData},
+ {ok, AR, Reply};
+ _ ->
+ Err5 = {invalid_SCP, Parms},
+ ED5 = cre_ErrDesc(Parms),
+ ErrReply5 = {discard_ack, ED5},
+ {error, Err5, ErrReply5}
+ end.
+
+
+%% Notify Request verification
+-ifndef(megaco_hipe_special).
+rarpanp_mgc_verify_notify_request_fun() ->
+ fun(Req) ->
+ rarpanp_mgc_verify_notify_request(Req)
+ end.
+-endif.
+
+rarpanp_mgc_verify_notify_request(
+ {handle_trans_request, _, ?VERSION, [AR]}) ->
+ (catch rarpanp_mgc_do_verify_notify_request(AR));
+rarpanp_mgc_verify_notify_request(Crap) ->
+ ED = cre_ErrDesc(Crap),
+ ErrReply = {discard_ack, ED},
+ {error, Crap, ErrReply}.
+
+rarpanp_mgc_do_verify_notify_request(AR) ->
+ io:format("rarpanp_mgc_do_verify_notify_request -> entry with"
+ "~n AR: ~p"
+ "~n", [AR]),
+ {Cid, CR} =
+ case AR of
+ #'ActionRequest'{contextId = CtxID,
+ commandRequests = [CmdReq]} ->
+ {CtxID, CmdReq};
+ _ ->
+ Err1 = {invalid_action_request, AR},
+ ED1 = cre_ErrDesc(AR),
+ ErrReply1 = {discard_ack, ED1},
+ throw({error, Err1, ErrReply1})
+ end,
+ Cmd =
+ case CR of
+ #'CommandRequest'{command = Command} ->
+ Command;
+ _ ->
+ Err2 = {invalid_command_request, CR},
+ ED2 = cre_ErrDesc(CR),
+ ErrReply2 = {discard_ack, ED2},
+ throw({error, Err2, ErrReply2})
+ end,
+ NR =
+ case Cmd of
+ {notifyReq, NotifReq} ->
+ NotifReq;
+ _ ->
+ Err3 = {invalid_command, Cmd},
+ ED3 = cre_ErrDesc(Cmd),
+ ErrReply3 = {discard_ack, ED3},
+ throw({error, Err3, ErrReply3})
+ end,
+ {Tid, OED} =
+ case NR of
+ #'NotifyRequest'{terminationID = [TermID],
+ observedEventsDescriptor = ObsEvsDesc,
+ errorDescriptor = asn1_NOVALUE} ->
+ {TermID, ObsEvsDesc};
+ _ ->
+ Err4 = {invalid_NR, NR},
+ ED4 = cre_ErrDesc(NR),
+ ErrReply4 = {discard_ack, ED4},
+ throw({error, Err4, ErrReply4})
+ end,
+ OE =
+ case OED of
+ #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
+ ObsEvLst;
+ _ ->
+ Err5 = {invalid_OED, OED},
+ ED5 = cre_ErrDesc(NR),
+ ErrReply5 = {discard_ack, ED5},
+ throw({error, Err5, ErrReply5})
+ end,
+ case OE of
+ #'ObservedEvent'{eventName = "al/of"} ->
+ AckData = notify_request_verified,
+ Replies = [rarpanp_mgc_notify_reply_ar(Cid, Tid)],
+ Reply = {{handle_pending_ack, AckData}, Replies},
+ {ok, AR, Reply};
+ _ ->
+ Err6 = {invalid_OE, OE},
+ ED6 = cre_ErrDesc(OE),
+ ErrReply6 = {discard_ack, ED6},
+ throw({error, Err6, ErrReply6})
+ end.
+
+
+%% Disconnect verification
+rarpanp_mgc_verify_handle_disconnect({handle_disconnect, CH, ?VERSION, _R}) ->
+ {ok, CH, ok};
+rarpanp_mgc_verify_handle_disconnect(Else) ->
+ {error, Else, ok}.
+
+rarpanp_mgc_service_change_reply_ar(Mid, Cid) ->
+ SCRP = cre_serviceChangeResParm(Mid),
+ SCRes = cre_serviceChangeResult(SCRP),
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = cre_serviceChangeReply([Root], SCRes),
+ CR = cre_cmdReply(SCR),
+ AR = cre_actionReply(Cid, [CR]),
+ AR.
+
+rarpanp_mgc_notify_reply_ar(Cid, TermId) ->
+ NR = cre_notifyReply([TermId]),
+ CR = cre_cmdReply(NR),
+ cre_actionReply(Cid, [CR]).
+
+
+%%
+%% MG generator stuff
+%%
+-ifdef(megaco_hipe_special).
+-define(rarpanp_mg_decode_msg_fun(Mod, Conf),
+ {?MODULE, decode_msg, [Mod, Conf]}).
+-define(rarpanp_mg_encode_msg_fun(Mod, Conf),
+ {?MODULE, encode_msg, [Mod, Conf]}).
+-define(rarpanp_mg_verify_service_change_rep_msg_fun(),
+ {?MODULE, rarpanp_mg_verify_service_change_rep_msg, []}).
+-define(rarpanp_mg_verify_notify_rep_msg_fun(TransId, TermId),
+ {?MODULE, rarpanp_mg_verify_notify_rep_msg, [TransId, TermId]}).
+-else.
+-define(rarpanp_mg_decode_msg_fun(Mod, Conf),
+ rarpanp_mg_decode_msg_fun(Mod, Conf)).
+-define(rarpanp_mg_encode_msg_fun(Mod, Conf),
+ rarpanp_mg_encode_msg_fun(Mod, Conf)).
+-define(rarpanp_mg_verify_service_change_rep_msg_fun(),
+ rarpanp_mg_verify_service_change_rep_msg_fun()).
+-define(rarpanp_mg_verify_notify_rep_msg_fun(TransId, TermId),
+ rarpanp_mg_verify_notify_rep_msg_fun(TransId, TermId)).
+-endif.
+
+rarpanp_mg_event_sequence(text, tcp) ->
+ DecodeFun = ?rarpanp_mg_decode_msg_fun(megaco_pretty_text_encoder, []),
+ EncodeFun = ?rarpanp_mg_encode_msg_fun(megaco_pretty_text_encoder, []),
+ Mid = {deviceName,"mg"},
+ ServiceChangeReq = rarpanp_mg_service_change_request_msg(Mid, 1, 0),
+ ScrVerifyFun = ?rarpanp_mg_verify_service_change_rep_msg_fun(),
+ TransId = 2,
+ TermId = #megaco_term_id{id = ["00000000","00000000","01101101"]},
+ NotifyReq = rarpanp_mg_notify_request_msg(Mid, TransId, 1, TermId, 1),
+ NrVerifyFun = ?rarpanp_mg_verify_notify_rep_msg_fun(TransId, TermId),
+ EvSeq = [{debug, true},
+ {decode, DecodeFun},
+ {encode, EncodeFun},
+ {connect, 2944},
+ {send, "service-change-request", ServiceChangeReq},
+ {expect_receive, "service-change-reply", {ScrVerifyFun, 10000}},
+ {send, "notify request", NotifyReq},
+ {expect_receive, "notify-reply", {NrVerifyFun, 10000}},
+ {expect_nothing, 11000},
+ disconnect
+ ],
+ EvSeq.
+
+
+-ifndef(megaco_hipe_special).
+rarpanp_mg_encode_msg_fun(Mod, Conf) ->
+ fun(M) ->
+ encode_msg(M, Mod, Conf)
+ end.
+-endif.
+
+-ifndef(megaco_hipe_special).
+rarpanp_mg_decode_msg_fun(Mod, Conf) ->
+ fun(M) ->
+ decode_msg(M, Mod, Conf)
+ end.
+-endif.
+
+-ifndef(megaco_hipe_special).
+rarpanp_mg_verify_service_change_rep_msg_fun() ->
+ fun(Msg) ->
+ (catch rarpanp_mg_verify_service_change_rep_msg(Msg))
+ end.
+-endif.
+
+rarpanp_mg_verify_service_change_rep_msg(#'MegacoMessage'{mess = Mess} = M) ->
+ io:format("rarpanp_mg_verify_service_change_rep_msg -> entry with"
+ "~n Mess: ~p"
+ "~n", [Mess]),
+ Body =
+ case Mess of
+ #'Message'{version = _V,
+ mId = _MgMid,
+ messageBody = MsgBody} ->
+ MsgBody;
+ _ ->
+ throw({error, {invalid_Message, Mess}})
+ end,
+ Trans =
+ case Body of
+ {transactions, [Transactions]} ->
+ Transactions;
+ _ ->
+ throw({error, {invalid_messageBody, Body}})
+ end,
+ TR =
+ case Trans of
+ {transactionReply, TransReply} ->
+ TransReply;
+ _ ->
+ throw({error, {invalid_transactions, Trans}})
+ end,
+ TRes =
+ case TR of
+ #'TransactionReply'{transactionId = _Tid,
+ immAckRequired = asn1_NOVALUE,
+ transactionResult = TransRes} ->
+ TransRes;
+ _ ->
+ throw({error, {invalid_transactionReply, TR}})
+ end,
+ AR =
+ case TRes of
+ {actionReplies, [ActRes]} ->
+ ActRes;
+ _ ->
+ throw({error, {invalid_transactionResult, TRes}})
+ end,
+ CR =
+ case AR of
+ #'ActionReply'{contextId = _Cid,
+ errorDescriptor = asn1_NOVALUE,
+ contextReply = _CtxReq,
+ commandReply = [CmdRep]} ->
+ CmdRep;
+ _ ->
+ throw({error, {invalid_actionReplies, AR}})
+ end,
+ SCR =
+ case CR of
+ {serviceChangeReply, ServChRep} ->
+ ServChRep;
+ _ ->
+ throw({error, {invalid_commandReply, CR}})
+ end,
+ SCRes =
+ case SCR of
+ #'ServiceChangeReply'{terminationID = _TermID,
+ serviceChangeResult = ServChRes} ->
+ ServChRes;
+ _ ->
+ throw({error, {invalid_serviceChangeReply, SCR}})
+ end,
+ SCRP =
+ case SCRes of
+ {serviceChangeResParms, Parms} ->
+ Parms;
+ _ ->
+ throw({error, {invalid_serviceChangeResult, SCRes}})
+ end,
+ case SCRP of
+ #'ServiceChangeResParm'{serviceChangeMgcId = _MgcMid} ->
+ {ok, M};
+ _ ->
+ {error, {invalid_serviceChangeResParms, SCRP}}
+ end;
+rarpanp_mg_verify_service_change_rep_msg(Crap) ->
+ {error, {invalid_message, Crap}}.
+
+-ifndef(megaco_hipe_special).
+rarpanp_mg_verify_notify_rep_msg_fun(TransId, TermId) ->
+ fun(Msg) ->
+ (catch rarpanp_mg_verify_notify_rep_msg(Msg, TransId, TermId))
+ end.
+-endif.
+
+rarpanp_mg_verify_notify_rep_msg(#'MegacoMessage'{mess = Mess} = M,
+ TransId, TermId) ->
+ io:format("rarpanp_mg_verify_notify_rep_msg -> entry with"
+ "~n TransId: ~p"
+ "~n TermId: ~p"
+ "~n Mess: ~p"
+ "~n", [TransId, TermId, Mess]),
+ Body =
+ case Mess of
+ #'Message'{version = _V,
+ mId = _MgMid,
+ messageBody = MsgBody} ->
+ MsgBody;
+ _ ->
+ throw({error, {invalid_Message, Mess}})
+ end,
+ Trans =
+ case Body of
+ {transactions, [Transactions]} ->
+ Transactions;
+ _ ->
+ throw({error, {invalid_messageBody, Body}})
+ end,
+ TR =
+ case Trans of
+ {transactionReply, TransReply} ->
+ TransReply;
+ _ ->
+ throw({error, {invalid_transactions, Trans}})
+ end,
+ TRes =
+ case TR of
+ #'TransactionReply'{transactionId = TransId,
+ immAckRequired = asn1_NOVALUE, % No ack
+ transactionResult = TransRes} ->
+ TransRes;
+ _ ->
+ throw({error, {invalid_transactionReply, TR}})
+ end,
+ AR =
+ case TRes of
+ {actionReplies, [ActRes]} ->
+ ActRes;
+ _ ->
+ throw({error, {invalid_transactionResult, TRes}})
+ end,
+ CR =
+ case AR of
+ #'ActionReply'{contextId = _Cid,
+ errorDescriptor = asn1_NOVALUE,
+ contextReply = _CtxReq,
+ commandReply = [CmdRep]} ->
+ CmdRep;
+ _ ->
+ throw({error, {invalid_actionReplies, AR}})
+ end,
+ NR =
+ case CR of
+ {notifyReply, NotifyRep} ->
+ NotifyRep;
+ _ ->
+ throw({error, {invalid_commandReply, CR}})
+ end,
+
+ case NR of
+ #'NotifyReply'{terminationID = [TermId],
+ errorDescriptor = asn1_NOVALUE} ->
+ io:format("rarpanp_mg_verify_notify_rep_msg -> done when verifyed"
+ "~n", []),
+ {ok, M};
+ #'NotifyReply'{terminationID = A,
+ errorDescriptor = B} ->
+ throw({error, {invalid_notifyReply,
+ {A, TermId},
+ {B, asn1_NOVALUE}}});
+ _ ->
+ throw({error, {invalid_notifyReply, NR}})
+ end;
+rarpanp_mg_verify_notify_rep_msg(_TransId, _TermId, Crap) ->
+ {error, {invalid_message, Crap}}.
+
+rarpanp_mg_service_change_request_ar(_Mid, Cid) ->
+ Prof = cre_serviceChangeProf("resgw", 1),
+ SCP = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = cre_serviceChangeReq([Root], SCP),
+ CMD = cre_command(SCR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+rarpanp_mg_service_change_request_msg(Mid, TransId, Cid) ->
+ AR = rarpanp_mg_service_change_request_ar(Mid, Cid),
+ TR = cre_transReq(TransId, [AR]),
+ Trans = cre_transaction(TR),
+ Mess = cre_message(?VERSION, Mid, cre_transactions([Trans])),
+ cre_megacoMessage(Mess).
+
+rarpanp_mg_notify_request_ar(Rid, Tid, Cid) ->
+ TT = cre_timeNotation("19990729", "22000000"),
+ Ev = cre_obsEvent("al/of", TT),
+ EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
+ NR = cre_notifyReq([Tid], EvsDesc),
+ CMD = cre_command(NR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+rarpanp_mg_notify_request_msg(Mid, TransId, Rid, TermId, Cid) ->
+ AR = rarpanp_mg_notify_request_ar(Rid, TermId, Cid),
+ TR = cre_transReq(TransId, [AR]),
+ Trans = cre_transaction(TR),
+ Mess = cre_message(?VERSION, Mid, cre_transactions([Trans])),
+ cre_megacoMessage(Mess).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+request_and_reply_pending_ack_one_pending(suite) ->
+ [];
+request_and_reply_pending_ack_one_pending(doc) ->
+ ["This test case tests that megaco correctly handles the return "
+ "value handle_pending_ack from handle_trans_request when ONE "
+ "pending message has been sent"];
+request_and_reply_pending_ack_one_pending(Config) when is_list(Config) ->
+ put(verbosity, ?TEST_VERBOSITY),
+ put(sname, "TEST"),
+ put(tc, rar_paop),
+ i("starting"),
+
+ MgcNode = make_node_name(mgc),
+ MgNode = make_node_name(mg),
+ d("start nodes: "
+ "~n MgcNode: ~p"
+ "~n MgNode: ~p",
+ [MgcNode, MgNode]),
+ ok = megaco_test_lib:start_nodes([MgcNode, MgNode], ?FILE, ?LINE),
+
+ d("[MGC] start the simulator"),
+ {ok, Mgc} = megaco_test_megaco_generator:start_link("MGC", MgcNode),
+
+ d("[MGC] create the event sequence"),
+ %% MgcEvSeq = rarpaop_mgc_event_sequence(text, tcp),
+ MgcEvSeq = rarpaop_mgc_event_sequence(binary, tcp),
+
+ i("wait some time before starting the MGC simulation"),
+ sleep(1000),
+
+ d("[MGC] start the simulation"),
+ {ok, MgcId} = megaco_test_megaco_generator:exec(Mgc, MgcEvSeq),
+
+ i("wait some time before starting the MG simulator"),
+ sleep(1000),
+
+ d("[MG] start the simulator (generator)"),
+ {ok, Mg} = megaco_test_tcp_generator:start_link("MG", MgNode),
+
+ d("[MG] create the event sequence"),
+ %% MgEvSeq = rarpaop_mg_event_sequence(text, tcp),
+ MgEvSeq = rarpaop_mg_event_sequence(binary, tcp),
+
+ i("wait some time before starting the MG simulation"),
+ sleep(1000),
+
+ d("[MG] start the simulation"),
+ {ok, MgId} = megaco_test_tcp_generator:exec(Mg, MgEvSeq),
+
+ d("await the generator reply(s)"),
+ await_completion([MgcId, MgId]),
+
+ %% Tell Mgc to stop
+ i("[MGC] stop generator"),
+ megaco_test_tcp_generator:stop(Mgc),
+
+ %% Tell Mg to stop
+ i("[MG] stop generator"),
+ megaco_test_megaco_generator:stop(Mg),
+
+ i("done", []),
+ ok.
+
+
+%%
+%% MGC generator stuff
+%%
+-ifdef(megaco_hipe_special).
+-define(rarpaop_mgc_verify_handle_connect_fun(),
+ {?MODULE, rarpaop_mgc_verify_handle_connect, []}).
+-define(rarpaop_mgc_verify_service_change_req_fun(Mid),
+ {?MODULE, rarpaop_mgc_verify_service_change_req, [Mid]}).
+-define(rarpaop_mgc_verify_notify_req_fun(),
+ {?MODULE, rarpaop_mgc_verify_notify_request, []}).
+-define(rarpaop_mgc_verify_reply_ack_fun(),
+ {?MODULE, rarpaop_mgc_verify_reply_ack, []}).
+-define(rarpaop_mgc_verify_handle_disconnect_fun(),
+ {?MODULE, rarpaop_mgc_verify_handle_disconnect, []}).
+-else.
+-define(rarpaop_mgc_verify_handle_connect_fun(),
+ fun rarpaop_mgc_verify_handle_connect/1).
+-define(rarpaop_mgc_verify_service_change_req_fun(Mid),
+ rarpaop_mgc_verify_service_change_req_fun(Mid)).
+-define(rarpaop_mgc_verify_notify_req_fun(),
+ rarpaop_mgc_verify_notify_request_fun()).
+-define(rarpaop_mgc_verify_reply_ack_fun(),
+ rarpaop_mgc_verify_reply_ack_fun()).
+-define(rarpaop_mgc_verify_handle_disconnect_fun(),
+ fun rarpaop_mgc_verify_handle_disconnect/1).
+-endif.
+
+rarpaop_mgc_event_sequence(text, tcp) ->
+ Port = 2944,
+ TranspMod = megaco_tcp,
+ EncMod = megaco_pretty_text_encoder,
+ EncConf = [],
+ rarpaop_mgc_event_sequence(Port, TranspMod, EncMod, EncConf);
+rarpaop_mgc_event_sequence(binary, tcp) ->
+ Port = 2945,
+ TranspMod = megaco_tcp,
+ EncMod = megaco_ber_bin_encoder,
+ EncConf = [],
+ rarpaop_mgc_event_sequence(Port, TranspMod, EncMod, EncConf).
+
+rarpaop_mgc_event_sequence(Port, TranspMod, EncMod, EncConf) ->
+ Mid = {deviceName,"ctrl"},
+ RI = [
+ {port, Port},
+ {transport_module, TranspMod},
+ {encoding_module, EncMod},
+ {encoding_config, EncConf}
+ ],
+ ConnectVerify = ?rarpaop_mgc_verify_handle_connect_fun(),
+ ScrVerify = ?rarpaop_mgc_verify_service_change_req_fun(Mid),
+ NrVerify = ?rarpaop_mgc_verify_notify_req_fun(),
+ AckVerify = ?rarpaop_mgc_verify_reply_ack_fun(),
+ DiscoVerify = ?rarpaop_mgc_verify_handle_disconnect_fun(),
+%% ConnectVerify = fun rarpaop_mgc_verify_handle_connect/1,
+%% ScrVerify = rarpaop_mgc_verify_service_change_req_fun(Mid),
+%% NrVerify = rarpaop_mgc_verify_notify_request_fun(),
+%% AckVerify = rarpaop_mgc_verify_reply_ack_fun(),
+%% DiscoVerify = fun rarpaop_mgc_verify_handle_disconnect/1,
+ EvSeq = [
+ {debug, true},
+ {megaco_trace, disable},
+ {megaco_trace, max},
+ megaco_start,
+ {megaco_start_user, Mid, RI, []},
+ {megaco_update_user_info, sent_pending_limit, 100},
+ start_transport,
+ listen,
+ {megaco_callback, handle_connect, ConnectVerify},
+ {megaco_conn_info, all},
+ {megaco_callback, handle_trans_request, ScrVerify},
+ {megaco_callback, handle_trans_request, NrVerify},
+ {megaco_callback, handle_trans_ack, AckVerify},
+ {megaco_callback, nocall, 10000},
+ {megaco_callback, handle_disconnect, DiscoVerify},
+ megaco_stop_user,
+ megaco_stop
+ ],
+ EvSeq.
+
+%% Connect verification
+rarpaop_mgc_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
+ {ok, CH, ok};
+rarpaop_mgc_verify_handle_connect(Else) ->
+ {error, Else, ok}.
+
+%% Service Change verification
+-ifndef(megaco_hipe_special).
+rarpaop_mgc_verify_service_change_req_fun(Mid) ->
+ fun(Req) ->
+ rarpaop_mgc_verify_service_change_req(Req, Mid)
+ end.
+-endif.
+
+rarpaop_mgc_verify_service_change_req(
+ {handle_trans_request, _, ?VERSION, [AR]}, Mid) ->
+ (catch rarpaop_do_verify_service_change_req(AR, Mid));
+rarpaop_mgc_verify_service_change_req(Crap, _Mid) ->
+ ED = cre_ErrDesc(Crap),
+ ErrReply = {discard_ack, ED},
+ {error, Crap, ErrReply}.
+
+rarpaop_do_verify_service_change_req(AR, Mid) ->
+ CR =
+ case AR of
+ #'ActionRequest'{commandRequests = [CmdReq]} ->
+ CmdReq;
+ _ ->
+ Err1 = {invalid_action_request, AR},
+ ED1 = cre_ErrDesc(AR),
+ ErrReply1 = {discard_ack, ED1},
+ throw({error, Err1, ErrReply1})
+ end,
+ Cmd =
+ case CR of
+ #'CommandRequest'{command = Command} ->
+ Command;
+ _ ->
+ Err2 = {invalid_command_request, CR},
+ ED2 = cre_ErrDesc(CR),
+ ErrReply2 = {discard_ack, ED2},
+ throw({error, Err2, ErrReply2})
+ end,
+ {Tid, Parms} =
+ case Cmd of
+ {serviceChangeReq,
+ #'ServiceChangeRequest'{terminationID = [TermID],
+ serviceChangeParms = ServChParms}} ->
+ {TermID, ServChParms};
+ _ ->
+ Err3 = {invalid_command, Cmd},
+ ED3 = cre_ErrDesc(Cmd),
+ ErrReply3 = {discard_ack, ED3},
+ throw({error, Err3, ErrReply3})
+ end,
+ case Tid of
+ #megaco_term_id{contains_wildcards = false, id = ["root"]} ->
+ ok;
+ _ ->
+ Err4 = {invalid_termination_id, Tid},
+ ED4 = cre_ErrDesc(Tid),
+ ErrReply4 = {discard_ack, ED4},
+ throw({error, Err4, ErrReply4})
+ end,
+ case Parms of
+ #'ServiceChangeParm'{serviceChangeMethod = restart,
+ serviceChangeReason = [[$9,$0,$1|_]]} ->
+ AckData = [rarpaop_mgc_service_change_reply_ar(Mid, 1)],
+ Reply = {discard_ack, AckData},
+ {ok, AR, Reply};
+ _ ->
+ Err5 = {invalid_SCP, Parms},
+ ED5 = cre_ErrDesc(Parms),
+ ErrReply5 = {discard_ack, ED5},
+ {error, Err5, ErrReply5}
+ end.
+
+
+%% Notify Request verification
+-ifndef(megaco_hipe_special).
+rarpaop_mgc_verify_notify_request_fun() ->
+ fun(Req) ->
+ rarpaop_mgc_verify_notify_request(Req)
+ end.
+-endif.
+
+rarpaop_mgc_verify_notify_request({handle_trans_request, _, ?VERSION, [AR]}) ->
+ (catch rarpaop_mgc_do_verify_notify_request(AR));
+rarpaop_mgc_verify_notify_request(Crap) ->
+ ED = cre_ErrDesc(Crap),
+ ErrReply = {discard_ack, ED},
+ {error, Crap, ErrReply}.
+
+rarpaop_mgc_do_verify_notify_request(AR) ->
+ {Cid, CR} =
+ case AR of
+ #'ActionRequest'{contextId = CtxID,
+ commandRequests = [CmdReq]} ->
+ {CtxID, CmdReq};
+ _ ->
+ Err1 = {invalid_action_request, AR},
+ ED1 = cre_ErrDesc(AR),
+ ErrReply1 = {discard_ack, ED1},
+ throw({error, Err1, ErrReply1})
+ end,
+ Cmd =
+ case CR of
+ #'CommandRequest'{command = Command} ->
+ Command;
+ _ ->
+ Err2 = {invalid_command_request, CR},
+ ED2 = cre_ErrDesc(CR),
+ ErrReply2 = {discard_ack, ED2},
+ throw({error, Err2, ErrReply2})
+ end,
+ NR =
+ case Cmd of
+ {notifyReq, NotifReq} ->
+ NotifReq;
+ _ ->
+ Err3 = {invalid_command, Cmd},
+ ED3 = cre_ErrDesc(Cmd),
+ ErrReply3 = {discard_ack, ED3},
+ throw({error, Err3, ErrReply3})
+ end,
+ {Tid, OED} =
+ case NR of
+ #'NotifyRequest'{terminationID = [TermID],
+ observedEventsDescriptor = ObsEvsDesc,
+ errorDescriptor = asn1_NOVALUE} ->
+ {TermID, ObsEvsDesc};
+ _ ->
+ Err4 = {invalid_NR, NR},
+ ED4 = cre_ErrDesc(NR),
+ ErrReply4 = {discard_ack, ED4},
+ throw({error, Err4, ErrReply4})
+ end,
+ OE =
+ case OED of
+ #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
+ ObsEvLst;
+ _ ->
+ Err5 = {invalid_OED, OED},
+ ED5 = cre_ErrDesc(NR),
+ ErrReply5 = {discard_ack, ED5},
+ throw({error, Err5, ErrReply5})
+ end,
+ case OE of
+ #'ObservedEvent'{eventName = "al/of"} ->
+ AckData = notify_request_verified,
+ Replies = [rarpaop_mgc_notify_reply_ar(Cid, Tid)],
+ Reply = {{handle_pending_ack, AckData}, Replies},
+ {ok, 5000, AR, Reply};
+ _ ->
+ Err6 = {invalid_OE, OE},
+ ED6 = cre_ErrDesc(OE),
+ ErrReply6 = {discard_ack, ED6},
+ throw({error, Err6, ErrReply6})
+ end.
+
+
+%% Ack verification
+-ifndef(megaco_hipe_special).
+rarpaop_mgc_verify_reply_ack_fun() ->
+ fun(M) ->
+ rarpaop_mgc_verify_reply_ack(M)
+ end.
+-endif.
+
+rarpaop_mgc_verify_reply_ack({handle_trans_ack, _, ?VERSION, ok, _}) ->
+ io:format("rarpaop_mgc_verify_reply_ack -> ok~n", []),
+ {ok, ok, ok};
+rarpaop_mgc_verify_reply_ack({handle_trans_ack, _, ?VERSION, AS, AD} = Crap) ->
+ io:format("rarpaop_mgc_verify_reply_ack -> incorrect ack-status:"
+ "~n AS: ~p"
+ "~n AD: ~p"
+ "~n", [AS, AD]),
+ ED = cre_ErrDesc({invalid_ack_status, {AS, AD}}),
+ ErrReply = {discard_ack, ED},
+ {error, Crap, ErrReply};
+rarpaop_mgc_verify_reply_ack(Crap) ->
+ io:format("rarpaop_mgc_verify_reply_ack -> invalid ack:"
+ "~n Crap: ~p"
+ "~n", [Crap]),
+ ED = cre_ErrDesc(Crap),
+ ErrReply = {discard_ack, ED},
+ {error, Crap, ErrReply}.
+
+
+%% Disconnect verification
+rarpaop_mgc_verify_handle_disconnect({handle_disconnect, CH, ?VERSION, _R}) ->
+ {ok, CH, ok};
+rarpaop_mgc_verify_handle_disconnect(Else) ->
+ {error, Else, ok}.
+
+rarpaop_mgc_service_change_reply_ar(Mid, Cid) ->
+ SCRP = cre_serviceChangeResParm(Mid),
+ SCRes = cre_serviceChangeResult(SCRP),
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = cre_serviceChangeReply([Root], SCRes),
+ CR = cre_cmdReply(SCR),
+ AR = cre_actionReply(Cid, [CR]),
+ AR.
+
+rarpaop_mgc_notify_reply_ar(Cid, TermId) ->
+ NR = cre_notifyReply([TermId]),
+ CR = cre_cmdReply(NR),
+ cre_actionReply(Cid, [CR]).
+
+
+%%
+%% MG generator stuff
+%%
+-ifdef(megaco_hipe_special).
+-define(rarpaop_mg_decode_msg_fun(Mod, Conf),
+ {?MODULE, decode_msg, [Mod, Conf]}).
+-define(rarpaop_mg_encode_msg_fun(Mod, Conf),
+ {?MODULE, encode_msg, [Mod, Conf]}).
+-define(rarpaop_mg_verify_service_change_rep_msg_fun(),
+ {?MODULE, rarpaop_mg_verify_service_change_rep_msg, []}).
+-define(rarpaop_mg_verify_pending_msg_fun(TransId),
+ {?MODULE, rarpaop_mg_verify_pending_msg, [TransId]}).
+-define(rarpaop_mg_verify_notify_rep_msg_fun(TransId, TermId),
+ {?MODULE, rarpaop_mg_verify_notify_rep_msg, [TransId, TermId]}).
+-else.
+-define(rarpaop_mg_decode_msg_fun(Mod, Conf),
+ rarpaop_mg_decode_msg_fun(Mod, Conf)).
+-define(rarpaop_mg_encode_msg_fun(Mod, Conf),
+ rarpaop_mg_encode_msg_fun(Mod, Conf)).
+-define(rarpaop_mg_verify_service_change_rep_msg_fun(),
+ rarpaop_mg_verify_service_change_rep_msg_fun()).
+-define(rarpaop_mg_verify_pending_msg_fun(TransId),
+ rarpaop_mg_verify_pending_msg_fun(TransId)).
+-define(rarpaop_mg_verify_notify_rep_msg_fun(TransId, TermId),
+ rarpaop_mg_verify_notify_rep_msg_fun(TransId, TermId)).
+-endif.
+
+rarpaop_mg_event_sequence(text, tcp) ->
+ Port = 2944,
+ EncMod = megaco_pretty_text_encoder,
+ EncConf = [],
+ rarpaop_mg_event_sequence(Port, EncMod, EncConf);
+rarpaop_mg_event_sequence(binary, tcp) ->
+ Port = 2945,
+ EncMod = megaco_ber_bin_encoder,
+ EncConf = [],
+ rarpaop_mg_event_sequence(Port, EncMod, EncConf).
+
+rarpaop_mg_event_sequence(Port, EncMod, EncConf) ->
+ DecodeFun = ?rarpaop_mg_decode_msg_fun(EncMod, EncConf),
+ EncodeFun = ?rarpaop_mg_encode_msg_fun(EncMod, EncConf),
+ Mid = {deviceName, "mg"},
+ TransId = 2,
+ TermId = #megaco_term_id{id = ["00000000","00000000","01101101"]},
+ ServiceChangeReq = rarpaop_mg_service_change_request_msg(Mid, 1, 0),
+ NotifyReq = rarpaop_mg_notify_request_msg(Mid, TransId, 1, TermId, 1),
+ Ack = rarpaop_mg_ack_msg(Mid, TransId),
+ ScrVerifyFun = ?rarpaop_mg_verify_service_change_rep_msg_fun(),
+ PendVerifyFun = ?rarpaop_mg_verify_pending_msg_fun(TransId),
+ NrVerifyFun = ?rarpaop_mg_verify_notify_rep_msg_fun(TransId, TermId),
+%% ScrVerifyFun = rarpaop_mg_verify_service_change_rep_msg_fun(),
+%% PendVerifyFun = rarpaop_mg_verify_pending_msg_fun(TransId),
+%% NrVerifyFun = rarpaop_mg_verify_notify_rep_msg_fun(TransId, TermId),
+ EvSeq = [{debug, true},
+ {decode, DecodeFun},
+ {encode, EncodeFun},
+ {connect, Port},
+ {send, "service-change-request", ServiceChangeReq},
+ {expect_receive, "service-change-reply", {ScrVerifyFun, 10000}},
+ {send, "notify request", NotifyReq},
+ {sleep, 2000},
+ {send, "notify request", NotifyReq},
+ {expect_receive, "pending", {PendVerifyFun, 5000}},
+ {expect_receive, "notify-reply", {NrVerifyFun, 5000}},
+ {send, "reply ack", Ack},
+ {expect_nothing, 11000},
+ disconnect
+ ],
+ EvSeq.
+
+-ifndef(megaco_hipe_special).
+rarpaop_mg_encode_msg_fun(Mod, Conf) ->
+ fun(M) ->
+ encode_msg(M, Mod, Conf)
+ end.
+-endif.
+
+-ifndef(megaco_hipe_special).
+rarpaop_mg_decode_msg_fun(Mod, Conf) ->
+ fun(M) ->
+ decode_msg(M, Mod, Conf)
+ end.
+-endif.
+
+-ifndef(megaco_hipe_special).
+rarpaop_mg_verify_service_change_rep_msg_fun() ->
+ fun(Msg) ->
+ (catch rarpaop_mg_verify_service_change_rep_msg(Msg))
+ end.
+-endif.
+
+rarpaop_mg_verify_service_change_rep_msg(#'MegacoMessage'{mess = Mess} = M) ->
+ Body =
+ case Mess of
+ #'Message'{version = _V,
+ mId = _MgMid,
+ messageBody = MsgBody} ->
+ MsgBody;
+ _ ->
+ throw({error, {invalid_Message, Mess}})
+ end,
+ Trans =
+ case Body of
+ {transactions, [Transactions]} ->
+ Transactions;
+ _ ->
+ throw({error, {invalid_messageBody, Body}})
+ end,
+ TR =
+ case Trans of
+ {transactionReply, TransReply} ->
+ TransReply;
+ _ ->
+ throw({error, {invalid_transactions, Trans}})
+ end,
+ TRes =
+ case TR of
+ #'TransactionReply'{transactionId = _Tid,
+ immAckRequired = asn1_NOVALUE,
+ transactionResult = TransRes} ->
+ TransRes;
+ _ ->
+ throw({error, {invalid_transactionReply, TR}})
+ end,
+ AR =
+ case TRes of
+ {actionReplies, [ActRes]} ->
+ ActRes;
+ _ ->
+ throw({error, {invalid_transactionResult, TRes}})
+ end,
+ CR =
+ case AR of
+ #'ActionReply'{contextId = _Cid,
+ errorDescriptor = asn1_NOVALUE,
+ contextReply = _CtxReq,
+ commandReply = [CmdRep]} ->
+ CmdRep;
+ _ ->
+ throw({error, {invalid_actionReplies, AR}})
+ end,
+ SCR =
+ case CR of
+ {serviceChangeReply, ServChRep} ->
+ ServChRep;
+ _ ->
+ throw({error, {invalid_commandReply, CR}})
+ end,
+ SCRes =
+ case SCR of
+ #'ServiceChangeReply'{terminationID = _TermID,
+ serviceChangeResult = ServChRes} ->
+ ServChRes;
+ _ ->
+ throw({error, {invalid_serviceChangeReply, SCR}})
+ end,
+ SCRP =
+ case SCRes of
+ {serviceChangeResParms, Parms} ->
+ Parms;
+ _ ->
+ throw({error, {invalid_serviceChangeResult, SCRes}})
+ end,
+ case SCRP of
+ #'ServiceChangeResParm'{serviceChangeMgcId = _MgcMid} ->
+ {ok, M};
+ _ ->
+ {error, {invalid_serviceChangeResParms, SCRP}}
+ end;
+rarpaop_mg_verify_service_change_rep_msg(Crap) ->
+ {error, {invalid_message, Crap}}.
+
+-ifndef(megaco_hipe_special).
+rarpaop_mg_verify_pending_msg_fun(TransId) ->
+ fun(Msg) ->
+ (catch rarpaop_mg_verify_pending_msg(Msg, TransId))
+ end.
+-endif.
+
+rarpaop_mg_verify_pending_msg(#'MegacoMessage'{mess = Mess} = M, TransId) ->
+ Body =
+ case Mess of
+ #'Message'{version = _V,
+ mId = _MgMid,
+ messageBody = MsgBody} ->
+ MsgBody;
+ _ ->
+ throw({error, {invalid_Message, Mess}})
+ end,
+ Trans =
+ case Body of
+ {transactions, [Transactions]} ->
+ Transactions;
+ _ ->
+ throw({error, {invalid_messageBody, Body}})
+ end,
+ TP =
+ case Trans of
+ {transactionPending, TransPending} ->
+ TransPending;
+ _ ->
+ throw({error, {invalid_transactions, Trans}})
+ end,
+ case TP of
+ #'TransactionPending'{transactionId = TransId} ->
+ {ok, M};
+ _ ->
+ throw({error, {invalid_transactionPending, TP}})
+ end;
+rarpaop_mg_verify_pending_msg(Crap, _TransId) ->
+ {error, {invalid_message, Crap}}.
+
+-ifndef(megaco_hipe_special).
+rarpaop_mg_verify_notify_rep_msg_fun(TransId, TermId) ->
+ fun(Msg) ->
+ (catch rarpaop_mg_verify_notify_rep_msg(Msg, TransId, TermId))
+ end.
+-endif.
+
+rarpaop_mg_verify_notify_rep_msg(#'MegacoMessage'{mess = Mess} = M,
+ TransId, TermId) ->
+ Body =
+ case Mess of
+ #'Message'{version = _V,
+ mId = _MgMid,
+ messageBody = MsgBody} ->
+ MsgBody;
+ _ ->
+ throw({error, {invalid_Message, Mess}})
+ end,
+ Trans =
+ case Body of
+ {transactions, [Transactions]} ->
+ Transactions;
+ _ ->
+ throw({error, {invalid_messageBody, Body}})
+ end,
+ TR =
+ case Trans of
+ {transactionReply, TransReply} ->
+ TransReply;
+ _ ->
+ throw({error, {invalid_transactions, Trans}})
+ end,
+ TRes =
+ case TR of
+ #'TransactionReply'{transactionId = TransId,
+ immAckRequired = 'NULL', % Ack
+ transactionResult = TransRes} ->
+ TransRes;
+ _ ->
+ throw({error, {invalid_transactionReply, TR}})
+ end,
+ AR =
+ case TRes of
+ {actionReplies, [ActRes]} ->
+ ActRes;
+ _ ->
+ throw({error, {invalid_transactionResult, TRes}})
+ end,
+ CR =
+ case AR of
+ #'ActionReply'{contextId = _Cid,
+ errorDescriptor = asn1_NOVALUE,
+ contextReply = _CtxReq,
+ commandReply = [CmdRep]} ->
+ CmdRep;
+ _ ->
+ throw({error, {invalid_actionReplies, AR}})
+ end,
+ NR =
+ case CR of
+ {notifyReply, NotifyRep} ->
+ NotifyRep;
+ _ ->
+ throw({error, {invalid_commandReply, CR}})
+ end,
+
+ case NR of
+ #'NotifyReply'{terminationID = [TermId],
+ errorDescriptor = asn1_NOVALUE} ->
+ {ok, M};
+ #'NotifyReply'{terminationID = A,
+ errorDescriptor = B} ->
+ throw({error, {invalid_notifyReply,
+ {A, TermId},
+ {B, asn1_NOVALUE}}});
+ _ ->
+ throw({error, {invalid_notifyReply, NR}})
+ end;
+rarpaop_mg_verify_notify_rep_msg(Crap, _TransId, _TermId) ->
+ {error, {invalid_message, Crap}}.
+
+rarpaop_mg_service_change_request_ar(_Mid, Cid) ->
+ Prof = cre_serviceChangeProf("resgw", 1),
+ SCP = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = cre_serviceChangeReq([Root], SCP),
+ CMD = cre_command(SCR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+rarpaop_mg_service_change_request_msg(Mid, TransId, Cid) ->
+ AR = rarpaop_mg_service_change_request_ar(Mid, Cid),
+ TR = cre_transReq(TransId, [AR]),
+ Trans = cre_transaction(TR),
+ Mess = cre_message(?VERSION, Mid, cre_transactions([Trans])),
+ cre_megacoMessage(Mess).
+
+rarpaop_mg_ack_msg(Mid, TransId) ->
+ TR = cre_transRespAck(cre_transAck(TransId)),
+ Trans = cre_transaction(TR),
+ Mess = cre_message(?VERSION, Mid, cre_transactions([Trans])),
+ cre_megacoMessage(Mess).
+
+rarpaop_mg_notify_request_ar(Rid, Tid, Cid) ->
+ TT = cre_timeNotation("19990729", "22000000"),
+ Ev = cre_obsEvent("al/of", TT),
+ EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
+ NR = cre_notifyReq([Tid], EvsDesc),
+ CMD = cre_command(NR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+rarpaop_mg_notify_request_msg(Mid, TransId, Rid, TermId, Cid) ->
+ AR = rarpaop_mg_notify_request_ar(Rid, TermId, Cid),
+ TR = cre_transReq(TransId, [AR]),
+ Trans = cre_transaction(TR),
+ Mess = cre_message(?VERSION, Mid, cre_transactions([Trans])),
+ cre_megacoMessage(Mess).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+single_trans_req_and_reply(suite) ->
+ [];
+single_trans_req_and_reply(doc) ->
+ ["Receive a (single) transaction request and then send a "
+ "reply (discard ack). "
+ "The MGC is a megaco instance (megaco event sequence) and the "
+ "MG is emulated (tcp event sequence)"];
+single_trans_req_and_reply(Config) when is_list(Config) ->
+ put(verbosity, ?TEST_VERBOSITY),
+ put(sname, "TEST"),
+ put(tc, strar),
+ i("starting"),
+
+ MgcNode = make_node_name(mgc),
+ MgNode = make_node_name(mg),
+ d("start nodes: "
+ "~n MgcNode: ~p"
+ "~n MgNode: ~p",
+ [MgcNode, MgNode]),
+ ok = megaco_test_lib:start_nodes([MgcNode, MgNode], ?FILE, ?LINE),
+
+
+ d("[MGC] start the simulator "),
+ {ok, Mgc} = megaco_test_megaco_generator:start_link("MGC", MgcNode),
+
+ d("[MGC] create the event sequence"),
+ MgcEvSeq = strar_mgc_event_sequence(text, tcp),
+
+ i("wait some time before starting the MGC simulation"),
+ sleep(1000),
+
+ d("[MGC] start the simulation"),
+ {ok, MgcId} = megaco_test_megaco_generator:exec(Mgc, MgcEvSeq),
+
+ i("wait some time before starting the MG simulator"),
+ sleep(1000),
+
+ d("[MG] start the simulator (generator)"),
+ {ok, Mg} = megaco_test_megaco_generator:start_link("MG", MgNode),
+
+ d("[MG] create the event sequence"),
+ MgEvSeq = strar_mg_event_sequence(text, tcp),
+
+ i("wait some time before starting the MG simulation"),
+ sleep(1000),
+
+ d("[MG] start the simulation"),
+ {ok, MgId} = megaco_test_megaco_generator:exec(Mg, MgEvSeq),
+
+ d("await the generator reply(s)"),
+ await_completion([MgcId, MgId], 30000),
+
+ %% Tell Mgc to stop
+ i("[MGC] stop generator"),
+ megaco_test_megaco_generator:stop(Mgc),
+
+ %% Tell Mg to stop
+ i("[MG] stop generator"),
+ megaco_test_megaco_generator:stop(Mg),
+
+ i("done", []),
+ ok.
+
+
+%%
+%% MGC generator stuff
+%%
+-ifdef(megaco_hipe_special).
+-define(strar_mgc_verify_handle_connect_fun(),
+ {?MODULE, strar_mgc_verify_handle_connect, []}).
+-define(strar_mgc_verify_service_change_req_fun(Mid),
+ {?MODULE, strar_mgc_verify_service_change_req, [Mid]}).
+-define(strar_mgc_verify_notify_req_fun(),
+ {?MODULE, strar_mgc_verify_notify_request, []}).
+-define(strar_mgc_verify_handle_disconnect_fun(),
+ {?MODULE, strar_mgc_verify_handle_disconnect, []}).
+-else.
+-define(strar_mgc_verify_handle_connect_fun(),
+ fun strar_mgc_verify_handle_connect/1).
+-define(strar_mgc_verify_service_change_req_fun(Mid),
+ strar_mgc_verify_service_change_req_fun(Mid)).
+-define(strar_mgc_verify_notify_req_fun(),
+ strar_mgc_verify_notify_request_fun()).
+-define(strar_mgc_verify_handle_disconnect_fun(),
+ fun strar_mgc_verify_handle_disconnect/1).
+-endif.
+
+strar_mgc_event_sequence(text, tcp) ->
+ Mid = {deviceName,"ctrl"},
+ RI = [
+ {port, 2944},
+ {encoding_module, megaco_pretty_text_encoder},
+ {encoding_config, []},
+ {transport_module, megaco_tcp}
+ ],
+ %% Tid = #megaco_term_id{id = ["00000000","00000000","01101101"]},
+%% ReqTmr = #megaco_incr_timer{wait_for = 500,
+%% factor = 1,
+%% max_retries = 1},
+ ConnectVerify = ?strar_mgc_verify_handle_connect_fun(),
+ ServiceChangeReqVerify = ?strar_mgc_verify_service_change_req_fun(Mid),
+ NotifyReqVerify = ?strar_mgc_verify_notify_req_fun(),
+ DiscoVerify = ?strar_mgc_verify_handle_disconnect_fun(),
+%% ConnectVerify = fun strar_mgc_verify_handle_connect/1,
+%% ServiceChangeReqVerify = strar_mgc_verify_service_change_req_fun(Mid),
+%% NotifyReqVerify = strar_mgc_verify_notify_request_fun(),
+%% DiscoVerify = fun strar_mgc_verify_handle_disconnect/1,
+ EvSeq = [
+ {debug, true},
+ {megaco_trace, disable},
+ megaco_start,
+ {megaco_start_user, Mid, RI, []},
+ start_transport,
+ listen,
+ {megaco_callback, handle_connect, ConnectVerify},
+ {megaco_callback, handle_trans_request, ServiceChangeReqVerify},
+ {megaco_callback, handle_trans_request, NotifyReqVerify},
+ {megaco_callback, handle_disconnect, DiscoVerify},
+ {sleep, 1000},
+ megaco_stop_user,
+ megaco_stop
+ ],
+ EvSeq.
+
+
+strar_mgc_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
+ io:format("strar_mgc_verify_handle_connect -> ok"
+ "~n CH: ~p~n", [CH]),
+ {ok, CH, ok};
+strar_mgc_verify_handle_connect(Else) ->
+ io:format("strar_mgc_verify_handle_connect -> unknown"
+ "~n Else: ~p~n", [Else]),
+ {error, Else, ok}.
+
+-ifndef(megaco_hipe_special).
+strar_mgc_verify_service_change_req_fun(Mid) ->
+ fun(Req) ->
+ strar_mgc_verify_service_change_req(Req, Mid)
+ end.
+-endif.
+
+strar_mgc_verify_service_change_req(
+ {handle_trans_request, _, ?VERSION, [AR]}, Mid) ->
+ (catch strar_mgc_do_verify_service_change_req(AR, Mid));
+strar_mgc_verify_service_change_req(Crap, _Mid) ->
+ ED = cre_ErrDesc(Crap),
+ ErrReply = {discard_ack, ED},
+ {error, Crap, ErrReply}.
+
+strar_mgc_do_verify_service_change_req(AR, Mid) ->
+ io:format("strar_mgc_verify_service_change_req -> entry with"
+ "~n AR: ~p"
+ "~n Mid: ~p"
+ "~n", [AR, Mid]),
+ CR =
+ case AR of
+ #'ActionRequest'{commandRequests = [CmdReq]} ->
+ CmdReq;
+ _ ->
+ Err1 = {invalid_action_request, AR},
+ ED1 = cre_ErrDesc(AR),
+ ErrReply1 = {discard_ack, ED1},
+ throw({error, Err1, ErrReply1})
+ end,
+ Cmd =
+ case CR of
+ #'CommandRequest'{command = Command} ->
+ Command;
+ _ ->
+ Err2 = {invalid_command_request, CR},
+ ED2 = cre_ErrDesc(CR),
+ ErrReply2 = {discard_ack, ED2},
+ throw({error, Err2, ErrReply2})
+ end,
+ {Tid, Parms} =
+ case Cmd of
+ {serviceChangeReq,
+ #'ServiceChangeRequest'{terminationID = [TermID],
+ serviceChangeParms = ServChParms}} ->
+ {TermID, ServChParms};
+ _ ->
+ Err3 = {invalid_command, Cmd},
+ ED3 = cre_ErrDesc(Cmd),
+ ErrReply3 = {discard_ack, ED3},
+ throw({error, Err3, ErrReply3})
+ end,
+ case Tid of
+ #megaco_term_id{contains_wildcards = false, id = ["root"]} ->
+ ok;
+ _ ->
+ Err4 = {invalid_termination_id, Tid},
+ ED4 = cre_ErrDesc(Tid),
+ ErrReply4 = {discard_ack, ED4},
+ throw({error, Err4, ErrReply4})
+ end,
+ case Parms of
+ #'ServiceChangeParm'{serviceChangeMethod = restart,
+ serviceChangeReason = [[$9,$0,$1|_]]} ->
+ AckData = [strar_mgc_service_change_reply_ar(Mid, 1)],
+ Reply = {discard_ack, AckData},
+ {ok, AR, Reply};
+ _ ->
+ Err5 = {invalid_SCP, Parms},
+ ED5 = cre_ErrDesc(Parms),
+ ErrReply5 = {discard_ack, ED5},
+ {error, Err5, ErrReply5}
+ end.
+
+-ifndef(megaco_hipe_special).
+strar_mgc_verify_notify_request_fun() ->
+ fun(Req) ->
+ strar_mgc_verify_notify_request(Req)
+ end.
+-endif.
+
+strar_mgc_verify_notify_request({handle_trans_request, _, ?VERSION, [AR]}) ->
+ (catch strar_mgc_do_verify_notify_request(AR));
+strar_mgc_verify_notify_request(Crap) ->
+ ED = cre_ErrDesc(Crap),
+ ErrReply = {discard_ack, ED},
+ {error, Crap, ErrReply}.
+
+strar_mgc_do_verify_notify_request(AR) ->
+ io:format("strar_mgc_do_verify_notify_request -> ok"
+ "~n AR: ~p~n", [AR]),
+ {Cid, CR} =
+ case AR of
+ #'ActionRequest'{contextId = CtxID,
+ commandRequests = [CmdReq]} when (CtxID == 1) or
+ (CtxID == 2) ->
+ {CtxID, CmdReq};
+ _ ->
+ Err1 = {invalid_action_request, AR},
+ ED1 = cre_ErrDesc(AR),
+ ErrReply1 = {discard_ack, ED1},
+ throw({error, Err1, ErrReply1})
+ end,
+ Cmd =
+ case CR of
+ #'CommandRequest'{command = Command} ->
+ Command;
+ _ ->
+ Err2 = {invalid_command_request, CR},
+ ED2 = cre_ErrDesc(CR),
+ ErrReply2 = {discard_ack, ED2},
+ throw({error, Err2, ErrReply2})
+ end,
+ NR =
+ case Cmd of
+ {notifyReq, NotifReq} ->
+ NotifReq;
+ _ ->
+ Err3 = {invalid_command, Cmd},
+ ED3 = cre_ErrDesc(Cmd),
+ ErrReply3 = {discard_ack, ED3},
+ throw({error, Err3, ErrReply3})
+ end,
+ {Tid, OED} =
+ case NR of
+ #'NotifyRequest'{terminationID = [TermID],
+ observedEventsDescriptor = ObsEvsDesc,
+ errorDescriptor = asn1_NOVALUE} ->
+ {TermID, ObsEvsDesc};
+ _ ->
+ Err4 = {invalid_NR, NR},
+ ED4 = cre_ErrDesc(NR),
+ ErrReply4 = {discard_ack, ED4},
+ throw({error, Err4, ErrReply4})
+ end,
+ OE =
+ case OED of
+ #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
+ ObsEvLst;
+ _ ->
+ Err5 = {invalid_OED, OED},
+ ED5 = cre_ErrDesc(NR),
+ ErrReply5 = {discard_ack, ED5},
+ throw({error, Err5, ErrReply5})
+ end,
+ case OE of
+ #'ObservedEvent'{eventName = "al/of"} ->
+ Replies = [strar_mgc_notify_reply_ar(Cid, Tid)],
+ Reply = {discard_ack, Replies},
+ {ok, AR, Reply};
+ _ ->
+ Err6 = {invalid_OE, OE},
+ ED6 = cre_ErrDesc(OE),
+ ErrReply6 = {discard_ack, ED6},
+ {error, Err6, ErrReply6}
+ end.
+
+strar_mgc_verify_handle_disconnect({handle_disconnect, CH, ?VERSION, R}) ->
+ io:format("strar_mgc_verify_handle_disconnect -> ok"
+ "~n CH: ~p"
+ "~n R: ~p"
+ "~n", [CH, R]),
+ {ok, CH, ok};
+strar_mgc_verify_handle_disconnect(Else) ->
+ io:format("strar_mgc_verify_handle_disconnect -> unknown"
+ "~n Else: ~p~n", [Else]),
+ {error, Else, ok}.
+
+
+strar_mgc_service_change_reply_ar(Mid, Cid) ->
+ SCRP = cre_serviceChangeResParm(Mid),
+ SCRes = cre_serviceChangeResult(SCRP),
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = cre_serviceChangeReply([Root], SCRes),
+ CR = cre_cmdReply(SCR),
+ cre_actionReply(Cid, [CR]).
+
+strar_mgc_notify_reply_ar(Cid, TermId) ->
+ NR = cre_notifyReply([TermId]),
+ CR = cre_cmdReply(NR),
+ cre_actionReply(Cid, [CR]).
+
+%% strar_mgc_notify_reply(Mid, TransId, Cid, TermId) ->
+%% AR = strar_mgc_notify_reply_ar(Cid, TermId),
+%% TRes = cre_transResult([AR]),
+%% TR = cre_transReply(TransId, TRes),
+%% Trans = cre_transaction(TR),
+%% Mess = cre_message(?VERSION, Mid, cre_transactions([Trans])),
+%% cre_megacoMessage(Mess).
+
+
+%%
+%% MG generator stuff
+%%
+-ifdef(megaco_hipe_special).
+-define(strar_mg_verify_handle_connect_fun(),
+ {?MODULE, strar_mg_verify_handle_connect, []}).
+-define(strar_mg_verify_service_change_reply_fun(),
+ {?MODULE, strar_mg_verify_service_change_reply, []}).
+-define(strar_mg_verify_notify_reply_fun(),
+ {?MODULE, strar_mg_verify_notify_reply, []}).
+-else.
+-define(strar_mg_verify_handle_connect_fun(),
+ strar_mg_verify_handle_connect_fun()).
+-define(strar_mg_verify_service_change_reply_fun(),
+ strar_mg_verify_service_change_reply_fun()).
+-define(strar_mg_verify_notify_reply_fun(),
+ strar_mg_verify_notify_reply_fun()).
+-endif.
+
+strar_mg_event_sequence(text, tcp) ->
+ Mid = {deviceName, "mg"},
+ RI = [
+ {port, 2944},
+ {encoding_module, megaco_pretty_text_encoder},
+ {encoding_config, []},
+ {transport_module, megaco_tcp}
+ ],
+ ServiceChangeReq = [strar_mg_service_change_request_ar(Mid, 1)],
+ Tid = #megaco_term_id{id = ["00000000","00000000","01101101"]},
+ NR = fun(Cid, Rid) ->
+ [strar_mg_notify_request_ar(Rid, Tid, Cid)]
+ end,
+ ConnectVerify = ?strar_mg_verify_handle_connect_fun(),
+ ServiceChangeReplyVerify = ?strar_mg_verify_service_change_reply_fun(),
+ NotifyReplyVerify = ?strar_mg_verify_notify_reply_fun(),
+%% ConnectVerify = strar_mg_verify_handle_connect_fun(),
+%% ServiceChangeReplyVerify = strar_mg_verify_service_change_reply_fun(),
+%% NotifyReplyVerify = fun strar_mg_verify_notify_reply/1,
+ EvSeq = [
+ {debug, true},
+ megaco_start,
+ {megaco_start_user, Mid, RI, []},
+ start_transport,
+ {megaco_trace, disable},
+ {megaco_system_info, users},
+ {megaco_system_info, connections},
+ connect,
+ {megaco_callback, handle_connect, ConnectVerify},
+ megaco_connect,
+ {megaco_cast, ServiceChangeReq, []},
+ {megaco_callback, handle_connect, ConnectVerify},
+ {megaco_callback, handle_trans_reply, ServiceChangeReplyVerify},
+ {sleep, 1000},
+ {megaco_system_info, users},
+ {megaco_system_info, connections},
+ {sleep, 1000},
+ {megaco_conn_info, all},
+ {megaco_cast, NR(1,1), []},
+ {megaco_callback, handle_trans_reply, NotifyReplyVerify},
+ {sleep, 3000},
+ megaco_stop_user,
+ megaco_stop,
+ {sleep, 1000}
+ ],
+ EvSeq.
+
+-ifndef(megaco_hipe_special).
+strar_mg_verify_handle_connect_fun() ->
+ fun(Ev) ->
+ strar_mg_verify_handle_connect(Ev)
+ end.
+-endif.
+
+strar_mg_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
+ io:format("strar_mg_verify_handle_connect -> ok"
+ "~n CH: ~p~n", [CH]),
+ {ok, CH, ok};
+strar_mg_verify_handle_connect(Else) ->
+ io:format("strar_mg_verify_handle_connect -> unknown"
+ "~n Else: ~p~n", [Else]),
+ {error, Else, ok}.
+
+-ifndef(megaco_hipe_special).
+strar_mg_verify_service_change_reply_fun() ->
+ fun(Rep) ->
+ strar_mg_verify_service_change_reply(Rep)
+ end.
+-endif.
+
+strar_mg_verify_service_change_reply(
+ {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _}) ->
+ (catch strar_mg_do_verify_service_change_reply(AR));
+strar_mg_verify_service_change_reply(Crap) ->
+ {error, Crap, ok}.
+
+strar_mg_do_verify_service_change_reply(AR) ->
+ io:format("strar_mg_verify_service_change_reply -> ok"
+ "~n AR: ~p~n", [AR]),
+ CR =
+ case AR of
+ #'ActionReply'{commandReply = [CmdRep]} ->
+ CmdRep;
+ _ ->
+ Reason1 = {invalid_action_reply, AR},
+ throw({error, Reason1, ok})
+ end,
+ SCR =
+ case CR of
+ {serviceChangeReply, ServChRep} ->
+ ServChRep;
+ _ ->
+ Reason2 = {invalid_command_reply, CR},
+ throw({error, Reason2, ok})
+ end,
+ {Tid, SCRes} =
+ case SCR of
+ #'ServiceChangeReply'{terminationID = [TermID],
+ serviceChangeResult = Res} ->
+ {TermID, Res};
+ _ ->
+ Reason3 = {invalid_service_change_reply, SCR},
+ throw({error, Reason3, ok})
+ end,
+ case Tid of
+ #megaco_term_id{contains_wildcards = false, id = ["root"]} ->
+ ok;
+ _ ->
+ Reason4 = {invalid_termination_id, Tid},
+ throw({error, Reason4, ok})
+ end,
+ SCRParm =
+ case SCRes of
+ {serviceChangeResParms, ServChResParms} ->
+ ServChResParms;
+ _ ->
+ Reason5 = {invalid_serviceChangeResult, SCRes},
+ throw({error, Reason5, ok})
+ end,
+ case SCRParm of
+ #'ServiceChangeResParm'{serviceChangeMgcId = _RemoteMid} ->
+ {ok, AR, ok};
+ _ ->
+ Reason6 = {invalid_service_change_result, SCRParm},
+ {error, Reason6, ok}
+ end.
+
+-ifndef(megaco_hipe_special).
+strar_mg_verify_notify_reply_fun() ->
+ fun(Rep) ->
+ strar_mg_verify_notify_reply(Rep)
+ end.
+-endif.
+
+strar_mg_verify_notify_reply({handle_trans_reply, _CH, ?VERSION,
+ {ok, [AR]}, _}) ->
+ io:format("strar_mg_verify_notify_reply -> ok"
+ "~n AR: ~p~n", [AR]),
+ {ok, AR, ok};
+strar_mg_verify_notify_reply(Else) ->
+ io:format("strar_mg_verify_notify_reply -> unknown"
+ "~n Else: ~p~n", [Else]),
+ {error, Else, ok}.
+
+strar_mg_service_change_request_ar(_Mid, Cid) ->
+ Prof = cre_serviceChangeProf("resgw", 1),
+ SCP = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = cre_serviceChangeReq([Root], SCP),
+ CMD = cre_command(SCR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+strar_mg_notify_request_ar(Rid, Tid, Cid) ->
+ TT = cre_timeNotation("19990729", "22000000"),
+ Ev = cre_obsEvent("al/of", TT),
+ EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
+ NR = cre_notifyReq([Tid], EvsDesc),
+ CMD = cre_command(NR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+single_trans_req_and_reply_sendopts(suite) ->
+ [];
+single_trans_req_and_reply_sendopts(doc) ->
+ ["Receive a (single) transaction request and then send a "
+ "reply with handle_ack and a reply_timer in sendoptions. "
+ "The MGC is a megaco instance (megaco event sequence) and the "
+ "MG is emulated (tcp event sequence)"];
+single_trans_req_and_reply_sendopts(Config) when is_list(Config) ->
+ %% <CONDITIONAL-SKIP>
+ Skippable = [{unix, [darwin, linux]}],
+ Condition = fun() -> ?OS_BASED_SKIP(Skippable) end,
+ ?NON_PC_TC_MAYBE_SKIP(Config, Condition),
+ %% </CONDITIONAL-SKIP>
+
+ put(verbosity, ?TEST_VERBOSITY),
+ put(sname, "TEST"),
+ put(tc, straro),
+ i("starting"),
+
+ MgcNode = make_node_name(mgc),
+ MgNode = make_node_name(mg),
+ d("start nodes: "
+ "~n MgcNode: ~p"
+ "~n MgNode: ~p",
+ [MgcNode, MgNode]),
+ ok = megaco_test_lib:start_nodes([MgcNode, MgNode], ?FILE, ?LINE),
+
+
+ d("[MGC] start the simulator "),
+ {ok, Mgc} = megaco_test_megaco_generator:start_link("MGC", MgcNode),
+
+ d("[MGC] create the event sequence"),
+ MgcEvSeq = straro_mgc_event_sequence(text, tcp),
+
+ i("wait some time before starting the MGC simulation"),
+ sleep(1000),
+
+ d("[MGC] start the simulation"),
+ {ok, MgcId} = megaco_test_megaco_generator:exec(Mgc, MgcEvSeq),
+
+ i("wait some time before starting the MG simulator"),
+ sleep(1000),
+
+ d("[MG] start the simulator (generator)"),
+ {ok, Mg} = megaco_test_megaco_generator:start_link("MG", MgNode),
+
+ d("[MG] create the event sequence"),
+ MgEvSeq = straro_mg_event_sequence(text, tcp),
+
+ i("wait some time before starting the MG simulation"),
+ sleep(1000),
+
+ d("[MG] start the simulation"),
+ {ok, MgId} = megaco_test_megaco_generator:exec(Mg, MgEvSeq),
+
+ d("await the generator reply(s)"),
+ await_completion([MgcId, MgId], 30000),
+
+ %% Tell Mgc to stop
+ i("[MGC] stop generator"),
+ megaco_test_megaco_generator:stop(Mgc),
+
+ %% Tell Mg to stop
+ i("[MG] stop generator"),
+ megaco_test_megaco_generator:stop(Mg),
+
+ i("done", []),
+ ok.
+
+
+%%
+%% MGC generator stuff
+%%
+-ifdef(megaco_hipe_special).
+-define(straro_mgc_verify_handle_connect_fun(),
+ {?MODULE, straro_mgc_verify_handle_connect, []}).
+-define(straro_mgc_verify_service_change_req_fun(Mid),
+ {?MODULE, straro_mgc_verify_service_change_req, [Mid]}).
+-define(straro_mgc_verify_notify_req_fun(),
+ {?MODULE, straro_mgc_verify_notify_request, []}).
+-define(straro_mgc_verify_handle_trans_ack_fun(),
+ {?MODULE, straro_mgc_verify_handle_trans_ack, []}).
+-else.
+-define(straro_mgc_verify_handle_connect_fun(),
+ fun straro_mgc_verify_handle_connect/1).
+-define(straro_mgc_verify_service_change_req_fun(Mid),
+ straro_mgc_verify_service_change_req_fun(Mid)).
+-define(straro_mgc_verify_notify_req_fun(),
+ straro_mgc_verify_notify_request_fun()).
+-define(straro_mgc_verify_handle_trans_ack_fun(),
+ straro_mgc_verify_handle_trans_ack_fun()).
+-endif.
+
+straro_mgc_event_sequence(text, tcp) ->
+ Mid = {deviceName,"ctrl"},
+ RI = [
+ {port, 2944},
+ {encoding_module, megaco_pretty_text_encoder},
+ {encoding_config, []},
+ {transport_module, megaco_tcp}
+ ],
+ ConnectVerify = ?straro_mgc_verify_handle_connect_fun(),
+ ServiceChangeReqVerify = ?straro_mgc_verify_service_change_req_fun(Mid),
+ NotifyReqVerify = ?straro_mgc_verify_notify_req_fun(),
+ TransAckVerify = ?straro_mgc_verify_handle_trans_ack_fun(),
+%% ConnectVerify = fun straro_mgc_verify_handle_connect/1,
+%% ServiceChangeReqVerify = straro_mgc_verify_service_change_req_fun(Mid),
+%% NotifyReqVerify = straro_mgc_verify_notify_request_fun(),
+%% TransAckVerify = straro_mgc_verify_handle_trans_ack_fun(),
+ EvSeq = [
+ {debug, true},
+ {megaco_trace, disable},
+ megaco_start,
+ {megaco_start_user, Mid, RI, []},
+ start_transport,
+ listen,
+ {megaco_callback, handle_connect, ConnectVerify},
+ {megaco_callback, handle_trans_request, ServiceChangeReqVerify},
+ {megaco_callback, handle_trans_request, NotifyReqVerify},
+ {megaco_callback, handle_trans_ack, TransAckVerify},
+ megaco_stop_user,
+ megaco_stop
+ ],
+ EvSeq.
+
+
+straro_mgc_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
+ io:format("straro_mgc_verify_handle_connect -> ok"
+ "~n CH: ~p~n", [CH]),
+ {ok, CH, ok};
+straro_mgc_verify_handle_connect(Else) ->
+ io:format("straro_mgc_verify_handle_connect -> unknown"
+ "~n Else: ~p~n", [Else]),
+ {error, Else, ok}.
+
+-ifndef(megaco_hipe_special).
+straro_mgc_verify_service_change_req_fun(Mid) ->
+ fun(Req) ->
+ straro_mgc_verify_service_change_req(Req, Mid)
+ end.
+-endif.
+
+straro_mgc_verify_service_change_req(
+ {handle_trans_request, _, ?VERSION, [AR]}, Mid) ->
+ (catch straro_mgc_do_verify_service_change_req(AR, Mid));
+straro_mgc_verify_service_change_req(Crap, _Mid) ->
+ ED = cre_ErrDesc(Crap),
+ ErrReply = {discard_ack, ED},
+ {error, Crap, ErrReply}.
+
+straro_mgc_do_verify_service_change_req(AR, Mid) ->
+ io:format("straro_mgc_do_verify_service_change_req -> ok"
+ "~n AR: ~p~n", [AR]),
+ CR =
+ case AR of
+ #'ActionRequest'{commandRequests = [CmdReq]} ->
+ CmdReq;
+ _ ->
+ Err1 = {invalid_action_request, AR},
+ ED1 = cre_ErrDesc(AR),
+ ErrReply1 = {discard_ack, ED1},
+ throw({error, Err1, ErrReply1})
+ end,
+ Cmd =
+ case CR of
+ #'CommandRequest'{command = Command} ->
+ Command;
+ _ ->
+ Err2 = {invalid_command_request, CR},
+ ED2 = cre_ErrDesc(CR),
+ ErrReply2 = {discard_ack, ED2},
+ throw({error, Err2, ErrReply2})
+ end,
+ {Tid, Parms} =
+ case Cmd of
+ {serviceChangeReq,
+ #'ServiceChangeRequest'{terminationID = [TermID],
+ serviceChangeParms = ServChParms}} ->
+ {TermID, ServChParms};
+ _ ->
+ Err3 = {invalid_command, Cmd},
+ ED3 = cre_ErrDesc(Cmd),
+ ErrReply3 = {discard_ack, ED3},
+ throw({error, Err3, ErrReply3})
+ end,
+ case Tid of
+ #megaco_term_id{contains_wildcards = false, id = ["root"]} ->
+ ok;
+ _ ->
+ Err4 = {invalid_termination_id, Tid},
+ ED4 = cre_ErrDesc(Tid),
+ ErrReply4 = {discard_ack, ED4},
+ throw({error, Err4, ErrReply4})
+ end,
+ case Parms of
+ #'ServiceChangeParm'{serviceChangeMethod = restart,
+ serviceChangeReason = [[$9,$0,$1|_]]} ->
+ AckData = [straro_mgc_service_change_reply_ar(Mid, 1)],
+ Reply = {discard_ack, AckData},
+ {ok, AR, Reply};
+ _ ->
+ Err5 = {invalid_SCP, Parms},
+ ED5 = cre_ErrDesc(Parms),
+ ErrReply5 = {discard_ack, ED5},
+ {error, Err5, ErrReply5}
+ end.
+
+-ifndef(megaco_hipe_special).
+straro_mgc_verify_notify_request_fun() ->
+ fun(Req) ->
+ straro_mgc_verify_notify_request(Req)
+ end.
+-endif.
+
+straro_mgc_verify_notify_request({handle_trans_request, _, ?VERSION, [AR]}) ->
+ (catch straro_mgc_do_verify_notify_request(AR));
+straro_mgc_verify_notify_request(Crap) ->
+ ED = cre_ErrDesc(Crap),
+ ErrReply = {discard_ack, ED},
+ {error, Crap, ErrReply}.
+
+straro_mgc_do_verify_notify_request(AR) ->
+ io:format("straro_mgc_do_verify_notify_request -> ok"
+ "~n AR: ~p~n", [AR]),
+ {Cid, CR} =
+ case AR of
+ #'ActionRequest'{contextId = CtxID,
+ commandRequests = [CmdReq]} when (CtxID == 1) or
+ (CtxID == 2) ->
+ {CtxID, CmdReq};
+ _ ->
+ Err1 = {invalid_action_request, AR},
+ ED1 = cre_ErrDesc(AR),
+ ErrReply1 = {discard_ack, ED1},
+ throw({error, Err1, ErrReply1})
+ end,
+ Cmd =
+ case CR of
+ #'CommandRequest'{command = Command} ->
+ Command;
+ _ ->
+ Err2 = {invalid_command_request, CR},
+ ED2 = cre_ErrDesc(CR),
+ ErrReply2 = {discard_ack, ED2},
+ throw({error, Err2, ErrReply2})
+ end,
+ NR =
+ case Cmd of
+ {notifyReq, NotifReq} ->
+ NotifReq;
+ _ ->
+ Err3 = {invalid_command, Cmd},
+ ED3 = cre_ErrDesc(Cmd),
+ ErrReply3 = {discard_ack, ED3},
+ throw({error, Err3, ErrReply3})
+ end,
+ {Tid, OED} =
+ case NR of
+ #'NotifyRequest'{terminationID = [TermID],
+ observedEventsDescriptor = ObsEvsDesc,
+ errorDescriptor = asn1_NOVALUE} ->
+ {TermID, ObsEvsDesc};
+ _ ->
+ Err4 = {invalid_NR, NR},
+ ED4 = cre_ErrDesc(NR),
+ ErrReply4 = {discard_ack, ED4},
+ throw({error, Err4, ErrReply4})
+ end,
+ OE =
+ case OED of
+ #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
+ ObsEvLst;
+ _ ->
+ Err5 = {invalid_OED, OED},
+ ED5 = cre_ErrDesc(NR),
+ ErrReply5 = {discard_ack, ED5},
+ throw({error, Err5, ErrReply5})
+ end,
+ case OE of
+ #'ObservedEvent'{eventName = "al/of"} ->
+ Replies = [straro_mgc_notify_reply_ar(Cid, Tid)],
+ SendOpts = [{protocol_version, 99}],
+ Reply = {{handle_ack, get(tc)}, Replies, SendOpts},
+ {ok, AR, Reply};
+ _ ->
+ Err6 = {invalid_OE, OE},
+ ED6 = cre_ErrDesc(OE),
+ ErrReply6 = {discard_ack, ED6},
+ {error, Err6, ErrReply6}
+ end.
+
+-ifndef(megaco_hipe_special).
+straro_mgc_verify_handle_trans_ack_fun() ->
+ fun(Ack) ->
+ straro_mgc_verify_handle_trans_ack(Ack)
+ end.
+-endif.
+
+straro_mgc_verify_handle_trans_ack(
+ {handle_trans_ack, _CH, ?VERSION, AS, _AD}) ->
+ (catch straro_mgc_do_verify_handle_trans_ack(AS));
+straro_mgc_verify_handle_trans_ack(Crap) ->
+ io:format("straro_mgc_verify_handle_trans_ack -> entry with"
+ "~n Crap: ~p"
+ "~n", [Crap]),
+ {error, Crap, ok}.
+
+straro_mgc_do_verify_handle_trans_ack({error, {EM, EF, [EC, Version, Msg], Reason}}) ->
+ io:format("straro_mgc_do_handle_verify_handle_trans_ack -> entry with"
+ "~n EM: ~p"
+ "~n EF: ~p"
+ "~n EC: ~p"
+ "~n Version: ~p"
+ "~n Msg: ~p"
+ "~n Reason: ~p"
+ "~n", [EM, EF, EC, Version, Msg, Reason]),
+ case Reason of
+ {bad_version, 99} ->
+ {ok, Reason, ok};
+ _ ->
+ {error, {unexpected_reason, Reason}, ok}
+ end;
+straro_mgc_do_verify_handle_trans_ack(Else) ->
+ io:format("straro_mgc_verify_handle_trans_ack -> unknown"
+ "~n Else: ~p"
+ "~n", [Else]),
+ {error, Else, ok}.
+
+%% straro_mgc_verify_handle_disconnect({handle_disconnect, CH, ?VERSION, R}) ->
+%% io:format("straro_mgc_verify_handle_disconnect -> ok"
+%% "~n CH: ~p"
+%% "~n R: ~p"
+%% "~n", [CH, R]),
+%% {ok, CH, ok};
+%% straro_mgc_verify_handle_disconnect(Else) ->
+%% io:format("straro_mgc_verify_handle_disconnect -> unknown"
+%% "~n Else: ~p~n", [Else]),
+%% {error, Else, ok}.
+
+
+straro_mgc_service_change_reply_ar(Mid, Cid) ->
+ SCRP = cre_serviceChangeResParm(Mid),
+ SCRes = cre_serviceChangeResult(SCRP),
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = cre_serviceChangeReply([Root], SCRes),
+ CR = cre_cmdReply(SCR),
+ cre_actionReply(Cid, [CR]).
+
+straro_mgc_notify_reply_ar(Cid, TermId) ->
+ NR = cre_notifyReply([TermId]),
+ CR = cre_cmdReply(NR),
+ cre_actionReply(Cid, [CR]).
+
+%% straro_mgc_notify_reply(Mid, TransId, Cid, TermId) ->
+%% AR = straro_mgc_notify_reply_ar(Cid, TermId),
+%% TRes = cre_transResult([AR]),
+%% TR = cre_transReply(TransId, TRes),
+%% Trans = cre_transaction(TR),
+%% Mess = cre_message(?VERSION, Mid, cre_transactions([Trans])),
+%% cre_megacoMessage(Mess).
+
+
+%%
+%% MG generator stuff
+%%
+-ifdef(megaco_hipe_special).
+-define(straro_mg_verify_handle_connect_fun(),
+ {?MODULE, straro_mg_verify_handle_connect, []}).
+-define(straro_mg_verify_service_change_reply_fun(),
+ {?MODULE, straro_mg_verify_service_change_reply, []}).
+-define(straro_mg_verify_handle_disconnect_fun(),
+ {?MODULE, straro_mg_verify_handle_disconnect, []}).
+-else.
+-define(straro_mg_verify_handle_connect_fun(),
+ straro_mg_verify_handle_connect_fun()).
+-define(straro_mg_verify_service_change_reply_fun(),
+ straro_mg_verify_service_change_reply_fun()).
+-define(straro_mg_verify_handle_disconnect_fun(),
+ fun straro_mg_verify_handle_disconnect/1).
+-endif.
+
+straro_mg_event_sequence(text, tcp) ->
+ Mid = {deviceName, "mg"},
+ RI = [
+ {port, 2944},
+ {encoding_module, megaco_pretty_text_encoder},
+ {encoding_config, []},
+ {transport_module, megaco_tcp}
+ ],
+ ServiceChangeReq = [straro_mg_service_change_request_ar(Mid, 1)],
+ Tid = #megaco_term_id{id = ["00000000","00000000","01101101"]},
+ NR = fun(Cid, Rid) ->
+ [straro_mg_notify_request_ar(Rid, Tid, Cid)]
+ end,
+ ConnectVerify = ?straro_mg_verify_handle_connect_fun(),
+ ServiceChangeReplyVerify = ?straro_mg_verify_service_change_reply_fun(),
+ DiscoVerify = ?straro_mg_verify_handle_disconnect_fun(),
+%% ConnectVerify = straro_mg_verify_handle_connect_fun(),
+%% DiscoVerify = fun straro_mg_verify_handle_disconnect/1,
+%% ServiceChangeReplyVerify = straro_mg_verify_service_change_reply_fun(),
+ EvSeq = [
+ {debug, true},
+ megaco_start,
+ {megaco_start_user, Mid, RI, []},
+ start_transport,
+ {megaco_trace, disable},
+ {megaco_system_info, users},
+ {megaco_system_info, connections},
+ connect,
+ {megaco_callback, handle_connect, ConnectVerify},
+ megaco_connect,
+ {megaco_cast, ServiceChangeReq, []},
+ {megaco_callback, handle_connect, ConnectVerify},
+ {megaco_callback, handle_trans_reply, ServiceChangeReplyVerify},
+ {sleep, 1000},
+ {megaco_system_info, users},
+ {megaco_system_info, connections},
+ {sleep, 1000},
+ {megaco_conn_info, all},
+ {megaco_cast, NR(1,1), []},
+ {megaco_callback, handle_disconnect, DiscoVerify},
+ megaco_stop_user,
+ megaco_stop,
+ {sleep, 1000}
+ ],
+ EvSeq.
+
+-ifndef(megaco_hipe_special).
+straro_mg_verify_handle_connect_fun() ->
+ fun(Ev) ->
+ straro_mg_verify_handle_connect(Ev)
+ end.
+-endif.
+
+straro_mg_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
+ io:format("straro_mg_verify_handle_connect -> ok"
+ "~n CH: ~p~n", [CH]),
+ {ok, CH, ok};
+straro_mg_verify_handle_connect(Else) ->
+ io:format("straro_mg_verify_handle_connect -> unknown"
+ "~n Else: ~p~n", [Else]),
+ {error, Else, ok}.
+
+straro_mg_verify_handle_disconnect({handle_disconnect, CH, ?VERSION, R}) ->
+ io:format("straro_mg_verify_handle_disconnect -> ok"
+ "~n CH: ~p"
+ "~n R: ~p"
+ "~n", [CH, R]),
+ {ok, CH, ok};
+straro_mg_verify_handle_disconnect(Else) ->
+ io:format("straro_mg_verify_handle_disconnect -> unknown"
+ "~n Else: ~p~n", [Else]),
+ {error, Else, ok}.
+
+
+-ifndef(megaco_hipe_special).
+straro_mg_verify_service_change_reply_fun() ->
+ fun(Rep) ->
+ straro_mg_verify_service_change_reply(Rep)
+ end.
+-endif.
+
+straro_mg_verify_service_change_reply(
+ {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _}) ->
+ (catch straro_mg_do_verify_service_change_reply(AR));
+straro_mg_verify_service_change_reply(Crap) ->
+ {error, Crap, ok}.
+
+straro_mg_do_verify_service_change_reply(AR) ->
+ io:format("straro_mg_verify_service_change_reply -> ok"
+ "~n AR: ~p~n", [AR]),
+ CR =
+ case AR of
+ #'ActionReply'{commandReply = [CmdRep]} ->
+ CmdRep;
+ _ ->
+ Reason1 = {invalid_action_reply, AR},
+ throw({error, Reason1, ok})
+ end,
+ SCR =
+ case CR of
+ {serviceChangeReply, ServChRep} ->
+ ServChRep;
+ _ ->
+ Reason2 = {invalid_command_reply, CR},
+ throw({error, Reason2, ok})
+ end,
+ {Tid, SCRes} =
+ case SCR of
+ #'ServiceChangeReply'{terminationID = [TermID],
+ serviceChangeResult = Res} ->
+ {TermID, Res};
+ _ ->
+ Reason3 = {invalid_service_change_reply, SCR},
+ throw({error, Reason3, ok})
+ end,
+ case Tid of
+ #megaco_term_id{contains_wildcards = false, id = ["root"]} ->
+ ok;
+ _ ->
+ Reason4 = {invalid_termination_id, Tid},
+ throw({error, Reason4, ok})
+ end,
+ SCRParm =
+ case SCRes of
+ {serviceChangeResParms, ServChResParms} ->
+ ServChResParms;
+ _ ->
+ Reason5 = {invalid_serviceChangeResult, SCRes},
+ throw({error, Reason5, ok})
+ end,
+ case SCRParm of
+ #'ServiceChangeResParm'{serviceChangeMgcId = _RemoteMid} ->
+ {ok, AR, ok};
+ _ ->
+ Reason6 = {invalid_service_change_result, SCRParm},
+ {error, Reason6, ok}
+ end.
+
+%% -ifndef(megaco_hipe_special).
+%% straro_mg_verify_notify_reply_fun() ->
+%% fun(Rep) ->
+%% straro_mg_verify_notify_reply(Rep)
+%% end.
+%% -endif.
+
+%% straro_mg_verify_notify_reply({handle_trans_reply, _CH, ?VERSION,
+%% {ok, [AR]}, _}) ->
+%% io:format("straro_mg_verify_notify_reply -> ok"
+%% "~n AR: ~p~n", [AR]),
+%% {ok, AR, ok};
+%% straro_mg_verify_notify_reply(Else) ->
+%% io:format("straro_mg_verify_notify_reply -> unknown"
+%% "~n Else: ~p~n", [Else]),
+%% {error, Else, ok}.
+
+straro_mg_service_change_request_ar(_Mid, Cid) ->
+ Prof = cre_serviceChangeProf("resgw", 1),
+ SCP = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = cre_serviceChangeReq([Root], SCP),
+ CMD = cre_command(SCR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+straro_mg_notify_request_ar(Rid, Tid, Cid) ->
+ TT = cre_timeNotation("19990729", "22000000"),
+ Ev = cre_obsEvent("al/of", TT),
+ EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
+ NR = cre_notifyReq([Tid], EvsDesc),
+ CMD = cre_command(NR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+request_and_reply_and_ack(suite) ->
+ [];
+request_and_reply_and_ack(doc) ->
+ ["This test case tests that megaco correctly handles three-way-handshake"];
+request_and_reply_and_ack(Config) when is_list(Config) ->
+ put(verbosity, ?TEST_VERBOSITY),
+ put(sname, "TEST"),
+ put(tc, raraa),
+ i("starting"),
+
+ MgcNode = make_node_name(mgc),
+ MgNode = make_node_name(mg),
+ d("start nodes: "
+ "~n MgcNode: ~p"
+ "~n MgNode: ~p",
+ [MgcNode, MgNode]),
+ ok = megaco_test_lib:start_nodes([MgcNode, MgNode], ?FILE, ?LINE),
+
+ d("[MGC] start the simulator "),
+ {ok, Mgc} = megaco_test_megaco_generator:start_link("MGC", MgcNode),
+
+ d("[MGC] create the event sequence"),
+ MgcEvSeq = raraa_mgc_event_sequence(text, tcp),
+
+ i("wait some time before starting the MGC simulation"),
+ sleep(1000),
+
+ d("[MGC] start the simulation"),
+ {ok, MgcId} = megaco_test_megaco_generator:exec(Mgc, MgcEvSeq),
+
+ i("wait some time before starting the MG simulator"),
+ sleep(1000),
+
+ d("[MG] start the simulator (generator)"),
+ {ok, Mg} = megaco_test_tcp_generator:start_link("MG", MgNode),
+
+ d("[MG] create the event sequence"),
+ MgEvSeq = raraa_mg_event_sequence(text, tcp),
+
+ i("wait some time before starting the MG simulation"),
+ sleep(1000),
+
+ d("[MG] start the simulation"),
+ {ok, MgId} = megaco_test_tcp_generator:exec(Mg, MgEvSeq),
+
+ d("await the generator reply(s)"),
+ await_completion([MgcId, MgId]),
+
+ %% Tell Mgc to stop
+ i("[MGC] stop generator"),
+ megaco_test_megaco_generator:stop(Mgc),
+
+ %% Tell Mg to stop
+ i("[MG] stop generator"),
+ megaco_test_tcp_generator:stop(Mg),
+
+ i("done", []),
+ ok.
+
+
+%%
+%% MGC generator stuff
+%%
+
+-ifdef(megaco_hipe_special).
+-define(raraa_mgc_verify_handle_connect_fun(),
+ {?MODULE, raraa_mgc_verify_handle_connect, []}).
+-define(raraa_mgc_verify_service_change_req_fun(Mid),
+ {?MODULE, raraa_mgc_verify_service_change_req, [Mid]}).
+-define(raraa_mgc_verify_notify_req_fun(),
+ {?MODULE, raraa_mgc_verify_notify_req, []}).
+-define(raraa_mgc_verify_handle_trans_ack_fun(),
+ {?MODULE, raraa_mgc_verify_handle_trans_ack, []}).
+-define(raraa_mgc_verify_handle_disconnect_fun(),
+ {?MODULE, raraa_mgc_verify_handle_disconnect, []}).
+-else.
+-define(raraa_mgc_verify_handle_connect_fun(),
+ fun raraa_mgc_verify_handle_connect/1).
+-define(raraa_mgc_verify_service_change_req_fun(Mid),
+ raraa_mgc_verify_service_change_req_fun(Mid)).
+-define(raraa_mgc_verify_notify_req_fun(),
+ raraa_mgc_verify_notify_req_fun()).
+-define(raraa_mgc_verify_handle_trans_ack_fun(),
+ raraa_mgc_verify_handle_trans_ack_fun()).
+-define(raraa_mgc_verify_handle_disconnect_fun(),
+ fun raraa_mgc_verify_handle_disconnect/1).
+-endif.
+
+raraa_mgc_event_sequence(text, tcp) ->
+ Mid = {deviceName,"ctrl"},
+ RI = [
+ {port, 2944},
+ {encoding_module, megaco_pretty_text_encoder},
+ {encoding_config, []},
+ {transport_module, megaco_tcp}
+ ],
+ ConnectVerify = ?raraa_mgc_verify_handle_connect_fun(),
+ ScrVerify = ?raraa_mgc_verify_service_change_req_fun(Mid),
+ NrVerify = ?raraa_mgc_verify_notify_req_fun(),
+ AckVerify = ?raraa_mgc_verify_handle_trans_ack_fun(),
+ DiscoVerify = ?raraa_mgc_verify_handle_disconnect_fun(),
+%% ConnectVerify = fun raraa_mgc_verify_handle_connect/1,
+%% ScrVerify = raraa_mgc_verify_service_change_req_fun(Mid),
+%% NrVerify = raraa_mgc_verify_notify_request_fun(),
+%% AckVerify = raraa_mgc_verify_trans_ack_fun(),
+%% DiscoVerify = fun raraa_mgc_verify_handle_disconnect/1,
+ EvSeq = [
+ {debug, true},
+ {megaco_trace, disable},
+ {megaco_trace, max},
+ megaco_start,
+ {megaco_start_user, Mid, RI, []},
+ {megaco_update_user_info, sent_pending_limit, 100},
+ start_transport,
+ listen,
+ {megaco_callback, handle_connect, ConnectVerify},
+ {megaco_conn_info, all},
+ {megaco_callback, handle_trans_request, ScrVerify},
+ {megaco_callback, handle_trans_request, NrVerify},
+ {megaco_callback, handle_trans_ack, AckVerify},
+ {megaco_callback, handle_disconnect, DiscoVerify},
+ megaco_stop_user,
+ megaco_stop
+ ],
+ EvSeq.
+
+%% Connect verification
+raraa_mgc_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
+ {ok, CH, ok};
+raraa_mgc_verify_handle_connect(Else) ->
+ {error, Else, ok}.
+
+%% Service Change verification
+-ifndef(megaco_hipe_special).
+raraa_mgc_verify_service_change_req_fun(Mid) ->
+ fun(Req) ->
+ raraa_mgc_verify_service_change_req(Req, Mid)
+ end.
+-endif.
+
+raraa_mgc_verify_service_change_req(
+ {handle_trans_request, _, ?VERSION, [AR]}, Mid) ->
+ (catch raraa_do_verify_service_change_req(AR, Mid));
+raraa_mgc_verify_service_change_req(Crap, _Mid) ->
+ ED = cre_ErrDesc(Crap),
+ ErrReply = {discard_ack, ED},
+ {error, Crap, ErrReply}.
+
+raraa_do_verify_service_change_req(AR, Mid) ->
+ io:format("raraa_mgc_verify_service_change_req -> entry with"
+ "~n AR: ~p"
+ "~n Mid: ~p"
+ "~n", [AR, Mid]),
+ CR =
+ case AR of
+ #'ActionRequest'{commandRequests = [CmdReq]} ->
+ CmdReq;
+ _ ->
+ Err1 = {invalid_action_request, AR},
+ ED1 = cre_ErrDesc(AR),
+ ErrReply1 = {discard_ack, ED1},
+ throw({error, Err1, ErrReply1})
+ end,
+ Cmd =
+ case CR of
+ #'CommandRequest'{command = Command} ->
+ Command;
+ _ ->
+ Err2 = {invalid_command_request, CR},
+ ED2 = cre_ErrDesc(CR),
+ ErrReply2 = {discard_ack, ED2},
+ throw({error, Err2, ErrReply2})
+ end,
+ {Tid, Parms} =
+ case Cmd of
+ {serviceChangeReq,
+ #'ServiceChangeRequest'{terminationID = [TermID],
+ serviceChangeParms = ServChParms}} ->
+ {TermID, ServChParms};
+ _ ->
+ Err3 = {invalid_command, Cmd},
+ ED3 = cre_ErrDesc(Cmd),
+ ErrReply3 = {discard_ack, ED3},
+ throw({error, Err3, ErrReply3})
+ end,
+ case Tid of
+ #megaco_term_id{contains_wildcards = false, id = ["root"]} ->
+ ok;
+ _ ->
+ Err4 = {invalid_termination_id, Tid},
+ ED4 = cre_ErrDesc(Tid),
+ ErrReply4 = {discard_ack, ED4},
+ throw({error, Err4, ErrReply4})
+ end,
+ case Parms of
+ #'ServiceChangeParm'{serviceChangeMethod = restart,
+ serviceChangeReason = [[$9,$0,$1|_]]} ->
+ AckData = [raraa_mgc_service_change_reply_ar(Mid, 1)],
+ Reply = {discard_ack, AckData},
+ {ok, AR, Reply};
+ _ ->
+ Err5 = {invalid_SCP, Parms},
+ ED5 = cre_ErrDesc(Parms),
+ ErrReply5 = {discard_ack, ED5},
+ {error, Err5, ErrReply5}
+ end.
+
+
+%% Notify Request verification
+-ifndef(megaco_hipe_special).
+raraa_mgc_verify_notify_req_fun() ->
+ fun(Req) ->
+ raraa_mgc_verify_notify_req(Req)
+ end.
+-endif.
+
+raraa_mgc_verify_notify_req({handle_trans_request, _, ?VERSION, [AR]}) ->
+ (catch raraa_mgc_do_verify_notify_req(AR));
+raraa_mgc_verify_notify_req(Crap) ->
+ ED = cre_ErrDesc(Crap),
+ ErrReply = {discard_ack, ED},
+ {error, Crap, ErrReply}.
+
+raraa_mgc_do_verify_notify_req(AR) ->
+ io:format("raraa_mgc_verify_notify_req -> entry with"
+ "~n AR: ~p"
+ "~n", [AR]),
+ {Cid, CR} =
+ case AR of
+ #'ActionRequest'{contextId = CtxID,
+ commandRequests = [CmdReq]} ->
+ {CtxID, CmdReq};
+ _ ->
+ Err1 = {invalid_action_request, AR},
+ ED1 = cre_ErrDesc(AR),
+ ErrReply1 = {discard_ack, ED1},
+ throw({error, Err1, ErrReply1})
+ end,
+ Cmd =
+ case CR of
+ #'CommandRequest'{command = Command} ->
+ Command;
+ _ ->
+ Err2 = {invalid_command_request, CR},
+ ED2 = cre_ErrDesc(CR),
+ ErrReply2 = {discard_ack, ED2},
+ throw({error, Err2, ErrReply2})
+ end,
+ NR =
+ case Cmd of
+ {notifyReq, NotifReq} ->
+ NotifReq;
+ _ ->
+ Err3 = {invalid_command, Cmd},
+ ED3 = cre_ErrDesc(Cmd),
+ ErrReply3 = {discard_ack, ED3},
+ throw({error, Err3, ErrReply3})
+ end,
+ {Tid, OED} =
+ case NR of
+ #'NotifyRequest'{terminationID = [TermID],
+ observedEventsDescriptor = ObsEvsDesc,
+ errorDescriptor = asn1_NOVALUE} ->
+ {TermID, ObsEvsDesc};
+ _ ->
+ Err4 = {invalid_NR, NR},
+ ED4 = cre_ErrDesc(NR),
+ ErrReply4 = {discard_ack, ED4},
+ throw({error, Err4, ErrReply4})
+ end,
+ OE =
+ case OED of
+ #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
+ ObsEvLst;
+ _ ->
+ Err5 = {invalid_OED, OED},
+ ED5 = cre_ErrDesc(NR),
+ ErrReply5 = {discard_ack, ED5},
+ throw({error, Err5, ErrReply5})
+ end,
+ case OE of
+ #'ObservedEvent'{eventName = "al/of"} ->
+ AckData = raraa,
+ Replies = [raraa_mgc_notify_reply_ar(Cid, Tid)],
+ Reply = {{handle_ack, AckData}, Replies},
+ {ok, AR, Reply};
+ _ ->
+ Err6 = {invalid_OE, OE},
+ ED6 = cre_ErrDesc(OE),
+ ErrReply6 = {discard_ack, ED6},
+ throw({error, Err6, ErrReply6})
+ end.
+
+
+-ifndef(megaco_hipe_special).
+raraa_mgc_verify_handle_trans_ack_fun() ->
+ fun(Ack) ->
+ raraa_mgc_verify_handle_trans_ack(Ack)
+ end.
+-endif.
+
+raraa_mgc_verify_handle_trans_ack(
+ {handle_trans_ack, CH, ?VERSION, ok, raraa}) ->
+ io:format("raraa_mgc_verify_handle_trans_ack -> ok"
+ "~n CH: ~p"
+ "~n", [CH]),
+ {ok, CH, ok};
+raraa_mgc_verify_handle_trans_ack(Crap) ->
+ io:format("raraa_mgc_verify_handle_trans_ack -> unknown"
+ "~n Crap: ~p~n", [Crap]),
+ {error, Crap, ok}.
+
+
+%% Disconnect verification
+raraa_mgc_verify_handle_disconnect({handle_disconnect, CH, ?VERSION, _R}) ->
+ {ok, CH, ok};
+raraa_mgc_verify_handle_disconnect(Else) ->
+ {error, Else, ok}.
+
+raraa_mgc_service_change_reply_ar(Mid, Cid) ->
+ SCRP = cre_serviceChangeResParm(Mid),
+ SCRes = cre_serviceChangeResult(SCRP),
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = cre_serviceChangeReply([Root], SCRes),
+ CR = cre_cmdReply(SCR),
+ AR = cre_actionReply(Cid, [CR]),
+ AR.
+
+raraa_mgc_notify_reply_ar(Cid, TermId) ->
+ NR = cre_notifyReply([TermId]),
+ CR = cre_cmdReply(NR),
+ cre_actionReply(Cid, [CR]).
+
+
+%%
+%% MG generator stuff
+%%
+-ifdef(megaco_hipe_special).
+-define(raraa_mg_decode_msg_fun(Mod, Conf),
+ {?MODULE, decode_msg, [Mod, Conf]}).
+-define(raraa_mg_encode_msg_fun(Mod, Conf),
+ {?MODULE, encode_msg, [Mod, Conf]}).
+-define(raraa_mg_verify_service_change_rep_msg_fun(),
+ {?MODULE, raraa_mg_verify_service_change_rep_msg, []}).
+-define(raraa_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId),
+ {?MODULE, raraa_mg_verify_notify_rep_msg, [TermId, TransId, ReqId, CtxId]}).
+-else.
+-define(raraa_mg_decode_msg_fun(Mod, Conf),
+ raraa_mg_decode_msg_fun(Mod, Conf)).
+-define(raraa_mg_encode_msg_fun(Mod, Conf),
+ raraa_mg_encode_msg_fun(Mod, Conf)).
+-define(raraa_mg_verify_service_change_rep_msg_fun(),
+ raraa_mg_verify_service_change_rep_msg_fun()).
+-define(raraa_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId),
+ raraa_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId)).
+-endif.
+
+raraa_mg_event_sequence(text, tcp) ->
+ DecodeFun = ?raraa_mg_decode_msg_fun(megaco_pretty_text_encoder, []),
+ EncodeFun = ?raraa_mg_encode_msg_fun(megaco_pretty_text_encoder, []),
+ Mid = {deviceName,"mg"},
+ ServiceChangeReq = raraa_mg_service_change_request_msg(Mid, 1, 0),
+ TermId = #megaco_term_id{id = ["00000000","00000000","01101101"]},
+ TransId = 2,
+ ReqId = 1,
+ CtxId = 1,
+ NotifyReq = raraa_mg_notify_request_msg(Mid, TermId,
+ TransId, ReqId, CtxId),
+ TransAck = raraa_mg_trans_ack_msg(Mid, TransId),
+ ScrVerifyFun = ?raraa_mg_verify_service_change_rep_msg_fun(),
+ NrVerifyFun = ?raraa_mg_verify_notify_rep_msg_fun(TermId,
+ TransId, ReqId, CtxId),
+%% ScrVerifyFun = raraa_mg_verify_service_change_rep_msg_fun(),
+%% NrVerifyFun = raraa_mg_verify_notify_rep_msg_fun(TermId,
+%% TransId, ReqId, CtxId),
+ EvSeq = [{debug, true},
+ {decode, DecodeFun},
+ {encode, EncodeFun},
+ {connect, 2944},
+ {send, "service-change-request", ServiceChangeReq},
+ {expect_receive, "service-change-reply", {ScrVerifyFun, 10000}},
+ {send, "notify request", NotifyReq},
+ {expect_receive, "notify-reply", {NrVerifyFun, 10000}},
+ {send, "transaction-ack", TransAck},
+ {expect_nothing, 11000},
+ disconnect
+ ],
+ EvSeq.
+
+-ifndef(megaco_hipe_special).
+raraa_mg_encode_msg_fun(Mod, Conf) ->
+ fun(M) ->
+ encode_msg(M, Mod, Conf)
+ end.
+-endif.
+
+-ifndef(megaco_hipe_special).
+raraa_mg_decode_msg_fun(Mod, Conf) ->
+ fun(M) ->
+ decode_msg(M, Mod, Conf)
+ end.
+-endif.
+
+-ifndef(megaco_hipe_special).
+raraa_mg_verify_service_change_rep_msg_fun() ->
+ fun(Msg) ->
+ (catch raraa_mg_verify_service_change_rep_msg(Msg))
+ end.
+-endif.
+
+raraa_mg_verify_service_change_rep_msg(#'MegacoMessage'{mess = Mess} = M) ->
+ Body =
+ case Mess of
+ #'Message'{version = _V,
+ mId = _MgMid,
+ messageBody = MsgBody} ->
+ MsgBody;
+ _ ->
+ throw({error, {invalid_Message, Mess}})
+ end,
+ Trans =
+ case Body of
+ {transactions, [Transactions]} ->
+ Transactions;
+ _ ->
+ throw({error, {invalid_messageBody, Body}})
+ end,
+ TR =
+ case Trans of
+ {transactionReply, TransReply} ->
+ TransReply;
+ _ ->
+ throw({error, {invalid_transactions, Trans}})
+ end,
+ TRes =
+ case TR of
+ #'TransactionReply'{transactionId = _Tid,
+ immAckRequired = asn1_NOVALUE,
+ transactionResult = TransRes} ->
+ TransRes;
+ _ ->
+ throw({error, {invalid_transactionReply, TR}})
+ end,
+ AR =
+ case TRes of
+ {actionReplies, [ActRes]} ->
+ ActRes;
+ _ ->
+ throw({error, {invalid_transactionResult, TRes}})
+ end,
+ CR =
+ case AR of
+ #'ActionReply'{contextId = _Cid,
+ errorDescriptor = asn1_NOVALUE,
+ contextReply = _CtxReq,
+ commandReply = [CmdRep]} ->
+ CmdRep;
+ _ ->
+ throw({error, {invalid_actionReplies, AR}})
+ end,
+ SCR =
+ case CR of
+ {serviceChangeReply, ServChRep} ->
+ ServChRep;
+ _ ->
+ throw({error, {invalid_commandReply, CR}})
+ end,
+ SCRes =
+ case SCR of
+ #'ServiceChangeReply'{terminationID = _TermID,
+ serviceChangeResult = ServChRes} ->
+ ServChRes;
+ _ ->
+ throw({error, {invalid_serviceChangeReply, SCR}})
+ end,
+ SCRP =
+ case SCRes of
+ {serviceChangeResParms, Parms} ->
+ Parms;
+ _ ->
+ throw({error, {invalid_serviceChangeResult, SCRes}})
+ end,
+ case SCRP of
+ #'ServiceChangeResParm'{serviceChangeMgcId = _MgcMid} ->
+ {ok, M};
+ _ ->
+ {error, {invalid_serviceChangeResParms, SCRP}}
+ end;
+raraa_mg_verify_service_change_rep_msg(Crap) ->
+ {error, {invalid_message, Crap}}.
+
+-ifndef(megaco_hipe_special).
+raraa_mg_verify_notify_rep_msg_fun(TermId, TransId, Rid, Cid) ->
+ fun(Msg) ->
+ (catch raraa_mg_verify_notify_rep_msg(Msg,
+ TermId, TransId, Rid, Cid))
+ end.
+-endif.
+
+raraa_mg_verify_notify_rep_msg(#'MegacoMessage'{mess = Mess} = M,
+ TermId, TransId, Rid, Cid) ->
+ io:format("raraa_mg_verify_notify_rep_msg -> entry with"
+ "~n M: ~p"
+ "~n TermId: ~p"
+ "~n TransId: ~p"
+ "~n Rid: ~p"
+ "~n Cid: ~p"
+ "~n", [M, TermId, TransId, Rid, Cid]),
+ Body =
+ case Mess of
+ #'Message'{version = ?VERSION,
+ mId = _Mid,
+ messageBody = MsgBody} ->
+ MsgBody;
+ _ ->
+ throw({error, {invalid_Message, Mess}})
+ end,
+ Trans =
+ case Body of
+ {transactions, [Transactions]} ->
+ Transactions;
+ _ ->
+ throw({error, {invalid_messageBody, Body}})
+ end,
+ TR =
+ case Trans of
+ {transactionReply, TransReply} ->
+ TransReply;
+ _ ->
+ throw({error, {invalid_transactions, Trans}})
+ end,
+ TRes =
+ case TR of
+ #'TransactionReply'{transactionId = TransId,
+ immAckRequired = 'NULL',
+ transactionResult = TransRes} ->
+ TransRes;
+ _ ->
+ throw({error, {invalid_transactionReply, TR}})
+ end,
+ AR =
+ case TRes of
+ {actionReplies, [ActRes]} ->
+ ActRes;
+ _ ->
+ throw({error, {invalid_transactionResult, TRes}})
+ end,
+ CR =
+ case AR of
+ #'ActionReply'{contextId = Cid,
+ errorDescriptor = asn1_NOVALUE,
+ contextReply = _CtxReq,
+ commandReply = [CmdRep]} ->
+ CmdRep;
+ _ ->
+ throw({error, {invalid_actionReplies, AR}})
+ end,
+ NR =
+ case CR of
+ {notifyReply, NotifyReply} ->
+ NotifyReply;
+ _ ->
+ throw({error, {invalid_commandReply, CR}})
+ end,
+ case NR of
+ #'NotifyReply'{terminationID = [TermId],
+ errorDescriptor = asn1_NOVALUE} ->
+ {ok, M};
+ _ ->
+ {error, {invalid_notifyReply, NR}}
+ end;
+raraa_mg_verify_notify_rep_msg(Crap, _TermId, _TransId, _Rid, _Cid) ->
+ {error, {invalid_message, Crap}}.
+
+raraa_mg_service_change_request_ar(_Mid, Cid) ->
+ Prof = cre_serviceChangeProf("resgw", 1),
+ SCP = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = cre_serviceChangeReq([Root], SCP),
+ CMD = cre_command(SCR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+raraa_mg_service_change_request_msg(Mid, TransId, Cid) ->
+ AR = raraa_mg_service_change_request_ar(Mid, Cid),
+ TR = cre_transReq(TransId, [AR]),
+ Trans = cre_transaction(TR),
+ Mess = cre_message(?VERSION, Mid, cre_transactions([Trans])),
+ cre_megacoMessage(Mess).
+
+raraa_mg_notify_request_ar(Rid, Tid, Cid) ->
+ TT = cre_timeNotation("19990729", "22000000"),
+ Ev = cre_obsEvent("al/of", TT),
+ EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
+ NR = cre_notifyReq([Tid], EvsDesc),
+ CMD = cre_command(NR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+raraa_mg_notify_request_msg(Mid, TermId, TransId, Rid, Cid) ->
+ AR = raraa_mg_notify_request_ar(Rid, TermId, Cid),
+ TR = cre_transReq(TransId, [AR]),
+ Trans = cre_transaction(TR),
+ Mess = cre_message(?VERSION, Mid, cre_transactions([Trans])),
+ cre_megacoMessage(Mess).
+
+raraa_mg_trans_ack_msg(Mid, TransId) ->
+ TR = cre_transRespAck(cre_transAck(TransId)),
+ Trans = cre_transaction(TR),
+ Mess = cre_message(?VERSION, Mid, cre_transactions([Trans])),
+ cre_megacoMessage(Mess).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+request_and_reply_and_no_ack(suite) ->
+ [];
+request_and_reply_and_no_ack(doc) ->
+ ["This test case tests that megaco handles a failed three-way-handshake,"
+ " i.e. when the ack never arrives"];
+request_and_reply_and_no_ack(Config) when is_list(Config) ->
+ put(verbosity, ?TEST_VERBOSITY),
+ put(sname, "TEST"),
+ put(tc, rarana),
+ i("starting"),
+
+ MgcNode = make_node_name(mgc),
+ MgNode = make_node_name(mg),
+ d("start nodes: "
+ "~n MgcNode: ~p"
+ "~n MgNode: ~p",
+ [MgcNode, MgNode]),
+ ok = megaco_test_lib:start_nodes([MgcNode, MgNode], ?FILE, ?LINE),
+
+ d("[MGC] start the simulator "),
+ {ok, Mgc} = megaco_test_megaco_generator:start_link("MGC", MgcNode),
+
+ d("[MGC] create the event sequence"),
+ MgcEvSeq = rarana_mgc_event_sequence(text, tcp),
+
+ i("wait some time before starting the MGC simulation"),
+ sleep(1000),
+
+ d("[MGC] start the simulation"),
+ {ok, MgcId} = megaco_test_megaco_generator:exec(Mgc, MgcEvSeq),
+
+ i("wait some time before starting the MG simulator"),
+ sleep(1000),
+
+ d("[MG] start the simulator (generator)"),
+ {ok, Mg} = megaco_test_tcp_generator:start_link("MG", MgNode),
+
+ d("[MG] create the event sequence"),
+ MgEvSeq = rarana_mg_event_sequence(text, tcp),
+
+ i("wait some time before starting the MG simulation"),
+ sleep(1000),
+
+ d("[MG] start the simulation"),
+ {ok, MgId} = megaco_test_tcp_generator:exec(Mg, MgEvSeq),
+
+ d("await the generator reply(s)"),
+ await_completion([MgcId, MgId]),
+
+ %% Tell Mgc to stop
+ i("[MGC] stop generator"),
+ megaco_test_megaco_generator:stop(Mgc),
+
+ %% Tell Mg to stop
+ i("[MG] stop generator"),
+ megaco_test_tcp_generator:stop(Mg),
+
+ i("done", []),
+ ok.
+
+
+%%
+%% MGC generator stuff
+%%
+
+-ifdef(megaco_hipe_special).
+-define(rarana_mgc_verify_handle_connect_fun(),
+ {?MODULE, rarana_mgc_verify_handle_connect, []}).
+-define(rarana_mgc_verify_service_change_req_fun(Mid),
+ {?MODULE, rarana_mgc_verify_service_change_req, [Mid]}).
+-define(rarana_mgc_verify_notify_req_fun(),
+ {?MODULE, rarana_mgc_verify_notify_req, []}).
+-define(rarana_mgc_verify_handle_trans_ack_fun(),
+ {?MODULE, rarana_mgc_verify_handle_trans_ack, []}).
+-define(rarana_mgc_verify_handle_disconnect_fun(),
+ {?MODULE, rarana_mgc_verify_handle_disconnect, []}).
+-else.
+-define(rarana_mgc_verify_handle_connect_fun(),
+ fun rarana_mgc_verify_handle_connect/1).
+-define(rarana_mgc_verify_service_change_req_fun(Mid),
+ rarana_mgc_verify_service_change_req_fun(Mid)).
+-define(rarana_mgc_verify_notify_req_fun(),
+ rarana_mgc_verify_notify_req_fun()).
+-define(rarana_mgc_verify_handle_trans_ack_fun(),
+ rarana_mgc_verify_handle_trans_ack_fun()).
+-define(rarana_mgc_verify_handle_disconnect_fun(),
+ fun rarana_mgc_verify_handle_disconnect/1).
+-endif.
+
+rarana_mgc_event_sequence(text, tcp) ->
+ Mid = {deviceName,"ctrl"},
+ RI = [
+ {port, 2944},
+ {encoding_module, megaco_pretty_text_encoder},
+ {encoding_config, []},
+ {transport_module, megaco_tcp}
+ ],
+ ConnectVerify = ?rarana_mgc_verify_handle_connect_fun(),
+ ScrVerify = ?rarana_mgc_verify_service_change_req_fun(Mid),
+ NrVerify = ?rarana_mgc_verify_notify_req_fun(),
+ AckVerify = ?rarana_mgc_verify_handle_trans_ack_fun(),
+ DiscoVerify = ?rarana_mgc_verify_handle_disconnect_fun(),
+%% ConnectVerify = fun rarana_mgc_verify_handle_connect/1,
+%% ScrVerify = rarana_mgc_verify_service_change_req_fun(Mid),
+%% NrVerify = rarana_mgc_verify_notify_request_fun(),
+%% AckVerify = rarana_mgc_verify_trans_ack_fun(),
+%% DiscoVerify = fun rarana_mgc_verify_handle_disconnect/1,
+ EvSeq = [
+ {debug, true},
+ {megaco_trace, disable},
+ {megaco_trace, max},
+ megaco_start,
+ {megaco_start_user, Mid, RI, []},
+ {megaco_update_user_info, sent_pending_limit, 100},
+ {megaco_update_user_info, reply_timer, 9000},
+ start_transport,
+ listen,
+ {megaco_callback, handle_connect, ConnectVerify},
+ {megaco_conn_info, all},
+ {megaco_callback, handle_trans_request, ScrVerify},
+ {megaco_callback, handle_trans_request, NrVerify},
+ {megaco_callback, handle_trans_ack, AckVerify},
+ %% {megaco_callback, nocall, 8000},
+ {megaco_callback, handle_disconnect, DiscoVerify},
+ megaco_stop_user,
+ megaco_stop
+ ],
+ EvSeq.
+
+%% Connect verification
+rarana_mgc_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
+ {ok, CH, ok};
+rarana_mgc_verify_handle_connect(Else) ->
+ {error, Else, ok}.
+
+%% Service Change verification
+-ifndef(megaco_hipe_special).
+rarana_mgc_verify_service_change_req_fun(Mid) ->
+ fun(Req) ->
+ rarana_mgc_verify_service_change_req(Req, Mid)
+ end.
+-endif.
+
+rarana_mgc_verify_service_change_req(
+ {handle_trans_request, _, ?VERSION, [AR]}, Mid) ->
+ (catch rarana_do_verify_service_change_req(AR, Mid));
+rarana_mgc_verify_service_change_req(Crap, _Mid) ->
+ ED = cre_ErrDesc(Crap),
+ ErrReply = {discard_ack, ED},
+ {error, Crap, ErrReply}.
+
+rarana_do_verify_service_change_req(AR, Mid) ->
+ CR =
+ case AR of
+ #'ActionRequest'{commandRequests = [CmdReq]} ->
+ CmdReq;
+ _ ->
+ Err1 = {invalid_action_request, AR},
+ ED1 = cre_ErrDesc(AR),
+ ErrReply1 = {discard_ack, ED1},
+ throw({error, Err1, ErrReply1})
+ end,
+ Cmd =
+ case CR of
+ #'CommandRequest'{command = Command} ->
+ Command;
+ _ ->
+ Err2 = {invalid_command_request, CR},
+ ED2 = cre_ErrDesc(CR),
+ ErrReply2 = {discard_ack, ED2},
+ throw({error, Err2, ErrReply2})
+ end,
+ {Tid, Parms} =
+ case Cmd of
+ {serviceChangeReq,
+ #'ServiceChangeRequest'{terminationID = [TermID],
+ serviceChangeParms = ServChParms}} ->
+ {TermID, ServChParms};
+ _ ->
+ Err3 = {invalid_command, Cmd},
+ ED3 = cre_ErrDesc(Cmd),
+ ErrReply3 = {discard_ack, ED3},
+ throw({error, Err3, ErrReply3})
+ end,
+ case Tid of
+ #megaco_term_id{contains_wildcards = false, id = ["root"]} ->
+ ok;
+ _ ->
+ Err4 = {invalid_termination_id, Tid},
+ ED4 = cre_ErrDesc(Tid),
+ ErrReply4 = {discard_ack, ED4},
+ throw({error, Err4, ErrReply4})
+ end,
+ case Parms of
+ #'ServiceChangeParm'{serviceChangeMethod = restart,
+ serviceChangeReason = [[$9,$0,$1|_]]} ->
+ AckData = [rarana_mgc_service_change_reply_ar(Mid, 1)],
+ Reply = {discard_ack, AckData},
+ {ok, AR, Reply};
+ _ ->
+ Err5 = {invalid_SCP, Parms},
+ ED5 = cre_ErrDesc(Parms),
+ ErrReply5 = {discard_ack, ED5},
+ {error, Err5, ErrReply5}
+ end.
+
+
+%% Notify Request verification
+-ifndef(megaco_hipe_special).
+rarana_mgc_verify_notify_req_fun() ->
+ fun(Req) ->
+ rarana_mgc_verify_notify_req(Req)
+ end.
+-endif.
+
+rarana_mgc_verify_notify_req({handle_trans_request, _, ?VERSION, [AR]}) ->
+ (catch rarana_mgc_do_verify_notify_req(AR));
+rarana_mgc_verify_notify_req(Crap) ->
+ ED = cre_ErrDesc(Crap),
+ ErrReply = {discard_ack, ED},
+ {error, Crap, ErrReply}.
+
+rarana_mgc_do_verify_notify_req(AR) ->
+ {Cid, CR} =
+ case AR of
+ #'ActionRequest'{contextId = CtxID,
+ commandRequests = [CmdReq]} ->
+ {CtxID, CmdReq};
+ _ ->
+ Err1 = {invalid_action_request, AR},
+ ED1 = cre_ErrDesc(AR),
+ ErrReply1 = {discard_ack, ED1},
+ throw({error, Err1, ErrReply1})
+ end,
+ Cmd =
+ case CR of
+ #'CommandRequest'{command = Command} ->
+ Command;
+ _ ->
+ Err2 = {invalid_command_request, CR},
+ ED2 = cre_ErrDesc(CR),
+ ErrReply2 = {discard_ack, ED2},
+ throw({error, Err2, ErrReply2})
+ end,
+ NR =
+ case Cmd of
+ {notifyReq, NotifReq} ->
+ NotifReq;
+ _ ->
+ Err3 = {invalid_command, Cmd},
+ ED3 = cre_ErrDesc(Cmd),
+ ErrReply3 = {discard_ack, ED3},
+ throw({error, Err3, ErrReply3})
+ end,
+ {Tid, OED} =
+ case NR of
+ #'NotifyRequest'{terminationID = [TermID],
+ observedEventsDescriptor = ObsEvsDesc,
+ errorDescriptor = asn1_NOVALUE} ->
+ {TermID, ObsEvsDesc};
+ _ ->
+ Err4 = {invalid_NR, NR},
+ ED4 = cre_ErrDesc(NR),
+ ErrReply4 = {discard_ack, ED4},
+ throw({error, Err4, ErrReply4})
+ end,
+ OE =
+ case OED of
+ #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
+ ObsEvLst;
+ _ ->
+ Err5 = {invalid_OED, OED},
+ ED5 = cre_ErrDesc(NR),
+ ErrReply5 = {discard_ack, ED5},
+ throw({error, Err5, ErrReply5})
+ end,
+ case OE of
+ #'ObservedEvent'{eventName = "al/of"} ->
+ AckData = rarana,
+ Replies = [rarana_mgc_notify_reply_ar(Cid, Tid)],
+ Reply = {{handle_ack, AckData}, Replies},
+ {ok, AR, Reply};
+ _ ->
+ Err6 = {invalid_OE, OE},
+ ED6 = cre_ErrDesc(OE),
+ ErrReply6 = {discard_ack, ED6},
+ throw({error, Err6, ErrReply6})
+ end.
+
+
+-ifndef(megaco_hipe_special).
+rarana_mgc_verify_handle_trans_ack_fun() ->
+ fun(Ack) ->
+ rarana_mgc_verify_handle_trans_ack(Ack)
+ end.
+-endif.
+
+rarana_mgc_verify_handle_trans_ack({handle_trans_ack, CH, ?VERSION,
+ {error, timeout}, rarana}) ->
+ io:format("rarana_mgc_verify_handle_trans_ack -> expected error: ok"
+ "~n CH: ~p"
+ "~n", [CH]),
+ {ok, CH, ok};
+rarana_mgc_verify_handle_trans_ack(Crap) ->
+ io:format("rarana_mgc_verify_trans_ack -> unknown"
+ "~n Crap: ~p~n", [Crap]),
+ {error, Crap, ok}.
+
+
+%% Disconnect verification
+rarana_mgc_verify_handle_disconnect({handle_disconnect, CH, ?VERSION, _R}) ->
+ {ok, CH, ok};
+rarana_mgc_verify_handle_disconnect(Else) ->
+ {error, Else, ok}.
+
+rarana_mgc_service_change_reply_ar(Mid, Cid) ->
+ SCRP = cre_serviceChangeResParm(Mid),
+ SCRes = cre_serviceChangeResult(SCRP),
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = cre_serviceChangeReply([Root], SCRes),
+ CR = cre_cmdReply(SCR),
+ AR = cre_actionReply(Cid, [CR]),
+ AR.
+
+rarana_mgc_notify_reply_ar(Cid, TermId) ->
+ NR = cre_notifyReply([TermId]),
+ CR = cre_cmdReply(NR),
+ cre_actionReply(Cid, [CR]).
+
+
+%%
+%% MG generator stuff
+%%
+-ifdef(megaco_hipe_special).
+-define(rarana_mg_decode_msg_fun(Mod, Conf),
+ {?MODULE, decode_msg, [Mod, Conf]}).
+-define(rarana_mg_encode_msg_fun(Mod, Conf),
+ {?MODULE, encode_msg, [Mod, Conf]}).
+-define(rarana_mg_verify_service_change_rep_msg_fun(),
+ {?MODULE, rarana_mg_verify_service_change_rep_msg, []}).
+-define(rarana_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId),
+ {?MODULE, rarana_mg_verify_notify_rep_msg, [TermId, TransId, ReqId, CtxId]}).
+-else.
+-define(rarana_mg_decode_msg_fun(Mod, Conf),
+ rarana_mg_decode_msg_fun(Mod, Conf)).
+-define(rarana_mg_encode_msg_fun(Mod, Conf),
+ rarana_mg_encode_msg_fun(Mod, Conf)).
+-define(rarana_mg_verify_service_change_rep_msg_fun(),
+ rarana_mg_verify_service_change_rep_msg_fun()).
+-define(rarana_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId),
+ rarana_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId)).
+-endif.
+
+rarana_mg_event_sequence(text, tcp) ->
+ DecodeFun = ?rarana_mg_decode_msg_fun(megaco_pretty_text_encoder, []),
+ EncodeFun = ?rarana_mg_encode_msg_fun(megaco_pretty_text_encoder, []),
+ Mid = {deviceName,"mg"},
+ ServiceChangeReq = rarana_mg_service_change_request_msg(Mid, 1, 0),
+ TermId = #megaco_term_id{id = ["00000000","00000000","01101101"]},
+ TransId = 2,
+ ReqId = 1,
+ CtxId = 1,
+ NotifyReq = rarana_mg_notify_request_msg(Mid, TermId,
+ TransId, ReqId, CtxId),
+ ScrVerifyFun = ?rarana_mg_verify_service_change_rep_msg_fun(),
+ NrVerifyFun = ?rarana_mg_verify_notify_rep_msg_fun(TermId,
+ TransId, ReqId, CtxId),
+%% ScrVerifyFun = rarana_mg_verify_service_change_rep_msg_fun(),
+%% NrVerifyFun = rarana_mg_verify_notify_rep_msg_fun(TermId,
+%% TransId, ReqId, CtxId),
+ EvSeq = [{debug, true},
+ {decode, DecodeFun},
+ {encode, EncodeFun},
+ {connect, 2944},
+ {send, "service-change-request", ServiceChangeReq},
+ {expect_receive, "service-change-reply", {ScrVerifyFun, 10000}},
+ {send, "notify request", NotifyReq},
+ {expect_receive, "notify-reply", {NrVerifyFun, 10000}},
+ {expect_nothing, 11000},
+ disconnect
+ ],
+ EvSeq.
+
+-ifndef(megaco_hipe_special).
+rarana_mg_encode_msg_fun(Mod, Conf) ->
+ fun(M) ->
+ encode_msg(M, Mod, Conf)
+ end.
+-endif.
+
+-ifndef(megaco_hipe_special).
+rarana_mg_decode_msg_fun(Mod, Conf) ->
+ fun(M) ->
+ decode_msg(M, Mod, Conf)
+ end.
+-endif.
+
+-ifndef(megaco_hipe_special).
+rarana_mg_verify_service_change_rep_msg_fun() ->
+ fun(Msg) ->
+ (catch rarana_mg_verify_service_change_rep_msg(Msg))
+ end.
+-endif.
+
+rarana_mg_verify_service_change_rep_msg(#'MegacoMessage'{mess = Mess} = M) ->
+ Body =
+ case Mess of
+ #'Message'{version = _V,
+ mId = _MgMid,
+ messageBody = MsgBody} ->
+ MsgBody;
+ _ ->
+ throw({error, {invalid_Message, Mess}})
+ end,
+ Trans =
+ case Body of
+ {transactions, [Transactions]} ->
+ Transactions;
+ _ ->
+ throw({error, {invalid_messageBody, Body}})
+ end,
+ TR =
+ case Trans of
+ {transactionReply, TransReply} ->
+ TransReply;
+ _ ->
+ throw({error, {invalid_transactions, Trans}})
+ end,
+ TRes =
+ case TR of
+ #'TransactionReply'{transactionId = _Tid,
+ immAckRequired = asn1_NOVALUE,
+ transactionResult = TransRes} ->
+ TransRes;
+ _ ->
+ throw({error, {invalid_transactionReply, TR}})
+ end,
+ AR =
+ case TRes of
+ {actionReplies, [ActRes]} ->
+ ActRes;
+ _ ->
+ throw({error, {invalid_transactionResult, TRes}})
+ end,
+ CR =
+ case AR of
+ #'ActionReply'{contextId = _Cid,
+ errorDescriptor = asn1_NOVALUE,
+ contextReply = _CtxReq,
+ commandReply = [CmdRep]} ->
+ CmdRep;
+ _ ->
+ throw({error, {invalid_actionReplies, AR}})
+ end,
+ SCR =
+ case CR of
+ {serviceChangeReply, ServChRep} ->
+ ServChRep;
+ _ ->
+ throw({error, {invalid_commandReply, CR}})
+ end,
+ SCRes =
+ case SCR of
+ #'ServiceChangeReply'{terminationID = _TermID,
+ serviceChangeResult = ServChRes} ->
+ ServChRes;
+ _ ->
+ throw({error, {invalid_serviceChangeReply, SCR}})
+ end,
+ SCRP =
+ case SCRes of
+ {serviceChangeResParms, Parms} ->
+ Parms;
+ _ ->
+ throw({error, {invalid_serviceChangeResult, SCRes}})
+ end,
+ case SCRP of
+ #'ServiceChangeResParm'{serviceChangeMgcId = _MgcMid} ->
+ {ok, M};
+ _ ->
+ {error, {invalid_serviceChangeResParms, SCRP}}
+ end;
+rarana_mg_verify_service_change_rep_msg(Crap) ->
+ {error, {invalid_message, Crap}}.
+
+-ifndef(megaco_hipe_special).
+rarana_mg_verify_notify_rep_msg_fun(TermId, TransId, Rid, Cid) ->
+ fun(Msg) ->
+ (catch rarana_mg_verify_notify_rep_msg(Msg,
+ TermId, TransId, Rid, Cid))
+ end.
+-endif.
+
+rarana_mg_verify_notify_rep_msg(#'MegacoMessage'{mess = Mess} = M,
+ TermId, TransId, Rid, Cid) ->
+ io:format("rarana_mg_verify_notify_rep_msg -> entry with"
+ "~n M: ~p"
+ "~n TermId: ~p"
+ "~n TransId: ~p"
+ "~n Rid: ~p"
+ "~n Cid: ~p"
+ "~n", [M, TermId, TransId, Rid, Cid]),
+ Body =
+ case Mess of
+ #'Message'{version = ?VERSION,
+ mId = _Mid,
+ messageBody = MsgBody} ->
+ MsgBody;
+ _ ->
+ throw({error, {invalid_Message, Mess}})
+ end,
+ Trans =
+ case Body of
+ {transactions, [Transactions]} ->
+ Transactions;
+ _ ->
+ throw({error, {invalid_messageBody, Body}})
+ end,
+ TR =
+ case Trans of
+ {transactionReply, TransReply} ->
+ TransReply;
+ _ ->
+ throw({error, {invalid_transactions, Trans}})
+ end,
+ TRes =
+ case TR of
+ #'TransactionReply'{transactionId = TransId,
+ immAckRequired = 'NULL',
+ transactionResult = TransRes} ->
+ TransRes;
+ _ ->
+ throw({error, {invalid_transactionReply, TR}})
+ end,
+ AR =
+ case TRes of
+ {actionReplies, [ActRes]} ->
+ ActRes;
+ _ ->
+ throw({error, {invalid_transactionResult, TRes}})
+ end,
+ CR =
+ case AR of
+ #'ActionReply'{contextId = Cid,
+ errorDescriptor = asn1_NOVALUE,
+ contextReply = _CtxReq,
+ commandReply = [CmdRep]} ->
+ CmdRep;
+ _ ->
+ throw({error, {invalid_actionReplies, AR}})
+ end,
+ NR =
+ case CR of
+ {notifyReply, NotifyReply} ->
+ NotifyReply;
+ _ ->
+ throw({error, {invalid_commandReply, CR}})
+ end,
+ case NR of
+ #'NotifyReply'{terminationID = [TermId],
+ errorDescriptor = asn1_NOVALUE} ->
+ {ok, M};
+ _ ->
+ {error, {invalid_notifyReply, NR}}
+ end;
+rarana_mg_verify_notify_rep_msg(Crap, _TermId, _TransId, _Rid, _Cid) ->
+ {error, {invalid_message, Crap}}.
+
+rarana_mg_service_change_request_ar(_Mid, Cid) ->
+ Prof = cre_serviceChangeProf("resgw", 1),
+ SCP = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = cre_serviceChangeReq([Root], SCP),
+ CMD = cre_command(SCR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+rarana_mg_service_change_request_msg(Mid, TransId, Cid) ->
+ AR = rarana_mg_service_change_request_ar(Mid, Cid),
+ TR = cre_transReq(TransId, [AR]),
+ Trans = cre_transaction(TR),
+ Mess = cre_message(?VERSION, Mid, cre_transactions([Trans])),
+ cre_megacoMessage(Mess).
+
+rarana_mg_notify_request_ar(Rid, Tid, Cid) ->
+ TT = cre_timeNotation("19990729", "22000000"),
+ Ev = cre_obsEvent("al/of", TT),
+ EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
+ NR = cre_notifyReq([Tid], EvsDesc),
+ CMD = cre_command(NR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+rarana_mg_notify_request_msg(Mid, TermId, TransId, Rid, Cid) ->
+ AR = rarana_mg_notify_request_ar(Rid, TermId, Cid),
+ TR = cre_transReq(TransId, [AR]),
+ Trans = cre_transaction(TR),
+ Mess = cre_message(?VERSION, Mid, cre_transactions([Trans])),
+ cre_megacoMessage(Mess).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+request_and_reply_and_late_ack(suite) ->
+ [];
+request_and_reply_and_late_ack(doc) ->
+ ["This test case tests that megaco handles three-way-handshake "
+ "when the ack is late (and requeire a retransmission)"];
+request_and_reply_and_late_ack(Config) when is_list(Config) ->
+ put(verbosity, ?TEST_VERBOSITY),
+ put(sname, "TEST"),
+ put(tc, rarala),
+ i("starting"),
+
+ MgcNode = make_node_name(mgc),
+ MgNode = make_node_name(mg),
+ d("start nodes: "
+ "~n MgcNode: ~p"
+ "~n MgNode: ~p",
+ [MgcNode, MgNode]),
+ ok = megaco_test_lib:start_nodes([MgcNode, MgNode], ?FILE, ?LINE),
+
+ d("[MGC] start the simulator "),
+ {ok, Mgc} = megaco_test_megaco_generator:start_link("MGC", MgcNode),
+
+ d("[MGC] create the event sequence"),
+ MgcEvSeq = rarala_mgc_event_sequence(text, tcp),
+
+ i("wait some time before starting the MGC simulation"),
+ sleep(1000),
+
+ d("[MGC] start the simulation"),
+ {ok, MgcId} = megaco_test_megaco_generator:exec(Mgc, MgcEvSeq),
+
+ i("wait some time before starting the MG simulator"),
+ sleep(1000),
+
+ d("[MG] start the simulator (generator)"),
+ {ok, Mg} = megaco_test_tcp_generator:start_link("MG", MgNode),
+
+ d("[MG] create the event sequence"),
+ MgEvSeq = rarala_mg_event_sequence(text, tcp),
+
+ i("wait some time before starting the MG simulation"),
+ sleep(1000),
+
+ d("[MG] start the simulation"),
+ {ok, MgId} = megaco_test_tcp_generator:exec(Mg, MgEvSeq),
+
+ d("await the generator reply(s)"),
+ await_completion([MgcId, MgId]),
+
+ %% Tell Mgc to stop
+ i("[MGC] stop generator"),
+ megaco_test_megaco_generator:stop(Mgc),
+
+ %% Tell Mg to stop
+ i("[MG] stop generator"),
+ megaco_test_tcp_generator:stop(Mg),
+
+ i("done", []),
+ ok.
+
+
+%%
+%% MGC generator stuff
+%%
+
+-ifdef(megaco_hipe_special).
+-define(rarala_mgc_verify_handle_connect_fun(),
+ {?MODULE, rarala_mgc_verify_handle_connect, []}).
+-define(rarala_mgc_verify_service_change_req_fun(Mid),
+ {?MODULE, rarala_mgc_verify_service_change_req, [Mid]}).
+-define(rarala_mgc_verify_notify_req_fun(),
+ {?MODULE, rarala_mgc_verify_notify_req, []}).
+-define(rarala_mgc_verify_handle_trans_ack_fun(),
+ {?MODULE, rarala_mgc_verify_handle_trans_ack, []}).
+-define(rarala_mgc_verify_handle_disconnect_fun(),
+ {?MODULE, rarala_mgc_verify_handle_disconnect, []}).
+-else.
+-define(rarala_mgc_verify_handle_connect_fun(),
+ fun rarala_mgc_verify_handle_connect/1).
+-define(rarala_mgc_verify_service_change_req_fun(Mid),
+ rarala_mgc_verify_service_change_req_fun(Mid)).
+-define(rarala_mgc_verify_notify_req_fun(),
+ rarala_mgc_verify_notify_req_fun()).
+-define(rarala_mgc_verify_handle_trans_ack_fun(),
+ rarala_mgc_verify_handle_trans_ack_fun()).
+-define(rarala_mgc_verify_handle_disconnect_fun(),
+ fun rarala_mgc_verify_handle_disconnect/1).
+-endif.
+
+rarala_mgc_event_sequence(text, tcp) ->
+ Mid = {deviceName,"ctrl"},
+ RI = [
+ {port, 2944},
+ {encoding_module, megaco_pretty_text_encoder},
+ {encoding_config, []},
+ {transport_module, megaco_tcp}
+ ],
+ RepTmr = #megaco_incr_timer{wait_for = 3000,
+ factor = 1,
+ incr = 0,
+ max_retries = 2
+ },
+ ConnectVerify = ?rarala_mgc_verify_handle_connect_fun(),
+ ScrVerify = ?rarala_mgc_verify_service_change_req_fun(Mid),
+ NrVerify = ?rarala_mgc_verify_notify_req_fun(),
+ AckVerify = ?rarala_mgc_verify_handle_trans_ack_fun(),
+ DiscoVerify = ?rarala_mgc_verify_handle_disconnect_fun(),
+%% ConnectVerify = fun rarala_mgc_verify_handle_connect/1,
+%% ScrVerify = rarala_mgc_verify_service_change_req_fun(Mid),
+%% NrVerify = rarala_mgc_verify_notify_request_fun(),
+%% AckVerify = rarala_mgc_verify_trans_ack_fun(),
+%% DiscoVerify = fun rarala_mgc_verify_handle_disconnect/1,
+ EvSeq = [
+ {debug, true},
+ {megaco_trace, disable},
+ {megaco_trace, max},
+ megaco_start,
+ {megaco_start_user, Mid, RI, []},
+ {megaco_update_user_info, sent_pending_limit, 100},
+ {megaco_update_user_info, reply_timer, RepTmr},
+ start_transport,
+ listen,
+ {megaco_callback, handle_connect, ConnectVerify},
+ {megaco_conn_info, all},
+ {megaco_callback, handle_trans_request, ScrVerify},
+ {megaco_callback, handle_trans_request, NrVerify},
+ {megaco_callback, handle_trans_ack, AckVerify},
+ {megaco_callback, handle_disconnect, DiscoVerify},
+ megaco_stop_user,
+ megaco_stop
+ ],
+ EvSeq.
+
+%% Connect verification
+rarala_mgc_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
+ {ok, CH, ok};
+rarala_mgc_verify_handle_connect(Else) ->
+ {error, Else, ok}.
+
+%% Service Change verification
+-ifndef(megaco_hipe_special).
+rarala_mgc_verify_service_change_req_fun(Mid) ->
+ fun(Req) ->
+ rarala_mgc_verify_service_change_req(Req, Mid)
+ end.
+-endif.
+
+rarala_mgc_verify_service_change_req(
+ {handle_trans_request, _, ?VERSION, [AR]}, Mid) ->
+ (catch rarala_do_verify_service_change_req(AR, Mid));
+rarala_mgc_verify_service_change_req(Crap, _Mid) ->
+ ED = cre_ErrDesc(Crap),
+ ErrReply = {discard_ack, ED},
+ {error, Crap, ErrReply}.
+
+rarala_do_verify_service_change_req(AR, Mid) ->
+ io:format("rarala_mgc_do_verify_service_change_req -> entry with"
+ "~n AR: ~p"
+ "~n Mid: ~p"
+ "~n", [AR, Mid]),
+ CR =
+ case AR of
+ #'ActionRequest'{commandRequests = [CmdReq]} ->
+ CmdReq;
+ _ ->
+ Err1 = {invalid_action_request, AR},
+ ED1 = cre_ErrDesc(AR),
+ ErrReply1 = {discard_ack, ED1},
+ throw({error, Err1, ErrReply1})
+ end,
+ Cmd =
+ case CR of
+ #'CommandRequest'{command = Command} ->
+ Command;
+ _ ->
+ Err2 = {invalid_command_request, CR},
+ ED2 = cre_ErrDesc(CR),
+ ErrReply2 = {discard_ack, ED2},
+ throw({error, Err2, ErrReply2})
+ end,
+ {Tid, Parms} =
+ case Cmd of
+ {serviceChangeReq,
+ #'ServiceChangeRequest'{terminationID = [TermID],
+ serviceChangeParms = ServChParms}} ->
+ {TermID, ServChParms};
+ _ ->
+ Err3 = {invalid_command, Cmd},
+ ED3 = cre_ErrDesc(Cmd),
+ ErrReply3 = {discard_ack, ED3},
+ throw({error, Err3, ErrReply3})
+ end,
+ case Tid of
+ #megaco_term_id{contains_wildcards = false, id = ["root"]} ->
+ ok;
+ _ ->
+ Err4 = {invalid_termination_id, Tid},
+ ED4 = cre_ErrDesc(Tid),
+ ErrReply4 = {discard_ack, ED4},
+ throw({error, Err4, ErrReply4})
+ end,
+ case Parms of
+ #'ServiceChangeParm'{serviceChangeMethod = restart,
+ serviceChangeReason = [[$9,$0,$1|_]]} ->
+ AckData = [rarala_mgc_service_change_reply_ar(Mid, 1)],
+ Reply = {discard_ack, AckData},
+ {ok, AR, Reply};
+ _ ->
+ Err5 = {invalid_SCP, Parms},
+ ED5 = cre_ErrDesc(Parms),
+ ErrReply5 = {discard_ack, ED5},
+ {error, Err5, ErrReply5}
+ end.
+
+
+%% Notify Request verification
+-ifndef(megaco_hipe_special).
+rarala_mgc_verify_notify_req_fun() ->
+ fun(Req) ->
+ rarala_mgc_verify_notify_req(Req)
+ end.
+-endif.
+
+rarala_mgc_verify_notify_req({handle_trans_request, _, ?VERSION, [AR]}) ->
+ (catch rarala_mgc_do_verify_notify_req(AR));
+rarala_mgc_verify_notify_req(Crap) ->
+ ED = cre_ErrDesc(Crap),
+ ErrReply = {discard_ack, ED},
+ {error, Crap, ErrReply}.
+
+rarala_mgc_do_verify_notify_req(AR) ->
+ io:format("rarala_mgc_do_verify_notify_req -> entry with"
+ "~n AR: ~p"
+ "~n", [AR]),
+ {Cid, CR} =
+ case AR of
+ #'ActionRequest'{contextId = CtxID,
+ commandRequests = [CmdReq]} ->
+ {CtxID, CmdReq};
+ _ ->
+ Err1 = {invalid_action_request, AR},
+ ED1 = cre_ErrDesc(AR),
+ ErrReply1 = {discard_ack, ED1},
+ throw({error, Err1, ErrReply1})
+ end,
+ Cmd =
+ case CR of
+ #'CommandRequest'{command = Command} ->
+ Command;
+ _ ->
+ Err2 = {invalid_command_request, CR},
+ ED2 = cre_ErrDesc(CR),
+ ErrReply2 = {discard_ack, ED2},
+ throw({error, Err2, ErrReply2})
+ end,
+ NR =
+ case Cmd of
+ {notifyReq, NotifReq} ->
+ NotifReq;
+ _ ->
+ Err3 = {invalid_command, Cmd},
+ ED3 = cre_ErrDesc(Cmd),
+ ErrReply3 = {discard_ack, ED3},
+ throw({error, Err3, ErrReply3})
+ end,
+ {Tid, OED} =
+ case NR of
+ #'NotifyRequest'{terminationID = [TermID],
+ observedEventsDescriptor = ObsEvsDesc,
+ errorDescriptor = asn1_NOVALUE} ->
+ {TermID, ObsEvsDesc};
+ _ ->
+ Err4 = {invalid_NR, NR},
+ ED4 = cre_ErrDesc(NR),
+ ErrReply4 = {discard_ack, ED4},
+ throw({error, Err4, ErrReply4})
+ end,
+ OE =
+ case OED of
+ #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
+ ObsEvLst;
+ _ ->
+ Err5 = {invalid_OED, OED},
+ ED5 = cre_ErrDesc(NR),
+ ErrReply5 = {discard_ack, ED5},
+ throw({error, Err5, ErrReply5})
+ end,
+ case OE of
+ #'ObservedEvent'{eventName = "al/of"} ->
+ AckData = rarala,
+ Replies = [rarala_mgc_notify_reply_ar(Cid, Tid)],
+ Reply = {{handle_ack, AckData}, Replies},
+ {ok, AR, Reply};
+ _ ->
+ Err6 = {invalid_OE, OE},
+ ED6 = cre_ErrDesc(OE),
+ ErrReply6 = {discard_ack, ED6},
+ throw({error, Err6, ErrReply6})
+ end.
+
+
+-ifndef(megaco_hipe_special).
+rarala_mgc_verify_handle_trans_ack_fun() ->
+ fun(Ack) ->
+ rarala_mgc_verify_handle_trans_ack(Ack)
+ end.
+-endif.
+
+rarala_mgc_verify_handle_trans_ack(
+ {handle_trans_ack, CH, ?VERSION, ok, rarala}) ->
+ io:format("rarala_mgc_verify_handle_trans_ack -> ok"
+ "~n CH: ~p"
+ "~n", [CH]),
+ {ok, CH, ok};
+rarala_mgc_verify_handle_trans_ack(Crap) ->
+ io:format("rarala_mgc_verify_handle_trans_ack -> unknown"
+ "~n Crap: ~p~n", [Crap]),
+ {error, Crap, ok}.
+
+
+%% Disconnect verification
+rarala_mgc_verify_handle_disconnect({handle_disconnect, CH, ?VERSION, _R}) ->
+ {ok, CH, ok};
+rarala_mgc_verify_handle_disconnect(Else) ->
+ {error, Else, ok}.
+
+rarala_mgc_service_change_reply_ar(Mid, Cid) ->
+ SCRP = cre_serviceChangeResParm(Mid),
+ SCRes = cre_serviceChangeResult(SCRP),
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = cre_serviceChangeReply([Root], SCRes),
+ CR = cre_cmdReply(SCR),
+ AR = cre_actionReply(Cid, [CR]),
+ AR.
+
+rarala_mgc_notify_reply_ar(Cid, TermId) ->
+ NR = cre_notifyReply([TermId]),
+ CR = cre_cmdReply(NR),
+ cre_actionReply(Cid, [CR]).
+
+
+%%
+%% MG generator stuff
+%%
+-ifdef(megaco_hipe_special).
+-define(rarala_mg_decode_msg_fun(Mod, Conf),
+ {?MODULE, decode_msg, [Mod, Conf]}).
+-define(rarala_mg_encode_msg_fun(Mod, Conf),
+ {?MODULE, encode_msg, [Mod, Conf]}).
+-define(rarala_mg_verify_service_change_rep_msg_fun(),
+ {?MODULE, rarala_mg_verify_service_change_rep_msg, []}).
+-define(rarala_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId),
+ {?MODULE, rarala_mg_verify_notify_rep_msg, [TermId, TransId, ReqId, CtxId]}).
+-else.
+-define(rarala_mg_decode_msg_fun(Mod, Conf),
+ rarala_mg_decode_msg_fun(Mod, Conf)).
+-define(rarala_mg_encode_msg_fun(Mod, Conf),
+ rarala_mg_encode_msg_fun(Mod, Conf)).
+-define(rarala_mg_verify_service_change_rep_msg_fun(),
+ rarala_mg_verify_service_change_rep_msg_fun()).
+-define(rarala_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId),
+ rarala_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId)).
+-endif.
+
+rarala_mg_event_sequence(text, tcp) ->
+ DecodeFun = ?rarala_mg_decode_msg_fun(megaco_pretty_text_encoder, []),
+ EncodeFun = ?rarala_mg_encode_msg_fun(megaco_pretty_text_encoder, []),
+ Mid = {deviceName,"mg"},
+ ServiceChangeReq = rarala_mg_service_change_request_msg(Mid, 1, 0),
+ TermId = #megaco_term_id{id = ["00000000","00000000","01101101"]},
+ TransId = 2,
+ ReqId = 1,
+ CtxId = 1,
+ NotifyReq = rarala_mg_notify_request_msg(Mid, TermId,
+ TransId, ReqId, CtxId),
+ TransAck = rarala_mg_trans_ack_msg(Mid, TransId),
+ ScrVerifyFun = ?rarala_mg_verify_service_change_rep_msg_fun(),
+ NrVerifyFun = ?rarala_mg_verify_notify_rep_msg_fun(TermId,
+ TransId, ReqId, CtxId),
+%% ScrVerifyFun = rarala_mg_verify_service_change_rep_msg_fun(),
+%% NrVerifyFun = rarala_mg_verify_notify_rep_msg_fun(TermId,
+%% TransId, ReqId, CtxId),
+ EvSeq = [{debug, true},
+ {decode, DecodeFun},
+ {encode, EncodeFun},
+ {connect, 2944},
+ {send, "service-change-request", ServiceChangeReq},
+ {expect_receive, "service-change-reply", {ScrVerifyFun, 10000}},
+ {send, "notify request", NotifyReq},
+ {expect_receive, "notify-reply", {NrVerifyFun, 4000}},
+ {expect_receive, "notify-reply", {NrVerifyFun, 4000}},
+ {expect_receive, "notify-reply", {NrVerifyFun, 4000}},
+ {send, "transaction-ack", TransAck},
+ {expect_nothing, 11000},
+ disconnect
+ ],
+ EvSeq.
+
+-ifndef(megaco_hipe_special).
+rarala_mg_encode_msg_fun(Mod, Conf) ->
+ fun(M) ->
+ encode_msg(M, Mod, Conf)
+ end.
+-endif.
+
+-ifndef(megaco_hipe_special).
+rarala_mg_decode_msg_fun(Mod, Conf) ->
+ fun(M) ->
+ decode_msg(M, Mod, Conf)
+ end.
+-endif.
+
+-ifndef(megaco_hipe_special).
+rarala_mg_verify_service_change_rep_msg_fun() ->
+ fun(Msg) ->
+ (catch rarala_mg_verify_service_change_rep_msg(Msg))
+ end.
+-endif.
+
+rarala_mg_verify_service_change_rep_msg(#'MegacoMessage'{mess = Mess} = M) ->
+ Body =
+ case Mess of
+ #'Message'{version = _V,
+ mId = _MgMid,
+ messageBody = MsgBody} ->
+ MsgBody;
+ _ ->
+ throw({error, {invalid_Message, Mess}})
+ end,
+ Trans =
+ case Body of
+ {transactions, [Transactions]} ->
+ Transactions;
+ _ ->
+ throw({error, {invalid_messageBody, Body}})
+ end,
+ TR =
+ case Trans of
+ {transactionReply, TransReply} ->
+ TransReply;
+ _ ->
+ throw({error, {invalid_transactions, Trans}})
+ end,
+ TRes =
+ case TR of
+ #'TransactionReply'{transactionId = _Tid,
+ immAckRequired = asn1_NOVALUE,
+ transactionResult = TransRes} ->
+ TransRes;
+ _ ->
+ throw({error, {invalid_transactionReply, TR}})
+ end,
+ AR =
+ case TRes of
+ {actionReplies, [ActRes]} ->
+ ActRes;
+ _ ->
+ throw({error, {invalid_transactionResult, TRes}})
+ end,
+ CR =
+ case AR of
+ #'ActionReply'{contextId = _Cid,
+ errorDescriptor = asn1_NOVALUE,
+ contextReply = _CtxReq,
+ commandReply = [CmdRep]} ->
+ CmdRep;
+ _ ->
+ throw({error, {invalid_actionReplies, AR}})
+ end,
+ SCR =
+ case CR of
+ {serviceChangeReply, ServChRep} ->
+ ServChRep;
+ _ ->
+ throw({error, {invalid_commandReply, CR}})
+ end,
+ SCRes =
+ case SCR of
+ #'ServiceChangeReply'{terminationID = _TermID,
+ serviceChangeResult = ServChRes} ->
+ ServChRes;
+ _ ->
+ throw({error, {invalid_serviceChangeReply, SCR}})
+ end,
+ SCRP =
+ case SCRes of
+ {serviceChangeResParms, Parms} ->
+ Parms;
+ _ ->
+ throw({error, {invalid_serviceChangeResult, SCRes}})
+ end,
+ case SCRP of
+ #'ServiceChangeResParm'{serviceChangeMgcId = _MgcMid} ->
+ {ok, M};
+ _ ->
+ {error, {invalid_serviceChangeResParms, SCRP}}
+ end;
+rarala_mg_verify_service_change_rep_msg(Crap) ->
+ {error, {invalid_message, Crap}}.
+
+-ifndef(megaco_hipe_special).
+rarala_mg_verify_notify_rep_msg_fun(TermId, TransId, Rid, Cid) ->
+ fun(Msg) ->
+ (catch rarala_mg_verify_notify_rep_msg(Msg,
+ TermId, TransId, Rid, Cid))
+ end.
+-endif.
+
+rarala_mg_verify_notify_rep_msg(#'MegacoMessage'{mess = Mess} = M,
+ TermId, TransId, Rid, Cid) ->
+ io:format("rarala_mg_verify_notify_rep_msg -> entry with"
+ "~n M: ~p"
+ "~n TermId: ~p"
+ "~n TransId: ~p"
+ "~n Rid: ~p"
+ "~n Cid: ~p"
+ "~n", [M, TermId, TransId, Rid, Cid]),
+ Body =
+ case Mess of
+ #'Message'{version = ?VERSION,
+ mId = _Mid,
+ messageBody = MsgBody} ->
+ MsgBody;
+ _ ->
+ throw({error, {invalid_Message, Mess}})
+ end,
+ Trans =
+ case Body of
+ {transactions, [Transactions]} ->
+ Transactions;
+ _ ->
+ throw({error, {invalid_messageBody, Body}})
+ end,
+ TR =
+ case Trans of
+ {transactionReply, TransReply} ->
+ TransReply;
+ _ ->
+ throw({error, {invalid_transactions, Trans}})
+ end,
+ TRes =
+ case TR of
+ #'TransactionReply'{transactionId = TransId,
+ immAckRequired = 'NULL',
+ transactionResult = TransRes} ->
+ TransRes;
+ _ ->
+ throw({error, {invalid_transactionReply, TR}})
+ end,
+ AR =
+ case TRes of
+ {actionReplies, [ActRes]} ->
+ ActRes;
+ _ ->
+ throw({error, {invalid_transactionResult, TRes}})
+ end,
+ CR =
+ case AR of
+ #'ActionReply'{contextId = Cid,
+ errorDescriptor = asn1_NOVALUE,
+ contextReply = _CtxReq,
+ commandReply = [CmdRep]} ->
+ CmdRep;
+ _ ->
+ throw({error, {invalid_actionReplies, AR}})
+ end,
+ NR =
+ case CR of
+ {notifyReply, NotifyReply} ->
+ NotifyReply;
+ _ ->
+ throw({error, {invalid_commandReply, CR}})
+ end,
+ case NR of
+ #'NotifyReply'{terminationID = [TermId],
+ errorDescriptor = asn1_NOVALUE} ->
+ {ok, M};
+ _ ->
+ {error, {invalid_notifyReply, NR}}
+ end;
+rarala_mg_verify_notify_rep_msg(Crap, _TermId, _TransId, _Rid, _Cid) ->
+ {error, {invalid_message, Crap}}.
+
+rarala_mg_service_change_request_ar(_Mid, Cid) ->
+ Prof = cre_serviceChangeProf("resgw", 1),
+ SCP = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = cre_serviceChangeReq([Root], SCP),
+ CMD = cre_command(SCR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+rarala_mg_service_change_request_msg(Mid, TransId, Cid) ->
+ AR = rarala_mg_service_change_request_ar(Mid, Cid),
+ TR = cre_transReq(TransId, [AR]),
+ Trans = cre_transaction(TR),
+ Mess = cre_message(?VERSION, Mid, cre_transactions([Trans])),
+ cre_megacoMessage(Mess).
+
+rarala_mg_notify_request_ar(Rid, Tid, Cid) ->
+ TT = cre_timeNotation("19990729", "22000000"),
+ Ev = cre_obsEvent("al/of", TT),
+ EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
+ NR = cre_notifyReq([Tid], EvsDesc),
+ CMD = cre_command(NR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+rarala_mg_notify_request_msg(Mid, TermId, TransId, Rid, Cid) ->
+ AR = rarala_mg_notify_request_ar(Rid, TermId, Cid),
+ TR = cre_transReq(TransId, [AR]),
+ Trans = cre_transaction(TR),
+ Mess = cre_message(?VERSION, Mid, cre_transactions([Trans])),
+ cre_megacoMessage(Mess).
+
+rarala_mg_trans_ack_msg(Mid, TransId) ->
+ TR = cre_transRespAck(cre_transAck(TransId)),
+ Trans = cre_transaction(TR),
+ Mess = cre_message(?VERSION, Mid, cre_transactions([Trans])),
+ cre_megacoMessage(Mess).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+trans_req_and_reply_and_req(suite) ->
+ [];
+trans_req_and_reply_and_req(doc) ->
+ ["Receive a transaction request, send a reply (discard ack)"
+ "then receive the same reply again after the timeout. "
+ "The MGC is a megaco instance (megaco event sequence) and the "
+ "MG is emulated (tcp event sequence)"];
+trans_req_and_reply_and_req(Config) when is_list(Config) ->
+ %% <CONDITIONAL-SKIP>
+ Skippable = [{unix, [darwin, linux]}],
+ Condition = fun() -> ?OS_BASED_SKIP(Skippable) end,
+ ?NON_PC_TC_MAYBE_SKIP(Config, Condition),
+ %% </CONDITIONAL-SKIP>
+
+ put(verbosity, ?TEST_VERBOSITY),
+ put(sname, "TEST"),
+ put(tc, trarar),
+ i("starting"),
+
+ MgcNode = make_node_name(mgc),
+ MgNode = make_node_name(mg),
+ d("start nodes: "
+ "~n MgcNode: ~p"
+ "~n MgNode: ~p",
+ [MgcNode, MgNode]),
+ ok = megaco_test_lib:start_nodes([MgcNode, MgNode], ?FILE, ?LINE),
+
+
+ d("[MGC] start the simulator "),
+ {ok, Mgc} = megaco_test_megaco_generator:start_link("MGC", MgcNode),
+
+ d("[MGC] create the event sequence"),
+ MgcEvSeq = trarar_mgc_event_sequence(text, tcp),
+
+ i("wait some time before starting the MGC simulation"),
+ sleep(1000),
+
+ d("[MGC] start the simulation"),
+ {ok, MgcId} = megaco_test_megaco_generator:exec(Mgc, MgcEvSeq),
+
+ i("wait some time before starting the MG simulator"),
+ sleep(1000),
+
+ d("[MG] start the simulator (generator)"),
+ {ok, Mg} = megaco_test_tcp_generator:start_link("MG", MgNode),
+
+ d("[MG] create the event sequence"),
+ MgEvSeq = trarar_mg_event_sequence(text, tcp),
+
+ i("wait some time before starting the MG simulation"),
+ sleep(1000),
+
+ d("[MG] start the simulation"),
+ {ok, MgId} = megaco_test_tcp_generator:exec(Mg, MgEvSeq),
+
+ d("await the generator reply(s)"),
+ await_completion([MgcId, MgId], 60000),
+
+ %% Tell Mgc to stop
+ i("[MGC] stop generator"),
+ megaco_test_megaco_generator:stop(Mgc),
+
+ %% Tell Mg to stop
+ i("[MG] stop generator"),
+ megaco_test_tcp_generator:stop(Mg),
+
+ i("done", []),
+ ok.
+
+
+%%
+%% MGC generator stuff
+%%
+-ifdef(megaco_hipe_special).
+-define(trarar_mgc_verify_handle_connect_fun(),
+ {?MODULE, trarar_mgc_verify_handle_connect, []}).
+-define(trarar_mgc_verify_service_change_req_fun(Mid),
+ {?MODULE, trarar_mgc_verify_service_change_req, [Mid]}).
+-define(trarar_mgc_verify_notify_req_fun(Cid),
+ {?MODULE, trarar_mgc_verify_notify_req, [Cid]}).
+-define(trarar_mgc_verify_handle_disconnect_fun(),
+ {?MODULE, trarar_mgc_verify_handle_disconnect, []}).
+-else.
+-define(trarar_mgc_verify_handle_connect_fun(),
+ fun trarar_mgc_verify_handle_connect/1).
+-define(trarar_mgc_verify_service_change_req_fun(Mid),
+ trarar_mgc_verify_service_change_req_fun(Mid)).
+-define(trarar_mgc_verify_notify_req_fun(Cid),
+ trarar_mgc_verify_notify_req_fun(Cid)).
+-define(trarar_mgc_verify_handle_disconnect_fun(),
+ fun trarar_mgc_verify_handle_disconnect/1).
+-endif.
+
+trarar_mgc_event_sequence(text, tcp) ->
+ Mid = {deviceName,"ctrl"},
+ RI = [
+ {port, 2944},
+ {encoding_module, megaco_pretty_text_encoder},
+ {encoding_config, []},
+ {transport_module, megaco_tcp}
+ ],
+%% Tid = #megaco_term_id{id = ["00000000","00000000","01101101"]},
+%% ReqTmr = #megaco_incr_timer{wait_for = 500,
+%% factor = 1,
+%% max_retries = 1},
+ ConnectVerify = ?trarar_mgc_verify_handle_connect_fun(),
+ ServiceChangeReqVerify = ?trarar_mgc_verify_service_change_req_fun(Mid),
+ NotifyReqVerify1 = ?trarar_mgc_verify_notify_req_fun(1),
+ NotifyReqVerify2 = ?trarar_mgc_verify_notify_req_fun(2),
+ NotifyReqVerify3 = ?trarar_mgc_verify_notify_req_fun(3),
+ NotifyReqVerify4 = ?trarar_mgc_verify_notify_req_fun(4),
+ DiscoVerify = ?trarar_mgc_verify_handle_disconnect_fun(),
+%% ConnectVerify = fun trarar_mgc_verify_handle_connect/1,
+%% ServiceChangeReqVerify = trarar_mgc_verify_service_change_req_fun(Mid),
+%% NotifyReqVerify1 = trarar_mgc_verify_notify_request_fun(1),
+%% NotifyReqVerify2 = trarar_mgc_verify_notify_request_fun(2),
+%% NotifyReqVerify3 = trarar_mgc_verify_notify_request_fun(3),
+%% NotifyReqVerify4 = trarar_mgc_verify_notify_request_fun(4),
+%% DiscoVerify = fun trarar_mgc_verify_handle_disconnect/1,
+ EvSeq = [
+ {debug, true},
+ {megaco_trace, disable},
+ megaco_start,
+ {megaco_start_user, Mid, RI, []},
+ {megaco_update_user_info, reply_timer, 2000},
+ start_transport,
+ listen,
+ {megaco_callback, handle_connect, ConnectVerify},
+ {megaco_callback, handle_trans_request, ServiceChangeReqVerify},
+ {megaco_callback, handle_trans_request, NotifyReqVerify1},
+ {megaco_callback, handle_trans_request, NotifyReqVerify2},
+ {megaco_update_conn_info, reply_timer, 4000},
+ {megaco_callback, handle_trans_request, NotifyReqVerify3},
+ {megaco_callback, handle_trans_request, NotifyReqVerify4},
+ {megaco_callback, handle_disconnect, DiscoVerify},
+ {sleep, 1000},
+ megaco_stop_user,
+ megaco_stop
+ ],
+ EvSeq.
+
+
+trarar_mgc_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
+ io:format("trarar_mgc_verify_handle_connect -> ok"
+ "~n CH: ~p~n", [CH]),
+ {ok, CH, ok};
+trarar_mgc_verify_handle_connect(Else) ->
+ io:format("trarar_mgc_verify_handle_connect -> unknown"
+ "~n Else: ~p~n", [Else]),
+ {error, Else, ok}.
+
+-ifndef(megaco_hipe_special).
+trarar_mgc_verify_service_change_req_fun(Mid) ->
+ fun(Req) ->
+ trarar_mgc_verify_service_change_req(Req, Mid)
+ end.
+-endif.
+
+trarar_mgc_verify_service_change_req(
+ {handle_trans_request, _, ?VERSION, [AR]}, Mid) ->
+ (catch trarar_mgc_do_verify_service_change_req(AR, Mid));
+trarar_mgc_verify_service_change_req(Crap, _Mid) ->
+ ED = cre_ErrDesc(Crap),
+ ErrReply = {discard_ack, ED},
+ {error, Crap, ErrReply}.
+
+trarar_mgc_do_verify_service_change_req(AR, Mid) ->
+ io:format("trarar_mgc_verify_service_change_req -> ok"
+ "~n AR: ~p"
+ "~n Mid: ~p"
+ "~n", [AR, Mid]),
+ CR =
+ case AR of
+ #'ActionRequest'{commandRequests = [CmdReq]} ->
+ CmdReq;
+ _ ->
+ Err1 = {invalid_action_request, AR},
+ ED1 = cre_ErrDesc(AR),
+ ErrReply1 = {discard_ack, ED1},
+ throw({error, Err1, ErrReply1})
+ end,
+ Cmd =
+ case CR of
+ #'CommandRequest'{command = Command} ->
+ Command;
+ _ ->
+ Err2 = {invalid_command_request, CR},
+ ED2 = cre_ErrDesc(CR),
+ ErrReply2 = {discard_ack, ED2},
+ throw({error, Err2, ErrReply2})
+ end,
+ {Tid, Parms} =
+ case Cmd of
+ {serviceChangeReq,
+ #'ServiceChangeRequest'{terminationID = [TermID],
+ serviceChangeParms = ServChParms}} ->
+ {TermID, ServChParms};
+ _ ->
+ Err3 = {invalid_command, Cmd},
+ ED3 = cre_ErrDesc(Cmd),
+ ErrReply3 = {discard_ack, ED3},
+ throw({error, Err3, ErrReply3})
+ end,
+ case Tid of
+ #megaco_term_id{contains_wildcards = false, id = ["root"]} ->
+ ok;
+ _ ->
+ Err4 = {invalid_termination_id, Tid},
+ ED4 = cre_ErrDesc(Tid),
+ ErrReply4 = {discard_ack, ED4},
+ throw({error, Err4, ErrReply4})
+ end,
+ case Parms of
+ #'ServiceChangeParm'{serviceChangeMethod = restart,
+ serviceChangeReason = [[$9,$0,$1|_]]} ->
+ AckData = [trarar_mgc_service_change_reply_ar(Mid, 1)],
+ Reply = {discard_ack, AckData},
+ {ok, AR, Reply};
+ _ ->
+ Err5 = {invalid_SCP, Parms},
+ ED5 = cre_ErrDesc(Parms),
+ ErrReply5 = {discard_ack, ED5},
+ {error, Err5, ErrReply5}
+ end.
+
+-ifndef(megaco_hipe_special).
+trarar_mgc_verify_notify_req_fun(Cid) ->
+ fun(Req) ->
+ trarar_mgc_verify_notify_req(Req, Cid)
+ end.
+-endif.
+
+trarar_mgc_verify_notify_req({handle_trans_request, _, ?VERSION, [AR]}, Cid) ->
+ (catch trarar_mgc_do_verify_notify_req(AR, Cid));
+trarar_mgc_verify_notify_req(Crap, _Cid) ->
+ ED = cre_ErrDesc(Crap),
+ ErrReply = {discard_ack, ED},
+ {error, Crap, ErrReply}.
+
+trarar_mgc_do_verify_notify_req(AR, Cid) ->
+ io:format("trarar_mgc_do_verify_notify_req -> entry with"
+ "~n AR: ~p"
+ "~n Cid: ~p"
+ "~n", [AR, Cid]),
+ {ContextID, CR} =
+ case AR of
+ #'ActionRequest'{contextId = CtxID,
+ commandRequests = [CmdReq]} when (CtxID == Cid) ->
+ {CtxID, CmdReq};
+ _ ->
+ Err1 = {invalid_action_request, AR},
+ ED1 = cre_ErrDesc(AR),
+ ErrReply1 = {discard_ack, ED1},
+ throw({error, Err1, ErrReply1})
+ end,
+ Cmd =
+ case CR of
+ #'CommandRequest'{command = Command} ->
+ Command;
+ _ ->
+ Err2 = {invalid_command_request, CR},
+ ED2 = cre_ErrDesc(CR),
+ ErrReply2 = {discard_ack, ED2},
+ throw({error, Err2, ErrReply2})
+ end,
+ NR =
+ case Cmd of
+ {notifyReq, NotifReq} ->
+ NotifReq;
+ _ ->
+ Err3 = {invalid_command, Cmd},
+ ED3 = cre_ErrDesc(Cmd),
+ ErrReply3 = {discard_ack, ED3},
+ throw({error, Err3, ErrReply3})
+ end,
+ {Tid, OED} =
+ case NR of
+ #'NotifyRequest'{terminationID = [TermID],
+ observedEventsDescriptor = ObsEvsDesc,
+ errorDescriptor = asn1_NOVALUE} ->
+ {TermID, ObsEvsDesc};
+ _ ->
+ Err4 = {invalid_NR, NR},
+ ED4 = cre_ErrDesc(NR),
+ ErrReply4 = {discard_ack, ED4},
+ throw({error, Err4, ErrReply4})
+ end,
+ OE =
+ case OED of
+ #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
+ ObsEvLst;
+ _ ->
+ Err5 = {invalid_OED, OED},
+ ED5 = cre_ErrDesc(NR),
+ ErrReply5 = {discard_ack, ED5},
+ throw({error, Err5, ErrReply5})
+ end,
+ case OE of
+ #'ObservedEvent'{eventName = "al/of"} ->
+ Replies = [trarar_mgc_notify_reply_ar(ContextID, Tid)],
+ Reply = {discard_ack, Replies},
+ {ok, AR, Reply};
+ _ ->
+ Err6 = {invalid_OE, OE},
+ ED6 = cre_ErrDesc(OE),
+ ErrReply6 = {discard_ack, ED6},
+ {error, Err6, ErrReply6}
+ end.
+
+trarar_mgc_verify_handle_disconnect({handle_disconnect, CH, ?VERSION, R}) ->
+ io:format("trarar_mgc_verify_handle_disconnect -> ok"
+ "~n CH: ~p"
+ "~n R: ~p"
+ "~n", [CH, R]),
+ {ok, CH, ok};
+trarar_mgc_verify_handle_disconnect(Else) ->
+ io:format("trarar_mgc_verify_handle_disconnect -> unknown"
+ "~n Else: ~p~n", [Else]),
+ {error, Else, ok}.
+
+
+trarar_mgc_service_change_reply_ar(Mid, Cid) ->
+ SCRP = cre_serviceChangeResParm(Mid),
+ SCRes = cre_serviceChangeResult(SCRP),
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = cre_serviceChangeReply([Root], SCRes),
+ CR = cre_cmdReply(SCR),
+ cre_actionReply(Cid, [CR]).
+
+trarar_mgc_notify_reply_ar(Cid, TermId) ->
+ NR = cre_notifyReply([TermId]),
+ CR = cre_cmdReply(NR),
+ cre_actionReply(Cid, [CR]).
+
+%% trarar_mgc_notify_reply(Mid, TransId, Cid, TermId) ->
+%% AR = trarar_mgc_notify_reply_ar(Cid, TermId),
+%% TRes = cre_transResult([AR]),
+%% TR = cre_transReply(TransId, TRes),
+%% Trans = cre_transaction(TR),
+%% Mess = cre_message(?VERSION, Mid, cre_transactions([Trans])),
+%% cre_megacoMessage(Mess).
+
+
+%%
+%% MG generator stuff
+%%
+-ifdef(megaco_hipe_special).
+-define(trarar_mg_decode_msg_fun(Mod, Conf),
+ {?MODULE, decode_msg, [Mod, Conf]}).
+-define(trarar_mg_encode_msg_fun(Mod, Conf),
+ {?MODULE, encode_msg, [Mod, Conf]}).
+-define(trarar_mg_verify_service_change_rep_msg_fun(),
+ {?MODULE, trarar_mg_verify_service_change_rep_msg, []}).
+-define(trarar_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId),
+ {?MODULE, trarar_mg_verify_notify_rep_msg, [TermId, TransId, ReqId, CtxId]}).
+-else.
+-define(trarar_mg_decode_msg_fun(Mod, Conf),
+ trarar_mg_decode_msg_fun(Mod, Conf)).
+-define(trarar_mg_encode_msg_fun(Mod, Conf),
+ trarar_mg_encode_msg_fun(Mod, Conf)).
+-define(trarar_mg_verify_service_change_rep_msg_fun(),
+ trarar_mg_verify_service_change_rep_msg_fun()).
+-define(trarar_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId),
+ trarar_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId)).
+-endif.
+
+trarar_mg_event_sequence(text, tcp) ->
+ DecodeFun = ?trarar_mg_decode_msg_fun(megaco_pretty_text_encoder, []),
+ EncodeFun = ?trarar_mg_encode_msg_fun(megaco_pretty_text_encoder, []),
+ Mid = {deviceName,"mg"},
+ ServiceChangeReq = trarar_mg_service_change_request_msg(Mid, 1, 0),
+ TermId = #megaco_term_id{id = ["00000000","00000000","01101101"]},
+ NotifyReq1 =
+ trarar_mg_notify_request_msg(Mid, TermId, 2, 1, 1),
+ NotifyReq2 =
+ trarar_mg_notify_request_msg(Mid, TermId, 2, 2, 2),
+ NotifyReq3 =
+ trarar_mg_notify_request_msg(Mid, TermId, 2, 3, 3),
+ NotifyReq4 =
+ trarar_mg_notify_request_msg(Mid, TermId, 2, 4, 4),
+ ScrVerifyFun = ?trarar_mg_verify_service_change_rep_msg_fun(),
+ NrVerifyFun1 =
+ ?trarar_mg_verify_notify_rep_msg_fun(TermId, 2, 1, 1),
+ NrVerifyFun2 =
+ ?trarar_mg_verify_notify_rep_msg_fun(TermId, 2, 2, 2),
+ NrVerifyFun3 =
+ ?trarar_mg_verify_notify_rep_msg_fun(TermId, 2, 3, 3),
+ NrVerifyFun4 =
+ ?trarar_mg_verify_notify_rep_msg_fun(TermId, 2, 4, 4),
+%% ScrVerifyFun = trarar_mg_verify_service_change_rep_msg_fun(),
+%% NrVerifyFun1 =
+%% trarar_mg_verify_notify_rep_msg_fun(TermId, 2, 1, 1),
+%% NrVerifyFun2 =
+%% trarar_mg_verify_notify_rep_msg_fun(TermId, 2, 2, 2),
+%% NrVerifyFun3 =
+%% trarar_mg_verify_notify_rep_msg_fun(TermId, 2, 3, 3),
+%% NrVerifyFun4 =
+%% trarar_mg_verify_notify_rep_msg_fun(TermId, 2, 4, 4),
+ EvSeq = [{debug, true},
+ {decode, DecodeFun},
+ {encode, EncodeFun},
+ {connect, 2944},
+
+ {send, "service-change-request", ServiceChangeReq},
+ {expect_receive, "service-change-reply", {ScrVerifyFun, 10000}},
+
+ %% the original setting for reply timer is 2000
+ {send, "notify request 1", NotifyReq1},
+ {expect_receive, "notify-reply 1", {NrVerifyFun1, 2500}},
+ {sleep, 1000},
+ {send, "notify request 2", NotifyReq2},
+ {expect_receive, "notify-reply 2 (resend of 1)", {NrVerifyFun1, 2500}},
+ {sleep, 3000}, % reply timer is set to 2000
+ {send, "notify request 3 (same as 2)", NotifyReq2},
+ {expect_receive, "notify-reply 3", {NrVerifyFun2, 2500}},
+
+ %% reply timer is now set to 4000 but previous was 2000
+ %% so, 3000 is enough to let the timer running with the
+ %% previous settings (2000) to time out
+ {sleep, 3000},
+ {send, "notify request 4", NotifyReq3},
+ {expect_receive, "notify-reply 4", {NrVerifyFun3, 4500}},
+ {sleep, 5000},
+ {send, "notify request 5", NotifyReq4},
+ {expect_receive, "notify-reply 5", {NrVerifyFun4, 4500}},
+
+ {expect_nothing, 5000},
+ disconnect
+ ],
+ EvSeq.
+
+-ifndef(megaco_hipe_special).
+trarar_mg_encode_msg_fun(Mod, Conf) ->
+ fun(M) ->
+ encode_msg(M, Mod, Conf)
+ end.
+-endif.
+
+-ifndef(megaco_hipe_special).
+trarar_mg_decode_msg_fun(Mod, Conf) ->
+ fun(M) ->
+ decode_msg(M, Mod, Conf)
+ end.
+-endif.
+
+-ifndef(megaco_hipe_special).
+trarar_mg_verify_service_change_rep_msg_fun() ->
+ fun(Msg) ->
+ (catch trarar_mg_verify_service_change_rep_msg(Msg))
+ end.
+-endif.
+
+trarar_mg_verify_service_change_rep_msg(#'MegacoMessage'{mess = Mess} = M) ->
+ Body =
+ case Mess of
+ #'Message'{version = _V,
+ mId = _MgMid,
+ messageBody = MsgBody} ->
+ MsgBody;
+ _ ->
+ throw({error, {invalid_Message, Mess}})
+ end,
+ Trans =
+ case Body of
+ {transactions, [Transactions]} ->
+ Transactions;
+ _ ->
+ throw({error, {invalid_messageBody, Body}})
+ end,
+ TR =
+ case Trans of
+ {transactionReply, TransReply} ->
+ TransReply;
+ _ ->
+ throw({error, {invalid_transactions, Trans}})
+ end,
+ TRes =
+ case TR of
+ #'TransactionReply'{transactionId = _Tid,
+ immAckRequired = asn1_NOVALUE,
+ transactionResult = TransRes} ->
+ TransRes;
+ _ ->
+ throw({error, {invalid_transactionReply, TR}})
+ end,
+ AR =
+ case TRes of
+ {actionReplies, [ActRes]} ->
+ ActRes;
+ _ ->
+ throw({error, {invalid_transactionResult, TRes}})
+ end,
+ CR =
+ case AR of
+ #'ActionReply'{contextId = _Cid,
+ errorDescriptor = asn1_NOVALUE,
+ contextReply = _CtxReq,
+ commandReply = [CmdRep]} ->
+ CmdRep;
+ _ ->
+ throw({error, {invalid_actionReplies, AR}})
+ end,
+ SCR =
+ case CR of
+ {serviceChangeReply, ServChRep} ->
+ ServChRep;
+ _ ->
+ throw({error, {invalid_commandReply, CR}})
+ end,
+ SCRes =
+ case SCR of
+ #'ServiceChangeReply'{terminationID = _TermID,
+ serviceChangeResult = ServChRes} ->
+ ServChRes;
+ _ ->
+ throw({error, {invalid_serviceChangeReply, SCR}})
+ end,
+ SCRP =
+ case SCRes of
+ {serviceChangeResParms, Parms} ->
+ Parms;
+ _ ->
+ throw({error, {invalid_serviceChangeResult, SCRes}})
+ end,
+ case SCRP of
+ #'ServiceChangeResParm'{serviceChangeMgcId = _MgcMid} ->
+ {ok, M};
+ _ ->
+ {error, {invalid_serviceChangeResParms, SCRP}}
+ end;
+trarar_mg_verify_service_change_rep_msg(Crap) ->
+ {error, {invalid_message, Crap}}.
+
+-ifndef(megaco_hipe_special).
+trarar_mg_verify_notify_rep_msg_fun(TermId, TransId, Rid, Cid) ->
+ fun(Msg) ->
+ (catch trarar_mg_verify_notify_rep_msg(Msg,
+ TermId, TransId, Rid, Cid))
+ end.
+-endif.
+
+trarar_mg_verify_notify_rep_msg(#'MegacoMessage'{mess = Mess} = M,
+ TermId, TransId, Rid, Cid) ->
+ io:format("trarar_mg_verify_notify_rep_msg -> entry with"
+ "~n M: ~p"
+ "~n TermId: ~p"
+ "~n TransId: ~p"
+ "~n Rid: ~p"
+ "~n Cid: ~p"
+ "~n", [M, TermId, TransId, Rid, Cid]),
+ Body =
+ case Mess of
+ #'Message'{version = ?VERSION,
+ mId = _Mid,
+ messageBody = MsgBody} ->
+ MsgBody;
+ _ ->
+ throw({error, {invalid_Message, Mess}})
+ end,
+ io:format("trarar_mg_verify_notify_rep_msg -> "
+ "~n Body: ~p"
+ "~n", [Body]),
+ Trans =
+ case Body of
+ {transactions, [Transactions]} ->
+ Transactions;
+ _ ->
+ throw({error, {invalid_messageBody, Body}})
+ end,
+ io:format("trarar_mg_verify_notify_rep_msg -> "
+ "~n Trans: ~p"
+ "~n", [Trans]),
+ TR =
+ case Trans of
+ {transactionReply, TransReply} ->
+ TransReply;
+ _ ->
+ throw({error, {invalid_transactions, Trans}})
+ end,
+ io:format("trarar_mg_verify_notify_rep_msg -> "
+ "~n TR: ~p"
+ "~n", [TR]),
+ TRes =
+ case TR of
+ #'TransactionReply'{transactionId = TransId,
+ immAckRequired = asn1_NOVALUE,
+ transactionResult = TransRes} ->
+ TransRes;
+ _ ->
+ throw({error, {invalid_transactionReply, TR}})
+ end,
+ io:format("trarar_mg_verify_notify_rep_msg -> "
+ "~n TRes: ~p"
+ "~n", [TRes]),
+ AR =
+ case TRes of
+ {actionReplies, [ActRes]} ->
+ ActRes;
+ _ ->
+ throw({error, {invalid_transactionResult, TRes}})
+ end,
+ io:format("trarar_mg_verify_notify_rep_msg -> "
+ "~n AR: ~p"
+ "~n", [AR]),
+ CR =
+ case AR of
+ #'ActionReply'{contextId = Cid,
+ errorDescriptor = asn1_NOVALUE,
+ contextReply = _CtxReq,
+ commandReply = [CmdRep]} ->
+ CmdRep;
+ _ ->
+ throw({error, {invalid_actionReplies, AR}})
+ end,
+ NR =
+ case CR of
+ {notifyReply, NotifyReply} ->
+ NotifyReply;
+ _ ->
+ throw({error, {invalid_commandReply, CR}})
+ end,
+ case NR of
+ #'NotifyReply'{terminationID = [TermId],
+ errorDescriptor = asn1_NOVALUE} ->
+ {ok, M};
+ _ ->
+ {error, {invalid_notifyReply, NR}}
+ end;
+trarar_mg_verify_notify_rep_msg(Crap, _TermId, _TransId, _Rid, _Cid) ->
+ {error, {invalid_message, Crap}}.
+
+trarar_mg_service_change_request_ar(_Mid, Cid) ->
+ Prof = cre_serviceChangeProf("resgw", 1),
+ SCP = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = cre_serviceChangeReq([Root], SCP),
+ CMD = cre_command(SCR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+trarar_mg_service_change_request_msg(Mid, TransId, Cid) ->
+ AR = trarar_mg_service_change_request_ar(Mid, Cid),
+ TR = cre_transReq(TransId, [AR]),
+ Trans = cre_transaction(TR),
+ Mess = cre_message(?VERSION, Mid, cre_transactions([Trans])),
+ cre_megacoMessage(Mess).
+
+trarar_mg_notify_request_ar(Rid, Tid, Cid) ->
+ TT = cre_timeNotation("19990729", "22000000"),
+ Ev = cre_obsEvent("al/of", TT),
+ EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
+ NR = cre_notifyReq([Tid], EvsDesc),
+ CMD = cre_command(NR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+trarar_mg_notify_request_msg(Mid, TermId, TransId, Rid, Cid) ->
+ AR = trarar_mg_notify_request_ar(Rid, TermId, Cid),
+ TR = cre_transReq(TransId, [AR]),
+ Trans = cre_transaction(TR),
+ Mess = cre_message(?VERSION, Mid, cre_transactions([Trans])),
+ cre_megacoMessage(Mess).
+
+%% trarar_mg_trans_ack_msg(Mid, TransId) ->
+%% TR = cre_transRespAck(cre_transAck(TransId)),
+%% Trans = cre_transaction(TR),
+%% Mess = cre_message(?VERSION, Mid, cre_transactions([Trans])),
+%% cre_megacoMessage(Mess).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+pending_ack_plain(suite) ->
+ [];
+pending_ack_plain(doc) ->
+ ["Receive a request and handle it as a long request, "
+ "i.e. return with {pending, _} and expect a call to the "
+ "long request function"];
+pending_ack_plain(Config) when is_list(Config) ->
+ put(verbosity, ?TEST_VERBOSITY),
+ put(sname, "TEST"),
+ put(tc, pap),
+ i("starting"),
+
+ MgcNode = make_node_name(mgc),
+ MgNode = make_node_name(mg),
+ d("start nodes: "
+ "~n MgcNode: ~p"
+ "~n MgNode: ~p",
+ [MgcNode, MgNode]),
+ ok = megaco_test_lib:start_nodes([MgcNode, MgNode], ?FILE, ?LINE),
+
+ d("[MGC] start the simulator "),
+ {ok, Mgc} = megaco_test_megaco_generator:start_link("MGC", MgcNode),
+
+ d("[MGC] create the event sequence"),
+ MgcEvSeq = pap_mgc_event_sequence(text, tcp),
+
+ i("wait some time before starting the MGC simulation"),
+ sleep(1000),
+
+ d("[MGC] start the simulation"),
+ {ok, MgcId} = megaco_test_megaco_generator:exec(Mgc, MgcEvSeq),
+
+ i("wait some time before starting the MG simulator"),
+ sleep(1000),
+
+ d("[MG] start the simulator (generator)"),
+ {ok, Mg} = megaco_test_tcp_generator:start_link("MG", MgNode),
+
+ d("[MG] create the event sequence"),
+ MgEvSeq = pap_mg_event_sequence(text, tcp),
+
+ i("wait some time before starting the MG simulation"),
+ sleep(1000),
+
+ d("[MG] start the simulation"),
+ {ok, MgId} = megaco_test_tcp_generator:exec(Mg, MgEvSeq),
+
+ d("await the generator reply(s)"),
+ await_completion([MgcId, MgId]),
+
+ %% Tell Mgc to stop
+ i("[MGC] stop generator"),
+ megaco_test_megaco_generator:stop(Mgc),
+
+ %% Tell Mg to stop
+ i("[MG] stop generator"),
+ megaco_test_tcp_generator:stop(Mg),
+
+ i("done", []),
+ ok.
+
+
+%%
+%% MGC generator stuff
+%%
+
+-ifdef(megaco_hipe_special).
+-define(pap_mgc_verify_handle_connect_fun(),
+ {?MODULE, pap_mgc_verify_handle_connect, []}).
+-define(pap_mgc_verify_service_change_req_fun(Mid),
+ {?MODULE, pap_mgc_verify_service_change_req, [Mid]}).
+-define(pap_mgc_verify_notify_req_fun(),
+ {?MODULE, pap_mgc_verify_notify_req, []}).
+-define(pap_mgc_verify_notify_req_long_fun(),
+ {?MODULE, pap_mgc_verify_notify_req_long, []}).
+-define(pap_mgc_verify_handle_trans_ack_fun(),
+ {?MODULE, pap_mgc_verify_handle_trans_ack, []}).
+-define(pap_mgc_verify_handle_disconnect_fun(),
+ {?MODULE, pap_mgc_verify_handle_disconnect, []}).
+-else.
+-define(pap_mgc_verify_handle_connect_fun(),
+ fun pap_mgc_verify_handle_connect/1).
+-define(pap_mgc_verify_service_change_req_fun(Mid),
+ pap_mgc_verify_service_change_req_fun(Mid)).
+-define(pap_mgc_verify_notify_req_fun(),
+ pap_mgc_verify_notify_req_fun()).
+-define(pap_mgc_verify_notify_req_long_fun(),
+ pap_mgc_verify_notify_req_long_fun()).
+-define(pap_mgc_verify_handle_trans_ack_fun(),
+ pap_mgc_verify_handle_trans_ack_fun()).
+-define(pap_mgc_verify_handle_disconnect_fun(),
+ fun pap_mgc_verify_handle_disconnect/1).
+-endif.
+
+pap_mgc_event_sequence(text, tcp) ->
+ Mid = {deviceName,"ctrl"},
+ RI = [
+ {port, 2944},
+ {encoding_module, megaco_pretty_text_encoder},
+ {encoding_config, []},
+ {transport_module, megaco_tcp}
+ ],
+ ConnectVerify = ?pap_mgc_verify_handle_connect_fun(),
+ ScrVerify = ?pap_mgc_verify_service_change_req_fun(Mid),
+ NrVerify1 = ?pap_mgc_verify_notify_req_fun(),
+ NrVerify2 = ?pap_mgc_verify_notify_req_long_fun(),
+ AckVerify = ?pap_mgc_verify_handle_trans_ack_fun(),
+ DiscoVerify = ?pap_mgc_verify_handle_disconnect_fun(),
+%% ConnectVerify = fun pap_mgc_verify_handle_connect/1,
+%% ScrVerify = pap_mgc_verify_service_change_req_fun(Mid),
+%% NrVerify1 = pap_mgc_verify_notify_request_fun(),
+%% NrVerify2 = pap_mgc_verify_notify_request_long_fun(),
+%% AckVerify = pap_mgc_verify_trans_ack_fun(),
+%% DiscoVerify = fun pap_mgc_verify_handle_disconnect/1,
+ EvSeq = [
+ {debug, true},
+ {megaco_trace, disable},
+ {megaco_trace, max},
+ megaco_start,
+ {megaco_start_user, Mid, RI, []},
+ {megaco_update_user_info, sent_pending_limit, 100},
+ start_transport,
+ listen,
+ {megaco_callback, handle_connect, ConnectVerify},
+ {megaco_conn_info, all},
+ {megaco_callback, handle_trans_request, ScrVerify},
+ {megaco_callback, handle_trans_request, NrVerify1},
+ {megaco_callback, handle_trans_long_request, NrVerify2},
+ {megaco_callback, handle_trans_ack, AckVerify},
+ {megaco_callback, handle_disconnect, DiscoVerify},
+ megaco_stop_user,
+ megaco_stop
+ ],
+ EvSeq.
+
+%% Connect verification
+pap_mgc_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
+ {ok, CH, ok};
+pap_mgc_verify_handle_connect(Else) ->
+ {error, Else, ok}.
+
+%% Service Change verification
+-ifndef(megaco_hipe_special).
+pap_mgc_verify_service_change_req_fun(Mid) ->
+ fun(Req) ->
+ pap_mgc_verify_service_change_req(Req, Mid)
+ end.
+-endif.
+
+pap_mgc_verify_service_change_req(
+ {handle_trans_request, _, ?VERSION, [AR]}, Mid) ->
+ (catch pap_do_verify_service_change_req(AR, Mid));
+pap_mgc_verify_service_change_req(Crap, _Mid) ->
+ ED = cre_ErrDesc(Crap),
+ ErrReply = {discard_ack, ED},
+ {error, Crap, ErrReply}.
+
+pap_do_verify_service_change_req(AR, Mid) ->
+ CR =
+ case AR of
+ #'ActionRequest'{commandRequests = [CmdReq]} ->
+ CmdReq;
+ _ ->
+ Err1 = {invalid_action_request, AR},
+ ED1 = cre_ErrDesc(AR),
+ ErrReply1 = {discard_ack, ED1},
+ throw({error, Err1, ErrReply1})
+ end,
+ Cmd =
+ case CR of
+ #'CommandRequest'{command = Command} ->
+ Command;
+ _ ->
+ Err2 = {invalid_command_request, CR},
+ ED2 = cre_ErrDesc(CR),
+ ErrReply2 = {discard_ack, ED2},
+ throw({error, Err2, ErrReply2})
+ end,
+ {Tid, Parms} =
+ case Cmd of
+ {serviceChangeReq,
+ #'ServiceChangeRequest'{terminationID = [TermID],
+ serviceChangeParms = ServChParms}} ->
+ {TermID, ServChParms};
+ _ ->
+ Err3 = {invalid_command, Cmd},
+ ED3 = cre_ErrDesc(Cmd),
+ ErrReply3 = {discard_ack, ED3},
+ throw({error, Err3, ErrReply3})
+ end,
+ case Tid of
+ #megaco_term_id{contains_wildcards = false, id = ["root"]} ->
+ ok;
+ _ ->
+ Err4 = {invalid_termination_id, Tid},
+ ED4 = cre_ErrDesc(Tid),
+ ErrReply4 = {discard_ack, ED4},
+ throw({error, Err4, ErrReply4})
+ end,
+ case Parms of
+ #'ServiceChangeParm'{serviceChangeMethod = restart,
+ serviceChangeReason = [[$9,$0,$1|_]]} ->
+ AckData = [pap_mgc_service_change_reply_ar(Mid, 1)],
+ Reply = {discard_ack, AckData},
+ {ok, AR, Reply};
+ _ ->
+ Err5 = {invalid_SCP, Parms},
+ ED5 = cre_ErrDesc(Parms),
+ ErrReply5 = {discard_ack, ED5},
+ {error, Err5, ErrReply5}
+ end.
+
+
+%% Notify Request verification
+-ifndef(megaco_hipe_special).
+pap_mgc_verify_notify_req_fun() ->
+ fun(Req) ->
+ pap_mgc_verify_notify_req(Req)
+ end.
+-endif.
+
+pap_mgc_verify_notify_req({handle_trans_request, _, ?VERSION, [AR]}) ->
+ io:format("pap_mgc_verify_notify_req -> entry with"
+ "~n AR: ~p"
+ "~n", [AR]),
+ Reply = {pending, AR},
+ {ok, AR, Reply};
+pap_mgc_verify_notify_req(Crap) ->
+ ED = cre_ErrDesc(Crap),
+ ErrReply = {discard_ack, ED},
+ {error, Crap, ErrReply}.
+
+%% Notify Request verification
+-ifndef(megaco_hipe_special).
+pap_mgc_verify_notify_req_long_fun() ->
+ fun(Req) ->
+ pap_mgc_verify_notify_req_long(Req)
+ end.
+-endif.
+
+pap_mgc_verify_notify_req_long(
+ {handle_trans_long_request, _, ?VERSION, AR}) ->
+ (catch pap_mgc_do_verify_notify_req_long(AR));
+pap_mgc_verify_notify_req_long(Crap) ->
+ ED = cre_ErrDesc(Crap),
+ ErrReply = {discard_ack, ED},
+ {error, Crap, ErrReply}.
+
+pap_mgc_do_verify_notify_req_long(AR) ->
+ io:format("pap_mgc_do_verify_notify_req_long -> entry with"
+ "~n AR: ~p"
+ "~n", [AR]),
+ {Cid, CR} =
+ case AR of
+ #'ActionRequest'{contextId = CtxID,
+ commandRequests = [CmdReq]} ->
+ {CtxID, CmdReq};
+ _ ->
+ Err1 = {invalid_action_request, AR},
+ ED1 = cre_ErrDesc(AR),
+ ErrReply1 = {discard_ack, ED1},
+ throw({error, Err1, ErrReply1})
+ end,
+ Cmd =
+ case CR of
+ #'CommandRequest'{command = Command} ->
+ Command;
+ _ ->
+ Err2 = {invalid_command_request, CR},
+ ED2 = cre_ErrDesc(CR),
+ ErrReply2 = {discard_ack, ED2},
+ throw({error, Err2, ErrReply2})
+ end,
+ NR =
+ case Cmd of
+ {notifyReq, NotifReq} ->
+ NotifReq;
+ _ ->
+ Err3 = {invalid_command, Cmd},
+ ED3 = cre_ErrDesc(Cmd),
+ ErrReply3 = {discard_ack, ED3},
+ throw({error, Err3, ErrReply3})
+ end,
+ {Tid, OED} =
+ case NR of
+ #'NotifyRequest'{terminationID = [TermID],
+ observedEventsDescriptor = ObsEvsDesc,
+ errorDescriptor = asn1_NOVALUE} ->
+ {TermID, ObsEvsDesc};
+ _ ->
+ Err4 = {invalid_NR, NR},
+ ED4 = cre_ErrDesc(NR),
+ ErrReply4 = {discard_ack, ED4},
+ throw({error, Err4, ErrReply4})
+ end,
+ OE =
+ case OED of
+ #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
+ ObsEvLst;
+ _ ->
+ Err5 = {invalid_OED, OED},
+ ED5 = cre_ErrDesc(NR),
+ ErrReply5 = {discard_ack, ED5},
+ throw({error, Err5, ErrReply5})
+ end,
+ case OE of
+ #'ObservedEvent'{eventName = "al/of"} ->
+ AckData = pap,
+ Replies = [pap_mgc_notify_reply_ar(Cid, Tid)],
+ Reply = {{handle_ack, AckData}, Replies},
+ {ok, AR, Reply};
+ _ ->
+ Err6 = {invalid_OE, OE},
+ ED6 = cre_ErrDesc(OE),
+ ErrReply6 = {discard_ack, ED6},
+ throw({error, Err6, ErrReply6})
+ end.
+
+
+-ifndef(megaco_hipe_special).
+pap_mgc_verify_handle_trans_ack_fun() ->
+ fun(Ack) ->
+ pap_mgc_verify_handle_trans_ack(Ack)
+ end.
+-endif.
+
+pap_mgc_verify_handle_trans_ack({handle_trans_ack, CH, ?VERSION, ok, pap}) ->
+ io:format("pap_mgc_verify_handle_trans_ack -> ok"
+ "~n CH: ~p"
+ "~n", [CH]),
+ {ok, CH, ok};
+pap_mgc_verify_handle_trans_ack(Crap) ->
+ io:format("pap_mgc_verify_handle_trans_ack -> unknown"
+ "~n Crap: ~p~n", [Crap]),
+ {error, Crap, ok}.
+
+
+%% Disconnect verification
+pap_mgc_verify_handle_disconnect({handle_disconnect, CH, ?VERSION, _R}) ->
+ {ok, CH, ok};
+pap_mgc_verify_handle_disconnect(Else) ->
+ {error, Else, ok}.
+
+pap_mgc_service_change_reply_ar(Mid, Cid) ->
+ SCRP = cre_serviceChangeResParm(Mid),
+ SCRes = cre_serviceChangeResult(SCRP),
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = cre_serviceChangeReply([Root], SCRes),
+ CR = cre_cmdReply(SCR),
+ AR = cre_actionReply(Cid, [CR]),
+ AR.
+
+pap_mgc_notify_reply_ar(Cid, TermId) ->
+ NR = cre_notifyReply([TermId]),
+ CR = cre_cmdReply(NR),
+ cre_actionReply(Cid, [CR]).
+
+
+%%
+%% MG generator stuff
+%%
+-ifdef(megaco_hipe_special).
+-define(pap_mg_decode_msg_fun(Mod, Conf),
+ {?MODULE, decode_msg, [Mod, Conf]}).
+-define(pap_mg_encode_msg_fun(Mod, Conf),
+ {?MODULE, encode_msg, [Mod, Conf]}).
+-define(pap_mg_verify_service_change_rep_msg_fun(),
+ {?MODULE, pap_mg_verify_service_change_rep_msg, []}).
+-define(pap_mg_verify_pending_msg_fun(TransId),
+ {?MODULE, pap_mg_verify_pending_msg, [TransId]}).
+-define(pap_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId),
+ {?MODULE, pap_mg_verify_notify_rep_msg, [TermId, TransId, ReqId, CtxId]}).
+-else.
+-define(pap_mg_decode_msg_fun(Mod, Conf),
+ pap_mg_decode_msg_fun(Mod, Conf)).
+-define(pap_mg_encode_msg_fun(Mod, Conf),
+ pap_mg_encode_msg_fun(Mod, Conf)).
+-define(pap_mg_verify_service_change_rep_msg_fun(),
+ pap_mg_verify_service_change_rep_msg_fun()).
+-define(pap_mg_verify_pending_msg_fun(TransId),
+ pap_mg_verify_pending_msg_fun(TransId)).
+-define(pap_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId),
+ pap_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId)).
+-endif.
+
+pap_mg_event_sequence(text, tcp) ->
+ DecodeFun = ?pap_mg_decode_msg_fun(megaco_pretty_text_encoder, []),
+ EncodeFun = ?pap_mg_encode_msg_fun(megaco_pretty_text_encoder, []),
+ Mid = {deviceName,"mg"},
+ ServiceChangeReq = pap_mg_service_change_request_msg(Mid, 1, 0),
+ TermId = #megaco_term_id{id = ["00000000","00000000","01101101"]},
+ TransId = 2,
+ ReqId = 1,
+ CtxId = 1,
+ NotifyReq =
+ pap_mg_notify_request_msg(Mid, TermId, TransId, ReqId, CtxId),
+ TransAck = pap_mg_trans_ack_msg(Mid, TransId),
+ ScrVerifyFun = ?pap_mg_verify_service_change_rep_msg_fun(),
+ PendingVerifyFun =
+ ?pap_mg_verify_pending_msg_fun(TransId),
+ NrVerifyFun =
+ ?pap_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId),
+%% ScrVerifyFun = pap_mg_verify_service_change_rep_msg_fun(),
+%% PendingVerifyFun =
+%% pap_mg_verify_pending_msg_fun(TransId),
+%% NrVerifyFun =
+%% pap_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId),
+ EvSeq = [{debug, true},
+ {decode, DecodeFun},
+ {encode, EncodeFun},
+ {connect, 2944},
+ {send, "service-change-request", ServiceChangeReq},
+ {expect_receive, "service-change-reply", {ScrVerifyFun, 10000}},
+ {send, "notify request", NotifyReq},
+ {expect_receive, "pending", {PendingVerifyFun, 4000}},
+ {expect_receive, "notify-reply", {NrVerifyFun, 4000}},
+ {send, "transaction-ack", TransAck},
+ {expect_nothing, 11000},
+ disconnect
+ ],
+ EvSeq.
+
+-ifndef(megaco_hipe_special).
+pap_mg_encode_msg_fun(Mod, Conf) ->
+ fun(M) ->
+ encode_msg(M, Mod, Conf)
+ end.
+-endif.
+
+-ifndef(megaco_hipe_special).
+pap_mg_decode_msg_fun(Mod, Conf) ->
+ fun(M) ->
+ decode_msg(M, Mod, Conf)
+ end.
+-endif.
+
+-ifndef(megaco_hipe_special).
+pap_mg_verify_service_change_rep_msg_fun() ->
+ fun(Msg) ->
+ (catch pap_mg_verify_service_change_rep_msg(Msg))
+ end.
+-endif.
+
+pap_mg_verify_service_change_rep_msg(#'MegacoMessage'{mess = Mess} = M) ->
+ Body =
+ case Mess of
+ #'Message'{version = _V,
+ mId = _MgMid,
+ messageBody = MsgBody} ->
+ MsgBody;
+ _ ->
+ throw({error, {invalid_Message, Mess}})
+ end,
+ Trans =
+ case Body of
+ {transactions, [Transactions]} ->
+ Transactions;
+ _ ->
+ throw({error, {invalid_messageBody, Body}})
+ end,
+ TR =
+ case Trans of
+ {transactionReply, TransReply} ->
+ TransReply;
+ _ ->
+ throw({error, {invalid_transactions, Trans}})
+ end,
+ TRes =
+ case TR of
+ #'TransactionReply'{transactionId = _Tid,
+ immAckRequired = asn1_NOVALUE,
+ transactionResult = TransRes} ->
+ TransRes;
+ _ ->
+ throw({error, {invalid_transactionReply, TR}})
+ end,
+ AR =
+ case TRes of
+ {actionReplies, [ActRes]} ->
+ ActRes;
+ _ ->
+ throw({error, {invalid_transactionResult, TRes}})
+ end,
+ CR =
+ case AR of
+ #'ActionReply'{contextId = _Cid,
+ errorDescriptor = asn1_NOVALUE,
+ contextReply = _CtxReq,
+ commandReply = [CmdRep]} ->
+ CmdRep;
+ _ ->
+ throw({error, {invalid_actionReplies, AR}})
+ end,
+ SCR =
+ case CR of
+ {serviceChangeReply, ServChRep} ->
+ ServChRep;
+ _ ->
+ throw({error, {invalid_commandReply, CR}})
+ end,
+ SCRes =
+ case SCR of
+ #'ServiceChangeReply'{terminationID = _TermID,
+ serviceChangeResult = ServChRes} ->
+ ServChRes;
+ _ ->
+ throw({error, {invalid_serviceChangeReply, SCR}})
+ end,
+ SCRP =
+ case SCRes of
+ {serviceChangeResParms, Parms} ->
+ Parms;
+ _ ->
+ throw({error, {invalid_serviceChangeResult, SCRes}})
+ end,
+ case SCRP of
+ #'ServiceChangeResParm'{serviceChangeMgcId = _MgcMid} ->
+ {ok, M};
+ _ ->
+ {error, {invalid_serviceChangeResParms, SCRP}}
+ end;
+pap_mg_verify_service_change_rep_msg(Crap) ->
+ {error, {invalid_message, Crap}}.
+
+-ifndef(megaco_hipe_special).
+pap_mg_verify_pending_msg_fun(TransId) ->
+ fun(Msg) ->
+ (catch pap_mg_verify_pending_msg(Msg, TransId))
+ end.
+-endif.
+
+pap_mg_verify_pending_msg(#'MegacoMessage'{mess = Mess} = M, TransId) ->
+ io:format("pap_mg_verify_pending_msg -> entry with"
+ "~n M: ~p"
+ "~n TransId: ~p"
+ "~n", [M, TransId]),
+ Body =
+ case Mess of
+ #'Message'{version = ?VERSION,
+ mId = _Mid,
+ messageBody = MsgBody} ->
+ MsgBody;
+ _ ->
+ throw({error, {invalid_Message, Mess}})
+ end,
+ Trans =
+ case Body of
+ {transactions, [Transactions]} ->
+ Transactions;
+ _ ->
+ throw({error, {invalid_messageBody, Body}})
+ end,
+ TP =
+ case Trans of
+ {transactionPending, TransPending} ->
+ TransPending;
+ _ ->
+ throw({error, {invalid_transactions, Trans}})
+ end,
+ case TP of
+ #'TransactionPending'{transactionId = TransId} ->
+ {ok, M};
+ _ ->
+ {error, {invalid_transactionPending, TP}}
+ end;
+pap_mg_verify_pending_msg(Crap, _TransId) ->
+ {error, {invalid_message, Crap}}.
+
+-ifndef(megaco_hipe_special).
+pap_mg_verify_notify_rep_msg_fun(TermId, TransId, Rid, Cid) ->
+ fun(Msg) ->
+ (catch pap_mg_verify_notify_rep_msg(Msg,
+ TermId, TransId, Rid, Cid))
+ end.
+-endif.
+
+pap_mg_verify_notify_rep_msg(#'MegacoMessage'{mess = Mess} = M,
+ TermId, TransId, Rid, Cid) ->
+ io:format("pap_mg_verify_notify_rep_msg -> entry with"
+ "~n M: ~p"
+ "~n TermId: ~p"
+ "~n TransId: ~p"
+ "~n Rid: ~p"
+ "~n Cid: ~p"
+ "~n", [M, TermId, TransId, Rid, Cid]),
+ Body =
+ case Mess of
+ #'Message'{version = ?VERSION,
+ mId = _Mid,
+ messageBody = MsgBody} ->
+ MsgBody;
+ _ ->
+ throw({error, {invalid_Message, Mess}})
+ end,
+ Trans =
+ case Body of
+ {transactions, [Transactions]} ->
+ Transactions;
+ _ ->
+ throw({error, {invalid_messageBody, Body}})
+ end,
+ TR =
+ case Trans of
+ {transactionReply, TransReply} ->
+ TransReply;
+ _ ->
+ throw({error, {invalid_transactions, Trans}})
+ end,
+ TRes =
+ case TR of
+ #'TransactionReply'{transactionId = TransId,
+ immAckRequired = 'NULL',
+ transactionResult = TransRes} ->
+ TransRes;
+ _ ->
+ throw({error, {invalid_transactionReply, TR}})
+ end,
+ AR =
+ case TRes of
+ {actionReplies, [ActRes]} ->
+ ActRes;
+ _ ->
+ throw({error, {invalid_transactionResult, TRes}})
+ end,
+ CR =
+ case AR of
+ #'ActionReply'{contextId = Cid,
+ errorDescriptor = asn1_NOVALUE,
+ contextReply = _CtxReq,
+ commandReply = [CmdRep]} ->
+ CmdRep;
+ _ ->
+ throw({error, {invalid_actionReplies, AR}})
+ end,
+ NR =
+ case CR of
+ {notifyReply, NotifyReply} ->
+ NotifyReply;
+ _ ->
+ throw({error, {invalid_commandReply, CR}})
+ end,
+ case NR of
+ #'NotifyReply'{terminationID = [TermId],
+ errorDescriptor = asn1_NOVALUE} ->
+ {ok, M};
+ _ ->
+ {error, {invalid_notifyReply, NR}}
+ end;
+pap_mg_verify_notify_rep_msg(Crap, _TermId, _TransId, _Rid, _Cid) ->
+ {error, {invalid_message, Crap}}.
+
+pap_mg_service_change_request_ar(_Mid, Cid) ->
+ Prof = cre_serviceChangeProf("resgw", 1),
+ SCP = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = cre_serviceChangeReq([Root], SCP),
+ CMD = cre_command(SCR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+pap_mg_service_change_request_msg(Mid, TransId, Cid) ->
+ AR = pap_mg_service_change_request_ar(Mid, Cid),
+ TR = cre_transReq(TransId, [AR]),
+ Trans = cre_transaction(TR),
+ Mess = cre_message(?VERSION, Mid, cre_transactions([Trans])),
+ cre_megacoMessage(Mess).
+
+pap_mg_notify_request_ar(Rid, Tid, Cid) ->
+ TT = cre_timeNotation("19990729", "22000000"),
+ Ev = cre_obsEvent("al/of", TT),
+ EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
+ NR = cre_notifyReq([Tid], EvsDesc),
+ CMD = cre_command(NR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+pap_mg_notify_request_msg(Mid, TermId, TransId, Rid, Cid) ->
+ AR = pap_mg_notify_request_ar(Rid, TermId, Cid),
+ TR = cre_transReq(TransId, [AR]),
+ Trans = cre_transaction(TR),
+ Mess = cre_message(?VERSION, Mid, cre_transactions([Trans])),
+ cre_megacoMessage(Mess).
+
+pap_mg_trans_ack_msg(Mid, TransId) ->
+ TR = cre_transRespAck(cre_transAck(TransId)),
+ Trans = cre_transaction(TR),
+ Mess = cre_message(?VERSION, Mid, cre_transactions([Trans])),
+ cre_megacoMessage(Mess).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+request_and_pending_and_late_reply(suite) ->
+ [];
+request_and_pending_and_late_reply(doc) ->
+ ["Receive a request and handle it as a long request, "
+ "i.e. return with {pending, _}. Then, expect the sender "
+ "to keep re-sending the request until the reply is sent."];
+request_and_pending_and_late_reply(Config) when is_list(Config) ->
+ put(verbosity, ?TEST_VERBOSITY),
+ put(sname, "TEST"),
+ put(tc, rapalr),
+ i("starting"),
+
+ MgcNode = make_node_name(mgc),
+ MgNode = make_node_name(mg),
+ d("start nodes: "
+ "~n MgcNode: ~p"
+ "~n MgNode: ~p",
+ [MgcNode, MgNode]),
+ ok = megaco_test_lib:start_nodes([MgcNode, MgNode], ?FILE, ?LINE),
+
+ d("[MGC] start the simulator "),
+ {ok, Mgc} = megaco_test_tcp_generator:start_link("MGC", MgcNode),
+
+ d("[MGC] create the event sequence"),
+ MgcEvSeq = rapalr_mgc_event_sequence(text, tcp),
+
+ i("wait some time before starting the MGC simulation"),
+ sleep(1000),
+
+ d("[MGC] start the simulation"),
+ {ok, MgcId} = megaco_test_tcp_generator:exec(Mgc, MgcEvSeq),
+
+ i("wait some time before starting the MG simulator"),
+ sleep(1000),
+
+ d("[MG] start the simulator (generator)"),
+ {ok, Mg} = megaco_test_megaco_generator:start_link("MG", MgNode),
+
+ d("[MG] create the event sequence"),
+ MgEvSeq = rapalr_mg_event_sequence(text, tcp),
+
+ i("wait some time before starting the MG simulation"),
+ sleep(1000),
+
+ d("[MG] start the simulation"),
+ {ok, MgId} = megaco_test_megaco_generator:exec(Mg, MgEvSeq),
+
+ d("await the generator reply(s)"),
+ await_completion([MgcId, MgId]),
+
+ %% Tell Mgc to stop
+ i("[MGC] stop generator"),
+ megaco_test_tcp_generator:stop(Mgc),
+
+ %% Tell Mg to stop
+ i("[MG] stop generator"),
+ megaco_test_megaco_generator:stop(Mg),
+
+ i("done", []),
+ ok.
+
+
+%%
+%% MGC generator stuff
+%%
+
+-ifdef(megaco_hipe_special).
+-define(rapalr_mgc_decode_msg_fun(Mod, Conf),
+ {?MODULE, decode_msg, [Mod, Conf]}).
+-define(rapalr_mgc_encode_msg_fun(Mod, Conf),
+ {?MODULE, encode_msg, [Mod, Conf]}).
+-define(rapalr_mgc_verify_service_change_req_msg_fun(),
+ {?MODULE, rapalr_mgc_verify_service_change_req_msg, []}).
+-define(rapalr_mgc_verify_notify_req_msg_fun(TermId, TransId, ReqId, CtxId),
+ {?MODULE, rapalr_mgc_verify_notify_req_msg, [TermId, TransId, ReqId, CtxId]}).
+-define(rapalr_mgc_verify_trans_ack_msg_fun(TransId),
+ {?MODULE, rapalr_mgc_verify_trans_ack_msg, [TransId]}).
+-else.
+-define(rapalr_mgc_decode_msg_fun(Mod, Conf),
+ rapalr_mgc_decode_msg_fun(Mod, Conf)).
+-define(rapalr_mgc_encode_msg_fun(Mod, Conf),
+ rapalr_mgc_encode_msg_fun(Mod, Conf)).
+-define(rapalr_mgc_verify_service_change_req_msg_fun(),
+ rapalr_mgc_verify_service_change_req_msg_fun()).
+-define(rapalr_mgc_verify_notify_req_msg_fun(TermId, TransId, ReqId, CtxId),
+ rapalr_mgc_verify_notify_req_msg_fun(TermId, TransId, ReqId, CtxId)).
+-define(rapalr_mgc_verify_trans_ack_msg_fun(TransId),
+ rapalr_mgc_verify_trans_ack_msg_fun(TransId)).
+-endif.
+
+rapalr_mgc_event_sequence(text, tcp) ->
+ DecodeFun = ?rapalr_mgc_decode_msg_fun(megaco_pretty_text_encoder, []),
+ EncodeFun = ?rapalr_mgc_encode_msg_fun(megaco_pretty_text_encoder, []),
+ Mid = {deviceName,"mgc"},
+ ServiceChangeRep = rapalr_mgc_service_change_reply_msg(Mid, 1),
+ TermId =
+ #megaco_term_id{id = ["00000000","00000000","01101101"]},
+ TransId = 2,
+ ReqId = 1,
+ CtxId = 1,
+ Pending = rapalr_mgc_trans_pending_msg(Mid, TransId),
+ NotifyRep = rapalr_mgc_notify_reply_msg(Mid, TransId,
+ CtxId, TermId),
+ ScrVerifyFun = ?rapalr_mgc_verify_service_change_req_msg_fun(),
+ NrVerifyFun =
+ ?rapalr_mgc_verify_notify_req_msg_fun(TermId, TransId, ReqId, CtxId),
+ AckVerifyFun = ?rapalr_mgc_verify_trans_ack_msg_fun(TransId),
+%% ScrVerifyFun = rapalr_mgc_verify_service_change_req_msg_fun(),
+%% NrVerifyFun =
+%% rapalr_mgc_verify_notify_req_msg_fun(TermId, TransId, ReqId, CtxId),
+%% AckVerifyFun = rapalr_mgc_verify_trans_ack_msg_fun(TransId),
+ EvSeq = [{debug, false},
+ {decode, DecodeFun},
+ {encode, EncodeFun},
+ {listen, 2944},
+ {expect_accept, any},
+ {expect_receive, "service-change-request", {ScrVerifyFun, 5000}},
+ {send, "service-change-reply", ServiceChangeRep},
+ {expect_receive, "notify-request(1)", {NrVerifyFun, 4000}},
+ {send, "pending", Pending},
+ {expect_receive, "notify-request(2)", {NrVerifyFun, 4000}},
+ {expect_receive, "notify-request(3)", {NrVerifyFun, 4000}},
+ {send, "notify reply", NotifyRep},
+ {expect_receive, "ack", {AckVerifyFun, 4000}},
+ {sleep, 1000},
+ disconnect
+ ],
+ EvSeq.
+
+-ifndef(megaco_hipe_special).
+rapalr_mgc_encode_msg_fun(Mod, Conf) ->
+ fun(M) ->
+ encode_msg(M, Mod, Conf)
+ end.
+-endif.
+
+-ifndef(megaco_hipe_special).
+rapalr_mgc_decode_msg_fun(Mod, Conf) ->
+ fun(M) ->
+ decode_msg(M, Mod, Conf)
+ end.
+-endif.
+
+-ifndef(megaco_hipe_special).
+rapalr_mgc_verify_service_change_req_msg_fun() ->
+ fun(Msg) ->
+ (catch rapalr_mgc_verify_service_change_req_msg(Msg))
+ end.
+-endif.
+
+rapalr_mgc_verify_service_change_req_msg(#'MegacoMessage'{mess = Mess} = M) ->
+ Body =
+ case Mess of
+ #'Message'{version = ?VERSION,
+ mId = _MgMid,
+ messageBody = MsgBody} ->
+ MsgBody;
+ _ ->
+ throw({error, {invalid_Message, Mess}})
+ end,
+ Trans =
+ case Body of
+ {transactions, [Transactions]} ->
+ Transactions;
+ _ ->
+ throw({error, {invalid_messageBody, Body}})
+ end,
+ TR =
+ case Trans of
+ {transactionRequest, TransRequest} ->
+ TransRequest;
+ _ ->
+ throw({error, {invalid_transactions, Trans}})
+ end,
+ AR =
+ case TR of
+ #'TransactionRequest'{transactionId = _TransId,
+ actions = [ActionReq]} ->
+ ActionReq;
+ _ ->
+ throw({error, {invalid_transactionRequest, TR}})
+ end,
+ CR =
+ case AR of
+ #'ActionRequest'{contextId = _Cid,
+ commandRequests = [CmdReq]} ->
+ CmdReq;
+ _ ->
+ throw({error, {invalid_action, AR}})
+ end,
+ Cmd =
+ case CR of
+ #'CommandRequest'{command = Command} ->
+ Command;
+ _ ->
+ throw({error, {invalid_commandRequest, CR}})
+ end,
+ {Tid, Parms} =
+ case Cmd of
+ {serviceChangeReq,
+ #'ServiceChangeRequest'{terminationID = [TermID],
+ serviceChangeParms = ServChParms}} ->
+ {TermID, ServChParms};
+ _ ->
+ throw({error, {invalid_command, Cmd}})
+ end,
+ case Tid of
+ #megaco_term_id{contains_wildcards = false, id = ["root"]} ->
+ ok;
+ _ ->
+ throw({error, {invalid_terminationID, Tid}})
+ end,
+ case Parms of
+ #'ServiceChangeParm'{serviceChangeMethod = restart,
+ serviceChangeReason = [[$9,$0,$1|_]]} ->
+ {ok, M};
+ _ ->
+ {error, {invalid_serviceChangeParms, Parms}}
+ end.
+
+-ifndef(megaco_hipe_special).
+rapalr_mgc_verify_notify_req_msg_fun(TermId, TransId, Rid, Cid) ->
+ fun(Msg) ->
+ (catch rapalr_mgc_verify_notify_req_msg(Msg,
+ TermId,
+ TransId, Rid, Cid))
+ end.
+-endif.
+
+rapalr_mgc_verify_notify_req_msg(#'MegacoMessage'{mess = Mess} = M,
+ TermId, TransId, Rid, Cid) ->
+ io:format("rapalr_mgc_verify_notify_req_msg -> entry with"
+ "~n M: ~p"
+ "~n TermId: ~p"
+ "~n TransId: ~p"
+ "~n Rid: ~p"
+ "~n Cid: ~p"
+ "~n", [M, TermId, TransId, Rid, Cid]),
+ Body =
+ case Mess of
+ #'Message'{version = ?VERSION,
+ mId = _Mid,
+ messageBody = MsgBody} ->
+ MsgBody;
+ _ ->
+ throw({error, {invalid_Message, Mess}})
+ end,
+ Trans =
+ case Body of
+ {transactions, [Transactions]} ->
+ Transactions;
+ _ ->
+ throw({error, {invalid_messageBody, Body}})
+ end,
+ TR =
+ case Trans of
+ {transactionRequest, TransRequest} ->
+ TransRequest;
+ _ ->
+ throw({error, {invalid_transactions, Trans}})
+ end,
+ AR =
+ case TR of
+ #'TransactionRequest'{transactionId = TransId,
+ actions = [ActReq]} ->
+ ActReq;
+ _ ->
+ throw({error, {invalid_transactionRequest, TR}})
+ end,
+ CR =
+ case AR of
+ #'ActionRequest'{contextId = Cid,
+ commandRequests = [CmdReq]} ->
+ CmdReq;
+ _ ->
+ throw({error, {invalid_actions, AR}})
+ end,
+ Cmd =
+ case CR of
+ #'CommandRequest'{command = Command} ->
+ Command;
+ _ ->
+ throw({error, {invalid_commandRequests, CR}})
+ end,
+ NR =
+ case Cmd of
+ {notifyReq, NotifReq} ->
+ NotifReq;
+ _ ->
+ throw({error, {invalid_command, Cmd}})
+ end,
+ OED =
+ case NR of
+ #'NotifyRequest'{terminationID = [TermId],
+ observedEventsDescriptor = ObsEvsDesc,
+ errorDescriptor = asn1_NOVALUE} ->
+ ObsEvsDesc;
+ _ ->
+ throw({error, {invalid_notifyReq, NR}})
+ end,
+ OE =
+ case OED of
+ #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
+ ObsEvLst;
+ _ ->
+ throw({error, {invalid_observedEventsDescriptor, OED}})
+ end,
+ case OE of
+ #'ObservedEvent'{eventName = "al/of"} ->
+ {ok, M};
+ _ ->
+ throw({error, {invalid_observedEventLst, OE}})
+ end;
+rapalr_mgc_verify_notify_req_msg(Crap, _TermId, _TransId, _Rid, _Cid) ->
+ {error, {invalid_MegacoMessage, Crap}}.
+
+-ifndef(megaco_hipe_special).
+rapalr_mgc_verify_trans_ack_msg_fun(TransId) ->
+ fun(Msg) ->
+ (catch rapalr_mgc_verify_trans_ack_msg(Msg, TransId))
+ end.
+-endif.
+
+rapalr_mgc_verify_trans_ack_msg(#'MegacoMessage'{mess = Mess} = M,
+ TransId) ->
+ io:format("rapalr_mgc_verify_trans_ack_msg -> entry with"
+ "~n M: ~p"
+ "~n TransId: ~p"
+ "~n", [M, TransId]),
+ Body =
+ case Mess of
+ #'Message'{version = ?VERSION,
+ mId = _Mid,
+ messageBody = MsgBody} ->
+ MsgBody;
+ _ ->
+ throw({error, {invalid_Message, Mess}})
+ end,
+ Trans =
+ case Body of
+ {transactions, [Transactions]} ->
+ Transactions;
+ _ ->
+ throw({error, {invalid_messageBody, Body}})
+ end,
+ TA =
+ case Trans of
+ {transactionResponseAck, [TransAck]} ->
+ TransAck;
+ _ ->
+ throw({error, {invalid_transactions, Trans}})
+ end,
+ case TA of
+ #'TransactionAck'{firstAck = TransId,
+ lastAck = asn1_NOVALUE} ->
+ {ok, M};
+ _ ->
+ throw({error, {invalid_transactionResponseAck, TA}})
+ end;
+rapalr_mgc_verify_trans_ack_msg(Crap, _TransId) ->
+ {error, {invalid_MegacoMessage, Crap}}.
+
+rapalr_mgc_service_change_reply_msg(Mid, Cid) ->
+ SCRP = cre_serviceChangeResParm(Mid),
+ SCRes = cre_serviceChangeResult(SCRP),
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = cre_serviceChangeReply([Root], SCRes),
+ CR = cre_cmdReply(SCR),
+ AR = cre_actionReply(Cid, [CR]),
+ TRes = cre_transResult([AR]),
+ TR = cre_transReply(1, TRes),
+ Trans = cre_transaction(TR),
+ Mess = cre_message(?VERSION, Mid, cre_transactions([Trans])),
+ cre_megacoMessage(Mess).
+
+rapalr_mgc_notify_reply_ar(Cid, TermId) ->
+ NR = cre_notifyReply([TermId]),
+ CR = cre_cmdReply(NR),
+ cre_actionReply(Cid, [CR]).
+
+rapalr_mgc_notify_reply_msg(Mid, TransId, Cid, TermId) ->
+ AR = rapalr_mgc_notify_reply_ar(Cid, TermId),
+ TRes = cre_transResult([AR]),
+ TR = cre_transReply(TransId, 'NULL', TRes),
+ Trans = cre_transaction(TR),
+ Mess = cre_message(?VERSION, Mid, cre_transactions([Trans])),
+ cre_megacoMessage(Mess).
+
+rapalr_mgc_trans_pending_msg(Mid, TransId) ->
+ TP = #'TransactionPending'{transactionId = TransId},
+ Body = {transactions, [{transactionPending, TP}]},
+ Mess = #'Message'{version = 1,
+ mId = Mid,
+ messageBody = Body},
+ #'MegacoMessage'{mess = Mess}.
+
+
+
+%%
+%% MG generator stuff
+%%
+-ifdef(megaco_hipe_special).
+-define(rapalr_mg_verify_handle_connect_fun(),
+ {?MODULE, rapalr_mg_verify_handle_connect, []}).
+-define(rapalr_mg_verify_service_change_rep_fun(),
+ {?MODULE, rapalr_mg_verify_service_change_rep, []}).
+-define(rapalr_mg_verify_notify_rep_fun(),
+ {?MODULE, rapalr_mg_verify_notify_rep, []}).
+-else.
+-define(rapalr_mg_verify_handle_connect_fun(),
+ rapalr_mg_verify_handle_connect_fun()).
+-define(rapalr_mg_verify_service_change_rep_fun(),
+ rapalr_mg_verify_service_change_rep_fun()).
+-define(rapalr_mg_verify_notify_rep_fun(),
+ rapalr_mg_verify_notify_rep_fun()).
+-endif.
+
+rapalr_mg_event_sequence(text, tcp) ->
+ Mid = {deviceName,"mg"},
+ RI = [
+ {port, 2944},
+ {encoding_module, megaco_pretty_text_encoder},
+ {encoding_config, []},
+ {transport_module, megaco_tcp}
+ ],
+ LReqTmr = #megaco_incr_timer{wait_for = 3000,
+ factor = 1,
+ incr = 0,
+ max_retries = 2
+ },
+ ServiceChangeReq = rapalr_mg_service_change_request_ar(Mid, 1),
+ Tid = #megaco_term_id{id = ["00000000","00000000","01101101"]},
+ NotifyReq = rapalr_mg_notify_request_ar(1, Tid, 1),
+ ConnectVerify = ?rapalr_mg_verify_handle_connect_fun(),
+ ServiceChangeReplyVerify = ?rapalr_mg_verify_service_change_rep_fun(),
+ NotifyReplyVerify = ?rapalr_mg_verify_notify_rep_fun(),
+%% ConnectVerify = rapalr_mg_verify_handle_connect_fun(),
+%% ServiceChangeReplyVerify = rapalr_mg_verify_service_change_reply_fun(),
+%% NotifyReplyVerify = rapalr_mg_verify_notify_reply_fun(),
+ EvSeq = [
+ {debug, false},
+ megaco_start,
+ {megaco_start_user, Mid, RI, []},
+ start_transport,
+ {megaco_trace, disable},
+ {megaco_system_info, users},
+ {megaco_system_info, connections},
+ {megaco_update_user_info, long_request_resend, true},
+ {megaco_update_user_info, long_request_timer, LReqTmr},
+ connect,
+ {megaco_callback, handle_connect, ConnectVerify},
+ megaco_connect,
+ {megaco_cast, [ServiceChangeReq], []},
+ {megaco_callback, handle_connect, ConnectVerify},
+ {megaco_callback, handle_trans_reply, ServiceChangeReplyVerify},
+ {sleep, 1000},
+ {megaco_cast, [NotifyReq], []},
+ {megaco_callback, handle_trans_reply, NotifyReplyVerify},
+ {sleep, 1000},
+ megaco_stop_user,
+ megaco_stop,
+ {sleep, 1000}
+ ],
+ EvSeq.
+
+
+-ifndef(megaco_hipe_special).
+rapalr_mg_verify_handle_connect_fun() ->
+ fun(Ev) ->
+ rapalr_mg_verify_handle_connect(Ev)
+ end.
+-endif.
+
+rapalr_mg_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
+ io:format("rapalr_mg_verify_handle_connect -> ok"
+ "~n CH: ~p~n", [CH]),
+ {ok, CH, ok};
+rapalr_mg_verify_handle_connect(Else) ->
+ io:format("rapalr_mg_verify_handle_connect -> unknown"
+ "~n Else: ~p~n", [Else]),
+ {error, Else, ok}.
+
+
+-ifndef(megaco_hipe_special).
+rapalr_mg_verify_service_change_rep_fun() ->
+ fun(Rep) ->
+ rapalr_mg_verify_service_change_rep(Rep)
+ end.
+-endif.
+
+rapalr_mg_verify_service_change_rep(
+ {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _}) ->
+ (catch rapalr_mg_do_verify_service_change_rep(AR));
+rapalr_mg_verify_service_change_rep(Crap) ->
+ {error, Crap, ok}.
+
+rapalr_mg_do_verify_service_change_rep(AR) ->
+ io:format("rapalr_mg_verify_service_change_rep -> ok"
+ "~n AR: ~p~n", [AR]),
+ CR =
+ case AR of
+ #'ActionReply'{commandReply = [CmdRep]} ->
+ CmdRep;
+ _ ->
+ Reason1 = {invalid_action_reply, AR},
+ throw({error, Reason1, ok})
+ end,
+ SCR =
+ case CR of
+ {serviceChangeReply, ServChRep} ->
+ ServChRep;
+ _ ->
+ Reason2 = {invalid_command_reply, CR},
+ throw({error, Reason2, ok})
+ end,
+ {Tid, SCRes} =
+ case SCR of
+ #'ServiceChangeReply'{terminationID = [TermID],
+ serviceChangeResult = Res} ->
+ {TermID, Res};
+ _ ->
+ Reason3 = {invalid_service_change_reply, SCR},
+ throw({error, Reason3, ok})
+ end,
+ case Tid of
+ #megaco_term_id{contains_wildcards = false, id = ["root"]} ->
+ ok;
+ _ ->
+ Reason4 = {invalid_termination_id, Tid},
+ throw({error, Reason4, ok})
+ end,
+ SCRParm =
+ case SCRes of
+ {serviceChangeResParms, ServChResParms} ->
+ ServChResParms;
+ _ ->
+ Reason5 = {invalid_serviceChangeResult, SCRes},
+ throw({error, Reason5, ok})
+ end,
+ case SCRParm of
+ #'ServiceChangeResParm'{serviceChangeMgcId = _RemoteMid} ->
+ {ok, AR, ok};
+ _ ->
+ Reason6 = {invalid_service_change_result, SCRParm},
+ {error, Reason6, ok}
+ end.
+
+-ifndef(megaco_hipe_special).
+rapalr_mg_verify_notify_rep_fun() ->
+ fun(Rep) ->
+ rapalr_mg_verify_notify_rep(Rep)
+ end.
+-endif.
+
+rapalr_mg_verify_notify_rep({handle_trans_reply, _CH, ?VERSION,
+ {ok, [AR]}, _}) ->
+ io:format("rapalr_mg_verify_notify_rep -> ok"
+ "~n AR: ~p~n", [AR]),
+ {ok, AR, ok};
+rapalr_mg_verify_notify_rep(Else) ->
+ io:format("rapalr_mg_verify_notify_rep -> unknown"
+ "~n Else: ~p~n", [Else]),
+ {error, Else, ok}.
+
+
+rapalr_mg_service_change_request_ar(_Mid, Cid) ->
+ Prof = cre_serviceChangeProf("resgw", 1),
+ SCP = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = cre_serviceChangeReq([Root], SCP),
+ CMD = cre_command(SCR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+rapalr_mg_notify_request_ar(Rid, Tid, Cid) ->
+ TT = cre_timeNotation("19990729", "22000000"),
+ Ev = cre_obsEvent("al/of", TT),
+ EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
+ NR = cre_notifyReq([Tid], EvsDesc),
+ CMD = cre_command(NR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+
+
+
+
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+dist(suite) ->
+ [];
+dist(Config) when is_list(Config) ->
+ [_Local, Dist] = ?ACQUIRE_NODES(2, Config),
+ d("dist -> start proxy",[]),
+ megaco_mess_user_test:start_proxy(),
+
+ PrelMid = preliminary_mid,
+ MgMid = ipv4_mid(4711),
+ MgcMid = ipv4_mid(),
+ UserMod = megaco_mess_user_test,
+ d("dist -> start megaco app",[]),
+ ?VERIFY(ok, application:start(megaco)),
+ UserConfig = [{user_mod, UserMod}, {send_mod, UserMod},
+ {request_timer, infinity}, {reply_timer, infinity}],
+
+ d("dist -> start megaco user MG (~p)",[MgMid]),
+ ?VERIFY(ok, megaco:start_user(MgMid, UserConfig)),
+
+ d("dist -> start megaco user MGC (~p)",[MgcMid]),
+ ?VERIFY(ok, megaco:start_user(MgcMid, UserConfig)),
+
+ d("dist -> retrieve (user info) receive_handle for MG",[]),
+ MgRH = user_info(MgMid, receive_handle),
+
+ d("dist -> retrieve (user info) receive_handle for MGC",[]),
+ MgcRH = user_info(MgcMid, receive_handle),
+
+ d("dist -> start transport",[]),
+ {ok, MgPid, MgSH} =
+ ?VERIFY({ok, _, _}, UserMod:start_transport(MgRH, MgcRH)),
+ PrelMgCH = #megaco_conn_handle{local_mid = MgMid,
+ remote_mid = preliminary_mid},
+ MgCH = #megaco_conn_handle{local_mid = MgMid,
+ remote_mid = MgcMid},
+ MgcCH = #megaco_conn_handle{local_mid = MgcMid,
+ remote_mid = MgMid},
+
+ d("dist -> (MG) connect",[]),
+ ?SEND(megaco:connect(MgRH, PrelMid, MgSH, MgPid)), % Mg prel
+
+ d("dist -> (MG) await connect",[]),
+ ?USER({connect, PrelMgCH, _V, []}, ok),
+ ?RECEIVE([{res, _, {ok, PrelMgCH}}]),
+
+ d("dist -> (MG) send service change request",[]),
+ Req = service_change_request(),
+ ?SEND(megaco:call(PrelMgCH, [Req], [])),
+
+ d("dist -> (MGC) await auto-connect",[]),
+ ?USER({connect, MgcCH, _V, []}, ok), % Mgc auto
+
+
+ Rep = service_change_reply(MgcMid),
+ d("dist -> (MGC) "
+ "await service change request and send reply when received",[]),
+ ?USER({request, MgcCH, _V, [[Req]]}, {discard_ack, [Rep]}),
+
+ d("dist -> (MG) await connect",[]),
+ ?USER({connect, MgCH, _V, []}, ok), % Mg confirm
+
+ d("dist -> (MG) await service change reply",[]),
+ ?RECEIVE([{res, _, {1, {ok, [Rep]}}}]),
+
+ %% Dist
+ d("dist -> start megaco on ~p", [Dist]),
+ ?VERIFY(ok, rpc:call(Dist, megaco, start, [])),
+
+ d("dist -> start megaco user on ~p", [Dist]),
+ ?VERIFY(ok, rpc:call(Dist, megaco, start_user, [MgcMid, UserConfig])),
+
+ d("dist -> (MG) connect to MGC", []),
+ MgcPid = self(),
+ MgcSH = {element(2, MgSH), element(1, MgSH)},
+ ?SEND(rpc:call(Dist, megaco, connect, [MgcRH, MgMid, MgcSH, MgcPid])), % Mgc dist
+
+ d("dist -> (MGC) await auto-connect (from MG on ~p)", [Dist]),
+ ?USER({connect, MgcCH, _V, []}, ok), % Mgc dist auto
+ ?RECEIVE([{res, _, {ok, MgcCH}}]),
+
+ d("dist -> (~p:MG) send service change request",[Dist]),
+ ?SEND(rpc:call(Dist, megaco, call, [MgcCH, [Req], []])),
+
+ d("dist -> (MG????????) "
+ "await service change request and send reply when received",[]),
+ ?USER({request, MgCH, _V, [[Req]]}, {discard_ack, [Rep]}),
+ ?RECEIVE([{res, _, {1, {ok, [Rep]}}}]),
+
+ d("dist -> retreive some info",[]),
+ connections([MgCH, MgcCH]),
+ ?VERIFY([MgCH], megaco:user_info(MgMid, connections)),
+ ?VERIFY([MgcCH], megaco:user_info(MgcMid, connections)),
+
+ ?VERIFY([MgcCH], rpc:call(Dist, megaco, system_info, [connections])),
+ ?VERIFY([], rpc:call(Dist, megaco, user_info, [MgMid, connections])),
+ ?VERIFY([MgcCH], rpc:call(Dist, megaco, user_info, [MgcMid, connections])),
+
+ %% Shutdown
+
+ d("dist -> close down the shop...",[]),
+ Reason = shutdown,
+ ?SEND(megaco:disconnect(MgCH, Reason)),
+ ?USER({disconnect, MgCH, _V, [{user_disconnect, Reason}]}, ok),
+ ?RECEIVE([{res, _, ok}]),
+ ?VERIFY(ok, megaco:stop_user(MgMid)),
+
+ ?SEND(megaco:disconnect(MgcCH, Reason)),
+ ?USER({disconnect, MgcCH, _V, [{user_disconnect, Reason}]}, ok),
+ ?USER({disconnect, MgcCH, _V, [{user_disconnect, Reason}]}, ok),
+ ?RECEIVE([{res, _, ok}]),
+ ?VERIFY(ok, megaco:stop_user(MgcMid)),
+
+ ?VERIFY(ok, application:stop(megaco)),
+ ?RECEIVE([]),
+ d("dist -> done",[]),
+ ok.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+otp_4359(suite) ->
+ [];
+otp_4359(Config) when is_list(Config) ->
+ ?ACQUIRE_NODES(1, Config),
+ Mid = {deviceName, "dummy_mid"},
+
+ io:format("otp_4359 -> start megaco application~n", []),
+ ?VERIFY(ok, application:start(megaco)),
+
+ %% megaco:enable_trace(max, io),
+ io:format("otp_4359 -> start and configure megaco user~n", []),
+ ?VERIFY(ok, megaco:start_user(Mid, [{send_mod, ?MODULE},
+ {request_timer, infinity},
+ {reply_timer, infinity}])),
+
+ io:format("otp_4359 -> update user info: user_mod -> ~p~n", [?MODULE]),
+ ?VERIFY(ok, megaco:update_user_info(Mid, user_mod, ?MODULE)),
+ io:format("otp_4359 -> update user info: user_args -> ~p~n", [self()]),
+ ?VERIFY(ok, megaco:update_user_info(Mid, user_args, [self()])),
+ io:format("otp_4359 -> retreive receive_handle~n", []),
+ RH0 = user_info(Mid, receive_handle),
+ io:format("otp_4359 -> RH0: ~p~n", [RH0]),
+ RH1 = RH0#megaco_receive_handle{send_mod = ?MODULE,
+ encoding_mod = megaco_compact_text_encoder,
+ encoding_config = []},
+
+ %% First an erroneous transaction (missing the transaction id number)
+ %% then an valid transaction.
+ M = "!/1 ml2 "
+ "T={C=${A=${M{O {MO=SR,RG=OFF,RV=OFF}}}}}"
+ "T=1{C=${A=${M{O {MO=SR,RG=OFF,RV=OFF}}}}}",
+
+ %% Simulate incomming message
+ %% Will result in an (auto) connect first
+ io:format("otp_4359 -> simulate receive message~n", []),
+ megaco:receive_message(RH1, self(), self(), list_to_binary(M)),
+ io:format("otp_4359 -> await actions~n", []),
+ Actions = otp_4359_await_actions([{handle_connect, ignore},
+ {send_message, ?megaco_bad_request},
+ {handle_trans_request, ignore},
+ {send_message, ?megaco_not_implemented}]),
+ io:format("otp_4359 -> analyze actions~n", []),
+ otp_4359_analyze_result(RH1, Actions),
+
+ Conns = megaco:system_info(connections),
+ io:format("otp_4359 -> connections~n~p~n", [Conns]),
+ OKs = lists:duplicate(length(Conns),ok),
+ io:format("otp_4359 -> verify (all) connection disconnect~n", []),
+ ?VERIFY(OKs, [megaco:disconnect(CH, test_complete) || CH <- Conns]),
+ io:format("otp_4359 -> stop user (~p)~n", [Mid]),
+ stop_user(Mid),
+ io:format("otp_4359 -> stop megaco application~n", []),
+ ?VERIFY(ok, application:stop(megaco)),
+ io:format("otp_4359 -> make sure we have nothing in the message queue~n", []),
+ ?RECEIVE([]),
+ io:format("otp_4359 -> done~n", []),
+ ok.
+
+
+otp_4359_await_actions(Exp) ->
+ otp_4359_await_actions(Exp, []).
+
+otp_4359_await_actions([], Rep) ->
+ lists:reverse(Rep);
+otp_4359_await_actions([{M,I}|R] = _All, Rep) ->
+ receive
+ {M, Info} ->
+ io:format("otp_4359 -> received expected event [~w]~n", [M]),
+ otp_4359_await_actions(R, [{M, I, Info}|Rep])
+%% Else ->
+%% exit({received_unexpected_message, M, Else})
+%% %% io:format("received unexpected: ~p~n", [Else]),
+%% %% otp_4359_await_actions(All, Rep)
+ after 10000 ->
+ exit({timeout,megaco_test_lib:flush()} )
+ end.
+
+otp_4359_analyze_result(_RH, []) ->
+ ok;
+otp_4359_analyze_result(RH,
+ [{send_message, ExpErrorCode, EncodedMessage}|L]) ->
+ io:format("otp_4359_analyze_result -> send_message: ", []),
+ otp_4359_analyze_encoded_message(RH, ExpErrorCode, EncodedMessage),
+ otp_4359_analyze_result(RH,L);
+otp_4359_analyze_result(RH, [{M,ignore,_}|T]) ->
+ io:format("otp_4359_analyze_result -> ignoring ~p~n", [M]),
+ otp_4359_analyze_result(RH,T).
+
+otp_4359_analyze_encoded_message(RH, ExpErrorCode, M)
+ when is_record(RH, megaco_receive_handle) andalso is_binary(M) ->
+ #megaco_receive_handle{encoding_mod = Mod,
+ encoding_config = Conf} = RH,
+ case (catch Mod:decode_message(Conf, M)) of
+ {ok, #'MegacoMessage'{mess = #'Message'{messageBody = Body}}} ->
+ case Body of
+ {transactions, [{transactionReply,Reply}]} ->
+ case Reply of
+ #'TransactionReply'{transactionResult = Result} ->
+ case Result of
+ {transactionError,ED} when is_record(ED, 'ErrorDescriptor') ->
+ case ED#'ErrorDescriptor'.errorCode of
+ ExpErrorCode ->
+ io:format("error code ~p ok~n", [ExpErrorCode]),
+ ok;
+ Code ->
+ io:format("error code ~p erroneous~n", [Code]),
+ exit({unexpected_error_code, ExpErrorCode, Code})
+ end;
+ _ ->
+ io:format("unexpected trans result~n", []),
+ exit({unexpected_trans_result, Result})
+ end;
+ _ ->
+ io:format("unexpected trans reply~n", []),
+ exit({unexpected_trans_reply, Reply})
+ end;
+ _ ->
+ io:format("unexpected body~n", []),
+ exit({unexpected_body, Body})
+ end;
+
+ Else ->
+ io:format("unexpected decode result~n", []),
+ exit({unexpected_decode_result, Else})
+ end.
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+otp_4836(suite) ->
+ [];
+otp_4836(Config) when is_list(Config) ->
+ put(verbosity, ?TEST_VERBOSITY),
+ put(sname, "TEST"),
+ put(tc, otp_4836),
+ i("starting"),
+
+ MgcNode = make_node_name(mgc),
+ MgNode = make_node_name(mg),
+ d("start nodes: "
+ "~n MgcNode: ~p"
+ "~n MgNode: ~p",
+ [MgcNode, MgNode]),
+ ok = megaco_test_lib:start_nodes([MgcNode, MgNode], ?FILE, ?LINE),
+
+ d("start the MGC simulator (generator)"),
+ {ok, Mgc} = megaco_test_tcp_generator:start_link("MGC", MgcNode),
+
+ d("create the MGC event sequence"),
+ MgcEvSeq = otp_4836_mgc_event_sequence(text, tcp),
+
+ d("start the MGC simulation"),
+ {ok, MgcId} = megaco_test_tcp_generator:exec(Mgc, MgcEvSeq),
+
+ i("[MG] start"),
+ MgMid = {deviceName, "mg"},
+ ReqTmr = #megaco_incr_timer{wait_for = 3000,
+ factor = 1,
+ incr = 0,
+ max_retries = 3},
+ %% 5000, %% Does not matter since we will not use this anyway...
+ LongReqTmr = #megaco_incr_timer{wait_for = 3000,
+ factor = 1,
+ incr = 0,
+ max_retries = 3},
+ PendingTmr = 10000,
+ ReplyTmr = 16000,
+ MgConfig = [{request_timer, ReqTmr},
+ {long_request_timer, LongReqTmr},
+ {pending_timer, PendingTmr},
+ {reply_timer, ReplyTmr}],
+ {ok, Mg} = ?MG_START(MgNode, MgMid, text, tcp, MgConfig, ?MG_VERBOSITY),
+
+ i("[MG] connect to the MGC (service change)"),
+ ServChRes = ?MG_SERV_CHANGE(Mg),
+ d("service change result: ~p", [ServChRes]),
+
+ d("[MG] send the notify"),
+ {ok, Reply} = (catch ?MG_NOTIF_RAR(Mg)),
+ {1, {ok, [AR]}} = Reply,
+ d("[MG] ActionReply: ~p", [AR]),
+
+ d("await the generator reply"),
+ await_completion([MgcId]),
+
+ %% Tell MG to stop
+ i("[MG] stop"),
+ ?MG_STOP(Mg),
+
+ %% Tell Mgc to stop
+ i("[MGC] stop generator"),
+ megaco_test_tcp_generator:stop(Mgc),
+
+ i("done", []),
+ ok.
+
+
+-ifdef(megaco_hipe_special).
+-define(otp_4836_mgc_decode_msg_fun(Mod, Conf),
+ {?MODULE, decode_msg, [Mod, Conf]}).
+-define(otp_4836_mgc_encode_msg_fun(Mod, Conf),
+ {?MODULE, encode_msg, [Mod, Conf]}).
+-define(otp_4836_mgc_verify_service_change_req_msg_fun(),
+ {?MODULE, otp_4836_mgc_verify_service_change_req_msg, []}).
+-define(otp_4836_mgc_verify_notify_req_msg_fun(),
+ {?MODULE, otp_4836_mgc_verify_notify_req_msg, []}).
+-else.
+-define(otp_4836_mgc_decode_msg_fun(Mod, Conf),
+ otp_4836_mgc_decode_msg_fun(Mod, Conf)).
+-define(otp_4836_mgc_encode_msg_fun(Mod, Conf),
+ otp_4836_mgc_encode_msg_fun(Mod, Conf)).
+-define(otp_4836_mgc_verify_service_change_req_msg_fun(),
+ otp_4836_mgc_verify_service_change_req_msg_fun()).
+-define(otp_4836_mgc_verify_notify_req_msg_fun(),
+ otp_4836_mgc_verify_notify_req_msg_fun()).
+-endif.
+
+otp_4836_mgc_event_sequence(text, tcp) ->
+ DecodeFun = ?otp_4836_mgc_decode_msg_fun(megaco_pretty_text_encoder, []),
+ EncodeFun = ?otp_4836_mgc_encode_msg_fun(megaco_pretty_text_encoder, []),
+ Mid = {deviceName,"ctrl"},
+ ServiceChangeReply = otp_4836_service_change_reply_msg(Mid, 1, 0),
+ TermId = #megaco_term_id{id = ["00000000","00000000","01101101"]},
+ NotifyReply = otp_4836_notify_reply_msg(Mid, 2, 0, TermId),
+ Pending = otp_4836_pending_msg(Mid,2),
+ ServiceChangeVerifyFun = ?otp_4836_mgc_verify_service_change_req_msg_fun(),
+ NotifyReqVerifyFun = ?otp_4836_mgc_verify_notify_req_msg_fun(),
+ MgcEvSeq = [{debug, true},
+ {decode, DecodeFun},
+ {encode, EncodeFun},
+ {listen, 2944},
+ {expect_accept, any},
+ {expect_receive, "service-change-request", {ServiceChangeVerifyFun, 10000}},
+ {send, "service-change-reply", ServiceChangeReply},
+ {expect_receive, "notify-request", {NotifyReqVerifyFun, 10000}},
+ {send, "pending 1", Pending},
+ {sleep, 100},
+ {send, "pending 2", Pending},
+ {sleep, 500},
+ {send, "notify-reply", NotifyReply},
+ {sleep, 2000}
+ ],
+ MgcEvSeq.
+
+otp_4836_service_change_reply_msg(Mid, TransId, Cid) ->
+ SCRP = #'ServiceChangeResParm'{serviceChangeMgcId = Mid},
+ SCRPs = {serviceChangeResParms,SCRP},
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = #'ServiceChangeReply'{terminationID = [Root],
+ serviceChangeResult = SCRPs},
+ CR = {serviceChangeReply, SCR},
+ otp_4836_msg(Mid, TransId, CR, Cid).
+
+otp_4836_notify_reply_msg(Mid, TransId, Cid, TermId) ->
+ NR = #'NotifyReply'{terminationID = [TermId]},
+ CR = {notifyReply, NR},
+ otp_4836_msg(Mid, TransId, CR, Cid).
+
+otp_4836_msg(Mid, TransId, CR, Cid) ->
+ AR = #'ActionReply'{contextId = Cid,
+ commandReply = [CR]},
+ ARs = {actionReplies, [AR]},
+ TR = #'TransactionReply'{transactionId = TransId,
+ transactionResult = ARs},
+ Body = {transactions, [{transactionReply, TR}]},
+ Mess = #'Message'{version = 1,
+ mId = Mid,
+ messageBody = Body},
+ #'MegacoMessage'{mess = Mess}.
+
+
+otp_4836_pending_msg(Mid, TransId) ->
+ TP = #'TransactionPending'{transactionId = TransId},
+ Body = {transactions, [{transactionPending, TP}]},
+ Mess = #'Message'{version = 1,
+ mId = Mid,
+ messageBody = Body},
+ #'MegacoMessage'{mess = Mess}.
+
+
+-ifndef(megaco_hipe_special).
+otp_4836_mgc_encode_msg_fun(Mod, Conf) ->
+ fun(M) ->
+ encode_msg(M, Mod, Conf)
+ end.
+-endif.
+%% otp_4836_mgc_encode_msg_fun(Mod, Conf, Ver) ->
+%% fun(M) ->
+%% encode_msg(M, Mod, Conf, Ver)
+%% end.
+
+-ifndef(megaco_hipe_special).
+otp_4836_mgc_decode_msg_fun(Mod, Conf) ->
+ fun(M) ->
+ decode_msg(M, Mod, Conf)
+ end.
+-endif.
+%% otp_4836_mgc_decode_msg_fun(Mod, Conf, Ver) ->
+%% fun(M) ->
+%% decode_msg(M, Mod, Conf, Ver)
+%% end.
+
+%% otp_4836_verify_msg_fun() ->
+%% fun(M) ->
+%% {ok, M}
+%% end.
+
+-ifndef(megaco_hipe_special).
+otp_4836_mgc_verify_service_change_req_msg_fun() ->
+ fun(M) ->
+ otp_4836_mgc_verify_service_change_req_msg(M)
+ end.
+-endif.
+
+otp_4836_mgc_verify_service_change_req_msg(
+ #'MegacoMessage'{mess = Mess} = M) ->
+ #'Message'{version = _V,
+ mId = _Mid,
+ messageBody = Body} = Mess,
+ {transactions, [Trans]} = Body,
+ {transactionRequest, TR} = Trans,
+ #'TransactionRequest'{transactionId = _Tid,
+ actions = [AR]} = TR,
+ #'ActionRequest'{contextId = _Cid,
+ contextRequest = _CtxReq,
+ contextAttrAuditReq = _CtxAar,
+ commandRequests = [CR]} = AR,
+ #'CommandRequest'{command = Cmd,
+ optional = _Opt,
+ wildcardReturn = _WR} = CR,
+ {serviceChangeReq, SCR} = Cmd,
+ #'ServiceChangeRequest'{terminationID = _TermID,
+ serviceChangeParms = SCP} = SCR,
+ #'ServiceChangeParm'{serviceChangeMethod = restart,
+ serviceChangeReason = [[$9,$0,$1|_]]} = SCP,
+ {ok, M};
+otp_4836_mgc_verify_service_change_req_msg(M) ->
+ {error, {invalid_message, M}}.
+
+-ifndef(megaco_hipe_special).
+otp_4836_mgc_verify_notify_req_msg_fun() ->
+ fun(M) ->
+ otp_4836_mgc_verify_notify_req_msg(M)
+ end.
+-endif.
+
+otp_4836_mgc_verify_notify_req_msg(#'MegacoMessage'{mess = Mess} = M) ->
+ #'Message'{messageBody = Body} = Mess,
+ {transactions, [Trans]} = Body,
+ {transactionRequest, TR} = Trans,
+ #'TransactionRequest'{actions = [AR]} = TR,
+ #'ActionRequest'{commandRequests = [CR1,CR2]} = AR,
+ #'CommandRequest'{command = Cmd1} = CR1,
+ {notifyReq, NR1} = Cmd1,
+ #'NotifyRequest'{observedEventsDescriptor = OED1} = NR1,
+ #'ObservedEventsDescriptor'{observedEventLst = [OE1]} = OED1,
+ #'ObservedEvent'{eventName = "al/of"} = OE1,
+ #'CommandRequest'{command = Cmd2} = CR2,
+ {notifyReq, NR2} = Cmd2,
+ #'NotifyRequest'{observedEventsDescriptor = OED2} = NR2,
+ #'ObservedEventsDescriptor'{observedEventLst = [OE2]} = OED2,
+ #'ObservedEvent'{eventName = "al/of"} = OE2,
+ {ok, M};
+otp_4836_mgc_verify_notify_req_msg(M) ->
+ {error, {invalid_message, M}}.
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+otp_5805(suite) ->
+ [];
+otp_5805(Config) when is_list(Config) ->
+ put(verbosity, ?TEST_VERBOSITY),
+ put(sname, "TEST"),
+ put(tc, otp_5805),
+ i("starting"),
+
+ MgcNode = make_node_name(mgc),
+ MgNode = make_node_name(mg),
+ d("start nodes: "
+ "~n MgcNode: ~p"
+ "~n MgNode: ~p",
+ [MgcNode, MgNode]),
+ ok = megaco_test_lib:start_nodes([MgcNode, MgNode], ?FILE, ?LINE),
+
+ d("[MGC] start the simulator "),
+ {ok, Mgc} = megaco_test_megaco_generator:start_link("MGC", MgcNode),
+
+ d("[MGC] create the event sequence"),
+ MgcEvSeq = otp_5805_mgc_event_sequence(text, tcp),
+
+ i("wait some time before starting the MGC simulation"),
+ sleep(1000),
+
+ d("[MGC] start the simulation"),
+ {ok, MgcId} =
+ megaco_test_megaco_generator:exec(Mgc, MgcEvSeq, timer:minutes(1)),
+
+ i("wait some time before starting the MG simulator"),
+ sleep(1000),
+
+ d("start the MG simulator (generator)"),
+ {ok, Mg} = megaco_test_tcp_generator:start_link("MG", MgNode),
+
+ d("create the MG event sequence"),
+ MgEvSeq = otp_5805_mg_event_sequence(text, tcp),
+
+ d("start the MG simulation"),
+ {ok, MgId} =
+ megaco_test_tcp_generator:exec(Mg, MgEvSeq, timer:minutes(1)),
+
+ d("await the generator reply(s)"),
+ await_completion([MgcId, MgId]),
+
+ %% Tell Mgc to stop
+ i("[MGC] stop generator"),
+ megaco_test_megaco_generator:stop(Mgc),
+
+ %% Tell Mg to stop
+ i("[MG] stop generator"),
+ megaco_test_tcp_generator:stop(Mg),
+
+ i("done", []),
+ ok.
+
+
+-ifdef(megaco_hipe_special).
+-define(otp_5805_mg_decode_msg_fun(Mod, Conf),
+ {?MODULE, decode_msg, [Mod, Conf]}).
+-define(otp_5805_mg_encode_msg_fun(Mod, Conf),
+ {?MODULE, encode_msg, [Mod, Conf]}).
+-define(otp_5805_mg_verify_service_change_rep_msg_fun(),
+ {?MODULE, otp_5805_mg_verify_service_change_rep_msg, []}).
+-define(otp_5805_mg_verify_error_descriptor_msg_fun(),
+ {?MODULE, otp_5805_mg_verify_error_descriptor_msg, []}).
+-else.
+-define(otp_5805_mg_decode_msg_fun(Mod, Conf),
+ otp_5805_mg_decode_msg_fun(Mod, Conf)).
+-define(otp_5805_mg_encode_msg_fun(Mod, Conf),
+ otp_5805_mg_encode_msg_fun(Mod, Conf)).
+-define(otp_5805_mg_verify_service_change_rep_msg_fun(),
+ otp_5805_mg_verify_service_change_rep_msg_fun()).
+-define(otp_5805_mg_verify_error_descriptor_msg_fun(),
+ otp_5805_mg_verify_error_descriptor_msg_fun()).
+-endif.
+
+otp_5805_mg_event_sequence(text, tcp) ->
+ DecodeFun = ?otp_5805_mg_decode_msg_fun(megaco_pretty_text_encoder, []),
+ EncodeFun = ?otp_5805_mg_encode_msg_fun(megaco_pretty_text_encoder, []),
+ Mid = {deviceName,"mg"},
+ ServiceChangeReq = otp_5805_mg_service_change_request_msg(Mid, 1, 0),
+ NotifyReqNNV = otp_5805_mg_notify_request_msg("1"),
+ NotifyReqUV = otp_5805_mg_notify_request_msg("4"),
+ ServiceChangeReplyVerifyFun =
+ ?otp_5805_mg_verify_service_change_rep_msg_fun(),
+ EDVerify =
+ ?otp_5805_mg_verify_error_descriptor_msg_fun(),
+%% ServiceChangeReplyVerifyFun =
+%% otp_5805_mg_verify_service_change_rep_msg_fun(),
+%% EDVerify = otp_5805_mg_verify_error_descriptor_msg_fun(),
+ MgEvSeq = [{debug, true},
+ {decode, DecodeFun},
+ {encode, EncodeFun},
+ {connect, 2944},
+
+ {send, "service-change-request", ServiceChangeReq},
+ {expect_receive, "service-change-reply", {ServiceChangeReplyVerifyFun, 5000}},
+ {sleep, 1000},
+ {send, "notify request (not negotiated version)", NotifyReqNNV},
+ {expect_receive, "error-descriptor", EDVerify},
+ {sleep, 1000},
+ {send, "notify request (unsupported version)", NotifyReqUV},
+ {expect_receive, "error-descriptor", EDVerify},
+
+ {expect_nothing, 4000},
+ disconnect
+ ],
+ MgEvSeq.
+
+-ifndef(megaco_hipe_special).
+otp_5805_mg_encode_msg_fun(Mod, Conf) ->
+ fun(M) ->
+ encode_msg(M, Mod, Conf)
+ end.
+-endif.
+
+-ifndef(megaco_hipe_special).
+otp_5805_mg_decode_msg_fun(Mod, Conf) ->
+ fun(M) ->
+ decode_msg(M, Mod, Conf)
+ end.
+-endif.
+
+-ifndef(megaco_hipe_special).
+otp_5805_mg_verify_service_change_rep_msg_fun() ->
+ fun(M) ->
+ otp_5805_mg_verify_service_change_rep_msg(M)
+ end.
+-endif.
+
+otp_5805_mg_verify_service_change_rep_msg(#'MegacoMessage'{mess = Mess} = M) ->
+ case Mess of
+ #'Message'{version = 1,
+ mId = _MgMid,
+ messageBody = Body} ->
+ case Body of
+ {transactions, [Trans]} ->
+ case Trans of
+ {transactionReply, TR} ->
+ case TR of
+ #'TransactionReply'{transactionId = _Tid,
+ immAckRequired = asn1_NOVALUE,
+ transactionResult = Res} ->
+ case Res of
+ {actionReplies, [AR]} ->
+ case AR of
+ #'ActionReply'{contextId = _Cid,
+ errorDescriptor = asn1_NOVALUE,
+ contextReply = _CtxReq,
+ commandReply = [CR]} ->
+ case CR of
+ {serviceChangeReply, SCR} ->
+ case SCR of
+ #'ServiceChangeReply'{
+ terminationID = _TermID,
+ serviceChangeResult = SCRes} ->
+ case SCRes of
+ {serviceChangeResParms, SCRP} ->
+ case SCRP of
+ #'ServiceChangeResParm'{
+ serviceChangeMgcId = _MgcMid,
+ serviceChangeVersion = 2} ->
+ {ok, M};
+ _ ->
+ {error, {invalid_scrp, SCRP}}
+ end;
+ _ ->
+ {error, {invalid_scres, SCRes}}
+ end;
+ _ ->
+ {error, {invalid_scr, SCR}}
+ end;
+ _ ->
+ {error, {invalid_cr, CR}}
+ end;
+ _ ->
+ {error, {invalid_ar, AR}}
+ end;
+ _ ->
+ {error, {invalid_tres, Res}}
+ end;
+ _ ->
+ {error, {invalid_tr, TR}}
+ end;
+ _ ->
+ {error, {invalid_trans, Trans}}
+ end;
+ _ ->
+ {error, {invalid_body, Body}}
+ end;
+ _ ->
+ {error, {invalid_mess, Mess}}
+ end;
+otp_5805_mg_verify_service_change_rep_msg(M) ->
+ {error, {invalid_message, M}}.
+
+
+-ifndef(megaco_hipe_special).
+otp_5805_mg_verify_error_descriptor_msg_fun() ->
+ fun(M) ->
+ otp_5805_mg_verify_error_descriptor_msg(M)
+ end.
+-endif.
+
+otp_5805_mg_verify_error_descriptor_msg(#'MegacoMessage'{mess = Mess} = M) ->
+ case Mess of
+ #'Message'{version = 2,
+ mId = _MgMid,
+ messageBody = Body} ->
+ io:format("otp_5805_mg_verify_error_descriptor_msg_fun -> ok"
+ "~n Body: ~p"
+ "~n", [Body]),
+ case Body of
+ {messageError, ED} ->
+ case ED of
+ #'ErrorDescriptor'{
+ errorCode = ?megaco_version_not_supported} ->
+ {ok, M};
+ _ ->
+ {error, {invalid_ed, ED}}
+ end;
+ _ ->
+ {error, {invalid_body, Body}}
+ end;
+ _ ->
+ {error, {invalid_mess, Mess}}
+ end;
+otp_5805_mg_verify_error_descriptor_msg(M) ->
+ {error, {invalid_message, M}}.
+
+otp_5805_mg_service_change_request_ar(_Mid, Cid) ->
+ Prof = cre_serviceChangeProf("resgw", 1),
+ SCP = cre_serviceChangeParm(restart, 2, ["901 mg col boot"], Prof),
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = cre_serviceChangeReq([Root], SCP),
+ CMD = cre_command(SCR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+otp_5805_mg_service_change_request_msg(Mid, TransId, Cid) ->
+ AR = otp_5805_mg_service_change_request_ar(Mid, Cid),
+ TR = cre_transReq(TransId, [AR]),
+ Trans = cre_transaction(TR),
+ Mess = cre_message(1, Mid, cre_transactions([Trans])),
+ cre_megacoMessage(Mess).
+
+%% otp_5805_mg_notify_request_ar(Rid, Tid, Cid) ->
+%% TT = cre_timeNotation("19990729", "22000000"),
+%% Ev = cre_obsEvent("al/of", TT),
+%% EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
+%% NR = cre_notifyReq([Tid], EvsDesc),
+%% CMD = cre_command(NR),
+%% CR = cre_cmdReq(CMD),
+%% cre_actionReq(Cid, [CR]).
+
+otp_5805_mg_notify_request_msg(V) ->
+ M =
+"MEGACO/" ++ V ++ " mg
+Transaction = 2 {
+ Context = 1 {
+ Notify = 00000000/00000000/01101101 {
+ ObservedEvents = 1 {
+ 19990729T22000000:al/of
+ }
+ }
+ }
+}",
+ list_to_binary(M).
+
+
+%%
+%% MGC generator stuff
+%%
+
+-ifdef(megaco_hipe_special).
+-define(otp_5805_mgc_verify_handle_connect_fun(),
+ {?MODULE, otp_5805_mgc_verify_handle_connect, []}).
+-define(otp_5805_mgc_verify_service_change_req_fun(Mid),
+ {?MODULE, otp_5805_mgc_verify_service_change_req, [Mid]}).
+-define(otp_5805_mgc_verify_handle_syntax_error_fun(),
+ {?MODULE, otp_5805_mgc_verify_handle_syntax_error, []}).
+-define(otp_5805_mgc_verify_handle_disconnect_fun(),
+ {?MODULE, otp_5805_mgc_verify_handle_disconnect, []}).
+-else.
+-define(otp_5805_mgc_verify_handle_connect_fun(),
+ fun otp_5805_mgc_verify_handle_connect/1).
+-define(otp_5805_mgc_verify_service_change_req_fun(Mid),
+ otp_5805_mgc_verify_service_change_req_fun(Mid)).
+-define(otp_5805_mgc_verify_handle_syntax_error_fun(),
+ fun otp_5805_mgc_verify_handle_syntax_error/1).
+-define(otp_5805_mgc_verify_handle_disconnect_fun(),
+ fun otp_5805_mgc_verify_handle_disconnect/1).
+-endif.
+
+otp_5805_mgc_event_sequence(text, tcp) ->
+ Mid = {deviceName,"ctrl"},
+ RI = [
+ {port, 2944},
+ {encoding_module, megaco_pretty_text_encoder},
+ {encoding_config, []},
+ {transport_module, megaco_tcp}
+ ],
+ ConnectVerify = ?otp_5805_mgc_verify_handle_connect_fun(),
+ ServiceChangeReqVerify = ?otp_5805_mgc_verify_service_change_req_fun(Mid),
+ SyntaxErrorVerify1 = ?otp_5805_mgc_verify_handle_syntax_error_fun(),
+ SyntaxErrorVerify2 = ?otp_5805_mgc_verify_handle_syntax_error_fun(),
+ DiscoVerify = ?otp_5805_mgc_verify_handle_disconnect_fun(),
+%% ConnectVerify = fun otp_5805_mgc_verify_handle_connect/1,
+%% ServiceChangeReqVerify = otp_5805_mgc_verify_service_change_req_fun(Mid),
+%% SyntaxErrorVerify1 = fun otp_5805_mgc_verify_handle_syntax_error/1,
+%% SyntaxErrorVerify2 = fun otp_5805_mgc_verify_handle_syntax_error/1,
+%% DiscoVerify = fun otp_5805_mgc_verify_handle_disconnect/1,
+ EvSeq = [
+ {debug, true},
+ {megaco_trace, disable},
+ {megaco_trace, max},
+ megaco_start,
+ {megaco_start_user, Mid, RI, []},
+ start_transport,
+ listen,
+ {megaco_callback, handle_connect, ConnectVerify},
+ {megaco_conn_info, all},
+ {megaco_callback, handle_trans_request_sc, ServiceChangeReqVerify},
+ {megaco_update_conn_info, protocol_version, 2},
+ {megaco_callback, handle_syntax_error, SyntaxErrorVerify1},
+ {megaco_callback, handle_syntax_error, SyntaxErrorVerify2},
+ {megaco_callback, handle_disconnect, DiscoVerify},
+ megaco_stop_user,
+ megaco_stop
+ ],
+ EvSeq.
+
+otp_5805_mgc_verify_handle_connect({handle_connect, CH, 1}) ->
+ io:format("otp_5805_mgc_verify_handle_connect -> ok"
+ "~n CH: ~p"
+ "~n", [CH]),
+ {ok, CH, ok};
+otp_5805_mgc_verify_handle_connect({handle_connect, CH, V}) ->
+ io:format("otp_5805_mgc_verify_handle_connect -> unexpected version"
+ "~n CH: ~p"
+ "~n V: ~p"
+ "~n", [CH, V]),
+ {error, {unexpected_version, V}, ok};
+otp_5805_mgc_verify_handle_connect(Else) ->
+ {error, Else, ok}.
+
+
+-ifndef(megaco_hipe_special).
+otp_5805_mgc_verify_service_change_req_fun(Mid) ->
+ fun(Ev) ->
+ otp_5805_mgc_verify_service_change_req(Ev, Mid)
+ end.
+-endif.
+
+otp_5805_mgc_verify_service_change_req({handle_trans_request, _, V, [AR]},
+ Mid) ->
+ io:format("otp_5805_mgc_verify_service_change_req -> ok so far"
+ "~n V: ~p"
+ "~n", [V]),
+ case AR of
+ #'ActionRequest'{commandRequests = [CR]} ->
+ case CR of
+ #'CommandRequest'{command = Cmd} ->
+ case Cmd of
+ {serviceChangeReq,
+ #'ServiceChangeRequest'{terminationID = [Tid],
+ serviceChangeParms = Parms}} ->
+ case Tid of
+ #megaco_term_id{contains_wildcards = false,
+ id = ["root"]} ->
+ case Parms of
+ #'ServiceChangeParm'{
+ serviceChangeMethod = restart,
+ serviceChangeVersion = 2,
+ serviceChangeReason = [[$9,$0,$1|_]]} ->
+ Reply =
+ {discard_ack,
+ [otp_5805_mgc_service_change_reply_ar(Mid, 1)]},
+ {ok, AR, Reply};
+ _ ->
+ Err = {invalid_SCP, Parms},
+ ED = otp_5805_err_desc(Parms),
+ ErrReply =
+ {discard_ack, ED},
+ {error, Err, ErrReply}
+ end;
+ _ ->
+ Err = {invalid_termination_id, Tid},
+ ED = otp_5805_err_desc(Tid),
+ ErrReply = {discard_ack, ED},
+ {error, Err, ErrReply}
+ end;
+ _ ->
+ Err = {invalid_command, Cmd},
+ ED = otp_5805_err_desc(Cmd),
+ ErrReply = {discard_ack, ED},
+ {error, Err, ErrReply}
+ end;
+ _ ->
+ Err = {invalid_command_request, CR},
+ ED = otp_5805_err_desc(CR),
+ ErrReply = {discard_ack, ED},
+ {error, Err, ErrReply}
+ end;
+ _ ->
+ Err = {invalid_action_request, AR},
+ ED = otp_5805_err_desc(AR),
+ ErrReply = {discard_ack, ED},
+ {error, Err, ErrReply}
+ end;
+otp_5805_mgc_verify_service_change_req(Else, _Mid) ->
+ ED = otp_5805_err_desc(Else),
+ ErrReply = {discard_ack, ED},
+ {error, Else, ErrReply}.
+
+otp_5805_mgc_verify_handle_syntax_error({handle_syntax_error, CH, _, ED})
+ when is_record(ED, 'ErrorDescriptor') ->
+ io:format("otp_5805_mgc_verify_handle_syntax_error -> ok so far"
+ "~n CH: ~p"
+ "~n ED: ~p"
+ "~n", [CH, ED]),
+ case ED of
+ #'ErrorDescriptor'{errorCode = ?megaco_version_not_supported} ->
+ {ok, CH, reply};
+ #'ErrorDescriptor'{errorCode = Code} ->
+ {error, {invalid_errorCode, Code}, ok}
+ end;
+otp_5805_mgc_verify_handle_syntax_error(Else) ->
+ io:format("otp_5805_mgc_verify_handle_syntax_error -> unknown"
+ "~n Else: ~p~n", [Else]),
+ {error, Else, ok}.
+
+otp_5805_mgc_verify_handle_disconnect({handle_disconnect, CH, V, _R}) ->
+ io:format("otp_5805_mgc_verify_handle_disconnect -> ok"
+ "~n CH: ~p"
+ "~n V: ~p"
+ "~n _R: ~p"
+ "~n", [CH, V, _R]),
+ {ok, CH, ok};
+otp_5805_mgc_verify_handle_disconnect(Else) ->
+ io:format("otp_5805_mgc_verify_handle_disconnect -> unknown"
+ "~n Else: ~p~n", [Else]),
+ {error, Else, ok}.
+
+otp_5805_mgc_service_change_reply_ar(Mid, Cid) ->
+ SCRP = cre_serviceChangeResParm(Mid, 2),
+ SCRes = cre_serviceChangeResult(SCRP),
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = cre_serviceChangeReply([Root], SCRes),
+ CR = cre_cmdReply(SCR),
+ cre_actionReply(Cid, [CR]).
+
+%% otp_5805_mgc_notify_reply_ar(Cid, TermId) ->
+%% NR = cre_notifyReply([TermId]),
+%% CR = cre_cmdReply(NR),
+%% cre_actionReply(Cid, [CR]).
+
+
+otp_5805_err_desc(T) ->
+ EC = ?megaco_internal_gateway_error,
+ ET = lists:flatten(io_lib:format("~w",[T])),
+ #'ErrorDescriptor'{errorCode = EC, errorText = ET}.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+otp_5881(suite) ->
+ [];
+otp_5881(Config) when is_list(Config) ->
+ ?SKIP("deprecated by OTP-5887"),
+ put(verbosity, ?TEST_VERBOSITY),
+ put(sname, "TEST"),
+ put(tc, otp_5881),
+ i("starting"),
+
+ MgcNode = make_node_name(mgc),
+ MgNode = make_node_name(mg),
+ d("start nodes: "
+ "~n MgcNode: ~p"
+ "~n MgNode: ~p",
+ [MgcNode, MgNode]),
+ ok = megaco_test_lib:start_nodes([MgcNode, MgNode], ?FILE, ?LINE),
+
+ d("start the MGC simulator (generator)"),
+ {ok, Mgc} = megaco_test_tcp_generator:start_link("MGC", MgcNode),
+
+ d("create the MGC event sequence"),
+ MgcEvSeq = otp_5881_mgc_event_sequence(text, tcp),
+
+ d("start the MGC simulation"),
+ {ok, MgcId} = megaco_test_tcp_generator:exec(Mgc, MgcEvSeq),
+
+ i("[MG] start"),
+ MgMid = {deviceName, "mg"},
+ ReqTmr = #megaco_incr_timer{wait_for = 3000,
+ factor = 1,
+ incr = 0,
+ max_retries = 3},
+ %% 5000, %% Does not matter since we will not use this anyway...
+ LongReqTmr = #megaco_incr_timer{wait_for = 3000,
+ factor = 1,
+ incr = 0,
+ max_retries = 3},
+ PendingTmr = 10000,
+ ReplyTmr = 16000,
+ MgConfig = [{request_timer, ReqTmr},
+ {long_request_timer, LongReqTmr},
+ {pending_timer, PendingTmr},
+ {reply_timer, ReplyTmr}],
+ {ok, Mg} = ?MG_START(MgNode, MgMid, text, tcp, MgConfig, ?MG_VERBOSITY),
+
+ i("[MG] verify transaction-id: undefined_serial"),
+ otp_5881_verify_trans_id(Mg, undefined_serial),
+
+ i("[MG] connect to the MGC (service change)"),
+ ServChRes = ?MG_SERV_CHANGE(Mg),
+ d("service change result: ~p", [ServChRes]),
+
+ i("[MG] verify transaction-id: 1"),
+ otp_5881_verify_trans_id(Mg, 1),
+
+ d("[MG] send the notify"),
+ {ok, Reply} = (catch ?MG_NOTIF_RAR(Mg)),
+ {1, {ok, [AR]}} = Reply,
+ d("[MG] ActionReply: ~p", [AR]),
+
+ i("[MG] verify transaction-id: 2"),
+ otp_5881_verify_trans_id(Mg, 2),
+
+ d("await the generator reply"),
+ await_completion([MgcId]),
+
+ %% Tell MG to stop
+ i("[MG] stop"),
+ ?MG_STOP(Mg),
+
+ %% Tell Mgc to stop
+ i("[MGC] stop generator"),
+ megaco_test_tcp_generator:stop(Mgc),
+
+ i("done", []),
+ ok.
+
+otp_5881_verify_trans_id(Mg, Expected) ->
+ case ?MG_CONN_INFO(Mg, trans_id) of
+ Expected ->
+ ok;
+ ErroneousValue ->
+ throw({unexpected_transaction_id_value, ErroneousValue, Expected})
+ end.
+
+
+-ifdef(megaco_hipe_special).
+-define(otp_5881_mgc_decode_msg_fun(Mod, Conf),
+ {?MODULE, decode_msg, [Mod, Conf]}).
+-define(otp_5881_mgc_encode_msg_fun(Mod, Conf),
+ {?MODULE, encode_msg, [Mod, Conf]}).
+-define(otp_5881_mgc_verify_service_change_req_msg_fun(),
+ {?MODULE, otp_5881_mgc_verify_service_change_req_msg, []}).
+-define(otp_5881_mgc_verify_notify_req_msg_fun(),
+ {?MODULE, otp_5881_mgc_verify_notify_req_msg, []}).
+-else.
+-define(otp_5881_mgc_decode_msg_fun(Mod, Conf),
+ otp_5881_mgc_decode_msg_fun(Mod, Conf)).
+-define(otp_5881_mgc_encode_msg_fun(Mod, Conf),
+ otp_5881_mgc_encode_msg_fun(Mod, Conf)).
+-define(otp_5881_mgc_verify_service_change_req_msg_fun(),
+ otp_5881_mgc_verify_service_change_req_msg_fun()).
+-define(otp_5881_mgc_verify_notify_req_msg_fun(),
+ otp_5881_mgc_verify_notify_req_msg_fun()).
+-endif.
+
+otp_5881_mgc_event_sequence(text, tcp) ->
+ DecodeFun = ?otp_5881_mgc_decode_msg_fun(megaco_pretty_text_encoder, []),
+ EncodeFun = ?otp_5881_mgc_encode_msg_fun(megaco_pretty_text_encoder, []),
+ Mid = {deviceName,"ctrl"},
+ ServiceChangeReply = otp_5881_service_change_reply_msg(Mid, 1, 0),
+ TermId = #megaco_term_id{id = ["00000000","00000000","01101101"]},
+ NotifyReply = otp_5881_notify_reply_msg(Mid, 2, 0, TermId),
+ %% Pending = otp_5881_pending_msg(Mid,2),
+ ServiceChangeVerifyFun = ?otp_5881_mgc_verify_service_change_req_msg_fun(),
+ NotifyReqVerifyFun = ?otp_5881_mgc_verify_notify_req_msg_fun(),
+%% ServiceChangeVerifyFun = otp_5881_verify_service_change_req_msg_fun(),
+%% NotifyReqVerifyFun = otp_5881_verify_notify_request_fun(),
+ MgcEvSeq = [{debug, true},
+ {decode, DecodeFun},
+ {encode, EncodeFun},
+ {listen, 2944},
+ {expect_accept, any},
+ {expect_receive, "service-change-request", {ServiceChangeVerifyFun, 10000}},
+ {send, "service-change-reply", ServiceChangeReply},
+ {expect_receive, "notify-request", {NotifyReqVerifyFun, 10000}},
+ {send, "notify-reply", NotifyReply},
+ {sleep, 2000}
+ ],
+ MgcEvSeq.
+
+-ifndef(megaco_hipe_special).
+otp_5881_mgc_encode_msg_fun(Mod, Conf) ->
+ fun(M) ->
+ encode_msg(M, Mod, Conf)
+ end.
+-endif.
+
+-ifndef(megaco_hipe_special).
+otp_5881_mgc_decode_msg_fun(Mod, Conf) ->
+ fun(M) ->
+ decode_msg(M, Mod, Conf)
+ end.
+-endif.
+
+otp_5881_service_change_reply_msg(Mid, TransId, Cid) ->
+ SCRP = #'ServiceChangeResParm'{serviceChangeMgcId = Mid},
+ SCRPs = {serviceChangeResParms,SCRP},
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = #'ServiceChangeReply'{terminationID = [Root],
+ serviceChangeResult = SCRPs},
+ CR = {serviceChangeReply, SCR},
+ otp_5881_msg(Mid, TransId, CR, Cid).
+
+otp_5881_notify_reply_msg(Mid, TransId, Cid, TermId) ->
+ NR = #'NotifyReply'{terminationID = [TermId]},
+ CR = {notifyReply, NR},
+ otp_5881_msg(Mid, TransId, CR, Cid).
+
+otp_5881_msg(Mid, TransId, CR, Cid) ->
+ AR = #'ActionReply'{contextId = Cid,
+ commandReply = [CR]},
+ ARs = {actionReplies, [AR]},
+ TR = #'TransactionReply'{transactionId = TransId,
+ transactionResult = ARs},
+ Body = {transactions, [{transactionReply, TR}]},
+ Mess = #'Message'{version = 1,
+ mId = Mid,
+ messageBody = Body},
+ #'MegacoMessage'{mess = Mess}.
+
+
+%% otp_5881_pending_msg(Mid, TransId) ->
+%% TP = #'TransactionPending'{transactionId = TransId},
+%% Body = {transactions, [{transactionPending, TP}]},
+%% Mess = #'Message'{version = 1,
+%% mId = Mid,
+%% messageBody = Body},
+%% #'MegacoMessage'{mess = Mess}.
+
+
+-ifndef(megaco_hipe_special).
+otp_5881_mgc_verify_service_change_req_msg_fun() ->
+ fun(M) ->
+ otp_5881_mgc_verify_service_change_req_msg(M)
+ end.
+-endif.
+
+otp_5881_mgc_verify_service_change_req_msg(
+ #'MegacoMessage'{mess = Mess} = M) ->
+ #'Message'{version = _V,
+ mId = _Mid,
+ messageBody = Body} = Mess,
+ {transactions, [Trans]} = Body,
+ {transactionRequest, TR} = Trans,
+ #'TransactionRequest'{transactionId = _Tid,
+ actions = [AR]} = TR,
+ #'ActionRequest'{contextId = _Cid,
+ contextRequest = _CtxReq,
+ contextAttrAuditReq = _CtxAar,
+ commandRequests = [CR]} = AR,
+ #'CommandRequest'{command = Cmd,
+ optional = _Opt,
+ wildcardReturn = _WR} = CR,
+ {serviceChangeReq, SCR} = Cmd,
+ #'ServiceChangeRequest'{terminationID = _TermID,
+ serviceChangeParms = SCP} = SCR,
+ #'ServiceChangeParm'{serviceChangeMethod = restart,
+ serviceChangeReason = [[$9,$0,$1|_]]} = SCP,
+ {ok, M};
+otp_5881_mgc_verify_service_change_req_msg(M) ->
+ {error, {invalid_message, M}}.
+
+-ifndef(megaco_hipe_special).
+otp_5881_mgc_verify_notify_req_msg_fun() ->
+ fun(M) ->
+ otp_5881_mgc_verify_notify_req_msg(M)
+ end.
+-endif.
+
+otp_5881_mgc_verify_notify_req_msg(#'MegacoMessage'{mess = Mess} = M) ->
+ #'Message'{messageBody = Body} = Mess,
+ {transactions, [Trans]} = Body,
+ {transactionRequest, TR} = Trans,
+ #'TransactionRequest'{actions = [AR]} = TR,
+ #'ActionRequest'{commandRequests = [CR1,CR2]} = AR,
+ #'CommandRequest'{command = Cmd1} = CR1,
+ {notifyReq, NR1} = Cmd1,
+ #'NotifyRequest'{observedEventsDescriptor = OED1} = NR1,
+ #'ObservedEventsDescriptor'{observedEventLst = [OE1]} = OED1,
+ #'ObservedEvent'{eventName = "al/of"} = OE1,
+ #'CommandRequest'{command = Cmd2} = CR2,
+ {notifyReq, NR2} = Cmd2,
+ #'NotifyRequest'{observedEventsDescriptor = OED2} = NR2,
+ #'ObservedEventsDescriptor'{observedEventLst = [OE2]} = OED2,
+ #'ObservedEvent'{eventName = "al/of"} = OE2,
+ {ok, M};
+otp_5881_mgc_verify_notify_req_msg(M) ->
+ {error, {invalid_message, M}}.
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+otp_5887(suite) ->
+ [];
+otp_5887(Config) when is_list(Config) ->
+ put(verbosity, ?TEST_VERBOSITY),
+ put(sname, "TEST"),
+ put(tc, otp_5887),
+ i("starting"),
+
+ MgcNode = make_node_name(mgc),
+ MgNode = make_node_name(mg),
+ d("start nodes: "
+ "~n MgcNode: ~p"
+ "~n MgNode: ~p",
+ [MgcNode, MgNode]),
+ ok = megaco_test_lib:start_nodes([MgcNode, MgNode], ?FILE, ?LINE),
+
+ d("start the MGC simulator (generator)"),
+ {ok, Mgc} = megaco_test_tcp_generator:start_link("MGC", MgcNode),
+
+ d("create the MGC event sequence"),
+ MgcEvSeq = otp_5887_mgc_event_sequence(text, tcp),
+
+ d("start the MGC simulation"),
+ {ok, MgcId} = megaco_test_tcp_generator:exec(Mgc, MgcEvSeq),
+
+ i("[MG] start"),
+ MgMid = {deviceName, "mg"},
+ ReqTmr = #megaco_incr_timer{wait_for = 3000,
+ factor = 1,
+ incr = 0,
+ max_retries = 3},
+ %% 5000, %% Does not matter since we will not use this anyway...
+ LongReqTmr = #megaco_incr_timer{wait_for = 3000,
+ factor = 1,
+ incr = 0,
+ max_retries = 3},
+ PendingTmr = 10000,
+ ReplyTmr = 16000,
+ MgConfig = [{request_timer, ReqTmr},
+ {long_request_timer, LongReqTmr},
+ {pending_timer, PendingTmr},
+ {reply_timer, ReplyTmr}],
+ {ok, Mg} = ?MG_START(MgNode, MgMid, text, tcp, MgConfig, ?MG_VERBOSITY),
+
+ i("[MG] conn info: ~n~p", [?MG_CONN_INFO(Mg, all)]),
+
+ i("[MG] verify conn transaction-id: 1"),
+ otp_5887_verify_conn_trans_id(Mg, 1),
+
+ i("[MG] user info: ~n~p", [?MG_USER_INFO(Mg, all)]),
+
+ i("[MG] verify user transaction-id: undefined_serial"),
+ otp_5887_verify_user_trans_id(Mg, undefined_serial),
+
+ i("[MG] connect to the MGC (service change)"),
+ ServChRes = ?MG_SERV_CHANGE(Mg),
+ d("service change result: ~p", [ServChRes]),
+
+ i("[MG] conn info: ~n~p", [?MG_CONN_INFO(Mg, all)]),
+
+ i("[MG] verify conn transaction-id: 2"),
+ otp_5887_verify_conn_trans_id(Mg, 2),
+
+ i("[MG] user info: ~n~p", [?MG_USER_INFO(Mg, all)]),
+
+ i("[MG] verify user transaction-id: 1"),
+ otp_5887_verify_user_trans_id(Mg, 1),
+
+ d("[MG] send the notify"),
+ {ok, Reply} = (catch ?MG_NOTIF_RAR(Mg)),
+ {1, {ok, [AR]}} = Reply,
+ d("[MG] ActionReply: ~p", [AR]),
+
+ i("[MG] conn info: ~n~p", [?MG_CONN_INFO(Mg, all)]),
+
+ i("[MG] verify conn transaction-id: 3"),
+ otp_5887_verify_conn_trans_id(Mg, 3),
+
+ i("[MG] user info: ~n~p", [?MG_USER_INFO(Mg, all)]),
+
+ i("[MG] verify user transaction-id: 2"),
+ otp_5887_verify_user_trans_id(Mg, 2),
+
+ d("await the generator reply"),
+ await_completion([MgcId]),
+
+ %% Tell MG to stop
+ i("[MG] stop"),
+ ?MG_STOP(Mg),
+
+ %% Tell Mgc to stop
+ i("[MGC] stop generator"),
+ megaco_test_tcp_generator:stop(Mgc),
+
+ i("done", []),
+ ok.
+
+
+otp_5887_verify_conn_trans_id(Mg, Expected) ->
+ F = fun() -> (catch ?MG_CONN_INFO(Mg, trans_id)) end,
+ otp_5887_verify_trans_id(F, Expected).
+
+otp_5887_verify_user_trans_id(Mg, Expected) ->
+ F = fun() -> (catch ?MG_USER_INFO(Mg, trans_id)) end,
+ otp_5887_verify_trans_id(F, Expected).
+
+otp_5887_verify_trans_id(F, Expected) ->
+ case F() of
+ Expected ->
+ ok;
+ ErroneousValue ->
+ throw({unexpected_transaction_id_value, ErroneousValue, Expected})
+ end.
+
+
+-ifdef(megaco_hipe_special).
+-define(otp_5887_mgc_decode_msg_fun(Mod, Conf),
+ {?MODULE, decode_msg, [Mod, Conf]}).
+-define(otp_5887_mgc_encode_msg_fun(Mod, Conf),
+ {?MODULE, encode_msg, [Mod, Conf]}).
+-define(otp_5887_mgc_verify_service_change_req_msg_fun(),
+ {?MODULE, otp_5887_mgc_verify_service_change_req_msg, []}).
+-define(otp_5887_mgc_verify_notify_req_msg_fun(),
+ {?MODULE, otp_5887_mgc_verify_notify_req_msg, []}).
+-else.
+-define(otp_5887_mgc_decode_msg_fun(Mod, Conf),
+ otp_5887_mgc_decode_msg_fun(Mod, Conf)).
+-define(otp_5887_mgc_encode_msg_fun(Mod, Conf),
+ otp_5887_mgc_encode_msg_fun(Mod, Conf)).
+-define(otp_5887_mgc_verify_service_change_req_msg_fun(),
+ otp_5887_mgc_verify_service_change_req_msg_fun()).
+-define(otp_5887_mgc_verify_notify_req_msg_fun(),
+ otp_5887_mgc_verify_notify_req_msg_fun()).
+-endif.
+
+otp_5887_mgc_event_sequence(text, tcp) ->
+ DecodeFun = ?otp_5887_mgc_decode_msg_fun(megaco_pretty_text_encoder, []),
+ EncodeFun = ?otp_5887_mgc_encode_msg_fun(megaco_pretty_text_encoder, []),
+ Mid = {deviceName,"ctrl"},
+ ServiceChangeReply = otp_5887_service_change_reply_msg(Mid, 1, 0),
+ TermId = #megaco_term_id{id = ["00000000","00000000","01101101"]},
+ NotifyReply = otp_5887_notify_reply_msg(Mid, 2, 0, TermId),
+ ServiceChangeVerifyFun = ?otp_5887_mgc_verify_service_change_req_msg_fun(),
+ NotifyReqVerifyFun = ?otp_5887_mgc_verify_notify_req_msg_fun(),
+%% ServiceChangeVerifyFun = otp_5887_verify_service_change_req_msg_fun(),
+%% NotifyReqVerifyFun = otp_5887_verify_notify_request_fun(),
+ MgcEvSeq = [{debug, true},
+ {decode, DecodeFun},
+ {encode, EncodeFun},
+ {listen, 2944},
+ {expect_accept, any},
+ {expect_receive, "service-change-request", {ServiceChangeVerifyFun, 10000}},
+ {send, "service-change-reply", ServiceChangeReply},
+ {expect_receive, "notify-request", {NotifyReqVerifyFun, 10000}},
+ {send, "notify-reply", NotifyReply},
+ {sleep, 2000}
+ ],
+ MgcEvSeq.
+
+otp_5887_service_change_reply_msg(Mid, TransId, Cid) ->
+ SCRP = #'ServiceChangeResParm'{serviceChangeMgcId = Mid},
+ SCRPs = {serviceChangeResParms,SCRP},
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = #'ServiceChangeReply'{terminationID = [Root],
+ serviceChangeResult = SCRPs},
+ CR = {serviceChangeReply, SCR},
+ otp_5887_msg(Mid, TransId, CR, Cid).
+
+otp_5887_notify_reply_msg(Mid, TransId, Cid, TermId) ->
+ NR = #'NotifyReply'{terminationID = [TermId]},
+ CR = {notifyReply, NR},
+ otp_5887_msg(Mid, TransId, CR, Cid).
+
+otp_5887_msg(Mid, TransId, CR, Cid) ->
+ AR = #'ActionReply'{contextId = Cid,
+ commandReply = [CR]},
+ ARs = {actionReplies, [AR]},
+ TR = #'TransactionReply'{transactionId = TransId,
+ transactionResult = ARs},
+ Body = {transactions, [{transactionReply, TR}]},
+ Mess = #'Message'{version = 1,
+ mId = Mid,
+ messageBody = Body},
+ #'MegacoMessage'{mess = Mess}.
+
+
+%% otp_5887_pending_msg(Mid, TransId) ->
+%% TP = #'TransactionPending'{transactionId = TransId},
+%% Body = {transactions, [{transactionPending, TP}]},
+%% Mess = #'Message'{version = 1,
+%% mId = Mid,
+%% messageBody = Body},
+%% #'MegacoMessage'{mess = Mess}.
+
+
+-ifndef(megaco_hipe_special).
+otp_5887_mgc_encode_msg_fun(Mod, Conf) ->
+ fun(M) ->
+ encode_msg(M, Mod, Conf)
+ end.
+-endif.
+%% otp_5887_mgc_encode_msg_fun(Mod, Conf, Ver) ->
+%% fun(M) ->
+%% encode_msg(M, Mod, Conf, Ver)
+%% end.
+
+-ifndef(megaco_hipe_special).
+otp_5887_mgc_decode_msg_fun(Mod, Conf) ->
+ fun(M) ->
+ decode_msg(M, Mod, Conf)
+ end.
+-endif.
+%% otp_5887_mgc_decode_msg_fun(Mod, Conf, Ver) ->
+%% fun(M) ->
+%% decode_msg(M, Mod, Conf, Ver)
+%% end.
+
+-ifndef(megaco_hipe_special).
+otp_5887_mgc_verify_service_change_req_msg_fun() ->
+ fun(M) ->
+ otp_5887_mgc_verify_service_change_req_msg(M)
+ end.
+-endif.
+
+otp_5887_mgc_verify_service_change_req_msg(
+ #'MegacoMessage'{mess = Mess} = M) ->
+ #'Message'{version = _V,
+ mId = _Mid,
+ messageBody = Body} = Mess,
+ {transactions, [Trans]} = Body,
+ {transactionRequest, TR} = Trans,
+ #'TransactionRequest'{transactionId = _Tid,
+ actions = [AR]} = TR,
+ #'ActionRequest'{contextId = _Cid,
+ contextRequest = _CtxReq,
+ contextAttrAuditReq = _CtxAar,
+ commandRequests = [CR]} = AR,
+ #'CommandRequest'{command = Cmd,
+ optional = _Opt,
+ wildcardReturn = _WR} = CR,
+ {serviceChangeReq, SCR} = Cmd,
+ #'ServiceChangeRequest'{terminationID = _TermID,
+ serviceChangeParms = SCP} = SCR,
+ #'ServiceChangeParm'{serviceChangeMethod = restart,
+ serviceChangeReason = [[$9,$0,$1|_]]} = SCP,
+ {ok, M};
+otp_5887_mgc_verify_service_change_req_msg(M) ->
+ {error, {invalid_message, M}}.
+
+
+-ifndef(megaco_hipe_special).
+otp_5887_mgc_verify_notify_req_msg_fun() ->
+ fun(M) ->
+ otp_5887_mgc_verify_notify_req_msg(M)
+ end.
+-endif.
+
+otp_5887_mgc_verify_notify_req_msg(#'MegacoMessage'{mess = Mess} = M) ->
+ #'Message'{messageBody = Body} = Mess,
+ {transactions, [Trans]} = Body,
+ {transactionRequest, TR} = Trans,
+ #'TransactionRequest'{actions = [AR]} = TR,
+ #'ActionRequest'{commandRequests = [CR1,CR2]} = AR,
+ #'CommandRequest'{command = Cmd1} = CR1,
+ {notifyReq, NR1} = Cmd1,
+ #'NotifyRequest'{observedEventsDescriptor = OED1} = NR1,
+ #'ObservedEventsDescriptor'{observedEventLst = [OE1]} = OED1,
+ #'ObservedEvent'{eventName = "al/of"} = OE1,
+ #'CommandRequest'{command = Cmd2} = CR2,
+ {notifyReq, NR2} = Cmd2,
+ #'NotifyRequest'{observedEventsDescriptor = OED2} = NR2,
+ #'ObservedEventsDescriptor'{observedEventLst = [OE2]} = OED2,
+ #'ObservedEvent'{eventName = "al/of"} = OE2,
+ {ok, M};
+otp_5887_mgc_verify_notify_req_msg(M) ->
+ {error, {invalid_message, M}}.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+otp_6253(suite) ->
+ [];
+otp_6253(Config) when is_list(Config) ->
+ ?ACQUIRE_NODES(1, Config),
+
+ put(verbosity, debug),
+ put(tc, otp_6253),
+
+ d("otp_6253 -> start test case controller",[]),
+ ok = megaco_tc_controller:start_link(),
+
+ PrelMid = preliminary_mid,
+ MgMid = ipv4_mid(4711),
+
+ ?VERIFY(ok, application:start(megaco)),
+ ?VERIFY(ok, megaco:start_user(MgMid, [{send_mod, megaco_mess_user_test},
+ {request_timer, infinity},
+ {reply_timer, infinity}])),
+
+ MgRH = user_info(MgMid, receive_handle),
+ {ok, PrelCH} = ?VERIFY({ok, _}, megaco:connect(MgRH, PrelMid, sh, self())),
+
+ connections([PrelCH]),
+ ?VERIFY([PrelCH], megaco:user_info(MgMid, connections)),
+
+ SC = service_change_request(),
+
+ %% Instruct the transport module to fail all send_message
+ d("otp_6253 -> instruct transport module to fail message send",[]),
+ ok = megaco_tc_controller:insert(allow_send_message, {fail, otp_6253}),
+
+ ?VERIFY({1, {error, {send_message_failed, otp_6253}}},
+ megaco:call(PrelCH, [SC], [])),
+
+ sleep(1000),
+
+ %% Instruct the transport module to cancel all send_message
+ d("otp_6253 -> instruct transport module to cancel message send",[]),
+ ok = megaco_tc_controller:insert(allow_send_message, {cancel, otp_6253}),
+
+ ?VERIFY({1, {error, {send_message_cancelled, otp_6253}}},
+ megaco:call(PrelCH, [SC], [])),
+
+ ?VERIFY(ok, megaco:disconnect(PrelCH, shutdown)),
+
+ ?VERIFY(ok, megaco:stop_user(MgMid)),
+ ?VERIFY(ok, application:stop(megaco)),
+ ?RECEIVE([]),
+ ok.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+otp_6275(suite) ->
+ [];
+otp_6275(Config) when is_list(Config) ->
+ put(verbosity, ?TEST_VERBOSITY),
+ put(sname, "TEST"),
+ put(tc, otp_6275),
+ i("starting"),
+
+ MgcNode = make_node_name(mgc),
+ MgNode = make_node_name(mg),
+ d("start nodes: "
+ "~n MgcNode: ~p"
+ "~n MgNode: ~p",
+ [MgcNode, MgNode]),
+ ok = megaco_test_lib:start_nodes([MgcNode, MgNode], ?FILE, ?LINE),
+
+ d("start the MGC simulator (generator)"),
+ {ok, Mgc} = megaco_test_tcp_generator:start_link("MGC", MgcNode),
+
+ d("create the MGC event sequence"),
+ MgcEvSeq = otp_6275_mgc_event_sequence(text, tcp),
+
+ d("start the MGC simulation"),
+ {ok, MgcId} = megaco_test_tcp_generator:exec(Mgc, MgcEvSeq),
+
+ d("[MG] start the simulator (generator)"),
+ {ok, Mg} = megaco_test_megaco_generator:start_link("MG", MgNode),
+
+ d("[MG] create the event sequence"),
+ MgEvSeq = otp_6275_mg_event_sequence(text, tcp),
+
+ i("wait some time before starting the MG simulation"),
+ sleep(1000),
+
+ d("[MG] start the simulation"),
+ {ok, MgId} = megaco_test_megaco_generator:exec(Mg, MgEvSeq),
+
+ d("[MGC] await the generator reply"),
+ await_completion([MgcId, MgId]),
+
+ %% Tell Mgc to stop
+ i("[MGC] stop generator"),
+ megaco_test_tcp_generator:stop(Mgc),
+
+ %% Tell Mg to stop
+ i("[MG] stop generator"),
+ megaco_test_megaco_generator:stop(Mg),
+
+ i("done", []),
+ ok.
+
+
+%%
+%% MG generator stuff
+%%
+-ifdef(megaco_hipe_special).
+-define(otp_6275_mg_verify_handle_connect_fun(),
+ {?MODULE, otp_6275_mg_verify_handle_connect, []}).
+-define(otp_6275_mg_verify_notify_req_fun(),
+ {?MODULE, otp_6275_mg_verify_notify_req, []}).
+-define(otp_6275_mg_verify_handle_trans_rep_fun(),
+ {?MODULE, otp_6275_mg_verify_handle_trans_rep, []}).
+-else.
+-define(otp_6275_mg_verify_handle_connect_fun(),
+ otp_6275_mg_verify_handle_connect_fun()).
+-define(otp_6275_mg_verify_notify_req_fun(),
+ otp_6275_mg_verify_notify_req_fun()).
+-define(otp_6275_mg_verify_handle_trans_rep_fun(),
+ otp_6275_mg_verify_handle_trans_rep_fun()).
+-endif.
+
+otp_6275_mg_event_sequence(text, tcp) ->
+ Mid = {deviceName,"mg"},
+ RI = [
+ {port, 2944},
+ {encoding_module, megaco_pretty_text_encoder},
+ {encoding_config, []},
+ {transport_module, megaco_tcp}
+ ],
+ otp_6275_mg_event_sequence2(Mid, RI).
+
+otp_6275_mg_event_sequence2(Mid, RI) ->
+ ServiceChangeReq = [otp_6275_mg_service_change_request_ar(Mid, 1)],
+ _Tid = #megaco_term_id{id = ["00000000","00000000","01101101"]},
+ ConnectVerify = ?otp_6275_mg_verify_handle_connect_fun(),
+ NotifyReqVerify = ?otp_6275_mg_verify_notify_req_fun(),
+ TransReplyVerify = ?otp_6275_mg_verify_handle_trans_rep_fun(),
+%% ConnectVerify = otp_6275_mg_verify_handle_connect_fun(),
+%% NotifyReqVerify = otp_6275_mg_verify_notify_request_fun(),
+%% TransReplyVerify = otp_6275_mg_verify_trans_reply_fun(),
+ EvSeq = [
+ {debug, true},
+ megaco_start,
+ {megaco_start_user, Mid, RI, []},
+ %% {megaco_update_user_info, recv_pending_limit, 4},
+ {megaco_update_user_info, request_timer, 3000},
+ start_transport,
+ {megaco_trace, disable}, %%100},
+ {megaco_system_info, users},
+ {megaco_system_info, connections},
+ connect,
+ {megaco_callback, handle_connect, ConnectVerify},
+ megaco_connect,
+ {megaco_cast, ServiceChangeReq, []},
+ {megaco_callback, handle_connect, ConnectVerify},
+ {megaco_callback, handle_trans_request, NotifyReqVerify},
+ {megaco_callback, handle_trans_reply, TransReplyVerify},
+ {sleep, 1000},
+ megaco_stop_user,
+ megaco_stop,
+ {sleep, 1000}
+ ],
+ EvSeq.
+
+
+-ifndef(megaco_hipe_special).
+otp_6275_mg_verify_handle_connect_fun() ->
+ fun(Event) ->
+ (catch otp_6275_mg_verify_handle_connect(Event))
+ end.
+-endif.
+
+otp_6275_mg_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
+ io:format("otp_6275_mg_verify_handle_connect -> ok"
+ "~n CH: ~p~n", [CH]),
+ {ok, CH, ok};
+otp_6275_mg_verify_handle_connect(Else) ->
+ io:format("otp_6275_mg_verify_handle_connect -> unknown"
+ "~n Else: ~p~n", [Else]),
+ {error, Else, ok}.
+
+
+-ifndef(megaco_hipe_special).
+otp_6275_mg_verify_notify_req_fun() ->
+ fun(Event) ->
+ (catch otp_6275_mg_verify_notify_req(Event))
+ end.
+-endif.
+
+otp_6275_mg_verify_notify_req(
+ {handle_trans_request, _CH, ?VERSION, [AR]}) ->
+ io:format("otp_6275_mg_verify_notify_req -> entry with"
+ "~n AR: ~p"
+ "~n", [AR]),
+ CR =
+ case AR of
+ #'ActionRequest'{commandRequests = [CmdReq]} ->
+ CmdReq;
+ _ ->
+ ET1 = lists:flatten(
+ io_lib:format("Invalid action request: ~w", [AR])),
+ EC1 = ?megaco_internal_gateway_error,
+ ED1 = #'ErrorDescriptor'{errorCode = EC1,
+ errorText = ET1},
+ throw({error, {invalid_ActionRequest, AR}, {discard_ack, ED1}})
+ end,
+
+ Cmd =
+ case CR of
+ #'CommandRequest'{command = Command} ->
+ Command;
+ _ ->
+ ET2 = lists:flatten(
+ io_lib:format("Invalid command request: ~w", [CR])),
+ EC2 = ?megaco_internal_gateway_error,
+ ED2 = #'ErrorDescriptor'{errorCode = EC2,
+ errorText = ET2},
+ throw({error, {invalid_CommandRequest, CR}, {discard_ack, ED2}})
+ end,
+
+ case Cmd of
+ {notifyReq, NotifyReq} ->
+ ET3 = "Unexpected request",
+ EC3 = ?megaco_transaction_req_received_before_servicechange_reply,
+ ED3 = #'ErrorDescriptor'{errorCode = EC3,
+ errorText = ET3},
+ throw({ok, {ok, NotifyReq}, {discard_ack, ED3}});
+ _ ->
+ ET4 = lists:flatten(
+ io_lib:format("Invalid command: ~w", [Cmd])),
+ EC4 = ?megaco_internal_gateway_error,
+ ED4 = #'ErrorDescriptor'{errorCode = EC4,
+ errorText = ET4},
+ throw({error, {invalid_command, Cmd}, {discard_ack, ED4}})
+ end;
+otp_6275_mg_verify_notify_req({Tag, CH, Version, ARs}) ->
+ io:format("otp_6275_mg_verify_notify_req -> ok"
+ "~n Tag: ~p"
+ "~n CH: ~p"
+ "~n Version: ~p"
+ "~n ARs: ~p"
+ "~n", [Tag, CH, Version, ARs]),
+ {error, {invalid_event, {Tag, CH, Version, ARs}}, ok};
+otp_6275_mg_verify_notify_req(Else) ->
+ io:format("otp_6275_mg_verify_notify_req -> unknown"
+ "~n Else: ~p~n", [Else]),
+ {error, Else, ok}.
+
+
+-ifndef(megaco_hipe_special).
+otp_6275_mg_verify_handle_trans_rep_fun() ->
+ fun(Event) ->
+ (catch otp_6275_mg_verify_handle_trans_rep(Event))
+ end.
+-endif.
+
+otp_6275_mg_verify_handle_trans_rep(
+ {handle_trans_reply, CH, ?VERSION, {error, timeout} = Error, _}) ->
+ io:format("otp_6275_mg_verify_trans_rep -> expected error"
+ "~n", []),
+ case CH of
+ #megaco_conn_handle{remote_mid = preliminary_mid} ->
+ {ok, Error, error};
+ _ ->
+ {error, {unexpected_connection, CH}, error}
+ end;
+otp_6275_mg_verify_handle_trans_rep(
+ {handle_trans_reply, _CH, ?VERSION, Error, _}) ->
+ io:format("otp_6275_mg_verify_handle_trans_rep -> unexpected error"
+ "~n Error: ~p"
+ "~n", [Error]),
+ {error, Error, error};
+otp_6275_mg_verify_handle_trans_rep(Else) ->
+ io:format("otp_6275_mg_verify_handle_trans_rep -> unknown"
+ "~n Else: ~p~n", [Else]),
+ {error, Else, error}.
+
+otp_6275_mg_service_change_request_ar(_Mid, Cid) ->
+ Prof = cre_serviceChangeProf("resgw", 1),
+ SCP = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = cre_serviceChangeReq([Root], SCP),
+ CMD = cre_command(SCR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+
+%%
+%% MGC generator stuff
+%%
+-ifdef(megaco_hipe_special).
+-define(otp_6275_mgc_decode_msg_fun(Mod, Conf),
+ {?MODULE, decode_msg, [Mod, Conf]}).
+-define(otp_6275_mgc_encode_msg_fun(Mod, Conf),
+ {?MODULE, encode_msg, [Mod, Conf]}).
+-define(otp_6275_mgc_verify_service_change_req_msg_fun(),
+ {?MODULE, otp_6275_mgc_verify_service_change_req_msg, []}).
+-define(otp_6275_mgc_verify_notify_rep_msg_fun(),
+ {?MODULE, otp_6275_mgc_verify_notify_rep_msg, []}).
+-else.
+-define(otp_6275_mgc_decode_msg_fun(Mod, Conf),
+ otp_6275_mgc_decode_msg_fun(Mod, Conf)).
+-define(otp_6275_mgc_encode_msg_fun(Mod, Conf),
+ otp_6275_mgc_encode_msg_fun(Mod, Conf)).
+-define(otp_6275_mgc_verify_service_change_req_msg_fun(),
+ otp_6275_mgc_verify_service_change_req_msg_fun()).
+-define(otp_6275_mgc_verify_notify_rep_msg_fun(),
+ otp_6275_mgc_verify_notify_rep_msg_fun()).
+-endif.
+
+otp_6275_mgc_event_sequence(text, tcp) ->
+ DecodeFun = ?otp_6275_mgc_decode_msg_fun(megaco_pretty_text_encoder, []),
+ EncodeFun = ?otp_6275_mgc_encode_msg_fun(megaco_pretty_text_encoder, []),
+ Mid = {deviceName,"ctrl"},
+ TermId = #megaco_term_id{id = ["00000000","00000000","01101101"]},
+ NotifyReq = otp_6275_mgc_notify_request_msg(Mid, 2, 1, TermId, 1),
+ SCRVerifyFun = ?otp_6275_mgc_verify_service_change_req_msg_fun(),
+ NotifyReplyVerifyFun = ?otp_6275_mgc_verify_notify_rep_msg_fun(),
+%% SCRVerifyFun = otp_6275_mgc_verify_service_change_req_fun(),
+%% NotifyReplyVerifyFun = otp_6275_mgc_verify_notify_reply_fun(),
+ MgcEvSeq =
+ [{debug, true},
+ {decode, DecodeFun},
+ {encode, EncodeFun},
+ {listen, 2944},
+
+ {expect_accept, any},
+ {expect_receive, "service-change-request", {SCRVerifyFun, 5000}},
+ {sleep, 1000}, %% Do _not_ send SC reply
+ {send, "notify-request", NotifyReq},
+ {expect_receive, "request before sc reply", {NotifyReplyVerifyFun, 5000}},
+ {sleep, 2000}
+ ],
+ MgcEvSeq.
+
+-ifndef(megaco_hipe_special).
+otp_6275_mgc_encode_msg_fun(Mod, Conf) ->
+ fun(M) ->
+ encode_msg(M, Mod, Conf)
+ end.
+-endif.
+
+%% otp_6275_mgc_encode_msg_fun(Mod, Conf, Ver) ->
+%% fun(M) ->
+%% encode_msg(M, Mod, Conf, Ver)
+%% end.
+
+-ifndef(megaco_hipe_special).
+otp_6275_mgc_decode_msg_fun(Mod, Conf) ->
+ fun(M) ->
+ decode_msg(M, Mod, Conf)
+ end.
+-endif.
+
+%% otp_6275_mgc_decode_msg_fun(Mod, Conf, Ver) ->
+%% fun(M) ->
+%% decode_msg(M, Mod, Conf, Ver)
+%% end.
+
+-ifndef(megaco_hipe_special).
+otp_6275_mgc_verify_service_change_req_msg_fun() ->
+ fun(M) ->
+ (catch otp_6275_mgc_verify_service_change_req_msg(M))
+ end.
+-endif.
+
+otp_6275_mgc_verify_service_change_req_msg(
+ #'MegacoMessage'{mess = Mess} = M) ->
+ io:format("otp_6275_mgc_verify_service_change_req_msg -> entry with"
+ "~n M: ~p"
+ "~n", [M]),
+ Body =
+ case Mess of
+ #'Message'{messageBody = MB} ->
+ MB;
+ _ ->
+ throw({error, {invalid_mess, Mess}})
+ end,
+
+ Trans =
+ case Body of
+ {transactions, [Transaction]} ->
+ Transaction;
+ _ ->
+ throw({error, {invalid_messageBody, Body}})
+ end,
+
+ TR =
+ case Trans of
+ {transactionRequest, TransReq} ->
+ TransReq;
+ _ ->
+ throw({error, {invalid_transaction, Trans}})
+ end,
+
+ AR =
+ case TR of
+ #'TransactionRequest'{actions = [ActionReq]} ->
+ ActionReq;
+ _ ->
+ throw({error, {invalid_transactionRequest, TR}})
+ end,
+
+ CR =
+ case AR of
+ #'ActionRequest'{commandRequests = [CmdReq]} ->
+ CmdReq;
+ _ ->
+ throw({error, {invalid_TransactionRequest, AR}})
+ end,
+
+ Cmd =
+ case CR of
+ #'CommandRequest'{command = Command} ->
+ Command;
+ _ ->
+ throw({error, {invalid_ActionRequest, CR}})
+ end,
+
+ SCR =
+ case Cmd of
+ {serviceChangeReq, ServiceChangeReq} ->
+ ServiceChangeReq;
+ _ ->
+ throw({error, {invalid_command, Cmd}})
+ end,
+
+ SCP =
+ case SCR of
+ #'ServiceChangeRequest'{serviceChangeParms = ServiceChangeParms} ->
+ ServiceChangeParms;
+ _ ->
+ throw({error, {invalid_serviceChangeReq, SCR}})
+ end,
+
+ case SCP of
+ #'ServiceChangeParm'{serviceChangeMethod = restart,
+ serviceChangeReason = [[$9,$0,$1|_]]} ->
+ {ok, M};
+ _ ->
+ {error, {invalid_serviceChangeParms, SCP}}
+ end;
+otp_6275_mgc_verify_service_change_req_msg(Crap) ->
+ {error, {invalid_MegacoMessage, Crap}}.
+
+-ifndef(megaco_hipe_special).
+otp_6275_mgc_verify_notify_rep_msg_fun() ->
+ fun(M) ->
+ (catch otp_6275_mgc_verify_notify_rep_msg(M))
+ end.
+-endif.
+
+otp_6275_mgc_verify_notify_rep_msg(#'MegacoMessage'{mess = Mess} = M) ->
+ io:format("otp_6275_mgc_verify_notify_rep_msg -> entry with"
+ "~n M: ~p"
+ "~n", [M]),
+ Body =
+ case Mess of
+ #'Message'{messageBody = MB} ->
+ MB;
+ _ ->
+ throw({error, {invalid_mess, Mess}})
+ end,
+
+ Trans =
+ case Body of
+ {transactions, [Transaction]} ->
+ Transaction;
+ _ ->
+ throw({error, {invalid_messageBody, Body}})
+ end,
+
+ TR =
+ case Trans of
+ {transactionReply, TransReply} ->
+ TransReply;
+ _ ->
+ throw({error, {invalid_transaction, Trans}})
+ end,
+
+ Res =
+ case TR of
+ #'TransactionReply'{transactionResult = TransRes} ->
+ TransRes;
+ _ ->
+ throw({error, {invalid_transactionReply, TR}})
+ end,
+
+ ED =
+ case Res of
+ {transactionError, ErrorDesc} ->
+ ErrorDesc;
+ _ ->
+ throw({error, {invalid_TransactionReply, Res}})
+ end,
+
+ case ED of
+ #'ErrorDescriptor'{errorCode = ?megaco_transaction_req_received_before_servicechange_reply} ->
+ ok;
+ _ ->
+ throw({error, {invalid_transactionError, ED}})
+ end,
+ {ok, M};
+otp_6275_mgc_verify_notify_rep_msg(Crap) ->
+ {error, {invalid_MegacoMessage, Crap}}.
+
+
+otp_6275_mgc_notify_request_ar(Rid, Tid, Cid) ->
+ TT = cre_timeNotation("19990729", "22000000"),
+ Ev = cre_obsEvent("al/of", TT),
+ EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
+ NR = cre_notifyReq([Tid], EvsDesc),
+ CMD = cre_command(NR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+otp_6275_mgc_notify_request_msg(Mid, TransId, Cid, TermId, Rid) ->
+ AR = otp_6275_mgc_notify_request_ar(Rid, TermId, Cid),
+ otp_6275_msg(Mid, TransId, AR).
+
+
+%% --
+
+otp_6275_msg(Mid, TransId, AR) ->
+ TR = cre_transReq(TransId, [AR]),
+ Trans = cre_transaction(TR),
+ Mess = cre_message(1, Mid, cre_transactions([Trans])),
+ cre_megacoMessage(Mess).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% This test case can only be run with the stack compiled with
+%% the MEGACO_TEST_CODE flag. Therefor there is no point in
+%% including this test case in the usual test suite
+-ifdef(MEGACO_TEST_CODE).
+otp_6276(suite) ->
+ [];
+otp_6276(doc) ->
+ "OTP-6276: Cancel when receiving reply raise condition";
+otp_6276(Config) when is_list(Config) ->
+ put(verbosity, ?TEST_VERBOSITY),
+ put(sname, "TEST"),
+ put(tc, otp_6276),
+ i("starting"),
+
+ d("create sequence controller"),
+ CtrlPid = otp_6276_sequence_controller_start(),
+
+ MgcNode = make_node_name(mgc),
+ MgNode = make_node_name(mg),
+ d("start nodes: "
+ "~n MgcNode: ~p"
+ "~n MgNode: ~p",
+ [MgcNode, MgNode]),
+ ok = megaco_test_lib:start_nodes([MgcNode, MgNode], ?FILE, ?LINE),
+
+ d("[MGC] start the simulator "),
+ {ok, Mgc} = megaco_test_tcp_generator:start_link("MGC", MgcNode),
+
+ d("[MGC] create the event sequence"),
+ MgcEvSeq = otp_6276_mgc_event_sequence(text, tcp, CtrlPid),
+
+ i("wait some time before starting the MGC simulation"),
+ sleep(1000),
+
+ d("[MGC] start the tcp-simulation"),
+ {ok, MgcId} = megaco_test_tcp_generator:exec(Mgc, MgcEvSeq),
+
+ i("wait some time before starting the MG simulator"),
+ sleep(1000),
+
+ d("[MG] start the simulator (generator)"),
+ {ok, Mg} = megaco_test_megaco_generator:start_link("MG", MgNode),
+
+ d("send start order to sequence controller"),
+ CtrlPid ! {start, self(), Mgc, Mg},
+
+ d("[MG] create the event sequence"),
+ MgEvSeq = otp_6276_mg_event_sequence(text, tcp, CtrlPid),
+
+ i("wait some time before starting the MG simulation"),
+ sleep(1000),
+
+ d("[MG] start the megaco-simulation"),
+ {ok, MgId} = megaco_test_megaco_generator:exec(Mg, MgEvSeq),
+
+ d("await the generator reply(s)"),
+ await_completion([MgcId, MgId]),
+
+ %% Tell Mgc to stop
+ i("[MGC] stop generator"),
+ megaco_test_tcp_generator:stop(Mgc),
+
+ %% Tell Mg to stop
+ i("[MG] stop generator"),
+ megaco_test_megaco_generator:stop(Mg),
+
+ i("done", []),
+ ok.
+
+
+otp_6276_sequence_controller_start() ->
+ Self = self(),
+ erlang:spawn(fun() -> otp_6276_sequence_controller(Self) end).
+
+otp_6276_sequence_controller(Parent) ->
+ io:format("otp_6276_sequence_controller -> entry with"
+ "~n Parent: ~p"
+ "~n self(): ~p"
+ "~n", [Parent, self()]),
+
+ d("start tc controller"),
+ put(dbg,true),
+ ok = megaco_tc_controller:start_link(),
+
+
+ %% Await MGC announcement
+ Mgc =
+ receive
+ {announce_mgc, MgcPid} ->
+ MgcPid
+ end,
+ io:format("otp_6276_sequence_controller -> MGC announced: "
+ "~n Mgc: ~p"
+ "~n", [Mgc]),
+
+ %% Await MG announcement
+ Mg =
+ receive
+ {announce_mg, MgPid} ->
+ MgPid
+ end,
+ io:format("otp_6276_sequence_controller -> MG announced: "
+ "~n Mg: ~p"
+ "~n", [Mg]),
+
+ %% Await request_received notification
+ receive
+ {notify_request_received, Mgc} ->
+ io:format("otp_6276_sequence_controller -> "
+ "request received from MGC (~p)"
+ "~n", [Mgc]),
+ ok
+ end,
+
+ %% Make sure the cancel operation gets blocked midway:
+ megaco_tc_controller:insert(block_on_cancel, {cancel_block, self()}),
+
+ %% Send start cancel order
+ io:format("otp_6276_sequence_controller -> "
+ "send cancel start order to MG (~p)"
+ "~n", [Mg]),
+ Mg ! {start_cancel, self()},
+ receive
+ {started_cancel, Mg} ->
+ ok
+ end,
+ io:format("otp_6276_sequence_controller -> "
+ "cancel started - now await blocked"
+ "~n", []),
+
+ receive
+ {cancel_block, Mg} ->
+ ok
+ end,
+ io:format("otp_6276_sequence_controller -> "
+ "cancel blocked - now instruct MGC to send notify reply"
+ "~n", []),
+
+ %% Make sure the cancel operation gets blocked midway:
+ megaco_tc_controller:insert(block_on_reply, {reply_block, self()}),
+
+ %% Send NR-send order
+ Mgc ! {notify_reply_send, self()},
+ io:format("otp_6276_sequence_controller -> "
+ "NR-send order sent - now await notify reply blocked received"
+ "~n", []),
+
+ ReplyPid =
+ receive
+ {reply_block, Pid, true} ->
+ io:format("otp_6276_sequence_controller -> "
+ "notify reply blocked received from ~p (true) - "
+ "now unblock cancel"
+ "~n", [Pid]),
+ %% Pid ! {reply_block, self()},
+ Pid;
+ {reply_block, Pid, Info} ->
+ io:format("otp_6276_sequence_controller -> "
+ "notify reply blocked received from ~p: ~p"
+ "~n", [Pid, Info]),
+ Pid ! {reply_block, self()},
+ exit({unexpected_reply_block_info, Info})
+ end,
+
+ %% Send cancel continue (unblock) order
+ Mg ! {cancel_block, self()},
+ io:format("otp_6276_sequence_controller -> "
+ "cancel unblocked - now await notify-request cancelled"
+ "~n", []),
+
+ %% Await request cancelled
+ receive
+ {notify_request_cancelled, Mg} ->
+ ok;
+ {notify_request_cancelled, Pid} ->
+ io:format("otp_6276_sequence_controller -> "
+ "notify-request cancelled - from ~p"
+ "~n", [Pid]),
+ ok
+ end,
+ io:format("otp_6276_sequence_controller -> "
+ "notify-request cancelled - now unblock notify-reply"
+ "~n", []),
+
+ %% await notify reply result
+ ReplyPid ! {reply_block, self()},
+ io:format("otp_6276_sequence_controller -> "
+ "notify-reply unblocked - now await unexpected trans"
+ "~n", []),
+
+ %% Await unexpected trans
+ receive
+ {unexpected_trans, Mg, _Trans} ->
+ ok;
+ {unexpected_trans, Pid, _Trans} ->
+ io:format("otp_6276_sequence_controller -> "
+ "unexpected_trans - from ~p"
+ "~n", [Pid]),
+ ok
+ end,
+ io:format("otp_6276_sequence_controller -> "
+ "unexpected transaction received"
+ "~n", []),
+
+ %% Await unexpected trans
+ Mgc ! {done, self()},
+ receive
+ {done, Mgc} ->
+ ok
+ end,
+ io:format("otp_6276_sequence_controller -> MGC instructed we are done"
+ "~n", []),
+
+ d("stop tc controller"),
+ megaco_tc_controller:stop(),
+
+ io:format("otp_6276_sequence_controller -> done~n", []),
+
+ exit(normal).
+
+
+%%
+%% MGC generator stuff
+%%
+otp_6276_mgc_event_sequence(text, tcp, Ctrl) ->
+ Mid = {deviceName,"ctrl"},
+ EM = megaco_pretty_text_encoder,
+ EC = [],
+ otp_6276_mgc_event_sequence2(Mid, EM, EC, Ctrl).
+
+otp_6276_mgc_event_sequence2(Mid, EM, EC, Ctrl) ->
+ DecodeFun = otp_6276_mgc_decode_msg_fun(EM, EC),
+ EncodeFun = otp_6276_mgc_encode_msg_fun(EM, EC),
+ AnnounceMe = otp_6276_mgc_announce_fun(Ctrl),
+ ServiceChangeReqVerify =
+ otp_6276_mgc_verify_service_change_req_fun(Mid),
+ ServiceChangeReply =
+ otp_6276_mgc_service_change_reply_msg(Mid, 1, 0),
+ NotifyReqVerify = otp_6276_mgc_verify_notify_request_fun(Ctrl),
+ TermId = #megaco_term_id{id = ["00000000","00000000","01101101"]},
+ AwaitNrSendOrder = otp_6276_mgc_await_notify_reply_send_order_fun(Ctrl),
+ NotifyReply = otp_6276_mgc_notify_reply_msg(Mid, 2, 0, TermId),
+ AwaitDoneOrder = otp_6276_mgc_await_done_order_fun(Ctrl),
+ EvSeq =
+ [
+ {trigger, AnnounceMe},
+ {debug, true},
+ {decode, DecodeFun},
+ {encode, EncodeFun},
+ {listen, 2944},
+ {expect_accept, any},
+ {expect_receive, "service-change-req",
+ {ServiceChangeReqVerify, 10000}},
+ {send, "service-change-reply", ServiceChangeReply},
+ {expect_receive, "notify-request", {NotifyReqVerify, 5000}},
+
+ {trigger, AwaitNrSendOrder},
+
+ {send, "notify-reply", NotifyReply},
+
+ {trigger, AwaitDoneOrder},
+
+ disconnect
+ ],
+ EvSeq.
+
+otp_6276_mgc_announce_fun(Pid) ->
+ fun() ->
+ Pid ! {announce_mgc, self()}
+ end.
+
+otp_6276_mgc_await_notify_reply_send_order_fun(Pid) ->
+ fun() ->
+ receive
+ {notify_reply_send, Pid} ->
+ Pid ! {notify_reply_send, self()}
+ end
+ end.
+
+otp_6276_mgc_await_done_order_fun(Pid) ->
+ fun() ->
+ receive
+ {done, Pid} ->
+ Pid ! {done, self()}
+ end
+ end.
+
+otp_6276_mgc_encode_msg_fun(Mod, Conf) ->
+ fun(M) ->
+ Mod:encode_message(Conf, M)
+ end.
+
+otp_6276_mgc_decode_msg_fun(Mod, Conf) ->
+ fun(M) ->
+ Mod:decode_message(Conf, M)
+ end.
+
+otp_6276_mgc_service_change_reply_msg(Mid, TransId, Cid) ->
+ SCRP = #'ServiceChangeResParm'{serviceChangeMgcId = Mid},
+ SCRPs = {serviceChangeResParms,SCRP},
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = #'ServiceChangeReply'{terminationID = [Root],
+ serviceChangeResult = SCRPs},
+ CR = {serviceChangeReply, SCR},
+ otp_6276_mgc_msg(Mid, TransId, CR, Cid).
+
+otp_6276_mgc_notify_reply_msg(Mid, TransId, Cid, TermId) ->
+ NR = #'NotifyReply'{terminationID = [TermId]},
+ CR = {notifyReply, NR},
+ otp_6276_mgc_msg(Mid, TransId, CR, Cid).
+
+otp_6276_mgc_msg(Mid, TransId, CR, Cid) ->
+ AR = #'ActionReply'{contextId = Cid,
+ commandReply = [CR]},
+ ARs = {actionReplies, [AR]},
+ TR = #'TransactionReply'{transactionId = TransId,
+ transactionResult = ARs},
+ Body = {transactions, [{transactionReply, TR}]},
+ Mess = #'Message'{version = 1,
+ mId = Mid,
+ messageBody = Body},
+ #'MegacoMessage'{mess = Mess}.
+
+otp_6276_mgc_pending_msg(Mid, TransId) ->
+ TP = #'TransactionPending'{transactionId = TransId},
+ Body = {transactions, [{transactionPending, TP}]},
+ Mess = #'Message'{version = 1,
+ mId = Mid,
+ messageBody = Body},
+ #'MegacoMessage'{mess = Mess}.
+
+otp_6276_mgc_verify_service_change_req_fun(_) ->
+ fun(#'MegacoMessage'{mess = Mess} = M) ->
+ #'Message'{version = _V,
+ mId = _Mid,
+ messageBody = Body} = Mess,
+ {transactions, [Trans]} = Body,
+ {transactionRequest, TR} = Trans,
+ #'TransactionRequest'{transactionId = _Tid,
+ actions = [AR]} = TR,
+ #'ActionRequest'{contextId = _Cid,
+ contextRequest = _CtxReq,
+ contextAttrAuditReq = _CtxAar,
+ commandRequests = [CR]} = AR,
+ #'CommandRequest'{command = Cmd,
+ optional = _Opt,
+ wildcardReturn = _WR} = CR,
+ {serviceChangeReq, SCR} = Cmd,
+ #'ServiceChangeRequest'{terminationID = _TermID,
+ serviceChangeParms = SCP} = SCR,
+ #'ServiceChangeParm'{serviceChangeMethod = restart,
+ serviceChangeReason = [[$9,$0,$1|_]]} = SCP,
+ {ok, M};
+ (M) ->
+ {error, {invalid_message, M}}
+ end.
+
+otp_6276_mgc_verify_notify_request_fun(Pid) ->
+ fun(M) ->
+ (catch otp_6276_mgc_verify_notify_request(M, Pid))
+ end.
+
+otp_6276_mgc_verify_notify_request(#'MegacoMessage'{mess = Mess} = M,
+ Pid) ->
+ io:format("otp_6276_mgc_verify_notify_request -> entry with"
+ "~n M: ~p"
+ "~n", [M]),
+ Body =
+ case Mess of
+ #'Message'{messageBody = MessageBody} ->
+ MessageBody;
+ _ ->
+ throw({error, {invalid_mess, Mess}})
+ end,
+
+ Trans =
+ case Body of
+ {transactions, [Transaction]} ->
+ Transaction;
+ _ ->
+ throw({error, {invalid_messageBody, Body}})
+ end,
+
+ TR =
+ case Trans of
+ {transactionRequest, TransReq} ->
+ TransReq;
+ _ ->
+ throw({error, {invalid_transaction, Trans}})
+ end,
+
+ AR =
+ case TR of
+ #'TransactionRequest'{actions = [Action]} ->
+ Action;
+ _ ->
+ throw({error, {invalid_transactionRequest, TR}})
+ end,
+
+ io:format("otp_6276_mgc_verify_notify_request -> "
+ "~n AR: ~p"
+ "~n", [AR]),
+
+ CR =
+ case AR of
+ #'ActionRequest'{commandRequests = [CommandReq]} ->
+ CommandReq;
+ _ ->
+ throw({error, {invalid_TransactionRequest, AR}})
+ end,
+
+ Cmd =
+ case CR of
+ #'CommandRequest'{command = Command} ->
+ Command;
+ _ ->
+ throw({error, {invalid_ActionRequest, CR}})
+ end,
+
+ NR =
+ case Cmd of
+ {notifyReq, NotifReq} ->
+ NotifReq;
+ _ ->
+ throw({error, {invalid_CommandRequest, Cmd}})
+ end,
+
+ OED =
+ case NR of
+ #'NotifyRequest'{observedEventsDescriptor = ObsEvDesc} ->
+ ObsEvDesc;
+ _ ->
+ throw({error, {invalid_notifyReq, NR}})
+ end,
+
+ OE =
+ case OED of
+ #'ObservedEventsDescriptor'{observedEventLst = [ObsEv]} ->
+ ObsEv;
+ _ ->
+ throw({error, {invalid_NotifyRequest, OED}})
+ end,
+
+ case OE of
+ #'ObservedEvent'{eventName = "al/of"} ->
+ ok;
+ _ ->
+ throw({error, {invalid_ObservedEventsDescriptor, OE}})
+ end,
+ io:format("otp_6276_mgc_verify_notify_request -> "
+ "send notify_request received to "
+ "~n Pid: ~p"
+ "~n self(): ~p"
+ "~n", [Pid, self()]),
+ Pid ! {notify_request_received, self()},
+ {ok, M};
+otp_6276_mgc_verify_notify_request(M, _Pid) ->
+ {error, {invalid_message, M}}.
+
+
+%%
+%% MG generator stuff
+%%
+otp_6276_mg_event_sequence(text, tcp, Ctrl) ->
+ Mid = {deviceName,"mg"},
+ RI = [
+ {port, 2944},
+ {encoding_module, megaco_pretty_text_encoder},
+ {encoding_config, []},
+ {transport_module, megaco_tcp}
+ ],
+ otp_6276_mg_event_sequence2(Mid, RI, Ctrl).
+
+otp_6276_mg_event_sequence2(Mid, RI, Ctrl) ->
+ AnnounceMe = otp_6276_mg_announce_fun(Ctrl),
+ ServiceChangeReq = [otp_6276_mg_service_change_request_ar(Mid, 1)],
+ ConnectVerify = fun otp_6276_mg_verify_handle_connect/1,
+ ServiceChangeReplyVerify =
+ fun otp_6276_mg_verify_service_change_reply/1,
+ Tid = #megaco_term_id{id = ["00000000","00000000","01101101"]},
+ NotifyReq = [otp_6276_mg_notify_request_ar(1, Tid, 1)],
+ AwaitCancelOrder = otp_6276_mg_await_cancel_order_fun(Ctrl),
+ TransReplyVerify = otp_6276_mg_verify_trans_reply_fun(Ctrl),
+ UnexpTransVerify = otp_6276_mg_verify_unexpected_trans_fun(Ctrl),
+ EvSeq = [
+ {trigger, AnnounceMe},
+ {debug, true},
+ megaco_start,
+ {megaco_start_user, Mid, RI, []},
+ {megaco_update_user_info, recv_pending_limit, 4},
+ start_transport,
+ {megaco_trace, disable}, %%100},
+ {megaco_system_info, users},
+ {megaco_system_info, connections},
+ connect,
+ {megaco_callback, handle_connect, ConnectVerify},
+ megaco_connect,
+ {megaco_cast, ServiceChangeReq, []},
+ {megaco_callback, handle_connect, ConnectVerify},
+ {megaco_callback, handle_trans_reply, ServiceChangeReplyVerify},
+ {sleep, 1000},
+ {megaco_cast, NotifyReq, []},
+
+ {trigger, AwaitCancelOrder},
+
+ {megaco_cancel, otp_6276},
+
+ {megaco_callback, handle_trans_reply, TransReplyVerify},
+ {megaco_callback, handle_unexpected_trans, UnexpTransVerify},
+ {sleep, 1000},
+ megaco_stop_user,
+ megaco_stop,
+ {sleep, 1000}
+ ],
+ EvSeq.
+
+otp_6276_mg_announce_fun(Pid) ->
+ fun() ->
+ Pid ! {announce_mg, self()}
+ end.
+
+otp_6276_mg_await_cancel_order_fun(Pid) ->
+ fun() ->
+ io:format("otp_6276_mg_await_cancel_order_fun -> entry with"
+ "~n Pid: ~p"
+ "~n self(): ~p"
+ "~n", [Pid, self()]),
+ receive
+ {start_cancel, Pid} ->
+ io:format("otp_6276_mg_await_cancel_order_fun -> "
+ "received cancel start order"
+ "~n Pid: ~p"
+ "~n self(): ~p"
+ "~n", [Pid, self()]),
+ Pid ! {started_cancel, self()}
+ end
+ end.
+
+otp_6276_mg_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
+ io:format("otp_6276_mg_verify_handle_connect -> ok"
+ "~n CH: ~p~n", [CH]),
+ {ok, CH, ok};
+otp_6276_mg_verify_handle_connect(Else) ->
+ io:format("otp_6276_mg_verify_handle_connect -> unknown"
+ "~n Else: ~p~n", [Else]),
+ {error, Else, ok}.
+
+otp_6276_mg_verify_service_change_reply({handle_trans_reply, _CH,
+ ?VERSION,
+ {ok, [AR]}, _}) ->
+ io:format("otp_6276_mg_verify_service_change_reply -> ok"
+ "~n AR: ~p~n", [AR]),
+ case AR of
+ #'ActionReply'{commandReply = [SCR]} ->
+ case SCR of
+ {serviceChangeReply,
+ #'ServiceChangeReply'{terminationID = [Tid],
+ serviceChangeResult = Res}} ->
+ case Tid of
+ #megaco_term_id{contains_wildcards = false,
+ id = ["root"]} ->
+ case Res of
+ {serviceChangeResParms,
+ #'ServiceChangeResParm'{
+ serviceChangeMgcId = _RemoteMid}} ->
+ {ok, AR, ok};
+ {Tag, Val} ->
+ Err = {invalid_service_change_result,
+ Tag, Val},
+ {error, Err, ok}
+ end;
+ _ ->
+ Err = {invalid_termination_id, Tid},
+ {error, Err, ok}
+ end;
+ {Tag, Val} ->
+ Err = {invalid_command_reply, Tag, Val},
+ {error, Err, ok}
+ end;
+ _ ->
+ Err = {invalid_action_reply, AR},
+ {error, Err, ok}
+ end;
+otp_6276_mg_verify_service_change_reply(Else) ->
+ io:format("otp_6276_mg_verify_service_change_reply -> unknown"
+ "~n Else: ~p~n", [Else]),
+ {error, Else, ok}.
+
+otp_6276_mg_verify_trans_reply_fun(Pid) ->
+ fun(Event) ->
+ otp_6276_mg_verify_trans_reply(Pid, Event)
+ end.
+
+otp_6276_mg_verify_trans_reply(Pid,
+ {handle_trans_reply, _CH, ?VERSION,
+ {error, {user_cancel, otp_6276}} = E, _}) ->
+ io:format("otp_6276_mg_verify_trans_reply -> expected error"
+ "~n", []),
+ Pid ! {notify_request_cancelled, self()},
+ {ok, E, error};
+otp_6276_mg_verify_trans_reply(_Pid,
+ {handle_trans_reply, _CH, ?VERSION,
+ {error, Reason} = E, _}) ->
+ io:format("otp_6276_mg_verify_trans_reply -> unexpected error"
+ "~n Reason: ~p"
+ "~n", [Reason]),
+ {error, E, error};
+otp_6276_mg_verify_trans_reply(_Pid,
+ {handle_trans_reply, _CH, ?VERSION, Result, _}) ->
+ io:format("otp_6276_mg_verify_trans_reply -> unexpected result"
+ "~n Result: ~p"
+ "~n", [Result]),
+ {error, Result, error};
+otp_6276_mg_verify_trans_reply(_Pid, Else) ->
+ io:format("otp_6276_mg_verify_trans_reply -> unknown event"
+ "~n Else: ~p"
+ "~n", [Else]),
+ {error, Else, error}.
+
+otp_6276_mg_verify_unexpected_trans_fun(Pid) ->
+ fun(Event) ->
+ otp_6276_mg_verify_unexpected_trans(Pid, Event)
+ end.
+
+otp_6276_mg_verify_unexpected_trans(Pid,
+ {handle_unexpected_trans, RH, ?VERSION, Trans}) ->
+ io:format("otp_6276_mg_verify_unexpected_trans -> expected event"
+ "~n RH: ~p"
+ "~n Trans: ~p"
+ "~n", [RH, Trans]),
+ Pid ! {unexpected_trans, self(), Trans},
+ {ok, Trans, error};
+otp_6276_mg_verify_unexpected_trans(_Pid, Else) ->
+ io:format("otp_6276_mg_verify_unexpected_trans -> unknown event"
+ "~n Else: ~p"
+ "~n", [Else]),
+ {error, Else, error}.
+
+otp_6276_mg_service_change_request_ar(_Mid, Cid) ->
+ Prof = cre_serviceChangeProf("resgw", 1),
+ SCP = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = cre_serviceChangeReq([Root], SCP),
+ CMD = cre_command(SCR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+otp_6276_mg_notify_request_ar(Rid, Tid, Cid) ->
+ TT = cre_timeNotation("19990729", "22000000"),
+ Ev = cre_obsEvent("al/of", TT),
+ EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
+ NR = cre_notifyReq([Tid], EvsDesc),
+ CMD = cre_command(NR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+
+-else. % -ifdef(MEGACO_TEST_CODE).
+
+otp_6276(suite) ->
+ [];
+otp_6276(doc) ->
+ "OTP-6276";
+otp_6276(Config) when is_list(Config) ->
+
+ ?SKIP("included only if compiled with USE_MEGACO_TEST_CODE=true").
+
+-endif. % -ifdef(MEGACO_TEST_CODE).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+otp_6442_resend_request1(suite) ->
+ [];
+otp_6442_resend_request1(Config) when is_list(Config) ->
+ put(verbosity, debug),
+ put(sname, "TEST"),
+ put(tc, otp6442rreq1),
+ i("starting"),
+
+ MgNode = make_node_name(mg),
+ d("start (MG) node: ~p", [MgNode]),
+ ok = megaco_test_lib:start_nodes([MgNode], ?FILE, ?LINE),
+
+ d("[MG] start the simulator "),
+ {ok, Mg} = megaco_test_megaco_generator:start_link("MG", MgNode),
+
+ d("[MG] create the event sequence"),
+ MgMid = {deviceName,"mg"},
+ MgEvSeq = otp_6442_resend_request1_mg_event_sequence(MgMid),
+
+ i("wait some time before starting the MG simulation"),
+ sleep(1000),
+
+ d("[MG] start the simulation"),
+ {ok, MgId} = megaco_test_megaco_generator:exec(Mg, MgEvSeq),
+
+ i("await the transport module service change send_message event"),
+ Pid = otp_6442_expect(fun otp_6442_rsrq1_verify_scr_msg/1, 5000),
+
+ i("wait some before issuing the service change reply"),
+ sleep(500),
+
+ i("send the service change reply"),
+ MgcMid = {deviceName,"mgc"},
+ ServiceChangeReply = otp_6442_mgc_service_change_reply_msg(MgcMid, 1, 1),
+ megaco_test_generic_transport:incomming_message(Pid, ServiceChangeReply),
+
+ i("await the transport module "
+ "notify-request send_message event from MG: "
+ "ignore"),
+ ok = otp_6442_expect(fun otp_6442_rsrq1_verify_first_nr_msg/1, 5000),
+
+ i("await the transport module "
+ "notify-request resend_message event from MG: "
+ "reply"),
+ {TransId2, Cid2, TermId2} =
+ otp_6442_expect(fun otp_6442_rsrq1_verify_second_nr_msg/1, 10000),
+
+ i("wait some before issuing the notify reply"),
+ sleep(500),
+
+ i("send the notify reply"),
+ NotifyReply =
+ otp_6442_mgc_notify_reply_msg(MgcMid, TransId2, Cid2, TermId2),
+ megaco_test_generic_transport:incomming_message(Pid, NotifyReply),
+
+ d("await the generator reply"),
+ await_completion([MgId]),
+
+ %% Tell Mg to stop
+ i("[MG] stop generator"),
+ megaco_test_megaco_generator:stop(Mg),
+
+ i("done", []),
+ ok.
+
+
+otp_6442_expect(Verify, Timeout) when (Timeout > 0) ->
+ T = mtime(),
+ receive
+ Msg ->
+ case (catch Verify(Msg)) of
+ {ok, Result} ->
+ d("verified after ~p msec", [mtime() - T]),
+ Result;
+ skip ->
+ otp_6442_expect(Verify, to(Timeout, T));
+ {error, Reason} ->
+ exit({verification_failed, Reason})
+ end
+ after Timeout ->
+ exit(timeout)
+ end;
+otp_6442_expect(_, _Timeout) ->
+ exit(timeout).
+
+otp_6442_rsrq1_verify_scr_msg(
+ {transport_event, {send_message, _SH, {message, Msg}}, Pid})
+ when is_record(Msg, 'MegacoMessage') ->
+ d("received expected service change request message: "
+ "~n Msg: ~p", [Msg]),
+ Reply = ok,
+ Pid ! {transport_reply, Reply, self()},
+ {ok, Pid};
+otp_6442_rsrq1_verify_scr_msg(
+ {transport_event, {send_message, _SH, BadMsg}, _Pid}) ->
+ io:format("otp_6442_rsrq1_verify_scr_msg -> error: "
+ "~n BadMsg: ~p"
+ "~n", [BadMsg]),
+ {error, {invalid_message, BadMsg}};
+otp_6442_rsrq1_verify_scr_msg({transport_event, BadEvent, _Pid}) ->
+ io:format("otp_6442_rsrq1_verify_scr_msg -> error: "
+ "~n BadEvent: ~p"
+ "~n", [BadEvent]),
+ {error, {invalid_message, BadEvent}};
+otp_6442_rsrq1_verify_scr_msg(Msg) ->
+ io:format("otp_6442_rsrq1_verify_scr_msg -> error: "
+ "~n Msg: ~p"
+ "~n", [Msg]),
+ {error, {invalid_message, Msg}}.
+
+otp_6442_rsrq1_verify_first_nr_msg(
+ {transport_event, {send_message, _SH, {message, Msg}}, Pid})
+ when is_record(Msg, 'MegacoMessage') ->
+ d("received expected first notify request send message: "
+ "~n Msg: ~p", [Msg]),
+ Reply = ok,
+ Pid ! {transport_reply, Reply, self()},
+ {ok, ok};
+otp_6442_rsrq1_verify_first_nr_msg(Msg) ->
+ io:format("otp_6442_rsrq1_verify_nr_msg -> error: "
+ "~n Msg: ~p"
+ "~n", [Msg]),
+ {error, {invalid_message, Msg}}.
+
+otp_6442_rsrq1_verify_second_nr_msg(
+ {transport_event, {send_message, _SH, {message, Msg}}, Pid})
+ when is_record(Msg, 'MegacoMessage') ->
+ io:format("otp_6442_rsrq1_verify_second_nr_msg -> "
+ "entry when received expected message with"
+ "~n Msg: ~p"
+ "~n", [Msg]),
+ Reply = ok,
+ Pid ! {transport_reply, Reply, self()},
+ #'MegacoMessage'{mess = Mess} = Msg,
+ #'Message'{mId = _Mid,
+ messageBody = Body} = Mess,
+ {transactions, Transactions} = Body,
+ [Transaction] = Transactions,
+ {transactionRequest, TransReq} = Transaction,
+ #'TransactionRequest'{transactionId = TransId,
+ actions = Actions} = TransReq,
+ [Action] = Actions,
+ #'ActionRequest'{contextId = Cid,
+ commandRequests = CmdReqs} = Action,
+ [CmdReq] = CmdReqs,
+ #'CommandRequest'{command = Cmd} = CmdReq,
+ {notifyReq, NR} = Cmd,
+ #'NotifyRequest'{terminationID = [TermId]} = NR,
+ {ok, {TransId, Cid, TermId}};
+otp_6442_rsrq1_verify_second_nr_msg(Msg) ->
+ io:format("otp_6442_rsrq1_verify_second_nr_msg -> entry when error with"
+ "~n Msg: ~p"
+ "~n", [Msg]),
+ {error, {invalid_message, Msg}}.
+
+
+otp_6442_mgc_service_change_reply_msg(Mid, TransId, Cid) ->
+ SCRP = #'ServiceChangeResParm'{serviceChangeMgcId = Mid},
+ SCRPs = {serviceChangeResParms, SCRP},
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = #'ServiceChangeReply'{terminationID = [Root],
+ serviceChangeResult = SCRPs},
+ CR = {serviceChangeReply, SCR},
+ otp_6442_mgc_reply_msg(Mid, TransId, CR, Cid).
+
+otp_6442_mgc_notify_reply_msg(Mid, TransId, Cid, TermId) ->
+ NR = #'NotifyReply'{terminationID = [TermId]},
+ CR = {notifyReply, NR},
+ otp_6442_mgc_reply_msg(Mid, TransId, CR, Cid).
+
+otp_6442_mgc_reply_msg(Mid, TransId, CR, Cid) ->
+ AR = #'ActionReply'{contextId = Cid,
+ commandReply = [CR]},
+ ARs = {actionReplies, [AR]},
+ TR = #'TransactionReply'{transactionId = TransId,
+ transactionResult = ARs},
+ Body = {transactions, [{transactionReply, TR}]},
+ Mess = #'Message'{version = 1,
+ mId = Mid,
+ messageBody = Body},
+ #'MegacoMessage'{mess = Mess}.
+
+
+%%
+%% MG generator stuff
+%%
+-ifdef(megaco_hipe_special).
+-define(otp_6442_resend_request1_mg_verify_handle_connect_fun(),
+ {?MODULE, otp_6442_resend_request1_mg_verify_handle_connect, []}).
+-define(otp_6442_resend_request1_mg_verify_service_change_rep_fun(),
+ {?MODULE, otp_6442_resend_request1_mg_verify_service_change_rep, []}).
+-define(otp_6442_resend_request1_mg_verify_notify_rep_fun(),
+ {?MODULE, otp_6442_resend_request1_mg_verify_notify_rep, []}).
+-else.
+-define(otp_6442_resend_request1_mg_verify_handle_connect_fun(),
+ otp_6442_resend_request1_mg_verify_handle_connect_fun()).
+-define(otp_6442_resend_request1_mg_verify_service_change_rep_fun(),
+ otp_6442_resend_request1_mg_verify_service_change_rep_fun()).
+-define(otp_6442_resend_request1_mg_verify_notify_rep_fun(),
+ otp_6442_resend_request1_mg_verify_notify_rep_fun()).
+-endif.
+
+otp_6442_resend_request1_mg_event_sequence(Mid) ->
+ RI = [
+ {port, self()}, % This is just a trick to get my pid to the transport module
+ {encoding_module, megaco_pretty_text_encoder},
+ {encoding_config, []},
+ {transport_module, megaco_test_generic_transport}
+ ],
+ ServiceChangeReq =
+ otp_6442_resend_request1_mg_service_change_request_ar(Mid, 1),
+ Tid = #megaco_term_id{id = ["00000000","00000000","01101101"]},
+ NotifyReq = otp_6442_resend_request1_mg_notify_request_ar(1, Tid, 1),
+ ConnectVerify =
+ ?otp_6442_resend_request1_mg_verify_handle_connect_fun(),
+ ServiceChangeReplyVerify =
+ ?otp_6442_resend_request1_mg_verify_service_change_rep_fun(),
+ NotifyReplyVerify =
+ ?otp_6442_resend_request1_mg_verify_notify_rep_fun(),
+ %% ConnectVerify =
+ %% otp_6442_resend_request1_mg_verify_handle_connect_fun(),
+ %% ServiceChangeReplyVerify =
+ %% otp_6442_resend_request1_mg_verify_service_change_reply_fun(),
+ %% NotifyReplyVerify = otp_6442_resend_request1_mg_verify_notify_reply_fun(),
+ EvSeq = [
+ {debug, false},
+ megaco_start,
+ {megaco_start_user, Mid, RI, []},
+ {megaco_update_user_info, resend_indication, false},
+ start_transport,
+ {megaco_trace, disable},
+ {megaco_system_info, users},
+ {megaco_system_info, connections},
+ connect,
+ {megaco_callback, handle_connect, ConnectVerify},
+ megaco_connect,
+ {megaco_cast, [ServiceChangeReq], []},
+ {megaco_callback, handle_connect, ConnectVerify},
+ {megaco_callback, handle_trans_reply, ServiceChangeReplyVerify},
+ {sleep, 1000},
+ {megaco_cast, [NotifyReq], []},
+ {megaco_callback, handle_trans_reply, NotifyReplyVerify},
+ {sleep, 1000},
+ megaco_stop_user,
+ megaco_stop,
+ {sleep, 1000}
+ ],
+ EvSeq.
+
+
+-ifndef(megaco_hipe_special).
+otp_6442_resend_request1_mg_verify_handle_connect_fun() ->
+ fun(Ev) ->
+ otp_6442_resend_request1_mg_verify_handle_connect(Ev)
+ end.
+-endif.
+
+otp_6442_resend_request1_mg_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
+ io:format("otp_6442_resend_request1_mg_verify_handle_connect -> ok"
+ "~n CH: ~p~n", [CH]),
+ {ok, CH, ok};
+otp_6442_resend_request1_mg_verify_handle_connect(Else) ->
+ io:format("otp_6442_resend_request1_mg_verify_handle_connect -> unknown"
+ "~n Else: ~p~n", [Else]),
+ {error, Else, ok}.
+
+-ifndef(megaco_hipe_special).
+otp_6442_resend_request1_mg_verify_service_change_rep_fun() ->
+ fun(Rep) ->
+ otp_6442_resend_request1_mg_verify_service_change_rep(Rep)
+ end.
+-endif.
+
+otp_6442_resend_request1_mg_verify_service_change_rep(
+ {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _}) ->
+ (catch otp_6442_resend_request1_mg_do_verify_service_change_rep(AR));
+otp_6442_resend_request1_mg_verify_service_change_rep(Crap) ->
+ {error, Crap, ok}.
+
+otp_6442_resend_request1_mg_do_verify_service_change_rep(AR) ->
+ io:format("otp_6442_resend_request1_mg_verify_service_change_rep -> ok"
+ "~n AR: ~p~n", [AR]),
+ CR =
+ case AR of
+ #'ActionReply'{commandReply = [CmdRep]} ->
+ CmdRep;
+ _ ->
+ Reason1 = {invalid_action_reply, AR},
+ throw({error, Reason1, ok})
+ end,
+ SCR =
+ case CR of
+ {serviceChangeReply, ServChRep} ->
+ ServChRep;
+ _ ->
+ Reason2 = {invalid_command_reply, CR},
+ throw({error, Reason2, ok})
+ end,
+ {Tid, SCRes} =
+ case SCR of
+ #'ServiceChangeReply'{terminationID = [TermID],
+ serviceChangeResult = Res} ->
+ {TermID, Res};
+ _ ->
+ Reason3 = {invalid_service_change_reply, SCR},
+ throw({error, Reason3, ok})
+ end,
+ case Tid of
+ #megaco_term_id{contains_wildcards = false, id = ["root"]} ->
+ ok;
+ _ ->
+ Reason4 = {invalid_termination_id, Tid},
+ throw({error, Reason4, ok})
+ end,
+ SCRParm =
+ case SCRes of
+ {serviceChangeResParms, ServChResParms} ->
+ ServChResParms;
+ _ ->
+ Reason5 = {invalid_serviceChangeResult, SCRes},
+ throw({error, Reason5, ok})
+ end,
+ case SCRParm of
+ #'ServiceChangeResParm'{serviceChangeMgcId = _RemoteMid} ->
+ {ok, AR, ok};
+ _ ->
+ Reason6 = {invalid_service_change_result, SCRParm},
+ {error, Reason6, ok}
+ end.
+
+-ifndef(megaco_hipe_special).
+otp_6442_resend_request1_mg_verify_notify_rep_fun() ->
+ fun(Rep) ->
+ otp_6442_resend_request1_mg_verify_notify_rep(Rep)
+ end.
+-endif.
+
+otp_6442_resend_request1_mg_verify_notify_rep(
+ {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _}) ->
+ io:format("otp_6442_resend_request1_mg_verify_notify_rep -> ok"
+ "~n AR: ~p~n", [AR]),
+ {ok, AR, ok};
+otp_6442_resend_request1_mg_verify_notify_rep(Else) ->
+ io:format("otp_6442_resend_request1_mg_verify_notify_rep -> unknown"
+ "~n Else: ~p~n", [Else]),
+ {error, Else, ok}.
+
+
+otp_6442_resend_request1_mg_service_change_request_ar(_Mid, Cid) ->
+ Prof = cre_serviceChangeProf("resgw", 1),
+ SCP = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = cre_serviceChangeReq([Root], SCP),
+ CMD = cre_command(SCR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+otp_6442_resend_request1_mg_notify_request_ar(Rid, Tid, Cid) ->
+ TT = cre_timeNotation("19990729", "22000000"),
+ Ev = cre_obsEvent("al/of", TT),
+ EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
+ NR = cre_notifyReq([Tid], EvsDesc),
+ CMD = cre_command(NR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+otp_6442_resend_request2(suite) ->
+ [];
+otp_6442_resend_request2(Config) when is_list(Config) ->
+ put(verbosity, debug),
+ put(sname, "TEST"),
+ put(tc, otp6442rreq2),
+ i("starting"),
+
+ MgNode = make_node_name(mg),
+ d("start (MG) node: ~p", [MgNode]),
+ ok = megaco_test_lib:start_nodes([MgNode], ?FILE, ?LINE),
+
+ d("[MG] start the simulator "),
+ {ok, Mg} = megaco_test_megaco_generator:start_link("MG", MgNode),
+
+ d("[MG] create the event sequence"),
+ Mid = {deviceName,"mg"},
+ MgcMid = {deviceName,"mgc"},
+ MgEvSeq = otp_6442_resend_request2_mg_event_sequence(Mid),
+
+ i("wait some time before starting the MG simulation"),
+ sleep(1000),
+
+ d("[MG] start the simulation"),
+ {ok, MgId} = megaco_test_megaco_generator:exec(Mg, MgEvSeq),
+
+ i("await the transport module service change send_message event"),
+ Pid = otp_6442_expect(fun otp_6442_rsrq2_verify_scr_msg/1, 5000),
+
+ i("wait some before issuing the service change reply"),
+ sleep(500),
+
+ i("send the service change reply"),
+ ServiceChangeReply = otp_6442_mgc_service_change_reply_msg(MgcMid, 1, 1),
+ megaco_test_generic_transport:incomming_message(Pid, ServiceChangeReply),
+
+ i("await the transport module notify-request send_message event from MG: ignore"),
+ ok = otp_6442_expect(fun otp_6442_rsrq2_verify_first_nr_msg/1, 5000),
+
+ i("await the transport module notify-request resend_message event from MG: reply"),
+ {TransId2, Cid2, TermId2} =
+ otp_6442_expect(fun otp_6442_rsrq2_verify_second_nr_msg/1, 10000),
+
+ i("wait some before issuing the notify reply"),
+ sleep(500),
+
+ i("send the notify reply"),
+ NotifyReply = otp_6442_mgc_notify_reply_msg(MgcMid, TransId2, Cid2, TermId2),
+ megaco_test_generic_transport:incomming_message(Pid, NotifyReply),
+
+ d("await the generator reply"),
+ await_completion([MgId]),
+
+ %% Tell Mg to stop
+ i("[MG] stop generator"),
+ megaco_test_megaco_generator:stop(Mg),
+
+ i("done", []),
+ ok.
+
+
+otp_6442_rsrq2_verify_scr_msg(
+ {transport_event, {send_message, _SH, {message, Msg}}, Pid})
+ when is_record(Msg, 'MegacoMessage') ->
+ d("received expected service change request message: "
+ "~n Msg: ~p", [Msg]),
+ Reply = ok,
+ Pid ! {transport_reply, Reply, self()},
+ {ok, Pid};
+otp_6442_rsrq2_verify_scr_msg(Msg) ->
+ io:format("otp_6442_rsrq2_verify_nr_msg -> error: "
+ "~n Msg: ~p"
+ "~n", [Msg]),
+ {error, {invalid_message, Msg}}.
+
+otp_6442_rsrq2_verify_first_nr_msg(
+ {transport_event, {send_message, _SH, {message, Msg}}, Pid})
+ when is_record(Msg, 'MegacoMessage') ->
+ d("received expected first notify request message: "
+ "~n Msg: ~p", [Msg]),
+ Reply = ok,
+ Pid ! {transport_reply, Reply, self()},
+ {ok, ok};
+otp_6442_rsrq2_verify_first_nr_msg(Msg) ->
+ {error, {invalid_message, Msg}}.
+
+otp_6442_rsrq2_verify_second_nr_msg(
+ {transport_event, {resend_message, _SH, {message, Msg}}, Pid})
+ when is_record(Msg, 'MegacoMessage') ->
+ d("received expected second notify request message: "
+ "~n Msg: ~p", [Msg]),
+ Reply = ok,
+ Pid ! {transport_reply, Reply, self()},
+ #'MegacoMessage'{mess = Mess} = Msg,
+ #'Message'{mId = _Mid,
+ messageBody = Body} = Mess,
+ {transactions, Transactions} = Body,
+ [Transaction] = Transactions,
+ {transactionRequest, TransReq} = Transaction,
+ #'TransactionRequest'{transactionId = TransId,
+ actions = Actions} = TransReq,
+ [Action] = Actions,
+ #'ActionRequest'{contextId = Cid,
+ commandRequests = CmdReqs} = Action,
+ [CmdReq] = CmdReqs,
+ #'CommandRequest'{command = Cmd} = CmdReq,
+ {notifyReq, NR} = Cmd,
+ #'NotifyRequest'{terminationID = [TermId]} = NR,
+ {ok, {TransId, Cid, TermId}};
+otp_6442_rsrq2_verify_second_nr_msg(Msg) ->
+ {error, {invalid_message, Msg}}.
+
+
+%%
+%% MG generator stuff
+%%
+-ifdef(megaco_hipe_special).
+-define(otp_6442_resend_request2_mg_verify_handle_connect_fun(),
+ {?MODULE, otp_6442_resend_request2_mg_verify_handle_connect, []}).
+-define(otp_6442_resend_request2_mg_verify_service_change_rep_fun(),
+ {?MODULE, otp_6442_resend_request2_mg_verify_service_change_rep, []}).
+-define(otp_6442_resend_request2_mg_verify_notify_rep_fun(),
+ {?MODULE, otp_6442_resend_request2_mg_verify_notify_rep, []}).
+-else.
+-define(otp_6442_resend_request2_mg_verify_handle_connect_fun(),
+ otp_6442_resend_request2_mg_verify_handle_connect_fun()).
+-define(otp_6442_resend_request2_mg_verify_service_change_rep_fun(),
+ otp_6442_resend_request2_mg_verify_service_change_rep_fun()).
+-define(otp_6442_resend_request2_mg_verify_notify_rep_fun(),
+ otp_6442_resend_request2_mg_verify_notify_rep_fun()).
+-endif.
+
+otp_6442_resend_request2_mg_event_sequence(Mid) ->
+ RI = [
+ {port, self()}, % This is just a trick to get my pid to the transport module
+ {encoding_module, megaco_pretty_text_encoder},
+ {encoding_config, []},
+ {transport_module, megaco_test_generic_transport}
+ ],
+ Tid = #megaco_term_id{id = ["00000000","00000000","01101101"]},
+ NotifyReq = otp_6442_resend_request2_mg_notify_request_ar(1, Tid, 1),
+ ServiceChangeReq =
+ otp_6442_resend_request2_mg_service_change_request_ar(Mid, 1),
+ ConnectVerify =
+ ?otp_6442_resend_request2_mg_verify_handle_connect_fun(),
+ ServiceChangeReplyVerify =
+ ?otp_6442_resend_request2_mg_verify_service_change_rep_fun(),
+ NotifyReplyVerify =
+ ?otp_6442_resend_request2_mg_verify_notify_rep_fun(),
+%% ConnectVerify =
+%% otp_6442_resend_request2_mg_verify_handle_connect_fun(),
+%% ServiceChangeReplyVerify =
+%% otp_6442_resend_request2_mg_verify_service_change_reply_fun(),
+%% NotifyReplyVerify = otp_6442_resend_request2_mg_verify_notify_reply_fun(),
+ EvSeq = [
+ {debug, false},
+ megaco_start,
+ {megaco_start_user, Mid, RI, []},
+ {megaco_update_user_info, resend_indication, true},
+ start_transport,
+ {megaco_trace, disable},
+ {megaco_system_info, users},
+ {megaco_system_info, connections},
+ connect,
+ {megaco_callback, handle_connect, ConnectVerify},
+ megaco_connect,
+ {megaco_cast, [ServiceChangeReq], []},
+ {megaco_callback, handle_connect, ConnectVerify},
+ {megaco_callback, handle_trans_reply, ServiceChangeReplyVerify},
+ {sleep, 1000},
+ {megaco_cast, [NotifyReq], []},
+ {megaco_callback, handle_trans_reply, NotifyReplyVerify},
+ {sleep, 1000},
+ megaco_stop_user,
+ megaco_stop,
+ {sleep, 1000}
+ ],
+ EvSeq.
+
+
+-ifndef(megaco_hipe_special).
+otp_6442_resend_request2_mg_verify_handle_connect_fun() ->
+ fun(Ev) ->
+ otp_6442_resend_request2_mg_verify_handle_connect(Ev)
+ end.
+-endif.
+
+otp_6442_resend_request2_mg_verify_handle_connect(
+ {handle_connect, CH, ?VERSION}) ->
+ io:format("otp_6442_resend_request2_mg_verify_handle_connect -> ok"
+ "~n CH: ~p~n", [CH]),
+ {ok, CH, ok};
+otp_6442_resend_request2_mg_verify_handle_connect(Else) ->
+ io:format("otp_6442_resend_request2_mg_verify_handle_connect -> unknown"
+ "~n Else: ~p~n", [Else]),
+ {error, Else, ok}.
+
+
+-ifndef(megaco_hipe_special).
+otp_6442_resend_request2_mg_verify_service_change_rep_fun() ->
+ fun(Rep) ->
+ otp_6442_resend_request2_mg_verify_service_change_rep(Rep)
+ end.
+-endif.
+
+otp_6442_resend_request2_mg_verify_service_change_rep(
+ {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _}) ->
+ (catch otp_6442_resend_request2_mg_do_verify_service_change_rep(AR));
+otp_6442_resend_request2_mg_verify_service_change_rep(Crap) ->
+ {error, Crap, ok}.
+
+otp_6442_resend_request2_mg_do_verify_service_change_rep(AR) ->
+ io:format("otp_6442_resend_request2_mg_verify_service_change_rep -> ok"
+ "~n AR: ~p~n", [AR]),
+ CR =
+ case AR of
+ #'ActionReply'{commandReply = [CmdRep]} ->
+ CmdRep;
+ _ ->
+ Reason1 = {invalid_action_reply, AR},
+ throw({error, Reason1, ok})
+ end,
+ SCR =
+ case CR of
+ {serviceChangeReply, ServChRep} ->
+ ServChRep;
+ _ ->
+ Reason2 = {invalid_command_reply, CR},
+ throw({error, Reason2, ok})
+ end,
+ {Tid, SCRes} =
+ case SCR of
+ #'ServiceChangeReply'{terminationID = [TermID],
+ serviceChangeResult = Res} ->
+ {TermID, Res};
+ _ ->
+ Reason3 = {invalid_service_change_reply, SCR},
+ throw({error, Reason3, ok})
+ end,
+ case Tid of
+ #megaco_term_id{contains_wildcards = false, id = ["root"]} ->
+ ok;
+ _ ->
+ Reason4 = {invalid_termination_id, Tid},
+ throw({error, Reason4, ok})
+ end,
+ SCRParm =
+ case SCRes of
+ {serviceChangeResParms, ServChResParms} ->
+ ServChResParms;
+ _ ->
+ Reason5 = {invalid_serviceChangeResult, SCRes},
+ throw({error, Reason5, ok})
+ end,
+ case SCRParm of
+ #'ServiceChangeResParm'{serviceChangeMgcId = _RemoteMid} ->
+ {ok, AR, ok};
+ _ ->
+ Reason6 = {invalid_service_change_result, SCRParm},
+ {error, Reason6, ok}
+ end.
+
+-ifndef(megaco_hipe_special).
+otp_6442_resend_request2_mg_verify_notify_rep_fun() ->
+ fun(Rep) ->
+ otp_6442_resend_request2_mg_verify_notify_rep(Rep)
+ end.
+-endif.
+
+otp_6442_resend_request2_mg_verify_notify_rep(
+ {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _}) ->
+ io:format("otp_6442_resend_request2_mg_verify_notify_rep -> ok"
+ "~n AR: ~p~n", [AR]),
+ {ok, AR, ok};
+otp_6442_resend_request2_mg_verify_notify_rep(Else) ->
+ io:format("otp_6442_resend_request2_mg_verify_notify_rep -> unknown"
+ "~n Else: ~p~n", [Else]),
+ {error, Else, ok}.
+
+
+otp_6442_resend_request2_mg_service_change_request_ar(_Mid, Cid) ->
+ Prof = cre_serviceChangeProf("resgw", 1),
+ SCP = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = cre_serviceChangeReq([Root], SCP),
+ CMD = cre_command(SCR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+otp_6442_resend_request2_mg_notify_request_ar(Rid, Tid, Cid) ->
+ TT = cre_timeNotation("19990729", "22000000"),
+ Ev = cre_obsEvent("al/of", TT),
+ EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
+ NR = cre_notifyReq([Tid], EvsDesc),
+ CMD = cre_command(NR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+otp_6442_resend_reply1(suite) ->
+ [];
+otp_6442_resend_reply1(Config) when is_list(Config) ->
+ put(sname, "TEST"),
+ put(verbosity, debug),
+ put(tc, otp6442rrep1),
+ i("starting"),
+
+ MgNode = make_node_name(mg),
+ d("start (MG) node: ~p", [MgNode]),
+ ok = megaco_test_lib:start_nodes([MgNode], ?FILE, ?LINE),
+
+ d("[MG] start the simulator "),
+ {ok, Mg} = megaco_test_megaco_generator:start_link("MG", MgNode),
+
+ d("[MG] create the event sequence"),
+ Mid = {deviceName,"mg"},
+ MgcMid = {deviceName,"mgc"},
+ TermId = #megaco_term_id{id = ["00000000","00000000","01101101"]},
+ MgEvSeq = otp_6442_resend_reply1_mg_event_sequence(Mid, TermId),
+
+ i("wait some time before starting the MG simulation"),
+ sleep(1000),
+
+ d("[MG] start the simulation"),
+ {ok, MgId} = megaco_test_megaco_generator:exec(Mg, MgEvSeq),
+
+ i("await the transport module service change send_message event"),
+ Pid = otp_6442_expect(fun otp_6442_rsrp1_verify_scr_msg/1, 5000),
+
+ i("wait some before issuing the service change reply"),
+ sleep(500),
+
+ i("simulate MGC sending the service change reply"),
+ ServiceChangeReply = otp_6442_mgc_service_change_reply_msg(MgcMid, 1, 1),
+ megaco_test_generic_transport:incomming_message(Pid, ServiceChangeReply),
+
+
+ i("wait some before issuing the notify request"),
+ sleep(500),
+
+ i("simulate MGC sending the notify request"),
+ NotifyRequest = otp_6442_mgc_notify_request_msg(MgcMid, TermId, 2, 1),
+ megaco_test_generic_transport:incomming_message(Pid, NotifyRequest),
+
+ i("await the transport module first notify-reply send_message event from MG: "
+ "ignore"),
+ otp_6442_expect(fun otp_6442_rsrp1_verify_first_nr_msg/1, 5000),
+
+ i("await the transport module second notify-reply send_message event from MG: "
+ "ack"),
+ {TransId, _, _} = otp_6442_expect(fun otp_6442_rsrp1_verify_second_nr_msg/1, 10000),
+
+ i("wait some before issuing the ack"),
+ sleep(500),
+
+ i("simulate MGC sending the ack"),
+ Ack = otp_6442_mgc_ack_msg(MgcMid, TransId),
+ megaco_test_generic_transport:incomming_message(Pid, Ack),
+
+
+ d("await the generator reply"),
+ await_completion([MgId]),
+
+ %% Tell Mg to stop
+ i("[MG] stop generator"),
+ megaco_test_megaco_generator:stop(Mg),
+
+ i("done", []),
+ ok.
+
+
+otp_6442_rsrp1_verify_scr_msg(
+ {transport_event, {send_message, _SH, {message, Msg}}, Pid})
+ when is_record(Msg, 'MegacoMessage') ->
+ d("received expected service change request message: "
+ "~n Msg: ~p", [Msg]),
+ Reply = ok,
+ Pid ! {transport_reply, Reply, self()},
+ {ok, Pid};
+otp_6442_rsrp1_verify_scr_msg(Msg) ->
+ {error, {invalid_message, Msg}}.
+
+otp_6442_rsrp1_verify_first_nr_msg(
+ {transport_event, {send_message, _SH, {message, Msg}}, Pid})
+ when is_record(Msg, 'MegacoMessage') ->
+ d("received expected first notify reply message: "
+ "~n Msg: ~p", [Msg]),
+ Reply = ok,
+ Pid ! {transport_reply, Reply, self()},
+ {ok, ok};
+otp_6442_rsrp1_verify_first_nr_msg(Msg) ->
+ {error, {invalid_message, Msg}}.
+
+otp_6442_rsrp1_verify_second_nr_msg(
+ {transport_event, {send_message, _SH, {message, Msg}}, Pid})
+ when is_record(Msg, 'MegacoMessage') ->
+ d("received expected second notify reply message: "
+ "~n Msg: ~p", [Msg]),
+ Reply = ok,
+ Pid ! {transport_reply, Reply, self()},
+ #'MegacoMessage'{mess = Mess} = Msg,
+ #'Message'{mId = _Mid,
+ messageBody = Body} = Mess,
+ {transactions, Transactions} = Body,
+ [Transaction] = Transactions,
+ {transactionReply, TransRep} = Transaction,
+ #'TransactionReply'{transactionId = TransId,
+ immAckRequired = 'NULL',
+ transactionResult = TransRes} = TransRep,
+ {actionReplies, ActReps} = TransRes,
+ [ActRep] = ActReps,
+ #'ActionReply'{contextId = Cid,
+ errorDescriptor = asn1_NOVALUE,
+ contextReply = asn1_NOVALUE,
+ commandReply = CmdReps} = ActRep,
+ [CmdRep] = CmdReps,
+ {notifyReply, NR} = CmdRep,
+ #'NotifyReply'{terminationID = TermId} = NR,
+ {ok, {TransId, Cid, TermId}};
+otp_6442_rsrp1_verify_second_nr_msg(Msg) ->
+ {error, {invalid_message, Msg}}.
+
+
+otp_6442_mgc_notify_request_msg(Mid, TermId, TransId, Cid) ->
+ TT = cre_timeNotation("19990729", "22000000"),
+ Ev = cre_obsEvent("al/of", TT),
+ EvsDesc = cre_obsEvsDesc(1, [Ev]),
+ NR = cre_notifyReq([TermId], EvsDesc),
+ CMD = cre_command(NR),
+ CR = cre_cmdReq(CMD),
+ AR = cre_actionReq(Cid, [CR]),
+ ARs = [AR],
+ TR = cre_transReq(TransId, ARs),
+ Trans = cre_transaction(TR),
+ Mess = cre_message(?VERSION, Mid, cre_transactions([Trans])),
+ cre_megacoMessage(Mess).
+
+
+otp_6442_mgc_ack_msg(Mid, TransId) ->
+ TR = cre_transRespAck(cre_transAck(TransId)),
+ Trans = cre_transaction(TR),
+ Mess = cre_message(?VERSION, Mid, cre_transactions([Trans])),
+ cre_megacoMessage(Mess).
+
+
+
+%%
+%% MG generator stuff
+%%
+-ifdef(megaco_hipe_special).
+-define(otp_6442_resend_reply1_mg_verify_handle_connect_fun(),
+ {?MODULE, otp_6442_resend_reply1_mg_verify_handle_connect, []}).
+-define(otp_6442_resend_reply1_mg_verify_service_change_rep_fun(),
+ {?MODULE, otp_6442_resend_reply1_mg_verify_service_change_rep, []}).
+-define(otp_6442_resend_reply1_mg_verify_notify_req_fun(TermId),
+ {?MODULE, otp_6442_resend_reply1_mg_verify_notify_req, [TermId]}).
+-define(otp_6442_resend_reply1_mg_verify_ack_fun(),
+ {?MODULE, otp_6442_resend_reply1_mg_verify_ack, []}).
+-else.
+-define(otp_6442_resend_reply1_mg_verify_handle_connect_fun(),
+ otp_6442_resend_reply1_mg_verify_handle_connect_fun()).
+-define(otp_6442_resend_reply1_mg_verify_service_change_rep_fun(),
+ otp_6442_resend_reply1_mg_verify_service_change_rep_fun()).
+-define(otp_6442_resend_reply1_mg_verify_notify_req_fun(TermId),
+ otp_6442_resend_reply1_mg_verify_notify_req_fun(TermId)).
+-define(otp_6442_resend_reply1_mg_verify_ack_fun(),
+ otp_6442_resend_reply1_mg_verify_ack_fun()).
+-endif.
+
+otp_6442_resend_reply1_mg_event_sequence(Mid, TermId) ->
+ RI = [
+ {port, self()}, % This is just a trick to get my pid to the transport module
+ {encoding_module, megaco_pretty_text_encoder},
+ {encoding_config, []},
+ {transport_module, megaco_test_generic_transport}
+ ],
+ ServiceChangeReq =
+ otp_6442_resend_reply1_mg_service_change_request_ar(Mid, 1),
+ RepTmr = #megaco_incr_timer{wait_for = 2000,
+ factor = 1,
+ max_retries = 1},
+ ConnectVerify =
+ ?otp_6442_resend_reply1_mg_verify_handle_connect_fun(),
+ ServiceChangeReplyVerify =
+ ?otp_6442_resend_reply1_mg_verify_service_change_rep_fun(),
+ NotifyReqVerify =
+ ?otp_6442_resend_reply1_mg_verify_notify_req_fun(TermId),
+ AckVerify =
+ ?otp_6442_resend_reply1_mg_verify_ack_fun(),
+%% ConnectVerify =
+%% otp_6442_resend_reply1_mg_verify_handle_connect_fun(),
+%% ServiceChangeReplyVerify =
+%% otp_6442_resend_reply1_mg_verify_service_change_reply_fun(),
+%% NotifyReqVerify =
+%% otp_6442_resend_reply1_mg_verify_notify_request_fun(TermId),
+%% AckVerify =
+%% otp_6442_resend_reply1_mg_verify_ack_fun(),
+ EvSeq = [
+ {debug, false},
+ megaco_start,
+ {megaco_start_user, Mid, RI, []},
+ {megaco_update_user_info, resend_indication, false},
+ {megaco_update_user_info, reply_timer, RepTmr},
+ start_transport,
+ {megaco_trace, disable},
+ {megaco_system_info, users},
+ {megaco_system_info, connections},
+ connect,
+ {megaco_callback, handle_connect, ConnectVerify},
+ megaco_connect,
+ {megaco_cast, [ServiceChangeReq], []},
+ {megaco_callback, handle_connect, ConnectVerify},
+ {megaco_callback, handle_trans_reply, ServiceChangeReplyVerify},
+ {sleep, 1000},
+
+ {megaco_callback, handle_trans_request, NotifyReqVerify},
+ {megaco_callback, handle_trans_ack, AckVerify},
+
+ {sleep, 1000},
+ megaco_stop_user,
+ megaco_stop,
+ {sleep, 1000}
+ ],
+ EvSeq.
+
+
+-ifndef(megaco_hipe_special).
+otp_6442_resend_reply1_mg_verify_handle_connect_fun() ->
+ fun(Ev) ->
+ otp_6442_resend_reply1_mg_verify_handle_connect(Ev)
+ end.
+-endif.
+
+otp_6442_resend_reply1_mg_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
+ io:format("otp_6442_resend_reply1_mg_verify_handle_connect -> ok"
+ "~n CH: ~p~n", [CH]),
+ {ok, CH, ok};
+otp_6442_resend_reply1_mg_verify_handle_connect(Else) ->
+ io:format("otp_6442_resend_reply1_mg_verify_handle_connect -> unknown"
+ "~n Else: ~p~n", [Else]),
+ {error, Else, ok}.
+
+
+-ifndef(megaco_hipe_special).
+otp_6442_resend_reply1_mg_verify_service_change_rep_fun() ->
+ fun(Rep) ->
+ otp_6442_resend_reply1_mg_verify_service_change_rep(Rep)
+ end.
+-endif.
+
+otp_6442_resend_reply1_mg_verify_service_change_rep(
+ {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _}) ->
+ (catch otp_6442_resend_reply1_mg_do_verify_service_change_rep(AR));
+otp_6442_resend_reply1_mg_verify_service_change_rep(Crap) ->
+ {error, Crap, ok}.
+
+otp_6442_resend_reply1_mg_do_verify_service_change_rep(AR) ->
+ io:format("otp_6442_resend_reply1_mg_verify_service_change_rep -> ok"
+ "~n AR: ~p~n", [AR]),
+ CR =
+ case AR of
+ #'ActionReply'{commandReply = [CmdRep]} ->
+ CmdRep;
+ _ ->
+ Reason1 = {invalid_action_reply, AR},
+ throw({error, Reason1, ok})
+ end,
+ SCR =
+ case CR of
+ {serviceChangeReply, ServChRep} ->
+ ServChRep;
+ _ ->
+ Reason2 = {invalid_command_reply, CR},
+ throw({error, Reason2, ok})
+ end,
+ {Tid, SCRes} =
+ case SCR of
+ #'ServiceChangeReply'{terminationID = [TermID],
+ serviceChangeResult = Res} ->
+ {TermID, Res};
+ _ ->
+ Reason3 = {invalid_service_change_reply, SCR},
+ throw({error, Reason3, ok})
+ end,
+ case Tid of
+ #megaco_term_id{contains_wildcards = false, id = ["root"]} ->
+ ok;
+ _ ->
+ Reason4 = {invalid_termination_id, Tid},
+ throw({error, Reason4, ok})
+ end,
+ SCRParm =
+ case SCRes of
+ {serviceChangeResParms, ServChResParms} ->
+ ServChResParms;
+ _ ->
+ Reason5 = {invalid_serviceChangeResult, SCRes},
+ throw({error, Reason5, ok})
+ end,
+ case SCRParm of
+ #'ServiceChangeResParm'{serviceChangeMgcId = _RemoteMid} ->
+ {ok, AR, ok};
+ _ ->
+ Reason6 = {invalid_service_change_result, SCRParm},
+ {error, Reason6, ok}
+ end.
+
+-ifndef(megaco_hipe_special).
+otp_6442_resend_reply1_mg_verify_notify_req_fun(TermId) ->
+ fun(Req) ->
+ otp_6442_resend_reply1_mg_verify_notify_req(Req, TermId)
+ end.
+-endif.
+
+otp_6442_resend_reply1_mg_verify_notify_req(
+ {handle_trans_request, _, ?VERSION, [AR]}, TermId) ->
+ io:format("otp_6442_resend_reply1_mg_verify_notify_req -> ok"
+ "~n AR: ~p~n", [AR]),
+ case AR of
+ #'ActionRequest'{contextId = 1 = Cid,
+ commandRequests = [CR]} ->
+ #'CommandRequest'{command = Cmd} = CR,
+ {notifyReq, NR} = Cmd,
+ #'NotifyRequest'{terminationID = [TermId],
+ observedEventsDescriptor = OED,
+ errorDescriptor = asn1_NOVALUE} = NR,
+ #'ObservedEventsDescriptor'{observedEventLst = [OE]} = OED,
+ #'ObservedEvent'{eventName = "al/of"} = OE,
+ HandleAck = {handle_ack, otp_6442_resend_reply1},
+ Reply = {HandleAck,
+ [otp_6442_resend_reply1_mg_notify_reply_ar(Cid, TermId)]},
+ {ok, AR, Reply};
+ _ ->
+ ED = otp_6442_resend_reply1_err_desc(AR),
+ ErrReply = {discard_ack, ED},
+ {error, AR, ErrReply}
+ end;
+otp_6442_resend_reply1_mg_verify_notify_req(Else, TermId) ->
+ io:format("otp_6442_resend_reply1_mg_verify_notify_request -> unknown"
+ "~n Else: ~p"
+ "~n TermId: ~p"
+ "~n", [Else, TermId]),
+ ED = otp_6442_resend_reply1_err_desc(Else),
+ ErrReply = {discard_ack, ED},
+ {error, Else, ErrReply}.
+
+otp_6442_resend_reply1_mg_notify_reply_ar(Cid, TermId) ->
+ NR = cre_notifyReply([TermId]),
+ CR = cre_cmdReply(NR),
+ cre_actionReply(Cid, [CR]).
+
+-ifndef(megaco_hipe_special).
+otp_6442_resend_reply1_mg_verify_ack_fun() ->
+ fun(Ack) ->
+ otp_6442_resend_reply1_mg_verify_ack(Ack)
+ end.
+-endif.
+
+otp_6442_resend_reply1_mg_verify_ack(
+ {handle_trans_ack, CH, ?VERSION, ok, otp_6442_resend_reply1}) ->
+ io:format("otp_6442_resend_reply1_verify_ack -> ok"
+ "~n CH: ~p"
+ "~n", [CH]),
+ {ok, CH, ok};
+otp_6442_resend_reply1_mg_verify_ack(Else) ->
+ io:format("otp_6442_resend_reply1_verify_ack -> unknown"
+ "~n Else: ~p~n", [Else]),
+ {error, Else, ok}.
+
+
+otp_6442_resend_reply1_mg_service_change_request_ar(_Mid, Cid) ->
+ Prof = cre_serviceChangeProf("resgw", 1),
+ SCP = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = cre_serviceChangeReq([Root], SCP),
+ CMD = cre_command(SCR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+otp_6442_resend_reply1_err_desc(T) ->
+ EC = ?megaco_internal_gateway_error,
+ ET = lists:flatten(io_lib:format("~w",[T])),
+ #'ErrorDescriptor'{errorCode = EC, errorText = ET}.
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+otp_6442_resend_reply2(suite) ->
+ [];
+otp_6442_resend_reply2(Config) when is_list(Config) ->
+ put(sname, "TEST"),
+ put(verbosity, debug),
+ put(tc, otp6442rrep2),
+ i("starting"),
+
+ MgNode = make_node_name(mg),
+ d("start (MG) node: ~p", [MgNode]),
+ ok = megaco_test_lib:start_nodes([MgNode], ?FILE, ?LINE),
+
+ d("[MG] start the simulator "),
+ {ok, Mg} = megaco_test_megaco_generator:start_link("MG", MgNode),
+
+ d("[MG] create the event sequence"),
+ Mid = {deviceName,"mg"},
+ MgcMid = {deviceName,"mgc"},
+ TermId = #megaco_term_id{id = ["00000000","00000000","01101101"]},
+ MgEvSeq = otp_6442_resend_reply2_mg_event_sequence(Mid, TermId),
+
+ i("wait some time before starting the MG simulation"),
+ sleep(1000),
+
+ d("[MG] start the simulation"),
+ {ok, MgId} = megaco_test_megaco_generator:exec(Mg, MgEvSeq),
+
+ i("await the transport module service change send_message event"),
+ Pid = otp_6442_expect(fun otp_6442_rsrp2_verify_scr_msg/1, 5000),
+
+ i("wait some before issuing the service change reply"),
+ sleep(500),
+
+ i("simulate MGC sending the service change reply"),
+ ServiceChangeReply = otp_6442_mgc_service_change_reply_msg(MgcMid, 1, 1),
+ megaco_test_generic_transport:incomming_message(Pid, ServiceChangeReply),
+
+
+ i("wait some before issuing the notify request"),
+ sleep(500),
+
+ i("simulate MGC sending the notify request"),
+ NotifyRequest = otp_6442_mgc_notify_request_msg(MgcMid, TermId, 2, 1),
+ megaco_test_generic_transport:incomming_message(Pid, NotifyRequest),
+
+ i("await the transport module notify-reply send_message event from MG: ignore"),
+ otp_6442_expect(otp_6442_rsrp2_verify_first_nr_msg_fun(), 5000),
+
+ i("await the transport module notify-reply resend_message event from MG: ack"),
+ {TransId, _, _} =
+ otp_6442_expect(otp_6442_rsrp2_verify_second_nr_msg_fun(), 10000),
+
+ i("wait some before issuing the ack"),
+ sleep(500),
+
+ i("simulate MGC sending the ack"),
+ Ack = otp_6442_mgc_ack_msg(MgcMid, TransId),
+ megaco_test_generic_transport:incomming_message(Pid, Ack),
+
+
+ d("await the generator reply"),
+ await_completion([MgId]),
+
+ %% Tell Mg to stop
+ i("[MG] stop generator"),
+ megaco_test_megaco_generator:stop(Mg),
+
+ i("done", []),
+ ok.
+
+
+otp_6442_rsrp2_verify_scr_msg(
+ {transport_event, {send_message, _SH, {message, Msg}}, Pid})
+ when is_record(Msg, 'MegacoMessage') ->
+ d("received expected service change request message: "
+ "~n Msg: ~p", [Msg]),
+ Reply = ok,
+ Pid ! {transport_reply, Reply, self()},
+ {ok, Pid};
+otp_6442_rsrp2_verify_scr_msg(Msg) ->
+ {error, {invalid_message, Msg}}.
+
+otp_6442_rsrp2_verify_first_nr_msg_fun() ->
+ fun(E) ->
+ otp_6442_rsrp2_verify_first_nr_msg(E)
+ end.
+
+otp_6442_rsrp2_verify_first_nr_msg(
+ {transport_event, {send_message, _SH, {message, Msg}}, Pid})
+ when is_record(Msg, 'MegacoMessage') ->
+ d("received expected first notify reply message: "
+ "~n Msg: ~p", [Msg]),
+ Reply = ok,
+ Pid ! {transport_reply, Reply, self()},
+ {ok, ok};
+otp_6442_rsrp2_verify_first_nr_msg(Msg) ->
+ {error, {invalid_message, Msg}}.
+
+otp_6442_rsrp2_verify_second_nr_msg_fun() ->
+ fun(E) ->
+ otp_6442_rsrp2_verify_second_nr_msg(E)
+ end.
+
+otp_6442_rsrp2_verify_second_nr_msg(
+ {transport_event, {resend_message, _SH, {message, Msg}}, Pid})
+ when is_record(Msg, 'MegacoMessage') ->
+ d("received expected second notify reply message: "
+ "~n Msg: ~p", [Msg]),
+ Reply = ok,
+ Pid ! {transport_reply, Reply, self()},
+ #'MegacoMessage'{mess = Mess} = Msg,
+ #'Message'{mId = _Mid,
+ messageBody = Body} = Mess,
+ {transactions, Transactions} = Body,
+ [Transaction] = Transactions,
+ {transactionReply, TransRep} = Transaction,
+ #'TransactionReply'{transactionId = TransId,
+ immAckRequired = 'NULL',
+ transactionResult = TransRes} = TransRep,
+ {actionReplies, ActReps} = TransRes,
+ [ActRep] = ActReps,
+ #'ActionReply'{contextId = Cid,
+ errorDescriptor = asn1_NOVALUE,
+ contextReply = asn1_NOVALUE,
+ commandReply = CmdReps} = ActRep,
+ [CmdRep] = CmdReps,
+ {notifyReply, NR} = CmdRep,
+ #'NotifyReply'{terminationID = TermId} = NR,
+ {ok, {TransId, Cid, TermId}};
+otp_6442_rsrp2_verify_second_nr_msg(Msg) ->
+ d("received expected bad second notify reply message: "
+ "~n Msg: ~p", [Msg]),
+ {error, {invalid_message, Msg}}.
+
+
+
+%%
+%% MG generator stuff
+%%
+-ifdef(megaco_hipe_special).
+-define(otp_6442_resend_reply2_mg_verify_handle_connect_fun(),
+ {?MODULE, otp_6442_resend_reply2_mg_verify_handle_connect, []}).
+-define(otp_6442_resend_reply2_mg_verify_service_change_rep_fun(),
+ {?MODULE, otp_6442_resend_reply2_mg_verify_service_change_rep, []}).
+-define(otp_6442_resend_reply2_mg_verify_notify_req_fun(TermId),
+ {?MODULE, otp_6442_resend_reply2_mg_verify_notify_req, [TermId]}).
+-define(otp_6442_resend_reply2_mg_verify_ack_fun(),
+ {?MODULE, otp_6442_resend_reply2_mg_verify_ack, []}).
+-else.
+-define(otp_6442_resend_reply2_mg_verify_handle_connect_fun(),
+ otp_6442_resend_reply2_mg_verify_handle_connect_fun()).
+-define(otp_6442_resend_reply2_mg_verify_service_change_rep_fun(),
+ otp_6442_resend_reply2_mg_verify_service_change_rep_fun()).
+-define(otp_6442_resend_reply2_mg_verify_notify_req_fun(TermId),
+ otp_6442_resend_reply2_mg_verify_notify_req_fun(TermId)).
+-define(otp_6442_resend_reply2_mg_verify_ack_fun(),
+ otp_6442_resend_reply2_mg_verify_ack_fun()).
+-endif.
+
+otp_6442_resend_reply2_mg_event_sequence(Mid, TermId) ->
+ RI = [
+ {port, self()}, % This is just a trick to get my pid to the transport module
+ {encoding_module, megaco_pretty_text_encoder},
+ {encoding_config, []},
+ {transport_module, megaco_test_generic_transport}
+ ],
+ ServiceChangeReq =
+ otp_6442_resend_reply2_mg_service_change_request_ar(Mid, 1),
+ RepTmr = #megaco_incr_timer{wait_for = 2000,
+ factor = 1,
+ max_retries = 1},
+ ConnectVerify =
+ ?otp_6442_resend_reply2_mg_verify_handle_connect_fun(),
+ ServiceChangeReplyVerify =
+ ?otp_6442_resend_reply2_mg_verify_service_change_rep_fun(),
+ NotifyReqVerify =
+ ?otp_6442_resend_reply2_mg_verify_notify_req_fun(TermId),
+ AckVerify =
+ ?otp_6442_resend_reply2_mg_verify_ack_fun(),
+%% ConnectVerify =
+%% otp_6442_resend_reply2_mg_verify_handle_connect_fun(),
+%% ServiceChangeReplyVerify =
+%% otp_6442_resend_reply2_mg_verify_service_change_reply_fun(),
+%% NotifyReqVerify =
+%% otp_6442_resend_reply2_mg_verify_notify_request_fun(TermId),
+%% AckVerify =
+%% otp_6442_resend_reply2_mg_verify_ack_fun(),
+ EvSeq = [
+ {debug, false},
+ megaco_start,
+ {megaco_start_user, Mid, RI, []},
+ {megaco_update_user_info, resend_indication, true},
+ {megaco_update_user_info, reply_timer, RepTmr},
+ start_transport,
+ {megaco_trace, disable},
+ {megaco_system_info, users},
+ {megaco_system_info, connections},
+ connect,
+ {megaco_callback, handle_connect, ConnectVerify},
+ megaco_connect,
+ {megaco_cast, [ServiceChangeReq], []},
+ {megaco_callback, handle_connect, ConnectVerify},
+ {megaco_callback, handle_trans_reply, ServiceChangeReplyVerify},
+ {sleep, 1000},
+
+ {megaco_callback, handle_trans_request, NotifyReqVerify},
+ {megaco_callback, handle_trans_ack, AckVerify},
+
+ {sleep, 1000},
+ megaco_stop_user,
+ megaco_stop,
+ {sleep, 1000}
+ ],
+ EvSeq.
+
+
+-ifndef(megaco_hipe_special).
+otp_6442_resend_reply2_mg_verify_handle_connect_fun() ->
+ fun(Ev) ->
+ otp_6442_resend_reply2_mg_verify_handle_connect(Ev)
+ end.
+-endif.
+
+otp_6442_resend_reply2_mg_verify_handle_connect(
+ {handle_connect, CH, ?VERSION}) ->
+ io:format("otp_6442_resend_reply2_mg_verify_handle_connect -> ok"
+ "~n CH: ~p~n", [CH]),
+ {ok, CH, ok};
+otp_6442_resend_reply2_mg_verify_handle_connect(Else) ->
+ io:format("otp_6442_resend_reply2_mg_verify_handle_connect -> unknown"
+ "~n Else: ~p~n", [Else]),
+ {error, Else, ok}.
+
+
+-ifndef(megaco_hipe_special).
+otp_6442_resend_reply2_mg_verify_service_change_rep_fun() ->
+ fun(Rep) ->
+ otp_6442_resend_reply2_mg_verify_service_change_rep(Rep)
+ end.
+-endif.
+
+otp_6442_resend_reply2_mg_verify_service_change_rep(
+ {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _}) ->
+ (catch otp_6442_resend_reply2_mg_do_verify_service_change_rep(AR));
+otp_6442_resend_reply2_mg_verify_service_change_rep(Crap) ->
+ {error, Crap, ok}.
+
+otp_6442_resend_reply2_mg_do_verify_service_change_rep(AR) ->
+ io:format("otp_6442_resend_reply2_mg_verify_service_change_rep -> ok"
+ "~n AR: ~p~n", [AR]),
+ CR =
+ case AR of
+ #'ActionReply'{commandReply = [CmdRep]} ->
+ CmdRep;
+ _ ->
+ Reason1 = {invalid_action_reply, AR},
+ throw({error, Reason1, ok})
+ end,
+ SCR =
+ case CR of
+ {serviceChangeReply, ServChRep} ->
+ ServChRep;
+ _ ->
+ Reason2 = {invalid_command_reply, CR},
+ throw({error, Reason2, ok})
+ end,
+ {Tid, SCRes} =
+ case SCR of
+ #'ServiceChangeReply'{terminationID = [TermID],
+ serviceChangeResult = Res} ->
+ {TermID, Res};
+ _ ->
+ Reason3 = {invalid_service_change_reply, SCR},
+ throw({error, Reason3, ok})
+ end,
+ case Tid of
+ #megaco_term_id{contains_wildcards = false, id = ["root"]} ->
+ ok;
+ _ ->
+ Reason4 = {invalid_termination_id, Tid},
+ throw({error, Reason4, ok})
+ end,
+ SCRParm =
+ case SCRes of
+ {serviceChangeResParms, ServChResParms} ->
+ ServChResParms;
+ _ ->
+ Reason5 = {invalid_serviceChangeResult, SCRes},
+ throw({error, Reason5, ok})
+ end,
+ case SCRParm of
+ #'ServiceChangeResParm'{serviceChangeMgcId = _RemoteMid} ->
+ {ok, AR, ok};
+ _ ->
+ Reason6 = {invalid_service_change_result, SCRParm},
+ {error, Reason6, ok}
+ end.
+
+-ifndef(megaco_hipe_special).
+otp_6442_resend_reply2_mg_verify_notify_req_fun(TermId) ->
+ fun(Req) ->
+ otp_6442_resend_reply2_mg_verify_notify_req(Req, TermId)
+ end.
+-endif.
+
+otp_6442_resend_reply2_mg_verify_notify_req(
+ {handle_trans_request, _, ?VERSION, [AR]}, TermId) ->
+ io:format("otp_6442_resend_reply2_mg_verify_notify_req -> ok"
+ "~n AR: ~p~n", [AR]),
+ case AR of
+ #'ActionRequest'{contextId = 1 = Cid,
+ commandRequests = [CR]} ->
+ #'CommandRequest'{command = Cmd} = CR,
+ {notifyReq, NR} = Cmd,
+ #'NotifyRequest'{terminationID = [TermId],
+ observedEventsDescriptor = OED,
+ errorDescriptor = asn1_NOVALUE} = NR,
+ #'ObservedEventsDescriptor'{observedEventLst = [OE]} = OED,
+ #'ObservedEvent'{eventName = "al/of"} = OE,
+ HandleAck = {handle_ack, otp_6442_resend_reply2},
+ Reply = {HandleAck,
+ [otp_6442_resend_reply2_mg_notify_reply_ar(Cid, TermId)]},
+ {ok, AR, Reply};
+ _ ->
+ ED = otp_6442_resend_reply2_err_desc(AR),
+ ErrReply = {discard_ack, ED},
+ {error, AR, ErrReply}
+ end;
+otp_6442_resend_reply2_mg_verify_notify_req(Else, TermId) ->
+ io:format("otp_6442_resend_reply2_mg_verify_notify_req -> unknown"
+ "~n Else: ~p"
+ "~n TermId: ~p"
+ "~n", [Else, TermId]),
+ ED = otp_6442_resend_reply2_err_desc(Else),
+ ErrReply = {discard_ack, ED},
+ {error, Else, ErrReply}.
+
+otp_6442_resend_reply2_mg_notify_reply_ar(Cid, TermId) ->
+ NR = cre_notifyReply([TermId]),
+ CR = cre_cmdReply(NR),
+ cre_actionReply(Cid, [CR]).
+
+
+-ifndef(megaco_hipe_special).
+otp_6442_resend_reply2_mg_verify_ack_fun() ->
+ fun(Ack) ->
+ otp_6442_resend_reply2_mg_verify_ack(Ack)
+ end.
+-endif.
+
+otp_6442_resend_reply2_mg_verify_ack(
+ {handle_trans_ack, CH, ?VERSION, ok, otp_6442_resend_reply2}) ->
+ io:format("otp_6442_resend_reply2_verify_ack -> ok"
+ "~n CH: ~p"
+ "~n", [CH]),
+ {ok, CH, ok};
+otp_6442_resend_reply2_mg_verify_ack(Else) ->
+ io:format("otp_6442_resend_reply2_verify_ack -> unknown"
+ "~n Else: ~p~n", [Else]),
+ {error, Else, ok}.
+
+
+otp_6442_resend_reply2_mg_service_change_request_ar(_Mid, Cid) ->
+ Prof = cre_serviceChangeProf("resgw", 1),
+ SCP = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = cre_serviceChangeReq([Root], SCP),
+ CMD = cre_command(SCR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+
+otp_6442_resend_reply2_err_desc(T) ->
+ EC = ?megaco_internal_gateway_error,
+ ET = lists:flatten(io_lib:format("~w",[T])),
+ #'ErrorDescriptor'{errorCode = EC, errorText = ET}.
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+otp_6865_request_and_reply_plain_extra1(suite) ->
+ [];
+otp_6865_request_and_reply_plain_extra1(Config) when is_list(Config) ->
+ ?ACQUIRE_NODES(1, Config),
+
+ put(sname, "TEST"),
+ put(verbosity, debug),
+ put(tc, otp6865e1),
+ i("starting"),
+
+ d("start test case controller",[]),
+ ok = megaco_tc_controller:start_link(),
+
+ %% Instruct the transport module to fail all send_message
+ d("instruct transport module to provide extra info: ",[]),
+ ExtraInfo = otp_6865_extra_info,
+ ok = megaco_tc_controller:insert(extra_transport_info, ExtraInfo),
+
+ d("start proxy",[]),
+ megaco_mess_user_test:start_proxy(),
+
+ PrelMid = preliminary_mid,
+ MgMid = ipv4_mid(4711),
+ MgcMid = ipv4_mid(),
+ UserMod = megaco_mess_user_test,
+ d("start megaco app",[]),
+ ?VERIFY(ok, application:start(megaco)),
+ UserConfig = [{user_mod, UserMod}, {send_mod, UserMod},
+ {request_timer, infinity}, {reply_timer, infinity}],
+ d("start (MG) user ~p",[MgMid]),
+ ?VERIFY(ok, megaco:start_user(MgMid, UserConfig)),
+
+ d("start (MGC) user ~p",[MgcMid]),
+ ?VERIFY(ok, megaco:start_user(MgcMid, UserConfig)),
+
+ d("get receive info for ~p",[MgMid]),
+ MgRH = user_info(MgMid, receive_handle),
+ d("get receive info for ~p",[MgcMid]),
+ MgcRH = user_info(MgcMid, receive_handle),
+ d("start transport",[]),
+ {ok, MgPid, MgSH} =
+ ?VERIFY({ok, _, _}, UserMod:start_transport(MgRH, MgcRH)),
+ PrelMgCH = #megaco_conn_handle{local_mid = MgMid,
+ remote_mid = preliminary_mid},
+ MgCH = #megaco_conn_handle{local_mid = MgMid,
+ remote_mid = MgcMid},
+ MgcCH = #megaco_conn_handle{local_mid = MgcMid,
+ remote_mid = MgMid},
+ d("(MG) try connect to MGC",[]),
+ ?SEND(megaco:connect(MgRH, PrelMid, MgSH, MgPid)), % Mg prel
+ d("await connect from MG",[]),
+ ?USER({connect, PrelMgCH, _V, []}, ok),
+ ?RECEIVE([{res, _, {ok, PrelMgCH}}]),
+
+ d("(MG) send service change request",[]),
+ Req = service_change_request(),
+ ?SEND(megaco:call(PrelMgCH, [Req], [])),
+
+ d("(MGC) send service change reply",[]),
+ ?USER({connect, MgcCH, _V, [ExtraInfo]}, ok), % Mgc auto
+ Rep = service_change_reply(MgcMid),
+ ?USER({request, MgcCH, _V, [[Req], ExtraInfo]}, {discard_ack, [Rep]}),
+ ?USER({connect, MgCH, _V, [ExtraInfo]}, ok), % Mg confirm
+ ?RECEIVE([{res, _, {1, {ok, [Rep], ExtraInfo}}}]),
+
+ d("get (system info) connections",[]),
+ connections([MgCH, MgcCH]),
+ d("get (~p) connections",[MgMid]),
+ ?VERIFY([MgCH], megaco:user_info(MgMid, connections)),
+ d("get (~p) connections",[MgcMid]),
+ ?VERIFY([MgcCH], megaco:user_info(MgcMid, connections)),
+
+ Reason = shutdown,
+ d("(MG) disconnect",[]),
+ ?SEND(megaco:disconnect(MgCH, Reason)),
+ ?USER({disconnect, MgCH, _V, [{user_disconnect, Reason}]}, ok),
+ ?RECEIVE([{res, _, ok}]),
+ ?VERIFY(ok, megaco:stop_user(MgMid)),
+
+ d("(MGC) disconnect",[]),
+ ?SEND(megaco:disconnect(MgcCH, Reason)),
+ ?USER({disconnect, MgcCH, _V, [{user_disconnect, Reason}]}, ok),
+ ?RECEIVE([{res, _, ok}]),
+ ?VERIFY(ok, megaco:stop_user(MgcMid)),
+
+ d("stop megaco app",[]),
+ ?VERIFY(ok, application:stop(megaco)),
+ ?RECEIVE([]),
+
+ d("stop test case controller",[]),
+ ok = megaco_tc_controller:stop(),
+
+ d("done",[]),
+ ok.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+otp_6865_request_and_reply_plain_extra2(suite) ->
+ [];
+otp_6865_request_and_reply_plain_extra2(doc) ->
+ [];
+otp_6865_request_and_reply_plain_extra2(Config) when is_list(Config) ->
+ put(verbosity, ?TEST_VERBOSITY),
+ put(sname, "TEST"),
+ put(tc, otp6865e2),
+ i("starting"),
+
+ d("start tc controller"),
+ ok = megaco_tc_controller:start_link(),
+
+ %% Instruct the transport module to fail all send_message
+ d("instruct transport module to provide extra info: ", []),
+ ExtraInfo = otp6865e2_extra_info,
+ ok = megaco_tc_controller:insert(extra_transport_info, ExtraInfo),
+
+ MgcNode = make_node_name(mgc),
+ MgNode = make_node_name(mg),
+ d("start nodes: "
+ "~n MgcNode: ~p"
+ "~n MgNode: ~p",
+ [MgcNode, MgNode]),
+ ok = megaco_test_lib:start_nodes([MgcNode, MgNode], ?FILE, ?LINE),
+
+
+ d("[MGC] start the simulator "),
+ {ok, Mgc} = megaco_test_megaco_generator:start_link("MGC", MgcNode),
+
+ d("[MGC] create the event sequence"),
+ MgcEvSeq = otp6865e2_mgc_event_sequence(ExtraInfo, text, tcp),
+
+ i("wait some time before starting the MGC simulation"),
+ sleep(1000),
+
+ d("[MGC] start the simulation"),
+ {ok, MgcId} = megaco_test_megaco_generator:exec(Mgc, MgcEvSeq),
+
+ i("wait some time before starting the MG simulator"),
+ sleep(1000),
+
+ d("[MG] start the simulator (generator)"),
+ {ok, Mg} = megaco_test_tcp_generator:start_link("MG", MgNode),
+
+ d("[MG] create the event sequence"),
+ MgEvSeq = otp6865e2_mg_event_sequence(text, tcp),
+
+ i("wait some time before starting the MG simulation"),
+ sleep(1000),
+
+ d("[MG] start the simulation"),
+ {ok, MgId} = megaco_test_tcp_generator:exec(Mg, MgEvSeq),
+
+ d("await the generator reply(s)"),
+ await_completion([MgcId, MgId], 60000),
+
+ %% Tell Mgc to stop
+ i("[MGC] stop generator"),
+ megaco_test_megaco_generator:stop(Mgc),
+
+ %% Tell Mg to stop
+ i("[MG] stop generator"),
+ megaco_test_tcp_generator:stop(Mg),
+
+ i("stop tc controller"),
+ ok = megaco_tc_controller:stop(),
+
+ i("done", []),
+ ok.
+
+
+%%
+%% MGC generator stuff
+%%
+-ifdef(megaco_hipe_special).
+-define(otp6865e2_mgc_verify_handle_connect_fun(ExtraInfo),
+ {?MODULE, otp6865e2_mgc_verify_handle_connect, [ExtraInfo]}).
+-define(otp6865e2_mgc_verify_service_change_req_fun(Mid, ExtraInfo),
+ {?MODULE, otp6865e2_mgc_verify_service_change_req, [Mid, ExtraInfo]}).
+-define(otp6865e2_mgc_verify_notify_req_fun(Cid, ExtraInfo, RequireAck),
+ {?MODULE, otp6865e2_mgc_verify_notify_req, [Cid, ExtraInfo, RequireAck]}).
+-define(otp6865e2_mgc_verify_reply_ack_fun(ExtraInfo),
+ {?MODULE, otp6865e2_mgc_verify_reply_ack, [ExtraInfo]}).
+-define(otp6865e2_mgc_verify_notify_reply_fun(ExtraInfo),
+ {?MODULE, otp6865e2_mgc_verify_notify_reply, [ExtraInfo]}).
+-define(otp6865e2_mgc_verify_handle_disconnect_fun(),
+ {?MODULE, otp6865e2_mgc_verify_handle_disconnect, []}).
+-else.
+-define(otp6865e2_mgc_verify_handle_connect_fun(ExtraInfo),
+ otp6865e2_mgc_verify_handle_connect(ExtraInfo)).
+-define(otp6865e2_mgc_verify_service_change_req_fun(Mid, ExtraInfo),
+ otp6865e2_mgc_verify_service_change_req_fun(Mid, ExtraInfo)).
+-define(otp6865e2_mgc_verify_notify_req_fun(Cid, ExtraInfo, RequireAck),
+ otp6865e2_mgc_verify_notify_req_fun(Cid, ExtraInfo, RequireAck)).
+-define(otp6865e2_mgc_verify_reply_ack_fun(ExtraInfo),
+ otp6865e2_mgc_verify_reply_ack_fun(ExtraInfo)).
+-define(otp6865e2_mgc_verify_notify_reply_fun(ExtraInfo),
+ otp6865e2_mgc_verify_notify_reply_fun(ExtraInfo)).
+-define(otp6865e2_mgc_verify_handle_disconnect_fun(),
+ fun otp6865e2_mgc_verify_handle_disconnect/1).
+-endif.
+
+otp6865e2_mgc_event_sequence(ExtraInfo, text, tcp) ->
+ Mid = {deviceName,"ctrl"},
+ RI = [
+ {port, 2944},
+ {encoding_module, megaco_pretty_text_encoder},
+ {encoding_config, []},
+ {transport_module, megaco_tcp}
+ ],
+ ConnectVerify =
+ ?otp6865e2_mgc_verify_handle_connect_fun(ExtraInfo),
+ ServiceChangeReqVerify =
+ ?otp6865e2_mgc_verify_service_change_req_fun(Mid, ExtraInfo),
+ NotifyReqVerify1 =
+ ?otp6865e2_mgc_verify_notify_req_fun(1, ExtraInfo, false),
+ NotifyReqVerify2 =
+ ?otp6865e2_mgc_verify_notify_req_fun(2, ExtraInfo, true),
+ AckVerify = ?otp6865e2_mgc_verify_reply_ack_fun(ExtraInfo),
+ Tid = #megaco_term_id{id = ["00000000","00000000","01101101"]},
+ NotifyReq = [otp6865e2_mgc_notify_request_ar(1, Tid, 1)],
+ NotifyReplyVerify = ?otp6865e2_mgc_verify_notify_reply_fun(ExtraInfo),
+ DiscoVerify =
+ ?otp6865e2_mgc_verify_handle_disconnect_fun(),
+ EvSeq = [
+ {debug, true},
+ {megaco_trace, disable},
+ megaco_start,
+ {megaco_start_user, Mid, RI, []},
+ start_transport,
+ listen,
+ {megaco_callback, handle_connect, ConnectVerify},
+ {megaco_callback, handle_trans_request, ServiceChangeReqVerify},
+ {megaco_callback, handle_trans_request, NotifyReqVerify1},
+ {megaco_callback, handle_trans_request, NotifyReqVerify2},
+ {megaco_callback, handle_trans_ack, AckVerify},
+ {megaco_cast, NotifyReq, []},
+ {megaco_callback, handle_trans_reply, NotifyReplyVerify},
+ {megaco_callback, handle_disconnect, DiscoVerify},
+ {sleep, 1000},
+ megaco_stop_user,
+ megaco_stop
+ ],
+ EvSeq.
+
+
+-ifndef(megaco_hipe_special).
+otp6865e2_mgc_verify_handle_connect(ExtraInfo) ->
+ fun(Req) ->
+ otp6865e2_mgc_verify_handle_connect(Req, ExtraInfo)
+ end.
+-endif.
+
+otp6865e2_mgc_verify_handle_connect({handle_connect, CH, ?VERSION, ExtraInfo},
+ ExtraInfo) ->
+ io:format("otp6865e2_mgc_verify_handle_connect -> ok"
+ "~n CH: ~p~n", [CH]),
+ {ok, CH, ok};
+otp6865e2_mgc_verify_handle_connect(Else, ExtraInfo) ->
+ io:format("otp6865e2_mgc_verify_handle_connect -> unknown"
+ "~n Else: ~p"
+ "~n ExtraInfo: ~p"
+ "~n", [Else, ExtraInfo]),
+ {error, {Else, ExtraInfo}, ok}.
+
+-ifndef(megaco_hipe_special).
+otp6865e2_mgc_verify_service_change_req_fun(Mid, ExtraInfo) ->
+ fun(Req) ->
+ otp6865e2_mgc_verify_service_change_req(Req, Mid, ExtraInfo)
+ end.
+-endif.
+
+otp6865e2_mgc_verify_service_change_req(
+ {handle_trans_request, _, ?VERSION, [AR], ExtraInfo}, Mid, ExtraInfo) ->
+ (catch otp6865e2_mgc_do_verify_service_change_req(AR, Mid));
+otp6865e2_mgc_verify_service_change_req(Crap, _Mid, ExtraInfo) ->
+ ED = cre_ErrDesc({Crap, ExtraInfo}),
+ ErrReply = {discard_ack, ED},
+ {error, {Crap, ExtraInfo}, ErrReply}.
+
+otp6865e2_mgc_do_verify_service_change_req(AR, Mid) ->
+ io:format("otp6865e2_mgc_verify_service_change_req -> ok"
+ "~n AR: ~p"
+ "~n Mid: ~p"
+ "~n", [AR, Mid]),
+ CR =
+ case AR of
+ #'ActionRequest'{commandRequests = [CmdReq]} ->
+ CmdReq;
+ _ ->
+ Err1 = {invalid_action_request, AR},
+ ED1 = cre_ErrDesc(AR),
+ ErrReply1 = {discard_ack, ED1},
+ throw({error, Err1, ErrReply1})
+ end,
+ Cmd =
+ case CR of
+ #'CommandRequest'{command = Command} ->
+ Command;
+ _ ->
+ Err2 = {invalid_command_request, CR},
+ ED2 = cre_ErrDesc(CR),
+ ErrReply2 = {discard_ack, ED2},
+ throw({error, Err2, ErrReply2})
+ end,
+ {Tid, Parms} =
+ case Cmd of
+ {serviceChangeReq,
+ #'ServiceChangeRequest'{terminationID = [TermID],
+ serviceChangeParms = ServChParms}} ->
+ {TermID, ServChParms};
+ _ ->
+ Err3 = {invalid_command, Cmd},
+ ED3 = cre_ErrDesc(Cmd),
+ ErrReply3 = {discard_ack, ED3},
+ throw({error, Err3, ErrReply3})
+ end,
+ case Tid of
+ #megaco_term_id{contains_wildcards = false, id = ["root"]} ->
+ ok;
+ _ ->
+ Err4 = {invalid_termination_id, Tid},
+ ED4 = cre_ErrDesc(Tid),
+ ErrReply4 = {discard_ack, ED4},
+ throw({error, Err4, ErrReply4})
+ end,
+ case Parms of
+ #'ServiceChangeParm'{serviceChangeMethod = restart,
+ serviceChangeReason = [[$9,$0,$1|_]]} ->
+ AckData = [otp6865e2_mgc_service_change_reply_ar(Mid, 1)],
+ Reply = {discard_ack, AckData},
+ {ok, AR, Reply};
+ _ ->
+ Err5 = {invalid_SCP, Parms},
+ ED5 = cre_ErrDesc(Parms),
+ ErrReply5 = {discard_ack, ED5},
+ {error, Err5, ErrReply5}
+ end.
+
+-ifndef(megaco_hipe_special).
+otp6865e2_mgc_verify_notify_req_fun(Cid, ExtraInfo, RequireAck) ->
+ fun(Req) ->
+ otp6865e2_mgc_verify_notify_req(Req, Cid, ExtraInfo, RequireAck)
+ end.
+-endif.
+
+otp6865e2_mgc_verify_notify_req(
+ {handle_trans_request, _, ?VERSION, [AR], ExtraInfo},
+ Cid, ExtraInfo, RequireAck) ->
+ (catch otp6865e2_mgc_do_verify_notify_req(AR, Cid, RequireAck));
+otp6865e2_mgc_verify_notify_req(Crap, _Cid, ExtraInfo, _RequireAck) ->
+ ED = cre_ErrDesc({Crap, ExtraInfo}),
+ ErrReply = {discard_ack, ED},
+ {error, {Crap, ExtraInfo}, ErrReply}.
+
+otp6865e2_mgc_do_verify_notify_req(AR, Cid, RequireAck) ->
+ io:format("otp6865e2_mgc_do_verify_notify_req -> entry with"
+ "~n AR: ~p"
+ "~n Cid: ~p"
+ "~n RequireAck: ~p"
+ "~n", [AR, Cid, RequireAck]),
+ {ContextID, CR} =
+ case AR of
+ #'ActionRequest'{contextId = CtxID,
+ commandRequests = [CmdReq]} when (CtxID == Cid) ->
+ {CtxID, CmdReq};
+ _ ->
+ Err1 = {invalid_action_request, AR},
+ ED1 = cre_ErrDesc(AR),
+ ErrReply1 = {discard_ack, ED1},
+ throw({error, Err1, ErrReply1})
+ end,
+ Cmd =
+ case CR of
+ #'CommandRequest'{command = Command} ->
+ Command;
+ _ ->
+ Err2 = {invalid_command_request, CR},
+ ED2 = cre_ErrDesc(CR),
+ ErrReply2 = {discard_ack, ED2},
+ throw({error, Err2, ErrReply2})
+ end,
+ NR =
+ case Cmd of
+ {notifyReq, NotifReq} ->
+ NotifReq;
+ _ ->
+ Err3 = {invalid_command, Cmd},
+ ED3 = cre_ErrDesc(Cmd),
+ ErrReply3 = {discard_ack, ED3},
+ throw({error, Err3, ErrReply3})
+ end,
+ {Tid, OED} =
+ case NR of
+ #'NotifyRequest'{terminationID = [TermID],
+ observedEventsDescriptor = ObsEvsDesc,
+ errorDescriptor = asn1_NOVALUE} ->
+ {TermID, ObsEvsDesc};
+ _ ->
+ Err4 = {invalid_NR, NR},
+ ED4 = cre_ErrDesc(NR),
+ ErrReply4 = {discard_ack, ED4},
+ throw({error, Err4, ErrReply4})
+ end,
+ OE =
+ case OED of
+ #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
+ ObsEvLst;
+ _ ->
+ Err5 = {invalid_OED, OED},
+ ED5 = cre_ErrDesc(NR),
+ ErrReply5 = {discard_ack, ED5},
+ throw({error, Err5, ErrReply5})
+ end,
+ case OE of
+ #'ObservedEvent'{eventName = "al/of"} ->
+ Replies = [otp6865e2_mgc_notify_reply_ar(ContextID, Tid)],
+ Reply =
+ case RequireAck of
+ true ->
+ {{handle_ack, otp6865e2}, Replies};
+ false ->
+ {discard_ack, Replies}
+ end,
+ {ok, AR, Reply};
+ _ ->
+ Err6 = {invalid_OE, OE},
+ ED6 = cre_ErrDesc(OE),
+ ErrReply6 = {discard_ack, ED6},
+ {error, Err6, ErrReply6}
+ end.
+
+%% Ack verification
+-ifndef(megaco_hipe_special).
+otp6865e2_mgc_verify_reply_ack_fun(ExtraInfo) ->
+ fun(M) ->
+ otp6865e2_mgc_verify_reply_ack(M, ExtraInfo)
+ end.
+-endif.
+
+otp6865e2_mgc_verify_reply_ack(
+ {handle_trans_ack, _, ?VERSION, ok, otp6865e2, ExtraInfo}, ExtraInfo) ->
+ io:format("otp6865e2_mgc_verify_reply_ack -> ok~n", []),
+ {ok, ok, ok};
+otp6865e2_mgc_verify_reply_ack(
+ {handle_trans_ack, _, ?VERSION, AS, AD, ExtraInfo1} = Crap, ExtraInfo2) ->
+ io:format("otp6865e2_mgc_verify_reply_ack -> incorrect ack-status:"
+ "~n AS: ~p"
+ "~n AD: ~p"
+ "~n ExtraInfo1: ~p"
+ "~n ExtraInfo2: ~p"
+ "~n", [AS, AD, ExtraInfo1, ExtraInfo2]),
+ ED = cre_ErrDesc({invalid_ack_status,
+ {AS, AD, ExtraInfo1, ExtraInfo2}}),
+ ErrReply = {discard_ack, ED},
+ {error, Crap, ErrReply};
+otp6865e2_mgc_verify_reply_ack(Crap, ExtraInfo) ->
+ io:format("otp6865e2_mgc_verify_reply_ack -> invalid ack:"
+ "~n Crap: ~p"
+ "~n ExtraInfo: ~p"
+ "~n", [Crap, ExtraInfo]),
+ ED = cre_ErrDesc({Crap, ExtraInfo}),
+ ErrReply = {discard_ack, ED},
+ {error, Crap, ErrReply}.
+
+
+%% Notify reply verification
+-ifndef(megaco_hipe_special).
+otp6865e2_mgc_verify_notify_reply_fun(ExtraInfo) ->
+ fun(Rep) ->
+ otp6865e2_mgc_verify_notify_reply(Rep, ExtraInfo)
+ end.
+-endif.
+
+otp6865e2_mgc_verify_notify_reply(
+ {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _, ExtraInfo}, ExtraInfo) ->
+ io:format("otp6865e2_mgc_verify_notify_reply -> ok"
+ "~n AR: ~p"
+ "~n ExtraInfo: ~p"
+ "~n", [AR, ExtraInfo]),
+ {ok, AR, ok};
+otp6865e2_mgc_verify_notify_reply(Else, ExtraInfo) ->
+ io:format("otp6865e2_mgc_verify_notify_reply -> received unknown event"
+ "~n Else: ~p"
+ "~n ExtraInfo: ~p"
+ "~n", [Else, ExtraInfo]),
+ {error, {Else, ExtraInfo}, ok}.
+
+
+%% Disconnect verification
+otp6865e2_mgc_verify_handle_disconnect(
+ {handle_disconnect, CH, ?VERSION, R}) ->
+ io:format("otp6865e2_mgc_verify_handle_disconnect -> ok"
+ "~n CH: ~p"
+ "~n R: ~p"
+ "~n", [CH, R]),
+ {ok, CH, ok};
+otp6865e2_mgc_verify_handle_disconnect(Else) ->
+ io:format("otp6865e2_mgc_verify_handle_disconnect -> unknown"
+ "~n Else: ~p~n", [Else]),
+ {error, Else, ok}.
+
+
+otp6865e2_mgc_service_change_reply_ar(Mid, Cid) ->
+ SCRP = cre_serviceChangeResParm(Mid),
+ SCRes = cre_serviceChangeResult(SCRP),
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = cre_serviceChangeReply([Root], SCRes),
+ CR = cre_cmdReply(SCR),
+ cre_actionReply(Cid, [CR]).
+
+otp6865e2_mgc_notify_reply_ar(Cid, TermId) ->
+ NR = cre_notifyReply([TermId]),
+ CR = cre_cmdReply(NR),
+ cre_actionReply(Cid, [CR]).
+
+otp6865e2_mgc_notify_request_ar(Rid, Tid, Cid) ->
+ TT = cre_timeNotation("19990729", "22000000"),
+ Ev = cre_obsEvent("al/of", TT),
+ EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
+ NR = cre_notifyReq([Tid], EvsDesc),
+ CMD = cre_command(NR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+
+%%
+%% MG generator stuff
+%%
+-ifdef(megaco_hipe_special).
+-define(otp6865e2_mg_decode_msg_fun(Mod, Conf),
+ {?MODULE, decode_msg, [Mod, Conf]}).
+-define(otp6865e2_mg_encode_msg_fun(Mod, Conf),
+ {?MODULE, encode_msg, [Mod, Conf]}).
+-define(otp6865e2_mg_verify_service_change_rep_msg_fun(),
+ {?MODULE, otp6865e2_mg_verify_service_change_rep_msg, []}).
+-define(otp6865e2_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId, AckRequired),
+ {?MODULE, otp6865e2_mg_verify_notify_rep_msg, [TermId, TransId, ReqId, CtxId, AckRequired]}).
+-define(otp6865e2_mg_verify_notify_req_msg_fun(),
+ {?MODULE, otp6865e2_mg_verify_notify_req_msg, []}).
+-else.
+-define(otp6865e2_mg_decode_msg_fun(Mod, Conf),
+ otp6865e2_mg_decode_msg_fun(Mod, Conf)).
+-define(otp6865e2_mg_encode_msg_fun(Mod, Conf),
+ otp6865e2_mg_encode_msg_fun(Mod, Conf)).
+-define(otp6865e2_mg_verify_service_change_rep_msg_fun(),
+ otp6865e2_mg_verify_service_change_rep_msg_fun()).
+-define(otp6865e2_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId, AckRequired),
+ otp6865e2_mg_verify_notify_rep_msg_fun(TermId, TransId, ReqId, CtxId, AckRequired)).
+-define(otp6865e2_mg_verify_notify_req_msg_fun(),
+ otp6865e2_mg_verify_notify_req_msg_fun()).
+-endif.
+
+otp6865e2_mg_event_sequence(text, tcp) ->
+ DecodeFun = ?otp6865e2_mg_decode_msg_fun(megaco_pretty_text_encoder, []),
+ EncodeFun = ?otp6865e2_mg_encode_msg_fun(megaco_pretty_text_encoder, []),
+ Mid = {deviceName,"mg"},
+ ServiceChangeReq = otp6865e2_mg_service_change_request_msg(Mid, 1, 0),
+ ScrVerifyFun = ?otp6865e2_mg_verify_service_change_rep_msg_fun(),
+ TermId1 = #megaco_term_id{id = ["00000000","00000000","01101101"]},
+ TermId2 = #megaco_term_id{id = ["00000000","00000000","10010010"]},
+ NotifyReq1 =
+ otp6865e2_mg_notify_request_msg(Mid, TermId1, 2, 1, 1),
+ NrVerifyFun1 =
+ ?otp6865e2_mg_verify_notify_rep_msg_fun(TermId1, 2, 1, 1, false),
+ NotifyReq2 =
+ otp6865e2_mg_notify_request_msg(Mid, TermId2, 3, 2, 2),
+ NrVerifyFun2 =
+ ?otp6865e2_mg_verify_notify_rep_msg_fun(TermId2, 3, 2, 2, true),
+ TransAck = otp6865e2_mg_trans_ack_msg(Mid, 3),
+ NotifyReqVerifyFun = ?otp6865e2_mg_verify_notify_req_msg_fun(),
+ NotifyReply = otp6865e2_mg_notify_reply_msg(Mid, 1, 0, TermId1),
+ EvSeq = [{debug, true},
+ {decode, DecodeFun},
+ {encode, EncodeFun},
+ {connect, 2944},
+
+ {send, "service-change-request", ServiceChangeReq},
+ {expect_receive, "service-change-reply", {ScrVerifyFun, 10000}},
+
+ %% the original setting for reply timer is 2000
+ {send, "notify request 1", NotifyReq1},
+ {expect_receive, "notify-reply 1", {NrVerifyFun1, 2500}},
+ {sleep, 1000},
+ {send, "notify request 2", NotifyReq2},
+ {expect_receive, "notify-reply 2", {NrVerifyFun2, 2500}},
+ {sleep, 100},
+ {send, "transacktion-ack", TransAck},
+ {expect_receive, "notify-request", {NotifyReqVerifyFun, 2500}},
+ {sleep, 100},
+ {send, "notify-reply", NotifyReply},
+
+ {expect_nothing, 5000},
+ disconnect
+ ],
+ EvSeq.
+
+-ifndef(megaco_hipe_special).
+otp6865e2_mg_encode_msg_fun(Mod, Conf) ->
+ fun(M) ->
+ encode_msg(M, Mod, Conf)
+ end.
+-endif.
+
+-ifndef(megaco_hipe_special).
+otp6865e2_mg_decode_msg_fun(Mod, Conf) ->
+ fun(M) ->
+ decode_msg(M, Mod, Conf)
+ end.
+-endif.
+
+-ifndef(megaco_hipe_special).
+otp6865e2_mg_verify_service_change_rep_msg_fun() ->
+ fun(Msg) ->
+ (catch otp6865e2_mg_verify_service_change_rep_msg(Msg))
+ end.
+-endif.
+
+otp6865e2_mg_verify_service_change_rep_msg(#'MegacoMessage'{mess = Mess} = M) ->
+ Body =
+ case Mess of
+ #'Message'{version = _V,
+ mId = _MgMid,
+ messageBody = MsgBody} ->
+ MsgBody;
+ _ ->
+ throw({error, {invalid_Message, Mess}})
+ end,
+ Trans =
+ case Body of
+ {transactions, [Transactions]} ->
+ Transactions;
+ _ ->
+ throw({error, {invalid_messageBody, Body}})
+ end,
+ TR =
+ case Trans of
+ {transactionReply, TransReply} ->
+ TransReply;
+ _ ->
+ throw({error, {invalid_transactions, Trans}})
+ end,
+ TRes =
+ case TR of
+ #'TransactionReply'{transactionId = _Tid,
+ immAckRequired = asn1_NOVALUE,
+ transactionResult = TransRes} ->
+ TransRes;
+ _ ->
+ throw({error, {invalid_transactionReply, TR}})
+ end,
+ AR =
+ case TRes of
+ {actionReplies, [ActRes]} ->
+ ActRes;
+ _ ->
+ throw({error, {invalid_transactionResult, TRes}})
+ end,
+ CR =
+ case AR of
+ #'ActionReply'{contextId = _Cid,
+ errorDescriptor = asn1_NOVALUE,
+ contextReply = _CtxReq,
+ commandReply = [CmdRep]} ->
+ CmdRep;
+ _ ->
+ throw({error, {invalid_actionReplies, AR}})
+ end,
+ SCR =
+ case CR of
+ {serviceChangeReply, ServChRep} ->
+ ServChRep;
+ _ ->
+ throw({error, {invalid_commandReply, CR}})
+ end,
+ SCRes =
+ case SCR of
+ #'ServiceChangeReply'{terminationID = _TermID,
+ serviceChangeResult = ServChRes} ->
+ ServChRes;
+ _ ->
+ throw({error, {invalid_serviceChangeReply, SCR}})
+ end,
+ SCRP =
+ case SCRes of
+ {serviceChangeResParms, Parms} ->
+ Parms;
+ _ ->
+ throw({error, {invalid_serviceChangeResult, SCRes}})
+ end,
+ case SCRP of
+ #'ServiceChangeResParm'{serviceChangeMgcId = _MgcMid} ->
+ {ok, M};
+ _ ->
+ {error, {invalid_serviceChangeResParms, SCRP}}
+ end;
+otp6865e2_mg_verify_service_change_rep_msg(Crap) ->
+ {error, {invalid_message, Crap}}.
+
+-ifndef(megaco_hipe_special).
+otp6865e2_mg_verify_notify_rep_msg_fun(TermId, TransId, Rid, Cid,
+ AckRequired) ->
+ fun(Msg) ->
+ (catch otp6865e2_mg_verify_notify_rep_msg(Msg,
+ TermId, TransId,
+ Rid, Cid,
+ AckRequired))
+ end.
+-endif.
+
+otp6865e2_mg_verify_notify_rep_msg(#'MegacoMessage'{mess = Mess} = M,
+ TermId, TransId, Rid, Cid, AckRequired) ->
+ io:format("otp6865e2_mg_verify_notify_rep_msg -> entry with"
+ "~n M: ~p"
+ "~n TermId: ~p"
+ "~n TransId: ~p"
+ "~n Rid: ~p"
+ "~n Cid: ~p"
+ "~n", [M, TermId, TransId, Rid, Cid]),
+ Body =
+ case Mess of
+ #'Message'{version = ?VERSION,
+ mId = _Mid,
+ messageBody = MsgBody} ->
+ MsgBody;
+ _ ->
+ throw({error, {invalid_Message, Mess}})
+ end,
+ io:format("otp6865e2_mg_verify_notify_rep_msg -> "
+ "~n Body: ~p"
+ "~n", [Body]),
+ Trans =
+ case Body of
+ {transactions, [Transactions]} ->
+ Transactions;
+ _ ->
+ throw({error, {invalid_messageBody, Body}})
+ end,
+ io:format("otp6865e2_mg_verify_notify_rep_msg -> "
+ "~n Trans: ~p"
+ "~n", [Trans]),
+ TR =
+ case Trans of
+ {transactionReply, TransReply} ->
+ TransReply;
+ _ ->
+ throw({error, {invalid_transactions, Trans}})
+ end,
+ io:format("otp6865e2_mg_verify_notify_rep_msg -> "
+ "~n TR: ~p"
+ "~n", [TR]),
+ TRes =
+ case TR of
+ #'TransactionReply'{transactionId = TransId,
+ immAckRequired = asn1_NOVALUE,
+ transactionResult = TransRes} when (AckRequired == false) ->
+ TransRes;
+ #'TransactionReply'{transactionId = TransId,
+ immAckRequired = 'NULL',
+ transactionResult = TransRes} when (AckRequired == true) ->
+ TransRes;
+ _ ->
+ throw({error, {invalid_transactionReply, TR}})
+ end,
+ io:format("otp6865e2_mg_verify_notify_rep_msg -> "
+ "~n TRes: ~p"
+ "~n", [TRes]),
+ AR =
+ case TRes of
+ {actionReplies, [ActRes]} ->
+ ActRes;
+ _ ->
+ throw({error, {invalid_transactionResult, TRes}})
+ end,
+ io:format("otp6865e2_mg_verify_notify_rep_msg -> "
+ "~n AR: ~p"
+ "~n", [AR]),
+ CR =
+ case AR of
+ #'ActionReply'{contextId = Cid,
+ errorDescriptor = asn1_NOVALUE,
+ contextReply = _CtxReq,
+ commandReply = [CmdRep]} ->
+ CmdRep;
+ _ ->
+ throw({error, {invalid_actionReplies, AR}})
+ end,
+ NR =
+ case CR of
+ {notifyReply, NotifyReply} ->
+ NotifyReply;
+ _ ->
+ throw({error, {invalid_commandReply, CR}})
+ end,
+ case NR of
+ #'NotifyReply'{terminationID = [TermId],
+ errorDescriptor = asn1_NOVALUE} ->
+ {ok, M};
+ _ ->
+ {error, {invalid_notifyReply, NR}}
+ end;
+otp6865e2_mg_verify_notify_rep_msg(Crap, _TermId, _TransId, _Rid, _Cid, _AckRequired) ->
+ {error, {invalid_message, Crap}}.
+
+-ifndef(megaco_hipe_special).
+otp6865e2_mg_verify_notify_req_msg_fun() ->
+ fun(M) ->
+ otp6865e2_mg_verify_notify_req_msg(M)
+ end.
+-endif.
+
+otp6865e2_mg_verify_notify_req_msg(#'MegacoMessage'{mess = Mess} = M) ->
+ io:format("otp6865e2_mg_verify_notify_req_msg -> entry with"
+ "~n M: ~p"
+ "~n", [M]),
+ Body =
+ case Mess of
+ #'Message'{version = ?VERSION,
+ mId = _Mid,
+ messageBody = MsgBody} ->
+ MsgBody;
+ _ ->
+ throw({error, {invalid_Message, Mess}})
+ end,
+ io:format("otp6865e2_mg_verify_notify_req_msg -> "
+ "~n Body: ~p"
+ "~n", [Body]),
+ Trans =
+ case Body of
+ {transactions, [Transactions]} ->
+ Transactions;
+ _ ->
+ throw({error, {invalid_messageBody, Body}})
+ end,
+ io:format("otp6865e2_mg_verify_notify_req_msg -> "
+ "~n Trans: ~p"
+ "~n", [Trans]),
+ TR =
+ case Trans of
+ {transactionRequest, TransRequest} ->
+ TransRequest;
+ _ ->
+ throw({error, {invalid_transactions, Trans}})
+ end,
+ io:format("otp6865e2_mg_verify_notify_req_msg -> "
+ "~n TR: ~p"
+ "~n", [TR]),
+ AR =
+ case TR of
+ #'TransactionRequest'{transactionId = _TransId,
+ actions = [ActReq]} ->
+ ActReq;
+ _ ->
+ throw({error, {invalid_transactionRequest, TR}})
+ end,
+ io:format("otp6865e2_mg_verify_notify_req_msg -> "
+ "~n AR: ~p"
+ "~n", [AR]),
+ CR =
+ case AR of
+ #'ActionRequest'{contextId = _Cid,
+ commandRequests = [CmdReq]} ->
+ CmdReq;
+ _ ->
+ throw({error, {invalid_actions, AR}})
+ end,
+ io:format("otp6865e2_mg_verify_notify_req_msg -> "
+ "~n CR: ~p"
+ "~n", [CR]),
+ Cmd =
+ case CR of
+ #'CommandRequest'{command = Command} ->
+ Command;
+ _ ->
+ throw({error, {invalid_commandRequests, CR}})
+ end,
+ io:format("otp6865e2_mg_verify_notify_req_msg -> "
+ "~n Cmd: ~p"
+ "~n", [Cmd]),
+ NR =
+ case Cmd of
+ {notifyReq, NotifReq} ->
+ NotifReq;
+ _ ->
+ throw({error, {invalid_command, Cmd}})
+ end,
+ io:format("otp6865e2_mg_verify_notify_req_msg -> "
+ "~n NR: ~p"
+ "~n", [NR]),
+ OED =
+ case NR of
+ #'NotifyRequest'{terminationID = [_TermId],
+ observedEventsDescriptor = ObsEvsDesc,
+ errorDescriptor = asn1_NOVALUE} ->
+ ObsEvsDesc;
+ _ ->
+ throw({error, {invalid_notifyReq, NR}})
+ end,
+ io:format("otp6865e2_mg_verify_notify_req_msg -> "
+ "~n OED: ~p"
+ "~n", [OED]),
+ OE =
+ case OED of
+ #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
+ ObsEvLst;
+ _ ->
+ throw({error, {invalid_observedEventsDescriptor, OED}})
+ end,
+ io:format("otp6865e2_mg_verify_notify_req_msg -> "
+ "~n OE: ~p"
+ "~n", [OE]),
+ case OE of
+ #'ObservedEvent'{eventName = "al/of"} ->
+ io:format("otp6865e2_mg_verify_notify_req_msg -> verifyed"
+ "~n", []),
+ {ok, M};
+ _ ->
+ throw({error, {invalid_observedEventLst, OE}})
+ end;
+otp6865e2_mg_verify_notify_req_msg(M) ->
+ {error, {invalid_message, M}}.
+
+otp6865e2_mg_service_change_request_ar(_Mid, Cid) ->
+ Prof = cre_serviceChangeProf("resgw", 1),
+ SCP = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = cre_serviceChangeReq([Root], SCP),
+ CMD = cre_command(SCR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+otp6865e2_mg_service_change_request_msg(Mid, TransId, Cid) ->
+ AR = otp6865e2_mg_service_change_request_ar(Mid, Cid),
+ TR = cre_transReq(TransId, [AR]),
+ Trans = cre_transaction(TR),
+ Mess = cre_message(?VERSION, Mid, cre_transactions([Trans])),
+ cre_megacoMessage(Mess).
+
+otp6865e2_mg_notify_request_ar(Rid, Tid, Cid) ->
+ TT = cre_timeNotation("19990729", "22000000"),
+ Ev = cre_obsEvent("al/of", TT),
+ EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
+ NR = cre_notifyReq([Tid], EvsDesc),
+ CMD = cre_command(NR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+otp6865e2_mg_notify_request_msg(Mid, TermId, TransId, Rid, Cid) ->
+ AR = otp6865e2_mg_notify_request_ar(Rid, TermId, Cid),
+ TR = cre_transReq(TransId, [AR]),
+ Trans = cre_transaction(TR),
+ Mess = cre_message(?VERSION, Mid, cre_transactions([Trans])),
+ cre_megacoMessage(Mess).
+
+otp6865e2_mg_notify_reply_msg(Mid, TransId, Cid, TermId) ->
+ NR = cre_notifyReply([TermId]),
+ CR = cre_cmdReply(NR),
+ AR = cre_actionReply(Cid, [CR]),
+ TRes = {actionReplies, [AR]},
+ TR = cre_transReply(TransId, TRes),
+ Trans = cre_transaction(TR),
+ Mess = cre_message(?VERSION, Mid, cre_transactions([Trans])),
+ cre_megacoMessage(Mess).
+
+otp6865e2_mg_trans_ack_msg(Mid, TransId) ->
+ TR = cre_transRespAck(cre_transAck(TransId)),
+ Trans = cre_transaction(TR),
+ Mess = cre_message(?VERSION, Mid, cre_transactions([Trans])),
+ cre_megacoMessage(Mess).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+otp_7189(suite) ->
+ [];
+otp_7189(doc) ->
+ "...";
+otp_7189(Config) when is_list(Config) ->
+ put(verbosity, ?TEST_VERBOSITY),
+ put(sname, "TEST"),
+ put(tc, otp_7189),
+ i("starting"),
+
+ MgcNode = make_node_name(mgc),
+ MgNode = make_node_name(mg),
+ d("start nodes: "
+ "~n MgcNode: ~p"
+ "~n MgNode: ~p",
+ [MgcNode, MgNode]),
+ ok = megaco_test_lib:start_nodes([MgcNode, MgNode], ?FILE, ?LINE),
+
+ d("[MGC] start the simulator "),
+ {ok, Mgc} = megaco_test_megaco_generator:start_link("MGC", MgcNode),
+
+ d("[MGC] create the event sequence"),
+ MgcEvSeq = otp_7189_mgc_event_sequence(text, tcp),
+
+ i("wait some time before starting the MGC simulation"),
+ sleep(1000),
+
+ d("[MGC] start the simulation"),
+ {ok, MgcId} = megaco_test_megaco_generator:exec(Mgc, MgcEvSeq),
+
+ i("wait some time before starting the MG simulator"),
+ sleep(1000),
+
+ d("[MG] start the simulator (generator)"),
+ {ok, Mg} = megaco_test_tcp_generator:start_link("MG", MgNode),
+
+ d("[MG] create the event sequence"),
+ MgEvSeq = otp_7189_mg_event_sequence(text, tcp),
+
+ i("wait some time before starting the MG simulation"),
+ sleep(1000),
+
+ d("[MG] start the simulation"),
+ {ok, MgId} = megaco_test_tcp_generator:exec(Mg, MgEvSeq),
+
+ d("await the generator reply(s)"),
+ await_completion([MgcId, MgId], 60000),
+
+ %% Tell Mgc to stop
+ i("[MGC] stop generator"),
+ megaco_test_megaco_generator:stop(Mgc),
+
+ %% Tell Mg to stop
+ i("[MG] stop generator"),
+ megaco_test_tcp_generator:stop(Mg),
+
+ i("done", []),
+ ok.
+
+
+%%
+%% MGC generator stuff
+%%
+-ifdef(megaco_hipe_special).
+-define(otp_7189_mgc_verify_handle_connect_fun(),
+ {?MODULE, otp_7189_mgc_verify_handle_connect, []}).
+-define(otp_7189_mgc_verify_service_change_req_fun(Mid),
+ {?MODULE, otp_7189_mgc_verify_service_change_req, [Mid]}).
+-define(otp_7189_mgc_verify_handle_trans_rep_fun(),
+ {?MODULE, otp_7189_mgc_verify_handle_trans_rep, []}).
+-define(otp_7189_mgc_verify_handle_disconnect_fun(),
+ {?MODULE, otp_7189_mgc_verify_handle_disconnect, []}).
+-else.
+-define(otp_7189_mgc_verify_handle_connect_fun(),
+ otp_7189_mgc_verify_handle_connect_fun()).
+-define(otp_7189_mgc_verify_service_change_req_fun(Mid),
+ otp_7189_mgc_verify_service_change_req_fun(Mid)).
+-define(otp_7189_mgc_verify_handle_trans_rep_fun(),
+ otp_7189_mgc_verify_handle_trans_rep_fun()).
+-define(otp_7189_mgc_verify_handle_disconnect_fun(),
+ fun otp_7189_mgc_verify_handle_disconnect/1).
+-endif.
+
+otp_7189_mgc_event_sequence(text, tcp) ->
+ Mid = {deviceName,"ctrl"},
+ RI = [
+ {port, 2944},
+ {encoding_module, megaco_pretty_text_encoder},
+ {encoding_config, []},
+ {transport_module, megaco_tcp}
+ ],
+ Tid = #megaco_term_id{id = ["00000000","00000000","01101101"]},
+ NotifyReq = [otp_7189_mgc_notify_req_ar(1, Tid, 1)],
+ ConnectVerify = ?otp_7189_mgc_verify_handle_connect_fun(),
+ ScrVerify = ?otp_7189_mgc_verify_service_change_req_fun(Mid),
+ TransReplyVerify = ?otp_7189_mgc_verify_handle_trans_rep_fun(),
+ PendingCountersVerify1 =
+ fun([{Counter, 1}]) ->
+ io:format("received expected recv pending counter:"
+ "~n Counter: ~p"
+ "~n", [Counter]),
+ ok;
+ (BadCounters) ->
+ io:format("ERROR: "
+ "received unexpected number of "
+ "recv pending counters "
+ "(expected one with counter value 1):"
+ "~n BadCounters: ~p"
+ "~n", [BadCounters]),
+ {error, {invalid_pending_counters, BadCounters}}
+ end,
+ PendingCountersVerify2 =
+ fun([]) ->
+ io:format("received expected number of recv pending counters (none)"
+ "~n", []),
+ ok;
+ (BadCounters) ->
+ io:format("ERROR: "
+ "received unexpected number of "
+ "recv pending counters "
+ "(expected none):"
+ "~n BadCounters: ~p"
+ "~n", [BadCounters]),
+ {error, {invalid_pending_counters, BadCounters}}
+ end,
+ EvSeq = [
+ {debug, true},
+ {megaco_trace, disable},
+ {megaco_trace, max},
+ megaco_start,
+ {megaco_start_user, Mid, RI, []},
+ {megaco_update_user_info, recv_pending_limit, 10},
+
+ {megaco_update_user_info, long_request_timer, timer:seconds(10)},
+ {megaco_user_info, all},
+ start_transport,
+ listen,
+ {megaco_callback, handle_connect, ConnectVerify},
+ {megaco_conn_info, all},
+ {megaco_callback, handle_trans_request, ScrVerify},
+ {sleep, 500},
+ {megaco_cast, NotifyReq, []},
+
+ %% Wait for 5 seconds to make sure we are on track
+ {megaco_callback, nocall, timer:seconds(5)},
+ {megaco_system_info, recv_pending_counters, PendingCountersVerify1},
+
+ %% Now wait for the timeout to hit
+ {megaco_callback, handle_trans_reply, TransReplyVerify},
+ {megaco_system_info, recv_pending_counters, PendingCountersVerify2},
+
+ megaco_stop_user,
+ megaco_stop
+ ],
+ EvSeq.
+
+
+-ifndef(megaco_hipe_special).
+otp_7189_mgc_verify_handle_connect_fun() ->
+ fun(M) ->
+ otp_7189_mgc_verify_handle_connect(M)
+ end.
+-endif.
+
+otp_7189_mgc_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
+ {ok, CH, ok};
+otp_7189_mgc_verify_handle_connect(Else) ->
+ {error, Else, ok}.
+
+-ifndef(megaco_hipe_special).
+otp_7189_mgc_verify_service_change_req_fun(Mid) ->
+ fun(Req) ->
+ otp_7189_mgc_verify_service_change_req(Req, Mid)
+ end.
+-endif.
+
+otp_7189_mgc_verify_service_change_req(
+ {handle_trans_request, _, ?VERSION, [AR]}, Mid) ->
+ io:format("otp_7189_mgc_verify_service_change_req -> ok"
+ "~n AR: ~p~n", [AR]),
+ case AR of
+ #'ActionRequest'{commandRequests = [CR]} ->
+ case CR of
+ #'CommandRequest'{command = Cmd} ->
+ case Cmd of
+ {serviceChangeReq,
+ #'ServiceChangeRequest'{terminationID = [Tid],
+ serviceChangeParms = Parms}} ->
+ case Tid of
+ #megaco_term_id{contains_wildcards = false,
+ id = ["root"]} ->
+ case Parms of
+ #'ServiceChangeParm'{
+ serviceChangeMethod = restart,
+ serviceChangeReason = [[$9,$0,$1|_]]} ->
+ Reply =
+ {discard_ack,
+ [otp_7189_mgc_service_change_reply_ar(Mid, 1)]},
+ {ok, AR, Reply};
+ _ ->
+ Err = {invalid_SCP, Parms},
+ ED = otp_7189_err_desc(Parms),
+ ErrReply = {discard_ack, ED},
+ {error, Err, ErrReply}
+ end;
+ _ ->
+ Err = {invalid_termination_id, Tid},
+ ED = otp_7189_err_desc(Tid),
+ ErrReply = {discard_ack, ED},
+ {error, Err, ErrReply}
+ end;
+ _ ->
+ Err = {invalid_command, Cmd},
+ ED = otp_7189_err_desc(Cmd),
+ ErrReply = {discard_ack, ED},
+ {error, Err, ErrReply}
+ end;
+ _ ->
+ Err = {invalid_command_request, CR},
+ ED = otp_7189_err_desc(CR),
+ ErrReply = {discard_ack, ED},
+ {error, Err, ErrReply}
+ end;
+ _ ->
+ Err = {invalid_action_request, AR},
+ ED = otp_7189_err_desc(AR),
+ ErrReply = {discard_ack, ED},
+ {error, Err, ErrReply}
+ end;
+otp_7189_mgc_verify_service_change_req(Else, _Mid) ->
+ io:format("otp_7189_mgc_verify_service_change_req -> unknown"
+ "~n Else: ~p~n", [Else]),
+ ED = otp_7189_err_desc(Else),
+ ErrReply = {discard_ack, ED},
+ {error, Else, ErrReply}.
+
+otp_7189_mgc_notify_req_ar(Rid, Tid, Cid) ->
+ TT = cre_timeNotation("19990729", "22000000"),
+ Ev = cre_obsEvent("al/of", TT),
+ EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
+ NR = cre_notifyReq([Tid], EvsDesc),
+ CMD = cre_command(NR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+otp_7189_mgc_service_change_reply_ar(Mid, Cid) ->
+ SCRP = cre_serviceChangeResParm(Mid),
+ SCRes = cre_serviceChangeResult(SCRP),
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = cre_serviceChangeReply([Root], SCRes),
+ CR = cre_cmdReply(SCR),
+ AR = cre_actionReply(Cid, [CR]),
+ AR.
+
+-ifndef(megaco_hipe_special).
+otp_7189_mgc_verify_handle_trans_rep_fun() ->
+ fun(Event) ->
+ (catch otp_7189_mgc_verify_handle_trans_rep(Event))
+ end.
+-endif.
+
+otp_7189_mgc_verify_handle_trans_rep(
+ {handle_trans_reply, CH, ?VERSION, {error, timeout} = Error, _}) ->
+ io:format("otp_6275_mgc_verify_trans_rep -> expected error"
+ "~n CH: ~p"
+ "~n", [CH]),
+ {ok, Error, error};
+otp_7189_mgc_verify_handle_trans_rep(
+ {handle_trans_reply, _CH, ?VERSION, Error, _}) ->
+ io:format("otp_6275_mgc_verify_handle_trans_rep -> unexpected error"
+ "~n Error: ~p"
+ "~n", [Error]),
+ {error, Error, error};
+otp_7189_mgc_verify_handle_trans_rep(Else) ->
+ io:format("otp_6275_mg_verify_handle_trans_rep -> unknown"
+ "~n Else: ~p~n", [Else]),
+ {error, Else, error}.
+
+
+
+%%
+%% MG generator stuff
+%%
+-ifdef(megaco_hipe_special).
+-define(otp_7189_mg_decode_msg_fun(Mod, Conf),
+ {?MODULE, decode_msg, [Mod, Conf]}).
+-define(otp_7189_mg_encode_msg_fun(Mod, Conf),
+ {?MODULE, encode_msg, [Mod, Conf]}).
+-define(otp_7189_mg_verify_service_change_rep_msg_fun(),
+ {?MODULE, otp_7189_mg_verify_service_change_rep_msg, []}).
+-define(otp_7189_mg_verify_notify_req_msg_fun(TermId, TransId, ReqId, CtxId),
+ {?MODULE, otp_7189_mg_verify_notify_req_msg, [TermId, TransId, ReqId, CtxId]}).
+-else.
+-define(otp_7189_mg_decode_msg_fun(Mod, Conf),
+ otp_7189_mg_decode_msg_fun(Mod, Conf)).
+-define(otp_7189_mg_encode_msg_fun(Mod, Conf),
+ otp_7189_mg_encode_msg_fun(Mod, Conf)).
+-define(otp_7189_mg_verify_service_change_rep_msg_fun(),
+ otp_7189_mg_verify_service_change_rep_msg_fun()).
+-define(otp_7189_mg_verify_notify_req_msg_fun(TermId, TransId, ReqId, CtxId),
+ otp_7189_mg_verify_notify_req_msg_fun(TermId, TransId, ReqId, CtxId)).
+-endif.
+
+otp_7189_mg_event_sequence(text, tcp) ->
+ DecodeFun = ?otp_7189_mg_decode_msg_fun(megaco_pretty_text_encoder, []),
+ EncodeFun = ?otp_7189_mg_encode_msg_fun(megaco_pretty_text_encoder, []),
+ Mid = {deviceName,"mg"},
+ ServiceChangeReq = otp_7189_mg_service_change_request_msg(Mid, 1, 0),
+ TermId =
+ #megaco_term_id{id = ["00000000","00000000","01101101"]},
+ TransId = 1,
+ ReqId = 1,
+ CtxId = 1,
+ Pending = otp_7189_mg_trans_pending_msg(Mid, TransId),
+ ServiceChangeReplyVerifyFun =
+ ?otp_7189_mg_verify_service_change_rep_msg_fun(),
+ NotifyReqVerify = ?otp_7189_mg_verify_notify_req_msg_fun(TermId, TransId, ReqId, CtxId),
+ EvSeq = [
+ {debug, true},
+ {decode, DecodeFun},
+ {encode, EncodeFun},
+ {connect, 2944},
+ {send, "service-change-request", ServiceChangeReq},
+ {expect_receive, "service-change-reply", {ServiceChangeReplyVerifyFun, 2000}},
+ {expect_receive, "notify request", {NotifyReqVerify, 2000}},
+ {sleep, 100},
+ {send, "pending", Pending},
+ {expect_closed, timer:seconds(120)},
+ disconnect
+ ],
+ EvSeq.
+
+otp_7189_mg_encode_msg_fun(Mod, Conf) ->
+ fun(M) ->
+ encode_msg(M, Mod, Conf)
+ end.
+
+otp_7189_mg_decode_msg_fun(Mod, Conf) ->
+ fun(M) ->
+ decode_msg(M, Mod, Conf)
+ end.
+
+otp_7189_mg_service_change_request_ar(_Mid, Cid) ->
+ Prof = cre_serviceChangeProf("resgw", 1),
+ SCP = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = cre_serviceChangeReq([Root], SCP),
+ CMD = cre_command(SCR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+otp_7189_mg_service_change_request_msg(Mid, TransId, Cid) ->
+ AR = otp_7189_mg_service_change_request_ar(Mid, Cid),
+ TR = cre_transReq(TransId, [AR]),
+ Trans = cre_transaction(TR),
+ Mess = cre_message(?VERSION, Mid, cre_transactions([Trans])),
+ cre_megacoMessage(Mess).
+
+-ifndef(megaco_hipe_special).
+otp_7189_mg_verify_service_change_rep_msg_fun() ->
+ fun(M) ->
+ otp_7189_mg_verify_service_change_rep_msg(M)
+ end.
+-endif.
+
+otp_7189_mg_verify_service_change_rep_msg(
+ #'MegacoMessage'{mess = Mess} = M) ->
+ io:format("otp_7189_mg_verify_service_change_rep_msg -> "
+ "ok so far~n",[]),
+ #'Message'{version = _V,
+ mId = _MgMid,
+ messageBody = Body} = Mess,
+ {transactions, [Trans]} = Body,
+ {transactionReply, TR} = Trans,
+ #'TransactionReply'{transactionId = _Tid,
+ immAckRequired = asn1_NOVALUE,
+ transactionResult = Res} = TR,
+ {actionReplies, [AR]} = Res,
+ #'ActionReply'{contextId = _Cid,
+ errorDescriptor = asn1_NOVALUE,
+ contextReply = _CtxReq,
+ commandReply = [CR]} = AR,
+ {serviceChangeReply, SCR} = CR,
+ #'ServiceChangeReply'{terminationID = _TermID,
+ serviceChangeResult = SCRes} = SCR,
+ {serviceChangeResParms, SCRP} = SCRes,
+ #'ServiceChangeResParm'{serviceChangeMgcId = _MgcMid} = SCRP,
+ {ok, M};
+otp_7189_mg_verify_service_change_rep_msg(M) ->
+ {error, {invalid_message, M}}.
+
+-ifndef(megaco_hipe_special).
+otp_7189_mg_verify_notify_req_msg_fun(TermId, TransId, Rid, Cid) ->
+ fun(Msg) ->
+ (catch otp_7189_mg_verify_notify_req_msg(Msg,
+ TermId,
+ TransId, Rid, Cid))
+ end.
+-endif.
+
+otp_7189_mg_verify_notify_req_msg(#'MegacoMessage'{mess = Mess} = M,
+ TermId, TransId, Rid, Cid) ->
+ io:format("otp_7189_mgc_verify_notify_req_msg -> entry with"
+ "~n M: ~p"
+ "~n TermId: ~p"
+ "~n TransId: ~p"
+ "~n Rid: ~p"
+ "~n Cid: ~p"
+ "~n", [M, TermId, TransId, Rid, Cid]),
+ Body =
+ case Mess of
+ #'Message'{version = ?VERSION,
+ mId = _Mid,
+ messageBody = MsgBody} ->
+ MsgBody;
+ _ ->
+ throw({error, {invalid_Message, Mess}})
+ end,
+ Trans =
+ case Body of
+ {transactions, [Transactions]} ->
+ Transactions;
+ _ ->
+ throw({error, {invalid_messageBody, Body}})
+ end,
+ TR =
+ case Trans of
+ {transactionRequest, TransRequest} ->
+ TransRequest;
+ _ ->
+ throw({error, {invalid_transactions, Trans}})
+ end,
+ AR =
+ case TR of
+ #'TransactionRequest'{transactionId = TransId,
+ actions = [ActReq]} ->
+ ActReq;
+ _ ->
+ throw({error, {invalid_transactionRequest, TR, TransId}})
+ end,
+ CR =
+ case AR of
+ #'ActionRequest'{contextId = Cid,
+ commandRequests = [CmdReq]} ->
+ CmdReq;
+ _ ->
+ throw({error, {invalid_actions, AR}})
+ end,
+ Cmd =
+ case CR of
+ #'CommandRequest'{command = Command} ->
+ Command;
+ _ ->
+ throw({error, {invalid_commandRequests, CR}})
+ end,
+ NR =
+ case Cmd of
+ {notifyReq, NotifReq} ->
+ NotifReq;
+ _ ->
+ throw({error, {invalid_command, Cmd}})
+ end,
+ OED =
+ case NR of
+ #'NotifyRequest'{terminationID = [TermId],
+ observedEventsDescriptor = ObsEvsDesc,
+ errorDescriptor = asn1_NOVALUE} ->
+ ObsEvsDesc;
+ _ ->
+ throw({error, {invalid_notifyReq, NR}})
+ end,
+ OE =
+ case OED of
+ #'ObservedEventsDescriptor'{observedEventLst = [ObsEvLst]} ->
+ ObsEvLst;
+ _ ->
+ throw({error, {invalid_observedEventsDescriptor, OED}})
+ end,
+ case OE of
+ #'ObservedEvent'{eventName = "al/of"} ->
+ {ok, M};
+ _ ->
+ throw({error, {invalid_observedEventLst, OE}})
+ end;
+otp_7189_mg_verify_notify_req_msg(Crap, _TermId, _TransId, _Rid, _Cid) ->
+ {error, {invalid_MegacoMessage, Crap}}.
+
+
+otp_7189_mg_trans_pending_msg(Mid, TransId) ->
+ TP = #'TransactionPending'{transactionId = TransId},
+ Body = {transactions, [{transactionPending, TP}]},
+ Mess = #'Message'{version = 1,
+ mId = Mid,
+ messageBody = Body},
+ #'MegacoMessage'{mess = Mess}.
+
+
+otp_7189_err_desc(T) ->
+ EC = ?megaco_internal_gateway_error,
+ ET = lists:flatten(io_lib:format("~w",[T])),
+ #'ErrorDescriptor'{errorCode = EC, errorText = ET}.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+otp_7259(suite) ->
+ [];
+otp_7259(doc) ->
+ ["This is a variant of ticket OTP-6442"];
+otp_7259(Config) when is_list(Config) ->
+ put(verbosity, debug),
+ put(sname, "TEST"),
+ put(tc, otp7259rr),
+ i("starting"),
+
+ MgNode = make_node_name(mg),
+ d("start (MG) node: ~p", [MgNode]),
+ ok = megaco_test_lib:start_nodes([MgNode], ?FILE, ?LINE),
+
+ d("[MG] start the simulator "),
+ {ok, Mg} = megaco_test_megaco_generator:start_link("MG", MgNode),
+
+ d("[MG] create the event sequence"),
+ MgMid = {deviceName,"mg"},
+ MgEvSeq = otp_7259_mg_event_sequence(MgMid),
+
+ i("wait some time before starting the MG simulation"),
+ sleep(1000),
+
+ d("[MG] start the simulation"),
+ {ok, MgId} = megaco_test_megaco_generator:exec(Mg, MgEvSeq),
+
+ i("await the transport module service change send_message event"),
+ Pid = otp_7259_expect(fun otp_7259_verify_scr_msg/1, 5000),
+
+ i("wait some before issuing the service change reply"),
+ sleep(500),
+
+ i("send the service change reply"),
+ MgcMid = {deviceName,"mgc"},
+ ServiceChangeReply = otp_7259_mgc_service_change_reply_msg(MgcMid, 1, 1),
+ megaco_test_generic_transport:incomming_message(Pid, ServiceChangeReply),
+
+ i("await the transport module "
+ "notify-request send_message event from MG: "
+ "ignore"),
+ ok = otp_7259_expect(fun otp_7259_verify_first_nr_msg/1, 5000),
+
+ i("await the transport module "
+ "notify-request resend_message event from MG: "
+ "reply"),
+ {TransId2, Cid2, TermId2} =
+ otp_7259_expect(fun otp_7259_verify_second_nr_msg/1, 10000),
+
+ i("wait some before issuing the notify reply"),
+ sleep(500),
+
+ i("send the notify reply"),
+ NotifyReply =
+ otp_7259_mgc_notify_reply_msg(MgcMid, TransId2, Cid2, TermId2),
+ megaco_test_generic_transport:incomming_message(Pid, NotifyReply),
+
+ d("[MG] await the generator reply"),
+ await_completion([MgId], 5000),
+
+ %% Tell Mg to stop
+ i("[MG] stop generator"),
+ megaco_test_megaco_generator:stop(Mg),
+
+ i("done", []),
+ ok.
+
+
+otp_7259_expect(Verify, Timeout) when (Timeout > 0) ->
+ T = mtime(),
+ receive
+ Msg ->
+ case (catch Verify(Msg)) of
+ {ok, Result} ->
+ d("verified after ~p msec", [mtime() - T]),
+ Result;
+ skip ->
+ otp_7259_expect(Verify, to(Timeout, T));
+ {error, Reason} ->
+ exit({verification_failed, Reason})
+ end
+ after Timeout ->
+ exit(timeout)
+ end;
+otp_7259_expect(_, _Timeout) ->
+ exit(timeout).
+
+otp_7259_verify_scr_msg(
+ {transport_event, {send_message, _SH, {message, Msg, Resend}}, Pid})
+ when is_record(Msg, 'MegacoMessage') andalso ((Resend =:= true) orelse (Resend =:= false)) ->
+ d("received expected service change request message: "
+ "~n Msg: ~p"
+ "~n Resend: ~p", [Msg, Resend]),
+ Reply = ok,
+ Pid ! {transport_reply, Reply, self()},
+ {ok, Pid};
+otp_7259_verify_scr_msg(Msg) ->
+ {error, {invalid_message, Msg}}.
+
+otp_7259_verify_first_nr_msg(
+ {transport_event, {send_message, _SH, {message, Msg, Resend}}, Pid})
+ when is_record(Msg, 'MegacoMessage') andalso ((Resend =:= true) orelse (Resend =:= false)) ->
+ d("received expected first notify request send message: "
+ "~n Msg: ~p", [Msg]),
+ Reply = ok,
+ Pid ! {transport_reply, Reply, self()},
+ {ok, ok};
+otp_7259_verify_first_nr_msg(Msg) ->
+ {error, {invalid_message, Msg}}.
+
+otp_7259_verify_second_nr_msg(
+ {transport_event, {send_message, _SH, {message, Msg, Resend}}, Pid})
+ when is_record(Msg, 'MegacoMessage') andalso ((Resend =:= true) orelse (Resend =:= false)) ->
+ d("received expected second notify request send message: "
+ "~n Msg: ~p", [Msg]),
+ Reply = ok,
+ Pid ! {transport_reply, Reply, self()},
+ #'MegacoMessage'{mess = Mess} = Msg,
+ #'Message'{mId = _Mid,
+ messageBody = Body} = Mess,
+ {transactions, Transactions} = Body,
+ [Transaction] = Transactions,
+ {transactionRequest, TransReq} = Transaction,
+ #'TransactionRequest'{transactionId = TransId,
+ actions = Actions} = TransReq,
+ [Action] = Actions,
+ #'ActionRequest'{contextId = Cid,
+ commandRequests = CmdReqs} = Action,
+ [CmdReq] = CmdReqs,
+ #'CommandRequest'{command = Cmd} = CmdReq,
+ {notifyReq, NR} = Cmd,
+ #'NotifyRequest'{terminationID = [TermId]} = NR,
+ {ok, {TransId, Cid, TermId}};
+otp_7259_verify_second_nr_msg(Msg) ->
+ {error, {invalid_message, Msg}}.
+
+
+otp_7259_mgc_service_change_reply_msg(Mid, TransId, Cid) ->
+ SCRP = #'ServiceChangeResParm'{serviceChangeMgcId = Mid},
+ SCRPs = {serviceChangeResParms, SCRP},
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = #'ServiceChangeReply'{terminationID = [Root],
+ serviceChangeResult = SCRPs},
+ CR = {serviceChangeReply, SCR},
+ otp_7259_mgc_reply_msg(Mid, TransId, CR, Cid).
+
+otp_7259_mgc_notify_reply_msg(Mid, TransId, Cid, TermId) ->
+ NR = #'NotifyReply'{terminationID = [TermId]},
+ CR = {notifyReply, NR},
+ otp_7259_mgc_reply_msg(Mid, TransId, CR, Cid).
+
+otp_7259_mgc_reply_msg(Mid, TransId, CR, Cid) ->
+ AR = #'ActionReply'{contextId = Cid,
+ commandReply = [CR]},
+ ARs = {actionReplies, [AR]},
+ TR = #'TransactionReply'{transactionId = TransId,
+ transactionResult = ARs},
+ Body = {transactions, [{transactionReply, TR}]},
+ Mess = #'Message'{version = 1,
+ mId = Mid,
+ messageBody = Body},
+ #'MegacoMessage'{mess = Mess}.
+
+
+%%
+%% MG generator stuff
+%%
+-ifdef(megaco_hipe_special).
+-define(otp_7259_mg_verify_handle_connect_fun(),
+ {?MODULE, otp_7259_mg_verify_handle_connect, []}).
+-define(otp_7259_mg_verify_service_change_rep_fun(),
+ {?MODULE, otp_7259_mg_verify_service_change_rep, []}).
+-define(otp_7259_mg_verify_notify_rep_fun(),
+ {?MODULE, otp_7259_mg_verify_notify_rep, []}).
+-else.
+-define(otp_7259_mg_verify_handle_connect_fun(),
+ otp_7259_mg_verify_handle_connect_fun()).
+-define(otp_7259_mg_verify_service_change_rep_fun(),
+ otp_7259_mg_verify_service_change_rep_fun()).
+-define(otp_7259_mg_verify_notify_rep_fun(),
+ otp_7259_mg_verify_notify_rep_fun()).
+-endif.
+
+otp_7259_mg_event_sequence(Mid) ->
+ RI = [
+ {port, self()}, % This is just a trick to get my pid to the transport module
+ {encoding_module, megaco_pretty_text_encoder},
+ {encoding_config, []},
+ {transport_module, megaco_test_generic_transport}
+ ],
+ ServiceChangeReq =
+ otp_7259_mg_service_change_request_ar(Mid, 1),
+ Tid = #megaco_term_id{id = ["00000000","00000000","01101101"]},
+ NotifyReq = otp_7259_mg_notify_request_ar(1, Tid, 1),
+ ConnectVerify =
+ ?otp_7259_mg_verify_handle_connect_fun(),
+ ServiceChangeReplyVerify =
+ ?otp_7259_mg_verify_service_change_rep_fun(),
+ NotifyReplyVerify =
+ ?otp_7259_mg_verify_notify_rep_fun(),
+ EvSeq = [
+ {debug, false},
+ megaco_start,
+ {megaco_start_user, Mid, RI, []},
+ {megaco_update_user_info, resend_indication, flag},
+ start_transport,
+ {megaco_trace, disable},
+ {megaco_system_info, users},
+ {megaco_system_info, connections},
+ connect,
+ {megaco_callback, handle_connect, ConnectVerify},
+ megaco_connect,
+ {megaco_cast, [ServiceChangeReq], []},
+ {megaco_callback, handle_connect, ConnectVerify},
+ {megaco_callback, handle_trans_reply, ServiceChangeReplyVerify},
+ {sleep, 1000},
+ {megaco_cast, [NotifyReq], []},
+ {megaco_callback, handle_trans_reply, NotifyReplyVerify},
+ {sleep, 1000},
+ megaco_stop_user,
+ megaco_stop,
+ {sleep, 1000}
+ ],
+ EvSeq.
+
+
+-ifndef(megaco_hipe_special).
+otp_7259_mg_verify_handle_connect_fun() ->
+ fun(Ev) ->
+ otp_7259_mg_verify_handle_connect(Ev)
+ end.
+-endif.
+
+otp_7259_mg_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
+ io:format("otp_7259_mg_verify_handle_connect -> ok"
+ "~n CH: ~p~n", [CH]),
+ {ok, CH, ok};
+otp_7259_mg_verify_handle_connect(Else) ->
+ io:format("otp_7259_mg_verify_handle_connect -> unknown"
+ "~n Else: ~p~n", [Else]),
+ {error, Else, ok}.
+
+-ifndef(megaco_hipe_special).
+otp_7259_mg_verify_service_change_rep_fun() ->
+ fun(Rep) ->
+ otp_7259_mg_verify_service_change_rep(Rep)
+ end.
+-endif.
+
+otp_7259_mg_verify_service_change_rep(
+ {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _}) ->
+ (catch otp_7259_mg_do_verify_service_change_rep(AR));
+otp_7259_mg_verify_service_change_rep(Crap) ->
+ {error, Crap, ok}.
+
+otp_7259_mg_do_verify_service_change_rep(AR) ->
+ io:format("otp_7259_mg_verify_service_change_rep -> ok"
+ "~n AR: ~p~n", [AR]),
+ CR =
+ case AR of
+ #'ActionReply'{commandReply = [CmdRep]} ->
+ CmdRep;
+ _ ->
+ Reason1 = {invalid_action_reply, AR},
+ throw({error, Reason1, ok})
+ end,
+ SCR =
+ case CR of
+ {serviceChangeReply, ServChRep} ->
+ ServChRep;
+ _ ->
+ Reason2 = {invalid_command_reply, CR},
+ throw({error, Reason2, ok})
+ end,
+ {Tid, SCRes} =
+ case SCR of
+ #'ServiceChangeReply'{terminationID = [TermID],
+ serviceChangeResult = Res} ->
+ {TermID, Res};
+ _ ->
+ Reason3 = {invalid_service_change_reply, SCR},
+ throw({error, Reason3, ok})
+ end,
+ case Tid of
+ #megaco_term_id{contains_wildcards = false, id = ["root"]} ->
+ ok;
+ _ ->
+ Reason4 = {invalid_termination_id, Tid},
+ throw({error, Reason4, ok})
+ end,
+ SCRParm =
+ case SCRes of
+ {serviceChangeResParms, ServChResParms} ->
+ ServChResParms;
+ _ ->
+ Reason5 = {invalid_serviceChangeResult, SCRes},
+ throw({error, Reason5, ok})
+ end,
+ case SCRParm of
+ #'ServiceChangeResParm'{serviceChangeMgcId = _RemoteMid} ->
+ {ok, AR, ok};
+ _ ->
+ Reason6 = {invalid_service_change_result, SCRParm},
+ {error, Reason6, ok}
+ end.
+
+-ifndef(megaco_hipe_special).
+otp_7259_mg_verify_notify_rep_fun() ->
+ fun(Rep) ->
+ otp_7259_mg_verify_notify_rep(Rep)
+ end.
+-endif.
+
+otp_7259_mg_verify_notify_rep(
+ {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _}) ->
+ io:format("otp_7259_mg_verify_notify_rep -> ok"
+ "~n AR: ~p~n", [AR]),
+ {ok, AR, ok};
+otp_7259_mg_verify_notify_rep(Else) ->
+ io:format("otp_7259_mg_verify_notify_rep -> unknown"
+ "~n Else: ~p~n", [Else]),
+ {error, Else, ok}.
+
+
+otp_7259_mg_service_change_request_ar(_Mid, Cid) ->
+ Prof = cre_serviceChangeProf("resgw", 1),
+ SCP = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = cre_serviceChangeReq([Root], SCP),
+ CMD = cre_command(SCR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+otp_7259_mg_notify_request_ar(Rid, Tid, Cid) ->
+ TT = cre_timeNotation("19990729", "22000000"),
+ Ev = cre_obsEvent("al/of", TT),
+ EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
+ NR = cre_notifyReq([Tid], EvsDesc),
+ CMD = cre_command(NR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+otp_7713(suite) ->
+ [];
+otp_7713(doc) ->
+ [];
+otp_7713(Config) when is_list(Config) ->
+ ?ACQUIRE_NODES(1, Config),
+
+ put(verbosity, debug),
+ put(sname, "TEST"),
+ put(tc, otp7713),
+ i("starting"),
+
+ d("start proxy",[]),
+ megaco_mess_user_test:start_proxy(),
+
+ Extra = otp7713_extra,
+ PrelMid = preliminary_mid,
+ MgMid = ipv4_mid(4711),
+ MgcMid = ipv4_mid(),
+ UserMod = megaco_mess_user_test,
+ d("start megaco app",[]),
+ ?VERIFY(ok, application:start(megaco)),
+ UserConfig = [{user_mod, UserMod}, {send_mod, UserMod},
+ {request_timer, infinity}, {reply_timer, infinity}],
+ d("start (MG) user ~p",[MgMid]),
+ ?VERIFY(ok, megaco:start_user(MgMid, UserConfig)),
+
+ d("start (MGC) user ~p",[MgcMid]),
+ ?VERIFY(ok, megaco:start_user(MgcMid, UserConfig)),
+
+ d("get receive info for ~p",[MgMid]),
+ MgRH = user_info(MgMid, receive_handle),
+ d("get receive info for ~p",[MgcMid]),
+ MgcRH = user_info(MgcMid, receive_handle),
+ d("start transport",[]),
+ {ok, MgPid, MgSH} =
+ ?VERIFY({ok, _, _}, UserMod:start_transport(MgRH, MgcRH)),
+ PrelMgCH = #megaco_conn_handle{local_mid = MgMid,
+ remote_mid = preliminary_mid},
+ MgCH = #megaco_conn_handle{local_mid = MgMid,
+ remote_mid = MgcMid},
+ MgcCH = #megaco_conn_handle{local_mid = MgcMid,
+ remote_mid = MgMid},
+ d("(MG) try connect to MGC",[]),
+ ?SEND(megaco:connect(MgRH, PrelMid, MgSH, MgPid, Extra)), % Mg prel
+ d("await connect from MG", []),
+ ?USER({connect, PrelMgCH, _V, [Extra]}, ok),
+ ?RECEIVE([{res, _, {ok, PrelMgCH}}]),
+
+ d("(MG) send service change request",[]),
+ Req = service_change_request(),
+ ?SEND(megaco:call(PrelMgCH, [Req], [])),
+
+ d("(MGC) send service change reply",[]),
+ ?USER({connect, MgcCH, _V, []}, ok), % Mgc auto
+ Rep = service_change_reply(MgcMid),
+ ?USER({request, MgcCH, _V, [[Req]]}, {discard_ack, [Rep]}),
+ ?USER({connect, MgCH, _V, []}, ok), % Mg confirm
+ ?RECEIVE([{res, _, {1, {ok, [Rep]}}}]),
+
+ d("get (system info) connections",[]),
+ connections([MgCH, MgcCH]),
+ d("get (~p) connections",[MgMid]),
+ ?VERIFY([MgCH], megaco:user_info(MgMid, connections)),
+ d("get (~p) connections",[MgcMid]),
+ ?VERIFY([MgcCH], megaco:user_info(MgcMid, connections)),
+
+ Reason = shutdown,
+ d("(MG) disconnect",[]),
+ ?SEND(megaco:disconnect(MgCH, Reason)),
+ ?USER({disconnect, MgCH, _V, [{user_disconnect, Reason}]}, ok),
+ ?RECEIVE([{res, _, ok}]),
+ ?VERIFY(ok, megaco:stop_user(MgMid)),
+
+ d("(MGC) disconnect",[]),
+ ?SEND(megaco:disconnect(MgcCH, Reason)),
+ ?USER({disconnect, MgcCH, _V, [{user_disconnect, Reason}]}, ok),
+ ?RECEIVE([{res, _, ok}]),
+ ?VERIFY(ok, megaco:stop_user(MgcMid)),
+
+ d("stop megaco app",[]),
+ ?VERIFY(ok, application:stop(megaco)),
+ ?RECEIVE([]),
+
+ d("done",[]),
+ ok.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+otp_8183_request1(suite) ->
+ [];
+otp_8183_request1(Config) when is_list(Config) ->
+ put(verbosity, debug),
+ put(sname, "TEST"),
+ put(tc, otp8183r1),
+ i("starting"),
+
+ MgNode = make_node_name(mg),
+ d("start (MG) node: ~p", [MgNode]),
+ ok = megaco_test_lib:start_nodes([MgNode], ?FILE, ?LINE),
+
+ d("[MG] start the simulator "),
+ {ok, Mg} = megaco_test_megaco_generator:start_link("MG", MgNode),
+
+ d("[MG] create the event sequence"),
+ MgMid = {deviceName,"mg"},
+ MgEvSeq = otp_8183_r1_mg_event_sequence(MgMid),
+
+ i("wait some time before starting the MG simulation"),
+ sleep(1000),
+
+ d("[MG] start the simulation"),
+ {ok, MgId} = megaco_test_megaco_generator:exec(Mg, MgEvSeq),
+
+ i("await the transport module service change send_message event"),
+ Pid = otp_8183_expect(fun(Ev) -> otp_8183_r1_verify_scr_msg(Ev) end, 5000),
+
+ i("wait some before issuing the service change reply"),
+ sleep(500),
+
+ i("send the service change reply"),
+ MgcMid = {deviceName,"mgc"},
+ ServiceChangeReply = otp_8183_r1_mgc_service_change_reply_msg(MgcMid, 1, 1),
+ megaco_test_generic_transport:incomming_message(Pid, ServiceChangeReply),
+
+ i("await the transport module "
+ "notify-request send_message event from MG: "
+ "ignore"),
+ {TransId2, Cid2, TermId2} =
+ otp_8183_expect(fun(Ev) -> otp_8183_r1_verify_nr_msg(Ev) end, 5000),
+
+ i("wait some before issuing the notify reply (twice)"),
+ sleep(500),
+
+ i("send the notify reply, twice times"),
+ NotifyReply =
+ otp_8183_r1_mgc_notify_reply_msg(MgcMid, TransId2, Cid2, TermId2),
+ megaco_test_generic_transport:incomming_message(Pid, NotifyReply),
+ megaco_test_generic_transport:incomming_message(Pid, NotifyReply),
+
+ d("await the generator reply"),
+ await_completion([MgId]),
+
+ %% Tell Mg to stop
+ i("[MG] stop generator"),
+ megaco_test_megaco_generator:stop(Mg),
+
+ i("done", []),
+ ok.
+
+
+otp_8183_expect(Verify, Timeout) when (Timeout > 0) ->
+ T = mtime(),
+ receive
+ Msg ->
+ case (catch Verify(Msg)) of
+ {ok, Result} ->
+ d("verified after ~p msec", [mtime() - T]),
+ Result;
+ skip ->
+ otp_8183_expect(Verify, to(Timeout, T));
+ {error, Reason} ->
+ exit({verification_failed, Reason})
+ end
+ after Timeout ->
+ exit(timeout)
+ end;
+otp_8183_expect(_, _Timeout) ->
+ exit(timeout).
+
+otp_8183_r1_verify_scr_msg(
+ {transport_event, {send_message, _SH, {message, Msg}}, Pid})
+ when is_record(Msg, 'MegacoMessage') ->
+ d("received expected service change request message: "
+ "~n Msg: ~p", [Msg]),
+ Reply = ok,
+ Pid ! {transport_reply, Reply, self()},
+ {ok, Pid};
+otp_8183_r1_verify_scr_msg(
+ {transport_event, {send_message, _SH, BadMsg}, _Pid}) ->
+ io:format("otp_8183_r1_verify_scr_msg -> error: "
+ "~n BadMsg: ~p"
+ "~n", [BadMsg]),
+ {error, {invalid_message, BadMsg}};
+otp_8183_r1_verify_scr_msg({transport_event, BadEvent, _Pid}) ->
+ io:format("otp_8183_r1_verify_scr_msg -> error: "
+ "~n BadEvent: ~p"
+ "~n", [BadEvent]),
+ {error, {invalid_message, BadEvent}};
+otp_8183_r1_verify_scr_msg(Msg) ->
+ io:format("otp_8183_r1_verify_scr_msg -> error: "
+ "~n Msg: ~p"
+ "~n", [Msg]),
+ {error, {invalid_message, Msg}}.
+
+otp_8183_r1_verify_nr_msg(
+ {transport_event, {send_message, _SH, {message, Msg}}, Pid})
+ when is_record(Msg, 'MegacoMessage') ->
+ io:format("otp_8183_r1_verify_nr_msg -> "
+ "entry when received expected message with"
+ "~n Msg: ~p"
+ "~n", [Msg]),
+ Reply = ok,
+ Pid ! {transport_reply, Reply, self()},
+ #'MegacoMessage'{mess = Mess} = Msg,
+ #'Message'{mId = _Mid,
+ messageBody = Body} = Mess,
+ {transactions, Transactions} = Body,
+ [Transaction] = Transactions,
+ {transactionRequest, TransReq} = Transaction,
+ #'TransactionRequest'{transactionId = TransId,
+ actions = Actions} = TransReq,
+ [Action] = Actions,
+ #'ActionRequest'{contextId = Cid,
+ commandRequests = CmdReqs} = Action,
+ [CmdReq] = CmdReqs,
+ #'CommandRequest'{command = Cmd} = CmdReq,
+ {notifyReq, NR} = Cmd,
+ #'NotifyRequest'{terminationID = [TermId]} = NR,
+ {ok, {TransId, Cid, TermId}};
+otp_8183_r1_verify_nr_msg(Msg) ->
+ io:format("otp_8183_r1_verify_nr_msg -> entry when error with"
+ "~n Msg: ~p"
+ "~n", [Msg]),
+ {error, {invalid_message, Msg}}.
+
+otp_8183_r1_mgc_service_change_reply_msg(Mid, TransId, Cid) ->
+ SCRP = #'ServiceChangeResParm'{serviceChangeMgcId = Mid},
+ SCRPs = {serviceChangeResParms, SCRP},
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = #'ServiceChangeReply'{terminationID = [Root],
+ serviceChangeResult = SCRPs},
+ CR = {serviceChangeReply, SCR},
+ otp_8183_r1_mgc_reply_msg(Mid, TransId, CR, Cid).
+
+otp_8183_r1_mgc_notify_reply_msg(Mid, TransId, Cid, TermId) ->
+ NR = #'NotifyReply'{terminationID = [TermId]},
+ CR = {notifyReply, NR},
+ otp_8183_r1_mgc_reply_msg(Mid, TransId, CR, Cid).
+
+otp_8183_r1_mgc_reply_msg(Mid, TransId, CR, Cid) ->
+ AR = #'ActionReply'{contextId = Cid,
+ commandReply = [CR]},
+ ARs = {actionReplies, [AR]},
+ TR = #'TransactionReply'{transactionId = TransId,
+ transactionResult = ARs},
+ Body = {transactions, [{transactionReply, TR}]},
+ Mess = #'Message'{version = 1,
+ mId = Mid,
+ messageBody = Body},
+ #'MegacoMessage'{mess = Mess}.
+
+
+%%
+%% MG generator stuff
+%%
+-ifdef(megaco_hipe_special).
+-define(otp_8183_r1_mg_verify_handle_connect_fun(),
+ {?MODULE, otp_8183_r1_mg_verify_handle_connect, []}).
+-define(otp_8183_r1_mg_verify_service_change_rep_fun(),
+ {?MODULE, otp_8183_r1_mg_verify_service_change_rep, []}).
+-define(otp_8183_r1_mg_verify_notify_rep_fun(Nr
+ {?MODULE, otp_8183_r1_mg_verify_notify_rep, [Nr).
+-else.
+-define(otp_8183_r1_mg_verify_handle_connect_fun(),
+ otp_8183_r1_mg_verify_handle_connect_fun()).
+-define(otp_8183_r1_mg_verify_service_change_rep_fun(),
+ otp_8183_r1_mg_verify_service_change_rep_fun()).
+-define(otp_8183_r1_mg_verify_notify_rep_fun(Nr),
+ otp_8183_r1_mg_verify_notify_rep_fun(Nr)).
+-endif.
+
+otp_8183_r1_mg_event_sequence(Mid) ->
+ RI = [
+ {port, self()}, % This is just a trick to get my pid to the transport module
+ {encoding_module, megaco_pretty_text_encoder},
+ {encoding_config, []},
+ {transport_module, megaco_test_generic_transport}
+ ],
+ ServiceChangeReq =
+ otp_8183_r1_mg_service_change_request_ar(Mid, 1),
+ Tid = #megaco_term_id{id = ["00000000","00000000","01101101"]},
+ NotifyReq = otp_8183_r1_mg_notify_request_ar(1, Tid, 1),
+ ConnectVerify =
+ ?otp_8183_r1_mg_verify_handle_connect_fun(),
+ ServiceChangeReplyVerify =
+ ?otp_8183_r1_mg_verify_service_change_rep_fun(),
+ NotifyReplyVerify =
+ fun(Nr) ->
+ ?otp_8183_r1_mg_verify_notify_rep_fun(Nr)
+ end,
+ EvSeq = [
+ {debug, true}, % false},
+ megaco_start,
+ {megaco_start_user, Mid, RI, []},
+ start_transport,
+ {megaco_trace, disable},
+ {megaco_system_info, users},
+ {megaco_system_info, connections},
+ connect,
+ {megaco_callback, handle_connect, ConnectVerify},
+ megaco_connect,
+ {megaco_cast, [ServiceChangeReq], []},
+ {megaco_callback, handle_connect, ConnectVerify},
+ {megaco_callback, handle_trans_reply, ServiceChangeReplyVerify},
+
+ {sleep, 1000},
+ {megaco_cast, [NotifyReq], [{request_keep_alive_timeout, 5000}]},
+ {megaco_callback, handle_trans_reply, NotifyReplyVerify(1)},
+ {megaco_callback, handle_trans_reply, NotifyReplyVerify(2)},
+ {sleep, 1000},
+ megaco_stop_user,
+ megaco_stop,
+ {sleep, 1000}
+ ],
+ EvSeq.
+
+
+-ifndef(megaco_hipe_special).
+otp_8183_r1_mg_verify_handle_connect_fun() ->
+ fun(Ev) ->
+ otp_8183_r1_mg_verify_handle_connect(Ev)
+ end.
+-endif.
+
+otp_8183_r1_mg_verify_handle_connect({handle_connect, CH, ?VERSION}) ->
+ io:format("otp_8183_r1_mg_verify_handle_connect -> ok"
+ "~n CH: ~p~n", [CH]),
+ {ok, CH, ok};
+otp_8183_r1_mg_verify_handle_connect(Else) ->
+ io:format("otp_8183_r1_mg_verify_handle_connect -> unknown"
+ "~n Else: ~p~n", [Else]),
+ {error, Else, ok}.
+
+-ifndef(megaco_hipe_special).
+otp_8183_r1_mg_verify_service_change_rep_fun() ->
+ fun(Rep) ->
+ otp_8183_r1_mg_verify_service_change_rep(Rep)
+ end.
+-endif.
+
+otp_8183_r1_mg_verify_service_change_rep(
+ {handle_trans_reply, _CH, ?VERSION, {ok, [AR]}, _}) ->
+ (catch otp_8183_r1_mg_do_verify_service_change_rep(AR));
+otp_8183_r1_mg_verify_service_change_rep(Crap) ->
+ io:format("otp_8183_r1_mg_verify_service_change_rep -> crap"
+ "~n Crap: ~p"
+ "~n", [Crap]),
+ {error, Crap, ok}.
+
+otp_8183_r1_mg_do_verify_service_change_rep(AR) ->
+ io:format("otp_8183_r1_mg_do_verify_service_change_rep -> ok"
+ "~n AR: ~p~n", [AR]),
+ CR =
+ case AR of
+ #'ActionReply'{commandReply = [CmdRep]} ->
+ CmdRep;
+ _ ->
+ Reason1 = {invalid_action_reply, AR},
+ throw({error, Reason1, ok})
+ end,
+ SCR =
+ case CR of
+ {serviceChangeReply, ServChRep} ->
+ ServChRep;
+ _ ->
+ Reason2 = {invalid_command_reply, CR},
+ throw({error, Reason2, ok})
+ end,
+ {Tid, SCRes} =
+ case SCR of
+ #'ServiceChangeReply'{terminationID = [TermID],
+ serviceChangeResult = Res} ->
+ {TermID, Res};
+ _ ->
+ Reason3 = {invalid_service_change_reply, SCR},
+ throw({error, Reason3, ok})
+ end,
+ case Tid of
+ #megaco_term_id{contains_wildcards = false, id = ["root"]} ->
+ ok;
+ _ ->
+ Reason4 = {invalid_termination_id, Tid},
+ throw({error, Reason4, ok})
+ end,
+ SCRParm =
+ case SCRes of
+ {serviceChangeResParms, ServChResParms} ->
+ ServChResParms;
+ _ ->
+ Reason5 = {invalid_serviceChangeResult, SCRes},
+ throw({error, Reason5, ok})
+ end,
+ case SCRParm of
+ #'ServiceChangeResParm'{serviceChangeMgcId = _RemoteMid} ->
+ {ok, AR, ok};
+ _ ->
+ Reason6 = {invalid_service_change_result, SCRParm},
+ {error, Reason6, ok}
+ end.
+
+-ifndef(megaco_hipe_special).
+otp_8183_r1_mg_verify_notify_rep_fun(Nr) ->
+ fun(Rep) ->
+ otp_8183_r1_mg_verify_notify_rep(Nr, Rep)
+ end.
+-endif.
+
+otp_8183_r1_mg_verify_notify_rep(Nr,
+ {handle_trans_reply, _CH, ?VERSION, {ok, Nr, [AR]}, _}) ->
+ io:format("otp_8183_r1_mg_verify_notify_rep -> ok"
+ "~n Nr: ~p"
+ "~n AR: ~p"
+ "~n", [Nr, AR]),
+ {ok, AR, ok};
+otp_8183_r1_mg_verify_notify_rep(Nr, Else) ->
+ io:format("otp_8183_r1_mg_verify_notify_rep -> unknown"
+ "~n Nr: ~p"
+ "~n Else: ~p"
+ "~n", [Nr, Else]),
+ {error, Else, ok}.
+
+
+otp_8183_r1_mg_service_change_request_ar(_Mid, Cid) ->
+ Prof = cre_serviceChangeProf("resgw", 1),
+ SCP = cre_serviceChangeParm(restart, ["901 mg col boot"], Prof),
+ Root = #megaco_term_id{id = ["root"]},
+ SCR = cre_serviceChangeReq([Root], SCP),
+ CMD = cre_command(SCR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+otp_8183_r1_mg_notify_request_ar(Rid, Tid, Cid) ->
+ TT = cre_timeNotation("19990729", "22000000"),
+ Ev = cre_obsEvent("al/of", TT),
+ EvsDesc = cre_obsEvsDesc(Rid, [Ev]),
+ NR = cre_notifyReq([Tid], EvsDesc),
+ CMD = cre_command(NR),
+ CR = cre_cmdReq(CMD),
+ cre_actionReq(Cid, [CR]).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+otp8212_scr(MidStr) ->
+ Msg = "!/1 " ++ MidStr ++ " T=19731{C=-{SC=ROOT{SV{MT=RS,RE=\"901\"}}}}",
+ list_to_binary(Msg).
+
+otp_8212(suite) ->
+ [];
+otp_8212(doc) ->
+ [];
+otp_8212(Config) when is_list(Config) ->
+ %% ?ACQUIRE_NODES(1, Config),
+
+ put(verbosity, debug),
+ put(sname, "TEST"),
+ put(tc, otp8212),
+ i("starting"),
+
+ Extra = otp8212_extra,
+ NoMid = preliminary_mid,
+ LocalMid = {deviceName, "MGC"},
+ RemoteMidStr1 = "bgf1",
+ RemoteMid1 = {deviceName, RemoteMidStr1},
+ RemoteMidStr2 = "bgf2",
+ RemoteMid2 = {deviceName, RemoteMidStr2},
+ UserMod = megaco_mess_otp8212_test,
+
+ d("set megaco trace level to max",[]),
+ megaco:enable_trace(max, io),
+
+ d("start megaco app",[]),
+ ?VERIFY(ok, application:start(megaco)),
+
+ d("start local user (MGC) ~p", [LocalMid]),
+ UserConfig = [{user_mod, UserMod}, {send_mod, UserMod}],
+ ?VERIFY(ok, megaco:start_user(LocalMid, UserConfig)),
+
+ d("get (MGC) receive info for ~p", [LocalMid]),
+ RH0 = user_info(LocalMid, receive_handle),
+ RH = RH0#megaco_receive_handle{encoding_mod = megaco_mess_otp8212_test,
+ encoding_config = []},
+
+ d("do a pre-connect for ~p", [LocalMid]),
+ ControlPid = self(),
+ SendHandle = {RH, ControlPid, RemoteMidStr1, RemoteMidStr2},
+ ?VERIFY({ok, _}, megaco:connect(RH, NoMid, SendHandle, ControlPid)),
+
+ d("simulate incomming service change message from ~p",
+ [RemoteMidStr1]),
+ ?VERIFY(ok,
+ megaco:process_received_message(RH, ControlPid,
+ otp8212_scr,
+ otp8212_scr(RemoteMidStr1))),
+
+ d("get the updated connection handle", []),
+ [CH] = megaco:user_info(LocalMid, connections),
+
+ d("verify connection with ~p", [RemoteMidStr1]),
+ ?VERIFY(RemoteMid1, megaco:conn_info(CH, remote_mid)),
+
+ d("send a request to ~p but receive no reply but an unexpected call",
+ [RemoteMidStr1]),
+ Res = megaco:call(CH, ["action request"], [{request_timer, 2000}]),
+ d("request result: ~p", [Res]),
+ ?VERIFY({1, [{error, {wrong_mid, RemoteMid2, RemoteMid1, _}, {Extra, _}}]}, Res),
+
+ Conns = disconnect_all(LocalMid),
+ await_disconnected(Conns),
+
+ d("stop megaco user ~p",[LocalMid]),
+ ok = await_stopped_user(LocalMid),
+
+ d("stop megaco app",[]),
+ ?VERIFY(ok, application:stop(megaco)),
+ ?RECEIVE([]),
+
+ d("done",[]),
+ ok.
+
+disconnect_all(LocalMid) ->
+ Conns = megaco:user_info(LocalMid, connections),
+ d("[~p] disconnect from all connections: ~n~p", [LocalMid, Conns]),
+ lists:foreach(
+ fun(Conn) ->
+ d("[~p] disconnect from connection ~p", [LocalMid, Conn]),
+ DiscoRes = megaco:disconnect(Conn, {otp8212_done, self()}),
+ d("[~p] disconnect result: ~p", [LocalMid, DiscoRes])
+ end,
+ Conns),
+ Conns.
+
+await_disconnected([]) ->
+ ok;
+await_disconnected(Conns) ->
+ receive
+ {disconnected, Conn} ->
+ d("disconnected: ~p", [Conn]),
+ Conns2 = lists:delete(Conn, Conns),
+ await_disconnected(Conns2)
+ end.
+
+
+await_stopped_user(LocalMid) ->
+ await_stopped_user(LocalMid, 10).
+
+await_stopped_user(LocalMid, N) when N =< 0 ->
+ ?ERROR({failed_stopping_user, LocalMid});
+await_stopped_user(LocalMid, N) ->
+ case megaco:stop_user(LocalMid) of
+ ok ->
+ d("user stopped(~w)", [N]),
+ ok;
+ {error, {active_connections, _}} ->
+ d("still active connections when N = ~w", [N]),
+ Conns = disconnect_all(LocalMid),
+ await_disconnected(Conns),
+ ?SLEEP(500),
+ await_stopped_user(LocalMid, N-1)
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+cre_ErrDesc(T) ->
+ EC = ?megaco_internal_gateway_error,
+ ET = lists:flatten(io_lib:format("~w",[T])),
+ #'ErrorDescriptor'{errorCode = EC, errorText = ET}.
+
+
+cre_serviceChangeParm(M,R,P) ->
+ #'ServiceChangeParm'{serviceChangeMethod = M,
+ serviceChangeReason = R,
+ serviceChangeProfile = P}.
+
+cre_serviceChangeParm(M, V, R, P) ->
+ #'ServiceChangeParm'{serviceChangeMethod = M,
+ serviceChangeVersion = V,
+ serviceChangeReason = R,
+ serviceChangeProfile = P}.
+
+cre_serviceChangeReq(Tid, Parms) ->
+ #'ServiceChangeRequest'{terminationID = Tid,
+ serviceChangeParms = Parms}.
+
+cre_timeNotation(D,T) ->
+ #'TimeNotation'{date = D, time = T}.
+
+cre_obsEvent(Name, Not) ->
+ #'ObservedEvent'{eventName = Name,
+ timeNotation = Not}.
+
+cre_obsEvsDesc(Id, EvList) ->
+ #'ObservedEventsDescriptor'{requestId = Id,
+ observedEventLst = EvList}.
+
+cre_notifyReq(Tid, EvsDesc) ->
+ #'NotifyRequest'{terminationID = Tid,
+ observedEventsDescriptor = EvsDesc}.
+
+cre_command(R) when is_record(R, 'NotifyRequest') ->
+ {notifyReq, R};
+cre_command(R) when is_record(R, 'ServiceChangeRequest') ->
+ {serviceChangeReq, R}.
+
+cre_cmdReq(Cmd) ->
+ #'CommandRequest'{command = Cmd}.
+
+cre_actionReq(CtxId, CmdReqs) when is_list(CmdReqs) ->
+ #'ActionRequest'{contextId = CtxId,
+ commandRequests = CmdReqs}.
+
+cre_transReq(TransId, ARs) when is_list(ARs) ->
+ #'TransactionRequest'{transactionId = TransId,
+ actions = ARs}.
+
+cre_transResult(ED) when is_record(ED, 'ErrorDescriptor') ->
+ {transactionError, ED};
+cre_transResult([AR|_] = ARs) when is_record(AR, 'ActionReply') ->
+ {actionReplies, ARs}.
+
+cre_transReply(TransId, Res) ->
+ #'TransactionReply'{transactionId = TransId,
+ transactionResult = Res}.
+
+cre_transReply(TransId, IAR, Res) ->
+ #'TransactionReply'{transactionId = TransId,
+ immAckRequired = IAR,
+ transactionResult = Res}.
+
+
+%% --
+
+cre_serviceChangeResParm(Mid) ->
+ cre_serviceChangeResParm(Mid, ?VERSION).
+
+cre_serviceChangeResParm(Mid, V) ->
+ #'ServiceChangeResParm'{serviceChangeMgcId = Mid,
+ serviceChangeVersion = V}.
+
+cre_serviceChangeResult(SCRP) when is_record(SCRP, 'ServiceChangeResParm') ->
+ {serviceChangeResParms, SCRP};
+cre_serviceChangeResult(ED) when is_record(ED, 'ErrorDescriptor') ->
+ {errorDescriptor, ED}.
+
+cre_serviceChangeReply(Tid, Res) ->
+ #'ServiceChangeReply'{terminationID = Tid,
+ serviceChangeResult = Res}.
+
+cre_cmdReply(R) when is_record(R, 'NotifyReply') ->
+ {notifyReply, R};
+cre_cmdReply(R) when is_record(R, 'ServiceChangeReply') ->
+ {serviceChangeReply, R}.
+
+cre_transRespAck(TransAck) when is_record(TransAck, 'TransactionAck') ->
+ [TransAck];
+cre_transRespAck(TRA) when is_list(TRA) ->
+ TRA.
+
+cre_transAck(TransId) ->
+ #'TransactionAck'{firstAck = TransId}.
+
+cre_notifyReply(Tid) ->
+ #'NotifyReply'{terminationID = Tid}.
+
+cre_actionReply(CtxId, CmdRep) ->
+ #'ActionReply'{contextId = CtxId,
+ commandReply = CmdRep}.
+
+cre_serviceChangeProf(Name, Ver) when is_list(Name) andalso is_integer(Ver) ->
+ #'ServiceChangeProfile'{profileName = Name,
+ version = Ver}.
+
+cre_transaction(Trans) when is_record(Trans, 'TransactionRequest') ->
+ {transactionRequest, Trans};
+cre_transaction(Trans) when is_record(Trans, 'TransactionPending') ->
+ {transactionPending, Trans};
+cre_transaction(Trans) when is_record(Trans, 'TransactionReply') ->
+ {transactionReply, Trans};
+cre_transaction(Trans) when is_list(Trans) ->
+ {transactionResponseAck, Trans}.
+
+cre_transactions(Trans) when is_list(Trans) ->
+ {transactions, Trans}.
+
+cre_message(Version, Mid, Body) ->
+ #'Message'{version = Version,
+ mId = Mid,
+ messageBody = Body}.
+
+cre_megacoMessage(Mess) ->
+ #'MegacoMessage'{mess = Mess}.
+
+service_change_request() ->
+ Parm = #'ServiceChangeParm'{serviceChangeMethod = restart,
+ serviceChangeReason = [?megaco_cold_boot]},
+ SCR = #'ServiceChangeRequest'{terminationID = [?megaco_root_termination_id],
+ serviceChangeParms = Parm},
+ CR = #'CommandRequest'{command = {serviceChangeReq, SCR}},
+ #'ActionRequest'{contextId = ?megaco_null_context_id,
+ commandRequests = [CR]}.
+
+service_change_reply(MgcMid) ->
+ Res = {serviceChangeResParms, #'ServiceChangeResParm'{serviceChangeMgcId = MgcMid}},
+ SCR = #'ServiceChangeReply'{terminationID = [?megaco_root_termination_id],
+ serviceChangeResult = Res},
+ #'ActionReply'{contextId = ?megaco_null_context_id,
+ commandReply = [{serviceChangeReply, SCR}]}.
+
+local_ip_address() ->
+ {ok, Hostname} = inet:gethostname(),
+ {ok, {A1, A2, A3, A4}} = inet:getaddr(Hostname, inet),
+ {A1, A2, A3, A4}.
+
+ipv4_mid() ->
+ ipv4_mid(asn1_NOVALUE).
+
+ipv4_mid(Port) ->
+ IpAddr = local_ip_address(),
+ Ip = tuple_to_list(IpAddr),
+ {ip4Address, #'IP4Address'{address = Ip, portNumber = Port}}.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%% -------------------------------------------------------------------------------
+%%% Megaco user callback interface
+%%% -------------------------------------------------------------------------------
+
+handle_connect(ConnHandle, ProtocolVersion, Pid) ->
+ Pid ! {handle_connect, {ConnHandle, ProtocolVersion}},
+ ok.
+
+handle_disconnect(_, _, {user_disconnect, test_complete}, _) ->
+ ok;
+handle_disconnect(ConnHandle, ProtocolVersion, Reason, Pid) ->
+ Pid ! {handle_disconnect, {ConnHandle, ProtocolVersion, Reason}},
+ ok.
+
+handle_syntax_error(ConnHandle, ProtocolVersion, ErrorDescriptor, Pid) ->
+ Pid ! {handle_syntax_error,{ConnHandle, ProtocolVersion, ErrorDescriptor}},
+ reply.
+
+handle_message_error(ConnHandle, ProtocolVersion, ErrorDescriptor, Pid) ->
+ Pid ! {handle_message_error,{ConnHandle, ProtocolVersion, ErrorDescriptor}},
+ reply.
+
+handle_trans_request(ConnHandle, ProtocolVersion, ActionRequests, Pid) ->
+ Pid ! {handle_trans_request,{ConnHandle, ProtocolVersion, ActionRequests}},
+ ED = #'ErrorDescriptor'{errorCode = ?megaco_not_implemented,
+ errorText = "not implemented yet"},
+ {discard_ack, ED}.
+
+handle_trans_long_request(ConnHandle, ProtocolVersion, Data, Pid) ->
+ Pid ! {handle_trans_long_request,{ConnHandle, ProtocolVersion, Data}},
+ ED = #'ErrorDescriptor'{errorCode = ?megaco_not_implemented,
+ errorText = "not implemented yet"},
+ {discard_ack, ED}.
+
+handle_trans_reply(ConnHandle, ProtocolVersion, ActualReply, Data, Pid) ->
+ Pid ! {handle_trans_reply,{ConnHandle, ProtocolVersion, ActualReply, Data}},
+ ok.
+
+handle_trans_ack(ConnHandle, ProtocolVersion, Status, Data, Pid) ->
+ Pid ! {handle_trans_ack,{ConnHandle, ProtocolVersion, Status, Data}},
+ ok.
+
+handle_unexpected_trans(ReceiveHandle, ProtocolVersion, Trans, Pid) ->
+ Pid ! {handle_unexpected_trans,
+ {ReceiveHandle, ProtocolVersion, Trans, Pid}},
+ ok.
+
+handle_trans_request_abort(ReceiveHandle, ProtocolVersion, TransNo, HandlerPid, Pid) ->
+ Pid ! {handle_trans_request_abort,
+ {ReceiveHandle, ProtocolVersion, TransNo, HandlerPid}},
+ ok.
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+encode_msg(M, Mod, Conf) ->
+ Mod:encode_message(Conf, M).
+
+%% encode_msg(M, Mod, Conf, Ver) ->
+%% Mod:encode_message(Conf, Ver, M).
+
+decode_msg(M, Mod, Conf) ->
+ Mod:decode_message(Conf, M).
+
+%% decode_msg(M, Mod, Conf, Ver) ->
+%% Mod:decode_message(Conf, Ver, M).
+
+
+
+%%% -------------------------------------------------------------------------------
+%%% Megaco transport module interface
+%%% -------------------------------------------------------------------------------
+
+send_message(Pid, Data) ->
+ Pid ! {send_message, Data},
+ ok.
+
+% block(Pid) ->
+% Pid ! {block, dummy},
+% ok.
+
+unblock(Pid) ->
+ Pid ! {unblock, dummy},
+ ok.
+
+% close(Pid) ->
+% Pid ! {close, dummy},
+% ok.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+make_node_name(Name) ->
+ case string:tokens(atom_to_list(node()), [$@]) of
+ [_,Host] ->
+ list_to_atom(lists:concat([atom_to_list(Name) ++ "@" ++ Host]));
+ _ ->
+ exit("Test node must be started with '-sname'")
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+user_info(Mid, Key) ->
+ case (catch megaco:user_info(Mid, Key)) of
+ {'EXIT', _} = Error ->
+ ?ERROR(Error);
+ Val ->
+ ?LOG("user_info -> ok: "
+ "~n ~p"
+ "~n", [Val]),
+ Val
+ end.
+
+
+stop_user(Mid) ->
+ case (catch megaco:stop_user(Mid)) of
+ {'EXIT', _} = Error ->
+ ?ERROR(Error);
+ Val ->
+ ?LOG("stop_user -> ok:"
+ "~n ~p"
+ "~n", [Val]),
+ Val
+ end.
+
+connections() ->
+ system_info(connections).
+
+connections(Conns0) ->
+ Conns1 = lists:sort(Conns0),
+ case lists:sort(connections()) of
+ Conns1 ->
+ ?LOG("connections -> ok:"
+ "~n ~p"
+ "~n", [Conns1]),
+ Conns1;
+ Conns2 ->
+ ?ERROR({Conns1, Conns2}),
+ Conns2
+ end.
+
+system_info(Key) ->
+ megaco:system_info(Key).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+await_completion(Ids) ->
+ case megaco_test_generator_lib:await_completion(Ids) of
+ {ok, Reply} ->
+ d("OK => Reply: ~n~p", [Reply]),
+ ok;
+ {error, Reply} ->
+ d("ERROR => Reply: ~n~p", [Reply]),
+ ?ERROR({failed, Reply})
+ end.
+
+await_completion(Ids, Timeout) ->
+ case megaco_test_generator_lib:await_completion(Ids, Timeout) of
+ {ok, Reply} ->
+ d("OK => Reply: ~n~p", [Reply]),
+ ok;
+ {error, Reply} ->
+ d("ERROR => Reply: ~n~p", [Reply]),
+ ?ERROR({failed, Reply})
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+sleep(X) -> receive after X -> ok end.
+
+% error_msg(F,A) -> error_logger:error_msg(F ++ "~n",A).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+i(F) ->
+ i(F, []).
+
+i(F, A) ->
+ print(info, get(verbosity), now(), get(tc), "INF", F, A).
+
+
+d(F) ->
+ d(F, []).
+
+d(F, A) ->
+ print(debug, get(verbosity), now(), get(tc), "DBG", F, A).
+
+
+printable(_, debug) -> true;
+printable(info, info) -> true;
+printable(_,_) -> false.
+
+print(Severity, Verbosity, Ts, Tc, P, F, A) ->
+ print(printable(Severity,Verbosity), Ts, Tc, P, F, A).
+
+print(true, Ts, Tc, P, F, A) ->
+ io:format("*** [~s] ~s ~p ~s:~w ***"
+ "~n " ++ F ++ "~n",
+ [format_timestamp(Ts), P, self(), get(sname), Tc | A]);
+print(_, _, _, _, _, _) ->
+ ok.
+
+format_timestamp({_N1, _N2, N3} = Now) ->
+ {Date, Time} = calendar:now_to_datetime(Now),
+ {YYYY,MM,DD} = Date,
+ {Hour,Min,Sec} = Time,
+ FormatDate =
+ io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w",
+ [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]),
+ lists:flatten(FormatDate).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+to(To, Start) ->
+ To - (mtime() - Start).
+
+%% Time in milli seconds
+mtime() ->
+ {A,B,C} = erlang:now(),
+ A*1000000000+B*1000+(C div 1000).
+
+%% random_init() ->
+%% {A,B,C} = now(),
+%% random:seed(A,B,C).
+
+%% random() ->
+%% 10 * random:uniform(50).
+