Presence Module

Anca-Maria Vamanu

   Voice Sistem SRL

Juha Heinanen

   TutPro Inc.

Edited by

Anca-Maria Vamanu

Juha Heinanen

   Copyright © 2006 Voice Sistem SRL

   Copyright © 2009 Juha Heinanen
     __________________________________________________________________

   Table of Contents

   1. Admin Guide

        1. Overview
        2. Dependencies

              2.1. Kamailio Modules
              2.2. External Libraries or Applications

        3. Parameters

              3.1. db_url(str)
              3.2. presentity_table(str)
              3.3. active_watchers_table(str)
              3.4. watchers_table(str)
              3.5. clean_period (int)
              3.6. cseq_offset (int)
              3.7. db_update_period (int)
              3.8. waitn_time (int)
              3.9. notifier_poll_rate (int)
              3.10. notifier_processes (int)
              3.11. force_delete (int)
              3.12. startup_mode (int)
              3.13. expires_offset (int)
              3.14. max_expires (int)
              3.15. min_expires (int)
              3.16. min_expires_action (int)
              3.17. server_address (str)
              3.18. subs_db_mode (int)
              3.19. publ_cache (int)
              3.20. subs_htable_size (int)
              3.21. pres_htable_size (int)
              3.22. send_fast_notify (int)
              3.23. enable_sphere_check (int)
              3.24. timeout_rm_subs (int)
              3.25. fetch_rows (integer)
              3.26. db_table_lock_type (integer)
              3.27. local_log_level (int)
              3.28. local_log_facility (int)
              3.29. subs_remove_match (int)
              3.30. xavp_cfg (str)
              3.31. retrieve_order (int)
              3.32. retrieve_order_by (str)
              3.33. sip_uri_match (int)
              3.34. enable_dmq (integer)
              3.35. pres_subs_mode (integer)
              3.36. delete_same_subs (integer)
              3.37. timer_mode (integer)
              3.38. subs_respond_200 (integer)

        4. Functions

              4.1. handle_publish([sender_uri])
              4.2. handle_subscribe([watcher_uri])
              4.3. pres_auth_status(watcher_uri, presentity_uri)
              4.4. pres_has_subscribers(presentity_uri, event)
              4.5. pres_refresh_watchers(uri, event, type[, file_uri,
                      filename])

              4.6. pres_update_watchers(uri, event)

        5. RPC Commands

              5.1. presence.cleanup
              5.2. presence.refreshWatchers
              5.3. presence.updateWatchers
              5.4. presence.presentity_list

        6. Exported Variables

              6.1. $subs(attr)
              6.2. $notify_reply(attr)

        7. Events

              7.1. presence:notify-reply

        8. Installation

   2. Developer Guide

        1. bind_presence(presence_api_t* api)
        2. add_event
        3. get_rules_doc
        4. get_auth_status
        5. apply_auth_nbody
        6. agg_nbody
        7. free_body
        8. aux_body_processing
        9. aux_free_body
        10. evs_publ_handl
        11. evs_subs_handl
        12. contains_event
        13. get_event_list
        14. update_watchers_status
        15. get_sphere
        16. get_presentity
        17. free_presentity

   List of Examples

   1.1. Set db_url parameter
   1.2. Set presentity_table parameter
   1.3. Set active_watchers_table parameter
   1.4. Set watchers_table parameter
   1.5. Set clean_period parameter
   1.6. Set cseq_offset parameter
   1.7. Set db_update_period parameter
   1.8. Set waitn_time parameter
   1.9. Set notifier_poll_rate parameter
   1.10. Set notifier_processes parameter
   1.11. Set force_delete parameter
   1.12. Set startup_mode parameter
   1.13. Set expires_offset parameter
   1.14. Set max_expires parameter
   1.15. Set min_expires parameter
   1.16. Set min_expires parameter
   1.17. Set server_address parameter
   1.18. Set subs_db_mode parameter
   1.19. Set publ_cache parameter
   1.20. Set subs_htable_size parameter
   1.21. Set pres_htable_size parameter
   1.22. Set send_fast_notify parameter
   1.23. Set enable_sphere_check parameter
   1.24. Set timeout_rm_subs parameter
   1.25. Set fetch_rows parameter
   1.26. Set db_table_lock_type parameter
   1.27. Set local_log_level parameter
   1.28. Set local_log_facility parameter
   1.29. Set subs_remove_match parameter
   1.30. Set xavp_cfg parameter
   1.31. Set retrieve_order parameter
   1.32. Set retrieve_order_by parameter
   1.33. Set sip_uri_match parameter
   1.34. Set enable_dmq parameter
   1.35. Set pres_subs_mode parameter
   1.36. Set delete_same_subs parameter
   1.37. Set timer_mode parameter
   1.38. Set subs_respond_200 parameter
   1.39. handle_publish usage
   1.40. handle_subscribe usage
   1.41. pres_auth_status usage
   1.42. pres_has_subscribers usage
   1.43. pres_refresh_watchers usage
   1.44. pres_update_watchers usage
   1.45. $subs(name) usage
   1.46. $notify_reply(name) usage
   1.47. $notify_reply(name) usage
   2.1. presence_api_t structure

Chapter 1. Admin Guide

   Table of Contents

   1. Overview
   2. Dependencies

        2.1. Kamailio Modules
        2.2. External Libraries or Applications

   3. Parameters

        3.1. db_url(str)
        3.2. presentity_table(str)
        3.3. active_watchers_table(str)
        3.4. watchers_table(str)
        3.5. clean_period (int)
        3.6. cseq_offset (int)
        3.7. db_update_period (int)
        3.8. waitn_time (int)
        3.9. notifier_poll_rate (int)
        3.10. notifier_processes (int)
        3.11. force_delete (int)
        3.12. startup_mode (int)
        3.13. expires_offset (int)
        3.14. max_expires (int)
        3.15. min_expires (int)
        3.16. min_expires_action (int)
        3.17. server_address (str)
        3.18. subs_db_mode (int)
        3.19. publ_cache (int)
        3.20. subs_htable_size (int)
        3.21. pres_htable_size (int)
        3.22. send_fast_notify (int)
        3.23. enable_sphere_check (int)
        3.24. timeout_rm_subs (int)
        3.25. fetch_rows (integer)
        3.26. db_table_lock_type (integer)
        3.27. local_log_level (int)
        3.28. local_log_facility (int)
        3.29. subs_remove_match (int)
        3.30. xavp_cfg (str)
        3.31. retrieve_order (int)
        3.32. retrieve_order_by (str)
        3.33. sip_uri_match (int)
        3.34. enable_dmq (integer)
        3.35. pres_subs_mode (integer)
        3.36. delete_same_subs (integer)
        3.37. timer_mode (integer)
        3.38. subs_respond_200 (integer)

   4. Functions

        4.1. handle_publish([sender_uri])
        4.2. handle_subscribe([watcher_uri])
        4.3. pres_auth_status(watcher_uri, presentity_uri)
        4.4. pres_has_subscribers(presentity_uri, event)
        4.5. pres_refresh_watchers(uri, event, type[, file_uri, filename])

        4.6. pres_update_watchers(uri, event)

   5. RPC Commands

        5.1. presence.cleanup
        5.2. presence.refreshWatchers
        5.3. presence.updateWatchers
        5.4. presence.presentity_list

   6. Exported Variables

        6.1. $subs(attr)
        6.2. $notify_reply(attr)

   7. Events

        7.1. presence:notify-reply

   8. Installation

1. Overview

   The Presence module implements the core functionality of SIP event
   notification. It handles PUBLISH and SUBSCRIBE messages and generates
   NOTIFY messages in a general, event independent way. It is extensible
   and allows registering events to it from other Kamailio modules.
   Supported SIP event packages are presence, presence.winfo, dialog;sla
   from the presence_xml module and message-summary from the presence_mwi
   module.

   The module can use database and memory storage (to improve
   performance). For subscriptions it supports the 4 storage modes: Memory
   Only, Write Back, Write Through and DB Only. For publishes, it stores
   the state documents in database only(because of the large size) and it
   can store a publish cache in memory to avoid unnecessary database
   queries. Read the subs_db_mode and publ_cache parameter sections to
   decide which is the best storage configuration for you.

   The module implements several API functions, that can be used by other
   modules. In fact, it can be used only as a resource module, or
   "library". This mode of operation is enabled if the db_url parameter is
   not set to any value.

   The Kamailio Presence module implements the specifications in: RFC3265,
   RFC3856, RFC3857, RFC3858.

2. Dependencies

   2.1. Kamailio Modules
   2.2. External Libraries or Applications

2.1. Kamailio Modules

   The following modules must be loaded before this module:
     * a database module.
     * sl.
     * tm.
     * dmq (only if replication is enabled).

2.2. External Libraries or Applications

     * libxml.

3. Parameters

   3.1. db_url(str)
   3.2. presentity_table(str)
   3.3. active_watchers_table(str)
   3.4. watchers_table(str)
   3.5. clean_period (int)
   3.6. cseq_offset (int)
   3.7. db_update_period (int)
   3.8. waitn_time (int)
   3.9. notifier_poll_rate (int)
   3.10. notifier_processes (int)
   3.11. force_delete (int)
   3.12. startup_mode (int)
   3.13. expires_offset (int)
   3.14. max_expires (int)
   3.15. min_expires (int)
   3.16. min_expires_action (int)
   3.17. server_address (str)
   3.18. subs_db_mode (int)
   3.19. publ_cache (int)
   3.20. subs_htable_size (int)
   3.21. pres_htable_size (int)
   3.22. send_fast_notify (int)
   3.23. enable_sphere_check (int)
   3.24. timeout_rm_subs (int)
   3.25. fetch_rows (integer)
   3.26. db_table_lock_type (integer)
   3.27. local_log_level (int)
   3.28. local_log_facility (int)
   3.29. subs_remove_match (int)
   3.30. xavp_cfg (str)
   3.31. retrieve_order (int)
   3.32. retrieve_order_by (str)
   3.33. sip_uri_match (int)
   3.34. enable_dmq (integer)
   3.35. pres_subs_mode (integer)
   3.36. delete_same_subs (integer)
   3.37. timer_mode (integer)
   3.38. subs_respond_200 (integer)

3.1. db_url(str)

   The database url.

   If set, the module is a fully operational presence server. Otherwise,
   it is used as a 'library', for its exported functions.

   Default value is “NULL”.

   Example 1.1. Set db_url parameter
...
modparam("presence", "db_url",
        "mysql://kamailio:kamailiorw@localhost/kamailio")
...

3.2. presentity_table(str)

   The name of the db table where PUBLISH presence information is stored.

   Default value is “presentity”.

   Example 1.2. Set presentity_table parameter
...
modparam("presence", "presentity_table", "presentity")
...

3.3. active_watchers_table(str)

   The name of the db table where active subscription information is
   stored.

   Default value is “active_watchers”.

   Example 1.3. Set active_watchers_table parameter
...
modparam("presence", "active_watchers_table", "active_watchers")
...

3.4. watchers_table(str)

   The name of the db table where subscription states are stored.

   Default value is “watchers”.

   Example 1.4. Set watchers_table parameter
...
modparam("presence", "watchers_table", "watchers")
...

3.5. clean_period (int)

   The period in seconds between checks if there are expired messages
   stored in database.

   Default value is “100”. A zero or negative value disables this
   activity.

   Example 1.5. Set clean_period parameter
...
modparam("presence", "clean_period", 100)
...

3.6. cseq_offset (int)

   The allowed offset between server and client cseq.

   Default value is “0”.

   Example 1.6. Set cseq_offset parameter
...
modparam("presence", "cseq_offset", 1)
...

3.7. db_update_period (int)

   The period at which to synchronize cached subscriber info with the
   database.

   Default value is “100”. A zero or negative value disables
   synchronization.

   Example 1.7. Set db_update_period parameter
...
modparam("presence", "db_update_period", 100)
...

3.8. waitn_time (int)

   The maximum time period that NOTIFY requests will be buffered for. The
   server will attempt to send NOTIFY requests within many seconds of a
   change occurring.

   Note: this parameter is only used when notifier_processes is greater
   than 0. When notifier_processes is less than or equal to 0 NOTIFY
   requests are sent immediately.

   Default value is “5”.

   Example 1.8. Set waitn_time parameter
...
modparam("presence", "waitn_time", 10)
...

3.9. notifier_poll_rate (int)

   The number of times per second that the notifier processes should check
   for work. Approximately 1/(waitn_time * notifier_poll_rate *
   notifier_processes) of the pending updates will be sent each time a
   notifier process runs.

   Separate notifier processes are only run when subs_db_mode is 3 (DB
   only mode).

   Default value is “10”.

   Example 1.9. Set notifier_poll_rate parameter
...
modparam("presence", "notifier_poll_rate", 20)
...

3.10. notifier_processes (int)

   The number of notifier processes that should be started.

   Separate notifier processes are only run when subs_db_mode is 3 (DB
   only mode).

   Note: setting this parameter to 0 when subs_db_mode is 3 keeps the old
   behaviour (sending NOTIFY requests immediately). This (old) behaviour
   is disabled by default in DB only mode because under load, when lots of
   NOTIFY requests can be sent on a dialog at the same time, there are
   race conditions which result in CSeq re-use.

   Default value is “1”.

   Example 1.10. Set notifier_processes parameter
...
modparam("presence", "notifier_processes", 2)
...

3.11. force_delete (int)

   Enabling this parameter will delete expired presentity records without
   updating watchers.

   Set this parameter to “1” to enable.

   Default value is “0”.

   Example 1.11. Set force_delete parameter
...
modparam("presence", "force_delete", 1)
...

3.12. startup_mode (int)

   Setting this parameter to 0 will provide startup related backward
   compatibility for some modules. Setting to 0 fixes presentity requests
   with low expires (e.g. time() + 1)

   Set this parameter to “0” to enable backward compatibility.

   Default value is “1”.

   Example 1.12. Set startup_mode parameter
...
modparam("presence", "startup_mode", 0)
...

3.13. expires_offset (int)

   The value in seconds that should be subtracted from the expires value
   when sending a 200OK for a publish. It is used for forcing the client
   to send an update before the old publish expires.

   Default value is “0”.

   Example 1.13. Set expires_offset parameter
...
modparam("presence", "expires_offset", 10)
...

3.14. max_expires (int)

   The maximum admissible expires value for PUBLISH/SUBSCRIBE message (in
   seconds).

   Default value is “3600”.

   Example 1.14. Set max_expires parameter
...
modparam("presence", "max_expires", 3600)
...

3.15. min_expires (int)

   The minimum admissible expires value for PUBLISH/SUBSCRIBE message (in
   seconds).

   If > 0 then min_expires_action parameter determines the response.

   Default value is “0”.

   Example 1.15. Set min_expires parameter
...
modparam("presence", "min_expires", 1800)
...

3.16. min_expires_action (int)

   The action to take when UA sends an expires value less then
   min_expires.

   Possible Values
     * 1 : RFC Compliant, returns “423 Interval Too Brief”
     * 2 : forces the min_expires value in the subscription

   If > 0 then min_expires_action parameter determines the response.

   Default value is “1”.

   Example 1.16. Set min_expires parameter
            ...
            modparam("presence", "min_expires", 1800)
            ...

3.17. server_address (str)

   The presence server address which will become the value of Contact
   header filed for 200 OK replies to SUBSCRIBE and PUBLISH and in NOTIFY
   messages.

   Example 1.17. Set server_address parameter
...
modparam("presence", "server_address", "sip:10.10.10.10:5060")
...

3.18. subs_db_mode (int)

   The presence module can utilize database for persistent subscription
   storage. If you use database, your subscriptions will survive machine
   restarts or SW crashes. The disadvantage is that accessing database can
   be time consuming. Therefore, presence module implements four database
   accessing modes:
     * 0 - This disables database completely. Only memory will be used.
       Subscriptions will not survive restart. Use this value if you need
       a really fast presence module and subscription persistence is not
       necessary or is provided by other means.
     * 1 - Write-Through scheme. Subscriptions are updated synchronously
       in database and in memory(used for read operations). Use this
       scheme if speed is not top priority, but it's important that no
       subscriptions will be lost during crash or reboot or if you have an
       external application that reads the state of the subscriptions from
       database and they need to be updated synchronously.
     * 2 - Write-Back scheme. This is a combination of previous two
       schemes. All changes are made to memory and database
       synchronization is done in the timer. The timer deletes all expired
       contacts and flushes all modified or new subscriptions to database.
       Use this scheme if you encounter high-load peaks and want them to
       process as fast as possible. Latency of this mode is much lower
       than latency of mode 1, but slightly higher than latency of mode 0.
       To control the interval at which data is flushed to database, set
       the db_update_period parameter.
     * 3 - DB-Only scheme. No memory cache is kept, all operations being
       directly performed with the database. The timer deletes all expired
       subscriptions from database. The mode is useful if you configure
       more servers sharing the same DB without any replication at SIP
       level. The mode may be slower due the high number of DB operation.

   Default value is 2 (Write-Back scheme).

   Example 1.18. Set subs_db_mode parameter
...
modparam("presence", "subs_db_mode", 1)
...

3.19. publ_cache (int)

   To improve performance, the presence module can operate in a couple of
   modes related to how PUBLISH data is stored. If publ_cache is 0, then
   no information is store in memory.

   If publ_cache is 1, then the module keeps in memory an index of the
   records stored in database, In this mode it keeps only the list of URIs
   and events, so it does not use much memory. The cache is used when a
   Subscription is received to check if there is any published state in
   database. This way unnecessary queries in presentity table are avoided.

   If publ_cache is 2, then the module keeps everything related to PUBLISH
   requests in memory, not storing anything in the database.

   Setting this parameter to 0 will disable the usage of the publish
   cache. This is desirable when you have more servers sharing the same
   database or there are other external entities inserting data into the
   presentity table.

   Default value is “1”.

   Example 1.19. Set publ_cache parameter
...
modparam("presence", "publ_cache", 0)
...

3.20. subs_htable_size (int)

   The size of the in-memory hash table to store subscription dialogs.
   This parameter will be used as the power of 2 when computing table
   size.

   Default value is “9 (512)”.

   Example 1.20. Set subs_htable_size parameter
...
modparam("presence", "subs_htable_size", 11)
...

3.21. pres_htable_size (int)

   The size of the in-memory hash table to store publish records. This
   parameter will be used as the power of 2 when computing table size.

   Default value is “9 (512)”.

   Example 1.21. Set pres_htable_size parameter
...
modparam("presence", "pres_htable_size", 11)
...

3.22. send_fast_notify (int)

   This parameter enables or disables the sending of an initial empty
   NOTIFY after a SUBSCRIBE/reSUBSCRIBE. This caused problems for MWI
   application, because some CPEs (like Samsung) fail to understand an
   empty NOTIFY to a message-summary event. This parameter is enabled by
   default, thus adhering to the standard.

   Default value is “1 ”.

   Example 1.22. Set send_fast_notify parameter
...
modparam("presence", "send_fast_notify", 0)
...

3.23. enable_sphere_check (int)

   This parameter is a flag that should be set if permission rules include
   sphere checking. The sphere information is expected to be present in
   the RPID body published by the presentity. The flag is introduced as
   this check requires extra processing that should be avoided if this
   feature is not supported by the clients.

   Default value is “0 ”.

   Example 1.23. Set enable_sphere_check parameter
...
modparam("presence", "enable_sphere_check", 1)
...

3.24. timeout_rm_subs (int)

   This parameter is a flag that should be set if subscriptions should be
   removed from the active_watchers when a NOTIFY times out. RFC3265
   section 3.2.2 defines this behaviour as a SHOULD, so by default it is
   on. Disabling this will keep subscriptions active on unreliable
   networks.

   Default value is “1”.

   Example 1.24. Set timeout_rm_subs parameter
...
modparam("presence", "timeout_rm_subs", 0)
...

3.25. fetch_rows (integer)

   Number of rows to be loaded in one step from database.

   Default value is 500.

   Example 1.25. Set fetch_rows parameter
...
modparam("presence", "fetch_rows", 1000)
...

3.26. db_table_lock_type (integer)

   Enable (=1) or disable (=0) the Locks for table during a transaction.
   Locking only the "current" table causes problems with a MySQL-Databases
   in "DB-Only" mode.

   In order to use the Presence-Module in "DB_ONLY"-mode with a
   MySQL-Backend, set this parameter to "0", otherwise the
   MySQL-Operations will fail. The Presence-Module will generate a "500
   Server error" due to the failed MySQL-queries.

   Default value is 1 (Write Lock for the Tables).

   Example 1.26. Set db_table_lock_type parameter
...
modparam("presence", "db_table_lock_type", 0)
...

3.27. local_log_level (int)

   Control log level for some debug messages inside the module.

   Default value is 2 (L_INFO).

   Example 1.27. Set local_log_level parameter
...
modparam("presence", "local_log_level", 3)
...

3.28. local_log_facility (int)

   Control syslog facility for some debug messages inside the module.

   Default value is taken from the core log_facility configuration
   parameter.

   Example 1.28. Set local_log_facility parameter
...
modparam("presence", "local_log_facility", "LOG_LOCAL3")
...

3.29. subs_remove_match (int)

   Control how to match the subscriptions to remove from memory. If set to
   0, then the match is done on To-Tag (local generated), if set to 1,
   then the match is done on all dialog attributes (Call-Id, From-Tag,
   To-Tag).

   Default value is 0.

   Example 1.29. Set subs_remove_match parameter
...
modparam("presence", "subs_remove_match", 1)
...

3.30. xavp_cfg (str)

   The name of the xavp to be used to specify attributes for internal
   processing of presence module.

   Inner attributes inside xavp can be:
     * priority - integer value to set the priority of the presence
       document (higher value, higher priority). It can set the order of
       the aggregated presence documents sent by NOTIFY (first the
       document with higher priority). If xavp_cfg parameter is set but
       this attribute is not in the avp, the priority of the presence
       document is based on timestamp, so newer documents have higher
       priority.
     * delete_subscription - integer value to give extra control of
       deleting the subscription after processing of
       event_route[presence:notify-reply]. If value = 1, it deletes the
       subscription. If xavp_cfg parameter is set but this attribute is
       not in the avp, the subscription is not deleted. this does not
       apply for codes 404, 481 and 408 (when timeout_rm_subs = 1) where
       subscription is deleted.

   Default value is empty (not set).

   Example 1.30. Set xavp_cfg parameter
...
modparam("presence", "xavp_cfg", "pres")
...
if(is_method("PUBLISH")) {
    $xavp(pres=>priority) = 100;
}
...

3.31. retrieve_order (int)

   If set to 0, presentity records are retrieve by received_time order. If
   set to 1, presentity records are retrieve by the value of
   retrieve_order_by parameter.

   Default value is 0.

   Example 1.31. Set retrieve_order parameter
...
modparam("presence", "retrieve_order", 1)
...

3.32. retrieve_order_by (str)

   Used to set the order-by of the db query for fetching the presence
   records when retrieve_order is set to 1.

   Default value is “priority”.

   Example 1.32. Set retrieve_order_by parameter
...
modparam("presence", "retrieve_order_by", "priority, received_time")
...

3.33. sip_uri_match (int)

   The mode used when comparing uris.

   Possible Values
     * 0 : case sensitive
     * 1 : case insensitive

   Default value is “0”.

   Example 1.33. Set sip_uri_match parameter
...
modparam("presence", "sip_uri_match", 1)
...

3.34. enable_dmq (integer)

   If set to 1, will enable DMQ replication of presentities between nodes.
   Use this instead of a shared DB to share state across a cluster and
   update local watchers in realtime (subs_db_mode < 3) or on next
   notifier run (subs_db_mode = 3).

   If this parameter is enabled, the DMQ module must be loaded first -
   otherwise, startup will fail.

   Default value is 0.

   Example 1.34. Set enable_dmq parameter
...
modparam("presence", "enable_dmq", 1)
...

3.35. pres_subs_mode (integer)

   Allow disabling cloning subscription structure for pv $subs(...),
   saving the pkg memory and copy operations for all its fields. If 1 the
   cloning is done; if 0, no cloning and $subs(...) returns $null.

   Default value is 1.

   Example 1.35. Set pres_subs_mode parameter
...
modparam("presence", "pres_subs_mode", 0)
...

3.36. delete_same_subs (integer)

   Enable deleting of subscriptions with the same presence uri and callid.

   Default value is 0 (disabled behavior).

   Example 1.36. Set delete_same_subs parameter
...
modparam("presence", "delete_same_subs", 1)
...

3.37. timer_mode (integer)

   Specify what timer process to be used. If set to 0, the core main timer
   is used. If set to 1, the core secondary timer is used.

   Default value is 1.

   Example 1.37. Set timer_mode parameter
...
modparam("presence", "timer_mode", 0)
...

3.38. subs_respond_200 (integer)

   Specify the response code for accepted SUBSCRIBE requests. If set to 0,
   "202 Accepted" will be returned (default behaviour till version 5.5).
   If set to 1, "200 OK" will be returned instead, in conformance to
   RFC6665, which prohibits 202 responses.

   Default value is 1.

   Example 1.38. Set subs_respond_200 parameter
...
modparam("presence", "subs_respond_200", 0)
...

4. Functions

   4.1. handle_publish([sender_uri])
   4.2. handle_subscribe([watcher_uri])
   4.3. pres_auth_status(watcher_uri, presentity_uri)
   4.4. pres_has_subscribers(presentity_uri, event)
   4.5. pres_refresh_watchers(uri, event, type[, file_uri, filename])
   4.6. pres_update_watchers(uri, event)

4.1.  handle_publish([sender_uri])

   Handles PUBLISH requests by storing and updating published information
   in memory cache and database, then calls functions to send NOTIFY
   messages when changes in the published information occur. It takes one
   argument -> sender_uri. The parameter was added for enabling BLA
   implementation. If present, notification of a change in published state
   is not sent to the respective uri even though a subscription exists. It
   should be taken from the Sender header. It was left at the decision of
   the administrator whether or not to transmit the content of this header
   as parameter for handle_publish, to prevent security problems.

   This function can be used from REQUEST_ROUTE.

   Return code:
     * 1 - if success.
     * -1 - if error.

   The module sends an appropriate stateless reply in all cases.

   Example 1.39. handle_publish usage
...
        if(is_method("PUBLISH"))
        {
                if($hdr(Sender)!= NULL)
                        handle_publish("$hdr(Sender)");
                else
                        handle_publish();
                t_release();
        }
...

4.2.  handle_subscribe([watcher_uri])

   The function which handles SUBSCRIBE requests. It stores or updates
   information in memory and database and calls functions to send NOTIFY
   messages when a SUBSCRIBE which initiate a dialog is received.

   By default this function uses the From: URI from the SUBSCRIBE request
   as the Watcher URI. The optional watcher_uri parameter can be used to
   specify a different Watcher URI, possibly taken from a SIP header like
   P-Asserted-Identity:.

   This function can be used from REQUEST_ROUTE.

   Return code:
     * 1 - if success.
     * -1 - if error.

   The module sends an appropriate stateless reply in all cases.

   Example 1.40. handle_subscribe usage
...
if(method=="SUBSCRIBE")
    handle_subscribe();
...

4.3.  pres_auth_status(watcher_uri, presentity_uri)

   The function checks if watcher URI is authorized to subscribe event
   'presence' of presentity URI. Both watcher_uri and presentity_uri can
   be static strings or contain pseudo variables.

   The function returns ACTIVE_STATUS, if subscription is allowed, and
   PENDING_STATUS, TERMINATED_STATUS, or WAITING_STATUS otherwise. See
   presence/subscribe.h for the corresponding integer codes. In case of
   error, function returns -1.

   This function can be used from REQUEST_ROUTE.

   Example 1.41. pres_auth_status usage
...
if (method=="MESSAGE") {
    pres_auth_status("$fu", $ru");
    if ($retcode == 1) {
        t_relay();
    } else {
        send_reply("403", "Forbidden");
    }
}
...

4.4.  pres_has_subscribers(presentity_uri, event)

   Allows to check if presentity has any subscribers of event.

   This function can be used from ANY_ROUTE.

   Example 1.42. pres_has_subscribers usage
...
if(pres_has_subscribers($var(uri), "message-summary"))
    # do something...;
...

4.5.  pres_refresh_watchers(uri, event, type[, file_uri, filename])

   The function can be used in configuration to trigger notifies to
   watchers if a change in watchers authorization or in published state
   occurred (i.e., updates of xcap documents).

   Parameters:
     * uri - the uri of the user who made the change and whose watchers
       should be informed.
     * event - the event package.
     * type - it distinguishes between the three different types of events
       that can trigger the refresh, depending on its value:
          + 0 - a change in watchers authentication.
          + 1 - a statical update in published state through direct update
            in db table.
          + 2 - a statical update in published state by modifying the pidf
            manipulation document.
     * file_uri - the uri of the pidf-manipulation file on the XCAP server
       (only used for type 2).
     * filename - the name of the pidf-manipulation file on the XCAP
       server (only used for type 2).

   This function can be used from ANY_ROUTE.

   Example 1.43. pres_refresh_watchers usage
...
pres_refresh_watchers("sip:test@kamailio.org", "presence", 1);
...

4.6.  pres_update_watchers(uri, event)

   The function can be used in configuration to triger updates to watchers
   status if a change in watchers authorization state occurred (i.e.,
   updates of xcap documents change state from pending to active).

   Parameters:
     * uri - the uri of the user who made the change and whose watchers
       should be informed. Can be PV.
     * event - the event package (e.g., presence).

   This function can be used from ANY_ROUTE.

   Example 1.44. pres_update_watchers usage
...
pres_update_watchers("sip:test@kamailio.org", "presence");
...

5. RPC Commands

   5.1. presence.cleanup
   5.2. presence.refreshWatchers
   5.3. presence.updateWatchers
   5.4. presence.presentity_list

5.1. presence.cleanup

   Manually triggers the cleanup functions for the active_watchers,
   presentity, and watchers tables. Useful if you have set clean_period
   and/or db_update_period to zero or less.

   Name: presence.cleanup

   Parameters: none

   RPC Command Format:
...
kamcmd presence.cleanup
...

5.2. presence.refreshWatchers

   Triggers sending Notify messages to watchers if a change in watchers
   authorization or in published state occurred.

   Name: presence.refreshWatchers

   Parameters:
     * uri - the uri of the user who made the change and whose watchers
       should be informed
     * event - the event package.
     * type - it distinguishes between the three different types of events
       that can trigger the refresh, depending on its value:
          + 0 - a change in watchers authentication.
          + 1 - a statical update in published state through direct update
            in db table.
          + 2 - a statical update in published state by modifying the pidf
            manipulation document.
     * file_uri - the uri of the pidf-manipulation file on the XCAP server
       (only used for type 2).
     * filename - the name of the pidf-manipulation file on the XCAP
       server (only used for type 2).

   RPC Command Format:
...
kamcmd presence.refreshWatchers sip:test@kamailio.org presence 1
...

5.3. presence.updateWatchers

   Manually triggers updates to watchers (for example, after the contents
   of XCAP docs has been updated).

   Name: presence.updateWatchers

   Parameters:
     * uri - the uri of the user who made the changes and whose watchers
       should be updated.
     * event - the event package (e.g. presence).

   RPC Command Format:
...
kamcmd presence.updateWatchers sip:alice@domain.com presence
...

5.4. presence.presentity_list

   List the presentity records stored in memory.

   Name: presence.presentity_list

   Parameters:
     * mode - (optional) it can be 'full' to print all the fields of
       presentity record. If missine, only a selected set of fields are
       printed in the response.

   RPC Command Format:
...
kamctl rpc presence.presentity_list
kamctl rpc presence.presentity_list full
...

6. Exported Variables

   6.1. $subs(attr)
   6.2. $notify_reply(attr)

6.1. $subs(attr)

   Access the attributes of handled subscription. It must be used after a
   successful call of “handle_subscription()” or in the following events.
     * tm:local-request - before notify is sent
     * presence:notify-reply - after notify is sent

   The “attr” can be:
     * uri - subscription presentity uri
     * pres_uri - alias for presentity uri
     * to_user
     * to_domain
     * from_user
     * from_domain
     * watcher_username
     * watcher_domain
     * event
     * event_id
     * to_tag
     * from_tag
     * callid
     * remote_cseq
     * local_cseq
     * contact
     * local_contact
     * record_route
     * expires
     * status
     * reason
     * version
     * flags
     * user_agent

   Example 1.45. $subs(name) usage
...
if(handle_subscription())
{
  xlog("presentity=$subs(uri)\n");
}
...

6.2. $notify_reply(attr)

   Access the reply message received when notifying subscriber. It must be
   used in the following events.
     * presence:notify-reply - after notify is sent

   The “attr” can be any pseudo var that accesses attributes of msg

   Example 1.46. $notify_reply(name) usage
...
event_route[presence:notify-reply]
{
  xlog("received message = $notify_reply($mb)\n");
}
...

7. Events

   7.1. presence:notify-reply

7.1. presence:notify-reply

   Fired after notify reply is received or timeout.

   Example 1.47. $notify_reply(name) usage
...
event_route[presence:notify-reply]
{
  xlog("received message = $notify_reply($mb)\n");
}
...

8. Installation

   The module requires 3 tables in the Kamailio database: "presentity",
   "active_watchers" and "watchers". The SQL syntax to create them can be
   found in presence-create.sql script in the database directories in the
   kamailio/scripts folder. You can also find the complete database
   documentation on the project webpage,
   https://www.kamailio.org/docs/db-tables/kamailio-db-devel.html.

Chapter 2. Developer Guide

   Table of Contents

   1. bind_presence(presence_api_t* api)
   2. add_event
   3. get_rules_doc
   4. get_auth_status
   5. apply_auth_nbody
   6. agg_nbody
   7. free_body
   8. aux_body_processing
   9. aux_free_body
   10. evs_publ_handl
   11. evs_subs_handl
   12. contains_event
   13. get_event_list
   14. update_watchers_status
   15. get_sphere
   16. get_presentity
   17. free_presentity

   The module provides the following functions that can be used in other
   Kamailio modules.

1.  bind_presence(presence_api_t* api)

   This function binds the presence modules and fills the structure with
   one exported function -> add_event, which when called adds a new event
   to be handled by presence.

   Example 2.1. presence_api_t structure
...
typedef struct presence_api {
        add_event_t add_event;
        contains_event_t contains_event;
        search_event_t search_event;
        get_event_list_t get_event_list;

        update_watchers_t update_watchers_status;

        /* subs hash table handling functions */
        new_shtable_t new_shtable;
        destroy_shtable_t destroy_shtable;
        insert_shtable_t insert_shtable;
        search_shtable_t search_shtable;
        delete_shtable_t delete_shtable;
        update_shtable_t update_shtable;
        /* function to duplicate a subs structure*/
        mem_copy_subs_t  mem_copy_subs;
        /* function used for update in database*/
        update_db_subs_t update_db_subs_timer;
        /* function to extract dialog information from a
        SUBSCRIBE message */
        extract_sdialog_info_t extract_sdialog_info;
        /* function to request sphere definition for a presentity */
        pres_get_sphere_t get_sphere;

}presence_api_t;
...

2.  add_event

   Field type:
...
typedef int (*add_event_t)(pres_ev_t* event);
...

   This function receives as a parameter a structure with event specific
   information and adds it to presence event list.

   The structure received as a parameter:
...
typedef struct pres_ev
{
        str name;
        event_t* evp;
        str content_type;
        int default_expires;
        int type;
        int etag_not_new;
        /*
         *  0 - the standard mechanism (allocating new etag
                        for each Publish)
         *  1 - allocating an etag only
                        for an initial Publish
        */
        int req_auth;
        get_rules_doc_t* get_rules_doc;
        apply_auth_t*  apply_auth_nbody;
        is_allowed_t*  get_auth_status;

        /* an agg_body_t function should be registered
         * if the event permits having multiple published
         * states and requires an aggregation of the information
         * otherwise, this field should be NULL and the last
         * published state is taken when constructing Notify msg
         */
        agg_nbody_t* agg_nbody;
        publ_handling_t  * evs_publ_handl;
        subs_handling_t  * evs_subs_handl;
        free_body_t* free_body;
    /* sometimes it is necessary that a module make changes for a body for each
     * active watcher (e.g. setting the "version" parameter in an XML document.
     * If a module registers the aux_body_processing callback, it gets called fo
r
     * each watcher. It either gets the body received by the PUBLISH, or the bod
y
     * generated by the agg_nbody function.
     * The module can decide if it makes a copy of the original body, which is t
hen
     * manipulated, or if it works directly in the original body. If the module
makes a
     * copy of the original body, it also has to register the aux_free_body() to
     * free this "per watcher" body.
     */
    aux_body_processing_t* aux_body_processing;
    free_body_t* aux_free_body;
        struct pres_ev* wipeer;
        struct pres_ev* next;

}pres_ev_t;
...

3.  get_rules_doc

   Filed type:
...
typedef int (get_rules_doc_t)(str* user, str* domain, str** rules_doc);
...

   This function returns the authorization rules document that will be
   used in obtaining the status of the subscription and processing the
   notified body. A reference to the document should be put in the
   auth_rules_doc of the subs_t structure given as a parameter to the
   functions described below.

4.  get_auth_status

   This filed is a function to be called for a subscription request to
   return the state for that subscription according to authorization
   rules. In the auth_rules_doc field of the subs_t structure received as
   a parameter should contain the rules document of the presentity in
   case, if it exists.

   It is called only if the req_auth field is not 0.

   Filed type:
...
typedef int (is_allowed_t)(struct subscription* subs);
...

5.  apply_auth_nbody

   This parameter should be a function to be called for an event that
   requires authorization, when constructing final body. The authorization
   document is taken from the auth_rules_doc field of the subs_t structure
   given as a parameter. It is called only if the req_auth field is not 0.

   Filed type:
...
typedef int (apply_auth_t)(str* , struct subscription*, str** );
...

6.  agg_nbody

   If present, this field marks that the events requires aggregation of
   states. This function receives a body array and should return the final
   body. If not present, it is considered that the event does not require
   aggregation and the most recent published information is used when
   constructing Notifies.

   Filed type:
...
typedef str* (agg_nbody_t)(str* pres_user, str* pres_domain,
str** body_array, int n, int off_index);
..

7.  free_body

   This field must be field in if subsequent processing is performed on
   the info from database before being inserted in Notify message body(if
   agg_nbody or apply_auth_nbody fields are filled in). It should match
   the allocation function used when processing the body.

   Filed type:
...
typedef void(free_body_t)(char* body);
..

8.  aux_body_processing

   This field must be set if the module needs to manipulate the NOTIFY
   body for each watcher. E.g. if the XML body includes a 'version'
   parameter which will be increased for each NOTIFY, on a "per watcher"
   basis. The module can either allocate a new buffer for the new body an
   return it (aux_free_body function must be set too) or it manipulates
   the original body directly and returns NULL.

   Filed type:
...
typedef str* (aux_body_processing_t)(struct subscription *subs, str* body);
..

9.  aux_free_body

   This field must be set if the module registers the aux_body_processing
   function and allocates memory for the new modified body. Then, this
   function will be used to free the pointer returned by the
   aux_body_processing function. If the module does use the
   aux_body_processing, but does not allocate new memory, but manipulates
   directly the original body buffer, then the aux_body_processing must
   return NULL and this field should not be set.

   Filed type:
...
typedef void(free_body_t)(char* body);
..

10.  evs_publ_handl

   This function is called when handling Publish requests. Most contain
   body correctness check.

...
typedef int (publ_handling_t)(struct sip_msg*);
..

11.  evs_subs_handl

   It is not compulsory. Should contain event specific handling for
   Subscription requests.

   Filed type:
...
typedef int (subs_handling_t)(struct sip_msg*);
..

12.  contains_event

   Field type:
..
typedef pres_ev_t* (*contains_event_t)(str* name,
event_t* parsed_event);
...

   The function parses the event name received as a parameter and searches
   the result in the list. It returns the found event or NULL, if not
   found. If the second argument is an allocated event_t* structure it
   fills it with the result of the parsing.

13.  get_event_list

   Field type:
...
typedef int (*get_event_list_t) (str** ev_list);
...

   This function returns a string representation of the events registered
   in presence module.( used for Allowed-Events header).

14.  update_watchers_status

   Field type:
...
typedef int (*update_watchers_t)(str pres_uri, pres_ev_t* ev,
str* rules_doc);
...

   This function is an external command that can be used to announce a
   change in authorization rules for a presentity. It updates the stored
   status and sends a Notify to the watchers whose status has changes.
   (used by presence_xml module when notified through an RPC command of a
   change in an xcap document).

15.  get_sphere

   Field type:
...
typedef char* (*pres_get_sphere_t)(str* pres_uri);
...

   This function searches for a sphere definition in the published
   information if this has type RPID. If not found returns NULL. (the
   return value is allocated in private memory and should be freed)

16.  get_presentity

   Field type:
...
typedef str* (*pres_get_presentity_t)(str pres_uri, pres_ev_t *ev, str *etag, st
r *contact);
...

   This function returns a pointer to a str containing an XML document
   with all of the matching presentities. If no matching presentities are
   found the function returns NULL.

   The etag and contact parameters are optional and may be set to NULL.
   Once you are finished with the presentity document you must call
   free_presentity to free the allocated memory.

17.  free_presentity

   Field type:
...
typedef void (*pres_free_presentity_t)(str *presentity, pres_ev_t *ev);
...

   This function frees memory allocated by a call to get_presentity. The
   ev parameter MUST point to the same pres_ev_t data-structure that was
   used in the call to get_presentity.
