فهرست منبع

Merge pull request #178 from kamailio/hpw/contact-attributes

Implement load and restore of contact attributes
Hugh Waite 10 سال پیش
والد
کامیت
9529a6bc08
6فایلهای تغییر یافته به همراه242 افزوده شده و 155 حذف شده
  1. 163 147
      modules/tm/README
  2. 21 0
      modules/tm/doc/params.xml
  3. 48 4
      modules/tm/t_serial.c
  4. 2 0
      modules/tm/tm.c
  5. 4 2
      modules/usrloc/README
  6. 4 2
      modules/usrloc/doc/usrloc_admin.xml

+ 163 - 147
modules/tm/README

@@ -67,6 +67,7 @@ Juha Heinanen
               4.43. remap_503_500 (boolean)
               4.43. remap_503_500 (boolean)
               4.44. failure_exec_mode (boolean)
               4.44. failure_exec_mode (boolean)
               4.45. dns_reuse_rcv_socket (boolean)
               4.45. dns_reuse_rcv_socket (boolean)
+              4.46. xavp_contact (string)
 
 
         5. Functions
         5. Functions
 
 
@@ -189,51 +190,52 @@ Juha Heinanen
    1.43. Set remap_503_500 parameter
    1.43. Set remap_503_500 parameter
    1.44. Set failure_exec_mode parameter
    1.44. Set failure_exec_mode parameter
    1.45. Set dns_reuse_rcv_socket parameter
    1.45. Set dns_reuse_rcv_socket parameter
-   1.46. t_relay usage
-   1.47. t_relay_to_udp usage
-   1.48. t_on_failure usage
-   1.49. t_on_branch_failure usage
-   1.50. t_on_reply usage
-   1.51. t_on_branch usage
-   1.52. t_newtran usage
-   1.53. t_reply usage
-   1.54. t_lookup_request usage
-   1.55. t_retransmit_reply usage
-   1.56. t_release usage
-   1.57. t_forward_nonack usage
-   1.58. t_set_fr usage
-   1.59. t_reset_fr usage
-   1.60. t_set_max_lifetime usage
-   1.61. t_reset_max_lifetime usage
-   1.62. t_set_retr usage
-   1.63. t_reset_retr usage
-   1.64. t_set_auto_inv_100 usage
-   1.65. t_branch_timeout usage
-   1.66. t_branch_replied usage
-   1.67. t_any_timeout usage
-   1.68. t_any_replied usage
-   1.69. t_grep_status usage
-   1.70. t_is_canceled usage
-   1.71. t_is_expired usage
-   1.72. t_relay_cancel usage
-   1.73. t_lookup_cancel usage
-   1.74. t_drop_replies() usage
-   1.75. t_save_lumps() usage
-   1.76. t_load_contacts usage
-   1.77. t_next_contacts usage
-   1.78. t_next_contact_flow usage
-   1.79. t_check_status usage
-   1.80. t_check_trans usage
-   1.81. t_set_disable_6xx usage
-   1.82. t_set_disable_failover usage
-   1.83. t_set_disable_internal_reply usage
-   1.84. t_replicate usage
-   1.85. t_relay_to usage
-   1.86. t_set_no_e2e_cancel_reason usage
-   1.87. t_replicate usage
-   1.88. t_use_uac_headers usage
-   1.89. t_is_retr_async_reply usage
-   1.90. event_route[tm:branch-failure] usage
+   1.46. Set xavp_contact parameter
+   1.47. t_relay usage
+   1.48. t_relay_to_udp usage
+   1.49. t_on_failure usage
+   1.50. t_on_branch_failure usage
+   1.51. t_on_reply usage
+   1.52. t_on_branch usage
+   1.53. t_newtran usage
+   1.54. t_reply usage
+   1.55. t_lookup_request usage
+   1.56. t_retransmit_reply usage
+   1.57. t_release usage
+   1.58. t_forward_nonack usage
+   1.59. t_set_fr usage
+   1.60. t_reset_fr usage
+   1.61. t_set_max_lifetime usage
+   1.62. t_reset_max_lifetime usage
+   1.63. t_set_retr usage
+   1.64. t_reset_retr usage
+   1.65. t_set_auto_inv_100 usage
+   1.66. t_branch_timeout usage
+   1.67. t_branch_replied usage
+   1.68. t_any_timeout usage
+   1.69. t_any_replied usage
+   1.70. t_grep_status usage
+   1.71. t_is_canceled usage
+   1.72. t_is_expired usage
+   1.73. t_relay_cancel usage
+   1.74. t_lookup_cancel usage
+   1.75. t_drop_replies() usage
+   1.76. t_save_lumps() usage
+   1.77. t_load_contacts usage
+   1.78. t_next_contacts usage
+   1.79. t_next_contact_flow usage
+   1.80. t_check_status usage
+   1.81. t_check_trans usage
+   1.82. t_set_disable_6xx usage
+   1.83. t_set_disable_failover usage
+   1.84. t_set_disable_internal_reply usage
+   1.85. t_replicate usage
+   1.86. t_relay_to usage
+   1.87. t_set_no_e2e_cancel_reason usage
+   1.88. t_replicate usage
+   1.89. t_use_uac_headers usage
+   1.90. t_is_retr_async_reply usage
+   1.91. event_route[tm:branch-failure] usage
 
 
 Chapter 1. Admin Guide
 Chapter 1. Admin Guide
 
 
@@ -289,6 +291,7 @@ Chapter 1. Admin Guide
         4.43. remap_503_500 (boolean)
         4.43. remap_503_500 (boolean)
         4.44. failure_exec_mode (boolean)
         4.44. failure_exec_mode (boolean)
         4.45. dns_reuse_rcv_socket (boolean)
         4.45. dns_reuse_rcv_socket (boolean)
+        4.46. xavp_contact (string)
 
 
    5. Functions
    5. Functions
 
 
@@ -655,6 +658,7 @@ failure_route["serial"]
    4.43. remap_503_500 (boolean)
    4.43. remap_503_500 (boolean)
    4.44. failure_exec_mode (boolean)
    4.44. failure_exec_mode (boolean)
    4.45. dns_reuse_rcv_socket (boolean)
    4.45. dns_reuse_rcv_socket (boolean)
+   4.46. xavp_contact (string)
 
 
 4.1. fr_timer (integer)
 4.1. fr_timer (integer)
 
 
@@ -1564,6 +1568,18 @@ modparam("tm", "failure_exec_mode", 1)
 modparam("tm", "dns_reuse_rcv_socket", 1)
 modparam("tm", "dns_reuse_rcv_socket", 1)
 ...
 ...
 
 
+4.46. xavp_contact (string)
+
+   The name of XAVP storing the attributes per contact. This must be the
+   same as the usrloc parameter xavp_contacts.
+
+   Default value is "NULL".
+
+   Example 1.46. Set xavp_contact parameter
+...
+modparam("tm|usrloc", "xavp_contact", "ulattrs")
+...
+
 5. Functions
 5. Functions
 
 
    5.1. t_relay([host, port])
    5.1. t_relay([host, port])
@@ -1618,7 +1634,7 @@ modparam("tm", "dns_reuse_rcv_socket", 1)
    5.50. t_use_uac_headers()
    5.50. t_use_uac_headers()
    5.51. t_is_retr_async_reply()
    5.51. t_is_retr_async_reply()
 
 
-5.1. t_relay([host, port])
+5.1.  t_relay([host, port])
 
 
    Relay a message statefully either to the destination indicated in the
    Relay a message statefully either to the destination indicated in the
    current URI (if called without any parameters) or to the specified host
    current URI (if called without any parameters) or to the specified host
@@ -1637,7 +1653,7 @@ modparam("tm", "dns_reuse_rcv_socket", 1)
    Returns a negative value on failure -- you may still want to send a
    Returns a negative value on failure -- you may still want to send a
    negative reply upstream statelessly not to leave upstream UAC in lurch.
    negative reply upstream statelessly not to leave upstream UAC in lurch.
 
 
-   Example 1.46. t_relay usage
+   Example 1.47. t_relay usage
 ...
 ...
 if (!t_relay())
 if (!t_relay())
 {
 {
@@ -1646,7 +1662,7 @@ if (!t_relay())
 };
 };
 ...
 ...
 
 
-5.2. t_relay_to_udp([ip, port])
+5.2.  t_relay_to_udp([ip, port])
 
 
    Relay a message statefully using a fixed protocol either to the
    Relay a message statefully using a fixed protocol either to the
    specified fixed destination or to a destination derived from the
    specified fixed destination or to a destination derived from the
@@ -1664,7 +1680,7 @@ if (!t_relay())
    derived from the message uri (using sip sepcific DNS lookups), but with
    derived from the message uri (using sip sepcific DNS lookups), but with
    the protocol corresponding to the function name.
    the protocol corresponding to the function name.
 
 
-   Example 1.47. t_relay_to_udp usage
+   Example 1.48. t_relay_to_udp usage
 ...
 ...
 if (src_ip==10.0.0.0/8)
 if (src_ip==10.0.0.0/8)
         t_relay_to_udp("1.2.3.4", "5060"); # sent to 1.2.3.4:5060 over udp
         t_relay_to_udp("1.2.3.4", "5060"); # sent to 1.2.3.4:5060 over udp
@@ -1672,19 +1688,19 @@ else
         t_relay_to_tcp(); # relay to msg. uri, but over tcp
         t_relay_to_tcp(); # relay to msg. uri, but over tcp
 ...
 ...
 
 
-5.3. t_relay_to_tcp([ip, port])
+5.3.  t_relay_to_tcp([ip, port])
 
 
    See function t_relay_to_udp([ip, port]).
    See function t_relay_to_udp([ip, port]).
 
 
-5.4. t_relay_to_tls([ip, port])
+5.4.  t_relay_to_tls([ip, port])
 
 
    See function t_relay_to_udp([ip, port]).
    See function t_relay_to_udp([ip, port]).
 
 
-5.5. t_relay_to_sctp([ip, port])
+5.5.  t_relay_to_sctp([ip, port])
 
 
    See function t_relay_to_udp([ip, port]).
    See function t_relay_to_udp([ip, port]).
 
 
-5.6. t_on_failure(failure_route)
+5.6.  t_on_failure(failure_route)
 
 
    Sets failure routing block, to which control is passed after a
    Sets failure routing block, to which control is passed after a
    transaction completed with a negative result but before sending a final
    transaction completed with a negative result but before sending a final
@@ -1704,7 +1720,7 @@ else
    Meaning of the parameters is as follows:
    Meaning of the parameters is as follows:
      * failure_route - Failure route block to be called.
      * failure_route - Failure route block to be called.
 
 
-   Example 1.48. t_on_failure usage
+   Example 1.49. t_on_failure usage
 ...
 ...
 route {
 route {
     t_on_failure("1");
     t_on_failure("1");
@@ -1721,7 +1737,7 @@ failure_route[1] {
    See test/onr.cfg for a more complex example of combination of serial
    See test/onr.cfg for a more complex example of combination of serial
    with parallel forking.
    with parallel forking.
 
 
-5.7. t_on_branch_failure(branch_failure_route)
+5.7.  t_on_branch_failure(branch_failure_route)
 
 
    Sets the branch_failure routing block, to which control is passed on
    Sets the branch_failure routing block, to which control is passed on
    each negative response to a transaction. This route is run before
    each negative response to a transaction. This route is run before
@@ -1740,7 +1756,7 @@ failure_route[1] {
      * branch_failure_route - Name of the branch_failure route block to be
      * branch_failure_route - Name of the branch_failure route block to be
        called (it is prefixed internally with 'tm:branch-failure:').
        called (it is prefixed internally with 'tm:branch-failure:').
 
 
-   Example 1.49. t_on_branch_failure usage
+   Example 1.50. t_on_branch_failure usage
 ...
 ...
 route {
 route {
     t_on_branch_failure("myroute");
     t_on_branch_failure("myroute");
@@ -1754,7 +1770,7 @@ event_route[tm:branch-failure:myroute] {
 }
 }
 ...
 ...
 
 
-5.8. t_on_reply(onreply_route)
+5.8.  t_on_reply(onreply_route)
 
 
    Sets the reply routing block, to which control is passed when a reply
    Sets the reply routing block, to which control is passed when a reply
    for the current transaction is received. Note that the set of commands
    for the current transaction is received. Note that the set of commands
@@ -1763,7 +1779,7 @@ event_route[tm:branch-failure:myroute] {
    Meaning of the parameters is as follows:
    Meaning of the parameters is as follows:
      * onreply_route - Onreply route block to be called.
      * onreply_route - Onreply route block to be called.
 
 
-   Example 1.50. t_on_reply usage
+   Example 1.51. t_on_reply usage
 ...
 ...
 loadmodule "/usr/local/lib/ser/modules/nathelper.so"
 loadmodule "/usr/local/lib/ser/modules/nathelper.so"
 ...
 ...
@@ -1784,7 +1800,7 @@ es');
         }
         }
 }
 }
 
 
-5.9. t_on_branch(branch_route)
+5.9.  t_on_branch(branch_route)
 
 
    Sets the branch routing block, to which control is passed after forking
    Sets the branch routing block, to which control is passed after forking
    (when a new branch is created). For now branch routes are intended only
    (when a new branch is created). For now branch routes are intended only
@@ -1795,7 +1811,7 @@ es');
    Meaning of the parameters is as follows:
    Meaning of the parameters is as follows:
      * branch_route - branch route block to be called.
      * branch_route - branch route block to be called.
 
 
-   Example 1.51. t_on_branch usage
+   Example 1.52. t_on_branch usage
 ...
 ...
 route {
 route {
         t_on_branch("1");
         t_on_branch("1");
@@ -1808,13 +1824,13 @@ branch_route[1] {
         }
         }
 }
 }
 
 
-5.10. t_newtran()
+5.10.  t_newtran()
 
 
    Creates a new transaction, returns a negative value on error. This is
    Creates a new transaction, returns a negative value on error. This is
    the only way a script can add a new transaction in an atomic way.
    the only way a script can add a new transaction in an atomic way.
    Typically, it is used to deploy a UAS.
    Typically, it is used to deploy a UAS.
 
 
-   Example 1.52. t_newtran usage
+   Example 1.53. t_newtran usage
 ...
 ...
 if (t_newtran()) {
 if (t_newtran()) {
     log("UAS logic");
     log("UAS logic");
@@ -1824,7 +1840,7 @@ if (t_newtran()) {
 
 
    See test/uas.cfg for more examples.
    See test/uas.cfg for more examples.
 
 
-5.11. t_reply(code, reason_phrase)
+5.11.  t_reply(code, reason_phrase)
 
 
    Sends a stateful reply after a transaction has been established. See
    Sends a stateful reply after a transaction has been established. See
    t_newtran for usage.
    t_newtran for usage.
@@ -1844,12 +1860,12 @@ if (t_newtran()) {
      * code - Reply code number.
      * code - Reply code number.
      * reason_phrase - Reason string.
      * reason_phrase - Reason string.
 
 
-   Example 1.53. t_reply usage
+   Example 1.54. t_reply usage
 ...
 ...
 t_reply("404", "Not found");
 t_reply("404", "Not found");
 ...
 ...
 
 
-5.12. t_lookup_request()
+5.12.  t_lookup_request()
 
 
    Checks if a transaction exists. Returns a positive value if so,
    Checks if a transaction exists. Returns a positive value if so,
    negative otherwise. Most likely you will not want to use it, as a
    negative otherwise. Most likely you will not want to use it, as a
@@ -1857,33 +1873,33 @@ t_reply("404", "Not found");
    none was found. However this is safely (atomically) done using
    none was found. However this is safely (atomically) done using
    t_newtran.
    t_newtran.
 
 
-   Example 1.54. t_lookup_request usage
+   Example 1.55. t_lookup_request usage
 ...
 ...
 if (t_lookup_request()) {
 if (t_lookup_request()) {
     ...
     ...
 };
 };
 ...
 ...
 
 
-5.13. t_retransmit_reply()
+5.13.  t_retransmit_reply()
 
 
    Retransmits a reply sent previously by UAS transaction.
    Retransmits a reply sent previously by UAS transaction.
 
 
-   Example 1.55. t_retransmit_reply usage
+   Example 1.56. t_retransmit_reply usage
 ...
 ...
 t_retransmit_reply();
 t_retransmit_reply();
 ...
 ...
 
 
-5.14. t_release()
+5.14.  t_release()
 
 
    Remove transaction from memory (it will be first put on a wait timer to
    Remove transaction from memory (it will be first put on a wait timer to
    absorb delayed messages).
    absorb delayed messages).
 
 
-   Example 1.56. t_release usage
+   Example 1.57. t_release usage
 ...
 ...
 t_release();
 t_release();
 ...
 ...
 
 
-5.15. t_forward_nonack([ip, port])
+5.15.  t_forward_nonack([ip, port])
 
 
    Mainly for internal usage -- forward a non-ACK request statefully.
    Mainly for internal usage -- forward a non-ACK request statefully.
    Variants of this functions can enforce a specific transport protocol.
    Variants of this functions can enforce a specific transport protocol.
@@ -1892,28 +1908,28 @@ t_release();
      * ip - IP address where the message should be sent.
      * ip - IP address where the message should be sent.
      * port - Port number.
      * port - Port number.
 
 
-   Example 1.57. t_forward_nonack usage
+   Example 1.58. t_forward_nonack usage
 ...
 ...
 t_forward_nonack("1.2.3.4", "5060");
 t_forward_nonack("1.2.3.4", "5060");
 ...
 ...
 
 
-5.16. t_forward_nonack_udp(ip, port)
+5.16.  t_forward_nonack_udp(ip, port)
 
 
    See function t_forward_nonack([ip, port]).
    See function t_forward_nonack([ip, port]).
 
 
-5.17. t_forward_nonack_tcp(ip, port)
+5.17.  t_forward_nonack_tcp(ip, port)
 
 
    See function t_forward_nonack([ip, port]).
    See function t_forward_nonack([ip, port]).
 
 
-5.18. t_forward_nonack_tls(ip, port)
+5.18.  t_forward_nonack_tls(ip, port)
 
 
    See function t_forward_nonack([ip, port]).
    See function t_forward_nonack([ip, port]).
 
 
-5.19. t_forward_nonack_sctp(ip, port)
+5.19.  t_forward_nonack_sctp(ip, port)
 
 
    See function t_forward_nonack([ip, port]).
    See function t_forward_nonack([ip, port]).
 
 
-5.20. t_set_fr(fr_inv_timeout [, fr_timeout])
+5.20.  t_set_fr(fr_inv_timeout [, fr_timeout])
 
 
    Sets the fr_inv_timeout and optionally fr_timeout for the current
    Sets the fr_inv_timeout and optionally fr_timeout for the current
    transaction or for transactions created during the same script
    transaction or for transactions created during the same script
@@ -1931,7 +1947,7 @@ t_forward_nonack("1.2.3.4", "5060");
 
 
    See also: fr_timer, fr_inv_timer, t_reset_fr().
    See also: fr_timer, fr_inv_timer, t_reset_fr().
 
 
-   Example 1.58. t_set_fr usage
+   Example 1.59. t_set_fr usage
 ...
 ...
 route {
 route {
         t_set_fr(10000); # set only fr invite timeout to 10s
         t_set_fr(10000); # set only fr invite timeout to 10s
@@ -1947,7 +1963,7 @@ branch_route[1] {
         }
         }
 }
 }
 
 
-5.21. t_reset_fr()
+5.21.  t_reset_fr()
 
 
    Resets the fr_inv_timer and fr_timer for the current transaction to the
    Resets the fr_inv_timer and fr_timer for the current transaction to the
    default values (set using the tm module parameters fr_inv_timer and
    default values (set using the tm module parameters fr_inv_timer and
@@ -1958,7 +1974,7 @@ branch_route[1] {
 
 
    See also: fr_timer, fr_inv_timer, t_set_fr.
    See also: fr_timer, fr_inv_timer, t_set_fr.
 
 
-   Example 1.59. t_reset_fr usage
+   Example 1.60. t_reset_fr usage
 ...
 ...
 route {
 route {
 ...
 ...
@@ -1966,7 +1982,7 @@ route {
 ...
 ...
 }
 }
 
 
-5.22. t_set_max_lifetime(inv_lifetime, noninv_lifetime)
+5.22.  t_set_max_lifetime(inv_lifetime, noninv_lifetime)
 
 
    Sets the maximum lifetime for the current INVITE or non-INVITE
    Sets the maximum lifetime for the current INVITE or non-INVITE
    transaction, or for transactions created during the same script
    transaction, or for transactions created during the same script
@@ -1984,7 +2000,7 @@ route {
 
 
    See also: max_inv_lifetime, max_noninv_lifetime, t_reset_max_lifetime.
    See also: max_inv_lifetime, max_noninv_lifetime, t_reset_max_lifetime.
 
 
-   Example 1.60. t_set_max_lifetime usage
+   Example 1.61. t_set_max_lifetime usage
 ...
 ...
 route {
 route {
     if (src_ip=1.2.3.4)
     if (src_ip=1.2.3.4)
@@ -1995,7 +2011,7 @@ route {
                                           # INVITE and to 15s if not
                                           # INVITE and to 15s if not
 }
 }
 
 
-5.23. t_reset_max_lifetime()
+5.23.  t_reset_max_lifetime()
 
 
    Resets the the maximum lifetime for the current INVITE or non-INVITE
    Resets the the maximum lifetime for the current INVITE or non-INVITE
    transaction to the default value (set using the tm module parameter
    transaction to the default value (set using the tm module parameter
@@ -2006,7 +2022,7 @@ route {
 
 
    See also: max_inv_lifetime, max_noninv_lifetime, t_set_max_lifetime.
    See also: max_inv_lifetime, max_noninv_lifetime, t_set_max_lifetime.
 
 
-   Example 1.61. t_reset_max_lifetime usage
+   Example 1.62. t_reset_max_lifetime usage
 ...
 ...
 route {
 route {
 ...
 ...
@@ -2014,7 +2030,7 @@ route {
 ...
 ...
 }
 }
 
 
-5.24. t_set_retr(retr_t1_interval, retr_t2_interval)
+5.24.  t_set_retr(retr_t1_interval, retr_t2_interval)
 
 
    Sets the retr_t1_interval and retr_t2_interval for the current
    Sets the retr_t1_interval and retr_t2_interval for the current
    transaction or for transactions created during the same script
    transaction or for transactions created during the same script
@@ -2044,7 +2060,7 @@ route {
 
 
    See also: retr_timer1, retr_timer2, t_reset_retr().
    See also: retr_timer1, retr_timer2, t_reset_retr().
 
 
-   Example 1.62. t_set_retr usage
+   Example 1.63. t_set_retr usage
 ...
 ...
 route {
 route {
         t_set_retr(250, 0); # set only T1 to 250 ms
         t_set_retr(250, 0); # set only T1 to 250 ms
@@ -2060,7 +2076,7 @@ branch_route[1] {
         }
         }
 }
 }
 
 
-5.25. t_reset_retr()
+5.25.  t_reset_retr()
 
 
    Resets the retr_timer1 and retr_timer2 for the current transaction to
    Resets the retr_timer1 and retr_timer2 for the current transaction to
    the default values (set using the tm module parameters retr_timer1 and
    the default values (set using the tm module parameters retr_timer1 and
@@ -2071,7 +2087,7 @@ branch_route[1] {
 
 
    See also: retr_timer1, retr_timer2, t_set_retr.
    See also: retr_timer1, retr_timer2, t_set_retr.
 
 
-   Example 1.63. t_reset_retr usage
+   Example 1.64. t_reset_retr usage
 ...
 ...
 route {
 route {
 ...
 ...
@@ -2079,7 +2095,7 @@ route {
 ...
 ...
 }
 }
 
 
-5.26. t_set_auto_inv_100(0|1)
+5.26.  t_set_auto_inv_100(0|1)
 
 
    Switch automatically sending 100 replies to INVITEs on/off on a per
    Switch automatically sending 100 replies to INVITEs on/off on a per
    transaction basis. It overrides the auto_inv_100 value for the current
    transaction basis. It overrides the auto_inv_100 value for the current
@@ -2087,7 +2103,7 @@ route {
 
 
    See also: auto_inv_100.
    See also: auto_inv_100.
 
 
-   Example 1.64. t_set_auto_inv_100 usage
+   Example 1.65. t_set_auto_inv_100 usage
 ...
 ...
 route {
 route {
 ...
 ...
@@ -2096,13 +2112,13 @@ route {
 ...
 ...
 }
 }
 
 
-5.27. t_branch_timeout()
+5.27.  t_branch_timeout()
 
 
    Returns true if the failure route is executed for a branch that did
    Returns true if the failure route is executed for a branch that did
    timeout. It can be used from failure_route and branch-failure event
    timeout. It can be used from failure_route and branch-failure event
    route.
    route.
 
 
-   Example 1.65. t_branch_timeout usage
+   Example 1.66. t_branch_timeout usage
 ...
 ...
 failure_route[0]{
 failure_route[0]{
         if (t_branch_timeout()){
         if (t_branch_timeout()){
@@ -2111,14 +2127,14 @@ failure_route[0]{
         }
         }
 }
 }
 
 
-5.28. t_branch_replied()
+5.28.  t_branch_replied()
 
 
    Returns true if the failure route is executed for a branch that did
    Returns true if the failure route is executed for a branch that did
    receive at least one reply in the past (the "current" reply is not
    receive at least one reply in the past (the "current" reply is not
    taken into account). It can be used from failure_route and
    taken into account). It can be used from failure_route and
    branch-failure event route.
    branch-failure event route.
 
 
-   Example 1.66. t_branch_replied usage
+   Example 1.67. t_branch_replied usage
 ...
 ...
 failure_route[0]{
 failure_route[0]{
         if (t_branch_timeout()){
         if (t_branch_timeout()){
@@ -2130,12 +2146,12 @@ failure_route[0]{
         }
         }
 }
 }
 
 
-5.29. t_any_timeout()
+5.29.  t_any_timeout()
 
 
    Returns true if at least one of the current transactions branches did
    Returns true if at least one of the current transactions branches did
    timeout.
    timeout.
 
 
-   Example 1.67. t_any_timeout usage
+   Example 1.68. t_any_timeout usage
 ...
 ...
 failure_route[0]{
 failure_route[0]{
         if (!t_branch_timeout()){
         if (!t_branch_timeout()){
@@ -2146,13 +2162,13 @@ failure_route[0]{
         }
         }
 }
 }
 
 
-5.30. t_any_replied()
+5.30.  t_any_replied()
 
 
    Returns true if at least one of the current transactions branches did
    Returns true if at least one of the current transactions branches did
    receive some reply in the past. If called from a failure or onreply
    receive some reply in the past. If called from a failure or onreply
    route, the "current" reply is not taken into account.
    route, the "current" reply is not taken into account.
 
 
-   Example 1.68. t_any_replied usage
+   Example 1.69. t_any_replied usage
 ...
 ...
 onreply_route[0]{
 onreply_route[0]{
         if (!t_any_replied()){
         if (!t_any_replied()){
@@ -2161,12 +2177,12 @@ onreply_route[0]{
         }
         }
 }
 }
 
 
-5.31. t_grep_status("code")
+5.31.  t_grep_status("code")
 
 
    Returns true if "code" is the final reply received (or locally
    Returns true if "code" is the final reply received (or locally
    generated) in at least one of the current transactions branches.
    generated) in at least one of the current transactions branches.
 
 
-   Example 1.69. t_grep_status usage
+   Example 1.70. t_grep_status usage
 ...
 ...
 onreply_route[0]{
 onreply_route[0]{
         if (t_grep_status("486")){
         if (t_grep_status("486")){
@@ -2175,11 +2191,11 @@ onreply_route[0]{
         }
         }
 }
 }
 
 
-5.32. t_is_canceled()
+5.32.  t_is_canceled()
 
 
    Returns true if the current transaction was canceled.
    Returns true if the current transaction was canceled.
 
 
-   Example 1.70. t_is_canceled usage
+   Example 1.71. t_is_canceled usage
 ...
 ...
 failure_route[0]{
 failure_route[0]{
         if (t_is_canceled()){
         if (t_is_canceled()){
@@ -2188,12 +2204,12 @@ failure_route[0]{
         }
         }
 }
 }
 
 
-5.33. t_is_expired()
+5.33.  t_is_expired()
 
 
    Returns true if the current transaction has already been expired, i.e.
    Returns true if the current transaction has already been expired, i.e.
    the max_inv_lifetime/max_noninv_lifetime interval has already elapsed.
    the max_inv_lifetime/max_noninv_lifetime interval has already elapsed.
 
 
-   Example 1.71. t_is_expired usage
+   Example 1.72. t_is_expired usage
 ...
 ...
 failure_route[0]{
 failure_route[0]{
         if (t_is_expired()){
         if (t_is_expired()){
@@ -2202,7 +2218,7 @@ failure_route[0]{
         }
         }
 }
 }
 
 
-5.34. t_relay_cancel()
+5.34.  t_relay_cancel()
 
 
    Forwards the CANCEL if the corresponding INVITE transaction exists. The
    Forwards the CANCEL if the corresponding INVITE transaction exists. The
    function is supposed to be used at the very beginning of the script,
    function is supposed to be used at the very beginning of the script,
@@ -2214,7 +2230,7 @@ failure_route[0]{
    CANCELs were successfully sent to the pending branches, true if the
    CANCELs were successfully sent to the pending branches, true if the
    INVITE was not found, and false in case of any error.
    INVITE was not found, and false in case of any error.
 
 
-   Example 1.72. t_relay_cancel usage
+   Example 1.73. t_relay_cancel usage
 if (method == CANCEL) {
 if (method == CANCEL) {
         if (!t_relay_cancel()) {  # implicit drop if relaying was successful,
         if (!t_relay_cancel()) {  # implicit drop if relaying was successful,
                                   # nothing to do
                                   # nothing to do
@@ -2227,7 +2243,7 @@ if (method == CANCEL) {
         # do the same as for INVITEs
         # do the same as for INVITEs
 }
 }
 
 
-5.35. t_lookup_cancel([1])
+5.35.  t_lookup_cancel([1])
 
 
    Returns true if the corresponding INVITE transaction exists for a
    Returns true if the corresponding INVITE transaction exists for a
    CANCEL request. The function can be called at the beginning of the
    CANCEL request. The function can be called at the beginning of the
@@ -2241,7 +2257,7 @@ if (method == CANCEL) {
    overwritten with the flags of the INVITE. isflagset() can be used to
    overwritten with the flags of the INVITE. isflagset() can be used to
    check the flags of the previously forwarded INVITE in this case.
    check the flags of the previously forwarded INVITE in this case.
 
 
-   Example 1.73. t_lookup_cancel usage
+   Example 1.74. t_lookup_cancel usage
 if (method == CANCEL) {
 if (method == CANCEL) {
         if (t_lookup_cancel()) {
         if (t_lookup_cancel()) {
                 log("INVITE transaction exists");
                 log("INVITE transaction exists");
@@ -2259,7 +2275,7 @@ if (method == CANCEL) {
         # do the same as for INVITEs
         # do the same as for INVITEs
 }
 }
 
 
-5.36. t_drop_replies([mode])
+5.36.  t_drop_replies([mode])
 
 
    Drops all the previously received replies in failure_route block to
    Drops all the previously received replies in failure_route block to
    make sure that none of them is picked up again.
    make sure that none of them is picked up again.
@@ -2271,7 +2287,7 @@ if (method == CANCEL) {
    Dropping replies works only if a new branch is added to the
    Dropping replies works only if a new branch is added to the
    transaction, or it is explicitly replied in the script!
    transaction, or it is explicitly replied in the script!
 
 
-   Example 1.74. t_drop_replies() usage
+   Example 1.75. t_drop_replies() usage
 ...
 ...
 failure_route[0]{
 failure_route[0]{
         if (t_check_status("5[0-9][0-9]")){
         if (t_check_status("5[0-9][0-9]")){
@@ -2287,7 +2303,7 @@ failure_route[0]{
         }
         }
 }
 }
 
 
-5.37. t_save_lumps()
+5.37.  t_save_lumps()
 
 
    Forces the modifications of the processed SIP message to be saved in
    Forces the modifications of the processed SIP message to be saved in
    shared memory before t_relay() is called. The new branches which are
    shared memory before t_relay() is called. The new branches which are
@@ -2302,7 +2318,7 @@ failure_route[0]{
    The transaction must be created by t_newtran() before calling
    The transaction must be created by t_newtran() before calling
    t_save_lumps().
    t_save_lumps().
 
 
-   Example 1.75. t_save_lumps() usage
+   Example 1.76. t_save_lumps() usage
 route {
 route {
         ...
         ...
         t_newtran();
         t_newtran();
@@ -2327,7 +2343,7 @@ failure_route[1] {
         t_relay();
         t_relay();
 }
 }
 
 
-5.38. t_load_contacts()
+5.38.  t_load_contacts()
 
 
    This is the first of the three functions that can be used to implement
    This is the first of the three functions that can be used to implement
    serial/parallel forking based on q and +sip.instance values of
    serial/parallel forking based on q and +sip.instance values of
@@ -2361,7 +2377,7 @@ failure_route[1] {
 
 
    This function can be used from REQUEST_ROUTE and FAILURE_ROUTE.
    This function can be used from REQUEST_ROUTE and FAILURE_ROUTE.
 
 
-   Example 1.76. t_load_contacts usage
+   Example 1.77. t_load_contacts usage
 ...
 ...
 if (!t_load_contacts()) {
 if (!t_load_contacts()) {
         sl_send_reply("500", "Server Internal Error - Cannot load contacts");
         sl_send_reply("500", "Server Internal Error - Cannot load contacts");
@@ -2369,7 +2385,7 @@ if (!t_load_contacts()) {
 };
 };
 ...
 ...
 
 
-5.39. t_next_contacts()
+5.39.  t_next_contacts()
 
 
    Function t_next_contacts() is the second of the three functions that
    Function t_next_contacts() is the second of the three functions that
    can be used to implement serial/parallel forking based on the q value
    can be used to implement serial/parallel forking based on the q value
@@ -2402,7 +2418,7 @@ if (!t_load_contacts()) {
    contact_flows_avp are not anymore set. Based on that test, you can then
    contact_flows_avp are not anymore set. Based on that test, you can then
    use t_set_fr() function to set timers according to your needs.
    use t_set_fr() function to set timers according to your needs.
 
 
-   Example 1.77. t_next_contacts usage
+   Example 1.78. t_next_contacts usage
 ...
 ...
 # First call after t_load_contacts() when transaction does not exist yet
 # First call after t_load_contacts() when transaction does not exist yet
 # and contacts should be available
 # and contacts should be available
@@ -2421,7 +2437,7 @@ if (!t_next_contacts()) {
 };
 };
 ...
 ...
 
 
-5.40. t_next_contact_flow()
+5.40.  t_next_contact_flow()
 
 
    Function t_next_contact_flow() is the last of the three functions that
    Function t_next_contact_flow() is the last of the three functions that
    can be used to implement serial/parallel forking based on the q value
    can be used to implement serial/parallel forking based on the q value
@@ -2439,7 +2455,7 @@ if (!t_next_contacts()) {
    thus there was nothing to do, and returns -1 in case of an error (see
    thus there was nothing to do, and returns -1 in case of an error (see
    syslog). This function can be used from a BRANCH_FAILURE event route.
    syslog). This function can be used from a BRANCH_FAILURE event route.
 
 
-   Example 1.78. t_next_contact_flow usage
+   Example 1.79. t_next_contact_flow usage
 ...
 ...
 event_route[tm:branch-failure:outbound]
 event_route[tm:branch-failure:outbound]
 {
 {
@@ -2451,7 +2467,7 @@ event_route[tm:branch-failure:outbound]
         }
         }
 ...
 ...
 
 
-5.41. t_check_status(re)
+5.41.  t_check_status(re)
 
 
    Returns true if the regular expresion "re" match the reply code of the
    Returns true if the regular expresion "re" match the reply code of the
    response message as follows:
    response message as follows:
@@ -2462,14 +2478,14 @@ event_route[tm:branch-failure:outbound]
 
 
    This function can be used from ANY_ROUTE .
    This function can be used from ANY_ROUTE .
 
 
-   Example 1.79. t_check_status usage
+   Example 1.80. t_check_status usage
 ...
 ...
 if (t_check_status("(487)|(408)")) {
 if (t_check_status("(487)|(408)")) {
     log("487 or 408 negative reply\n");
     log("487 or 408 negative reply\n");
 }
 }
 ...
 ...
 
 
-5.42. t_check_trans()
+5.42.  t_check_trans()
 
 
    t_check_trans() can be used to quickly check if a message belongs or is
    t_check_trans() can be used to quickly check if a message belongs or is
    related to a transaction. It behaves differently for different types of
    related to a transaction. It behaves differently for different types of
@@ -2516,12 +2532,12 @@ Note
 
 
    See also: t_lookup_request(), t_lookup_cancel().
    See also: t_lookup_request(), t_lookup_cancel().
 
 
-   Example 1.80. t_check_trans usage
+   Example 1.81. t_check_trans usage
 if ( method == "CANCEL" && !t_check_trans())
 if ( method == "CANCEL" && !t_check_trans())
         sl_reply("403", "cancel out of the blue forbidden");
         sl_reply("403", "cancel out of the blue forbidden");
 # note: in this example t_check_trans() can be replaced by t_lookup_cancel()
 # note: in this example t_check_trans() can be replaced by t_lookup_cancel()
 
 
-5.43. t_set_disable_6xx(0|1)
+5.43.  t_set_disable_6xx(0|1)
 
 
    Turn off/on 6xx replies special rfc conformant handling on a per
    Turn off/on 6xx replies special rfc conformant handling on a per
    transaction basis. If turned off (t_set_disable_6xx("1")) 6XXs will be
    transaction basis. If turned off (t_set_disable_6xx("1")) 6XXs will be
@@ -2531,7 +2547,7 @@ if ( method == "CANCEL" && !t_check_trans())
 
 
    See also: disable_6xx_block.
    See also: disable_6xx_block.
 
 
-   Example 1.81. t_set_disable_6xx usage
+   Example 1.82. t_set_disable_6xx usage
 ...
 ...
 route {
 route {
 ...
 ...
@@ -2540,13 +2556,13 @@ route {
 ...
 ...
 }
 }
 
 
-5.44. t_set_disable_failover(0|1)
+5.44.  t_set_disable_failover(0|1)
 
 
    Turn off/on dns failover on a per transaction basis.
    Turn off/on dns failover on a per transaction basis.
 
 
    See also: use_dns_failover.
    See also: use_dns_failover.
 
 
-   Example 1.82. t_set_disable_failover usage
+   Example 1.83. t_set_disable_failover usage
 ...
 ...
 route {
 route {
 ...
 ...
@@ -2555,11 +2571,11 @@ route {
 ...
 ...
 }
 }
 
 
-5.45. t_set_disable_internal_reply(0|1)
+5.45.  t_set_disable_internal_reply(0|1)
 
 
    Turn off/on sending internally a SIP reply in case of relay errors.
    Turn off/on sending internally a SIP reply in case of relay errors.
 
 
-   Example 1.83. t_set_disable_internal_reply usage
+   Example 1.84. t_set_disable_internal_reply usage
 ...
 ...
 t_set_disable_internal_reply(1); # turn off sending internal reply on error
 t_set_disable_internal_reply(1); # turn off sending internal reply on error
 if(!t_relay()) {
 if(!t_relay()) {
@@ -2567,7 +2583,7 @@ if(!t_relay()) {
 }
 }
 ...
 ...
 
 
-5.46. t_replicate([params])
+5.46.  t_replicate([params])
 
 
    Replicate the SIP request to a specific address.
    Replicate the SIP request to a specific address.
 
 
@@ -2590,7 +2606,7 @@ if(!t_relay()) {
      * hostport - address in "host:port" format. It can be given via an
      * hostport - address in "host:port" format. It can be given via an
        AVP.
        AVP.
 
 
-   Example 1.84. t_replicate usage
+   Example 1.85. t_replicate usage
 ...
 ...
 # sent to 1.2.3.4:5060 over tcp
 # sent to 1.2.3.4:5060 over tcp
 t_replicate("sip:1.2.3.4:5060;transport=tcp");
 t_replicate("sip:1.2.3.4:5060;transport=tcp");
@@ -2603,7 +2619,7 @@ t_replicate("sip:$var(h);transport=tls");
 t_replicate_to_udp("1.2.3.4", "5060");
 t_replicate_to_udp("1.2.3.4", "5060");
 ...
 ...
 
 
-5.47. t_relay_to(proxy, flags)
+5.47.  t_relay_to(proxy, flags)
 
 
    Forward the SIP request to a specific address, controlling internal
    Forward the SIP request to a specific address, controlling internal
    behavior via flags.
    behavior via flags.
@@ -2624,7 +2640,7 @@ t_replicate_to_udp("1.2.3.4", "5060");
           + 0x02 - do not generate reply on internal error.
           + 0x02 - do not generate reply on internal error.
           + 0x04 - disable dns failover.
           + 0x04 - disable dns failover.
 
 
-   Example 1.85. t_relay_to usage
+   Example 1.86. t_relay_to usage
 ...
 ...
 # sent to 1.2.3.4:5060 over tcp
 # sent to 1.2.3.4:5060 over tcp
 t_relay_to("tcp:1.2.3.4:5060");
 t_relay_to("tcp:1.2.3.4:5060");
@@ -2636,7 +2652,7 @@ t_relay_to("tls:1.2.3.4");
 t_relay_to("0x01");
 t_relay_to("0x01");
 ...
 ...
 
 
-5.48. t_set_no_e2e_cancel_reason(0|1)
+5.48.  t_set_no_e2e_cancel_reason(0|1)
 
 
    Enables/disables reason header (RFC 3326) copying from the triggering
    Enables/disables reason header (RFC 3326) copying from the triggering
    received CANCEL to the generated hop-by-hop CANCEL. 0 enables and 1
    received CANCEL to the generated hop-by-hop CANCEL. 0 enables and 1
@@ -2647,7 +2663,7 @@ t_relay_to("0x01");
 
 
    See also: e2e_cancel_reason.
    See also: e2e_cancel_reason.
 
 
-   Example 1.86. t_set_no_e2e_cancel_reason usage
+   Example 1.87. t_set_no_e2e_cancel_reason usage
 ...
 ...
 route {
 route {
 ...
 ...
@@ -2657,7 +2673,7 @@ opying
 ...
 ...
 }
 }
 
 
-5.49. t_is_set(target)
+5.49.  t_is_set(target)
 
 
    Return true if the attribute specified by 'target' is set for
    Return true if the attribute specified by 'target' is set for
    transaction.
    transaction.
@@ -2670,13 +2686,13 @@ opying
      * onreply_route - the function returns true if an onreply route is
      * onreply_route - the function returns true if an onreply route is
        set to be executed.
        set to be executed.
 
 
-   Example 1.87. t_replicate usage
+   Example 1.88. t_replicate usage
 ...
 ...
 if(!t_is_set("failure_route"))
 if(!t_is_set("failure_route"))
     LM_DBG("no failure route will be executed for current transaction\n");
     LM_DBG("no failure route will be executed for current transaction\n");
 ...
 ...
 
 
-5.50. t_use_uac_headers()
+5.50.  t_use_uac_headers()
 
 
    Set internal flags to tell tm to use UAC side for building headers for
    Set internal flags to tell tm to use UAC side for building headers for
    local generated requests (ACK, CANCEL) - useful when changing From/To
    local generated requests (ACK, CANCEL) - useful when changing From/To
@@ -2684,12 +2700,12 @@ if(!t_is_set("failure_route"))
 
 
    It returns true.
    It returns true.
 
 
-   Example 1.88. t_use_uac_headers usage
+   Example 1.89. t_use_uac_headers usage
 ...
 ...
 t_use_uac_headers();
 t_use_uac_headers();
 ...
 ...
 
 
-5.51. t_is_retr_async_reply()
+5.51.  t_is_retr_async_reply()
 
 
    Check to see if the reply is a retransmitted reply on a transaction
    Check to see if the reply is a retransmitted reply on a transaction
    that is currently suspended asynchronously (suspended during reply
    that is currently suspended asynchronously (suspended during reply
@@ -2703,7 +2719,7 @@ t_use_uac_headers();
    returns true if the transaction is currently reply suspended or false
    returns true if the transaction is currently reply suspended or false
    if not.
    if not.
 
 
-   Example 1.89. t_is_retr_async_reply usage
+   Example 1.90. t_is_retr_async_reply usage
 ...
 ...
 if (t_is_retr_async_reply()) {
 if (t_is_retr_async_reply()) {
         xlog("L_DBG", "Dropping retransmitted reply which is still currently sus
         xlog("L_DBG", "Dropping retransmitted reply which is still currently sus
@@ -2792,7 +2808,7 @@ end of body
 
 
 6.2. Functions
 6.2. Functions
 
 
-6.2.1. register_tmcb(cb_type, cb_func)
+6.2.1.  register_tmcb(cb_type, cb_func)
 
 
    For programmatic use only--register a function to be called back on an
    For programmatic use only--register a function to be called back on an
    event. See t_hooks.h for more details.
    event. See t_hooks.h for more details.
@@ -2801,7 +2817,7 @@ end of body
      * cb_type - Callback type.
      * cb_type - Callback type.
      * cb_func - Callback function.
      * cb_func - Callback function.
 
 
-6.2.2. load_tm(*import_structure)
+6.2.2.  load_tm(*import_structure)
 
 
    For programmatic use only--import exported TM functions. See the acc
    For programmatic use only--import exported TM functions. See the acc
    module for an example of use.
    module for an example of use.
@@ -2809,7 +2825,7 @@ end of body
    Meaning of the parameters is as follows:
    Meaning of the parameters is as follows:
      * import_structure - Pointer to the import structure.
      * import_structure - Pointer to the import structure.
 
 
-6.2.3. int t_suspend(struct sip_msg *msg, unsigned int *hash_index, unsigned
+6.2.3.  int t_suspend(struct sip_msg *msg, unsigned int *hash_index, unsigned
 int *label)
 int *label)
 
 
    For programmatic use only. This function together with t_continue() can
    For programmatic use only. This function together with t_continue() can
@@ -2847,7 +2863,7 @@ int *label)
    t_suspend() should return 0 to make sure that the script processing
    t_suspend() should return 0 to make sure that the script processing
    does not continue.
    does not continue.
 
 
-6.2.4. int t_continue(unsigned int hash_index, unsigned int label, struct
+6.2.4.  int t_continue(unsigned int hash_index, unsigned int label, struct
 action *route)
 action *route)
 
 
    For programmatic use only. This function is the pair of t_suspend(),
    For programmatic use only. This function is the pair of t_suspend(),
@@ -2863,7 +2879,7 @@ action *route)
 
 
    Return value: 0 - success, <0 - error.
    Return value: 0 - success, <0 - error.
 
 
-6.2.5. int t_cancel_suspend(unsigned int hash_index, unsigned int label)
+6.2.5.  int t_cancel_suspend(unsigned int hash_index, unsigned int label)
 
 
    For programmatic use only. This function is for revoking t_suspend()
    For programmatic use only. This function is for revoking t_suspend()
    from the same process as it was executed before. t_cancel_suspend() can
    from the same process as it was executed before. t_cancel_suspend() can
@@ -2883,7 +2899,7 @@ action *route)
 
 
    7.1. event_route[tm:branch-failure]
    7.1. event_route[tm:branch-failure]
 
 
-7.1. event_route[tm:branch-failure]
+7.1.  event_route[tm:branch-failure]
 
 
    Named branch failure routes can be defined to run when when a failure
    Named branch failure routes can be defined to run when when a failure
    response is received. This allows handling failures on individual
    response is received. This allows handling failures on individual
@@ -2893,7 +2909,7 @@ action *route)
    enabled with the t_on_branch_failure function. This event_route uses
    enabled with the t_on_branch_failure function. This event_route uses
    the BRANCH_FAILURE_ROUTE route type.
    the BRANCH_FAILURE_ROUTE route type.
 
 
-   Example 1.90. event_route[tm:branch-failure] usage
+   Example 1.91. event_route[tm:branch-failure] usage
 ...
 ...
 route {
 route {
     t_on_branch_failure("myroute");
     t_on_branch_failure("myroute");

+ 21 - 0
modules/tm/doc/params.xml

@@ -1407,4 +1407,25 @@ modparam("tm", "dns_reuse_rcv_socket", 1)
 		</example>
 		</example>
 	</section>
 	</section>
 
 
+	<section id="tm.p.xavp_contact">
+		<title><varname>xavp_contact</varname> (string)</title>
+		<para>
+		The name of XAVP storing the attributes per contact. This must be the same as
+		the usrloc parameter <varname>xavp_contacts</varname>.
+		</para>
+		<para>
+		<emphasis>
+			Default value is <quote>NULL</quote>.
+		</emphasis>
+		</para>
+		<example>
+		<title>Set <varname>xavp_contact</varname> parameter</title>
+		<programlisting format="linespecific">
+...
+modparam("tm|usrloc", "xavp_contact", "ulattrs")
+...
+</programlisting>
+		</example>
+	</section>
+
 </section>
 </section>

+ 48 - 4
modules/tm/t_serial.c

@@ -32,6 +32,7 @@
 #include "../../dset.h"
 #include "../../dset.h"
 #include "../../parser/msg_parser.h"
 #include "../../parser/msg_parser.h"
 #include "../../ut.h"
 #include "../../ut.h"
+#include "../../xavp.h"
 #include "config.h"
 #include "config.h"
 #include "t_funcs.h"
 #include "t_funcs.h"
 #include "t_reply.h"
 #include "t_reply.h"
@@ -40,6 +41,8 @@
 /* usr_avp flag for sequential forking */
 /* usr_avp flag for sequential forking */
 #define Q_FLAG      (1<<2)
 #define Q_FLAG      (1<<2)
 
 
+extern str ulattrs_xavp_name;
+
 /* Struture where information regarding contacts is stored */
 /* Struture where information regarding contacts is stored */
 struct contact {
 struct contact {
 	str uri;
 	str uri;
@@ -53,6 +56,7 @@ struct contact {
 	unsigned int flags;
 	unsigned int flags;
 	unsigned short q_flag;
 	unsigned short q_flag;
 	struct contact *next;
 	struct contact *next;
+	sr_xavp_t *ulattrs;
 };
 };
 
 
 struct instance_list {
 struct instance_list {
@@ -97,7 +101,7 @@ static str ua_name = {"ua", 2};
 
 
 void add_contacts_avp(str *uri, str *dst_uri, str *path, str *sock_str,
 void add_contacts_avp(str *uri, str *dst_uri, str *path, str *sock_str,
 		unsigned int flags, unsigned int q_flag, str *instance,
 		unsigned int flags, unsigned int q_flag, str *instance,
-		str *ruid, str *location_ua)
+		str *ruid, str *location_ua, sr_xavp_t *ulattrs_xavp)
 {
 {
 	sr_xavp_t *record;
 	sr_xavp_t *record;
 	sr_xval_t val;
 	sr_xval_t val;
@@ -151,6 +155,8 @@ void add_contacts_avp(str *uri, str *dst_uri, str *path, str *sock_str,
 		xavp_add_value(&ua_name, &val, &record);
 		xavp_add_value(&ua_name, &val, &record);
 	}
 	}
 
 
+	xavp_add(xavp_clone_level_nodata(ulattrs_xavp), &record);
+
 	val.type = SR_XTYPE_XAVP;
 	val.type = SR_XTYPE_XAVP;
 	val.v.xavp = record;
 	val.v.xavp = record;
 	if(xavp_add_value(&contacts_avp, &val, NULL)==NULL) {
 	if(xavp_add_value(&contacts_avp, &val, NULL)==NULL) {
@@ -215,6 +221,10 @@ int t_load_contacts(struct sip_msg* msg, char* key, char* value)
 		contacts->instance = msg->instance;
 		contacts->instance = msg->instance;
 		contacts->ruid = msg->ruid;
 		contacts->ruid = msg->ruid;
 		contacts->location_ua = msg->location_ua;
 		contacts->location_ua = msg->location_ua;
+		if (ulattrs_xavp_name.s != NULL)
+		{
+			contacts->ulattrs = xavp_get_by_index(&ulattrs_xavp_name, 0, NULL);
+		}
 		first_idx = 0;
 		first_idx = 0;
 	} else {
 	} else {
 		/* Insert first branch to first contact */
 		/* Insert first branch to first contact */
@@ -234,6 +244,10 @@ int t_load_contacts(struct sip_msg* msg, char* key, char* value)
 		contacts->ruid.len = branch->ruid_len;
 		contacts->ruid.len = branch->ruid_len;
 		contacts->location_ua.s = branch->location_ua;
 		contacts->location_ua.s = branch->location_ua;
 		contacts->location_ua.len = branch->location_ua_len;
 		contacts->location_ua.len = branch->location_ua_len;
+		if (ulattrs_xavp_name.s != NULL)
+		{
+			contacts->ulattrs = xavp_get_by_index(&ulattrs_xavp_name, 1, NULL);
+		}
 		first_idx = 1;
 		first_idx = 1;
 	}
 	}
 
 
@@ -249,6 +263,7 @@ int t_load_contacts(struct sip_msg* msg, char* key, char* value)
 			return -1;
 			return -1;
 		}
 		}
 
 
+		memset(next, 0, sizeof(struct contact));
 		next->uri.s = branch->uri;
 		next->uri.s = branch->uri;
 		next->uri.len = branch->len;
 		next->uri.len = branch->len;
 		next->dst_uri.s = branch->dst_uri;
 		next->dst_uri.s = branch->dst_uri;
@@ -264,6 +279,10 @@ int t_load_contacts(struct sip_msg* msg, char* key, char* value)
 		next->ruid.len = branch->ruid_len;
 		next->ruid.len = branch->ruid_len;
 		next->location_ua.s = branch->location_ua;
 		next->location_ua.s = branch->location_ua;
 		next->location_ua.len = branch->location_ua_len;
 		next->location_ua.len = branch->location_ua_len;
+		if (ulattrs_xavp_name.s != NULL)
+		{
+			next->ulattrs = xavp_get_by_index(&ulattrs_xavp_name, idx + 1, NULL);
+		}
 		next->next = (struct contact *)0;
 		next->next = (struct contact *)0;
 
 
 		prev = (struct contact *)0;
 		prev = (struct contact *)0;
@@ -320,13 +339,17 @@ int t_load_contacts(struct sip_msg* msg, char* key, char* value)
 
 
 		add_contacts_avp(&(curr->uri), &(curr->dst_uri), &(curr->path),
 		add_contacts_avp(&(curr->uri), &(curr->dst_uri), &(curr->path),
 				&sock_str, curr->flags, curr->q_flag,
 				&sock_str, curr->flags, curr->q_flag,
-				&(curr->instance), &(curr->ruid), &(curr->location_ua));
+				&(curr->instance), &(curr->ruid), &(curr->location_ua),
+				curr->ulattrs);
 
 
 		curr = curr->next;
 		curr = curr->next;
 	}
 	}
 
 
 	/* Clear all branches */
 	/* Clear all branches */
 	clear_branches();
 	clear_branches();
+	if (ulattrs_xavp_name.s != NULL){
+		xavp_rm_by_name(&ulattrs_xavp_name, 1, NULL);
+	}
 
 
 	/* Free contact list */
 	/* Free contact list */
 	free_contact_list(contacts);
 	free_contact_list(contacts);
@@ -336,7 +359,7 @@ int t_load_contacts(struct sip_msg* msg, char* key, char* value)
 
 
 void add_contact_flows_avp(str *uri, str *dst_uri, str *path, str *sock_str,
 void add_contact_flows_avp(str *uri, str *dst_uri, str *path, str *sock_str,
 		unsigned int flags, str *instance, str *ruid,
 		unsigned int flags, str *instance, str *ruid,
-		str *location_ua)
+		str *location_ua, sr_xavp_t *ulattrs_xavp)
 {
 {
 	sr_xavp_t *record;
 	sr_xavp_t *record;
 	sr_xval_t val;
 	sr_xval_t val;
@@ -382,6 +405,8 @@ void add_contact_flows_avp(str *uri, str *dst_uri, str *path, str *sock_str,
 		xavp_add_value(&ua_name, &val, &record);
 		xavp_add_value(&ua_name, &val, &record);
 	}
 	}
 
 
+	xavp_add(ulattrs_xavp, &record);
+
 	val.type = SR_XTYPE_INT;
 	val.type = SR_XTYPE_INT;
 	val.v.i = flags;
 	val.v.i = flags;
 	xavp_add_value(&flags_name, &val, &record);
 	xavp_add_value(&flags_name, &val, &record);
@@ -516,6 +541,12 @@ int t_next_contacts(struct sip_msg* msg, char* key, char* value)
 		location_ua.len = 0;
 		location_ua.len = 0;
 	}
 	}
 
 
+	if (ulattrs_xavp_name.s != NULL)
+	{
+		vavp = xavp_extract(&ulattrs_xavp_name, &xavp->val.v.xavp);
+		xavp_insert(vavp, 0, NULL);
+	}
+
 	/* Rewrite Request-URI */
 	/* Rewrite Request-URI */
 	rewrite_uri(msg, &uri);
 	rewrite_uri(msg, &uri);
 
 
@@ -627,8 +658,9 @@ int t_next_contacts(struct sip_msg* msg, char* key, char* value)
 				ilp = ilp->next;
 				ilp = ilp->next;
 			}
 			}
 			if (ilp) {
 			if (ilp) {
+				vavp = (ulattrs_xavp_name.s != NULL)?xavp_extract(&ulattrs_xavp_name, &xavp->val.v.xavp):NULL;
 				add_contact_flows_avp(&uri, &dst_uri, &path, &sock_str,
 				add_contact_flows_avp(&uri, &dst_uri, &path, &sock_str,
-						flags, &instance, &ruid, &location_ua);
+						flags, &instance, &ruid, &location_ua, vavp);
 				goto check_q_flag;
 				goto check_q_flag;
 			}
 			}
 			if (!q_flag) {
 			if (!q_flag) {
@@ -672,6 +704,12 @@ int t_next_contacts(struct sip_msg* msg, char* key, char* value)
 			return -1;
 			return -1;
 		}
 		}
 
 
+		if (ulattrs_xavp_name.s != NULL)
+		{
+			vavp = xavp_extract(&ulattrs_xavp_name, &xavp->val.v.xavp);
+			xavp_insert(vavp, nr_branches, NULL);
+		}
+
 check_q_flag:
 check_q_flag:
 		if (q_flag) {
 		if (q_flag) {
 			free_instance_list(il);
 			free_instance_list(il);
@@ -808,6 +846,12 @@ int t_next_contact_flow(struct sip_msg* msg, char* key, char* value)
 			return -1;
 			return -1;
 		}
 		}
 
 
+		if (ulattrs_xavp_name.s != NULL)
+		{
+			vavp = xavp_extract(&ulattrs_xavp_name, &xavp->val.v.xavp);
+			xavp_insert(vavp, nr_branches, NULL);
+		}
+
 		xavp_rm(xavp, NULL);
 		xavp_rm(xavp, NULL);
 		return 1;
 		return 1;
 next_xavp:
 next_xavp:

+ 2 - 0
modules/tm/tm.c

@@ -268,6 +268,7 @@ static char *fr_inv_timer_param = 0 /*FR_INV_TIMER_AVP*/;
 
 
 str contacts_avp = {0, 0};
 str contacts_avp = {0, 0};
 str contact_flows_avp = {0, 0};
 str contact_flows_avp = {0, 0};
+str ulattrs_xavp_name = {NULL, 0};
 
 
 int tm_remap_503_500 = 1;
 int tm_remap_503_500 = 1;
 
 
@@ -512,6 +513,7 @@ static param_export_t params[]={
 	{"local_cancel_reason", PARAM_INT, &default_tm_cfg.local_cancel_reason   },
 	{"local_cancel_reason", PARAM_INT, &default_tm_cfg.local_cancel_reason   },
 	{"e2e_cancel_reason",   PARAM_INT, &default_tm_cfg.e2e_cancel_reason     },
 	{"e2e_cancel_reason",   PARAM_INT, &default_tm_cfg.e2e_cancel_reason     },
 #endif /* CANCEL_REASON_SUPPORT */
 #endif /* CANCEL_REASON_SUPPORT */
+	{"xavp_contact",        PARAM_STR, &ulattrs_xavp_name                    },
 	{0,0,0}
 	{0,0,0}
 };
 };
 
 

+ 4 - 2
modules/usrloc/README

@@ -807,8 +807,10 @@ modparam("usrloc", "timer_procs", 4)
 
 
 3.34. xavp_contact (string)
 3.34. xavp_contact (string)
 
 
-   The name of XAVP storring the attributes per contact. They are saved in
-   location record and restored at lookup.
+   The name of XAVP storing the attributes per contact. They are saved in
+   location record and restored at lookup. The tm module parameter
+   xavp_contact must also be set to the same value to use the
+   t_load_contacts and t_next_contacts functions.
 
 
    Default value is "NULL".
    Default value is "NULL".
 
 

+ 4 - 2
modules/usrloc/doc/usrloc_admin.xml

@@ -895,8 +895,10 @@ modparam("usrloc", "timer_procs", 4)
 	<section id="usrloc.p.xavp_contact">
 	<section id="usrloc.p.xavp_contact">
 		<title><varname>xavp_contact</varname> (string)</title>
 		<title><varname>xavp_contact</varname> (string)</title>
 		<para>
 		<para>
-		The name of XAVP storring the attributes per contact. They are saved
-		in location record and restored at lookup.
+		The name of XAVP storing the attributes per contact. They are saved
+		in location record and restored at lookup. The tm module parameter
+		<varname>xavp_contact</varname> must also be set to the same value to use the
+		<varname>t_load_contacts</varname> and <varname>t_next_contacts</varname> functions.
 		</para>
 		</para>
 		<para>
 		<para>
 		<emphasis>
 		<emphasis>