Asterisk - The Open Source Telephony Project GIT-master-4f2b068
Loading...
Searching...
No Matches
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.
 
struct ast_sip_channel_pvtast_sip_channel_pvt_alloc (void *pvt, struct ast_sip_session *session)
 Allocate a new SIP channel pvt structure.
 
struct ast_sip_sessionast_sip_dialog_get_session (pjsip_dialog *dlg)
 Retrieves a session from a dialog.
 
int ast_sip_session_add_datastore (struct ast_sip_session *session, struct ast_datastore *datastore)
 Add a datastore to a SIP session.
 
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.
 
int ast_sip_session_add_supplements (struct ast_sip_session *session)
 Add supplements to a SIP session.
 
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.
 
struct ast_datastoreast_sip_session_alloc_datastore (const struct ast_datastore_info *info, const char *uid)
 Alternative for ast_datastore_alloc()
 
int ast_sip_session_create_invite (struct ast_sip_session *session, pjsip_tx_data **tdata)
 Creates an INVITE request.
 
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.
 
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.
 
void ast_sip_session_defer_termination_cancel (struct ast_sip_session *session)
 Cancel a pending deferred termination.
 
void ast_sip_session_end_if_deferred (struct ast_sip_session *session)
 End the session if it had been previously deferred.
 
struct ast_datastoreast_sip_session_get_datastore (struct ast_sip_session *session, const char *name)
 Retrieve a session datastore.
 
pjsip_dialog * ast_sip_session_get_dialog (const struct ast_sip_session *session)
 Retrieves a dialog from a session.
 
const char * ast_sip_session_get_name (const struct ast_sip_session *session)
 Get the channel or endpoint name associated with the session.
 
pjsip_inv_state ast_sip_session_get_pjsip_inv_state (const struct ast_sip_session *session)
 Retrieves the pjsip_inv_state from a session.
 
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.
 
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.
 
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.
 
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.
 
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.
 
struct ast_sip_session_media_stateast_sip_session_media_state_alloc (void)
 Allocate a session media state structure.
 
struct ast_sip_session_media_stateast_sip_session_media_state_clone (const struct ast_sip_session_media_state *media_state)
 Clone a media state.
 
void ast_sip_session_media_state_free (struct ast_sip_session_media_state *media_state)
 Free a session media state structure.
 
void ast_sip_session_media_state_reset (struct ast_sip_session_media_state *media_state)
 Reset a media state to a clean state.
 
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.
 
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.
 
int ast_sip_session_regenerate_answer (struct ast_sip_session *session, ast_sip_session_sdp_creation_cb on_sdp_creation)
 Regenerate SDP Answer.
 
int ast_sip_session_register_sdp_handler (struct ast_sip_session_sdp_handler *handler, const char *stream_type)
 Register an SDP handler.
 
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.
 
void ast_sip_session_remove_datastore (struct ast_sip_session *session, const char *name)
 Remove a session datastore from the session.
 
void ast_sip_session_remove_supplements (struct ast_sip_session *session)
 Remove supplements from a SIP session.
 
void ast_sip_session_resume_reinvite (struct ast_sip_session *session)
 Resumes processing of a deferred incoming re-invite.
 
void ast_sip_session_send_request (struct ast_sip_session *session, pjsip_tx_data *tdata)
 Send a SIP request.
 
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.
 
void ast_sip_session_send_response (struct ast_sip_session *session, pjsip_tx_data *tdata)
 Send a SIP response.
 
void ast_sip_session_suspend (struct ast_sip_session *session)
 Request and wait for the session serializer to be suspended.
 
void ast_sip_session_terminate (struct ast_sip_session *session, int response)
 Terminate a session and, if possible, send the provided response code.
 
void ast_sip_session_unregister_sdp_handler (struct ast_sip_session_sdp_handler *handler, const char *stream_type)
 Unregister an SDP handler.
 
void ast_sip_session_unregister_supplement (struct ast_sip_session_supplement *supplement)
 Unregister a an supplement to SIP session processing.
 
void ast_sip_session_unsuspend (struct ast_sip_session *session)
 Request the session serializer be unsuspended.
 

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 618 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 252 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 253 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 254 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 265 of file res_pjsip_session.h.

265 {
266 /*!
267 * When processing 3XX responses, the supplement is called into before
268 * the redirecting information is processed.
269 */
271 /*!
272 * For responses to INVITE transactions, the supplement is called into
273 * before media is negotiated.
274 *
275 * This priority is applied by default to any session supplement that
276 * does not specify a response priority.
277 */
279 /*!
280 * For INVITE transactions, the supplement is called into after media
281 * is negotiated.
282 */
284};
@ 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 369 of file res_pjsip_session.h.

369 {
370 /*! The stream was not handled by this handler. If there are other registered handlers for this stream type, they will be called. */
372 /*! There was an error encountered. No further operations will take place and the current negotiation will be abandoned. */
374 /*! Re-invite is not needed */
376 /*! Re-invite should be deferred and will be resumed later. No further operations will take place. */
378};
@ 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 132 of file res_pjsip_session.c.

133{
134 return id->number.valid
135 && (session->endpoint->id.trust_outbound
137}
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:1807

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 2995 of file res_pjsip_session.c.

2996{
2997 struct ast_sip_channel_pvt *channel = ao2_alloc(sizeof(*channel), sip_channel_destroy);
2998
2999 if (!channel) {
3000 return NULL;
3001 }
3002
3003 ao2_ref(pvt, +1);
3004 channel->pvt = pvt;
3005 ao2_ref(session, +1);
3006 channel->session = session;
3007
3008 return channel;
3009}
#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 3548 of file res_pjsip_session.c.

3549{
3550 pjsip_inv_session *inv_session = pjsip_dlg_get_inv_session(dlg);
3551 struct ast_sip_session *session;
3552
3553 if (!inv_session ||
3554 !(session = inv_session->mod_data[session_module.id])) {
3555 return NULL;
3556 }
3557
3558 ao2_ref(session, +1);
3559
3560 return session;
3561}
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_ari_request(), 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 1285 of file res_pjsip_session.c.

1286{
1287 ast_assert(datastore != NULL);
1288 ast_assert(datastore->info != NULL);
1289 ast_assert(ast_strlen_zero(datastore->uid) == 0);
1290
1291 if (!ao2_link(session->datastores, datastore)) {
1292 return -1;
1293 }
1294 return 0;
1295}
#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:779

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(), outgoing_request(), 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;
144 rr->response_str = ast_strdup(text);
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}
#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:981

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:337
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.
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
#define AST_RWLIST_TRAVERSE
#define SCOPED_LOCK(varname, lock, lockfunc, unlockfunc)
Scoped Locks.
Definition lock.h:590
#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)
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 3011 of file res_pjsip_session.c.

3013{
3015 struct ast_sip_session *ret_session;
3016 int dsp_features = 0;
3017
3019 if (!session) {
3020 return NULL;
3021 }
3022
3023 AST_LIST_HEAD_INIT(&session->supplements);
3024 AST_LIST_HEAD_INIT_NOLOCK(&session->delayed_requests);
3026
3028 if (!session->direct_media_cap) {
3029 return NULL;
3030 }
3033 if (!session->datastores) {
3034 return NULL;
3035 }
3036 session->active_media_state = ast_sip_session_media_state_alloc();
3037 if (!session->active_media_state) {
3038 return NULL;
3039 }
3040 session->pending_media_state = ast_sip_session_media_state_alloc();
3041 if (!session->pending_media_state) {
3042 return NULL;
3043 }
3044 if (AST_VECTOR_INIT(&session->media_stats, 1) < 0) {
3045 return NULL;
3046 }
3047
3049 dsp_features |= DSP_FEATURE_DIGIT_DETECT;
3050 }
3051 if (endpoint->faxdetect) {
3052 dsp_features |= DSP_FEATURE_FAX_DETECT;
3053 }
3054 if (dsp_features) {
3055 session->dsp = ast_dsp_new();
3056 if (!session->dsp) {
3057 return NULL;
3058 }
3059
3060 ast_dsp_set_features(session->dsp, dsp_features);
3061 }
3062
3063 session->endpoint = ao2_bump(endpoint);
3064
3065 if (rdata) {
3066 /*
3067 * We must continue using the serializer that the original
3068 * INVITE came in on for the dialog. There may be
3069 * retransmissions already enqueued in the original
3070 * serializer that can result in reentrancy and message
3071 * sequencing problems.
3072 */
3073 session->serializer = ast_sip_get_distributor_serializer(rdata);
3074 } else {
3075 char tps_name[AST_TASKPROCESSOR_MAX_NAME + 1];
3076
3077 /* Create name with seq number appended. */
3078 ast_taskprocessor_build_name(tps_name, sizeof(tps_name), "pjsip/outsess/%s",
3080
3081 session->serializer = ast_sip_create_serializer(tps_name);
3082 }
3083 if (!session->serializer) {
3084 return NULL;
3085 }
3088
3089 /* When a PJSIP INVITE session is created it is created with a reference
3090 * count of 1, with that reference being managed by the underlying state
3091 * of the INVITE session itself. When the INVITE session transitions to
3092 * a DISCONNECTED state that reference is released. This means we can not
3093 * rely on that reference to ensure the INVITE session remains for the
3094 * lifetime of our session. To ensure it does we add our own reference
3095 * and release it when our own session goes away, ensuring that the INVITE
3096 * session remains for the lifetime of session.
3097 */
3098
3099#ifdef HAVE_PJSIP_INV_SESSION_REF
3100 if (pjsip_inv_add_ref(inv_session) != PJ_SUCCESS) {
3101 ast_log(LOG_ERROR, "Can't increase the session reference counter\n");
3102 return NULL;
3103 }
3104#endif
3105
3106 pjsip_dlg_inc_session(inv_session->dlg, &session_module);
3107 inv_session->mod_data[session_module.id] = ao2_bump(session);
3108 session->contact = ao2_bump(contact);
3109 session->inv_session = inv_session;
3110
3111 session->dtmf = endpoint->dtmf;
3112 session->moh_passthrough = endpoint->moh_passthrough;
3113
3115 /* Release the ref held by session->inv_session */
3116 ao2_ref(session, -1);
3117 return NULL;
3118 }
3119
3120 session->authentication_challenge_count = 0;
3121
3122 /* Fire session begin handlers */
3124
3125 /* Avoid unnecessary ref manipulation to return a session */
3126 ret_session = session;
3127 session = NULL;
3128 return ret_session;
3129}
#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:1743
#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:1772
struct ast_dsp * ast_dsp_new(void)
Allocates a new dsp, assumes 8khz for internal sample rate.
Definition dsp.c:1762
@ 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:2088
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.
#define AST_LIST_HEAD_INIT(head)
Initializes a list head structure.
@ AST_SIP_DTMF_AUTO
Definition res_pjsip.h:556
@ AST_SIP_DTMF_INBAND
Definition res_pjsip.h:552
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.
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition sorcery.c:2381
unsigned int moh_passthrough
Definition res_pjsip.h:1134
enum ast_sip_dtmf_mode dtmf
Definition res_pjsip.h:1110
unsigned int faxdetect
Definition res_pjsip.h:1122
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).
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition vector.h:124

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 1255 of file res_pjsip_session.c.

1256{
1257 RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
1258 char uuid_buf[AST_UUID_STR_LEN];
1259 const char *uid_ptr = uid;
1260
1261 if (!info) {
1262 return NULL;
1263 }
1264
1265 datastore = ao2_alloc(sizeof(*datastore), session_datastore_destroy);
1266 if (!datastore) {
1267 return NULL;
1268 }
1269
1270 datastore->info = info;
1271 if (ast_strlen_zero(uid)) {
1272 /* They didn't provide an ID so we'll provide one ourself */
1273 uid_ptr = ast_uuid_generate_str(uuid_buf, sizeof(uuid_buf));
1274 }
1275
1276 datastore->uid = ast_strdup(uid_ptr);
1277 if (!datastore->uid) {
1278 return NULL;
1279 }
1280
1281 ao2_ref(datastore, +1);
1282 return datastore;
1283}
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, ast_datastore::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(), outgoing_request(), 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 2868 of file res_pjsip_session.c.

2869{
2870 pjmedia_sdp_session *offer;
2872
2873 if (!(offer = create_local_sdp(session->inv_session, session, NULL, 0))) {
2874 pjsip_inv_terminate(session->inv_session, 500, PJ_FALSE);
2875 SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create offer\n");
2876 }
2877
2878 pjsip_inv_set_local_sdp(session->inv_session, offer);
2879 pjmedia_sdp_neg_set_prefer_remote_codec_order(session->inv_session->neg, PJ_FALSE);
2880#ifdef PJMEDIA_SDP_NEG_ANSWER_MULTIPLE_CODECS
2881 if (!session->endpoint->preferred_codec_only) {
2882 pjmedia_sdp_neg_set_answer_multiple_codecs(session->inv_session->neg, PJ_TRUE);
2883 }
2884#endif
2885
2886 /*
2887 * We MUST call set_from_header() before pjsip_inv_invite. If we don't, the
2888 * From in the initial INVITE will be wrong but the rest of the messages will be OK.
2889 */
2891
2892 if (pjsip_inv_invite(session->inv_session, tdata) != PJ_SUCCESS) {
2893 SCOPE_EXIT_RTN_VALUE(-1, "pjsip_inv_invite failed\n");
2894 }
2895
2897}
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 3237 of file res_pjsip_session.c.

3240{
3241 const char *uri = NULL;
3242 RAII_VAR(struct ast_sip_aor *, found_aor, NULL, ao2_cleanup);
3243 RAII_VAR(struct ast_sip_contact *, found_contact, NULL, ao2_cleanup);
3244 pjsip_timer_setting timer;
3245 pjsip_dialog *dlg;
3246 struct pjsip_inv_session *inv_session;
3248 struct ast_sip_session *ret_session;
3249 SCOPE_ENTER(1, "%s %s Topology: %s\n", ast_sorcery_object_get_id(endpoint), request_user,
3250 ast_str_tmp(256, ast_stream_topology_to_str(req_topology, &STR_TMP)));
3251
3252 /* If no location has been provided use the AOR list from the endpoint itself */
3253 if (location || !contact) {
3254 location = S_OR(location, endpoint->aors);
3255
3257 &found_aor, &found_contact);
3258 if (!found_contact || ast_strlen_zero(found_contact->uri)) {
3259 uri = location;
3260 } else {
3261 uri = found_contact->uri;
3262 }
3263 } else {
3264 uri = contact->uri;
3265 }
3266
3267 /* If we still have no URI to dial fail to create the session */
3268 if (ast_strlen_zero(uri)) {
3269 ast_log(LOG_ERROR, "Endpoint '%s': No URI available. Is endpoint registered?\n",
3271 SCOPE_EXIT_RTN_VALUE(NULL, "No URI\n");
3272 }
3273
3274 if (!(dlg = ast_sip_create_dialog_uac(endpoint, uri, request_user))) {
3275 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create dialog\n");
3276 }
3277
3278 if (setup_outbound_invite_auth(dlg)) {
3279 pjsip_dlg_terminate(dlg);
3280 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't setup auth\n");
3281 }
3282
3283 if (pjsip_inv_create_uac(dlg, NULL, endpoint->extensions.flags, &inv_session) != PJ_SUCCESS) {
3284 pjsip_dlg_terminate(dlg);
3285 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create uac\n");
3286 }
3287#if defined(HAVE_PJSIP_REPLACE_MEDIA_STREAM) || defined(PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE)
3288 inv_session->sdp_neg_flags = PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE;
3289#endif
3290
3291 pjsip_timer_setting_default(&timer);
3293 timer.sess_expires = endpoint->extensions.timer.sess_expires;
3294 pjsip_timer_init_session(inv_session, &timer);
3295
3296 session = ast_sip_session_alloc(endpoint, found_contact ? found_contact : contact,
3297 inv_session, NULL);
3298 if (!session) {
3299 pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
3300 return NULL;
3301 }
3302 session->aor = ao2_bump(found_aor);
3303 session->call_direction = AST_SIP_SESSION_OUTGOING_CALL;
3304
3306
3307 if (ast_stream_topology_get_count(req_topology) > 0) {
3308 /* get joint caps between req_topology and endpoint topology */
3309 int i;
3310
3311 for (i = 0; i < ast_stream_topology_get_count(req_topology); ++i) {
3312 struct ast_stream *req_stream;
3313 struct ast_stream *clone_stream;
3314
3315 req_stream = ast_stream_topology_get_stream(req_topology, i);
3316
3318 continue;
3319 }
3320
3321 clone_stream = ast_sip_session_create_joint_call_stream(session, req_stream);
3322 if (!clone_stream || ast_stream_get_format_count(clone_stream) == 0) {
3323 ast_stream_free(clone_stream);
3324 continue;
3325 }
3326
3327 if (!session->pending_media_state->topology) {
3328 session->pending_media_state->topology = ast_stream_topology_alloc();
3329 if (!session->pending_media_state->topology) {
3330 pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
3331 ao2_ref(session, -1);
3332 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create topology\n");
3333 }
3334 }
3335
3336 if (ast_stream_topology_append_stream(session->pending_media_state->topology, clone_stream) < 0) {
3337 ast_stream_free(clone_stream);
3338 continue;
3339 }
3340 }
3341 }
3342
3343 if (!session->pending_media_state->topology) {
3344 /* Use the configured topology on the endpoint as the pending one */
3345 session->pending_media_state->topology = ast_stream_topology_clone(endpoint->media.topology);
3346 if (!session->pending_media_state->topology) {
3347 pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
3348 ao2_ref(session, -1);
3349 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't clone topology\n");
3350 }
3351 }
3352
3353 if (pjsip_dlg_add_usage(dlg, &session_module, NULL) != PJ_SUCCESS) {
3354 pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
3355 /* Since we are not notifying ourselves that the INVITE session is being terminated
3356 * we need to manually drop its reference to session
3357 */
3358 ao2_ref(session, -1);
3359 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't add usage\n");
3360 }
3361
3362 /* Avoid unnecessary ref manipulation to return a session */
3363 ret_session = session;
3364 session = NULL;
3365 SCOPE_EXIT_RTN_VALUE(ret_session);
3366}
static struct ast_timer * timer
Definition chan_iax2.c:388
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:1751
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:958
@ AST_SIP_CONTACT_FILTER_REACHABLE
Return only reachable or unknown contacts.
Definition res_pjsip.h:1437
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:652
@ 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:751
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:939
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:791
int ast_stream_topology_get_count(const struct ast_stream_topology *topology)
Get the number of streams in a topology.
Definition stream.c:768
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:670
#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:390
const ast_string_field uri
Definition res_pjsip.h:412
struct ast_sip_timer_options timer
Definition res_pjsip.h:819
struct ast_stream_topology * topology
Definition res_pjsip.h:1021
struct ast_sip_endpoint_id_configuration id
Definition res_pjsip.h:1100
const ast_string_field aors
Definition res_pjsip.h:1090
struct ast_sip_endpoint_extensions extensions
Definition res_pjsip.h:1092
struct ast_sip_endpoint_media_configuration media
Definition res_pjsip.h:1094
unsigned int sess_expires
Definition res_pjsip.h:806
unsigned int min_se
Definition res_pjsip.h:804

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 3474 of file res_pjsip_session.c.

3475{
3476 pj_time_val delay = { .sec = 60, };
3477 int res;
3478
3479 /* The session should not have an active deferred termination request. */
3480 ast_assert(!session->defer_terminate);
3481
3482 session->defer_terminate = 1;
3483
3484 session->defer_end = 1;
3485 session->ended_while_deferred = 0;
3486
3487 ao2_ref(session, +1);
3488 pj_timer_entry_init(&session->scheduled_termination, 0, session, session_termination_cb);
3489
3490 res = (pjsip_endpt_schedule_timer(ast_sip_get_pjsip_endpoint(),
3491 &session->scheduled_termination, &delay) != PJ_SUCCESS) ? -1 : 0;
3492 if (res) {
3493 session->defer_terminate = 0;
3494 ao2_ref(session, -1);
3495 }
3496 return res;
3497}
pjsip_endpoint * ast_sip_get_pjsip_endpoint(void)
Get a pointer to the PJSIP endpoint.
Definition res_pjsip.c:514
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 3514 of file res_pjsip_session.c.

3515{
3516 if (!session->defer_terminate) {
3517 /* Already canceled or timer fired. */
3518 return;
3519 }
3520
3521 session->defer_terminate = 0;
3522
3523 if (session->terminate_while_deferred) {
3524 /* Complete the termination started by the upper layer. */
3526 }
3527
3528 /* Stop the termination timer if it is still running. */
3530}
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 3532 of file res_pjsip_session.c.

3533{
3534 if (!session->defer_end) {
3535 return;
3536 }
3537
3538 session->defer_end = 0;
3539
3540 if (session->ended_while_deferred) {
3541 /* Complete the session end started by the remote hangup. */
3542 ast_debug(3, "%s: Ending session after being deferred\n", ast_sip_session_get_name(session));
3543 session->ended_while_deferred = 0;
3545 }
3546}
#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 1297 of file res_pjsip_session.c.

1298{
1299 return ao2_find(session->datastores, name, OBJ_KEY);
1300}
#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 3563 of file res_pjsip_session.c.

3564{
3565 pjsip_inv_session *inv_session = session->inv_session;
3566
3567 if (!inv_session) {
3568 return NULL;
3569 }
3570
3571 return inv_session->dlg;
3572}

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 118 of file res_pjsip_session.c.

119{
120 if (!session) {
121 return "(null session)";
122 }
123 if (session->channel) {
124 return ast_channel_name(session->channel);
125 } else if (session->endpoint) {
126 return ast_sorcery_object_get_id(session->endpoint);
127 } else {
128 return "unknown";
129 }
130}
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_request(), handle_incoming_response(), handle_incoming_sdp(), handle_negotiated_sdp(), handle_negotiated_sdp_session_media(), handle_new_invite_request(), handle_outgoing_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 3574 of file res_pjsip_session.c.

3575{
3576 pjsip_inv_session *inv_session = session->inv_session;
3577
3578 if (!inv_session) {
3579 return PJSIP_INV_STATE_NULL;
3580 }
3581
3582 return inv_session->state;
3583}

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 369 of file res_pjsip_session.c.

370{
371 int index;
372
373 if (!session->pending_media_state->topology) {
374 ast_log(LOG_WARNING, "Pending topology was NULL for channel '%s'\n",
375 session->channel ? ast_channel_name(session->channel) : "unknown");
376 return 0;
377 }
378
380 return 0;
381 }
382
383 for (index = 0; index < ast_stream_topology_get_count(session->pending_media_state->topology); ++index) {
384 if (ast_stream_get_type(ast_stream_topology_get_stream(session->pending_media_state->topology, index)) !=
385 ast_stream_get_type(stream)) {
386 continue;
387 }
388
389 return ast_stream_topology_get_stream(session->pending_media_state->topology, index) == stream ? 1 : 0;
390 }
391
392 return 0;
393}
#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 395 of file res_pjsip_session.c.

397{
398 struct ast_sip_session_media_read_callback_state callback_state = {
399 .fd = fd,
400 .read_callback = callback,
401 .session = session_media,
402 };
403
404 /* The contents of the vector are whole structs and not pointers */
405 return AST_VECTOR_APPEND(&session->pending_media_state->read_callbacks, callback_state);
406}
static struct ast_channel * callback(struct ast_channelstorage_instance *driver, ao2_callback_data_fn *cb_fn, void *arg, void *data, int ao2_flags, int rdlock)
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:267

References AST_VECTOR_APPEND, callback(), ast_sip_session_media_read_callback_state::fd, and session.

Referenced by apply_negotiated_sdp_stream(), and 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 424 of file res_pjsip_session.c.

425{
426 int index;
427
428 if (!session->endpoint->media.bundle || ast_strlen_zero(session_media->mid)) {
429 return session_media;
430 }
431
432 for (index = 0; index < AST_VECTOR_SIZE(&session->pending_media_state->sessions); ++index) {
433 struct ast_sip_session_media *bundle_group_session_media;
434
435 bundle_group_session_media = AST_VECTOR_GET(&session->pending_media_state->sessions, index);
436
437 /* The first session which is in the bundle group is considered the authoritative session for transport */
438 if (bundle_group_session_media->bundle_group == session_media->bundle_group) {
439 return bundle_group_session_media;
440 }
441 }
442
443 return session_media;
444}
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:620
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition vector.h:691

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 408 of file res_pjsip_session.c.

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

References callback(), and ast_sip_session_media::write_callback.

Referenced by apply_negotiated_sdp_stream(), and 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 500 of file res_pjsip_session.c.

502{
503 struct ast_sip_session_media *session_media = NULL;
504 struct ast_sip_session_media *current_session_media = NULL;
505 SCOPE_ENTER(1, "%s Adding position %d\n", ast_sip_session_get_name(session), position);
506
507 /* It is possible for this media state to already contain a session for the stream. If this
508 * is the case we simply return it.
509 */
510 if (position < AST_VECTOR_SIZE(&media_state->sessions)) {
511 current_session_media = AST_VECTOR_GET(&media_state->sessions, position);
512 if (current_session_media && current_session_media->type == type) {
513 SCOPE_EXIT_RTN_VALUE(current_session_media, "Using existing media_session\n");
514 }
515 }
516
517 /* Determine if we can reuse the session media from the active media state if present */
518 if (position < AST_VECTOR_SIZE(&session->active_media_state->sessions)) {
519 session_media = AST_VECTOR_GET(&session->active_media_state->sessions, position);
520 /* A stream can never exist without an accompanying media session */
521 if (session_media->type == type) {
522 ao2_ref(session_media, +1);
523 ast_trace(1, "Reusing existing media session\n");
524 /*
525 * If this session_media was previously removed, its bundle group was probably reset
526 * to -1 so if bundling is enabled on the endpoint, we need to reset it to 0, set
527 * the bundled flag and reset its mid.
528 */
529 if (session->endpoint->media.bundle && session_media->bundle_group == -1) {
530 session_media->bundled = session->endpoint->media.webrtc;
531 session_media->bundle_group = 0;
532 ast_free(session_media->mid);
533 if (ast_asprintf(&session_media->mid, "%s-%d", ast_codec_media_type2str(type), position) < 0) {
534 ao2_ref(session_media, -1);
535 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't alloc mid\n");
536 }
537 }
538 } else {
539 ast_trace(1, "Can't reuse existing media session because the types are different. %s <> %s\n",
541 session_media = NULL;
542 }
543 }
544
545 if (!session_media) {
546 /* No existing media session we can use so create a new one */
547 session_media = ao2_alloc_options(sizeof(*session_media), session_media_dtor, AO2_ALLOC_OPT_LOCK_NOLOCK);
548 if (!session_media) {
549 return NULL;
550 }
551 ast_trace(1, "Creating new media session\n");
552
553 session_media->encryption = session->endpoint->media.rtp.encryption;
554 session_media->remote_ice = session->endpoint->media.rtp.ice_support;
555 session_media->remote_rtcp_mux = session->endpoint->media.rtcp_mux;
556 session_media->keepalive_sched_id = -1;
557 session_media->timeout_sched_id = -1;
558 session_media->type = type;
559 session_media->stream_num = position;
560
561 if (session->endpoint->media.bundle) {
562 /* This is a new stream so create a new mid based on media type and position, which makes it unique.
563 * If this is the result of an offer the mid will just end up getting replaced.
564 */
565 if (ast_asprintf(&session_media->mid, "%s-%d", ast_codec_media_type2str(type), position) < 0) {
566 ao2_ref(session_media, -1);
567 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't alloc mid\n");
568 }
569 session_media->bundle_group = 0;
570
571 /* Some WebRTC clients can't handle an offer to bundle media streams. Instead they expect them to
572 * already be bundled. Every client handles this scenario though so if WebRTC is enabled just go
573 * ahead and treat the streams as having already been bundled.
574 */
575 session_media->bundled = session->endpoint->media.webrtc;
576 } else {
577 session_media->bundle_group = -1;
578 }
579 }
580
581 ast_free(session_media->stream_name);
582 session_media->stream_name = ast_strdup(ast_stream_get_name(ast_stream_topology_get_stream(media_state->topology, position)));
583
584 if (AST_VECTOR_REPLACE(&media_state->sessions, position, session_media)) {
585 ao2_ref(session_media, -1);
586
587 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't replace media_session\n");
588 }
589
590 ao2_cleanup(current_session_media);
591
592 /* 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 */
594 ast_trace(1, "Setting media session as default for %s\n", ast_codec_media_type2str(session_media->type));
595
596 media_state->default_session[type] = session_media;
597 }
598
599 SCOPE_EXIT_RTN_VALUE(session_media, "Done\n");
600}
#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[]
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_sip_session_media_state::@282 sessions
Mapping of stream to media sessions.
struct ast_stream_topology * topology
The media stream topology.
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:295

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 248 of file res_pjsip_session.c.

249{
252}
#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 307 of file res_pjsip_session.c.

308{
309 struct ast_sip_session_media_state *cloned;
310 int index;
311
312 if (!media_state) {
313 return NULL;
314 }
315
317 AST_VECTOR_SIZE(&media_state->sessions),
318 AST_VECTOR_SIZE(&media_state->read_callbacks));
319 if (!cloned) {
320 return NULL;
321 }
322
323 if (media_state->topology) {
324 cloned->topology = ast_stream_topology_clone(media_state->topology);
325 if (!cloned->topology) {
327 return NULL;
328 }
329 }
330
331 for (index = 0; index < AST_VECTOR_SIZE(&media_state->sessions); ++index) {
332 struct ast_sip_session_media *session_media = AST_VECTOR_GET(&media_state->sessions, index);
334
335 ao2_bump(session_media);
336 if (AST_VECTOR_REPLACE(&cloned->sessions, index, session_media)) {
337 ao2_cleanup(session_media);
338 }
340 !cloned->default_session[type]) {
341 cloned->default_session[type] = session_media;
342 }
343 }
344
345 for (index = 0; index < AST_VECTOR_SIZE(&media_state->read_callbacks); ++index) {
347
349 }
350
351 return cloned;
352}
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::@283 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:679

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 354 of file res_pjsip_session.c.

355{
356 if (!media_state) {
357 return;
358 }
359
360 /* This will reset the internal state so we only have to free persistent things */
362
363 AST_VECTOR_FREE(&media_state->sessions);
364 AST_VECTOR_FREE(&media_state->read_callbacks);
365
366 ast_free(media_state);
367}
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:185

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 288 of file res_pjsip_session.c.

289{
290 int index;
291
292 if (!media_state) {
293 return;
294 }
295
296 AST_VECTOR_RESET(&media_state->sessions, ao2_cleanup);
298
299 for (index = 0; index < AST_MEDIA_TYPE_END; ++index) {
300 media_state->default_session[index] = NULL;
301 }
302
304 media_state->topology = NULL;
305}
@ 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:746
#define AST_VECTOR_RESET(vec, cleanup)
Reset vector.
Definition vector.h:636
#define AST_VECTOR_ELEM_CLEANUP_NOOP(elem)
Vector element cleanup that does nothing.
Definition vector.h:582

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 254 of file res_pjsip_session.c.

255{
256 int i;
257 int ret;
258
259 if (!media_state || !sip_session) {
260 return;
261 }
262
263 for (i = 0; i < AST_VECTOR_SIZE(&media_state->sessions); i++) {
264 struct ast_rtp_instance_stats *stats_tmp = NULL;
265 struct ast_sip_session_media *media = AST_VECTOR_GET(&media_state->sessions, i);
266 if (!media || !media->rtp) {
267 continue;
268 }
269
270 stats_tmp = ast_calloc(1, sizeof(struct ast_rtp_instance_stats));
271 if (!stats_tmp) {
272 return;
273 }
274
276 if (ret) {
277 ast_free(stats_tmp);
278 continue;
279 }
280
281 /* remove all the duplicated stats if exist */
283
284 AST_VECTOR_APPEND(&sip_session->media_stats, stats_tmp);
285 }
286}
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:187
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.
struct ast_rtp_instance * rtp
RTP instance itself.
struct ast_sip_session::@286 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:499

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 2537 of file res_pjsip_session.c.

2543{
2544 return sip_session_refresh(session, on_request_creation, on_sdp_creation,
2545 on_response, method, generate_new_sdp, media_state, NULL, 0);
2546}
const char * method
Definition res_pjsip.c:1273
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 2548 of file res_pjsip_session.c.

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

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 148 of file res_pjsip_session.c.

149{
150 RAII_VAR(struct sdp_handler_list *, handler_list,
151 ao2_find(sdp_handlers, stream_type, OBJ_KEY), ao2_cleanup);
153
154 if (handler_list) {
155 struct ast_sip_session_sdp_handler *iter;
156 /* Check if this handler is already registered for this stream type */
157 AST_LIST_TRAVERSE(&handler_list->list, iter, next) {
158 if (!strcmp(iter->id, handler->id)) {
159 ast_log(LOG_WARNING, "Handler '%s' already registered for stream type '%s'.\n", handler->id, stream_type);
160 return -1;
161 }
162 }
163 AST_LIST_INSERT_TAIL(&handler_list->list, handler, next);
164 ast_debug(1, "Registered SDP stream handler '%s' for stream type '%s'\n", handler->id, stream_type);
165
166 return 0;
167 }
168
169 /* No stream of this type has been registered yet, so we need to create a new list */
170 handler_list = ao2_alloc(sizeof(*handler_list) + strlen(stream_type), NULL);
171 if (!handler_list) {
172 return -1;
173 }
174 /* Safe use of strcpy */
175 strcpy(handler_list->stream_type, stream_type);
176 AST_LIST_HEAD_INIT_NOLOCK(&handler_list->list);
177 AST_LIST_INSERT_TAIL(&handler_list->list, handler, next);
178 if (!ao2_link(sdp_handlers, handler_list)) {
179 return -1;
180 }
181 ast_debug(1, "Registered SDP stream handler '%s' for stream type '%s'\n", handler->id, stream_type);
182
183 return 0;
184}
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define SCOPED_AO2LOCK(varname, obj)
scoped lock specialization for ao2 mutexes.
Definition lock.h:611
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(), and 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
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition linkedlists.h:52
#define AST_RWLIST_TRAVERSE_SAFE_END
#define AST_RWLIST_INSERT_TAIL
#define AST_RWLIST_INSERT_BEFORE_CURRENT
enum ast_sip_session_response_priority response_priority
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::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 1302 of file res_pjsip_session.c.

1303{
1304 ao2_callback(session->datastores, OBJ_KEY | OBJ_UNLINK | OBJ_NODATA, NULL, (void *) name);
1305}
#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. */
123 ast_module_unref(iter->module);
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.
#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::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 2819 of file res_pjsip_session.c.

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

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 2863 of file res_pjsip_session.c.

2864{
2866}
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 2839 of file res_pjsip_session.c.

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

2590{
2591 pjsip_dialog *dlg = pjsip_tdata_get_dlg(tdata);
2592 RAII_VAR(struct ast_sip_session *, dlg_session, dlg ? ast_sip_dialog_get_session(dlg) : NULL, ao2_cleanup);
2593 if (!dlg_session) {
2594 /* If the dialog has a session, handle_outgoing_response will be called
2595 from session_on_tx_response. If it does not, call it from here. */
2597 }
2598 pjsip_inv_send_msg(session->inv_session, tdata);
2599 return;
2600}
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 3131 of file res_pjsip_session.c.

3132{
3134}
int ast_taskpool_serializer_suspend(struct ast_taskprocessor *serializer)
Suspend a serializer, causing tasks to be queued until unsuspended.
Definition taskpool.c:1001

References ast_taskpool_serializer_suspend(), and session.

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 3371 of file res_pjsip_session.c.

3372{
3373 pj_status_t status;
3374 pjsip_tx_data *packet = NULL;
3375 SCOPE_ENTER(1, "%s Response %d\n", ast_sip_session_get_name(session), response);
3376
3377 if (session->defer_terminate) {
3378 session->terminate_while_deferred = 1;
3379 SCOPE_EXIT_RTN("Deferred\n");
3380 }
3381
3382 if (!response) {
3383 response = 603;
3384 }
3385
3386 /* The media sessions need to exist for the lifetime of the underlying channel
3387 * to ensure that anything (such as bridge_native_rtp) has access to them as
3388 * appropriate. Since ast_sip_session_terminate is called by chan_pjsip and other
3389 * places when the session is to be terminated we terminate any existing
3390 * media sessions here.
3391 */
3392 ast_sip_session_media_stats_save(session, session->active_media_state);
3393 SWAP(session->active_media_state, session->pending_media_state);
3394 ast_sip_session_media_state_reset(session->pending_media_state);
3395
3396 switch (session->inv_session->state) {
3397 case PJSIP_INV_STATE_NULL:
3398 if (!session->inv_session->invite_tsx) {
3399 /*
3400 * Normally, it's pjproject's transaction cleanup that ultimately causes the
3401 * final session reference to be released but if both STATE and invite_tsx are NULL,
3402 * we never created a transaction in the first place. In this case, we need to
3403 * do the cleanup ourselves.
3404 */
3405 /* Transfer the inv_session session reference to the session_end_task */
3406 session->inv_session->mod_data[session_module.id] = NULL;
3407 pjsip_inv_terminate(session->inv_session, response, PJ_TRUE);
3409 /*
3410 * session_end_completion will cleanup the final session reference unless
3411 * ast_sip_session_terminate's caller is holding one.
3412 */
3414 } else {
3415 pjsip_inv_terminate(session->inv_session, response, PJ_TRUE);
3416 }
3417 break;
3418 case PJSIP_INV_STATE_CONFIRMED:
3419 if (session->inv_session->invite_tsx) {
3420 ast_debug(3, "%s: Delay sending BYE because of outstanding transaction...\n",
3422 /* If this is delayed the only thing that will happen is a BYE request so we don't
3423 * actually need to store the response code for when it happens.
3424 */
3426 break;
3427 }
3428 /* Fall through */
3429 default:
3430 status = pjsip_inv_end_session(session->inv_session, response, NULL, &packet);
3431 if (status == PJ_SUCCESS && packet) {
3432 struct ast_sip_session_delayed_request *delay;
3433
3434 /* Flush any delayed requests so they cannot overlap this transaction. */
3435 while ((delay = AST_LIST_REMOVE_HEAD(&session->delayed_requests, next))) {
3436 delayed_request_free(delay);
3437 }
3438
3439 if (packet->msg->type == PJSIP_RESPONSE_MSG) {
3441 } else {
3443 }
3444 }
3445 break;
3446 }
3448}
jack_status_t status
Definition app_jack.c:149
#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:256

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 209 of file res_pjsip_session.c.

210{
212}
#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(), and unload_module().

◆ ast_sip_session_unregister_supplement()

void ast_sip_session_unregister_supplement ( struct ast_sip_session_supplement supplement)

◆ 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 3136 of file res_pjsip_session.c.

3137{
3139}
int ast_taskpool_serializer_unsuspend(struct ast_taskprocessor *serializer)
Unsuspend a serializer, causing tasks to be executed.
Definition taskpool.c:1050

References ast_taskpool_serializer_unsuspend(), and session.

Referenced by chan_pjsip_indicate().