<!-- OSP Module User's Guide -->

<chapter>

  <title>&adminguide;</title>
  <section id="overview" xreflabel="Overview">
    <title>Overview</title>
    <para>The OSP module enables OpenSIPS to support secure, multi-lateral peering using the OSP standard defined by ETSI (TS 101 321 V4.1.1). This module will enable your OpenSIPS to:</para>
    <itemizedlist>
      <listitem>
        <para>Send a peering authorization request to a peering server.</para>
      </listitem>
      <listitem>
        <para>Validate a digitally signed peering authorization token received in a SIP INVITE message.</para>
      </listitem>
      <listitem>
        <para>Report usage information to a peering server.</para>
      </listitem>
    </itemizedlist>
  </section>
  <section id="dependencies" xreflabel="Dependencies">
    <title>Dependencies</title>
    <para>The OSP module depends on the following modules which must be loaded before the OSP module.</para>
    <itemizedlist>
      <listitem>
        <para><emphasis>auth</emphasis> -- Authentication Framework module</para>
      </listitem>
      <listitem>
        <para><emphasis>sqlops</emphasis> -- SQL operation module</para>
      </listitem>
      <listitem>
        <para><emphasis>maxfwd</emphasis> -- Max-Forward processor module</para>
      </listitem>
      <listitem>
        <para><emphasis>mi_fifo</emphasis> -- FIFO support for Management Interface</para>
      </listitem>
      <listitem>
        <para><emphasis>options</emphasis> -- OPTIONS server replier module</para>
      </listitem>
      <listitem>
        <para><emphasis>proto_udp</emphasis> -- UDP protocol module - implements UDP-plain transport for SIP</para>
      </listitem>
      <listitem>
        <para><emphasis>registrar</emphasis> -- SIP Registrar implementation module</para>
      </listitem>
      <listitem>
        <para><emphasis>rr</emphasis> -- Record-Route and Route module</para>
      </listitem>
      <listitem>
        <para><emphasis>signaling</emphasis> -- SIP signaling module</para>
      </listitem>
      <listitem>
        <para><emphasis>sipmsgops</emphasis> -- SIP operations module</para>
      </listitem>
      <listitem>
        <para><emphasis>sl</emphasis> -- Stateless replier module</para>
      </listitem>
      <listitem>
        <para><emphasis>tm</emphasis> -- Transaction (stateful) module</para>
      </listitem>
      <listitem>
        <para><emphasis>uac</emphasis> -- UAC functionalies (FROM mangling and UAC auth)</para>
      </listitem>
      <listitem>
        <para><emphasis>uac_auth</emphasis> -- UAC Authentication functionality</para>
      </listitem>
      <listitem>
        <para><emphasis>usrloc</emphasis> -- User location implementation module</para>
      </listitem>
      <listitem>
        <para><emphasis>OSP Toolkit</emphasis> -- The OSP Toolkit, available from https://github.com/TransNexus/osptoolkit, must be built before building OpenSIPS with the OSP module. For instructions on building OpenSIPS with the OSP Toolkit, see http://www.http://transnexus.com/wp-content/uploads/OSP-Routing-and-CDR-Collection-Server-with-OpenSIPS-1.7.2.pdf. For OpenSIPS 2.4.0, OSP Toolkit 4.16.0 or later versions should be used.</para>
      </listitem>
    </itemizedlist>
  </section>
  <section id="exported_parameters" xreflabel="Exported Parameters">
    <title>Exported Parameters</title>
    <section id="param_work_mode" xreflabel="work_mode">
      <title><varname>work_mode</varname></title>
      <para>The work_mode (integer) parameter instructs the OSP module what mode it should work in. If this value is set to 0, the OSP module works in direct mode. If this value is set to 1, the OSP module works in indirect mode. The default value is 0.</para>
      <example>
        <title>Instructing the module to work in direct mode</title>
        <programlisting format="linespecific">
modparam("osp","work_mode",0)
        </programlisting>
      </example>
    </section>
    <section id="param_service_type" xreflabel="service_type">
      <title><varname>service_type</varname></title>
      <para>The service_type (integer) parameter instructs the OSP module what services it should provide. If this value is set to 0, the OSP module provides normal voice service. If this value is set to 1, the OSP module provides ported number query service. If this value is set to 2, the OSP module provides CNAM query service. The default value is 0.</para>
      <example>
        <title>Instructing the module to provide normal voice service</title>
        <programlisting format="linespecific">
modparam("osp","service_type",0)
        </programlisting>
      </example>
    </section>
    <section id="param_sp1_uri" xreflabel="sp1_uri">
      <title><varname>sp1_uri</varname>, <varname>sp2_uri</varname>, ..., <varname>sp16_uri</varname></title>
      <para>These sp_uri (string) parameters define peering servers to be used for requesting peering authorization and routing information. At least one peering server must be configured. Others are required only if there are more than one peering servers. Each peering server address takes the form of a standard URL, and consists of up to four components:</para>
      <itemizedlist>
        <listitem>
          <para>An optional indication of the protocol to be used for communicating with the peering server. Both HTTP and HTTP secured with SSL/TLS are supported and are indicated by "http://" and "https://" respectively. If the protocol is not explicitly indicated, the OpenSIPS defaults to HTTP secured with SSL.</para>
        </listitem>
        <listitem>
          <para>The Internet domain name for the peering server. An IP address may also be used, provided it is enclosed in square brackets such as [172.16.1.1].</para>
        </listitem>
        <listitem>
          <para>An optional TCP port number for communicating with the peering server. If the port number is omitted, the OpenSIPS defaults to port 5045 (for HTTP) or port 1443 (for HTTP secured with SSL).</para>
          <para>The uniform resource identifier for requests to the peering server. This component is not optional and must be included.</para>
        </listitem>
      </itemizedlist>
      <example>
        <title>Setting the OSP servers</title>
        <programlisting format="linespecific">
modparam("osp","sp1_uri","http://osptestserver.transnexus.com:5045/osp")
modparam("osp","sp2_uri","https://[1.2.3.4]:1443/osp")
        </programlisting>
      </example>
    </section>
    <section id="param_sp1_weight" xreflabel="sp1_weight">
      <title><varname>sp1_weight</varname>, <varname>sp2_weight</varname>, ..., <varname>sp16_weight</varname></title>
      <para>These sp_weight (integer) parameters are used for load balancing peering requests to peering servers. These parameters are most effective when configured as factors of 1000. For example, if sp1_uri should manage twice the traffic load of sp2_uri, then set sp1_weight to 2000 and sp2_weight to 1000. Shared load balancing between peering servers is recommended. However, peering servers can be configured as primary and backup by assigning a sp_weight of 0 to the primary server and a non-zero sp_weight to the back-up server. The default values for sp1_weight and sp2_weight are 1000.</para>
      <example>
        <title>Setting the OSP server weights</title>
        <programlisting format="linespecific">
modparam("osp","sp1_weight",1000)
        </programlisting>
      </example>
    </section>
    <section id="param_device_ip" xreflabel="device_ip">
      <title><varname>device_ip</varname></title>
      <para>The device_ip (string) is a recommended parameter that explicitly defines the IP address of OpenSIPS in a peering request message (as SourceAlternate type=transport).  The dotted-decimal IP address must be in brackets as shown in the example below.</para>
      <example>
        <title>Setting the device IP address</title>
        <programlisting format="linespecific">
modparam("osp","device_ip","[127.0.0.1]:5060")
        </programlisting>
      </example>
    </section>
    <section id="param_use_security_features" xreflabel="use_security_features">
      <title><varname>use_security_features</varname></title>
      <para>The use_security_features (integer) parameter instructs the OSP module how to use the OSP security features. If this value is set to 1, the OSP module uses the OSP security features. If this value is set to 0, the OSP module will not use the OSP security features. The default value is 0.</para>
      <example>
        <title>Instructing the module not to use OSP security features</title>
        <programlisting format="linespecific">
modparam("osp","use_security_features",0)
        </programlisting>
      </example>
    </section>
    <section id="param_token_format" xreflabel="token_format">
      <title><varname>token_format</varname></title>
      <para>When OpenSIPS receives a SIP INVITE with a peering token, the OSP module will validate the token to determine whether or not the call has been authorized by a peering server. Peering tokens may, or may not, be digitally signed. The token_format (integer) parameter defines if OpenSIPS will validate signed or unsigned tokens or both. The values for token format are defined below. The default value is 2.</para>
      <para>If use_security_features parameter is set to 0, signed tokens cannot be validated.</para>
      <para>0 - Validate only signed tokens. Calls with valid signed tokens are allowed.</para>
      <para>1 - Validate only unsigned tokens. Calls with valid unsigned tokens are allowed.</para>
      <para>2 - Validate both signed and unsigned tokens are allowed. Calls with valid tokens are allowed.</para>
      <example>
        <title>Setting the token format</title>
        <programlisting format="linespecific">
modparam("osp","token_format",2)
        </programlisting>
      </example>
    </section>
    <section id="param_private_key" xreflabel="private_key">
      <title><varname>private_key</varname>, <varname>local_certificate</varname>, <varname>ca_certificates</varname></title>
      <para>These parameters identify files are used for validating peering authorization tokens and establishing a secure channel between OpenSIPS and a peering server using SSL.  The files are generated using the 'Enroll' utility from the OSP Toolkit. By default, the proxy will look for pkey.pem, localcert.pem, and cacart_0.pem in the default configuration directory. The default config directory is set at compile time using CFG_DIR and defaults to /usr/local/etc/opensips/. The files may be copied to the expected file location or the parameters below may be changed.</para>
      <para>If use_security_features parameter is set to 0, these parameters will be ignored.</para>
      <example>
        <title>Set authorization files</title>
        <para>If the default CFG_DIR value was used at compile time, the files will be loaded from:</para>
        <programlisting format="linespecific">
modparam("osp","private_key","/usr/local/etc/opensips/pkey.pem")
modparam("osp","local_certificate","/usr/local/etc/opensips/localcert.pem")
modparam("osp","ca_certificates","/usr/local/etc/opensips/cacert.pem")
        </programlisting>
      </example>
    </section>
    <section id="param_enable_crypto_hardware_support" xreflabel="enable_crypto_hardware_support">
      <title><varname>enable_crypto_hardware_support</varname></title>
      <para>The enable_crypto_hardware_support (integer) parameter is used to set the cryptographic hardware acceleration engine in the openssl library. The default value is 0 (no crypto hardware is present). If crypto hardware is used, the value should be set to 1.</para>
      <example>
        <title>Setting the hardware support</title>
        <programlisting format="linespecific">
modparam("osp","enable_crypto_hardware_support",0)
        </programlisting>
      </example>
    </section>
    <section id="param_ssl_lifetime" xreflabel="ssl_lifetime">
      <title><varname>ssl_lifetime</varname></title>
      <para>The ssl_lifetime (integer) parameter defines the lifetime, in seconds, of a single SSL session key. Once this time limit is exceeded, the OSP module will negotiate a new session key. Communication exchanges in progress will not be interrupted when this time limit expires. This is an optional field with default value is 200 seconds.</para>
      <example>
        <title>Setting the ssl lifetime</title>
        <programlisting format="linespecific">
modparam("osp","ssl_lifetime",200)
        </programlisting>
      </example>
    </section>
    <section id="param_persistence" xreflabel="persistence">
      <title><varname>persistence</varname></title>
      <para>The persistence (integer) parameter defines the time, in seconds, that an HTTP connection should be maintained after the completion of a communication exchange. The OSP module will maintain the connection for this time period in anticipation of future communication exchanges to the same peering server.</para>
      <example>
        <title>Setting the persistence</title>
        <programlisting format="linespecific">
modparam("osp","persistence",1000)
        </programlisting>
      </example>
    </section>
    <section id="param_retry_delay" xreflabel="retry_delay">
      <title><varname>retry_delay</varname></title>
      <para>The retry_delay (integer) parameter defines the time, in seconds, between retrying connection attempts to an OSP peering server. After exhausting all peering servers the OSP module will delay for this amount of time before resuming connection attempts. This is an optional field with default value is 1 second.</para>
      <example>
        <title>Setting the retry delay</title>
        <programlisting format="linespecific">
modparam("osp","retry_delay",1)
        </programlisting>
      </example>
    </section>
    <section id="param_retry_limit" xreflabel="retry_limit">
      <title><varname>retry_limit</varname></title>
      <para>The retry_limit (integer) parameter defines the maximum number of retries for connection attempts to a peering server. If no connection is established after this many retry attempts to all peering servers, the OSP module will cease connection attempts and return appropriate error codes. This number does not count the initial connection attempt, so that a retry_limit of 1 will result in a total of two connection attempts to every peering server. The default value is 2.</para>
      <example>
        <title>Setting the retry limit</title>
        <programlisting format="linespecific">
modparam("osp","retry_limit",2)
        </programlisting>
      </example>
    </section>
    <section id="param_timeout" xreflabel="timeout">
      <title><varname>timeout</varname></title>
      <para>The timeout (integer) parameter defines the maximum time in milliseconds, to wait for a response from a peering server. If no response is received within this time, the current connection is aborted and the OSP module attempts to contact the next peering server. The default value is 10 seconds.</para>
      <example>
        <title>Setting the timeout</title>
        <programlisting format="linespecific">
modparam("osp","timeout",10)
        </programlisting>
      </example>
    </section>
    <section id="param_support_nonsip_protocol" xreflabel="support_nonsip_protocol">
      <title><varname>support_nonsip_protocol</varname></title>
      <para>The support_nonsip_protocol (integer) parameter is used to tell the OSP module if non-SIP signaling protocol destination devices are supported. The default value is 0.</para>
      <example>
        <title>Setting support non-SIP destination devices</title>
        <programlisting format="linespecific">
modparam("osp","support_nonsip_protocol",0)
        </programlisting>
      </example>
    </section>
    <section id="param_max_destinations" xreflabel="max_destinations">
      <title><varname>max_destinations</varname></title>
      <para>The max_destinations (integer) parameter defines the maximum number of destinations that OpenSIPS requests the peering server to return in a peering response. The OSP module supports up to 12 destinations.  The default value is 12.</para>
      <example>
        <title>Setting the number of destination</title>
        <programlisting format="linespecific">
modparam("osp","max_destinations",12)
        </programlisting>
      </example>
    </section>
    <section id="param_report_networkid" xreflabel="report_networkid">
      <title><varname>report_networkid</varname></title>
      <para>The report_networkid (integer) parameter is used to tell the OSP module if to report network ID in completed call CDRs. If it is set to 0, ths OSP module does not report any network ID. If it is set to 1, the OSP module reports source network ID. If it is set to 2, the OSP module reports destination network ID. If it is set to 3, the OSP module report both source and destination network IDs.  The default value is 3.</para>
      <example>
        <title>Setting report network ID flag</title>
        <programlisting format="linespecific">
modparam("osp","report_networkid",3)
        </programlisting>
      </example>
    </section>
    <section id="param_validate_call_id" xreflabel="validate_call_id">
      <title><varname>validate_call_id</varname></title>
      <para>The validate_call_id (integer) parameter instructs the OSP module to validate call id in the peering token. If this value is set to 1, the OSP module validates that the call id in the SIP INVITE message matches the call id in the peering token. If they do not match the INVITE is rejected. If this value is set to 0, the OSP module will not validate the call id in the peering token. The default value is 1.</para>
      <example>
        <title>Instructing the module to validate call id</title>
        <programlisting format="linespecific">
modparam("osp","validate_call_id",1)
        </programlisting>
      </example>
    </section>
    <section id="param_use_number_portability" xreflabel="use_number_portability">
      <title><varname>use_number_portability</varname></title>
      <para>The use_number_portability (integer) parameter instructs the OSP module how to use the number portability parameters in the Request URI of the SIP INVITE message. If this value is set to 1, the OSP module uses the number portability parameters in the Request URI when these parameters exist. If this value is set to 0, the OSP module will not use the number portability parameters. The default value is 1.</para>
      <example>
        <title>Instructing the module to use number portability parameters in Request URI</title>
        <programlisting format="linespecific">
modparam("osp","use_number_portablity",1)
        </programlisting>
      </example>
    </section>
    <section id="param_append_userphone" xreflabel="append_userphone">
      <title><varname>append_userphone</varname></title>
      <para>The append_userphone (integer) parameter instructs the OSP module if to append "user=phone" parameter in URI. If this value is set to 0, the OSP module does not append "user=phone" parameter. If this value is set to 1, the OSP module will append "user=phone" parameter. The default value is 0</para>
      <example>
        <title>Append user=phone parameter</title>
        <programlisting format="linespecific">
modparam("osp","append_userphone",0)
        </programlisting>
      </example>
    </section>
    <section id="param_networkid_location" xreflabel="networkid_location">
      <title><varname>networkid_location</varname></title>
      <para>The networkid_location (integer) parameter instructs the OSP module where the destination network ID should be appended. The default value is 2</para>
      <para>0 - network ID is not appended.</para>
      <para>1 - network ID is appended as userinfo parameter.</para>
      <para>2 - network ID is appended as URI parameter.</para>
      <example>
        <title>Append networkid location</title>
        <programlisting format="linespecific">
modparam("osp","networkid_location",2)
        </programlisting>
      </example>
    </section>
    <section id="param_networkid_parameter" xreflabel="networkid_parameter">
      <title><varname>networkid_parameter</varname></title>
      <para>The networkid_parameter (string) parameter instructs the OSP module to use which parameter name in outbound destination URIs to append destination network ID. The default value is "networkid"</para>
      <example>
        <title>Networkid parameter name</title>
        <programlisting format="linespecific">
modparam("osp","networkid_param","networkid")
        </programlisting>
      </example>
    </section>
    <section id="param_switchid_location" xreflabel="switchid_location">
      <title><varname>switchid_location</varname></title>
      <para>The switchid_location (integer) parameter instructs the OSP module where the destination switch ID should be appended. The default value is 2</para>
      <para>0 - switch ID is not appended.</para>
      <para>1 - switch ID is appended as userinfo parameter.</para>
      <para>2 - switch ID is appended as URI parameter.</para>
      <example>
        <title>Append switchid location</title>
        <programlisting format="linespecific">
modparam("osp","switchid_location",2)
        </programlisting>
      </example>
    </section>
    <section id="param_switchid_parameter" xreflabel="switchid_parameter">
      <title><varname>switchid_parameter</varname></title>
      <para>The switchid_parameter (string) parameter instructs the OSP module to use which parameter name in outbound destination URIs to append destination switch ID. The default value is "switchid"</para>
      <example>
        <title>Networkid parameter name</title>
        <programlisting format="linespecific">
modparam("osp","switchid_param","switchid")
        </programlisting>
      </example>
    </section>
    <section id="param_parameterstring_location" xreflabel="parameterstring_location">
      <title><varname>parameterstring_location</varname></title>
      <para>The parameterstring_location (integer) parameter instructs the OSP module where the parameter string should be appended. The default value is 0</para>
      <para>0 - parameter string is not appended.</para>
      <para>1 - parameter string is appended as userinfo parameter.</para>
      <para>2 - parameter string is appended as URI parameter.</para>
      <example>
        <title>Append parameter string location</title>
        <programlisting format="linespecific">
modparam("osp","parameterstring_location",0)
        </programlisting>
      </example>
    </section>
    <section id="param_parameterstring_value" xreflabel="parameterstring_value">
      <title><varname>parameterstring_value</varname></title>
      <para>The parameterstring_value (string) parameter instructs the OSP module to append the parameter string in outbound URIs. The default value is ""</para>
      <example>
        <title>Parameter string value</title>
        <programlisting format="linespecific">
modparam("osp","parameterstring_value","")
        </programlisting>
      </example>
    </section>
    <section id="param_source_device_avp" xreflabel="source_device_avp">
      <title><varname>source_device_avp</varname></title>
      <para>The source_device_avp (string) parameter instructs the OSP module to use the defined AVP to pass the source device IP value in the indirect work mode. The default value is "$avp(_osp_source_device_)".  Then the source device IP can be set by "$avp(_osp_source_device_) = pseudo-variables".  All pseudo variables are described in https://opensips.org/Resources/DocsCoreVar.</para>
      <example>
        <title>Setting the source device IP AVP</title>
        <programlisting format="linespecific">
modparam("osp","source_device_avp","$avp(srcdev)")
        </programlisting>
      </example>
    </section>
    <section id="param_source_networkid_avp" xreflabel="source_networkid_avp">
      <title><varname>source_networkid_avp</varname></title>
      <para>The source_networkid_avp (string) parameter instructs the OSP module to use the defined AVP to pass the source network ID value. The default value is "$avp(_osp_source_networkid_)".  Then the source network ID can be set by "$avp(_osp_source_networkid_) = pseudo-variables".  All pseudo variables are described in https://opensips.org/Resources/DocsCoreVar.</para>
      <example>
        <title>Setting the source network ID AVP</title>
        <programlisting format="linespecific">
modparam("osp","source_networkid_avp","$avp(snid)")
        </programlisting>
      </example>
    </section>
    <section id="param_source_switchid_avp" xreflabel="source_switchid_avp">
      <title><varname>source_switchid_avp</varname></title>
      <para>The source_switchid_avp (string) parameter instructs the OSP module to use the defined AVP to pass the source switch ID value. The default value is "$avp(_osp_source_switchid_)".  Then the source switch ID can be set by "$avp(_osp_source_switchid_) = pseudo-variables".  All pseudo variables are described in https://opensips.org/Resources/DocsCoreVar.</para>
      <example>
        <title>Setting the source switch ID AVP</title>
        <programlisting format="linespecific">
modparam("osp","source_switchid_avp","$avp(swid)")
        </programlisting>
      </example>
    </section>
    <section id="param_custom_info_avp" xreflabel="custom_info_avp">
      <title><varname>custom_info_avp</varname></title>
      <para>The custom_info_avp (string) parameter instructs the OSP module to use the defined AVP to pass the custom information values. The default value is "$avp(_osp_custom_info_)".  Then the custom information can be set by "$avp(_osp_custom_info_) = pseudo-variables".  All pseudo variables are described in https://opensips.org/Resources/DocsCoreVar.</para>
      <example>
        <title>Setting the custom info AVP</title>
        <programlisting format="linespecific">
modparam("osp","custom_info_avp","$avp(cinfo)")
        </programlisting>
      </example>
    </section>
    <section id="param_cnam_avp" xreflabel="cnam_avp">
      <title><varname>cnam_avp</varname></title>
      <para>The cnam_avp (string) parameter instructs the OSP module to use the defined AVP to pass the CNAM values. The default value is "$avp(_osp_cnam_)".  Then the CNAM can be used by "$avp(_osp_cnam_)".  All pseudo variables are described in https://opensips.org/Resources/DocsCoreVar.</para>
      <example>
        <title>Setting the CNAM AVP</title>
        <programlisting format="linespecific">
modparam("osp","cnam_avp","$avp(cnam)")
        </programlisting>
      </example>
    </section>
    <section id="param_extraheaders_value" xreflabel="extraheaders_value">
      <title><varname>extraheaders_value</varname></title>
      <para>The extraheaders_value (string) parameter instructs the OSP module to append the defined SIP headers in outbound SIP NOTIFY messages. The default value is empty.</para>
      <example>
        <title>Setting the NOTIFY extra headers</title>
        <programlisting format="linespecific">
modparam("osp", "extraheaders_value", "Source: N")
        </programlisting>
      </example>
    </section>
    <section id="param_source_media_avp, destination_media_avp" xreflabel="source_media_avp, destination_media_avp">
      <title><varname>source_media_avp, destination_media_avp</varname></title>
      <para>These parameters are used to tell the OSP module which AVPs are used to store media addresses. The default values are "$avp(_osp_source_media_address_)" and "$avp(_osp_destination_media_address_)".  All pseudo variables are described in https://opensips.org/Resources/DocsCoreVar.</para>
      <example>
        <title>Setting the media address AVPs</title>
        <programlisting format="linespecific">
modparam("osp", "source_media_avp", "$avp(srcmedia)")
modparam("osp", "destination_media_avp", "$avp(destmedia)")
        </programlisting>
      </example>
    </section>
    <section id="param_request_date_avp" xreflabel="request_date_avp">
      <title><varname>request_date_avp</varname></title>
      <para>The request_date_avp (string) parameter instructs the OSP module to use the defined AVP to pass the SIP request Date header values. The default value is "$avp(_osp_request_date_)".  Then the request date can be used by "$avp(_osp_request_date_)".  All pseudo variables are described in https://opensips.org/Resources/DocsCoreVar.</para>
      <example>
        <title>Setting the request date AVP</title>
        <programlisting format="linespecific">
modparam("osp","request_date_avp","$avp(reqdate)")
        </programlisting>
      </example>
    </section>
    <section id="param_sdp_fingerprint_avp" xreflabel="sdp_fingerprint_avp">
      <title><varname>sdp_fingerprint_avp</varname></title>
      <para>The sdp_fingerprint_avp (string) parameter instructs the OSP module to use the defined AVP to pass the SDP fing print attribute values. The default value is "$avp(_osp_sdp_fingerprint_)".  Then the SDP finger print attributes can be used by "$avp(_osp_sdp_fingerprint_)".  All pseudo variables are described in https://opensips.org/Resources/DocsCoreVar.</para>
      <example>
        <title>Setting the SDP finger print AVP</title>
        <programlisting format="linespecific">
modparam("osp","sdp_fingerprint_avp","$avp(sdpfp)")
        </programlisting>
      </example>
    </section>
    <section id="param_identity_signature_avp" xreflabel="identity_signature_avp">
      <title><varname>identity_signature_avp</varname>, <varname>identity_algorithm_avp</varname>, <varname>identity_information_avp</varname>, <varname>identity_type_avp</varname>, <varname>identity_canon_avp</varname></title>
      <para>These parameters instruct the OSP module to use the defined AVPs to pass the Identity related values. The default values are "$avp(_osp_identity_signature_)", "$avp(_osp_identity_algorithm_)", "$avp(_osp_identity_information_)", "$avp(_osp_identity_type_)", "$avp(_osp_identity_canon_)".  Then the indentity related values can be used by these AVPs.  All pseudo variables are described in https://opensips.org/Resources/DocsCoreVar.</para>
      <example>
        <title>Setting the Identity related AVPs</title>
        <programlisting format="linespecific">
modparam("osp","identity_signature_avp","$avp(idsign)")
modparam("osp","identity_algorithm_avp","$avp(idalg)")
modparam("osp","identity_information_avp","$avp(idinfo)")
modparam("osp","identity_type_avp","$avp(idtype)")
modparam("osp","identity_canon_avp","$avp(idcanon)")
        </programlisting>
      </example>
    </section>
    <section id="param_service_provider_avp" xreflabel="param_service_provider_avp">
      <title><varname>service_provider_avp</varname></title>
      <para>These parameter is used to tell the OSP module which AVP is used to store source service provider information. The default value is "$avp(_osp_service_provider_)".  All pseudo variables are described in https://opensips.org/Resources/DocsCoreVar.</para>
      <example>
        <title>Setting the source service provider AVP</title>
        <programlisting format="linespecific">
modparam("osp", "service_provider_avp", "$avp(sp)")
        </programlisting>
      </example>
    </section>
    <section id="param_user_group_avp" xreflablel="param_user_group_avp">
      <title><varname>user_group_avp</varname></title>
      <para>These parameter is used to tell the OSP module which AVP is used to store source user group information. The default value is "$avp(_osp_user_group_)".  All pseudo variables are described in https://opensips.org/Resources/DocsCoreVar.</para>
      <example>
        <title>Setting the source user group AVP</title>
        <programlisting format="linespecific">
modparam("osp", "user_group_avp", "$avp(groupid)")
        </programlisting>
      </example>
    </section>
    <section id="param_user_id_avp" xreflabel="param_user_id_avp">
      <title><varname>user_id_avp</varname></title>
      <para>These parameter is used to tell the OSP module which AVP is used to store source user ID information. The default value is "$avp(_osp_user_id_)".  All pseudo variables are described in https://opensips.org/Resources/DocsCoreVar.</para>
      <example>
        <title>Setting the source user ID AVP</title>
        <programlisting format="linespecific">
modparam("osp", "user_id_avp", "$avp(userid)")
        </programlisting>
      </example>
    </section>
  </section>
  <section id="exported_functions" xreflabel="exported_functions">
    <title>Exported Functions</title>
    <section id="func_checkospheader" xreflabel="checkospheader()">
      <title><function moreinfo="none">checkospheader()</function></title>
      <para>This function checks for the existence of the OSP-Auth-Token header field.</para>
      <para>This function can be used from REQUEST_ROUTE.</para>
      <example>
        <title>checkospheader usage</title>
        <programlisting format="linespecific">
...
if (checkospheader()) {
  log(1,"OSP header field found.\n");
} else {
  log(1,"no OSP header field present\n");
};
...
        </programlisting>
      </example>
    </section>
    <section id="func_validateospheader" xreflabel="validateospheader()">
      <title><function moreinfo="none">validateospheader()</function></title>
      <para>This function validates an OSP-Token specified in the OSP-Auth-Tokenheader field of the SIP message. If a peering token is present, it will be validated locally. If no OSP header is found or the header token is invalid or expired, -1 is returned; on successful validation 1 is returned.</para>
      <para>This function can be used from REQUEST_ROUTE.</para>
      <example>
        <title>validateospheader usage</title>
        <programlisting format="linespecific">
...
if (validateospheader()) {
  log(1,"valid OSP header found\n");
} else {
  log(1,"OSP header not found, invalid or expired\n");
};
...
        </programlisting>
      </example>
    </section>
    <section id="func_getlocaladdress" xreflabel="getlocaladdress()">
      <title><function moreinfo="none">getlocaladdress()</function></title>
      <para>This function gets the receiving IP address of SIP response and stores it as proxy egress address.</para>
      <para>This function can be used from ONREPLY_ROUTE.</para>
      <example>
        <title>getlocaladress usage</title>
        <programlisting format="linespecific">
...
if (getlocaladdress()) {
  log(1,"Obtain proxy local egress address\n");
} else {
  log(1,"Failed to get proxy local egress address\n");
};
...
        </programlisting>
      </example>
    </section>
    <section id="func_setrequestdate" xreflabel="setrequestdate()">
      <title><function moreinfo="none">setrequestdate()</function></title>
      <para>This function gets the receiving IP address of SIP response and stores it as proxy egress address.</para>
      <para>This function can be used from REQUEST_ROUTE.</para>
      <example>
        <title>setrequestdate usage</title>
        <programlisting format="linespecific">
...
if (setrequest()) {
  log(1,"Set request date\n");
} else {
  log(1,"Failed to set request date\n");
};
...
        </programlisting>
      </example>
    </section>
    <section id="func_requestosprouting" xreflabel="requestosprouting()">
      <title><function moreinfo="none">requestosprouting()</function></title>
      <para>This function launches a query to the peering server requesting the IP address of one or more destination peers serving the called party. If destination peers are available, the peering server will return the IP address and a peering authorization token for each destination peer. The OSP-Auth-Token Header field is inserted into the SIP message and the SIP uri is rewritten to the IP address of destination peer provided by the peering server.</para>
      <para>The address of the called party must be a valid E164 number, otherwise this function returns -1. If the transaction was accepted by the peering server, the uri is being rewritten and 1 returned, on errors (peering servers are not available, authentication failed or there is no route to destination or the route is blocked) -1 is returned.</para>
      <para>This function can be used from REQUEST_ROUTE.</para>
      <example>
        <title>requestosprouting usage</title>
        <programlisting format="linespecific">
...
if (requestosprouting()) {
  log(1,"successfully queried OSP server, now relaying call\n");
} else {
  log(1,"Authorization request was rejected from OSP server\n");
};
...
        </programlisting>
      </example>
    </section>
    <section id="func_checkosproute" xreflabel="checkosproute()">
      <title><function moreinfo="none">checkosproute()</function></title>
      <para>This function is used to check if there is any route for the call.</para>
      <para>This function can be used from REQUEST_ROUTE.</para>
      <example>
        <title>checkosproute usage</title>
        <programlisting format="linespecific">
...
if (checkosproute()) {
  log(1,"There is at least one route for the call\n");
} else {
  log(1,"There is not any route for the call\n");
};
...
        </programlisting>
      </example>
    </section>
    <section id="func_prepareosproute" xreflabel="prepareosproute()">
      <title><function moreinfo="none">prepareosproute()</function></title>
      <para>This function tries to prepare the INVITE to be forwarded using the destination in the list returned by the peering server. If the calling number is translated, a RPID value for the RPID AVP will be set. If the route could not be prepared, the function returns 'FALSE' back to the script, which can then decide how to handle the failure. Note, if checkosproute has been called and returns 'TRUE' before calling prepareosproute, prepareosproute should not return 'FALSE' because checkosproute has confirmed that there is at least one route.</para>
      <para>This function can be used from BRANCH_ROUTE.</para>
      <example>
        <title>prepareosproute usage</title>
        <programlisting format="linespecific">
...
if (prepareosproute()) {
  log(1,"successfully prepared the route, now relaying call\n");
} else {
  log(1,"could not prepare the route, there is not route\n");
};
...
        </programlisting>
      </example>
    </section>
    <section id="func_prepareospresponse" xreflabel="prepareospresponse()">
      <title><function moreinfo="none">prepareospresponse()</function></title>
      <para>This function tries to prepare all the routes in the list returned by the peering server into SIP 300 Redirect or SIP 380 Alternative Service message. The message is then replied to the source. If unsuccessful in preparing the routes a SIP 500 is sent back and a trace message is logged.</para>
      <para>This function can be used from REQUEST_ROUTE.</para>
      <example>
        <title>prepareospresponse usage</title>
        <programlisting format="linespecific">
...
if (prepareospresponse()) {
  log(1,"Response is prepared.\n");
} else {
  log(1,"Could not prepare the response.\n");
};
...
        </programlisting>
      </example>
    </section>
    <section id="func_prepareallosproutes" xreflabel="prepareallosproutes()">
      <title><function moreinfo="none">prepareallosproutes()</function></title>
      <para>This function tries to prepare all the routes in the list returned by the peering server. The message is then forked off to the destinations. If unsuccessful in preparing the routes a SIP 500 is sent back and a trace message is logged.</para>
      <para>This function can be used from REQUEST_ROUTE.</para>
      <example>
        <title>prepareallosproutes usage</title>
        <programlisting format="linespecific">
...
if (prepareallosproutes()) {
  log(1,"Routes are prepared, now forking the call\n");
} else {
  log(1,"Could not prepare the routes. No destination available\n");
};
...
        </programlisting>
      </example>
    </section>
    <section id="func_checkcallingtranslation" xreflabel="checkcallingtranslation()">
      <title><function moreinfo="none">checkcallingtranslation()</function></title>
      <para>This function is used to check if the calling number is translated. Before calling checkcallingtranslation, prepareosproute should be called. If the calling number does been translated, the original Remote-Party-ID, if it exists, should be removed from the INVITE message. And a new Remote-Party-ID header should be added (a RPID value for the RPID AVP has been set by prepareosproute). If the calling number is not translated, nothing should be done.</para>
      <para>This function can be used from BRANCH_ROUTE.</para>
      <example>
        <title>checkcallingtranslation usage</title>
        <programlisting format="linespecific">
...
if (checkcallingtranslation()) {
  # Remove the Remote_Party-ID from the received message
  # Otherwise it will be forwarded on to the next hop
  remove_hf("Remote-Party-ID");

  # Append a new Remote_Party
  append_rpid_hf();
}
...
        </programlisting>
      </example>
    </section>
    <section id="func_reportospusage" xreflabel="reportospusage()">
      <title><function moreinfo="none">reportospusage()</function></title>
      <para>This function should be called after receiving a BYE message. If the message contains an OSP cookie, the function will forward originating and/or terminating duration usage information to a peering server. The function returns TRUE if the BYE includes an OSP cookie. The actual usage message will be send on a different thread and will not delay BYE processing. The function should be called before relaying the message.</para>
      <para>Meaning of the parameter is as follows:
        <itemizedlist>
          <listitem>
            <para>0 - Source device releases the call.</para>
          </listitem>
          <listitem>
            <para>1 - Destination device releases the call.</para>
          </listitem>
        </itemizedlist>
      </para>
      <para>This function can be used from REQUEST_ROUTE.</para>
      <example>
        <title>reportospusage usage</title>
        <programlisting format="linespecific">
...
if (is_direction("downstream")) {
  log(1,"This BYE message is from SOURCE\n");
  if (!reportospusage(0)) {
    log(1,"This BYE message does not include OSP usage information\n");
  }
} else {
  log(1,"This BYE message is from DESTINATION\n");
  if (!reportospusage(1)) {
    log(1,"This BYE message does not include OSP usage information\n");
  }
}
...
        </programlisting>
      </example>
    </section>
    <section id="func_processsubscribe" xreflabel="processsubscribe()">
      <title><function moreinfo="none">processsubscribe([cachedcnamrecord])</function></title>
      <para>This function should be called after receiving a SUBSCRIBE for CNAM message and there is a cached CNAM record for this message. This function generates a NOTIFY message including the cached CNAM record, then sends the NOTIFY message to the device sending the SUBSCRIBE message.</para>
      <para>Meaning of the parameter is as follows:
        <itemizedlist>
          <listitem>
            <para><emphasis>cachedcnamrecord</emphasis> (string) - Cached CNAM record.</para>
          </listitem>
        </itemizedlist>
      </para>
      <para>This function can be used from REQUEST_ROUTE.</para>
      <example>
        <title>processsubscribe usage</title>
        <programlisting format="linespecific">
...
if (is_method("SUBSCRIBE")) {
    if (($var(sevent) == "calling-name") &amp;&amp; (is_myself("$rd"))) {
        if ($var(cnamrecord) != NULL) {
            processsubscribe($(var(cnamrecord){s.b64decode}));
        } else {
            t_relay("1.2.3.4", 0x02);
        }
    } else {
        t_relay();
    }
}
...
        </programlisting>
      </example>
    </section>
  </section>
</chapter>

