Group PJSIP_DIALOG

group PJSIP_DIALOG

The base dialog framework to support dialog usages.

The base dialog framework provides management for base dialog properties such as From header, To header, CSeq sequencing, Call-ID header, Contact header management, dialog route-set management, and common authentication. This basic dialog functionality will be shared by all dialog usages of a particular dialog.

More detailed information is explained in PJSIP Developer’s Guide PDF document, and readers are encouraged to read the document to get the concept behind dialog, dialog usages, and INVITE sessions.

Application MUST initialize the user agent layer module by calling pjsip_ua_init_module() before using any of the dialog API, and link the application with with pjsip-core library.

Defines

DEPRECATED_FOR_TICKET_1902

Deprecated API pjsip_dlg_create_uas() due to a fatal bug of possible premature dialog destroy. Application should not change this setting, unless it uses single worker thread. See also https://github.com/pjsip/pjproject/issues/1902.

Enums

enum pjsip_dialog_state

Dialog state.

Values:

enumerator PJSIP_DIALOG_STATE_NULL

Dialog is not established.

enumerator PJSIP_DIALOG_STATE_ESTABLISHED

Dialog has been established (probably early)

enum pjsip_dialog_cap_status

Dialog capability status.

Values:

enumerator PJSIP_DIALOG_CAP_UNSUPPORTED

Capability is unsupported.

enumerator PJSIP_DIALOG_CAP_SUPPORTED

Capability is supported

enumerator PJSIP_DIALOG_CAP_UNKNOWN

Unknown capability status. This is usually because we lack the capability info which is retrieved from capability header specified in the dialog messages.

Functions

pj_bool_t pjsip_method_creates_dialog(const pjsip_method *m)

This utility function returns PJ_TRUE if the specified method is a dialog creating request. This method property is used to determine whether Contact header should be included in outgoing request.

Parameters:

m – The SIP method.

Returns:

PJ_TRUE if the method creates a dialog.

pj_status_t pjsip_dlg_create_uac(pjsip_user_agent *ua, const pj_str_t *local_uri, const pj_str_t *local_contact, const pj_str_t *remote_uri, const pj_str_t *target, pjsip_dialog **p_dlg)

Create a new dialog and return the instance in p_dlg parameter. After creating the dialog, application can add modules as dialog usages by calling pjsip_dlg_add_usage().

If the request has To tag parameter, dialog’s local tag will be initialized from this value. Otherwise a globally unique id generator will be invoked to create dialog’s local tag.

This function also initializes the dialog’s route set based on the Record-Route headers in the request, if present.

Note that initially, the session count in the dialog will be initialized to zero.

Parameters:
  • ua – The user agent module instance.

  • local_uri – Dialog local URI (i.e. From header).

  • local_contact – Optional dialog local Contact to be put as Contact header value, hence the format must follow RFC 3261 Section 20.10: When the header field value contains a display name, the URI including all URI parameters is enclosed in “<” and “>”. If no “<” and “>” are present, all parameters after the URI are header parameters, not URI parameters. The display name can be tokens, or a quoted string, if a larger character set is desired. If this argument is NULL, the Contact will be taken from the local URI.

  • remote_uri – Dialog remote URI (i.e. To header).

  • target – Optional initial remote target. If this argument is NULL, the initial target will be set to remote URI.

  • p_dlg – Pointer to receive the dialog.

Returns:

PJ_SUCCESS on success.

pj_status_t pjsip_dlg_create_uac2(const pjsip_dlg_create_uac_param *create_param, pjsip_dialog **p_dlg)

Variant of pjsip_dlg_create_uac() with additional parameter to specify the group lock to use. Group lock can be used to synchronize locking among several objects to prevent deadlock, and to synchronize the lifetime of objects sharing the same group lock.

See pjsip_dlg_create_uac() for general info about this function.

Parameters:
Returns:

PJ_SUCCESS on success.

pj_status_t pjsip_dlg_create_uas_and_inc_lock(pjsip_user_agent *ua, pjsip_rx_data *rdata, const pj_str_t *contact, pjsip_dialog **p_dlg)

Initialize UAS dialog from the information found in the incoming request that creates a dialog (such as INVITE, REFER, or SUBSCRIBE), and set the local Contact to contact. If contact is not specified, the local contact is initialized from the URI in the To header in the request.

This function will also create UAS transaction for the incoming request, and associate the transaction to the rdata. Application can query the transaction used to handle this request by calling pjsip_rdata_get_tsx() after this function returns.

Note that initially, the session count in the dialog will be initialized to 1 (one), and the dialog is locked. Application needs to explicitly call pjsip_dlg_dec_lock() to release the lock and decrease the session count.

Parameters:
  • ua – The user agent module instance.

  • rdata – The incoming request that creates the dialog, such as INVITE, SUBSCRIBE, or REFER.

  • contact – Optional dialog local Contact to be put as Contact header value, hence the format must follow RFC 3261 Section 20.10: When the header field value contains a display name, the URI including all URI parameters is enclosed in “<” and “>”. If no “<” and “>” are present, all parameters after the URI are header parameters, not URI parameters. The display name can be tokens, or a quoted string, if a larger character set is desired. If this argument is NULL, the local contact will be initialized from the value of To header in the request.

  • p_dlg – Pointer to receive the dialog.

Returns:

PJ_SUCCESS on success.

pj_status_t pjsip_dlg_set_transport(pjsip_dialog *dlg, const pjsip_tpselector *sel)

Lock/bind dialog to a specific transport/listener. This is optional, as normally transport will be selected automatically based on the destination of messages upon resolver completion. When the dialog is explicitly bound to the specific transport/listener, all transactions originated by this dialog will use the specified transport/listener when sending outgoing requests.

Note that this doesn’t affect the Contact header generated by this dialog. Application must manually update the Contact header if necessary, to adjust the address according to the transport being selected.

Parameters:
  • dlg – The dialog instance.

  • sel – Transport selector containing the specification of transport or listener to be used by this dialog to send requests.

Returns:

PJ_SUCCESS on success, or the appropriate error code.

pj_status_t pjsip_dlg_set_via_sent_by(pjsip_dialog *dlg, pjsip_host_port *via_addr, pjsip_transport *via_tp)

Set the “sent-by” field of the Via header for outgoing requests.

Parameters:
  • dlg – The dialog instance.

  • via_addr – Set via_addr to use for the Via header or NULL to use the transport’s published name.

  • via_tp – via_addr will only be used if we are using via_tp transport.

Returns:

PJ_SUCCESS on success.

pj_status_t pjsip_dlg_fork(const pjsip_dialog *original_dlg, const pjsip_rx_data *rdata, pjsip_dialog **new_dlg)

Create a new (forked) dialog on receipt on forked response in rdata. The new dialog will be created from original_dlg, except that it will have new remote tag as copied from the To header in the response. Upon return, the new_dlg will have been registered to the user agent. Applications just need to add modules as dialog’s usages.

Note that initially, the session count in the dialog will be initialized to zero.

Parameters:
  • original_dlg – The original UAC dialog.

  • rdata – The incoming forked response message.

  • new_dlg – Pointer to receive the new dialog.

Returns:

PJ_SUCCESS on success.

pj_status_t pjsip_dlg_terminate(pjsip_dialog *dlg)

Forcefully terminate the dialog. Application can only call this function when there is no session associated to the dialog. If there are sessions that use this dialog, this function will refuse to terminate the dialog. For this case, application MUST call the appropriate termination function for each dialog session (e.g. pjsip_inv_terminate() to terminate INVITE session).

Parameters:

dlg – The dialog.

Returns:

PJ_SUCCESS if dialog has been terminated.

pj_status_t pjsip_dlg_set_route_set(pjsip_dialog *dlg, const pjsip_route_hdr *route_set)

Set dialog’s initial route set to route_set list. This can only be called for UAC dialog, before any request is sent. After dialog has been established, the route set can not be changed.

For UAS dialog, the route set will be initialized in pjsip_dlg_create_uas_and_inc_lock() from the Record-Route headers in the incoming request.

The route_set argument is standard list of Route headers (i.e. with sentinel).

Parameters:
  • dlg – The UAC dialog.

  • route_set – List of Route header.

Returns:

PJ_SUCCESS on success.

pj_status_t pjsip_dlg_inc_session(pjsip_dialog *dlg, pjsip_module *mod)

Increment the number of sessions in the dialog. Note that initially (after created) the dialog has the session counter set to zero.

Parameters:
  • dlg – The dialog.

  • mod – The module that increments the session counter.

Returns:

PJ_SUCCESS on success.

pj_status_t pjsip_dlg_dec_session(pjsip_dialog *dlg, pjsip_module *mod)

Decrement the number of sessions in the dialog. Once the session counter reach zero and there is no pending transaction, the dialog will be destroyed. Note that this function may destroy the dialog immediately if there is no pending transaction when this function is called.

Parameters:
  • dlg – The dialog.

  • mod – The module that decrements the session counter.

Returns:

PJ_SUCCESS on success.

pj_status_t pjsip_dlg_add_usage(pjsip_dialog *dlg, pjsip_module *module, void *mod_data)

Add a module as dialog usage, and optionally set the module specific data.

Parameters:
  • dlg – The dialog.

  • module – The module to be registered as dialog usage.

  • mod_data – Optional arbitrary data to be attached to dialog’s mod_data array at the module’s index.

Returns:

PJ_SUCCESS on success.

pj_bool_t pjsip_dlg_has_usage(pjsip_dialog *dlg, pjsip_module *module)

Check if the specified module has been registered as usage to the dialog.

Parameters:
  • dlg – The dialog.

  • module – The module.

Returns:

PJ_TRUE if the specified module is currently registered as a usage to the dialog.

pj_status_t pjsip_dlg_set_mod_data(pjsip_dialog *dlg, int mod_id, void *data)

Attach module specific data to the dialog. Application can also set the value directly by accessing dlg->mod_data[module_id].

Parameters:
  • dlg – The dialog

  • mod_id – The ID of the module from which the data is to be set to the dialog.

  • data – Arbitrary data.

Returns:

PJ_SUCCESS on success.

void *pjsip_dlg_get_mod_data(pjsip_dialog *dlg, int mod_id)

Get module specific data previously attached to the dialog. Application can also get value directly by accessing dlg->mod_data[module_id].

Parameters:
  • dlg – The dialog

  • mod_id – The ID of the module from which the data is to be retrieved from the dialog.

Returns:

The data that was previously set, or NULL.

void pjsip_dlg_inc_lock(pjsip_dialog *dlg)

Lock dialog and increment session counter termporarily, to prevent it from being destroyed.

Parameters:

dlg – The dialog.

pj_status_t pjsip_dlg_try_inc_lock(pjsip_dialog *dlg)

Try to acquire dialog’s lock, but return immediately if lock can not be acquired.

Parameters:

dlg – The dialog.

Returns:

PJ_SUCCESS if lock has been acquired.

void pjsip_dlg_dec_lock(pjsip_dialog *dlg)

Unlock dialog and decrement temporary session counter. After this function is called, dialog may be destroyed.

Parameters:

dlg – The dialog.

pj_grp_lock_t *pjsip_dlg_get_lock(pjsip_dialog *dlg)

Get the group lock for the SIP dialog. Note that prior to calling this method, it is recommended to hold reference to the dialog (e.g: call pjsip_dlg_inc_session() or pjsip_dlg_inc_lock()).

Parameters:

dlg – The dialog.

Returns:

The group lock.

pjsip_dialog *pjsip_rdata_get_dlg(pjsip_rx_data *rdata)

Get the dialog instance in the incoming rdata. If an incoming message matches an existing dialog, the user agent must have put the matching dialog instance in the rdata, or otherwise this function will return NULL if the message didn’t match any existing dialog.

This function can only be called after endpoint distributes the message to the transaction layer or UA layer. In other words, application can only call this function in the context of module that runs in priority number higher than PJSIP_MOD_PRIORITY_UA_PROXY_LAYER.

Parameters:

rdata – Incoming message buffer.

Returns:

The dialog instance that “owns” the message.

pjsip_dialog *pjsip_tdata_get_dlg(pjsip_tx_data *tdata)

Get the dialog instance for the outgoing tdata. Returns NULL if the message wasn’t sent from a dialog.

Parameters:

tdata – Outgoing message buffer.

Returns:

The dialog instance that “owns” the message.

pjsip_dialog *pjsip_tsx_get_dlg(pjsip_transaction *tsx)

Get the associated dialog for the specified transaction, if any.

Parameters:

tsx – The transaction.

Returns:

The dialog instance which has been registered to the transaction as transaction user, or NULL if the transaction is outside any dialogs.

pj_status_t pjsip_dlg_create_request(pjsip_dialog *dlg, const pjsip_method *method, int cseq, pjsip_tx_data **tdata)

Create a basic/generic request with the specified method and optionally specify the cseq. Use value -1 for cseq to have the dialog automatically put next cseq number for the request. Otherwise for some requests, e.q. CANCEL and ACK, application must put the CSeq in the original INVITE request as the parameter.

This function will also put Contact header where appropriate.

Parameters:
  • dlg – The dialog instance.

  • method – The method of the request.

  • cseq – Optional CSeq, which only needs to be specified when creating ACK and CANCEL. For other requests, specify -1 to use dialog’s internal counter.

  • tdata – Pointer to receive the request’s transmit data buffer.

Returns:

PJ_SUCCESS on success.

pj_status_t pjsip_dlg_send_request(pjsip_dialog *dlg, pjsip_tx_data *tdata, int mod_data_id, void *mod_data)

Send request message to remote peer. If the request is not an ACK request, the dialog will send the request statefully, by creating an UAC transaction and send the request with the transaction.

Also when the request is not ACK or CANCEL, the dialog will increment its local cseq number and update the cseq in the request according to dialog’s cseq.

If p_tsx is not null, this argument will be set with the transaction instance that was used to send the request.

This function will decrement the transmit data’s reference counter regardless the status of the operation.

Parameters:
  • dlg – The dialog.

  • tdata – The request message to be sent.

  • mod_data_id – Optional module data index to put an optional data into the transaction. If no module data is to be attached, this value should be -1.

  • mod_data – Optional module data to be attached to the transaction at mod_data_id index.

Returns:

PJ_SUCCESS on success.

pj_status_t pjsip_dlg_create_response(pjsip_dialog *dlg, pjsip_rx_data *rdata, int st_code, const pj_str_t *st_text, pjsip_tx_data **tdata)

Create a response message for the incoming request in rdata with status code st_code and optional status text st_text. This function is different than endpoint’s API pjsip_endpt_create_response() in that the dialog function adds Contact header and Record-Routes headers in the response where appropriate.

Parameters:
  • dlg – The dialog.

  • rdata – The incoming request message for which the response will be created.

  • st_code – Status code.

  • st_text – Optional string for custom status reason text.

  • tdata – Pointer to receive the response message transmit data buffer.

Returns:

PJ_SUCCESS on success.

pj_status_t pjsip_dlg_modify_response(pjsip_dialog *dlg, pjsip_tx_data *tdata, int st_code, const pj_str_t *st_text)

Modify previously sent response with other status code. Contact header will be added when appropriate.

Parameters:
  • dlg – The dialog.

  • tdata – The transmit data buffer containing response message to be modified. Upon successful return, the reference count will be incremented.

  • st_code – New status code to be set.

  • st_text – Optional string for custom status reason text.

Returns:

PJ_SUCCESS on success.

pj_status_t pjsip_dlg_send_response(pjsip_dialog *dlg, pjsip_transaction *tsx, pjsip_tx_data *tdata)

Send response message statefully. The transaction instance MUST be the transaction that was reported on on_rx_request() callback.

This function decrements the transmit data’s reference counter regardless the status of the operation.

Parameters:
  • dlg – The dialog.

  • tsx – The UAS transaction associated with the incoming request. If the request is within a dialog, or a dialog has been created for the request that creates the dialog, application can get the transaction instance for the request by calling pjsip_rdata_get_tsx().

  • tdata – Response message to be sent.

Returns:

PJ_SUCCESS on success.

pj_status_t pjsip_dlg_respond(pjsip_dialog *dlg, pjsip_rx_data *rdata, int st_code, const pj_str_t *st_text, const pjsip_hdr *hdr_list, const pjsip_msg_body *body)

This composite function sends response message statefully to an incoming request message inside dialog.

Parameters:
  • dlg – The endpoint instance.

  • rdata – The incoming request message.

  • st_code – Status code of the response.

  • st_text – Optional status text of the response.

  • hdr_list – Optional header list to be added to the response.

  • body – Optional message body to be added to the response.

Returns:

PJ_SUCCESS if response message has successfully been sent.

pjsip_dialog_cap_status pjsip_dlg_remote_has_cap(pjsip_dialog *dlg, int htype, const pj_str_t *hname, const pj_str_t *token)

Check if remote peer have the specified capability as published in the dialog messages from remote peer.

Notes:

  • The capability token lookup will apply exact match, but not case-sensitive, for example: "text/html" will not match "text / html" (notice the spaces).

Parameters:
  • dlg – The dialog.

  • htype – The header type to be checked, which value may be:

    • PJSIP_H_ACCEPT

    • PJSIP_H_ALLOW

    • PJSIP_H_SUPPORTED

  • hname – If htype specifies PJSIP_H_OTHER, then the header name must be supplied in this argument. Otherwise the value must be set to NULL.

  • token – The capability token to check. For example, if htype is PJSIP_H_ALLOW, then token specifies the method names; if htype is PJSIP_H_SUPPORTED, then token specifies the extension names such as “100rel”.

Returns:

PJSIP_DIALOG_CAP_SUPPORTED if the specified capability is explicitly supported, see pjsip_dialog_cap_status for more info.

const pjsip_hdr *pjsip_dlg_get_remote_cap_hdr(pjsip_dialog *dlg, int htype, const pj_str_t *hname)

Get the specified capability header from the remote capability headers stored in the dialog.

Parameters:
  • dlg – The dialog.

  • htype – The header type to be retrieved, which value may be:

    • PJSIP_H_ACCEPT

    • PJSIP_H_ALLOW

    • PJSIP_H_SUPPORTED

  • hname – If htype specifies PJSIP_H_OTHER, then the header name must be supplied in this argument. Otherwise the value must be set to NULL.

Returns:

The appropriate header, or NULL if the header is not available.

pj_status_t pjsip_dlg_set_remote_cap_hdr(pjsip_dialog *dlg, const pjsip_generic_array_hdr *cap_hdr)

Set remote capability from a SIP header containing array of capability tags/values.

Parameters:
  • dlg – The dialog.

  • cap_hdr – The SIP header.

Returns:

PJ_SUCCESS when successful, otherwise the appropriate error code will be returned.

pj_status_t pjsip_dlg_remove_remote_cap_hdr(pjsip_dialog *dlg, int htype, const pj_str_t *hname)

Remove a remote capability header.

Parameters:
  • dlg – The dialog.

  • htype – The header type to be removed, which value may be:

    • PJSIP_H_ACCEPT

    • PJSIP_H_ALLOW

    • PJSIP_H_SUPPORTED

  • hname – If htype specifies PJSIP_H_OTHER, then the header name must be supplied in this argument. Otherwise the value must be set to NULL.

Returns:

PJ_SUCCESS when successful, otherwise the appropriate error code will be returned.

pj_status_t pjsip_dlg_update_remote_cap(pjsip_dialog *dlg, const pjsip_msg *msg, pj_bool_t strict)

Update remote capabilities from a received message. The header types to be updated from the message will only be PJSIP_H_ACCEPT, PJSIP_H_ALLOW, and PJSIP_H_SUPPORTED.

Parameters:
  • dlg – The dialog.

  • msg – The received message.

  • strict – If this is set to PJ_TRUE, any header types missing from the message will cause removal of existing header types in the capability list. Otherwise, the capability list will not be modified when any header type is missing.

Returns:

PJ_SUCCESS when successful, otherwise the appropriate error code will be returned.

struct pjsip_dlg_party
#include <sip_dialog.h>

This structure is used to describe dialog’s participants, which in this case is local party (i.e. us) and remote party.

Public Members

pjsip_fromto_hdr *info

From/To header, inc tag.

pj_str_t info_str

String rep of info header.

pj_uint32_t tag_hval

Hashed value of the tag.

pjsip_contact_hdr *contact

Contact header.

pj_int32_t first_cseq

First CSeq seen.

pj_int32_t cseq

Next sequence number.

struct pjsip_dialog
#include <sip_dialog.h>

This structure describes the dialog structure. Application MUST NOT try to SET the values here directly, but instead it MUST use the appropriate dialog API. The dialog declaration only needs to be made visible because other PJSIP modules need to see it (e.g. INVITE session, the event framework, etc.).

Application MAY READ the dialog contents directly after it acquires dialog lock.

To acquire dialog lock, use pjsip_dlg_inc_lock(), and to release it, use pjsip_dlg_dec_lock(). DO NOT USE pj_mutex_lock()/pj_mutex_unlock() on the dialog’s mutex directly, because this will not protect against dialog being destroyed.

Forward declaration for dialog (sip_dialog.h).

Public Functions

PJ_DECL_LIST_MEMBER(pjsip_dialog)

The dialog set list.

Public Members

char obj_name[PJ_MAX_OBJ_NAME]

Standard id.

pj_pool_t *pool

Dialog’s pool.

pjsip_user_agent *ua

User agent instance.

pjsip_endpoint *endpt

Endpoint instance.

pj_grp_lock_t *grp_lock_

Dialog’s grp lock. Do not call!! Use pjsip_dlg_inc_lock() instead!

void *dlg_set

The dialog set which this dialog belongs (opaque type).

pjsip_dialog_state state

Dialog state.

pjsip_uri *target

Current target.

pjsip_target_set target_set

Target set, for UAC only.

pjsip_hdr inv_hdr

Headers from hparam in dest URL

pjsip_dlg_party local

Local party info.

pjsip_dlg_party remote

Remote party info.

pjsip_hdr rem_cap_hdr

List of remote capability header.

pjsip_role_e role

Initial role.

pj_bool_t uac_has_2xx

UAC has received 2xx response?

pj_bool_t secure

Use secure transport?

pj_bool_t add_allow

Add Allow header in requests?

pj_bool_t ack_sent

ACK has been sent?

pjsip_cid_hdr *call_id

Call-ID header.

pjsip_route_hdr route_set

Route set.

pj_bool_t route_set_frozen

Route set has been set.

pjsip_auth_clt_sess auth_sess

Client authentication session.

pj_str_t initial_dest

Initial destination host (used for verifying remote TLS cert).

int sess_count

Session counter. Number of sessions.

int tsx_count

Transaction counter. Number of pending transactions.

pjsip_tpselector tp_sel

Transport selector.

unsigned usage_cnt

Number of registered usages.

pjsip_module *usage[PJSIP_MAX_MODULE]

Array of usages, priority sorted

void *mod_data[PJSIP_MAX_MODULE]

Module specific data. Module data.

pjsip_host_port via_addr

If via_addr is set, it will be used as the “sent-by” field of the Via header for outgoing requests as long as the request uses via_tp transport. Normally application should not use or access these fields. Via address.

const void *via_tp

Via transport.

struct pjsip_dlg_create_uac_param
#include <sip_dialog.h>

The parameter for pjsip_dlg_create_uac2().

Public Members

pjsip_user_agent *ua

The user agent module instance.

pj_str_t local_uri

Dialog local URI (i.e. From header).

pj_str_t local_contact

Optional dialog local Contact to be put as Contact header value, hence the format must follow RFC 3261 Section 20.10: When the header field value contains a display name, the URI including all URI parameters is enclosed in “<” and “>”. If no “<” and “>” are present, all parameters after the URI are header parameters, not URI parameters. The display name can be tokens, or a quoted string, if a larger character set is desired. If this argument is NULL, the Contact will be taken from the local URI.

pj_str_t remote_uri

Dialog remote URI (i.e. To header).

pj_str_t target

Optional initial remote target. If this argument is NULL, the initial target will be set to remote URI.

pj_grp_lock_t *grp_lock

Optional group lock to use by this dialog. If the value is NULL, the dialog will create its own group lock.