From 20c2dcc70525f110c6f71c4b968d7d67682b7c35 Mon Sep 17 00:00:00 2001 From: Anders Svensson Date: Fri, 16 Dec 2011 16:51:19 +0100 Subject: Move example code to examples/code --- lib/diameter/examples/GNUmakefile | 35 -------- lib/diameter/examples/client.erl | 125 -------------------------- lib/diameter/examples/client_cb.erl | 103 --------------------- lib/diameter/examples/code/GNUmakefile | 35 ++++++++ lib/diameter/examples/code/client.erl | 125 ++++++++++++++++++++++++++ lib/diameter/examples/code/client_cb.erl | 103 +++++++++++++++++++++ lib/diameter/examples/code/peer.erl | 139 +++++++++++++++++++++++++++++ lib/diameter/examples/code/redirect.erl | 70 +++++++++++++++ lib/diameter/examples/code/redirect_cb.erl | 63 +++++++++++++ lib/diameter/examples/code/relay.erl | 92 +++++++++++++++++++ lib/diameter/examples/code/relay_cb.erl | 69 ++++++++++++++ lib/diameter/examples/code/sctp.erl | 131 +++++++++++++++++++++++++++ lib/diameter/examples/code/server.erl | 88 ++++++++++++++++++ lib/diameter/examples/code/server_cb.erl | 115 ++++++++++++++++++++++++ lib/diameter/examples/peer.erl | 139 ----------------------------- lib/diameter/examples/redirect.erl | 70 --------------- lib/diameter/examples/redirect_cb.erl | 63 ------------- lib/diameter/examples/relay.erl | 92 ------------------- lib/diameter/examples/relay_cb.erl | 69 -------------- lib/diameter/examples/sctp.erl | 113 ----------------------- lib/diameter/examples/server.erl | 88 ------------------ lib/diameter/examples/server_cb.erl | 115 ------------------------ lib/diameter/src/Makefile | 17 +++- lib/diameter/src/modules.mk | 16 ++-- 24 files changed, 1053 insertions(+), 1022 deletions(-) delete mode 100644 lib/diameter/examples/GNUmakefile delete mode 100644 lib/diameter/examples/client.erl delete mode 100644 lib/diameter/examples/client_cb.erl create mode 100644 lib/diameter/examples/code/GNUmakefile create mode 100644 lib/diameter/examples/code/client.erl create mode 100644 lib/diameter/examples/code/client_cb.erl create mode 100644 lib/diameter/examples/code/peer.erl create mode 100644 lib/diameter/examples/code/redirect.erl create mode 100644 lib/diameter/examples/code/redirect_cb.erl create mode 100644 lib/diameter/examples/code/relay.erl create mode 100644 lib/diameter/examples/code/relay_cb.erl create mode 100644 lib/diameter/examples/code/sctp.erl create mode 100644 lib/diameter/examples/code/server.erl create mode 100644 lib/diameter/examples/code/server_cb.erl delete mode 100644 lib/diameter/examples/peer.erl delete mode 100644 lib/diameter/examples/redirect.erl delete mode 100644 lib/diameter/examples/redirect_cb.erl delete mode 100644 lib/diameter/examples/relay.erl delete mode 100644 lib/diameter/examples/relay_cb.erl delete mode 100644 lib/diameter/examples/sctp.erl delete mode 100644 lib/diameter/examples/server.erl delete mode 100644 lib/diameter/examples/server_cb.erl (limited to 'lib/diameter') diff --git a/lib/diameter/examples/GNUmakefile b/lib/diameter/examples/GNUmakefile deleted file mode 100644 index 4c3f87939b..0000000000 --- a/lib/diameter/examples/GNUmakefile +++ /dev/null @@ -1,35 +0,0 @@ -# -# %CopyrightBegin% -# -# Copyright Ericsson AB 2010-2011. 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% -# - -EXAMPLES = client server relay # redirect proxy - -CALLBACKS = $(EXAMPLES:%=%_cb) -MODULES = peer $(EXAMPLES) $(EXAMPLES:%=%_cb) - -BEAM = $(MODULES:%=%.beam) - -%.beam: %.erl - erlc -W $< - -all: $(BEAM) - -clean: - rm -f $(BEAM) - -.PHONY: all clean diff --git a/lib/diameter/examples/client.erl b/lib/diameter/examples/client.erl deleted file mode 100644 index 36a77dd524..0000000000 --- a/lib/diameter/examples/client.erl +++ /dev/null @@ -1,125 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2010-2011. 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% -%% - -%% -%% An example Diameter client that can sends base protocol RAR -%% requests to a connected peer. -%% -%% The simplest usage is as follows this to connect to a server -%% listening on the default port on the local host, assuming diameter -%% is already started (eg. diameter:start()). -%% -%% client:start(). -%% client:connect(tcp). -%% client:call(). -%% -%% The first call starts the a service with the default name of -%% ?MODULE, the second defines a connecting transport that results in -%% a connection to the peer (if it's listening), the third sends it a -%% RAR and returns the answer. -%% - --module(client). - --include_lib("diameter/include/diameter.hrl"). --include_lib("diameter/src/app/diameter_gen_base_rfc3588.hrl"). - --export([start/1, %% start a service - connect/2, %% add a connecting transport - call/1, %% send using the record encoding - cast/1, %% send using the list encoding and detached - stop/1]). %% stop a service -%% A real application would typically choose an encoding and whether -%% they want the call to return the answer or not. Sending with -%% both the record and list encoding here, one detached and one not, -%% is just for demonstration purposes. - -%% Convenience functions using the default service name, ?SVC_NAME. --export([start/0, - connect/1, - stop/0, - call/0, - cast/0]). - --define(SVC_NAME, ?MODULE). --define(APP_ALIAS, ?MODULE). --define(CALLBACK_MOD, client_cb). - --define(L, atom_to_list). - -%% The service configuration. As in the server example, a client -%% supporting multiple Diameter applications may or may not want to -%% configure a common callback module on all applications. --define(SERVICE(Name), [{'Origin-Host', ?L(Name) ++ ".example.com"}, - {'Origin-Realm', "example.com"}, - {'Vendor-Id', 0}, - {'Product-Name', "Client"}, - {'Auth-Application-Id', [?DIAMETER_APP_ID_COMMON]}, - {application, [{alias, ?APP_ALIAS}, - {dictionary, ?DIAMETER_DICT_COMMON}, - {module, ?CALLBACK_MOD}]}]). - -%% start/1 - -start(Name) - when is_atom(Name) -> - peer:start(Name, ?SERVICE(Name)). - -start() -> - start(?SVC_NAME). - -%% connect/2 - -connect(Name, T) -> - peer:connect(Name, T). - -connect(T) -> - connect(?SVC_NAME, T). - -%% call/1 - -call(Name) -> - SId = diameter:session_id(?L(Name)), - RAR = #diameter_base_RAR{'Session-Id' = SId, - 'Auth-Application-Id' = 0, - 'Re-Auth-Request-Type' = 0}, - diameter:call(Name, ?APP_ALIAS, RAR, []). - -call() -> - call(?SVC_NAME). - -%% cast/1 - -cast(Name) -> - SId = diameter:session_id(?L(Name)), - RAR = ['RAR', {'Session-Id', SId}, - {'Auth-Application-Id', 0}, - {'Re-Auth-Request-Type', 1}], - diameter:call(Name, ?APP_ALIAS, RAR, [detach]). - -cast() -> - cast(?SVC_NAME). - -%% stop/1 - -stop(Name) -> - peer:stop(Name). - -stop() -> - stop(?SVC_NAME). diff --git a/lib/diameter/examples/client_cb.erl b/lib/diameter/examples/client_cb.erl deleted file mode 100644 index 524a8f94a1..0000000000 --- a/lib/diameter/examples/client_cb.erl +++ /dev/null @@ -1,103 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2010-2011. 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% -%% - --module(client_cb). - --include_lib("diameter/include/diameter.hrl"). --include_lib("diameter/src/app/diameter_gen_base_rfc3588.hrl"). - -%% diameter callbacks --export([peer_up/3, - peer_down/3, - pick_peer/4, - prepare_request/3, - prepare_retransmit/3, - handle_answer/4, - handle_error/4, - handle_request/3]). - -%% peer_up/3 - -peer_up(_SvcName, _Peer, State) -> - State. - -%% peer_down/3 - -peer_down(_SvcName, _Peer, State) -> - State. - -%% pick_peer/4 - -pick_peer([Peer | _], _, _SvcName, _State) -> - {ok, Peer}. - -%% prepare_request/3 - -prepare_request(#diameter_packet{msg = ['RAR' = T | Avps]}, _, {_, Caps}) -> - #diameter_caps{origin_host = {OH, DH}, - origin_realm = {OR, DR}} - = Caps, - - {send, [T, {'Origin-Host', OH}, - {'Origin-Realm', OR}, - {'Destination-Host', DH}, - {'Destination-Realm', DR} - | Avps]}; - -prepare_request(#diameter_packet{msg = Rec}, _, {_, Caps}) -> - #diameter_caps{origin_host = {OH, DH}, - origin_realm = {OR, DR}} - = Caps, - - {send, Rec#diameter_base_RAR{'Origin-Host' = OH, - 'Origin-Realm' = OR, - 'Destination-Host' = DH, - 'Destination-Realm' = DR}}. - -%% prepare_retransmit/3 - -prepare_retransmit(Packet, SvcName, Peer) -> - prepare_request(Packet, SvcName, Peer). - -%% handle_answer/4 - -%% Since client.erl has detached the call when using the list -%% encoding and not otherwise, output to the terminal in the -%% the former case, return in the latter. - -handle_answer(#diameter_packet{msg = Msg}, Request, _SvcName, _Peer) - when is_list(Request) -> - io:format("answer: ~p~n", [Msg]); - -handle_answer(#diameter_packet{msg = Msg}, _Request, _SvcName, _Peer) -> - {ok, Msg}. - -%% handle_error/4 - -handle_error(Reason, Request, _SvcName, _Peer) - when is_list(Request) -> - io:format("error: ~p~n", [Reason]); - -handle_error(Reason, _Request, _SvcName, _Peer) -> - {error, Reason}. - -%% handle_request/3 - -handle_request(_Packet, _SvcName, _Peer) -> - erlang:error({unexpected, ?MODULE, ?LINE}). diff --git a/lib/diameter/examples/code/GNUmakefile b/lib/diameter/examples/code/GNUmakefile new file mode 100644 index 0000000000..a0669119d2 --- /dev/null +++ b/lib/diameter/examples/code/GNUmakefile @@ -0,0 +1,35 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2010-2011. 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% +# + +EXAMPLES = client server relay # redirect proxy + +CALLBACKS = $(EXAMPLES:%=%_cb) +MODULES = peer $(EXAMPLES) $(EXAMPLES:%=%_cb) + +BEAM = $(MODULES:%=%.beam) + +%.beam: %.erl + erlc -W $< + +all: $(BEAM) + +clean: + rm -f $(BEAM) + +.PHONY: all clean diff --git a/lib/diameter/examples/code/client.erl b/lib/diameter/examples/code/client.erl new file mode 100644 index 0000000000..9e65f98de0 --- /dev/null +++ b/lib/diameter/examples/code/client.erl @@ -0,0 +1,125 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2010-2011. 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% +%% + +%% +%% An example Diameter client that can sends base protocol RAR +%% requests to a connected peer. +%% +%% The simplest usage is as follows this to connect to a server +%% listening on the default port on the local host, assuming diameter +%% is already started (eg. diameter:start()). +%% +%% client:start(). +%% client:connect(tcp). +%% client:call(). +%% +%% The first call starts the a service with the default name of +%% ?MODULE, the second defines a connecting transport that results in +%% a connection to the peer (if it's listening), the third sends it a +%% RAR and returns the answer. +%% + +-module(client). + +-include_lib("diameter/include/diameter.hrl"). +-include_lib("diameter/src/app/diameter_gen_base_rfc3588.hrl"). + +-export([start/1, %% start a service + connect/2, %% add a connecting transport + call/1, %% send using the record encoding + cast/1, %% send using the list encoding and detached + stop/1]). %% stop a service +%% A real application would typically choose an encoding and whether +%% they want the call to return the answer or not. Sending with +%% both the record and list encoding here, one detached and one not, +%% is just for demonstration purposes. + +%% Convenience functions using the default service name, ?SVC_NAME. +-export([start/0, + connect/1, + stop/0, + call/0, + cast/0]). + +-define(SVC_NAME, ?MODULE). +-define(APP_ALIAS, ?MODULE). +-define(CALLBACK_MOD, client_cb). + +-define(L, atom_to_list). + +%% The service configuration. As in the server example, a client +%% supporting multiple Diameter applications may or may not want to +%% configure a common callback module on all applications. +-define(SERVICE(Name), [{'Origin-Host', ?L(Name) ++ ".example.com"}, + {'Origin-Realm', "example.com"}, + {'Vendor-Id', 0}, + {'Product-Name', "Client"}, + {'Auth-Application-Id', [?DIAMETER_APP_ID_COMMON]}, + {application, [{alias, ?APP_ALIAS}, + {dictionary, ?DIAMETER_DICT_COMMON}, + {module, ?CALLBACK_MOD}]}]). + +%% start/1 + +start(Name) + when is_atom(Name) -> + peer:start(Name, ?SERVICE(Name)). + +start() -> + start(?SVC_NAME). + +%% connect/2 + +connect(Name, T) -> + peer:connect(Name, T). + +connect(T) -> + connect(?SVC_NAME, T). + +%% call/1 + +call(Name) -> + SId = diameter:session_id(?L(Name)), + RAR = #diameter_base_RAR{'Session-Id' = SId, + 'Auth-Application-Id' = 0, + 'Re-Auth-Request-Type' = 0}, + diameter:call(Name, ?APP_ALIAS, RAR, []). + +call() -> + call(?SVC_NAME). + +%% cast/1 + +cast(Name) -> + SId = diameter:session_id(?L(Name)), + RAR = ['RAR', {'Session-Id', SId}, + {'Auth-Application-Id', 0}, + {'Re-Auth-Request-Type', 1}], + diameter:call(Name, ?APP_ALIAS, RAR, [detach]). + +cast() -> + cast(?SVC_NAME). + +%% stop/1 + +stop(Name) -> + peer:stop(Name). + +stop() -> + stop(?SVC_NAME). diff --git a/lib/diameter/examples/code/client_cb.erl b/lib/diameter/examples/code/client_cb.erl new file mode 100644 index 0000000000..524a8f94a1 --- /dev/null +++ b/lib/diameter/examples/code/client_cb.erl @@ -0,0 +1,103 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2010-2011. 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% +%% + +-module(client_cb). + +-include_lib("diameter/include/diameter.hrl"). +-include_lib("diameter/src/app/diameter_gen_base_rfc3588.hrl"). + +%% diameter callbacks +-export([peer_up/3, + peer_down/3, + pick_peer/4, + prepare_request/3, + prepare_retransmit/3, + handle_answer/4, + handle_error/4, + handle_request/3]). + +%% peer_up/3 + +peer_up(_SvcName, _Peer, State) -> + State. + +%% peer_down/3 + +peer_down(_SvcName, _Peer, State) -> + State. + +%% pick_peer/4 + +pick_peer([Peer | _], _, _SvcName, _State) -> + {ok, Peer}. + +%% prepare_request/3 + +prepare_request(#diameter_packet{msg = ['RAR' = T | Avps]}, _, {_, Caps}) -> + #diameter_caps{origin_host = {OH, DH}, + origin_realm = {OR, DR}} + = Caps, + + {send, [T, {'Origin-Host', OH}, + {'Origin-Realm', OR}, + {'Destination-Host', DH}, + {'Destination-Realm', DR} + | Avps]}; + +prepare_request(#diameter_packet{msg = Rec}, _, {_, Caps}) -> + #diameter_caps{origin_host = {OH, DH}, + origin_realm = {OR, DR}} + = Caps, + + {send, Rec#diameter_base_RAR{'Origin-Host' = OH, + 'Origin-Realm' = OR, + 'Destination-Host' = DH, + 'Destination-Realm' = DR}}. + +%% prepare_retransmit/3 + +prepare_retransmit(Packet, SvcName, Peer) -> + prepare_request(Packet, SvcName, Peer). + +%% handle_answer/4 + +%% Since client.erl has detached the call when using the list +%% encoding and not otherwise, output to the terminal in the +%% the former case, return in the latter. + +handle_answer(#diameter_packet{msg = Msg}, Request, _SvcName, _Peer) + when is_list(Request) -> + io:format("answer: ~p~n", [Msg]); + +handle_answer(#diameter_packet{msg = Msg}, _Request, _SvcName, _Peer) -> + {ok, Msg}. + +%% handle_error/4 + +handle_error(Reason, Request, _SvcName, _Peer) + when is_list(Request) -> + io:format("error: ~p~n", [Reason]); + +handle_error(Reason, _Request, _SvcName, _Peer) -> + {error, Reason}. + +%% handle_request/3 + +handle_request(_Packet, _SvcName, _Peer) -> + erlang:error({unexpected, ?MODULE, ?LINE}). diff --git a/lib/diameter/examples/code/peer.erl b/lib/diameter/examples/code/peer.erl new file mode 100644 index 0000000000..89203e15c3 --- /dev/null +++ b/lib/diameter/examples/code/peer.erl @@ -0,0 +1,139 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2010-2011. 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% +%% + +%% +%% A library module that factors out commonality in the example +%% Diameter peers. +%% + +-module(peer). + +-include_lib("diameter/include/diameter.hrl"). +-include_lib("diameter/src/app/diameter_gen_base_rfc3588.hrl"). + +-export([start/2, + listen/2, + connect/2, + stop/1]). + +-type service_name() + :: term(). + +-type protocol() + :: tcp | sctp. + +-type ip_address() + :: default + | inet:ip_address(). + +-type server_config() + :: protocol() + | {protocol(), ip_address(), non_neg_integer()}. + +-type client_config() + :: protocol() + | {protocol(), ip_address(), non_neg_integer()} + | {protocol(), ip_address(), ip_address(), non_neg_integer()}. + +-define(DEFAULT_ADDR, {127,0,0,1}). +-define(DEFAULT_PORT, 3868). + +%% --------------------------------------------------------------------------- +%% Interface functions +%% --------------------------------------------------------------------------- + +%% start/2 + +-spec start(service_name(), list()) + -> ok + | {error, term()}. + +start(Name, Opts) + when is_atom(Name), is_list(Opts) -> + diameter:start_service(Name, Opts). + +%% connect/2 + +-spec connect(service_name(), client_config()) + -> {ok, reference()} + | {error, term()}. + +connect(Name, T) -> + diameter:add_transport(Name, {connect, [{reconnect_timer, 5000} + | client(T)]}). + +%% listen/2 + +-spec listen(service_name(), server_config()) + -> {ok, reference()} + | {error, term()}. + +listen(Name, T) -> + diameter:add_transport(Name, {listen, server(T)}). + +%% stop/1 + +-spec stop(service_name()) + -> ok + | {error, term()}. + +stop(Name) -> + diameter:stop_service(Name). + +%% --------------------------------------------------------------------------- +%% Internal functions +%% --------------------------------------------------------------------------- + +%% server/1 +%% +%% Return config for a listening transport. + +server({T, Addr, Port}) -> + [{transport_module, tmod(T)}, + {transport_config, [{reuseaddr, true}, + {ip, addr(Addr)}, + {port, Port}]}]; + +server(T) -> + server({T, ?DEFAULT_ADDR, ?DEFAULT_PORT}). + +%% client/1 +%% +%% Return config for a connecting transport. + +client({T, LA, RA, RP}) -> + [{transport_module, tmod(T)}, + {transport_config, [{ip, addr(LA)}, + {raddr, addr(RA)}, + {rport, RP}, + {reuseaddr, true}]}]; + +client({T, LA, RP}) -> + client({T, LA, LA, RP}); + +client(T) -> + client({T, ?DEFAULT_ADDR, ?DEFAULT_ADDR, ?DEFAULT_PORT}). + +tmod(tcp) -> diameter_tcp; +tmod(sctp) -> diameter_sctp. + +addr(default) -> + ?DEFAULT_ADDR; +addr(A) -> + A. diff --git a/lib/diameter/examples/code/redirect.erl b/lib/diameter/examples/code/redirect.erl new file mode 100644 index 0000000000..b54701243f --- /dev/null +++ b/lib/diameter/examples/code/redirect.erl @@ -0,0 +1,70 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2010-2011. 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% +%% + +-module(redirect). + +-include_lib("diameter/include/diameter.hrl"). +-include_lib("diameter/src/app/diameter_gen_base_rfc3588.hrl"). + +-export([start/1, + listen/2, + stop/1]). + +-export([start/0, + listen/1, + stop/0]). + +-define(APP_ALIAS, ?MODULE). +-define(SVC_NAME, ?MODULE). +-define(CALLBACK_MOD, redirect_mod). + +%% The service configuration. +-define(SERVICE(Name), [{'Origin-Host', atom_to_list(Name) ++ ".example.com"}, + {'Origin-Realm', "example.com"}, + {'Vendor-Id', 193}, + {'Product-Name', "RedirectAgent"}, + {'Auth-Application-Id', [?DIAMETER_APP_ID_RELAY]}, + {application, [{alias, ?APP_ALIAS}, + {dictionary, ?DIAMETER_DICT_RELAY}, + {module, ?CALLBACK_MOD}]}]). + +%% start/1 + +start(Name) + when is_atom(Name) -> + peer:start(Name, ?SERVICE(Name)). + +start() -> + start(?SVC_NAME). + +%% listen/2 + +listen(Name, T) -> + peer:listen(Name, T). + +listen(T) -> + listen(?SVC_NAME, T). + +%% stop/1 + +stop(Name) -> + peer:stop(Name). + +stop() -> + stop(?SVC_NAME). diff --git a/lib/diameter/examples/code/redirect_cb.erl b/lib/diameter/examples/code/redirect_cb.erl new file mode 100644 index 0000000000..ea7ad38749 --- /dev/null +++ b/lib/diameter/examples/code/redirect_cb.erl @@ -0,0 +1,63 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2010-2011. 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% +%% + +-module(redirect_cb). + +-include_lib("diameter/include/diameter.hrl"). +-include_lib("diameter/src/app/diameter_gen_base_rfc3588.hrl"). + +%% diameter callbacks +-export([peer_up/3, + peer_down/3, + pick_peer/4, + prepare_request/3, + prepare_retransmit/3, + handle_answer/4, + handle_error/4, + handle_request/3]). + +-define(UNEXPECTED, erlang:error({unexpected, ?MODULE, ?LINE})). + +peer_up(_SvcName, {PeerRef, _}, State) -> + io:format("up: ~p~n", [PeerRef]), + State. + +peer_down(_SvcName, {PeerRef, _}, State) -> + io:format("down: ~p~n", [PeerRef]), + State. + +pick_peer(_, _, _SvcName, _State) -> + ?UNEXPECTED. + +prepare_request(_, _SvcName, _Peer) -> + ?UNEXPECTED. + +prepare_retransmit(_Packet, _SvcName, _Peer) -> + ?UNEXPECTED. + +handle_answer(_Packet, _Request, _SvcName, _Peer) -> + ?UNEXPECTED. + +handle_error(_Reason, _Request, _SvcName, _Peer) -> + ?UNEXPECTED. + +handle_request(#diameter_packet{msg = _, errors = []}, _SvcName, {_, Caps}) -> + #diameter_caps{} + = Caps, + discard. %% TODO diff --git a/lib/diameter/examples/code/relay.erl b/lib/diameter/examples/code/relay.erl new file mode 100644 index 0000000000..deecb1cfc0 --- /dev/null +++ b/lib/diameter/examples/code/relay.erl @@ -0,0 +1,92 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2010-2011. 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% +%% + +%% +%% An example Diameter relay agent. +%% +%% Usage to connect to a server listening on the default port over TCP +%% and to listen on the default port over SCTP is as follows, assuming +%% diameter is already started (eg. diameter:start()). +%% +%% Eg. relay:start(). +%% relay:connect(tcp). +%% relay:listen(sctp). +%% + +-module(relay). + +-include_lib("diameter/include/diameter.hrl"). +-include_lib("diameter/src/app/diameter_gen_base_rfc3588.hrl"). + +-export([start/1, + listen/2, + connect/2, + stop/1]). + +-export([start/0, + listen/1, + connect/1, + stop/0]). + +-define(APP_ALIAS, ?MODULE). +-define(SVC_NAME, ?MODULE). +-define(CALLBACK_MOD, relay_cb). + +%% The service configuration. +-define(SERVICE(Name), [{'Origin-Host', atom_to_list(Name) ++ ".example.com"}, + {'Origin-Realm', "example.com"}, + {'Vendor-Id', 193}, + {'Product-Name', "RelayAgent"}, + {'Auth-Application-Id', [?DIAMETER_APP_ID_RELAY]}, + {application, [{alias, ?MODULE}, + {dictionary, ?DIAMETER_DICT_RELAY}, + {module, ?CALLBACK_MOD}]}]). + +%% start/1 + +start(Name) + when is_atom(Name) -> + peer:start(Name, ?SERVICE(Name)). + +start() -> + start(?SVC_NAME). + +%% listen/2 + +listen(Name, T) -> + peer:listen(Name, T). + +listen(T) -> + listen(?SVC_NAME, T). + +%% connect/2 + +connect(Name, T) -> + peer:connect(Name, T). + +connect(T) -> + connect(?SVC_NAME, T). + +%% stop/1 + +stop(Name) -> + peer:stop(Name). + +stop() -> + stop(?SVC_NAME). diff --git a/lib/diameter/examples/code/relay_cb.erl b/lib/diameter/examples/code/relay_cb.erl new file mode 100644 index 0000000000..9ed6517d5c --- /dev/null +++ b/lib/diameter/examples/code/relay_cb.erl @@ -0,0 +1,69 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2010-2011. 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% +%% + +-module(relay_cb). + +-include_lib("diameter/include/diameter.hrl"). +-include_lib("diameter/src/app/diameter_gen_base_rfc3588.hrl"). + +%% diameter callbacks +-export([peer_up/3, + peer_down/3, + pick_peer/5, + prepare_request/4, + prepare_retransmit/4, + handle_answer/5, + handle_error/5, + handle_request/3]). + +peer_up(_SvcName, {PeerRef, _}, State) -> + io:format("up: ~p~n", [PeerRef]), + State. + +peer_down(_SvcName, {PeerRef, _}, State) -> + io:format("down: ~p~n", [PeerRef]), + State. + +%% Returning 'relay' from handle_request causes diameter to resend the +%% incoming request, which leads to pick_peer and prepare_request +%% callbacks as if sending explicitly. The 'extra' argument is +%% appended to the argument list for callbacks following from +%% resending of the request. + +handle_request(_Pkt, _SvcName, _Peer) -> + {relay, [{timeout, 1000}, {extra, [relayed]}]}. + +%% diameter will filter the sender in the Peers list. +pick_peer([Peer | _], _, _SvcName, _State, relayed) -> + {ok, Peer}. + +prepare_request(Pkt, _SvcName, _Peer, relayed) -> + {send, Pkt}. + +prepare_retransmit(Pkt, _SvcName, _Peer, relayed) -> + {send, Pkt}. + +%% diameter expects handle_answer to return the diameter_packet record +%% containing the answer when called for a relayed request. + +handle_answer(Pkt, _Request, _SvcName, _Peer, relayed) -> + Pkt. + +handle_error(Reason, _Request, _SvcName, _Peer, relayed) -> + {error, Reason}. diff --git a/lib/diameter/examples/code/sctp.erl b/lib/diameter/examples/code/sctp.erl new file mode 100644 index 0000000000..08de023571 --- /dev/null +++ b/lib/diameter/examples/code/sctp.erl @@ -0,0 +1,131 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2010-2011. 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% +%% + +-module(sctp). + +%% +%% A small example demonstrating the establishment of an SCTP +%% association with gen_sctp. +%% + +-export([assoc/0, + dbg/0]). + +-include_lib("kernel/include/inet_sctp.hrl"). + +-define(ADDR, {127,0,0,1}). +-define(SERVER_PORT, 3868). +-define(CONNECT_TIMEOUT, 2000). +-define(REQUEST, <<0:64>>). +-define(REPLY, <<1:64>>). + +-record(server, {client, + socket, + assoc}). + +-record(client, {socket, + assoc}). + +%% assoc/0 +%% +%% Return on a successfully established association, raise an +%% exception otherwise. + +assoc() -> + {_, MRef} = spawn_monitor(fun server/0), + receive {'DOWN', MRef, process, _, Info} -> Info end. + +%% dbg/0 + +dbg() -> + dbg:tracer(), + dbg:p(all,c), + dbg:tpl(?MODULE, [{'_',[],[{exception_trace}]}]), + dbg:tp(gen_sctp, [{'_',[],[{exception_trace}]}]), + ok. + +%% server/0 + +server() -> + {ok, Sock} = gen_sctp:open([binary, + {reuseaddr, true}, + {active, true}, + {ip, ?ADDR}, + {port, ?SERVER_PORT}]), + ok = gen_sctp:listen(Sock, true), + {_Pid, MRef} = spawn_monitor(fun client/0), + s(#server{client = MRef, socket = Sock}), + gen_sctp:close(Sock). + +%% s/1 + +s(#server{} = S) -> + s(s(receive T -> T end, S)); +s(T) -> + T. + +%% s/2 + +s({sctp, Sock, _RA, _RP, {[], #sctp_assoc_change{state = comm_up, + assoc_id = Id}}}, + #server{socket = Sock, assoc = undefined} + = S) -> + S#server{assoc = Id}; + +s({sctp, Sock, _RA, _RP, {[#sctp_sndrcvinfo{assoc_id = AId, + stream = SId}], + ?REQUEST}}, + #server{socket = Sock, assoc = AId} + = S) -> + ok = gen_sctp:send(Sock, AId, SId, ?REPLY), + S; + +s({'DOWN', MRef, process, _, normal} = T, #server{client = MRef}) -> + T. + +%% client/0 + +client() -> + {ok, Sock} = gen_sctp:open([binary, + {reuseaddr, true}, + {active, true}, + {ip, ?ADDR}, + {port, 0}]), + ok = gen_sctp:connect_init(Sock, ?ADDR, ?SERVER_PORT, []), + c(#client{socket = Sock}), + gen_sctp:close(Sock). + + +%% c/1 + +c(#client{} = S) -> + c(c(receive T -> T end, S)); +c(T) -> + T. + +c({sctp, Sock, _RA, _RP, {[], #sctp_assoc_change{state = comm_up, + assoc_id = Id}}}, + #client{socket = Sock, assoc = undefined} + = S) -> + ok = gen_sctp:send(Sock, Id, 0, ?REQUEST), + S#client{assoc = Id}; + +c({sctp, Sock, _RA, _RP, {[#sctp_sndrcvinfo{assoc_id = AId}], ?REPLY}}, + #client{socket = Sock, assoc = AId}) -> + ok. diff --git a/lib/diameter/examples/code/server.erl b/lib/diameter/examples/code/server.erl new file mode 100644 index 0000000000..ebb408e501 --- /dev/null +++ b/lib/diameter/examples/code/server.erl @@ -0,0 +1,88 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2010-2011. 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% +%% + +%% +%% An example Diameter server that can respond to the base protocol +%% RAR sent by the client example. +%% +%% The simplest example to start a server listening on the loopback +%% address (which will serve the example usage given in client.erl) is +%% like this assuming diameter is already started (eg. diameter:start()): +%% +%% server:start(). +%% server:listen(tcp). +%% +%% The first call starts a service, the second adds a transport listening +%% on the default port. +%% + +-module(server). + +-include_lib("diameter/include/diameter.hrl"). +-include_lib("diameter/src/app/diameter_gen_base_rfc3588.hrl"). + +-export([start/1, %% start a service + listen/2, %% add a listening transport + stop/1]). %% stop a service + +%% Convenience functions using the default service name, ?SVC_NAME. +-export([start/0, + listen/1, + stop/0]). + +-define(SVC_NAME, ?MODULE). +-define(APP_ALIAS, ?MODULE). +-define(CALLBACK_MOD, server_cb). + +%% The service configuration. In a server supporting multiple Diameter +%% applications each application may have its own, although they could all +%% be configured with a common callback module. +-define(SERVICE(Name), [{'Origin-Host', atom_to_list(Name) ++ ".example.com"}, + {'Origin-Realm', "example.com"}, + {'Vendor-Id', 193}, + {'Product-Name', "Server"}, + {'Auth-Application-Id', [?DIAMETER_APP_ID_COMMON]}, + {application, [{alias, ?APP_ALIAS}, + {dictionary, ?DIAMETER_DICT_COMMON}, + {module, ?CALLBACK_MOD}]}]). + +%% start/1 + +start(Name) + when is_atom(Name) -> + peer:start(Name, ?SERVICE(Name)). + +start() -> + start(?SVC_NAME). + +%% listen/2 + +listen(Name, T) -> + peer:listen(Name, T). + +listen(T) -> + listen(?SVC_NAME, T). + +%% stop/1 + +stop(Name) -> + peer:stop(Name). + +stop() -> + stop(?SVC_NAME). diff --git a/lib/diameter/examples/code/server_cb.erl b/lib/diameter/examples/code/server_cb.erl new file mode 100644 index 0000000000..43b8e24b5c --- /dev/null +++ b/lib/diameter/examples/code/server_cb.erl @@ -0,0 +1,115 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2010-2011. 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% +%% + +%% +%% The diameter application callback module configured by server.erl. +%% + +-module(server_cb). + +-include_lib("diameter/include/diameter.hrl"). +-include_lib("diameter/src/app/diameter_gen_base_rfc3588.hrl"). + +%% diameter callbacks +-export([peer_up/3, + peer_down/3, + pick_peer/4, + prepare_request/3, + prepare_retransmit/3, + handle_answer/4, + handle_error/4, + handle_request/3]). + +-define(UNEXPECTED, erlang:error({unexpected, ?MODULE, ?LINE})). + +peer_up(_SvcName, {PeerRef, _}, State) -> + io:format("up: ~p~n", [PeerRef]), + State. + +peer_down(_SvcName, {PeerRef, _}, State) -> + io:format("down: ~p~n", [PeerRef]), + State. + +pick_peer(_, _, _SvcName, _State) -> + ?UNEXPECTED. + +prepare_request(_, _SvcName, _Peer) -> + ?UNEXPECTED. + +prepare_retransmit(_Packet, _SvcName, _Peer) -> + ?UNEXPECTED. + +handle_answer(_Packet, _Request, _SvcName, _Peer) -> + ?UNEXPECTED. + +handle_error(_Reason, _Request, _SvcName, _Peer) -> + ?UNEXPECTED. + +%% A request whose decode was successful ... +handle_request(#diameter_packet{msg = Req, errors = []}, _SvcName, {_, Caps}) + when is_record(Req, diameter_base_RAR) -> + #diameter_caps{origin_host = {OH,_}, + origin_realm = {OR,_}} + = Caps, + #diameter_base_RAR{'Session-Id' = Id, + 'Re-Auth-Request-Type' = RT} + = Req, + + {reply, answer(RT, Id, OH, OR)}; + +%% ... or one that wasn't. 3xxx errors are answered by diameter itself +%% but these are 5xxx errors for which we must contruct a reply. +%% diameter will set Result-Code and Failed-AVP's. +handle_request(#diameter_packet{msg = Req} = Pkt, _SvcName, {_, Caps}) + when is_record(Req, diameter_base_RAR) -> + #diameter_caps{origin_host = {OH,_}, + origin_realm = {OR,_}} + = Caps, + #diameter_base_RAR{'Session-Id' = Id} + = Req, + + Ans = #diameter_base_RAA{'Origin-Host' = OH, + 'Origin-Realm' = OR, + 'Session-Id' = Id}, + + {reply, Ans}; + +%% Should really reply to other base messages that we don't support +%% but simply discard them instead. +handle_request(#diameter_packet{}, _SvcName, {_,_}) -> + discard. + +%% --------------------------------------------------------------------------- + +%% Answer using the record or list encoding depending on +%% Re-Auth-Request-Type. This is just as an example. You would +%% typically just choose one, and this has nothing to do with the how +%% client.erl sends. + +answer(0, Id, OH, OR) -> + #diameter_base_RAA{'Result-Code' = 2001, %% DIAMETER_SUCCESS + 'Origin-Host' = OH, + 'Origin-Realm' = OR, + 'Session-Id' = Id}; + +answer(_, Id, OH, OR) -> + ['RAA', {'Result-Code', 5012}, %% DIAMETER_UNABLE_TO_COMPLY + {'Origin-Host', OH}, + {'Origin-Realm', OR}, + {'Session-Id', Id}]. diff --git a/lib/diameter/examples/peer.erl b/lib/diameter/examples/peer.erl deleted file mode 100644 index 89203e15c3..0000000000 --- a/lib/diameter/examples/peer.erl +++ /dev/null @@ -1,139 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2010-2011. 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% -%% - -%% -%% A library module that factors out commonality in the example -%% Diameter peers. -%% - --module(peer). - --include_lib("diameter/include/diameter.hrl"). --include_lib("diameter/src/app/diameter_gen_base_rfc3588.hrl"). - --export([start/2, - listen/2, - connect/2, - stop/1]). - --type service_name() - :: term(). - --type protocol() - :: tcp | sctp. - --type ip_address() - :: default - | inet:ip_address(). - --type server_config() - :: protocol() - | {protocol(), ip_address(), non_neg_integer()}. - --type client_config() - :: protocol() - | {protocol(), ip_address(), non_neg_integer()} - | {protocol(), ip_address(), ip_address(), non_neg_integer()}. - --define(DEFAULT_ADDR, {127,0,0,1}). --define(DEFAULT_PORT, 3868). - -%% --------------------------------------------------------------------------- -%% Interface functions -%% --------------------------------------------------------------------------- - -%% start/2 - --spec start(service_name(), list()) - -> ok - | {error, term()}. - -start(Name, Opts) - when is_atom(Name), is_list(Opts) -> - diameter:start_service(Name, Opts). - -%% connect/2 - --spec connect(service_name(), client_config()) - -> {ok, reference()} - | {error, term()}. - -connect(Name, T) -> - diameter:add_transport(Name, {connect, [{reconnect_timer, 5000} - | client(T)]}). - -%% listen/2 - --spec listen(service_name(), server_config()) - -> {ok, reference()} - | {error, term()}. - -listen(Name, T) -> - diameter:add_transport(Name, {listen, server(T)}). - -%% stop/1 - --spec stop(service_name()) - -> ok - | {error, term()}. - -stop(Name) -> - diameter:stop_service(Name). - -%% --------------------------------------------------------------------------- -%% Internal functions -%% --------------------------------------------------------------------------- - -%% server/1 -%% -%% Return config for a listening transport. - -server({T, Addr, Port}) -> - [{transport_module, tmod(T)}, - {transport_config, [{reuseaddr, true}, - {ip, addr(Addr)}, - {port, Port}]}]; - -server(T) -> - server({T, ?DEFAULT_ADDR, ?DEFAULT_PORT}). - -%% client/1 -%% -%% Return config for a connecting transport. - -client({T, LA, RA, RP}) -> - [{transport_module, tmod(T)}, - {transport_config, [{ip, addr(LA)}, - {raddr, addr(RA)}, - {rport, RP}, - {reuseaddr, true}]}]; - -client({T, LA, RP}) -> - client({T, LA, LA, RP}); - -client(T) -> - client({T, ?DEFAULT_ADDR, ?DEFAULT_ADDR, ?DEFAULT_PORT}). - -tmod(tcp) -> diameter_tcp; -tmod(sctp) -> diameter_sctp. - -addr(default) -> - ?DEFAULT_ADDR; -addr(A) -> - A. diff --git a/lib/diameter/examples/redirect.erl b/lib/diameter/examples/redirect.erl deleted file mode 100644 index b54701243f..0000000000 --- a/lib/diameter/examples/redirect.erl +++ /dev/null @@ -1,70 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2010-2011. 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% -%% - --module(redirect). - --include_lib("diameter/include/diameter.hrl"). --include_lib("diameter/src/app/diameter_gen_base_rfc3588.hrl"). - --export([start/1, - listen/2, - stop/1]). - --export([start/0, - listen/1, - stop/0]). - --define(APP_ALIAS, ?MODULE). --define(SVC_NAME, ?MODULE). --define(CALLBACK_MOD, redirect_mod). - -%% The service configuration. --define(SERVICE(Name), [{'Origin-Host', atom_to_list(Name) ++ ".example.com"}, - {'Origin-Realm', "example.com"}, - {'Vendor-Id', 193}, - {'Product-Name', "RedirectAgent"}, - {'Auth-Application-Id', [?DIAMETER_APP_ID_RELAY]}, - {application, [{alias, ?APP_ALIAS}, - {dictionary, ?DIAMETER_DICT_RELAY}, - {module, ?CALLBACK_MOD}]}]). - -%% start/1 - -start(Name) - when is_atom(Name) -> - peer:start(Name, ?SERVICE(Name)). - -start() -> - start(?SVC_NAME). - -%% listen/2 - -listen(Name, T) -> - peer:listen(Name, T). - -listen(T) -> - listen(?SVC_NAME, T). - -%% stop/1 - -stop(Name) -> - peer:stop(Name). - -stop() -> - stop(?SVC_NAME). diff --git a/lib/diameter/examples/redirect_cb.erl b/lib/diameter/examples/redirect_cb.erl deleted file mode 100644 index ea7ad38749..0000000000 --- a/lib/diameter/examples/redirect_cb.erl +++ /dev/null @@ -1,63 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2010-2011. 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% -%% - --module(redirect_cb). - --include_lib("diameter/include/diameter.hrl"). --include_lib("diameter/src/app/diameter_gen_base_rfc3588.hrl"). - -%% diameter callbacks --export([peer_up/3, - peer_down/3, - pick_peer/4, - prepare_request/3, - prepare_retransmit/3, - handle_answer/4, - handle_error/4, - handle_request/3]). - --define(UNEXPECTED, erlang:error({unexpected, ?MODULE, ?LINE})). - -peer_up(_SvcName, {PeerRef, _}, State) -> - io:format("up: ~p~n", [PeerRef]), - State. - -peer_down(_SvcName, {PeerRef, _}, State) -> - io:format("down: ~p~n", [PeerRef]), - State. - -pick_peer(_, _, _SvcName, _State) -> - ?UNEXPECTED. - -prepare_request(_, _SvcName, _Peer) -> - ?UNEXPECTED. - -prepare_retransmit(_Packet, _SvcName, _Peer) -> - ?UNEXPECTED. - -handle_answer(_Packet, _Request, _SvcName, _Peer) -> - ?UNEXPECTED. - -handle_error(_Reason, _Request, _SvcName, _Peer) -> - ?UNEXPECTED. - -handle_request(#diameter_packet{msg = _, errors = []}, _SvcName, {_, Caps}) -> - #diameter_caps{} - = Caps, - discard. %% TODO diff --git a/lib/diameter/examples/relay.erl b/lib/diameter/examples/relay.erl deleted file mode 100644 index deecb1cfc0..0000000000 --- a/lib/diameter/examples/relay.erl +++ /dev/null @@ -1,92 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2010-2011. 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% -%% - -%% -%% An example Diameter relay agent. -%% -%% Usage to connect to a server listening on the default port over TCP -%% and to listen on the default port over SCTP is as follows, assuming -%% diameter is already started (eg. diameter:start()). -%% -%% Eg. relay:start(). -%% relay:connect(tcp). -%% relay:listen(sctp). -%% - --module(relay). - --include_lib("diameter/include/diameter.hrl"). --include_lib("diameter/src/app/diameter_gen_base_rfc3588.hrl"). - --export([start/1, - listen/2, - connect/2, - stop/1]). - --export([start/0, - listen/1, - connect/1, - stop/0]). - --define(APP_ALIAS, ?MODULE). --define(SVC_NAME, ?MODULE). --define(CALLBACK_MOD, relay_cb). - -%% The service configuration. --define(SERVICE(Name), [{'Origin-Host', atom_to_list(Name) ++ ".example.com"}, - {'Origin-Realm', "example.com"}, - {'Vendor-Id', 193}, - {'Product-Name', "RelayAgent"}, - {'Auth-Application-Id', [?DIAMETER_APP_ID_RELAY]}, - {application, [{alias, ?MODULE}, - {dictionary, ?DIAMETER_DICT_RELAY}, - {module, ?CALLBACK_MOD}]}]). - -%% start/1 - -start(Name) - when is_atom(Name) -> - peer:start(Name, ?SERVICE(Name)). - -start() -> - start(?SVC_NAME). - -%% listen/2 - -listen(Name, T) -> - peer:listen(Name, T). - -listen(T) -> - listen(?SVC_NAME, T). - -%% connect/2 - -connect(Name, T) -> - peer:connect(Name, T). - -connect(T) -> - connect(?SVC_NAME, T). - -%% stop/1 - -stop(Name) -> - peer:stop(Name). - -stop() -> - stop(?SVC_NAME). diff --git a/lib/diameter/examples/relay_cb.erl b/lib/diameter/examples/relay_cb.erl deleted file mode 100644 index 9ed6517d5c..0000000000 --- a/lib/diameter/examples/relay_cb.erl +++ /dev/null @@ -1,69 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2010-2011. 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% -%% - --module(relay_cb). - --include_lib("diameter/include/diameter.hrl"). --include_lib("diameter/src/app/diameter_gen_base_rfc3588.hrl"). - -%% diameter callbacks --export([peer_up/3, - peer_down/3, - pick_peer/5, - prepare_request/4, - prepare_retransmit/4, - handle_answer/5, - handle_error/5, - handle_request/3]). - -peer_up(_SvcName, {PeerRef, _}, State) -> - io:format("up: ~p~n", [PeerRef]), - State. - -peer_down(_SvcName, {PeerRef, _}, State) -> - io:format("down: ~p~n", [PeerRef]), - State. - -%% Returning 'relay' from handle_request causes diameter to resend the -%% incoming request, which leads to pick_peer and prepare_request -%% callbacks as if sending explicitly. The 'extra' argument is -%% appended to the argument list for callbacks following from -%% resending of the request. - -handle_request(_Pkt, _SvcName, _Peer) -> - {relay, [{timeout, 1000}, {extra, [relayed]}]}. - -%% diameter will filter the sender in the Peers list. -pick_peer([Peer | _], _, _SvcName, _State, relayed) -> - {ok, Peer}. - -prepare_request(Pkt, _SvcName, _Peer, relayed) -> - {send, Pkt}. - -prepare_retransmit(Pkt, _SvcName, _Peer, relayed) -> - {send, Pkt}. - -%% diameter expects handle_answer to return the diameter_packet record -%% containing the answer when called for a relayed request. - -handle_answer(Pkt, _Request, _SvcName, _Peer, relayed) -> - Pkt. - -handle_error(Reason, _Request, _SvcName, _Peer, relayed) -> - {error, Reason}. diff --git a/lib/diameter/examples/sctp.erl b/lib/diameter/examples/sctp.erl deleted file mode 100644 index 2e0e9d8b0b..0000000000 --- a/lib/diameter/examples/sctp.erl +++ /dev/null @@ -1,113 +0,0 @@ - --module(sctp). - -%% -%% A small example demonstrating the establishment of an SCTP -%% association with gen_sctp. -%% - --export([assoc/0, - dbg/0]). - --include_lib("kernel/include/inet_sctp.hrl"). - --define(ADDR, {127,0,0,1}). --define(SERVER_PORT, 3868). --define(CONNECT_TIMEOUT, 2000). --define(REQUEST, <<0:64>>). --define(REPLY, <<1:64>>). - --record(server, {client, - socket, - assoc}). - --record(client, {socket, - assoc}). - -%% assoc/0 -%% -%% Return on a successfully established association, raise an -%% exception otherwise. - -assoc() -> - {_, MRef} = spawn_monitor(fun server/0), - receive {'DOWN', MRef, process, _, Info} -> Info end. - -%% dbg/0 - -dbg() -> - dbg:tracer(), - dbg:p(all,c), - dbg:tpl(?MODULE, [{'_',[],[{exception_trace}]}]), - dbg:tp(gen_sctp, [{'_',[],[{exception_trace}]}]), - ok. - -%% server/0 - -server() -> - {ok, Sock} = gen_sctp:open([binary, - {reuseaddr, true}, - {active, true}, - {ip, ?ADDR}, - {port, ?SERVER_PORT}]), - ok = gen_sctp:listen(Sock, true), - {_Pid, MRef} = spawn_monitor(fun client/0), - s(#server{client = MRef, socket = Sock}), - gen_sctp:close(Sock). - -%% s/1 - -s(#server{} = S) -> - s(s(receive T -> T end, S)); -s(T) -> - T. - -%% s/2 - -s({sctp, Sock, _RA, _RP, {[], #sctp_assoc_change{state = comm_up, - assoc_id = Id}}}, - #server{socket = Sock, assoc = undefined} - = S) -> - S#server{assoc = Id}; - -s({sctp, Sock, _RA, _RP, {[#sctp_sndrcvinfo{assoc_id = AId, - stream = SId}], - ?REQUEST}}, - #server{socket = Sock, assoc = AId} - = S) -> - ok = gen_sctp:send(Sock, AId, SId, ?REPLY), - S; - -s({'DOWN', MRef, process, _, normal} = T, #server{client = MRef}) -> - T. - -%% client/0 - -client() -> - {ok, Sock} = gen_sctp:open([binary, - {reuseaddr, true}, - {active, true}, - {ip, ?ADDR}, - {port, 0}]), - ok = gen_sctp:connect_init(Sock, ?ADDR, ?SERVER_PORT, []), - c(#client{socket = Sock}), - gen_sctp:close(Sock). - - -%% c/1 - -c(#client{} = S) -> - c(c(receive T -> T end, S)); -c(T) -> - T. - -c({sctp, Sock, _RA, _RP, {[], #sctp_assoc_change{state = comm_up, - assoc_id = Id}}}, - #client{socket = Sock, assoc = undefined} - = S) -> - ok = gen_sctp:send(Sock, Id, 0, ?REQUEST), - S#client{assoc = Id}; - -c({sctp, Sock, _RA, _RP, {[#sctp_sndrcvinfo{assoc_id = AId}], ?REPLY}}, - #client{socket = Sock, assoc = AId}) -> - ok. diff --git a/lib/diameter/examples/server.erl b/lib/diameter/examples/server.erl deleted file mode 100644 index ebb408e501..0000000000 --- a/lib/diameter/examples/server.erl +++ /dev/null @@ -1,88 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2010-2011. 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% -%% - -%% -%% An example Diameter server that can respond to the base protocol -%% RAR sent by the client example. -%% -%% The simplest example to start a server listening on the loopback -%% address (which will serve the example usage given in client.erl) is -%% like this assuming diameter is already started (eg. diameter:start()): -%% -%% server:start(). -%% server:listen(tcp). -%% -%% The first call starts a service, the second adds a transport listening -%% on the default port. -%% - --module(server). - --include_lib("diameter/include/diameter.hrl"). --include_lib("diameter/src/app/diameter_gen_base_rfc3588.hrl"). - --export([start/1, %% start a service - listen/2, %% add a listening transport - stop/1]). %% stop a service - -%% Convenience functions using the default service name, ?SVC_NAME. --export([start/0, - listen/1, - stop/0]). - --define(SVC_NAME, ?MODULE). --define(APP_ALIAS, ?MODULE). --define(CALLBACK_MOD, server_cb). - -%% The service configuration. In a server supporting multiple Diameter -%% applications each application may have its own, although they could all -%% be configured with a common callback module. --define(SERVICE(Name), [{'Origin-Host', atom_to_list(Name) ++ ".example.com"}, - {'Origin-Realm', "example.com"}, - {'Vendor-Id', 193}, - {'Product-Name', "Server"}, - {'Auth-Application-Id', [?DIAMETER_APP_ID_COMMON]}, - {application, [{alias, ?APP_ALIAS}, - {dictionary, ?DIAMETER_DICT_COMMON}, - {module, ?CALLBACK_MOD}]}]). - -%% start/1 - -start(Name) - when is_atom(Name) -> - peer:start(Name, ?SERVICE(Name)). - -start() -> - start(?SVC_NAME). - -%% listen/2 - -listen(Name, T) -> - peer:listen(Name, T). - -listen(T) -> - listen(?SVC_NAME, T). - -%% stop/1 - -stop(Name) -> - peer:stop(Name). - -stop() -> - stop(?SVC_NAME). diff --git a/lib/diameter/examples/server_cb.erl b/lib/diameter/examples/server_cb.erl deleted file mode 100644 index 43b8e24b5c..0000000000 --- a/lib/diameter/examples/server_cb.erl +++ /dev/null @@ -1,115 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2010-2011. 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% -%% - -%% -%% The diameter application callback module configured by server.erl. -%% - --module(server_cb). - --include_lib("diameter/include/diameter.hrl"). --include_lib("diameter/src/app/diameter_gen_base_rfc3588.hrl"). - -%% diameter callbacks --export([peer_up/3, - peer_down/3, - pick_peer/4, - prepare_request/3, - prepare_retransmit/3, - handle_answer/4, - handle_error/4, - handle_request/3]). - --define(UNEXPECTED, erlang:error({unexpected, ?MODULE, ?LINE})). - -peer_up(_SvcName, {PeerRef, _}, State) -> - io:format("up: ~p~n", [PeerRef]), - State. - -peer_down(_SvcName, {PeerRef, _}, State) -> - io:format("down: ~p~n", [PeerRef]), - State. - -pick_peer(_, _, _SvcName, _State) -> - ?UNEXPECTED. - -prepare_request(_, _SvcName, _Peer) -> - ?UNEXPECTED. - -prepare_retransmit(_Packet, _SvcName, _Peer) -> - ?UNEXPECTED. - -handle_answer(_Packet, _Request, _SvcName, _Peer) -> - ?UNEXPECTED. - -handle_error(_Reason, _Request, _SvcName, _Peer) -> - ?UNEXPECTED. - -%% A request whose decode was successful ... -handle_request(#diameter_packet{msg = Req, errors = []}, _SvcName, {_, Caps}) - when is_record(Req, diameter_base_RAR) -> - #diameter_caps{origin_host = {OH,_}, - origin_realm = {OR,_}} - = Caps, - #diameter_base_RAR{'Session-Id' = Id, - 'Re-Auth-Request-Type' = RT} - = Req, - - {reply, answer(RT, Id, OH, OR)}; - -%% ... or one that wasn't. 3xxx errors are answered by diameter itself -%% but these are 5xxx errors for which we must contruct a reply. -%% diameter will set Result-Code and Failed-AVP's. -handle_request(#diameter_packet{msg = Req} = Pkt, _SvcName, {_, Caps}) - when is_record(Req, diameter_base_RAR) -> - #diameter_caps{origin_host = {OH,_}, - origin_realm = {OR,_}} - = Caps, - #diameter_base_RAR{'Session-Id' = Id} - = Req, - - Ans = #diameter_base_RAA{'Origin-Host' = OH, - 'Origin-Realm' = OR, - 'Session-Id' = Id}, - - {reply, Ans}; - -%% Should really reply to other base messages that we don't support -%% but simply discard them instead. -handle_request(#diameter_packet{}, _SvcName, {_,_}) -> - discard. - -%% --------------------------------------------------------------------------- - -%% Answer using the record or list encoding depending on -%% Re-Auth-Request-Type. This is just as an example. You would -%% typically just choose one, and this has nothing to do with the how -%% client.erl sends. - -answer(0, Id, OH, OR) -> - #diameter_base_RAA{'Result-Code' = 2001, %% DIAMETER_SUCCESS - 'Origin-Host' = OH, - 'Origin-Realm' = OR, - 'Session-Id' = Id}; - -answer(_, Id, OH, OR) -> - ['RAA', {'Result-Code', 5012}, %% DIAMETER_UNABLE_TO_COMPLY - {'Origin-Host', OH}, - {'Origin-Realm', OR}, - {'Session-Id', Id}]. diff --git a/lib/diameter/src/Makefile b/lib/diameter/src/Makefile index 2ec016ecbc..8b763e73ec 100644 --- a/lib/diameter/src/Makefile +++ b/lib/diameter/src/Makefile @@ -88,6 +88,9 @@ TARGET_FILES = \ # Subdirectories of src to release modules into. TARGET_DIRS = $(sort $(dir $(TARGET_MODULES))) +# Ditto for examples. +EXAMPLE_DIRS = $(sort $(dir $(EXAMPLES))) + APP_FILE = diameter.app APP_SRC = $(APP_FILE).src APP_TARGET = $(EBIN)/$(APP_FILE) @@ -169,6 +172,8 @@ info: @echo @$(call list,EXAMPLES) @echo + @$(call list,EXAMPLE_DIRS) + @echo @$(call list,BINS) @echo ======================================== @@ -189,23 +194,31 @@ endif # Can't $(INSTALL_DIR) more than one directory at a time on Solaris. release_spec: opt - for d in bin ebin examples include src/dict $(TARGET_DIRS:%/=src/%); do \ + for d in bin ebin include src/dict; do \ $(INSTALL_DIR) $(RELSYSDIR)/$$d; \ done $(INSTALL_SCRIPT) $(BINS:%=../bin/%) $(RELSYSDIR)/bin $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(EXAMPLES:%=../examples/%) $(RELSYSDIR)/examples $(INSTALL_DATA) $(EXTERNAL_HRLS:%=../include/%) $(DICT_HRLS) \ $(RELSYSDIR)/include $(INSTALL_DATA) $(DICTS:%=dict/%.dia) $(RELSYSDIR)/src/dict $(MAKE) $(TARGET_DIRS:%/=release_src_%) + $(MAKE) $(EXAMPLE_DIRS:%/=release_examples_%) $(TARGET_DIRS:%/=release_src_%): release_src_%: + $(INSTALL_DIR) $(RELSYSDIR)/src/$* $(INSTALL_DATA) $(filter $*/%, $(TARGET_MODULES:%=%.erl) \ $(INTERNAL_HRLS)) \ $(filter $*/%, compiler/$(DICT_YRL).yrl) \ $(RELSYSDIR)/src/$* +$(EXAMPLE_DIRS:%/=release_examples_%): release_examples_%: + $(INSTALL_DIR) $(RELSYSDIR)/examples/$* + $(INSTALL_DATA) $(patsubst, %, \ + ../examples/%, \ + $(filter $*/%, $(EXAMPLES))) \ + $(RELSYSDIR)/examples/$* + release_docs_spec: # ---------------------------------------------------- diff --git a/lib/diameter/src/modules.mk b/lib/diameter/src/modules.mk index 11d354e57e..0b591e7c1e 100644 --- a/lib/diameter/src/modules.mk +++ b/lib/diameter/src/modules.mk @@ -88,11 +88,11 @@ BINS = \ # Released files relative to ../examples. EXAMPLES = \ - GNUmakefile \ - peer.erl \ - client.erl \ - client_cb.erl \ - server.erl \ - server_cb.erl \ - relay.erl \ - relay_cb.erl + code/GNUmakefile \ + code/peer.erl \ + code/client.erl \ + code/client_cb.erl \ + code/server.erl \ + code/server_cb.erl \ + code/relay.erl \ + code/relay_cb.erl -- cgit v1.2.3