# &develguide;

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

## `bind_pua(pua_api_t* api)`

This function binds the pua modules and fills the structure with the two exported functions.

### `pua_api` structure

    ...
    typedef struct pua_api {
    	send_subscribe_t send_subscribe;
    	send_publish_t send_publish;
    	query_dialog_t is_dialog;
    	register_puacb_t register_puacb;
    	add_pua_event_t add_event;
    } pua_api_t;
    ...

## `send_publish`

Field type:

    ...
    typedef int (*send_publish_t)(publ_info_t* publ);
    ...

This function receives as a parameter a structure with Publish required information and sends a Publish message.

The structure received as a parameter:

    ...
    typedef struct publ_info

      str id;             /*  (optional )a value unique for one combination
                              of pres_uri and flag */
      str* pres_uri;      /*  the presentity uri */
      str* body;          /*  the body of the Publish message;
                              can be NULL in case of an update expires*/
      int  expires;       /*  the expires value that will be used in
                              Publish Expires header*/
      int flag;           /*  it can be : INSERT_TYPE or UPDATE_TYPE
                              if missing it will be established according
                              to the result of the search in hash table*/
      int source_flag;    /*  flag identifying the resource ;
                              supported values: UL_PUBLISH, MI_PUBLISH,
                              BLA_PUBLISH, XMPP_PUBLISH*/
      int event;          /*  the event flag;
                              supported values: PRESENCE_EVENT, BLA_EVENT,
                              MWI_EVENT */
      str content_type;   /*  the content_type of the body if present
                              (optional if the same as the default value
                              for that event)*/
      str* etag;          /*  (optional) the value of the etag the request
                              should match */
      str* outbound_proxy;/*  outbound_proxy to use when sending the
                              Publish request */
      str* extra_headers  /*  (optional) extra_headers that should be added
                              to Publish msg*/
    }publ_info_t;
    ...

## `send_subscribe`

Field type:

    ...
    typedef int (*send_subscribe_t)(subs_info_t* subs);
    ...

This function receives as a parameter a structure with Subscribe required information and sends a Subscribe message.

The structure received as a parameter:

    ...
    typedef struct subs_info

      str id;              /*  an id value unique for one combination
                               of pres_uri and flag */
      str* pres_uri;       /*  the presentity uri */
      str* watcher_uri;    /*  the watcher uri */
      str* contact;        /*  the uri that will be used in
                               Contact header*/
      str* remote_target;  /*  the uri that will be used as R-URI
                               for the Subscribe message(not compulsory;
                               if not set the value of the pres_uri field
                               is used) */
      str* outbound_proxy; /*  the outbound_proxy to use when sending the
                               Subscribe request*/
      int event;           /*  the event flag; supported value:
                               PRESENCE_EVENT, BLA_EVENT, PWINFO_EVENT*/
      int expires;         /*  the expires value that will be used in
                               Subscribe Expires header */
      int flag;            /*  it can be : INSERT_TYPE or UPDATE_TYPE
                               not compulsory */
      int source_flag;     /*  flag identifying the resource ;
                               supported values:  MI_SUBSCRIBE,
                               BLA_SUBSCRIBE, XMPP_SUBSCRIBE,
                               XMPP_INITIAL_SUBS */
    }subs_info_t;
    ...

## `is_dialog`

Field type:

    ...
    typedef int  (*query_dialog_t)(ua_pres_t* presentity);
    ...

This function checks is the parameter corresponds to a stored Subscribe initiated dialog.

### `pua_is_dialog` usage example

    ...
    	if(pua_is_dialog(dialog) < 0)
    	{
    		LM_ERR("querying dialog\n");
    		goto error;
    	}
    ...

## `register_puacb`

Field type:

    ...
    typedef int (*register_puacb_t)(int types, pua_cb f, void* param );
    ...

This function registers a callback to be called on receiving the reply message for a sent Publish or Subscribe request. The type parameter should be set the same as the source_flag for that request. The function registered as callback for pua should be of type pua_cb , which is: typedef void (pua_cb)(ua_pres_t* hentity, struct msg_start * fl); The parameters are the dialog structure for that request and the first line of the reply message.

### `register_puacb` usage example

    ...
    	if(pua.register_puacb(XMPP_SUBSCRIBE, Sipreply2Xmpp, NULL) & 0)
    	{
    		LM_ERR("Could not register callback\n");
    		return -1;
    	}
    ...

The callback function type:

    ...
    typedef int (pua_cb)(ua_pres_t* hentity, struct sip_msg*);
    ...

## `add_event`

Field type:

    ...
    typedef int (*add_pua_event_t)(int ev_flag, char* name,
       char* content_type,evs_process_body_t* process_body);

    - ev_flag     : an event flag defined as a macro in pua module
    - name        : the event name to be used in Event request headers
    - content_type: the default content_type for Publish body for
                    that event (NULL if winfo event)
    - process_body: function that processes the received body before
                    using it to construct the PUBLISH request
                    (NULL if winfo event)
    ...

This function allows registering new events to the pua module. Now there are 4 events supported by the pua module: presence, presence;winfo, message-summary, dialog;sla, application/reginfo+xml. These events are registered from within the pua module.

Filed type for process_body:

    ...
    typedef int (evs_process_body_t)(struct publ_info* publ,
      str** final_body, int ver, str* tuple);
    - publ      : the structure received as a parameter in send_publish
                  function ( initial body found in publ->body)
    - final_body: the pointer where the result(final_body) should be stored
    - ver       : a counter for the sent Publish requests
                  (used for winfo events)
    - tuple     : a unique identifier for the resource;
                  if an initial Publish it should be returned as a result
                  and it will be stored  for that record, otherwise it will
                  be given as a parameter;
    ...

### `add_event` usage example

    ...
    	if(pua.add_event((PRESENCE_EVENT, "presence", "application/pidf+xml",
    				pres_process_body) & 0)
    	{
    		LM_ERR("Could not register new event\n");
    		return -1;
    	}
    ...