From 84adefa331c4159d432d22840663c38f155cd4c1 Mon Sep 17 00:00:00 2001 From: Erlang/OTP Date: Fri, 20 Nov 2009 14:54:40 +0000 Subject: The R13B03 release. --- .../src/flex/megaco_flex_scanner_handler.erl | 232 +++++++++++++++++++++ 1 file changed, 232 insertions(+) create mode 100644 lib/megaco/src/flex/megaco_flex_scanner_handler.erl (limited to 'lib/megaco/src/flex/megaco_flex_scanner_handler.erl') diff --git a/lib/megaco/src/flex/megaco_flex_scanner_handler.erl b/lib/megaco/src/flex/megaco_flex_scanner_handler.erl new file mode 100644 index 0000000000..d09e0c6fff --- /dev/null +++ b/lib/megaco/src/flex/megaco_flex_scanner_handler.erl @@ -0,0 +1,232 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2001-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: Handle the flex scanner +%%---------------------------------------------------------------------- + +-module(megaco_flex_scanner_handler). + +-behaviour(gen_server). + + +%%----------------------------------------------------------------- +%% Include files +%%----------------------------------------------------------------- +-include_lib("megaco/src/app/megaco_internal.hrl"). + + +%% External exports +-export([ + start_link/0, start_link/1, + stop/1, + get_config/1 + ]). + +%% gen_server callbacks +-export([ + init/1, + handle_call/3, handle_cast/2, handle_info/2, + terminate/2, + code_change/3 + ]). + +-record(state, {conf}). + + +%%%---------------------------------------------------------------------- +%%% API +%%%---------------------------------------------------------------------- + +start_link() -> + start_link([]). + +start_link(Opts) -> + case gen_server:start_link(?MODULE, Opts, []) of + {ok, Pid} -> + Conf = get_config(Pid), + {ok, Pid, Conf}; + Else -> + Else + end. + +stop(Pid) -> + gen_server:call(Pid, stop). + +get_config(Pid) -> + gen_server:call(Pid, get_config). + + +%%%---------------------------------------------------------------------- +%%% Callback functions from gen_server +%%%---------------------------------------------------------------------- + +%%---------------------------------------------------------------------- +%% Func: init/1 +%% Returns: {ok, State} | +%% {ok, State, Timeout} | +%% ignore | +%% {stop, Reason} +%%---------------------------------------------------------------------- +init(_Opts) -> + process_flag(trap_exit, true), + case start_flex_scanners() of + {ok, PortOrPorts} -> + {ok, #state{conf = {flex, PortOrPorts}}}; + {error, Reason} -> + %% {stop, {failed_starting_scanner, Reason, Opts}}; + {stop, {failed_starting_scanner, Reason, []}}; + Else -> + {stop, {failed_starting_scanner, Else}} + end. + + +%%---------------------------------------------------------------------- +%% Func: handle_call/3 +%% Returns: {reply, Reply, State} | +%% {reply, Reply, State, Timeout} | +%% {noreply, State} | +%% {noreply, State, Timeout} | +%% {stop, Reason, Reply, State} | (terminate/2 is called) +%% {stop, Reason, State} (terminate/2 is called) +%%---------------------------------------------------------------------- +handle_call(get_config, _From, #state{conf = Conf} = S) -> + {reply, Conf, S}; + +handle_call(stop, _From, #state{conf = {flex, PortOrPorts}} = S) -> + megaco_flex_scanner:stop(PortOrPorts), + Reason = normal, + Reply = ok, + {stop, Reason, Reply, S}; + +handle_call(Req, From, S) -> + warning_msg("received unexpected request from ~p: " + "~n~w", [From, Req]), + {reply, {error, {unknown_request, Req}}, S}. + + +%%---------------------------------------------------------------------- +%% Func: handle_cast/2 +%% Returns: {noreply, State} | +%% {noreply, State, Timeout} | +%% {stop, Reason, State} (terminate/2 is called) +%%---------------------------------------------------------------------- +handle_cast(Msg, S) -> + warning_msg("received unexpected message: " + "~n~w", [Msg]), + {noreply, S}. + + +%%---------------------------------------------------------------------- +%% Func: handle_info/2 +%% Returns: {noreply, State} | +%% {noreply, State, Timeout} | +%% {stop, Reason, State} (terminate/2 is called) +%%---------------------------------------------------------------------- +handle_info({'EXIT', Port, Error}, #state{conf = {flex, PortOrPorts}} = S) -> + case megaco_flex_scanner:is_scanner_port(Port, PortOrPorts) of + true -> + error_msg("Port [~p] exited:" + "~n~w", [Port, Error]), + {stop, {port_exit, Port, Error}, S}; + false -> + {noreply, S} + end; + +handle_info({'EXIT', Port, _Error}, S) when is_port(Port) -> + %% This is propably the old flex scanner, + %% terminating after a code change... + {noreply, S}; + +handle_info({'EXIT', Id, Error}, S) -> + warning_msg("received unexpected 'EXIT' signal from ~p:" + "~n~w", [Id, Error]), + {noreply, S}; + +handle_info(Info, S) -> + warning_msg("received unexpected info: " + "~n~w", [Info]), + {noreply, S}. + + +%%---------------------------------------------------------------------- +%% Func: terminate/2 +%% Purpose: Shutdown the server +%% Returns: any (ignored by gen_server) +%%---------------------------------------------------------------------- +terminate(_Reason, _S) -> + ok. + + +%%---------------------------------------------------------------------- +%% Func: code_change/3 +%% Purpose: Called to change the internal state +%% Returns: {ok, NewState} +%%---------------------------------------------------------------------- +%% code_change({down, _Vsn}, #state{conf = Conf} = State, downgrade_to_pre_3_8) -> +%% Port = downgrade_flex_scanner(Conf), +%% {ok, State#state{conf = {flex, Port}}}; + +code_change(_Vsn, State, _Extra) -> + {ok, State}. + +%% downgrade_flex_scanner({flex, Port}) when is_port(Port) -> +%% Port; +%% downgrade_flex_scanner({flex, [Port]}) when is_port(Port) -> +%% Port; +%% downgrade_flex_scanner({flex, Ports}) when is_list(Ports) -> +%% megaco_flex_scanner:stop(Ports), +%% case megaco_flex_scanner:start() of +%% {ok, Port} -> +%% Port; +%% Error -> +%% exit(Error) +%% end; +%% downgrade_flex_scanner(BadConfig) -> +%% exit({invalid_config, BadConfig}). + + +%%%---------------------------------------------------------------------- +%%% Internal functions +%%%---------------------------------------------------------------------- + +start_flex_scanners() -> + megaco_flex_scanner:start(). + + +%% get_env(Key, Opts, Default) -> +%% case lists:keysearch(Key, 1, Opts) of +%% {value, {Key, Value}} -> +%% Value; +%% false -> +%% Default +%% end. + +warning_msg(F, A) -> + ?megaco_warning("Flex scanner handler: " ++ F, A). + +error_msg(F, A) -> + ?megaco_error("Flex scanner handler: " ++ F, A). + + + +% d(F, A) -> +% io:format("~w:" ++ F ++ "~n", [?MODULE|A]). + -- cgit v1.2.3