📄 megacosessionudp_impl.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: Send and process a (sequence of) Megaco/H.248 transactions%%-----------------------------------------------------------------------module('MegacoSessionUdp_impl').%% Application internal export-export([ init/1, handle_info/2, terminate/2, code_change/3 ]).%% Module internal export-export([ open/5, close/4, block/4, unblock/4 ]).-include_lib("megaco/include/megaco.hrl").-include_lib("megaco_session/include/Megaco.hrl").-include_lib("megaco_session/include/MegacoSessionIp.hrl").-include_lib("megaco_session/include/MegacoSessionUdp.hrl").-record(state,{sup}).%% Defines:-define(EXT(Fun, Value), megaco_session_externalizer:Fun(Value, undefined)).-define(INT(Fun, Value), megaco_session_internalizer:Fun(Value, undefined)).-define(d(F,A),dbg(F,A)).%%----------------------------------------------------------%% Gen server API%%----------------------------------------------------------init(_Env) -> put(debug, get_debug()), ?d("init -> start transport", []), case megaco_udp:start_transport() of {ok,SupPid} -> ?d("init -> transport started: ~p",[SupPid]), {ok,#state{sup = SupPid}}; {error,Reason} -> ?d("init -> transport start failed: ~p",Reason), {stop,{start_transport_failed,Reason}}; Else -> ?d("init -> Else: ~w",Else), {stop,{unexpected_response_from_start_transport,Else}} end.handle_info(Info, State) -> ?d("handle_info -> entry with" "~n Info: ~p",[Info]), {noreply,State}.terminate(Reason, State) -> ?d("terminate -> entry with" "~n Reason: ~p",[Reason]), ok.code_change({down,Vsn}, State, Extra) -> {ok,State};code_change(Vsn,State,Extra) -> {ok,State}.%%----------------------------------------------------------%% App API%%----------------------------------------------------------open(State, RequestRef, ReplyTo, ReceiveHandle, Options) -> ?d("open -> entry with" "~n RequestRef: ~w" "~n ReplyTo: ~w" "~n ReceiveHandle: ~w" "~n Options: ~w",[RequestRef, ReplyTo, ReceiveHandle, Options]), case (catch do_open(State, ReplyTo, ReceiveHandle, Options)) of {ok, SendHandle, CtrlPid} -> ?d("open -> performed: " "~n SendHandle: ~w" "~n CtrlPid: ~w", [SendHandle, CtrlPid]), open_response(ReplyTo, RequestRef, SendHandle, CtrlPid); Error -> ?d("open -> error: " "~n Error: ~w", [Error]), open_response(ReplyTo, RequestRef, Error) end, {noreply, State}.do_open(State, ReplyTo, ReceiveHandle, Options0) -> RH = ?INT(tr_receive_handle, ReceiveHandle), RH2 = RH#megaco_receive_handle{send_mod = megaco_udp}, Sup = State#state.sup, Options1 = ?INT(tr_IpOptions, Options0), {Host, Port, Options2} = get_host_and_port(Options1), do_open(Host, Port, RH2, Options2, Sup).%% This is an MGC:do_open(nohost, Port, RecvHandle, Opts0, Sup) -> ?d("do_open -> entry with" "~n Port: ~w" "~n RecvHandle: ~w" "~n Opts0: ~w" "~n Sup: ~w", [Port, RecvHandle, Opts0, Sup]), Opts = [{receive_handle, RecvHandle}, {port, Port} | Opts0], case megaco_udp:open(Sup, Opts) of {ok, SendHandle, CtrlPid} -> {ok, ?EXT(tr_send_handle, SendHandle), CtrlPid}; Error -> Error end;%% This is an MGdo_open(MgcHost, MgcPort, RecvHandle, Opts0, Sup) -> ?d("do_open -> entry with" "~n MgcHost: ~w" "~n MgcPort: ~w" "~n RecvHandle: ~w" "~n Opts0: ~w" "~n Sup: ~w", [MgcHost, MgcPort, RecvHandle, Opts0, Sup]), Opts = [{receive_handle, RecvHandle}, {port, 0} | Opts0], case megaco_udp:open(Sup, Opts) of {ok, Handle, CtrlPid} -> SendHandle = megaco_udp:create_send_handle(Handle, MgcHost, MgcPort), {ok, ?EXT(tr_send_handle, SendHandle), CtrlPid}; Error -> Error end. get_host_and_port(Opts0) -> {Host, Opts1} = get_host(Opts0), {Port, Opts2} = get_port(Opts1), {Host, Port, Opts2}.get_host(Opts) -> case lists:keysearch(host, 1, Opts) of {value, {host, Host}} -> %% This is an MG {Host, lists:keydelete(host, 1, Opts)}; false -> %% This is an MGC {nohost, Opts} end.get_port(Opts) -> case lists:keysearch(port, 1, Opts) of {value, {port, Port}} -> {Port, lists:keydelete(port, 1, Opts)}; false -> %% Nothing given, so use the default for text {2944, Opts} end. %% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - close(State, RequestRef, ReplyTo, SendHandleBin) when binary(SendHandleBin) -> ?d("close -> entry with" "~n RequestRef: ~w" "~n ReplyTo: ~w",[RequestRef, ReplyTo]), SendHandle = ?INT(tr_send_handle, SendHandleBin), megaco_udp:close(SendHandle), close_response(ReplyTo, RequestRef), ?d("close -> done", []), {noreply,State}.%% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - block(State, RequestRef, ReplyTo, SendHandleBin) when binary(SendHandleBin) -> ?d("unblock -> entry with" "~n RequestRef: ~w" "~n ReplyTo: ~w",[RequestRef, ReplyTo]), SendHandle = ?INT(tr_send_handle, SendHandleBin), megaco_udp:block(SendHandle), block_response(ReplyTo, RequestRef), ?d("block -> done", []), {noreply,State}.%% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - unblock(State, RequestRef, ReplyTo, SendHandleBin) when binary(SendHandleBin) -> ?d("unblock -> entry with" "~n RequestRef: ~w" "~n ReplyTo: ~w",[RequestRef, ReplyTo]), SendHandle = ?INT(tr_send_handle, SendHandleBin), megaco_udp:unblock(SendHandle), unblock_response(ReplyTo, RequestRef), ?d("unblock -> done", []), {noreply,State}.%% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -%% Internal callback wrappers%% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -open_response(ReplyTo, RequestRef, {'EXIT',Reason}) -> ErrorString = lists:flatten( io_lib:format("Exit while handling open request: ~p",[Reason])), open_response1(ReplyTo, RequestRef,ErrorString);open_response(ReplyTo, RequestRef,{error,Reason}) -> ErrorString = lists:flatten( io_lib:format("Error while handling open request: ~p",[Reason])), open_response1(ReplyTo, RequestRef,ErrorString).open_response1(ReplyTo, RequestRef,ErrorString) -> Status = ?EXT(tr_Status, {errorString,ErrorString}), DummyHandle = term_to_binary([]), DummyCtrlPid = ReplyTo, open_response(ReplyTo, RequestRef, Status, DummyHandle, DummyCtrlPid).open_response(RequestRef, Pid, SendHandle, CtrlPid) -> open_response(RequestRef, Pid, ?EXT(tr_Status, ok), SendHandle, CtrlPid).open_response(ReplyTo, RequestRef,Status,SendHandle,CtrlPid) -> 'MegacoSessionUdpUser':openResponse(ReplyTo, RequestRef,Status,SendHandle,CtrlPid).close_response(ReplyTo, RequestRef) -> 'MegacoSessionUdpUser':closeResponse(ReplyTo, RequestRef, ?EXT(tr_Status, ok)).block_response(ReplyTo, RequestRef) -> 'MegacoSessionUdpUser':blockResponse(ReplyTo, RequestRef, ?EXT(tr_Status, ok)).unblock_response(ReplyTo, RequestRef) -> 'MegacoSessionUdpUser':unblockResponse(ReplyTo, RequestRef, ?EXT(tr_Status, ok)).%% ----------------------------------------------------------------------%% Internal functions%% ----------------------------------------------------------------------get_debug() -> app_get_env(udp_debug, false).app_get_env(Key, Default) -> case application:get_env(megaco_session, Key) of {ok, Value} -> Value; _ -> Default end.dbg(F, A) -> dbg(get(debug), F, A).dbg(true, F, A) -> io:format("MSUI-DBG:~w: " ++ F ++ "~n", [self()|A]);dbg(_, _, _) -> ok.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -