📄 megaco_tcp.erl
字号:
%%-----------------------------------------------------------------init({SupPid, _}) -> process_flag(trap_exit, true), {ok, #state{supervisor_pid = SupPid}}.%%-----------------------------------------------------------------%% Func: terminate/1%% Description: Termination function for the generic server%%-----------------------------------------------------------------terminate(_Reason, _State) -> ok.%%-----------------------------------------------------------------%% Internal Functions%%-----------------------------------------------------------------%%-----------------------------------------------------------------%% Func: start_tcp_listener/2%% Description: Function which parses the list of transport layers%% to start %%-----------------------------------------------------------------start_tcp_listener(P, State) -> ?d1("start_tcp_listener -> entry with" "~n P: ~p", [P]), case setup(State#state.supervisor_pid, P) of {ok, Pid, Data} -> ?d1("start_tcp_listener -> setup ok" "~n Pid: ~p" "~n Data: ~p", [Pid, Data]), link(Pid), {reply, ok, State#state{linkdb=[{Pid, Data} | State#state.linkdb]}}; {error, Reason} -> ?d1("start_tcp_listener -> setup failed" "~n Reason: ~p", [Reason]), {reply, {error, {could_not_start_listener, Reason}}, State} end.%%-----------------------------------------------------------------%% Func: handle_call/3%% Description: Handling call messages (really just garbage)%%-----------------------------------------------------------------handle_call({add_listener, Parameters}, _From, State) -> ?d1("handle_call(add_listener) -> entry with" "~n Parameters: ~p", [Parameters]), start_tcp_listener(Parameters, State);handle_call(Req, From, State) -> warning_msg("received unexpected request from ~p: " "~n~w", [From, Req]), {noreply, State}.%%------------------------------------------------------------%% Func: handle_cast/2%% Description: Handling cast messages (really just garbage)%%------------------------------------------------------------handle_cast(Msg, State) -> warning_msg("received unexpected message: " "~n~w", [Msg]), {noreply, State}.%%-----------------------------------------------------------------%% Func: handle_info/2%% Description: Handling non call/cast messages, eg exit messages%%-----------------------------------------------------------------handle_info({'EXIT', Pid, Reason}, State) when pid(Pid) -> %% Accept process died NewState = resetup(Pid, Reason, State), {noreply, NewState};handle_info(Info, State) -> warning_msg("received unexpected info: " "~n~w", [Info]), {noreply, State}.%%-----------------------------------------------------------------%% Func: code_change/3%% Descrition: Handles code change messages during upgrade.%%-----------------------------------------------------------------code_change(_Vsn, State, _Extra) -> {ok, State}.%%-----------------------------------------------------------------%% Internal functions%%-----------------------------------------------------------------%%-----------------------------------------------------------------%% Func: setup/2%% Description: Function is used when setting up an TCP listen %% socket in the MGC%%-----------------------------------------------------------------setup(SupPid, Options) -> ?d1("setup -> entry with" "~n SupPid: ~p" "~n Options: ~p", [SupPid, Options]), Mand = [port, receive_handle], case parse_options(Options, #megaco_tcp{}, Mand) of {ok, TcpRec} -> ?d1("setup -> options parsed" "~n TcpRec: ~p", [TcpRec]), %%------------------------------------------------------ %% Setup the listen socket IpOpts = [binary, {packet, tpkt}, {active, once}, {reuseaddr, true} | TcpRec#megaco_tcp.options], case catch gen_tcp:listen(TcpRec#megaco_tcp.port, IpOpts) of {ok, Listen} -> ?d1("setup -> listen ok" "~n Listen: ~p", [Listen]), %%----------------------------------------------- %% Startup the accept process that will wait for %% connect attempts case start_accept(SupPid, TcpRec, Listen) of {ok, Pid} -> ?d1("setup -> accept process started" "~n Pid: ~p", [Pid]), ?tcp_debug(TcpRec, "tcp listen setup", []), {ok, Pid, {TcpRec, Listen}}; {error, _Reason} = Error -> ?d1("setup -> failed starting accept process" "~n Error: ~p", [Error]), ?tcp_debug(TcpRec, "tcp listen setup failed", [Error]), Error end; {error, Reason} -> ?d1("setup -> listen failed" "~n Reason: ~p", [Reason]), Error = {error, {gen_tcp_listen, Reason}}, ?tcp_debug(TcpRec, "tcp listen setup failed", [Error]), Error; {'EXIT', _Reason} = Exit -> ?d1("setup -> listen exited" "~n Exit: ~p", [Exit]), Error = {error, {gen_tcp_listen, Exit}}, ?tcp_debug(TcpRec, "tcp listen setup failed", [Error]), Error end; {error, _Reason} = Error -> ?d1("setup -> failed parsing options" "~n Error: ~p", [Error]), ?tcp_debug(#megaco_tcp{}, "tcp listen setup failed", [Error, {options, Options}]), Error end. %%-----------------------------------------------------------------%% Func: resetup%% Description: Function is used when restarting the accept process%% if it died for some reason.%%-----------------------------------------------------------------resetup(Pid, Reason, State) -> ?d1("resetup -> entry with" "~n Pid: ~p" "~n Reason: ~p", [Pid, Reason]), case lists:keysearch(Pid, 1, State#state.linkdb) of {value, {Pid, {TcpRec, Listener}}} -> ?d1("resetup -> found accept process: " "~n TcpRec: ~p" "~n Listener: ~p", [TcpRec, Listener]), ?tcp_debug(TcpRec, "tcp listen resetup", [{error, Reason}]), unlink(Pid), warning_msg("received unexpected 'EXIT' signal " "from accept process ~p: " "~n~w", [Pid, Reason]), case start_accept(State#state.supervisor_pid, TcpRec, Listener) of {ok, NewPid} -> ?d1("resetup -> start new accept process ok: " "~n NewPid: ~p", [NewPid]), link(NewPid), NewList = lists:keyreplace(Pid, 1, State#state.linkdb, {NewPid, {TcpRec, Listener}}), State#state{linkdb=NewList}; {error, Reason} -> ?d1("resetup -> failed starting new accept process: " "~n :Reason ~p", [Reason]), ?tcp_debug(TcpRec, "tcp listen resetup failed", [{error, Reason}]), State end; false -> warning_msg("received unexpected 'EXIT' signal from ~p: " "~n~w", [Pid, Reason]), State end.%%-----------------------------------------------------------------%% Func: start_accept%% Description: Function is used for starting up an TCP accept%% process%%-----------------------------------------------------------------start_accept(SupPid, TcpRec, Listen) -> ?d1("start_accept -> entry with" "~n SupPid: ~p" "~n TcpRec: ~p" "~n Reason: ~p", [SupPid, TcpRec, Listen]), case get_pid_from_supervisor(SupPid, megaco_tcp_accept_sup) of {ok, AcceptSupPid} -> ?d1("start_accept -> found accept supervisor" "~n AcceptSupPid: ~p", [AcceptSupPid]), case supervisor:start_child(AcceptSupPid, [{TcpRec, SupPid, Listen}]) of {ok, Pid} -> ?d1("start_accept -> accept process started" "~n Pid: ~p", [Pid]), {ok, Pid}; {error, Reason} -> ?d1("start_accept -> failed starting accept process: " "~n Reason: ~p", [Reason]), {error, {accept_not_started, Reason}} end; {error, Reason} -> ?d1("start_accept -> could not find acceept supervisor: " "~n Reason: ~p", [Reason]), {error, {no_tcp_accept_sup, Reason}} end.%%-----------------------------------------------------------------%% Func: add_tpkt_header%% Description: Function is used to add the TPKT header%%-----------------------------------------------------------------add_tpkt_header(Data) when binary(Data) -> L = size(Data) + 4, {L, [3, 0, ((L) bsr 8) band 16#ff, (L) band 16#ff ,Data]};add_tpkt_header(IOList) when list(IOList) -> Binary = list_to_binary(IOList), L = size(Binary) + 4, {L, [3, 0, ((L) bsr 8) band 16#ff, (L) band 16#ff , Binary]}.%%-----------------------------------------------------------------%% Func: parse_options%% Description: Function that parses the options sent to the TCP %% module.%%-----------------------------------------------------------------parse_options([{Tag, Val} | T], TcpRec, Mand) -> ?d1("parse_options -> entry with" "~n Tag: ~p" "~n Val: ~p", [Tag, Val]), Mand2 = Mand -- [Tag], case Tag of port -> parse_options(T, TcpRec#megaco_tcp{port = Val}, Mand2); host -> parse_options(T, TcpRec#megaco_tcp{host = Val}, Mand2); tcp_options when list(Val)-> parse_options(T, TcpRec#megaco_tcp{options = Val}, Mand2); receive_handle -> parse_options(T, TcpRec#megaco_tcp{receive_handle = Val}, Mand2); module when atom(Val) -> parse_options(T, TcpRec#megaco_tcp{module = Val}, Mand2); serialize when Val == true; Val == false -> parse_options(T, TcpRec#megaco_tcp{serialize = Val}, Mand2); Bad -> ?d1("parse_options -> bad option: " "~n Tag: ~p", [Tag]), {error, {bad_option, Bad}} end;parse_options([], TcpRec, []) -> ?d2("parse_options -> done"), {ok, TcpRec};parse_options([], _TcpRec, Mand) -> ?d1("parse_options -> entry with" "~n Mand: ~p", [Mand]), {error, {missing_options, Mand}};parse_options(BadList, _TcpRec, _Mand) -> ?d1("parse_options -> entry with" "~n BadList: ~p", [BadList]), {error, {bad_option_list, BadList}}.%%-----------------------------------------------------------------%% Func: get_pid_from_supervisor%% Description: Function that get a pid form a supervisor %% with the help of the name.%%-----------------------------------------------------------------get_pid_from_supervisor(SupPid, ProcName) -> ProcList = supervisor:which_children(SupPid), %% ProcList of type [{Name, Pid, Type, Modules}| Rest] case lists:keysearch(ProcName, 1, ProcList) of {value, {_Name, Pid, _Type, _Modules}} -> {ok, Pid}; false -> {error, no_such_process} end.%%-----------------------------------------------------------------%% Func: incNumOutMessages/1, incNumOutOctets/2, incNumErrors/1%% Description: SNMP counter increment functions%% %%-----------------------------------------------------------------incNumOutMessages(Socket) -> incCounter({Socket, medGwyGatewayNumOutMessages}, 1).incNumOutOctets(Socket, NumOctets) -> incCounter({Socket, medGwyGatewayNumOutOctets}, NumOctets).incCounter(Key, Inc) -> ets:update_counter(megaco_tcp_stats, Key, Inc).% incNumErrors(Socket) ->% ets:update_counter(megaco_tcp_stats, % {Socket, medGwyGatewayNumErrors}, 1).%%-----------------------------------------------------------------warning_msg(F, A) -> ?megaco_warning("TCP server: " ++ F, A). %% error_msg(F, A) ->%% ?megaco_error("TCP server: " ++ F, A).call(Pid, Req) -> gen_server:call(Pid, Req, infinity).
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -