57#define SDP_HANDLER_BUCKETS 11
59#define MOD_DATA_ON_RESPONSE "on_response"
60#define MOD_DATA_NAT_HOOK "nat_hook"
63#define DEFAULT_NUM_SESSION_MEDIA 2
107static 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);
120 return "(null session)";
124 }
else if (
session->endpoint) {
133 return id->number.valid
134 && (
session->endpoint->id.trust_outbound
163 ast_debug(1,
"Registered SDP stream handler '%s' for stream type '%s'\n",
handler->id, stream_type);
169 handler_list =
ao2_alloc(
sizeof(*handler_list) + strlen(stream_type),
NULL);
174 strcpy(handler_list->stream_type, stream_type);
180 ast_debug(1,
"Registered SDP stream handler '%s' for stream type '%s'\n",
handler->id, stream_type);
190 const char *stream_type = arg;
195 ast_debug(1,
"Unregistered SDP stream handler '%s' for stream type '%s'\n",
handler->id, stream_type);
201 ast_debug(3,
"No more handlers exist for stream type '%s'\n", stream_type);
228 media_state =
ast_calloc(1,
sizeof(*media_state));
258 if (!media_state || !sip_session) {
265 if (!media || !media->
rtp) {
372 if (!
session->pending_media_state->topology) {
399 .read_callback = callback,
400 .session = session_media,
428 return session_media;
438 return bundle_group_session_media;
442 return session_media;
472 handler->stream_destroy(session_media);
489 if (session_media->
srtp) {
511 if (current_session_media && current_session_media->
type ==
type) {
522 ast_trace(1,
"Reusing existing media session\n");
538 ast_trace(1,
"Can't reuse existing media session because the types are different. %s <> %s\n",
540 session_media =
NULL;
544 if (!session_media) {
547 if (!session_media) {
550 ast_trace(1,
"Creating new media session\n");
560 if (
session->endpoint->media.bundle) {
610 return (type_streams[
type] > 0);
626 for (index = 0; index < sdp->attr_count; ++index) {
627 pjmedia_sdp_attr *attr = sdp->attr[index];
628 char value[pj_strlen(&attr->value) + 1], *mids =
value, *attr_mid;
630 if (pj_strcmp2(&attr->name,
"group") || pj_strncmp2(&attr->value,
"BUNDLE", 6)) {
639 while ((attr_mid =
strsep(&mids,
" "))) {
640 if (!strcmp(attr_mid,
mid)) {
657 const pjmedia_sdp_session *sdp,
658 const struct pjmedia_sdp_media *stream)
660 pjmedia_sdp_attr *attr;
662 if (!
session->endpoint->media.bundle) {
673 attr = pjmedia_sdp_media_find_attr2(stream,
"mid",
NULL);
679 if (!session_media->
mid) {
695 const pjmedia_sdp_session *sdp,
696 const struct pjmedia_sdp_media *stream,
706 for (index = 0; index < stream->attr_count; ++index) {
707 pjmedia_sdp_attr *attr = stream->attr[index];
708 char attr_value[pj_strlen(&attr->value) + 1];
709 char *ssrc_attribute_name, *ssrc_attribute_value =
NULL;
710 char *msid, *
tmp = attr_value;
711 static const pj_str_t STR_msid = {
"msid", 4 };
712 static const pj_str_t STR_ssrc = {
"ssrc", 4 };
713 static const pj_str_t STR_label = {
"label", 5 };
715 if (!pj_strcmp(&attr->name, &STR_label)) {
718 }
else if (!pj_strcmp(&attr->name, &STR_msid)) {
723 }
else if (!pj_strcmp(&attr->name, &STR_ssrc)) {
726 if ((ssrc_attribute_name = strchr(attr_value,
' '))) {
728 *ssrc_attribute_name++ =
'\0';
729 ssrc_attribute_value = strchr(ssrc_attribute_name,
':');
730 if (ssrc_attribute_value) {
732 *ssrc_attribute_value++ =
'\0';
735 if (!strcasecmp(ssrc_attribute_name,
"mslabel") && !
ast_strlen_zero(ssrc_attribute_value)) {
780 if (
session->inv_session &&
session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
786 if (!
session->pending_media_state->topology) {
788 if (!
session->pending_media_state->topology) {
794 for (i = 0; i < sdp->media_count; ++i) {
803 pjmedia_sdp_media *remote_stream = sdp->media[i];
818 char *stream_name =
NULL, *stream_name_allocated =
NULL;
819 const char *stream_label =
NULL;
821 if (
session->active_media_state->topology &&
840 stream_name = stream_name_allocated;
869 if (pjmedia_sdp_media_find_attr2(remote_stream,
"sendonly",
NULL)) {
875 }
else if (pjmedia_sdp_media_find_attr2(remote_stream,
"recvonly",
NULL)) {
877 }
else if (pjmedia_sdp_media_find_attr2(remote_stream,
"inactive",
NULL)) {
890 if (!session_media) {
898 SCOPE_EXIT_EXPR(
continue,
"%s: Declining incoming SDP media stream %s'\n",
907 ast_trace(-1,
"%s: Negotiating incoming SDP media stream %s using %s SDP handler\n",
910 res =
handler->negotiate_incoming_sdp_stream(
session, session_media, sdp, i, stream);
915 }
else if (res == 0) {
917 SCOPE_EXIT_EXPR(
continue,
"%s: Declining incoming SDP media stream %s\n",
919 }
else if (res > 0) {
921 ++type_streams[
type];
931 SCOPE_EXIT_EXPR(
continue,
"%s: Media stream %s has no registered handlers\n",
938 ast_trace(-1,
"%s: Negotiating incoming SDP media stream %s using %s SDP handler\n",
942 res =
handler->negotiate_incoming_sdp_stream(
session, session_media, sdp, i, stream);
948 }
else if (res == 0) {
950 ast_trace(-1,
"%s: Declining incoming SDP media stream %s\n",
953 }
else if (res > 0) {
956 ++type_streams[
type];
957 ast_trace(-1,
"%s: Media stream %s handled by %s\n",
970 handled ?
"yes" :
"no");
975 const pjmedia_sdp_session *remote,
int index,
struct ast_stream *asterisk_stream)
978 struct pjmedia_sdp_media *local_stream = local->media[index];
986 ast_copy_pj_str(media, &local->media[index]->desc.media,
sizeof(media));
996 if (pjmedia_sdp_media_find_attr2(local_stream,
"sendonly",
NULL)) {
998 }
else if (pjmedia_sdp_media_find_attr2(local_stream,
"recvonly",
NULL)) {
1000 }
else if (pjmedia_sdp_media_find_attr2(local_stream,
"inactive",
NULL)) {
1014 ast_debug(4,
"%s: Applying negotiated SDP media stream '%s' using %s SDP handler\n",
1017 res =
handler->apply_negotiated_sdp_stream(
session, session_media, local, remote, index, asterisk_stream);
1019 ast_debug(4,
"%s: Applied negotiated SDP media stream '%s' using %s SDP handler\n",
1026 SCOPE_EXIT_RTN_VALUE(-1,
"%s: Failed to apply negotiated SDP media stream '%s' using %s SDP handler\n",
1032 if (!handler_list) {
1040 ast_debug(4,
"%s: Applying negotiated SDP media stream '%s' using %s SDP handler\n",
1043 res =
handler->apply_negotiated_sdp_stream(
session, session_media, local, remote, index, asterisk_stream);
1050 ast_debug(4,
"%s: Applied negotiated SDP media stream '%s' using %s SDP handler\n",
1062 ast_debug(4,
"%s: Stopping SDP media stream '%s' as it is not currently negotiated\n",
1069 res ?
"not negotiated. Stopped" :
"handled");
1076 unsigned int changed = 0;
1079 if (!
session->pending_media_state->topology) {
1080 if (
session->active_media_state->topology) {
1088 active_media_state_clone =
1090 if (!active_media_state_clone) {
1097 session->pending_media_state = active_media_state_clone;
1112 ast_log(
LOG_WARNING,
"%s: Local SDP contains %d media streams while we expected it to contain %u\n",
1120 for (i = 0; i < local->media_count; ++i) {
1124 if (!remote->media[i]) {
1135 if (!remote->media[i]->desc.port) {
1157 changed |= session_media->
changed;
1165 for (i = 0; i < local->media_count; ++i) {
1169 if (!remote->media[i]) {
1195 if (pjmedia_sdp_neg_was_answer_remote(
session->inv_session->neg) == PJ_FALSE &&
1196 session->active_media_state &&
session->active_media_state->topology &&
1228 }
else if (changed == 2) {
1237#define DATASTORE_BUCKETS 53
1238#define MEDIA_BUCKETS 7
1258 const char *uid_ptr =
uid;
1269 datastore->info =
info;
1276 if (!datastore->uid) {
1323 const char *
str =
"<unknown>";
1408 SCOPE_ENTER(3,
"%s: sending delayed %s request\n",
1508 timer_running = pj_timer_entry_running(&
session->rescheduled_reinvite);
1513 if (!timer_running) {
1555 if (
session->inv_session->invite_tsx) {
1584 if (
session->inv_session->invite_tsx) {
1594 int (*cb)(
void *vsession))
1606 int generate_new_sdp,
1634 pjsip_inv_session *inv_session =
session->inv_session;
1635 const pjmedia_sdp_session *previous_sdp =
NULL;
1638 if (inv_session->neg) {
1639 if (pjmedia_sdp_neg_was_answer_remote(inv_session->neg)) {
1640 pjmedia_sdp_neg_get_active_remote(inv_session->neg, &previous_sdp);
1642 pjmedia_sdp_neg_get_active_local(inv_session->neg, &previous_sdp);
1652 pj_pool_t *dlg_pool;
1653 pjsip_fromto_hdr *dlg_info;
1654 pjsip_contact_hdr *dlg_contact;
1655 pjsip_name_addr *dlg_info_name_addr;
1656 pjsip_sip_uri *dlg_info_uri;
1657 pjsip_sip_uri *dlg_contact_uri;
1659 const char *pjsip_from_domain;
1677 dlg_pool =
session->inv_session->dlg->pool;
1678 dlg_info =
session->inv_session->dlg->local.info;
1679 dlg_contact =
session->inv_session->dlg->local.contact;
1680 dlg_info_name_addr = (pjsip_name_addr *) dlg_info->uri;
1681 dlg_info_uri = pjsip_uri_get_uri(dlg_info_name_addr);
1682 dlg_contact_uri = (pjsip_sip_uri*)pjsip_uri_get_uri(dlg_contact->uri);
1684 if (
session->endpoint->id.trust_outbound || !restricted) {
1694 dlg_info_name_addr->display.ptr =
NULL;
1695 dlg_info_name_addr->display.slen = 0;
1696 pj_strdup2(dlg_pool, &dlg_info_uri->user,
session->endpoint->fromuser);
1700 pj_strdup2(dlg_pool, &dlg_info_uri->host,
session->endpoint->fromdomain);
1709 ast_debug(3,
"%s: From header domain reset by channel variable SIPFROMDOMAIN (%s)\n",
1711 pj_strdup2(dlg_pool, &dlg_info_uri->host, pjsip_from_domain);
1716 session->saved_from_hdr = pjsip_hdr_clone(dlg_pool, dlg_info);
1724 pj_strdup2(dlg_pool, &dlg_info_name_addr->display,
"Anonymous");
1727 pj_strdup2(dlg_pool, &dlg_info_uri->user,
"anonymous");
1731 pj_strdup2(dlg_pool, &dlg_contact_uri->user,
"anonymous");
1735 pj_strdup2(dlg_pool, &dlg_info_uri->host,
"anonymous.invalid");
1745#define STREAM_REMOVED(_stream) (ast_stream_get_state(_stream) == AST_STREAM_STATE_REMOVED)
1746#define STATE_REMOVED(_stream_state) (_stream_state == AST_STREAM_STATE_REMOVED)
1747#define STATE_NONE(_stream_state) (_stream_state == AST_STREAM_STATE_END)
1748#define GET_STREAM_SAFE(_topology, _i) (_i < ast_stream_topology_get_count(_topology) ? ast_stream_topology_get_stream(_topology, _i) : NULL)
1749#define GET_STREAM_STATE_SAFE(_stream) (_stream ? ast_stream_get_state(_stream) : AST_STREAM_STATE_END)
1750#define GET_STREAM_NAME_SAFE(_stream) (_stream ? ast_stream_get_name(_stream) : "")
1769 SCOPE_ENTER(3,
"%s: Topology: %s\n", session_name,
1777 for (i = 0; i < stream_count; i++) {
1780 const char *stream_name =
NULL;
1789 for (j = 0; j < stream_count; j++) {
1791 if (j == i || !possible_dup) {
1807 if (j == i || !possible_dup) {
1813 i, media->
label, j);
1848 const char *session_name,
1852 int run_post_validation)
1861 int max_stream_count;
1863 SCOPE_ENTER(2,
"%s: DP: %s DA: %s CA: %s\n", session_name,
1878 if (!new_pending_state) {
1881 new_pending = new_pending_state->topology;
1883 for (i = 0; i < max_stream_count; i++) {
1900 const char *found_da_name __attribute__((unused)) =
"";
1901 const char *found_np_name __attribute__((unused)) =
"";
1902 int found_da_slot __attribute__((unused)) = -1;
1903 int found_np_slot = -1;
1904 int removed_np_slot = -1;
1906 SCOPE_ENTER(3,
"%s: slot: %d DP: %s DA: %s CA: %s\n", session_name, i,
1936 SCOPE_EXIT_EXPR(
continue,
"%s: No DP stream so use CA stream as is\n", session_name);
1944 ast_trace(-1,
"%s: Same stream in all 3 states\n", session_name);
1945 if (dp_state == da_state && da_state == ca_state) {
1947 SCOPE_EXIT_EXPR(
continue,
"%s: All in the same state so nothing to do\n", session_name);
1949 if (da_state != ca_state) {
1954 SCOPE_EXIT_EXPR(
continue,
"%s: Ignoring request to change state from %s to %s\n",
1957 if (dp_state != da_state) {
1960 SCOPE_EXIT_EXPR(
continue,
"%s: Changed NP stream state from %s to %s\n",
1985 ast_trace(-1,
"%s: Checking if DP is already in NP somewhere\n", session_name);
1990 ast_trace(-1,
"%s: Checking %s against %s\n", session_name, dp_name, possible_existing_name);
1991 if (found_np_slot == -1 &&
ast_strings_equal(dp_name, possible_existing_name)) {
1992 ast_trace(-1,
"%s: Pending stream %s slot %d is in NP slot %d\n", session_name,
1995 found_np_stream = possible_existing;
1999 if (
STREAM_REMOVED(possible_existing) && removed_np_slot == -1) {
2000 removed_np_slot = j;
2002 if (removed_np_slot >= 0 && found_np_slot >= 0) {
2009 found_np_stream = np_stream;
2010 found_np_state = np_state;
2011 found_np_name = np_name;
2022 ast_trace(-1,
"%s: Checking if DP is already in DA somewhere\n", session_name);
2027 ast_trace(-1,
"%s: Checking %s against %s\n", session_name, dp_name, possible_existing_name);
2029 ast_trace(-1,
"%s: Pending stream %s slot %d is already in delayed active slot %d\n",
2030 session_name, dp_name, i, j);
2032 found_da_stream = possible_existing;
2041 found_da_stream = da_stream;
2042 found_da_state = da_state;
2043 found_da_name = da_name;
2046 ast_trace(-1,
"%s: Found NP slot: %d Found removed NP slot: %d Found DA slot: %d\n",
2047 session_name, found_np_slot, removed_np_slot, found_da_slot);
2054 if (!found_da_stream) {
2061 ast_trace(-1,
"%s: There was no corresponding DA stream so the request was to add a stream\n", session_name);
2063 if (found_np_stream) {
2068 SCOPE_EXIT_EXPR(
continue,
"%s: New stream requested but it's already in CA\n", session_name);
2073 ast_trace(-1,
"%s: There was no corresponding NP stream\n", session_name);
2082 "%s: Attempting to remove stream %d:%s but it doesn't exist anywhere.\n", session_name, i, dp_name);
2089 ast_trace(-1,
"%s: Checking for open slot\n", session_name);
2090 if (removed_np_slot >= 0) {
2108 session_name, removed_np_slot);
2120 session_name, new_slot);
2128 ast_trace(-1,
"%s: There was a corresponding DA stream so the request was to change/remove a stream\n", session_name);
2129 if (dp_state == found_da_state) {
2131 if (!found_np_stream) {
2139 SCOPE_EXIT_EXPR(
continue,
"%s: Stream doesn't exist in CA so nothing to do\n", session_name);
2140 }
else if (dp_state == found_np_state) {
2141 SCOPE_EXIT_EXPR(
continue,
"%s: States are the same all around so nothing to do\n", session_name);
2143 SCOPE_EXIT_EXPR(
continue,
"%s: Something changed the CA state so we're going to leave it as is\n", session_name);
2148 if (!found_np_stream) {
2149 SCOPE_EXIT_EXPR(
continue,
"%s: Stream doesn't exist in CA so nothing to do\n", session_name);
2150 }
else if (da_state == found_np_state) {
2152 SCOPE_EXIT_EXPR(
continue,
"%s: Changed NP stream state from %s to %s\n",
2155 SCOPE_EXIT_EXPR(
continue,
"%s: Something changed the CA state so we're going to leave it as is\n",
2161 SCOPE_EXIT(
"%s: Done with slot %d\n", session_name, i);
2164 ast_trace(-1,
"%s: Resetting default media states\n", session_name);
2167 new_pending_state->default_session[i] =
NULL;
2173 new_pending_state->default_session[i] = media;
2179 if (run_post_validation) {
2180 ast_trace(-1,
"%s: Running post-validation\n", session_name);
2190 returned_media_state = new_pending_state;
2191 new_pending_state =
NULL;
2205 pjsip_inv_session *inv_session =
session->inv_session;
2206 pjmedia_sdp_session *new_sdp =
NULL;
2207 pjsip_tx_data *tdata;
2210 generate_new_sdp ?
"yes" :
"no", queued ?
"yes" :
"no",
2214 if (pending_media_state && (!pending_media_state->
topology || !generate_new_sdp)) {
2219 pending_media_state->
topology ==
NULL ?
"pending topology is null " :
"",
2220 !generate_new_sdp ?
"generate_new_sdp is false" :
"");
2223 if (inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
2232 if (inv_session->dlg->state != PJSIP_DIALOG_STATE_ESTABLISHED) {
2238 SCOPE_EXIT_RTN_VALUE(res,
"%s: Delay sending reinvite because dialog has not been established\n",
2243 if (inv_session->invite_tsx) {
2250 }
else if (inv_session->state != PJSIP_INV_STATE_CONFIRMED) {
2261 if (generate_new_sdp) {
2263 if (inv_session->neg
2264 && pjmedia_sdp_neg_get_state(inv_session->neg)
2265 != PJMEDIA_SDP_NEG_STATE_DONE) {
2267 on_response, generate_new_sdp,
2271 SCOPE_EXIT_RTN_VALUE(res,
"%s: Delay session refresh with new SDP because SDP negotiation is not yet done\n",
2276 if (pending_media_state) {
2289 on_response, generate_new_sdp,
2301 if (active_media_state && active_media_state->
topology &&
2315 pending_media_state, active_media_state,
session->active_media_state, 1);
2316 if (new_pending_state) {
2319 pending_media_state = new_pending_state;
2340 if (
session->active_media_state->topology &&
2367 if (!existing_stream) {
2393 if (!existing_stream) {
2428 if (
session->active_media_state->topology) {
2462 SCOPE_EXIT(
"%s: Appended empty stream in position %d to make counts match\n",
2485 session->pending_media_state = pending_media_state;
2495 if (on_sdp_creation) {
2496 if (on_sdp_creation(
session, new_sdp)) {
2505 if (pjsip_inv_reinvite(inv_session,
NULL, new_sdp, &tdata)) {
2506 if (generate_new_sdp) {
2512 }
else if (pjsip_inv_update(inv_session,
NULL, new_sdp, &tdata)) {
2513 if (generate_new_sdp) {
2519 if (on_request_creation) {
2520 if (on_request_creation(
session, tdata)) {
2521 if (generate_new_sdp) {
2544 on_response,
method, generate_new_sdp, media_state,
NULL, 0);
2550 pjsip_inv_session *inv_session =
session->inv_session;
2551 pjmedia_sdp_session *new_answer =
NULL;
2552 const pjmedia_sdp_session *previous_offer =
NULL;
2556 if (!inv_session->neg || (pjmedia_sdp_neg_get_state(inv_session->neg) != PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER &&
2557 pjmedia_sdp_neg_get_state(inv_session->neg) != PJMEDIA_SDP_NEG_STATE_WAIT_NEGO)) {
2558 ast_log(
LOG_WARNING,
"Requested to regenerate local SDP answer for channel '%s' but negotiation in state '%s'\n",
2563 pjmedia_sdp_neg_get_neg_remote(inv_session->neg, &previous_offer);
2564 if (pjmedia_sdp_neg_get_state(inv_session->neg) == PJMEDIA_SDP_NEG_STATE_WAIT_NEGO) {
2566 pjmedia_sdp_neg_negotiate(inv_session->pool, inv_session->neg, 0);
2567 pjmedia_sdp_neg_set_remote_offer(inv_session->pool, inv_session->neg, previous_offer);
2577 if (on_sdp_creation) {
2578 if (on_sdp_creation(
session, new_answer)) {
2583 pjsip_inv_set_sdp_answer(inv_session, new_answer);
2590 pjsip_dialog *dlg = pjsip_tdata_get_dlg(tdata);
2597 pjsip_inv_send_msg(
session->inv_session, tdata);
2607 .name = {
"Session Module", 14},
2608 .priority = PJSIP_MOD_PRIORITY_APPLICATION,
2624 if (!
session->pending_media_state->topology) {
2626 if (!
session->pending_media_state->topology) {
2631 for (i = 0; i < sdp->media_count; ++i) {
2641 pjmedia_sdp_media *remote_stream = sdp->media[i];
2646 if (
session->active_media_state->topology &&
2665 if (existing_stream) {
2674 if (!session_media) {
2680 if (pjmedia_sdp_media_find_attr2(remote_stream,
"sendonly",
NULL)) {
2686 }
else if (pjmedia_sdp_media_find_attr2(remote_stream,
"recvonly",
NULL)) {
2688 }
else if (pjmedia_sdp_media_find_attr2(remote_stream,
"inactive",
NULL)) {
2699 if (
handler->defer_incoming_sdp_stream) {
2700 res =
handler->defer_incoming_sdp_stream(
session, session_media, sdp,
2718 if (!handler_list) {
2726 if (!
handler->defer_incoming_sdp_stream) {
2729 res =
handler->defer_incoming_sdp_stream(
session, session_media, sdp,
2757 pjsip_rdata_sdp_info *sdp_info;
2760 if (rdata->msg_info.msg->line.req.method.id != PJSIP_INVITE_METHOD ||
2761 !(dlg = pjsip_ua_find_dialog(&rdata->msg_info.cid->id, &rdata->msg_info.to->tag, &rdata->msg_info.from->tag, PJ_FALSE)) ||
2767 if (
session->inv_session->invite_tsx) {
2772 if (
session->deferred_reinvite) {
2773 pj_str_t key, deferred_key;
2774 pjsip_tx_data *tdata;
2777 pjsip_tsx_create_key(rdata->tp_info.pool, &key, PJSIP_ROLE_UAS, &rdata->msg_info.cseq->method, rdata);
2778 pjsip_tsx_create_key(rdata->tp_info.pool, &deferred_key, PJSIP_ROLE_UAS, &
session->deferred_reinvite->msg_info.cseq->method,
2782 if (!pj_strcmp(&key, &deferred_key)) {
2787 if (pjsip_dlg_create_response(dlg, rdata, 491,
NULL, &tdata) == PJ_SUCCESS) {
2789 pjsip_tx_data_dec_ref(tdata);
2796 if (!(sdp_info = pjsip_rdata_get_sdp_info(rdata)) ||
2797 (sdp_info->sdp_err != PJ_SUCCESS)) {
2801 if (!sdp_info->sdp) {
2806 if (deferred == -1) {
2809 }
else if (!deferred) {
2813 pjsip_rx_data_clone(rdata, 0, &
session->deferred_reinvite);
2820 if (!
session->deferred_reinvite) {
2828 pjsip_rx_data_free_cloned(
session->deferred_reinvite);
2833 .name = {
"Session Re-Invite Module", 24 },
2834 .priority = PJSIP_MOD_PRIORITY_UA_PROXY_LAYER - 1,
2841 pjsip_inv_session *inv_session =
session->inv_session;
2848 if (inv_session->state == PJSIP_INV_STATE_DISCONNECTED &&
2849 tdata->msg->line.req.method.id != PJSIP_BYE_METHOD) {
2857 pjsip_inv_send_msg(
session->inv_session, tdata);
2869 pjmedia_sdp_session *offer;
2873 pjsip_inv_terminate(
session->inv_session, 500, PJ_FALSE);
2877 pjsip_inv_set_local_sdp(
session->inv_session, offer);
2878 pjmedia_sdp_neg_set_prefer_remote_codec_order(
session->inv_session->neg, PJ_FALSE);
2879#ifdef PJMEDIA_SDP_NEG_ANSWER_MULTIPLE_CODECS
2880 if (!
session->endpoint->preferred_codec_only) {
2881 pjmedia_sdp_neg_set_answer_multiple_codecs(
session->inv_session->neg, PJ_TRUE);
2891 if (pjsip_inv_invite(
session->inv_session, tdata) != PJ_SUCCESS) {
2912 const char *uid2 = flags &
OBJ_KEY ? arg : datastore2->
uid;
2925#ifdef TEST_FRAMEWORK
2927 const char *endpoint_name =
session->endpoint ?
2970 struct pjsip_dialog *dlg =
session->inv_session->dlg;
2976#ifdef HAVE_PJSIP_INV_SESSION_REF
2977 pjsip_inv_dec_ref(
session->inv_session);
3015 int dsp_features = 0;
3027 if (!
session->direct_media_cap) {
3036 if (!
session->active_media_state) {
3040 if (!
session->pending_media_state) {
3098#ifdef HAVE_PJSIP_INV_SESSION_REF
3099 if (pjsip_inv_add_ref(
inv_session) != PJ_SUCCESS) {
3119 session->authentication_challenge_count = 0;
3208 session->suspended = suspender;
3253 pjsip_transaction *tsx;
3255 pjsip_inv_session *inv;
3256 pjsip_tx_data *tdata;
3259 if (rdata->msg_info.msg->line.status.code != 401
3260 && rdata->msg_info.msg->line.status.code != 407) {
3265 tsx = pjsip_rdata_get_tsx(rdata);
3266 dlg = pjsip_rdata_get_dlg(rdata);
3271 if (tsx->method.id != PJSIP_INVITE_METHOD) {
3276 inv = pjsip_dlg_get_inv_session(dlg);
3279 if (PJSIP_INV_STATE_CONFIRMED <= inv->
state) {
3296 tsx->last_tx, &tdata)) {
3304 pjsip_inv_uac_restart(inv, PJ_FALSE);
3311 .name = {
"Outbound INVITE Auth", 20},
3312 .priority = PJSIP_MOD_PRIORITY_DIALOG_USAGE,
3334 return status != PJ_SUCCESS ? -1 : 0;
3341 const char *uri =
NULL;
3344 pjsip_timer_setting
timer;
3346 struct pjsip_inv_session *inv_session;
3357 &found_aor, &found_contact);
3361 uri = found_contact->uri;
3369 ast_log(
LOG_ERROR,
"Endpoint '%s': No URI available. Is endpoint registered?\n",
3379 pjsip_dlg_terminate(dlg);
3384 pjsip_dlg_terminate(dlg);
3387#if defined(HAVE_PJSIP_REPLACE_MEDIA_STREAM) || defined(PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE)
3388 inv_session->sdp_neg_flags = PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE;
3391 pjsip_timer_setting_default(&
timer);
3427 if (!
session->pending_media_state->topology) {
3429 if (!
session->pending_media_state->topology) {
3430 pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
3443 if (!
session->pending_media_state->topology) {
3446 if (!
session->pending_media_state->topology) {
3447 pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
3454 pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
3474 pjsip_tx_data *packet =
NULL;
3477 if (
session->defer_terminate) {
3478 session->terminate_while_deferred = 1;
3496 switch (
session->inv_session->state) {
3497 case PJSIP_INV_STATE_NULL:
3498 if (!
session->inv_session->invite_tsx) {
3507 pjsip_inv_terminate(
session->inv_session, response, PJ_TRUE);
3515 pjsip_inv_terminate(
session->inv_session, response, PJ_TRUE);
3518 case PJSIP_INV_STATE_CONFIRMED:
3519 if (
session->inv_session->invite_tsx) {
3520 ast_debug(3,
"%s: Delay sending BYE because of outstanding transaction...\n",
3531 if (
status == PJ_SUCCESS && packet) {
3539 if (packet->msg->type == PJSIP_RESPONSE_MSG) {
3554 if (
session->defer_terminate) {
3576 pj_time_val delay = { .sec = 60, };
3585 session->ended_while_deferred = 0;
3591 &
session->scheduled_termination, &delay) != PJ_SUCCESS) ? -1 : 0;
3609 &
session->scheduled_termination,
session->scheduled_termination.id)) {
3616 if (!
session->defer_terminate) {
3623 if (
session->terminate_while_deferred) {
3640 if (
session->ended_while_deferred) {
3643 session->ended_while_deferred = 0;
3650 pjsip_inv_session *
inv_session = pjsip_dlg_get_inv_session(dlg);
3679 return PJSIP_INV_STATE_NULL;
3724 pjsip_uri *ruri = rdata->msg_info.msg->line.req.uri;
3735 ast_debug(1,
"RURI contains no user portion: defaulting to extension 's'\n");
3747 ast_log(
LOG_ERROR,
"%s: Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n",
3765 session->request_uri = pjsip_uri_clone(
session->inv_session->pool, ruri);
3773 if (
session->endpoint->allow_overlap && (
3806 int answer_code,
int terminate_code, pj_bool_t notify)
3808 pjsip_tx_data *tdata =
NULL;
3811 if (inv_session->state != PJSIP_INV_STATE_DISCONNECTED) {
3812 if (pjsip_inv_initial_answer(
3813 inv_session, rdata, answer_code,
NULL,
NULL, &tdata) != PJ_SUCCESS) {
3815 pjsip_inv_terminate(inv_session, terminate_code ? terminate_code : answer_code, notify);
3818 pjsip_inv_send_msg(inv_session, tdata);
3822 if (answer_code >= 300) {
3827 pjsip_dlg_dec_lock(inv_session->dlg);
3854 pjsip_tx_data *tdata;
3856 pjsip_inv_session *inv_session;
3858 const pj_str_t STR_100REL = {
"100rel", 6};
3860 pj_status_t dlg_status = PJ_EUNKNOWN;
3867 for (i = 0; i < rdata->msg_info.supported->count; ++i) {
3868 if (pj_stricmp(&rdata->msg_info.supported->values[i], &STR_100REL) == 0) {
3869 options |= PJSIP_INV_REQUIRE_100REL;
3878 pjsip_tx_data_dec_ref(tdata);
3888 if (dlg_status != PJ_EEXISTS) {
3899 if (pjsip_inv_create_uas(dlg, rdata,
NULL,
options, &inv_session) != PJ_SUCCESS) {
3906 pjsip_dlg_dec_lock(dlg);
3907 pjsip_dlg_terminate(dlg);
3911#if defined(HAVE_PJSIP_REPLACE_MEDIA_STREAM) || defined(PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE)
3912 inv_session->sdp_neg_flags = PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE;
3935 pjsip_media_type app_sdp;
3936 pjsip_media_type_init2(&app_sdp,
"application",
"sdp");
3938 if (!pjsip_media_type_cmp(content_type, &app_sdp, 0)) {
3947 pjsip_hdr *hdr = part->hdr.next;
3948 static const pj_str_t str_handling_required = {
"handling=required", 16};
3950 while (hdr != &part->hdr) {
3951 if (hdr->type == PJSIP_H_OTHER) {
3952 pjsip_generic_string_hdr *generic_hdr = (pjsip_generic_string_hdr*)hdr;
3954 if (!pj_stricmp2(&hdr->name,
"Content-Disposition") &&
3955 pj_stristr(&generic_hdr->hvalue, &str_handling_required) &&
3971 pjsip_msg_body *body = rdata->msg_info.msg->body;
3972 pjsip_ctype_hdr *ctype_hdr = rdata->msg_info.ctype;
3974 if (body && ctype_hdr &&
3977 pjsip_multipart_part *part = pjsip_multipart_get_first_part(body);
3978 while (part !=
NULL) {
3982 part = pjsip_multipart_get_next_part(body, part);
3990 pjsip_tx_data *tdata =
NULL;
3991 pjsip_timer_setting
timer;
3992 pjsip_rdata_sdp_info *sdp_info;
3993 pjmedia_sdp_session *local =
NULL;
4015 ast_trace(-1,
"%s: Call (%s:%s) to extension '%s' - unsupported uri\n",
4017 invite->
rdata->tp_info.transport->type_name,
4018 pj_sockaddr_print(&invite->
rdata->pkt_info.src_addr, buffer,
sizeof(buffer), 3),
4027 ast_trace(-1,
"%s: Call (%s:%s) to extension '%s' - partial match\n",
4029 invite->
rdata->tp_info.transport->type_name,
4030 pj_sockaddr_print(&invite->
rdata->pkt_info.src_addr, buffer,
sizeof(buffer), 3),
4041 ast_trace_log(-1,
LOG_NOTICE,
"%s: Call (%s:%s) to extension '%s' rejected because extension not found in context '%s'.\n",
4043 invite->
rdata->tp_info.transport->type_name,
4044 pj_sockaddr_print(&invite->
rdata->pkt_info.src_addr, buffer,
sizeof(buffer), 3),
4065 pjsip_timer_setting_default(&
timer);
4084 ast_trace(-1,
"%s: Call (%s:%s) to extension '%s' sending 100 Trying\n",
4086 invite->
rdata->tp_info.transport->type_name,
4087 pj_sockaddr_print(&invite->
rdata->pkt_info.src_addr, buffer,
sizeof(buffer), 3),
4091 sdp_info = pjsip_rdata_get_sdp_info(invite->
rdata);
4092 if (sdp_info && (sdp_info->sdp_err == PJ_SUCCESS) && sdp_info->sdp) {
4119 pjmedia_sdp_neg_set_prefer_remote_codec_order(invite->
session->
inv_session->neg, PJ_FALSE);
4120#ifdef PJMEDIA_SDP_NEG_ANSWER_MULTIPLE_CODECS
4122 pjmedia_sdp_neg_set_answer_multiple_codecs(invite->
session->
inv_session->neg, PJ_TRUE);
4140 int res =
TRACE_ATLEAST(1) ? pjsip_uri_print(PJSIP_URI_IN_REQ_URI,
rdata->msg_info.msg->line.req.uri, req_uri, 256) : 0;
4141 SCOPE_ENTER(1,
"Request: %s\n", res ? req_uri :
"");
4179 pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
4205 pjsip_dlg_dec_lock(inv_session->dlg);
4219 pj_cstr(&
method, supplement_method);
4227 struct pjsip_method *
method = &rdata->msg_info.msg->line.req.method;
4248 pjsip_dialog *dlg = pjsip_tsx_get_dlg(tsx);
4249 pjsip_inv_session *inv_session = (dlg ? pjsip_dlg_get_inv_session(dlg) :
NULL);
4255 ast_trace(2,
"Topology: Pending: %s Active: %s\n",
4270 struct pjsip_status_line
status = rdata->msg_info.msg->line.status;
4271 pjsip_dialog *dlg = pjsip_rdata_get_dlg(rdata);
4272 pjsip_inv_session *inv_session = dlg ? pjsip_dlg_get_inv_session(dlg) :
NULL;
4275 (
int)rdata->msg_info.cseq->method.name.slen, rdata->msg_info.cseq->method.name.ptr,
status.code);
4299 pj_status_t handled = PJ_FALSE;
4300 struct pjsip_request_line req = rdata->msg_info.msg->line.req;
4301 pjsip_dialog *dlg = pjsip_rdata_get_dlg(rdata);
4302 pjsip_inv_session *inv_session = (dlg ? pjsip_dlg_get_inv_session(dlg) :
NULL);
4305 int res =
TRACE_ATLEAST(1) ? pjsip_uri_print(PJSIP_URI_IN_REQ_URI, rdata->msg_info.msg->line.req.uri, req_uri, 256) : 0;
4307 (
int) pj_strlen(&req.method.name), pj_strbuf(&req.method.name), res ? req_uri :
"");
4309 switch (req.method.id) {
4310 case PJSIP_INVITE_METHOD:
4320 handled = dlg && (
inv_session = pjsip_dlg_get_inv_session(dlg)) &&
4326 (
int) pj_strlen(&req.method.name), pj_strbuf(&req.method.name), req_uri,
4327 handled == PJ_TRUE ?
"yes" :
"no");
4333 pjsip_dialog *dlg = pjsip_tdata_get_dlg(tdata);
4346 ast_debug(3,
"%s: re-INVITE collision timer expired.\n",
4365 pjsip_inv_session *inv =
session->inv_session;
4370 int use_pending = 0;
4384 use_pending =
session->pending_media_state->topology !=
NULL;
4385 use_active =
session->active_media_state->topology !=
NULL;
4398 if (!pending_media_state) {
<