📄 megaco_test_mgc.erl
字号:
%% ``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 via the world wide web 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.%% %% The Initial Developer of the Original Code is Ericsson Utvecklings AB.%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings%% AB. All Rights Reserved.''%% %% $Id$%%%%----------------------------------------------------------------------%% Purpose: Implements an "MGC" used by the test suite%%-----------------------------------------------------------------------module(megaco_test_mgc).-export([start/4, start/5, stop/1, get_stats/2, reset_stats/1, user_info/1, user_info/2, conn_info/1, conn_info/2, update_user_info/3, update_conn_info/3, request_ignore/1, request_discard/1, request_discard/2, request_pending/1, request_pending/2, request_pending_ignore/1, request_handle/1, request_handle/2, request_handle_pending/1, request_handle_pending/2, request_handle_sloppy/1, request_handle_sloppy/2, ack_info/2, abort_info/2, req_info/2, disconnect/2, verbosity/2]).-export([mgc/3]).%% Megaco callback api-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 ]).-include("megaco_test_lib.hrl").-include_lib("megaco/include/megaco.hrl").-include_lib("megaco/include/megaco_message_v1.hrl").-define(A4444, ["11111111", "00000000", "00000000"]).-define(A4445, ["11111111", "00000000", "11111111"]).-define(A5555, ["11111111", "11111111", "00000000"]).-define(A5556, ["11111111", "11111111", "11111111"]).-define(valid_actions, [ignore, pending, pending_ignore, discard_ack, handle_ack, handle_pending_ack, handle_sloppy_ack]).-record(mgc, {parent = undefined, tcp_sup = undefined, udp_sup = undefined, req_action = discard_ack, req_timeout = 0, mid = undefined, ack_info = undefined, abort_info = undefined, req_info = undefined, mg = []}).%%% ------------------------------------------------------------------start(Node, Mid, ET, Verbosity) -> %% Conf = [{megaco_trace, io}], %% Conf = [{megaco_trace, "megaco-mgc.trace"}], Conf = [{megaco_trace, false}], start(Node, Mid, ET, Conf, Verbosity).start(Node, Mid, ET, Conf, Verbosity) -> d("start mgc[~p]: ~p", [Node, Mid]), RI = {receive_info, mk_recv_info(ET)}, Config = [{local_mid, Mid}, RI] ++ Conf, Pid = spawn_link(Node, ?MODULE, mgc, [self(), Verbosity, Config]), await_started(Pid).mk_recv_info(ET) -> mk_recv_info(ET, []).mk_recv_info([], Acc) -> Acc;mk_recv_info([{Encoding, Transport}|ET], Acc) -> {EMod, Port} = select_encoding(Encoding), TMod = select_transport(Transport), RI = [{encoding_module, EMod}, {encoding_config, []}, {transport_module, TMod}, {port, Port}], mk_recv_info(ET, [RI|Acc]);mk_recv_info([{Encoding, EC, Transport}|ET], Acc) -> {EMod, Port} = select_encoding(Encoding), TMod = select_transport(Transport), RI = [{encoding_module, EMod}, {encoding_config, EC}, {transport_module, TMod}, {port, Port}], mk_recv_info(ET, [RI|Acc]);mk_recv_info([ET|_], _) -> throw({error, {invalid_encoding_transport, ET}}).select_encoding(text) -> {megaco_pretty_text_encoder, 2944};select_encoding(pretty_text) -> {megaco_pretty_text_encoder, 2944};select_encoding(compact_text) -> {megaco_compact_text_encoder, 2944};select_encoding(binary) -> {megaco_ber_bin_encoder, 2945};select_encoding(erl_dist) -> {megaco_erl_dist_encoder, 2946};select_encoding(Encoding) -> throw({error, {invalid_encoding, Encoding}}).select_transport(tcp) -> megaco_tcp;select_transport(udp) -> megaco_udp;select_transport(Transport) -> throw({error, {invalid_transport, Transport}}).await_started(Pid) -> receive {started, Pid} -> d("await_started ~p: ok", [Pid]), {ok, Pid}; {'EXIT', Pid, Reason} -> i("await_started ~p: received exit signal: ~p", [Pid, Reason]), exit({failed_starting, Pid, Reason}) after 10000 -> i("await_started ~p: timeout", [Pid]), exit({error, timeout}) end.stop(Pid) -> server_request(Pid, stop, stopped).get_stats(Pid, No) -> server_request(Pid, {statistics, No}, {statistics_reply, No}).reset_stats(Pid) -> server_request(Pid, reset_stats, reset_stats_ack).user_info(Pid) -> server_request(Pid, {user_info, all}, user_info_ack).user_info(Pid, Tag) -> server_request(Pid, {user_info, Tag}, user_info_ack).conn_info(Pid) -> server_request(Pid, {conn_info, all}, conn_info_ack).conn_info(Pid, Tag) -> server_request(Pid, {conn_info, Tag}, conn_info_ack).update_user_info(Pid, Tag, Val) -> server_request(Pid, {update_user_info, Tag, Val}, update_user_info_ack).update_conn_info(Pid, Tag, Val) -> server_request(Pid, {update_conn_info, Tag, Val}, update_conn_info_ack).disconnect(Pid, Reason) -> server_request(Pid, {disconnect, Reason}, disconnected).ack_info(Pid, InfoPid) -> Pid ! {ack_info, InfoPid, self()}.abort_info(Pid, InfoPid) -> Pid ! {abort_info, InfoPid, self()}.req_info(Pid, InfoPid) -> Pid ! {req_info, InfoPid, self()}.verbosity(Pid, V) -> Pid ! {verbosity, V, self()}.request_ignore(Pid) -> request_action(Pid, {ignore, infinity}).request_pending_ignore(Pid) -> request_action(Pid, {pending_ignore, infinity}).request_discard(Pid) -> request_discard(Pid,0).request_discard(Pid, To) -> request_action(Pid, {discard_ack, To}).request_pending(Pid) -> request_pending(Pid, 5000).request_pending(Pid, To) -> request_action(Pid, {pending, To}).request_handle(Pid) -> request_handle(Pid, 0).request_handle(Pid, To) -> request_action(Pid, {handle_ack, To}).request_handle_pending(Pid) -> request_handle_pending(Pid, 0).request_handle_pending(Pid, To) -> request_action(Pid, {handle_pending_ack, To}).request_handle_sloppy(Pid) -> request_handle_sloppy(Pid, 0).request_handle_sloppy(Pid, To) -> request_action(Pid, {handle_sloppy_ack, To}).request_action(Pid, Action) -> server_request(Pid, request_action, Action, request_action_ack).server_request(Pid, Req, ReplyTag) -> Pid ! {Req, self()}, receive {ReplyTag, Reply, Pid} -> Reply; {'EXIT', Pid, Reason} -> exit({failed, Req, Pid, Reason}) after 10000 -> exit({timeout, Req, Pid}) end.server_request(Pid, Req, ReqData, ReplyTag) -> Pid ! {Req, ReqData, self()}, receive {ReplyTag, Reply, Pid} -> Reply; {'EXIT', Pid, Reason} -> exit({failed, Req, Pid, Reason}) after 10000 -> exit({timeout, Req, Pid}) end.server_reply(Pid, ReplyTag, Reply) -> Pid ! {ReplyTag, Reply, self()}.%%% ------------------------------------------------------------------mgc(Parent, Verbosity, Config) -> process_flag(trap_exit, true), put(verbosity, Verbosity), put(sname, "MGC"), i("mgc -> starting"), {Mid, TcpSup, UdpSup} = init(Config), notify_started(Parent), S = #mgc{parent = Parent, tcp_sup = TcpSup, udp_sup = UdpSup, mid = Mid}, i("mgc -> started"), loop(S).init(Config) -> d("init -> entry"), Mid = get_conf(local_mid, Config), RI = get_conf(receive_info, Config), d("init -> start megaco"), application:start(megaco), d("init -> possibly enable megaco trace"), case lists:keysearch(megaco_trace, 1, Config) of {value, {megaco_trace, true}} -> megaco:enable_trace(max, io); {value, {megaco_trace, io}} -> megaco:enable_trace(max, io); {value, {megaco_trace, File}} when list(File) -> megaco:enable_trace(max, File); _ -> ok end, Conf0 = lists:keydelete(megaco_trace, 1, Config), d("init -> start megaco user"), Conf1 = lists:keydelete(local_mid, 1, Conf0), Conf2 = lists:keydelete(receive_info, 1, Conf1), ok = megaco:start_user(Mid, Conf2), d("init -> update user info (user_mod)"), ok = megaco:update_user_info(Mid, user_mod, ?MODULE), d("init -> update user info (user_args)"), ok = megaco:update_user_info(Mid, user_args, [self()]), d("init -> get user info (receive_handle)"), RH = megaco:user_info(Mid,receive_handle), d("init -> parse receive info"), ListenTo = parse_receive_info(RI, RH), d("init -> start transports"), {Tcp, Udp} = start_transports(ListenTo), {Mid, Tcp, Udp}. loop(S) -> d("loop -> await request"), receive {stop, Parent} when S#mgc.parent == Parent -> i("loop -> stopping", []), Mid = S#mgc.mid, (catch close_conns(Mid)), megaco:stop_user(Mid), application:stop(megaco), i("loop -> stopped", []), server_reply(Parent, stopped, ok), exit(normal); {{disconnect, Reason}, Parent} when S#mgc.parent == Parent -> i("loop -> disconnecting", []), Mid = S#mgc.mid, [Conn|_] = megaco:user_info(Mid, connections), Res = megaco:disconnect(Conn, {self(), Reason}), server_reply(Parent, disconnected, Res), loop(S); {{update_user_info, Tag, Val}, Parent} when S#mgc.parent == Parent -> i("loop -> got update_user_info: ~w -> ~p", [Tag, Val]), Res = (catch megaco:update_user_info(S#mgc.mid, Tag, Val)), d("loop -> Res: ~p", [Res]), server_reply(Parent, update_user_info_ack, Res), loop(S); {{user_info, Tag}, Parent} when S#mgc.parent == Parent -> i("loop -> got user_info request for ~w", [Tag]), Res = (catch megaco:user_info(S#mgc.mid, Tag)), d("loop -> Res: ~p", [Res]),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -