1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 2010-2020. 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%% The diameter application callback module configured by server.erl.
23%%
24
25-module(server_cb).
26
27-include_lib("diameter/include/diameter.hrl").
28
29%% diameter callbacks
30-export([peer_up/3,
31         peer_down/3,
32         pick_peer/4,
33         prepare_request/3,
34         prepare_retransmit/3,
35         handle_answer/4,
36         handle_error/4,
37         handle_request/3]).
38
39%% Raise an error on callbacks that aren't expected.
40-define(ERROR, error({unexpected, ?MODULE, ?LINE})).
41
42%% peer_up/3
43
44peer_up(_SvcName, _Peer, State) ->
45    State.
46
47%% peer_down/3
48
49peer_down(_SvcName, _Peer, State) ->
50    State.
51
52%% pick_peer/3
53
54%% Don't let requests be sent, so other request callbacks shouldn't
55%% happen.
56pick_peer(_LocalCandidates, _RemoteCandidates, _SvcName, _State) ->
57    false.
58
59%% prepare_request/3
60
61prepare_request(_Packet, _SvcName, _Peer) ->
62    ?ERROR.
63
64%% prepare_retransmit/3
65
66prepare_retransmit(_Packet, _SvcName, _Peer) ->
67    ?ERROR.
68
69%% handle_answer/4
70
71handle_answer(_Packet, _Request, _SvcName, _Peer) ->
72    ?ERROR.
73
74%% handle_error/4
75
76handle_error(_Reason, _Request, _SvcName, _Peer) ->
77    ?ERROR.
78
79%% handle_request/3
80
81%% ACR without decode errors.
82handle_request(#diameter_packet{msg = ['ACR' | #{} = Request],
83                                errors = []},
84               _SvcName,
85               {_, Caps}) ->
86    #diameter_caps{origin_host = {OH,_},
87                   origin_realm = {OR,_}}
88        = Caps,
89
90    #{'Session-Id' := Sid,
91      'Accounting-Record-Type' := T,
92      'Accounting-Record-Number' := N}
93        = Request,
94
95    Answer = #{'Result-Code' => 2001,  %% DIAMETER_SUCCESS
96               'Origin-Host' => OH,
97               'Origin-Realm' => OR,
98               'Session-Id' => Sid,
99               'Accounting-Record-Type' => T,
100               'Accounting-Record-Number' => N},
101
102    {reply, ['ACA' | Answer]};
103
104%% ACR with decode errors.
105handle_request(#diameter_packet{msg = ['ACR' | #{} = Request]},
106               _SvcName,
107               {_, Caps}) ->
108    #diameter_caps{origin_host = {OH,_},
109                   origin_realm = {OR,_}}
110        = Caps,
111
112    Answer = maps:merge(maps:with(['Session-Id'], Request),
113                        #{'Origin-Host' => OH,
114                          'Origin-Realm' => OR}),
115
116    %% Let diameter set Result-Code and Failed-AVP if there were
117    %% decode errors.
118    {reply, ['answer-message' | Answer]};
119
120%% Answer anything else as unsupported.
121handle_request(#diameter_packet{}, _SvcName, _) ->
122    {answer_message, 3001}.  %% DIAMETER_COMMAND_UNSUPPORTED
123