55 #define SDP_HANDLER_BUCKETS 11
57 #define MOD_DATA_ON_RESPONSE "on_response"
58 #define MOD_DATA_NAT_HOOK "nat_hook"
61 #define DEFAULT_NUM_SESSION_MEDIA 2
118 return "(null session)";
122 }
else if (
session->endpoint) {
154 ast_debug(1,
"Registered SDP stream handler '%s' for stream type '%s'\n",
handler->id, stream_type);
160 handler_list =
ao2_alloc(
sizeof(*handler_list) + strlen(stream_type),
NULL);
165 strcpy(handler_list->stream_type, stream_type);
171 ast_debug(1,
"Registered SDP stream handler '%s' for stream type '%s'\n",
handler->id, stream_type);
181 const char *stream_type = arg;
186 ast_debug(1,
"Unregistered SDP stream handler '%s' for stream type '%s'\n",
handler->id, stream_type);
192 ast_debug(3,
"No more handlers exist for stream type '%s'\n", stream_type);
219 media_state =
ast_calloc(1,
sizeof(*media_state));
249 if (!media_state || !sip_session) {
256 if (!media || !media->
rtp) {
363 if (!
session->pending_media_state->topology) {
390 .read_callback = callback,
391 .session = session_media,
419 return session_media;
429 return bundle_group_session_media;
433 return session_media;
463 handler->stream_destroy(session_media);
480 if (session_media->
srtp) {
502 if (current_session_media && current_session_media->
type ==
type) {
513 ast_trace(1,
"Reusing existing media session\n");
529 ast_trace(1,
"Can't reuse existing media session because the types are different. %s <> %s\n",
531 session_media =
NULL;
535 if (!session_media) {
538 if (!session_media) {
541 ast_trace(1,
"Creating new media session\n");
551 if (
session->endpoint->media.bundle) {
601 return (type_streams[
type] > 0);
617 for (index = 0; index < sdp->attr_count; ++index) {
618 pjmedia_sdp_attr *attr = sdp->attr[index];
619 char value[pj_strlen(&attr->value) + 1], *mids =
value, *attr_mid;
621 if (pj_strcmp2(&attr->name,
"group") || pj_strncmp2(&attr->value,
"BUNDLE", 6)) {
630 while ((attr_mid =
strsep(&mids,
" "))) {
631 if (!strcmp(attr_mid,
mid)) {
648 const pjmedia_sdp_session *sdp,
649 const struct pjmedia_sdp_media *stream)
651 pjmedia_sdp_attr *attr;
653 if (!
session->endpoint->media.bundle) {
664 attr = pjmedia_sdp_media_find_attr2(stream,
"mid",
NULL);
670 if (!session_media->
mid) {
686 const pjmedia_sdp_session *sdp,
687 const struct pjmedia_sdp_media *stream,
697 for (index = 0; index < stream->attr_count; ++index) {
698 pjmedia_sdp_attr *attr = stream->attr[index];
699 char attr_value[pj_strlen(&attr->value) + 1];
700 char *ssrc_attribute_name, *ssrc_attribute_value =
NULL;
701 char *msid, *
tmp = attr_value;
702 static const pj_str_t STR_msid = {
"msid", 4 };
703 static const pj_str_t STR_ssrc = {
"ssrc", 4 };
704 static const pj_str_t STR_label = {
"label", 5 };
706 if (!pj_strcmp(&attr->name, &STR_label)) {
709 }
else if (!pj_strcmp(&attr->name, &STR_msid)) {
714 }
else if (!pj_strcmp(&attr->name, &STR_ssrc)) {
717 if ((ssrc_attribute_name = strchr(attr_value,
' '))) {
719 *ssrc_attribute_name++ =
'\0';
720 ssrc_attribute_value = strchr(ssrc_attribute_name,
':');
721 if (ssrc_attribute_value) {
723 *ssrc_attribute_value++ =
'\0';
726 if (!strcasecmp(ssrc_attribute_name,
"mslabel") && !
ast_strlen_zero(ssrc_attribute_value)) {
771 if (
session->inv_session &&
session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
777 if (!
session->pending_media_state->topology) {
779 if (!
session->pending_media_state->topology) {
785 for (i = 0; i < sdp->media_count; ++i) {
794 pjmedia_sdp_media *remote_stream = sdp->media[i];
809 char *stream_name =
NULL, *stream_name_allocated =
NULL;
810 const char *stream_label =
NULL;
812 if (
session->active_media_state->topology &&
831 stream_name = stream_name_allocated;
860 if (pjmedia_sdp_media_find_attr2(remote_stream,
"sendonly",
NULL)) {
866 }
else if (pjmedia_sdp_media_find_attr2(remote_stream,
"recvonly",
NULL)) {
868 }
else if (pjmedia_sdp_media_find_attr2(remote_stream,
"inactive",
NULL)) {
881 if (!session_media) {
889 SCOPE_EXIT_EXPR(
continue,
"%s: Declining incoming SDP media stream %s'\n",
898 ast_trace(-1,
"%s: Negotiating incoming SDP media stream %s using %s SDP handler\n",
901 res =
handler->negotiate_incoming_sdp_stream(
session, session_media, sdp, i, stream);
906 }
else if (res == 0) {
908 SCOPE_EXIT_EXPR(
continue,
"%s: Declining incoming SDP media stream %s\n",
910 }
else if (res > 0) {
912 ++type_streams[
type];
922 SCOPE_EXIT_EXPR(
continue,
"%s: Media stream %s has no registered handlers\n",
929 ast_trace(-1,
"%s: Negotiating incoming SDP media stream %s using %s SDP handler\n",
933 res =
handler->negotiate_incoming_sdp_stream(
session, session_media, sdp, i, stream);
939 }
else if (res == 0) {
941 ast_trace(-1,
"%s: Declining incoming SDP media stream %s\n",
944 }
else if (res > 0) {
947 ++type_streams[
type];
948 ast_trace(-1,
"%s: Media stream %s handled by %s\n",
961 handled ?
"yes" :
"no");
966 const pjmedia_sdp_session *remote,
int index,
struct ast_stream *asterisk_stream)
969 struct pjmedia_sdp_media *local_stream = local->media[index];
977 ast_copy_pj_str(media, &local->media[index]->desc.media,
sizeof(media));
987 if (pjmedia_sdp_media_find_attr2(local_stream,
"sendonly",
NULL)) {
989 }
else if (pjmedia_sdp_media_find_attr2(local_stream,
"recvonly",
NULL)) {
991 }
else if (pjmedia_sdp_media_find_attr2(local_stream,
"inactive",
NULL)) {
1005 ast_debug(4,
"%s: Applying negotiated SDP media stream '%s' using %s SDP handler\n",
1008 res =
handler->apply_negotiated_sdp_stream(
session, session_media, local, remote, index, asterisk_stream);
1010 ast_debug(4,
"%s: Applied negotiated SDP media stream '%s' using %s SDP handler\n",
1017 SCOPE_EXIT_RTN_VALUE(-1,
"%s: Failed to apply negotiated SDP media stream '%s' using %s SDP handler\n",
1023 if (!handler_list) {
1031 ast_debug(4,
"%s: Applying negotiated SDP media stream '%s' using %s SDP handler\n",
1034 res =
handler->apply_negotiated_sdp_stream(
session, session_media, local, remote, index, asterisk_stream);
1041 ast_debug(4,
"%s: Applied negotiated SDP media stream '%s' using %s SDP handler\n",
1053 ast_debug(4,
"%s: Stopping SDP media stream '%s' as it is not currently negotiated\n",
1060 res ?
"not negotiated. Stopped" :
"handled");
1067 unsigned int changed = 0;
1070 if (!
session->pending_media_state->topology) {
1071 if (
session->active_media_state->topology) {
1079 active_media_state_clone =
1081 if (!active_media_state_clone) {
1088 session->pending_media_state = active_media_state_clone;
1103 ast_log(
LOG_WARNING,
"%s: Local SDP contains %d media streams while we expected it to contain %u\n",
1109 for (i = 0; i < local->media_count; ++i) {
1113 if (!remote->media[i]) {
1124 if (!remote->media[i]->desc.port) {
1146 changed |= session_media->
changed;
1154 for (i = 0; i < local->media_count; ++i) {
1158 if (!remote->media[i]) {
1184 if (pjmedia_sdp_neg_was_answer_remote(
session->inv_session->neg) == PJ_FALSE &&
1185 session->active_media_state &&
session->active_media_state->topology &&
1217 }
else if (changed == 2) {
1226 #define DATASTORE_BUCKETS 53
1227 #define MEDIA_BUCKETS 7
1247 const char *uid_ptr =
uid;
1258 datastore->info =
info;
1265 if (!datastore->uid) {
1312 const char *
str =
"<unknown>";
1397 SCOPE_ENTER(3,
"%s: sending delayed %s request\n",
1497 timer_running = pj_timer_entry_running(&
session->rescheduled_reinvite);
1502 if (!timer_running) {
1544 if (
session->inv_session->invite_tsx) {
1573 if (
session->inv_session->invite_tsx) {
1583 int (*cb)(
void *vsession))
1595 int generate_new_sdp,
1623 pjsip_inv_session *inv_session =
session->inv_session;
1624 const pjmedia_sdp_session *previous_sdp =
NULL;
1627 if (inv_session->neg) {
1628 if (pjmedia_sdp_neg_was_answer_remote(inv_session->neg)) {
1629 pjmedia_sdp_neg_get_active_remote(inv_session->neg, &previous_sdp);
1631 pjmedia_sdp_neg_get_active_local(inv_session->neg, &previous_sdp);
1641 pj_pool_t *dlg_pool;
1642 pjsip_fromto_hdr *dlg_info;
1643 pjsip_contact_hdr *dlg_contact;
1644 pjsip_name_addr *dlg_info_name_addr;
1645 pjsip_sip_uri *dlg_info_uri;
1646 pjsip_sip_uri *dlg_contact_uri;
1648 const char *pjsip_from_domain;
1666 dlg_pool =
session->inv_session->dlg->pool;
1667 dlg_info =
session->inv_session->dlg->local.info;
1668 dlg_contact =
session->inv_session->dlg->local.contact;
1669 dlg_info_name_addr = (pjsip_name_addr *) dlg_info->uri;
1670 dlg_info_uri = pjsip_uri_get_uri(dlg_info_name_addr);
1671 dlg_contact_uri = (pjsip_sip_uri*)pjsip_uri_get_uri(dlg_contact->uri);
1673 if (
session->endpoint->id.trust_outbound || !restricted) {
1683 dlg_info_name_addr->display.ptr =
NULL;
1684 dlg_info_name_addr->display.slen = 0;
1685 pj_strdup2(dlg_pool, &dlg_info_uri->user,
session->endpoint->fromuser);
1689 pj_strdup2(dlg_pool, &dlg_info_uri->host,
session->endpoint->fromdomain);
1698 ast_debug(3,
"%s: From header domain reset by channel variable SIPFROMDOMAIN (%s)\n",
1700 pj_strdup2(dlg_pool, &dlg_info_uri->host, pjsip_from_domain);
1705 session->saved_from_hdr = pjsip_hdr_clone(dlg_pool, dlg_info);
1713 pj_strdup2(dlg_pool, &dlg_info_name_addr->display,
"Anonymous");
1716 pj_strdup2(dlg_pool, &dlg_info_uri->user,
"anonymous");
1720 pj_strdup2(dlg_pool, &dlg_contact_uri->user,
"anonymous");
1724 pj_strdup2(dlg_pool, &dlg_info_uri->host,
"anonymous.invalid");
1734 #define STREAM_REMOVED(_stream) (ast_stream_get_state(_stream) == AST_STREAM_STATE_REMOVED)
1735 #define STATE_REMOVED(_stream_state) (_stream_state == AST_STREAM_STATE_REMOVED)
1736 #define STATE_NONE(_stream_state) (_stream_state == AST_STREAM_STATE_END)
1737 #define GET_STREAM_SAFE(_topology, _i) (_i < ast_stream_topology_get_count(_topology) ? ast_stream_topology_get_stream(_topology, _i) : NULL)
1738 #define GET_STREAM_STATE_SAFE(_stream) (_stream ? ast_stream_get_state(_stream) : AST_STREAM_STATE_END)
1739 #define GET_STREAM_NAME_SAFE(_stream) (_stream ? ast_stream_get_name(_stream) : "")
1758 SCOPE_ENTER(3,
"%s: Topology: %s\n", session_name,
1766 for (i = 0; i < stream_count; i++) {
1769 const char *stream_name =
NULL;
1778 for (j = 0; j < stream_count; j++) {
1780 if (j == i || !possible_dup) {
1796 if (j == i || !possible_dup) {
1802 i, media->
label, j);
1837 const char *session_name,
1841 int run_post_validation)
1850 int max_stream_count;
1852 SCOPE_ENTER(2,
"%s: DP: %s DA: %s CA: %s\n", session_name,
1867 if (!new_pending_state) {
1870 new_pending = new_pending_state->topology;
1872 for (i = 0; i < max_stream_count; i++) {
1889 const char *found_da_name __attribute__((unused)) =
"";
1890 const char *found_np_name __attribute__((unused)) =
"";
1891 int found_da_slot __attribute__((unused)) = -1;
1892 int found_np_slot = -1;
1893 int removed_np_slot = -1;
1895 SCOPE_ENTER(3,
"%s: slot: %d DP: %s DA: %s CA: %s\n", session_name, i,
1925 SCOPE_EXIT_EXPR(
continue,
"%s: No DP stream so use CA stream as is\n", session_name);
1933 ast_trace(-1,
"%s: Same stream in all 3 states\n", session_name);
1934 if (dp_state == da_state && da_state == ca_state) {
1936 SCOPE_EXIT_EXPR(
continue,
"%s: All in the same state so nothing to do\n", session_name);
1938 if (da_state != ca_state) {
1943 SCOPE_EXIT_EXPR(
continue,
"%s: Ignoring request to change state from %s to %s\n",
1946 if (dp_state != da_state) {
1949 SCOPE_EXIT_EXPR(
continue,
"%s: Changed NP stream state from %s to %s\n",
1974 ast_trace(-1,
"%s: Checking if DP is already in NP somewhere\n", session_name);
1979 ast_trace(-1,
"%s: Checking %s against %s\n", session_name, dp_name, possible_existing_name);
1980 if (found_np_slot == -1 &&
ast_strings_equal(dp_name, possible_existing_name)) {
1981 ast_trace(-1,
"%s: Pending stream %s slot %d is in NP slot %d\n", session_name,
1984 found_np_stream = possible_existing;
1988 if (
STREAM_REMOVED(possible_existing) && removed_np_slot == -1) {
1989 removed_np_slot = j;
1991 if (removed_np_slot >= 0 && found_np_slot >= 0) {
1998 found_np_stream = np_stream;
1999 found_np_state = np_state;
2000 found_np_name = np_name;
2011 ast_trace(-1,
"%s: Checking if DP is already in DA somewhere\n", session_name);
2016 ast_trace(-1,
"%s: Checking %s against %s\n", session_name, dp_name, possible_existing_name);
2018 ast_trace(-1,
"%s: Pending stream %s slot %d is already in delayed active slot %d\n",
2019 session_name, dp_name, i, j);
2021 found_da_stream = possible_existing;
2030 found_da_stream = da_stream;
2031 found_da_state = da_state;
2032 found_da_name = da_name;
2035 ast_trace(-1,
"%s: Found NP slot: %d Found removed NP slot: %d Found DA slot: %d\n",
2036 session_name, found_np_slot, removed_np_slot, found_da_slot);
2043 if (!found_da_stream) {
2050 ast_trace(-1,
"%s: There was no corresponding DA stream so the request was to add a stream\n", session_name);
2052 if (found_np_stream) {
2057 SCOPE_EXIT_EXPR(
continue,
"%s: New stream requested but it's already in CA\n", session_name);
2062 ast_trace(-1,
"%s: There was no corresponding NP stream\n", session_name);
2071 "%s: Attempting to remove stream %d:%s but it doesn't exist anywhere.\n", session_name, i, dp_name);
2078 ast_trace(-1,
"%s: Checking for open slot\n", session_name);
2079 if (removed_np_slot >= 0) {
2097 session_name, removed_np_slot);
2109 session_name, new_slot);
2117 ast_trace(-1,
"%s: There was a corresponding DA stream so the request was to change/remove a stream\n", session_name);
2118 if (dp_state == found_da_state) {
2120 if (!found_np_stream) {
2128 SCOPE_EXIT_EXPR(
continue,
"%s: Stream doesn't exist in CA so nothing to do\n", session_name);
2129 }
else if (dp_state == found_np_state) {
2130 SCOPE_EXIT_EXPR(
continue,
"%s: States are the same all around so nothing to do\n", session_name);
2132 SCOPE_EXIT_EXPR(
continue,
"%s: Something changed the CA state so we're going to leave it as is\n", session_name);
2137 if (!found_np_stream) {
2138 SCOPE_EXIT_EXPR(
continue,
"%s: Stream doesn't exist in CA so nothing to do\n", session_name);
2139 }
else if (da_state == found_np_state) {
2141 SCOPE_EXIT_EXPR(
continue,
"%s: Changed NP stream state from %s to %s\n",
2144 SCOPE_EXIT_EXPR(
continue,
"%s: Something changed the CA state so we're going to leave it as is\n",
2150 SCOPE_EXIT(
"%s: Done with slot %d\n", session_name, i);
2153 ast_trace(-1,
"%s: Resetting default media states\n", session_name);
2156 new_pending_state->default_session[i] =
NULL;
2162 new_pending_state->default_session[i] = media;
2168 if (run_post_validation) {
2169 ast_trace(-1,
"%s: Running post-validation\n", session_name);
2179 returned_media_state = new_pending_state;
2180 new_pending_state =
NULL;
2194 pjsip_inv_session *inv_session =
session->inv_session;
2195 pjmedia_sdp_session *new_sdp =
NULL;
2196 pjsip_tx_data *tdata;
2199 generate_new_sdp ?
"yes" :
"no", queued ?
"yes" :
"no",
2203 if (pending_media_state && (!pending_media_state->
topology || !generate_new_sdp)) {
2208 pending_media_state->
topology ==
NULL ?
"pending topology is null " :
"",
2209 !generate_new_sdp ?
"generate_new_sdp is false" :
"");
2212 if (inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
2221 if (inv_session->dlg->state != PJSIP_DIALOG_STATE_ESTABLISHED) {
2227 SCOPE_EXIT_RTN_VALUE(res,
"%s: Delay sending reinvite because dialog has not been established\n",
2232 if (inv_session->invite_tsx) {
2239 }
else if (inv_session->state != PJSIP_INV_STATE_CONFIRMED) {
2250 if (generate_new_sdp) {
2252 if (inv_session->neg
2253 && pjmedia_sdp_neg_get_state(inv_session->neg)
2254 != PJMEDIA_SDP_NEG_STATE_DONE) {
2256 on_response, generate_new_sdp,
2260 SCOPE_EXIT_RTN_VALUE(res,
"%s: Delay session refresh with new SDP because SDP negotiation is not yet done\n",
2265 if (pending_media_state) {
2278 on_response, generate_new_sdp,
2290 if (active_media_state && active_media_state->
topology &&
2304 pending_media_state, active_media_state,
session->active_media_state, 1);
2305 if (new_pending_state) {
2308 pending_media_state = new_pending_state;
2329 if (
session->active_media_state->topology &&
2356 if (!existing_stream) {
2382 if (!existing_stream) {
2417 if (
session->active_media_state->topology) {
2451 SCOPE_EXIT(
"%s: Appended empty stream in position %d to make counts match\n",
2474 session->pending_media_state = pending_media_state;
2484 if (on_sdp_creation) {
2485 if (on_sdp_creation(
session, new_sdp)) {
2494 if (pjsip_inv_reinvite(inv_session,
NULL, new_sdp, &tdata)) {
2495 if (generate_new_sdp) {
2501 }
else if (pjsip_inv_update(inv_session,
NULL, new_sdp, &tdata)) {
2502 if (generate_new_sdp) {
2508 if (on_request_creation) {
2509 if (on_request_creation(
session, tdata)) {
2510 if (generate_new_sdp) {
2533 on_response,
method, generate_new_sdp, media_state,
NULL, 0);
2539 pjsip_inv_session *inv_session =
session->inv_session;
2540 pjmedia_sdp_session *new_answer =
NULL;
2541 const pjmedia_sdp_session *previous_offer =
NULL;
2545 if (!inv_session->neg || (pjmedia_sdp_neg_get_state(inv_session->neg) != PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER &&
2546 pjmedia_sdp_neg_get_state(inv_session->neg) != PJMEDIA_SDP_NEG_STATE_WAIT_NEGO)) {
2547 ast_log(
LOG_WARNING,
"Requested to regenerate local SDP answer for channel '%s' but negotiation in state '%s'\n",
2552 pjmedia_sdp_neg_get_neg_remote(inv_session->neg, &previous_offer);
2553 if (pjmedia_sdp_neg_get_state(inv_session->neg) == PJMEDIA_SDP_NEG_STATE_WAIT_NEGO) {
2555 pjmedia_sdp_neg_negotiate(inv_session->pool, inv_session->neg, 0);
2556 pjmedia_sdp_neg_set_remote_offer(inv_session->pool, inv_session->neg, previous_offer);
2566 if (on_sdp_creation) {
2567 if (on_sdp_creation(
session, new_answer)) {
2572 pjsip_inv_set_sdp_answer(inv_session, new_answer);
2580 pjsip_inv_send_msg(
session->inv_session, tdata);
2589 .name = {
"Session Module", 14},
2590 .priority = PJSIP_MOD_PRIORITY_APPLICATION,
2605 if (!
session->pending_media_state->topology) {
2607 if (!
session->pending_media_state->topology) {
2612 for (i = 0; i < sdp->media_count; ++i) {
2622 pjmedia_sdp_media *remote_stream = sdp->media[i];
2627 if (
session->active_media_state->topology &&
2646 if (existing_stream) {
2655 if (!session_media) {
2661 if (pjmedia_sdp_media_find_attr2(remote_stream,
"sendonly",
NULL)) {
2667 }
else if (pjmedia_sdp_media_find_attr2(remote_stream,
"recvonly",
NULL)) {
2669 }
else if (pjmedia_sdp_media_find_attr2(remote_stream,
"inactive",
NULL)) {
2680 if (
handler->defer_incoming_sdp_stream) {
2681 res =
handler->defer_incoming_sdp_stream(
session, session_media, sdp,
2699 if (!handler_list) {
2707 if (!
handler->defer_incoming_sdp_stream) {
2710 res =
handler->defer_incoming_sdp_stream(
session, session_media, sdp,
2738 pjsip_rdata_sdp_info *sdp_info;
2741 if (rdata->msg_info.msg->line.req.method.id != PJSIP_INVITE_METHOD ||
2742 !(dlg = pjsip_ua_find_dialog(&rdata->msg_info.cid->id, &rdata->msg_info.to->tag, &rdata->msg_info.from->tag, PJ_FALSE)) ||
2748 if (
session->inv_session->invite_tsx) {
2753 if (
session->deferred_reinvite) {
2754 pj_str_t key, deferred_key;
2755 pjsip_tx_data *tdata;
2758 pjsip_tsx_create_key(rdata->tp_info.pool, &key, PJSIP_ROLE_UAS, &rdata->msg_info.cseq->method, rdata);
2759 pjsip_tsx_create_key(rdata->tp_info.pool, &deferred_key, PJSIP_ROLE_UAS, &
session->deferred_reinvite->msg_info.cseq->method,
2763 if (!pj_strcmp(&key, &deferred_key)) {
2768 if (pjsip_dlg_create_response(dlg, rdata, 491,
NULL, &tdata) == PJ_SUCCESS) {
2770 pjsip_tx_data_dec_ref(tdata);
2777 if (!(sdp_info = pjsip_rdata_get_sdp_info(rdata)) ||
2778 (sdp_info->sdp_err != PJ_SUCCESS)) {
2782 if (!sdp_info->sdp) {
2787 if (deferred == -1) {
2790 }
else if (!deferred) {
2794 pjsip_rx_data_clone(rdata, 0, &
session->deferred_reinvite);
2801 if (!
session->deferred_reinvite) {
2809 pjsip_rx_data_free_cloned(
session->deferred_reinvite);
2814 .name = {
"Session Re-Invite Module", 24 },
2815 .priority = PJSIP_MOD_PRIORITY_UA_PROXY_LAYER - 1,
2822 pjsip_inv_session *inv_session =
session->inv_session;
2829 if (inv_session->state == PJSIP_INV_STATE_DISCONNECTED &&
2830 tdata->msg->line.req.method.id != PJSIP_BYE_METHOD) {
2838 pjsip_inv_send_msg(
session->inv_session, tdata);
2850 pjmedia_sdp_session *offer;
2854 pjsip_inv_terminate(
session->inv_session, 500, PJ_FALSE);
2858 pjsip_inv_set_local_sdp(
session->inv_session, offer);
2859 pjmedia_sdp_neg_set_prefer_remote_codec_order(
session->inv_session->neg, PJ_FALSE);
2860 #ifdef PJMEDIA_SDP_NEG_ANSWER_MULTIPLE_CODECS
2861 if (!
session->endpoint->preferred_codec_only) {
2862 pjmedia_sdp_neg_set_answer_multiple_codecs(
session->inv_session->neg, PJ_TRUE);
2872 if (pjsip_inv_invite(
session->inv_session, tdata) != PJ_SUCCESS) {
2893 const char *uid2 = flags &
OBJ_KEY ? arg : datastore2->
uid;
2906 #ifdef TEST_FRAMEWORK
2908 const char *endpoint_name =
session->endpoint ?
2951 struct pjsip_dialog *dlg =
session->inv_session->dlg;
2957 #ifdef HAVE_PJSIP_INV_SESSION_REF
2958 pjsip_inv_dec_ref(
session->inv_session);
2996 int dsp_features = 0;
3008 if (!
session->direct_media_cap) {
3017 if (!
session->active_media_state) {
3021 if (!
session->pending_media_state) {
3079 #ifdef HAVE_PJSIP_INV_SESSION_REF
3080 if (pjsip_inv_add_ref(
inv_session) != PJ_SUCCESS) {
3100 session->authentication_challenge_count = 0;
3189 session->suspended = suspender;
3234 pjsip_transaction *tsx;
3236 pjsip_inv_session *inv;
3237 pjsip_tx_data *tdata;
3240 if (rdata->msg_info.msg->line.status.code != 401
3241 && rdata->msg_info.msg->line.status.code != 407) {
3246 tsx = pjsip_rdata_get_tsx(rdata);
3247 dlg = pjsip_rdata_get_dlg(rdata);
3252 if (tsx->method.id != PJSIP_INVITE_METHOD) {
3257 inv = pjsip_dlg_get_inv_session(dlg);
3260 if (PJSIP_INV_STATE_CONFIRMED <= inv->
state) {
3277 tsx->last_tx, &tdata)) {
3285 pjsip_inv_uac_restart(inv, PJ_FALSE);
3292 .name = {
"Outbound INVITE Auth", 20},
3293 .priority = PJSIP_MOD_PRIORITY_DIALOG_USAGE,
3315 return status != PJ_SUCCESS ? -1 : 0;
3322 const char *uri =
NULL;
3325 pjsip_timer_setting
timer;
3327 struct pjsip_inv_session *inv_session;
3338 &found_aor, &found_contact);
3342 uri = found_contact->uri;
3350 ast_log(
LOG_ERROR,
"Endpoint '%s': No URI available. Is endpoint registered?\n",
3360 pjsip_dlg_terminate(dlg);
3365 pjsip_dlg_terminate(dlg);
3368 #if defined(HAVE_PJSIP_REPLACE_MEDIA_STREAM) || defined(PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE)
3369 inv_session->sdp_neg_flags = PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE;
3372 pjsip_timer_setting_default(&
timer);
3408 if (!
session->pending_media_state->topology) {
3410 if (!
session->pending_media_state->topology) {
3411 pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
3424 if (!
session->pending_media_state->topology) {
3427 if (!
session->pending_media_state->topology) {
3428 pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
3435 pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
3455 pjsip_tx_data *packet =
NULL;
3458 if (
session->defer_terminate) {
3459 session->terminate_while_deferred = 1;
3477 switch (
session->inv_session->state) {
3478 case PJSIP_INV_STATE_NULL:
3479 if (!
session->inv_session->invite_tsx) {
3488 pjsip_inv_terminate(
session->inv_session, response, PJ_TRUE);
3496 pjsip_inv_terminate(
session->inv_session, response, PJ_TRUE);
3499 case PJSIP_INV_STATE_CONFIRMED:
3500 if (
session->inv_session->invite_tsx) {
3501 ast_debug(3,
"%s: Delay sending BYE because of outstanding transaction...\n",
3512 if (
status == PJ_SUCCESS && packet) {
3520 if (packet->msg->type == PJSIP_RESPONSE_MSG) {
3535 if (
session->defer_terminate) {
3557 pj_time_val delay = { .sec = 60, };
3566 session->ended_while_deferred = 0;
3572 &
session->scheduled_termination, &delay) != PJ_SUCCESS) ? -1 : 0;
3590 &
session->scheduled_termination,
session->scheduled_termination.id)) {
3597 if (!
session->defer_terminate) {
3604 if (
session->terminate_while_deferred) {
3621 if (
session->ended_while_deferred) {
3624 session->ended_while_deferred = 0;
3631 pjsip_inv_session *
inv_session = pjsip_dlg_get_inv_session(dlg);
3667 pjsip_uri *ruri = rdata->msg_info.msg->line.req.uri;
3668 pjsip_sip_uri *sip_ruri;
3672 if (!PJSIP_URI_SCHEME_IS_SIP(ruri) && !PJSIP_URI_SCHEME_IS_SIPS(ruri)) {
3676 sip_ruri = pjsip_uri_get_uri(ruri);
3687 ast_log(
LOG_ERROR,
"%s: Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n",
3701 session->request_uri = pjsip_uri_clone(
session->inv_session->pool, ruri);
3709 if (
session->endpoint->allow_overlap && (
3742 int answer_code,
int terminate_code, pj_bool_t notify)
3744 pjsip_tx_data *tdata =
NULL;
3747 if (inv_session->state != PJSIP_INV_STATE_DISCONNECTED) {
3748 if (pjsip_inv_initial_answer(
3749 inv_session, rdata, answer_code,
NULL,
NULL, &tdata) != PJ_SUCCESS) {
3751 pjsip_inv_terminate(inv_session, terminate_code ? terminate_code : answer_code, notify);
3754 pjsip_inv_send_msg(inv_session, tdata);
3758 if (answer_code >= 300) {
3763 pjsip_dlg_dec_lock(inv_session->dlg);
3790 pjsip_tx_data *tdata;
3792 pjsip_inv_session *inv_session;
3794 pj_status_t dlg_status = PJ_EUNKNOWN;
3799 pjsip_tx_data_dec_ref(tdata);
3809 if (dlg_status != PJ_EEXISTS) {
3820 if (pjsip_inv_create_uas(dlg, rdata,
NULL,
options, &inv_session) != PJ_SUCCESS) {
3827 pjsip_dlg_dec_lock(dlg);
3828 pjsip_dlg_terminate(dlg);
3832 #if defined(HAVE_PJSIP_REPLACE_MEDIA_STREAM) || defined(PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE)
3833 inv_session->sdp_neg_flags = PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE;
3856 pjsip_media_type app_sdp;
3857 pjsip_media_type_init2(&app_sdp,
"application",
"sdp");
3859 if (!pjsip_media_type_cmp(content_type, &app_sdp, 0)) {
3868 pjsip_hdr *hdr = part->hdr.next;
3869 static const pj_str_t str_handling_required = {
"handling=required", 16};
3871 while (hdr != &part->hdr) {
3872 if (hdr->type == PJSIP_H_OTHER) {
3873 pjsip_generic_string_hdr *generic_hdr = (pjsip_generic_string_hdr*)hdr;
3875 if (!pj_stricmp2(&hdr->name,
"Content-Disposition") &&
3876 pj_stristr(&generic_hdr->hvalue, &str_handling_required) &&
3892 pjsip_msg_body *body = rdata->msg_info.msg->body;
3893 pjsip_ctype_hdr *ctype_hdr = rdata->msg_info.ctype;
3895 if (body && ctype_hdr &&
3898 pjsip_multipart_part *part = pjsip_multipart_get_first_part(body);
3899 while (part !=
NULL) {
3903 part = pjsip_multipart_get_next_part(body, part);
3911 pjsip_tx_data *tdata =
NULL;
3912 pjsip_timer_setting
timer;
3913 pjsip_rdata_sdp_info *sdp_info;
3914 pjmedia_sdp_session *local =
NULL;
3936 ast_trace(-1,
"%s: Call (%s:%s) to extension '%s' - unsupported uri\n",
3938 invite->
rdata->tp_info.transport->type_name,
3939 pj_sockaddr_print(&invite->
rdata->pkt_info.src_addr, buffer,
sizeof(buffer), 3),
3948 ast_trace(-1,
"%s: Call (%s:%s) to extension '%s' - partial match\n",
3950 invite->
rdata->tp_info.transport->type_name,
3951 pj_sockaddr_print(&invite->
rdata->pkt_info.src_addr, buffer,
sizeof(buffer), 3),
3962 ast_trace_log(-1,
LOG_NOTICE,
"%s: Call (%s:%s) to extension '%s' rejected because extension not found in context '%s'.\n",
3964 invite->
rdata->tp_info.transport->type_name,
3965 pj_sockaddr_print(&invite->
rdata->pkt_info.src_addr, buffer,
sizeof(buffer), 3),
3986 pjsip_timer_setting_default(&
timer);
3996 ast_trace(-1,
"%s: Call (%s:%s) to extension '%s' sending 100 Trying\n",
3998 invite->
rdata->tp_info.transport->type_name,
3999 pj_sockaddr_print(&invite->
rdata->pkt_info.src_addr, buffer,
sizeof(buffer), 3),
4007 sdp_info = pjsip_rdata_get_sdp_info(invite->
rdata);
4008 if (sdp_info && (sdp_info->sdp_err == PJ_SUCCESS) && sdp_info->sdp) {
4035 pjmedia_sdp_neg_set_prefer_remote_codec_order(invite->
session->
inv_session->neg, PJ_FALSE);
4036 #ifdef PJMEDIA_SDP_NEG_ANSWER_MULTIPLE_CODECS
4038 pjmedia_sdp_neg_set_answer_multiple_codecs(invite->
session->
inv_session->neg, PJ_TRUE);
4052 static const pj_str_t identity_str = {
"Identity", 8 };
4053 const pj_str_t use_identity_header_str = {
4061 int res =
TRACE_ATLEAST(1) ? pjsip_uri_print(PJSIP_URI_IN_REQ_URI,
rdata->msg_info.msg->line.req.uri, req_uri, 256) : 0;
4062 SCOPE_ENTER(1,
"Request: %s\n", res ? req_uri :
"");
4070 ast_debug(3,
"No Identity header when we require one\n");
4108 pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
4134 pjsip_dlg_dec_lock(inv_session->dlg);
4148 pj_cstr(&
method, supplement_method);
4156 struct pjsip_method *
method = &rdata->msg_info.msg->line.req.method;
4177 pjsip_dialog *dlg = pjsip_tsx_get_dlg(tsx);
4178 pjsip_inv_session *inv_session = (dlg ? pjsip_dlg_get_inv_session(dlg) :
NULL);
4184 ast_trace(2,
"Topology: Pending: %s Active: %s\n",
4199 struct pjsip_status_line
status = rdata->msg_info.msg->line.status;
4200 pjsip_dialog *dlg = pjsip_rdata_get_dlg(rdata);
4201 pjsip_inv_session *inv_session = dlg ? pjsip_dlg_get_inv_session(dlg) :
NULL;
4204 (
int)rdata->msg_info.cseq->method.name.slen, rdata->msg_info.cseq->method.name.ptr,
status.code);
4228 pj_status_t handled = PJ_FALSE;
4229 struct pjsip_request_line req = rdata->msg_info.msg->line.req;
4230 pjsip_dialog *dlg = pjsip_rdata_get_dlg(rdata);
4231 pjsip_inv_session *inv_session = (dlg ? pjsip_dlg_get_inv_session(dlg) :
NULL);
4234 int res =
TRACE_ATLEAST(1) ? pjsip_uri_print(PJSIP_URI_IN_REQ_URI, rdata->msg_info.msg->line.req.uri, req_uri, 256) : 0;
4236 (
int) pj_strlen(&req.method.name), pj_strbuf(&req.method.name), res ? req_uri :
"");
4238 switch (req.method.id) {
4239 case PJSIP_INVITE_METHOD:
4249 handled = dlg && (
inv_session = pjsip_dlg_get_inv_session(dlg)) &&
4255 (
int) pj_strlen(&req.method.name), pj_strbuf(&req.method.name), req_uri,
4256 handled == PJ_TRUE ?
"yes" :
"no");
4263 ast_debug(3,
"%s: re-INVITE collision timer expired.\n",
4282 pjsip_inv_session *inv =
session->inv_session;
4287 int use_pending = 0;
4301 use_pending =
session->pending_media_state->topology !=
NULL;
4302 use_active =
session->active_media_state->topology !=
NULL;
4315 if (!pending_media_state) {
4322 if (!active_media_state) {
4329 active_media_state, 1)) {
4335 if (pj_timer_entry_running(&
session->rescheduled_reinvite)) {
4341 if (inv->role == PJSIP_ROLE_UAC) {
4350 &
session->rescheduled_reinvite, &tv) != PJ_SUCCESS) {
4369 function, pjsip_event_str(e->type));
4371 ast_log(
LOG_DEBUG,
"Transaction %p does not belong to an inv_session?\n", tsx);
4373 pjsip_tsx_state_str(tsx->state));
4386 if (inv->invite_tsx) {
4393 ast_log(
LOG_DEBUG,
"The %s %.*s transaction involved in this state change is %p\n",
4394 pjsip_role_name(tsx->role),
4395 (
int) pj_strlen(&tsx->method.name), pj_strbuf(&tsx->method.name),
4398 pjsip_tsx_state_str(tsx->state));
4400 pjsip_event_str(e->body.tsx_state.type));
4402 ast_log(
LOG_DEBUG,
"There is no transaction involved in this state change\n");
4404 ast_log(
LOG_DEBUG,
"The current inv state is %s\n", pjsip_inv_state_name(inv->state));
4407 #define print_debug_details(inv, tsx, e) __print_debug_details(__PRETTY_FUNCTION__, (inv), (tsx), (e))
4412 struct pjsip_request_line req = rdata->msg_info.msg->line.req;
4464 struct pjsip_status_line
status = rdata->msg_info.msg->line.status;
4483 if (rdata->msg_info.msg->type == PJSIP_REQUEST_MSG) {
4495 struct pjsip_request_line req = tdata->msg->line.req;
4497 (
int) pj_strlen(&req.method.name), pj_strbuf(&req.method.name));
4512 struct pjsip_status_line
status = tdata->msg->line.status;
4513 pjsip_cseq_hdr *cseq = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CSEQ,
NULL);
4515 (
int) pj_strlen(&cseq->method.name),
4516 pj_strbuf(&cseq->method.name),
status.code, (
int) pj_strlen(&
status.reason),
4517 pj_strbuf(&
status.reason));
4574 pjsip_transaction *tsx = e->body.tsx_state.tsx;
4576 if (tsx->status_code != 503 && tsx->status_code != 408) {
4584 pjsip_inv_uac_restart(inv, PJ_FALSE);
4589 pjsip_tx_data_add_ref(tsx->last_tx);
4599 "request" :
"response");
4603 msg = rdata->msg_info.msg;
4604 if (msg->type == PJSIP_REQUEST_MSG
4605 && msg->line.req.method.id == PJSIP_ACK_METHOD
4606 && pjmedia_sdp_neg_get_state(inv->neg) != PJMEDIA_SDP_NEG_STATE_DONE) {
4607 pjsip_tx_data *tdata;
4616 "%s: Ending session due to incomplete SDP negotiation. %s\n",
4618 pjsip_rx_data_get_info(rdata));
4619 if (pjsip_inv_end_session(inv, 400,
NULL, &tdata) == PJ_SUCCESS
4628 pjsip_event_id_e
type;
4631 pjsip_event_str(e->type), pjsip_inv_state_name(inv->state));
4641 type = PJSIP_EVENT_UNKNOWN;
4650 case PJSIP_EVENT_TX_MSG:
4652 case PJSIP_EVENT_RX_MSG:
4655 case PJSIP_EVENT_TSX_STATE:
4657 pjsip_event_str(e->body.tsx_state.type));
4659 switch(e->body.tsx_state.type) {
4660 case PJSIP_EVENT_TX_MSG:
4662 case PJSIP_EVENT_RX_MSG:
4667 case PJSIP_EVENT_TRANSPORT_ERROR:
4668 case PJSIP_EVENT_TIMER:
4676 case PJSIP_EVENT_USER:
4677 case PJSIP_EVENT_UNKNOWN:
4678 case PJSIP_EVENT_TSX_STATE:
4683 case PJSIP_EVENT_TRANSPORT_ERROR:
4684 case PJSIP_EVENT_TIMER:
4685 case PJSIP_EVENT_UNKNOWN:
4686 case PJSIP_EVENT_USER:
4691 if (inv->state == PJSIP_INV_STATE_DISCONNECTED) {
4694 session->ended_while_deferred = 1;