# &develguide;

The module provides the following functions that can be used in other &kamailio; modules.

## `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.

### `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;
    ...

## `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 for
         * each watcher. It either gets the body received by the PUBLISH, or the body
         * generated by the agg_nbody function.
         * The module can decide if it makes a copy of the original body, which is then
         * 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;
    ...

## `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.

## `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);
    ...

## `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** );
    ...

## `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);
    ..

## `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);
    ..

## `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 and 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);
    ..

## `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);
    ..

## `evs_publ_handl`

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

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

## `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*);
    ..

## `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.

## `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).

## `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).

## `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)

## `get_presentity`

Field type:

    ...
    typedef str* (*pres_get_presentity_t)(str pres_uri, pres_ev_t *ev, str *etag, str *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.

## `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.