Asterisk - The Open Source Telephony Project GIT-master-5467495
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_check_supplement_create (struct ast_sip_endpoint *endpoint, struct ast_sip_contact *contact, const char *location, const char *request_user, struct ast_stream_topology *req_topology)
 Check registered supplements for permission to create an outgoing session.
 
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 645 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 254 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 255 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 256 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 267 of file res_pjsip_session.h.

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

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

◆ ast_sip_session_t38state

T.38 states for a session.

Enumerator
T38_DISABLED 

Not enabled

T38_LOCAL_REINVITE 

Offered from local - REINVITE

T38_PEER_REINVITE 

Offered from peer - REINVITE

T38_ENABLED 

Negotiated (enabled)

T38_REJECTED 

Refused

T38_MAX_ENUM 

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

Definition at line 56 of file res_pjsip_session.h.

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

Function Documentation

◆ ast_sip_can_present_connected_id()

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

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

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

Definition at line 131 of file res_pjsip_session.c.

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

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

3058{
3059 struct ast_sip_channel_pvt *channel = ao2_alloc(sizeof(*channel), sip_channel_destroy);
3060
3061 if (!channel) {
3062 return NULL;
3063 }
3064
3065 ao2_ref(pvt, +1);
3066 channel->pvt = pvt;
3067 ao2_ref(session, +1);
3068 channel->session = session;
3069
3070 return channel;
3071}
#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 3620 of file res_pjsip_session.c.

3621{
3622 pjsip_inv_session *inv_session = pjsip_dlg_get_inv_session(dlg);
3623 struct ast_sip_session *session;
3624
3625 if (!inv_session ||
3626 !(session = inv_session->mod_data[session_module.id])) {
3627 return NULL;
3628 }
3629
3630 ao2_ref(session, +1);
3631
3632 return session;
3633}
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 1284 of file res_pjsip_session.c.

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

3075{
3077 struct ast_sip_session *ret_session;
3078 int dsp_features = 0;
3079
3081 if (!session) {
3082 return NULL;
3083 }
3084
3085 AST_LIST_HEAD_INIT(&session->supplements);
3086 AST_LIST_HEAD_INIT_NOLOCK(&session->delayed_requests);
3088
3090 if (!session->direct_media_cap) {
3091 return NULL;
3092 }
3095 if (!session->datastores) {
3096 return NULL;
3097 }
3098 session->active_media_state = ast_sip_session_media_state_alloc();
3099 if (!session->active_media_state) {
3100 return NULL;
3101 }
3102 session->pending_media_state = ast_sip_session_media_state_alloc();
3103 if (!session->pending_media_state) {
3104 return NULL;
3105 }
3106 if (AST_VECTOR_INIT(&session->media_stats, 1) < 0) {
3107 return NULL;
3108 }
3109
3111 dsp_features |= DSP_FEATURE_DIGIT_DETECT;
3112 }
3113 if (endpoint->faxdetect) {
3114 dsp_features |= DSP_FEATURE_FAX_DETECT;
3115 }
3116 if (dsp_features) {
3117 session->dsp = ast_dsp_new();
3118 if (!session->dsp) {
3119 return NULL;
3120 }
3121
3122 ast_dsp_set_features(session->dsp, dsp_features);
3123 }
3124
3125 session->endpoint = ao2_bump(endpoint);
3126
3127 if (rdata) {
3128 /*
3129 * We must continue using the serializer that the original
3130 * INVITE came in on for the dialog. There may be
3131 * retransmissions already enqueued in the original
3132 * serializer that can result in reentrancy and message
3133 * sequencing problems.
3134 */
3135 session->serializer = ast_sip_get_distributor_serializer(rdata);
3136 } else {
3137 char tps_name[AST_TASKPROCESSOR_MAX_NAME + 1];
3138
3139 /* Create name with seq number appended. */
3140 ast_taskprocessor_build_name(tps_name, sizeof(tps_name), "pjsip/outsess/%s",
3142
3143 session->serializer = ast_sip_create_serializer(tps_name);
3144 }
3145 if (!session->serializer) {
3146 return NULL;
3147 }
3150
3151 /* When a PJSIP INVITE session is created it is created with a reference
3152 * count of 1, with that reference being managed by the underlying state
3153 * of the INVITE session itself. When the INVITE session transitions to
3154 * a DISCONNECTED state that reference is released. This means we can not
3155 * rely on that reference to ensure the INVITE session remains for the
3156 * lifetime of our session. To ensure it does we add our own reference
3157 * and release it when our own session goes away, ensuring that the INVITE
3158 * session remains for the lifetime of session.
3159 */
3160
3161#ifdef HAVE_PJSIP_INV_SESSION_REF
3162 if (pjsip_inv_add_ref(inv_session) != PJ_SUCCESS) {
3163 ast_log(LOG_ERROR, "Can't increase the session reference counter\n");
3164 return NULL;
3165 }
3166#endif
3167
3168 pjsip_dlg_inc_session(inv_session->dlg, &session_module);
3169 inv_session->mod_data[session_module.id] = ao2_bump(session);
3170 session->contact = ao2_bump(contact);
3171 session->inv_session = inv_session;
3172
3173 session->dtmf = endpoint->dtmf;
3174 session->moh_passthrough = endpoint->moh_passthrough;
3175
3177 /* Release the ref held by session->inv_session */
3178 ao2_ref(session, -1);
3179 return NULL;
3180 }
3181
3182 session->authentication_challenge_count = 0;
3183
3184 /* Fire session begin handlers */
3186
3187 /* Avoid unnecessary ref manipulation to return a session */
3188 ret_session = session;
3189 session = NULL;
3190 return ret_session;
3191}
#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:1744
#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:1953
struct ast_dsp * ast_dsp_new(void)
Allocates a new dsp, assumes 8khz for internal sample rate.
Definition dsp.c:1943
@ 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:2092
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:558
@ AST_SIP_DTMF_INBAND
Definition res_pjsip.h:554
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:1140
enum ast_sip_dtmf_mode dtmf
Definition res_pjsip.h:1116
unsigned int faxdetect
Definition res_pjsip.h:1128
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 1254 of file res_pjsip_session.c.

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

int ast_sip_session_check_supplement_create ( struct ast_sip_endpoint endpoint,
struct ast_sip_contact contact,
const char *  location,
const char *  request_user,
struct ast_stream_topology req_topology 
)

Check registered supplements for permission to create an outgoing session.

Iterates the global supplement list and calls any registered session_create callbacks. The first callback to return a non-zero value stops the iteration and causes this function to return -1, blocking the session creation.

This is called at the beginning of ast_sip_session_create_outgoing() before any dialog or invite session resources are allocated.

Since
20.20.0
22.10.0
23.4.0
Parameters
endpointThe endpoint the outgoing session would be created for
contactThe contact to use for the outgoing session, or NULL
locationName of the location to call, be it named location or explicit URI, or NULL
request_userOptional request user to place in the request URI, or NULL
req_topologyThe requested stream capabilities
Return values
0Session creation is allowed
-1Session creation is blocked by a supplement

Definition at line 111 of file pjsip_session.c.

114{
115 struct ast_sip_session_supplement *iter;
117
119 if (iter->session_create && iter->session_create(endpoint, contact, location,
120 request_user, req_topology)) {
121 return -1;
122 }
123 }
124
125 return 0;
126}
int(* session_create)(struct ast_sip_endpoint *endpoint, struct ast_sip_contact *contact, const char *location, const char *request_user, struct ast_stream_topology *req_topology)
Called before an outgoing session is created.

References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, lock, ast_sip_session_supplement::next, SCOPED_LOCK, and ast_sip_session_supplement::session_create.

Referenced by ast_sip_session_create_outgoing().

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

2934{
2935 pjmedia_sdp_session *offer;
2937
2938 if (!(offer = create_local_sdp(session->inv_session, session, NULL, 0))) {
2939 pjsip_inv_terminate(session->inv_session, 500, PJ_FALSE);
2940 SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create offer\n");
2941 }
2942
2943 pjsip_inv_set_local_sdp(session->inv_session, offer);
2944 pjmedia_sdp_neg_set_prefer_remote_codec_order(session->inv_session->neg, PJ_FALSE);
2945#ifdef PJMEDIA_SDP_NEG_ANSWER_MULTIPLE_CODECS
2946 if (!session->endpoint->preferred_codec_only) {
2947 pjmedia_sdp_neg_set_answer_multiple_codecs(session->inv_session->neg, PJ_TRUE);
2948 }
2949#endif
2950
2951 /*
2952 * We MUST call set_from_header() before pjsip_inv_invite. If we don't, the
2953 * From in the initial INVITE will be wrong but the rest of the messages will be OK.
2954 */
2956
2957 if (pjsip_inv_invite(session->inv_session, tdata) != PJ_SUCCESS) {
2958 SCOPE_EXIT_RTN_VALUE(-1, "pjsip_inv_invite failed\n");
2959 }
2960
2962}
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 3299 of file res_pjsip_session.c.

3302{
3303 const char *uri = NULL;
3304 RAII_VAR(struct ast_sip_aor *, found_aor, NULL, ao2_cleanup);
3305 RAII_VAR(struct ast_sip_contact *, found_contact, NULL, ao2_cleanup);
3306 pjsip_timer_setting timer;
3307 pjsip_dialog *dlg;
3308 struct pjsip_inv_session *inv_session;
3310 struct ast_sip_session *ret_session;
3311 SCOPE_ENTER(1, "%s %s Topology: %s\n", ast_sorcery_object_get_id(endpoint), request_user,
3312 ast_str_tmp(256, ast_stream_topology_to_str(req_topology, &STR_TMP)));
3313
3315 request_user, req_topology)) {
3316 SCOPE_EXIT_RTN_VALUE(NULL, "%s: Session creation blocked by supplement\n",
3318 }
3319
3320 /* If no location has been provided use the AOR list from the endpoint itself */
3321 if (location || !contact) {
3322 location = S_OR(location, endpoint->aors);
3323
3325 &found_aor, &found_contact);
3326 if (!found_contact || ast_strlen_zero(found_contact->uri)) {
3327 uri = location;
3328 } else {
3329 uri = found_contact->uri;
3330 }
3331 } else {
3332 uri = contact->uri;
3333 }
3334
3335 /* If we still have no URI to dial fail to create the session */
3336 if (ast_strlen_zero(uri)) {
3337 ast_log(LOG_ERROR, "Endpoint '%s': No URI available. Is endpoint registered?\n",
3339 SCOPE_EXIT_RTN_VALUE(NULL, "No URI\n");
3340 }
3341
3342 if (!(dlg = ast_sip_create_dialog_uac(endpoint, uri, request_user))) {
3343 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create dialog\n");
3344 }
3345
3346 if (setup_outbound_invite_auth(dlg)) {
3347 pjsip_dlg_terminate(dlg);
3348 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't setup auth\n");
3349 }
3350
3351 if (pjsip_inv_create_uac(dlg, NULL, endpoint->extensions.flags, &inv_session) != PJ_SUCCESS) {
3352 pjsip_dlg_terminate(dlg);
3353 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create uac\n");
3354 }
3355#if defined(HAVE_PJSIP_REPLACE_MEDIA_STREAM) || defined(PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE)
3356 inv_session->sdp_neg_flags = PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE;
3357#endif
3358
3359 pjsip_timer_setting_default(&timer);
3361 timer.sess_expires = endpoint->extensions.timer.sess_expires;
3362 pjsip_timer_init_session(inv_session, &timer);
3363
3364 session = ast_sip_session_alloc(endpoint, found_contact ? found_contact : contact,
3365 inv_session, NULL);
3366 if (!session) {
3367 pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
3368 return NULL;
3369 }
3370 session->aor = ao2_bump(found_aor);
3371 session->call_direction = AST_SIP_SESSION_OUTGOING_CALL;
3372
3374
3375 if (ast_stream_topology_get_count(req_topology) > 0) {
3376 /* get joint caps between req_topology and endpoint topology */
3377 int i;
3378
3379 for (i = 0; i < ast_stream_topology_get_count(req_topology); ++i) {
3380 struct ast_stream *req_stream;
3381 struct ast_stream *clone_stream;
3382
3383 req_stream = ast_stream_topology_get_stream(req_topology, i);
3384
3386 continue;
3387 }
3388
3389 clone_stream = ast_sip_session_create_joint_call_stream(session, req_stream);
3390 if (!clone_stream || ast_stream_get_format_count(clone_stream) == 0) {
3391 ast_stream_free(clone_stream);
3392 continue;
3393 }
3394
3395 if (!session->pending_media_state->topology) {
3396 session->pending_media_state->topology = ast_stream_topology_alloc();
3397 if (!session->pending_media_state->topology) {
3398 pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
3399 ao2_ref(session, -1);
3400 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create topology\n");
3401 }
3402 }
3403
3404 if (ast_stream_topology_append_stream(session->pending_media_state->topology, clone_stream) < 0) {
3405 ast_stream_free(clone_stream);
3406 continue;
3407 }
3408 }
3409 }
3410
3411 if (!session->pending_media_state->topology) {
3412 /* Use the configured topology on the endpoint as the pending one */
3413 session->pending_media_state->topology = ast_stream_topology_clone(endpoint->media.topology);
3414 if (!session->pending_media_state->topology) {
3415 pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
3416 ao2_ref(session, -1);
3417 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't clone topology\n");
3418 }
3419 }
3420
3421 if (pjsip_dlg_add_usage(dlg, &session_module, NULL) != PJ_SUCCESS) {
3422 pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
3423 /* Since we are not notifying ourselves that the INVITE session is being terminated
3424 * we need to manually drop its reference to session
3425 */
3426 ao2_ref(session, -1);
3427 SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't add usage\n");
3428 }
3429
3430 /* Avoid unnecessary ref manipulation to return a session */
3431 ret_session = session;
3432 session = NULL;
3433 SCOPE_EXIT_RTN_VALUE(ret_session);
3434}
static struct ast_timer * timer
Definition chan_iax2.c:401
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:1752
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:962
@ AST_SIP_CONTACT_FILTER_REACHABLE
Return only reachable or unknown contacts.
Definition res_pjsip.h:1443
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)
int ast_sip_session_check_supplement_create(struct ast_sip_endpoint *endpoint, struct ast_sip_contact *contact, const char *location, const char *request_user, struct ast_stream_topology *req_topology)
Check registered supplements for permission to create an outgoing session.
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:480
Contact associated with an address of record.
Definition res_pjsip.h:392
const ast_string_field uri
Definition res_pjsip.h:414
struct ast_sip_timer_options timer
Definition res_pjsip.h:821
struct ast_stream_topology * topology
Definition res_pjsip.h:1027
struct ast_sip_endpoint_id_configuration id
Definition res_pjsip.h:1106
const ast_string_field aors
Definition res_pjsip.h:1096
struct ast_sip_endpoint_extensions extensions
Definition res_pjsip.h:1098
struct ast_sip_endpoint_media_configuration media
Definition res_pjsip.h:1100
unsigned int sess_expires
Definition res_pjsip.h:808
unsigned int min_se
Definition res_pjsip.h:806

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_check_supplement_create(), 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 3546 of file res_pjsip_session.c.

3547{
3548 pj_time_val delay = { .sec = 60, };
3549 int res;
3550
3551 /* The session should not have an active deferred termination request. */
3552 ast_assert(!session->defer_terminate);
3553
3554 session->defer_terminate = 1;
3555
3556 session->defer_end = 1;
3557 session->ended_while_deferred = 0;
3558
3559 ao2_ref(session, +1);
3560 pj_timer_entry_init(&session->scheduled_termination, 0, session, session_termination_cb);
3561
3562 res = (pjsip_endpt_schedule_timer(ast_sip_get_pjsip_endpoint(),
3563 &session->scheduled_termination, &delay) != PJ_SUCCESS) ? -1 : 0;
3564 if (res) {
3565 session->defer_terminate = 0;
3566 ao2_ref(session, -1);
3567 }
3568 return res;
3569}
pjsip_endpoint * ast_sip_get_pjsip_endpoint(void)
Get a pointer to the PJSIP endpoint.
Definition res_pjsip.c:518
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 3586 of file res_pjsip_session.c.

3587{
3588 if (!session->defer_terminate) {
3589 /* Already canceled or timer fired. */
3590 return;
3591 }
3592
3593 session->defer_terminate = 0;
3594
3595 if (session->terminate_while_deferred) {
3596 /* Complete the termination started by the upper layer. */
3598 }
3599
3600 /* Stop the termination timer if it is still running. */
3602}
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 3604 of file res_pjsip_session.c.

3605{
3606 if (!session->defer_end) {
3607 return;
3608 }
3609
3610 session->defer_end = 0;
3611
3612 if (session->ended_while_deferred) {
3613 /* Complete the session end started by the remote hangup. */
3614 ast_debug(3, "%s: Ending session after being deferred\n", ast_sip_session_get_name(session));
3615 session->ended_while_deferred = 0;
3617 }
3618}
#define ast_debug(level,...)
Log a DEBUG message.
static int session_end(void *vsession)

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

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

◆ ast_sip_session_get_datastore()

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

Retrieve a session datastore.

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

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

Definition at line 1296 of file res_pjsip_session.c.

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

References ao2_find, name, OBJ_KEY, and session.

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

◆ ast_sip_session_get_dialog()

pjsip_dialog * ast_sip_session_get_dialog ( const struct ast_sip_session session)

Retrieves a dialog from a session.

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

Definition at line 3635 of file res_pjsip_session.c.

3636{
3637 pjsip_inv_session *inv_session = session->inv_session;
3638
3639 if (!inv_session) {
3640 return NULL;
3641 }
3642
3643 return inv_session->dlg;
3644}

References ast_sip_session::inv_session, NULL, and session.

◆ ast_sip_session_get_name()

const char * ast_sip_session_get_name ( const struct ast_sip_session session)

Get the channel or endpoint name associated with the session.

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

Definition at line 117 of file res_pjsip_session.c.

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

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

Referenced by add_date_header(), add_eprofile_to_channel(), add_fingerprints_if_present(), add_sdp_streams(), answer(), apply_negotiated_sdp_stream(), ast_sip_session_add_reason_header(), ast_sip_session_create_invite(), ast_sip_session_end_if_deferred(), ast_sip_session_media_state_add(), ast_sip_session_regenerate_answer(), ast_sip_session_terminate(), call(), chan_pjsip_call(), chan_pjsip_incoming_ack(), chan_pjsip_incoming_prack(), chan_pjsip_incoming_request(), chan_pjsip_incoming_response(), chan_pjsip_incoming_response_update_cause(), chan_pjsip_new(), chan_pjsip_session_begin(), chan_pjsip_session_end(), create_local_sdp(), create_outgoing_sdp_stream(), delay_request(), generate_session_refresh_sdp(), get_codecs(), get_destination(), handle_incoming_before_media(), handle_incoming_request(), handle_incoming_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(), set_outstanding_invite_timeout(), 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 3646 of file res_pjsip_session.c.

3647{
3648 pjsip_inv_session *inv_session = session->inv_session;
3649
3650 if (!inv_session) {
3651 return PJSIP_INV_STATE_NULL;
3652 }
3653
3654 return inv_session->state;
3655}

References ast_sip_session::inv_session, and session.

◆ ast_sip_session_is_pending_stream_default()

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

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

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

Definition at line 368 of file res_pjsip_session.c.

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

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

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

◆ ast_sip_session_media_add_read_callback()

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

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

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

Definition at line 394 of file res_pjsip_session.c.

396{
397 struct ast_sip_session_media_read_callback_state callback_state = {
398 .fd = fd,
399 .read_callback = callback,
400 .session = session_media,
401 };
402
403 /* The contents of the vector are whole structs and not pointers */
404 return AST_VECTOR_APPEND(&session->pending_media_state->read_callbacks, callback_state);
405}
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 423 of file res_pjsip_session.c.

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

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

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

◆ ast_sip_session_media_set_write_callback()

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

Set a write callback for a media session.

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

Definition at line 407 of file res_pjsip_session.c.

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

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

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

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

References DEFAULT_NUM_SESSION_MEDIA, and internal_sip_session_media_state_alloc().

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

◆ ast_sip_session_media_state_clone()

struct ast_sip_session_media_state * ast_sip_session_media_state_clone ( const struct ast_sip_session_media_state media_state)

Clone a media state.

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

Definition at line 306 of file res_pjsip_session.c.

307{
308 struct ast_sip_session_media_state *cloned;
309 int index;
310
311 if (!media_state) {
312 return NULL;
313 }
314
316 AST_VECTOR_SIZE(&media_state->sessions),
317 AST_VECTOR_SIZE(&media_state->read_callbacks));
318 if (!cloned) {
319 return NULL;
320 }
321
322 if (media_state->topology) {
323 cloned->topology = ast_stream_topology_clone(media_state->topology);
324 if (!cloned->topology) {
326 return NULL;
327 }
328 }
329
330 for (index = 0; index < AST_VECTOR_SIZE(&media_state->sessions); ++index) {
331 struct ast_sip_session_media *session_media = AST_VECTOR_GET(&media_state->sessions, index);
333
334 ao2_bump(session_media);
335 if (AST_VECTOR_REPLACE(&cloned->sessions, index, session_media)) {
336 ao2_cleanup(session_media);
337 }
339 !cloned->default_session[type]) {
340 cloned->default_session[type] = session_media;
341 }
342 }
343
344 for (index = 0; index < AST_VECTOR_SIZE(&media_state->read_callbacks); ++index) {
346
348 }
349
350 return cloned;
351}
ast_media_type
Types of media.
Definition codec.h:30
void ast_sip_session_media_state_free(struct ast_sip_session_media_state *media_state)
Free a session media state structure.
ast_sip_session_media_read_cb read_callback
The callback to invoke.
Structure which contains media state information (streams, sessions)
struct ast_sip_session_media_state::@281 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:696

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

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

◆ ast_sip_session_media_state_free()

void ast_sip_session_media_state_free ( struct ast_sip_session_media_state media_state)

Free a session media state structure.

Since
15.0.0

Definition at line 353 of file res_pjsip_session.c.

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

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

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

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

◆ ast_sip_session_media_stats_save()

void ast_sip_session_media_stats_save ( struct ast_sip_session sip_session,
struct ast_sip_session_media_state media_state 
)

Save a media stats.

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

Definition at line 253 of file res_pjsip_session.c.

254{
255 int i;
256 int ret;
257
258 if (!media_state || !sip_session) {
259 return;
260 }
261
262 for (i = 0; i < AST_VECTOR_SIZE(&media_state->sessions); i++) {
263 struct ast_rtp_instance_stats *stats_tmp = NULL;
264 struct ast_sip_session_media *media = AST_VECTOR_GET(&media_state->sessions, i);
265 if (!media || !media->rtp) {
266 continue;
267 }
268
269 stats_tmp = ast_calloc(1, sizeof(struct ast_rtp_instance_stats));
270 if (!stats_tmp) {
271 return;
272 }
273
275 if (ret) {
276 ast_free(stats_tmp);
277 continue;
278 }
279
280 /* remove all the duplicated stats if exist */
282
283 AST_VECTOR_APPEND(&sip_session->media_stats, stats_tmp);
284 }
285}
static int media_stats_local_ssrc_cmp(const struct ast_rtp_instance_stats *vec_elem, const struct ast_rtp_instance_stats *srch)
@ AST_RTP_INSTANCE_STAT_ALL
Definition rtp_engine.h: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::@284 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:516

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

2608{
2609 return sip_session_refresh(session, on_request_creation, on_sdp_creation,
2610 on_response, method, generate_new_sdp, media_state, NULL, 0);
2611}
const char * method
Definition res_pjsip.c:1277
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 2613 of file res_pjsip_session.c.

2615{
2616 pjsip_inv_session *inv_session = session->inv_session;
2617 pjmedia_sdp_session *new_answer = NULL;
2618 const pjmedia_sdp_session *previous_offer = NULL;
2620
2621 /* The SDP answer can only be regenerated if it is still pending to be sent */
2622 if (!inv_session->neg || (pjmedia_sdp_neg_get_state(inv_session->neg) != PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER &&
2623 pjmedia_sdp_neg_get_state(inv_session->neg) != PJMEDIA_SDP_NEG_STATE_WAIT_NEGO)) {
2624 ast_log(LOG_WARNING, "Requested to regenerate local SDP answer for channel '%s' but negotiation in state '%s'\n",
2625 ast_channel_name(session->channel), pjmedia_sdp_neg_state_str(pjmedia_sdp_neg_get_state(inv_session->neg)));
2626 SCOPE_EXIT_RTN_VALUE(-1, "Bad negotiation state\n");
2627 }
2628
2629 pjmedia_sdp_neg_get_neg_remote(inv_session->neg, &previous_offer);
2630 if (pjmedia_sdp_neg_get_state(inv_session->neg) == PJMEDIA_SDP_NEG_STATE_WAIT_NEGO) {
2631 /* Transition the SDP negotiator back to when it received the remote offer */
2632 pjmedia_sdp_neg_negotiate(inv_session->pool, inv_session->neg, 0);
2633 pjmedia_sdp_neg_set_remote_offer(inv_session->pool, inv_session->neg, previous_offer);
2634 }
2635
2636 new_answer = create_local_sdp(inv_session, session, previous_offer, 0);
2637 if (!new_answer) {
2638 ast_log(LOG_WARNING, "Could not create a new local SDP answer for channel '%s'\n",
2639 ast_channel_name(session->channel));
2640 SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create new SDP\n");
2641 }
2642
2643 if (on_sdp_creation) {
2644 if (on_sdp_creation(session, new_answer)) {
2645 SCOPE_EXIT_RTN_VALUE(-1, "Callback failed\n");
2646 }
2647 }
2648
2649 pjsip_inv_set_sdp_answer(inv_session, new_answer);
2650
2652}

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

Referenced by dtmf_mode_refresh_cb().

◆ ast_sip_session_register_sdp_handler()

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

Register an SDP handler.

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

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

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

Definition at line 147 of file res_pjsip_session.c.

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

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

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

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

◆ ast_sip_session_remove_supplements()

void ast_sip_session_remove_supplements ( struct ast_sip_session session)

Remove supplements from a SIP session.

Parameters
sessionThe session to remove

Definition at line 128 of file pjsip_session.c.

129{
130 struct ast_sip_session_supplement *iter;
131
132 if (!session) {
133 return;
134 }
135
136 /* free the supplements */
137 while ((iter = AST_LIST_REMOVE_HEAD(&session->supplements, next))) {
138 if (iter->module) {
139 /* referenced session closed. decreasing module reference. */
140 ast_module_unref(iter->module);
141 }
142
143 ast_free(iter);
144 }
145
146 return;
147}
#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 2884 of file res_pjsip_session.c.

2885{
2886 if (!session->deferred_reinvite) {
2887 return;
2888 }
2889
2890 if (session->channel) {
2891 pjsip_endpt_process_rx_data(ast_sip_get_pjsip_endpoint(),
2892 session->deferred_reinvite, NULL, NULL);
2893 }
2894 pjsip_rx_data_free_cloned(session->deferred_reinvite);
2895 session->deferred_reinvite = NULL;
2896}

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

2929{
2931}
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 2904 of file res_pjsip_session.c.

2906{
2907 pjsip_inv_session *inv_session = session->inv_session;
2908
2909 /* For every request except BYE we disallow sending of the message when
2910 * the session has been disconnected. A BYE request is special though
2911 * because it can be sent again after the session is disconnected except
2912 * with credentials.
2913 */
2914 if (inv_session->state == PJSIP_INV_STATE_DISCONNECTED &&
2915 tdata->msg->line.req.method.id != PJSIP_BYE_METHOD) {
2916 return;
2917 }
2918
2919 ast_sip_mod_data_set(tdata->pool, tdata->mod_data, session_module.id,
2920 MOD_DATA_ON_RESPONSE, on_response);
2921
2923 pjsip_inv_send_msg(session->inv_session, tdata);
2924
2925 return;
2926}
#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:3130
#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 2654 of file res_pjsip_session.c.

2655{
2656 pjsip_dialog *dlg = pjsip_tdata_get_dlg(tdata);
2657 RAII_VAR(struct ast_sip_session *, dlg_session, dlg ? ast_sip_dialog_get_session(dlg) : NULL, ao2_cleanup);
2658 if (!dlg_session) {
2659 /* If the dialog has a session, handle_outgoing_response will be called
2660 from session_on_tx_response. If it does not, call it from here. */
2662 }
2663 pjsip_inv_send_msg(session->inv_session, tdata);
2664 return;
2665}
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 3193 of file res_pjsip_session.c.

3194{
3196}
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 3439 of file res_pjsip_session.c.

3440{
3441 pj_status_t status;
3442 pjsip_tx_data *packet = NULL;
3443 SCOPE_ENTER(1, "%s Response %d\n", ast_sip_session_get_name(session), response);
3444
3445 if (session->defer_terminate) {
3446 session->terminate_while_deferred = 1;
3447 SCOPE_EXIT_RTN("Deferred\n");
3448 }
3449
3450 if (!response) {
3451 response = 603;
3452 }
3453
3454 /* The media sessions need to exist for the lifetime of the underlying channel
3455 * to ensure that anything (such as bridge_native_rtp) has access to them as
3456 * appropriate. Since ast_sip_session_terminate is called by chan_pjsip and other
3457 * places when the session is to be terminated we terminate any existing
3458 * media sessions here.
3459 */
3460 ast_sip_session_media_stats_save(session, session->active_media_state);
3461 SWAP(session->active_media_state, session->pending_media_state);
3462 ast_sip_session_media_state_reset(session->pending_media_state);
3463
3464 switch (session->inv_session->state) {
3465 case PJSIP_INV_STATE_NULL:
3466 if (!session->inv_session->invite_tsx) {
3467 /*
3468 * Normally, it's pjproject's transaction cleanup that ultimately causes the
3469 * final session reference to be released but if both STATE and invite_tsx are NULL,
3470 * we never created a transaction in the first place. In this case, we need to
3471 * do the cleanup ourselves.
3472 */
3473 /* Transfer the inv_session session reference to the session_end_task */
3474 session->inv_session->mod_data[session_module.id] = NULL;
3475 pjsip_inv_terminate(session->inv_session, response, PJ_TRUE);
3477 /*
3478 * session_end_completion will cleanup the final session reference unless
3479 * ast_sip_session_terminate's caller is holding one.
3480 */
3482 } else {
3483 pjsip_inv_terminate(session->inv_session, response, PJ_TRUE);
3484 }
3485 break;
3486 case PJSIP_INV_STATE_CONFIRMED:
3487 if (session->inv_session->invite_tsx) {
3488 ast_debug(3, "%s: Delay sending BYE because of outstanding transaction...\n",
3490 /*
3491 * If this is delayed the only thing that will happen is a BYE request, so
3492 * no response code needs to be stored. Queue the BYE as before, then arm
3493 * a transaction timeout so a malformed/lost final re-INVITE response
3494 * cannot leave the session and RTP state referenced forever.
3495 */
3497 ast_log(LOG_ERROR, "%s: Unable to delay BYE request\n",
3500 session->terminate_on_invite_timeout = 1;
3501 }
3502 break;
3503 }
3504 /* Fall through */
3505 default:
3506 status = pjsip_inv_end_session(session->inv_session, response, NULL, &packet);
3507 if (status == PJ_SUCCESS && packet) {
3508 /* Flush any delayed requests so they cannot overlap this transaction. */
3510
3511 if (packet->msg->type == PJSIP_RESPONSE_MSG) {
3513 } else {
3515 }
3516 }
3517 break;
3518 }
3520}
jack_status_t status
Definition app_jack.c:149
#define SCOPE_EXIT_RTN(...)
static void flush_delayed_requests(struct ast_sip_session *session)
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)
static int set_outstanding_invite_timeout(struct ast_sip_session *session)
@ DELAYED_METHOD_BYE
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.
#define SWAP(a, b)
Definition utils.h:256

References ast_debug, ast_log, 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, flush_delayed_requests(), LOG_ERROR, NULL, SCOPE_ENTER, SCOPE_EXIT_RTN, session, session_end(), session_end_completion(), session_module, set_outstanding_invite_timeout(), status, and SWAP.

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

◆ ast_sip_session_unregister_sdp_handler()

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

Unregister an SDP handler.

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

Definition at line 208 of file res_pjsip_session.c.

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

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

Referenced by unload_module(), 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 3198 of file res_pjsip_session.c.

3199{
3201}
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().