Provided by: erlang-manpages_25.3.2.8+dfsg-1ubuntu4.4_all bug

NAME

       diameter_app - Callback module of a Diameter application.

DESCRIPTION

       A  diameter  service as started by diameter:start_service/2 configures one of more Diameter applications,
       each of whose configuration specifies a callback that handles messages specific to the  application.  The
       messages  and  AVPs  of  the  application  are defined in a dictionary file whose format is documented in
       diameter_dict(5) while the callback module  is  documented  here.  The  callback  module  implements  the
       Diameter application-specific functionality of a service.

       A  callback  module  must  export  all of the functions documented below. The functions themselves are of
       three distinct flavours:

         * peer_up/3 and peer_down/3 signal the attainment or loss of connectivity with a Diameter peer.

         * pick_peer/4, prepare_request/3, prepare_retransmit/3, handle_answer/4 and handle_error/4 are (or  may
           be)  called  as  a  consequence  of  a  call  to diameter:call/4 to send an outgoing Diameter request
           message.

         * handle_request/3 is called in response to an incoming Diameter request message.

       The arities for the the callback functions here assume no extra arguments. All  functions  will  also  be
       passed    any   extra   arguments   configured   with   the   callback   module   itself   when   calling
       diameter:start_service/2  and,  for  the  call-specific  callbacks,  any  extra   arguments   passed   to
       diameter:call/4.

DATA TYPES

         capabilities() = #diameter_caps{}:
           A  record containing the identities of the local Diameter node and the remote Diameter peer having an
           established transport connection, as well as the capabilities as determined by capabilities exchange.
           Each field of the record is a 2-tuple consisting of values for the (local) host  and  (remote)  peer.
           Optional  or  possibly  multiple  values are encoded as lists of values, mandatory values as the bare
           value.

         message() = diameter_codec:message():
           The  representation  of  a  Diameter  message  as  passed  to  diameter:call/4  or  returned  from  a
           handle_request/3 callback.

         packet() = diameter_codec:packet():
           A  container  for  incoming  and  outgoing  Diameter messages that's passed through encode/decode and
           transport. Fields should not be set in return values except as documented.

         peer_ref() = term():
           A term identifying a transport connection with a Diameter peer.

         peer() = {peer_ref(), capabilities()}:
           A tuple representing a Diameter peer connection.

         state() = term():
           The state maintained by the application callback functions peer_up/3,  peer_down/3  and  (optionally)
           pick_peer/4.  The initial state is configured in the call to diameter:start_service/2 that configures
           the application on a service. Callback functions returning a state are evaluated in a common service-
           specific process while those not returning state are evaluated in a request-specific process.

EXPORTS

       Mod:peer_up(SvcName, Peer, State) -> NewState

              Types:

                 SvcName = diameter:service_name()
                 Peer = peer()
                 State = NewState = state()

              Invoked to signal the availability of a peer connection on the local Erlang node.  In  particular,
              capabilities exchange with the peer has indicated support for the application in question, the RFC
              3539 watchdog state machine for the connection has reached state OKAY and Diameter messages can be
              both sent and received.

          Note:
              A  watchdog  state  machine  can  reach  state  OKAY from state SUSPECT without a new capabilities
              exchange taking place. A new transport connection (and capabilities exchange)  results  in  a  new
              peer_ref().

          Note:
              There   is  no  requirement  that  a  callback  return  before  incoming  requests  are  received:
              handle_request/3 callbacks must be handled independently of peer_up/3 and peer_down/3.

       Mod:peer_down(SvcName, Peer, State) -> NewState

              Types:

                 SvcName = diameter:service_name()
                 Peer = peer()
                 State = NewState = state()

              Invoked to signal that a peer connection on the local Erlang node is no longer available following
              a previous call to peer_up/3. In particular, that the RFC 3539  watchdog  state  machine  for  the
              connection  has  left  state  OKAY  and  the  peer  will  no  longer be a candidate in pick_peer/4
              callbacks.

       Mod:pick_peer(LocalCandidates, RemoteCandidates, SvcName, State) -> Selection | false

              Types:

                 LocalCandidates = RemoteCandidates = [peer()]
                 SvcName = diameter:service_name()
                 State = NewState = state()
                 Selection = {ok, Peer} | {Peer, NewState}
                 Peer = peer() | false

              Invoked as a consequence of a call to diameter:call/4 to select a destination peer for an outgoing
              request. The return value indicates the selected peer.

              The candidate lists contain only those  peers  that  have  advertised  support  for  the  Diameter
              application in question during capabilities exchange, that have not be excluded by a filter option
              in the call to diameter:call/4 and whose watchdog state machine is in the OKAY state. The order of
              the  elements is unspecified except that any peers whose Origin-Host and Origin-Realm matches that
              of  the  outgoing  request  (in  the  sense  of  a  {filter,  {all,  [host,  realm]}}  option   to
              diameter:call/4)  will  be  placed  at  the head of the list. LocalCandidates contains peers whose
              transport process resides on the local Erlang node while RemoteCandidates contains peers that have
              been communicated from other nodes by services of the same name.

              A callback that returns a peer() will be followed by a  prepare_request/3  callback  and,  if  the
              latter  indicates  that  the  request  should be sent, by either handle_answer/4 or handle_error/4
              depending on whether or not an answer message is received from the peer. If the transport  becomes
              unavailable  after prepare_request/3 then a new pick_peer/4 callback may take place to failover to
              an alternate peer, after which  prepare_retransmit/3  takes  the  place  of  prepare_request/3  in
              resending  the  request.  There is no guarantee that a pick_peer/4 callback to select an alternate
              peer will be followed by any additional callbacks since a retransmission to an alternate  peer  is
              abandoned if an answer is received from a previously selected peer.

              The return values false and {false, State} (that is, NewState = State) are equivalent, as are {ok,
              Peer} and {Peer, State}.

          Note:
              The  diameter:service_opt() use_shared_peers determines whether or not a service uses peers shared
              from other nodes. If not then RemoteCandidates is the empty list.

          Warning:
              The return value {Peer, NewState} is only allowed if the  Diameter  application  in  question  was
              configured  with  the  diameter:application_opt() {call_mutates_state, true}. Otherwise, the State
              argument is always the initial value as configured on the application, not  any  subsequent  value
              returned by a peer_up/3 or peer_down/3 callback.

       Mod:prepare_request(Packet, SvcName, Peer) -> Action

              Types:

                 Packet = packet()
                 SvcName = diameter:service_name()
                 Peer = peer()
                 Action = Send | Discard | {eval_packet, Action, PostF}
                 Send = {send, packet() | message()}
                 Discard = {discard, Reason} | discard
                 PostF = diameter:eval()}

              Invoked  to  return  a  request  for encoding and transport. Allows the sender to use the selected
              peer's capabilities to modify the outgoing request. Many implementations may simply want to return
              {send, Packet}

              A returned packet() should set the request to be  encoded  in  its  msg  field  and  can  set  the
              transport_data field in order to pass information to the transport process. Extra arguments passed
              to diameter:call/4 can be used to communicate transport (or any other) data to the callback.

              A returned packet() can set the header field to a #diameter_header{} to specify values that should
              be  preserved in the outgoing request, values otherwise being those in the header record contained
              in Packet. A returned length, cmd_code or application_id is ignored.

              A returned PostF will be evaluated on any encoded #diameter_packet{} prior  to  transmission,  the
              bin field containing the encoded binary. The return value is ignored.

              Returning {discard, Reason} causes the request to be aborted and the diameter:call/4 for which the
              callback  has  taken place to return {error, Reason}. Returning discard is equivalent to returning
              {discard, discarded}.

       Mod:prepare_retransmit(Packet, SvcName, Peer) -> Action

              Types:

                 Packet = packet()
                 SvcName = diameter:service_name()
                 Peer = peer()
                 Action = Send | Discard | {eval_packet, Action, PostF}
                 Send = {send, packet() | message()}
                 Discard = {discard, Reason} | discard
                 PostF = diameter:eval()}

              Invoked  to  return  a  request  for  encoding  and  retransmission.  Has   the   same   role   as
              prepare_request/3 in the case that a peer connection is lost an an alternate peer selected but the
              argument packet() is as returned by the initial prepare_request/3.

              Returning {discard, Reason} causes the request to be aborted and a handle_error/4 callback to take
              place  with  Reason  as  initial  argument. Returning discard is equivalent to returning {discard,
              discarded}.

       Mod:handle_answer(Packet, Request, SvcName, Peer) -> Result

              Types:

                 Packet = packet()
                 Request = message()
                 SvcName = diameter:service_name()
                 Peer = peer()
                 Result = term()

              Invoked when an answer message is received  from  a  peer.  The  return  value  is  returned  from
              diameter:call/4 unless the detach option was specified.

              The  decoded  answer  record  and  undecoded  binary are in the msg and bin fields of the argument
              packet()  respectively.  Request  is  the  outgoing  request  message   as   was   returned   from
              prepare_request/3 or prepare_retransmit/3.

              For any given call to diameter:call/4 there is at most one handle_answer/4 callback: any duplicate
              answer  (due  to retransmission or otherwise) is discarded. Similarly, only one of handle_answer/4
              or handle_error/4 is called.

              By default, an incoming answer message that cannot be  successfully  decoded  causes  the  request
              process  to  fail, causing diameter:call/4 to return {error, failure} unless the detach option was
              specified.  In  particular,  there   is   no   handle_error/4   callback   in   this   case.   The
              diameter:application_opt() answer_errors can be set to change this behaviour.

       Mod:handle_error(Reason, Request, SvcName, Peer) -> Result

              Types:

                 Reason = timeout | failover | term()
                 Request = message()
                 SvcName = diameter:service_name()
                 Peer = peer()
                 Result = term()

              Invoked  when  an  error  occurs  before  an answer message is received in response to an outgoing
              request. The return value is returned from diameter:call/4 unless the detach option was specified.

              Reason timeout indicates that an answer message has not been received within  the  time  specified
              with   the  corresponding  diameter:call_opt().  Reason  failover  indicates  that  the  transport
              connection to the peer to which the request has been sent has  become  unavailable  and  that  not
              alternate peer was not selected.

       Mod:handle_request(Packet, SvcName, Peer) -> Action

              Types:

                 Packet = packet()
                 SvcName = term()
                 Peer = peer()
                 Action = Reply | {relay, [Opt]} | discard | {eval|eval_packet, Action, PostF}
                 Reply   =   {reply,   packet()   |   message()}  |  {answer_message,  3000..3999|5000..5999}  |
                 {protocol_error, 3000..3999}
                 Opt = diameter:call_opt()
                 PostF = diameter:eval()

              Invoked when a request message is received from a peer. The  application  in  which  the  callback
              takes  place  (that  is,  the  callback  module  as  configured  with diameter:start_service/2) is
              determined by the Application Identifier in the  header  of  the  incoming  request  message,  the
              selected  module  being  the one whose corresponding dictionary declares itself as defining either
              the application in question or the Relay application.

              The argument packet() has the following signature.

              #diameter_packet{header = #diameter_header{},
                               avps   = [#diameter_avp{}],
                               msg    = record() | undefined,
                               errors = [Unsigned32() | {Unsigned32(), #diameter_avp{}}],
                               bin    = binary(),
                               transport_data = term()}

              The msg field will be undefined in case the request has been received in  the  relay  application.
              Otherwise it contains the record representing the request as outlined in diameter_dict(5).

              The  errors field specifies any results codes identifying errors found while decoding the request.
              This is used to set Result-Code and/or Failed-AVP in a returned answer unless the callback returns
              a #diameter_packet{} whose errors field is set to either a non-empty list of  its  own,  in  which
              case  this  list  is  used  instead,  or  the atom false to disable any setting of Result-Code and
              Failed-AVP. Note that the errors detected by diameter are of the 3xxx and  5xxx  series,  Protocol
              Errors  and  Permanent  Failures  respectively.  The  errors list is empty if the request has been
              received in the relay application.

              The transport_data field contains an arbitrary term passed into diameter from the transport module
              in question, or the atom undefined if the transport specified no data. The term is preserved if  a
              message() is returned but must be set explicitly in a returned packet().

              The semantics of each of the possible return values are as follows.

                {reply, packet() | message()}:
                  Send  the  specified  answer message to the peer. In the case of a packet(), the message to be
                  sent must be set in the msg field and the header field can be set to a  #diameter_header{}  to
                  specify  values  that should be preserved in the outgoing answer, appropriate values otherwise
                  being set by diameter.

                {answer_message, 3000..3999|5000..5999}:
                  Send an answer message to the peer containing the specified Result-Code. Equivalent to

                {reply, ['answer-message' | Avps]

                  where Avps sets the Origin-Host, Origin-Realm, the specified Result-Code and (if  the  request
                  contained one) Session-Id AVPs, and possibly Failed-AVP as described below.

                  Returning  a value other than 3xxx or 5xxx will cause the request process in question to fail,
                  as will returning a 5xxx value if the peer connection in question has been configured with the
                  RFC 3588 common dictionary diameter_gen_base_rfc3588. (Since RFC 3588 only allows 3xxx  values
                  in an answer-message.)

                  When  returning  5xxx, Failed-AVP will be populated with the AVP of the first matching Result-
                  Code/AVP pair in the errors field  of  the  argument  packet(),  if  found.  If  this  is  not
                  appropriate  then  an  answer-message should be constructed explicitly and returned in a reply
                  tuple instead.

                {relay, Opts}:
                  Relay a request to another peer in the role of a Diameter relay agent. If a  routing  loop  is
                  detected  then  the request is answered with 3005 (DIAMETER_LOOP_DETECTED). Otherwise a Route-
                  Record AVP (containing the sending peer's Origin-Host) is added to the request and pick_peer/4
                  and subsequent callbacks take place just as if diameter:call/4 had been called explicitly. The
                  End-to-End Identifier of the incoming request is  preserved  in  the  header  of  the  relayed
                  request.

                  The  returned  Opts  should  not specify detach. A subsequent handle_answer/4 callback for the
                  relayed request must return its first argument, the packet() containing  the  answer  message.
                  Note that the extra option can be specified to supply arguments that can distinguish the relay
                  case  from  others  if  so desired. Any other return value (for example, from a handle_error/4
                  callback) causes the request to be answered with 3002 (DIAMETER_UNABLE_TO_DELIVER).

                discard:
                  Discard the request. No answer message is sent to the peer.

                {eval, Action, PostF}:
                  Handle the request as if Action has been returned and  then  evaluate  PostF  in  the  request
                  process. The return value is ignored.

                {eval_packet, Action, PostF}:
                  Like  eval but evaluate PostF on any encoded #diameter_packet{} prior to transmission, the bin
                  field containing the encoded binary. The return value is ignored.

                {protocol_error, 3000..3999}:
                  Equivalent to {answer_message, 3000..3999}.

          Note:
              Requests containing errors may be answered by diameter, without a callback taking place, depending
              on the value of the diameter:application_opt() request_errors.

Ericsson AB                                      diameter 2.2.7                               diameter_app(3erl)