diff options
author | Anders Svensson <[email protected]> | 2011-05-18 18:58:01 +0200 |
---|---|---|
committer | Anders Svensson <[email protected]> | 2011-05-18 18:58:01 +0200 |
commit | 1756ed583f24ba2206a0f573635a6fa3cdea5c54 (patch) | |
tree | c762a6e700f09fb580f8c9945fd6886ecc2c9923 /lib/diameter/doc/src/diameter.xml | |
parent | e993da4426a76bb172290a10999267d3023120d5 (diff) | |
parent | 3c15ff32e89e401b4dde2b8acc9699be2614b996 (diff) | |
download | otp-1756ed583f24ba2206a0f573635a6fa3cdea5c54.tar.gz otp-1756ed583f24ba2206a0f573635a6fa3cdea5c54.tar.bz2 otp-1756ed583f24ba2206a0f573635a6fa3cdea5c54.zip |
Merge branch 'anders/diameter_import/OTP-9321' into dev
* anders/diameter_import/OTP-9321:
Initial commit of the diameter application.
Diffstat (limited to 'lib/diameter/doc/src/diameter.xml')
-rw-r--r-- | lib/diameter/doc/src/diameter.xml | 1123 |
1 files changed, 1123 insertions, 0 deletions
diff --git a/lib/diameter/doc/src/diameter.xml b/lib/diameter/doc/src/diameter.xml new file mode 100644 index 0000000000..9774183a2a --- /dev/null +++ b/lib/diameter/doc/src/diameter.xml @@ -0,0 +1,1123 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> +<header> + +<copyright> +<year>2011</year> +<holder>Ericsson AB. All Rights Reserved.</holder> +</copyright> +<legalnotice> +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. + +</legalnotice> + +<title>diameter(3)</title> + +<prepared>Anders Svensson</prepared> +<responsible></responsible> +<docno></docno> +<approved></approved> +<checked></checked> +<date></date> +<rev>%VSN%</rev> +<file>diameter.xml</file> + +</header> + +<!-- ===================================================================== --> +<!-- ===================================================================== --> + +<module>diameter</module> +<modulesummary>Main API of the diameter application.</modulesummary> + +<description> +<p> +This module provides the interface with which a user +creates a service that sends and receives messages using the +Diameter protocol as defined in RFC 3588.</p> + +<p> +Basic usage consists of creating a representation of a +locally implemented Diameter peer and its capabilities with <seealso +marker="#start_service">start_service/2</seealso>, adding transport +capability using <seealso +marker="#add_transport">add_transport/2</seealso> and sending Diameter +requests and receiving Diameter answers with <seealso +marker="#call">call/4</seealso>. +Incoming Diameter requests are communicated as callbacks to a +<seealso +marker="diameter_app">diameter_app(3)</seealso> callback modules as +specified in the service configuration.</p> + +<p> +Beware the difference between <em>diameter application</em> and +<em>Diameter application</em>. +The former refers to the Erlang application named diameter whose main +api is defined here, the latter to an application of the Diameter +protocol in the sense of RFC 3588. +More generally, capitalized Diameter refers to the RFC +and diameter to this implementation.</p> + +<p> +The diameter application must be started before calling functions in +this module.</p> + +</description> + +<!-- ===================================================================== --> +<!-- ===================================================================== --> +<section> +<title>DATA TYPES</title> + +<taglist> + +<tag><c>Address()</c></tag> +<tag><c>DiameterIdentity()</c></tag> +<tag><c>Time()</c></tag> +<tag><c>Unsigned32()</c></tag> +<tag><c>UTF8String()</c></tag> +<item> +<p> +Types corresponding to RFC 3588 AVP Data Formats. +Defined in <seealso marker="diameter_dict">diameter_dict(4)</seealso>.</p> + +<marker id="application_alias"/> +</item> + +<tag><c>application_alias() = term()</c></tag> +<item> +<p> +A name identifying a Diameter application in +service configuration passed to <seealso +marker="#start_service">start_service/2</seealso> and passed to +<seealso marker="#call">call/4</seealso> when sending requests +belonging to the application.</p> + +<marker id="application_module"/> +</item> + +<tag><c>application_module() = Mod | [Mod | ExtraArgs]</c></tag> +<item> +<code> +Mod = atom() +ExtraArgs = list() +</code> + +<p> +A module implementing the callback interface defined in <seealso +marker="diameter_app">diameter_app(3)</seealso>, along with any +extra arguments to be appended to those documented for the interface. +Any extra arguments are appended to the documented list of arguments for +each function. +Note that additional arguments specific to an outgoing request be +specified to <seealso marker="#call">call/4</seealso>, in which case +the call-specific arguments are appended to any specified with the +callback module.</p> + +<marker id="application_opt"/> +</item> + +<tag><c>application_opt()</c></tag> +<item> + +<p> +Options defining a Diameter application as configured in an +<c>application</c> option passed to +<seealso marker="#start_service">start_service/2</seealso>.</p> + +<taglist> + +<tag><c>{alias, application_alias()}</c></tag> +<item> +<p> +An unique identifier for the application in the scope of the +service. +Optional, defaults to the value of the <c>dictionary</c> option.</p> +</item> + +<tag><c>{dictionary, atom()}</c></tag> +<item> +<p> +The name of an encode/decode module for the Diameter +messages defined by the application. +These modules are generated from a specification file whose format is +documented in <seealso +marker="diameter_dict">diameter_dict(4)</seealso>.</p> +</item> + +<tag><c>{module, application_module()}</c></tag> +<item> +<p> +A callback module with which messages of the Diameter application are +handled. +See <seealso marker="diameter_app">diameter_app(3)</seealso> for +information on the required interface and semantics.</p> +</item> + +<tag><c>{state, term()}</c></tag> +<item> +<p> +The initial callback state. +Defaults to the value of the <c>alias</c> option if unspecified. +The prevailing state is passed to certain +<seealso marker="diameter_app">diameter_app(3)</seealso> +callbacks, which can then return a new state.</p> +</item> + +<tag><c>{call_mutates_state, true|false}</c></tag> +<item> +<p> +Specifies whether or not the <seealso +marker="diameter_app#pick_peer">pick_peer/4</seealso> +application callback (following from a call to +<seealso marker="#call">call/4</seealso>) +can modifiy state, +Defaults to <c>false</c> if unspecified.</p> + +<p> +Note that <seealso +marker="diameter_app#pick_peer">pick_peer</seealso> callbacks are +serialized when these are allowed to modify state, which is a +potential performance bottleneck. +A simple Diameter client may suffer no ill effects from using mutable +state but a server or agent that responds to incoming request but +sending its own requests should probably avoid it.</p> +</item> + +<tag><c>{answer_errors, callback|report|discard}</c></tag> +<item> +<p> +Determines the manner in which incoming answer messages containing +decode errors are handled. +If <c>callback</c> then errors result in a <seealso +marker="diameter_app#handle_answer">handle_answer/4</seealso> +callback in the same fashion as for <seealso +marker="diameter_app#handle_request">handle_request/3</seealso>, in the +<c>errors</c> field of the <c>diameter_packet</c> record passed into +the callback. +If <c>report</c> then an answer containing errors is discarded +without a callback and a warning report is written to the log. +If <c>discard</c> then an answer containing errors is silently +discarded without a callback. +In both the <c>report</c> and <c>discard</c> cases the return value +for the <seealso marker="#call">call/4</seealso> invocation in +question is as if a callback had taken place and returned +<c>{error, failure}</c>.</p> + +<p> +Defaults to <c>report</c> if unspecified.</p> +</item> + +</taglist> + +<marker id="call_opt"/> +</item> + +<tag><c>call_opt()</c></tag> +<item> + +<p> +Options available to <seealso marker="#call">call/4</seealso> when +sending an outgoing Diameter request.</p> + +<taglist> + +<tag><c>{extra, list()}</c></tag> +<item> +<p> +Extra arguments to append to callbacks to the callback +module in question. +These are appended to any extra arguments configured with the callback +itself. +Multiple options append to the argument list.</p> +</item> + +<tag><c>{filter, peer_filter()}</c></tag> +<item> +<p> +A filter to apply to the list of available peers before passing them to +the <seealso marker="diameter_app#pick_peer">pick_peer/4</seealso> +callback for the application in question. +Multiple options are equivalent a single <c>all</c> filter on the +corresponding list of filters. +Defaults to <c>none</c>.</p> +</item> + +<tag><c>{timeout, Unsigned32()}</c></tag> +<item> +<p> +The number of milliseconds after which the request should +timeout. +Defaults to 5000.</p> +</item> + +<tag><c>detach</c></tag> +<item> +<p> +Causes <seealso marker="#call">call/4</seealso> to return <c>ok</c> as +soon as the request in +question has been encoded instead of waiting for and returning +the result from a subsequent +<seealso marker="diameter_app#handle_answer">handle_answer/4</seealso> +or <seealso +marker="diameter_app#handle_error">handle_error/4</seealso> +callback.</p> +</item> + +</taglist> + +<marker id="capability"/> +</item> + +<tag><c>capability()</c></tag> +<item> + +<p> +AVP values used in outgoing CER/CEA messages during capabilities exchange. +Can be configured both on a service and a transport, the latter taking +precedence over the former.</p> + +<taglist> + +<tag><c>{'Origin-Host', DiameterIdentity()}</c></tag> +<item> +<p> +Value of the Origin-Host AVP in outgoing messages.</p> +</item> + +<tag><c>{'Origin-Realm', DiameterIdentity()}</c></tag> +<item> +<p> +Value of the Origin-Realm AVP in outgoing messages.</p> +</item> + +<tag><c>{'Host-IP-Address', [Address()]}</c></tag> +<item> +<p> +Values of Host-IP-Address AVPs. +Optional.</p> + +<p> +The list of addresses is available to the start function of a +transport module, which either uses them as is or returns a new list +(typically as configured as <c>transport_config()</c> on the +transport module in question) in order for the correct list of +addresses to be sent in capabilities exchange messages.</p> +</item> + +<tag><c>{'Vendor-Id', Unsigned32()}</c></tag> +<item> +<p> +Value of the Vendor-Id AVP sent in an outgoing capabilities +exchange message.</p> +</item> + +<tag><c>{'Product-Name', UTF8String()}</c></tag> +<item> +<p> +Value of the Product-Name AVP sent in an outgoing capabilities +exchange message.</p> +</item> + +<tag><c>{'Origin-State-Id', Unsigned32()}</c></tag> +<item> +<p> +Value of Origin-State-Id to be included in outgoing messages sent by +diameter itself. +In particular, the AVP will be included in CER/CEA and DWR/DWA messages. +Optional.</p> + +<p> +Setting a value of <c>0</c> (zero) is equivalent to not setting a +value as documented in RFC 3588. +The function <seealso +marker="#origin_state_id">origin_state_id/0</seealso> +can be used as to retrieve a value that is set when the diameter +application is started.</p> +</item> + +<tag><c>{'Supported-Vendor-Id', [Unsigned32()]}</c></tag> +<item> +<p> +Values of Supported-Vendor-Id AVPs sent in an outgoing +capabilities exchange message. +Optional, defaults to the empty list.</p> +</item> + +<tag><c>{'Auth-Application-Id', [Unsigned32()]}</c></tag> +<item> +<p> +Values of Auth-Application-Id AVPs sent in an outgoing +capabilities exchange message. +Optional, defaults to the empty list.</p> +</item> + +<tag><c>{'Acct-Application-Id', [Unsigned32()]}</c></tag> +<item> +<p> +Values of Acct-Application-Id AVPs sent in an outgoing +capabilities exchange message. +Optional, defaults to the empty list.</p> +</item> + +<tag><c>{'Vendor-Specific-Application-Id', [Grouped()]}</c></tag> +<item> +<p> +Values of Vendor-Specific-Application-Id AVPs sent in +an outgoing capabilities exchange message. +Optional, defaults to the empty list.</p> +</item> + +<tag><c>{'Firmware-Revision', Unsigned32()}</c></tag> +<item> +<p> +Value of the Firmware-Revision AVP sent in an outgoing capabilities +exchange message. +Optional.</p> +</item> + +</taglist> + +<p> +Note that each tuple communicates one or more AVP values. +It is an error to specify duplicate tuples.</p> + +<marker id="evaluable"/> +</item> + +<tag><c>evaluable() = {M,F,A} | fun() | [evaluable() | A]</c></tag> +<item> +<p> +An expression that can be evaluated as a function in the following +sense.</p> + +<code> +eval([{M,F,A} | T]) -> + apply(M, F, T ++ A); +eval([F|A]) -> + apply(F, A); +eval(F) -> + eval([F]). +</code> + +<p> +Evaluating an evaluable() <c>E</c> on an argument list <c>A</c> +is meant in the sense of <c>eval([E|A])</c>.</p> + +<marker id="peer_filter"/> +</item> + +<tag><c>peer_filter() = term()</c></tag> +<item> +<p> +A filter passed to <seealso marker="#call">call/4</seealso> +in order to select candidate peers for a +<seealso marker="diameter_app#pick_peer">pick_peer/4</seealso> +callback. +Has one of the following types.</p> + +<taglist> + +<tag><c>none</c></tag> +<item> +<p> +Matches any peer. +This is a convenience that provides a filter equivalent to no +filter at all.</p> +</item> + +<tag><c>host</c></tag> +<item> +<p> +Matches only those peers whose <c>Origin-Host</c> has the same value +as <c>Destination-Host</c> in the outgoing request in question, +or any peer if the request does not contain +a <c>Destination-Host</c> AVP.</p> +</item> + +<tag><c>realm</c></tag> +<item> +<p> +Matches only those peers whose <c>Origin-Realm</c> has the same value +as <c>Destination-Realm</c> in the outgoing request in question, +or any peer if the request does not contain +a <c>Destination-Realm</c> AVP.</p> +</item> + +<tag><c>{host, any|UTF8String()}</c></tag> +<item> +<p> +Matches only those peers whose <c>Origin-Host</c> has the +specified value, or all peers if the atom <c>any</c>.</p> +</item> + +<tag><c>{realm, any|UTF8String()</c></tag> +<item> +<p> +Matches only those peers whose <c>Origin-Realm</c> has the +value, or all peers if the atom <c>any</c>.</p> +</item> + +<tag><c>{eval, evaluable()}</c></tag> +<item> +<p> +Matches only those peers for which the specified evaluable() evaluates +to true on the peer's <c>diameter_caps</c> record.</p> +</item> + +<tag><c>{neg, peer_filter()}</c></tag> +<item> +<p> +Matches only those peers not matched by the specified filter.</p> +</item> + +<tag><c>{all, [peer_filter()]}</c></tag> +<item> +<p> +Matches only those peers matched by each filter of the specified list.</p> +</item> + +<tag><c>{any, [peer_filter()]}</c></tag> +<item> +<p> +Matches only those peers matched by at least one filter of the +specified list.</p> +</item> + +</taglist> + +<marker id="service_event"/> +</item> + +<tag><c>service_event() = #diameter_event{}</c></tag> +<item> +<p> +Event message sent to processes that have subscribed using <seealso +marker="#subscribe">subscribe/1</seealso>.</p> + +<p> +The <c>info</c> field of the event record can be one of the +following.</p> + +<taglist> + +<tag><c>{up, Ref, Peer, Config, Pkt}</c></tag> +<tag><c>{up, Ref, Peer, Config}</c></tag> +<tag><c>{down, Ref, Peer, Config}</c></tag> +<item> +<code> +Ref = transport_ref() +Peer = diameter_app:peer() +Config = {connect|listen, [transport_opt()]} +Pkt = #diameter_packet{} +</code> + +<p> +Reports that the RFC 3539 watchdog state machine has +transitioned into (<c>up</c>) or out of (<c>down</c>) the open +state. +If a <c>diameter_packet</c> record is present in an <c>up</c> tuple +then there has been an exchange of capabilities exchange messages and +the record contains the received CER or CEA, otherwise the +connection has reestablished without the loss or transport +connectivity.</p> + +<p> +Note that a single up/down event for a given peer corresponds to +as many peer_up/down callbacks as there are Diameter +applications shared by the peer, as determined during capablilities +exchange. +That is, the event communicates connectivity with the +peer as a whole while the callbacks communicate connectivity with +respect to individual Diameter applications.</p> +</item> + +<tag><c>{reconnect, Ref, Opts}</c></tag> +<item> +<code> +Ref = transport_ref() +Opts = [transport_opt()] +</code> + +<p> +A connecting transport is attempting to establish/reestablish a +transport connection with a peer following <c>reconnect_timer</c> or +<c>watchdog_timer</c> expiry.</p> +</item> + +</taglist> + +<p> +For forward compatibility, a subscriber should be prepared to receive +<c>diameter_event.info</c> of forms other than those documented +above.</p> + +<marker id="service_name"/> +</item> + +<tag><c>service_name() = term()</c></tag> +<item> +<p> +The name of a service as passed to <seealso +marker="#start_service">start_service/2</seealso> and with which the +service is identified. +There can be at most one service with a given name on a given node. +Note that <c>erlang:make_ref/0</c> can be used to generate a service name +that is somewhat unique.</p> + +<marker id="service_opt"/> +</item> + +<tag><c>service_opt()</c></tag> +<item> +<p> +Options accepted by <seealso +marker="#start_service">start_service/2</seealso>. +Can be any <c>capability()</c> tuple as +well as the following.</p> + +<taglist> + +<tag><c>{application, [application_opt()]}</c></tag> +<item> +<p> +Defines a Diameter application supported by the service.</p> + +<p> +A service must define one application for each Diameter application it +intends to support. +For an outgoing Diameter request, the application is specified by +passing the desired application's <c>application_alias()</c> to +<seealso marker="#call">call/4</seealso>, while for an +incoming request the application identifier in the message +header determines the application (and callback module), the +application identifier being specified in the <seealso +marker="diameter_dict">dictionary</seealso> file defining the +application.</p> +</item> + +</taglist> + +<marker id="transport_opt"/> +</item> + +<tag><c>transport_opt()</c></tag> +<item> +<p> +Options accepted by <seealso +marker="#add_transport">add_transport/2</seealso>.</p> + +<taglist> +<tag><c>{transport_module, atom()}</c></tag> +<item> +<p> +A module implementing a transport process as defined in <seealso +marker="diameter_transport">diameter_transport(3)</seealso>. +Defaults to <c>diameter_tcp</c> if unspecified.</p> + +<p> +The interface required of a transport module is documented in <seealso +marker="diameter_transport">diameter_transport(3)</seealso>.</p> +</item> + +<tag><c>{transport_config, term()}</c></tag> +<item> +<p> +A term passed as the third argument to the <seealso +marker="diameter_transport#start">start/3</seealso> function of +the relevant <c>transport_module</c> in order to start a transport process. +Defaults to the empty list if unspecified.</p> +</item> + +<tag><c>{applications, [application_alias()]}</c></tag> +<item> +<p> +The list of Diameter applications to which usage of the transport +should be restricted. +Defaults to all applications configured on the service +in question.</p> +</item> + +<tag><c>{capabilities, [capability()]}</c></tag> +<item> +<p> +AVP's used to construct outgoing CER/CEA messages. +Any AVP specified takes precedence over a corresponding value specified +for the service in question.</p> +</item> + +<tag><c>{watchdog_timer, TwInit}</c></tag> +<item> +<code> +TwInit = Unsigned32() + | {M,F,A} +</code> + +<p> +The RFC 3539 watchdog timer. +An integer value is interpreted as the RFC's TwInit in milliseconds, +a jitter of ± 2 seconds being added at each rearming of the +timer to compute the RFC's Tw. +An MFA is expected to return the RFC's Tw directly, with jitter +applied, allowing the jitter calculation to be performed by +the callback.</p> + +<p> +An integer value must be at least 6000 as required by RFC 3539. +Defaults to 30000 if unspecified.</p> +</item> + +<tag><c>{reconnect_timer, Tc}</c></tag> +<item> +<code> +Tc = Unsigned32() +</code> + +<p> +For a connecting transport, the RFC 3588 Tc timer, in milliseconds. +Note that this timer determines the frequency with which the transport +will attempt to establish a connection with its peer only <em>before</em> +an initial connection is established: once there is an initial +connection it's watchdog_timer that determines the frequency of +reconnection attempts, as required by RFC 3539.</p> + +<p> +For a listening transport, the timer specifies the time after which a +previously connected peer will be forgotten: a connection after this time is +regarded as an initial connection rather than a reestablishment, +causing the RFC 3539 state machine to pass to state OPEN rather than +REOPEN. +Note that these semantics are not goverened by the RFC and +that a listening transport's reconnect_timer should be greater than its +peers's Tc plus jitter.</p> + +<p> +Defaults to 30000 for a connecting transport and 60000 for a listening +transport.</p> +</item> + +</taglist> + +<p> +Unrecognized options are silently ignored but are returned unmodified +by <seealso +marker="#service_info_1">service_info/1,2</seealso> and can be referred to +in predicate functions passed to <seealso +marker="#remove_transport">remove_transport/2</seealso>.</p> + +</item> + +</taglist> + +</section> + +<marker id="add_transport"/> +<funcs> + +<!-- ===================================================================== --> + +<func> +<name>add_transport(SvcName, {connect|listen, Options}) + -> {ok, Ref} | {error, Reason}</name> +<fsummary>Add transport capability to a service.</fsummary> +<type> +<v>SvcName = service_name()</v> +<v>Options = [transport_opt()]</v> +<v>Ref = ref()</v> +<v>Reason = term()</v> +</type> +<desc> +<p> +Add transport capability to a service. +The service will start a transport process(es) in order to establish a +connection with the peer, either by connecting to the peer +(<c>connect</c>) or by accepting incoming connection requests +(<c>listen</c>). +A connecting transport establishes transport connections with at most +one peer, an listening transport potentially with many.</p> + +<p> +The diameter application takes responsibility for exchanging +CER/CEA with the peer. +Upon successful completion of capabilities exchange the service +calls each relevant application module's <seealso +marker="diameter_app#peer_up">peer_up/3</seealso> callback +after which the caller can exchange Diameter messages with the peer over +the transport. +In addition to CER/CEA, the service takes responsibility for the +handling of DWR/DWA and required by RFC 3539 as well as for DPR/DPA.</p> + +<p> +The returned reference uniquely identifies the transport within the +scope of the service. +Not that the function returns before a transport connection has been +established.</p> + +<p> +It is not an error to add a transport to a service that has not yet +been configured: a service can be started after configuring +transports.</p> + +<marker id="call"/> +</desc> +</func> + +<!-- ===================================================================== --> + +<func> +<name>call(SvcName, App, Request, Options) -> Answer | {error, Reason}</name> +<fsummary>Send a Diameter request message.</fsummary> +<type> +<v>SvcName = service_name()</v> +<v>App = application_alias()</v> +<v>Request = diameter_app:message()</v> +<v>Answer = term()</v> +<v>Options = [call_opt()]</v> +</type> +<desc> +<p> +Send a Diameter request message and possibly return the answer or error.</p> + +<p> +<c>App</c> identifies the Diameter application in which the request is +defined and callbacks to the corresponding callback module +will follow as described below and in <seealso +marker="diameter_app">diameter_app(3)</seealso>. +The call returns either when an answer message is received from the +peer or an error occurs, unless the <c>detach</c> option has been +specified. +If <c>detach</c> is not specified then the form of an <c>Answer</c> is +as returned from a <seealso +marker="diameter_app#handle_answer">handle_answer/4</seealso> or +<seealso +marker="diameter_app#handle_error">handle_error/4</seealso> +callback.</p> + +<p> +If there are no suitable peers, or if +<seealso marker="diameter_app#pick_peer">pick_peer/4</seealso> +rejects them by returning 'false', then <c>{error, no_connection}</c> +is returned. +If <seealso marker="diameter_app#pick_peer">pick_peer/4</seealso> +selects a candidate peer then a request process is spawned for the +outgoing request, in which there is a +<seealso +marker="diameter_app#prepare_request">prepare_request/3</seealso> +callback, the message is encoded and sent.</p> + +<p> +There are several error cases which may prevent an +answer from being received and passed to a +<seealso marker="diameter_app#handle_answer">handle_answer/4</seealso> +callback:</p> + +<list> + +<item> +<p> +If the initial encode of the outgoing request +fails, then the request process fails and <c>{error, encode}</c> +is returned.</p> +</item> + +<item> +<p> +If the request is successfully encoded and sent but +the answer times out then a +<seealso marker="diameter_app#handle_error">handle_error/4</seealso> +callback takes place with <c>Reason = timeout</c>.</p> +</item> + +<item> +<p> +If the request is successfully encoded and sent but the service in +question is stopped before an answer is received then a +<seealso marker="diameter_app#handle_error">handle_error/4</seealso> +callback takes place <c>Reason = cancel</c>.</p> +</item> + +<item> +<p> +If the transport connection with the peer goes down after the request +has been sent but before an answer has been received then an attempt +is made to resend the request to an alternate peer. +If no such peer is available, or if the subsequent +<seealso marker="diameter_app#pick_peer">pick_peer/4</seealso> +callback rejects the candidates, then a +<seealso marker="diameter_app#handle_error">handle_error/4</seealso> +callback takes place with <c>Reason = failover</c>. +If a peer is selected then a +<seealso +marker="diameter_app#prepare_retransmit">prepare_retransmit/3</seealso> +callback takes place, after which the semantics are the same as +following an initial +<seealso marker="diameter_app#prepare_request"> +prepare_request/3</seealso> +callback.</p> +</item> + +<item> +<p> +If an encode error takes place during +retransmission then the request process fails and +<c>{error, failure}</c> is returned.</p> +</item> + +<item> +<p> +If an application callback made in processing the request fails +(pick_peer, prepare_request, prepare_retransmit, +handle_answer or handle_error) then either +<c>{error, encode}</c> or <c>{error, failure}</c> +is returned depending on whether or not there has been an +attempt to send the request over the transport.</p> +</item> + +</list> + +<p> +Note that <c>{error, encode}</c> is the only return value which +guarantees that the request has not been sent over the transport.</p> + +<marker id="origin_state_id"/> +</desc> +</func> + +<!-- ===================================================================== --> + +<func> +<name>origin_state_id() -> Unsigned32()</name> +<fsummary>Returns a reasonable Origin-State-Id.</fsummary> +<desc> +<p> +Return a reasonable value for use as Origin-State-Id in +outgoing messages. +The value returned is the number of seconds since 19680120T031408Z +(the first value that can be encoded as a Time()) +at the time the diameter application was started.</p> + +<marker id="remove_transport"/> +</desc> +</func> + +<!-- ===================================================================== --> + +<func> +<name>remove_transport(SvcName, Pred) -> ok</name> +<fsummary>Remove previously added transports.</fsummary> +<type> +<v>SvcName = service_name()</v> +<v>Pred = Fun | MFA | ref() | list() | true | false</v> +<v></v> +<v>Fun = fun((reference(), connect|listen, list()) -> boolean())</v> +<v> | fun((reference(), list()) -> boolean())</v> +<v> | fun((list()) -> boolean())</v> +<v>MFA = {atom(), atom(), list()}</v> +</type> +<desc> +<p> +Remove previously added transports.</p> + +<p> +<c>Pred</c> determines which transports to remove. +An arity-3-valued <c>Pred</c> removes all transports for which +<c>Pred(Ref, Type, Opts)</c> returns <c>true</c>, where <c>Type</c> and +<c>Opts</c> are as passed to <seealso +marker="#add_transport">add_transport/2</seealso> and <c>Ref</c> is +as returned by the corresponding call. +The remaining forms are equivalent to an arity-3 fun as follows.</p> + +<code> +Pred = fun(reference(), list()): fun(Ref, _, Opts) -> Pred(Ref, Opts) end +Pred = fun(list()): fun(_, _, Opts) -> Pred(Opts) end +Pred = reference(): fun(Ref, _, _) -> Pred == Ref end +Pred = list(): fun(_, _, Opts) -> [] == Pred -- Opts end +Pred = true: fun(_, _, _) -> true end +Pred = false: fun(_, _, _) -> false end +Pred = {M,F,A}: fun(Ref, Type, Opts) -> apply(M, F, [Ref, Type, Opts | A]) end +</code> + +<p> +Removing a transport causes all associated transport connections to +be broken. +A base application DPR message with +Disconnect-Cause <c>DO_NOT_WANT_TO_TALK_TO_YOU</c> will be sent +to each connected peer before disassociating the transport configuration +from the service and terminating the transport upon reception of +DPA or timeout.</p> + +<!-- TODO: document the timeout value, possibly make configurable. --> + +<marker id="service_info_1"/> +</desc> +</func> + +<!-- ===================================================================== --> + +<func> +<name>service_info(SvcName) -> Info</name> +<fsummary>Return information about a started service.</fsummary> +<type> +<v>SvcName = service_name()</v> +<v>Info = [{Item, Value}]</v> +</type> +<desc> +<p> +Return information about a started service. +Equivalent to <c>service_info(SvcName, all)</c>.</p> + +<marker id="service_info_2"/> +</desc> +</func> + +<!-- ===================================================================== --> + +<func> +<name>service_info(SvcName, Item) -> Value</name> +<fsummary>Return specific information about a started service.</fsummary> +<type> +<v>SvcName = service_name()</v> +<v>Value = term()</v> +</type> +<desc> +<p> +Return specific information about a started service.</p> + +<marker id="services"/> +</desc> +</func> + +<!-- ===================================================================== --> + +<func> +<name>services() -> [SvcName]</name> +<fsummary>Return the list of started services.</fsummary> +<type> +<v>SvcName = service_name()</v> +</type> +<desc> +<p> +Return the list of started services.</p> + +<marker id="session_id"/> +</desc> +</func> + +<!-- ===================================================================== --> + +<func> +<name>session_id(Ident) -> OctetString()</name> +<fsummary>Return a value for a Session-Id AVP</fsummary> +<type> +<v>Ident = DiameterIdentity()</v> +</type> +<desc> +<p> +Return a value for a Session-Id AVP. +The value has the form required by section 8.8 of RFC 3588. +Ident should be the Origin-Host of the peer from which +the message containing the returned value will be sent.</p> + +<marker id="start_service"/> +</desc> +</func> + +<!-- ===================================================================== --> +<func> +<name>start_service(SvcName, Options) -> ok | {error, Reason}</name> +<fsummary>Start a Diameter service</fsummary> +<type> +<v>SvcName = service_name()</v> +<v>Options = [service_opt()]</v> +<v>Reason = term()</v> +</type> +<desc> +<p> +Start a diameter service. +A service defines a locally-implemented Diameter peer, specifying the +capabilities of the peer to be used during capabilities exchange and +the Diameter applications that it supports. +Transports are added to a service using <seealso +marker="#add_transport">add_transport/2</seealso>.</p> + +<marker id="stop_service"/> +</desc> +</func> + +<!-- ===================================================================== --> +<func> +<name>stop_service(SvcName) -> ok | {error, Reason}</name> +<fsummary>Stops a Diameter service.</fsummary> +<type> +<v>SvcName = service_name()</v> +<v>Reason = term()</v> +</type> +<desc> +<p> +Stop a diameter service.</p> + +<marker id="subscribe"/> +</desc> +</func> + +<!-- ===================================================================== --> + +<func> +<name>subscribe(SvcName) -> true</name> +<fsummary>Subscribe to event messages from a service.</fsummary> +<type> +<v>SvcName = service_name()</v> +</type> +<desc> +<p> +Subscribe to <c>service_event()</c> messages from a service.</p> + +<p> +It is not an error to subscribe to events from a service +that does not yet exist.</p> + +<marker id="unsubscribe"/> +</desc> +</func> + +<!-- ===================================================================== --> + +<func> +<name>unsubscribe(SvcName) -> true</name> +<fsummary></fsummary> +<type> +<v>SvcName = service_name()</v> +</type> +<desc> +<p> +Unsubscribe to event messages from a service.</p> + +</desc> +</func> + +</funcs> + +<!-- ===================================================================== --> +<!-- ===================================================================== --> +<section> +<title>SEE ALSO</title> + +<p> +<seealso marker="diameter_app">diameter_app(3)</seealso>, +<seealso marker="diameter_transport">diameter_transport(3)</seealso>, +<seealso marker="diameter_dict">diameter_dict(4)</seealso></p> + +</section> + +</erlref> |