⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 megacosessiontcp_impl.erl

📁 一个Megaco实现源代码
💻 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('MegacoSessionTcp_impl').%% Application internal export-export([         init/1,         handle_info/2,         terminate/2,         code_change/3        ]).%% Module internal export-export([         listen/5,         connect/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/MegacoSessionTcp.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_tcp:start_transport() of	{ok, SupPid} ->	    ?d("init -> transport started: ~p",[SupPid]),	    {ok,#state{sup = SupPid}};	{error, Reason} ->	    ?d("init -> transport start failed: ~w",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%%----------------------------------------------------------%% MGC calls this:listen(State, RequestRef, ReplyTo, ReceiveHandle, Options) when pid(ReplyTo) ->    ?d("listen -> entry with"      "~n   RequestRef:    ~w"      "~n   ReplyTo:       ~w"      "~n   ReceiveHandle: ~w"      "~n   Options:       ~w",[RequestRef, ReplyTo, ReceiveHandle, Options]),    listen_response(ReplyTo, RequestRef, 		    (catch do_listen(State,ReceiveHandle,Options))),    {noreply,State}.do_listen(State,ReceiveHandle,Options) ->    Options2 = ?INT(tr_IpOptions, Options),    RH       = ?INT(tr_receive_handle, ReceiveHandle),    ?d("do_listen -> RH: ~w", [RH]),    RH2      = RH#megaco_receive_handle{send_mod = megaco_tcp},    ?d("do_listen -> RH2: ~w", [RH2]),    Sup      = State#state.sup,    case megaco_tcp:listen(Sup,[{receive_handle, RH2}|Options2]) of	ok ->	    ok;	Error ->	    ?d("do_listen -> Error: ~w", [Error]),	    Error    end;do_listen(_State, Error, _Options) ->    Error.%% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - %% MG calls this:connect(State, RequestRef, ReplyTo, ReceiveHandle, Options)   when pid(ReplyTo) ->    ?d("connect -> entry with"      "~n   RequestRef:    ~w"      "~n   ReplyTo:       ~w"      "~n   ReceiveHandle: ~w"      "~n   Options:       ~w",[RequestRef, ReplyTo, ReceiveHandle, Options]),    case (catch do_connect(State, ReceiveHandle, Options)) of	{ok, SendHandle, CtrlPid} ->	    ?d("connect -> performed:"	      "~n   SendHandle: ~w"	      "~n   CtrlPid:    ~w",[SendHandle, CtrlPid]),	    connect_response(ReplyTo, RequestRef, ok, SendHandle, CtrlPid);	Error ->	    connect_response(ReplyTo, RequestRef, Error)    end,    {noreply,State}.do_connect(State, RH0, Opts0) ->    Opts1 = ?INT(tr_IpOptions, Opts0),    RH1   = ?INT(tr_receive_handle, RH0),    RH2   = RH1#megaco_receive_handle{send_mod = megaco_tcp},    Sup   = State#state.sup,    ?d("do_connect -> call megaco_tcp:connect with"	"~n   RH2:   ~w"	"~n   Opts1: ~w",[RH2, Opts1]),    case megaco_tcp:connect(Sup,[{receive_handle, RH2}| Opts1]) of	{ok, SendHandle, CtrlPid} ->	    {ok, ?EXT(tr_send_handle, SendHandle), CtrlPid};	Error ->	    Error    end.    %% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - close(State, RequestRef, ReplyTo, SendHandleBin)   when pid(ReplyTo), binary(SendHandleBin) ->    SendHandle = binary_to_term(SendHandleBin),        megaco_tcp:close(SendHandle),    close_response(ReplyTo, RequestRef),    {noreply,State}.%% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - block(State, RequestRef, ReplyTo, SendHandleBin)   when pid(ReplyTo), binary(SendHandleBin) ->    SendHandle = binary_to_term(SendHandleBin),        megaco_tcp:block(SendHandle),    block_response(ReplyTo, RequestRef),    {noreply,State}.%% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - unblock(State, RequestRef, ReplyTo, SendHandleBin)   when pid(ReplyTo), binary(SendHandleBin) ->    SendHandle = binary_to_term(SendHandleBin),        megaco_tcp:unblock(SendHandle),    unblock_response(ReplyTo, RequestRef),    {noreply,State}.%% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -%% Internal callback wrappers%% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -listen_response(ReplyTo, RequestRef, ok) ->    Status = ?EXT(tr_Status, ok),    listen_response1(ReplyTo, RequestRef, Status);listen_response(ReplyTo, RequestRef, {'EXIT',Reason}) ->    ErrorString = 	lists:flatten(	  io_lib:format("Exit while handling listen request: ~p",[Reason])),    Status = ?EXT(tr_Status, {errorString,ErrorString}),    listen_response1(RequestRef,id,Status);listen_response(ReplyTo, RequestRef, {error,Reason}) ->    ErrorString = 	lists:flatten(	  io_lib:format("Error while handling listen request: ~p",[Reason])),    Status = ?EXT(tr_Status, {errorString,ErrorString}),    listen_response1(ReplyTo, RequestRef, Status).    listen_response1(ReplyTo, RequestRef, Status) ->    'MegacoSessionTcpUser':listenResponse(ReplyTo, RequestRef, Status).connect_response(ReplyTo, RequestRef, {'EXIT', Reason}) ->    error("connect failed (exit): ~p",[Reason]),    connect_response1(ReplyTo, RequestRef, Reason, 		      "Exit while handling connect request");connect_response(ReplyTo, RequestRef, {error, Reason}) ->    error("connect failed (error): ~p",[Reason]),    connect_response1(ReplyTo, RequestRef, Reason, 		      "Error while handling connect request").connect_response1(ReplyTo, RequestRef, Reason, Str) ->    ErrorString  = lists:flatten(io_lib:format("~s: ~p",[Str, Reason])),    DummyHandle  = term_to_binary([]),    DummyCtrlPid = ReplyTo,    connect_response(ReplyTo, RequestRef, {errorString, ErrorString}, 		     DummyHandle, DummyCtrlPid).connect_response(ReplyTo, RequestRef, Status0, H, C) ->    Status = ?EXT(tr_Status, Status0),    'MegacoSessionTcpUser':connectResponse(ReplyTo, RequestRef, Status, H, C).close_response(ReplyTo, RequestRef) ->    'MegacoSessionTcpUser':closeResponse(ReplyTo, RequestRef,  ?EXT(tr_Status, ok)).block_response(ReplyTo, RequestRef) ->    'MegacoSessionTcpUser':blockResponse(ReplyTo, RequestRef, ?EXT(tr_Status, ok)).unblock_response(ReplyTo, RequestRef) ->    'MegacoSessionTcpUser':unblockResponse(ReplyTo, RequestRef, ?EXT(tr_Status, ok)).%% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -error(F,A) -> io:format("ERROR: " ++ F ++ "~n",A).get_debug() ->    app_get_env(tcp_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("MSTI-DBG:~w: " ++ F ++ "~n", [self()|A]);dbg(_, _, _) ->    ok.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -