megaco_test_generator.erl
来自「OTP是开放电信平台的简称」· ERL 代码 · 共 1,523 行 · 第 1/4 页
ERL
1,523 行
end;do_megaco({listen, Opts0}, #megaco{recv_handle = RH, port = Port, transport_sup = Pid} = State) when RH#megaco_receive_handle.send_mod == megaco_udp -> p("listen(udp) - open"), Opts = [{port, Port}, {receive_handle, RH}|Opts0], case megaco_udp:open(Pid, Opts) of {ok, _SH, _CtrlPid} -> State; Else -> megaco_error({listen, Opts0}, {failed_starting_udp_open, Else}) end;do_megaco({connect, Host, Opts0}, #megaco{transport_sup = Sup, recv_handle = RH, port = Port} = State) -> #megaco_receive_handle{send_mod = TM} = RH, p("connect ~w ~p", [TM,Host]), PrelMid = preliminary_mid, case TM of megaco_tcp -> Opts = [{host, Host}, {port, Port}, {receive_handle, RH}|Opts0], case (catch megaco_tcp:connect(Sup, Opts)) of {ok, SH, ControlPid} -> d("tcp connected: ~p, ~p", [SH, ControlPid]), megaco_connector_start(RH, PrelMid, SH, ControlPid), State#megaco{send_handle = SH, ctrl_pid = ControlPid}; Error -> megaco_error({connect, tcp, Host, Opts0}, Error) end; megaco_udp -> Opts = [{port, 0}, {receive_handle, RH}|Opts0], d("udp open", []), case (catch megaco_udp:open(Sup, Opts)) of {ok, Handle, ControlPid} -> d("udp opened: ~p, ~p", [Handle, ControlPid]), SH = megaco_udp:create_send_handle(Handle, Host, Port), megaco_connector_start(RH, PrelMid, SH, ControlPid), State#megaco{send_handle = SH, ctrl_pid = ControlPid}; Error -> megaco_error({connect, udp, Host, Opts0}, Error) end; megaco_test_generic_transport -> Opts = [{host, Host}, {port, Port}, {receive_handle, RH}|Opts0], case (catch megaco_test_generic_transport:connect(Sup, Opts)) of {ok, SH, ControlPid} -> d("generic connected: ~p, ~p", [SH, ControlPid]), megaco_connector_start(RH, PrelMid, SH, ControlPid), State#megaco{send_handle = SH, ctrl_pid = ControlPid}; Error -> megaco_error({connect, generic, Host, Opts0}, Error) end end;do_megaco(megaco_connect, State) -> p("megaco_connect"), receive {megaco_connect_result, {ok, CH}} -> p("megaco connect succeeded: ~p", [CH]), State#megaco{conn_handle = CH}; {megaco_connect_result, Error} -> p("megaco connect failed: ~p", [Error]), #megaco{result = Res} = State, State#megaco{result = [Error|Res]} end;do_megaco({megaco_user_info, Tag}, #megaco{mid = Mid, result = Res} = State) when Mid /= undefined -> p("megaco_user_info: ~w", [Tag]), Val = (catch megaco:user_info(Mid, Tag)), d("megaco_user_info: ~p", [Val]), State#megaco{result = [Val|Res]};do_megaco({megaco_update_user_info, Tag, Val}, #megaco{mid = Mid} = State) when Mid /= undefined -> p("megaco_update_user_info: ~w -> ~p", [Tag, Val]), ok = megaco:update_user_info(Mid, Tag, Val), State;do_megaco({megaco_conn_info, Tag}, #megaco{conn_handle = CH, result = Res} = State) when CH /= undefined -> p("megaco_conn_info: ~w", [Tag]), Val = (catch megaco:conn_info(CH, Tag)), d("megaco_conn_info: ~p", [Val]), State#megaco{result = [Val|Res]};do_megaco({megaco_update_conn_info, Tag, Val}, #megaco{conn_handle = CH} = State) when CH /= undefined -> p("megaco_update_conn_info: ~w -> ~p", [Tag, Val]), ok = megaco:update_conn_info(CH, Tag, Val), State;do_megaco({megaco_system_info, Tag}, #megaco{result = Res} = State) -> p("megaco_system_info: ~w", [Tag]), Val = (catch megaco:system_info(Tag)), d("megaco_system_info: ~p", [Val]), State#megaco{result = [Val|Res]};%% This is either a MG or a MGC which is only connected to one MGdo_megaco({megaco_call, ARs, Opts}, #megaco{conn_handle = CH} = State) when CH /= undefined -> p("megaco_call"), {_PV, UserReply} = megaco:call(CH, ARs, Opts), d("megaco_cast -> UserReply: ~n~p", [UserReply]), State;do_megaco({megaco_call, RemoteMid, ARs, Opts}, #megaco{mid = Mid} = State) -> p("megaco_call: ~p", [RemoteMid]), %% First we have to find the CH for this Mid Conns = megaco:user_info(Mid, connections), {value, {_, CH}} = lists:keysearch(RemoteMid, #megaco_conn_handle.remote_mid, Conns), {_PV, UserReply} = megaco:call(CH, ARs, Opts), d("megaco_call -> UserReply: ~n~p", [UserReply]), State;%% This is either a MG or a MGC which is only connected to one MGdo_megaco({megaco_cast, ARs, Opts}, #megaco{conn_handle = CH} = State) when CH /= undefined -> p("megaco_cast"), case megaco:cast(CH, ARs, Opts) of ok -> State; Error -> d("failed sending (cast) message: ~n~p", [Error]), #megaco{result = Acc} = State, {error, State#megaco{result = [Error|Acc]}} end;do_megaco({megaco_cast, RemoteMid, ARs, Opts}, #megaco{mid = Mid} = State) -> p("megaco_cast: ~p", [RemoteMid]), %% First we have to find the CH for this Mid Conns = megaco:user_info(Mid, connections), {value, {_, CH}} = lists:keysearch(RemoteMid, #megaco_conn_handle.remote_mid, Conns), case megaco:cast(CH, ARs, Opts) of ok -> State; Error -> d("failed sending (cast) message: ~n~p", [Error]), #megaco{result = Acc} = State, {error, State#megaco{result = [Error|Acc]}} end;%% Nothing shall happen for atleast Timeout timedo_megaco({megaco_callback, nocall, Timeout}, State) -> p("megaco_callback [~w]", [nocall]), receive {handle_megaco_callback, Type, Msg, Pid} -> d("received unexpected megaco callback: ~n~p", [Msg]), #megaco{result = Res} = State, Err = {unexpected_callback, Type, Msg, Pid}, {error, State#megaco{result = [Err|Res]}} after Timeout -> State end;do_megaco({megaco_callback, Tag, Verify}, State) when is_function(Verify) -> p("megaco_callback [~w]", [Tag]), receive {handle_megaco_callback, Type, Msg, Pid} -> d("received megaco callback: ~n~p", [Msg]), case Verify(Msg) of {VRes, Res, Reply} -> d("megaco_callback [~w] ~w",[Tag, VRes]), handle_megaco_callback_reply(Pid, Type, Reply), validate(VRes, Tag, Res, State); {VRes, Delay, Res, Reply} -> d("megaco_callback [~w] ~w, ~w",[Tag,Delay,VRes]), handle_megaco_callback_reply(Pid, Type, Delay, Reply), validate(VRes, Tag, Res, State) end end;do_megaco({megaco_callback, Tag, {VMod, VFunc, VArgs}}, State) when is_atom(VMod) and is_atom(VFunc) and is_list(VArgs) -> p("megaco_callback [~w]", [Tag]), receive {handle_megaco_callback, Type, Msg, Pid} -> d("received megaco callback: ~n~p" "~n VMod: ~w" "~n VFunc: ~w" "~n VArgs: ~p", [Msg, VMod, VFunc, VArgs]), case apply(VMod, VFunc, [Msg|VArgs]) of {VRes, Res, Reply} -> d("megaco_callback [~w] ~w",[Tag, VRes]), handle_megaco_callback_reply(Pid, Type, Reply), validate(VRes, Tag, Res, State); {VRes, Delay, Res, Reply} -> d("megaco_callback [~w] ~w, ~w",[Tag,Delay,VRes]), handle_megaco_callback_reply(Pid, Type, Delay, Reply), validate(VRes, Tag, Res, State) end end;do_megaco({megaco_callback, Tag, Verify, Timeout}, State) when is_function(Verify) and (is_integer(Timeout) and (Timeout > 0)) -> p("megaco_callback [~w]", [Tag]), receive {handle_megaco_callback, Type, Msg, Pid} -> d("received megaco callback: ~n~p", [Msg]), case Verify(Msg) of {VRes, Res, Reply} -> d("megaco_callback [~w] ~w",[Tag,VRes]), handle_megaco_callback_reply(Pid, Type, Reply), validate(VRes, Tag, Res, State); {VRes, Delay, Res, Reply} -> d("megaco_callback [~w] ~w, ~w",[Tag,Delay,VRes]), handle_megaco_callback_reply(Pid, Type, Delay, Reply), validate(VRes, Tag, Res, State) end after Timeout -> #megaco{result = Res} = State, Err = {callback_timeout, Tag, Timeout}, {error, State#megaco{result = [Err|Res]}} end;do_megaco({megaco_callback, Verifiers}, State) -> p("megaco_callback"), (catch megaco_callback_verify(Verifiers, State));do_megaco({megaco_cancel, Reason}, #megaco{conn_handle = CH} = State) -> p("megaco_cancel [~w]", [Reason]), case megaco:cancel(CH, Reason) of ok -> State; Error -> d("failed cancel: ~n~p", [Error]), #megaco{result = Acc} = State, {error, State#megaco{result = [Error|Acc]}} end;do_megaco({trigger, Trigger}, State) when is_function(Trigger) -> p("trigger"), Trigger(), State;do_megaco({sleep, To}, State) -> p("sleep ~p", [To]), sleep(To), State;do_megaco(Instr, _State) -> megaco_error(Instr, invalid_instruction).%% This is used when a number of callback's is expected, but where%% the specific order is unknown.megaco_callback_verify([], State) -> d("megaco_callback_verify -> done"), State;megaco_callback_verify(Verifiers0, State0) -> d("megaco_callback_verify -> entry when" "~n length(Verifiers0): ~w", [length(Verifiers0)]), receive {handle_megaco_callback, Type, Msg, Pid} -> d("received megaco callback: ~w~n~p", [Type,Msg]), case megaco_callback_verify(Verifiers0, Type, Msg, Pid, State0) of {ok, Verifiers, State} -> megaco_callback_verify(Verifiers, State); Error -> Error end end. megaco_callback_verify(Verifiers0, Type, Msg, Pid, State0) -> d("megaco_callback_verify -> entry"), Tag = element(1,Msg), d("megaco_callback_verify -> Tag: ~w",[Tag]), case lists:keysearch(Tag, 1, Verifiers0) of {value, {Tag, N, Verify}} when (N > 0) and is_function(Verify) -> d("megaco_callback_verify -> N: ~w",[N]), case Verify(Msg) of {VRes, Res, Reply} -> d("megaco_callback_verify -> VRes: ~w",[VRes]), handle_megaco_callback_reply(Pid, Type, Reply), case validate(VRes, Tag, Res, State0) of {error, _} = EState -> d("megaco_callback_verify -> (1) error"), throw(EState); State when N > 1 -> d("megaco_callback_verify -> (1) validated"), Rec = {Tag, N-1, Verify}, Verifiers = lists:keyreplace(Tag, 1, Verifiers0, Rec), {ok, Verifiers, State}; State -> d("megaco_callback_verify -> (2) validated"), Verifiers = lists:keydelete(Tag, 1, Verifiers0), {ok, Verifiers, State} end; {VRes, Delay, Res, Reply} -> d("megaco_callback_verify -> Delay: ~w, VRes: ~w", [Delay,VRes]), handle_megaco_callback_reply(Pid, Type, Delay, Reply), case validate(VRes, Tag, Res, State0) of {error, _} = EState -> d("megaco_callback_verify -> (2) error"), throw(EState); State when N > 1 -> d("megaco_callback_verify -> (3) validated"), Rec = {Tag, N-1, Verify}, Verifiers = lists:keyreplace(Tag, 1, Verifiers0, Rec), {ok, Verifiers, State}; State -> d("megaco_callback_verify -> (4) validated"), Verifiers = lists:keydelete(Tag, 1, Verifiers0), {ok, Verifiers, State} end end; false -> d("megaco_callback_verify -> no such tag ~w~n~p", [Tag, Verifiers0]), #megaco{result = Res} = State0, State = State0#megaco{result = [{Type, error, Msg}|Res]}, throw({error, State}) end.validate(ok, handle_connect = Tag, CH, #megaco{result = Acc} = S) -> S#megaco{conn_handle = CH, result = [{Tag, ok, CH}|Acc]};validate(ok, Tag, Res, #megaco{result = Acc} = S) -> S#megaco{result = [{Tag, ok, Res}|Acc]};validate(error, Tag, Res, #megaco{result = Acc} = S) -> {error, S#megaco{result = [{Tag, error, Res}|Acc]}}.megaco_error(Instr, Error) -> throw({error, {Instr, Error}}).megaco_connector_start(RH, PrelMid, SH, ControlPid) -> spawn_link(?MODULE, megaco_connect, [RH, PrelMid, SH, ControlPid, self()]).megaco_connect(RH, PrelMid, SH, ControlPid, Parent) -> Result = megaco:connect(RH, PrelMid, SH, ControlPid), Parent ! {megaco_connect_result, Result}, exit(normal).megaco_cleanup(#megaco{mid = Mid}) -> Close = fun(CH) -> do_megaco_cleanup(CH) end, Conns = megaco:user_info(Mid, connections), lists:foreach(Close, Conns).do_megaco_cleanup(CH) -> case (catch do_megaco_cleanup2(CH)) of ok -> ok; {'EXIT', {no_such_connection, _}} -> ok; {'EXIT', Reason} -> exit(Reason) end.do_megaco_cleanup2(CH) -> d("do_megaco_cleanup2 -> entry with" "~n CH: ~p", [CH]), Reason = {stopped_by_user,self()}, Pid = megaco:conn_info(CH, control_pid), SendMod = megaco:conn_info(CH, send_mod), SendHandle = megaco:conn_info(CH, send_handle), d("do_megaco_cleanup2 -> disconnect"), megaco:disconnect(CH, Reason), d("do_megaco_cleanup2 -> disconnected, now cancel"), megaco:cancel(CH, Reason), d("do_megaco_cleanup2 -> canceled, now close"), case SendMod of megaco_tcp -> megaco_tcp:close(SendHandle); megaco_udp -> megaco_udp:close(SendHandle); SendMod -> exit(Pid, Reason) end, ok.parse_megaco([], RevInstrs) -> {ok, lists:reverse(RevInstrs)};
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?