Asterisk - The Open Source Telephony Project  GIT-master-932eae6
Data Structures | Macros | Typedefs | Functions | Variables
res_pjsip.c File Reference
#include "asterisk.h"
#include <pjsip.h>
#include <pjsip_simple.h>
#include <pjsip/sip_transaction.h>
#include <pj/timer.h>
#include <pjlib.h>
#include <pjmedia/errno.h>
#include "asterisk/res_pjsip.h"
#include "res_pjsip/include/res_pjsip_private.h"
#include "asterisk/linkedlists.h"
#include "asterisk/logger.h"
#include "asterisk/lock.h"
#include "asterisk/utils.h"
#include "asterisk/astobj2.h"
#include "asterisk/module.h"
#include "asterisk/serializer.h"
#include "asterisk/threadpool.h"
#include "asterisk/taskprocessor.h"
#include "asterisk/uuid.h"
#include "asterisk/sorcery.h"
#include "asterisk/file.h"
#include "asterisk/cli.h"
#include "asterisk/res_pjsip_cli.h"
#include "asterisk/test.h"
#include "asterisk/res_pjsip_presence_xml.h"
#include "asterisk/res_pjproject.h"

Go to the source code of this file.

Data Structures

struct  endpoint_formatters
 
struct  endpoint_identifier_list
 
struct  endpoint_identifiers
 
struct  send_request_data
 Structure to hold information about an outbound request. More...
 
struct  send_request_wrapper
 
struct  supplements
 
struct  sync_task_data
 

Macros

#define ENDPOINT_IDENTIFIER_FORMAT   "%-20.20s\n"
 
#define MOD_DATA_CONTACT   "contact"
 
#define SERIALIZER_POOL_SIZE   8
 
#define SIP_SERVANT_ID   0x5E2F1D
 
#define TIMEOUT_TIMER2   5
 
#define TIMER_INACTIVE   0
 

Typedefs

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

Functions

static void __init_pj_thread_storage (void)
 
static void __init_servant_id_storage (void)
 
static void __reg_module (void)
 
static void __unreg_module (void)
 
static pjsip_msg_body * ast_body_to_pjsip_body (pj_pool_t *pool, const struct ast_sip_body *body)
 
void ast_copy_pj_str (char *dest, const pj_str_t *src, size_t size)
 Copy a pj_str_t into a standard character buffer. More...
 
int ast_copy_pj_str2 (char **dest, const pj_str_t *src)
 Create and copy a pj_str_t into a standard character buffer. More...
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
int ast_sip_add_body (pjsip_tx_data *tdata, const struct ast_sip_body *body)
 Add a body to an outbound SIP message. More...
 
int ast_sip_add_body_multipart (pjsip_tx_data *tdata, const struct ast_sip_body *bodies[], int num_bodies)
 Add a multipart body to an outbound SIP message. More...
 
int ast_sip_add_header (pjsip_tx_data *tdata, const char *name, const char *value)
 Add a header to an outbound SIP message. More...
 
void ast_sip_add_usereqphone (const struct ast_sip_endpoint *endpoint, pj_pool_t *pool, pjsip_uri *uri)
 Add 'user=phone' parameter to URI if enabled and user is a phone number. More...
 
int ast_sip_append_body (pjsip_tx_data *tdata, const char *body_text)
 Append body data to a SIP message. More...
 
const char * ast_sip_call_codec_pref_to_str (struct ast_flags pref)
 Convert the call codec preference flags to a string. More...
 
int ast_sip_call_codec_str_to_pref (struct ast_flags *pref, const char *pref_str, int is_outgoing)
 Convert a call codec preference string to preference flags. More...
 
enum ast_sip_check_auth_result ast_sip_check_authentication (struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, pjsip_tx_data *tdata)
 Method to determine authentication status of an incoming request. More...
 
pjsip_dialog * ast_sip_create_dialog_uac (const struct ast_sip_endpoint *endpoint, const char *uri, const char *request_user)
 General purpose method for creating a UAC dialog with an endpoint. More...
 
pjsip_dialog * ast_sip_create_dialog_uas (const struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, pj_status_t *status)
 General purpose method for creating a UAS dialog with an endpoint. More...
 
pjsip_dialog * ast_sip_create_dialog_uas_locked (const struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, pj_status_t *status)
 General purpose method for creating a UAS dialog with an endpoint. More...
 
int ast_sip_create_rdata (pjsip_rx_data *rdata, char *packet, const char *src_name, int src_port, char *transport_type, const char *local_name, int local_port)
 General purpose method for creating an rdata structure using specific information. More...
 
int ast_sip_create_rdata_with_contact (pjsip_rx_data *rdata, char *packet, const char *src_name, int src_port, char *transport_type, const char *local_name, int local_port, const char *contact)
 General purpose method for creating an rdata structure using specific information. More...
 
int ast_sip_create_request (const char *method, struct pjsip_dialog *dlg, struct ast_sip_endpoint *endpoint, const char *uri, struct ast_sip_contact *contact, pjsip_tx_data **tdata)
 General purpose method for creating a SIP request. More...
 
int ast_sip_create_request_with_auth (const struct ast_sip_auth_vector *auths, pjsip_rx_data *challenge, pjsip_tx_data *old_request, pjsip_tx_data **new_request)
 Create a response to an authentication challenge. More...
 
int ast_sip_create_response (const pjsip_rx_data *rdata, int st_code, struct ast_sip_contact *contact, pjsip_tx_data **tdata)
 General purpose method for creating a SIP response. More...
 
struct ast_taskprocessorast_sip_create_serializer (const char *name)
 Create a new serializer for SIP tasks. More...
 
struct ast_taskprocessorast_sip_create_serializer_group (const char *name, struct ast_serializer_shutdown_group *shutdown_group)
 Create a new serializer for SIP tasks. More...
 
void * ast_sip_dict_get (void *ht, const char *key)
 Retrieves the value associated with the given key. More...
 
void * ast_sip_dict_set (pj_pool_t *pool, void *ht, const char *key, void *val)
 Set the value for the given key. More...
 
int ast_sip_dlg_set_transport (const struct ast_sip_endpoint *endpoint, pjsip_dialog *dlg, pjsip_tpselector *selector)
 Set the transport on a dialog. More...
 
int ast_sip_dtmf_to_str (const enum ast_sip_dtmf_mode dtmf, char *buf, size_t buf_len)
 Convert the DTMF mode enum value into a string. More...
 
int ast_sip_failover_request (pjsip_tx_data *tdata)
 Set a request to use the next value in the list of resolved addresses. More...
 
int ast_sip_format_endpoint_ami (struct ast_sip_endpoint *endpoint, struct ast_sip_ami *ami, int *count)
 Formats the endpoint and sends over AMI. More...
 
int ast_sip_get_host_ip (int af, pj_sockaddr *addr)
 Retrieve the local host address in IP form. More...
 
const char * ast_sip_get_host_ip_string (int af)
 Retrieve the local host address in string form. More...
 
pjsip_endpoint * ast_sip_get_pjsip_endpoint (void)
 Get a pointer to the PJSIP endpoint. More...
 
int ast_sip_get_transport_name (const struct ast_sip_endpoint *endpoint, pjsip_sip_uri *sip_uri, char *buf, size_t buf_len)
 Get the transport name from an endpoint or request uri. More...
 
struct ast_sip_endpointast_sip_identify_endpoint (pjsip_rx_data *rdata)
 Determine the endpoint that has sent a SIP message. More...
 
int ast_sip_is_content_type (pjsip_media_type *content_type, char *type, char *subtype)
 Checks if the given content type matches type/subtype. More...
 
void ast_sip_modify_id_header (pj_pool_t *pool, pjsip_fromto_hdr *id_hdr, const struct ast_party_id *id)
 Set name and number information on an identity header. More...
 
int ast_sip_push_task (struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
 Pushes a task to SIP servants. More...
 
int ast_sip_push_task_synchronous (struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
 Push a task to SIP servants and wait for it to complete. More...
 
static int ast_sip_push_task_wait (struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
 
int ast_sip_push_task_wait_serializer (struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
 Push a task to the serializer and wait for it to complete. More...
 
int ast_sip_push_task_wait_servant (struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
 Push a task to SIP servants and wait for it to complete. More...
 
char * ast_sip_rdata_get_header_value (pjsip_rx_data *rdata, const pj_str_t str)
 Get a specific header value from rdata. More...
 
int ast_sip_register_authenticator (struct ast_sip_authenticator *auth)
 Register a SIP authenticator. More...
 
void ast_sip_register_endpoint_formatter (struct ast_sip_endpoint_formatter *obj)
 Register an endpoint formatter. More...
 
int ast_sip_register_endpoint_identifier (struct ast_sip_endpoint_identifier *identifier)
 Register a SIP endpoint identifier. More...
 
int ast_sip_register_endpoint_identifier_with_name (struct ast_sip_endpoint_identifier *identifier, const char *name)
 Register a SIP endpoint identifier with a name. More...
 
int ast_sip_register_outbound_authenticator (struct ast_sip_outbound_authenticator *auth)
 Register an outbound SIP authenticator. More...
 
int ast_sip_register_service (pjsip_module *module)
 Register a SIP service in Asterisk. More...
 
void ast_sip_register_supplement (struct ast_sip_supplement *supplement)
 Register a supplement to SIP out of dialog processing. More...
 
int ast_sip_requires_authentication (struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata)
 Determine if an incoming request requires authentication. More...
 
int ast_sip_send_out_of_dialog_request (pjsip_tx_data *tdata, struct ast_sip_endpoint *endpoint, int timeout, void *token, void(*callback)(void *token, pjsip_event *e))
 General purpose method for sending an Out-Of-Dialog SIP request. More...
 
int ast_sip_send_request (pjsip_tx_data *tdata, struct pjsip_dialog *dlg, struct ast_sip_endpoint *endpoint, void *token, void(*callback)(void *token, pjsip_event *e))
 General purpose method for sending a SIP request. More...
 
int ast_sip_send_response (pjsip_response_addr *res_addr, pjsip_tx_data *tdata, struct ast_sip_endpoint *sip_endpoint)
 Send a response to an out of dialog request. More...
 
int ast_sip_send_stateful_response (pjsip_rx_data *rdata, pjsip_tx_data *tdata, struct ast_sip_endpoint *sip_endpoint)
 Send a stateful response to an out of dialog request. More...
 
int ast_sip_set_outbound_proxy (pjsip_tx_data *tdata, const char *proxy)
 Set the outbound proxy for an outbound SIP message. More...
 
int ast_sip_set_tpselector_from_ep_or_uri (const struct ast_sip_endpoint *endpoint, pjsip_sip_uri *sip_uri, pjsip_tpselector *selector)
 Sets pjsip_tpselector from an endpoint or uri. More...
 
int ast_sip_set_tpselector_from_transport (const struct ast_sip_transport *transport, pjsip_tpselector *selector)
 Sets pjsip_tpselector from ast_sip_transport. More...
 
int ast_sip_set_tpselector_from_transport_name (const char *transport_name, pjsip_tpselector *selector)
 Sets pjsip_tpselector from ast_sip_transport. More...
 
int ast_sip_str_to_dtmf (const char *dtmf_mode)
 Convert the DTMF mode name into an enum. More...
 
int ast_sip_thread_is_servant (void)
 Determine if the current thread is a SIP servant thread. More...
 
struct ast_threadpoolast_sip_threadpool (void)
 Retrieve the SIP threadpool object. More...
 
long ast_sip_threadpool_queue_size (void)
 Return the size of the SIP threadpool's task queue. More...
 
void ast_sip_tpselector_unref (pjsip_tpselector *selector)
 Unreference a pjsip_tpselector. More...
 
void ast_sip_unregister_authenticator (struct ast_sip_authenticator *auth)
 Unregister a SIP authenticator. More...
 
void ast_sip_unregister_endpoint_formatter (struct ast_sip_endpoint_formatter *obj)
 Unregister an endpoint formatter. More...
 
void ast_sip_unregister_endpoint_identifier (struct ast_sip_endpoint_identifier *identifier)
 Unregister a SIP endpoint identifier. More...
 
void ast_sip_unregister_outbound_authenticator (struct ast_sip_outbound_authenticator *auth)
 Unregister an outbound SIP authenticator. More...
 
void ast_sip_unregister_service (pjsip_module *module)
 
void ast_sip_unregister_supplement (struct ast_sip_supplement *supplement)
 Unregister a an supplement to SIP out of dialog processing. More...
 
int ast_sip_will_uri_survive_restart (pjsip_sip_uri *uri, struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata)
 
static int check_request_status (struct send_request_data *req_data, pjsip_event *e)
 
static char * cli_dump_endpt (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * cli_show_endpoint_identifiers (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * cli_show_settings (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static pjsip_dialog * create_dialog_uas (const struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, pj_status_t *status, create_dlg_uac create_fun)
 
static int create_in_dialog_request (const pjsip_method *method, struct pjsip_dialog *dlg, pjsip_tx_data **tdata)
 
static int create_out_of_dialog_request (const pjsip_method *method, struct ast_sip_endpoint *endpoint, const char *uri, struct ast_sip_contact *provided_contact, pjsip_tx_data **tdata)
 
static int do_cli_dump_endpt (void *v_a)
 
static pj_bool_t does_method_match (const pj_str_t *message_method, const char *supplement_method)
 
static pj_status_t endpt_send_request (struct ast_sip_endpoint *endpoint, pjsip_tx_data *tdata, pj_int32_t timeout, void *token, pjsip_endpt_send_callback cb)
 
static void endpt_send_request_cb (void *token, pjsip_event *e)
 
static const pjsip_method * get_pjsip_method (const char *method)
 
static int load_module (void)
 
static int load_pjsip (void)
 
static void * monitor_thread_exec (void *endpt)
 
void never_called_res_pjsip (void)
 
static int register_service (void *data)
 
static int reload_configuration_task (void *obj)
 
static int reload_module (void)
 
static void remove_request_headers (pjsip_endpoint *endpt)
 
static int send_in_dialog_request (pjsip_tx_data *tdata, struct pjsip_dialog *dlg)
 
static void send_request_cb (void *token, pjsip_event *e)
 
static struct send_request_datasend_request_data_alloc (struct ast_sip_endpoint *endpoint, void *token, void(*callback)(void *token, pjsip_event *e))
 
static void send_request_data_destroy (void *obj)
 
static void send_request_timer_callback (pj_timer_heap_t *theap, pj_timer_entry *entry)
 
static void send_request_wrapper_destructor (void *obj)
 
static int sip_dialog_create_from (pj_pool_t *pool, pj_str_t *from, const char *user, const char *domain, const pj_str_t *target, pjsip_tpselector *selector)
 
static void sip_thread_start (void)
 
static void stop_monitor_thread (void)
 
static pj_bool_t supplement_on_rx_request (pjsip_rx_data *rdata)
 
static void supplement_outgoing_response (pjsip_tx_data *tdata, struct ast_sip_endpoint *sip_endpoint)
 
static int sync_task (void *data)
 
static int uas_use_sips_contact (pjsip_rx_data *rdata)
 Determine if a SIPS Contact header is required. More...
 
static int unload_module (void)
 
static int unload_pjsip (void *data)
 
static int unregister_service (void *data)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "Basic SIP resource" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND - 5, .requires = "dnsmgr,res_pjproject,res_sorcery_config,res_sorcery_memory,res_sorcery_astdb", .optional_modules = "res_statsd", }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static pjsip_endpoint * ast_pjsip_endpoint
 
pj_caching_pool caching_pool
 
static struct ast_cli_entry cli_commands []
 
struct endpoint_formatters endpoint_formatters = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
 
static struct endpoint_identifiers endpoint_identifiers = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
 
static pj_sockaddr host_ip_ipv4
 
static char host_ip_ipv4_string [PJ_INET6_ADDRSTRLEN]
 
static pj_sockaddr host_ip_ipv6
 
static char host_ip_ipv6_string [PJ_INET6_ADDRSTRLEN]
 
static const pjsip_method info_method = {PJSIP_OTHER_METHOD, {"INFO", 4} }
 
pj_pool_t * memory_pool
 
static const pjsip_method message_method = {PJSIP_OTHER_METHOD, {"MESSAGE", 7} }
 
struct {
   const char *   method
 
   const pjsip_method *   pmethod
 
methods []
 
static int monitor_continue
 
pj_thread_t * monitor_thread
 
static struct ast_threadstorage pj_thread_storage = { .once = PTHREAD_ONCE_INIT , .key_init = __init_pj_thread_storage , .custom_init = NULL , }
 
static struct ast_sip_authenticatorregistered_authenticator
 
static struct ast_sip_outbound_authenticatorregistered_outbound_authenticator
 
static struct ast_threadstorage servant_id_storage = { .once = PTHREAD_ONCE_INIT , .key_init = __init_servant_id_storage , .custom_init = NULL , }
 
static struct ast_serializer_poolsip_serializer_pool
 
static struct ast_threadpoolsip_threadpool
 
static pjsip_module supplement_module
 
struct supplements supplements = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
 

Macro Definition Documentation

◆ ENDPOINT_IDENTIFIER_FORMAT

#define ENDPOINT_IDENTIFIER_FORMAT   "%-20.20s\n"

◆ MOD_DATA_CONTACT

#define MOD_DATA_CONTACT   "contact"

◆ SERIALIZER_POOL_SIZE

#define SERIALIZER_POOL_SIZE   8

Number of serializers in pool if one not supplied.

Definition at line 3181 of file res_pjsip.c.

Referenced by load_module().

◆ SIP_SERVANT_ID

#define SIP_SERVANT_ID   0x5E2F1D

Definition at line 5179 of file res_pjsip.c.

Referenced by ast_sip_thread_is_servant(), and sip_thread_start().

◆ TIMEOUT_TIMER2

#define TIMEOUT_TIMER2   5

◆ TIMER_INACTIVE

#define TIMER_INACTIVE   0

Typedef Documentation

◆ create_dlg_uac

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

Definition at line 4059 of file res_pjsip.c.

Function Documentation

◆ __init_pj_thread_storage()

static void __init_pj_thread_storage ( void  )
static

Definition at line 5177 of file res_pjsip.c.

5182 {

◆ __init_servant_id_storage()

static void __init_servant_id_storage ( void  )
static

Definition at line 5178 of file res_pjsip.c.

5182 {

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 5847 of file res_pjsip.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 5847 of file res_pjsip.c.

◆ ast_body_to_pjsip_body()

static pjsip_msg_body* ast_body_to_pjsip_body ( pj_pool_t *  pool,
const struct ast_sip_body body 
)
static

Definition at line 4963 of file res_pjsip.c.

References ast_sip_body::body_text, ast_sip_body::subtype, type, and ast_sip_body::type.

Referenced by ast_sip_add_body(), and ast_sip_add_body_multipart().

4964 {
4965  pj_str_t type;
4966  pj_str_t subtype;
4967  pj_str_t body_text;
4968 
4969  pj_cstr(&type, body->type);
4970  pj_cstr(&subtype, body->subtype);
4971  pj_cstr(&body_text, body->body_text);
4972 
4973  return pjsip_msg_body_create(pool, &type, &subtype, &body_text);
4974 }
static const char type[]
Definition: chan_ooh323.c:109
const char * body_text
Definition: res_pjsip.h:2020
const char * type
Definition: res_pjsip.h:2016
const char * subtype
Definition: res_pjsip.h:2018

◆ ast_copy_pj_str()

void ast_copy_pj_str ( char *  dest,
const pj_str_t *  src,
size_t  size 
)

Copy a pj_str_t into a standard character buffer.

pj_str_t is not NULL-terminated. Any place that expects a NULL- terminated string needs to have the pj_str_t copied into a separate buffer.

This method copies the pj_str_t contents into the destination buffer and NULL-terminates the buffer.

Parameters
destThe destination buffer
srcThe pj_str_t to copy
sizeThe size of the destination buffer.

Definition at line 5125 of file res_pjsip.c.

References MIN.

Referenced by apply_dtls_attrib(), apply_negotiated_sdp_stream(), assign_uuid(), ast_sip_get_transport_name(), ast_sip_report_auth_challenge_sent(), ast_sip_report_auth_failed_challenge_response(), chan_pjsip_get_uniqueid(), change_outgoing_sdp_stream_media_address(), channel_read_pjsip(), cli_complete_subscription_common(), cli_list_subscriptions_detail(), cli_show_subscriptions_detail(), determine_sip_publish_type(), endpoint_lookup(), evaluate_like(), extract_contact_addr(), find_aor(), find_aor_name(), find_challenge(), get_auth_header(), get_codecs(), get_destination(), get_endpoint_details(), get_from_header(), get_mid_bundle_group(), get_user_agent(), handle_incoming_sdp(), handle_negotiated_sdp_session_media(), handle_registration_response(), headers_to_vars(), incoming_in_dialog_request(), log_failed_request(), negotiate_incoming_sdp_stream(), options_on_rx_request(), parse_uri_cb(), process_extmap_attributes(), process_ice_attributes(), process_ssrc_attributes(), publish_request_initial(), pubsub_on_rx_publish_request(), pubsub_on_rx_subscribe_request(), refer_blind_callback(), refer_incoming_blind_request(), refer_incoming_refer_request(), register_aor_core(), rfc3326_use_reason_header(), rx_data_to_ast_msg(), save_response_fields_to_transport(), sdp_requires_deferral(), security_event_populate(), session_inv_on_redirected(), session_outgoing_nat_hook(), set_id_from_hdr(), set_mid_and_bundle_group(), set_redirecting_value(), set_remote_mslabel_and_stream_group(), set_sipdomain_variable(), sip_subscription_to_ami(), sub_persistence_recreate(), subscription_get_generator_from_rdata(), subscription_get_handler_from_rdata(), subscription_persistence_create(), subscription_persistence_update(), and transfer_refer().

5126 {
5127  size_t chars_to_copy = MIN(size - 1, pj_strlen(src));
5128  memcpy(dest, pj_strbuf(src), chars_to_copy);
5129  dest[chars_to_copy] = '\0';
5130 }
#define MIN(a, b)
Definition: utils.h:226

◆ ast_copy_pj_str2()

int ast_copy_pj_str2 ( char **  dest,
const pj_str_t *  src 
)

Create and copy a pj_str_t into a standard character buffer.

pj_str_t is not NULL-terminated. Any place that expects a NULL- terminated string needs to have the pj_str_t copied into a separate buffer.

Copies the pj_str_t contents into a newly allocated buffer pointed to by dest. NULL-terminates the buffer.

Note
Caller is responsible for freeing the allocated memory.
Parameters
dest[out] The destination buffer
srcThe pj_str_t to copy
Return values
Numberof characters copied or negative value on error

Definition at line 5132 of file res_pjsip.c.

References ast_asprintf, and NULL.

5133 {
5134  int res = ast_asprintf(dest, "%.*s", (int)pj_strlen(src), pj_strbuf(src));
5135 
5136  if (res < 0) {
5137  *dest = NULL;
5138  }
5139 
5140  return res;
5141 }
#define NULL
Definition: resample.c:96
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:269

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 5847 of file res_pjsip.c.

◆ ast_sip_add_body()

int ast_sip_add_body ( pjsip_tx_data *  tdata,
const struct ast_sip_body body 
)

Add a body to an outbound SIP message.

If this is called multiple times, the latest body will replace the current body.

Parameters
tdataThe message to add the body to
bodyThe message body to add
Return values
0Success
-1Failure

Definition at line 4976 of file res_pjsip.c.

References ast_body_to_pjsip_body().

Referenced by build_notify_body(), msg_send(), send_unsolicited_mwi_notify_to_contact(), sendtext(), sip_publisher_service_queue(), transmit_info_dtmf(), and transmit_info_with_vidupdate().

4977 {
4978  pjsip_msg_body *pjsip_body = ast_body_to_pjsip_body(tdata->pool, body);
4979  tdata->msg->body = pjsip_body;
4980  return 0;
4981 }
static pjsip_msg_body * ast_body_to_pjsip_body(pj_pool_t *pool, const struct ast_sip_body *body)
Definition: res_pjsip.c:4963

◆ ast_sip_add_body_multipart()

int ast_sip_add_body_multipart ( pjsip_tx_data *  tdata,
const struct ast_sip_body bodies[],
int  num_bodies 
)

Add a multipart body to an outbound SIP message.

This will treat each part of the input vector as part of a multipart body and add each part to the SIP message.

Parameters
tdataThe message to add the body to
bodiesThe parts of the body to add
Return values
0Success
-1Failure

Definition at line 4983 of file res_pjsip.c.

References ast_body_to_pjsip_body(), and NULL.

4984 {
4985  int i;
4986  /* NULL for type and subtype automatically creates "multipart/mixed" */
4987  pjsip_msg_body *body = pjsip_multipart_create(tdata->pool, NULL, NULL);
4988 
4989  for (i = 0; i < num_bodies; ++i) {
4990  pjsip_multipart_part *part = pjsip_multipart_create_part(tdata->pool);
4991  part->body = ast_body_to_pjsip_body(tdata->pool, bodies[i]);
4992  pjsip_multipart_add_part(tdata->pool, body, part);
4993  }
4994 
4995  tdata->msg->body = body;
4996  return 0;
4997 }
#define NULL
Definition: resample.c:96
static pjsip_msg_body * ast_body_to_pjsip_body(pj_pool_t *pool, const struct ast_sip_body *body)
Definition: res_pjsip.c:4963

◆ ast_sip_add_header()

int ast_sip_add_header ( pjsip_tx_data *  tdata,
const char *  name,
const char *  value 
)

Add a header to an outbound SIP message.

Parameters
tdataThe message to add the header to
nameThe header name
valueThe header value
Return values
0Success
-1Failure

Definition at line 4948 of file res_pjsip.c.

Referenced by add_header_from_channel_var(), add_headers_to_message(), ast_sip_message_apply_transport(), build_notify(), notify_channel(), notify_contact(), notify_uri(), options_incoming_request(), registrar_add_date_header(), rfc3326_add_reason_header(), send_options_response(), sip_publication_respond(), transfer_refer(), and vars_to_headers().

4949 {
4950  pj_str_t hdr_name;
4951  pj_str_t hdr_value;
4952  pjsip_generic_string_hdr *hdr;
4953 
4954  pj_cstr(&hdr_name, name);
4955  pj_cstr(&hdr_value, value);
4956 
4957  hdr = pjsip_generic_string_hdr_create(tdata->pool, &hdr_name, &hdr_value);
4958 
4959  pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *) hdr);
4960  return 0;
4961 }
int value
Definition: syslog.c:37
static const char name[]
Definition: cdr_mysql.c:74

◆ ast_sip_add_usereqphone()

void ast_sip_add_usereqphone ( const struct ast_sip_endpoint endpoint,
pj_pool_t *  pool,
pjsip_uri *  uri 
)

Add 'user=phone' parameter to URI if enabled and user is a phone number.

Parameters
endpointThe endpoint to use for configuration
poolThe memory pool to allocate the parameter from
uriThe URI to check for user and to add parameter to

Definition at line 3879 of file res_pjsip.c.

References AST_DIGIT_ANY, and ast_sip_endpoint::usereqphone.

Referenced by ast_sip_create_dialog_uac(), create_out_of_dialog_request(), and set_from_header().

3880 {
3881  pjsip_sip_uri *sip_uri;
3882  int i = 0;
3883  static const pj_str_t STR_PHONE = { "phone", 5 };
3884 
3885  if (!endpoint || !endpoint->usereqphone || (!PJSIP_URI_SCHEME_IS_SIP(uri) && !PJSIP_URI_SCHEME_IS_SIPS(uri))) {
3886  return;
3887  }
3888 
3889  sip_uri = pjsip_uri_get_uri(uri);
3890 
3891  if (!pj_strlen(&sip_uri->user)) {
3892  return;
3893  }
3894 
3895  if (pj_strbuf(&sip_uri->user)[0] == '+') {
3896  i = 1;
3897  }
3898 
3899  /* Test URI user against allowed characters in AST_DIGIT_ANY */
3900  for (; i < pj_strlen(&sip_uri->user); i++) {
3901  if (!strchr(AST_DIGIT_ANY, pj_strbuf(&sip_uri->user)[i])) {
3902  break;
3903  }
3904  }
3905 
3906  if (i < pj_strlen(&sip_uri->user)) {
3907  return;
3908  }
3909 
3910  sip_uri->user_param = STR_PHONE;
3911 }
#define AST_DIGIT_ANY
Definition: file.h:48
unsigned int usereqphone
Definition: res_pjsip.h:877

◆ ast_sip_append_body()

int ast_sip_append_body ( pjsip_tx_data *  tdata,
const char *  body_text 
)

Append body data to a SIP message.

This acts mostly the same as ast_sip_add_body, except that rather than replacing a body if it currently exists, it appends data to an existing body.

Parameters
tdataThe message to append the body to
bodyThe string to append to the end of the current body
Return values
0Success
-1Failure

Definition at line 4999 of file res_pjsip.c.

References ast_str_alloca, ast_str_buffer(), and ast_str_set().

5000 {
5001  size_t combined_size = strlen(body_text) + tdata->msg->body->len;
5002  struct ast_str *body_buffer = ast_str_alloca(combined_size);
5003 
5004  ast_str_set(&body_buffer, 0, "%.*s%s", (int) tdata->msg->body->len, (char *) tdata->msg->body->data, body_text);
5005 
5006  tdata->msg->body->data = pj_pool_alloc(tdata->pool, combined_size);
5007  pj_memcpy(tdata->msg->body->data, ast_str_buffer(body_buffer), combined_size);
5008  tdata->msg->body->len = combined_size;
5009 
5010  return 0;
5011 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define ast_str_alloca(init_len)
Definition: strings.h:800
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584

◆ ast_sip_call_codec_pref_to_str()

const char* ast_sip_call_codec_pref_to_str ( struct ast_flags  pref)

Convert the call codec preference flags to a string.

Since
18.0.0
Parameters
prefthe call codec preference setting
Returns
a constant string with either the setting value or 'unknown'
Note
Don't try to free the string!

Definition at line 5419 of file res_pjsip.c.

References value.

Referenced by incoming_call_offer_pref_to_str(), log_caps(), and outgoing_call_offer_pref_to_str().

5420 {
5421  const char *value;
5422 
5423  if (ast_sip_call_codec_pref_test(pref, LOCAL) && ast_sip_call_codec_pref_test(pref, INTERSECT) && ast_sip_call_codec_pref_test(pref, ALL)) {
5424  value = "local";
5425  } else if (ast_sip_call_codec_pref_test(pref, LOCAL) && ast_sip_call_codec_pref_test(pref, UNION) && ast_sip_call_codec_pref_test(pref, ALL)) {
5426  value = "local_merge";
5427  } else if (ast_sip_call_codec_pref_test(pref, LOCAL) && ast_sip_call_codec_pref_test(pref, INTERSECT) && ast_sip_call_codec_pref_test(pref, FIRST)) {
5428  value = "local_first";
5429  } else if (ast_sip_call_codec_pref_test(pref, REMOTE) && ast_sip_call_codec_pref_test(pref, INTERSECT) && ast_sip_call_codec_pref_test(pref, ALL)) {
5430  value = "remote";
5431  } else if (ast_sip_call_codec_pref_test(pref, REMOTE) && ast_sip_call_codec_pref_test(pref, UNION) && ast_sip_call_codec_pref_test(pref, ALL)) {
5432  value = "remote_merge";
5433  } else if (ast_sip_call_codec_pref_test(pref, REMOTE) && ast_sip_call_codec_pref_test(pref, UNION) && ast_sip_call_codec_pref_test(pref, FIRST)) {
5434  value = "remote_first";
5435  } else {
5436  value = "unknown";
5437  }
5438 
5439  return value;
5440 }
int value
Definition: syslog.c:37

◆ ast_sip_call_codec_str_to_pref()

int ast_sip_call_codec_str_to_pref ( struct ast_flags pref,
const char *  pref_str,
int  is_outgoing 
)

Convert a call codec preference string to preference flags.

Since
18.0.0
Parameters
prefA pointer to an ast_flags structure to receive the preference flags
pref_strThe call codec preference setting string
is_outgoingIs for outgoing calls?
Return values
0The string was parsed successfully
-1The string option was invalid

Definition at line 5442 of file res_pjsip.c.

References ast_set_flag, AST_SIP_CALL_CODEC_PREF_ALL, AST_SIP_CALL_CODEC_PREF_FIRST, AST_SIP_CALL_CODEC_PREF_INTERSECT, AST_SIP_CALL_CODEC_PREF_LOCAL, AST_SIP_CALL_CODEC_PREF_REMOTE, AST_SIP_CALL_CODEC_PREF_UNION, and ast_flags::flags.

Referenced by call_offer_pref_handler(), and test_create_joint().

5443 {
5444  pref->flags = 0;
5445 
5446  if (strcmp(pref_str, "local") == 0) {
5448  } else if (is_outgoing && strcmp(pref_str, "local_merge") == 0) {
5450  } else if (strcmp(pref_str, "local_first") == 0) {
5452  } else if (strcmp(pref_str, "remote") == 0) {
5454  } else if (is_outgoing && strcmp(pref_str, "remote_merge") == 0) {
5456  } else if (strcmp(pref_str, "remote_first") == 0) {
5458  } else {
5459  return -1;
5460  }
5461 
5462  return 0;
5463 }
#define ast_set_flag(p, flag)
Definition: utils.h:70
unsigned int flags
Definition: utils.h:200

◆ ast_sip_check_authentication()

enum ast_sip_check_auth_result ast_sip_check_authentication ( struct ast_sip_endpoint endpoint,
pjsip_rx_data *  rdata,
pjsip_tx_data *  tdata 
)

Method to determine authentication status of an incoming request.

This will call into a registered authenticator. The registered authenticator will do what is necessary to determine whether the incoming request passes authentication. A tentative response is passed into this function so that if, say, a digest authentication challenge should be sent in the ensuing response, it can be added to the response.

Parameters
endpointThe endpoint from the request was sent
rdataThe request to potentially authenticate
tdataTentative response to the request
Returns
The result of checking authentication.

Definition at line 3273 of file res_pjsip.c.

References ast_log, AST_SIP_AUTHENTICATION_SUCCESS, ast_sip_authenticator::check_authentication, and LOG_WARNING.

Referenced by authenticate().

3275 {
3276  if (!registered_authenticator) {
3277  ast_log(LOG_WARNING, "No SIP authenticator registered. Assuming authentication is successful\n");
3279  }
3280  return registered_authenticator->check_authentication(endpoint, rdata, tdata);
3281 }
static struct ast_sip_authenticator * registered_authenticator
Definition: res_pjsip.c:3238
#define LOG_WARNING
Definition: logger.h:274
enum ast_sip_check_auth_result(* check_authentication)(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, pjsip_tx_data *tdata)
Check that an incoming request passes authentication.
Definition: res_pjsip.h:963
#define ast_log
Definition: astobj2.c:42

◆ ast_sip_create_dialog_uac()

pjsip_dialog* ast_sip_create_dialog_uac ( const struct ast_sip_endpoint endpoint,
const char *  aor_name,
const char *  request_user 
)

General purpose method for creating a UAC dialog with an endpoint.

Parameters
endpointA pointer to the endpoint
aor_nameOptional name of the AOR to target, may even be an explicit SIP URI
request_userOptional user to place into the target URI
Return values
non-NULLsuccess
NULLfailure

Definition at line 3913 of file res_pjsip.c.

References ast_log, ast_sip_add_usereqphone(), ast_sip_dlg_set_transport(), ast_sip_tpselector_unref(), ast_sorcery_object_get_id(), ast_strlen_zero, ast_sip_endpoint::contact_user, ast_sip_endpoint::fromdomain, ast_sip_endpoint::fromuser, ast_sip_endpoint::info, LOG_ERROR, NULL, ast_sip_endpoint::outbound_proxy, sip_dialog_create_from(), and tmp().

Referenced by ast_sip_create_subscription(), and ast_sip_session_create_outgoing().

3915 {
3916  char enclosed_uri[PJSIP_MAX_URL_SIZE];
3917  pj_str_t local_uri = { "sip:temp@temp", 13 }, remote_uri, target_uri;
3918  pj_status_t res;
3919  pjsip_dialog *dlg = NULL;
3920  const char *outbound_proxy = endpoint->outbound_proxy;
3921  pjsip_tpselector selector = { .type = PJSIP_TPSELECTOR_NONE, };
3922  static const pj_str_t HCONTACT = { "Contact", 7 };
3923 
3924  snprintf(enclosed_uri, sizeof(enclosed_uri), "<%s>", uri);
3925  pj_cstr(&remote_uri, enclosed_uri);
3926 
3927  pj_cstr(&target_uri, uri);
3928 
3929  res = pjsip_dlg_create_uac(pjsip_ua_instance(), &local_uri, NULL, &remote_uri, &target_uri, &dlg);
3930  if (res == PJ_SUCCESS && !(PJSIP_URI_SCHEME_IS_SIP(dlg->target) || PJSIP_URI_SCHEME_IS_SIPS(dlg->target))) {
3931  /* dlg->target is a pjsip_other_uri, but it's assumed to be a
3932  * pjsip_sip_uri below. Fail fast. */
3933  res = PJSIP_EINVALIDURI;
3934  pjsip_dlg_terminate(dlg);
3935  }
3936  if (res != PJ_SUCCESS) {
3937  if (res == PJSIP_EINVALIDURI) {
3939  "Endpoint '%s': Could not create dialog to invalid URI '%s'. Is endpoint registered and reachable?\n",
3940  ast_sorcery_object_get_id(endpoint), uri);
3941  }
3942  return NULL;
3943  }
3944 
3945  /* We have to temporarily bump up the sess_count here so the dialog is not prematurely destroyed */
3946  dlg->sess_count++;
3947 
3948  ast_sip_dlg_set_transport(endpoint, dlg, &selector);
3949 
3950  if (sip_dialog_create_from(dlg->pool, &local_uri, endpoint->fromuser, endpoint->fromdomain, &remote_uri, &selector)) {
3951  dlg->sess_count--;
3952  pjsip_dlg_terminate(dlg);
3953  ast_sip_tpselector_unref(&selector);
3954  return NULL;
3955  }
3956 
3957  ast_sip_tpselector_unref(&selector);
3958 
3959  /* Update the dialog with the new local URI, we do it afterwards so we can use the dialog pool for construction */
3960  pj_strdup_with_null(dlg->pool, &dlg->local.info_str, &local_uri);
3961  dlg->local.info->uri = pjsip_parse_uri(dlg->pool, dlg->local.info_str.ptr, dlg->local.info_str.slen, 0);
3962  if (!dlg->local.info->uri) {
3964  "Could not parse URI '%s' for endpoint '%s'\n",
3965  dlg->local.info_str.ptr, ast_sorcery_object_get_id(endpoint));
3966  dlg->sess_count--;
3967  pjsip_dlg_terminate(dlg);
3968  return NULL;
3969  }
3970 
3971  dlg->local.contact = pjsip_parse_hdr(dlg->pool, &HCONTACT, local_uri.ptr, local_uri.slen, NULL);
3972 
3973  if (!ast_strlen_zero(endpoint->contact_user)) {
3974  pjsip_sip_uri *sip_uri;
3975 
3976  sip_uri = pjsip_uri_get_uri(dlg->local.contact->uri);
3977  pj_strdup2(dlg->pool, &sip_uri->user, endpoint->contact_user);
3978  }
3979 
3980  /* If a request user has been specified and we are permitted to change it, do so */
3981  if (!ast_strlen_zero(request_user)) {
3982  pjsip_sip_uri *sip_uri;
3983 
3984  if (PJSIP_URI_SCHEME_IS_SIP(dlg->target) || PJSIP_URI_SCHEME_IS_SIPS(dlg->target)) {
3985  sip_uri = pjsip_uri_get_uri(dlg->target);
3986  pj_strdup2(dlg->pool, &sip_uri->user, request_user);
3987  }
3988  if (PJSIP_URI_SCHEME_IS_SIP(dlg->remote.info->uri) || PJSIP_URI_SCHEME_IS_SIPS(dlg->remote.info->uri)) {
3989  sip_uri = pjsip_uri_get_uri(dlg->remote.info->uri);
3990  pj_strdup2(dlg->pool, &sip_uri->user, request_user);
3991  }
3992  }
3993 
3994  /* Add the user=phone parameter if applicable */
3995  ast_sip_add_usereqphone(endpoint, dlg->pool, dlg->target);
3996  ast_sip_add_usereqphone(endpoint, dlg->pool, dlg->remote.info->uri);
3997 
3998  if (!ast_strlen_zero(outbound_proxy)) {
3999  pjsip_route_hdr route_set, *route;
4000  static const pj_str_t ROUTE_HNAME = { "Route", 5 };
4001  pj_str_t tmp;
4002 
4003  pj_list_init(&route_set);
4004 
4005  pj_strdup2_with_null(dlg->pool, &tmp, outbound_proxy);
4006  if (!(route = pjsip_parse_hdr(dlg->pool, &ROUTE_HNAME, tmp.ptr, tmp.slen, NULL))) {
4007  ast_log(LOG_ERROR, "Could not create dialog to endpoint '%s' as outbound proxy URI '%s' is not valid\n",
4008  ast_sorcery_object_get_id(endpoint), outbound_proxy);
4009  dlg->sess_count--;
4010  pjsip_dlg_terminate(dlg);
4011  return NULL;
4012  }
4013  pj_list_insert_nodes_before(&route_set, route);
4014 
4015  pjsip_dlg_set_route_set(dlg, &route_set);
4016  }
4017 
4018  dlg->sess_count--;
4019 
4020  return dlg;
4021 }
void ast_sip_add_usereqphone(const struct ast_sip_endpoint *endpoint, pj_pool_t *pool, pjsip_uri *uri)
Add &#39;user=phone&#39; parameter to URI if enabled and user is a phone number.
Definition: res_pjsip.c:3879
const ast_string_field fromuser
Definition: res_pjsip.h:829
char * contact_user
Definition: res_pjsip.h:887
static int tmp()
Definition: bt_open.c:389
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2309
const ast_string_field outbound_proxy
Definition: res_pjsip.h:819
struct ast_sip_endpoint_info_configuration info
Definition: res_pjsip.h:849
#define LOG_ERROR
Definition: logger.h:285
#define ast_strlen_zero(a)
Definition: muted.c:73
void ast_sip_tpselector_unref(pjsip_tpselector *selector)
Unreference a pjsip_tpselector.
Definition: res_pjsip.c:3872
int ast_sip_dlg_set_transport(const struct ast_sip_endpoint *endpoint, pjsip_dialog *dlg, pjsip_tpselector *selector)
Set the transport on a dialog.
Definition: res_pjsip.c:3687
static int sip_dialog_create_from(pj_pool_t *pool, pj_str_t *from, const char *user, const char *domain, const pj_str_t *target, pjsip_tpselector *selector)
Definition: res_pjsip.c:3709
const ast_string_field fromdomain
Definition: res_pjsip.h:831

◆ ast_sip_create_dialog_uas()

pjsip_dialog* ast_sip_create_dialog_uas ( const struct ast_sip_endpoint endpoint,
pjsip_rx_data *  rdata,
pj_status_t *  status 
)

General purpose method for creating a UAS dialog with an endpoint.

Deprecated:
This function is unsafe (due to the returned object not being locked nor having its reference incremented) and should no longer be used. Instead use ast_sip_create_dialog_uas_locked so a properly locked and referenced object is returned.
Parameters
endpointA pointer to the endpoint
rdataThe request that is starting the dialog
[out]statusOn failure, the reason for failure in creating the dialog

Definition at line 4118 of file res_pjsip.c.

References create_dialog_uas().

4119 {
4120 #ifdef HAVE_PJSIP_DLG_CREATE_UAS_AND_INC_LOCK
4121  pjsip_dialog *dlg;
4122 
4123  dlg = create_dialog_uas(endpoint, rdata, status, pjsip_dlg_create_uas_and_inc_lock);
4124  if (dlg) {
4125  pjsip_dlg_dec_lock(dlg);
4126  }
4127 
4128  return dlg;
4129 #else
4130  return create_dialog_uas(endpoint, rdata, status, pjsip_dlg_create_uas);
4131 #endif
4132 }
static pjsip_dialog * create_dialog_uas(const struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, pj_status_t *status, create_dlg_uac create_fun)
Definition: res_pjsip.c:4062
jack_status_t status
Definition: app_jack.c:146

◆ ast_sip_create_dialog_uas_locked()

pjsip_dialog* ast_sip_create_dialog_uas_locked ( const struct ast_sip_endpoint endpoint,
pjsip_rx_data *  rdata,
pj_status_t *  status 
)

General purpose method for creating a UAS dialog with an endpoint.

This function creates and returns a locked, and referenced counted pjsip dialog object. The caller is thus responsible for freeing the allocated memory, decrementing the reference, and releasing the lock when done with the returned object.

Note
The safest way to unlock the object, and decrement its reference is by calling pjsip_dlg_dec_lock. Alternatively, pjsip_dlg_dec_session can be used to decrement the reference only.

The dialog is returned locked and with a reference in order to ensure that the dialog object, and any of its associated objects (e.g. transaction) are not untimely destroyed. For instance, that could happen when a transport error occurs.

As long as the caller maintains a reference to the dialog there should be no worry that it might unknowningly be destroyed. However, once the caller unlocks the dialog there is a danger that some of the dialog's internal objects could be lost and/or compromised. For example, when the aforementioned transport error occurs the dialog's associated transaction gets destroyed (see pjsip_dlg_on_tsx_state in sip_dialog.c, and mod_inv_on_tsx_state in sip_inv.c).

In this case and before using the dialog again the caller should re-lock the dialog, check to make sure the dialog is still established, and the transaction still exists and has not been destroyed.

Parameters
endpointA pointer to the endpoint
rdataThe request that is starting the dialog
[out]statusOn failure, the reason for failure in creating the dialog
Return values
Alocked, and reference counted pjsip_dialog object.
NULLon failure

Definition at line 4134 of file res_pjsip.c.

References create_dialog_uas().

Referenced by create_subscription_tree(), and pre_session_setup().

4136 {
4137 #ifdef HAVE_PJSIP_DLG_CREATE_UAS_AND_INC_LOCK
4138  return create_dialog_uas(endpoint, rdata, status, pjsip_dlg_create_uas_and_inc_lock);
4139 #else
4140  /*
4141  * This is put here in order to be compatible with older versions of pjproject.
4142  * Best we can do in this case is immediately lock after getting the dialog.
4143  * However, that does leave a "gap" between creating and locking.
4144  */
4145  pjsip_dialog *dlg;
4146 
4147  dlg = create_dialog_uas(endpoint, rdata, status, pjsip_dlg_create_uas);
4148  if (dlg) {
4149  pjsip_dlg_inc_lock(dlg);
4150  }
4151 
4152  return dlg;
4153 #endif
4154  }
static pjsip_dialog * create_dialog_uas(const struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, pj_status_t *status, create_dlg_uac create_fun)
Definition: res_pjsip.c:4062
jack_status_t status
Definition: app_jack.c:146

◆ ast_sip_create_rdata()

int ast_sip_create_rdata ( pjsip_rx_data *  rdata,
char *  packet,
const char *  src_name,
int  src_port,
char *  transport_type,
const char *  local_name,
int  local_port 
)

General purpose method for creating an rdata structure using specific information.

Parameters
rdata[out]The rdata structure that will be populated
packetA SIP message
src_nameThe source IP address of the message
src_portThe source port of the message
transport_typeThe type of transport the message was received on
local_nameThe local IP address the message was received on
local_portThe local port the message was received on
Return values
0success
-1failure

Definition at line 4208 of file res_pjsip.c.

References ast_sip_create_rdata_with_contact(), and NULL.

4210 {
4211  return ast_sip_create_rdata_with_contact(rdata, packet, src_name, src_port, transport_type,
4212  local_name, local_port, NULL);
4213 }
#define NULL
Definition: resample.c:96
int ast_sip_create_rdata_with_contact(pjsip_rx_data *rdata, char *packet, const char *src_name, int src_port, char *transport_type, const char *local_name, int local_port, const char *contact)
General purpose method for creating an rdata structure using specific information.
Definition: res_pjsip.c:4156

◆ ast_sip_create_rdata_with_contact()

int ast_sip_create_rdata_with_contact ( pjsip_rx_data *  rdata,
char *  packet,
const char *  src_name,
int  src_port,
char *  transport_type,
const char *  local_name,
int  local_port,
const char *  contact_uri 
)

General purpose method for creating an rdata structure using specific information.

Since
13.15.0
Parameters
rdata[out]The rdata structure that will be populated
packetA SIP message
src_nameThe source IP address of the message
src_portThe source port of the message
transport_typeThe type of transport the message was received on
local_nameThe local IP address the message was received on
local_portThe local port the message was received on
contact_uriThe contact URI of the message
Return values
0success
-1failure

Definition at line 4156 of file res_pjsip.c.

References ast_copy_string(), ast_log, ast_strlen_zero, LOG_WARNING, NULL, and tmp().

Referenced by ast_sip_create_rdata(), and subscription_persistence_recreate().

4158 {
4159  pj_str_t tmp;
4160 
4161  /*
4162  * Initialize the error list in case there is a parse error
4163  * in the given packet.
4164  */
4165  pj_list_init(&rdata->msg_info.parse_err);
4166 
4167  rdata->tp_info.transport = PJ_POOL_ZALLOC_T(rdata->tp_info.pool, pjsip_transport);
4168  if (!rdata->tp_info.transport) {
4169  return -1;
4170  }
4171 
4172  ast_copy_string(rdata->pkt_info.packet, packet, sizeof(rdata->pkt_info.packet));
4173  ast_copy_string(rdata->pkt_info.src_name, src_name, sizeof(rdata->pkt_info.src_name));
4174  rdata->pkt_info.src_port = src_port;
4175  pj_sockaddr_parse(pj_AF_UNSPEC(), 0, pj_cstr(&tmp, src_name), &rdata->pkt_info.src_addr);
4176  pj_sockaddr_set_port(&rdata->pkt_info.src_addr, src_port);
4177 
4178  pjsip_parse_rdata(packet, strlen(packet), rdata);
4179  if (!rdata->msg_info.msg || !pj_list_empty(&rdata->msg_info.parse_err)) {
4180  return -1;
4181  }
4182 
4183  if (!ast_strlen_zero(contact)) {
4184  pjsip_contact_hdr *contact_hdr;
4185 
4186  contact_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, NULL);
4187  if (contact_hdr) {
4188  contact_hdr->uri = pjsip_parse_uri(rdata->tp_info.pool, (char *)contact,
4189  strlen(contact), PJSIP_PARSE_URI_AS_NAMEADDR);
4190  if (!contact_hdr->uri) {
4191  ast_log(LOG_WARNING, "Unable to parse contact URI from '%s'.\n", contact);
4192  return -1;
4193  }
4194  }
4195  }
4196 
4197  pj_strdup2(rdata->tp_info.pool, &rdata->msg_info.via->recvd_param, rdata->pkt_info.src_name);
4198  rdata->msg_info.via->rport_param = -1;
4199 
4200  rdata->tp_info.transport->key.type = pjsip_transport_get_type_from_name(pj_cstr(&tmp, transport_type));
4201  rdata->tp_info.transport->type_name = transport_type;
4202  pj_strdup2(rdata->tp_info.pool, &rdata->tp_info.transport->local_name.host, local_name);
4203  rdata->tp_info.transport->local_name.port = local_port;
4204 
4205  return 0;
4206 }
#define LOG_WARNING
Definition: logger.h:274
static int tmp()
Definition: bt_open.c:389
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
#define ast_strlen_zero(a)
Definition: muted.c:73
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401

◆ ast_sip_create_request()

int ast_sip_create_request ( const char *  method,
struct pjsip_dialog *  dlg,
struct ast_sip_endpoint endpoint,
const char *  uri,
struct ast_sip_contact contact,
pjsip_tx_data **  tdata 
)

General purpose method for creating a SIP request.

Its typical use would be to create one-off requests such as an out of dialog SIP MESSAGE.

The request can either be in- or out-of-dialog. If in-dialog, the dlg parameter MUST be present. If out-of-dialog the endpoint parameter MUST be present. If both are present, then we will assume that the message is to be sent in-dialog.

The uri parameter can be specified if the request should be sent to an explicit URI rather than one configured on the endpoint.

Parameters
methodThe method of the SIP request to send
dlgOptional. If specified, the dialog on which to request the message.
endpointOptional. If specified, the request will be created out-of-dialog to the endpoint.
uriOptional. If specified, the request will be sent to this URI rather than one configured for the endpoint.
contactThe contact with which this request is associated for out-of-dialog requests.
[out]tdataThe newly-created request

The provided contact is attached to tdata with its reference bumped, but will not survive for the entire lifetime of tdata since the contact is cleaned up when all supplements have completed execution.

Return values
0Success
-1Failure

Definition at line 4375 of file res_pjsip.c.

References ast_assert, ast_log, create_in_dialog_request(), create_out_of_dialog_request(), get_pjsip_method(), LOG_WARNING, NULL, and pmethod.

Referenced by msg_send(), notify_channel(), notify_contact(), notify_uri(), send_unsolicited_mwi_notify_to_contact(), sendtext(), sip_options_qualify_contact(), transmit_info_dtmf(), and transmit_info_with_vidupdate().

4378 {
4379  const pjsip_method *pmethod = get_pjsip_method(method);
4380 
4381  if (!pmethod) {
4382  ast_log(LOG_WARNING, "Unknown method '%s'. Cannot send request\n", method);
4383  return -1;
4384  }
4385 
4386  if (dlg) {
4387  return create_in_dialog_request(pmethod, dlg, tdata);
4388  } else {
4389  ast_assert(endpoint != NULL);
4390  return create_out_of_dialog_request(pmethod, endpoint, uri, contact, tdata);
4391  }
4392 }
static const pjsip_method * get_pjsip_method(const char *method)
Definition: res_pjsip.c:4236
static int create_in_dialog_request(const pjsip_method *method, struct pjsip_dialog *dlg, pjsip_tx_data **tdata)
Definition: res_pjsip.c:4247
#define LOG_WARNING
Definition: logger.h:274
const pjsip_method * pmethod
Definition: res_pjsip.c:4221
#define ast_assert(a)
Definition: utils.h:650
#define NULL
Definition: resample.c:96
static int create_out_of_dialog_request(const pjsip_method *method, struct ast_sip_endpoint *endpoint, const char *uri, struct ast_sip_contact *provided_contact, pjsip_tx_data **tdata)
Definition: res_pjsip.c:4265
#define ast_log
Definition: astobj2.c:42
const char * method
Definition: res_pjsip.c:4220

◆ ast_sip_create_request_with_auth()

int ast_sip_create_request_with_auth ( const struct ast_sip_auth_vector auths,
pjsip_rx_data *  challenge,
pjsip_tx_data *  tdata,
pjsip_tx_data **  new_request 
)

Create a response to an authentication challenge.

This will call into an outbound authenticator's create_request_with_auth callback to create a new request with authentication credentials. See the create_request_with_auth callback in the ast_sip_outbound_authenticator structure for details about the parameters and return values.

Definition at line 3308 of file res_pjsip.c.

References ast_log, ast_sip_outbound_authenticator::create_request_with_auth, and LOG_WARNING.

Referenced by check_request_status(), handle_registration_response(), outbound_invite_auth(), session_inv_on_tsx_state_changed(), and sip_outbound_publish_callback().

3310 {
3312  ast_log(LOG_WARNING, "No SIP outbound authenticator registered. Cannot respond to authentication challenge\n");
3313  return -1;
3314  }
3315  return registered_outbound_authenticator->create_request_with_auth(auths, challenge, old_request, new_request);
3316 }
#define LOG_WARNING
Definition: logger.h:274
int(* create_request_with_auth)(const struct ast_sip_auth_vector *auths, struct pjsip_rx_data *challenge, struct pjsip_tx_data *old_request, struct pjsip_tx_data **new_request)
Create a new request with authentication credentials.
Definition: res_pjsip.h:984
static struct ast_sip_outbound_authenticator * registered_outbound_authenticator
Definition: res_pjsip.c:3283
#define ast_log
Definition: astobj2.c:42
static void challenge(const char *realm, pjsip_tx_data *tdata, const pjsip_rx_data *rdata, int is_stale)
astobj2 callback for adding digest challenges to responses

◆ ast_sip_create_response()

int ast_sip_create_response ( const pjsip_rx_data *  rdata,
int  st_code,
struct ast_sip_contact contact,
pjsip_tx_data **  p_tdata 
)

General purpose method for creating a SIP response.

Its typical use would be to create responses for out of dialog requests.

Parameters
rdataThe rdata from the incoming request.
st_codeThe response code to transmit.
contactThe contact with which this request is associated.
[out]tdataThe newly-created response

The provided contact is attached to tdata with its reference bumped, but will not survive for the entire lifetime of tdata since the contact is cleaned up when all supplements have completed execution.

Return values
0Success
-1Failure

Definition at line 5333 of file res_pjsip.c.

References ao2_bump, ast_sip_get_pjsip_endpoint(), ast_sip_mod_data_set, MOD_DATA_CONTACT, NULL, and supplement_module.

Referenced by register_aor_core(), send_options_response(), and send_response().

5335 {
5336  int res = pjsip_endpt_create_response(ast_sip_get_pjsip_endpoint(), rdata, st_code, NULL, tdata);
5337 
5338  if (!res) {
5339  ast_sip_mod_data_set((*tdata)->pool, (*tdata)->mod_data, supplement_module.id, MOD_DATA_CONTACT, ao2_bump(contact));
5340  }
5341 
5342  return res;
5343 }
#define NULL
Definition: resample.c:96
#define ao2_bump(obj)
Definition: astobj2.h:491
static pjsip_module supplement_module
Definition: res_pjsip.c:4258
#define ast_sip_mod_data_set(pool, mod_data, id, key, val)
Utilizing a mod_data array for a given id, set the value associated with the given key...
Definition: res_pjsip.h:2621
#define MOD_DATA_CONTACT
Definition: res_pjsip.c:3178
pjsip_endpoint * ast_sip_get_pjsip_endpoint(void)
Get a pointer to the PJSIP endpoint.
Definition: res_pjsip.c:3614

◆ ast_sip_dict_get()

void* ast_sip_dict_get ( void *  ht,
const char *  key 
)

Retrieves the value associated with the given key.

Parameters
htthe hash table/dictionary to search
keythe key to find
Return values
thevalue associated with the key, NULL otherwise.

Definition at line 5223 of file res_pjsip.c.

References NULL.

5224 {
5225  unsigned int hval = 0;
5226 
5227  if (!ht) {
5228  return NULL;
5229  }
5230 
5231  return pj_hash_get(ht, key, PJ_HASH_KEY_STRING, &hval);
5232 }
#define NULL
Definition: resample.c:96

◆ ast_sip_dict_set()

void* ast_sip_dict_set ( pj_pool_t *  pool,
void *  ht,
const char *  key,
void *  val 
)

Set the value for the given key.

Note - if the hash table does not exist one is created first, the key/value pair is set, and the hash table returned.

Parameters
poolthe pool to allocate memory in
htthe hash table/dictionary in which to store the key/value pair
keythe key to associate a value with
valthe value to associate with a key
Return values
thegiven, or newly created, hash table.

Definition at line 5234 of file res_pjsip.c.

5236 {
5237  if (!ht) {
5238  ht = pj_hash_create(pool, 11);
5239  }
5240 
5241  pj_hash_set(pool, ht, key, PJ_HASH_KEY_STRING, 0, val);
5242 
5243  return ht;
5244 }
Definition: ast_expr2.c:325

◆ ast_sip_dlg_set_transport()

int ast_sip_dlg_set_transport ( const struct ast_sip_endpoint endpoint,
pjsip_dialog *  dlg,
pjsip_tpselector *  selector 
)

Set the transport on a dialog.

Since
13.15.0
Parameters
endpoint
dlg
selector(optional)
Note
This API calls ast_sip_get_transport_name(endpoint, dlg->target) and if the result is non-NULL, calls pjsip_dlg_set_transport. If 'selector' is non-NULL, it is updated with the selector used.
It is the responsibility of the caller to unref the passed in selector if one is provided.

Definition at line 3687 of file res_pjsip.c.

References ast_sip_set_tpselector_from_ep_or_uri(), and ast_sip_tpselector_unref().

Referenced by ast_sip_create_dialog_uac().

3689 {
3690  pjsip_sip_uri *uri;
3691  pjsip_tpselector sel = { .type = PJSIP_TPSELECTOR_NONE, };
3692 
3693  uri = pjsip_uri_get_uri(dlg->target);
3694  if (!selector) {
3695  selector = &sel;
3696  }
3697 
3698  ast_sip_set_tpselector_from_ep_or_uri(endpoint, uri, selector);
3699 
3700  pjsip_dlg_set_transport(dlg, selector);
3701 
3702  if (selector == &sel) {
3704  }
3705 
3706  return 0;
3707 }
int ast_sip_set_tpselector_from_ep_or_uri(const struct ast_sip_endpoint *endpoint, pjsip_sip_uri *sip_uri, pjsip_tpselector *selector)
Sets pjsip_tpselector from an endpoint or uri.
Definition: res_pjsip.c:3860
void ast_sip_tpselector_unref(pjsip_tpselector *selector)
Unreference a pjsip_tpselector.
Definition: res_pjsip.c:3872

◆ ast_sip_dtmf_to_str()

int ast_sip_dtmf_to_str ( const enum ast_sip_dtmf_mode  dtmf,
char *  buf,
size_t  buf_len 
)

Convert the DTMF mode enum value into a string.

Since
13.18.0
Parameters
dtmfthe dtmf mode
bufBuffer to receive dtmf mode string
buf_lenBuffer length
Return values
0Success
-1Failure

Definition at line 5369 of file res_pjsip.c.

References ast_copy_string(), AST_SIP_DTMF_AUTO, AST_SIP_DTMF_AUTO_INFO, AST_SIP_DTMF_INBAND, AST_SIP_DTMF_INFO, AST_SIP_DTMF_NONE, and AST_SIP_DTMF_RFC_4733.

Referenced by dtmf_to_str(), and pjsip_acf_dtmf_mode_read().

5371 {
5372  switch (dtmf) {
5373  case AST_SIP_DTMF_NONE:
5374  ast_copy_string(buf, "none", buf_len);
5375  break;
5376  case AST_SIP_DTMF_RFC_4733:
5377  ast_copy_string(buf, "rfc4733", buf_len);
5378  break;
5379  case AST_SIP_DTMF_INBAND:
5380  ast_copy_string(buf, "inband", buf_len);
5381  break;
5382  case AST_SIP_DTMF_INFO:
5383  ast_copy_string(buf, "info", buf_len);
5384  break;
5385  case AST_SIP_DTMF_AUTO:
5386  ast_copy_string(buf, "auto", buf_len);
5387  break;
5389  ast_copy_string(buf, "auto_info", buf_len);
5390  break;
5391  default:
5392  buf[0] = '\0';
5393  return -1;
5394  }
5395  return 0;
5396 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401

◆ ast_sip_failover_request()

int ast_sip_failover_request ( pjsip_tx_data *  tdata)

Set a request to use the next value in the list of resolved addresses.

Parameters
tdatathe tx data from the original request
Return values
0No more addresses to try
1The request was successfully re-intialized

Definition at line 4756 of file res_pjsip.c.

References NULL, and send_request_cb().

Referenced by check_request_status(), and handle_registration_response().

4757 {
4758  pjsip_via_hdr *via;
4759 
4760  if (!tdata || !tdata->dest_info.addr.count
4761  || (tdata->dest_info.cur_addr == tdata->dest_info.addr.count - 1)) {
4762  /* No more addresses to try */
4763  return 0;
4764  }
4765 
4766  /* Try next address */
4767  ++tdata->dest_info.cur_addr;
4768 
4769  via = (pjsip_via_hdr*)pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL);
4770  via->branch_param.slen = 0;
4771 
4772  pjsip_tx_data_invalidate_msg(tdata);
4773 
4774  return 1;
4775 }
#define NULL
Definition: resample.c:96

◆ ast_sip_format_endpoint_ami()

int ast_sip_format_endpoint_ami ( struct ast_sip_endpoint endpoint,
struct ast_sip_ami ami,
int *  count 
)

Formats the endpoint and sends over AMI.

Parameters
endpointthe endpoint to format and send
endpointami AMI variable container
countthe number of formatters operated on
Return values
0Success, otherwise non-zero on error

Definition at line 3595 of file res_pjsip.c.

References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_sip_endpoint_formatter::format_ami, lock, and SCOPED_LOCK.

Referenced by ami_show_endpoint().

3597 {
3598  int res = 0;
3599  struct ast_sip_endpoint_formatter *i;
3601  *count = 0;
3603  if (i->format_ami && ((res = i->format_ami(endpoint, ami)) < 0)) {
3604  return res;
3605  }
3606 
3607  if (!res) {
3608  (*count)++;
3609  }
3610  }
3611  return 0;
3612 }
An entity responsible formatting endpoint information.
Definition: res_pjsip.h:2714
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
ast_mutex_t lock
Definition: app_meetme.c:1091
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
#define SCOPED_LOCK(varname, lock, lockfunc, unlockfunc)
Scoped Locks.
Definition: lock.h:581
int(* format_ami)(const struct ast_sip_endpoint *endpoint, struct ast_sip_ami *ami)
Callback used to format endpoint information over AMI.
Definition: res_pjsip.h:2718

◆ ast_sip_get_host_ip()

int ast_sip_get_host_ip ( int  af,
pj_sockaddr *  addr 
)

Retrieve the local host address in IP form.

Parameters
afThe address family to retrieve
addrA place to store the local host address
Return values
0success
-1failure
Since
13.6.0

Definition at line 5345 of file res_pjsip.c.

References ast_strlen_zero, host_ip_ipv4, host_ip_ipv4_string, host_ip_ipv6, and host_ip_ipv6_string.

5346 {
5347  if (af == pj_AF_INET() && !ast_strlen_zero(host_ip_ipv4_string)) {
5348  pj_sockaddr_copy_addr(addr, &host_ip_ipv4);
5349  return 0;
5350  } else if (af == pj_AF_INET6() && !ast_strlen_zero(host_ip_ipv6_string)) {
5351  pj_sockaddr_copy_addr(addr, &host_ip_ipv6);
5352  return 0;
5353  }
5354 
5355  return -1;
5356 }
static pj_sockaddr host_ip_ipv6
Definition: res_pjsip.c:3197
static char host_ip_ipv6_string[PJ_INET6_ADDRSTRLEN]
Definition: res_pjsip.c:3200
#define ast_strlen_zero(a)
Definition: muted.c:73
static char host_ip_ipv4_string[PJ_INET6_ADDRSTRLEN]
Definition: res_pjsip.c:3194
static pj_sockaddr host_ip_ipv4
Definition: res_pjsip.c:3191

◆ ast_sip_get_host_ip_string()

const char* ast_sip_get_host_ip_string ( int  af)

Retrieve the local host address in string form.

Parameters
afThe address family to retrieve
Return values
non-NULLsuccess
NULLfailure
Since
13.6.0
Note
An empty string may be returned if the address family is valid but no local address exists

Definition at line 5358 of file res_pjsip.c.

References host_ip_ipv4_string, host_ip_ipv6_string, and NULL.

Referenced by create_local_sdp(), create_outgoing_sdp_stream(), and multihomed_rewrite_sdp().

5359 {
5360  if (af == pj_AF_INET()) {
5361  return host_ip_ipv4_string;
5362  } else if (af == pj_AF_INET6()) {
5363  return host_ip_ipv6_string;
5364  }
5365 
5366  return NULL;
5367 }
static char host_ip_ipv6_string[PJ_INET6_ADDRSTRLEN]
Definition: res_pjsip.c:3200
#define NULL
Definition: resample.c:96
static char host_ip_ipv4_string[PJ_INET6_ADDRSTRLEN]
Definition: res_pjsip.c:3194

◆ ast_sip_get_pjsip_endpoint()

pjsip_endpoint* ast_sip_get_pjsip_endpoint ( void  )

Get a pointer to the PJSIP endpoint.

This is useful when modules have specific information they need to register with the PJSIP core.

Return values
NULLendpoint has not been created yet.
non-NULLPJSIP endpoint.

Definition at line 3614 of file res_pjsip.c.

References ast_pjsip_endpoint.

Referenced by acl_on_rx_msg(), ast_res_pjsip_cleanup_options_handling(), ast_res_pjsip_init_options_handling(), ast_sip_create_response(), ast_sip_destroy_transport_events(), ast_sip_initialize_transport_events(), ast_sip_pubsub_register_body_generator(), ast_sip_send_response(), ast_sip_session_defer_termination(), ast_sip_session_resume_reinvite(), authenticate(), cancel_publish_refresh(), cancel_registration(), channel_read_pjsip(), create_out_of_dialog_request(), digest_create_request_with_auth(), distribute(), distributor(), do_cli_dump_endpt(), endpoint_lookup(), endpt_send_request(), endpt_send_request_cb(), exten_state_data_alloc(), exten_state_data_destructor(), exten_state_publisher_cb(), filter_on_tx_message(), find_registrar_aor(), keepalive_transport_send_keepalive(), load_module(), logging_on_rx_msg(), logging_on_tx_msg(), notify_task(), on_rx_process_uris(), options_incoming_request(), parse_uri_cb(), pre_session_setup(), publish_request_initial(), pubsub_on_rx_mwi_notify_request(), pubsub_on_rx_publish_request(), pubsub_on_rx_subscribe_request(), register_aor(), register_aor_core(), registrar_on_rx_request(), reschedule_reinvite(), schedule_publish_refresh(), schedule_registration(), send_options_response(), session_reinvite_on_rx_request(), sip_dialog_create_contact(), sip_dialog_create_from(), sip_outbound_publisher_init(), sip_outbound_registration_regc_alloc(), sip_publication_respond(), sip_session_defer_termination_stop_timer(), subscription_persistence_load(), system_create_resolver_and_set_nameservers(), t38_change_state(), transport_apply(), and transport_create().

3615 {
3616  return ast_pjsip_endpoint;
3617 }
static pjsip_endpoint * ast_pjsip_endpoint
Definition: res_pjsip.c:3186

◆ ast_sip_get_transport_name()

int ast_sip_get_transport_name ( const struct ast_sip_endpoint endpoint,
pjsip_sip_uri *  sip_uri,
char *  buf,
size_t  buf_len 
)

Get the transport name from an endpoint or request uri.

Since
13.15.0
Parameters
endpoint
sip_uri
bufBuffer to receive transport name
buf_lenBuffer length
Return values
0Success
-1Failure
Note
If endpoint->transport is not NULL, it is returned in buf. Otherwise if sip_uri has an 'x-ast-txp' parameter AND the sip_uri host is an ip4 or ip6 address, its value is returned,

Definition at line 3658 of file res_pjsip.c.

References ast_alloca, ast_copy_pj_str(), ast_copy_string(), AST_SIP_X_AST_TXP, AST_SIP_X_AST_TXP_LEN, ast_sockaddr_parse(), ast_strlen_zero, host, NULL, PARSE_PORT_FORBID, and ast_sip_endpoint::transport.

Referenced by ast_sip_set_tpselector_from_ep_or_uri().

3660 {
3661  char *host = NULL;
3662  static const pj_str_t x_name = { AST_SIP_X_AST_TXP, AST_SIP_X_AST_TXP_LEN };
3663  pjsip_param *x_transport;
3664 
3665  if (!ast_strlen_zero(endpoint->transport)) {
3666  ast_copy_string(buf, endpoint->transport, buf_len);
3667  return 0;
3668  }
3669 
3670  x_transport = pjsip_param_find(&sip_uri->other_param, &x_name);
3671  if (!x_transport) {
3672  return -1;
3673  }
3674 
3675  /* Only use x_transport if the uri host is an ip (4 or 6) address */
3676  host = ast_alloca(sip_uri->host.slen + 1);
3677  ast_copy_pj_str(host, &sip_uri->host, sip_uri->host.slen + 1);
3678  if (!ast_sockaddr_parse(NULL, host, PARSE_PORT_FORBID)) {
3679  return -1;
3680  }
3681 
3682  ast_copy_pj_str(buf, &x_transport->value, buf_len);
3683 
3684  return 0;
3685 }
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:230
const ast_string_field transport
Definition: res_pjsip.h:817
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define NULL
Definition: resample.c:96
void ast_copy_pj_str(char *dest, const pj_str_t *src, size_t size)
Copy a pj_str_t into a standard character buffer.
Definition: res_pjsip.c:5125
static char host[256]
Definition: muted.c:77
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
#define AST_SIP_X_AST_TXP_LEN
Definition: res_pjsip.h:908
#define ast_strlen_zero(a)
Definition: muted.c:73
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define AST_SIP_X_AST_TXP
Definition: res_pjsip.h:907

◆ ast_sip_identify_endpoint()

struct ast_sip_endpoint* ast_sip_identify_endpoint ( pjsip_rx_data *  rdata)

Determine the endpoint that has sent a SIP message.

This will call into each of the registered endpoint identifiers' identify_endpoint() callbacks until one returns a non-NULL endpoint. This will return an ao2 object. Its reference count will need to be decremented when completed using the endpoint.

Parameters
rdataThe inbound SIP message to use when identifying the endpoint.
Return values
NULLNo matching endpoint
non-NULLThe matching endpoint

Definition at line 3424 of file res_pjsip.c.

References ast_assert, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, endpoint_identifier_list::identifier, ast_sip_endpoint_identifier::identify_endpoint, lock, NULL, and SCOPED_LOCK.

Referenced by endpoint_lookup().

3425 {
3426  struct endpoint_identifier_list *iter;
3427  struct ast_sip_endpoint *endpoint = NULL;
3431  endpoint = iter->identifier->identify_endpoint(rdata);
3432  if (endpoint) {
3433  break;
3434  }
3435  }
3436  return endpoint;
3437 }
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define ast_assert(a)
Definition: utils.h:650
struct ast_sip_endpoint *(* identify_endpoint)(pjsip_rx_data *rdata)
Callback used to identify the source of a message. See ast_sip_identify_endpoint for more details...
Definition: res_pjsip.h:996
#define NULL
Definition: resample.c:96
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
ast_mutex_t lock
Definition: app_meetme.c:1091
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
#define SCOPED_LOCK(varname, lock, lockfunc, unlockfunc)
Scoped Locks.
Definition: lock.h:581
An entity with which Asterisk communicates.
Definition: res_pjsip.h:812
struct ast_sip_endpoint_identifier * identifier
Definition: res_pjsip.c:3321

◆ ast_sip_is_content_type()

int ast_sip_is_content_type ( pjsip_media_type *  content_type,
char *  type,
char *  subtype 
)

Checks if the given content type matches type/subtype.

Compares the pjsip_media_type with the passed type and subtype and returns the result of that comparison. The media type parameters are ignored.

Parameters
content_typeThe pjsip_media_type structure to compare
typeThe media type to compare
subtypeThe media subtype to compare
Return values
0No match
-1Match

Definition at line 5144 of file res_pjsip.c.

References compare().

Referenced by asterisk_publication_devicestate_state_change(), asterisk_publication_mwi_state_change(), check_content_type(), filter_on_tx_message(), pubsub_on_rx_notify_request(), session_outgoing_nat_hook(), and video_info_incoming_request().

5145 {
5146  pjsip_media_type compare;
5147 
5148  if (!content_type) {
5149  return 0;
5150  }
5151 
5152  pjsip_media_type_init2(&compare, type, subtype);
5153 
5154  return pjsip_media_type_cmp(content_type, &compare, 0) ? 0 : -1;
5155 }
static const char type[]
Definition: chan_ooh323.c:109
static int compare(const char *text, const char *template)

◆ ast_sip_modify_id_header()

void ast_sip_modify_id_header ( pj_pool_t *  pool,
pjsip_fromto_hdr *  id_hdr,
const struct ast_party_id id 
)

Set name and number information on an identity header.

Parameters
poolMemory pool to use for string duplication
id_hdrA From, P-Asserted-Identity, or Remote-Party-ID header to modify
idThe identity information to apply to the header

Definition at line 5472 of file res_pjsip.c.

References ast_alloca, ast_escape_quoted(), ast_strlen_zero, ast_party_id::name, NULL, ast_party_id::number, ast_party_name::str, ast_party_number::str, ast_party_name::valid, and ast_party_number::valid.

Referenced by add_pai_header(), add_rpid_header(), and set_from_header().

5473 {
5474  pjsip_name_addr *id_name_addr;
5475  pjsip_sip_uri *id_uri;
5476 
5477  id_name_addr = (pjsip_name_addr *) id_hdr->uri;
5478  id_uri = pjsip_uri_get_uri(id_name_addr->uri);
5479 
5480  if (id->name.valid) {
5481  if (!ast_strlen_zero(id->name.str)) {
5482  int name_buf_len = strlen(id->name.str) * 2 + 1;
5483  char *name_buf = ast_alloca(name_buf_len);
5484 
5485  ast_escape_quoted(id->name.str, name_buf, name_buf_len);
5486  pj_strdup2(pool, &id_name_addr->display, name_buf);
5487  } else {
5488  pj_strdup2(pool, &id_name_addr->display, NULL);
5489  }
5490  }
5491 
5492  if (id->number.valid) {
5493  pj_strdup2(pool, &id_uri->user, id->number.str);
5494  }
5495 }
char * str
Subscriber phone number (Malloced)
Definition: channel.h:292
struct ast_party_name name
Subscriber name.
Definition: channel.h:341
char * str
Subscriber name (Malloced)
Definition: channel.h:265
#define NULL
Definition: resample.c:96
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
#define ast_strlen_zero(a)
Definition: muted.c:73
char * ast_escape_quoted(const char *string, char *outbuf, int buflen)
Escape characters found in a quoted string.
Definition: main/utils.c:506
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:280
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:298
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:343

◆ ast_sip_push_task_wait()

static int ast_sip_push_task_wait ( struct ast_taskprocessor serializer,
int(*)(void *)  sip_task,
void *  task_data 
)
static

Definition at line 5061 of file res_pjsip.c.

References ast_cond_destroy, ast_cond_init, ast_cond_wait, ast_mutex_destroy, ast_mutex_init, ast_mutex_lock, ast_mutex_unlock, ast_sip_push_task(), sync_task_data::complete, sync_task_data::cond, sync_task_data::fail, sync_task_data::lock, NULL, sync_task(), sync_task_data::task, and sync_task_data::task_data.

Referenced by ast_sip_push_task_wait_serializer(), and ast_sip_push_task_wait_servant().

5062 {
5063  /* This method is an onion */
5064  struct sync_task_data std;
5065 
5066  memset(&std, 0, sizeof(std));
5067  ast_mutex_init(&std.lock);
5068  ast_cond_init(&std.cond, NULL);
5069  std.task = sip_task;
5070  std.task_data = task_data;
5071 
5072  if (ast_sip_push_task(serializer, sync_task, &std)) {
5073  ast_mutex_destroy(&std.lock);
5074  ast_cond_destroy(&std.cond);
5075  return -1;
5076  }
5077 
5078  ast_mutex_lock(&std.lock);
5079  while (!std.complete) {
5080  ast_cond_wait(&std.cond, &std.lock);
5081  }
5082  ast_mutex_unlock(&std.lock);
5083 
5084  ast_mutex_destroy(&std.lock);
5085  ast_cond_destroy(&std.cond);
5086  return std.fail;
5087 }
#define ast_cond_wait(cond, mutex)
Definition: lock.h:203
#define ast_cond_init(cond, attr)
Definition: lock.h:199
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
int ast_sip_push_task(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Pushes a task to SIP servants.
Definition: res_pjsip.c:5023
#define ast_cond_destroy(cond)
Definition: lock.h:200
static int sync_task(void *data)
Definition: res_pjsip.c:5041
void * task_data
Definition: stasis.c:1279
#define ast_mutex_init(pmutex)
Definition: lock.h:184
#define ast_mutex_destroy(a)
Definition: lock.h:186
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ ast_sip_rdata_get_header_value()

char* ast_sip_rdata_get_header_value ( pjsip_rx_data *  rdata,
const pj_str_t  str 
)

Get a specific header value from rdata.

Note
The returned value does not need to be freed since it's from the rdata pool
Parameters
rdataThe rdata
strThe header to find
Return values
NULLon failure
Theheader value on success

Definition at line 3439 of file res_pjsip.c.

References NULL.

Referenced by stir_shaken_incoming_request().

3440 {
3441  pjsip_generic_string_hdr *hdr;
3442  pj_str_t hdr_val;
3443 
3444  hdr = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str, NULL);
3445  if (!hdr) {
3446  return NULL;
3447  }
3448 
3449  pj_strdup_with_null(rdata->tp_info.pool, &hdr_val, &hdr->hvalue);
3450 
3451  return hdr_val.ptr;
3452 }
const char * str
Definition: app_jack.c:147
#define NULL
Definition: resample.c:96

◆ ast_sip_register_authenticator()

int ast_sip_register_authenticator ( struct ast_sip_authenticator auth)

Register a SIP authenticator.

An authenticator has three main purposes: 1) Determining if authentication should be performed on an incoming request 2) Gathering credentials necessary for issuing an authentication challenge 3) Authenticating a request that has credentials

Asterisk provides a default authenticator, but it may be replaced by a custom one if desired.

Parameters
authThe authenticator to register
Return values
0Success
-1Failure

Definition at line 3240 of file res_pjsip.c.

References ast_debug, ast_log, and LOG_WARNING.

Referenced by load_module().

3241 {
3243  ast_log(LOG_WARNING, "Authenticator %p is already registered. Cannot register a new one\n", registered_authenticator);
3244  return -1;
3245  }
3246  registered_authenticator = auth;
3247  ast_debug(1, "Registered SIP authenticator module %p\n", auth);
3248 
3249  return 0;
3250 }
static struct ast_sip_authenticator * registered_authenticator
Definition: res_pjsip.c:3238
#define LOG_WARNING
Definition: logger.h:274
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#define ast_log
Definition: astobj2.c:42

◆ ast_sip_register_endpoint_formatter()

void ast_sip_register_endpoint_formatter ( struct ast_sip_endpoint_formatter obj)

Register an endpoint formatter.

Parameters
objthe formatter to register

Definition at line 3575 of file res_pjsip.c.

References AST_RWLIST_INSERT_TAIL, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, lock, ast_cli_entry::next, and SCOPED_LOCK.

Referenced by ast_res_pjsip_init_options_handling(), ast_sip_initialize_sorcery_auth(), ast_sip_initialize_sorcery_location(), ast_sip_initialize_sorcery_transport(), and load_module().

3576 {
3579 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
ast_mutex_t lock
Definition: app_meetme.c:1091
#define SCOPED_LOCK(varname, lock, lockfunc, unlockfunc)
Scoped Locks.
Definition: lock.h:581
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:740

◆ ast_sip_register_endpoint_identifier()

int ast_sip_register_endpoint_identifier ( struct ast_sip_endpoint_identifier identifier)

Register a SIP endpoint identifier.

An endpoint identifier's purpose is to determine which endpoint a given SIP message has come from.

Multiple endpoint identifiers may be registered so that if an endpoint cannot be identified by one identifier, it may be identified by another.

Asterisk provides two endpoint identifiers. One identifies endpoints based on the user part of the From header URI. The other identifies endpoints based on the source IP address.

If the order in which endpoint identifiers is run is important to you, then be sure to load individual endpoint identifier modules in the order you wish for them to be run in modules.conf

Note
endpoint identifiers registered using this method (no name specified) are placed at the front of the endpoint identifiers list ahead of any named identifiers.
Parameters
identifierThe SIP endpoint identifier to register
Return values
0Success
-1Failure

Definition at line 3404 of file res_pjsip.c.

References ast_sip_register_endpoint_identifier_with_name(), and NULL.

Referenced by load_module().

3405 {
3407 }
#define NULL
Definition: resample.c:96
int ast_sip_register_endpoint_identifier_with_name(struct ast_sip_endpoint_identifier *identifier, const char *name)
Register a SIP endpoint identifier with a name.
Definition: res_pjsip.c:3327

◆ ast_sip_register_endpoint_identifier_with_name()

int ast_sip_register_endpoint_identifier_with_name ( struct ast_sip_endpoint_identifier identifier,
const char *  name 
)

Register a SIP endpoint identifier with a name.

An endpoint identifier's purpose is to determine which endpoint a given SIP message has come from.

Multiple endpoint identifiers may be registered so that if an endpoint cannot be identified by one identifier, it may be identified by another.

Parameters
identifierThe SIP endpoint identifier to register
nameThe name of the endpoint identifier
Return values
0Success
-1Failure

Definition at line 3327 of file res_pjsip.c.

References ast_calloc, ast_debug, ast_free, ast_log, AST_RWLIST_EMPTY, AST_RWLIST_INSERT_AFTER, AST_RWLIST_INSERT_BEFORE_CURRENT, AST_RWLIST_INSERT_HEAD, AST_RWLIST_INSERT_TAIL, AST_RWLIST_NEXT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_sip_get_endpoint_identifier_order(), ast_strlen_zero, endpoint_identifier_list::identifier, lock, LOG_ERROR, endpoint_identifier_list::name, endpoint_identifier_list::priority, and SCOPED_LOCK.

Referenced by ast_sip_register_endpoint_identifier(), and load_module().

3329 {
3330  char *prev, *current, *identifier_order;
3331  struct endpoint_identifier_list *iter, *id_list_item;
3333 
3334  id_list_item = ast_calloc(1, sizeof(*id_list_item));
3335  if (!id_list_item) {
3336  ast_log(LOG_ERROR, "Unable to add endpoint identifier. Out of memory.\n");
3337  return -1;
3338  }
3339  id_list_item->identifier = identifier;
3340  id_list_item->name = name;
3341 
3342  ast_debug(1, "Register endpoint identifier %s(%p)\n", name ?: "", identifier);
3343 
3344  if (ast_strlen_zero(name)) {
3345  /* if an identifier has no name then place in front */
3346  AST_RWLIST_INSERT_HEAD(&endpoint_identifiers, id_list_item, list);
3347  return 0;
3348  }
3349 
3350  /* see if the name of the identifier is in the global endpoint_identifier_order list */
3351  identifier_order = prev = current = ast_sip_get_endpoint_identifier_order();
3352 
3353  if (ast_strlen_zero(identifier_order)) {
3354  id_list_item->priority = UINT_MAX;
3355  AST_RWLIST_INSERT_TAIL(&endpoint_identifiers, id_list_item, list);
3356  ast_free(identifier_order);
3357  return 0;
3358  }
3359 
3360  id_list_item->priority = 0;
3361  while ((current = strchr(current, ','))) {
3362  ++id_list_item->priority;
3363  if (!strncmp(prev, name, current - prev)
3364  && strlen(name) == current - prev) {
3365  break;
3366  }
3367  prev = ++current;
3368  }
3369 
3370  if (!current) {
3371  /* check to see if it is the only or last item */
3372  if (!strcmp(prev, name)) {
3373  ++id_list_item->priority;
3374  } else {
3375  id_list_item->priority = UINT_MAX;
3376  }
3377  }
3378 
3379  if (id_list_item->priority == UINT_MAX || AST_RWLIST_EMPTY(&endpoint_identifiers)) {
3380  /* if not in the endpoint_identifier_order list then consider it less in
3381  priority and add it to the end */
3382  AST_RWLIST_INSERT_TAIL(&endpoint_identifiers, id_list_item, list);
3383  ast_free(identifier_order);
3384  return 0;
3385  }
3386 
3388  if (id_list_item->priority < iter->priority) {
3389  AST_RWLIST_INSERT_BEFORE_CURRENT(id_list_item, list);
3390  break;
3391  }
3392 
3393  if (!AST_RWLIST_NEXT(iter, list)) {
3394  AST_RWLIST_INSERT_AFTER(&endpoint_identifiers, iter, id_list_item, list);
3395  break;
3396  }
3397  }
3399 
3400  ast_free(identifier_order);
3401  return 0;
3402 }
#define AST_RWLIST_NEXT
Definition: linkedlists.h:440
#define AST_RWLIST_INSERT_AFTER
Definition: linkedlists.h:701
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define AST_RWLIST_INSERT_HEAD
Definition: linkedlists.h:717
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#define ast_log
Definition: astobj2.c:42
ast_mutex_t lock
Definition: app_meetme.c:1091
#define SCOPED_LOCK(varname, lock, lockfunc, unlockfunc)
Scoped Locks.
Definition: lock.h:581
#define AST_RWLIST_INSERT_BEFORE_CURRENT
Definition: linkedlists.h:609
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:544
#define AST_RWLIST_EMPTY
Definition: linkedlists.h:451
#define LOG_ERROR
Definition: logger.h:285
char * ast_sip_get_endpoint_identifier_order(void)
Retrieve the global endpoint_identifier_order setting.
#define ast_strlen_zero(a)
Definition: muted.c:73
static const char name[]
Definition: cdr_mysql.c:74
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
struct ast_sip_endpoint_identifier * identifier
Definition: res_pjsip.c:3321
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:740
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:616

◆ ast_sip_register_outbound_authenticator()

int ast_sip_register_outbound_authenticator ( struct ast_sip_outbound_authenticator outbound_auth)

Register an outbound SIP authenticator.

An outbound authenticator is responsible for creating responses to authentication challenges by remote endpoints.

Parameters
authThe authenticator to register
Return values
0Success
-1Failure

Definition at line 3285 of file res_pjsip.c.

References ast_debug, ast_log, and LOG_WARNING.

Referenced by load_module().

3286 {
3288  ast_log(LOG_WARNING, "Outbound authenticator %p is already registered. Cannot register a new one\n", registered_outbound_authenticator);
3289  return -1;
3290  }
3292  ast_debug(1, "Registered SIP outbound authenticator module %p\n", auth);
3293 
3294  return 0;
3295 }
#define LOG_WARNING
Definition: logger.h:274
static struct ast_sip_outbound_authenticator * registered_outbound_authenticator
Definition: res_pjsip.c:3283
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#define ast_log
Definition: astobj2.c:42

◆ ast_sip_register_service()

int ast_sip_register_service ( pjsip_module *  module)

Register a SIP service in Asterisk.

This is more-or-less a wrapper around pjsip_endpt_register_module(). Registering a service makes it so that PJSIP will call into the service at appropriate times. For more information about PJSIP module callbacks, see the PJSIP documentation. Asterisk modules that call this function will likely do so at module load time.

Parameters
moduleThe module that is to be registered with PJSIP
Return values
0Success
-1Failure

Definition at line 3217 of file res_pjsip.c.

References ast_sip_push_task_wait_servant(), NULL, and register_service().

Referenced by ast_res_pjsip_init_message_filter(), ast_sip_initialize_distributor(), ast_sip_initialize_global_headers(), ast_sip_initialize_transport_management(), and load_module().

3218 {
3220 }
#define NULL
Definition: resample.c:96
static int register_service(void *data)
Definition: res_pjsip.c:3202
int ast_sip_push_task_wait_servant(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Push a task to SIP servants and wait for it to complete.
Definition: res_pjsip.c:5089

◆ ast_sip_register_supplement()

void ast_sip_register_supplement ( struct ast_sip_supplement supplement)

Register a supplement to SIP out of dialog processing.

This allows for someone to insert themselves in the processing of out of dialog SIP requests and responses. This, for example could allow for a module to set channel data based on headers in an incoming message. Similarly, a module could reject an incoming request if desired.

Parameters
supplementThe supplement to register
Return values
0Success
-1Failure

Definition at line 4396 of file res_pjsip.c.

References AST_RWLIST_INSERT_BEFORE_CURRENT, AST_RWLIST_INSERT_TAIL, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, lock, ast_sip_supplement::next, ast_sip_supplement::priority, and SCOPED_LOCK.

Referenced by ast_res_pjsip_init_message_filter(), and load_module().

4397 {
4398  struct ast_sip_supplement *iter;
4399  int inserted = 0;
4401 
4403  if (iter->priority > supplement->priority) {
4405  inserted = 1;
4406  break;
4407  }
4408  }
4410 
4411  if (!inserted) {
4412  AST_RWLIST_INSERT_TAIL(&supplements, supplement, next);
4413  }
4414 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
ast_mutex_t lock
Definition: app_meetme.c:1091
struct ast_sip_supplement * next
Definition: res_pjsip.h:2889
#define SCOPED_LOCK(varname, lock, lockfunc, unlockfunc)
Scoped Locks.
Definition: lock.h:581
#define AST_RWLIST_INSERT_BEFORE_CURRENT
Definition: linkedlists.h:609
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:544
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:740
A supplement to SIP message processing.
Definition: res_pjsip.h:2839
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:616
enum ast_sip_supplement_priority priority
Definition: res_pjsip.h:2843

◆ ast_sip_requires_authentication()

int ast_sip_requires_authentication ( struct ast_sip_endpoint endpoint,
pjsip_rx_data *  rdata 
)

Determine if an incoming request requires authentication.

This calls into the registered authenticator's requires_authentication callback in order to determine if the request requires authentication.

If there is no registered authenticator, then authentication will be assumed not to be required.

Parameters
endpointThe endpoint from which the request originates
rdataThe incoming SIP request
Return values
non-zeroThe request requires authentication
0The request does not require authentication

Definition at line 3263 of file res_pjsip.c.

References ast_log, LOG_WARNING, and ast_sip_authenticator::requires_authentication.

Referenced by authenticate().

3264 {
3265  if (!registered_authenticator) {
3266  ast_log(LOG_WARNING, "No SIP authenticator registered. Assuming authentication is not required\n");
3267  return 0;
3268  }
3269 
3270  return registered_authenticator->requires_authentication(endpoint, rdata);
3271 }
static struct ast_sip_authenticator * registered_authenticator
Definition: res_pjsip.c:3238
#define LOG_WARNING
Definition: logger.h:274
#define ast_log
Definition: astobj2.c:42
int(* requires_authentication)(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata)
Check if a request requires authentication See ast_sip_requires_authentication for more details...
Definition: res_pjsip.h:953

◆ ast_sip_send_out_of_dialog_request()

int ast_sip_send_out_of_dialog_request ( pjsip_tx_data *  tdata,
struct ast_sip_endpoint endpoint,
int  timeout,
void *  token,
void(*)(void *token, pjsip_event *e)  callback 
)

General purpose method for sending an Out-Of-Dialog SIP request.

This is a companion function for ast_sip_create_request. The request created there can be passed to this function, though any request may be passed in.

This will automatically set up handling outbound authentication challenges if they arrive.

Parameters
tdataThe request to send
endpointOptional. If specified, the out-of-dialog request is sent to the endpoint.
timeout.If non-zero, after the timeout the transaction will be terminated and the callback will be called with the PJSIP_EVENT_TIMER type.
tokenData to be passed to the callback upon receipt of out-of-dialog response.
callbackCallback to be called upon receipt of out-of-dialog response.
Return values
0Success
-1Failure (out-of-dialog callback will not be called.)
Note
Timeout processing: There are 2 timers associated with this request, PJSIP timer_b which is set globally in the "system" section of pjsip.conf, and the timeout specified on this call. The timer that expires first (before normal completion) will cause the callback to be run with e->body.tsx_state.type = PJSIP_EVENT_TIMER. The timer that expires second is simply ignored and the callback is not run again.

Definition at line 4878 of file res_pjsip.c.

References ao2_cleanup, AST_LIST_TRAVERSE, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, ast_sip_message_apply_transport(), ast_sip_mod_data_get, ast_sip_mod_data_set, does_method_match(), endpt_send_request(), ast_sip_supplement::method, MOD_DATA_CONTACT, NULL, ast_sip_supplement::outgoing_request, send_request_data_alloc(), supplement_module, and ast_sip_endpoint::transport.

Referenced by ast_sip_send_request(), and sip_options_qualify_contact().

4881 {
4882  struct ast_sip_supplement *supplement;
4883  struct send_request_data *req_data;
4884  struct ast_sip_contact *contact;
4885 
4886  req_data = send_request_data_alloc(endpoint, token, callback);
4887  if (!req_data) {
4888  pjsip_tx_data_dec_ref(tdata);
4889  return -1;
4890  }
4891 
4892  if (endpoint) {
4893  ast_sip_message_apply_transport(endpoint->transport, tdata);
4894  }
4895 
4896  contact = ast_sip_mod_data_get(tdata->mod_data, supplement_module.id, MOD_DATA_CONTACT);
4897 
4899  AST_LIST_TRAVERSE(&supplements, supplement, next) {
4900  if (supplement->outgoing_request
4901  && does_method_match(&tdata->msg->line.req.method.name, supplement->method)) {
4902  supplement->outgoing_request(endpoint, contact, tdata);
4903  }
4904  }
4906 
4907  ast_sip_mod_data_set(tdata->pool, tdata->mod_data, supplement_module.id, MOD_DATA_CONTACT, NULL);
4908  ao2_cleanup(contact);
4909 
4910  if (endpt_send_request(endpoint, tdata, timeout, req_data, send_request_cb)
4911  != PJ_SUCCESS) {
4912  ao2_cleanup(req_data);
4913  return -1;
4914  }
4915 
4916  return 0;
4917 }
const ast_string_field transport
Definition: res_pjsip.h:817
static struct send_request_data * send_request_data_alloc(struct ast_sip_endpoint *endpoint, void *token, void(*callback)(void *token, pjsip_event *e))
Definition: res_pjsip.c:4474
static int timeout
Definition: cdr_mysql.c:86
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
const char * method
Definition: res_pjsip.h:2841
#define NULL
Definition: resample.c:96
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
static pjsip_module supplement_module
Definition: res_pjsip.c:4258
#define ast_sip_mod_data_set(pool, mod_data, id, key, val)
Utilizing a mod_data array for a given id, set the value associated with the given key...
Definition: res_pjsip.h:2621
#define ast_sip_mod_data_get(mod_data, id, key)
Using the dictionary stored in mod_data array at a given id, retrieve the value associated with the g...
Definition: res_pjsip.h:2589
static pj_status_t endpt_send_request(struct ast_sip_endpoint *endpoint, pjsip_tx_data *tdata, pj_int32_t timeout, void *token, pjsip_endpt_send_callback cb)
Definition: res_pjsip.c:4636
static pj_bool_t does_method_match(const pj_str_t *message_method, const char *supplement_method)
Definition: res_pjsip.c:4439
Contact associated with an address of record.
Definition: res_pjsip.h:281
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
void ast_sip_message_apply_transport(const char *transport_name, pjsip_tx_data *tdata)
Apply the configuration for a transport to an outgoing message.
#define MOD_DATA_CONTACT
Definition: res_pjsip.c:3178
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
A supplement to SIP message processing.
Definition: res_pjsip.h:2839
Structure to hold information about an outbound request.
Definition: res_pjsip.c:4456
void(* outgoing_request)(struct ast_sip_endpoint *endpoint, struct ast_sip_contact *contact, struct pjsip_tx_data *tdata)
Called on an outgoing SIP request This method is always called from a SIP servant thread...
Definition: res_pjsip.h:2882
static void send_request_cb(void *token, pjsip_event *e)
Definition: res_pjsip.c:4822

◆ ast_sip_send_request()

int ast_sip_send_request ( pjsip_tx_data *  tdata,
struct pjsip_dialog *  dlg,
struct ast_sip_endpoint endpoint,
void *  token,
void(*)(void *token, pjsip_event *e)  callback 
)

General purpose method for sending a SIP request.

This is a companion function for ast_sip_create_request. The request created there can be passed to this function, though any request may be passed in.

This will automatically set up handling outbound authentication challenges if they arrive.

Parameters
tdataThe request to send
dlgOptional. The dialog in which the request is sent. Otherwise it is out-of-dialog.
endpointOptional. If specified, the out-of-dialog request is sent to the endpoint.
tokenData to be passed to the callback upon receipt of out-of-dialog response.
callbackCallback to be called upon receipt of out-of-dialog response.
Return values
0Success
-1Failure (out-of-dialog callback will not be called.)

Definition at line 4919 of file res_pjsip.c.

References ast_assert, ast_sip_send_out_of_dialog_request(), and send_in_dialog_request().

Referenced by msg_send(), notify_channel(), notify_contact(), notify_uri(), send_unsolicited_mwi_notify_to_contact(), and sendtext().

4922 {
4923  ast_assert(tdata->msg->type == PJSIP_REQUEST_MSG);
4924 
4925  if (dlg) {
4926  return send_in_dialog_request(tdata, dlg);
4927  } else {
4928  return ast_sip_send_out_of_dialog_request(tdata, endpoint, -1, token, callback);
4929  }
4930 }
#define ast_assert(a)
Definition: utils.h:650
int ast_sip_send_out_of_dialog_request(pjsip_tx_data *tdata, struct ast_sip_endpoint *endpoint, int timeout, void *token, void(*callback)(void *token, pjsip_event *e))
General purpose method for sending an Out-Of-Dialog SIP request.
Definition: res_pjsip.c:4878
static int send_in_dialog_request(pjsip_tx_data *tdata, struct pjsip_dialog *dlg)
Definition: res_pjsip.c:4430

◆ ast_sip_send_response()

int ast_sip_send_response ( pjsip_response_addr *  res_addr,
pjsip_tx_data *  tdata,
struct ast_sip_endpoint sip_endpoint 
)

Send a response to an out of dialog request.

Use this function sparingly, since this does not create a transaction within PJSIP. This means that if the request is retransmitted, it is your responsibility to detect this and not process the same request twice, and to send the same response for each retransmission.

Parameters
res_addrThe response address for this response
tdataThe response to send
endpointThe ast_sip_endpoint associated with this response
Return values
0Success
-1Failure

Definition at line 5292 of file res_pjsip.c.

References ast_sip_get_pjsip_endpoint(), NULL, status, and supplement_outgoing_response().

5293 {
5294  pj_status_t status;
5295 
5296  supplement_outgoing_response(tdata, sip_endpoint);
5297  status = pjsip_endpt_send_response(ast_sip_get_pjsip_endpoint(), res_addr, tdata, NULL, NULL);
5298  if (status != PJ_SUCCESS) {
5299  pjsip_tx_data_dec_ref(tdata);
5300  }
5301 
5302  return status == PJ_SUCCESS ? 0 : -1;
5303 }
#define NULL
Definition: resample.c:96
static void supplement_outgoing_response(pjsip_tx_data *tdata, struct ast_sip_endpoint *sip_endpoint)
Definition: res_pjsip.c:5270
jack_status_t status
Definition: app_jack.c:146
pjsip_endpoint * ast_sip_get_pjsip_endpoint(void)
Get a pointer to the PJSIP endpoint.
Definition: res_pjsip.c:3614

◆ ast_sip_send_stateful_response()

int ast_sip_send_stateful_response ( pjsip_rx_data *  rdata,
pjsip_tx_data *  tdata,
struct ast_sip_endpoint sip_endpoint 
)

Send a stateful response to an out of dialog request.

This creates a transaction within PJSIP, meaning that if the request that we are responding to is retransmitted, we will not attempt to re-handle the request.

Parameters
rdataThe request that is being responded to
tdataThe response to send
endpointThe ast_sip_endpoint associated with this response
Since
13.4.0
Return values
0Success
-1Failure

Definition at line 5305 of file res_pjsip.c.

References ao2_cleanup, ast_sip_mod_data_get, ast_sip_mod_data_set, MOD_DATA_CONTACT, NULL, supplement_module, and supplement_outgoing_response().

Referenced by register_aor(), send_options_response(), and send_response().

5306 {
5307  pjsip_transaction *tsx;
5308 
5309  if (pjsip_tsx_create_uas(NULL, rdata, &tsx) != PJ_SUCCESS) {
5310  struct ast_sip_contact *contact;
5311 
5312  /* ast_sip_create_response bumps the refcount of the contact and adds it to the tdata.
5313  * We'll leak that reference if we don't get rid of it here.
5314  */
5315  contact = ast_sip_mod_data_get(tdata->mod_data, supplement_module.id, MOD_DATA_CONTACT);
5316  ao2_cleanup(contact);
5317  ast_sip_mod_data_set(tdata->pool, tdata->mod_data, supplement_module.id, MOD_DATA_CONTACT, NULL);
5318  pjsip_tx_data_dec_ref(tdata);
5319  return -1;
5320  }
5321  pjsip_tsx_recv_msg(tsx, rdata);
5322 
5323  supplement_outgoing_response(tdata, sip_endpoint);
5324 
5325  if (pjsip_tsx_send_msg(tsx, tdata) != PJ_SUCCESS) {
5326  pjsip_tx_data_dec_ref(tdata);
5327  return -1;
5328  }
5329 
5330  return 0;
5331 }
#define NULL
Definition: resample.c:96
static pjsip_module supplement_module
Definition: res_pjsip.c:4258
#define ast_sip_mod_data_set(pool, mod_data, id, key, val)
Utilizing a mod_data array for a given id, set the value associated with the given key...
Definition: res_pjsip.h:2621
#define ast_sip_mod_data_get(mod_data, id, key)
Using the dictionary stored in mod_data array at a given id, retrieve the value associated with the g...
Definition: res_pjsip.h:2589
static void supplement_outgoing_response(pjsip_tx_data *tdata, struct ast_sip_endpoint *sip_endpoint)
Definition: res_pjsip.c:5270
Contact associated with an address of record.
Definition: res_pjsip.h:281
#define MOD_DATA_CONTACT
Definition: res_pjsip.c:3178
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ ast_sip_set_outbound_proxy()

int ast_sip_set_outbound_proxy ( pjsip_tx_data *  tdata,
const char *  proxy 
)

Set the outbound proxy for an outbound SIP message.

Parameters
tdataThe message to set the outbound proxy on
proxySIP uri of the proxy
Return values
0Success
-1Failure

Definition at line 4932 of file res_pjsip.c.

References NULL, and tmp().

Referenced by create_out_of_dialog_request(), path_outgoing_request(), and sip_options_qualify_contact().

4933 {
4934  pjsip_route_hdr *route;
4935  static const pj_str_t ROUTE_HNAME = { "Route", 5 };
4936  pj_str_t tmp;
4937 
4938  pj_strdup2_with_null(tdata->pool, &tmp, proxy);
4939  if (!(route = pjsip_parse_hdr(tdata->pool, &ROUTE_HNAME, tmp.ptr, tmp.slen, NULL))) {
4940  return -1;
4941  }
4942 
4943  pj_list_insert_nodes_before(&tdata->msg->hdr, (pjsip_hdr*)route);
4944 
4945  return 0;
4946 }
static int tmp()
Definition: bt_open.c:389
#define NULL
Definition: resample.c:96

◆ ast_sip_set_tpselector_from_ep_or_uri()

int ast_sip_set_tpselector_from_ep_or_uri ( const struct ast_sip_endpoint endpoint,
pjsip_sip_uri *  sip_uri,
pjsip_tpselector *  selector 
)

Sets pjsip_tpselector from an endpoint or uri.

Since
13.15.0
Parameters
endpointIf endpoint->transport is set, it's used
sip_uriIf sip_uri contains a x-ast-txp parameter, it's used
selectorThe selector to be populated
Return values
0success
-1failure

Definition at line 3860 of file res_pjsip.c.

References ast_sip_get_transport_name(), and ast_sip_set_tpselector_from_transport_name().

Referenced by ast_sip_dlg_set_transport(), create_dialog_uas(), and create_out_of_dialog_request().

3862 {
3863  char transport_name[128];
3864 
3865  if (ast_sip_get_transport_name(endpoint, sip_uri, transport_name, sizeof(transport_name))) {
3866  return 0;
3867  }
3868 
3869  return ast_sip_set_tpselector_from_transport_name(transport_name, selector);
3870 }
int ast_sip_set_tpselector_from_transport_name(const char *transport_name, pjsip_tpselector *selector)
Sets pjsip_tpselector from ast_sip_transport.
Definition: res_pjsip.c:3842
int ast_sip_get_transport_name(const struct ast_sip_endpoint *endpoint, pjsip_sip_uri *sip_uri, char *buf, size_t buf_len)
Get the transport name from an endpoint or request uri.
Definition: res_pjsip.c:3658

◆ ast_sip_set_tpselector_from_transport()

int ast_sip_set_tpselector_from_transport ( const struct ast_sip_transport transport,
pjsip_tpselector *  selector 
)

Sets pjsip_tpselector from ast_sip_transport.

Since
13.8.0
Parameters
transportThe transport to be used
selectorThe selector to be populated
Return values
0success
-1failure
Note
The transport selector must be unreffed using ast_sip_tpselector_unref

Definition at line 3792 of file res_pjsip.c.

References ao2_lock, ao2_ref, ao2_unlock, ast_log, ast_sip_get_transport_state(), ast_sorcery_object_get_id(), AST_TRANSPORT_WS, AST_TRANSPORT_WSS, ast_sip_transport_state::factory, ast_sip_transport_state::flow, ast_sip_transport::flow, LOG_ERROR, LOG_WARNING, ast_sip_transport_state::transport, and ast_sip_transport::type.

Referenced by ast_sip_set_tpselector_from_transport_name().

3793 {
3794  int res = 0;
3795  struct ast_sip_transport_state *transport_state;
3796 
3797  transport_state = ast_sip_get_transport_state(ast_sorcery_object_get_id(transport));
3798  if (!transport_state) {
3799  ast_log(LOG_ERROR, "Unable to retrieve PJSIP transport state for '%s'\n",
3800  ast_sorcery_object_get_id(transport));
3801  return -1;
3802  }
3803 
3804  /* Only flows maintain dynamic state which needs protection */
3805  if (transport_state->flow) {
3806  ao2_lock(transport_state);
3807  }
3808 
3809  if (transport_state->transport) {
3810  selector->type = PJSIP_TPSELECTOR_TRANSPORT;
3811  selector->u.transport = transport_state->transport;
3812  pjsip_transport_add_ref(selector->u.transport);
3813  } else if (transport_state->factory) {
3814  selector->type = PJSIP_TPSELECTOR_LISTENER;
3815  selector->u.listener = transport_state->factory;
3816  } else if (transport->type == AST_TRANSPORT_WS || transport->type == AST_TRANSPORT_WSS) {
3817  /* The WebSocket transport has no factory as it can not create outgoing connections, so
3818  * even if an endpoint is locked to a WebSocket transport we let the PJSIP logic
3819  * find the existing connection if available and use it.
3820  */
3821  } else if (transport->flow) {
3822  /* This is a child of another transport, so we need to establish a new connection */
3823 #ifdef HAVE_PJSIP_TRANSPORT_DISABLE_CONNECTION_REUSE
3824  selector->disable_connection_reuse = PJ_TRUE;
3825 #else
3826  ast_log(LOG_WARNING, "Connection reuse could not be disabled on transport '%s' as support is not available\n",
3827  ast_sorcery_object_get_id(transport));
3828 #endif
3829  } else {
3830  res = -1;
3831  }
3832 
3833  if (transport_state->flow) {
3834  ao2_unlock(transport_state);
3835  }
3836 
3837  ao2_ref(transport_state, -1);
3838 
3839  return res;
3840 }
#define LOG_WARNING
Definition: logger.h:274
#define ao2_unlock(a)
Definition: astobj2.h:730
enum ast_transport type
Definition: res_pjsip.h:193
#define ast_log
Definition: astobj2.c:42
Structure for SIP transport information.
Definition: res_pjsip.h:87
struct pjsip_transport * transport
Transport itself.
Definition: res_pjsip.h:89
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2309
#define LOG_ERROR
Definition: logger.h:285
struct ast_sip_transport_state * ast_sip_get_transport_state(const char *transport_id)
Retrieve transport state.
struct pjsip_tpfactory * factory
Transport factory.
Definition: res_pjsip.h:91

◆ ast_sip_set_tpselector_from_transport_name()

int ast_sip_set_tpselector_from_transport_name ( const char *  transport_name,
pjsip_tpselector *  selector 
)

Sets pjsip_tpselector from ast_sip_transport.

Since
13.8.0
Parameters
transport_nameThe name of the transport to be used
selectorThe selector to be populated
Return values
0success
-1failure
Note
The transport selector must be unreffed using ast_sip_tpselector_unref

Definition at line 3842 of file res_pjsip.c.

References ao2_cleanup, ast_log, ast_sip_get_sorcery(), ast_sip_set_tpselector_from_transport(), ast_sorcery_retrieve_by_id(), ast_strlen_zero, LOG_ERROR, NULL, RAII_VAR, and ast_sip_transport_state::transport.

Referenced by ast_sip_set_tpselector_from_ep_or_uri(), registration_client_send(), set_transport(), and sip_outbound_registration_regc_alloc().

3843 {
3845 
3846  if (ast_strlen_zero(transport_name)) {
3847  return 0;
3848  }
3849 
3850  transport = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "transport", transport_name);
3851  if (!transport) {
3852  ast_log(LOG_ERROR, "Unable to retrieve PJSIP transport '%s'\n",
3853  transport_name);
3854  return -1;
3855  }
3856 
3858 }
#define NULL
Definition: resample.c:96
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
Definition: sorcery.c:1850
#define ast_log
Definition: astobj2.c:42
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:851
struct pjsip_transport * transport
Transport itself.
Definition: res_pjsip.h:89
#define LOG_ERROR
Definition: logger.h:285
Transport to bind to.
Definition: res_pjsip.h:171
#define ast_strlen_zero(a)
Definition: muted.c:73
int ast_sip_set_tpselector_from_transport(const struct ast_sip_transport *transport, pjsip_tpselector *selector)
Sets pjsip_tpselector from ast_sip_transport.
Definition: res_pjsip.c:3792
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ ast_sip_str_to_dtmf()

int ast_sip_str_to_dtmf ( const char *  dtmf_mode)

Convert the DTMF mode name into an enum.

Since
13.18.0
Parameters
dtmf_modedtmf mode as a string
Return values
>=0 The enum value
-1Failure

Definition at line 5398 of file res_pjsip.c.

References AST_SIP_DTMF_AUTO, AST_SIP_DTMF_AUTO_INFO, AST_SIP_DTMF_INBAND, AST_SIP_DTMF_INFO, AST_SIP_DTMF_NONE, AST_SIP_DTMF_RFC_4733, and result.

Referenced by dtmf_handler(), and pjsip_acf_dtmf_mode_write().

5399 {
5400  int result = -1;
5401 
5402  if (!strcasecmp(dtmf_mode, "info")) {
5403  result = AST_SIP_DTMF_INFO;
5404  } else if (!strcasecmp(dtmf_mode, "rfc4733")) {
5405  result = AST_SIP_DTMF_RFC_4733;
5406  } else if (!strcasecmp(dtmf_mode, "inband")) {
5407  result = AST_SIP_DTMF_INBAND;
5408  } else if (!strcasecmp(dtmf_mode, "none")) {
5409  result = AST_SIP_DTMF_NONE;
5410  } else if (!strcasecmp(dtmf_mode, "auto")) {
5411  result = AST_SIP_DTMF_AUTO;
5412  } else if (!strcasecmp(dtmf_mode, "auto_info")) {
5413  result = AST_SIP_DTMF_AUTO_INFO;
5414  }
5415 
5416  return result;
5417 }
static PGresult * result
Definition: cel_pgsql.c:88

◆ ast_sip_threadpool()

struct ast_threadpool* ast_sip_threadpool ( void  )

Retrieve the SIP threadpool object.

Definition at line 5515 of file res_pjsip.c.

References ast_sip_sanitize_xml(), AST_TEST_DEFINE, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, sip_to_pjsip::info(), sip_threadpool, TEST_EXECUTE, and TEST_INIT.

Referenced by load_module().

5516 {
5517  return sip_threadpool;
5518 }
static struct ast_threadpool * sip_threadpool
Definition: res_pjsip.c:3188

◆ ast_sip_threadpool_queue_size()

long ast_sip_threadpool_queue_size ( void  )

Return the size of the SIP threadpool's task queue.

Since
13.7.0

Definition at line 5510 of file res_pjsip.c.

References ast_threadpool_queue_size().

5511 {
5513 }
static struct ast_threadpool * sip_threadpool
Definition: res_pjsip.c:3188
long ast_threadpool_queue_size(struct ast_threadpool *pool)
Return the size of the threadpool&#39;s task queue.
Definition: threadpool.c:1437

◆ ast_sip_tpselector_unref()

void ast_sip_tpselector_unref ( pjsip_tpselector *  selector)

Unreference a pjsip_tpselector.

Since
17.0.0
Parameters
selectorThe selector to be unreffed

Definition at line 3872 of file res_pjsip.c.

Referenced by ast_sip_create_dialog_uac(), ast_sip_dlg_set_transport(), create_dialog_uas(), create_out_of_dialog_request(), registration_client_send(), set_transport(), and sip_outbound_registration_regc_alloc().

3873 {
3874  if (selector->type == PJSIP_TPSELECTOR_TRANSPORT && selector->u.transport) {
3875  pjsip_transport_dec_ref(selector->u.transport);
3876  }
3877 }

◆ ast_sip_unregister_authenticator()

void ast_sip_unregister_authenticator ( struct ast_sip_authenticator auth)

Unregister a SIP authenticator.

When there is no authenticator registered, requests cannot be challenged or authenticated.

Parameters
authThe authenticator to unregister

Definition at line 3252 of file res_pjsip.c.

References ast_debug, ast_log, LOG_WARNING, and NULL.

Referenced by unload_module().

3253 {
3254  if (registered_authenticator != auth) {
3255  ast_log(LOG_WARNING, "Trying to unregister authenticator %p but authenticator %p registered\n",
3256  auth, registered_authenticator);
3257  return;
3258  }
3260  ast_debug(1, "Unregistered SIP authenticator %p\n", auth);
3261 }
static struct ast_sip_authenticator * registered_authenticator
Definition: res_pjsip.c:3238
#define LOG_WARNING
Definition: logger.h:274
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#define ast_log
Definition: astobj2.c:42

◆ ast_sip_unregister_endpoint_formatter()

void ast_sip_unregister_endpoint_formatter ( struct ast_sip_endpoint_formatter obj)

Unregister an endpoint formatter.

Parameters
objthe formatter to unregister

Definition at line 3581 of file res_pjsip.c.

References AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, lock, and SCOPED_LOCK.

Referenced by ast_res_pjsip_cleanup_options_handling(), ast_sip_destroy_sorcery_auth(), ast_sip_destroy_sorcery_location(), ast_sip_destroy_sorcery_transport(), and unload_module().

3582 {
3583  struct ast_sip_endpoint_formatter *i;
3585 
3587  if (i == obj) {
3589  break;
3590  }
3591  }
3593 }
An entity responsible formatting endpoint information.
Definition: res_pjsip.h:2714
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
ast_mutex_t lock
Definition: app_meetme.c:1091
#define AST_RWLIST_REMOVE_CURRENT
Definition: linkedlists.h:569
#define SCOPED_LOCK(varname, lock, lockfunc, unlockfunc)
Scoped Locks.
Definition: lock.h:581
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:544
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:616

◆ ast_sip_unregister_endpoint_identifier()

void ast_sip_unregister_endpoint_identifier ( struct ast_sip_endpoint_identifier identifier)

Unregister a SIP endpoint identifier.

This stops an endpoint identifier from being used.

Parameters
identifierThe SIP endoint identifier to unregister

Definition at line 3409 of file res_pjsip.c.

References ast_debug, ast_free, AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, endpoint_identifier_list::identifier, lock, and SCOPED_LOCK.

Referenced by unload_module().

3410 {
3411  struct endpoint_identifier_list *iter;
3414  if (iter->identifier == identifier) {
3416  ast_free(iter);
3417  ast_debug(1, "Unregistered endpoint identifier %p\n", identifier);
3418  break;
3419  }
3420  }
3422 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
ast_mutex_t lock
Definition: app_meetme.c:1091
#define AST_RWLIST_REMOVE_CURRENT
Definition: linkedlists.h:569
#define SCOPED_LOCK(varname, lock, lockfunc, unlockfunc)
Scoped Locks.
Definition: lock.h:581
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:544
#define ast_free(a)
Definition: astmm.h:182
struct ast_sip_endpoint_identifier * identifier
Definition: res_pjsip.c:3321
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:616

◆ ast_sip_unregister_outbound_authenticator()

void ast_sip_unregister_outbound_authenticator ( struct ast_sip_outbound_authenticator auth)

Unregister an outbound SIP authenticator.

When there is no outbound authenticator registered, authentication challenges will be handled as any other final response would be.

Parameters
authThe authenticator to unregister

Definition at line 3297 of file res_pjsip.c.

References ast_debug, ast_log, LOG_WARNING, and NULL.

Referenced by unload_module().

3298 {
3299  if (registered_outbound_authenticator != auth) {
3300  ast_log(LOG_WARNING, "Trying to unregister outbound authenticator %p but outbound authenticator %p registered\n",
3302  return;
3303  }
3305  ast_debug(1, "Unregistered SIP outbound authenticator %p\n", auth);
3306 }
#define LOG_WARNING
Definition: logger.h:274
static struct ast_sip_outbound_authenticator * registered_outbound_authenticator
Definition: res_pjsip.c:3283
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#define ast_log
Definition: astobj2.c:42

◆ ast_sip_unregister_service()

void ast_sip_unregister_service ( pjsip_module *  module)

This is the opposite of ast_sip_register_service(). Unregistering a service means that PJSIP will no longer call into the module any more. This will likely occur when an Asterisk module is unloaded.

Parameters
moduleThe PJSIP module to unregister

Definition at line 3233 of file res_pjsip.c.

References ast_sip_push_task_wait_servant(), NULL, and unregister_service().

Referenced by ast_res_pjsip_cleanup_message_filter(), ast_sip_destroy_distributor(), ast_sip_destroy_global_headers(), ast_sip_destroy_transport_management(), load_module(), unload_module(), and unload_pjsip().

3234 {
3236 }
#define NULL
Definition: resample.c:96
int ast_sip_push_task_wait_servant(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Push a task to SIP servants and wait for it to complete.
Definition: res_pjsip.c:5089
static int unregister_service(void *data)
Definition: res_pjsip.c:3222

◆ ast_sip_unregister_supplement()

void ast_sip_unregister_supplement ( struct ast_sip_supplement supplement)

Unregister a an supplement to SIP out of dialog processing.

Parameters
supplementThe supplement to unregister

Definition at line 4416 of file res_pjsip.c.

References AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, lock, ast_sip_supplement::next, and SCOPED_LOCK.

Referenced by ast_res_pjsip_cleanup_message_filter(), and unload_module().

4417 {
4418  struct ast_sip_supplement *iter;
4420 
4422  if (supplement == iter) {
4424  break;
4425  }
4426  }
4428 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
ast_mutex_t lock
Definition: app_meetme.c:1091
#define AST_RWLIST_REMOVE_CURRENT
Definition: linkedlists.h:569
struct ast_sip_supplement * next
Definition: res_pjsip.h:2889
#define SCOPED_LOCK(varname, lock, lockfunc, unlockfunc)
Scoped Locks.
Definition: lock.h:581
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:544
A supplement to SIP message processing.
Definition: res_pjsip.h:2839
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:616

◆ ast_sip_will_uri_survive_restart()

int ast_sip_will_uri_survive_restart ( pjsip_sip_uri *  uri,
struct ast_sip_endpoint endpoint,
pjsip_rx_data *  rdata 
)

Definition at line 3619 of file res_pjsip.c.

References ast_sip_endpoint::nat, result, and ast_sip_endpoint_nat_configuration::rewrite_contact.

Referenced by register_aor_core(), and subscription_persistence_update().

3621 {
3622  pj_str_t host_name;
3623  int result = 1;
3624 
3625  /* Determine if the contact cannot survive a restart/boot. */
3626  if (uri->port == rdata->pkt_info.src_port
3627  && !pj_strcmp(&uri->host,
3628  pj_cstr(&host_name, rdata->pkt_info.src_name))
3629  /* We have already checked if the URI scheme is sip: or sips: */
3630  && PJSIP_TRANSPORT_IS_RELIABLE(rdata->tp_info.transport)) {
3631  pj_str_t type_name;
3632 
3633  /* Determine the transport parameter value */
3634  if (!strcasecmp("WSS", rdata->tp_info.transport->type_name)) {
3635  /* WSS is special, as it needs to be ws. */
3636  pj_cstr(&type_name, "ws");
3637  } else {
3638  pj_cstr(&type_name, rdata->tp_info.transport->type_name);
3639  }
3640 
3641  if (!pj_stricmp(&uri->transport_param, &type_name)
3642  && (endpoint->nat.rewrite_contact
3643  /* Websockets are always rewritten */
3644  || !pj_stricmp(&uri->transport_param,
3645  pj_cstr(&type_name, "ws")))) {
3646  /*
3647  * The contact was rewritten to the reliable transport's
3648  * source address. Disconnecting the transport for any
3649  * reason invalidates the contact.
3650  */
3651  result = 0;
3652  }
3653  }
3654 
3655  return result;
3656 }
struct ast_sip_endpoint_nat_configuration nat
Definition: res_pjsip.h:845
static PGresult * result
Definition: cel_pgsql.c:88

◆ check_request_status()

static int check_request_status ( struct send_request_data req_data,
pjsip_event *  e 
)
static

Definition at line 4779 of file res_pjsip.c.

References ao2_bump, ao2_ref, ast_sip_create_request_with_auth(), ast_sip_failover_request(), send_request_data::challenge_count, send_request_data::endpoint, endpt_send_request(), MAX_RX_CHALLENGES, and ast_sip_endpoint::outbound_auths.

Referenced by send_request_cb().

4780 {
4781  struct ast_sip_endpoint *endpoint;
4782  pjsip_transaction *tsx;
4783  pjsip_tx_data *tdata;
4784  int res = 0;
4785 
4786  if (!(endpoint = ao2_bump(req_data->endpoint))) {
4787  return 0;
4788  }
4789 
4790  tsx = e->body.tsx_state.tsx;
4791 
4792  switch (tsx->status_code) {
4793  case 401:
4794  case 407:
4795  /* Resend the request with a challenge response if we are challenged. */
4796  res = ++req_data->challenge_count < MAX_RX_CHALLENGES /* Not in a challenge loop */
4798  e->body.tsx_state.src.rdata, tsx->last_tx, &tdata);
4799  break;
4800  case 408:
4801  case 503:
4802  if ((res = ast_sip_failover_request(tsx->last_tx))) {
4803  tdata = tsx->last_tx;
4804  /*
4805  * Bump the ref since it will be on a new transaction and
4806  * we don't want it to go away along with the old transaction.
4807  */
4808  pjsip_tx_data_add_ref(tdata);
4809  }
4810  break;
4811  }
4812 
4813  if (res) {
4814  res = endpt_send_request(endpoint, tdata, -1,
4815  req_data, send_request_cb) == PJ_SUCCESS;
4816  }
4817 
4818  ao2_ref(endpoint, -1);
4819  return res;
4820 }
struct ast_sip_auth_vector outbound_auths
Definition: res_pjsip.h:855
#define ao2_bump(obj)
Definition: astobj2.h:491
#define ao2_ref(o, delta)
Definition: astobj2.h:464
An entity with which Asterisk communicates.
Definition: res_pjsip.h:812
static pj_status_t endpt_send_request(struct ast_sip_endpoint *endpoint, pjsip_tx_data *tdata, pj_int32_t timeout, void *token, pjsip_endpt_send_callback cb)
Definition: res_pjsip.c:4636
#define MAX_RX_CHALLENGES
Definition: res_pjsip.h:80
int ast_sip_failover_request(pjsip_tx_data *tdata)
Set a request to use the next value in the list of resolved addresses.
Definition: res_pjsip.c:4756
unsigned int challenge_count
Definition: res_pjsip.c:4464
static void send_request_cb(void *token, pjsip_event *e)
Definition: res_pjsip.c:4822
int ast_sip_create_request_with_auth(const struct ast_sip_auth_vector *auths, pjsip_rx_data *challenge, pjsip_tx_data *old_request, pjsip_tx_data **new_request)
Create a response to an authentication challenge.
Definition: res_pjsip.c:3308
struct ast_sip_endpoint * endpoint
Definition: res_pjsip.c:4458

◆ cli_dump_endpt()

static char* cli_dump_endpt ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 3465 of file res_pjsip.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_sip_push_task_wait_servant(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, do_cli_dump_endpt(), NULL, and ast_cli_entry::usage.

3466 {
3467  switch (cmd) {
3468  case CLI_INIT:
3469 #ifdef AST_DEVMODE
3470  e->command = "pjsip dump endpt [details]";
3471  e->usage =
3472  "Usage: pjsip dump endpt [details]\n"
3473  " Dump the res_pjsip endpt internals.\n"
3474  "\n"
3475  "Warning: PJPROJECT documents that the function used by this\n"
3476  "CLI command may cause a crash when asking for details because\n"
3477  "it tries to access all active memory pools.\n";
3478 #else
3479  /*
3480  * In non-developer mode we will not document or make easily accessible
3481  * the details option even though it is still available. The user has
3482  * to know it exists to use it. Presumably they would also be aware of
3483  * the potential crash warning.
3484  */
3485  e->command = "pjsip dump endpt";
3486  e->usage =
3487  "Usage: pjsip dump endpt\n"
3488  " Dump the res_pjsip endpt internals.\n";
3489 #endif /* AST_DEVMODE */
3490  return NULL;
3491  case CLI_GENERATE:
3492  return NULL;
3493  }
3494 
3495  if (4 < a->argc
3496  || (a->argc == 4 && strcasecmp(a->argv[3], "details"))) {
3497  return CLI_SHOWUSAGE;
3498  }
3499 
3501 
3502  return CLI_SUCCESS;
3503 }
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
int ast_sip_push_task_wait_servant(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Push a task to SIP servants and wait for it to complete.
Definition: res_pjsip.c:5089
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
static int do_cli_dump_endpt(void *v_a)
Definition: res_pjsip.c:3454

◆ cli_show_endpoint_identifiers()

static char* cli_show_endpoint_identifiers ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 3505 of file res_pjsip.c.

References ast_cli_args::argc, ast_cli(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ENDPOINT_IDENTIFIER_FORMAT, ast_cli_args::fd, lock, endpoint_identifier_list::name, NULL, SCOPED_LOCK, and ast_cli_entry::usage.

3506 {
3507 #define ENDPOINT_IDENTIFIER_FORMAT "%-20.20s\n"
3508  struct endpoint_identifier_list *iter;
3509 
3510  switch (cmd) {
3511  case CLI_INIT:
3512  e->command = "pjsip show identifiers";
3513  e->usage = "Usage: pjsip show identifiers\n"
3514  " List all registered endpoint identifiers\n";
3515  return NULL;
3516  case CLI_GENERATE:
3517  return NULL;
3518  }
3519 
3520  if (a->argc != 3) {
3521  return CLI_SHOWUSAGE;
3522  }
3523 
3524  ast_cli(a->fd, ENDPOINT_IDENTIFIER_FORMAT, "Identifier Names:");
3525  {
3529  iter->name ? iter->name : "name not specified");
3530  }
3531  }
3532  return CLI_SUCCESS;
3533 #undef ENDPOINT_IDENTIFIER_FORMAT
3534 }
const int argc
Definition: cli.h:160
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
#define ENDPOINT_IDENTIFIER_FORMAT
const int fd
Definition: cli.h:159
ast_mutex_t lock
Definition: app_meetme.c:1091
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
#define SCOPED_LOCK(varname, lock, lockfunc, unlockfunc)
Scoped Locks.
Definition: lock.h:581
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44

◆ cli_show_settings()

static char* cli_show_settings ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 3536 of file res_pjsip.c.

References ast_cli(), ast_free, ast_str_buffer(), ast_str_create, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, NULL, ast_sip_cli_context::output_buffer, sip_cli_print_global(), sip_cli_print_system(), and ast_cli_entry::usage.

3537 {
3539 
3540  switch (cmd) {
3541  case CLI_INIT:
3542  e->command = "pjsip show settings";
3543  e->usage = "Usage: pjsip show settings\n"
3544  " Show global and system configuration options\n";
3545  return NULL;
3546  case CLI_GENERATE:
3547  return NULL;
3548  }
3549 
3550  context.output_buffer = ast_str_create(256);
3551  if (!context.output_buffer) {
3552  ast_cli(a->fd, "Could not allocate output buffer.\n");
3553  return CLI_FAILURE;
3554  }
3555 
3557  ast_free(context.output_buffer);
3558  ast_cli(a->fd, "Error retrieving settings.\n");
3559  return CLI_FAILURE;
3560  }
3561 
3562  ast_cli(a->fd, "%s", ast_str_buffer(context.output_buffer));
3563  ast_free(context.output_buffer);
3564  return CLI_SUCCESS;
3565 }
int sip_cli_print_global(struct ast_sip_cli_context *context)
int sip_cli_print_system(struct ast_sip_cli_context *context)
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const int fd
Definition: cli.h:159
#define CLI_FAILURE
Definition: cli.h:46
#define ast_free(a)
Definition: astmm.h:182
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ create_dialog_uas()

static pjsip_dialog* create_dialog_uas ( const struct ast_sip_endpoint endpoint,
pjsip_rx_data *  rdata,
pj_status_t *  status,
create_dlg_uac  create_fun 
)
static

Definition at line 4062 of file res_pjsip.c.

References ast_assert, ast_log, ast_sip_set_tpselector_from_ep_or_uri(), ast_sip_tpselector_unref(), ast_sorcery_object_get_id(), LOG_ERROR, NULL, ast_sip_transport_state::transport, type, and uas_use_sips_contact().

Referenced by ast_sip_create_dialog_uas(), and ast_sip_create_dialog_uas_locked().

4064 {
4065  pjsip_dialog *dlg;
4066  pj_str_t contact;
4067  pjsip_transport_type_e type = rdata->tp_info.transport->key.type;
4068  pjsip_tpselector selector = { .type = PJSIP_TPSELECTOR_NONE, };
4069  pjsip_transport *transport;
4070  pjsip_contact_hdr *contact_hdr;
4071 
4072  ast_assert(status != NULL);
4073 
4074  contact_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, NULL);
4075  if (!contact_hdr || ast_sip_set_tpselector_from_ep_or_uri(endpoint, pjsip_uri_get_uri(contact_hdr->uri),
4076  &selector)) {
4077  return NULL;
4078  }
4079 
4080  transport = rdata->tp_info.transport;
4081  if (selector.type == PJSIP_TPSELECTOR_TRANSPORT) {
4082  transport = selector.u.transport;
4083  }
4084  type = transport->key.type;
4085 
4086  contact.ptr = pj_pool_alloc(rdata->tp_info.pool, PJSIP_MAX_URL_SIZE);
4087  contact.slen = pj_ansi_snprintf(contact.ptr, PJSIP_MAX_URL_SIZE,
4088  "<%s:%s%.*s%s:%d%s%s>",
4089  uas_use_sips_contact(rdata) ? "sips" : "sip",
4090  (type & PJSIP_TRANSPORT_IPV6) ? "[" : "",
4091  (int)transport->local_name.host.slen,
4092  transport->local_name.host.ptr,
4093  (type & PJSIP_TRANSPORT_IPV6) ? "]" : "",
4094  transport->local_name.port,
4095  (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? ";transport=" : "",
4096  (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? pjsip_transport_get_type_name(type) : "");
4097 
4098  *status = create_fun(pjsip_ua_instance(), rdata, &contact, &dlg);
4099  if (*status != PJ_SUCCESS) {
4100  char err[PJ_ERR_MSG_SIZE];
4101 
4102  pj_strerror(*status, err, sizeof(err));
4103  ast_log(LOG_ERROR, "Could not create dialog with endpoint %s. %s\n",
4104  ast_sorcery_object_get_id(endpoint), err);
4105  ast_sip_tpselector_unref(&selector);
4106  return NULL;
4107  }
4108 
4109  dlg->sess_count++;
4110  pjsip_dlg_set_transport(dlg, &selector);
4111  dlg->sess_count--;
4112 
4113  ast_sip_tpselector_unref(&selector);
4114 
4115  return dlg;
4116 }
static const char type[]
Definition: chan_ooh323.c:109
#define ast_assert(a)
Definition: utils.h:650
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2309
#define LOG_ERROR
Definition: logger.h:285
int ast_sip_set_tpselector_from_ep_or_uri(const struct ast_sip_endpoint *endpoint, pjsip_sip_uri *sip_uri, pjsip_tpselector *selector)
Sets pjsip_tpselector from an endpoint or uri.
Definition: res_pjsip.c:3860
void ast_sip_tpselector_unref(pjsip_tpselector *selector)
Unreference a pjsip_tpselector.
Definition: res_pjsip.c:3872
static int uas_use_sips_contact(pjsip_rx_data *rdata)
Determine if a SIPS Contact header is required.
Definition: res_pjsip.c:4033
jack_status_t status
Definition: app_jack.c:146

◆ create_in_dialog_request()

static int create_in_dialog_request ( const pjsip_method *  method,
struct pjsip_dialog *  dlg,
pjsip_tx_data **  tdata 
)
static

Definition at line 4247 of file res_pjsip.c.

References ast_log, LOG_WARNING, and supplement_on_rx_request().

Referenced by ast_sip_create_request().

4248 {
4249  if (pjsip_dlg_create_request(dlg, method, -1, tdata) != PJ_SUCCESS) {
4250  ast_log(LOG_WARNING, "Unable to create in-dialog request.\n");
4251  return -1;
4252  }
4253 
4254  return 0;
4255 }
#define LOG_WARNING
Definition: logger.h:274
#define ast_log
Definition: astobj2.c:42
const char * method
Definition: res_pjsip.c:4220

◆ create_out_of_dialog_request()

static int create_out_of_dialog_request ( const pjsip_method *  method,
struct ast_sip_endpoint endpoint,
const char *  uri,
struct ast_sip_contact provided_contact,
pjsip_tx_data **  tdata 
)
static

Definition at line 4265 of file res_pjsip.c.

References ao2_bump, ao2_cleanup, ast_sip_endpoint::aors, ast_log, ast_sip_add_usereqphone(), ast_sip_get_pjsip_endpoint(), ast_sip_location_retrieve_contact_from_aor_list(), ast_sip_mod_data_set, ast_sip_set_outbound_proxy(), ast_sip_set_tpselector_from_ep_or_uri(), ast_sip_tpselector_unref(), ast_sorcery_object_get_id(), ast_strlen_zero, ast_sip_endpoint::contact_user, ast_sip_endpoint::fromdomain, ast_sip_endpoint::fromuser, LOG_ERROR, LOG_WARNING, MOD_DATA_CONTACT, NULL, ast_sip_endpoint::outbound_proxy, RAII_VAR, sip_dialog_create_from(), and supplement_module.

Referenced by ast_sip_create_request().

4267 {
4268  RAII_VAR(struct ast_sip_contact *, contact, ao2_bump(provided_contact), ao2_cleanup);
4269  pj_str_t remote_uri;
4270  pj_str_t from;
4271  pj_pool_t *pool;
4272  pjsip_tpselector selector = { .type = PJSIP_TPSELECTOR_NONE, };
4273  pjsip_uri *sip_uri;
4274  const char *fromuser;
4275 
4276  if (ast_strlen_zero(uri)) {
4277  if (!endpoint && (!contact || ast_strlen_zero(contact->uri))) {
4278  ast_log(LOG_ERROR, "An endpoint and/or uri must be specified\n");
4279  return -1;
4280  }
4281 
4282  if (!contact) {
4284  }
4285  if (!contact || ast_strlen_zero(contact->uri)) {
4286  ast_log(LOG_WARNING, "Unable to retrieve contact for endpoint %s\n",
4287  ast_sorcery_object_get_id(endpoint));
4288  return -1;
4289  }
4290 
4291  pj_cstr(&remote_uri, contact->uri);
4292  } else {
4293  pj_cstr(&remote_uri, uri);
4294  }
4295 
4296  pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(), "Outbound request", 256, 256);
4297 
4298  if (!pool) {
4299  ast_log(LOG_ERROR, "Unable to create PJLIB memory pool\n");
4300  return -1;
4301  }
4302 
4303  sip_uri = pjsip_parse_uri(pool, remote_uri.ptr, remote_uri.slen, 0);
4304  if (!sip_uri || (!PJSIP_URI_SCHEME_IS_SIP(sip_uri) && !PJSIP_URI_SCHEME_IS_SIPS(sip_uri))) {
4305  ast_log(LOG_ERROR, "Unable to create outbound %.*s request to endpoint %s as URI '%s' is not valid\n",
4306  (int) pj_strlen(&method->name), pj_strbuf(&method->name),
4307  endpoint ? ast_sorcery_object_get_id(endpoint) : "<none>",
4308  pj_strbuf(&remote_uri));
4309  pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
4310  return -1;
4311  }
4312 
4313  ast_sip_set_tpselector_from_ep_or_uri(endpoint, pjsip_uri_get_uri(sip_uri), &selector);
4314 
4315  fromuser = endpoint ? (!ast_strlen_zero(endpoint->fromuser) ? endpoint->fromuser : ast_sorcery_object_get_id(endpoint)) : NULL;
4316  if (sip_dialog_create_from(pool, &from, fromuser,
4317  endpoint ? endpoint->fromdomain : NULL, &remote_uri, &selector)) {
4318  ast_log(LOG_ERROR, "Unable to create From header for %.*s request to endpoint %s\n",
4319  (int) pj_strlen(&method->name), pj_strbuf(&method->name),
4320  endpoint ? ast_sorcery_object_get_id(endpoint) : "<none>");
4321  pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
4322  ast_sip_tpselector_unref(&selector);
4323  return -1;
4324  }
4325 
4326  if (pjsip_endpt_create_request(ast_sip_get_pjsip_endpoint(), method, &remote_uri,
4327  &from, &remote_uri, &from, NULL, -1, NULL, tdata) != PJ_SUCCESS) {
4328  ast_log(LOG_ERROR, "Unable to create outbound %.*s request to endpoint %s\n",
4329  (int) pj_strlen(&method->name), pj_strbuf(&method->name),
4330  endpoint ? ast_sorcery_object_get_id(endpoint) : "<none>");
4331  pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
4332  ast_sip_tpselector_unref(&selector);
4333  return -1;
4334  }
4335 
4336  pjsip_tx_data_set_transport(*tdata, &selector);
4337 
4338  ast_sip_tpselector_unref(&selector);
4339 
4340  if (endpoint && !ast_strlen_zero(endpoint->contact_user)){
4341  pjsip_contact_hdr *contact_hdr;
4342  pjsip_sip_uri *contact_uri;
4343  static const pj_str_t HCONTACT = { "Contact", 7 };
4344  static const pj_str_t HCONTACTSHORT = { "m", 1 };
4345 
4346  contact_hdr = pjsip_msg_find_hdr_by_names((*tdata)->msg, &HCONTACT, &HCONTACTSHORT, NULL);
4347  if (contact_hdr) {
4348  contact_uri = pjsip_uri_get_uri(contact_hdr->uri);
4349  pj_strdup2((*tdata)->pool, &contact_uri->user, endpoint->contact_user);
4350  }
4351  }
4352 
4353  /* Add the user=phone parameter if applicable */
4354  ast_sip_add_usereqphone(endpoint, (*tdata)->pool, (*tdata)->msg->line.req.uri);
4355 
4356  /* If an outbound proxy is specified on the endpoint apply it to this request */
4357  if (endpoint && !ast_strlen_zero(endpoint->outbound_proxy) &&
4358  ast_sip_set_outbound_proxy((*tdata), endpoint->outbound_proxy)) {
4359  ast_log(LOG_ERROR, "Unable to apply outbound proxy on request %.*s to endpoint %s as outbound proxy URI '%s' is not valid\n",
4360  (int) pj_strlen(&method->name), pj_strbuf(&method->name), ast_sorcery_object_get_id(endpoint),
4361  endpoint->outbound_proxy);
4362  pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
4363  return -1;
4364  }
4365 
4366  ast_sip_mod_data_set((*tdata)->pool, (*tdata)->mod_data, supplement_module.id, MOD_DATA_CONTACT, ao2_bump(contact));
4367 
4368  /* We can release this pool since request creation copied all the necessary
4369  * data into the outbound request's pool
4370  */
4371  pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
4372  return 0;
4373 }
void ast_sip_add_usereqphone(const struct ast_sip_endpoint *endpoint, pj_pool_t *pool, pjsip_uri *uri)
Add &#39;user=phone&#39; parameter to URI if enabled and user is a phone number.
Definition: res_pjsip.c:3879
int ast_sip_set_outbound_proxy(pjsip_tx_data *tdata, const char *proxy)
Set the outbound proxy for an outbound SIP message.
Definition: res_pjsip.c:4932
const ast_string_field fromuser
Definition: res_pjsip.h:829
#define LOG_WARNING
Definition: logger.h:274
char * contact_user
Definition: res_pjsip.h:887
#define NULL
Definition: resample.c:96
#define ao2_bump(obj)
Definition: astobj2.h:491
#define ast_log
Definition: astobj2.c:42
static pjsip_module supplement_module
Definition: res_pjsip.c:4258
#define ast_sip_mod_data_set(pool, mod_data, id, key, val)
Utilizing a mod_data array for a given id, set the value associated with the given key...
Definition: res_pjsip.h:2621
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:851
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2309
const char * method
Definition: res_pjsip.c:4220
struct ast_sip_contact * ast_sip_location_retrieve_contact_from_aor_list(const char *aor_list)
Retrieve the first bound contact from a list of AORs.
Definition: location.c:304
const ast_string_field outbound_proxy
Definition: res_pjsip.h:819
#define LOG_ERROR
Definition: logger.h:285
int ast_sip_set_tpselector_from_ep_or_uri(const struct ast_sip_endpoint *endpoint, pjsip_sip_uri *sip_uri, pjsip_tpselector *selector)
Sets pjsip_tpselector from an endpoint or uri.
Definition: res_pjsip.c:3860
Contact associated with an address of record.
Definition: res_pjsip.h:281
#define ast_strlen_zero(a)
Definition: muted.c:73
void ast_sip_tpselector_unref(pjsip_tpselector *selector)
Unreference a pjsip_tpselector.
Definition: res_pjsip.c:3872
#define MOD_DATA_CONTACT
Definition: res_pjsip.c:3178
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
const ast_string_field aors
Definition: res_pjsip.h:821
static int sip_dialog_create_from(pj_pool_t *pool, pj_str_t *from, const char *user, const char *domain, const pj_str_t *target, pjsip_tpselector *selector)
Definition: res_pjsip.c:3709
const ast_string_field fromdomain
Definition: res_pjsip.h:831
pjsip_endpoint * ast_sip_get_pjsip_endpoint(void)
Get a pointer to the PJSIP endpoint.
Definition: res_pjsip.c:3614

◆ do_cli_dump_endpt()

static int do_cli_dump_endpt ( void *  v_a)
static

Definition at line 3454 of file res_pjsip.c.

References a, ast_cli_args::argc, ast_pjproject_log_intercept_begin(), ast_pjproject_log_intercept_end(), ast_sip_get_pjsip_endpoint(), and ast_cli_args::fd.

Referenced by cli_dump_endpt().

3455 {
3456  struct ast_cli_args *a = v_a;
3457 
3459  pjsip_endpt_dump(ast_sip_get_pjsip_endpoint(), a->argc == 4 ? PJ_TRUE : PJ_FALSE);
3461 
3462  return 0;
3463 }
const int argc
Definition: cli.h:160
const int fd
Definition: cli.h:159
void ast_pjproject_log_intercept_end(void)
End PJPROJECT log interception for CLI output.
void ast_pjproject_log_intercept_begin(int fd)
Begin PJPROJECT log interception for CLI output.
pjsip_endpoint * ast_sip_get_pjsip_endpoint(void)
Get a pointer to the PJSIP endpoint.
Definition: res_pjsip.c:3614
static struct test_val a

◆ does_method_match()

static pj_bool_t does_method_match ( const pj_str_t *  message_method,
const char *  supplement_method 
)
static

Definition at line 4439 of file res_pjsip.c.

References ast_strlen_zero, and method.

Referenced by ast_sip_send_out_of_dialog_request(), send_request_cb(), supplement_on_rx_request(), and supplement_outgoing_response().

4440 {
4441  pj_str_t method;
4442 
4443  if (ast_strlen_zero(supplement_method)) {
4444  return PJ_TRUE;
4445  }
4446 
4447  pj_cstr(&method, supplement_method);
4448 
4449  return pj_stristr(&method, message_method) ? PJ_TRUE : PJ_FALSE;
4450 }
static const pjsip_method message_method
Definition: res_pjsip.c:4217
const char * method
Definition: res_pjsip.c:4220
#define ast_strlen_zero(a)
Definition: muted.c:73

◆ endpt_send_request()

static pj_status_t endpt_send_request ( struct ast_sip_endpoint endpoint,
pjsip_tx_data *  tdata,
pj_int32_t  timeout,
void *  token,
pjsip_endpt_send_callback  cb 
)
static

Definition at line 4636 of file res_pjsip.c.

References ao2_alloc, ao2_lock, ao2_ref, ao2_t_ref, ao2_unlock, ast_debug, ast_log, ast_sip_get_pjsip_endpoint(), ast_sorcery_object_get_id(), send_request_wrapper::callback, send_request_wrapper::cb_called, endpt_send_request_cb(), LOG_ERROR, NULL, send_request_wrapper::send_cb_called, send_request_timer_callback(), send_request_wrapper_destructor(), send_request_wrapper::tdata, timeout, send_request_wrapper::timeout, send_request_wrapper::timeout_timer, TIMEOUT_TIMER2, TIMER_INACTIVE, and send_request_wrapper::token.

Referenced by ast_sip_send_out_of_dialog_request(), and check_request_status().

4638 {
4639  struct send_request_wrapper *req_wrapper;
4640  pj_status_t ret_val;
4641  pjsip_endpoint *endpt = ast_sip_get_pjsip_endpoint();
4642 
4643  if (!cb && token) {
4644  /* Silly. Without a callback we cannot do anything with token. */
4645  pjsip_tx_data_dec_ref(tdata);
4646  return PJ_EINVAL;
4647  }
4648 
4649  /* Create wrapper to detect if the callback was actually called on an error. */
4650  req_wrapper = ao2_alloc(sizeof(*req_wrapper), send_request_wrapper_destructor);
4651  if (!req_wrapper) {
4652  pjsip_tx_data_dec_ref(tdata);
4653  return PJ_ENOMEM;
4654  }
4655 
4656  ast_debug(2, "%p: Wrapper created\n", req_wrapper);
4657 
4658  req_wrapper->token = token;
4659  req_wrapper->callback = cb;
4660  req_wrapper->timeout = timeout;
4661  req_wrapper->timeout_timer = NULL;
4662  req_wrapper->tdata = tdata;
4663  /* Add a reference to tdata. The wrapper destructor cleans it up. */
4664  pjsip_tx_data_add_ref(tdata);
4665 
4666  if (timeout > 0) {
4667  pj_time_val timeout_timer_val = { timeout / 1000, timeout % 1000 };
4668 
4669  req_wrapper->timeout_timer = PJ_POOL_ALLOC_T(tdata->pool, pj_timer_entry);
4670 
4671  ast_debug(2, "%p: Set timer to %d msec\n", req_wrapper, timeout);
4672 
4673  pj_timer_entry_init(req_wrapper->timeout_timer, TIMEOUT_TIMER2,
4674  req_wrapper, send_request_timer_callback);
4675 
4676  /* We need to insure that the wrapper and tdata are available if/when the
4677  * timer callback is executed.
4678  */
4679  ao2_ref(req_wrapper, +1);
4680  ret_val = pj_timer_heap_schedule(pjsip_endpt_get_timer_heap(endpt),
4681  req_wrapper->timeout_timer, &timeout_timer_val);
4682  if (ret_val != PJ_SUCCESS) {
4684  "Failed to set timer. Not sending %.*s request to endpoint %s.\n",
4685  (int) pj_strlen(&tdata->msg->line.req.method.name),
4686  pj_strbuf(&tdata->msg->line.req.method.name),
4687  endpoint ? ast_sorcery_object_get_id(endpoint) : "<unknown>");
4688  ao2_t_ref(req_wrapper, -2, "Drop timer and routine ref");
4689  pjsip_tx_data_dec_ref(tdata);
4690  return ret_val;
4691  }
4692  }
4693 
4694  /* We need to insure that the wrapper and tdata are available when the
4695  * transaction callback is executed.
4696  */
4697  ao2_ref(req_wrapper, +1);
4698  ret_val = pjsip_endpt_send_request(endpt, tdata, -1, req_wrapper, endpt_send_request_cb);
4699  if (ret_val != PJ_SUCCESS) {
4700  char errmsg[PJ_ERR_MSG_SIZE];
4701 
4702  if (!req_wrapper->send_cb_called) {
4703  /* endpt_send_request_cb is not expected to ever be called now. */
4704  ao2_ref(req_wrapper, -1);
4705  }
4706 
4707  /* Complain of failure to send the request. */
4708  pj_strerror(ret_val, errmsg, sizeof(errmsg));
4709  ast_log(LOG_ERROR, "Error %d '%s' sending %.*s request to endpoint %s\n",
4710  (int) ret_val, errmsg, (int) pj_strlen(&tdata->msg->line.req.method.name),
4711  pj_strbuf(&tdata->msg->line.req.method.name),
4712  endpoint ? ast_sorcery_object_get_id(endpoint) : "<unknown>");
4713 
4714  if (timeout > 0) {
4715  int timers_cancelled;
4716 
4717  ao2_lock(req_wrapper);
4718  timers_cancelled = pj_timer_heap_cancel_if_active(
4719  pjsip_endpt_get_timer_heap(endpt),
4720  req_wrapper->timeout_timer, TIMER_INACTIVE);
4721  if (timers_cancelled > 0) {
4722  ao2_ref(req_wrapper, -1);
4723  }
4724 
4725  /* Was the callback called? */
4726  if (req_wrapper->cb_called) {
4727  /*
4728  * Yes so we cannot report any error. The callback
4729  * has already freed any resources associated with
4730  * token.
4731  */
4732  ret_val = PJ_SUCCESS;
4733  } else {
4734  /*
4735  * No so we claim it is called so our caller can free
4736  * any resources associated with token because of
4737  * failure.
4738  */
4739  req_wrapper->cb_called = 1;
4740  }
4741  ao2_unlock(req_wrapper);
4742  } else if (req_wrapper->cb_called) {
4743  /*
4744  * We cannot report any error. The callback has
4745  * already freed any resources associated with
4746  * token.
4747  */
4748  ret_val = PJ_SUCCESS;
4749  }
4750  }
4751 
4752  ao2_ref(req_wrapper, -1);
4753  return ret_val;
4754 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:463
void(* callback)(void *token, pjsip_event *e)
Definition: res_pjsip.c:4496
pj_int32_t timeout
Definition: res_pjsip.c:4504
pj_timer_entry * timeout_timer
Definition: res_pjsip.c:4502
static int timeout
Definition: cdr_mysql.c:86
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
#define TIMEOUT_TIMER2
Definition: res_pjsip.c:4453
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#define ast_log
Definition: astobj2.c:42
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2309
unsigned int cb_called
Definition: res_pjsip.c:4498
#define LOG_ERROR
Definition: logger.h:285
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
static void endpt_send_request_cb(void *token, pjsip_event *e)
Definition: res_pjsip.c:4513
#define TIMER_INACTIVE
Definition: res_pjsip.c:4452
static void send_request_timer_callback(pj_timer_heap_t *theap, pj_timer_entry *entry)
Definition: res_pjsip.c:4588
pjsip_tx_data * tdata
Definition: res_pjsip.c:4506
unsigned int send_cb_called
Definition: res_pjsip.c:4500
pjsip_endpoint * ast_sip_get_pjsip_endpoint(void)
Get a pointer to the PJSIP endpoint.
Definition: res_pjsip.c:3614
static void send_request_wrapper_destructor(void *obj)
Definition: res_pjsip.c:4628

◆ endpt_send_request_cb()

static void endpt_send_request_cb ( void *  token,
pjsip_event *  e 
)
static

Definition at line 4513 of file res_pjsip.c.

References ao2_lock, ao2_ref, ao2_unlock, ast_debug, ast_sip_get_pjsip_endpoint(), send_request_wrapper::callback, send_request_wrapper::cb_called, send_request_wrapper::send_cb_called, send_request_wrapper::timeout_timer, TIMEOUT_TIMER2, TIMER_INACTIVE, and send_request_wrapper::token.

Referenced by endpt_send_request().

4514 {
4515  struct send_request_wrapper *req_wrapper = token;
4516  unsigned int cb_called;
4517 
4518  /*
4519  * Needed because we cannot otherwise tell if this callback was
4520  * called when pjsip_endpt_send_request() returns error.
4521  */
4522  req_wrapper->send_cb_called = 1;
4523 
4524  if (e->body.tsx_state.type == PJSIP_EVENT_TIMER) {
4525  ast_debug(2, "%p: PJSIP tsx timer expired\n", req_wrapper);
4526 
4527  if (req_wrapper->timeout_timer
4528  && req_wrapper->timeout_timer->id != TIMEOUT_TIMER2) {
4529  ast_debug(3, "%p: Timeout already handled\n", req_wrapper);
4530  ao2_ref(req_wrapper, -1);
4531  return;
4532  }
4533  } else {
4534  ast_debug(2, "%p: PJSIP tsx response received\n", req_wrapper);
4535  }
4536 
4537  ao2_lock(req_wrapper);
4538 
4539  /* It's possible that our own timer was already processing while
4540  * we were waiting on the lock so check the timer id. If it's
4541  * still TIMER2 then we still need to process.
4542  */
4543  if (req_wrapper->timeout_timer
4544  && req_wrapper->timeout_timer->id == TIMEOUT_TIMER2) {
4545  int timers_cancelled = 0;
4546 
4547  ast_debug(3, "%p: Cancelling timer\n", req_wrapper);
4548 
4549  timers_cancelled = pj_timer_heap_cancel_if_active(
4550  pjsip_endpt_get_timer_heap(ast_sip_get_pjsip_endpoint()),
4551  req_wrapper->timeout_timer, TIMER_INACTIVE);
4552  if (timers_cancelled > 0) {
4553  /* If the timer was cancelled the callback will never run so
4554  * clean up its reference to the wrapper.
4555  */
4556  ast_debug(3, "%p: Timer cancelled\n", req_wrapper);
4557  ao2_ref(req_wrapper, -1);
4558  } else {
4559  /*
4560  * If it wasn't cancelled, it MAY be in the callback already
4561  * waiting on the lock. When we release the lock, it will
4562  * now know not to proceed.
4563  */
4564  ast_debug(3, "%p: Timer already expired\n", req_wrapper);
4565  }
4566  }
4567 
4568  cb_called = req_wrapper->cb_called;
4569  req_wrapper->cb_called = 1;
4570  ao2_unlock(req_wrapper);
4571 
4572  /* It's possible that our own timer expired and called the callbacks
4573  * so no need to call them again.
4574  */
4575  if (!cb_called && req_wrapper->callback) {
4576  req_wrapper->callback(req_wrapper->token, e);
4577  ast_debug(2, "%p: Callbacks executed\n", req_wrapper);
4578  }
4579 
4580  ao2_ref(req_wrapper, -1);
4581 }
void(* callback)(void *token, pjsip_event *e)
Definition: res_pjsip.c:4496
pj_timer_entry * timeout_timer
Definition: res_pjsip.c:4502
#define ao2_unlock(a)
Definition: astobj2.h:730
#define TIMEOUT_TIMER2
Definition: res_pjsip.c:4453
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
unsigned int cb_called
Definition: res_pjsip.c:4498
#define TIMER_INACTIVE
Definition: res_pjsip.c:4452
unsigned int send_cb_called
Definition: res_pjsip.c:4500
pjsip_endpoint * ast_sip_get_pjsip_endpoint(void)
Get a pointer to the PJSIP endpoint.
Definition: res_pjsip.c:3614

◆ get_pjsip_method()

static const pjsip_method* get_pjsip_method ( const char *  method)
static

Definition at line 4236 of file res_pjsip.c.

References ARRAY_LEN, methods, and NULL.

Referenced by ast_sip_create_request().

4237 {
4238  int i;
4239  for (i = 0; i < ARRAY_LEN(methods); ++i) {
4240  if (!strcmp(method, methods[i].method)) {
4241  return methods[i].pmethod;
4242  }
4243  }
4244  return NULL;
4245 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define NULL
Definition: resample.c:96
static struct @464 methods[]
const char * method
Definition: res_pjsip.c:4220

◆ load_module()

static int load_module ( void  )
static

Definition at line 5695 of file res_pjsip.c.

References ARRAY_LEN, ast_cli_register_multiple, ast_log, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_res_pjsip_init_message_filter(), ast_res_pjsip_init_options_handling(), ast_res_pjsip_initialize_configuration(), ast_res_pjsip_preinit_options_handling(), ast_serializer_pool_create(), ast_serializer_pool_destroy(), ast_sip_destroy_scheduler(), ast_sip_initialize_distributor(), ast_sip_initialize_dns(), ast_sip_initialize_global_headers(), ast_sip_initialize_resolver(), ast_sip_initialize_scheduler(), ast_sip_initialize_system(), ast_sip_initialize_transport_events(), ast_sip_initialize_transport_management(), ast_sip_register_service(), AST_TEST_REGISTER, ast_threadpool_create(), ast_threadpool_shutdown(), error(), load_pjsip(), LOG_ERROR, LOG_WARNING, NULL, SERIALIZER_POOL_SIZE, sip_get_threadpool_options(), sip_thread_start(), supplement_module, ast_threadpool_options::thread_start, and unload_pjsip().

Referenced by unload_module().

5696 {
5698 
5699  /* pjproject and config_system need to be initialized before all else */
5700  if (pj_init() != PJ_SUCCESS) {
5701  return AST_MODULE_LOAD_DECLINE;
5702  }
5703 
5704  if (pjlib_util_init() != PJ_SUCCESS) {
5705  goto error;
5706  }
5707 
5708  /* Register PJMEDIA error codes for SDP parsing errors */
5709  if (pj_register_strerror(PJMEDIA_ERRNO_START, PJ_ERRNO_SPACE_SIZE, pjmedia_strerror)
5710  != PJ_SUCCESS) {
5711  ast_log(LOG_WARNING, "Failed to register pjmedia error codes. Codes will not be decoded.\n");
5712  }
5713 
5714  if (ast_sip_initialize_system()) {
5715  ast_log(LOG_ERROR, "Failed to initialize SIP 'system' configuration section. Aborting load\n");
5716  goto error;
5717  }
5718 
5719  /* The serializer needs threadpool and threadpool needs pjproject to be initialized so it's next */
5721  options.thread_start = sip_thread_start;
5723  if (!sip_threadpool) {
5724  goto error;
5725  }
5726 
5728  "pjsip/default", SERIALIZER_POOL_SIZE, sip_threadpool, -1);
5729  if (!sip_serializer_pool) {
5730  ast_log(LOG_ERROR, "Failed to create SIP serializer pool. Aborting load\n");
5731  goto error;
5732  }
5733 
5735  ast_log(LOG_ERROR, "Failed to start scheduler. Aborting load\n");
5736  goto error;
5737  }
5738 
5739  /* Now load all the pjproject infrastructure. */
5740  if (load_pjsip()) {
5741  goto error;
5742  }
5743 
5745  ast_log(LOG_ERROR, "Failed to initialize SIP transport monitor. Aborting load\n");
5746  goto error;
5747  }
5748 
5751 
5753  ast_log(LOG_ERROR, "Failed to pre-initialize OPTIONS handling. Aborting load\n");
5754  goto error;
5755  }
5756 
5758  ast_log(LOG_ERROR, "Failed to initialize SIP configuration. Aborting load\n");
5759  goto error;
5760  }
5761 
5764 
5766  ast_log(LOG_ERROR, "Failed to initialize SIP transport management. Aborting load\n");
5767  goto error;
5768  }
5769 
5771  ast_log(LOG_ERROR, "Failed to register distributor module. Aborting load\n");
5772  goto error;
5773  }
5774 
5776  ast_log(LOG_ERROR, "Failed to initialize supplement hooks. Aborting load\n");
5777  goto error;
5778  }
5779 
5781  ast_log(LOG_ERROR, "Failed to initialize OPTIONS handling. Aborting load\n");
5782  goto error;
5783  }
5784 
5786  ast_log(LOG_ERROR, "Failed to initialize message IP updating. Aborting load\n");
5787  goto error;
5788  }
5789 
5791 
5792  AST_TEST_REGISTER(xml_sanitization_end_null);
5793  AST_TEST_REGISTER(xml_sanitization_exceeds_buffer);
5794 
5795  return AST_MODULE_LOAD_SUCCESS;
5796 
5797 error:
5798  unload_pjsip(NULL);
5799 
5800  /* These functions all check for NULLs and are safe to call at any time */
5804 
5805  return AST_MODULE_LOAD_DECLINE;
5806 }
int ast_res_pjsip_preinit_options_handling(void)
static struct ast_cli_entry cli_commands[]
Definition: res_pjsip.c:3567
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
void ast_sip_initialize_global_headers(void)
int ast_sip_initialize_scheduler(void)
Initialize scheduler.
int ast_sip_initialize_distributor(void)
int ast_serializer_pool_destroy(struct ast_serializer_pool *pool)
Destroy the serializer pool.
Definition: serializer.c:39
#define LOG_WARNING
Definition: logger.h:274
static struct ast_threadpool * sip_threadpool
Definition: res_pjsip.c:3188
int ast_sip_destroy_scheduler(void)
static void sip_thread_start(void)
Definition: res_pjsip.c:5181
#define AST_TEST_REGISTER(cb)
Definition: test.h:127
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
int ast_sip_initialize_transport_management(void)
#define NULL
Definition: resample.c:96
void ast_sip_initialize_dns(void)
void ast_sip_initialize_resolver(void)
int ast_sip_register_service(pjsip_module *module)
Register a SIP service in Asterisk.
Definition: res_pjsip.c:3217
#define ast_log
Definition: astobj2.c:42
static pjsip_module supplement_module
Definition: res_pjsip.c:4258
static int load_pjsip(void)
Definition: res_pjsip.c:5629
int ast_sip_initialize_system(void)
#define LOG_ERROR
Definition: logger.h:285
void sip_get_threadpool_options(struct ast_threadpool_options *threadpool_options)
Definition: config_system.c:70
int ast_res_pjsip_init_options_handling(int reload)
int ast_sip_initialize_transport_events(void)
static struct ast_serializer_pool * sip_serializer_pool
Definition: res_pjsip.c:3184
struct ast_threadpool * ast_threadpool_create(const char *name, struct ast_threadpool_listener *listener, const struct ast_threadpool_options *options)
Create a new threadpool.
Definition: threadpool.c:915
#define SERIALIZER_POOL_SIZE
Definition: res_pjsip.c:3181
int ast_res_pjsip_initialize_configuration(void)
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
void ast_threadpool_shutdown(struct ast_threadpool *pool)
Shut down a threadpool and destroy it.
Definition: threadpool.c:965
static int unload_pjsip(void *data)
Definition: res_pjsip.c:5585
struct ast_serializer_pool * ast_serializer_pool_create(const char *name, unsigned int size, struct ast_threadpool *threadpool, int timeout)
Create a serializer pool.
Definition: serializer.c:76
int error(const char *format,...)
Definition: utils/frame.c:999
int ast_res_pjsip_init_message_filter(void)
static struct test_options options

◆ load_pjsip()

static int load_pjsip ( void  )
static

Definition at line 5629 of file res_pjsip.c.

References ast_log, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_pjproject_caching_pool_init(), ast_pjsip_endpoint, ast_verb, error(), host_ip_ipv4, host_ip_ipv4_string, host_ip_ipv6, host_ip_ipv6_string, LOG_ERROR, monitor_thread_exec(), never_called_res_pjsip(), NULL, remove_request_headers(), and status.

Referenced by load_module().

5630 {
5631  const unsigned int flags = 0; /* no port, no brackets */
5632  pj_status_t status;
5633 
5634  /* The third parameter is just copied from
5635  * example code from PJLIB. This can be adjusted
5636  * if necessary.
5637  */
5639  if (pjsip_endpt_create(&caching_pool.factory, "SIP", &ast_pjsip_endpoint) != PJ_SUCCESS) {
5640  ast_log(LOG_ERROR, "Failed to create PJSIP endpoint structure. Aborting load\n");
5641  goto error;
5642  }
5643 
5644  /* PJSIP will automatically try to add a Max-Forwards header. Since we want to control that,
5645  * we need to stop PJSIP from doing it automatically
5646  */
5648 
5649  memory_pool = pj_pool_create(&caching_pool.factory, "SIP", 1024, 1024, NULL);
5650  if (!memory_pool) {
5651  ast_log(LOG_ERROR, "Failed to create memory pool for SIP. Aborting load\n");
5652  goto error;
5653  }
5654 
5655  if (!pj_gethostip(pj_AF_INET(), &host_ip_ipv4)) {
5656  pj_sockaddr_print(&host_ip_ipv4, host_ip_ipv4_string, sizeof(host_ip_ipv4_string), flags);
5657  ast_verb(3, "Local IPv4 address determined to be: %s\n", host_ip_ipv4_string);
5658  }
5659 
5660  if (!pj_gethostip(pj_AF_INET6(), &host_ip_ipv6)) {
5661  pj_sockaddr_print(&host_ip_ipv6, host_ip_ipv6_string, sizeof(host_ip_ipv6_string), flags);
5662  ast_verb(3, "Local IPv6 address determined to be: %s\n", host_ip_ipv6_string);
5663  }
5664 
5665  pjsip_tsx_layer_init_module(ast_pjsip_endpoint);
5666  pjsip_ua_init_module(ast_pjsip_endpoint, NULL);
5667 
5668  monitor_continue = 1;
5669  status = pj_thread_create(memory_pool, "SIP", (pj_thread_proc *) &monitor_thread_exec,
5670  NULL, PJ_THREAD_DEFAULT_STACK_SIZE * 2, 0, &monitor_thread);
5671  if (status != PJ_SUCCESS) {
5672  ast_log(LOG_ERROR, "Failed to start SIP monitor thread. Aborting load\n");
5673  goto error;
5674  }
5675 
5676  return AST_MODULE_LOAD_SUCCESS;
5677 
5678 error:
5679  return AST_MODULE_LOAD_DECLINE;
5680 }
static pj_sockaddr host_ip_ipv6
Definition: res_pjsip.c:3197
pj_thread_t * monitor_thread
Definition: res_pjsip.c:5159
pj_caching_pool caching_pool
Definition: res_pjsip.c:5157
static char host_ip_ipv6_string[PJ_INET6_ADDRSTRLEN]
Definition: res_pjsip.c:3200
#define NULL
Definition: resample.c:96
#define ast_verb(level,...)
Definition: logger.h:455
static void * monitor_thread_exec(void *endpt)
Definition: res_pjsip.c:5162
#define ast_log
Definition: astobj2.c:42
void ast_pjproject_caching_pool_init(pj_caching_pool *cp, const pj_pool_factory_policy *policy, pj_size_t max_capacity)
Initialize the caching pool factory.
#define LOG_ERROR
Definition: logger.h:285
static pjsip_endpoint * ast_pjsip_endpoint
Definition: res_pjsip.c:3186
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
static char host_ip_ipv4_string[PJ_INET6_ADDRSTRLEN]
Definition: res_pjsip.c:3194
static int monitor_continue
Definition: res_pjsip.c:5160
pj_pool_t * memory_pool
Definition: res_pjsip.c:5158
static pj_sockaddr host_ip_ipv4
Definition: res_pjsip.c:3191
static void remove_request_headers(pjsip_endpoint *endpt)
Definition: res_pjsip.c:5498
int error(const char *format,...)
Definition: utils/frame.c:999
jack_status_t status
Definition: app_jack.c:146

◆ monitor_thread_exec()

static void* monitor_thread_exec ( void *  endpt)
static

Definition at line 5162 of file res_pjsip.c.

References ast_pjsip_endpoint, and NULL.

Referenced by load_pjsip().

5163 {
5164  while (monitor_continue) {
5165  const pj_time_val delay = {0, 10};
5166  pjsip_endpt_handle_events(ast_pjsip_endpoint, &delay);
5167  }
5168  return NULL;
5169 }
#define NULL
Definition: resample.c:96
static pjsip_endpoint * ast_pjsip_endpoint
Definition: res_pjsip.c:3186
static int monitor_continue
Definition: res_pjsip.c:5160

◆ never_called_res_pjsip()

void never_called_res_pjsip ( void  )

Definition at line 5690 of file res_pjsip.c.

References NULL.

Referenced by load_pjsip().

5691 {
5692  pjmedia_strerror(0, NULL, 0);
5693 }
#define NULL
Definition: resample.c:96

◆ register_service()

static int register_service ( void *  data)
static

Definition at line 3202 of file res_pjsip.c.

References ast_debug, ast_log, ast_pjsip_endpoint, and LOG_ERROR.

Referenced by ast_sip_register_service().

3203 {
3204  pjsip_module **module = data;
3205  if (!ast_pjsip_endpoint) {
3206  ast_log(LOG_ERROR, "There is no PJSIP endpoint. Unable to register services\n");
3207  return -1;
3208  }
3209  if (pjsip_endpt_register_module(ast_pjsip_endpoint, *module) != PJ_SUCCESS) {
3210  ast_log(LOG_ERROR, "Unable to register module %.*s\n", (int) pj_strlen(&(*module)->name), pj_strbuf(&(*module)->name));
3211  return -1;
3212  }
3213  ast_debug(1, "Registered SIP service %.*s (%p)\n", (int) pj_strlen(&(*module)->name), pj_strbuf(&(*module)->name), *module);
3214  return 0;
3215 }
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
static pjsip_endpoint * ast_pjsip_endpoint
Definition: res_pjsip.c:3186

◆ reload_configuration_task()

static int reload_configuration_task ( void *  obj)
static

Definition at line 5577 of file res_pjsip.c.

References ast_res_pjsip_init_options_handling(), ast_res_pjsip_reload_configuration(), and ast_sip_initialize_dns().

Referenced by reload_module().

5578 {
5582  return 0;
5583 }
void ast_sip_initialize_dns(void)
int ast_res_pjsip_init_options_handling(int reload)
int ast_res_pjsip_reload_configuration(void)

◆ reload_module()

static int reload_module ( void  )
static

Definition at line 5808 of file res_pjsip.c.

References ast_log, ast_sip_push_task_wait_servant(), LOG_WARNING, NULL, and reload_configuration_task().

Referenced by unload_module().

5809 {
5810  /*
5811  * We must wait for the reload to complete so multiple
5812  * reloads cannot happen at the same time.
5813  */
5815  ast_log(LOG_WARNING, "Failed to reload PJSIP\n");
5816  return -1;
5817  }
5818 
5819  return 0;
5820 }
#define LOG_WARNING
Definition: logger.h:274
#define NULL
Definition: resample.c:96
int ast_sip_push_task_wait_servant(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Push a task to SIP servants and wait for it to complete.
Definition: res_pjsip.c:5089
#define ast_log
Definition: astobj2.c:42
static int reload_configuration_task(void *obj)
Definition: res_pjsip.c:5577

◆ remove_request_headers()

static void remove_request_headers ( pjsip_endpoint *  endpt)
static

Definition at line 5498 of file res_pjsip.c.

References request_headers.

Referenced by load_pjsip().

5499 {
5500  const pjsip_hdr *request_headers = pjsip_endpt_get_request_headers(endpt);
5501  pjsip_hdr *iter = request_headers->next;
5502 
5503  while (iter != request_headers) {
5504  pjsip_hdr *to_erase = iter;
5505  iter = iter->next;
5506  pj_list_erase(to_erase);
5507  }
5508 }
static struct header_list request_headers

◆ send_in_dialog_request()

static int send_in_dialog_request ( pjsip_tx_data *  tdata,
struct pjsip_dialog *  dlg 
)
static

Definition at line 4430 of file res_pjsip.c.

References ast_log, LOG_WARNING, and NULL.

Referenced by ast_sip_send_request().

4431 {
4432  if (pjsip_dlg_send_request(dlg, tdata, -1, NULL) != PJ_SUCCESS) {
4433  ast_log(LOG_WARNING, "Unable to send in-dialog request.\n");
4434  return -1;
4435  }
4436  return 0;
4437 }
#define LOG_WARNING
Definition: logger.h:274
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42

◆ send_request_cb()

static void send_request_cb ( void *  token,
pjsip_event *  e 
)
static

Definition at line 4822 of file res_pjsip.c.

References ao2_ref, AST_LIST_TRAVERSE, ast_log, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, send_request_data::callback, challenge(), check_request_status(), does_method_match(), send_request_data::endpoint, ast_sip_supplement::incoming_response, LOG_ERROR, ast_sip_supplement::method, ast_sip_supplement::next, and send_request_data::token.

Referenced by ast_sip_failover_request().

4823 {
4824  struct send_request_data *req_data = token;
4825  pjsip_rx_data *challenge;
4826  struct ast_sip_supplement *supplement;
4827 
4828  if (e->type == PJSIP_EVENT_TSX_STATE) {
4829  switch(e->body.tsx_state.type) {
4830  case PJSIP_EVENT_TRANSPORT_ERROR:
4831  case PJSIP_EVENT_TIMER:
4832  /*
4833  * Check the request status on transport error or timeout. A transport
4834  * error can occur when a TCP socket closes and that can be the result
4835  * of a 503. Also we may need to failover on a timeout (408).
4836  */
4837  if (check_request_status(req_data, e)) {
4838  return;
4839  }
4840  break;
4841  case PJSIP_EVENT_RX_MSG:
4842  challenge = e->body.tsx_state.src.rdata;
4843 
4844  /*
4845  * Call any supplements that want to know about a response
4846  * with any received data.
4847  */
4849  AST_LIST_TRAVERSE(&supplements, supplement, next) {
4850  if (supplement->incoming_response
4851  && does_method_match(&challenge->msg_info.cseq->method.name,
4852  supplement->method)) {
4853  supplement->incoming_response(req_data->endpoint, challenge);
4854  }
4855  }
4857 
4858  if (check_request_status(req_data, e)) {
4859  /*
4860  * Request with challenge response or failover sent.
4861  * Passed our req_data ref to the new request.
4862  */
4863  return;
4864  }
4865  break;
4866  default:
4867  ast_log(LOG_ERROR, "Unexpected PJSIP event %u\n", e->body.tsx_state.type);
4868  break;
4869  }
4870  }
4871 
4872  if (req_data->callback) {
4873  req_data->callback(req_data->token, e);
4874  }
4875  ao2_ref(req_data, -1);
4876 }
static int check_request_status(struct send_request_data *req_data, pjsip_event *e)
Definition: res_pjsip.c:4779
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
const char * method
Definition: res_pjsip.h:2841
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
#define ast_log
Definition: astobj2.c:42
void(* incoming_response)(struct ast_sip_endpoint *endpoint, struct pjsip_rx_data *rdata)
Called on an incoming SIP response This method is always called from a SIP servant thread...
Definition: res_pjsip.h:2877
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_sip_supplement * next
Definition: res_pjsip.h:2889
static void challenge(const char *realm, pjsip_tx_data *tdata, const pjsip_rx_data *rdata, int is_stale)
astobj2 callback for adding digest challenges to responses
#define LOG_ERROR
Definition: logger.h:285
static pj_bool_t does_method_match(const pj_str_t *message_method, const char *supplement_method)
Definition: res_pjsip.c:4439
void(* callback)(void *token, pjsip_event *e)
Definition: res_pjsip.c:4462
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
A supplement to SIP message processing.
Definition: res_pjsip.h:2839
Structure to hold information about an outbound request.
Definition: res_pjsip.c:4456
struct ast_sip_endpoint * endpoint
Definition: res_pjsip.c:4458

◆ send_request_data_alloc()

static struct send_request_data* send_request_data_alloc ( struct ast_sip_endpoint endpoint,
void *  token,
void(*)(void *token, pjsip_event *e)  callback 
)
static

Definition at line 4474 of file res_pjsip.c.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_bump, send_request_data::callback, send_request_data::endpoint, NULL, send_request_data_destroy(), and send_request_data::token.

Referenced by ast_sip_send_out_of_dialog_request().

4476 {
4477  struct send_request_data *req_data;
4478 
4479  req_data = ao2_alloc_options(sizeof(*req_data), send_request_data_destroy,
4481  if (!req_data) {
4482  return NULL;
4483  }
4484 
4485  req_data->endpoint = ao2_bump(endpoint);
4486  req_data->token = token;
4487  req_data->callback = callback;
4488 
4489  return req_data;
4490 }
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:406
#define NULL
Definition: resample.c:96
#define ao2_bump(obj)
Definition: astobj2.h:491
static void send_request_data_destroy(void *obj)
Definition: res_pjsip.c:4467
void(* callback)(void *token, pjsip_event *e)
Definition: res_pjsip.c:4462
Structure to hold information about an outbound request.
Definition: res_pjsip.c:4456
struct ast_sip_endpoint * endpoint
Definition: res_pjsip.c:4458

◆ send_request_data_destroy()

static void send_request_data_destroy ( void *  obj)
static

Definition at line 4467 of file res_pjsip.c.

References ao2_cleanup, and send_request_data::endpoint.

Referenced by send_request_data_alloc().

4468 {
4469  struct send_request_data *req_data = obj;
4470 
4471  ao2_cleanup(req_data->endpoint);
4472 }
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Structure to hold information about an outbound request.
Definition: res_pjsip.c:4456
struct ast_sip_endpoint * endpoint
Definition: res_pjsip.c:4458

◆ send_request_timer_callback()

static void send_request_timer_callback ( pj_timer_heap_t *  theap,
pj_timer_entry *  entry 
)
static

Definition at line 4588 of file res_pjsip.c.

References ao2_lock, ao2_ref, ao2_unlock, ast_debug, send_request_wrapper::callback, send_request_wrapper::cb_called, send_request_wrapper::tdata, send_request_wrapper::timeout, TIMEOUT_TIMER2, TIMER_INACTIVE, and send_request_wrapper::token.

Referenced by endpt_send_request().

4589 {
4590  struct send_request_wrapper *req_wrapper = entry->user_data;
4591  unsigned int cb_called;
4592 
4593  ast_debug(2, "%p: Internal tsx timer expired after %d msec\n",
4594  req_wrapper, req_wrapper->timeout);
4595 
4596  ao2_lock(req_wrapper);
4597  /*
4598  * If the id is not TIMEOUT_TIMER2 then the timer was cancelled
4599  * before we got the lock or it was already handled so just clean up.
4600  */
4601  if (entry->id != TIMEOUT_TIMER2) {
4602  ao2_unlock(req_wrapper);
4603  ast_debug(3, "%p: Timeout already handled\n", req_wrapper);
4604  ao2_ref(req_wrapper, -1);
4605  return;
4606  }
4607  entry->id = TIMER_INACTIVE;
4608 
4609  ast_debug(3, "%p: Timer handled here\n", req_wrapper);
4610 
4611  cb_called = req_wrapper->cb_called;
4612  req_wrapper->cb_called = 1;
4613  ao2_unlock(req_wrapper);
4614 
4615  if (!cb_called && req_wrapper->callback) {
4616  pjsip_event event;
4617 
4618  PJSIP_EVENT_INIT_TX_MSG(event, req_wrapper->tdata);
4619  event.body.tsx_state.type = PJSIP_EVENT_TIMER;
4620 
4621  req_wrapper->callback(req_wrapper->token, &event);
4622  ast_debug(2, "%p: Callbacks executed\n", req_wrapper);
4623  }
4624 
4625  ao2_ref(req_wrapper, -1);
4626 }
void(* callback)(void *token, pjsip_event *e)
Definition: res_pjsip.c:4496
pj_int32_t timeout
Definition: res_pjsip.c:4504
Definition: astman.c:222
#define ao2_unlock(a)
Definition: astobj2.h:730
#define TIMEOUT_TIMER2
Definition: res_pjsip.c:4453
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
unsigned int cb_called
Definition: res_pjsip.c:4498
#define TIMER_INACTIVE
Definition: res_pjsip.c:4452
pjsip_tx_data * tdata
Definition: res_pjsip.c:4506
Definition: search.h:40

◆ send_request_wrapper_destructor()

static void send_request_wrapper_destructor ( void *  obj)
static

Definition at line 4628 of file res_pjsip.c.

References ast_debug, and send_request_wrapper::tdata.

Referenced by endpt_send_request().

4629 {
4630  struct send_request_wrapper *req_wrapper = obj;
4631 
4632  pjsip_tx_data_dec_ref(req_wrapper->tdata);
4633  ast_debug(2, "%p: wrapper destroyed\n", req_wrapper);
4634 }
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
pjsip_tx_data * tdata
Definition: res_pjsip.c:4506

◆ sip_dialog_create_from()

static int sip_dialog_create_from ( pj_pool_t *  pool,
pj_str_t *  from,
const char *  user,
const char *  domain,
const pj_str_t *  target,
pjsip_tpselector *  selector 
)
static

Definition at line 3709 of file res_pjsip.c.

References ast_sip_get_default_from_user(), ast_sip_get_pjsip_endpoint(), ast_strlen_zero, tmp(), and type.

Referenced by ast_sip_create_dialog_uac(), and create_out_of_dialog_request().

3711 {
3712  pj_str_t tmp, local_addr;
3713  pjsip_uri *uri;
3714  pjsip_sip_uri *sip_uri;
3715  pjsip_transport_type_e type;
3716  int local_port;
3717  char default_user[PJSIP_MAX_URL_SIZE];
3718 
3719  if (ast_strlen_zero(user)) {
3720  ast_sip_get_default_from_user(default_user, sizeof(default_user));
3721  user = default_user;
3722  }
3723 
3724  /* Parse the provided target URI so we can determine what transport it will end up using */
3725  pj_strdup_with_null(pool, &tmp, target);
3726 
3727  if (!(uri = pjsip_parse_uri(pool, tmp.ptr, tmp.slen, 0)) ||
3728  (!PJSIP_URI_SCHEME_IS_SIP(uri) && !PJSIP_URI_SCHEME_IS_SIPS(uri))) {
3729  return -1;
3730  }
3731 
3732  sip_uri = pjsip_uri_get_uri(uri);
3733 
3734  /* Determine the transport type to use */
3735  type = pjsip_transport_get_type_from_name(&sip_uri->transport_param);
3736  if (PJSIP_URI_SCHEME_IS_SIPS(sip_uri)) {
3737  if (type == PJSIP_TRANSPORT_UNSPECIFIED
3738  || !(pjsip_transport_get_flag_from_type(type) & PJSIP_TRANSPORT_SECURE)) {
3739  type = PJSIP_TRANSPORT_TLS;
3740  }
3741  } else if (!sip_uri->transport_param.slen) {
3742  type = PJSIP_TRANSPORT_UDP;
3743  } else if (type == PJSIP_TRANSPORT_UNSPECIFIED) {
3744  return -1;
3745  }
3746 
3747  /* If the host is IPv6 turn the transport into an IPv6 version */
3748  if (pj_strchr(&sip_uri->host, ':')) {
3749  type |= PJSIP_TRANSPORT_IPV6;
3750  }
3751 
3752  if (!ast_strlen_zero(domain)) {
3753  from->ptr = pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE);
3754  from->slen = pj_ansi_snprintf(from->ptr, PJSIP_MAX_URL_SIZE,
3755  "<sip:%s@%s%s%s>",
3756  user,
3757  domain,
3758  (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? ";transport=" : "",
3759  (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? pjsip_transport_get_type_name(type) : "");
3760  return 0;
3761  }
3762 
3763  /* Get the local bound address for the transport that will be used when communicating with the provided URI */
3764  if (pjsip_tpmgr_find_local_addr(pjsip_endpt_get_tpmgr(ast_sip_get_pjsip_endpoint()), pool, type, selector,
3765  &local_addr, &local_port) != PJ_SUCCESS) {
3766 
3767  /* If no local address can be retrieved using the transport manager use the host one */
3768  pj_strdup(pool, &local_addr, pj_gethostname());
3769  local_port = pjsip_transport_get_default_port_for_type(PJSIP_TRANSPORT_UDP);
3770  }
3771 
3772  /* If IPv6 was specified in the transport, set the proper type */
3773  if (pj_strchr(&local_addr, ':')) {
3774  type |= PJSIP_TRANSPORT_IPV6;
3775  }
3776 
3777  from->ptr = pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE);
3778  from->slen = pj_ansi_snprintf(from->ptr, PJSIP_MAX_URL_SIZE,
3779  "<sip:%s@%s%.*s%s:%d%s%s>",
3780  user,
3781  (type & PJSIP_TRANSPORT_IPV6) ? "[" : "",
3782  (int)local_addr.slen,
3783  local_addr.ptr,
3784  (type & PJSIP_TRANSPORT_IPV6) ? "]" : "",
3785  local_port,
3786  (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? ";transport=" : "",
3787  (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? pjsip_transport_get_type_name(type) : "");
3788 
3789  return 0;
3790 }
static const char type[]
Definition: chan_ooh323.c:109
static int tmp()
Definition: bt_open.c:389
Domain data structure.
Definition: sip.h:888
void ast_sip_get_default_from_user(char *from_user, size_t size)
Retrieve the global default from user.
#define ast_strlen_zero(a)
Definition: muted.c:73
structure to hold users read from users.conf
pjsip_endpoint * ast_sip_get_pjsip_endpoint(void)
Get a pointer to the PJSIP endpoint.
Definition: res_pjsip.c:3614

◆ sip_thread_start()

static void sip_thread_start ( void  )
static

Definition at line 5181 of file res_pjsip.c.

References ast_log, ast_threadstorage_get(), desc, LOG_ERROR, pj_thread_storage, servant_id_storage, SIP_SERVANT_ID, and thread.

Referenced by load_module().

5182 {
5183  pj_thread_desc *desc;
5184  pj_thread_t *thread;
5185  uint32_t *servant_id;
5186 
5187  servant_id = ast_threadstorage_get(&servant_id_storage, sizeof(*servant_id));
5188  if (!servant_id) {
5189  ast_log(LOG_ERROR, "Could not set SIP servant ID in thread-local storage.\n");
5190  return;
5191  }
5192  *servant_id = SIP_SERVANT_ID;
5193 
5194  desc = ast_threadstorage_get(&pj_thread_storage, sizeof(pj_thread_desc));
5195  if (!desc) {
5196  ast_log(LOG_ERROR, "Could not get thread desc from thread-local storage. Expect awful things to occur\n");
5197  return;
5198  }
5199  pj_bzero(*desc, sizeof(*desc));
5200 
5201  if (pj_thread_register("Asterisk Thread", *desc, &thread) != PJ_SUCCESS) {
5202  ast_log(LOG_ERROR, "Couldn't register thread with PJLIB.\n");
5203  }
5204 }
pthread_t thread
Definition: app_meetme.c:1089
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
static struct ast_threadstorage pj_thread_storage
Definition: res_pjsip.c:5177
static const char desc[]
Definition: cdr_mysql.c:73
#define ast_log
Definition: astobj2.c:42
#define SIP_SERVANT_ID
Definition: res_pjsip.c:5179
#define LOG_ERROR
Definition: logger.h:285
static struct ast_threadstorage servant_id_storage
Definition: res_pjsip.c:5178

◆ stop_monitor_thread()

static void stop_monitor_thread ( void  )
static

Definition at line 5171 of file res_pjsip.c.

Referenced by unload_pjsip().

5172 {
5173  monitor_continue = 0;
5174  pj_thread_join(monitor_thread);
5175 }
pj_thread_t * monitor_thread
Definition: res_pjsip.c:5159
static int monitor_continue
Definition: res_pjsip.c:5160

◆ supplement_on_rx_request()

static pj_bool_t supplement_on_rx_request ( pjsip_rx_data *  rdata)
static

Definition at line 5246 of file res_pjsip.c.

References ao2_cleanup, AST_LIST_TRAVERSE, ast_pjsip_rdata_get_endpoint(), AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, does_method_match(), ast_sip_supplement::incoming_request, ast_sip_supplement::method, and ast_sip_supplement::next.

Referenced by create_in_dialog_request().

5247 {
5248  struct ast_sip_supplement *supplement;
5249 
5250  if (pjsip_rdata_get_dlg(rdata)) {
5251  return PJ_FALSE;
5252  }
5253 
5255  AST_LIST_TRAVERSE(&supplements, supplement, next) {
5256  if (supplement->incoming_request
5257  && does_method_match(&rdata->msg_info.msg->line.req.method.name, supplement->method)) {
5258  struct ast_sip_endpoint *endpoint;
5259 
5260  endpoint = ast_pjsip_rdata_get_endpoint(rdata);
5261  supplement->incoming_request(endpoint, rdata);
5262  ao2_cleanup(endpoint);
5263  }
5264  }
5266 
5267  return PJ_FALSE;
5268 }
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
const char * method
Definition: res_pjsip.h:2841
struct ast_sip_endpoint * ast_pjsip_rdata_get_endpoint(pjsip_rx_data *rdata)
Get the looked-up endpoint on an out-of dialog request or response.
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
struct ast_sip_supplement * next
Definition: res_pjsip.h:2889
An entity with which Asterisk communicates.
Definition: res_pjsip.h:812
static pj_bool_t does_method_match(const pj_str_t *message_method, const char *supplement_method)
Definition: res_pjsip.c:4439
int(* incoming_request)(struct ast_sip_endpoint *endpoint, struct pjsip_rx_data *rdata)
Called on incoming SIP request This method can indicate a failure in processing in its return...
Definition: res_pjsip.h:2861
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
A supplement to SIP message processing.
Definition: res_pjsip.h:2839

◆ supplement_outgoing_response()

static void supplement_outgoing_response ( pjsip_tx_data *  tdata,
struct ast_sip_endpoint sip_endpoint 
)
static

Definition at line 5270 of file res_pjsip.c.

References ao2_cleanup, AST_LIST_TRAVERSE, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, ast_sip_message_apply_transport(), ast_sip_mod_data_get, ast_sip_mod_data_set, does_method_match(), ast_sip_supplement::method, MOD_DATA_CONTACT, NULL, ast_sip_supplement::outgoing_response, supplement_module, and ast_sip_endpoint::transport.

Referenced by ast_sip_send_response(), and ast_sip_send_stateful_response().

5271 {
5272  struct ast_sip_supplement *supplement;
5273  pjsip_cseq_hdr *cseq = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CSEQ, NULL);
5275 
5276  if (sip_endpoint) {
5277  ast_sip_message_apply_transport(sip_endpoint->transport, tdata);
5278  }
5279 
5281  AST_LIST_TRAVERSE(&supplements, supplement, next) {
5282  if (supplement->outgoing_response && does_method_match(&cseq->method.name, supplement->method)) {
5283  supplement->outgoing_response(sip_endpoint, contact, tdata);
5284  }
5285  }
5287 
5288  ast_sip_mod_data_set(tdata->pool, tdata->mod_data, supplement_module.id, MOD_DATA_CONTACT, NULL);
5289  ao2_cleanup(contact);
5290 }
void(* outgoing_response)(struct ast_sip_endpoint *endpoint, struct ast_sip_contact *contact, struct pjsip_tx_data *tdata)
Called on an outgoing SIP response This method is always called from a SIP servant thread...
Definition: res_pjsip.h:2887
const ast_string_field transport
Definition: res_pjsip.h:817
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
const char * method
Definition: res_pjsip.h:2841
#define NULL
Definition: resample.c:96
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
static pjsip_module supplement_module
Definition: res_pjsip.c:4258
#define ast_sip_mod_data_set(pool, mod_data, id, key, val)
Utilizing a mod_data array for a given id, set the value associated with the given key...
Definition: res_pjsip.h:2621
#define ast_sip_mod_data_get(mod_data, id, key)
Using the dictionary stored in mod_data array at a given id, retrieve the value associated with the g...
Definition: res_pjsip.h:2589
static pj_bool_t does_method_match(const pj_str_t *message_method, const char *supplement_method)
Definition: res_pjsip.c:4439
Contact associated with an address of record.
Definition: res_pjsip.h:281
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
void ast_sip_message_apply_transport(const char *transport_name, pjsip_tx_data *tdata)
Apply the configuration for a transport to an outgoing message.
#define MOD_DATA_CONTACT
Definition: res_pjsip.c:3178
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
A supplement to SIP message processing.
Definition: res_pjsip.h:2839

◆ sync_task()

static int sync_task ( void *  data)
static

Definition at line 5041 of file res_pjsip.c.

References ast_cond_signal, ast_mutex_lock, ast_mutex_unlock, sync_task_data::complete, sync_task_data::cond, sync_task_data::fail, sync_task_data::lock, sync_task_data::task, and sync_task_data::task_data.

Referenced by ast_sip_push_task_wait().

5042 {
5043  struct sync_task_data *std = data;
5044  int ret;
5045 
5046  std->fail = std->task(std->task_data);
5047 
5048  /*
5049  * Once we unlock std->lock after signaling, we cannot access
5050  * std again. The thread waiting within ast_sip_push_task_wait()
5051  * is free to continue and release its local variable (std).
5052  */
5053  ast_mutex_lock(&std->lock);
5054  std->complete = 1;
5055  ast_cond_signal(&std->cond);
5056  ret = std->fail;
5057  ast_mutex_unlock(&std->lock);
5058  return ret;
5059 }
#define ast_mutex_lock(a)
Definition: lock.h:187
#define ast_cond_signal(cond)
Definition: lock.h:201
ast_cond_t cond
Definition: stasis.c:1277
ast_mutex_t lock
Definition: stasis.c:1276
int(* task)(void *)
Definition: res_pjsip.c:5037
void * task_data
Definition: stasis.c:1279
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ uas_use_sips_contact()

static int uas_use_sips_contact ( pjsip_rx_data *  rdata)
static

Determine if a SIPS Contact header is required.

This uses the guideline provided in RFC 3261 Section 12.1.1 to determine if the Contact header must be a sips: URI.

Parameters
rdataThe incoming dialog-starting request
Return values
0SIPS not required
1SIPS required

Definition at line 4033 of file res_pjsip.c.

References ast_assert, and NULL.

Referenced by create_dialog_uas().

4034 {
4035  pjsip_rr_hdr *record_route;
4036 
4037  if (PJSIP_URI_SCHEME_IS_SIPS(rdata->msg_info.msg->line.req.uri)) {
4038  return 1;
4039  }
4040 
4041  record_route = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_RECORD_ROUTE, NULL);
4042  if (record_route) {
4043  if (PJSIP_URI_SCHEME_IS_SIPS(&record_route->name_addr)) {
4044  return 1;
4045  }
4046  } else {
4047  pjsip_contact_hdr *contact;
4048 
4049  contact = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, NULL);
4050  ast_assert(contact != NULL);
4051  if (PJSIP_URI_SCHEME_IS_SIPS(contact->uri)) {
4052  return 1;
4053  }
4054  }
4055 
4056  return 0;
4057 }
#define ast_assert(a)
Definition: utils.h:650
#define NULL
Definition: resample.c:96

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 5822 of file res_pjsip.c.

References ARRAY_LEN, ast_cli_unregister_multiple(), AST_MODFLAG_GLOBAL_SYMBOLS, AST_MODFLAG_LOAD_ORDER, AST_MODPRI_CHANNEL_DEPEND, AST_MODULE_INFO(), AST_MODULE_SUPPORT_CORE, ast_serializer_pool_destroy(), ast_sip_destroy_scheduler(), ast_sip_push_task_wait_servant(), AST_TEST_UNREGISTER, ast_threadpool_shutdown(), ASTERISK_GPL_KEY, load_module(), NULL, reload(), reload_module(), and unload_pjsip().

5823 {
5824  AST_TEST_UNREGISTER(xml_sanitization_end_null);
5825  AST_TEST_UNREGISTER(xml_sanitization_exceeds_buffer);
5827 
5828  /* The thread this is called from cannot call PJSIP/PJLIB functions,
5829  * so we have to push the work to the threadpool to handle
5830  */
5835 
5836  return 0;
5837 }
static struct ast_cli_entry cli_commands[]
Definition: res_pjsip.c:3567
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
int ast_serializer_pool_destroy(struct ast_serializer_pool *pool)
Destroy the serializer pool.
Definition: serializer.c:39
static struct ast_threadpool * sip_threadpool
Definition: res_pjsip.c:3188
int ast_sip_destroy_scheduler(void)
#define NULL
Definition: resample.c:96
int ast_sip_push_task_wait_servant(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Push a task to SIP servants and wait for it to complete.
Definition: res_pjsip.c:5089
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128
static struct ast_serializer_pool * sip_serializer_pool
Definition: res_pjsip.c:3184
void ast_threadpool_shutdown(struct ast_threadpool *pool)
Shut down a threadpool and destroy it.
Definition: threadpool.c:965
static int unload_pjsip(void *data)
Definition: res_pjsip.c:5585

◆ unload_pjsip()

static int unload_pjsip ( void *  data)
static

Definition at line 5585 of file res_pjsip.c.

References ast_pjproject_caching_pool_destroy(), ast_pjsip_endpoint, ast_res_pjsip_cleanup_message_filter(), ast_res_pjsip_cleanup_options_handling(), ast_res_pjsip_destroy_configuration(), ast_sip_destroy_distributor(), ast_sip_destroy_global_headers(), ast_sip_destroy_system(), ast_sip_destroy_transport_events(), ast_sip_destroy_transport_management(), ast_sip_unregister_service(), memory_pool, NULL, stop_monitor_thread(), and supplement_module.

Referenced by load_module(), and unload_module().

5586 {
5587  /*
5588  * These calls need the pjsip endpoint and serializer to clean up.
5589  * If they're not set, then there's nothing to clean up anyway.
5590  */
5601  }
5602 
5603  if (monitor_thread) {
5605  monitor_thread = NULL;
5606  }
5607 
5608  if (memory_pool) {
5609  /* This mimics the behavior of pj_pool_safe_release
5610  * which was introduced in pjproject 2.6.
5611  */
5612  pj_pool_t *temp_pool = memory_pool;
5613 
5614  memory_pool = NULL;
5615  pj_pool_release(temp_pool);
5616  }
5617 
5619 
5620  if (caching_pool.lock) {
5622  }
5623 
5624  pj_shutdown();
5625 
5626  return 0;
5627 }
void ast_pjproject_caching_pool_destroy(pj_caching_pool *cp)
Destroy caching pool factory and all cached pools.
void ast_sip_destroy_global_headers(void)
pj_thread_t * monitor_thread
Definition: res_pjsip.c:5159
pj_caching_pool caching_pool
Definition: res_pjsip.c:5157
#define NULL
Definition: resample.c:96
void ast_res_pjsip_cleanup_options_handling(void)
void ast_sip_destroy_transport_events(void)
void ast_sip_unregister_service(pjsip_module *module)
Definition: res_pjsip.c:3233
void ast_sip_destroy_transport_management(void)
static pjsip_module supplement_module
Definition: res_pjsip.c:4258
static pjsip_endpoint * ast_pjsip_endpoint
Definition: res_pjsip.c:3186
static struct ast_serializer_pool * sip_serializer_pool
Definition: res_pjsip.c:3184
pj_pool_t * memory_pool
Definition: res_pjsip.c:5158
void ast_res_pjsip_destroy_configuration(void)
void ast_res_pjsip_cleanup_message_filter(void)
void ast_sip_destroy_system(void)
static void stop_monitor_thread(void)
Definition: res_pjsip.c:5171
void ast_sip_destroy_distributor(void)

◆ unregister_service()

static int unregister_service ( void *  data)
static

Definition at line 3222 of file res_pjsip.c.

References ast_debug, and ast_pjsip_endpoint.

Referenced by ast_sip_unregister_service().

3223 {
3224  pjsip_module **module = data;
3225  if (!ast_pjsip_endpoint) {
3226  return -1;
3227  }
3228  pjsip_endpt_unregister_module(ast_pjsip_endpoint, *module);
3229  ast_debug(1, "Unregistered SIP service %.*s\n", (int) pj_strlen(&(*module)->name), pj_strbuf(&(*module)->name));
3230  return 0;
3231 }
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
static pjsip_endpoint * ast_pjsip_endpoint
Definition: res_pjsip.c:3186

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "Basic SIP resource" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must