📄 megaco_tcp.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: %% Interface the TPKT (TCP/IP) transport module for Megaco/H.248%%%%------------------------------------------------------------------module(megaco_tcp).-behaviour(gen_server).%%-----------------------------------------------------------------%% Include files%%------------------------------------------------------------------include_lib("megaco/include/megaco.hrl").-include_lib("megaco/src/tcp/megaco_tcp.hrl"). -include_lib("megaco/src/app/megaco_internal.hrl"). -define(d1(F, A), ?d("~p " ++ F, [self()|A])).-define(d2(F), ?d1(F, [])).%%-----------------------------------------------------------------%% External exports%%------------------------------------------------------------------export([ start_transport/0, %% Start TPKT transport service listen/2, %% Starts a new listener socket connect/2, %% Used on client side to connect server socket/1, %% Returns the inet socket send_message/2, %% Used to send data on connection block/1, %% Used to block the socket for incomming %% messages unblock/1, %% Used to unblock the node close/1, %% Used on both sides to close connection upgrade_receive_handle/2 ]).%% Statistics exports-export([ get_stats/0, get_stats/1, get_stats/2, reset_stats/0, reset_stats/1 ]).%%-----------------------------------------------------------------%% Internal exports%%------------------------------------------------------------------export([ start_link/1, %% Start TCP/IP net server init/1, %% terminate/2, handle_call/3, handle_cast/2, handle_info/2, code_change/3, start_connection/2 ]).%%-----------------------------------------------------------------%% Server state record%%------------------------------------------------------------------record(state, {supervisor_pid, linkdb}).%%-----------------------------------------------------------------%% External interface functions%%-----------------------------------------------------------------%%-----------------------------------------------------------------%% Func: get_stats/0, get_stats/1, get_stats/2%% Description: Retreive statistics (counters) for TCP%%-----------------------------------------------------------------get_stats() -> megaco_stats:get_stats(megaco_tcp_stats).get_stats(Socket) -> megaco_stats:get_stats(megaco_tcp_stats, Socket).get_stats(Socket, Counter) -> megaco_stats:get_stats(megaco_tcp_stats, Socket, Counter).%%-----------------------------------------------------------------%% Func: reset_stats/0, reaet_stats/1%% Description: Reset statistics (counters) for TCP%%-----------------------------------------------------------------reset_stats() -> megaco_stats:reset_stats(megaco_tcp_stats).reset_stats(Socket) -> megaco_stats:reset_stats(megaco_tcp_stats, Socket).%%-----------------------------------------------------------------%% Func: start_transport/0%% Description: Starts the TPKT transport service%%-----------------------------------------------------------------start_transport() -> ?d2("start_transport -> entry"), (catch megaco_stats:init(megaco_tcp_stats)), megaco_tcp_sup:start_link().%%-----------------------------------------------------------------%% Func: listen/2%% Description: Starts new TPKT listener sockets%%-----------------------------------------------------------------listen(SupPid, Parameters) -> ?d1("listen -> entry with" "~n SupPid: ~p" "~n Parameters: ~p", [SupPid, Parameters]), ProcList = supervisor:which_children(SupPid), case lists:keysearch(megaco_tcp, 1, ProcList) of {value, {_Name, Pid, _Type, _Modules}} -> ?d1("listen -> found listener: " "~n Pid: ~p", [Pid]), call(Pid, {add_listener, Parameters}); false -> {error, no_tcp_server} end. %%-----------------------------------------------------------------%% Func: connect%% Description: Function is used when opening an TCP socket %% at the MG side when trying to connect an MGC%%-----------------------------------------------------------------connect(SupPid, Parameters) -> ?d1("connect -> entry with" "~n SupPid: ~p" "~n Parameters: ~p", [SupPid, Parameters]), Mand = [host, port, receive_handle], case parse_options(Parameters, #megaco_tcp{}, Mand) of {ok, TcpRec} -> ?d1("connect -> options parsed: " "~n TcpRec: ~p", [TcpRec]), IpOpt = [binary, {packet, tpkt}, {active, once} | TcpRec#megaco_tcp.options], %%------------------------------------------------------ %% Connect the other side case catch gen_tcp:connect(TcpRec#megaco_tcp.host, TcpRec#megaco_tcp.port, IpOpt) of {ok, Socket} -> ?d1("connect -> connected: " "~n Socket: ~p", [Socket]), %%---------------------------------------------- %% Socket up start a new control process Rec2 = TcpRec#megaco_tcp{socket = Socket}, case start_connection(SupPid, Rec2) of {ok, Pid} -> ?d1("connect -> connection started: " "~n Pid: ~p", [Pid]), gen_tcp:controlling_process(Socket, Pid), ?d2("connect -> control transferred"), {ok, Socket, Pid}; {error, Reason} -> ?d1("connect -> failed starting connection: " "~n Reason: ~p", [Reason]), {error, Reason} end; {error, Reason} -> ?d1("connect -> failed connecting: " "~n Reason: ~p", [Reason]), Error = {error, {gen_tcp_connect, Reason}}, ?tcp_debug(TcpRec, "tcp connect failed", [Error]), Error; {'EXIT', _Reason} = Exit -> ?d1("connect -> connect exited: " "~n Exit: ~p", [Exit]), Error = {error, {gen_tcp_connect, Exit}}, ?tcp_debug(TcpRec, "tcp connect failed", [Error]), Error end; {error, _Reason} = Error -> ?d1("connect -> failed parsing options: " "~n Error: ~p", [Error]), ?tcp_debug(#megaco_tcp{}, "tcp connect failed", [Error, {options, Parameters}]), Error end.%%-----------------------------------------------------------------%% Func: send_message%% Description: Function is used for sending data on the TCP socket%%-----------------------------------------------------------------send_message(Socket, Data) -> ?d1("send_message -> entry with" "~n Socket: ~p" "~n size(Data): ~p", [Socket, size(Data)]), {Size, NewData} = add_tpkt_header(Data), Res = gen_tcp:send(Socket, NewData), case Res of ok -> incNumOutMessages(Socket), incNumOutOctets(Socket, Size); _ -> ok end, Res. %%-----------------------------------------------------------------%% Func: block%% Description: Function is used for blocking incomming messages%% on the TCP socket%%-----------------------------------------------------------------block(Socket) -> ?tcp_debug({socket, Socket}, "tcp block", []), inet:setopts(Socket, [{active, false}]).%%-----------------------------------------------------------------%% Func: unblock%% Description: Function is used for blocking incomming messages%% on the TCP socket%%-----------------------------------------------------------------unblock(Socket) -> ?tcp_debug({socket, Socket}, "tcp unblock", []), inet:setopts(Socket, [{active, once}]).%%-----------------------------------------------------------------%% Func: close%% Description: Function is used for closing the TCP socket%%-----------------------------------------------------------------close(Socket) -> ?tcp_debug({socket, Socket}, "tcp close", []), gen_tcp:close(Socket).%%-----------------------------------------------------------------%% Func: socket%% Description: Returns the inet socket%%-----------------------------------------------------------------socket(Socket) -> Socket.upgrade_receive_handle(Pid, NewHandle) when pid(Pid), record(NewHandle, megaco_receive_handle) -> megaco_tcp_connection:upgrade_receive_handle(Pid, NewHandle).%%-----------------------------------------------------------------%% Internal Interface functions%%-----------------------------------------------------------------%%-----------------------------------------------------------------%% Func: start_link/1%% Description: Starts the net server%%-----------------------------------------------------------------start_link(Args) -> gen_server:start_link(?MODULE, Args, []).%%-----------------------------------------------------------------%% Func: start_connection%% Description: Function is used for starting up a connection%% process%%-----------------------------------------------------------------start_connection(SupPid, #megaco_tcp{socket = Socket} = TcpRec) -> ?d1("start_connection -> entry with" "~n SupPid: ~p" "~n Socket: ~p", [SupPid, Socket]), ProcList = supervisor:which_children(SupPid), case lists:keysearch(megaco_tcp_connection_sup, 1, ProcList) of {value, {_Name, ConnSupPid, _Type, _Modules}} -> ?d1("start_connection -> found connection supervisor: " "~n ConnSupPid: ~p", [ConnSupPid]), ?tcp_debug(TcpRec, "tcp connect", []), case supervisor:start_child(ConnSupPid, [TcpRec]) of {ok, Pid} -> ?d1("start_connection -> started: " "~n Pid: ~p", [Pid]), ?tcp_debug(TcpRec, "connect handler started", [Pid]), create_snmp_counters(Socket), {ok, Pid}; {error, Reason} -> ?d1("start_connection -> failed starting: " "~n Reason: ~p", [Reason]), Error = {error, {controlling_process_not_started, Reason}}, ?tcp_debug(TcpRec, "tcp connect failed", [Error]), Error end; false -> ?d2("start_connection -> could not find connection supervisor"), Error = {error, no_connection_supervisor}, ?tcp_debug(TcpRec, "tcp connect failed", [Error]), Error end.create_snmp_counters(Socket) -> Counters = [medGwyGatewayNumInMessages, medGwyGatewayNumInOctets, medGwyGatewayNumOutMessages, medGwyGatewayNumOutOctets, medGwyGatewayNumErrors], create_snmp_counters(Socket, Counters).create_snmp_counters(_Socket, []) -> ok;create_snmp_counters(Socket, [Counter|Counters]) -> Key = {Socket, Counter}, ets:insert(megaco_tcp_stats, {Key, 0}), create_snmp_counters(Socket, Counters).%%-----------------------------------------------------------------%% Server functions%%-----------------------------------------------------------------%%-----------------------------------------------------------------%% Func: init/1%% Description: Init funcion for the supervisor
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -