aboutsummaryrefslogtreecommitdiffstats
path: root/lib/megaco/src/udp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/megaco/src/udp')
-rw-r--r--lib/megaco/src/udp/Makefile117
-rw-r--r--lib/megaco/src/udp/megaco_udp.erl324
-rw-r--r--lib/megaco/src/udp/megaco_udp.hrl64
-rw-r--r--lib/megaco/src/udp/megaco_udp_server.erl234
-rw-r--r--lib/megaco/src/udp/megaco_udp_sup.erl112
-rw-r--r--lib/megaco/src/udp/modules.mk30
6 files changed, 881 insertions, 0 deletions
diff --git a/lib/megaco/src/udp/Makefile b/lib/megaco/src/udp/Makefile
new file mode 100644
index 0000000000..64b6478c2c
--- /dev/null
+++ b/lib/megaco/src/udp/Makefile
@@ -0,0 +1,117 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2000-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%
+
+include $(ERL_TOP)/make/target.mk
+
+EBIN = ../../ebin
+MEGACO_INCLUDEDIR = ../../include
+
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+
+# ----------------------------------------------------
+# Application version
+# ----------------------------------------------------
+include ../../vsn.mk
+VSN=$(MEGACO_VSN)
+
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/lib/megaco-$(VSN)
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+
+include modules.mk
+
+ERL_FILES = $(MODULES:%=%.erl)
+
+TARGET_FILES = \
+ $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+
+
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+ifeq ($(TYPE),debug)
+ERL_COMPILE_FLAGS += -Ddebug
+endif
+
+include ../app/megaco.mk
+
+ERL_COMPILE_FLAGS += \
+ $(MEGACO_ERL_COMPILE_FLAGS) \
+ -I../../include
+
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+debug:
+ @${MAKE} TYPE=debug opt
+
+opt: $(TARGET_FILES)
+
+clean:
+ rm -f $(TARGET_FILES)
+ rm -f errs core *~
+
+docs:
+
+
+# ----------------------------------------------------
+# Special Build Targets
+# ----------------------------------------------------
+
+
+# ----------------------------------------------------
+# Release Target
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+
+release_spec: opt
+ $(INSTALL_DIR) $(RELSYSDIR)/ebin
+ $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin
+ $(INSTALL_DIR) $(RELSYSDIR)/src
+ $(INSTALL_DIR) $(RELSYSDIR)/src/udp
+ $(INSTALL_DATA) $(ERL_FILES) $(INTERNAL_HRL_FILES) $(RELSYSDIR)/src/udp
+
+
+release_docs_spec:
+
+
+# ----------------------------------------------------
+# Include dependencies
+# ----------------------------------------------------
+
+$(EBIN)/megaco_udp.$(EMULATOR): megaco_udp.erl \
+ megaco_udp.hrl $(MEGACO_INCLUDEDIR)/megaco.hrl
+
+$(EBIN)/megaco_udp_server.$(EMULATOR): megaco_udp_server.erl \
+ megaco_udp.hrl $(MEGACO_INCLUDEDIR)/megaco.hrl
+
+$(EBIN)/megaco_udp_sup.$(EMULATOR): megaco_udp_sup.erl \
+ megaco_udp.hrl $(MEGACO_INCLUDEDIR)/megaco.hrl
+
+$(EBIN)/megaco_udp_test.$(EMULATOR): megaco_udp_test.erl \
+ megaco_udp.hrl $(MEGACO_INCLUDEDIR)/megaco.hrl
+
diff --git a/lib/megaco/src/udp/megaco_udp.erl b/lib/megaco/src/udp/megaco_udp.erl
new file mode 100644
index 0000000000..c75b703949
--- /dev/null
+++ b/lib/megaco/src/udp/megaco_udp.erl
@@ -0,0 +1,324 @@
+%%
+%% %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: Interface to the UDP transport module for Megaco/H.248
+%%-----------------------------------------------------------------
+-module(megaco_udp).
+
+-include_lib("megaco/include/megaco.hrl").
+-include_lib("megaco/src/udp/megaco_udp.hrl").
+
+-record(send_handle, {socket, addr, port}).
+
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([
+ start_transport/0, stop_transport/1,
+ open/2,
+ socket/1,
+ create_send_handle/3,
+ send_message/2,
+ close/1,
+ block/1,
+ unblock/1,
+
+ upgrade_receive_handle/2
+ ]).
+
+%% Statistics exports
+-export([get_stats/0, get_stats/1, get_stats/2,
+ reset_stats/0, reset_stats/1]).
+
+
+%%-----------------------------------------------------------------
+%% 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_udp_stats).
+
+get_stats(SH) when is_record(SH, send_handle) ->
+ megaco_stats:get_stats(megaco_udp_stats, SH).
+
+get_stats(SH, Counter)
+ when is_record(SH, send_handle) andalso is_atom(Counter) ->
+ megaco_stats:get_stats(megaco_udp_stats, SH, Counter).
+
+
+%%-----------------------------------------------------------------
+%% Func: reset_stats/0, reaet_stats/1
+%% Description: Reset statistics (counters) for TCP
+%%-----------------------------------------------------------------
+reset_stats() ->
+ megaco_stats:reset_stats(megaco_udp_stats).
+
+reset_stats(SH) when is_record(SH, send_handle) ->
+ megaco_stats:reset_stats(megaco_udp_stats, SH).
+
+
+
+%%-----------------------------------------------------------------
+%% Func: start_transport
+%% Description: Starts the UDP transport service
+%%-----------------------------------------------------------------
+start_transport() ->
+ (catch megaco_stats:init(megaco_udp_stats)),
+ megaco_udp_sup:start_link().
+
+
+%%-----------------------------------------------------------------
+%% Func: stop_transport
+%% Description: Stop the UDP transport service
+%%-----------------------------------------------------------------
+stop_transport(Pid) ->
+ (catch unlink(Pid)),
+ stop_transport(Pid, shutdown).
+
+stop_transport(Pid, Reason) ->
+ exit(Pid, Reason).
+
+
+%%-----------------------------------------------------------------
+%% Func: open
+%% Description: Function is used when opening an UDP socket
+%%-----------------------------------------------------------------
+open(SupPid, Options) ->
+ Mand = [port, receive_handle],
+ case parse_options(Options, #megaco_udp{}, Mand) of
+ {ok, UdpRec} ->
+
+ %%------------------------------------------------------
+ %% Setup the socket
+ IpOpts = [binary, {reuseaddr, true}, {active, once} |
+ UdpRec#megaco_udp.options],
+
+ case (catch gen_udp:open(UdpRec#megaco_udp.port, IpOpts)) of
+ {ok, Socket} ->
+ ?udp_debug(UdpRec, "udp open", []),
+ NewUdpRec = UdpRec#megaco_udp{socket = Socket},
+ case start_udp_server(SupPid, NewUdpRec) of
+ {ok, ControlPid} ->
+ gen_udp:controlling_process(Socket, ControlPid),
+ {ok, Socket, ControlPid};
+ {error, Reason} ->
+ Error = {error, {could_not_start_udp_server, Reason}},
+ ?udp_debug({socket, Socket}, "udp close", []),
+ gen_udp:close(Socket),
+ Error
+
+ end;
+ {'EXIT', Reason} ->
+ Error = {error, {could_not_open_udp_port, Reason}},
+ ?udp_debug(UdpRec, "udp open exited", [Error]),
+ Error;
+ {error, Reason} ->
+ Error = {error, {could_not_open_udp_port, Reason}},
+ ?udp_debug(UdpRec, "udp open failed", [Error]),
+ Error
+ end;
+ {error, Reason} = Error ->
+ ?udp_debug(#megaco_udp{}, "udp open failed",
+ [Error, {options, Options}]),
+ {error, Reason}
+ end.
+
+
+%%-----------------------------------------------------------------
+%% Func: socket
+%% Description: Returns the inet socket
+%%-----------------------------------------------------------------
+socket(SH) when is_record(SH, send_handle) ->
+ SH#send_handle.socket;
+socket(Socket) ->
+ Socket.
+
+
+upgrade_receive_handle(Pid, NewHandle)
+ when is_pid(Pid) andalso is_record(NewHandle, megaco_receive_handle) ->
+ megaco_udp_server:upgrade_receive_handle(Pid, NewHandle).
+
+
+%%-----------------------------------------------------------------
+%% Func: create_send_handle
+%% Description: Function is used for creating the handle used when
+%% sending data on the UDP socket
+%%-----------------------------------------------------------------
+create_send_handle(Socket, {_, _, _, _} = Addr, Port) ->
+ do_create_send_handle(Socket, Addr, Port);
+create_send_handle(Socket, Addr0, Port) ->
+ {ok, Addr} = inet:getaddr(Addr0, inet),
+ do_create_send_handle(Socket, Addr, Port).
+
+do_create_send_handle(Socket, Addr, Port) ->
+ %% If neccessary create snmp counter's
+ SH = #send_handle{socket = Socket, addr = Addr, port = Port},
+ maybe_create_snmp_counters(SH),
+ SH.
+
+
+maybe_create_snmp_counters(SH) ->
+ Counters = [medGwyGatewayNumInMessages,
+ medGwyGatewayNumInOctets,
+ medGwyGatewayNumOutMessages,
+ medGwyGatewayNumOutOctets,
+ medGwyGatewayNumErrors],
+ %% Only need to check one of them, since either all of them exist
+ %% or none of them exist:
+ Key = {SH, medGwyGatewayNumInMessages},
+ case (catch ets:lookup(megaco_udp_stats, Key)) of
+ [] ->
+ create_snmp_counters(SH, Counters);
+ [_] ->
+ ok;
+ _ ->
+ ok
+ end.
+
+create_snmp_counters(_SH, []) ->
+ ok;
+create_snmp_counters(SH, [Counter|Counters]) ->
+ Key = {SH, Counter},
+ ets:insert(megaco_udp_stats, {Key, 0}),
+ create_snmp_counters(SH, Counters).
+
+
+%%-----------------------------------------------------------------
+%% Func: send_message
+%% Description: Function is used for sending data on the UDP socket
+%%-----------------------------------------------------------------
+send_message(SH, Data) when is_record(SH, send_handle) ->
+ #send_handle{socket = Socket, addr = Addr, port = Port} = SH,
+ Res = gen_udp:send(Socket, Addr, Port, Data),
+ case Res of
+ ok ->
+ incNumOutMessages(SH),
+ incNumOutOctets(SH, size(Data));
+ _ ->
+ ok
+ end,
+ Res;
+send_message(SH, _Data) ->
+ {error, {bad_send_handle, SH}}.
+
+
+%%-----------------------------------------------------------------
+%% Func: block
+%% Description: Function is used for blocking incomming messages
+%% on the TCP socket
+%%-----------------------------------------------------------------
+block(SH) when is_record(SH, send_handle) ->
+ block(SH#send_handle.socket);
+block(Socket) ->
+ ?udp_debug({socket, Socket}, "udp block", []),
+ inet:setopts(Socket, [{active, false}]).
+
+
+%%-----------------------------------------------------------------
+%% Func: unblock
+%% Description: Function is used for blocking incomming messages
+%% on the TCP socket
+%%-----------------------------------------------------------------
+unblock(SH) when is_record(SH, send_handle) ->
+ unblock(SH#send_handle.socket);
+unblock(Socket) ->
+ ?udp_debug({socket, Socket}, "udp unblock", []),
+ inet:setopts(Socket, [{active, once}]).
+
+
+%%-----------------------------------------------------------------
+%% Func: close
+%% Description: Function is used for closing the UDP socket
+%%-----------------------------------------------------------------
+close(#send_handle{socket = Socket}) ->
+ close(Socket);
+close(Socket) ->
+ ?udp_debug({socket, Socket}, "udp close", []),
+ case erlang:port_info(Socket, connected) of
+ {connected, ControlPid} ->
+ megaco_udp_server:stop(ControlPid);
+ undefined ->
+ {error, already_closed}
+ end.
+
+
+%%-----------------------------------------------------------------
+%% Internal functions
+%%-----------------------------------------------------------------
+%%-----------------------------------------------------------------
+%% Func: start_udp_server/1
+%% Description: Function is used for starting up a connection
+%% process
+%%-----------------------------------------------------------------
+start_udp_server(SupPid, UdpRec) ->
+ megaco_udp_sup:start_child(SupPid, UdpRec).
+
+
+%%-----------------------------------------------------------------
+%% Func: parse_options
+%% Description: Function that parses the options sent to the UDP
+%% module.
+%%-----------------------------------------------------------------
+parse_options([{Tag, Val} | T], UdpRec, Mand) ->
+ Mand2 = Mand -- [Tag],
+ case Tag of
+ port ->
+ parse_options(T, UdpRec#megaco_udp{port = Val}, Mand2);
+ udp_options when is_list(Val) ->
+ parse_options(T, UdpRec#megaco_udp{options = Val}, Mand2);
+ receive_handle ->
+ parse_options(T, UdpRec#megaco_udp{receive_handle = Val}, Mand2);
+ module when is_atom(Val) ->
+ parse_options(T, UdpRec#megaco_udp{module = Val}, Mand2);
+ serialize when (Val =:= true) orelse (Val =:= false) ->
+ parse_options(T, UdpRec#megaco_udp{serialize = Val}, Mand2);
+ Bad ->
+ {error, {bad_option, Bad}}
+ end;
+parse_options([], UdpRec, []) ->
+ {ok, UdpRec};
+parse_options([], _UdpRec, Mand) ->
+ {error, {missing_options, Mand}};
+parse_options(BadList, _UdpRec, _Mand) ->
+ {error, {bad_option_list, BadList}}.
+
+
+%%-----------------------------------------------------------------
+%% Func: incNumOutMessages/1, incNumOutOctets/2, incNumErrors/1
+%% Description: SNMP counter increment functions
+%%
+%%-----------------------------------------------------------------
+incNumOutMessages(SH) ->
+ incCounter({SH, medGwyGatewayNumOutMessages}, 1).
+
+incNumOutOctets(SH, NumOctets) ->
+ incCounter({SH, medGwyGatewayNumOutOctets}, NumOctets).
+
+incCounter(Key, Inc) ->
+ ets:update_counter(megaco_udp_stats, Key, Inc).
+
+% incNumErrors(SH) ->
+% incCounter({SH, medGwyGatewayNumErrors}, 1).
diff --git a/lib/megaco/src/udp/megaco_udp.hrl b/lib/megaco/src/udp/megaco_udp.hrl
new file mode 100644
index 0000000000..d0b9ec1916
--- /dev/null
+++ b/lib/megaco/src/udp/megaco_udp.hrl
@@ -0,0 +1,64 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2000-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: Define the protocol options for Megaco/H.248 IP connections
+%%-----------------------------------------------------------------
+
+%%----------------------------------------------------------------------
+%% IP options
+%%----------------------------------------------------------------------
+-record(megaco_udp,
+ {port,
+ options = [],
+ socket,
+ receive_handle,
+ module = megaco,
+ serialize = false % false: Spawn a new process for each message
+ }).
+
+
+-define(GC_MSG_LIMIT,1000).
+-define(HEAP_SIZE(S),5000 + 2*(S)).
+
+
+%%----------------------------------------------------------------------
+%% Event Trace
+%%----------------------------------------------------------------------
+
+-define(udp_report(Level, UdpRec, From, To, Label, Contents),
+ megaco:report_event(Level, From, To, Label,
+ [{line, ?MODULE, ?LINE}, UdpRec | Contents])).
+
+-define(udp_debug(UdpRec, Label, Contents),
+ ?udp_report_debug(UdpRec,
+ megaco_udp,
+ megaco_udp,
+ Label,
+ Contents)).
+
+-define(udp_report_important(C, From, To, Label, Contents),
+ ?udp_report(20, C, From, To, Label, Contents)).
+-define(udp_report_verbose(C, From, To, Label, Contents),
+ ?udp_report(40, C, From, To, Label, Contents)).
+-define(udp_report_debug(C, From, To, Label, Contents),
+ ?udp_report(60, C, From, To, Label, Contents)).
+-define(udp_report_trace(C, From, To, Label, Contents),
+ ?udp_report(80, C, From, To, Label, Contents)).
diff --git a/lib/megaco/src/udp/megaco_udp_server.erl b/lib/megaco/src/udp/megaco_udp_server.erl
new file mode 100644
index 0000000000..f126043141
--- /dev/null
+++ b/lib/megaco/src/udp/megaco_udp_server.erl
@@ -0,0 +1,234 @@
+%%
+%% %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%
+%%
+
+%%
+%%-----------------------------------------------------------------
+%%
+%% Description:
+%% This file handles the H.248 UDP connections.
+%%
+%%-----------------------------------------------------------------
+-module(megaco_udp_server).
+
+-behaviour(gen_server).
+
+%%-----------------------------------------------------------------
+%% Include files
+%%-----------------------------------------------------------------
+-include_lib("megaco/src/udp/megaco_udp.hrl").
+-include_lib("megaco/src/app/megaco_internal.hrl").
+
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([
+ start_link/1,
+ stop/1,
+
+ upgrade_receive_handle/2
+ ]).
+
+%%-----------------------------------------------------------------
+%% Internal exports
+%%-----------------------------------------------------------------
+-export([
+ init/1,
+ handle_call/3,
+ handle_cast/2,
+ handle_info/2,
+ code_change/3,
+ terminate/2,
+
+ handle_received_message/5
+ ]).
+
+%%-----------------------------------------------------------------
+%% External interface functions
+%%-----------------------------------------------------------------
+%%-----------------------------------------------------------------
+%% Func: start_link/1
+%% Description: Starts the process that keeps track of an UDP
+%% socket.
+%%-----------------------------------------------------------------
+start_link(Arg) ->
+ gen_server:start_link(?MODULE, Arg, []).
+
+%%-----------------------------------------------------------------
+%% Func: stop/1
+%% Description: Stops the process that keeps track of an UDP
+%% socket.
+%%-----------------------------------------------------------------
+stop(Pid) ->
+ call(Pid, stop).
+
+
+upgrade_receive_handle(Pid, NewHandle) ->
+ call(Pid, {upgrade_receive_handle, NewHandle}).
+
+%%-----------------------------------------------------------------
+%% Internal interface functions
+%%-----------------------------------------------------------------
+
+%%-----------------------------------------------------------------
+%% Server functions
+%%-----------------------------------------------------------------
+%%-----------------------------------------------------------------
+%% Func: init/1
+%% Description: Init funcion for the generic server
+%%-----------------------------------------------------------------
+init(Arg) ->
+ ?udp_debug(Arg, "udp server starting", [self()]),
+ {ok, Arg}.
+
+%%-----------------------------------------------------------------
+%% Func: terminate/2
+%% Description: Termination function for the generic server
+%%-----------------------------------------------------------------
+terminate(Reason, State) ->
+ ?udp_debug(State, "udp server terminating", [self(), Reason]),
+ ok.
+
+%%-----------------------------------------------------------------
+%% Func: handle_call/3
+%% Description: Handling call messages (really just stop and garbage)
+%%-----------------------------------------------------------------
+handle_call(stop, _From, UdpRec) ->
+ Reply = do_stop(UdpRec),
+ {stop, shutdown, Reply, UdpRec};
+handle_call({upgrade_receive_handle, NewHandle}, _From, UdpRec) ->
+ {reply, ok, UdpRec#megaco_udp{receive_handle = NewHandle}};
+handle_call(Req, From, UdpRec) ->
+ warning_msg("received unexpected request from ~p: "
+ "~n~p", [From, Req]),
+ {reply, {error, {invalid_request, Req}}, UdpRec}.
+
+%%-----------------------------------------------------------------
+%% Func: handle_cast/2
+%% Description: Handling cast messages (really just stop and garbage)
+%%-----------------------------------------------------------------
+handle_cast(stop, UdpRec) ->
+ do_stop(UdpRec),
+ {stop, shutdown, UdpRec};
+handle_cast(Msg, UdpRec) ->
+ warning_msg("received unexpected message: "
+ "~n~w", [Msg]),
+ {noreply, UdpRec}.
+
+%%-----------------------------------------------------------------
+%% Func: handle_info/2
+%% Description: Handling non call/cast messages. Incomming messages
+%% from the socket and exit codes.
+%%-----------------------------------------------------------------
+handle_info({udp, _UdpId, Ip, Port, Msg},
+ #megaco_udp{serialize = false} = UdpRec) ->
+ #megaco_udp{socket = Socket, module = Mod, receive_handle = RH} = UdpRec,
+ SH = megaco_udp:create_send_handle(Socket, Ip, Port),
+ MsgSize = size(Msg),
+ incNumInMessages(SH),
+ incNumInOctets(SH, MsgSize),
+ case MsgSize of
+ Sz when Sz < ?GC_MSG_LIMIT ->
+ apply(Mod, receive_message, [RH, self(), SH, Msg]);
+ Sz ->
+ receive_message(Mod, RH, SH, Sz, Msg)
+ end,
+ inet:setopts(Socket, [{active, once}]),
+ {noreply, UdpRec};
+handle_info({udp, _UdpId, Ip, Port, Msg},
+ #megaco_udp{serialize = true} = UdpRec) ->
+ #megaco_udp{socket = Socket, module = Mod, receive_handle = RH} = UdpRec,
+ SH = megaco_udp:create_send_handle(Socket, Ip, Port),
+ MsgSize = size(Msg),
+ incNumInMessages(SH),
+ incNumInOctets(SH, MsgSize),
+ process_received_message(Mod, RH, SH, Msg),
+ inet:setopts(Socket, [{active, once}]),
+ {noreply, UdpRec};
+handle_info(Info, UdpRec) ->
+ warning_msg("received unexpected info: "
+ "~n~w", [Info]),
+ {noreply, UdpRec}.
+
+
+process_received_message(Mod, RH, SH, Msg) ->
+ case (catch Mod:process_received_message(RH, self(), SH, Msg)) of
+ ok ->
+ ok;
+ Error ->
+ error_msg("failed processing received message: "
+ "~n~p", [Error]),
+ ok
+ end.
+
+
+receive_message(Mod, RH, SendHandle, Length, Msg) ->
+ Opts = [link , {min_heap_size, ?HEAP_SIZE(Length)}],
+ spawn_opt(?MODULE, handle_received_message,
+ [Mod, RH, self(), SendHandle, Msg], Opts).
+
+
+handle_received_message(Mod, RH, Parent, SH, Msg) ->
+ Mod:process_received_message(RH, Parent, SH, Msg),
+ unlink(Parent),
+ exit(normal).
+
+
+
+%%-----------------------------------------------------------------
+%% Func: code_change/3
+%% Descrition: Handles code change messages during upgrade.
+%%-----------------------------------------------------------------
+code_change(_Vsn, State, _Extra) ->
+ {ok, State}.
+
+do_stop(#megaco_udp{socket = Socket}) ->
+ gen_udp:close(Socket).
+
+
+%%-----------------------------------------------------------------
+%% Func: incNumInMessages/1, incNumInOctets/2, incNumErrors/1
+%% Description: SNMP counter increment functions
+%%
+%%-----------------------------------------------------------------
+incNumInMessages(SH) ->
+ incCounter({SH, medGwyGatewayNumInMessages}, 1).
+
+incNumInOctets(SH, NumOctets) ->
+ incCounter({SH, medGwyGatewayNumInOctets}, NumOctets).
+
+incCounter(Key, Inc) ->
+ ets:update_counter(megaco_udp_stats, Key, Inc).
+
+% incNumErrors(SH) ->
+% incCounter({SH, medGwyGatewayNumErrors}, 1).
+
+
+%% info_msg(F, A) ->
+%% ?megaco_info("UDP server: " ++ F, A).
+
+warning_msg(F, A) ->
+ ?megaco_warning("UDP server: " ++ F, A).
+
+error_msg(F, A) ->
+ ?megaco_error("UDP server: " ++ F, A).
+
+
+call(Pid, Req) ->
+ gen_server:call(Pid, Req, infinity).
diff --git a/lib/megaco/src/udp/megaco_udp_sup.erl b/lib/megaco/src/udp/megaco_udp_sup.erl
new file mode 100644
index 0000000000..6a381c22d8
--- /dev/null
+++ b/lib/megaco/src/udp/megaco_udp_sup.erl
@@ -0,0 +1,112 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2000-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: Supervisor for all active UDP port servers
+%%-----------------------------------------------------------------
+-module(megaco_udp_sup).
+
+-behaviour(supervisor).
+
+%%-----------------------------------------------------------------
+%% Include files
+%%-----------------------------------------------------------------
+-include_lib("megaco/include/megaco.hrl").
+
+%%-----------------------------------------------------------------
+%% External exports
+%%-----------------------------------------------------------------
+-export([
+ start_link/0,
+ start_child/2
+ ]).
+
+
+%%-----------------------------------------------------------------
+%% Internal exports
+%%-----------------------------------------------------------------
+-export([
+ init/1,
+ terminate/2,
+ start_server/1
+ ]).
+
+
+%%-----------------------------------------------------------------
+%% External interface functions
+%%-----------------------------------------------------------------
+
+%%-----------------------------------------------------------------
+%% Func: start_link
+%% Description: Starts the UDP port server supervisor
+%%-----------------------------------------------------------------
+start_link() ->
+ supervisor:start_link(?MODULE, [[]]).
+
+
+%%-----------------------------------------------------------------
+%% Func: start_child
+%% Description: Starts the UDP port server supervisor
+%%-----------------------------------------------------------------
+start_child(SupPid, UdpRec) ->
+ supervisor:start_child(SupPid, [UdpRec]).
+
+
+%%-----------------------------------------------------------------
+%% Internal interface functions
+%%-----------------------------------------------------------------
+%%-----------------------------------------------------------------
+%% Func: start_server/1
+%% Description: Function which the supervisor calls to start a child
+%%-----------------------------------------------------------------
+start_server(Args) ->
+ megaco_udp_server:start_link(Args).
+
+
+%%-----------------------------------------------------------------
+%% Server functions
+%%-----------------------------------------------------------------
+%%-----------------------------------------------------------------
+%% Func: init/1
+%% Description: Init funcion for the supervisor
+%%-----------------------------------------------------------------
+init(_) ->
+ SupFlags = {simple_one_for_one, 500, 100},
+ ChildSpec = [
+ {megaco_udp_server,
+ {?MODULE, start_server, []},
+ permanent,
+ 10000,
+ worker,
+ []}
+ ],
+ {ok, {SupFlags, ChildSpec}}.
+
+
+%%-----------------------------------------------------------------
+%% Func: terminate/1
+%% Description: Termination function for the supervisor
+%%-----------------------------------------------------------------
+terminate(_Reason, _State) ->
+ ok.
+
+%%-----------------------------------------------------------------
+%% Internal functions
+%%-----------------------------------------------------------------
diff --git a/lib/megaco/src/udp/modules.mk b/lib/megaco/src/udp/modules.mk
new file mode 100644
index 0000000000..47126f6207
--- /dev/null
+++ b/lib/megaco/src/udp/modules.mk
@@ -0,0 +1,30 @@
+#-*-makefile-*- ; force emacs to enter makefile-mode
+
+# %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%
+
+MODULES = \
+ megaco_udp \
+ megaco_udp_sup \
+ megaco_udp_server
+
+
+INTERNAL_HRL_FILES = \
+ megaco_udp.hrl
+
+
+