1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 2010-2017. All Rights Reserved.
5%%
6%% Licensed under the Apache License, Version 2.0 (the "License");
7%% you may not use this file except in compliance with the License.
8%% You may obtain a copy of the License at
9%%
10%%     http://www.apache.org/licenses/LICENSE-2.0
11%%
12%% Unless required by applicable law or agreed to in writing, software
13%% distributed under the License is distributed on an "AS IS" BASIS,
14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15%% See the License for the specific language governing permissions and
16%% limitations under the License.
17%%
18%% %CopyrightEnd%
19%%
20
21%%
22%% An example Diameter client that can sends base protocol RAR
23%% requests to a connected peer.
24%%
25%% The simplest usage is as follows this to connect to a server
26%% listening on the default port on the local host, assuming diameter
27%% is already started (eg. diameter:start()).
28%%
29%%   client:start().
30%%   client:connect(tcp).
31%%   client:call().
32%%
33%% The first call starts the a service with the default name of
34%% ?MODULE, the second defines a connecting transport that results in
35%% a connection to the peer (if it's listening), the third sends it a
36%% RAR and returns the answer.
37%%
38
39-module(client).
40
41-include_lib("diameter/include/diameter.hrl").
42
43-export([start/1,     %% start a service
44         start/2,     %%
45         connect/2,   %% add a connecting transport
46         call/1,      %% send using the record encoding
47         cast/1,      %% send using the list encoding and detached
48         stop/1]).    %% stop a service
49%% A real application would typically choose an encoding and whether
50%% they want the call to return the answer or not. Sending with
51%% both the record and list encoding here, one detached and one not,
52%% is just for demonstration purposes.
53
54%% Convenience functions using the default service name.
55-export([start/0,
56         connect/1,
57         stop/0,
58         call/0,
59         cast/0]).
60
61-define(DEF_SVC_NAME, ?MODULE).
62-define(L, atom_to_list).
63
64%% The service configuration. As in the server example, a client
65%% supporting multiple Diameter applications may or may not want to
66%% configure a common callback module on all applications.
67-define(SERVICE(Name), [{'Origin-Host', ?L(Name) ++ ".example.com"},
68                        {'Origin-Realm', "example.com"},
69                        {'Vendor-Id', 0},
70                        {'Product-Name', "Client"},
71                        {'Auth-Application-Id', [0]},
72                        {string_decode, false},
73                        {decode_format, map},
74                        {application, [{alias, common},
75                                       {dictionary, diameter_gen_base_rfc6733},
76                                       {module, client_cb}]}]).
77
78%% start/1
79
80start(Name)
81  when is_atom(Name) ->
82    start(Name, []);
83
84start(Opts)
85  when is_list(Opts) ->
86    start(?DEF_SVC_NAME, Opts).
87
88%% start/0
89
90start() ->
91    start(?DEF_SVC_NAME).
92
93%% start/2
94
95start(Name, Opts) ->
96    node:start(Name, Opts ++ [T || {K,_} = T <- ?SERVICE(Name),
97                                   false == lists:keymember(K, 1, Opts)]).
98
99%% connect/2
100
101connect(Name, T) ->
102    node:connect(Name, T).
103
104connect(T) ->
105    connect(?DEF_SVC_NAME, T).
106
107%% call/1
108
109call(Name) ->
110    SId = diameter:session_id(?L(Name)),
111    RAR = ['RAR' | #{'Session-Id' => SId,
112                     'Auth-Application-Id' => 0,
113                     'Re-Auth-Request-Type' => 0}],
114    diameter:call(Name, common, RAR, []).
115
116call() ->
117    call(?DEF_SVC_NAME).
118
119%% cast/1
120
121cast(Name) ->
122    SId = diameter:session_id(?L(Name)),
123    RAR = ['RAR', {'Session-Id', SId},
124                  {'Auth-Application-Id', 0},
125                  {'Re-Auth-Request-Type', 1}],
126    diameter:call(Name, common, RAR, [detach]).
127
128cast() ->
129    cast(?DEF_SVC_NAME).
130
131%% stop/1
132
133stop(Name) ->
134    node:stop(Name).
135
136stop() ->
137    stop(?DEF_SVC_NAME).
138