diff options
Diffstat (limited to 'lib/megaco/test/megaco_mess_user_test.erl')
-rw-r--r-- | lib/megaco/test/megaco_mess_user_test.erl | 309 |
1 files changed, 309 insertions, 0 deletions
diff --git a/lib/megaco/test/megaco_mess_user_test.erl b/lib/megaco/test/megaco_mess_user_test.erl new file mode 100644 index 0000000000..50284be549 --- /dev/null +++ b/lib/megaco/test/megaco_mess_user_test.erl @@ -0,0 +1,309 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2000-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: A fun implementation of user callbacks +%%---------------------------------------------------------------------- + +-module(megaco_mess_user_test). + +-behaviour(megaco_user). + +-export([ + handle_connect/2, handle_connect/3, + handle_disconnect/3, + handle_syntax_error/3, handle_syntax_error/4, + handle_message_error/3, handle_message_error/4, + handle_trans_request/3, handle_trans_request/4, + handle_trans_long_request/3, handle_trans_long_request/4, + handle_trans_reply/4, handle_trans_reply/5, + handle_trans_ack/4, handle_trans_ack/5, + handle_unexpected_trans/3, handle_unexpected_trans/4, + handle_trans_request_abort/4, handle_trans_request_abort/5, + handle_segment_reply/5, handle_segment_reply/6 + ]). + +-export([ + start_proxy/0, + stop_proxy/0, + apply_proxy/1, + reply/3, + + start_transport/2, + loop_transport/1, % Internal only + send_message/2, + resend_message/2 + ]). + +-include("megaco_test_lib.hrl"). +-define(SERVER, ?MODULE). + +start_proxy() -> + yes = global:register_name(?SERVER, self()), + Pid = megaco_test_lib:proxy_start(?MODULE), + put(?MODULE, Pid), + Pid. + +stop_proxy() -> + global:unregister_name(?SERVER), + Pid = erase(?MODULE), + unlink(Pid), + exit(Pid, shutdown). + +whereis_proxy() -> + case get(?MODULE) of + undefined -> + exit(no_server, ?MODULE); + Pid when is_pid(Pid) -> + Pid + end. + +apply_proxy(Fun) -> + Pid = whereis_proxy(), + ?APPLY(Pid, Fun), + ok. + +reply(Mod, Line, Fun) when is_function(Fun) -> + receive + {?MODULE, Pid, UserCallback} -> + UserReply = Fun(UserCallback), + Pid ! {?MODULE, self(), UserReply}, + UserReply; + Other -> + megaco_test_lib:error(Other, Mod, Line), + {error, Other} +%% after 1000 -> +%% megaco_test_lib:error(timeout, Mod, Line), +%% {error, timeout} + end. + +call(UserCallback) -> + Request = {?MODULE, self(), UserCallback}, + case global:whereis_name(?SERVER) of + undefined -> + exit({no_server, ?SERVER, Request}); + Pid when is_pid(Pid) -> + ?LOG("call[~p] -> bang request: " + "~n ~p" + "~n", [Pid, Request]), + Pid ! Request, + call_await_reply(Pid) + end. + +call_await_reply(Pid) -> + receive + {?MODULE, Pid, UserReply} = _Reply -> + case UserReply of + {ok, Good} -> Good; + {error, Bad} -> exit(Bad) + end; + {'EXIT', Pid, Reason} = Bad -> + ?LOG("receive test case exit: ~p~n", [Bad]), + exit(Reason); + {'EXIT', _, _Reason} = Bad -> + ?LOG("receive unknown exit: ~p~n", [Bad]), + call_await_reply(Pid); + Bad -> + ?LOG("receive other: ~p~n", [Bad]), + exit(Bad) + end. + +%%---------------------------------------------------------------------- +%% Megaco user callback +%%---------------------------------------------------------------------- + +%% -- handle_connect/2 -- + +handle_connect(ConnHandle, ProtocolVersion) -> +%% io:format("~p~p[~p]: handle_connect -> entry with" +%% "~n ConnHandle: ~p" +%% "~n ProtocolVersion: ~p" +%% "~n", +%% [self(), ?MODULE, ?LINE, ConnHandle, ProtocolVersion]), + call({connect, ConnHandle, ProtocolVersion, []}). + +handle_connect(ConnHandle, ProtocolVersion, Extra) -> +%% io:format(user,"~p~p[~p]: handle_connect -> entry with" +%% "~n ConnHandle: ~p" +%% "~n ProtocolVersion: ~p" +%% "~n Extra: ~p" +%% "~n", +%% [self(), ?MODULE, ?LINE, ConnHandle, ProtocolVersion, Extra]), + call({connect, ConnHandle, ProtocolVersion, [Extra]}). + + +%% -- handle_disconnect/3 -- + +handle_disconnect(ConnHandle, ProtocolVersion, Reason) -> + %% io:format("~w:~w:~p:handle_disconnect -> entry with" + %% "~n ConnHandle: ~p" + %% "~n ProtocolVersion: ~p" + %% "~n Reason: ~p" + %% "~n", + %% [?MODULE, ?LINE, self(), ConnHandle, ProtocolVersion, Reason]), + call({disconnect, ConnHandle, ProtocolVersion, [Reason]}). + + +%% -- handle_syntax_error/3,4 -- + +handle_syntax_error(ReceiveHandle, ProtocolVersion, ErrorDescriptor) -> + call({syntax_error, ReceiveHandle, ProtocolVersion, [ErrorDescriptor]}). + +handle_syntax_error(ReceiveHandle, ProtocolVersion, ErrorDescriptor, Extra) -> + call({syntax_error, ReceiveHandle, ProtocolVersion, [ErrorDescriptor, Extra]}). + + +%% -- handle_message_error/3,4 -- + +handle_message_error(ConnHandle, ProtocolVersion, ErrorDescriptor) -> + call({message_error, ConnHandle, ProtocolVersion, [ErrorDescriptor]}). + +handle_message_error(ConnHandle, ProtocolVersion, ErrorDescriptor, Extra) -> + call({message_error, ConnHandle, ProtocolVersion, [ErrorDescriptor, Extra]}). + + +%% -- handle_trans_request/3,4 -- + +handle_trans_request(ConnHandle, ProtocolVersion, ActionRequests) -> + call({request, ConnHandle, ProtocolVersion, [ActionRequests]}). + +handle_trans_request(ConnHandle, ProtocolVersion, ActionRequests, Extra) -> + call({request, ConnHandle, ProtocolVersion, [ActionRequests, Extra]}). + +%% -- handle_trans_long_request/3,4 -- + +handle_trans_long_request(ConnHandle, ProtocolVersion, RequestData) -> + call({long_request, ConnHandle, ProtocolVersion, [RequestData]}). + +handle_trans_long_request(ConnHandle, ProtocolVersion, RequestData, Extra) -> + call({long_request, ConnHandle, ProtocolVersion, [RequestData, Extra]}). + + +%% -- handle_trans_relpy/4,5 -- + +handle_trans_reply(ConnHandle, ProtocolVersion, UserReply, UserData) -> + call({reply, ConnHandle, ProtocolVersion, [UserReply, UserData]}). + +handle_trans_reply(ConnHandle, ProtocolVersion, UserReply, UserData, Extra) -> + call({reply, ConnHandle, ProtocolVersion, [UserReply, UserData, Extra]}). + + +%% -- handle_trans_relpy/4,5 -- + +handle_trans_ack(ConnHandle, ProtocolVersion, AckStatus, AckData) -> + call({ack, ConnHandle, ProtocolVersion, [AckStatus, AckData]}). + +handle_trans_ack(ConnHandle, ProtocolVersion, AckStatus, AckData, Extra) -> + call({ack, ConnHandle, ProtocolVersion, [AckStatus, AckData, Extra]}). + + +%% -- handle_unexpected_trans/3,4 -- + +handle_unexpected_trans(ConnHandle, ProtocolVersion, Trans) -> + call({unepected_trans, ConnHandle, ProtocolVersion, [Trans]}). + +handle_unexpected_trans(ConnHandle, ProtocolVersion, Trans, Extra) -> + call({unepected_trans, ConnHandle, ProtocolVersion, [Trans, Extra]}). + + +%% -- handle_trans_request_abort/4,5 -- + +handle_trans_request_abort(ConnHandle, ProtocolVersion, TransId, Pid) -> + call({request_abort, ConnHandle, ProtocolVersion, [TransId, Pid]}). + +handle_trans_request_abort(ConnHandle, ProtocolVersion, TransId, Pid, Extra) -> + call({request_abort, ConnHandle, ProtocolVersion, [TransId, Pid, Extra]}). + + +%% -- handle_segment_reply/5,6 -- + +handle_segment_reply(ConnHandle, ProtocolVersion, TransId, SN, SC) -> + call({segment_reply, ConnHandle, ProtocolVersion, [TransId, SN, SC]}). + +handle_segment_reply(ConnHandle, ProtocolVersion, TransId, SN, SC, Extra) -> + call({segment_reply, ConnHandle, ProtocolVersion, [TransId, SN, SC, Extra]}). + + +%%---------------------------------------------------------------------- +%% The ultimate Megaco transport callback +%%---------------------------------------------------------------------- + +start_transport(MgReceiveHandle, MgcReceiveHandle) -> + MgControlPid = spawn_link(?MODULE, loop_transport, [self()]), + MgSendHandle = {MgcReceiveHandle, MgControlPid}, + MgcControlPid = spawn_link(?MODULE, loop_transport, [self()]), + MgcSendHandle = {MgReceiveHandle, MgcControlPid}, + SendHandle = {MgSendHandle, MgcSendHandle}, + {ok, MgControlPid, SendHandle}. + +loop_transport(Parent) -> + receive + {'EXIT', _Pid, Reason} = Error -> + ok = io:format("transport stopped: ~p~n", [{Parent, Error}]), + exit(Reason) + end. + +send_message(Handles, Bin) -> + ?LOG("send_message -> entry with" + "~n Handles: ~p" + "~n", [Handles]), + case megaco_tc_controller:lookup(allow_send_message) of + {value, ok} -> + do_send_message(Handles, Bin); + {value, {fail, Reason}} -> + {error, Reason}; + {value, {cancel, Reason}} -> + {cancel, Reason}; + {value, {skip, Result}} -> + Result; + false -> + do_send_message(Handles, Bin) + end. + +resend_message(Handles, Bin) -> + ?LOG("resend_message -> entry with" + "~n Handles: ~p" + "~n", [Handles]), + case megaco_tc_controller:lookup(allow_resend_message) of + {value, ok} -> + do_send_message(Handles, Bin); + {value, {fail, Reason}} -> + {error, Reason}; + {value, {cancel, Reason}} -> + {cancel, Reason}; + {value, {skip, Result}} -> + Result; + false -> + do_send_message(Handles, Bin) + end. + +do_send_message({{RH, Pid} = LocalSendHandle, RemoteSendHandle}, Bin) -> + ?LOG("do_send_message -> entry with" + "~n RH: ~p" + "~n Pid: ~p" + "~n RemoteSendHandle: ~p" + "~n", [RH, Pid, RemoteSendHandle]), + SwappedSendHandle = {RemoteSendHandle, LocalSendHandle}, + case megaco_tc_controller:lookup(extra_transport_info) of + {value, Extra} -> + megaco:receive_message(RH, Pid, SwappedSendHandle, Bin, Extra); + _ -> + megaco:receive_message(RH, Pid, SwappedSendHandle, Bin) + end. |