%% %% %CopyrightBegin% %% %% Copyright Ericsson AB 1999-2009. All Rights Reserved. %% %% 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 online 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. %% %% %CopyrightEnd% %% %% %%----------------------------------------------------------------- %% Purpose: Waiting in accept for new connections. %%----------------------------------------------------------------- -module(megaco_tcp_accept). %%----------------------------------------------------------------- %% Include files %%----------------------------------------------------------------- -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_link/1 ]). %%----------------------------------------------------------------- %% Internal exports %%----------------------------------------------------------------- -export([ net_accept/4 ]). %%----------------------------------------------------------------- %% External interface functions %%----------------------------------------------------------------- %%----------------------------------------------------------------- %% Func: start %% Description: Starts the proces that makes the accept call. %%----------------------------------------------------------------- start_link({TcpRec, SupPid, Listen}) -> Args = [TcpRec, SupPid, Listen, self()], Pid = proc_lib:spawn_link(?MODULE, net_accept, Args), {ok, Pid}. %%----------------------------------------------------------------- %% Internal Interface Functions %%----------------------------------------------------------------- %%----------------------------------------------------------------- %% Func: net_accept %% Description: Loop function which calls accept and %% spawns a connection process when there is an initial %% contact. %%----------------------------------------------------------------- net_accept(TcpRec, SupPid, ListenFd, Parent) -> do_accept(TcpRec, SupPid, ListenFd), net_accept(TcpRec, SupPid, ListenFd, Parent). do_accept(Tcp, Sup, Fd) -> case gen_tcp:accept(Fd) of {ok, S} -> ?d1("do_accept -> accepted: " "~n S: ~p", [S]), case megaco_tcp:start_connection(Sup, Tcp#megaco_tcp{socket = S}) of {ok, Pid} -> ?d1("do_accept -> connection started" "~n Pid: ~p", [Pid]), case gen_tcp:controlling_process(S, Pid) of ok -> ?d2("do_accept -> control transferred"), ok; {error, _Reason} -> ?d1("do_accept -> " "failed changing controlling process: " "n _Reason: ~p", [_Reason]), tcp_clear(S), gen_tcp:close(S) end; {error, _Reason} -> ?d1("do_accept -> failed starting connection: " "~n _Reason: ~p", [_Reason]), tcp_clear(S), gen_tcp:close(S) end; {error, _Reason} -> ?d1("do_accept -> accept failed: " "~n _Reason: ~p", [_Reason]), ok end. tcp_clear(Socket) -> receive {tcp, Socket, _Data} -> tcp_clear(Socket); {tcp_closed, Socket} -> tcp_clear(Socket); {tcp_error, Socket} -> tcp_clear(Socket) after 0 -> ok end.