Asterisk - The Open Source Telephony Project GIT-master-25686a5
Data Structures | Macros | Typedefs | Enumerations | Functions
res_pjsip_session.h File Reference
#include <pjlib.h>
#include "asterisk/linkedlists.h"
#include "asterisk/channel.h"
#include "asterisk/netsock2.h"
#include "asterisk/sdp_srtp.h"
#include "asterisk/codec.h"
#include <pjsip_ua.h>
#include "asterisk/res_pjsip.h"
Include dependency graph for res_pjsip_session.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ast_sip_channel_pvt
 A structure which contains a channel implementation and session. More...
 
struct  ast_sip_session
 A structure describing a SIP session. More...
 
struct  ast_sip_session_media
 A structure containing SIP session media information. More...
 
struct  ast_sip_session_media_read_callback_state
 Structure which contains read callback information. More...
 
struct  ast_sip_session_media_state
 Structure which contains media state information (streams, sessions) More...
 
struct  ast_sip_session_sdp_handler
 A handler for SDPs in SIP sessions. More...
 
struct  ast_sip_session_supplement
 A supplement to SIP message processing. More...
 

Macros

#define ast_sip_session_register_supplement(supplement)    ast_sip_session_register_supplement_with_module(AST_MODULE_SELF, supplement)
 

Typedefs

typedef struct ast_frame *(* ast_sip_session_media_read_cb) (struct ast_sip_session *session, struct ast_sip_session_media *session_media)
 
typedef int(* ast_sip_session_media_write_cb) (struct ast_sip_session *session, struct ast_sip_session_media *session_media, struct ast_frame *frame)
 
typedef int(* ast_sip_session_request_creation_cb) (struct ast_sip_session *session, pjsip_tx_data *tdata)
 
typedef int(* ast_sip_session_response_cb) (struct ast_sip_session *session, pjsip_rx_data *rdata)
 
typedef int(* ast_sip_session_sdp_creation_cb) (struct ast_sip_session *session, pjmedia_sdp_session *sdp)
 

Enumerations

enum  ast_sip_session_call_direction { AST_SIP_SESSION_INCOMING_CALL = 0 , AST_SIP_SESSION_OUTGOING_CALL }
 Indicates the call direction respective to Asterisk. More...
 
enum  ast_sip_session_response_priority { AST_SIP_SESSION_BEFORE_REDIRECTING = (1 << 0) , AST_SIP_SESSION_BEFORE_MEDIA = (1 << 1) , AST_SIP_SESSION_AFTER_MEDIA = (1 << 2) }
 Describes when a supplement should be called into on incoming responses. More...
 
enum  ast_sip_session_sdp_stream_defer { AST_SIP_SESSION_SDP_DEFER_NOT_HANDLED , AST_SIP_SESSION_SDP_DEFER_ERROR , AST_SIP_SESSION_SDP_DEFER_NOT_NEEDED , AST_SIP_SESSION_SDP_DEFER_NEEDED }
 
enum  ast_sip_session_t38state {
  T38_DISABLED = 0 , T38_LOCAL_REINVITE , T38_PEER_REINVITE , T38_ENABLED ,
  T38_REJECTED , T38_MAX_ENUM
}
 T.38 states for a session. More...
 

Functions

int ast_sip_can_present_connected_id (const struct ast_sip_session *session, const struct ast_party_id *id)
 Determines if the Connected Line info can be presented for this session. More...
 
struct ast_sip_channel_pvtast_sip_channel_pvt_alloc (void *pvt, struct ast_sip_session *session)
 Allocate a new SIP channel pvt structure. More...
 
struct ast_sip_sessionast_sip_dialog_get_session (pjsip_dialog *dlg)
 Retrieves a session from a dialog. More...
 
int ast_sip_session_add_datastore (struct ast_sip_session *session, struct ast_datastore *datastore)
 Add a datastore to a SIP session. More...
 
int ast_sip_session_add_reason_header (struct ast_sip_session *session, const char *protocol, int code, const char *text)
 Adds a Reason header in the next reponse to an incoming INVITE. More...
 
int ast_sip_session_add_supplements (struct ast_sip_session *session)
 Add supplements to a SIP session. More...
 
struct ast_sip_sessionast_sip_session_alloc (struct ast_sip_endpoint *endpoint, struct ast_sip_contact *contact, pjsip_inv_session *inv, pjsip_rx_data *rdata)
 Allocate a new SIP session. More...
 
struct ast_datastoreast_sip_session_alloc_datastore (const struct ast_datastore_info *info, const char *uid)
 Alternative for ast_datastore_alloc() More...
 
int ast_sip_session_create_invite (struct ast_sip_session *session, pjsip_tx_data **tdata)
 Creates an INVITE request. More...
 
struct ast_sip_sessionast_sip_session_create_outgoing (struct ast_sip_endpoint *endpoint, struct ast_sip_contact *contact, const char *location, const char *request_user, struct ast_stream_topology *req_topology)
 Create a new outgoing SIP session. More...
 
int ast_sip_session_defer_termination (struct ast_sip_session *session)
 Defer local termination of a session until remote side terminates, or an amount of time passes. More...
 
void ast_sip_session_defer_termination_cancel (struct ast_sip_session *session)
 Cancel a pending deferred termination. More...
 
void ast_sip_session_end_if_deferred (struct ast_sip_session *session)
 End the session if it had been previously deferred. More...
 
struct ast_datastoreast_sip_session_get_datastore (struct ast_sip_session *session, const char *name)
 Retrieve a session datastore. More...
 
pjsip_dialog * ast_sip_session_get_dialog (const struct ast_sip_session *session)
 Retrieves a dialog from a session. More...
 
const char * ast_sip_session_get_name (const struct ast_sip_session *session)
 Get the channel or endpoint name associated with the session. More...
 
pjsip_inv_state ast_sip_session_get_pjsip_inv_state (const struct ast_sip_session *session)
 Retrieves the pjsip_inv_state from a session. More...
 
int ast_sip_session_is_pending_stream_default (const struct ast_sip_session *session, const struct ast_stream *stream)
 Determines if a provided pending stream will be the default stream or not. More...
 
int ast_sip_session_media_add_read_callback (struct ast_sip_session *session, struct ast_sip_session_media *session_media, int fd, ast_sip_session_media_read_cb callback)
 Set a read callback for a media session with a specific file descriptor. More...
 
struct ast_sip_session_mediaast_sip_session_media_get_transport (struct ast_sip_session *session, struct ast_sip_session_media *session_media)
 Retrieve the underlying media session that is acting as transport for a media session. More...
 
int ast_sip_session_media_set_write_callback (struct ast_sip_session *session, struct ast_sip_session_media *session_media, ast_sip_session_media_write_cb callback)
 Set a write callback for a media session. More...
 
struct ast_sip_session_mediaast_sip_session_media_state_add (struct ast_sip_session *session, struct ast_sip_session_media_state *media_state, enum ast_media_type type, int position)
 Allocate an ast_session_media and add it to the media state's vector. More...
 
struct ast_sip_session_media_stateast_sip_session_media_state_alloc (void)
 Allocate a session media state structure. More...
 
struct ast_sip_session_media_stateast_sip_session_media_state_clone (const struct ast_sip_session_media_state *media_state)
 Clone a media state. More...
 
void ast_sip_session_media_state_free (struct ast_sip_session_media_state *media_state)
 Free a session media state structure. More...
 
void ast_sip_session_media_state_reset (struct ast_sip_session_media_state *media_state)
 Reset a media state to a clean state. More...
 
void ast_sip_session_media_stats_save (struct ast_sip_session *sip_session, struct ast_sip_session_media_state *media_state)
 Save a media stats. More...
 
int ast_sip_session_refresh (struct ast_sip_session *session, ast_sip_session_request_creation_cb on_request_creation, ast_sip_session_sdp_creation_cb on_sdp_creation, ast_sip_session_response_cb on_response, enum ast_sip_session_refresh_method method, int generate_new_sdp, struct ast_sip_session_media_state *media_state)
 Send a reinvite or UPDATE on a session. More...
 
int ast_sip_session_regenerate_answer (struct ast_sip_session *session, ast_sip_session_sdp_creation_cb on_sdp_creation)
 Regenerate SDP Answer. More...
 
int ast_sip_session_register_sdp_handler (struct ast_sip_session_sdp_handler *handler, const char *stream_type)
 Register an SDP handler. More...
 
void ast_sip_session_register_supplement_with_module (struct ast_module *module, struct ast_sip_session_supplement *supplement)
 Register a supplement to SIP session processing. More...
 
void ast_sip_session_remove_datastore (struct ast_sip_session *session, const char *name)
 Remove a session datastore from the session. More...
 
void ast_sip_session_remove_supplements (struct ast_sip_session *session)
 Remove supplements from a SIP session. More...
 
void ast_sip_session_resume_reinvite (struct ast_sip_session *session)
 Resumes processing of a deferred incoming re-invite. More...
 
void ast_sip_session_send_request (struct ast_sip_session *session, pjsip_tx_data *tdata)
 Send a SIP request. More...
 
void ast_sip_session_send_request_with_cb (struct ast_sip_session *session, pjsip_tx_data *tdata, ast_sip_session_response_cb on_response)
 Send a SIP request and get called back when a response is received. More...
 
void ast_sip_session_send_response (struct ast_sip_session *session, pjsip_tx_data *tdata)
 Send a SIP response. More...
 
void ast_sip_session_suspend (struct ast_sip_session *session)
 Request and wait for the session serializer to be suspended. More...
 
void ast_sip_session_terminate (struct ast_sip_session *session, int response)
 Terminate a session and, if possible, send the provided response code. More...
 
void ast_sip_session_unregister_sdp_handler (struct ast_sip_session_sdp_handler *handler, const char *stream_type)
 Unregister an SDP handler. More...
 
void ast_sip_session_unregister_supplement (struct ast_sip_session_supplement *supplement)
 Unregister a an supplement to SIP session processing. More...
 
void ast_sip_session_unsuspend (struct ast_sip_session *session)
 Request the session serializer be unsuspended. More...
 

Macro Definition Documentation

◆ ast_sip_session_register_supplement

#define ast_sip_session_register_supplement (   supplement)     ast_sip_session_register_supplement_with_module(AST_MODULE_SELF, supplement)

Definition at line 616 of file res_pjsip_session.h.

Typedef Documentation

◆ ast_sip_session_media_read_cb

typedef struct ast_frame *(* ast_sip_session_media_read_cb) (struct ast_sip_session *session, struct ast_sip_session_media *session_media)

Definition at line 1 of file res_pjsip_session.h.

◆ ast_sip_session_media_write_cb

typedef int(* ast_sip_session_media_write_cb) (struct ast_sip_session *session, struct ast_sip_session_media *session_media, struct ast_frame *frame)

Definition at line 71 of file res_pjsip_session.h.

◆ ast_sip_session_request_creation_cb

typedef int(* ast_sip_session_request_creation_cb) (struct ast_sip_session *session, pjsip_tx_data *tdata)

Definition at line 250 of file res_pjsip_session.h.

◆ ast_sip_session_response_cb

typedef int(* ast_sip_session_response_cb) (struct ast_sip_session *session, pjsip_rx_data *rdata)

Definition at line 251 of file res_pjsip_session.h.

◆ ast_sip_session_sdp_creation_cb

typedef int(* ast_sip_session_sdp_creation_cb) (struct ast_sip_session *session, pjmedia_sdp_session *sdp)

Definition at line 252 of file res_pjsip_session.h.

Enumeration Type Documentation

◆ ast_sip_session_call_direction

Indicates the call direction respective to Asterisk.

Enumerator
AST_SIP_SESSION_INCOMING_CALL 
AST_SIP_SESSION_OUTGOING_CALL 

Definition at line 168 of file res_pjsip_session.h.

168 {
171};
@ AST_SIP_SESSION_OUTGOING_CALL
@ AST_SIP_SESSION_INCOMING_CALL

◆ ast_sip_session_response_priority

Describes when a supplement should be called into on incoming responses.

In most cases, session supplements will not need to worry about this because in most cases, the correct value will be automatically applied. However, there are rare circumstances when a supplement will want to specify when it should be called.

The values below are listed in chronological order.

Enumerator
AST_SIP_SESSION_BEFORE_REDIRECTING 

When processing 3XX responses, the supplement is called into before the redirecting information is processed.

AST_SIP_SESSION_BEFORE_MEDIA 

For responses to INVITE transactions, the supplement is called into before media is negotiated.

This priority is applied by default to any session supplement that does not specify a response priority.

AST_SIP_SESSION_AFTER_MEDIA 

For INVITE transactions, the supplement is called into after media is negotiated.

Definition at line 263 of file res_pjsip_session.h.

263 {
264 /*!
265 * When processing 3XX responses, the supplement is called into before
266 * the redirecting information is processed.
267 */
269 /*!
270 * For responses to INVITE transactions, the supplement is called into
271 * before media is negotiated.
272 *
273 * This priority is applied by default to any session supplement that
274 * does not specify a response priority.
275 */
277 /*!
278 * For INVITE transactions, the supplement is called into after media
279 * is negotiated.
280 */
282};
@ AST_SIP_SESSION_BEFORE_REDIRECTING
@ AST_SIP_SESSION_AFTER_MEDIA
@ AST_SIP_SESSION_BEFORE_MEDIA

◆ ast_sip_session_sdp_stream_defer

Enumerator
AST_SIP_SESSION_SDP_DEFER_NOT_HANDLED 

The stream was not handled by this handler. If there are other registered handlers for this stream type, they will be called.

AST_SIP_SESSION_SDP_DEFER_ERROR 

There was an error encountered. No further operations will take place and the current negotiation will be abandoned.

AST_SIP_SESSION_SDP_DEFER_NOT_NEEDED 

Re-invite is not needed

AST_SIP_SESSION_SDP_DEFER_NEEDED 

Re-invite should be deferred and will be resumed later. No further operations will take place.

Definition at line 367 of file res_pjsip_session.h.

367 {
368 /*! The stream was not handled by this handler. If there are other registered handlers for this stream type, they will be called. */
370 /*! There was an error encountered. No further operations will take place and the current negotiation will be abandoned. */
372 /*! Re-invite is not needed */
374 /*! Re-invite should be deferred and will be resumed later. No further operations will take place. */
376};
@ AST_SIP_SESSION_SDP_DEFER_NEEDED
@ AST_SIP_SESSION_SDP_DEFER_NOT_HANDLED
@ AST_SIP_SESSION_SDP_DEFER_NOT_NEEDED
@ AST_SIP_SESSION_SDP_DEFER_ERROR

◆ ast_sip_session_t38state

T.38 states for a session.

Enumerator
T38_DISABLED 

Not enabled

T38_LOCAL_REINVITE 

Offered from local - REINVITE

T38_PEER_REINVITE 

Offered from peer - REINVITE

T38_ENABLED 

Negotiated (enabled)

T38_REJECTED 

Refused

T38_MAX_ENUM 

Not an actual state; used as max value in the enum

Definition at line 56 of file res_pjsip_session.h.

56 {
57 T38_DISABLED = 0, /*!< Not enabled */
58 T38_LOCAL_REINVITE, /*!< Offered from local - REINVITE */
59 T38_PEER_REINVITE, /*!< Offered from peer - REINVITE */
60 T38_ENABLED, /*!< Negotiated (enabled) */
61 T38_REJECTED, /*!< Refused */
62 T38_MAX_ENUM, /*!< Not an actual state; used as max value in the enum */
63};
@ T38_PEER_REINVITE
@ T38_LOCAL_REINVITE
@ T38_MAX_ENUM
@ T38_ENABLED
@ T38_REJECTED
@ T38_DISABLED

Function Documentation

◆ ast_sip_can_present_connected_id()

int ast_sip_can_present_connected_id ( const struct ast_sip_session session,
const struct ast_party_id id 
)

Determines if the Connected Line info can be presented for this session.

Parameters
sessionThe session
idThe Connected Line info to evaluate
Return values
1The Connected Line info can be presented
0The Connected Line info cannot be presented

Definition at line 131 of file res_pjsip_session.c.

132{
133 return id->number.valid
134 && (session->endpoint->id.trust_outbound
136}
static struct ast_mansession session
#define AST_PRES_ALLOWED
Definition: callerid.h:432
#define AST_PRES_RESTRICTION
Definition: callerid.h:431
int ast_party_id_presentation(const struct ast_party_id *id)
Determine the overall presentation value for the given party.
Definition: channel.c:1821

References ast_party_id_presentation(), AST_PRES_ALLOWED, AST_PRES_RESTRICTION, and session.

Referenced by add_id_headers(), and stir_shaken_outgoing_request().

◆ ast_sip_channel_pvt_alloc()

struct ast_sip_channel_pvt * ast_sip_channel_pvt_alloc ( void *  pvt,
struct ast_sip_session session 
)

Allocate a new SIP channel pvt structure.

Parameters
pvtPointer to channel specific information
sessionPointer to SIP session
Return values
non-NULLsuccess
NULLfailure

Definition at line 2994 of file res_pjsip_session.c.

2995{
2996 struct ast_sip_channel_pvt *channel = ao2_alloc(sizeof(*channel), sip_channel_destroy);
2997
2998 if (!channel) {
2999 return NULL;
3000 }
3001
3002 ao2_ref(pvt, +1);
3003 channel->pvt = pvt;
3004 ao2_ref(session, +1);
3005 channel->session = session;
3006
3007 return channel;
3008}
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
static void sip_channel_destroy(void *obj)
Destructor for SIP channel.
#define NULL
Definition: resample.c:96
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
void * pvt
Pointer to channel specific implementation information, must be ao2 object.

References ao2_alloc, ao2_ref, NULL, ast_sip_channel_pvt::pvt, ast_sip_channel_pvt::session, session, and sip_channel_destroy().

Referenced by chan_pjsip_new().

◆ ast_sip_dialog_get_session()

struct ast_sip_session * ast_sip_dialog_get_session ( pjsip_dialog *  dlg)

Retrieves a session from a dialog.

Parameters
dlgThe dialog to retrieve the session from
Return values
non-NULLif session exists
NULLif no session
Note
The reference count of the session is increased when returned
This function must be called with the dialog locked

Definition at line 3648 of file res_pjsip_session.c.

3649{
3650 pjsip_inv_session *inv_session = pjsip_dlg_get_inv_session(dlg);
3651 struct ast_sip_session *session;
3652
3653 if (!inv_session ||
3654 !(session = inv_session->mod_data[session_module.id])) {
3655 return NULL;
3656 }
3657
3658 ao2_ref(session, +1);
3659
3660 return session;
3661}
static pjsip_module session_module
A structure describing a SIP session.
struct pjsip_inv_session * inv_session

References ao2_ref, ast_sip_session::inv_session, NULL, session, and session_module.

Referenced by assign_uuid(), ast_sip_session_send_response(), refer_incoming_attended_request(), refer_incoming_invite_request(), session_on_tx_response(), session_outgoing_nat_hook(), and session_reinvite_on_rx_request().

◆ ast_sip_session_add_datastore()

int ast_sip_session_add_datastore ( struct ast_sip_session session,
struct ast_datastore datastore 
)

Add a datastore to a SIP session.

Note that SIP uses reference counted datastores. The datastore passed into this function must have been allocated using ao2_alloc() or there will be serious problems.

Parameters
sessionThe session to add the datastore to
datastoreThe datastore to be added to the session
Return values
0Success
-1Failure

Definition at line 1284 of file res_pjsip_session.c.

1285{
1286 ast_assert(datastore != NULL);
1287 ast_assert(datastore->info != NULL);
1288 ast_assert(ast_strlen_zero(datastore->uid) == 0);
1289
1290 if (!ao2_link(session->datastores, datastore)) {
1291 return -1;
1292 }
1293 return 0;
1294}
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
const struct ast_datastore_info * info
Definition: datastore.h:67
const char * uid
Definition: datastore.h:65
#define ast_assert(a)
Definition: utils.h:739

References ao2_link, ast_assert, ast_strlen_zero(), ast_datastore::info, NULL, session, and ast_datastore::uid.

Referenced by add_header(), aoc_send_as_xml(), ast_sip_session_add_reason_header(), chan_pjsip_incoming_request(), chan_pjsip_session_begin(), handle_incoming_request(), incoming_request(), incoming_response(), rfc3329_incoming_response(), session_refresh_state_get_or_alloc(), and t38_state_get_or_alloc().

◆ ast_sip_session_add_reason_header()

int ast_sip_session_add_reason_header ( struct ast_sip_session session,
const char *  protocol,
int  code,
const char *  text 
)

Adds a Reason header in the next reponse to an incoming INVITE.

Parameters
sessionThe session
protocolUsually "SIP" but may be "STIR" for stir-shaken
codeSIP response code
textReason string
Return values
0the header is accepted
-1the header is rejected

Definition at line 123 of file pjsip_session_reason_header.c.

125{
126 struct return_reason_data *rr;
127 RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
128 const char *tag = ast_sip_session_get_name(session);
129 SCOPE_ENTER(4, "%s: Adding Reason header %s %d %s\n",
130 tag, S_OR(protocol,"<missing protocol>"),
131 code, S_OR(text, "<missing text>"));
132
133 if (ast_strlen_zero(protocol) || !text) {
134 SCOPE_EXIT_RTN_VALUE(-1, "%s: Missing protocol or text\n", tag);
135 }
136 rr = ast_calloc(1, sizeof(*rr));
137 if (!rr) {
138 SCOPE_EXIT_RTN_VALUE(-1, "%s: Failed to allocate datastore\n", tag);
139 }
143 rr->response_code = code;
145 datastore->data = rr;
146 if (ast_sip_session_add_datastore(session, datastore) != 0) {
148 "%s: Failed to add datastore to session\n", tag);
149 }
150
151 SCOPE_EXIT_RTN_VALUE(0, "%s: Done\n", tag);
152}
char * text
Definition: app_queue.c:1639
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
#define SCOPE_ENTER(level,...)
static struct ast_datastore_info return_reason_info
int ast_sip_session_add_datastore(struct ast_sip_session *session, struct ast_datastore *datastore)
Add a datastore to a SIP session.
struct ast_datastore * ast_sip_session_alloc_datastore(const struct ast_datastore_info *info, const char *uid)
Alternative for ast_datastore_alloc()
const char * ast_sip_session_get_name(const struct ast_sip_session *session)
Get the channel or endpoint name associated with the session.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
const char * type
Definition: datastore.h:32
Structure for a data store object.
Definition: datastore.h:64
#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:941

References ao2_cleanup, ast_calloc, ast_sip_session_add_datastore(), ast_sip_session_alloc_datastore(), ast_sip_session_get_name(), ast_strdup, ast_strlen_zero(), NULL, return_reason_data::protocol, RAII_VAR, return_reason_data::response_code, return_reason_data::response_str, return_reason_info, S_OR, SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, session, text, and ast_datastore_info::type.

Referenced by process_failure().

◆ ast_sip_session_add_supplements()

int ast_sip_session_add_supplements ( struct ast_sip_session session)

Add supplements to a SIP session.

Parameters
sessionThe session to initialize

Definition at line 90 of file pjsip_session.c.

91{
92 struct ast_sip_session_supplement *iter;
94
97
98 if (!copy) {
99 return -1;
100 }
101
102 /* referenced session created. increasing module reference. */
103 ast_module_ref(copy->module);
104
105 AST_LIST_INSERT_TAIL(&session->supplements, copy, next);
106 }
107
108 return 0;
109}
ast_mutex_t lock
Definition: app_sla.c:331
static int copy(char *infile, char *outfile)
Utility function to copy a file.
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:78
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:494
#define SCOPED_LOCK(varname, lock, lockfunc, unlockfunc)
Scoped Locks.
Definition: lock.h:583
#define ast_module_ref(mod)
Hold a reference to the module.
Definition: module.h:457
static struct ast_sip_session_supplement * supplement_dup(const struct ast_sip_session_supplement *src)
Definition: pjsip_session.c:77
A supplement to SIP message processing.
struct ast_sip_session_supplement * next

References AST_LIST_INSERT_TAIL, ast_module_ref, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, copy(), lock, ast_sip_session_supplement::next, SCOPED_LOCK, session, and supplement_dup().

Referenced by ast_sip_session_alloc().

◆ ast_sip_session_alloc()

struct ast_sip_session * ast_sip_session_alloc ( struct ast_sip_endpoint endpoint,
struct ast_sip_contact contact,
pjsip_inv_session *  inv,
pjsip_rx_data *  rdata 
)

Allocate a new SIP session.

This will take care of allocating the datastores container on the session as well as placing all registered supplements onto the session.

The endpoint that is passed in will have its reference count increased by one since the session will be keeping a reference to the endpoint. The session will relinquish this reference when the session is destroyed.

Parameters
endpointThe endpoint that this session communicates with
contactThe contact associated with this session
invThe PJSIP INVITE session data
rdataINVITE request received (NULL if for outgoing allocation)

Definition at line 3010 of file res_pjsip_session.c.

3012{
3014 struct ast_sip_session *ret_session;
3015 int dsp_features = 0;
3016
3018 if (!session) {
3019 return NULL;
3020 }
3021
3022 AST_LIST_HEAD_INIT(&session->supplements);
3023 AST_LIST_HEAD_INIT_NOLOCK(&session->delayed_requests);
3025
3027 if (!session->direct_media_cap) {
3028 return NULL;
3029 }
3032 if (!session->datastores) {
3033 return NULL;
3034 }
3035 session->active_media_state = ast_sip_session_media_state_alloc();
3036 if (!session->active_media_state) {
3037 return NULL;
3038 }
3039 session->pending_media_state = ast_sip_session_media_state_alloc();
3040 if (!session->pending_media_state) {
3041 return NULL;
3042 }
3043 if (AST_VECTOR_INIT(&session->media_stats, 1) < 0) {
3044 return NULL;
3045 }
3046
3048 dsp_features |= DSP_FEATURE_DIGIT_DETECT;
3049 }
3050 if (endpoint->faxdetect) {
3051 dsp_features |= DSP_FEATURE_FAX_DETECT;
3052 }
3053 if (dsp_features) {
3054 session->dsp = ast_dsp_new();
3055 if (!session->dsp) {
3056 return NULL;
3057 }
3058
3059 ast_dsp_set_features(session->dsp, dsp_features);
3060 }
3061
3062 session->endpoint = ao2_bump(endpoint);
3063
3064 if (rdata) {
3065 /*
3066 * We must continue using the serializer that the original
3067 * INVITE came in on for the dialog. There may be
3068 * retransmissions already enqueued in the original
3069 * serializer that can result in reentrancy and message
3070 * sequencing problems.
3071 */
3072 session->serializer = ast_sip_get_distributor_serializer(rdata);
3073 } else {
3074 char tps_name[AST_TASKPROCESSOR_MAX_NAME + 1];
3075
3076 /* Create name with seq number appended. */
3077 ast_taskprocessor_build_name(tps_name, sizeof(tps_name), "pjsip/outsess/%s",
3079
3080 session->serializer = ast_sip_create_serializer(tps_name);
3081 }
3082 if (!session->serializer) {
3083 return NULL;
3084 }
3087
3088 /* When a PJSIP INVITE session is created it is created with a reference
3089 * count of 1, with that reference being managed by the underlying state
3090 * of the INVITE session itself. When the INVITE session transitions to
3091 * a DISCONNECTED state that reference is released. This means we can not
3092 * rely on that reference to ensure the INVITE session remains for the
3093 * lifetime of our session. To ensure it does we add our own reference
3094 * and release it when our own session goes away, ensuring that the INVITE
3095 * session remains for the lifetime of session.
3096 */
3097
3098#ifdef HAVE_PJSIP_INV_SESSION_REF
3099 if (pjsip_inv_add_ref(inv_session) != PJ_SUCCESS) {
3100 ast_log(LOG_ERROR, "Can't increase the session reference counter\n");
3101 return NULL;
3102 }
3103#endif
3104
3105 pjsip_dlg_inc_session(inv_session->dlg, &session_module);
3106 inv_session->mod_data[session_module.id] = ao2_bump(session);
3107 session->contact = ao2_bump(contact);
3108 session->inv_session = inv_session;
3109
3110 session->dtmf = endpoint->dtmf;
3111 session->moh_passthrough = endpoint->moh_passthrough;
3112
3114 /* Release the ref held by session->inv_session */
3115 ao2_ref(session, -1);
3116 return NULL;
3117 }
3118
3119 session->authentication_challenge_count = 0;
3120
3121 /* Fire session begin handlers */
3123
3124 /* Avoid unnecessary ref manipulation to return a session */
3125 ret_session = session;
3126 session = NULL;
3127 return ret_session;
3128}
#define ast_log
Definition: astobj2.c:42
@ AO2_ALLOC_OPT_LOCK_MUTEX
Definition: astobj2.h:363
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
Definition: astobj2.h:1303
void ast_party_id_init(struct ast_party_id *init)
Initialize the given party id structure.
Definition: channel.c:1757
#define DSP_FEATURE_DIGIT_DETECT
Definition: dsp.h:28
#define DSP_FEATURE_FAX_DETECT
Definition: dsp.h:29
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition: dsp.c:1768
struct ast_dsp * ast_dsp_new(void)
Allocates a new dsp, assumes 8khz for internal sample rate.
Definition: dsp.c:1758
@ AST_FORMAT_CAP_FLAG_DEFAULT
Definition: format_cap.h:38
#define ast_format_cap_alloc(flags)
Allocate a new ast_format_cap structure.
Definition: format_cap.h:49
struct ast_taskprocessor * ast_sip_get_distributor_serializer(pjsip_rx_data *rdata)
Determine the distributor serializer for the SIP message.
struct ast_taskprocessor * ast_sip_create_serializer(const char *name)
Create a new serializer for SIP tasks.
Definition: res_pjsip.c:2094
void ast_sip_dialog_set_endpoint(pjsip_dialog *dlg, struct ast_sip_endpoint *endpoint)
Set an endpoint on a SIP dialog so in-dialog requests do not undergo endpoint lookup.
void ast_sip_dialog_set_serializer(pjsip_dialog *dlg, struct ast_taskprocessor *serializer)
Set a serializer on a SIP dialog so requests and responses are automatically serialized.
#define LOG_ERROR
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:681
#define AST_LIST_HEAD_INIT(head)
Initializes a list head structure.
Definition: linkedlists.h:626
@ AST_SIP_DTMF_AUTO
Definition: res_pjsip.h:554
@ AST_SIP_DTMF_INBAND
Definition: res_pjsip.h:550
static void handle_session_begin(struct ast_sip_session *session)
#define DATASTORE_BUCKETS
struct ast_sip_session_media_state * ast_sip_session_media_state_alloc(void)
Allocate a session media state structure.
static void session_destructor(void *obj)
static int datastore_cmp(void *obj, void *arg, int flags)
static int datastore_hash(const void *obj, int flags)
int ast_sip_session_add_supplements(struct ast_sip_session *session)
Add supplements to a SIP session.
Definition: pjsip_session.c:90
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2317
unsigned int moh_passthrough
Definition: res_pjsip.h:1032
enum ast_sip_dtmf_mode dtmf
Definition: res_pjsip.h:1010
unsigned int faxdetect
Definition: res_pjsip.h:1022
struct ast_sip_contact * contact
struct ast_sip_endpoint * endpoint
void ast_taskprocessor_build_name(char *buf, unsigned int size, const char *format,...)
Build a taskprocessor name with a sequence number on the end.
#define AST_TASKPROCESSOR_MAX_NAME
Suggested maximum taskprocessor name length (less null terminator).
Definition: taskprocessor.h:61
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113

References ao2_alloc, AO2_ALLOC_OPT_LOCK_MUTEX, ao2_bump, ao2_cleanup, ao2_container_alloc_hash, ao2_ref, ast_dsp_new(), ast_dsp_set_features(), ast_format_cap_alloc, AST_FORMAT_CAP_FLAG_DEFAULT, AST_LIST_HEAD_INIT, AST_LIST_HEAD_INIT_NOLOCK, ast_log, ast_party_id_init(), ast_sip_create_serializer(), ast_sip_dialog_set_endpoint(), ast_sip_dialog_set_serializer(), AST_SIP_DTMF_AUTO, AST_SIP_DTMF_INBAND, ast_sip_get_distributor_serializer(), ast_sip_session_add_supplements(), ast_sip_session_media_state_alloc(), ast_sorcery_object_get_id(), ast_taskprocessor_build_name(), AST_TASKPROCESSOR_MAX_NAME, AST_VECTOR_INIT, ast_sip_session::contact, DATASTORE_BUCKETS, datastore_cmp(), datastore_hash(), DSP_FEATURE_DIGIT_DETECT, DSP_FEATURE_FAX_DETECT, ast_sip_endpoint::dtmf, ast_sip_session::endpoint, ast_sip_endpoint::faxdetect, handle_session_begin(), ast_sip_session::inv_session, LOG_ERROR, ast_sip_endpoint::moh_passthrough, NULL, RAII_VAR, session, session_destructor(), and session_module.

Referenced by ast_sip_session_create_outgoing(), and handle_new_invite_request().

◆ ast_sip_session_alloc_datastore()

struct ast_datastore * ast_sip_session_alloc_datastore ( const struct ast_datastore_info info,
const char *  uid 
)

Alternative for ast_datastore_alloc()

There are two major differences between this and ast_datastore_alloc() 1) This allocates a refcounted object 2) This will fill in a uid if one is not provided

DO NOT call ast_datastore_free() on a datastore allocated in this way since that function will attempt to free the datastore rather than play nicely with its refcount.

Parameters
infoCallbacks for datastore
uidIdentifier for datastore
Return values
NULLFailed to allocate datastore
non-NULLNewly allocated datastore

Definition at line 1254 of file res_pjsip_session.c.

1255{
1256 RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
1257 char uuid_buf[AST_UUID_STR_LEN];
1258 const char *uid_ptr = uid;
1259
1260 if (!info) {
1261 return NULL;
1262 }
1263
1264 datastore = ao2_alloc(sizeof(*datastore), session_datastore_destroy);
1265 if (!datastore) {
1266 return NULL;
1267 }
1268
1269 datastore->info = info;
1270 if (ast_strlen_zero(uid)) {
1271 /* They didn't provide an ID so we'll provide one ourself */
1272 uid_ptr = ast_uuid_generate_str(uuid_buf, sizeof(uuid_buf));
1273 }
1274
1275 datastore->uid = ast_strdup(uid_ptr);
1276 if (!datastore->uid) {
1277 return NULL;
1278 }
1279
1280 ao2_ref(datastore, +1);
1281 return datastore;
1282}
def info(msg)
static void session_datastore_destroy(void *obj)
#define AST_UUID_STR_LEN
Definition: uuid.h:27
char * ast_uuid_generate_str(char *buf, size_t size)
Generate a UUID string.
Definition: uuid.c:141

References ao2_alloc, ao2_cleanup, ao2_ref, ast_strdup, ast_strlen_zero(), ast_uuid_generate_str(), AST_UUID_STR_LEN, sip_to_pjsip::info(), NULL, RAII_VAR, session_datastore_destroy(), and ast_datastore::uid.

Referenced by add_header(), aoc_send_as_xml(), ast_sip_session_add_reason_header(), chan_pjsip_incoming_request(), chan_pjsip_session_begin(), handle_incoming_request(), incoming_request(), incoming_response(), rfc3329_incoming_response(), session_refresh_state_get_or_alloc(), and t38_state_get_or_alloc().

◆ ast_sip_session_create_invite()

int ast_sip_session_create_invite ( struct ast_sip_session session,
pjsip_tx_data **  tdata 
)

Creates an INVITE request.

Parameters
sessionStarting session for the INVITE
tdataThe created request.

Definition at line 2867 of file res_pjsip_session.c.

2868{
2869 pjmedia_sdp_session *offer;
2871
2872 if (!(offer = create_local_sdp(session->inv_session, session, NULL, 0))) {
2873 pjsip_inv_terminate(session->inv_session, 500, PJ_FALSE);
2874 SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create offer\n");
2875 }
2876
2877 pjsip_inv_set_local_sdp(session->inv_session, offer);
2878 pjmedia_sdp_neg_set_prefer_remote_codec_order(session->inv_session->neg, PJ_FALSE);
2879#ifdef PJMEDIA_SDP_NEG_ANSWER_MULTIPLE_CODECS
2880 if (!session->endpoint->preferred_codec_only) {
2881 pjmedia_sdp_neg_set_answer_multiple_codecs(session->inv_session->neg, PJ_TRUE);
2882 }
2883#endif
2884
2885 /*
2886 * We MUST call set_from_header() before pjsip_inv_invite. If we don't, the
2887 * From in the initial INVITE will be wrong but the rest of the messages will be OK.
2888 */
2890
2891 if (pjsip_inv_invite(session->inv_session, tdata) != PJ_SUCCESS) {
2892 SCOPE_EXIT_RTN_VALUE(-1, "pjsip_inv_invite failed\n");
2893 }
2894
2896}
static void set_from_header(struct ast_sip_session *session)
static struct pjmedia_sdp_session * create_local_sdp(pjsip_inv_session *inv, struct ast_sip_session *session, const pjmedia_sdp_session *offer, const unsigned int ignore_active_stream_topology)
const char * ast_sip_session_get_name(const struct ast_sip_session *session)
Get the channel or endpoint name associated with the session.

References ast_sip_session_get_name(), create_local_sdp(), NULL, SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, session, and set_from_header().

Referenced by call().

◆ ast_sip_session_create_outgoing()

struct ast_sip_session * ast_sip_session_create_outgoing ( struct ast_sip_endpoint endpoint,
struct ast_sip_contact contact,
const char *  location,
const char *  request_user,
struct ast_stream_topology req_topology 
)

Create a new outgoing SIP session.

The endpoint that is passed in will have its reference count increased by one since the session will be keeping a reference to the endpoint. The session will relinquish this reference when the session is destroyed.

Parameters
endpointThe endpoint that this session uses for settings
contactThe contact that this session will communicate with
locationName of the location to call, be it named location or explicit URI. Overrides contact if present.
request_userOptional request user to place in the request URI if permitted
req_topologyThe requested capabilities

Definition at line 3337 of file res_pjsip_session.c.

3340{
3341 const char *uri = NULL;
3342 RAII_VAR(struct ast_sip_aor *, found_aor, NULL, ao2_cleanup);
3343 RAII_VAR(struct ast_sip_contact *, found_contact, NULL, ao2_cleanup);
3344 pjsip_timer_setting timer;
3345 pjsip_dialog *dlg;
3346 struct pjsip_inv_session *inv_session;
3348 struct ast_sip_session *ret_session;
3349 SCOPE_ENTER(1, "%s %s Topology: %s\n", ast_sorcery_object_get_id(endpoint), request_user,
3350 ast_str_tmp(256, ast_stream_topology_to_str(req_topology, &STR_TMP)));
3351
3352 /* If no location has been provided use the AOR list from the endpoint itself */
3353 if (location || !contact) {
3354 location = S_OR(location, endpoint->aors);
3355
3357 &found_aor, &found_contact);
3358 if (!found_contact || ast_strlen_zero(found_contact->uri)) {
3359 uri = location;
3360 } else {
3361 uri = found_contact->uri;
3362 }
3363 } else {
3364 uri = contact->uri;
3365 }
3366
3367 /* If we still have no URI to dial fail to create the session */
3368 if (ast_strlen_zero(uri)) {
3369 ast_log(LOG_ERROR, "Endpoint '%s': No URI available. Is endpoint registered?\n",
3371 SCOPE_EXIT_RTN_VALUE(NULL, "No URI\n");
3372 }
3373
3374 if (!(dlg = ast_sip_create_dialog_uac(endpoint, uri, request_user))) {
3375 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create dialog\n");
3376 }
3377
3378 if (setup_outbound_invite_auth(dlg)) {
3379 pjsip_dlg_terminate(dlg);
3380 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't setup auth\n");
3381 }
3382
3383 if (pjsip_inv_create_uac(dlg, NULL, endpoint->extensions.flags, &inv_session) != PJ_SUCCESS) {
3384 pjsip_dlg_terminate(dlg);
3385 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create uac\n");
3386 }
3387#if defined(HAVE_PJSIP_REPLACE_MEDIA_STREAM) || defined(PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE)
3388 inv_session->sdp_neg_flags = PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE;
3389#endif
3390
3391 pjsip_timer_setting_default(&timer);
3393 timer.sess_expires = endpoint->extensions.timer.sess_expires;
3394 pjsip_timer_init_session(inv_session, &timer);
3395
3396 session = ast_sip_session_alloc(endpoint, found_contact ? found_contact : contact,
3397 inv_session, NULL);
3398 if (!session) {
3399 pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
3400 return NULL;
3401 }
3402 session->aor = ao2_bump(found_aor);
3403 session->call_direction = AST_SIP_SESSION_OUTGOING_CALL;
3404
3406
3407 if (ast_stream_topology_get_count(req_topology) > 0) {
3408 /* get joint caps between req_topology and endpoint topology */
3409 int i;
3410
3411 for (i = 0; i < ast_stream_topology_get_count(req_topology); ++i) {
3412 struct ast_stream *req_stream;
3413 struct ast_stream *clone_stream;
3414
3415 req_stream = ast_stream_topology_get_stream(req_topology, i);
3416
3418 continue;
3419 }
3420
3421 clone_stream = ast_sip_session_create_joint_call_stream(session, req_stream);
3422 if (!clone_stream || ast_stream_get_format_count(clone_stream) == 0) {
3423 ast_stream_free(clone_stream);
3424 continue;
3425 }
3426
3427 if (!session->pending_media_state->topology) {
3428 session->pending_media_state->topology = ast_stream_topology_alloc();
3429 if (!session->pending_media_state->topology) {
3430 pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
3431 ao2_ref(session, -1);
3432 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create topology\n");
3433 }
3434 }
3435
3436 if (ast_stream_topology_append_stream(session->pending_media_state->topology, clone_stream) < 0) {
3437 ast_stream_free(clone_stream);
3438 continue;
3439 }
3440 }
3441 }
3442
3443 if (!session->pending_media_state->topology) {
3444 /* Use the configured topology on the endpoint as the pending one */
3445 session->pending_media_state->topology = ast_stream_topology_clone(endpoint->media.topology);
3446 if (!session->pending_media_state->topology) {
3447 pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
3448 ao2_ref(session, -1);
3449 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't clone topology\n");
3450 }
3451 }
3452
3453 if (pjsip_dlg_add_usage(dlg, &session_module, NULL) != PJ_SUCCESS) {
3454 pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
3455 /* Since we are not notifying ourselves that the INVITE session is being terminated
3456 * we need to manually drop its reference to session
3457 */
3458 ao2_ref(session, -1);
3459 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't add usage\n");
3460 }
3461
3462 /* Avoid unnecessary ref manipulation to return a session */
3463 ret_session = session;
3464 session = NULL;
3465 SCOPE_EXIT_RTN_VALUE(ret_session);
3466}
static struct ast_timer * timer
Definition: chan_iax2.c:364
void ast_party_id_copy(struct ast_party_id *dest, const struct ast_party_id *src)
Copy the source party id information to the destination party id.
Definition: channel.c:1765
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.
Definition: res_pjsip.c:964
@ AST_SIP_CONTACT_FILTER_REACHABLE
Return only reachable or unknown contacts.
Definition: res_pjsip.h:1304
void ast_sip_location_retrieve_contact_and_aor_from_list_filtered(const char *aor_list, unsigned int flags, struct ast_sip_aor **aor, struct ast_sip_contact **contact)
Retrieve the first bound contact AND the AOR chosen from a list of AORs and filter based on flags.
Definition: location.c:272
struct ast_sip_session * ast_sip_session_alloc(struct ast_sip_endpoint *endpoint, struct ast_sip_contact *contact, pjsip_inv_session *inv_session, pjsip_rx_data *rdata)
Allocate a new SIP session.
static int setup_outbound_invite_auth(pjsip_dialog *dlg)
struct ast_stream * ast_sip_session_create_joint_call_stream(const struct ast_sip_session *session, struct ast_stream *remote)
Create a new stream of joint capabilities.
struct ast_stream_topology * ast_stream_topology_alloc(void)
Create a stream topology.
Definition: stream.c:650
@ AST_STREAM_STATE_REMOVED
Set when the stream has been removed/declined.
Definition: stream.h:78
int ast_stream_topology_append_stream(struct ast_stream_topology *topology, struct ast_stream *stream)
Append a stream to the topology.
Definition: stream.c:748
const char * ast_stream_topology_to_str(const struct ast_stream_topology *topology, struct ast_str **buf)
Get a string representing the topology for debugging/display purposes.
Definition: stream.c:936
struct ast_stream * ast_stream_topology_get_stream(const struct ast_stream_topology *topology, unsigned int position)
Get a specific stream from the topology.
Definition: stream.c:788
int ast_stream_topology_get_count(const struct ast_stream_topology *topology)
Get the number of streams in a topology.
Definition: stream.c:765
int ast_stream_get_format_count(const struct ast_stream *stream)
Get the count of the current negotiated formats of a stream.
Definition: stream.c:358
enum ast_stream_state ast_stream_get_state(const struct ast_stream *stream)
Get the current state of a stream.
Definition: stream.c:373
void ast_stream_free(struct ast_stream *stream)
Destroy a media stream representation.
Definition: stream.c:292
struct ast_stream_topology * ast_stream_topology_clone(const struct ast_stream_topology *topology)
Create a deep clone of an existing stream topology.
Definition: stream.c:667
#define ast_str_tmp(init_len, __expr)
Provides a temporary ast_str and returns a copy of its buffer.
Definition: strings.h:1189
A SIP address of record.
Definition: res_pjsip.h:478
Contact associated with an address of record.
Definition: res_pjsip.h:392
const ast_string_field uri
Definition: res_pjsip.h:414
struct ast_sip_timer_options timer
Definition: res_pjsip.h:719
struct ast_party_id self
Definition: res_pjsip.h:770
struct ast_stream_topology * topology
Definition: res_pjsip.h:921
struct ast_sip_endpoint_id_configuration id
Definition: res_pjsip.h:1000
const ast_string_field aors
Definition: res_pjsip.h:990
struct ast_sip_endpoint_extensions extensions
Definition: res_pjsip.h:992
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:994
unsigned int sess_expires
Definition: res_pjsip.h:706
unsigned int min_se
Definition: res_pjsip.h:704

References ao2_bump, ao2_cleanup, ao2_ref, ast_sip_endpoint::aors, ast_log, ast_party_id_copy(), AST_SIP_CONTACT_FILTER_REACHABLE, ast_sip_create_dialog_uac(), ast_sip_location_retrieve_contact_and_aor_from_list_filtered(), ast_sip_session_alloc(), ast_sip_session_create_joint_call_stream(), AST_SIP_SESSION_OUTGOING_CALL, ast_sorcery_object_get_id(), ast_str_tmp, ast_stream_free(), ast_stream_get_format_count(), ast_stream_get_state(), AST_STREAM_STATE_REMOVED, ast_stream_topology_alloc(), ast_stream_topology_append_stream(), ast_stream_topology_clone(), ast_stream_topology_get_count(), ast_stream_topology_get_stream(), ast_stream_topology_to_str(), ast_strlen_zero(), ast_sip_session::contact, ast_sip_session::endpoint, ast_sip_endpoint::extensions, ast_sip_endpoint_extensions::flags, ast_sip_endpoint::id, ast_sip_session::inv_session, LOG_ERROR, ast_sip_endpoint::media, ast_sip_timer_options::min_se, NULL, RAII_VAR, S_OR, SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, ast_sip_endpoint_id_configuration::self, ast_sip_timer_options::sess_expires, session, session_module, setup_outbound_invite_auth(), timer, ast_sip_endpoint_extensions::timer, ast_sip_endpoint_media_configuration::topology, and ast_sip_contact::uri.

Referenced by request().

◆ ast_sip_session_defer_termination()

int ast_sip_session_defer_termination ( struct ast_sip_session session)

Defer local termination of a session until remote side terminates, or an amount of time passes.

Parameters
sessionThe session to defer termination on
Return values
0Success
-1Failure

Definition at line 3574 of file res_pjsip_session.c.

3575{
3576 pj_time_val delay = { .sec = 60, };
3577 int res;
3578
3579 /* The session should not have an active deferred termination request. */
3580 ast_assert(!session->defer_terminate);
3581
3582 session->defer_terminate = 1;
3583
3584 session->defer_end = 1;
3585 session->ended_while_deferred = 0;
3586
3587 ao2_ref(session, +1);
3588 pj_timer_entry_init(&session->scheduled_termination, 0, session, session_termination_cb);
3589
3590 res = (pjsip_endpt_schedule_timer(ast_sip_get_pjsip_endpoint(),
3591 &session->scheduled_termination, &delay) != PJ_SUCCESS) ? -1 : 0;
3592 if (res) {
3593 session->defer_terminate = 0;
3594 ao2_ref(session, -1);
3595 }
3596 return res;
3597}
pjsip_endpoint * ast_sip_get_pjsip_endpoint(void)
Get a pointer to the PJSIP endpoint.
Definition: res_pjsip.c:520
static void session_termination_cb(pj_timer_heap_t *timer_heap, struct pj_timer_entry *entry)

References ao2_ref, ast_assert, ast_sip_get_pjsip_endpoint(), session, and session_termination_cb().

Referenced by refer_incoming_attended_request(), and refer_incoming_blind_request().

◆ ast_sip_session_defer_termination_cancel()

void ast_sip_session_defer_termination_cancel ( struct ast_sip_session session)

Cancel a pending deferred termination.

Parameters
sessionThe session to cancel a deferred termination on.

Definition at line 3614 of file res_pjsip_session.c.

3615{
3616 if (!session->defer_terminate) {
3617 /* Already canceled or timer fired. */
3618 return;
3619 }
3620
3621 session->defer_terminate = 0;
3622
3623 if (session->terminate_while_deferred) {
3624 /* Complete the termination started by the upper layer. */
3626 }
3627
3628 /* Stop the termination timer if it is still running. */
3630}
static void sip_session_defer_termination_stop_timer(struct ast_sip_session *session)
void ast_sip_session_terminate(struct ast_sip_session *session, int response)
Terminate a session and, if possible, send the provided response code.

References ast_sip_session_terminate(), session, and sip_session_defer_termination_stop_timer().

Referenced by defer_termination_cancel_task(), refer_incoming_attended_request(), and refer_incoming_blind_request().

◆ ast_sip_session_end_if_deferred()

void ast_sip_session_end_if_deferred ( struct ast_sip_session session)

End the session if it had been previously deferred.

Parameters
sessionThe session to end if it had been deferred

Definition at line 3632 of file res_pjsip_session.c.

3633{
3634 if (!session->defer_end) {
3635 return;
3636 }
3637
3638 session->defer_end = 0;
3639
3640 if (session->ended_while_deferred) {
3641 /* Complete the session end started by the remote hangup. */
3642 ast_debug(3, "%s: Ending session after being deferred\n", ast_sip_session_get_name(session));
3643 session->ended_while_deferred = 0;
3645 }
3646}
#define ast_debug(level,...)
Log a DEBUG message.
static int session_end(void *vsession)

References ast_debug, ast_sip_session_get_name(), session, and session_end().

Referenced by defer_termination_cancel_task(), refer_attended_task(), refer_incoming_attended_request(), refer_incoming_blind_request(), and session_end_if_deferred_task().

◆ ast_sip_session_get_datastore()

struct ast_datastore * ast_sip_session_get_datastore ( struct ast_sip_session session,
const char *  name 
)

Retrieve a session datastore.

The datastore retrieved will have its reference count incremented. When the caller is done with the datastore, the reference counted needs to be decremented using ao2_ref().

Parameters
sessionThe session from which to retrieve the datastore
nameThe name of the datastore to retrieve
Return values
NULLFailed to find the specified datastore
non-NULLThe specified datastore

Definition at line 1296 of file res_pjsip_session.c.

1297{
1298 return ao2_find(session->datastores, name, OBJ_KEY);
1299}
#define OBJ_KEY
Definition: astobj2.h:1151
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1736
static const char name[]
Definition: format_mp3.c:68

References ao2_find, name, OBJ_KEY, and session.

Referenced by add_header(), aoc_bye_outgoing_request(), aoc_bye_outgoing_response(), aoc_invite_outgoing_response(), aoc_send_as_xml(), chan_pjsip_get_rtp_peer(), channel_read_pjsip(), direct_media_mitigate_glare(), handle_outgoing_response(), incoming_request(), incoming_response(), outgoing_request(), read_header(), read_headers(), reason_header_outgoing_response(), remove_header(), rfc3329_incoming_response(), rfc3329_outgoing_request(), session_refresh_state_get_or_alloc(), t38_automatic_reject(), t38_state_get_or_alloc(), and update_header().

◆ ast_sip_session_get_dialog()

pjsip_dialog * ast_sip_session_get_dialog ( const struct ast_sip_session session)

Retrieves a dialog from a session.

Parameters
sessionThe session to retrieve the dialog from
Return values
non-NULLif dialog exists
NULLif no dialog

Definition at line 3663 of file res_pjsip_session.c.

3664{
3665 pjsip_inv_session *inv_session = session->inv_session;
3666
3667 if (!inv_session) {
3668 return NULL;
3669 }
3670
3671 return inv_session->dlg;
3672}

References ast_sip_session::inv_session, NULL, and session.

◆ ast_sip_session_get_name()

const char * ast_sip_session_get_name ( const struct ast_sip_session session)

Get the channel or endpoint name associated with the session.

Since
18.0.0
Parameters
session
Return values
Channelname or endpoint name or "unknown"

Definition at line 117 of file res_pjsip_session.c.

118{
119 if (!session) {
120 return "(null session)";
121 }
122 if (session->channel) {
123 return ast_channel_name(session->channel);
124 } else if (session->endpoint) {
125 return ast_sorcery_object_get_id(session->endpoint);
126 } else {
127 return "unknown";
128 }
129}
const char * ast_channel_name(const struct ast_channel *chan)

References ast_channel_name(), ast_sorcery_object_get_id(), and session.

Referenced by add_date_header(), add_eprofile_to_channel(), add_fingerprints_if_present(), add_sdp_streams(), answer(), apply_negotiated_sdp_stream(), ast_sip_session_add_reason_header(), ast_sip_session_create_invite(), ast_sip_session_end_if_deferred(), ast_sip_session_media_state_add(), ast_sip_session_regenerate_answer(), ast_sip_session_terminate(), call(), chan_pjsip_call(), chan_pjsip_incoming_ack(), chan_pjsip_incoming_prack(), chan_pjsip_incoming_request(), chan_pjsip_incoming_response(), chan_pjsip_incoming_response_update_cause(), chan_pjsip_new(), chan_pjsip_session_begin(), chan_pjsip_session_end(), create_local_sdp(), create_outgoing_sdp_stream(), delay_request(), generate_session_refresh_sdp(), get_codecs(), get_destination(), handle_incoming_before_media(), handle_incoming_request(), handle_incoming_response(), handle_incoming_sdp(), handle_negotiated_sdp(), handle_negotiated_sdp_session_media(), handle_new_invite_request(), handle_outgoing_request(), handle_outgoing_response(), invite_collision_timeout(), invite_proceeding(), invite_terminated(), negotiate_incoming_sdp_stream(), new_invite(), on_topology_change_response(), outbound_invite_auth(), pbx_start_incoming_request(), process_failure(), reason_header_outgoing_response(), reschedule_reinvite(), resend_reinvite(), sdp_requires_deferral(), send_delayed_request(), send_topology_change_refresh(), session_destructor(), session_inv_on_create_offer(), session_inv_on_media_update(), session_inv_on_rx_offer(), session_inv_on_state_changed(), session_inv_on_tsx_state_changed(), session_on_rx_request(), session_on_rx_response(), session_on_tsx_state(), session_outgoing_nat_hook(), set_caps(), set_from_header(), set_incoming_call_offer_cap(), sip_session_refresh(), stir_shaken_incoming_request(), and stir_shaken_outgoing_request().

◆ ast_sip_session_get_pjsip_inv_state()

pjsip_inv_state ast_sip_session_get_pjsip_inv_state ( const struct ast_sip_session session)

Retrieves the pjsip_inv_state from a session.

Parameters
sessionThe session to retrieve the state from
Return values
stateif inv_session exists
PJSIP_INV_STATE_NULLif inv_session is NULL

Definition at line 3674 of file res_pjsip_session.c.

3675{
3676 pjsip_inv_session *inv_session = session->inv_session;
3677
3678 if (!inv_session) {
3679 return PJSIP_INV_STATE_NULL;
3680 }
3681
3682 return inv_session->state;
3683}

References ast_sip_session::inv_session, and session.

◆ ast_sip_session_is_pending_stream_default()

int ast_sip_session_is_pending_stream_default ( const struct ast_sip_session session,
const struct ast_stream stream 
)

Determines if a provided pending stream will be the default stream or not.

Since
15.0.0
Parameters
sessionThe session to check against
streamThe pending stream
Return values
1if stream will be default
0if stream will NOT be the default

Definition at line 368 of file res_pjsip_session.c.

369{
370 int index;
371
372 if (!session->pending_media_state->topology) {
373 ast_log(LOG_WARNING, "Pending topology was NULL for channel '%s'\n",
374 session->channel ? ast_channel_name(session->channel) : "unknown");
375 return 0;
376 }
377
379 return 0;
380 }
381
382 for (index = 0; index < ast_stream_topology_get_count(session->pending_media_state->topology); ++index) {
383 if (ast_stream_get_type(ast_stream_topology_get_stream(session->pending_media_state->topology, index)) !=
384 ast_stream_get_type(stream)) {
385 continue;
386 }
387
388 return ast_stream_topology_get_stream(session->pending_media_state->topology, index) == stream ? 1 : 0;
389 }
390
391 return 0;
392}
#define LOG_WARNING
enum ast_media_type ast_stream_get_type(const struct ast_stream *stream)
Get the media type of a stream.
Definition: stream.c:316

References ast_channel_name(), ast_log, ast_stream_get_state(), ast_stream_get_type(), AST_STREAM_STATE_REMOVED, ast_stream_topology_get_count(), ast_stream_topology_get_stream(), LOG_WARNING, and session.

Referenced by create_outgoing_sdp_stream(), handle_incoming_sdp(), handle_negotiated_sdp_session_media(), sdp_requires_deferral(), set_caps(), and set_session_media_remotely_held().

◆ ast_sip_session_media_add_read_callback()

int ast_sip_session_media_add_read_callback ( struct ast_sip_session session,
struct ast_sip_session_media session_media,
int  fd,
ast_sip_session_media_read_cb  callback 
)

Set a read callback for a media session with a specific file descriptor.

Since
15.0.0
Parameters
sessionThe session
session_mediaThe media session
fdThe file descriptor
callbackThe read callback
Return values
0the read callback was successfully added
-1the read callback could not be added
Note
This operations on the pending media state

Definition at line 394 of file res_pjsip_session.c.

396{
397 struct ast_sip_session_media_read_callback_state callback_state = {
398 .fd = fd,
399 .read_callback = callback,
400 .session = session_media,
401 };
402
403 /* The contents of the vector are whole structs and not pointers */
404 return AST_VECTOR_APPEND(&session->pending_media_state->read_callbacks, callback_state);
405}
Structure which contains read callback information.
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256

References AST_VECTOR_APPEND, ast_sip_session_media_read_callback_state::fd, and session.

Referenced by apply_negotiated_sdp_stream().

◆ ast_sip_session_media_get_transport()

struct ast_sip_session_media * ast_sip_session_media_get_transport ( struct ast_sip_session session,
struct ast_sip_session_media session_media 
)

Retrieve the underlying media session that is acting as transport for a media session.

Since
15.0.0
Parameters
sessionThe session
session_mediaThe media session to retrieve the transport for
Note
This operates on the pending media state
This function is guaranteed to return non-NULL

Definition at line 423 of file res_pjsip_session.c.

424{
425 int index;
426
427 if (!session->endpoint->media.bundle || ast_strlen_zero(session_media->mid)) {
428 return session_media;
429 }
430
431 for (index = 0; index < AST_VECTOR_SIZE(&session->pending_media_state->sessions); ++index) {
432 struct ast_sip_session_media *bundle_group_session_media;
433
434 bundle_group_session_media = AST_VECTOR_GET(&session->pending_media_state->sessions, index);
435
436 /* The first session which is in the bundle group is considered the authoritative session for transport */
437 if (bundle_group_session_media->bundle_group == session_media->bundle_group) {
438 return bundle_group_session_media;
439 }
440 }
441
442 return session_media;
443}
A structure containing SIP session media information.
int bundle_group
The bundle group the stream belongs to.
char * mid
Media identifier for this stream (may be shared across multiple streams)
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:609
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:680

References ast_strlen_zero(), AST_VECTOR_GET, AST_VECTOR_SIZE, ast_sip_session_media::bundle_group, ast_sip_session_media::mid, and session.

Referenced by apply_negotiated_sdp_stream(), create_outgoing_sdp_stream(), and negotiate_incoming_sdp_stream().

◆ ast_sip_session_media_set_write_callback()

int ast_sip_session_media_set_write_callback ( struct ast_sip_session session,
struct ast_sip_session_media session_media,
ast_sip_session_media_write_cb  callback 
)

Set a write callback for a media session.

Since
15.0.0
Parameters
sessionThe session
session_mediaThe media session
callbackThe write callback
Return values
0the write callback was successfully add
-1the write callback is already set to something different
Note
This operates on the pending media state

Definition at line 407 of file res_pjsip_session.c.

409{
410 if (session_media->write_callback) {
411 if (session_media->write_callback == callback) {
412 return 0;
413 }
414
415 return -1;
416 }
417
418 session_media->write_callback = callback;
419
420 return 0;
421}
ast_sip_session_media_write_cb write_callback
The write callback when writing frames.

References ast_sip_session_media::write_callback.

Referenced by apply_negotiated_sdp_stream().

◆ ast_sip_session_media_state_add()

struct ast_sip_session_media * ast_sip_session_media_state_add ( struct ast_sip_session session,
struct ast_sip_session_media_state media_state,
enum ast_media_type  type,
int  position 
)

Allocate an ast_session_media and add it to the media state's vector.

Since
15.0.0

This allocates a session media of the specified type. The position argument determines where in the vector that the new session media will be inserted.

Note
The returned ast_session_media is the reference held by the vector. Callers of this function must NOT decrement the refcount of the session media.
Parameters
sessionSession on which to query active media state for
media_stateMedia state to place the session media into
typeThe type of the session media
positionPosition at which to insert the new session media.
Note
The active media state will be queried and if a media session already exists at the given position for the same type it will be reused instead of allocating a new one.
Return values
non-NULLsuccess
NULLfailure

Definition at line 499 of file res_pjsip_session.c.

501{
502 struct ast_sip_session_media *session_media = NULL;
503 struct ast_sip_session_media *current_session_media = NULL;
504 SCOPE_ENTER(1, "%s Adding position %d\n", ast_sip_session_get_name(session), position);
505
506 /* It is possible for this media state to already contain a session for the stream. If this
507 * is the case we simply return it.
508 */
509 if (position < AST_VECTOR_SIZE(&media_state->sessions)) {
510 current_session_media = AST_VECTOR_GET(&media_state->sessions, position);
511 if (current_session_media && current_session_media->type == type) {
512 SCOPE_EXIT_RTN_VALUE(current_session_media, "Using existing media_session\n");
513 }
514 }
515
516 /* Determine if we can reuse the session media from the active media state if present */
517 if (position < AST_VECTOR_SIZE(&session->active_media_state->sessions)) {
518 session_media = AST_VECTOR_GET(&session->active_media_state->sessions, position);
519 /* A stream can never exist without an accompanying media session */
520 if (session_media->type == type) {
521 ao2_ref(session_media, +1);
522 ast_trace(1, "Reusing existing media session\n");
523 /*
524 * If this session_media was previously removed, its bundle group was probably reset
525 * to -1 so if bundling is enabled on the endpoint, we need to reset it to 0, set
526 * the bundled flag and reset its mid.
527 */
528 if (session->endpoint->media.bundle && session_media->bundle_group == -1) {
529 session_media->bundled = session->endpoint->media.webrtc;
530 session_media->bundle_group = 0;
531 ast_free(session_media->mid);
532 if (ast_asprintf(&session_media->mid, "%s-%d", ast_codec_media_type2str(type), position) < 0) {
533 ao2_ref(session_media, -1);
534 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't alloc mid\n");
535 }
536 }
537 } else {
538 ast_trace(1, "Can't reuse existing media session because the types are different. %s <> %s\n",
540 session_media = NULL;
541 }
542 }
543
544 if (!session_media) {
545 /* No existing media session we can use so create a new one */
546 session_media = ao2_alloc_options(sizeof(*session_media), session_media_dtor, AO2_ALLOC_OPT_LOCK_NOLOCK);
547 if (!session_media) {
548 return NULL;
549 }
550 ast_trace(1, "Creating new media session\n");
551
552 session_media->encryption = session->endpoint->media.rtp.encryption;
553 session_media->remote_ice = session->endpoint->media.rtp.ice_support;
554 session_media->remote_rtcp_mux = session->endpoint->media.rtcp_mux;
555 session_media->keepalive_sched_id = -1;
556 session_media->timeout_sched_id = -1;
557 session_media->type = type;
558 session_media->stream_num = position;
559
560 if (session->endpoint->media.bundle) {
561 /* This is a new stream so create a new mid based on media type and position, which makes it unique.
562 * If this is the result of an offer the mid will just end up getting replaced.
563 */
564 if (ast_asprintf(&session_media->mid, "%s-%d", ast_codec_media_type2str(type), position) < 0) {
565 ao2_ref(session_media, -1);
566 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't alloc mid\n");
567 }
568 session_media->bundle_group = 0;
569
570 /* Some WebRTC clients can't handle an offer to bundle media streams. Instead they expect them to
571 * already be bundled. Every client handles this scenario though so if WebRTC is enabled just go
572 * ahead and treat the streams as having already been bundled.
573 */
574 session_media->bundled = session->endpoint->media.webrtc;
575 } else {
576 session_media->bundle_group = -1;
577 }
578 }
579
580 ast_free(session_media->stream_name);
581 session_media->stream_name = ast_strdup(ast_stream_get_name(ast_stream_topology_get_stream(media_state->topology, position)));
582
583 if (AST_VECTOR_REPLACE(&media_state->sessions, position, session_media)) {
584 ao2_ref(session_media, -1);
585
586 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't replace media_session\n");
587 }
588
589 ao2_cleanup(current_session_media);
590
591 /* If this stream will be active in some way and it is the first of this type then consider this the default media session to match */
593 ast_trace(1, "Setting media session as default for %s\n", ast_codec_media_type2str(session_media->type));
594
595 media_state->default_session[type] = session_media;
596 }
597
598 SCOPE_EXIT_RTN_VALUE(session_media, "Done\n");
599}
#define ast_free(a)
Definition: astmm.h:180
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:267
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition: astobj2.h:367
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:404
static const char type[]
Definition: chan_ooh323.c:109
const char * ast_codec_media_type2str(enum ast_media_type type)
Conversion function to take a media type and turn it into a string.
Definition: codec.c:348
#define ast_trace(level,...)
static void session_media_dtor(void *obj)
const char * ast_stream_get_name(const struct ast_stream *stream)
Get the name of a stream.
Definition: stream.c:309
struct ast_stream_topology * topology
The media stream topology.
struct ast_sip_session_media_state::@263 sessions
Mapping of stream to media sessions.
struct ast_sip_session_media * default_session[AST_MEDIA_TYPE_END]
Default media sessions for each type.
char * stream_name
Stream name.
unsigned int remote_ice
Does remote support ice.
enum ast_media_type type
Media type of this session media.
unsigned int remote_rtcp_mux
Does remote support rtcp_mux.
int timeout_sched_id
Scheduler ID for RTP timeout.
int stream_num
The stream number to place into any resulting frames.
enum ast_sip_session_media_encryption encryption
What type of encryption is in use on this stream.
unsigned int bundled
Whether this stream is currently bundled or not.
int keepalive_sched_id
Scheduler ID for RTP keepalive.
#define AST_VECTOR_REPLACE(vec, idx, elem)
Replace an element at a specific position in a vector, growing the vector if needed.
Definition: vector.h:284

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_cleanup, ao2_ref, ast_asprintf, ast_codec_media_type2str(), ast_free, ast_sip_session_get_name(), ast_strdup, ast_stream_get_name(), ast_stream_get_state(), AST_STREAM_STATE_REMOVED, ast_stream_topology_get_stream(), ast_trace, AST_VECTOR_GET, AST_VECTOR_REPLACE, AST_VECTOR_SIZE, ast_sip_session_media::bundle_group, ast_sip_session_media::bundled, ast_sip_session_media_state::default_session, ast_sip_session_media::encryption, ast_sip_session_media::keepalive_sched_id, ast_sip_session_media::mid, NULL, ast_sip_session_media::remote_ice, ast_sip_session_media::remote_rtcp_mux, SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, session, session_media_dtor(), ast_sip_session_media_state::sessions, ast_sip_session_media::stream_name, ast_sip_session_media::stream_num, ast_sip_session_media::timeout_sched_id, ast_sip_session_media_state::topology, type, and ast_sip_session_media::type.

Referenced by create_local_sdp(), handle_incoming_sdp(), sdp_requires_deferral(), and t38_create_media_state().

◆ ast_sip_session_media_state_alloc()

struct ast_sip_session_media_state * ast_sip_session_media_state_alloc ( void  )

Allocate a session media state structure.

Since
15.0.0
Return values
non-NULLsuccess
NULLfailure

Definition at line 247 of file res_pjsip_session.c.

248{
251}
#define DEFAULT_NUM_SESSION_MEDIA
static struct ast_sip_session_media_state * internal_sip_session_media_state_alloc(size_t sessions, size_t read_callbacks)

References DEFAULT_NUM_SESSION_MEDIA, and internal_sip_session_media_state_alloc().

Referenced by ast_sip_session_alloc(), session_refresh_state_get_or_alloc(), t38_create_media_state(), and topology_change_refresh_data_alloc().

◆ ast_sip_session_media_state_clone()

struct ast_sip_session_media_state * ast_sip_session_media_state_clone ( const struct ast_sip_session_media_state media_state)

Clone a media state.

Since
15.0.0
Parameters
media_stateThe media state to clone
Return values
non-NULLsuccess
NULLfailure

Definition at line 306 of file res_pjsip_session.c.

307{
308 struct ast_sip_session_media_state *cloned;
309 int index;
310
311 if (!media_state) {
312 return NULL;
313 }
314
316 AST_VECTOR_SIZE(&media_state->sessions),
317 AST_VECTOR_SIZE(&media_state->read_callbacks));
318 if (!cloned) {
319 return NULL;
320 }
321
322 if (media_state->topology) {
323 cloned->topology = ast_stream_topology_clone(media_state->topology);
324 if (!cloned->topology) {
326 return NULL;
327 }
328 }
329
330 for (index = 0; index < AST_VECTOR_SIZE(&media_state->sessions); ++index) {
331 struct ast_sip_session_media *session_media = AST_VECTOR_GET(&media_state->sessions, index);
333
334 ao2_bump(session_media);
335 if (AST_VECTOR_REPLACE(&cloned->sessions, index, session_media)) {
336 ao2_cleanup(session_media);
337 }
339 !cloned->default_session[type]) {
340 cloned->default_session[type] = session_media;
341 }
342 }
343
344 for (index = 0; index < AST_VECTOR_SIZE(&media_state->read_callbacks); ++index) {
346
348 }
349
350 return cloned;
351}
ast_media_type
Types of media.
Definition: codec.h:30
void ast_sip_session_media_state_free(struct ast_sip_session_media_state *media_state)
Free a session media state structure.
ast_sip_session_media_read_cb read_callback
The callback to invoke.
Structure which contains media state information (streams, sessions)
struct ast_sip_session_media_state::@264 read_callbacks
Added read callbacks - these are whole structs and not pointers.
#define AST_VECTOR_GET_ADDR(vec, idx)
Get an address of element in a vector.
Definition: vector.h:668

References ao2_bump, ao2_cleanup, ast_sip_session_media_state_free(), ast_stream_get_state(), ast_stream_get_type(), AST_STREAM_STATE_REMOVED, ast_stream_topology_clone(), ast_stream_topology_get_stream(), AST_VECTOR_GET, AST_VECTOR_GET_ADDR, AST_VECTOR_REPLACE, AST_VECTOR_SIZE, ast_sip_session_media_state::default_session, internal_sip_session_media_state_alloc(), NULL, ast_sip_session_media_read_callback_state::read_callback, ast_sip_session_media_state::read_callbacks, ast_sip_session_media_state::sessions, ast_sip_session_media_state::topology, and type.

Referenced by handle_negotiated_sdp(), reschedule_reinvite(), resolve_refresh_media_states(), sip_session_refresh(), and t38_reinvite_sdp_cb().

◆ ast_sip_session_media_state_free()

void ast_sip_session_media_state_free ( struct ast_sip_session_media_state media_state)

Free a session media state structure.

Since
15.0.0

Definition at line 353 of file res_pjsip_session.c.

354{
355 if (!media_state) {
356 return;
357 }
358
359 /* This will reset the internal state so we only have to free persistent things */
361
362 AST_VECTOR_FREE(&media_state->sessions);
363 AST_VECTOR_FREE(&media_state->read_callbacks);
364
365 ast_free(media_state);
366}
void ast_sip_session_media_state_reset(struct ast_sip_session_media_state *media_state)
Reset a media state to a clean state.
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174

References ast_free, ast_sip_session_media_state_reset(), AST_VECTOR_FREE, ast_sip_session_media_state::read_callbacks, and ast_sip_session_media_state::sessions.

Referenced by ast_sip_session_media_state_clone(), delay_request(), delayed_request_free(), handle_negotiated_sdp(), reschedule_reinvite(), resolve_refresh_media_states(), session_destructor(), session_refresh_state_destroy(), sip_session_refresh(), t38_create_media_state(), t38_reinvite_response_cb(), t38_state_destroy(), and topology_change_refresh_data_free().

◆ ast_sip_session_media_state_reset()

void ast_sip_session_media_state_reset ( struct ast_sip_session_media_state media_state)

Reset a media state to a clean state.

Since
15.0.0
Parameters
media_stateThe media state to reset

Definition at line 287 of file res_pjsip_session.c.

288{
289 int index;
290
291 if (!media_state) {
292 return;
293 }
294
295 AST_VECTOR_RESET(&media_state->sessions, ao2_cleanup);
297
298 for (index = 0; index < AST_MEDIA_TYPE_END; ++index) {
299 media_state->default_session[index] = NULL;
300 }
301
303 media_state->topology = NULL;
304}
@ AST_MEDIA_TYPE_END
Definition: codec.h:36
void ast_stream_topology_free(struct ast_stream_topology *topology)
Unreference and destroy a stream topology.
Definition: stream.c:743
#define AST_VECTOR_RESET(vec, cleanup)
Reset vector.
Definition: vector.h:625
#define AST_VECTOR_ELEM_CLEANUP_NOOP(elem)
Vector element cleanup that does nothing.
Definition: vector.h:571

References ao2_cleanup, AST_MEDIA_TYPE_END, ast_stream_topology_free(), AST_VECTOR_ELEM_CLEANUP_NOOP, AST_VECTOR_RESET, ast_sip_session_media_state::default_session, NULL, ast_sip_session_media_state::read_callbacks, ast_sip_session_media_state::sessions, and ast_sip_session_media_state::topology.

Referenced by ast_sip_session_media_state_free(), ast_sip_session_terminate(), handle_negotiated_sdp(), on_topology_change_response(), session_inv_on_media_update(), session_inv_on_rx_offer(), session_reinvite_on_rx_request(), sip_session_refresh(), and t38_reinvite_response_cb().

◆ ast_sip_session_media_stats_save()

void ast_sip_session_media_stats_save ( struct ast_sip_session sip_session,
struct ast_sip_session_media_state media_state 
)

Save a media stats.

Parameters
sip_sessionSession on which to save active media state for
media_stateThe media state to save

Definition at line 253 of file res_pjsip_session.c.

254{
255 int i;
256 int ret;
257
258 if (!media_state || !sip_session) {
259 return;
260 }
261
262 for (i = 0; i < AST_VECTOR_SIZE(&media_state->sessions); i++) {
263 struct ast_rtp_instance_stats *stats_tmp = NULL;
264 struct ast_sip_session_media *media = AST_VECTOR_GET(&media_state->sessions, i);
265 if (!media || !media->rtp) {
266 continue;
267 }
268
269 stats_tmp = ast_calloc(1, sizeof(struct ast_rtp_instance_stats));
270 if (!stats_tmp) {
271 return;
272 }
273
275 if (ret) {
276 ast_free(stats_tmp);
277 continue;
278 }
279
280 /* remove all the duplicated stats if exist */
282
283 AST_VECTOR_APPEND(&sip_session->media_stats, stats_tmp);
284 }
285}
static int media_stats_local_ssrc_cmp(const struct ast_rtp_instance_stats *vec_elem, const struct ast_rtp_instance_stats *srch)
@ AST_RTP_INSTANCE_STAT_ALL
Definition: rtp_engine.h:184
int ast_rtp_instance_get_stats(struct ast_rtp_instance *instance, struct ast_rtp_instance_stats *stats, enum ast_rtp_instance_stat stat)
Retrieve statistics about an RTP instance.
Definition: rtp_engine.c:2561
struct ast_rtp_instance * rtp
RTP instance itself.
struct ast_sip_session::@267 media_stats
#define AST_VECTOR_REMOVE_CMP_UNORDERED(vec, value, cmp, cleanup)
Remove an element from a vector that matches the given comparison.
Definition: vector.h:488

References ast_calloc, ast_free, ast_rtp_instance_get_stats(), AST_RTP_INSTANCE_STAT_ALL, AST_VECTOR_APPEND, AST_VECTOR_GET, AST_VECTOR_REMOVE_CMP_UNORDERED, AST_VECTOR_SIZE, ast_sip_session::media_stats, media_stats_local_ssrc_cmp(), NULL, ast_sip_session_media::rtp, and ast_sip_session_media_state::sessions.

Referenced by ast_sip_session_terminate(), and handle_negotiated_sdp().

◆ ast_sip_session_refresh()

int ast_sip_session_refresh ( struct ast_sip_session session,
ast_sip_session_request_creation_cb  on_request_creation,
ast_sip_session_sdp_creation_cb  on_sdp_creation,
ast_sip_session_response_cb  on_response,
enum ast_sip_session_refresh_method  method,
int  generate_new_sdp,
struct ast_sip_session_media_state media_state 
)

Send a reinvite or UPDATE on a session.

This method will inspect the session in order to construct an appropriate session refresh request. As with any outgoing request in res_pjsip_session, this will call into registered supplements in case they wish to add anything.

Note: The on_request_creation callback may or may not be called in the same thread where this function is called. Request creation may need to be delayed due to the current INVITE transaction state.

Parameters
sessionThe session on which the reinvite will be sent
on_request_creationCallback called when request is created
on_sdp_creationCallback called when SDP is created
on_responseCallback called when response for request is received
methodThe method that should be used when constructing the session refresh
generate_new_sdpBoolean to indicate if a new SDP should be created
media_stateOptional requested media state for the SDP
Return values
0Successfully sent refresh
-1Failure to send refresh
Note
If a media_state is passed in ownership will be taken in all cases

Definition at line 2536 of file res_pjsip_session.c.

2542{
2543 return sip_session_refresh(session, on_request_creation, on_sdp_creation,
2544 on_response, method, generate_new_sdp, media_state, NULL, 0);
2545}
const char * method
Definition: res_pjsip.c:1279
static int sip_session_refresh(struct ast_sip_session *session, ast_sip_session_request_creation_cb on_request_creation, ast_sip_session_sdp_creation_cb on_sdp_creation, ast_sip_session_response_cb on_response, enum ast_sip_session_refresh_method method, int generate_new_sdp, struct ast_sip_session_media_state *pending_media_state, struct ast_sip_session_media_state *active_media_state, int queued)

References method, NULL, session, and sip_session_refresh().

Referenced by dtmf_mode_refresh_cb(), refresh_write_cb(), remote_send_hold_refresh(), send_direct_media_request(), send_topology_change_refresh(), t38_interpret_parameters(), and update_connected_line_information().

◆ ast_sip_session_regenerate_answer()

int ast_sip_session_regenerate_answer ( struct ast_sip_session session,
ast_sip_session_sdp_creation_cb  on_sdp_creation 
)

Regenerate SDP Answer.

This method is used when an SDP offer has been received but an SDP answer has not been sent yet. It requests that a new local SDP be created and set as the SDP answer. As with any outgoing request in res_pjsip_session, this will call into registered supplements in case they wish to add anything.

Parameters
sessionThe session on which the answer will be updated
on_sdp_creationCallback called when SDP is created
Return values
0Successfully updated the SDP answer
-1Failure to updated the SDP answer

Definition at line 2547 of file res_pjsip_session.c.

2549{
2550 pjsip_inv_session *inv_session = session->inv_session;
2551 pjmedia_sdp_session *new_answer = NULL;
2552 const pjmedia_sdp_session *previous_offer = NULL;
2554
2555 /* The SDP answer can only be regenerated if it is still pending to be sent */
2556 if (!inv_session->neg || (pjmedia_sdp_neg_get_state(inv_session->neg) != PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER &&
2557 pjmedia_sdp_neg_get_state(inv_session->neg) != PJMEDIA_SDP_NEG_STATE_WAIT_NEGO)) {
2558 ast_log(LOG_WARNING, "Requested to regenerate local SDP answer for channel '%s' but negotiation in state '%s'\n",
2559 ast_channel_name(session->channel), pjmedia_sdp_neg_state_str(pjmedia_sdp_neg_get_state(inv_session->neg)));
2560 SCOPE_EXIT_RTN_VALUE(-1, "Bad negotiation state\n");
2561 }
2562
2563 pjmedia_sdp_neg_get_neg_remote(inv_session->neg, &previous_offer);
2564 if (pjmedia_sdp_neg_get_state(inv_session->neg) == PJMEDIA_SDP_NEG_STATE_WAIT_NEGO) {
2565 /* Transition the SDP negotiator back to when it received the remote offer */
2566 pjmedia_sdp_neg_negotiate(inv_session->pool, inv_session->neg, 0);
2567 pjmedia_sdp_neg_set_remote_offer(inv_session->pool, inv_session->neg, previous_offer);
2568 }
2569
2570 new_answer = create_local_sdp(inv_session, session, previous_offer, 0);
2571 if (!new_answer) {
2572 ast_log(LOG_WARNING, "Could not create a new local SDP answer for channel '%s'\n",
2573 ast_channel_name(session->channel));
2574 SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create new SDP\n");
2575 }
2576
2577 if (on_sdp_creation) {
2578 if (on_sdp_creation(session, new_answer)) {
2579 SCOPE_EXIT_RTN_VALUE(-1, "Callback failed\n");
2580 }
2581 }
2582
2583 pjsip_inv_set_sdp_answer(inv_session, new_answer);
2584
2586}

References ast_channel_name(), ast_log, ast_sip_session_get_name(), create_local_sdp(), LOG_WARNING, NULL, SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, and session.

Referenced by dtmf_mode_refresh_cb().

◆ ast_sip_session_register_sdp_handler()

int ast_sip_session_register_sdp_handler ( struct ast_sip_session_sdp_handler handler,
const char *  stream_type 
)

Register an SDP handler.

An SDP handler is responsible for parsing incoming SDP streams and ensuring that Asterisk can cope with the contents. Similarly, the SDP handler will be responsible for constructing outgoing SDP streams.

Multiple handlers for the same stream type may be registered. They will be visited in the order they were registered. Handlers will be visited for each stream type until one claims to have handled the stream.

Parameters
handlerThe SDP handler to register
stream_typeThe type of media stream for which to call the handler
Return values
0Success
-1Failure

Definition at line 147 of file res_pjsip_session.c.

148{
149 RAII_VAR(struct sdp_handler_list *, handler_list,
150 ao2_find(sdp_handlers, stream_type, OBJ_KEY), ao2_cleanup);
152
153 if (handler_list) {
154 struct ast_sip_session_sdp_handler *iter;
155 /* Check if this handler is already registered for this stream type */
156 AST_LIST_TRAVERSE(&handler_list->list, iter, next) {
157 if (!strcmp(iter->id, handler->id)) {
158 ast_log(LOG_WARNING, "Handler '%s' already registered for stream type '%s'.\n", handler->id, stream_type);
159 return -1;
160 }
161 }
162 AST_LIST_INSERT_TAIL(&handler_list->list, handler, next);
163 ast_debug(1, "Registered SDP stream handler '%s' for stream type '%s'\n", handler->id, stream_type);
164
165 return 0;
166 }
167
168 /* No stream of this type has been registered yet, so we need to create a new list */
169 handler_list = ao2_alloc(sizeof(*handler_list) + strlen(stream_type), NULL);
170 if (!handler_list) {
171 return -1;
172 }
173 /* Safe use of strcpy */
174 strcpy(handler_list->stream_type, stream_type);
175 AST_LIST_HEAD_INIT_NOLOCK(&handler_list->list);
176 AST_LIST_INSERT_TAIL(&handler_list->list, handler, next);
177 if (!ao2_link(sdp_handlers, handler_list)) {
178 return -1;
179 }
180 ast_debug(1, "Registered SDP stream handler '%s' for stream type '%s'\n", handler->id, stream_type);
181
182 return 0;
183}
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
#define SCOPED_AO2LOCK(varname, obj)
scoped lock specialization for ao2 mutexes.
Definition: lock.h:604
static struct ao2_container * sdp_handlers
Registered SDP stream handlers.
A handler for SDPs in SIP sessions.
struct ast_sip_session_sdp_handler * next
static void handler(const char *name, int response_code, struct ast_variable *get_params, struct ast_variable *path_vars, struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
Definition: test_ari.c:59

References ao2_alloc, ao2_cleanup, ao2_find, ao2_link, ast_debug, AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log, handler(), ast_sip_session_sdp_handler::id, lock, LOG_WARNING, ast_sip_session_sdp_handler::next, NULL, OBJ_KEY, RAII_VAR, SCOPED_AO2LOCK, sdp_handlers, and sdp_handler_list::stream_type.

Referenced by load_module().

◆ ast_sip_session_register_supplement_with_module()

void ast_sip_session_register_supplement_with_module ( struct ast_module module,
struct ast_sip_session_supplement supplement 
)

Register a supplement to SIP session processing.

This allows for someone to insert themselves in the processing of 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
moduleReferenced module(NULL safe)
supplementThe supplement to register

Definition at line 35 of file pjsip_session.c.

36{
37 struct ast_sip_session_supplement *iter;
38 int inserted = 0;
40
41 ast_assert(supplement != NULL);
42
43 supplement->module = module;
44
45 if (!supplement->response_priority) {
47 }
48
50 if (iter->priority > supplement->priority) {
52 inserted = 1;
53 break;
54 }
55 }
57
58 if (!inserted) {
60 }
61}
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:545
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:52
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:617
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:741
#define AST_RWLIST_INSERT_BEFORE_CURRENT
Definition: linkedlists.h:610
enum ast_sip_session_response_priority response_priority
struct ast_module * module
enum ast_sip_supplement_priority priority

References ast_assert, 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, AST_SIP_SESSION_BEFORE_MEDIA, lock, ast_sip_session_supplement::module, ast_sip_session_supplement::next, NULL, ast_sip_session_supplement::priority, ast_sip_session_supplement::response_priority, and SCOPED_LOCK.

◆ ast_sip_session_remove_datastore()

void ast_sip_session_remove_datastore ( struct ast_sip_session session,
const char *  name 
)

Remove a session datastore from the session.

This operation may cause the datastore's free() callback to be called if the reference count reaches zero.

Parameters
sessionThe session to remove the datastore from
nameThe name of the datastore to remove

Definition at line 1301 of file res_pjsip_session.c.

1302{
1303 ao2_callback(session->datastores, OBJ_KEY | OBJ_UNLINK | OBJ_NODATA, NULL, (void *) name);
1304}
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
Definition: astobj2.h:1693
@ OBJ_NODATA
Definition: astobj2.h:1044
@ OBJ_UNLINK
Definition: astobj2.h:1039

References ao2_callback, name, NULL, OBJ_KEY, OBJ_NODATA, OBJ_UNLINK, and session.

Referenced by direct_media_mitigate_glare(), handle_outgoing_response(), outgoing_request(), reason_header_outgoing_response(), refresh_write_cb(), and session_refresh_state_get_or_alloc().

◆ ast_sip_session_remove_supplements()

void ast_sip_session_remove_supplements ( struct ast_sip_session session)

Remove supplements from a SIP session.

Parameters
sessionThe session to remove

Definition at line 111 of file pjsip_session.c.

112{
113 struct ast_sip_session_supplement *iter;
114
115 if (!session) {
116 return;
117 }
118
119 /* free the supplements */
120 while ((iter = AST_LIST_REMOVE_HEAD(&session->supplements, next))) {
121 if (iter->module) {
122 /* referenced session closed. decreasing module reference. */
124 }
125
126 ast_free(iter);
127 }
128
129 return;
130}
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:483

References ast_free, AST_LIST_REMOVE_HEAD, ast_module_unref, ast_sip_session_supplement::module, ast_sip_session_supplement::next, and session.

Referenced by session_destructor().

◆ ast_sip_session_resume_reinvite()

void ast_sip_session_resume_reinvite ( struct ast_sip_session session)

Resumes processing of a deferred incoming re-invite.

Parameters
sessionThe session which has a pending incoming re-invite
Note
When resuming a re-invite it is given to the pjsip stack as if it had just been received from a transport, this means that the deferral callback will be called again.

Definition at line 2818 of file res_pjsip_session.c.

2819{
2820 if (!session->deferred_reinvite) {
2821 return;
2822 }
2823
2824 if (session->channel) {
2825 pjsip_endpt_process_rx_data(ast_sip_get_pjsip_endpoint(),
2826 session->deferred_reinvite, NULL, NULL);
2827 }
2828 pjsip_rx_data_free_cloned(session->deferred_reinvite);
2829 session->deferred_reinvite = NULL;
2830}

References ast_sip_get_pjsip_endpoint(), NULL, and session.

Referenced by t38_automatic_reject(), and t38_interpret_parameters().

◆ ast_sip_session_send_request()

void ast_sip_session_send_request ( struct ast_sip_session session,
pjsip_tx_data *  tdata 
)

Send a SIP request.

This will send the SIP request specified in tdata and call into any registered supplements' outgoing_request callback.

Parameters
sessionThe session to which to send the request
tdataThe request to send

Definition at line 2862 of file res_pjsip_session.c.

2863{
2865}
void ast_sip_session_send_request_with_cb(struct ast_sip_session *session, pjsip_tx_data *tdata, ast_sip_session_response_cb on_response)
Send a SIP request and get called back when a response is received.

References ast_sip_session_send_request_with_cb(), NULL, and session.

Referenced by aoc_send_as_xml(), ast_sip_session_terminate(), call(), check_request_status(), handle_incoming_before_media(), outbound_invite_auth(), session_inv_on_tsx_state_changed(), transmit_info_dtmf(), and transmit_info_with_vidupdate().

◆ ast_sip_session_send_request_with_cb()

void ast_sip_session_send_request_with_cb ( struct ast_sip_session session,
pjsip_tx_data *  tdata,
ast_sip_session_response_cb  on_response 
)

Send a SIP request and get called back when a response is received.

This will send the request out exactly the same as ast_sip_send_request() does. The difference is that when a response arrives, the specified callback will be called into

Parameters
sessionThe session on which to send the request
tdataThe request to send
on_responseCallback to be called when a response is received

Definition at line 2838 of file res_pjsip_session.c.

2840{
2841 pjsip_inv_session *inv_session = session->inv_session;
2842
2843 /* For every request except BYE we disallow sending of the message when
2844 * the session has been disconnected. A BYE request is special though
2845 * because it can be sent again after the session is disconnected except
2846 * with credentials.
2847 */
2848 if (inv_session->state == PJSIP_INV_STATE_DISCONNECTED &&
2849 tdata->msg->line.req.method.id != PJSIP_BYE_METHOD) {
2850 return;
2851 }
2852
2853 ast_sip_mod_data_set(tdata->pool, tdata->mod_data, session_module.id,
2854 MOD_DATA_ON_RESPONSE, on_response);
2855
2857 pjsip_inv_send_msg(session->inv_session, tdata);
2858
2859 return;
2860}
#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:2978
#define MOD_DATA_ON_RESPONSE
static void handle_outgoing_request(struct ast_sip_session *session, pjsip_tx_data *tdata)

References ast_sip_mod_data_set, handle_outgoing_request(), MOD_DATA_ON_RESPONSE, session, and session_module.

Referenced by ast_sip_session_send_request(), session_inv_on_tsx_state_changed(), and sip_session_refresh().

◆ ast_sip_session_send_response()

void ast_sip_session_send_response ( struct ast_sip_session session,
pjsip_tx_data *  tdata 
)

Send a SIP response.

This will send the SIP response specified in tdata and call into any registered supplements' outgoing_response callback.

Parameters
sessionThe session on which to send the response.
tdataThe response to send

Definition at line 2588 of file res_pjsip_session.c.

2589{
2590 pjsip_dialog *dlg = pjsip_tdata_get_dlg(tdata);
2591 RAII_VAR(struct ast_sip_session *, dlg_session, dlg ? ast_sip_dialog_get_session(dlg) : NULL, ao2_cleanup);
2592 if (!dlg_session) {
2593 /* If the dialog has a session, handle_outgoing_response will be called
2594 from session_on_tx_response. If it does not, call it from here. */
2596 }
2597 pjsip_inv_send_msg(session->inv_session, tdata);
2598 return;
2599}
struct ast_sip_session * ast_sip_dialog_get_session(pjsip_dialog *dlg)
Retrieves a session from a dialog.
static void handle_outgoing_response(struct ast_sip_session *session, pjsip_tx_data *tdata)

References ao2_cleanup, ast_sip_dialog_get_session(), handle_outgoing_response(), NULL, RAII_VAR, and session.

Referenced by answer(), ast_sip_session_terminate(), chan_pjsip_incoming_request(), indicate(), new_invite(), pjsip_hangup(), refer_incoming_invite_request(), transfer_redirect(), and update_connected_line_information().

◆ ast_sip_session_suspend()

void ast_sip_session_suspend ( struct ast_sip_session session)

Request and wait for the session serializer to be suspended.

Since
12.7.0
Parameters
sessionWhich session to suspend the serializer.
Note
No channel locks can be held while calling without risk of deadlock.

Definition at line 3175 of file res_pjsip_session.c.

3176{
3177 struct ast_sip_session_suspender *suspender;
3178 int res;
3179
3180 ast_assert(session->suspended == NULL);
3181
3182 if (ast_taskprocessor_is_task(session->serializer)) {
3183 /* I am the session's serializer thread so I cannot suspend. */
3184 return;
3185 }
3186
3187 if (ast_taskprocessor_is_suspended(session->serializer)) {
3188 /* The serializer already suspended. */
3189 return;
3190 }
3191
3192 suspender = ao2_alloc(sizeof(*suspender), sip_session_suspender_dtor);
3193 if (!suspender) {
3194 /* We will just have to hope that the system does not deadlock */
3195 return;
3196 }
3197 ast_cond_init(&suspender->cond_suspended, NULL);
3198 ast_cond_init(&suspender->cond_complete, NULL);
3199
3200 ao2_ref(suspender, +1);
3201 res = ast_sip_push_task(session->serializer, sip_session_suspend_task, suspender);
3202 if (res) {
3203 /* We will just have to hope that the system does not deadlock */
3204 ao2_ref(suspender, -2);
3205 return;
3206 }
3207
3208 session->suspended = suspender;
3209
3210 /* Wait for the serializer to get suspended. */
3211 ao2_lock(suspender);
3212 while (!suspender->suspended) {
3213 ast_cond_wait(&suspender->cond_suspended, ao2_object_get_lockaddr(suspender));
3214 }
3215 ao2_unlock(suspender);
3216
3218}
#define ao2_unlock(a)
Definition: astobj2.h:729
#define ao2_lock(a)
Definition: astobj2.h:717
void * ao2_object_get_lockaddr(void *obj)
Return the mutex lock address of an object.
Definition: astobj2.c:476
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:2099
#define ast_cond_wait(cond, mutex)
Definition: lock.h:205
#define ast_cond_init(cond, attr)
Definition: lock.h:201
static int sip_session_suspend_task(void *data)
static void sip_session_suspender_dtor(void *vdoomed)
struct controlling the suspension of the session's serializer.
int ast_taskprocessor_is_suspended(struct ast_taskprocessor *tps)
Get the task processor suspend status.
int ast_taskprocessor_is_task(struct ast_taskprocessor *tps)
Am I the given taskprocessor's current task.
int ast_taskprocessor_suspend(struct ast_taskprocessor *tps)
Indicate the taskprocessor is suspended.

References ao2_alloc, ao2_lock, ao2_object_get_lockaddr(), ao2_ref, ao2_unlock, ast_assert, ast_cond_init, ast_cond_wait, ast_sip_push_task(), ast_taskprocessor_is_suspended(), ast_taskprocessor_is_task(), ast_taskprocessor_suspend(), ast_sip_session_suspender::cond_complete, ast_sip_session_suspender::cond_suspended, NULL, session, sip_session_suspend_task(), sip_session_suspender_dtor(), and ast_sip_session_suspender::suspended.

Referenced by chan_pjsip_indicate().

◆ ast_sip_session_terminate()

void ast_sip_session_terminate ( struct ast_sip_session session,
int  response 
)

Terminate a session and, if possible, send the provided response code.

Parameters
sessionThe session to terminate
responseThe response code to use for termination if possible
Warning
Calling this function MAY cause the last session reference to be released and the session destructor to be called. If you need to do something with session after this call, be sure to bump the ref count before calling terminate.

Definition at line 3471 of file res_pjsip_session.c.

3472{
3473 pj_status_t status;
3474 pjsip_tx_data *packet = NULL;
3475 SCOPE_ENTER(1, "%s Response %d\n", ast_sip_session_get_name(session), response);
3476
3477 if (session->defer_terminate) {
3478 session->terminate_while_deferred = 1;
3479 SCOPE_EXIT_RTN("Deferred\n");
3480 }
3481
3482 if (!response) {
3483 response = 603;
3484 }
3485
3486 /* The media sessions need to exist for the lifetime of the underlying channel
3487 * to ensure that anything (such as bridge_native_rtp) has access to them as
3488 * appropriate. Since ast_sip_session_terminate is called by chan_pjsip and other
3489 * places when the session is to be terminated we terminate any existing
3490 * media sessions here.
3491 */
3492 ast_sip_session_media_stats_save(session, session->active_media_state);
3493 SWAP(session->active_media_state, session->pending_media_state);
3494 ast_sip_session_media_state_reset(session->pending_media_state);
3495
3496 switch (session->inv_session->state) {
3497 case PJSIP_INV_STATE_NULL:
3498 if (!session->inv_session->invite_tsx) {
3499 /*
3500 * Normally, it's pjproject's transaction cleanup that ultimately causes the
3501 * final session reference to be released but if both STATE and invite_tsx are NULL,
3502 * we never created a transaction in the first place. In this case, we need to
3503 * do the cleanup ourselves.
3504 */
3505 /* Transfer the inv_session session reference to the session_end_task */
3506 session->inv_session->mod_data[session_module.id] = NULL;
3507 pjsip_inv_terminate(session->inv_session, response, PJ_TRUE);
3509 /*
3510 * session_end_completion will cleanup the final session reference unless
3511 * ast_sip_session_terminate's caller is holding one.
3512 */
3514 } else {
3515 pjsip_inv_terminate(session->inv_session, response, PJ_TRUE);
3516 }
3517 break;
3518 case PJSIP_INV_STATE_CONFIRMED:
3519 if (session->inv_session->invite_tsx) {
3520 ast_debug(3, "%s: Delay sending BYE because of outstanding transaction...\n",
3522 /* If this is delayed the only thing that will happen is a BYE request so we don't
3523 * actually need to store the response code for when it happens.
3524 */
3526 break;
3527 }
3528 /* Fall through */
3529 default:
3530 status = pjsip_inv_end_session(session->inv_session, response, NULL, &packet);
3531 if (status == PJ_SUCCESS && packet) {
3532 struct ast_sip_session_delayed_request *delay;
3533
3534 /* Flush any delayed requests so they cannot overlap this transaction. */
3535 while ((delay = AST_LIST_REMOVE_HEAD(&session->delayed_requests, next))) {
3536 delayed_request_free(delay);
3537 }
3538
3539 if (packet->msg->type == PJSIP_RESPONSE_MSG) {
3541 } else {
3543 }
3544 }
3545 break;
3546 }
3548}
jack_status_t status
Definition: app_jack.c:146
#define SCOPE_EXIT_RTN(...)
static int session_end_completion(void *vsession)
void ast_sip_session_send_request(struct ast_sip_session *session, pjsip_tx_data *tdata)
Send a SIP request.
static int delay_request(struct ast_sip_session *session, ast_sip_session_request_creation_cb on_request, ast_sip_session_sdp_creation_cb on_sdp_creation, ast_sip_session_response_cb on_response, int generate_new_sdp, enum delayed_method method, struct ast_sip_session_media_state *pending_media_state, struct ast_sip_session_media_state *active_media_state, int queue_head)
@ DELAYED_METHOD_BYE
static void delayed_request_free(struct ast_sip_session_delayed_request *delay)
void ast_sip_session_send_response(struct ast_sip_session *session, pjsip_tx_data *tdata)
Send a SIP response.
void ast_sip_session_media_stats_save(struct ast_sip_session *sip_session, struct ast_sip_session_media_state *media_state)
Save a media stats.
Structure used for sending delayed requests.
struct ast_sip_session_delayed_request * next
#define SWAP(a, b)
Definition: utils.h:235

References ast_debug, AST_LIST_REMOVE_HEAD, ast_sip_session_get_name(), ast_sip_session_media_state_reset(), ast_sip_session_media_stats_save(), ast_sip_session_send_request(), ast_sip_session_send_response(), delay_request(), DELAYED_METHOD_BYE, delayed_request_free(), ast_sip_session_delayed_request::next, NULL, SCOPE_ENTER, SCOPE_EXIT_RTN, session, session_end(), session_end_completion(), session_module, status, and SWAP.

Referenced by ast_sip_session_defer_termination_cancel(), chan_pjsip_incoming_request(), hangup(), reject_incoming_call(), send_delayed_request(), and session_termination_task().

◆ ast_sip_session_unregister_sdp_handler()

void ast_sip_session_unregister_sdp_handler ( struct ast_sip_session_sdp_handler handler,
const char *  stream_type 
)

Unregister an SDP handler.

Parameters
handlerThe SDP handler to unregister
stream_typeStream type for which the SDP handler was registered

Definition at line 208 of file res_pjsip_session.c.

209{
211}
#define ao2_callback_data(container, flags, cb_fn, arg, data)
Definition: astobj2.h:1723
static int remove_handler(void *obj, void *arg, void *data, int flags)

References ao2_callback_data, handler(), OBJ_KEY, OBJ_NODATA, OBJ_UNLINK, remove_handler(), and sdp_handlers.

Referenced by unload_module().

◆ ast_sip_session_unregister_supplement()

void ast_sip_session_unregister_supplement ( struct ast_sip_session_supplement supplement)

Unregister a an supplement to SIP session processing.

Parameters
supplementThe supplement to unregister

Definition at line 63 of file pjsip_session.c.

64{
65 struct ast_sip_session_supplement *iter;
67
69 if (supplement == iter) {
71 break;
72 }
73 }
75}
#define AST_RWLIST_REMOVE_CURRENT
Definition: linkedlists.h:570

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

Referenced by ast_res_pjsip_cleanup_message_filter(), load_module(), pjsip_reason_header_unload(), and unload_module().

◆ ast_sip_session_unsuspend()

void ast_sip_session_unsuspend ( struct ast_sip_session session)

Request the session serializer be unsuspended.

Since
12.7.0
Parameters
sessionWhich session to unsuspend the serializer.

Definition at line 3220 of file res_pjsip_session.c.

3221{
3222 struct ast_sip_session_suspender *suspender = session->suspended;
3223
3224 if (!suspender) {
3225 /* Nothing to do */
3226 return;
3227 }
3228 session->suspended = NULL;
3229
3230 /* Signal that the serializer task suspension is now complete. */
3231 ao2_lock(suspender);
3232 suspender->complete = 1;
3233 ast_cond_signal(&suspender->cond_complete);
3234 ao2_unlock(suspender);
3235
3236 ao2_ref(suspender, -1);
3237
3239}
#define ast_cond_signal(cond)
Definition: lock.h:203
int ast_taskprocessor_unsuspend(struct ast_taskprocessor *tps)
Indicate the taskprocessor is unsuspended.

References ao2_lock, ao2_ref, ao2_unlock, ast_cond_signal, ast_taskprocessor_unsuspend(), ast_sip_session_suspender::complete, ast_sip_session_suspender::cond_complete, NULL, and session.

Referenced by chan_pjsip_indicate().